ZGlmZiAtLWdpdCBhL3Rvb2xzL0xJQ0VOU0UuVFhUIGIvdG9vbHMvTElDRU5TRS5UWFQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTMxMjIzYQotLS0gL2Rldi9udWxsCisrKyBiL3Rvb2xzL0xJQ0VOU0UuVFhUCkBAIC0wLDAgKzEsNjMgQEAKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorTExWTSBSZWxlYXNlIExpY2Vuc2UKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorVW5pdmVyc2l0eSBvZiBJbGxpbm9pcy9OQ1NBCitPcGVuIFNvdXJjZSBMaWNlbnNlCisKK0NvcHlyaWdodCAoYykgMjAwNy0yMDEzIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgYXQgVXJiYW5hLUNoYW1wYWlnbi4KK0FsbCByaWdodHMgcmVzZXJ2ZWQuCisKK0RldmVsb3BlZCBieToKKworICAgIExMVk0gVGVhbQorCisgICAgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBhdCBVcmJhbmEtQ2hhbXBhaWduCisKKyAgICBodHRwOi8vbGx2bS5vcmcKKworUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weSBvZgordGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwgd2l0aAordGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0bwordXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMKK29mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbworc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgorCisgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsCisgICAgICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVycy4KKworICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLAorICAgICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcnMgaW4gdGhlCisgICAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgorCisgICAgKiBOZWl0aGVyIHRoZSBuYW1lcyBvZiB0aGUgTExWTSBUZWFtLCBVbml2ZXJzaXR5IG9mIElsbGlub2lzIGF0CisgICAgICBVcmJhbmEtQ2hhbXBhaWduLCBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8KKyAgICAgIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBTb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljCisgICAgICBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisKK1RIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCitJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUworRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKK0NPTlRSSUJVVE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUgorTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKK09VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgV0lUSCBUSEUKK1NPRlRXQVJFLgorCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KK1RoZSBMTFZNIHNvZnR3YXJlIGNvbnRhaW5zIGNvZGUgd3JpdHRlbiBieSB0aGlyZCBwYXJ0aWVzLiAgU3VjaCBzb2Z0d2FyZSB3aWxsCitoYXZlIGl0cyBvd24gaW5kaXZpZHVhbCBMSUNFTlNFLlRYVCBmaWxlIGluIHRoZSBkaXJlY3RvcnkgaW4gd2hpY2ggaXQgYXBwZWFycy4KK1RoaXMgZmlsZSB3aWxsIGRlc2NyaWJlIHRoZSBjb3B5cmlnaHRzLCBsaWNlbnNlLCBhbmQgcmVzdHJpY3Rpb25zIHdoaWNoIGFwcGx5Cit0byB0aGF0IGNvZGUuCisKK1RoZSBkaXNjbGFpbWVyIG9mIHdhcnJhbnR5IGluIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlIExpY2Vuc2UKK2FwcGxpZXMgdG8gYWxsIGNvZGUgaW4gdGhlIExMVk0gRGlzdHJpYnV0aW9uLCBhbmQgbm90aGluZyBpbiBhbnkgb2YgdGhlCitvdGhlciBsaWNlbnNlcyBnaXZlcyBwZXJtaXNzaW9uIHRvIHVzZSB0aGUgbmFtZXMgb2YgdGhlIExMVk0gVGVhbSBvciB0aGUKK1VuaXZlcnNpdHkgb2YgSWxsaW5vaXMgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCitTb2Z0d2FyZS4KKworVGhlIGZvbGxvd2luZyBwaWVjZXMgb2Ygc29mdHdhcmUgaGF2ZSBhZGRpdGlvbmFsIG9yIGFsdGVybmF0ZSBjb3B5cmlnaHRzLAorbGljZW5zZXMsIGFuZC9vciByZXN0cmljdGlvbnM6CisKK1Byb2dyYW0gICAgICAgICAgICAgRGlyZWN0b3J5CistLS0tLS0tICAgICAgICAgICAgIC0tLS0tLS0tLQorPG5vbmUgeWV0PgorCmRpZmYgLS1naXQgYS90b29scy9zY2FuLWJ1aWxkL2MrKy1hbmFseXplciBiL3Rvb2xzL3NjYW4tYnVpbGQvYysrLWFuYWx5emVyCm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLmRkYTVkYjkKLS0tIC9kZXYvbnVsbAorKysgYi90b29scy9zY2FuLWJ1aWxkL2MrKy1hbmFseXplcgpAQCAtMCwwICsxLDggQEAKKyMhL3Vzci9iaW4vZW52IHBlcmwKKwordXNlIEN3ZCBxdy8gYWJzX3BhdGggLzsKK3VzZSBGaWxlOjpCYXNlbmFtZSBxdy8gZGlybmFtZSAvOworIyBBZGQgc2Nhbi1idWlsZCBkaXIgdG8gdGhlIGxpc3Qgb2YgcGxhY2VzIHdoZXJlIHBlcmwgbG9va3MgZm9yIG1vZHVsZXMuCit1c2UgbGliIGRpcm5hbWUoYWJzX3BhdGgoJDApKTsKKworZG8gJ2NjYy1hbmFseXplcic7CmRpZmYgLS1naXQgYS90b29scy9zY2FuLWJ1aWxkL2NjYy1hbmFseXplciBiL3Rvb2xzL3NjYW4tYnVpbGQvY2NjLWFuYWx5emVyCm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjVmNjMxNDgKLS0tIC9kZXYvbnVsbAorKysgYi90b29scy9zY2FuLWJ1aWxkL2NjYy1hbmFseXplcgpAQCAtMCwwICsxLDcwNiBAQAorIyEvdXNyL2Jpbi9lbnYgcGVybAorIworIyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisjCisjIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorIyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisjCisjIz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0jIworIworIyAgQSBzY3JpcHQgZGVzaWduZWQgdG8gaW50ZXJwb3NlIGJldHdlZW4gdGhlIGJ1aWxkIHN5c3RlbSBhbmQgZ2NjLiAgSXQgaW52b2tlcworIyAgYm90aCBnY2MgYW5kIHRoZSBzdGF0aWMgYW5hbHl6ZXIuCisjCisjIz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0jIworCit1c2Ugc3RyaWN0OwordXNlIHdhcm5pbmdzOwordXNlIEZpbmRCaW47Cit1c2UgQ3dkIHF3LyBnZXRjd2QgYWJzX3BhdGggLzsKK3VzZSBGaWxlOjpUZW1wIHF3LyB0ZW1wZmlsZSAvOwordXNlIEZpbGU6OlBhdGggcXcgLyBta3BhdGggLzsKK3VzZSBGaWxlOjpCYXNlbmFtZTsKK3VzZSBUZXh0OjpQYXJzZVdvcmRzOworCisjIz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0jIworIyBDb21waWxlciBjb21tYW5kIHNldHVwLgorIyM9PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09IyMKKworbXkgJENvbXBpbGVyOworbXkgJENsYW5nOworbXkgJERlZmF1bHRDQ29tcGlsZXI7CitteSAkRGVmYXVsdENYWENvbXBpbGVyOworCitpZiAoYHVuYW1lIC1hYCA9fiBtL0Rhcndpbi8pIHsgCisgICREZWZhdWx0Q0NvbXBpbGVyID0gJ2NsYW5nJzsKKyAgJERlZmF1bHRDWFhDb21waWxlciA9ICdjbGFuZysrJzsKK30gZWxzZSB7CisgICREZWZhdWx0Q0NvbXBpbGVyID0gJ2djYyc7CisgICREZWZhdWx0Q1hYQ29tcGlsZXIgPSAnZysrJzsKK30KKworaWYgKCRGaW5kQmluOjpTY3JpcHQgPX4gL2NcK1wrLWFuYWx5emVyLykgeworICAkQ29tcGlsZXIgPSAkRU5WeydDQ0NfQ1hYJ307CisgIGlmICghZGVmaW5lZCAkQ29tcGlsZXIpIHsgJENvbXBpbGVyID0gJERlZmF1bHRDWFhDb21waWxlcjsgfQorICAKKyAgJENsYW5nID0gJEVOVnsnQ0xBTkdfQ1hYJ307CisgIGlmICghZGVmaW5lZCAkQ2xhbmcpIHsgJENsYW5nID0gJ2NsYW5nKysnOyB9Cit9CitlbHNlIHsKKyAgJENvbXBpbGVyID0gJEVOVnsnQ0NDX0NDJ307CisgIGlmICghZGVmaW5lZCAkQ29tcGlsZXIpIHsgJENvbXBpbGVyID0gJERlZmF1bHRDQ29tcGlsZXI7IH0KKworICAkQ2xhbmcgPSAkRU5WeydDTEFORyd9OworICBpZiAoIWRlZmluZWQgJENsYW5nKSB7ICRDbGFuZyA9ICdjbGFuZyc7IH0KK30KKworIyM9PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09IyMKKyMgQ2xlYW51cC4KKyMjPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PSMjCisKK215ICRSZXBvcnRGYWlsdXJlcyA9ICRFTlZ7J0NDQ19SRVBPUlRfRkFJTFVSRVMnfTsKK2lmICghZGVmaW5lZCAkUmVwb3J0RmFpbHVyZXMpIHsgJFJlcG9ydEZhaWx1cmVzID0gMTsgfQorCitteSAkQ2xlYW51cEZpbGU7CitteSAkUmVzdWx0RmlsZTsKKworIyBSZW1vdmUgYW55IHN0YWxlIGZpbGVzIGF0IGV4aXQuCitFTkQgeyAKKyAgaWYgKGRlZmluZWQgJFJlc3VsdEZpbGUgJiYgLXogJFJlc3VsdEZpbGUpIHsKKyAgICBgcm0gLWYgJFJlc3VsdEZpbGVgOworICB9CisgIGlmIChkZWZpbmVkICRDbGVhbnVwRmlsZSkgeworICAgIGBybSAtZiAkQ2xlYW51cEZpbGVgOworICB9Cit9CisKKyMjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSMjCisjICBQcm9jZXNzIENsYW5nIENyYXNoZXMuCisjIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0jIworCitzdWIgR2V0UFBFeHQgeworICBteSAkTGFuZyA9IHNoaWZ0OworICBpZiAoJExhbmcgPX4gL29iamVjdGl2ZS1jXCtcKy8pIHsgcmV0dXJuICIubWlpIiB9OworICBpZiAoJExhbmcgPX4gL29iamVjdGl2ZS1jLykgeyByZXR1cm4gIi5taSI7IH0KKyAgaWYgKCRMYW5nID1+IC9jXCtcKy8pIHsgcmV0dXJuICIuaWkiOyB9CisgIHJldHVybiAiLmkiOworfQorCisjIFNldCB0aGlzIHRvIDEgaWYgd2Ugd2FudCB0byBpbmNsdWRlICdwYXJzZXIgcmVqZWN0cycgZmlsZXMuCitteSAkSW5jbHVkZVBhcnNlclJlamVjdHMgPSAwOworbXkgJFBhcnNlclJlamVjdHMgPSAiUGFyc2VyIFJlamVjdHMiOworbXkgJEF0dHJpYnV0ZUlnbm9yZWQgPSAiQXR0cmlidXRlIElnbm9yZWQiOworbXkgJE90aGVyRXJyb3IgPSAiT3RoZXIgRXJyb3IiOworCitzdWIgUHJvY2Vzc0NsYW5nRmFpbHVyZSB7CisgIG15ICgkQ2xhbmcsICRMYW5nLCAkZmlsZSwgJEFyZ3MsICRIdG1sRGlyLCAkRXJyb3JUeXBlLCAkb2ZpbGUpID0gQF87CisgIG15ICREaXIgPSAiJEh0bWxEaXIvZmFpbHVyZXMiOworICBta3BhdGggJERpcjsKKyAgCisgIG15ICRwcmVmaXggPSAiY2xhbmdfY3Jhc2giOworICBpZiAoJEVycm9yVHlwZSBlcSAkUGFyc2VyUmVqZWN0cykgeworICAgICRwcmVmaXggPSAiY2xhbmdfcGFyc2VyX3JlamVjdHMiOworICB9CisgIGVsc2lmICgkRXJyb3JUeXBlIGVxICRBdHRyaWJ1dGVJZ25vcmVkKSB7CisgICAgJHByZWZpeCA9ICJjbGFuZ19hdHRyaWJ1dGVfaWdub3JlZCI7CisgIH0KKyAgZWxzaWYgKCRFcnJvclR5cGUgZXEgJE90aGVyRXJyb3IpIHsKKyAgICAkcHJlZml4ID0gImNsYW5nX290aGVyX2Vycm9yIjsKKyAgfQorCisgICMgR2VuZXJhdGUgdGhlIHByZXByb2Nlc3NlZCBmaWxlIHdpdGggQ2xhbmcuCisgIG15ICgkUFBILCAkUFBGaWxlKSA9IHRlbXBmaWxlKCAkcHJlZml4IC4gIl9YWFhYWFgiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1VGRklYID0+IEdldFBQRXh0KCRMYW5nKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERJUiA9PiAkRGlyKTsKKyAgc3lzdGVtICRDbGFuZywgQCRBcmdzLCAiLUUiLCAiLW8iLCAkUFBGaWxlOworICBjbG9zZSAoJFBQSCk7CisgIAorICAjIENyZWF0ZSB0aGUgaW5mbyBmaWxlLgorICBvcGVuIChPVVQsICI+IiwgIiRQUEZpbGUuaW5mby50eHQiKSBvciBkaWUgIkNhbm5vdCBvcGVuICRQUEZpbGUuaW5mby50eHRcbiI7CisgIHByaW50IE9VVCBhYnNfcGF0aCgkZmlsZSksICJcbiI7CisgIHByaW50IE9VVCAiJEVycm9yVHlwZVxuIjsKKyAgcHJpbnQgT1VUICJAJEFyZ3NcbiI7CisgIGNsb3NlIE9VVDsKKyAgYHVuYW1lIC1hID4+ICRQUEZpbGUuaW5mby50eHQgMj4mMWA7CisgIGAkQ29tcGlsZXIgLXYgPj4gJFBQRmlsZS5pbmZvLnR4dCAyPiYxYDsKKyAgc3lzdGVtICdtdicsJG9maWxlLCIkUFBGaWxlLnN0ZGVyci50eHQiOworICByZXR1cm4gKGJhc2VuYW1lICRQUEZpbGUpOworfQorCisjIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0jIworIyAgUnVubmluZyB0aGUgYW5hbHl6ZXIuCisjIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0jIworCitzdWIgR2V0Q0NBcmdzIHsKKyAgbXkgJG1vZGUgPSBzaGlmdDsKKyAgbXkgJEFyZ3MgPSBzaGlmdDsKKyAgCisgIHBpcGUgKEZST01fQ0hJTEQsIFRPX1BBUkVOVCk7CisgIG15ICRwaWQgPSBmb3JrKCk7CisgIGlmICgkcGlkID09IDApIHsKKyAgICBjbG9zZSBGUk9NX0NISUxEOworICAgIG9wZW4oU1RET1VULCI+JiIsIFwqVE9fUEFSRU5UKTsKKyAgICBvcGVuKFNUREVSUiwiPiYiLCBcKlRPX1BBUkVOVCk7CisgICAgZXhlYyAkQ2xhbmcsICItIyMjIiwgJG1vZGUsIEAkQXJnczsKKyAgfSAgCisgIGNsb3NlKFRPX1BBUkVOVCk7CisgIG15ICRsaW5lOworICB3aGlsZSAoPEZST01fQ0hJTEQ+KSB7CisgICAgbmV4dCBpZiAoIS8tY2MxLyk7CisgICAgJGxpbmUgPSAkXzsKKyAgfQorCisgIHdhaXRwaWQoJHBpZCwwKTsKKyAgY2xvc2UoRlJPTV9DSElMRCk7CisgIAorICBkaWUgImNvdWxkIG5vdCBmaW5kIGNsYW5nIGxpbmVcbiIgaWYgKCFkZWZpbmVkICRsaW5lKTsKKyAgIyBTdHJpcCB0aGUgbmV3bGluZSBhbmQgaW5pdGlhbCB3aGl0c3BhY2UKKyAgY2hvbXAgJGxpbmU7CisgICRsaW5lID1+IHMvXlxzKy8vOworICBteSBAaXRlbXMgPSBxdW90ZXdvcmRzKCdccysnLCAwLCAkbGluZSk7CisgIG15ICRjbWQgPSBzaGlmdCBAaXRlbXM7CisgIGRpZSAiY2Fubm90IGZpbmQgJ2NsYW5nJyBpbiAnY2xhbmcnIGNvbW1hbmRcbiIgaWYgKCEoJGNtZCA9fiAvY2xhbmcvKSk7CisgIHJldHVybiBcQGl0ZW1zOworfQorCitzdWIgQW5hbHl6ZSB7CisgIG15ICgkQ2xhbmcsICRPcmlnaW5hbEFyZ3MsICRBbmFseXplQXJncywgJExhbmcsICRPdXRwdXQsICRWZXJib3NlLCAkSHRtbERpciwKKyAgICAgICRmaWxlKSA9IEBfOworCisgIG15IEBBcmdzID0gQCRPcmlnaW5hbEFyZ3M7CisgIG15ICRDbWQ7CisgIG15IEBDbWRBcmdzOworICBteSBAQ21kQXJnc1NhbnNBbmFseXNlczsKKworICBpZiAoJExhbmcgPX4gL2hlYWRlci8pIHsKKyAgICBleGl0IDAgaWYgKCFkZWZpbmVkICgkT3V0cHV0KSk7CisgICAgJENtZCA9ICdjcCc7CisgICAgcHVzaCBAQ21kQXJncywgJGZpbGU7CisgICAgIyBSZW1vdmUgdGhlIFBDSCBleHRlbnNpb24uCisgICAgJE91dHB1dCA9fiBzL1suXWdjaCQvLzsKKyAgICBwdXNoIEBDbWRBcmdzLCAkT3V0cHV0OworICAgIEBDbWRBcmdzU2Fuc0FuYWx5c2VzID0gQENtZEFyZ3M7CisgIH0KKyAgZWxzZSB7CisgICAgJENtZCA9ICRDbGFuZzsKKworICAgICMgQ3JlYXRlIGFyZ3VtZW50cyBmb3IgZG9pbmcgcmVndWxhciBwYXJzaW5nLgorICAgIG15ICRTeW50YXhBcmdzID0gR2V0Q0NBcmdzKCItZnN5bnRheC1vbmx5IiwgXEBBcmdzKTsKKyAgICBAQ21kQXJnc1NhbnNBbmFseXNlcyA9IEAkU3ludGF4QXJnczsKKworICAgICMgQ3JlYXRlIGFyZ3VtZW50cyBmb3IgZG9pbmcgc3RhdGljIGFuYWx5c2lzLgorICAgIGlmIChkZWZpbmVkICRSZXN1bHRGaWxlKSB7CisgICAgICBwdXNoIEBBcmdzLCAnLW8nLCAkUmVzdWx0RmlsZTsKKyAgICB9CisgICAgZWxzaWYgKGRlZmluZWQgJEh0bWxEaXIpIHsKKyAgICAgIHB1c2ggQEFyZ3MsICctbycsICRIdG1sRGlyOworICAgIH0KKyAgICBpZiAoJFZlcmJvc2UpIHsKKyAgICAgIHB1c2ggQEFyZ3MsICItWGNsYW5nIiwgIi1hbmFseXplci1kaXNwbGF5LXByb2dyZXNzIjsKKyAgICB9CisKKyAgICBmb3JlYWNoIG15ICRhcmcgKEAkQW5hbHl6ZUFyZ3MpIHsKKyAgICAgIHB1c2ggQEFyZ3MsICItWGNsYW5nIiwgJGFyZzsKKyAgICB9CisKKyAgICAjIERpc3BsYXkgVWJpdml6IGdyYXBoPworICAgIGlmIChkZWZpbmVkICRFTlZ7J0NDQ19VQkknfSkgeyAgIAorICAgICAgcHVzaCBAQXJncywgIi1YY2xhbmciLCAiLWFuYWx5emVyLXZpei1lZ3JhcGgtdWJpZ3JhcGgiOworICAgIH0KKworICAgIG15ICRBbmFseXNpc0FyZ3MgPSBHZXRDQ0FyZ3MoIi0tYW5hbHl6ZSIsIFxAQXJncyk7CisgICAgQENtZEFyZ3MgPSBAJEFuYWx5c2lzQXJnczsKKyAgfQorCisgIG15IEBQcmludEFyZ3M7CisgIG15ICRkaXI7CisKKyAgaWYgKCRWZXJib3NlKSB7CisgICAgJGRpciA9IGdldGN3ZCgpOworICAgIHByaW50IFNUREVSUiAiXG5bTE9DQVRJT05dOiAkZGlyXG4iOworICAgIHB1c2ggQFByaW50QXJncywiJyRDbWQnIjsKKyAgICBmb3JlYWNoIG15ICRhcmcgKEBDbWRBcmdzKSB7CisgICAgICAgIHB1c2ggQFByaW50QXJncywiXCckYXJnXCciOworICAgIH0KKyAgfQorICBpZiAoJFZlcmJvc2UgPT0gMSkgeworICAgICMgV2UgTVVTVCBwcmludCB0byBzdGRlcnIuICBTb21lIGNsaWVudHMgdXNlIHRoZSBzdGRvdXQgb3V0cHV0IG9mCisgICAgIyBnY2MgZm9yIHZhcmlvdXMgcHVycG9zZXMuIAorICAgIHByaW50IFNUREVSUiBqb2luKCcgJywgQFByaW50QXJncyk7CisgICAgcHJpbnQgU1RERVJSICJcbiI7CisgIH0KKyAgZWxzaWYgKCRWZXJib3NlID09IDIpIHsKKyAgICBwcmludCBTVERFUlIgIiNTSEVMTCAoY2QgJyRkaXInICYmIEBQcmludEFyZ3MpXG4iOworICB9CisKKyAgIyBDYXB0dXJlIHRoZSBTVERFUlIgb2YgY2xhbmcgYW5kIHNlbmQgaXQgdG8gYSB0ZW1wb3JhcnkgZmlsZS4KKyAgIyBDYXB0dXJlIHRoZSBTVERPVVQgb2YgY2xhbmcgYW5kIHJlcm91dGUgaXQgdG8gY2NjLWFuYWx5emVyJ3MgU1RERVJSLgorICAjIFdlIHNhdmUgdGhlIG91dHB1dCBmaWxlIGluIHRoZSAnY3Jhc2hlcycgZGlyZWN0b3J5IGlmIGNsYW5nIGVuY291bnRlcnMKKyAgIyBhbnkgcHJvYmxlbXMgd2l0aCB0aGUgZmlsZS4gIAorICBwaXBlIChGUk9NX0NISUxELCBUT19QQVJFTlQpOworICBteSAkcGlkID0gZm9yaygpOworICBpZiAoJHBpZCA9PSAwKSB7CisgICAgY2xvc2UgRlJPTV9DSElMRDsKKyAgICBvcGVuKFNURE9VVCwiPiYiLCBcKlRPX1BBUkVOVCk7CisgICAgb3BlbihTVERFUlIsIj4mIiwgXCpUT19QQVJFTlQpOworICAgIGV4ZWMgJENtZCwgQENtZEFyZ3M7CisgIH0KKworICBjbG9zZSBUT19QQVJFTlQ7CisgIG15ICgkb2ZoLCAkb2ZpbGUpID0gdGVtcGZpbGUoImNsYW5nX291dHB1dF9YWFhYWFgiLCBESVIgPT4gJEh0bWxEaXIpOworICAKKyAgd2hpbGUgKDxGUk9NX0NISUxEPikgeworICAgIHByaW50ICRvZmggJF87CisgICAgcHJpbnQgU1RERVJSICRfOworICB9CisgIGNsb3NlICRvZmg7CisKKyAgd2FpdHBpZCgkcGlkLDApOworICBjbG9zZShGUk9NX0NISUxEKTsKKyAgbXkgJFJlc3VsdCA9ICQ/OworCisgICMgRGlkIHRoZSBjb21tYW5kIGRpZSBiZWNhdXNlIG9mIGEgc2lnbmFsPworICBpZiAoJFJlcG9ydEZhaWx1cmVzKSB7CisgICAgaWYgKCRSZXN1bHQgJiAxMjcgYW5kICRDbWQgZXEgJENsYW5nIGFuZCBkZWZpbmVkICRIdG1sRGlyKSB7CisgICAgICBQcm9jZXNzQ2xhbmdGYWlsdXJlKCRDbGFuZywgJExhbmcsICRmaWxlLCBcQENtZEFyZ3NTYW5zQW5hbHlzZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICRIdG1sRGlyLCAiQ3Jhc2giLCAkb2ZpbGUpOworICAgIH0KKyAgICBlbHNpZiAoJFJlc3VsdCkgeworICAgICAgaWYgKCRJbmNsdWRlUGFyc2VyUmVqZWN0cyAmJiAhKCRmaWxlID1+L2NvbmZ0ZXN0LykpIHsKKyAgICAgICAgUHJvY2Vzc0NsYW5nRmFpbHVyZSgkQ2xhbmcsICRMYW5nLCAkZmlsZSwgXEBDbWRBcmdzU2Fuc0FuYWx5c2VzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICRIdG1sRGlyLCAkUGFyc2VyUmVqZWN0cywgJG9maWxlKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIFByb2Nlc3NDbGFuZ0ZhaWx1cmUoJENsYW5nLCAkTGFuZywgJGZpbGUsIFxAQ21kQXJnc1NhbnNBbmFseXNlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAkSHRtbERpciwgJE90aGVyRXJyb3IsICRvZmlsZSk7CisgICAgICB9CisgICAgfQorICAgIGVsc2UgeworICAgICAgIyBDaGVjayBpZiB0aGVyZSB3ZXJlIGFueSB1bmhhbmRsZWQgYXR0cmlidXRlcy4KKyAgICAgIGlmIChvcGVuKENISUxELCAkb2ZpbGUpKSB7CisgICAgICAgIG15ICVhdHRyaWJ1dGVzX25vdF9oYW5kbGVkOworCisgICAgICAgICMgRG9uJ3QgZmxhZyB3YXJuaW5ncyBhYm91dCB0aGUgZm9sbG93aW5nIGF0dHJpYnV0ZXMgdGhhdCB3ZQorICAgICAgICAjIGtub3cgYXJlIGN1cnJlbnRseSBub3Qgc3VwcG9ydGVkIGJ5IENsYW5nLgorICAgICAgICAkYXR0cmlidXRlc19ub3RfaGFuZGxlZHsiY2RlY2wifSA9IDE7CisKKyAgICAgICAgbXkgJHBwZmlsZTsKKyAgICAgICAgd2hpbGUgKDxDSElMRD4pIHsKKyAgICAgICAgICBuZXh0IGlmICghIC93YXJuaW5nOiAnKFteXCddKyknIGF0dHJpYnV0ZSBpZ25vcmVkLyk7CisKKyAgICAgICAgICAjIEhhdmUgd2UgYWxyZWFkeSBzcG90dGVkIHRoaXMgdW5oYW5kbGVkIGF0dHJpYnV0ZT8KKyAgICAgICAgICBuZXh0IGlmIChkZWZpbmVkICRhdHRyaWJ1dGVzX25vdF9oYW5kbGVkeyQxfSk7CisgICAgICAgICAgJGF0dHJpYnV0ZXNfbm90X2hhbmRsZWR7JDF9ID0gMTsKKyAgICAgICAgCisgICAgICAgICAgIyBHZXQgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSBmaWxlLgorICAgICAgICAgIG15ICRkaXIgPSAiJEh0bWxEaXIvZmFpbHVyZXMiOworICAgICAgICAgIG15ICRhZmlsZSA9ICIkZGlyL2F0dHJpYnV0ZV9pZ25vcmVkXyQxLnR4dCI7CisgICAgICAgIAorICAgICAgICAgICMgT25seSBjcmVhdGUgYW5vdGhlciBwcmVwcm9jZXNzZWQgZmlsZSBpZiB0aGUgYXR0cmlidXRlIGZpbGUKKyAgICAgICAgICAjIGRvZXNuJ3QgZXhpc3QgeWV0LgorICAgICAgICAgIG5leHQgaWYgKC1lICRhZmlsZSk7CisgICAgICAgIAorICAgICAgICAgICMgQWRkIHRoaXMgZmlsZSB0byB0aGUgbGlzdCBvZiBmaWxlcyB0aGF0IGNvbnRhaW5lZCB0aGlzIGF0dHJpYnV0ZS4KKyAgICAgICAgICAjIEdlbmVyYXRlIGEgcHJlcHJvY2Vzc2VkIGZpbGUgaWYgd2UgaGF2ZW4ndCBhbHJlYWR5LgorICAgICAgICAgIGlmICghKGRlZmluZWQgJHBwZmlsZSkpIHsKKyAgICAgICAgICAgICRwcGZpbGUgPSBQcm9jZXNzQ2xhbmdGYWlsdXJlKCRDbGFuZywgJExhbmcsICRmaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXEBDbWRBcmdzU2Fuc0FuYWx5c2VzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJEh0bWxEaXIsICRBdHRyaWJ1dGVJZ25vcmVkLCAkb2ZpbGUpOworICAgICAgICAgIH0KKworICAgICAgICAgIG1rcGF0aCAkZGlyOworICAgICAgICAgIG9wZW4oQUZJTEUsICI+JGFmaWxlIik7CisgICAgICAgICAgcHJpbnQgQUZJTEUgIiRwcGZpbGVcbiI7CisgICAgICAgICAgY2xvc2UoQUZJTEUpOworICAgICAgICB9CisgICAgICAgIGNsb3NlIENISUxEOworICAgICAgfQorICAgIH0KKyAgfQorICAKKyAgdW5saW5rKCRvZmlsZSk7Cit9CisKKyMjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSMjCisjICBMb29rdXAgdGFibGVzLgorIyMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIyMKKworbXkgJUNvbXBpbGVPcHRpb25NYXAgPSAoCisgICctbm9zdGRpbmMnID0+IDAsCisgICctaW5jbHVkZScgPT4gMSwKKyAgJy1pZGlyYWZ0ZXInID0+IDEsCisgICctaW1hY3JvcycgPT4gMSwKKyAgJy1pcHJlZml4JyA9PiAxLAorICAnLWlxdW90ZScgPT4gMSwKKyAgJy1pc3lzdGVtJyA9PiAxLAorICAnLWl3aXRocHJlZml4JyA9PiAxLAorICAnLWl3aXRocHJlZml4YmVmb3JlJyA9PiAxCispOworCitteSAlTGlua2VyT3B0aW9uTWFwID0gKAorICAnLWZyYW1ld29yaycgPT4gMSwKKyAgJy1mb2JqYy1saW5rLXJ1bnRpbWUnID0+IDAKKyk7CisKK215ICVDb21waWxlckxpbmtlck9wdGlvbk1hcCA9ICgKKyAgJy1Xd3JpdGUtc3RyaW5ncycgPT4gMCwKKyAgJy1mdHJhcHYtaGFuZGxlcicgPT4gMSwgIyBzcGVjaWZpY2FsbHkgY2FsbCBvdXQgc2VwYXJhdGVkIC1mIGZsYWcKKyAgJy1taW9zLXNpbXVsYXRvci12ZXJzaW9uLW1pbicgPT4gMCwgIyBUaGlzIHJlYWxseSBoYXMgMSBhcmd1bWVudCwgYnV0IGFsd2F5cyBoYXMgJz0nCisgICctaXN5c3Jvb3QnID0+IDEsCisgICctYXJjaCcgPT4gMSwKKyAgJy1tMzInID0+IDAsCisgICctbTY0JyA9PiAwLAorICAnLXN0ZGxpYicgPT4gMCwgIyBUaGlzIGlzIHJlYWxseSBhIDEgYXJndW1lbnQsIGJ1dCBhbHdheXMgaGFzICc9JworICAnLXRhcmdldCcgPT4gMSwKKyAgJy12JyA9PiAwLAorICAnLW1tYWNvc3gtdmVyc2lvbi1taW4nID0+IDAsICMgVGhpcyBpcyByZWFsbHkgYSAxIGFyZ3VtZW50LCBidXQgYWx3YXlzIGhhcyAnPScKKyAgJy1taXBob25lb3MtdmVyc2lvbi1taW4nID0+IDAgIyBUaGlzIGlzIHJlYWxseSBhIDEgYXJndW1lbnQsIGJ1dCBhbHdheXMgaGFzICc9JworKTsKKworbXkgJUlnbm9yZWRPcHRpb25NYXAgPSAoCisgICctTVQnID0+IDEsICAjIElnbm9yZSB0aGVzZSBwcmVwcm9jZXNzb3Igb3B0aW9ucy4KKyAgJy1NRicgPT4gMSwKKworICAnLWZzeW50YXgtb25seScgPT4gMCwKKyAgJy1zYXZlLXRlbXBzJyA9PiAwLAorICAnLWluc3RhbGxfbmFtZScgPT4gMSwKKyAgJy1leHBvcnRlZF9zeW1ib2xzX2xpc3QnID0+IDEsCisgICctY3VycmVudF92ZXJzaW9uJyA9PiAxLAorICAnLWNvbXBhdGliaWxpdHlfdmVyc2lvbicgPT4gMSwKKyAgJy1pbml0JyA9PiAxLAorICAnLWUnID0+IDEsCisgICctc2VnMWFkZHInID0+IDEsCisgICctYnVuZGxlX2xvYWRlcicgPT4gMSwKKyAgJy1tdWx0aXBseV9kZWZpbmVkJyA9PiAxLAorICAnLXNlY3RvcmRlcicgPT4gMywKKyAgJy0tcGFyYW0nID0+IDEsCisgICctdScgPT4gMSwKKyAgJy0tc2VyaWFsaXplLWRpYWdub3N0aWNzJyA9PiAxCispOworCitteSAlTGFuZ01hcCA9ICgKKyAgJ2MnICAgPT4gJ2MnLAorICAnY3AnICA9PiAnYysrJywKKyAgJ2NwcCcgPT4gJ2MrKycsCisgICdjeHgnID0+ICdjKysnLAorICAndHh4JyA9PiAnYysrJywKKyAgJ2NjJyAgPT4gJ2MrKycsCisgICdDJyAgID0+ICdjKysnLAorICAnaWknICA9PiAnYysrJywKKyAgJ2knICAgPT4gJ2MtY3BwLW91dHB1dCcsCisgICdtJyAgID0+ICdvYmplY3RpdmUtYycsCisgICdtaScgID0+ICdvYmplY3RpdmUtYy1jcHAtb3V0cHV0JywKKyAgJ21tJyAgPT4gJ29iamVjdGl2ZS1jKysnCispOworCitteSAlVW5pcXVlT3B0aW9ucyA9ICgKKyAgJy1pc3lzcm9vdCcgPT4gMCAgCispOworCisjIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0jIworIyBMYW5ndWFnZXMgYWNjZXB0ZWQuCisjIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0jIworCitteSAlTGFuZ3NBY2NlcHRlZCA9ICgKKyAgIm9iamVjdGl2ZS1jIiA9PiAxLAorICAiYyIgPT4gMSwKKyAgImMrKyIgPT4gMSwKKyAgIm9iamVjdGl2ZS1jKysiID0+IDEKKyk7CisKKyMjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSMjCisjICBNYWluIExvZ2ljLgorIyMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIyMKKworbXkgJEFjdGlvbiA9ICdsaW5rJzsKK215IEBDb21waWxlT3B0czsKK215IEBMaW5rT3B0czsKK215IEBGaWxlczsKK215ICRMYW5nOworbXkgJE91dHB1dDsKK215ICVVbmlxdWVkOworCisjIEZvcndhcmQgYXJndW1lbnRzIHRvIGdjYy4KK215ICRTdGF0dXMgPSBzeXN0ZW0oJENvbXBpbGVyLEBBUkdWKTsKK2lmIChkZWZpbmVkICRFTlZ7J0NDQ19BTkFMWVpFUl9MT0cnfSkgeworICBwcmludCBTVERFUlIgIiRDb21waWxlciBAQVJHVlxuIjsKK30KK2lmICgkU3RhdHVzKSB7IGV4aXQoJFN0YXR1cyA+PiA4KTsgfQorCisjIEdldCB0aGUgYW5hbHlzaXMgb3B0aW9ucy4KK215ICRBbmFseXNlcyA9ICRFTlZ7J0NDQ19BTkFMWVpFUl9BTkFMWVNJUyd9OworCisjIEdldCB0aGUgcGx1Z2lucyB0byBsb2FkLgorbXkgJFBsdWdpbnMgPSAkRU5WeydDQ0NfQU5BTFlaRVJfUExVR0lOUyd9OworCisjIEdldCB0aGUgc3RvcmUgbW9kZWwuCitteSAkU3RvcmVNb2RlbCA9ICRFTlZ7J0NDQ19BTkFMWVpFUl9TVE9SRV9NT0RFTCd9OworCisjIEdldCB0aGUgY29uc3RyYWludHMgZW5naW5lLgorbXkgJENvbnN0cmFpbnRzTW9kZWwgPSAkRU5WeydDQ0NfQU5BTFlaRVJfQ09OU1RSQUlOVFNfTU9ERUwnfTsKKworI0dldCB0aGUgaW50ZXJuYWwgc3RhdHMgc2V0dGluZy4KK215ICRJbnRlcm5hbFN0YXRzID0gJEVOVnsnQ0NDX0FOQUxZWkVSX0lOVEVSTkFMX1NUQVRTJ307CisKKyMgR2V0IHRoZSBvdXRwdXQgZm9ybWF0LgorbXkgJE91dHB1dEZvcm1hdCA9ICRFTlZ7J0NDQ19BTkFMWVpFUl9PVVRQVVRfRk9STUFUJ307CitpZiAoIWRlZmluZWQgJE91dHB1dEZvcm1hdCkgeyAkT3V0cHV0Rm9ybWF0ID0gImh0bWwiOyB9CisKKyMgRGV0ZXJtaW5lIHRoZSBsZXZlbCBvZiB2ZXJib3NpdHkuCitteSAkVmVyYm9zZSA9IDA7CitpZiAoZGVmaW5lZCAkRU5WeydDQ0NfQU5BTFlaRVJfVkVSQk9TRSd9KSB7ICRWZXJib3NlID0gMTsgfQoraWYgKGRlZmluZWQgJEVOVnsnQ0NDX0FOQUxZWkVSX0xPRyd9KSB7ICRWZXJib3NlID0gMjsgfQorCisjIEdldCB0aGUgSFRNTCBvdXRwdXQgZGlyZWN0b3J5LgorbXkgJEh0bWxEaXIgPSAkRU5WeydDQ0NfQU5BTFlaRVJfSFRNTCd9OworCitteSAlRGlzYWJsZWRBcmNocyA9ICgncHBjJyA9PiAxLCAncHBjNjQnID0+IDEpOworbXkgJUFyY2hzU2VlbjsKK215ICRIYWRBcmNoID0gMDsKKworIyBQcm9jZXNzIHRoZSBhcmd1bWVudHMuCitmb3JlYWNoIChteSAkaSA9IDA7ICRpIDwgc2NhbGFyKEBBUkdWKTsgKyskaSkgeworICBteSAkQXJnID0gJEFSR1ZbJGldOyAgCisgIG15ICgkQXJnS2V5KSA9IHNwbGl0IC89LywkQXJnLDI7CisKKyAgIyBNb2RlcyBjY2MtYW5hbHl6ZXIgc3VwcG9ydHMKKyAgaWYgKCRBcmcgPX4gL14tKEV8TU0/KSQvKSB7ICRBY3Rpb24gPSAncHJlcHJvY2Vzcyc7IH0KKyAgZWxzaWYgKCRBcmcgZXEgJy1jJykgeyAkQWN0aW9uID0gJ2NvbXBpbGUnOyB9CisgIGVsc2lmICgkQXJnID1+IC9eLXByaW50LXByb2ctbmFtZS8pIHsgZXhpdCAwOyB9CisKKyAgIyBTcGVjaWFsbHkgaGFuZGxlIGR1cGxpY2F0ZSBjYXNlcyBvZiAtYXJjaAorICBpZiAoJEFyZyBlcSAiLWFyY2giKSB7CisgICAgbXkgJGFyY2ggPSAkQVJHVlskaSsxXTsKKyAgICAjIFdlIGRvbid0IHdhbnQgdG8gcHJvY2VzcyAncHBjJyBiZWNhdXNlIG9mIENsYW5nJ3MgbGFjayBvZiBzdXBwb3J0CisgICAgIyBmb3IgQWx0aXZlYyAoYWxzbyBzb21lICNkZWZpbmVzIHdvbid0IGxpa2VseSBiZSBkZWZpbmVkIGNvcnJlY3RseSwgZXRjLikKKyAgICBpZiAoIShkZWZpbmVkICREaXNhYmxlZEFyY2hzeyRhcmNofSkpIHsgJEFyY2hzU2VlbnskYXJjaH0gPSAxOyB9CisgICAgJEhhZEFyY2ggPSAxOworICAgICsrJGk7CisgICAgbmV4dDsKKyAgfQorCisgICMgT3B0aW9ucyB3aXRoIHBvc3NpYmxlIGFyZ3VtZW50cyB0aGF0IHNob3VsZCBwYXNzIHRocm91Z2ggdG8gY29tcGlsZXIuCisgIGlmIChkZWZpbmVkICRDb21waWxlT3B0aW9uTWFweyRBcmdLZXl9KSB7CisgICAgbXkgJENudCA9ICRDb21waWxlT3B0aW9uTWFweyRBcmdLZXl9OworICAgIHB1c2ggQENvbXBpbGVPcHRzLCRBcmc7CisgICAgd2hpbGUgKCRDbnQgPiAwKSB7ICsrJGk7IC0tJENudDsgcHVzaCBAQ29tcGlsZU9wdHMsICRBUkdWWyRpXTsgfQorICAgIG5leHQ7CisgIH0KKyAgaWYgKCRBcmcgPX4gLy1tLiovKSB7CisgICAgcHVzaCBAQ29tcGlsZU9wdHMsJEFyZzsKKyAgICBuZXh0OworICB9CisgICMgSGFuZGxlIHRoZSBjYXNlIHdoZXJlIHRoZXJlIGlzbid0IGEgc3BhY2UgYWZ0ZXIgLWlxdW90ZQorICBpZiAoJEFyZyA9fiAvLWlxdW90ZS4qLykgeworICAgIHB1c2ggQENvbXBpbGVPcHRzLCRBcmc7CisgICAgbmV4dDsKKyAgfQorCisgICMgT3B0aW9ucyB3aXRoIHBvc3NpYmxlIGFyZ3VtZW50cyB0aGF0IHNob3VsZCBwYXNzIHRocm91Z2ggdG8gbGlua2VyLgorICBpZiAoZGVmaW5lZCAkTGlua2VyT3B0aW9uTWFweyRBcmdLZXl9KSB7CisgICAgbXkgJENudCA9ICRMaW5rZXJPcHRpb25NYXB7JEFyZ0tleX07CisgICAgcHVzaCBATGlua09wdHMsJEFyZzsKKyAgICB3aGlsZSAoJENudCA+IDApIHsgKyskaTsgLS0kQ250OyBwdXNoIEBMaW5rT3B0cywgJEFSR1ZbJGldOyB9CisgICAgbmV4dDsKKyAgfQorCisgICMgT3B0aW9ucyB3aXRoIHBvc3NpYmxlIGFyZ3VtZW50cyB0aGF0IHNob3VsZCBwYXNzIHRocm91Z2ggdG8gYm90aCBjb21waWxlcgorICAjIGFuZCB0aGUgbGlua2VyLgorICBpZiAoZGVmaW5lZCAkQ29tcGlsZXJMaW5rZXJPcHRpb25NYXB7JEFyZ0tleX0pIHsKKyAgICBteSAkQ250ID0gJENvbXBpbGVyTGlua2VyT3B0aW9uTWFweyRBcmdLZXl9OworICAgIAorICAgICMgQ2hlY2sgaWYgdGhpcyBpcyBhbiBvcHRpb24gdGhhdCBzaG91bGQgaGF2ZSBhIHVuaXF1ZSB2YWx1ZSwgYW5kIGlmIHNvCisgICAgIyBkZXRlcm1pbmUgaWYgdGhlIHZhbHVlIHdhcyBjaGVja2VkIGJlZm9yZS4KKyAgICBpZiAoJFVuaXF1ZU9wdGlvbnN7JEFyZ30pIHsKKyAgICAgIGlmIChkZWZpbmVkICRVbmlxdWVkeyRBcmd9KSB7CisgICAgICAgICRpICs9ICRDbnQ7CisgICAgICAgIG5leHQ7CisgICAgICB9CisgICAgICAkVW5pcXVlZHskQXJnfSA9IDE7CisgICAgfQorICAgIAorICAgIHB1c2ggQENvbXBpbGVPcHRzLCRBcmc7ICAgIAorICAgIHB1c2ggQExpbmtPcHRzLCRBcmc7CisKKyAgICB3aGlsZSAoJENudCA+IDApIHsKKyAgICAgICsrJGk7IC0tJENudDsKKyAgICAgIHB1c2ggQENvbXBpbGVPcHRzLCAkQVJHVlskaV07CisgICAgICBwdXNoIEBMaW5rT3B0cywgJEFSR1ZbJGldOworICAgIH0KKyAgICBuZXh0OworICB9CisgIAorICAjIElnbm9yZWQgb3B0aW9ucy4KKyAgaWYgKGRlZmluZWQgJElnbm9yZWRPcHRpb25NYXB7JEFyZ0tleX0pIHsKKyAgICBteSAkQ250ID0gJElnbm9yZWRPcHRpb25NYXB7JEFyZ0tleX07CisgICAgd2hpbGUgKCRDbnQgPiAwKSB7CisgICAgICArKyRpOyAtLSRDbnQ7CisgICAgfQorICAgIG5leHQ7CisgIH0KKyAgCisgICMgQ29tcGlsZSBtb2RlIGZsYWdzLgorICBpZiAoJEFyZyA9fiAvXi1bRCxJLFVdKC4qKSQvKSB7CisgICAgbXkgJFRtcCA9ICRBcmc7ICAgIAorICAgIGlmICgkMSBlcSAnJykgeworICAgICAgIyBGSVhNRTogQ2hlY2sgaWYgd2UgYXJlIGdvaW5nIG9mZiB0aGUgZW5kLgorICAgICAgKyskaTsKKyAgICAgICRUbXAgPSAkQXJnIC4gJEFSR1ZbJGldOworICAgIH0KKyAgICBwdXNoIEBDb21waWxlT3B0cywkVG1wOworICAgIG5leHQ7CisgIH0KKyAgCisgICMgTGFuZ3VhZ2UuCisgIGlmICgkQXJnIGVxICcteCcpIHsKKyAgICAkTGFuZyA9ICRBUkdWWyRpKzFdOworICAgICsrJGk7IG5leHQ7CisgIH0KKworICAjIE91dHB1dCBmaWxlLgorICBpZiAoJEFyZyBlcSAnLW8nKSB7CisgICAgKyskaTsKKyAgICAkT3V0cHV0ID0gJEFSR1ZbJGldOworICAgIG5leHQ7CisgIH0KKyAgCisgICMgR2V0IHRoZSBsaW5rIG1vZGUuCisgIGlmICgkQXJnID1+IC9eLVtsLEwsT10vKSB7CisgICAgaWYgKCRBcmcgZXEgJy1PJykgeyBwdXNoIEBMaW5rT3B0cywnLU8xJzsgfQorICAgIGVsc2lmICgkQXJnIGVxICctT3MnKSB7IHB1c2ggQExpbmtPcHRzLCctTzInOyB9CisgICAgZWxzZSB7IHB1c2ggQExpbmtPcHRzLCRBcmc7IH0KKworICAgICMgTXVzdCBwYXNzIHRoaXMgYWxvbmcgZm9yIHRoZSBfX09QVElNSVpFX18gbWFjcm8KKyAgICBpZiAoJEFyZyA9fiAvXi1PLykgeyBwdXNoIEBDb21waWxlT3B0cywkQXJnOyB9CisgICAgbmV4dDsKKyAgfQorICAKKyAgaWYgKCRBcmcgPX4gL14tc3RkPS8pIHsKKyAgICBwdXNoIEBDb21waWxlT3B0cywkQXJnOworICAgIG5leHQ7CisgIH0KKyAgCisgICMgR2V0IHRoZSBjb21waWxlci9saW5rIG1vZGUuCisgIGlmICgkQXJnID1+IC9eLUYoLispJC8pIHsKKyAgICBteSAkVG1wID0gJEFyZzsKKyAgICBpZiAoJDEgZXEgJycpIHsKKyAgICAgICMgRklYTUU6IENoZWNrIGlmIHdlIGFyZSBnb2luZyBvZmYgdGhlIGVuZC4KKyAgICAgICsrJGk7CisgICAgICAkVG1wID0gJEFyZyAuICRBUkdWWyRpXTsKKyAgICB9CisgICAgcHVzaCBAQ29tcGlsZU9wdHMsJFRtcDsKKyAgICBwdXNoIEBMaW5rT3B0cywkVG1wOworICAgIG5leHQ7CisgIH0KKworICAjIElucHV0IGZpbGVzLgorICBpZiAoJEFyZyBlcSAnLWZpbGVsaXN0JykgeworICAgICMgRklYTUU6IE1ha2Ugc3VyZSB3ZSBhcmVuJ3Qgd2Fsa2luZyBvZmYgdGhlIGVuZC4KKyAgICBvcGVuKElOLCAkQVJHVlskaSsxXSk7CisgICAgd2hpbGUgKDxJTj4pIHsgcy9cMDE1P1wwMTIvLzsgcHVzaCBARmlsZXMsJF87IH0KKyAgICBjbG9zZShJTik7CisgICAgKyskaTsKKyAgICBuZXh0OworICB9CisgIAorICBpZiAoJEFyZyA9fiAvXi1mLykgeworICAgIHB1c2ggQENvbXBpbGVPcHRzLCRBcmc7CisgICAgcHVzaCBATGlua09wdHMsJEFyZzsKKyAgICBuZXh0OworICB9CisgIAorICAjIEhhbmRsZSAtV25vLS4gIFdlIGRvbid0IGNhcmUgYWJvdXQgZXh0cmEgd2FybmluZ3MsIGJ1dAorICAjIHdlIHNob3VsZCBzdXBwcmVzcyBvbmVzIHRoYXQgd2UgZG9uJ3Qgd2FudCB0byBzZWUuCisgIGlmICgkQXJnID1+IC9eLVduby0vKSB7CisgICAgcHVzaCBAQ29tcGlsZU9wdHMsICRBcmc7CisgICAgbmV4dDsKKyAgfQorCisgIGlmICghKCRBcmcgPX4gL14tLykpIHsKKyAgICBwdXNoIEBGaWxlcywgJEFyZzsKKyAgICBuZXh0OworICB9Cit9CisKK2lmICgkQWN0aW9uIGVxICdjb21waWxlJyBvciAkQWN0aW9uIGVxICdsaW5rJykgeworICBteSBAQXJjaHMgPSBrZXlzICVBcmNoc1NlZW47CisgICMgU2tpcCB0aGUgZmlsZSBpZiB3ZSBkb24ndCBzdXBwb3J0IHRoZSBhcmNoaXRlY3R1cmVzIHNwZWNpZmllZC4KKyAgZXhpdCAwIGlmICgkSGFkQXJjaCAmJiBzY2FsYXIoQEFyY2hzKSA9PSAwKTsKKworICBmb3JlYWNoIG15ICRmaWxlIChARmlsZXMpIHsKKyAgICAjIERldGVybWluZSB0aGUgbGFuZ3VhZ2UgZm9yIHRoZSBmaWxlLgorICAgIG15ICRGaWxlTGFuZyA9ICRMYW5nOworCisgICAgaWYgKCFkZWZpbmVkKCRGaWxlTGFuZykpIHsKKyAgICAgICMgSW5mZXIgdGhlIGxhbmd1YWdlIGZyb20gdGhlIGV4dGVuc2lvbi4KKyAgICAgIGlmICgkZmlsZSA9fiAvWy5dKFteLl0rKSQvKSB7CisgICAgICAgICRGaWxlTGFuZyA9ICRMYW5nTWFweyQxfTsKKyAgICAgIH0KKyAgICB9CisgICAgCisgICAgIyBGaWxlTGFuZyBzdGlsbCBub3QgZGVmaW5lZD8gIFNraXAgdGhlIGZpbGUuCisgICAgbmV4dCBpZiAoIWRlZmluZWQgJEZpbGVMYW5nKTsKKworICAgICMgTGFuZ3VhZ2Ugbm90IGFjY2VwdGVkPworICAgIG5leHQgaWYgKCFkZWZpbmVkICRMYW5nc0FjY2VwdGVkeyRGaWxlTGFuZ30pOworCisgICAgbXkgQENtZEFyZ3M7CisgICAgbXkgQEFuYWx5emVBcmdzOyAgICAKKyAgICAKKyAgICBpZiAoJEZpbGVMYW5nIG5lICd1bmtub3duJykgeworICAgICAgcHVzaCBAQ21kQXJncywgJy14JywgJEZpbGVMYW5nOworICAgIH0KKworICAgIGlmIChkZWZpbmVkICRTdG9yZU1vZGVsKSB7CisgICAgICBwdXNoIEBBbmFseXplQXJncywgIi1hbmFseXplci1zdG9yZT0kU3RvcmVNb2RlbCI7CisgICAgfQorCisgICAgaWYgKGRlZmluZWQgJENvbnN0cmFpbnRzTW9kZWwpIHsKKyAgICAgIHB1c2ggQEFuYWx5emVBcmdzLCAiLWFuYWx5emVyLWNvbnN0cmFpbnRzPSRDb25zdHJhaW50c01vZGVsIjsKKyAgICB9CisKKyAgICBpZiAoZGVmaW5lZCAkSW50ZXJuYWxTdGF0cykgeworICAgICAgcHVzaCBAQW5hbHl6ZUFyZ3MsICItYW5hbHl6ZXItc3RhdHMiOworICAgIH0KKyAgICAKKyAgICBpZiAoZGVmaW5lZCAkQW5hbHlzZXMpIHsKKyAgICAgIHB1c2ggQEFuYWx5emVBcmdzLCBzcGxpdCAnXHMrJywgJEFuYWx5c2VzOworICAgIH0KKworICAgIGlmIChkZWZpbmVkICRQbHVnaW5zKSB7CisgICAgICBwdXNoIEBBbmFseXplQXJncywgc3BsaXQgJ1xzKycsICRQbHVnaW5zOworICAgIH0KKworICAgIGlmIChkZWZpbmVkICRPdXRwdXRGb3JtYXQpIHsKKyAgICAgIHB1c2ggQEFuYWx5emVBcmdzLCAiLWFuYWx5emVyLW91dHB1dD0iIC4gJE91dHB1dEZvcm1hdDsKKyAgICAgIGlmICgkT3V0cHV0Rm9ybWF0ID1+IC9wbGlzdC8pIHsKKyAgICAgICAgIyBDaGFuZ2UgIk91dHB1dCIgdG8gYmUgYSBmaWxlLgorICAgICAgICBteSAoJGgsICRmKSA9IHRlbXBmaWxlKCJyZXBvcnQtWFhYWFhYIiwgU1VGRklYID0+ICIucGxpc3QiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERJUiA9PiAkSHRtbERpcik7CisgICAgICAgICRSZXN1bHRGaWxlID0gJGY7CisgICAgICAgICMgSWYgdGhlIEh0bWxEaXIgaXMgbm90IHNldCwgd2Ugc291bGQgY2xlYW4gdXAgdGhlIHBsaXN0IGZpbGVzLgorICAgICAgICBpZiAoIWRlZmluZWQgJEh0bWxEaXIgfHwgLXogJEh0bWxEaXIpIHsKKyAgICAgICAgICAkQ2xlYW51cEZpbGUgPSAkZjsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKworICAgIHB1c2ggQENtZEFyZ3MsIEBDb21waWxlT3B0czsKKyAgICBwdXNoIEBDbWRBcmdzLCAkZmlsZTsKKworICAgIGlmIChzY2FsYXIgQEFyY2hzKSB7CisgICAgICBmb3JlYWNoIG15ICRhcmNoIChAQXJjaHMpIHsKKyAgICAgICAgbXkgQE5ld0FyZ3M7CisgICAgICAgIHB1c2ggQE5ld0FyZ3MsICctYXJjaCcsICRhcmNoOworICAgICAgICBwdXNoIEBOZXdBcmdzLCBAQ21kQXJnczsKKyAgICAgICAgQW5hbHl6ZSgkQ2xhbmcsIFxATmV3QXJncywgXEBBbmFseXplQXJncywgJEZpbGVMYW5nLCAkT3V0cHV0LAorICAgICAgICAgICAgICAgICRWZXJib3NlLCAkSHRtbERpciwgJGZpbGUpOworICAgICAgfQorICAgIH0KKyAgICBlbHNlIHsKKyAgICAgIEFuYWx5emUoJENsYW5nLCBcQENtZEFyZ3MsIFxAQW5hbHl6ZUFyZ3MsICRGaWxlTGFuZywgJE91dHB1dCwKKyAgICAgICAgICAgICAgJFZlcmJvc2UsICRIdG1sRGlyLCAkZmlsZSk7CisgICAgfQorICB9Cit9CisKK2V4aXQoJFN0YXR1cyA+PiA4KTsKKwpkaWZmIC0tZ2l0IGEvdG9vbHMvc2Nhbi1idWlsZC9zY2FuLWJ1aWxkIGIvdG9vbHMvc2Nhbi1idWlsZC9zY2FuLWJ1aWxkCm5ldyBmaWxlIG1vZGUgMTAwNzU1CmluZGV4IDAwMDAwMDAuLjQ1OTAyNzkKLS0tIC9kZXYvbnVsbAorKysgYi90b29scy9zY2FuLWJ1aWxkL3NjYW4tYnVpbGQKQEAgLTAsMCArMSwxNjg0IEBACisjIS91c3IvYmluL2VudiBwZXJsCisjCisjICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKyMKKyMgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisjIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKyMKKyMjPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PSMjCisjCisjIEEgc2NyaXB0IGRlc2lnbmVkIHRvIHdyYXAgYSBidWlsZCBzbyB0aGF0IGFsbCBjYWxscyB0byBnY2MgYXJlIGludGVyY2VwdGVkCisjIGFuZCBwaXBlZCB0byB0aGUgc3RhdGljIGFuYWx5emVyLgorIworIyM9PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09IyMKKwordXNlIHN0cmljdDsKK3VzZSB3YXJuaW5nczsKK3VzZSBGaW5kQmluIHF3KCRSZWFsQmluKTsKK3VzZSBEaWdlc3Q6Ok1ENTsKK3VzZSBGaWxlOjpCYXNlbmFtZTsKK3VzZSBGaWxlOjpGaW5kOwordXNlIFRlcm06OkFOU0lDb2xvcjsKK3VzZSBUZXJtOjpBTlNJQ29sb3IgcXcoOmNvbnN0YW50cyk7Cit1c2UgQ3dkIHF3LyBnZXRjd2QgYWJzX3BhdGggLzsKK3VzZSBTeXM6Okhvc3RuYW1lOworCitteSAkVmVyYm9zZSA9IDA7ICAgICAgICMgVmVyYm9zZSBvdXRwdXQgZnJvbSB0aGlzIHNjcmlwdC4KK215ICRQcm9nID0gInNjYW4tYnVpbGQiOworbXkgJEJ1aWxkTmFtZTsKK215ICRCdWlsZERhdGU7CisKK215ICRURVJNID0gJEVOVnsnVEVSTSd9OworbXkgJFVzZUNvbG9yID0gKGRlZmluZWQgJFRFUk0gYW5kICRURVJNID1+ICd4dGVybS0uKmNvbG9yJyBhbmQgLXQgU1RET1VUCisgICAgICAgICAgICAgICAgYW5kIGRlZmluZWQgJEVOVnsnU0NBTl9CVUlMRF9DT0xPUid9KTsKKworIyBQb3J0YWJpbGl0eTogZ2V0cHd1aWQgaXMgbm90IGltcGxlbWVudGVkIGZvciBXaW4zMiAoc2VlIFBlcmwgbGFuZ3VhZ2UgCisjIHJlZmVyZW5jZSwgcGVybHBvcnQpLCB1c2UgZ2V0bG9naW4gaW5zdGVhZC4KK215ICRVc2VyTmFtZSA9IEh0bWxFc2NhcGUoZ2V0bG9naW4oKSB8fCBnZXRwd3VpZCgkPCkgfHwgJ3Vua25vd24nKTsKK215ICRIb3N0TmFtZSA9IEh0bWxFc2NhcGUoaG9zdG5hbWUoKSB8fCAndW5rbm93bicpOworbXkgJEN1cnJlbnREaXIgPSBIdG1sRXNjYXBlKGdldGN3ZCgpKTsKK215ICRDdXJyZW50RGlyU3VmZml4ID0gYmFzZW5hbWUoJEN1cnJlbnREaXIpOworCitteSBAUGx1Z2luc1RvTG9hZDsKK215ICRDbWRBcmdzOworCitteSAkSHRtbFRpdGxlOworCitteSAkRGF0ZSA9IGxvY2FsdGltZSgpOworCisjIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0jIworIyBEaWFnbm9zdGljcworIyMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIyMKKworc3ViIERpYWcgeworICBpZiAoJFVzZUNvbG9yKSB7CisgICAgcHJpbnQgQk9MRCwgTUFHRU5UQSAiJFByb2c6IEBfIjsKKyAgICBwcmludCBSRVNFVDsKKyAgfQorICBlbHNlIHsKKyAgICBwcmludCAiJFByb2c6IEBfIjsKKyAgfSAgCit9CisKK3N1YiBFcnJvckRpYWcgeworICBpZiAoJFVzZUNvbG9yKSB7CisgICAgcHJpbnQgU1RERVJSIEJPTEQsIFJFRCAiJFByb2c6ICI7CisgICAgcHJpbnQgU1RERVJSIFJFU0VULCBSRUQgQF87CisgICAgcHJpbnQgU1RERVJSIFJFU0VUOworICB9IGVsc2UgeworICAgIHByaW50IFNUREVSUiAiJFByb2c6IEBfIjsKKyAgfSAgCit9CisKK3N1YiBEaWFnQ3Jhc2hlcyB7CisgIG15ICREaXIgPSBzaGlmdDsKKyAgRGlhZyAoIlRoZSBhbmFseXplciBlbmNvdW50ZXJlZCBwcm9ibGVtcyBvbiBzb21lIHNvdXJjZSBmaWxlcy5cbiIpOworICBEaWFnICgiUHJlcHJvY2Vzc2VkIHZlcnNpb25zIG9mIHRoZXNlIHNvdXJjZXMgd2VyZSBkZXBvc2l0ZWQgaW4gJyREaXIvZmFpbHVyZXMnLlxuIik7CisgIERpYWcgKCJQbGVhc2UgY29uc2lkZXIgc3VibWl0dGluZyBhIGJ1ZyByZXBvcnQgdXNpbmcgdGhlc2UgZmlsZXM6XG4iKTsKKyAgRGlhZyAoIiAgaHR0cDovL2NsYW5nLWFuYWx5emVyLmxsdm0ub3JnL2ZpbGluZ19idWdzLmh0bWxcbiIpCit9CisKK3N1YiBEaWVEaWFnIHsKKyAgaWYgKCRVc2VDb2xvcikgeworICAgIHByaW50IFNUREVSUiBCT0xELCBSRUQgIiRQcm9nOiAiOworICAgIHByaW50IFNUREVSUiBSRVNFVCwgUkVEIEBfOworICAgIHByaW50IFNUREVSUiBSRVNFVDsKKyAgfQorICBlbHNlIHsKKyAgICBwcmludCBTVERFUlIgIiRQcm9nOiAiLCBAXzsKKyAgfQorICBleGl0IDE7Cit9CisKKyMjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSMjCisjIFByaW50IGRlZmF1bHQgY2hlY2tlciBuYW1lcworIyMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIyMKKworaWYgKGdyZXAgL14tLWhlbHAtY2hlY2tlcnMkLywgQEFSR1YpIHsKKyAgICBteSBAb3B0aW9ucyA9IHF4KCQwIC1oKTsKKyAgICBmb3JlYWNoIChAb3B0aW9ucykgeworCW5leHQgdW5sZXNzIC9eIFwrLzsKKwlzL15ccyovLzsKKwlteSAoJHNpZ24sICRuYW1lLCBAdGV4dCkgPSBzcGxpdCAnICcsICRfOworCXByaW50ICRuYW1lLCAkLyBpZiAkc2lnbiBlcSAnKyc7CisgICAgfQorICAgIGV4aXQgMDsKK30KKworIyMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIyMKKyMgRGVjbGFyYXRpb24gb2YgQ2xhbmcgb3B0aW9ucy4gIFBvcHVsYXRlZCBsYXRlci4KKyMjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSMjCisKK215ICRDbGFuZzsKK215ICRDbGFuZ1NCOworbXkgJENsYW5nQ1hYOworbXkgJENsYW5nVmVyc2lvbjsKKworIyMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIyMKKyMgR2V0SFRNTFJ1bkRpciAtIENvbnN0cnVjdCBhbiBIVE1MIGRpcmVjdG9yeSBuYW1lIGZvciB0aGUgY3VycmVudCBzdWItcnVuLgorIyMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIyMKKworc3ViIEdldEhUTUxSdW5EaXIgeyAgCisgIGRpZSAiTm90IGVub3VnaCBhcmd1bWVudHMuIiBpZiAoQF8gPT0gMCk7ICAKKyAgbXkgJERpciA9IHNoaWZ0IEBfOyAgICAKKyAgbXkgJFRtcE1vZGUgPSAwOworICBpZiAoIWRlZmluZWQgJERpcikgeworICAgICREaXIgPSAkRU5WeydUTVBESVInfSB8fCAkRU5WeydURU1QJ30gfHwgJEVOVnsnVE1QJ30gfHwgIi90bXAiOworICAgICRUbXBNb2RlID0gMTsKKyAgfQorICAKKyAgIyBDaG9wIG9mZiBhbnkgdHJhaWxpbmcgJy8nIGNoYXJhY3RlcnMuCisgIHdoaWxlICgkRGlyID1+IC9cLyQvKSB7IGNob3AgJERpcjsgfQorCisgICMgR2V0IGN1cnJlbnQgZGF0ZSBhbmQgdGltZS4KKyAgbXkgQEN1cnJlbnRUaW1lID0gbG9jYWx0aW1lKCk7ICAKKyAgbXkgJHllYXIgID0gJEN1cnJlbnRUaW1lWzVdICsgMTkwMDsKKyAgbXkgJGRheSAgID0gJEN1cnJlbnRUaW1lWzNdOworICBteSAkbW9udGggPSAkQ3VycmVudFRpbWVbNF0gKyAxOworICBteSAkRGF0ZVN0cmluZyA9IHNwcmludGYoIiVkLSUwMmQtJTAyZCIsICR5ZWFyLCAkbW9udGgsICRkYXkpOworICAKKyAgIyBEZXRlcm1pbmUgdGhlIHJ1biBudW1iZXIuICAKKyAgbXkgJFJ1bk51bWJlcjsKKyAgCisgIGlmICgtZCAkRGlyKSB7ICAgIAorICAgIGlmICghIC1yICREaXIpIHsKKyAgICAgIERpZURpYWcoImRpcmVjdG9yeSAnJERpcicgZXhpc3RzIGJ1dCBpcyBub3QgcmVhZGFibGUuXG4iKTsKKyAgICB9ICAgIAorICAgICMgSXRlcmF0ZSBvdmVyIGFsbCBmaWxlcyBpbiB0aGUgc3BlY2lmaWVkIGRpcmVjdG9yeS4gICAgCisgICAgbXkgJG1heCA9IDA7ICAgIAorICAgIG9wZW5kaXIoRElSLCAkRGlyKTsKKyAgICBteSBARklMRVMgPSBncmVwIHsgLWQgIiREaXIvJF8iIH0gcmVhZGRpcihESVIpOworICAgIGNsb3NlZGlyKERJUik7CisKKyAgICBmb3JlYWNoIG15ICRmIChARklMRVMpIHsKKyAgICAgICMgU3RyaXAgdGhlIHByZWZpeCAnJFByb2ctJyBpZiB3ZSBhcmUgZHVtcGluZyBmaWxlcyB0byAvdG1wLgorICAgICAgaWYgKCRUbXBNb2RlKSB7CisgICAgICAgIG5leHQgaWYgKCEoJGYgPX4gL14kUHJvZy0oLispLykpOworICAgICAgICAkZiA9ICQxOworICAgICAgfQorCisgICAgICBteSBAeCA9IHNwbGl0Ly0vLCAkZjsKKyAgICAgIG5leHQgaWYgKHNjYWxhcihAeCkgIT0gNCk7CisgICAgICBuZXh0IGlmICgkeFswXSAhPSAkeWVhcik7CisgICAgICBuZXh0IGlmICgkeFsxXSAhPSAkbW9udGgpOworICAgICAgbmV4dCBpZiAoJHhbMl0gIT0gJGRheSk7CisgICAgICAKKyAgICAgIGlmICgkeFszXSA+ICRtYXgpIHsKKyAgICAgICAgJG1heCA9ICR4WzNdOworICAgICAgfSAgICAgIAorICAgIH0KKyAgICAKKyAgICAkUnVuTnVtYmVyID0gJG1heCArIDE7CisgIH0KKyAgZWxzZSB7CisgICAgCisgICAgaWYgKC14ICREaXIpIHsKKyAgICAgIERpZURpYWcoIickRGlyJyBleGlzdHMgYnV0IGlzIG5vdCBhIGRpcmVjdG9yeS5cbiIpOworICAgIH0KKworICAgIGlmICgkVG1wTW9kZSkgeworICAgICAgRGllRGlhZygiVGhlIGRpcmVjdG9yeSAnL3RtcCcgZG9lcyBub3QgZXhpc3Qgb3IgY2Fubm90IGJlIGFjY2Vzc2VkLlxuIik7CisgICAgfQorCisgICAgIyAkRGlyIGRvZXMgbm90IGV4aXN0LiAgSXQgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IGNyZWF0ZWQgYnkgdGhlIAorICAgICMgY2xhbmcgZHJpdmVyLiAgU2V0IHRoZSBydW4gbnVtYmVyIHRvIDEuICAKKworICAgICRSdW5OdW1iZXIgPSAxOworICB9CisgIAorICBkaWUgIlJ1bk51bWJlciBtdXN0IGJlIGRlZmluZWQhIiBpZiAoIWRlZmluZWQgJFJ1bk51bWJlcik7CisgIAorICAjIEFwcGVuZCB0aGUgcnVuIG51bWJlci4KKyAgbXkgJE5ld0RpcjsKKyAgaWYgKCRUbXBNb2RlKSB7CisgICAgJE5ld0RpciA9ICIkRGlyLyRQcm9nLSREYXRlU3RyaW5nLSRSdW5OdW1iZXIiOworICB9CisgIGVsc2UgeworICAgICROZXdEaXIgPSAiJERpci8kRGF0ZVN0cmluZy0kUnVuTnVtYmVyIjsKKyAgfQorICBzeXN0ZW0gJ21rZGlyJywnLXAnLCROZXdEaXI7CisgIHJldHVybiAkTmV3RGlyOworfQorCitzdWIgU2V0SHRtbEVudiB7CisgIAorICBkaWUgIldyb25nIG51bWJlciBvZiBhcmd1bWVudHMuIiBpZiAoc2NhbGFyKEBfKSAhPSAyKTsKKyAgCisgIG15ICRBcmdzID0gc2hpZnQ7CisgIG15ICREaXIgPSBzaGlmdDsKKyAgCisgIGRpZSAiTm8gYnVpbGQgY29tbWFuZC4iIGlmIChzY2FsYXIoQCRBcmdzKSA9PSAwKTsKKyAgCisgIG15ICRDbWQgPSAkJEFyZ3NbMF07CisKKyAgaWYgKCRDbWQgPX4gL2NvbmZpZ3VyZS8gfHwgJENtZCA9fiAvYXV0b2dlbi8pIHsKKyAgICByZXR1cm47CisgIH0KKyAgCisgIGlmICgkVmVyYm9zZSkgeworICAgIERpYWcoIkVtaXR0aW5nIHJlcG9ydHMgZm9yIHRoaXMgcnVuIHRvICckRGlyJy5cbiIpOworICB9CisgIAorICAkRU5WeydDQ0NfQU5BTFlaRVJfSFRNTCd9ID0gJERpcjsKK30KKworIyMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIyMKKyMgQ29tcHV0ZURpZ2VzdCAtIENvbXB1dGUgYSBkaWdlc3Qgb2YgdGhlIHNwZWNpZmllZCBmaWxlLgorIyMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIyMKKworc3ViIENvbXB1dGVEaWdlc3QgeworICBteSAkRk5hbWUgPSBzaGlmdDsKKyAgRGllRGlhZygiQ2Fubm90IHJlYWQgJEZOYW1lIHRvIGNvbXB1dGUgRGlnZXN0LlxuIikgaWYgKCEgLXIgJEZOYW1lKTsgIAorICAKKyAgIyBVc2UgRGlnZXN0OjpNRDUuICBXZSBkb24ndCBoYXZlIHRvIGJlIGNyeXB0b2dyYXBoaWNhbGx5IHNlY3VyZS4gIFdlJ3JlCisgICMganVzdCBsb29raW5nIGZvciBkdXBsaWNhdGUgZmlsZXMgdGhhdCBjb21lIGZyb20gYSBub24tbWFsaWNpb3VzIHNvdXJjZS4KKyAgIyBXZSB1c2UgRGlnZXN0OjpNRDUgYmVjYXVzZSBpdCBpcyBhIHN0YW5kYXJkIFBlcmwgbW9kdWxlIHRoYXQgc2hvdWxkCisgICMgY29tZSBidW5kbGVkIG9uIG1vc3Qgc3lzdGVtcy4gIAorICBvcGVuKEZJTEUsICRGTmFtZSkgb3IgRGllRGlhZygiQ2Fubm90IG9wZW4gJEZOYW1lIHdoZW4gY29tcHV0aW5nIERpZ2VzdC5cbiIpOworICBiaW5tb2RlIEZJTEU7CisgIG15ICRSZXN1bHQgPSBEaWdlc3Q6Ok1ENS0+bmV3LT5hZGRmaWxlKCpGSUxFKS0+aGV4ZGlnZXN0OworICBjbG9zZShGSUxFKTsKKyAgCisgICMgUmV0dXJuIHRoZSBkaWdlc3QuICAKKyAgcmV0dXJuICRSZXN1bHQ7Cit9CisKKyMjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSMjCisjICBVcGRhdGVQcmVmaXggLSBDb21wdXRlIHRoZSBjb21tb24gcHJlZml4IG9mIGZpbGVzLgorIyMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIyMKKworbXkgJFByZWZpeDsKKworc3ViIFVwZGF0ZVByZWZpeCB7CisgIG15ICR4ID0gc2hpZnQ7CisgIG15ICR5ID0gYmFzZW5hbWUoJHgpOworICAkeCA9fiBzL1xRJHlcRSQvLzsKKworICBpZiAoIWRlZmluZWQgJFByZWZpeCkgeworICAgICRQcmVmaXggPSAkeDsKKyAgICByZXR1cm47CisgIH0KKyAgCisgIGNob3AgJFByZWZpeCB3aGlsZSAoISgkeCA9fiAvXlxRJFByZWZpeC8pKTsKK30KKworc3ViIEdldFByZWZpeCB7CisgIHJldHVybiAkUHJlZml4OworfQorCisjIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0jIworIyAgVXBkYXRlSW5GaWxlUGF0aCAtIFVwZGF0ZSB0aGUgcGF0aCBpbiB0aGUgcmVwb3J0IGZpbGUuCisjIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0jIworCitzdWIgVXBkYXRlSW5GaWxlUGF0aCB7CisgIG15ICRmbmFtZSA9IHNoaWZ0OworICBteSAkcmVnZXggPSBzaGlmdDsKKyAgbXkgJG5ld3RleHQgPSBzaGlmdDsKKworICBvcGVuIChSSU4sICRmbmFtZSkgb3IgZGllICJjYW5ub3Qgb3BlbiAkZm5hbWUiOworICBvcGVuIChST1VULCAiPiIsICIkZm5hbWUudG1wIikgb3IgZGllICJjYW5ub3Qgb3BlbiAkZm5hbWUudG1wIjsKKworICB3aGlsZSAoPFJJTj4pIHsKKyAgICBzLyRyZWdleC8kbmV3dGV4dC87CisgICAgcHJpbnQgUk9VVCAkXzsKKyAgfQorCisgIGNsb3NlIChST1VUKTsKKyAgY2xvc2UgKFJJTik7CisgIHN5c3RlbSgibXYiLCAiJGZuYW1lLnRtcCIsICRmbmFtZSk7Cit9CisKKyMjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSMjCisjIEFkZFN0YXRMaW5lIC0gRGVjb2RlIGFuZCBpbnNlcnQgYSBzdGF0aXN0aWNzIGxpbmUgaW50byB0aGUgZGF0YWJhc2UuCisjIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0jIworCitzdWIgQWRkU3RhdExpbmUgeworICBteSAkTGluZSAgPSBzaGlmdDsKKyAgbXkgJFN0YXRzID0gc2hpZnQ7CisgIG15ICRGaWxlICA9IHNoaWZ0OworCisgIHByaW50ICRMaW5lIC4gIlxuIjsKKworICBteSAkUmVnZXggPSBxci8oLio/KVwgLT5cIFRvdGFsXCBDRkdCbG9ja3M6XCAoXGQrKVwgXHxcIFVucmVhY2hhYmxlCisgICAgICBcIENGR0Jsb2NrczpcIChcZCspXCBcfFwgRXhoYXVzdGVkXCBCbG9jazpcICh5ZXN8bm8pXCBcfFwgRW1wdHlcIFdvcmtMaXN0OgorICAgICAgXCAoeWVzfG5vKS94OworCisgIGlmICgkTGluZSAhfiAkUmVnZXgpIHsKKyAgICByZXR1cm47CisgIH0KKworICAjIENyZWF0ZSBhIGhhc2ggb2YgdGhlIGludGVyZXN0aW5nIGZpZWxkcworICBteSAkUm93ID0geworICAgIEZpbGVuYW1lICAgID0+ICRGaWxlLAorICAgIEZ1bmN0aW9uICAgID0+ICQxLAorICAgIFRvdGFsICAgICAgID0+ICQyLAorICAgIFVucmVhY2hhYmxlID0+ICQzLAorICAgIEFib3J0ZWQgICAgID0+ICQ0LAorICAgIEVtcHR5ICAgICAgID0+ICQ1CisgIH07CisKKyAgIyBBZGQgdGhlbSB0byB0aGUgc3RhdHMgYXJyYXkKKyAgcHVzaCBAJFN0YXRzLCAkUm93OworfQorCisjIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0jIworIyBTY2FuRmlsZSAtIFNjYW4gYSByZXBvcnQgZmlsZSBmb3IgdmFyaW91cyBpZGVudGlmeWluZyBhdHRyaWJ1dGVzLgorIyMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIyMKKworIyBTb21ldGltZXMgYSBzb3VyY2UgZmlsZSBpcyBzY2FubmVkIG1vcmUgdGhhbiBvbmNlLCBhbmQgdGh1cyBwcm9kdWNlcworIyBtdWx0aXBsZSBlcnJvciByZXBvcnRzLiAgV2UgdXNlIGEgY2FjaGUgdG8gc29sdmUgdGhpcyBwcm9ibGVtLgorCitteSAlQWxyZWFkeVNjYW5uZWQ7CisKK3N1YiBTY2FuRmlsZSB7CisgIAorICBteSAkSW5kZXggPSBzaGlmdDsKKyAgbXkgJERpciA9IHNoaWZ0OworICBteSAkRk5hbWUgPSBzaGlmdDsKKyAgbXkgJFN0YXRzID0gc2hpZnQ7CisgIAorICAjIENvbXB1dGUgYSBkaWdlc3QgZm9yIHRoZSByZXBvcnQgZmlsZS4gIERldGVybWluZSBpZiB3ZSBoYXZlIGFscmVhZHkKKyAgIyBzY2FubmVkIGEgZmlsZSB0aGF0IGxvb2tzIGp1c3QgbGlrZSBpdC4KKyAgCisgIG15ICRkaWdlc3QgPSBDb21wdXRlRGlnZXN0KCIkRGlyLyRGTmFtZSIpOworCisgIGlmIChkZWZpbmVkICRBbHJlYWR5U2Nhbm5lZHskZGlnZXN0fSkgeworICAgICMgUmVkdW5kYW50IGZpbGUuICBSZW1vdmUgaXQuCisgICAgc3lzdGVtICgicm0iLCAiLWYiLCAiJERpci8kRk5hbWUiKTsKKyAgICByZXR1cm47CisgIH0KKyAgCisgICRBbHJlYWR5U2Nhbm5lZHskZGlnZXN0fSA9IDE7CisgIAorICAjIEF0IHRoaXMgcG9pbnQgdGhlIHJlcG9ydCBmaWxlIGlzIG5vdCB3b3JsZCByZWFkYWJsZS4gIE1ha2UgaXQgaGFwcGVuLgorICBzeXN0ZW0gKCJjaG1vZCIsICI2NDQiLCAiJERpci8kRk5hbWUiKTsKKyAgCisgICMgU2NhbiB0aGUgcmVwb3J0IGZpbGUgZm9yIHRhZ3MuCisgIG9wZW4oSU4sICIkRGlyLyRGTmFtZSIpIG9yIERpZURpYWcoIkNhbm5vdCBvcGVuICckRGlyLyRGTmFtZSdcbiIpOworCisgIG15ICRCdWdUeXBlICAgICAgICA9ICIiOworICBteSAkQnVnRmlsZSAgICAgICAgPSAiIjsKKyAgbXkgJEJ1Z0NhdGVnb3J5ICAgID0gIiI7CisgIG15ICRCdWdEZXNjcmlwdGlvbiA9ICIiOworICBteSAkQnVnUGF0aExlbmd0aCAgPSAxOworICBteSAkQnVnTGluZSAgICAgICAgPSAwOworCisgIHdoaWxlICg8SU4+KSB7CisgICAgbGFzdCBpZiAoLzwhLS0gQlVHTUVUQUVORCAtLT4vKTsKKworICAgIGlmICgvPCEtLSBCVUdUWVBFICguKikgLS0+JC8pIHsKKyAgICAgICRCdWdUeXBlID0gJDE7CisgICAgfQorICAgIGVsc2lmICgvPCEtLSBCVUdGSUxFICguKikgLS0+JC8pIHsKKyAgICAgICRCdWdGaWxlID0gYWJzX3BhdGgoJDEpOworICAgICAgVXBkYXRlUHJlZml4KCRCdWdGaWxlKTsKKyAgICB9CisgICAgZWxzaWYgKC88IS0tIEJVR1BBVEhMRU5HVEggKC4qKSAtLT4kLykgeworICAgICAgJEJ1Z1BhdGhMZW5ndGggPSAkMTsKKyAgICB9CisgICAgZWxzaWYgKC88IS0tIEJVR0xJTkUgKC4qKSAtLT4kLykgeworICAgICAgJEJ1Z0xpbmUgPSAkMTsgICAgCisgICAgfQorICAgIGVsc2lmICgvPCEtLSBCVUdDQVRFR09SWSAoLiopIC0tPiQvKSB7CisgICAgICAkQnVnQ2F0ZWdvcnkgPSAkMTsKKyAgICB9CisgICAgZWxzaWYgKC88IS0tIEJVR0RFU0MgKC4qKSAtLT4kLykgeworICAgICAgJEJ1Z0Rlc2NyaXB0aW9uID0gJDE7CisgICAgfQorICB9CisKKyAgY2xvc2UoSU4pOworICAKKyAgaWYgKCFkZWZpbmVkICRCdWdDYXRlZ29yeSkgeworICAgICRCdWdDYXRlZ29yeSA9ICJPdGhlciI7CisgIH0KKworICAjIERvbid0IGFkZCBpbnRlcm5hbCBzdGF0aXN0aWNzIHRvIHRoZSBidWcgcmVwb3J0cworICBpZiAoJEJ1Z0NhdGVnb3J5ID1+IC9zdGF0aXN0aWNzL2kpIHsKKyAgICBBZGRTdGF0TGluZSgkQnVnRGVzY3JpcHRpb24sICRTdGF0cywgJEJ1Z0ZpbGUpOworICAgIHJldHVybjsKKyAgfQorICAKKyAgcHVzaCBAJEluZGV4LFsgJEZOYW1lLCAkQnVnQ2F0ZWdvcnksICRCdWdUeXBlLCAkQnVnRmlsZSwgJEJ1Z0xpbmUsCisgICAgICAgICAgICAgICAgICRCdWdQYXRoTGVuZ3RoIF07Cit9CisKKyMjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSMjCisjIENvcHlGaWxlcyAtIENvcHkgcmVzb3VyY2UgZmlsZXMgdG8gdGFyZ2V0IGRpcmVjdG9yeS4KKyMjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSMjCisKK3N1YiBDb3B5RmlsZXMgeworCisgIG15ICREaXIgPSBzaGlmdDsKKworICBteSAkSlMgPSBDd2Q6OnJlYWxwYXRoKCIkUmVhbEJpbi9zb3J0dGFibGUuanMiKTsKKyAgCisgIERpZURpYWcoIkNhbm5vdCBmaW5kICdzb3J0dGFibGUuanMnLlxuIikKKyAgICBpZiAoISAtciAkSlMpOyAgCisKKyAgc3lzdGVtICgiY3AiLCAkSlMsICIkRGlyIik7CisKKyAgRGllRGlhZygiQ291bGQgbm90IGNvcHkgJ3NvcnR0YWJsZS5qcycgdG8gJyREaXInLlxuIikKKyAgICBpZiAoISAtciAiJERpci9zb3J0dGFibGUuanMiKTsKKyAgICAKKyAgbXkgJENTUyA9IEN3ZDo6cmVhbHBhdGgoIiRSZWFsQmluL3NjYW52aWV3LmNzcyIpOworICAKKyAgRGllRGlhZygiQ2Fubm90IGZpbmQgJ3NjYW52aWV3LmNzcycuXG4iKQorICAgIGlmICghIC1yICRDU1MpOworCisgIHN5c3RlbSAoImNwIiwgJENTUywgIiREaXIiKTsKKworICBEaWVEaWFnKCJDb3VsZCBub3QgY29weSAnc2NhbnZpZXcuY3NzJyB0byAnJERpcicuXG4iKQorICAgIGlmICghIC1yICRDU1MpOworfQorCisjIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0jIworIyBDYWxjU3RhdHMgLSBDYWxjdWxhdGVzIHZpc2l0YXRpb24gc3RhdGlzdGljcyBhbmQgcmV0dXJucyB0aGUgc3RyaW5nLgorIyMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIyMKKworc3ViIENhbGNTdGF0cyB7CisgIG15ICRTdGF0cyA9IHNoaWZ0OworCisgIG15ICRUb3RhbEJsb2NrcyA9IDA7CisgIG15ICRVbnJlYWNoZWRCbG9ja3MgPSAwOworICBteSAkVG90YWxGdW5jdGlvbnMgPSBzY2FsYXIoQCRTdGF0cyk7CisgIG15ICRCbG9ja0Fib3J0ZWQgPSAwOworICBteSAkV29ya0xpc3RBYm9ydGVkID0gMDsKKyAgbXkgJEFib3J0ZWQgPSAwOworCisgICMgQ2FsY3VsYXRlIHRoZSB1bmlxdWUgZmlsZXMKKyAgbXkgJEZpbGVzSGFzaCA9IHt9OworCisgIGZvcmVhY2ggbXkgJFJvdyAoQCRTdGF0cykgeworICAgICRGaWxlc0hhc2gtPnskUm93LT57RmlsZW5hbWV9fSA9IDE7CisgICAgJFRvdGFsQmxvY2tzICs9ICRSb3ctPntUb3RhbH07CisgICAgJFVucmVhY2hlZEJsb2NrcyArPSAkUm93LT57VW5yZWFjaGFibGV9OworICAgICRCbG9ja0Fib3J0ZWQrKyBpZiAkUm93LT57QWJvcnRlZH0gZXEgJ3llcyc7CisgICAgJFdvcmtMaXN0QWJvcnRlZCsrIGlmICRSb3ctPntFbXB0eX0gZXEgJ25vJzsKKyAgICAkQWJvcnRlZCsrIGlmICRSb3ctPntBYm9ydGVkfSBlcSAneWVzJyB8fCAkUm93LT57RW1wdHl9IGVxICdubyc7CisgIH0KKworICBteSAkVG90YWxGaWxlcyA9IHNjYWxhcihrZXlzKCUkRmlsZXNIYXNoKSk7CisKKyAgIyBDYWxjdWxhdGlvbnMKKyAgbXkgJFBlcmNlbnRBYm9ydGVkID0gc3ByaW50ZigiJS4yZiIsICRBYm9ydGVkIC8gJFRvdGFsRnVuY3Rpb25zICogMTAwKTsKKyAgbXkgJFBlcmNlbnRCbG9ja0Fib3J0ZWQgPSBzcHJpbnRmKCIlLjJmIiwgJEJsb2NrQWJvcnRlZCAvICRUb3RhbEZ1bmN0aW9ucworICAgICAgKiAxMDApOworICBteSAkUGVyY2VudFdvcmtMaXN0QWJvcnRlZCA9IHNwcmludGYoIiUuMmYiLCAkV29ya0xpc3RBYm9ydGVkIC8KKyAgICAgICRUb3RhbEZ1bmN0aW9ucyAqIDEwMCk7CisgIG15ICRQZXJjZW50QmxvY2tzVW5yZWFjaGVkID0gc3ByaW50ZigiJS4yZiIsICRVbnJlYWNoZWRCbG9ja3MgLyAkVG90YWxCbG9ja3MKKyAgICAgICogMTAwKTsKKworICBteSAkU3RhdHNTdHJpbmcgPSAiQW5hbHl6ZWQgJFRvdGFsQmxvY2tzIGJsb2NrcyBpbiAkVG90YWxGdW5jdGlvbnMgZnVuY3Rpb25zIgorICAgIC4gIiBpbiAkVG90YWxGaWxlcyBmaWxlc1xuIgorICAgIC4gIiRBYm9ydGVkIGZ1bmN0aW9ucyBhYm9ydGVkIGVhcmx5ICgkUGVyY2VudEFib3J0ZWQlKVxuIgorICAgIC4gIiRCbG9ja0Fib3J0ZWQgaGFkIGFib3J0ZWQgYmxvY2tzICgkUGVyY2VudEJsb2NrQWJvcnRlZCUpXG4iCisgICAgLiAiJFdvcmtMaXN0QWJvcnRlZCBoYWQgdW5maW5pc2hlZCB3b3JrbGlzdHMgKCRQZXJjZW50V29ya0xpc3RBYm9ydGVkJSlcbiIKKyAgICAuICIkVW5yZWFjaGVkQmxvY2tzIGJsb2NrcyB3ZXJlIG5ldmVyIHJlYWNoZWQgKCRQZXJjZW50QmxvY2tzVW5yZWFjaGVkJSlcbiI7CisKKyAgcmV0dXJuICRTdGF0c1N0cmluZzsKK30KKworIyMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIyMKKyMgUG9zdHByb2Nlc3MgLSBQb3N0cHJvY2VzcyB0aGUgcmVzdWx0cyBvZiBhbiBhbmFseXNpcyBzY2FuLgorIyMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIyMKKworbXkgQGZpbGVzRm91bmQ7CitteSAkYmFzZURpcjsKK3N1YiBGaWxlV2FudGVkIHsgCisgICAgbXkgJGJhc2VEaXJSZWdFeCA9IHF1b3RlbWV0YSAkYmFzZURpcjsKKyAgICBteSAkZmlsZSA9ICRGaWxlOjpGaW5kOjpuYW1lOworICAgIGlmICgkZmlsZSA9fiAvcmVwb3J0LS4qXC5odG1sJC8pIHsKKyAgICAgICBteSAkcmVsYXRpdmVfZmlsZSA9ICRmaWxlOworICAgICAgICRyZWxhdGl2ZV9maWxlID1+IHMvJGJhc2VEaXJSZWdFeC8vZzsKKyAgICAgICBwdXNoIEBmaWxlc0ZvdW5kLCAkcmVsYXRpdmVfZmlsZTsKKyAgICB9Cit9CisKK3N1YiBQb3N0cHJvY2VzcyB7CisgIAorICBteSAkRGlyICAgICAgICAgICA9IHNoaWZ0OworICBteSAkQmFzZURpciAgICAgICA9IHNoaWZ0OworICBteSAkQW5hbHl6ZXJTdGF0cyA9IHNoaWZ0OworICBteSAkS2VlcEVtcHR5ICAgICA9IHNoaWZ0OworICAKKyAgZGllICJObyBkaXJlY3Rvcnkgc3BlY2lmaWVkLiIgaWYgKCFkZWZpbmVkICREaXIpOworICAKKyAgaWYgKCEgLWQgJERpcikgeworICAgIERpYWcoIk5vIGJ1Z3MgZm91bmQuXG4iKTsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgICRiYXNlRGlyID0gJERpciAuICIvIjsKKyAgZmluZCh7IHdhbnRlZCA9PiBcJkZpbGVXYW50ZWQsIGZvbGxvdyA9PiAwfSwgJERpcik7CisKKyAgaWYgKHNjYWxhcihAZmlsZXNGb3VuZCkgPT0gMCBhbmQgISAtZSAiJERpci9mYWlsdXJlcyIpIHsKKyAgICBpZiAoISAkS2VlcEVtcHR5KSB7CisgICAgICBEaWFnKCJSZW1vdmluZyBkaXJlY3RvcnkgJyREaXInIGJlY2F1c2UgaXQgY29udGFpbnMgbm8gcmVwb3J0cy5cbiIpOworICAgICAgc3lzdGVtICgicm0iLCAiLWZSIiwgJERpcik7CisgICAgfQorICAgIERpYWcoIk5vIGJ1Z3MgZm91bmQuXG4iKTsKKyAgICByZXR1cm4gMDsKKyAgfQorICAKKyAgIyBTY2FuIGVhY2ggcmVwb3J0IGZpbGUgYW5kIGJ1aWxkIGFuIGluZGV4LiAgCisgIG15IEBJbmRleDsKKyAgbXkgQFN0YXRzOworICBmb3JlYWNoIG15ICRmaWxlIChAZmlsZXNGb3VuZCkgeyBTY2FuRmlsZShcQEluZGV4LCAkRGlyLCAkZmlsZSwgXEBTdGF0cyk7IH0KKyAgCisgICMgU2NhbiB0aGUgZmFpbHVyZXMgZGlyZWN0b3J5IGFuZCB1c2UgdGhlIGluZm9ybWF0aW9uIGluIHRoZSAuaW5mbyBmaWxlcworICAjIHRvIHVwZGF0ZSB0aGUgY29tbW9uIHByZWZpeCBkaXJlY3RvcnkuCisgIG15IEBmYWlsdXJlczsKKyAgbXkgQGF0dHJpYnV0ZXNfaWdub3JlZDsKKyAgaWYgKC1kICIkRGlyL2ZhaWx1cmVzIikgeworICAgIG9wZW5kaXIoRElSLCAiJERpci9mYWlsdXJlcyIpOworICAgIEBmYWlsdXJlcyA9IGdyZXAgeyAvWy5daW5mby50eHQkLyAmJiAhL2F0dHJpYnV0ZV9pZ25vcmVkLzsgfSByZWFkZGlyKERJUik7CisgICAgY2xvc2VkaXIoRElSKTsKKyAgICBvcGVuZGlyKERJUiwgIiREaXIvZmFpbHVyZXMiKTsgICAgICAgIAorICAgIEBhdHRyaWJ1dGVzX2lnbm9yZWQgPSBncmVwIHsgL15hdHRyaWJ1dGVfaWdub3JlZC87IH0gcmVhZGRpcihESVIpOworICAgIGNsb3NlZGlyKERJUik7CisgICAgZm9yZWFjaCBteSAkZmlsZSAoQGZhaWx1cmVzKSB7CisgICAgICBvcGVuIElOLCAiJERpci9mYWlsdXJlcy8kZmlsZSIgb3IgRGllRGlhZygiY2Fubm90IG9wZW4gJGZpbGVcbiIpOworICAgICAgbXkgJFBhdGggPSA8SU4+OworICAgICAgaWYgKGRlZmluZWQgJFBhdGgpIHsgVXBkYXRlUHJlZml4KCRQYXRoKTsgfQorICAgICAgY2xvc2UgSU47CisgICAgfSAgICAKKyAgfQorICAKKyAgIyBHZW5lcmF0ZSBhbiBpbmRleC5odG1sIGZpbGUuICAKKyAgbXkgJEZOYW1lID0gIiREaXIvaW5kZXguaHRtbCI7ICAKKyAgb3BlbihPVVQsICI+IiwgJEZOYW1lKSBvciBEaWVEaWFnKCJDYW5ub3QgY3JlYXRlIGZpbGUgJyRGTmFtZSdcbiIpOworICAKKyAgIyBQcmludCBvdXQgdGhlIGhlYWRlci4KKyAgCitwcmludCBPVVQgPDxFTkRURVhUOworPGh0bWw+Cis8aGVhZD4KKzx0aXRsZT4ke0h0bWxUaXRsZX08L3RpdGxlPgorPGxpbmsgdHlwZT0idGV4dC9jc3MiIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0ic2NhbnZpZXcuY3NzIi8+Cis8c2NyaXB0IHNyYz0ic29ydHRhYmxlLmpzIj48L3NjcmlwdD4KKzxzY3JpcHQgbGFuZ3VhZ2U9J2phdmFzY3JpcHQnIHR5cGU9InRleHQvamF2YXNjcmlwdCI+CitmdW5jdGlvbiBTZXREaXNwbGF5KFJvd0NsYXNzLCBEaXNwbGF5VmFsKQoreworICB2YXIgUm93cyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJ0ciIpOworICBmb3IgKCB2YXIgaSA9IDAgOyBpIDwgUm93cy5sZW5ndGg7ICsraSApIHsKKyAgICBpZiAoUm93c1tpXS5jbGFzc05hbWUgPT0gUm93Q2xhc3MpIHsKKyAgICAgIFJvd3NbaV0uc3R5bGUuZGlzcGxheSA9IERpc3BsYXlWYWw7CisgICAgfQorICB9Cit9CisKK2Z1bmN0aW9uIENvcHlDaGVja2VkU3RhdGVUb0NoZWNrQnV0dG9ucyhTdW1tYXJ5Q2hlY2tCdXR0b24pIHsKKyAgdmFyIElucHV0cyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJpbnB1dCIpOworICBmb3IgKCB2YXIgaSA9IDAgOyBpIDwgSW5wdXRzLmxlbmd0aDsgKytpICkgeworICAgIGlmIChJbnB1dHNbaV0udHlwZSA9PSAiY2hlY2tib3giKSB7CisgICAgICBpZihJbnB1dHNbaV0gIT0gU3VtbWFyeUNoZWNrQnV0dG9uKSB7CisgICAgICAgIElucHV0c1tpXS5jaGVja2VkID0gU3VtbWFyeUNoZWNrQnV0dG9uLmNoZWNrZWQ7CisgICAgICAgIElucHV0c1tpXS5vbmNsaWNrKCk7CisJICB9CisgICAgfQorICB9Cit9CisKK2Z1bmN0aW9uIHJldHVybk9iakJ5SWQoIGlkICkgeworICAgIGlmIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCkgCisgICAgICAgIHZhciByZXR1cm5WYXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCk7CisgICAgZWxzZSBpZiAoZG9jdW1lbnQuYWxsKQorICAgICAgICB2YXIgcmV0dXJuVmFyID0gZG9jdW1lbnQuYWxsW2lkXTsKKyAgICBlbHNlIGlmIChkb2N1bWVudC5sYXllcnMpIAorICAgICAgICB2YXIgcmV0dXJuVmFyID0gZG9jdW1lbnQubGF5ZXJzW2lkXTsKKyAgICByZXR1cm4gcmV0dXJuVmFyOyAKK30KKwordmFyIE51bVVuY2hlY2tlZCA9IDA7CisKK2Z1bmN0aW9uIFRvZ2dsZURpc3BsYXkoQ2hlY2tCdXR0b24sIENsYXNzTmFtZSkgeworICBpZiAoQ2hlY2tCdXR0b24uY2hlY2tlZCkgeworICAgIFNldERpc3BsYXkoQ2xhc3NOYW1lLCAiIik7CisgICAgaWYgKC0tTnVtVW5jaGVja2VkID09IDApIHsKKyAgICAgIHJldHVybk9iakJ5SWQoIkFsbEJ1Z3NDaGVjayIpLmNoZWNrZWQgPSB0cnVlOworICAgIH0KKyAgfQorICBlbHNlIHsKKyAgICBTZXREaXNwbGF5KENsYXNzTmFtZSwgIm5vbmUiKTsKKyAgICBOdW1VbmNoZWNrZWQrKzsKKyAgICByZXR1cm5PYmpCeUlkKCJBbGxCdWdzQ2hlY2siKS5jaGVja2VkID0gZmFsc2U7CisgIH0KK30KKzwvc2NyaXB0PgorPCEtLSBTVU1NQVJZRU5ESEVBRCAtLT4KKzwvaGVhZD4KKzxib2R5PgorPGgxPiR7SHRtbFRpdGxlfTwvaDE+CisKKzx0YWJsZT4KKzx0cj48dGg+VXNlcjo8L3RoPjx0ZD4ke1VzZXJOYW1lfVxAJHtIb3N0TmFtZX08L3RkPjwvdHI+Cis8dHI+PHRoPldvcmtpbmcgRGlyZWN0b3J5OjwvdGg+PHRkPiR7Q3VycmVudERpcn08L3RkPjwvdHI+Cis8dHI+PHRoPkNvbW1hbmQgTGluZTo8L3RoPjx0ZD4ke0NtZEFyZ3N9PC90ZD48L3RyPgorPHRyPjx0aD5DbGFuZyBWZXJzaW9uOjwvdGg+PHRkPiR7Q2xhbmdWZXJzaW9ufTwvdGQ+PC90cj4KKzx0cj48dGg+RGF0ZTo8L3RoPjx0ZD4ke0RhdGV9PC90ZD48L3RyPgorRU5EVEVYVAorCitwcmludCBPVVQgIjx0cj48dGg+VmVyc2lvbjo8L3RoPjx0ZD4ke0J1aWxkTmFtZX0gKCR7QnVpbGREYXRlfSk8L3RkPjwvdHI+XG4iCisgIGlmIChkZWZpbmVkKCRCdWlsZE5hbWUpICYmIGRlZmluZWQoJEJ1aWxkRGF0ZSkpOworCitwcmludCBPVVQgPDxFTkRURVhUOworPC90YWJsZT4KK0VORFRFWFQKKworICBpZiAoc2NhbGFyKEBmaWxlc0ZvdW5kKSkgeworICAgICMgUHJpbnQgb3V0IHRoZSBzdW1tYXJ5IHRhYmxlLgorICAgIG15ICVUb3RhbHM7CisKKyAgICBmb3IgbXkgJHJvdyAoIEBJbmRleCApIHsKKyAgICAgIG15ICRidWdfdHlwZSA9ICgkcm93LT5bMl0pOworICAgICAgbXkgJGJ1Z19jYXRlZ29yeSA9ICgkcm93LT5bMV0pOworICAgICAgbXkgJGtleSA9ICIkYnVnX2NhdGVnb3J5OiRidWdfdHlwZSI7CisKKyAgICAgIGlmICghZGVmaW5lZCAkVG90YWxzeyRrZXl9KSB7ICRUb3RhbHN7JGtleX0gPSBbMSwkYnVnX2NhdGVnb3J5LCRidWdfdHlwZV07IH0KKyAgICAgIGVsc2UgeyAkVG90YWxzeyRrZXl9LT5bMF0rKzsgfQorICAgIH0KKworICAgIHByaW50IE9VVCAiPGgyPkJ1ZyBTdW1tYXJ5PC9oMj4iOworCisgICAgaWYgKGRlZmluZWQgJEJ1aWxkTmFtZSkgeworICAgICAgcHJpbnQgT1VUICJcbjxwPlJlc3VsdHMgaW4gdGhpcyBhbmFseXNpcyBydW4gYXJlIGJhc2VkIG9uIGFuYWx5emVyIGJ1aWxkIDxiPiRCdWlsZE5hbWU8L2I+LjwvcD5cbiIKKyAgICB9CisgIAorICBteSAkVG90YWxCdWdzID0gc2NhbGFyKEBJbmRleCk7CitwcmludCBPVVQgPDxFTkRURVhUOworPHRhYmxlPgorPHRoZWFkPjx0cj48dGQ+QnVnIFR5cGU8L3RkPjx0ZD5RdWFudGl0eTwvdGQ+PHRkIGNsYXNzPSJzb3J0dGFibGVfbm9zb3J0Ij5EaXNwbGF5PzwvdGQ+PC90cj48L3RoZWFkPgorPHRyIHN0eWxlPSJmb250LXdlaWdodDpib2xkIj48dGQgY2xhc3M9IlNVTU1fREVTQyI+QWxsIEJ1Z3M8L3RkPjx0ZCBjbGFzcz0iUSI+JFRvdGFsQnVnczwvdGQ+PHRkPjxjZW50ZXI+PGlucHV0IHR5cGU9ImNoZWNrYm94IiBpZD0iQWxsQnVnc0NoZWNrIiBvbkNsaWNrPSJDb3B5Q2hlY2tlZFN0YXRlVG9DaGVja0J1dHRvbnModGhpcyk7IiBjaGVja2VkLz48L2NlbnRlcj48L3RkPjwvdHI+CitFTkRURVhUCisgIAorICAgIG15ICRsYXN0X2NhdGVnb3J5OworCisgICAgZm9yIG15ICRrZXkgKAorICAgICAgc29ydCB7CisgICAgICAgIG15ICR4ID0gJFRvdGFsc3skYX07CisgICAgICAgIG15ICR5ID0gJFRvdGFsc3skYn07CisgICAgICAgIG15ICRyZXMgPSAkeC0+WzFdIGNtcCAkeS0+WzFdOworICAgICAgICAkcmVzID0gJHgtPlsyXSBjbXAgJHktPlsyXSBpZiAoJHJlcyA9PSAwKTsKKyAgICAgICAgJHJlcworICAgICAgfSBrZXlzICVUb3RhbHMgKSAKKyAgICB7CisgICAgICBteSAkdmFsID0gJFRvdGFsc3ska2V5fTsKKyAgICAgIG15ICRjYXRlZ29yeSA9ICR2YWwtPlsxXTsKKyAgICAgIGlmICghZGVmaW5lZCAkbGFzdF9jYXRlZ29yeSBvciAkbGFzdF9jYXRlZ29yeSBuZSAkY2F0ZWdvcnkpIHsKKyAgICAgICAgJGxhc3RfY2F0ZWdvcnkgPSAkY2F0ZWdvcnk7CisgICAgICAgIHByaW50IE9VVCAiPHRyPjx0aD4kY2F0ZWdvcnk8L3RoPjx0aCBjb2xzcGFuPTI+PC90aD48L3RyPlxuIjsKKyAgICAgIH0gICAgICAKKyAgICAgIG15ICR4ID0gbGMgJGtleTsKKyAgICAgICR4ID1+IHMvWyAsJyI6XC8oKV0rL18vZzsKKyAgICAgIHByaW50IE9VVCAiPHRyPjx0ZCBjbGFzcz1cIlNVTU1fREVTQ1wiPiI7CisgICAgICBwcmludCBPVVQgJHZhbC0+WzJdOworICAgICAgcHJpbnQgT1VUICI8L3RkPjx0ZCBjbGFzcz1cIlFcIj4iOworICAgICAgcHJpbnQgT1VUICR2YWwtPlswXTsKKyAgICAgIHByaW50IE9VVCAiPC90ZD48dGQ+PGNlbnRlcj48aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgb25DbGljaz1cIlRvZ2dsZURpc3BsYXkodGhpcywnYnRfJHgnKTtcIiBjaGVja2VkLz48L2NlbnRlcj48L3RkPjwvdHI+XG4iOworICAgIH0KKworICAjIFByaW50IG91dCB0aGUgdGFibGUgb2YgZXJyb3JzLgorCitwcmludCBPVVQgPDxFTkRURVhUOworPC90YWJsZT4KKzxoMj5SZXBvcnRzPC9oMj4KKworPHRhYmxlIGNsYXNzPSJzb3J0YWJsZSIgc3R5bGU9InRhYmxlLWxheW91dDphdXRvbWF0aWMiPgorPHRoZWFkPjx0cj4KKyAgPHRkPkJ1ZyBHcm91cDwvdGQ+CisgIDx0ZCBjbGFzcz0ic29ydHRhYmxlX3NvcnRlZCI+QnVnIFR5cGU8c3BhbiBpZD0ic29ydHRhYmxlX3NvcnRmd2RpbmQiPiZuYnNwOyYjeDI1QkU7PC9zcGFuPjwvdGQ+CisgIDx0ZD5GaWxlPC90ZD4KKyAgPHRkIGNsYXNzPSJRIj5MaW5lPC90ZD4KKyAgPHRkIGNsYXNzPSJRIj5QYXRoIExlbmd0aDwvdGQ+CisgIDx0ZCBjbGFzcz0ic29ydHRhYmxlX25vc29ydCI+PC90ZD4KKyAgPCEtLSBSRVBPUlRCVUdDT0wgLS0+Cis8L3RyPjwvdGhlYWQ+Cis8dGJvZHk+CitFTkRURVhUCisKKyAgICBteSAkcHJlZml4ID0gR2V0UHJlZml4KCk7CisgICAgbXkgJHJlZ2V4OworICAgIG15ICRJbkZpbGVSZWdleDsKKyAgICBteSAkSW5GaWxlUHJlZml4ID0gIkZpbGU6PC90ZD48dGQ+IjsKKyAgCisgICAgaWYgKGRlZmluZWQgJHByZWZpeCkgeyAKKyAgICAgICRyZWdleCA9IHFyL15cUSRwcmVmaXhcRS9pczsgICAgCisgICAgICAkSW5GaWxlUmVnZXggPSBxci9cUSRJbkZpbGVQcmVmaXgkcHJlZml4XEUvaXM7CisgICAgfSAgICAKKworICAgIGZvciBteSAkcm93ICggc29ydCB7ICRhLT5bMl0gY21wICRiLT5bMl0gfSBASW5kZXggKSB7CisgICAgICBteSAkeCA9ICIkcm93LT5bMV06JHJvdy0+WzJdIjsKKyAgICAgICR4ID0gbGMgJHg7CisgICAgICAkeCA9fiBzL1sgLCciOlwvKCldKy9fL2c7CisgICAgCisgICAgICBteSAkUmVwb3J0RmlsZSA9ICRyb3ctPlswXTsKKyAgICAgICAgICAKKyAgICAgIHByaW50IE9VVCAiPHRyIGNsYXNzPVwiYnRfJHhcIj4iOworICAgICAgcHJpbnQgT1VUICI8dGQgY2xhc3M9XCJERVNDXCI+IjsKKyAgICAgIHByaW50IE9VVCAkcm93LT5bMV07CisgICAgICBwcmludCBPVVQgIjwvdGQ+IjsKKyAgICAgIHByaW50IE9VVCAiPHRkIGNsYXNzPVwiREVTQ1wiPiI7CisgICAgICBwcmludCBPVVQgJHJvdy0+WzJdOworICAgICAgcHJpbnQgT1VUICI8L3RkPiI7CisgICAgICAKKyAgICAgICMgVXBkYXRlIHRoZSBmaWxlIHByZWZpeC4gICAgICAKKyAgICAgIG15ICRmbmFtZSA9ICRyb3ctPlszXTsKKworICAgICAgaWYgKGRlZmluZWQgJHJlZ2V4KSB7CisgICAgICAgICRmbmFtZSA9fiBzLyRyZWdleC8vOworICAgICAgICBVcGRhdGVJbkZpbGVQYXRoKCIkRGlyLyRSZXBvcnRGaWxlIiwgJEluRmlsZVJlZ2V4LCAkSW5GaWxlUHJlZml4KQorICAgICAgfQorICAgICAgCisgICAgICBwcmludCBPVVQgIjx0ZD4iOyAgICAgIAorICAgICAgbXkgQGZuYW1lID0gc3BsaXQgL1wvLywkZm5hbWU7CisgICAgICBpZiAoJCNmbmFtZSA+IDApIHsKKyAgICAgICAgd2hpbGUgKCQjZm5hbWUgPj0gMCkgeworICAgICAgICAgIG15ICR4ID0gc2hpZnQgQGZuYW1lOworICAgICAgICAgIHByaW50IE9VVCAkeDsKKyAgICAgICAgICBpZiAoJCNmbmFtZSA+PSAwKSB7CisgICAgICAgICAgICBwcmludCBPVVQgIjxzcGFuIGNsYXNzPVwiV1wiPiA8L3NwYW4+LyI7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisgICAgICBlbHNlIHsKKyAgICAgICAgcHJpbnQgT1VUICRmbmFtZTsKKyAgICAgIH0gICAgICAKKyAgICAgIHByaW50IE9VVCAiPC90ZD4iOworICAgICAgCisgICAgICAjIFByaW50IG91dCB0aGUgcXVhbnRpdGllcy4KKyAgICAgIGZvciBteSAkaiAoIDQgLi4gNSApIHsKKyAgICAgICAgcHJpbnQgT1VUICI8dGQgY2xhc3M9XCJRXCI+JHJvdy0+WyRqXTwvdGQ+IjsgICAgICAgIAorICAgICAgfQorICAgICAgCisgICAgICAjIFByaW50IHRoZSByZXN0IG9mIHRoZSBjb2x1bW5zLgorICAgICAgZm9yIChteSAkaiA9IDY7ICRqIDw9ICQjeyRyb3d9OyArKyRqKSB7CisgICAgICAgIHByaW50IE9VVCAiPHRkPiRyb3ctPlskal08L3RkPiIKKyAgICAgIH0KKworICAgICAgIyBFbWl0IHRoZSAiVmlldyIgbGluay4KKyAgICAgIHByaW50IE9VVCAiPHRkPjxhIGhyZWY9XCIkUmVwb3J0RmlsZSNFbmRQYXRoXCI+VmlldyBSZXBvcnQ8L2E+PC90ZD4iOworICAgICAgICAKKyAgICAgICMgRW1pdCBSRVBPUlRCVUcgbWFya2Vycy4KKyAgICAgIHByaW50IE9VVCAiXG48IS0tIFJFUE9SVEJVRyBpZD1cIiRSZXBvcnRGaWxlXCIgLS0+XG4iOworICAgICAgICAKKyAgICAgICMgRW5kIHRoZSByb3cuCisgICAgICBwcmludCBPVVQgIjwvdHI+XG4iOworICAgIH0KKyAgCisgICAgcHJpbnQgT1VUICI8L3Rib2R5PlxuPC90YWJsZT5cblxuIjsKKyAgfQorCisgIGlmIChzY2FsYXIgKEBmYWlsdXJlcykgfHwgc2NhbGFyKEBhdHRyaWJ1dGVzX2lnbm9yZWQpKSB7CisgICAgcHJpbnQgT1VUICI8aDI+QW5hbHl6ZXIgRmFpbHVyZXM8L2gyPlxuIjsKKyAgICAKKyAgICBpZiAoc2NhbGFyIEBhdHRyaWJ1dGVzX2lnbm9yZWQpIHsKKyAgICAgIHByaW50IE9VVCAiVGhlIGFuYWx5emVyJ3MgcGFyc2VyIGlnbm9yZWQgdGhlIGZvbGxvd2luZyBhdHRyaWJ1dGVzOjxwPlxuIjsKKyAgICAgIHByaW50IE9VVCAiPHRhYmxlPlxuIjsKKyAgICAgIHByaW50IE9VVCAiPHRoZWFkPjx0cj48dGQ+QXR0cmlidXRlPC90ZD48dGQ+U291cmNlIEZpbGU8L3RkPjx0ZD5QcmVwcm9jZXNzZWQgRmlsZTwvdGQ+PHRkPlNUREVSUiBPdXRwdXQ8L3RkPjwvdHI+PC90aGVhZD5cbiI7CisgICAgICBmb3JlYWNoIG15ICRmaWxlIChzb3J0IEBhdHRyaWJ1dGVzX2lnbm9yZWQpIHsKKyAgICAgICAgZGllICJjYW5ub3QgZGVtYW5nbGUgYXR0cmlidXRlIG5hbWVcbiIgaWYgKCEgKCRmaWxlID1+IC9eYXR0cmlidXRlX2lnbm9yZWRfKC4rKS50eHQvKSk7CisgICAgICAgIG15ICRhdHRyaWJ1dGUgPSAkMTsKKyAgICAgICAgIyBPcGVuIHRoZSBhdHRyaWJ1dGUgZmlsZSB0byBnZXQgdGhlIGZpcnN0IGZpbGUgdGhhdCBmYWlsZWQuCisgICAgICAgIG5leHQgaWYgKCFvcGVuIChBVFRSLCAiJERpci9mYWlsdXJlcy8kZmlsZSIpKTsKKyAgICAgICAgbXkgJHBwZmlsZSA9IDxBVFRSPjsKKyAgICAgICAgY2hvbXAgJHBwZmlsZTsKKyAgICAgICAgY2xvc2UgQVRUUjsKKyAgICAgICAgbmV4dCBpZiAoISAtZSAiJERpci9mYWlsdXJlcy8kcHBmaWxlIik7CisgICAgICAgICMgT3BlbiB0aGUgaW5mbyBmaWxlIGFuZCBnZXQgdGhlIG5hbWUgb2YgdGhlIHNvdXJjZSBmaWxlLgorICAgICAgICBvcGVuIChJTkZPLCAiJERpci9mYWlsdXJlcy8kcHBmaWxlLmluZm8udHh0Iikgb3IKKyAgICAgICAgICBkaWUgIkNhbm5vdCBvcGVuICREaXIvZmFpbHVyZXMvJHBwZmlsZS5pbmZvLnR4dFxuIjsKKyAgICAgICAgbXkgJHNyY2ZpbGUgPSA8SU5GTz47CisgICAgICAgIGNob21wICRzcmNmaWxlOworICAgICAgICBjbG9zZSAoSU5GTyk7CisgICAgICAgICMgUHJpbnQgdGhlIGluZm9ybWF0aW9uIGluIHRoZSB0YWJsZS4KKyAgICAgICAgbXkgJHByZWZpeCA9IEdldFByZWZpeCgpOworICAgICAgICBpZiAoZGVmaW5lZCAkcHJlZml4KSB7ICRzcmNmaWxlID1+IHMvXlxRJHByZWZpeC8vOyB9CisgICAgICAgIHByaW50IE9VVCAiPHRyPjx0ZD4kYXR0cmlidXRlPC90ZD48dGQ+JHNyY2ZpbGU8L3RkPjx0ZD48YSBocmVmPVwiZmFpbHVyZXMvJHBwZmlsZVwiPiRwcGZpbGU8L2E+PC90ZD48dGQ+PGEgaHJlZj1cImZhaWx1cmVzLyRwcGZpbGUuc3RkZXJyLnR4dFwiPiRwcGZpbGUuc3RkZXJyLnR4dDwvYT48L3RkPjwvdHI+XG4iOworICAgICAgICBteSAkcHBmaWxlX2NsYW5nID0gJHBwZmlsZTsKKyAgICAgICAgJHBwZmlsZV9jbGFuZyA9fiBzL1suXSguKykkLy5jbGFuZy4kMS87CisgICAgICAgIHByaW50IE9VVCAiICA8IS0tIFJFUE9SVFBST0JMRU0gc3JjPVwiJHNyY2ZpbGVcIiBmaWxlPVwiZmFpbHVyZXMvJHBwZmlsZVwiIGNsYW5nZmlsZT1cImZhaWx1cmVzLyRwcGZpbGVfY2xhbmdcIiBzdGRlcnI9XCJmYWlsdXJlcy8kcHBmaWxlLnN0ZGVyci50eHRcIiBpbmZvPVwiZmFpbHVyZXMvJHBwZmlsZS5pbmZvLnR4dFwiIC0tPlxuIjsKKyAgICAgIH0KKyAgICAgIHByaW50IE9VVCAiPC90YWJsZT5cbiI7CisgICAgfQorICAgIAorICAgIGlmIChzY2FsYXIgQGZhaWx1cmVzKSB7CisgICAgICBwcmludCBPVVQgIjxwPlRoZSBhbmFseXplciBoYWQgcHJvYmxlbXMgcHJvY2Vzc2luZyB0aGUgZm9sbG93aW5nIGZpbGVzOjwvcD5cbiI7CisgICAgICBwcmludCBPVVQgIjx0YWJsZT5cbiI7CisgICAgICBwcmludCBPVVQgIjx0aGVhZD48dHI+PHRkPlByb2JsZW08L3RkPjx0ZD5Tb3VyY2UgRmlsZTwvdGQ+PHRkPlByZXByb2Nlc3NlZCBGaWxlPC90ZD48dGQ+U1RERVJSIE91dHB1dDwvdGQ+PC90cj48L3RoZWFkPlxuIjsKKyAgICAgIGZvcmVhY2ggbXkgJGZpbGUgKHNvcnQgQGZhaWx1cmVzKSB7CisgICAgICAgICRmaWxlID1+IC8oLispLmluZm8udHh0JC87CisgICAgICAgICMgR2V0IHRoZSBwcmVwcm9jZXNzZWQgZmlsZS4KKyAgICAgICAgbXkgJHBwZmlsZSA9ICQxOworICAgICAgICAjIE9wZW4gdGhlIGluZm8gZmlsZSBhbmQgZ2V0IHRoZSBuYW1lIG9mIHRoZSBzb3VyY2UgZmlsZS4KKyAgICAgICAgb3BlbiAoSU5GTywgIiREaXIvZmFpbHVyZXMvJGZpbGUiKSBvcgorICAgICAgICAgIGRpZSAiQ2Fubm90IG9wZW4gJERpci9mYWlsdXJlcy8kZmlsZVxuIjsKKyAgICAgICAgbXkgJHNyY2ZpbGUgPSA8SU5GTz47CisgICAgICAgIGNob21wICRzcmNmaWxlOworICAgICAgICBteSAkcHJvYmxlbSA9IDxJTkZPPjsKKyAgICAgICAgY2hvbXAgJHByb2JsZW07CisgICAgICAgIGNsb3NlIChJTkZPKTsKKyAgICAgICAgIyBQcmludCB0aGUgaW5mb3JtYXRpb24gaW4gdGhlIHRhYmxlLgorICAgICAgICBteSAkcHJlZml4ID0gR2V0UHJlZml4KCk7CisgICAgICAgIGlmIChkZWZpbmVkICRwcmVmaXgpIHsgJHNyY2ZpbGUgPX4gcy9eXFEkcHJlZml4Ly87IH0KKyAgICAgICAgcHJpbnQgT1VUICI8dHI+PHRkPiRwcm9ibGVtPC90ZD48dGQ+JHNyY2ZpbGU8L3RkPjx0ZD48YSBocmVmPVwiZmFpbHVyZXMvJHBwZmlsZVwiPiRwcGZpbGU8L2E+PC90ZD48dGQ+PGEgaHJlZj1cImZhaWx1cmVzLyRwcGZpbGUuc3RkZXJyLnR4dFwiPiRwcGZpbGUuc3RkZXJyLnR4dDwvYT48L3RkPjwvdHI+XG4iOworICAgICAgICBteSAkcHBmaWxlX2NsYW5nID0gJHBwZmlsZTsKKyAgICAgICAgJHBwZmlsZV9jbGFuZyA9fiBzL1suXSguKykkLy5jbGFuZy4kMS87CisgICAgICAgIHByaW50IE9VVCAiICA8IS0tIFJFUE9SVFBST0JMRU0gc3JjPVwiJHNyY2ZpbGVcIiBmaWxlPVwiZmFpbHVyZXMvJHBwZmlsZVwiIGNsYW5nZmlsZT1cImZhaWx1cmVzLyRwcGZpbGVfY2xhbmdcIiBzdGRlcnI9XCJmYWlsdXJlcy8kcHBmaWxlLnN0ZGVyci50eHRcIiBpbmZvPVwiZmFpbHVyZXMvJHBwZmlsZS5pbmZvLnR4dFwiIC0tPlxuIjsKKyAgICAgIH0KKyAgICAgIHByaW50IE9VVCAiPC90YWJsZT5cbiI7CisgICAgfSAgICAKKyAgICBwcmludCBPVVQgIjxwPlBsZWFzZSBjb25zaWRlciBzdWJtaXR0aW5nIHByZXByb2Nlc3NlZCBmaWxlcyBhcyA8YSBocmVmPVwiaHR0cDovL2NsYW5nLWFuYWx5emVyLmxsdm0ub3JnL2ZpbGluZ19idWdzLmh0bWxcIj5idWcgcmVwb3J0czwvYT4uIDwhLS0gUkVQT1JUQ1JBU0hFUyAtLT4gPC9wPlxuIjsKKyAgfQorICAKKyAgcHJpbnQgT1VUICI8L2JvZHk+PC9odG1sPlxuIjsgIAorICBjbG9zZShPVVQpOworICBDb3B5RmlsZXMoJERpcik7CisKKyAgIyBNYWtlIHN1cmUgJERpciBhbmQgJEJhc2VEaXIgYXJlIHdvcmxkIHJlYWRhYmxlL2V4ZWN1dGFibGUuCisgIHN5c3RlbSgiY2htb2QiLCAiNzU1IiwgJERpcik7CisgIGlmIChkZWZpbmVkICRCYXNlRGlyKSB7IHN5c3RlbSgiY2htb2QiLCAiNzU1IiwgJEJhc2VEaXIpOyB9CisKKyAgIyBQcmludCBzdGF0aXN0aWNzCisgIHByaW50IENhbGNTdGF0cyhcQFN0YXRzKSBpZiAkQW5hbHl6ZXJTdGF0czsKKworICBteSAkTnVtID0gc2NhbGFyKEBJbmRleCk7CisgIERpYWcoIiROdW0gYnVncyBmb3VuZC5cbiIpOworICBpZiAoJE51bSA+IDAgJiYgLXIgIiREaXIvaW5kZXguaHRtbCIpIHsKKyAgICBEaWFnKCJSdW4gJ3NjYW4tdmlldyAkRGlyJyB0byBleGFtaW5lIGJ1ZyByZXBvcnRzLlxuIik7CisgIH0KKyAgCisgIERpYWdDcmFzaGVzKCREaXIpIGlmIChzY2FsYXIgQGZhaWx1cmVzIHx8IHNjYWxhciBAYXR0cmlidXRlc19pZ25vcmVkKTsKKyAgCisgIHJldHVybiAkTnVtOworfQorCisjIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0jIworIyBSdW5CdWlsZENvbW1hbmQgLSBSdW4gdGhlIGJ1aWxkIGNvbW1hbmQuCisjIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0jIworCitzdWIgQWRkSWZOb3RQcmVzZW50IHsKKyAgbXkgJEFyZ3MgPSBzaGlmdDsKKyAgbXkgJEFyZyA9IHNoaWZ0OyAgCisgIG15ICRmb3VuZCA9IDA7CisgIAorICBmb3JlYWNoIG15ICRrIChAJEFyZ3MpIHsKKyAgICBpZiAoJGsgZXEgJEFyZykgeworICAgICAgJGZvdW5kID0gMTsKKyAgICAgIGxhc3Q7CisgICAgfQorICB9CisgIAorICBpZiAoJGZvdW5kID09IDApIHsKKyAgICBwdXNoIEAkQXJncywgJEFyZzsKKyAgfQorfQorCitzdWIgU2V0RW52IHsKKyAgbXkgJE9wdGlvbnMgPSBzaGlmdCBAXzsKKyAgZm9yZWFjaCBteSAkb3B0ICgnQ0MnLCAnQ1hYJywgJ0NMQU5HJywgJ0NMQU5HX0NYWCcsCisgICAgICAgICAgICAgICAgICAgICdDQ0NfQU5BTFlaRVJfQU5BTFlTSVMnLCAnQ0NDX0FOQUxZWkVSX1BMVUdJTlMnKSB7CisgICAgZGllICIkb3B0IGlzIHVuZGVmaW5lZFxuIiBpZiAoIWRlZmluZWQgJG9wdCk7CisgICAgJEVOVnskb3B0fSA9ICRPcHRpb25zLT57JG9wdH07CisgIH0KKyAgZm9yZWFjaCBteSAkb3B0ICgnQ0NDX0FOQUxZWkVSX1NUT1JFX01PREVMJywKKyAgICAgICAgICAgICAgICAgICAgJ0NDQ19BTkFMWVpFUl9QTFVHSU5TJywKKyAgICAgICAgICAgICAgICAgICAgJ0NDQ19BTkFMWVpFUl9JTlRFUk5BTF9TVEFUUycsCisgICAgICAgICAgICAgICAgICAgICdDQ0NfQU5BTFlaRVJfT1VUUFVUX0ZPUk1BVCcpIHsKKyAgICBteSAkeCA9ICRPcHRpb25zLT57JG9wdH07CisgICAgaWYgKGRlZmluZWQgJHgpIHsgJEVOVnskb3B0fSA9ICR4IH0KKyAgfQorICBteSAkVmVyYm9zZSA9ICRPcHRpb25zLT57J1ZFUkJPU0UnfTsKKyAgaWYgKCRWZXJib3NlID49IDIpIHsKKyAgICAkRU5WeydDQ0NfQU5BTFlaRVJfVkVSQk9TRSd9ID0gMTsKKyAgfQorICBpZiAoJFZlcmJvc2UgPj0gMykgeworICAgICRFTlZ7J0NDQ19BTkFMWVpFUl9MT0cnfSA9IDE7CisgIH0KK30KKworIyBUaGUgZmxhZyBjb3JyZXNwb25kaW5nIHRvIHRoZSAtLW92ZXJyaWRlLWNvbXBpbGVyIGNvbW1hbmQgbGluZSBvcHRpb24uCitteSAkT3ZlcnJpZGVDb21waWxlciA9IDA7IAorCitzdWIgUnVuWGNvZGVidWlsZCB7CisgIG15ICRBcmdzID0gc2hpZnQ7CisgIG15ICRJZ25vcmVFcnJvcnMgPSBzaGlmdDsKKyAgbXkgJENDQW5hbHl6ZXIgPSBzaGlmdDsKKyAgbXkgJENYWEFuYWx5emVyID0gc2hpZnQ7CisgIG15ICRPcHRpb25zID0gc2hpZnQ7CisKKyAgaWYgKCRJZ25vcmVFcnJvcnMpIHsKKyAgICBBZGRJZk5vdFByZXNlbnQoJEFyZ3MsIi1QQlhCdWlsZHNDb250aW51ZUFmdGVyRXJyb3JzPVlFUyIpOworICB9CisKKyAgIyBEZXRlY3QgdGhlIHZlcnNpb24gb2YgWGNvZGUuICBJZiBYY29kZSA0LjYgb3IgaGlnaGVyLCB1c2UgbmV3CisgICMgaW4gc2l0dSBzdXBwb3J0IGZvciBhbmFseXplciBpbnRlcnBvc2l0aW9uIHdpdGhvdXQgbmVlZGVkIHRvIG92ZXJyaWRlCisgICMgdGhlIGNvbXBpbGVyLgorICBvcGVuKERFVEVDVF9YQ09ERSwgIi18IiwgJEFyZ3MtPlswXSwgIi12ZXJzaW9uIikgb3IKKyAgICBkaWUgImVycm9yOiBjYW5ub3QgZGV0ZWN0IHZlcnNpb24gb2YgeGNvZGVidWlsZFxuIjsKKworICBteSAkb2xkQmVoYXZpb3IgPSAxOworCisgIHdoaWxlKDxERVRFQ1RfWENPREU+KSB7CisgICAgaWYgKC9eWGNvZGUgKC4rKSQvKSB7CisgICAgICBteSAkdmVyID0gJDE7CisgICAgICBpZiAoJHZlciA9fiAvXihbMC05XStbLl1bMC05XSspW14wLTldPy8pIHsKKyAgICAgICAgaWYgKCQxID49IDQuNikgeworICAgICAgICAgICRvbGRCZWhhdmlvciA9IDA7CisgICAgICAgICAgbGFzdDsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorICBjbG9zZShERVRFQ1RfWENPREUpOworICAKKyAgIyBJZiAtLW92ZXJyaWRlLWNvbXBpbGVyIGlzIGV4cGxpY2l0ZWx5IHJlcXVlc3RlZCwgcmVzb3J0IHRvIHRoZSBvbGQgCisgICMgYmVoYXZpb3IgcmVnYXJkbGVzcyBvZiBYY29kZSB2ZXJzaW9uLgorICBpZiAoJE92ZXJyaWRlQ29tcGlsZXIpIHsKKyAgICAkb2xkQmVoYXZpb3IgPSAxOworICB9CisgIAorICBpZiAoJG9sZEJlaGF2aW9yID09IDApIHsKKyAgICBteSAkT3V0cHV0RGlyID0gJE9wdGlvbnMtPnsiT1VUUFVUX0RJUiJ9OworICAgIG15ICRDTEFORyA9ICRPcHRpb25zLT57IkNMQU5HIn07CisgICAgbXkgJE90aGVyRmxhZ3MgPSAkT3B0aW9ucy0+eyJDQ0NfQU5BTFlaRVJfQU5BTFlTSVMifTsKKyAgICBwdXNoIEAkQXJncywKKyAgICAgICAgIlJVTl9DTEFOR19TVEFUSUNfQU5BTFlaRVI9WUVTIiwKKyAgICAgICAgIkNMQU5HX0FOQUxZWkVSX09VVFBVVD1wbGlzdC1odG1sIiwKKyAgICAgICAgIkNMQU5HX0FOQUxZWkVSX0VYRUM9JENMQU5HIiwKKyAgICAgICAgIkNMQU5HX0FOQUxZWkVSX09VVFBVVF9ESVI9JE91dHB1dERpciIsCisgICAgICAgICJDTEFOR19BTkFMWVpFUl9PVEhFUl9GTEFHUz0kT3RoZXJGbGFncyI7CisKKyAgICByZXR1cm4gKHN5c3RlbShAJEFyZ3MpID4+IDgpOworICB9CisgIAorICAjIERlZmF1bHQgdG8gb2xkIGJlaGF2aW9yIHdoZXJlIHdlIGluc2VydCBhIGJvZ3VzIGNvbXBpbGVyLgorICBTZXRFbnYoJE9wdGlvbnMpOworICAKKyAgIyBDaGVjayBpZiB1c2luZyBpUGhvbmUgU0RLIDMuMCAoc2ltdWxhdG9yKS4gIElmIHNvIHRoZSBjb21waWxlciBiZWluZworICAjIHVzZWQgc2hvdWxkIGJlIGdjYy00LjIuCisgIGlmICghZGVmaW5lZCAkRU5WeyJDQ0NfQ0MifSkgeworICAgIGZvciAobXkgJGkgPSAwIDsgJGkgPCBzY2FsYXIoQCRBcmdzKTsgKyskaSkgeworICAgICAgaWYgKCRBcmdzLT5bJGldIGVxICItc2RrIiAmJiAkaSArIDEgPCBzY2FsYXIoQCRBcmdzKSkgeworICAgICAgICBpZiAoQCRBcmdzWyRpKzFdID1+IC9eaXBob25lc2ltdWxhdG9yMy8pIHsKKyAgICAgICAgICAkRU5WeyJDQ0NfQ0MifSA9ICJnY2MtNC4yIjsKKyAgICAgICAgICAkRU5WeyJDQ0NfQ1hYIn0gPSAiZysrLTQuMiI7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0KKworICAjIERpc2FibGUgUENIIGZpbGVzIHVudGlsIGNsYW5nIHN1cHBvcnRzIHRoZW0uCisgIEFkZElmTm90UHJlc2VudCgkQXJncywiR0NDX1BSRUNPTVBJTEVfUFJFRklYX0hFQURFUj1OTyIpOworICAKKyAgIyBXaGVuICdDQycgaXMgc2V0LCB4Y29kZWJ1aWxkIHVzZXMgaXQgdG8gZG8gYWxsIGxpbmtpbmcsIGV2ZW4gaWYgd2UgYXJlCisgICMgbGlua2luZyBDKysgb2JqZWN0IGZpbGVzLiAgU2V0ICdMRFBMVVNQTFVTJyBzbyB0aGF0IHhjb2RlYnVpbGQgdXNlcyAnZysrJworICAjICh2aWEgYysrLWFuYWx5emVyKSB3aGVuIGxpbmtpbmcgc3VjaCBmaWxlcy4KKyAgJEVOVnsiTERQTFVTUExVUyJ9ID0gJENYWEFuYWx5emVyOworIAorICByZXR1cm4gKHN5c3RlbShAJEFyZ3MpID4+IDgpOyAKK30KKworc3ViIFJ1bkJ1aWxkQ29tbWFuZCB7ICAKKyAgbXkgJEFyZ3MgPSBzaGlmdDsKKyAgbXkgJElnbm9yZUVycm9ycyA9IHNoaWZ0OworICBteSAkQ21kID0gJEFyZ3MtPlswXTsKKyAgbXkgJENDQW5hbHl6ZXIgPSBzaGlmdDsKKyAgbXkgJENYWEFuYWx5emVyID0gc2hpZnQ7CisgIG15ICRPcHRpb25zID0gc2hpZnQ7CisKKyAgaWYgKCRDbWQgPX4gL1xieGNvZGVidWlsZCQvKSB7CisgICAgcmV0dXJuIFJ1blhjb2RlYnVpbGQoJEFyZ3MsICRJZ25vcmVFcnJvcnMsICRDQ0FuYWx5emVyLCAkQ1hYQW5hbHl6ZXIsICRPcHRpb25zKTsKKyAgfQorCisgICMgU2V0dXAgdGhlIGVudmlyb25tZW50LgorICBTZXRFbnYoJE9wdGlvbnMpOworICAKKyAgaWYgKCRDbWQgPX4gLyguKlwvP2djY1teXC9dKiQpLyBvciAKKyAgICAgICRDbWQgPX4gLyguKlwvP2NjW15cL10qJCkvIG9yCisgICAgICAkQ21kID1+IC8oLipcLz9sbHZtLWdjY1teXC9dKiQpLyBvcgorICAgICAgJENtZCA9fiAvKC4qXC8/Y2xhbmckKS8gb3IgCisgICAgICAkQ21kID1+IC8oLipcLz9jY2MtYW5hbHl6ZXJbXlwvXSokKS8pIHsKKworICAgIGlmICghKCRDbWQgPX4gL2NjYy1hbmFseXplci8pIGFuZCAhZGVmaW5lZCAkRU5WeyJDQ0NfQ0MifSkgeworICAgICAgJEVOVnsiQ0NDX0NDIn0gPSAkMTsgICAgICAKKyAgICB9CisgICAgICAgIAorICAgIHNoaWZ0IEAkQXJnczsKKyAgICB1bnNoaWZ0IEAkQXJncywgJENDQW5hbHl6ZXI7CisgIH0KKyAgZWxzaWYgKCRDbWQgPX4gLyguKlwvP2dcK1wrW15cL10qJCkvIG9yIAorICAgICAgICAkQ21kID1+IC8oLipcLz9jXCtcK1teXC9dKiQpLyBvcgorICAgICAgICAkQ21kID1+IC8oLipcLz9sbHZtLWdcK1wrW15cL10qJCkvIG9yCisgICAgICAgICRDbWQgPX4gLyguKlwvP2NsYW5nXCtcKyQpLyBvcgorICAgICAgICAkQ21kID1+IC8oLipcLz9jXCtcKy1hbmFseXplclteXC9dKiQpLykgeworICAgIGlmICghKCRDbWQgPX4gL2NcK1wrLWFuYWx5emVyLykgYW5kICFkZWZpbmVkICRFTlZ7IkNDQ19DWFgifSkgeworICAgICAgJEVOVnsiQ0NDX0NYWCJ9ID0gJDE7ICAgICAgCisgICAgfSAgICAgICAgCisgICAgc2hpZnQgQCRBcmdzOworICAgIHVuc2hpZnQgQCRBcmdzLCAkQ1hYQW5hbHl6ZXI7CisgIH0KKyAgZWxzaWYgKCRDbWQgZXEgIm1ha2UiIG9yICRDbWQgZXEgImdtYWtlIikgeworICAgIEFkZElmTm90UHJlc2VudCgkQXJncywgIkNDPSRDQ0FuYWx5emVyIik7CisgICAgQWRkSWZOb3RQcmVzZW50KCRBcmdzLCAiQ1hYPSRDWFhBbmFseXplciIpOworICAgIGlmICgkSWdub3JlRXJyb3JzKSB7CisgICAgICBBZGRJZk5vdFByZXNlbnQoJEFyZ3MsIi1rIik7CisgICAgICBBZGRJZk5vdFByZXNlbnQoJEFyZ3MsIi1pIik7CisgICAgfQorICB9IAorCisgIHJldHVybiAoc3lzdGVtKEAkQXJncykgPj4gOCk7Cit9CisKKyMjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSMjCisjIERpc3BsYXlIZWxwIC0gVXRpbGl0eSBmdW5jdGlvbiB0byBkaXNwbGF5IGFsbCBoZWxwIG9wdGlvbnMuCisjIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0jIworCitzdWIgRGlzcGxheUhlbHAgeworICAKK3ByaW50IDw8RU5EVEVYVDsKK1VTQUdFOiAkUHJvZyBbb3B0aW9uc10gPGJ1aWxkIGNvbW1hbmQ+IFtidWlsZCBvcHRpb25zXQorCitFTkRURVhUCisKKyAgaWYgKGRlZmluZWQgJEJ1aWxkTmFtZSkgeworICAgIHByaW50ICJBTkFMWVpFUiBCVUlMRDogJEJ1aWxkTmFtZSAoJEJ1aWxkRGF0ZSlcblxuIjsKKyAgfQorCitwcmludCA8PEVORFRFWFQ7CitPUFRJT05TOgorCisgLWFuYWx5emUtaGVhZGVycworIAorICAgQWxzbyBhbmFseXplIGZ1bmN0aW9ucyBpbiAjaW5jbHVkZWQgZmlsZXMuICBCeSBkZWZhdWx0LCBzdWNoIGZ1bmN0aW9ucworICAgYXJlIHNraXBwZWQgdW5sZXNzIHRoZXkgYXJlIGNhbGxlZCBieSBmdW5jdGlvbnMgd2l0aGluIHRoZSBtYWluIHNvdXJjZSBmaWxlLgorIAorIC1vIDxvdXRwdXQgbG9jYXRpb24+CisgIAorICAgU3BlY2lmaWVzIHRoZSBvdXRwdXQgZGlyZWN0b3J5IGZvciBhbmFseXplciByZXBvcnRzLiBTdWJkaXJlY3RvcmllcyB3aWxsIGJlCisgICBjcmVhdGVkIGFzIG5lZWRlZCB0byByZXByZXNlbnQgc2VwYXJhdGUgInJ1bnMiIG9mIHRoZSBhbmFseXplci4gSWYgdGhpcworICAgb3B0aW9uIGlzIG5vdCBzcGVjaWZpZWQsIGEgZGlyZWN0b3J5IGlzIGNyZWF0ZWQgaW4gL3RtcCAoVE1QRElSIG9uIE1hYyBPUyBYKQorICAgdG8gc3RvcmUgdGhlIHJlcG9ydHMuCisKKyAtaCAgICAgICAgICAgICAKKyAtLWhlbHAKKworICAgRGlzcGxheSB0aGlzIG1lc3NhZ2UuCisKKyAtaworIC0ta2VlcC1nb2luZworCQkJCSAgCisgICBBZGQgYSAia2VlcCBvbiBnb2luZyIgb3B0aW9uIHRvIHRoZSBzcGVjaWZpZWQgYnVpbGQgY29tbWFuZC4gVGhpcyBvcHRpb24KKyAgIGN1cnJlbnRseSBzdXBwb3J0cyBtYWtlIGFuZCB4Y29kZWJ1aWxkLiBUaGlzIGlzIGEgY29udmVuaWVuY2Ugb3B0aW9uOyBvbmUKKyAgIGNhbiBzcGVjaWZ5IHRoaXMgYmVoYXZpb3IgZGlyZWN0bHkgdXNpbmcgYnVpbGQgb3B0aW9ucy4KKworIC0taHRtbC10aXRsZSBbdGl0bGVdCisgLS1odG1sLXRpdGxlPVt0aXRsZV0KKworICAgU3BlY2lmeSB0aGUgdGl0bGUgdXNlZCBvbiBnZW5lcmF0ZWQgSFRNTCBwYWdlcy4gSWYgbm90IHNwZWNpZmllZCwgYSBkZWZhdWx0CisgICB0aXRsZSB3aWxsIGJlIHVzZWQuCisKKyAtcGxpc3QKKyAKKyAgIEJ5IGRlZmF1bHQgdGhlIG91dHB1dCBvZiBzY2FuLWJ1aWxkIGlzIGEgc2V0IG9mIEhUTUwgZmlsZXMuIFRoaXMgb3B0aW9uCisgICBvdXRwdXRzIHRoZSByZXN1bHRzIGFzIGEgc2V0IG9mIC5wbGlzdCBmaWxlcy4KKyAKKyAtcGxpc3QtaHRtbAorIAorICAgQnkgZGVmYXVsdCB0aGUgb3V0cHV0IG9mIHNjYW4tYnVpbGQgaXMgYSBzZXQgb2YgSFRNTCBmaWxlcy4gVGhpcyBvcHRpb24KKyAgIG91dHB1dHMgdGhlIHJlc3VsdHMgYXMgYSBzZXQgb2YgSFRNTCBhbmQgLnBsaXN0IGZpbGVzLgorIAorIC0tc3RhdHVzLWJ1Z3MKKyAKKyAgIEJ5IGRlZmF1bHQsIHRoZSBleGl0IHN0YXR1cyBvZiBzY2FuLWJ1aWxkIGlzIHRoZSBzYW1lIGFzIHRoZSBleGVjdXRlZCBidWlsZAorICAgY29tbWFuZC4gU3BlY2lmeWluZyB0aGlzIG9wdGlvbiBjYXVzZXMgdGhlIGV4aXQgc3RhdHVzIG9mIHNjYW4tYnVpbGQgdG8gYmUgMQorICAgaWYgaXQgZm91bmQgcG90ZW50aWFsIGJ1Z3MgYW5kIDAgb3RoZXJ3aXNlLgorCisgLS11c2UtY2MgW2NvbXBpbGVyIHBhdGhdICAgCisgLS11c2UtY2M9W2NvbXBpbGVyIHBhdGhdCisgIAorICAgc2Nhbi1idWlsZCBhbmFseXplcyBhIHByb2plY3QgYnkgaW50ZXJwb3NpbmcgYSAiZmFrZSBjb21waWxlciIsIHdoaWNoCisgICBleGVjdXRlcyBhIHJlYWwgY29tcGlsZXIgZm9yIGNvbXBpbGF0aW9uIGFuZCB0aGUgc3RhdGljIGFuYWx5emVyIGZvciBhbmFseXNpcy4KKyAgIEJlY2F1c2Ugb2YgdGhlIGN1cnJlbnQgaW1wbGVtZW50YXRpb24gb2YgaW50ZXJwb3NpdGlvbiwgc2Nhbi1idWlsZCBkb2VzIG5vdAorICAga25vdyB3aGF0IGNvbXBpbGVyIHlvdXIgcHJvamVjdCBub3JtYWxseSB1c2VzLiAgSW5zdGVhZCwgaXQgc2ltcGx5IG92ZXJyaWRlcworICAgdGhlIENDIGVudmlyb25tZW50IHZhcmlhYmxlLCBhbmQgZ3Vlc3NlcyB5b3VyIGRlZmF1bHQgY29tcGlsZXIuCisgICAKKyAgIEluIHRoZSBmdXR1cmUsIHRoaXMgaW50ZXJwb3NpdGlvbiBtZWNoYW5pc20gdG8gYmUgaW1wcm92ZWQsIGJ1dCBpZiB5b3UgbmVlZAorICAgc2Nhbi1idWlsZCB0byB1c2UgYSBzcGVjaWZpYyBjb21waWxlciBmb3IgKmNvbXBpbGF0aW9uKiB0aGVuIHlvdSBjYW4gdXNlCisgICB0aGlzIG9wdGlvbiB0byBzcGVjaWZ5IGEgcGF0aCB0byB0aGF0IGNvbXBpbGVyLgorCisgLS11c2UtYysrIFtjb21waWxlciBwYXRoXQorIC0tdXNlLWMrKz1bY29tcGlsZXIgcGF0aF0KKyAKKyAgIFRoaXMgaXMgdGhlIHNhbWUgYXMgIi11c2UtY2MiIGJ1dCBmb3IgQysrIGNvZGUuCisgCisgLXYKKyAKKyAgIEVuYWJsZSB2ZXJib3NlIG91dHB1dCBmcm9tIHNjYW4tYnVpbGQuIEEgc2Vjb25kIGFuZCB0aGlyZCAnLXYnIGluY3JlYXNlcworICAgdmVyYm9zaXR5LgorCisgLVYKKyAtLXZpZXcKKworICAgVmlldyBhbmFseXNpcyByZXN1bHRzIGluIGEgd2ViIGJyb3dzZXIgd2hlbiB0aGUgYnVpbGQgY29tcGxldGVzLgorCitBRFZBTkNFRCBPUFRJT05TOgorCisgLW5vLWZhaWx1cmUtcmVwb3J0cworIAorICAgRG8gbm90IGNyZWF0ZSBhICdmYWlsdXJlcycgc3ViZGlyZWN0b3J5IHRoYXQgaW5jbHVkZXMgYW5hbHl6ZXIgY3Jhc2ggcmVwb3J0cworICAgYW5kIHByZXByb2Nlc3NlZCBzb3VyY2UgZmlsZXMuCisKKyAtc3RhdHMKKyAKKyAgIEdlbmVyYXRlcyB2aXNpdGF0aW9uIHN0YXRpc3RpY3MgZm9yIHRoZSBwcm9qZWN0IGJlaW5nIGFuYWx5emVkLgorCisgLW1heGxvb3AgPGxvb3AgY291bnQ+CisgCisgICBTcGVjaWZpeSB0aGUgbnVtYmVyIG9mIHRpbWVzIGEgYmxvY2sgY2FuIGJlIHZpc2l0ZWQgYmVmb3JlIGdpdmluZyB1cC4KKyAgIERlZmF1bHQgaXMgNC4gSW5jcmVhc2UgZm9yIG1vcmUgY29tcHJlaGVuc2l2ZSBjb3ZlcmFnZSBhdCBhIGNvc3Qgb2Ygc3BlZWQuCisgIAorIC1pbnRlcm5hbC1zdGF0cworIAorICAgR2VuZXJhdGUgaW50ZXJuYWwgYW5hbHl6ZXIgc3RhdGlzdGljcy4KKyAKKyAtLXVzZS1hbmFseXplciBbWGNvZGV8cGF0aCB0byBjbGFuZ10gCisgLS11c2UtYW5hbHl6ZXI9W1hjb2RlfHBhdGggdG8gY2xhbmddCisgCisgICBzY2FuLWJ1aWxkIHVzZXMgdGhlICdjbGFuZycgZXhlY3V0YWJsZSByZWxhdGl2ZSB0byBpdHNlbGYgZm9yIHN0YXRpYworICAgYW5hbHlzaXMuIE9uZSBjYW4gb3ZlcnJpZGUgdGhpcyBiZWhhdmlvciB3aXRoIHRoaXMgb3B0aW9uIGJ5IHVzaW5nIHRoZQorICAgJ2NsYW5nJyBwYWNrYWdlZCB3aXRoIFhjb2RlIChvbiBPUyBYKSBvciBmcm9tIHRoZSBQQVRILgorCisgLS1rZWVwLWVtcHR5CisKKyAgIERvbid0IHJlbW92ZSB0aGUgYnVpbGQgcmVzdWx0cyBkaXJlY3RvcnkgZXZlbiBpZiBubyBpc3N1ZXMgd2VyZSByZXBvcnRlZC4KKworIC0tb3ZlcnJpZGUtY29tcGlsZXIgCisgICBBbHdheXMgcmVzb3J0IHRvIHRoZSBjY2MtYW5hbHl6ZXIgZXZlbiB3aGVuIGJldHRlciBpbnRlcnBvc2l0aW9uIG1ldGhvZHMgCisgICBhcmUgYXZhaWxhYmxlLgorICAgCitDT05UUk9MTElORyBDSEVDS0VSUzoKKworIEEgZGVmYXVsdCBncm91cCBvZiBjaGVja2VycyBhcmUgYWx3YXlzIHJ1biB1bmxlc3MgZXhwbGljaXRseSBkaXNhYmxlZC4KKyBDaGVja2VycyBtYXkgYmUgZW5hYmxlZC9kaXNhYmxlZCB1c2luZyB0aGUgZm9sbG93aW5nIG9wdGlvbnM6CisKKyAtZW5hYmxlLWNoZWNrZXIgW2NoZWNrZXIgbmFtZV0KKyAtZGlzYWJsZS1jaGVja2VyIFtjaGVja2VyIG5hbWVdCisgCitMT0FESU5HIENIRUNLRVJTOgorCisgTG9hZGluZyBleHRlcm5hbCBjaGVja2VycyB1c2luZyB0aGUgY2xhbmcgcGx1Z2luIGludGVyZmFjZToKKworIC1sb2FkLXBsdWdpbiBbcGx1Z2luIGxpYnJhcnldCitFTkRURVhUCisKKyMgUXVlcnkgY2xhbmcgZm9yIGxpc3Qgb2YgY2hlY2tlcnMgdGhhdCBhcmUgZW5hYmxlZC4KKworIyBjcmVhdGUgYSBsaXN0IHRvIGxvYWQgdGhlIHBsdWdpbnMgdmlhIHRoZSAnWGNsYW5nJyBjb21tYW5kIGxpbmUKKyMgYXJndW1lbnQKK215IEBQbHVnaW5Mb2FkQ29tbWFuZGxpbmVfeGNsYW5nOworZm9yZWFjaCBteSAkcGFyYW0gKCBAUGx1Z2luc1RvTG9hZCApIHsKKyAgcHVzaCAoIEBQbHVnaW5Mb2FkQ29tbWFuZGxpbmVfeGNsYW5nLCAiLVhjbGFuZyIgKTsKKyAgcHVzaCAoIEBQbHVnaW5Mb2FkQ29tbWFuZGxpbmVfeGNsYW5nLCAkcGFyYW0gKTsKK30KK215ICVFbmFibGVkQ2hlY2tlcnM7Citmb3JlYWNoIG15ICRsYW5nICgiYyIsICJvYmplY3RpdmUtYyIsICJvYmplY3RpdmUtYysrIiwgImMrKyIpIHsKKyAgcGlwZShGUk9NX0NISUxELCBUT19QQVJFTlQpOworICBteSAkcGlkID0gZm9yaygpOworICBpZiAoJHBpZCA9PSAwKSB7CisgICAgY2xvc2UgRlJPTV9DSElMRDsKKyAgICBvcGVuKFNURE9VVCwiPiYiLCBcKlRPX1BBUkVOVCk7CisgICAgb3BlbihTVERFUlIsIj4mIiwgXCpUT19QQVJFTlQpOworICAgIGV4ZWMgJENsYW5nLCAoIEBQbHVnaW5Mb2FkQ29tbWFuZGxpbmVfeGNsYW5nLCAnLS1hbmFseXplJywgJy14JywgJGxhbmcsICctJywgJy0jIyMnKTsgCisgIH0KKyAgY2xvc2UoVE9fUEFSRU5UKTsKKyAgd2hpbGUoPEZST01fQ0hJTEQ+KSB7CisgICAgZm9yZWFjaCBteSAkdmFsIChzcGxpdCAvXHMrLykgeworICAgICAgJHZhbCA9fiBzL1wiLy9nOworICAgICAgaWYgKCR2YWwgPX4gLy1hbmFseXplci1jaGVja2VyXD0oW15cc10rKS8pIHsKKyAgICAgICAgJEVuYWJsZWRDaGVja2Vyc3skMX0gPSAxOworICAgICAgfQorICAgIH0KKyAgfQorICB3YWl0cGlkKCRwaWQsMCk7CisgIGNsb3NlKEZST01fQ0hJTEQpOworfQorCisjIFF1ZXJ5IGNsYW5nIGZvciBjb21wbGV0ZSBsaXN0IG9mIGNoZWNrZXJzLgoraWYgKGRlZmluZWQgJENsYW5nICYmIC14ICRDbGFuZykgeworICBwaXBlKEZST01fQ0hJTEQsIFRPX1BBUkVOVCk7CisgIG15ICRwaWQgPSBmb3JrKCk7CisgIGlmICgkcGlkID09IDApIHsKKyAgICBjbG9zZSBGUk9NX0NISUxEOworICAgIG9wZW4oU1RET1VULCI+JiIsIFwqVE9fUEFSRU5UKTsKKyAgICBvcGVuKFNUREVSUiwiPiYiLCBcKlRPX1BBUkVOVCk7CisgICAgZXhlYyAkQ2xhbmcsICgnLWNjMScsIEBQbHVnaW5zVG9Mb2FkICwgJy1hbmFseXplci1jaGVja2VyLWhlbHAnKTsKKyAgfQorICBjbG9zZShUT19QQVJFTlQpOworICBteSAkZm91bmRDaGVja2VycyA9IDA7CisgIHdoaWxlKDxGUk9NX0NISUxEPikgeworICAgIGlmICgvQ0hFQ0tFUlM6LykgeworICAgICAgJGZvdW5kQ2hlY2tlcnMgPSAxOworICAgICAgbGFzdDsKKyAgICB9CisgIH0KKyAgaWYgKCEkZm91bmRDaGVja2VycykgeworICAgIHByaW50ICIgICoqKiBDb3VsZCBub3QgcXVlcnkgQ2xhbmcgZm9yIHRoZSBsaXN0IG9mIGF2YWlsYWJsZSBjaGVja2Vycy4iOworICB9CisgIGVsc2UgeworICAgIHByaW50KCJcbkFWQUlMQUJMRSBDSEVDS0VSUzpcblxuIik7CisgICAgbXkgJHNraXAgPSAwOworICAgIHdoaWxlKDxGUk9NX0NISUxEPikgeworICAgICAgaWYgKC9leHBlcmltZW50YWwvKSB7CisgICAgICAgICRza2lwID0gMTsKKyAgICAgICAgbmV4dDsKKyAgICAgIH0KKyAgICAgIGlmICgkc2tpcCkgeworICAgICAgICBuZXh0IGlmICghL15cc1xzW15cc10vKTsKKyAgICAgICAgJHNraXAgPSAwOworICAgICAgfQorICAgICAgcy9eXHNccy8vOworICAgICAgaWYgKC9eKFteXHNdKykvKSB7CisgICAgICAgICMgSXMgdGhlIGNoZWNrZXIgZW5hYmxlZD8KKyAgICAgICAgbXkgJGNoZWNrZXIgPSAkMTsKKyAgICAgICAgbXkgJGVuYWJsZWQgPSAwOworICAgICAgICBteSAkYWdncmVnYXRlID0gIiI7CisgICAgICAgIGZvcmVhY2ggbXkgJGRvbWFpbiAoc3BsaXQgL1wuLywgJGNoZWNrZXIpIHsKKyAgICAgICAgICAkYWdncmVnYXRlIC49ICRkb21haW47CisgICAgICAgICAgaWYgKCRFbmFibGVkQ2hlY2tlcnN7JGFnZ3JlZ2F0ZX0pIHsKKyAgICAgICAgICAgICRlbmFibGVkID0xOworICAgICAgICAgICAgbGFzdDsKKyAgICAgICAgICB9CisgICAgICAgICAgIyBhcHBlbmQgYSBkb3QsIGlmIGFuIGFkZGl0aW9uYWwgZG9tYWluIGlzIGFkZGVkIGluIHRoZSBuZXh0IGl0ZXJhdGlvbgorICAgICAgICAgICRhZ2dyZWdhdGUgLj0gIi4iOworICAgICAgICB9CisgICAgICAKKyAgICAgICAgaWYgKCRlbmFibGVkKSB7CisgICAgICAgICAgcHJpbnQgIiArICI7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgcHJpbnQgIiAgICI7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGVsc2UgeworICAgICAgICBwcmludCAiICAgIjsKKyAgICAgIH0KKyAgICAgIHByaW50ICRfOworICAgIH0KKyAgICBwcmludCAiXG5OT1RFOiBcIitcIiBpbmRpY2F0ZXMgdGhhdCBhbiBhbmFseXNpcyBpcyBlbmFibGVkIGJ5IGRlZmF1bHQuXG4iCisgIH0KKyAgd2FpdHBpZCgkcGlkLDApOworICBjbG9zZShGUk9NX0NISUxEKTsKK30KKworcHJpbnQgPDxFTkRURVhUCisKK0JVSUxEIE9QVElPTlMKKworIFlvdSBjYW4gc3BlY2lmeSBhbnkgYnVpbGQgb3B0aW9uIGFjY2VwdGFibGUgdG8gdGhlIGJ1aWxkIGNvbW1hbmQuCisKK0VYQU1QTEUKKworIHNjYW4tYnVpbGQgLW8gL3RtcC9teWh0bWxkaXIgbWFrZSAtajQKKyAgICAgCitUaGUgYWJvdmUgZXhhbXBsZSBjYXVzZXMgYW5hbHlzaXMgcmVwb3J0cyB0byBiZSBkZXBvc2l0ZWQgaW50byBhIHN1YmRpcmVjdG9yeQorb2YgIi90bXAvbXlodG1sZGlyIiBhbmQgdG8gcnVuICJtYWtlIiB3aXRoIHRoZSAiLWo0IiBvcHRpb24uIEEgZGlmZmVyZW50CitzdWJkaXJlY3RvcnkgaXMgY3JlYXRlZCBlYWNoIHRpbWUgc2Nhbi1idWlsZCBhbmFseXplcyBhIHByb2plY3QuIFRoZSBhbmFseXplcgorc2hvdWxkIHN1cHBvcnQgbW9zdCBwYXJhbGxlbCBidWlsZHMsIGJ1dCBub3QgZGlzdHJpYnV0ZWQgYnVpbGRzLgorCitFTkRURVhUCit9CisKKyMjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSMjCisjIEh0bWxFc2NhcGUgLSBIVE1MIGVudGl0eSBlbmNvZGUgY2hhcmFjdGVycyB0aGF0IGFyZSBzcGVjaWFsIGluIEhUTUwKKyMjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSMjCisKK3N1YiBIdG1sRXNjYXBlIHsKKyAgIyBjb3B5IGFyZ3VtZW50IHRvIG5ldyB2YXJpYWJsZSBzbyB3ZSBkb24ndCBjbG9iYmVyIHRoZSBvcmlnaW5hbAorICBteSAkYXJnID0gc2hpZnQgfHwgJyc7CisgIG15ICR0bXAgPSAkYXJnOworICAkdG1wID1+IHMvJi8mYW1wOy9nOworICAkdG1wID1+IHMvPC8mbHQ7L2c7CisgICR0bXAgPX4gcy8+LyZndDsvZzsKKyAgcmV0dXJuICR0bXA7Cit9CisKKyMjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSMjCisjIFNoZWxsRXNjYXBlIC0gYmFja3NsYXNoIGVzY2FwZSBjaGFyYWN0ZXJzIHRoYXQgYXJlIHNwZWNpYWwgdG8gdGhlIHNoZWxsCisjIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0jIworCitzdWIgU2hlbGxFc2NhcGUgeworICAjIGNvcHkgYXJndW1lbnQgdG8gbmV3IHZhcmlhYmxlIHNvIHdlIGRvbid0IGNsb2JiZXIgdGhlIG9yaWdpbmFsCisgIG15ICRhcmcgPSBzaGlmdCB8fCAnJzsKKyAgaWYgKCRhcmcgPX4gL1siXHNdLykgeyByZXR1cm4gIiciIC4gJGFyZyAuICInIjsgfQorICByZXR1cm4gJGFyZzsKK30KKworIyMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIyMKKyMgUHJvY2VzcyBjb21tYW5kLWxpbmUgYXJndW1lbnRzLgorIyMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIyMKKworbXkgJEFuYWx5emVIZWFkZXJzID0gMDsKK215ICRIdG1sRGlyOyAgICAgICAgICAgIyBQYXJlbnQgZGlyZWN0b3J5IHRvIHN0b3JlIEhUTUwgZmlsZXMuCitteSAkSWdub3JlRXJyb3JzID0gMDsgICMgSWdub3JlIGJ1aWxkIGVycm9ycy4KK215ICRWaWV3UmVzdWx0cyAgPSAwOyAgIyBWaWV3IHJlc3VsdHMgd2hlbiB0aGUgYnVpbGQgdGVybWluYXRlcy4KK215ICRFeGl0U3RhdHVzRm91bmRCdWdzID0gMDsgIyBFeGl0IHN0YXR1cyByZWZsZWN0cyB3aGV0aGVyIGJ1Z3Mgd2VyZSBmb3VuZAorbXkgJEtlZXBFbXB0eSAgICA9IDA7ICAjIERvbid0IHJlbW92ZSBvdXRwdXQgZGlyZWN0b3J5IGV2ZW4gd2l0aCAwIHJlc3VsdHMuCitteSBAQW5hbHlzZXNUb1J1bjsKK215ICRTdG9yZU1vZGVsOworbXkgJENvbnN0cmFpbnRzTW9kZWw7CitteSAkSW50ZXJuYWxTdGF0czsKK215ICRPdXRwdXRGb3JtYXQgPSAiaHRtbCI7CitteSAkQW5hbHl6ZXJTdGF0cyA9IDA7CitteSAkTWF4TG9vcCA9IDA7CitteSAkUmVxdWVzdERpc3BsYXlIZWxwID0gMDsKK215ICRGb3JjZURpc3BsYXlIZWxwID0gMDsKK215ICRBbmFseXplckRpc2NvdmVyeU1ldGhvZDsKKworaWYgKCFAQVJHVikgeworICAkRm9yY2VEaXNwbGF5SGVscCA9IDEKK30KKword2hpbGUgKEBBUkdWKSB7CisgIAorICAjIFNjYW4gZm9yIG9wdGlvbnMgd2UgcmVjb2duaXplLgorICAKKyAgbXkgJGFyZyA9ICRBUkdWWzBdOworCisgIGlmICgkYXJnIGVxICItaCIgb3IgJGFyZyBlcSAiLS1oZWxwIikgeworICAgICRSZXF1ZXN0RGlzcGxheUhlbHAgPSAxOworICAgIHNoaWZ0IEBBUkdWOworICAgIG5leHQ7CisgIH0KKyAgCisgIGlmICgkYXJnIGVxICctYW5hbHl6ZS1oZWFkZXJzJykgeworICAgIHNoaWZ0IEBBUkdWOyAgICAKKyAgICAkQW5hbHl6ZUhlYWRlcnMgPSAxOworICAgIG5leHQ7CisgIH0KKyAgCisgIGlmICgkYXJnIGVxICItbyIpIHsKKyAgICBzaGlmdCBAQVJHVjsKKyAgICAgICAgCisgICAgaWYgKCFAQVJHVikgeworICAgICAgRGllRGlhZygiJy1vJyBvcHRpb24gcmVxdWlyZXMgYSB0YXJnZXQgZGlyZWN0b3J5IG5hbWUuXG4iKTsKKyAgICB9CisgICAgCisgICAgIyBDb25zdHJ1Y3QgYW4gYWJzb2x1dGUgcGF0aC4gIFVzZXMgdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkKKyAgICAjIGFzIGEgYmFzZSBpZiB0aGUgb3JpZ2luYWwgcGF0aCB3YXMgbm90IGFic29sdXRlLgorICAgICRIdG1sRGlyID0gYWJzX3BhdGgoc2hpZnQgQEFSR1YpOworICAgIAorICAgIG5leHQ7CisgIH0KKworICBpZiAoJGFyZyA9fiAvXi0taHRtbC10aXRsZSg9KC4rKSk/JC8pIHsKKyAgICBzaGlmdCBAQVJHVjsKKworICAgIGlmICghZGVmaW5lZCAkMiB8fCAkMiBlcSAnJykgeworICAgICAgaWYgKCFAQVJHVikgeworICAgICAgICBEaWVEaWFnKCInLS1odG1sLXRpdGxlJyBvcHRpb24gcmVxdWlyZXMgYSBzdHJpbmcuXG4iKTsKKyAgICAgIH0KKworICAgICAgJEh0bWxUaXRsZSA9IHNoaWZ0IEBBUkdWOworICAgIH0gZWxzZSB7CisgICAgICAkSHRtbFRpdGxlID0gJDI7CisgICAgfQorCisgICAgbmV4dDsKKyAgfQorICAKKyAgaWYgKCRhcmcgZXEgIi1rIiBvciAkYXJnIGVxICItLWtlZXAtZ29pbmciKSB7CisgICAgc2hpZnQgQEFSR1Y7CisgICAgJElnbm9yZUVycm9ycyA9IDE7CisgICAgbmV4dDsKKyAgfQorCisgIGlmICgkYXJnID1+IC9eLS11c2UtY2MoPSguKykpPyQvKSB7CisgICAgc2hpZnQgQEFSR1Y7CisgICAgbXkgJGNjOworICAgIAorICAgIGlmICghZGVmaW5lZCAkMiB8fCAkMiBlcSAiIikgeworICAgICAgaWYgKCFAQVJHVikgeworICAgICAgICBEaWVEaWFnKCInLS11c2UtY2MnIG9wdGlvbiByZXF1aXJlcyBhIGNvbXBpbGVyIGV4ZWN1dGFibGUgbmFtZS5cbiIpOworICAgICAgfQorICAgICAgJGNjID0gc2hpZnQgQEFSR1Y7CisgICAgfQorICAgIGVsc2UgeworICAgICAgJGNjID0gJDI7CisgICAgfQorICAgIAorICAgICRFTlZ7IkNDQ19DQyJ9ID0gJGNjOworICAgIG5leHQ7CisgIH0KKyAgCisgIGlmICgkYXJnID1+IC9eLS11c2UtY1wrXCsoPSguKykpPyQvKSB7CisgICAgc2hpZnQgQEFSR1Y7CisgICAgbXkgJGN4eDsgICAgCisgICAgCisgICAgaWYgKCFkZWZpbmVkICQyIHx8ICQyIGVxICIiKSB7CisgICAgICBpZiAoIUBBUkdWKSB7CisgICAgICAgIERpZURpYWcoIictLXVzZS1jKysnIG9wdGlvbiByZXF1aXJlcyBhIGNvbXBpbGVyIGV4ZWN1dGFibGUgbmFtZS5cbiIpOworICAgICAgfQorICAgICAgJGN4eCA9IHNoaWZ0IEBBUkdWOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICRjeHggPSAkMjsKKyAgICB9CisgICAgCisgICAgJEVOVnsiQ0NDX0NYWCJ9ID0gJGN4eDsKKyAgICBuZXh0OworICB9CisgIAorICBpZiAoJGFyZyBlcSAiLXYiKSB7CisgICAgc2hpZnQgQEFSR1Y7CisgICAgJFZlcmJvc2UrKzsKKyAgICBuZXh0OworICB9CisgIAorICBpZiAoJGFyZyBlcSAiLVYiIG9yICRhcmcgZXEgIi0tdmlldyIpIHsKKyAgICBzaGlmdCBAQVJHVjsKKyAgICAkVmlld1Jlc3VsdHMgPSAxOyAgICAKKyAgICBuZXh0OworICB9CisgIAorICBpZiAoJGFyZyBlcSAiLS1zdGF0dXMtYnVncyIpIHsKKyAgICBzaGlmdCBAQVJHVjsKKyAgICAkRXhpdFN0YXR1c0ZvdW5kQnVncyA9IDE7CisgICAgbmV4dDsKKyAgfQorCisgIGlmICgkYXJnIGVxICItc3RvcmUiKSB7CisgICAgc2hpZnQgQEFSR1Y7CisgICAgJFN0b3JlTW9kZWwgPSBzaGlmdCBAQVJHVjsKKyAgICBuZXh0OworICB9CisgIAorICBpZiAoJGFyZyBlcSAiLWNvbnN0cmFpbnRzIikgeworICAgIHNoaWZ0IEBBUkdWOworICAgICRDb25zdHJhaW50c01vZGVsID0gc2hpZnQgQEFSR1Y7CisgICAgbmV4dDsKKyAgfQorCisgIGlmICgkYXJnIGVxICItaW50ZXJuYWwtc3RhdHMiKSB7CisgICAgc2hpZnQgQEFSR1Y7CisgICAgJEludGVybmFsU3RhdHMgPSAxOworICAgIG5leHQ7CisgIH0KKyAgCisgIGlmICgkYXJnIGVxICItcGxpc3QiKSB7CisgICAgc2hpZnQgQEFSR1Y7CisgICAgJE91dHB1dEZvcm1hdCA9ICJwbGlzdCI7CisgICAgbmV4dDsKKyAgfQorICBpZiAoJGFyZyBlcSAiLXBsaXN0LWh0bWwiKSB7CisgICAgc2hpZnQgQEFSR1Y7CisgICAgJE91dHB1dEZvcm1hdCA9ICJwbGlzdC1odG1sIjsKKyAgICBuZXh0OworICB9CisgIAorICBpZiAoJGFyZyBlcSAiLW5vLWZhaWx1cmUtcmVwb3J0cyIpIHsKKyAgICAkRU5WeyJDQ0NfUkVQT1JUX0ZBSUxVUkVTIn0gPSAwOworICAgIG5leHQ7CisgIH0KKyAgaWYgKCRhcmcgZXEgIi1zdGF0cyIpIHsKKyAgICBzaGlmdCBAQVJHVjsKKyAgICAkQW5hbHl6ZXJTdGF0cyA9IDE7CisgICAgbmV4dDsKKyAgfQorICBpZiAoJGFyZyBlcSAiLW1heGxvb3AiKSB7CisgICAgc2hpZnQgQEFSR1Y7CisgICAgJE1heExvb3AgPSBzaGlmdCBAQVJHVjsKKyAgICBuZXh0OworICB9CisgIGlmICgkYXJnIGVxICItZW5hYmxlLWNoZWNrZXIiKSB7CisgICAgc2hpZnQgQEFSR1Y7CisgICAgcHVzaCBAQW5hbHlzZXNUb1J1biwgIi1hbmFseXplci1jaGVja2VyIiwgc2hpZnQgQEFSR1Y7CisgICAgbmV4dDsKKyAgfQorICBpZiAoJGFyZyBlcSAiLWRpc2FibGUtY2hlY2tlciIpIHsKKyAgICBzaGlmdCBAQVJHVjsKKyAgICBwdXNoIEBBbmFseXNlc1RvUnVuLCAiLWFuYWx5emVyLWRpc2FibGUtY2hlY2tlciIsIHNoaWZ0IEBBUkdWOworICAgIG5leHQ7CisgIH0KKyAgaWYgKCRhcmcgZXEgIi1sb2FkLXBsdWdpbiIpIHsKKyAgICBzaGlmdCBAQVJHVjsKKyAgICBwdXNoIEBQbHVnaW5zVG9Mb2FkLCAiLWxvYWQiLCBzaGlmdCBAQVJHVjsKKyAgICBuZXh0OworICB9CisgIGlmICgkYXJnIGVxICItLXVzZS1hbmFseXplciIpIHsKKyAJc2hpZnQgQEFSR1Y7CisgIAkkQW5hbHl6ZXJEaXNjb3ZlcnlNZXRob2QgPSBzaGlmdCBAQVJHVjsKKwluZXh0OworICB9CisgIGlmICgkYXJnID1+IC9eLS11c2UtYW5hbHl6ZXI9KC4rKSQvKSB7CisgICAgc2hpZnQgQEFSR1Y7CisJJEFuYWx5emVyRGlzY292ZXJ5TWV0aG9kID0gJDE7CisJbmV4dDsKKyAgfQorICBpZiAoJGFyZyBlcSAiLS1rZWVwLWVtcHR5IikgeworICAgIHNoaWZ0IEBBUkdWOworICAgICRLZWVwRW1wdHkgPSAxOworICAgIG5leHQ7CisgIH0KKworICBpZiAoJGFyZyBlcSAiLS1vdmVycmlkZS1jb21waWxlciIpIHsKKyAgICBzaGlmdCBAQVJHVjsKKyAgICAkT3ZlcnJpZGVDb21waWxlciA9IDE7CisgICAgbmV4dDsKKyAgfQorICAKKyAgRGllRGlhZygidW5yZWNvZ25pemVkIG9wdGlvbiAnJGFyZydcbiIpIGlmICgkYXJnID1+IC9eLS8pOworICAKKyAgbGFzdDsKK30KKworaWYgKCFAQVJHViBhbmQgISRSZXF1ZXN0RGlzcGxheUhlbHApIHsKKyAgRXJyb3JEaWFnKCJObyBidWlsZCBjb21tYW5kIHNwZWNpZmllZC5cblxuIik7CisgICRGb3JjZURpc3BsYXlIZWxwID0gMTsKK30KKworIyBGaW5kICdjbGFuZycKK2lmICghZGVmaW5lZCAkQW5hbHl6ZXJEaXNjb3ZlcnlNZXRob2QpIHsKKyAgJENsYW5nID0gQ3dkOjpyZWFscGF0aCgiJFJlYWxCaW4vYmluL2NsYW5nIik7CisgIGlmICghZGVmaW5lZCAkQ2xhbmcgfHwgISAteCAkQ2xhbmcpIHsKKyAgICAkQ2xhbmcgPSBDd2Q6OnJlYWxwYXRoKCIkUmVhbEJpbi9jbGFuZyIpOworICB9CisgIGlmICghZGVmaW5lZCAkQ2xhbmcgfHwgISAteCAkQ2xhbmcpIHsKKyAgICBpZiAoISRSZXF1ZXN0RGlzcGxheUhlbHAgJiYgISRGb3JjZURpc3BsYXlIZWxwKSB7CisgICAgICBEaWVEaWFnKCJlcnJvcjogQ2Fubm90IGZpbmQgYW4gZXhlY3V0YWJsZSAnY2xhbmcnIHJlbGF0aXZlIHRvIHNjYW4tYnVpbGQuIiAuCisgICAJICAgICAgICAgICIgIENvbnNpZGVyIHVzaW5nIC0tdXNlLWFuYWx5emVyIHRvIHBpY2sgYSB2ZXJzaW9uIG9mICdjbGFuZycgdG8gdXNlIGZvciBzdGF0aWMgYW5hbHlzaXMuXG4iKTsKKyAgICB9CisgIH0KK30gCitlbHNlIHsgIAorICBpZiAoJEFuYWx5emVyRGlzY292ZXJ5TWV0aG9kID1+IC9eW1h4XWNvZGUkLykgeworCW15ICR4Y3J1biA9IGB3aGljaCB4Y3J1bmA7CisgICAgY2hvbXAgJHhjcnVuOworCWlmICgkeGNydW4gZXEgIiIpIHsKKyAgCSAgRGllRGlhZygiQ2Fubm90IGZpbmQgJ3hjcnVuJyB0byBmaW5kICdjbGFuZycgZm9yIGFuYWx5c2lzLlxuIik7CisJfQorICAgICRDbGFuZyA9IGAkeGNydW4gLXRvb2xjaGFpbiBYY29kZURlZmF1bHQgLWZpbmQgY2xhbmdgOworICAgIGNob21wICRDbGFuZzsgIAorICAgIGlmICgkQ2xhbmcgZXEgIiIpIHsKKyAgICAgIERpZURpYWcoIk5vICdjbGFuZycgZXhlY3V0YWJsZSBmb3VuZCBieSAneGNydW4nXG4iKTsgCisgICAgfQorICB9CisgIGVsc2UgeworICAgICRDbGFuZyA9IEN3ZDo6cmVhbHBhdGgoJEFuYWx5emVyRGlzY292ZXJ5TWV0aG9kKTsKKwlpZiAoIWRlZmluZWQgJENsYW5nIG9yIG5vdCAteCAkQ2xhbmcpIHsKKyAgIAkgIERpZURpYWcoIkNhbm5vdCBmaW5kIGFuIGV4ZWN1dGFibGUgY2xhbmcgYXQgJyRBbmFseXplckRpc2NvdmVyeU1ldGhvZCdcbiIpOworCX0KKyAgfQorfQorCitpZiAoJEZvcmNlRGlzcGxheUhlbHAgfHwgJFJlcXVlc3REaXNwbGF5SGVscCkgeworICBEaXNwbGF5SGVscCgpOworICBleGl0ICRGb3JjZURpc3BsYXlIZWxwOworfQorCiskQ2xhbmdDWFggPSAkQ2xhbmc7CisjIERldGVybWluZSBvcGVyYXRpbmcgc3lzdGVtIHVuZGVyIHdoaWNoIHRoaXMgY29weSBvZiBQZXJsIHdhcyBidWlsdC4KK215ICRJc1dpbkJ1aWxkID0gKCReTyA9fi9tc3lzfGN5Z3dpbnxNU1dpbjMyLyk7CitpZigkSXNXaW5CdWlsZCkgeworICAkQ2xhbmdDWFggPX4gcy8uZXhlJC8rKy5leGUvOworfQorZWxzZSB7CisgICRDbGFuZ0NYWCA9fiBzL1wtXGQrXC5cZCskLy87CisgICRDbGFuZ0NYWCAuPSAiKysiOworfQorCisjIE1ha2Ugc3VyZSB0byB1c2UgIiIgdG8gaGFuZGxlIHBhdGhzIHdpdGggc3BhY2VzLgorJENsYW5nVmVyc2lvbiA9IEh0bWxFc2NhcGUoYCIkQ2xhbmciIC0tdmVyc2lvbmApOworCisjIERldGVybWluZSB3aGVyZSByZXN1bHRzIGdvLgorJENtZEFyZ3MgPSBIdG1sRXNjYXBlKGpvaW4oJyAnLCBtYXAoU2hlbGxFc2NhcGUoJF8pLCBAQVJHVikpKTsKKyRIdG1sVGl0bGUgPSAiJHtDdXJyZW50RGlyU3VmZml4fSAtIHNjYW4tYnVpbGQgcmVzdWx0cyIKKyAgdW5sZXNzIChkZWZpbmVkKCRIdG1sVGl0bGUpKTsKKworIyBEZXRlcm1pbmUgdGhlIG91dHB1dCBkaXJlY3RvcnkgZm9yIHRoZSBIVE1MIHJlcG9ydHMuCitteSAkQmFzZURpciA9ICRIdG1sRGlyOworJEh0bWxEaXIgPSBHZXRIVE1MUnVuRGlyKCRIdG1sRGlyKTsKKworIyBEZXRlcm1pbmUgdGhlIGxvY2F0aW9uIG9mIGNjYy1hbmFseXplci4KK215ICRBYnNSZWFsQmluID0gQ3dkOjpyZWFscGF0aCgkUmVhbEJpbik7CitteSAkQ21kID0gIiRBYnNSZWFsQmluL2xpYmV4ZWMvY2NjLWFuYWx5emVyIjsKK215ICRDbWRDWFggPSAiJEFic1JlYWxCaW4vbGliZXhlYy9jKystYW5hbHl6ZXIiOworCisjIFBvcnRhYmlsaXR5OiB1c2UgbGVzcyBzdHJpY3QgYnV0IHBvcnRhYmxlIGNoZWNrIC1lIChmaWxlIGV4aXN0cykgaW5zdGVhZCBvZiAKKyMgbm9uLXBvcnRhYmxlIC14IChmaWxlIGlzIGV4ZWN1dGFibGUpLiBPbiBzb21lIHdpbmRvd3MgcG9ydHMgLXgganVzdCBjaGVja3MKKyMgZmlsZSBleHRlbnNpb24gdG8gZGV0ZXJtaW5lIGlmIGEgZmlsZSBpcyBleGVjdXRhYmxlIChzZWUgUGVybCBsYW5ndWFnZSAKKyMgcmVmZXJlbmNlLCBwZXJscG9ydCkKK2lmICghZGVmaW5lZCAkQ21kIHx8ICEgLWUgJENtZCkgeworICAkQ21kID0gIiRBYnNSZWFsQmluL2NjYy1hbmFseXplciI7CisgIERpZURpYWcoIidjY2MtYW5hbHl6ZXInIGRvZXMgbm90IGV4aXN0IGF0ICckQ21kJ1xuIikgaWYoISAtZSAkQ21kKTsKK30KK2lmICghZGVmaW5lZCAkQ21kQ1hYIHx8ICEgLWUgJENtZENYWCkgeworICAkQ21kQ1hYID0gIiRBYnNSZWFsQmluL2MrKy1hbmFseXplciI7CisgIERpZURpYWcoIidjKystYW5hbHl6ZXInIGRvZXMgbm90IGV4aXN0IGF0ICckQ21kQ1hYJ1xuIikgaWYoISAtZSAkQ21kQ1hYKTsKK30KKworRGlhZygiVXNpbmcgJyRDbGFuZycgZm9yIHN0YXRpYyBhbmFseXNpc1xuIik7CisKK1NldEh0bWxFbnYoXEBBUkdWLCAkSHRtbERpcik7CitpZiAoJEFuYWx5emVIZWFkZXJzKSB7IHB1c2ggQEFuYWx5c2VzVG9SdW4sIi1hbmFseXplci1vcHQtYW5hbHl6ZS1oZWFkZXJzIjsgfQoraWYgKCRBbmFseXplclN0YXRzKSB7IHB1c2ggQEFuYWx5c2VzVG9SdW4sICctYW5hbHl6ZXItY2hlY2tlcj1kZWJ1Zy5TdGF0cyc7IH0KK2lmICgkTWF4TG9vcCA+IDApIHsgcHVzaCBAQW5hbHlzZXNUb1J1biwgIi1hbmFseXplci1tYXgtbG9vcCAkTWF4TG9vcCI7IH0KKworIyBEZWxheSBzZXR0aW5nIHVwIG90aGVyIGVudmlyb25tZW50IHZhcmlhYmxlcyBpbiBjYXNlIHdlIGNhbiBkbyB0cnVlCisjIGludGVycG9zaXRpb24uCitteSAkQ0NDX0FOQUxZWkVSX0FOQUxZU0lTID0gam9pbiAnICcsQEFuYWx5c2VzVG9SdW47CitteSAkQ0NDX0FOQUxZWkVSX1BMVUdJTlMgPSBqb2luICcgJyxAUGx1Z2luc1RvTG9hZDsKK215ICVPcHRpb25zID0gKAorICAnQ0MnID0+ICRDbWQsCisgICdDWFgnID0+ICRDbWRDWFgsCisgICdDTEFORycgPT4gJENsYW5nLAorICAnQ0xBTkdfQ1hYJyA9PiAkQ2xhbmdDWFgsCisgICdWRVJCT1NFJyA9PiAkVmVyYm9zZSwKKyAgJ0NDQ19BTkFMWVpFUl9BTkFMWVNJUycgPT4gJENDQ19BTkFMWVpFUl9BTkFMWVNJUywKKyAgJ0NDQ19BTkFMWVpFUl9QTFVHSU5TJyA9PiAkQ0NDX0FOQUxZWkVSX1BMVUdJTlMsCisgICdPVVRQVVRfRElSJyA9PiAkSHRtbERpcgorKTsKKworaWYgKGRlZmluZWQgJFN0b3JlTW9kZWwpIHsKKyAgJE9wdGlvbnN7J0NDQ19BTkFMWVpFUl9TVE9SRV9NT0RFTCd9ID0gJFN0b3JlTW9kZWw7Cit9CitpZiAoZGVmaW5lZCAkQ29uc3RyYWludHNNb2RlbCkgeworICAkT3B0aW9uc3snQ0NDX0FOQUxZWkVSX0NPTlNUUkFJTlRTX01PREVMJ30gPSAkQ29uc3RyYWludHNNb2RlbDsKK30KK2lmIChkZWZpbmVkICRJbnRlcm5hbFN0YXRzKSB7CisgICRPcHRpb25zeydDQ0NfQU5BTFlaRVJfSU5URVJOQUxfU1RBVFMnfSA9IDE7Cit9CitpZiAoZGVmaW5lZCAkT3V0cHV0Rm9ybWF0KSB7CisgICRPcHRpb25zeydDQ0NfQU5BTFlaRVJfT1VUUFVUX0ZPUk1BVCd9ID0gJE91dHB1dEZvcm1hdDsKK30KKworIyBSdW4gdGhlIGJ1aWxkLgorbXkgJEV4aXRTdGF0dXMgPSBSdW5CdWlsZENvbW1hbmQoXEBBUkdWLCAkSWdub3JlRXJyb3JzLCAkQ21kLCAkQ21kQ1hYLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcJU9wdGlvbnMpOworCitpZiAoZGVmaW5lZCAkT3V0cHV0Rm9ybWF0KSB7CisgIGlmICgkT3V0cHV0Rm9ybWF0ID1+IC9wbGlzdC8pIHsKKyAgICBEaWFnICJBbmFseXNpcyBydW4gY29tcGxldGUuXG4iOworICAgIERpYWcgIkFuYWx5c2lzIHJlc3VsdHMgKHBsaXN0IGZpbGVzKSBkZXBvc2l0ZWQgaW4gJyRIdG1sRGlyJ1xuIjsKKyAgfQorICBpZiAoJE91dHB1dEZvcm1hdCA9fiAvaHRtbC8pIHsKKyAgICAjIFBvc3Rwcm9jZXNzIHRoZSBIVE1MIGRpcmVjdG9yeS4KKyAgICBteSAkTnVtQnVncyA9IFBvc3Rwcm9jZXNzKCRIdG1sRGlyLCAkQmFzZURpciwgJEFuYWx5emVyU3RhdHMsICRLZWVwRW1wdHkpOworCisgICAgaWYgKCRWaWV3UmVzdWx0cyBhbmQgLXIgIiRIdG1sRGlyL2luZGV4Lmh0bWwiKSB7CisgICAgICBEaWFnICJBbmFseXNpcyBydW4gY29tcGxldGUuXG4iOworICAgICAgRGlhZyAiVmlld2luZyBhbmFseXNpcyByZXN1bHRzIGluICckSHRtbERpcicgdXNpbmcgc2Nhbi12aWV3LlxuIjsKKyAgICAgIG15ICRTY2FuVmlldyA9IEN3ZDo6cmVhbHBhdGgoIiRSZWFsQmluL3NjYW4tdmlldyIpOworICAgICAgaWYgKCEgLXggJFNjYW5WaWV3KSB7ICRTY2FuVmlldyA9ICJzY2FuLXZpZXciOyB9CisgICAgICBleGVjICRTY2FuVmlldywgIiRIdG1sRGlyIjsKKyAgICB9CisKKyAgICBpZiAoJEV4aXRTdGF0dXNGb3VuZEJ1Z3MpIHsKKyAgICAgIGV4aXQgMSBpZiAoJE51bUJ1Z3MgPiAwKTsKKyAgICAgIGV4aXQgMDsKKyAgICB9CisgIH0KK30KKworZXhpdCAkRXhpdFN0YXR1czsKKwpkaWZmIC0tZ2l0IGEvdG9vbHMvc2Nhbi1idWlsZC9zY2FuLWJ1aWxkLjEgYi90b29scy9zY2FuLWJ1aWxkL3NjYW4tYnVpbGQuMQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wYzdlZjFkCi0tLSAvZGV2L251bGwKKysrIGIvdG9vbHMvc2Nhbi1idWlsZC9zY2FuLWJ1aWxkLjEKQEAgLTAsMCArMSwzNDkgQEAKKy5cIiBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy5cIiBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisuXCIgJElkOiBzY2FuLWJ1aWxkLjEgMTY3NTM3IDIwMTItMTEtMDcgMTc6MTI6MzdaIGpyb3NlICQKKy5EZCBNYXkgMjUsIDIwMTIKKy5EdCBTQ0FOLUJVSUxEIDEKKy5PcyAiY2xhbmciICIzLjEiCisuU2ggTkFNRQorLk5tIHNjYW4tYnVpbGQKKy5OZCBDbGFuZyBzdGF0aWMgYW5hbHl6ZXIKKy5TaCBTWU5PUFNJUworLk5tCisuT3AgRmwgb2hrdlYKKy5PcCBGbCBhbmFseXplLWhlYWRlcnMKKy5PcCBGbCBlbmFibGUtY2hlY2tlciBPcCBBciBjaGVja2VyX25hbWUKKy5PcCBGbCBkaXNhYmxlLWNoZWNrZXIgT3AgQXIgY2hlY2tlcl9uYW1lCisuT3AgRmwgRmwgaGVscAorLk9wIEZsIEZsIGhlbHAtY2hlY2tlcnMKKy5PcCBGbCBGbCBodG1sLXRpdGxlIE9wIEFyID10aXRsZQorLk9wIEZsIEZsIGtlZXAtZ29pbmcKKy5PcCBGbCBwbGlzdAorLk9wIEZsIHBsaXN0LWh0bWwKKy5PcCBGbCBGbCBzdGF0dXMtYnVncworLk9wIEZsIEZsIHVzZS1jKysgT3AgQXIgPWNvbXBpbGVyX3BhdGgKKy5PcCBGbCBGbCB1c2UtY2MgT3AgQXIgPWNvbXBpbGVyX3BhdGgKKy5PcCBGbCBGbCB2aWV3CisuT3AgRmwgY29uc3RyYWludHMgT3AgQXIgbW9kZWwKKy5PcCBGbCBtYXhsb29wIEFyIE4KKy5PcCBGbCBuby1mYWlsdXJlLXJlcG9ydHMKKy5PcCBGbCBzdGF0cworLk9wIEZsIHN0b3JlIE9wIEFyIG1vZGVsCisuQXIgYnVpbGRfY29tbWFuZAorLk9wIGJ1aWxkX29wdGlvbnMKKy5cIgorLlwiIFNoIERFU0NSSVBUSU9OCisuU2ggREVTQ1JJUFRJT04KKy5ObQoraXMgYSBQZXJsIHNjcmlwdCB0aGF0IGludm9rZXMgdGhlIENsYW5nIHN0YXRpYyBhbmFseXplci4gIE9wdGlvbnMgdXNlZCBieQorLk5tCitvciBieSB0aGUgYW5hbHl6ZXIgYXBwZWFyIGZpcnN0LCBmb2xsb3dlZCBieSB0aGUKKy5BciBidWlsZF9jb21tYW5kCithbmQgYW55CisuQXIgYnVpbGRfb3B0aW9ucworbm9ybWFsbHkgdXNlZCB0byBidWlsZCB0aGUgdGFyZ2V0IHN5c3RlbS4KKy5QcAorVGhlIHN0YXRpYyBhbmFseXplciBlbXBsb3lzIGEgbG9uZyBsaXN0IG9mIGNoZWNraW5nIGFsZ29yaXRobXMsIHNlZQorLlN4IENIRUNLRVJTIC4KK091dHB1dCBjYW4gYmUgd3JpdHRlbiBpbiBzdGFuZGFyZAorLkxpIC5wbGlzdAorYW5kL29yIEhUTUwgZm9ybWF0LgorLlBwCitUaGUgZm9sbG93aW5nIG9wdGlvbnMgYXJlIHN1cHBvcnRlZDoKKy5CbCAtdGFnIC13aWR0aCBpbmRlbnQKKy5JdCBGbCBhbmFseXplLWhlYWRlcnMKK0Fsc28gYW5hbHl6ZSBmdW5jdGlvbnMgaW4gI2luY2x1ZGVkIGZpbGVzLgorLkl0IEZsIGVuYWJsZS1jaGVja2VyIEFyIGNoZWNrZXJfbmFtZSAsIEZsIGRpc2FibGUtY2hlY2tlciBBciBjaGVja2VyX25hbWUKK0VuYWJsZS9kaXNhYmxlCisuQXIgY2hlY2tlcl9uYW1lIC4KK1NlZQorLlN4IENIRUNLRVJTIC4KKy5JdCBGbCBoICwgRmwgRmwgaGVscAorRGlzcGxheSB0aGlzIG1lc3NhZ2UuCisuSXQgRmwgRmwgaGVscC1jaGVja2VycworTGlzdCBkZWZhdWx0IGNoZWNrZXJzLCBzZWUKKy5TeCBDSEVDS0VSUyAuCisuSXQgRmwgRmwgaHRtbC10aXRsZSBOcyBPcCA9IE5zIEFyIHRpdGxlCitTcGVjaWZ5IHRoZSB0aXRsZSB1c2VkIG9uIGdlbmVyYXRlZCBIVE1MIHBhZ2VzLgorQSBkZWZhdWx0IHRpdGxlIGlzIGdlbmVyYXRlZCBpZgorLkFyIHRpdGxlCitpcyBub3Qgc3BlY2lmaWVkLgorLkl0IEZsIGsgLCBGbCBGbCBrZWVwLWdvaW5nCitBZGQgYQorLkRxIGtlZXAgb24gZ29pbmcKK29wdGlvbiB0bworLkFyIGJ1aWxkX2NvbW1hbmQgLgorQ3VycmVudGx5IHN1cHBvcnRzIG1ha2UgYW5kIHhjb2RlYnVpbGQuIFRoaXMgaXMgYSBjb252ZW5pZW5jZSBvcHRpb247CitvbmUgY2FuIHNwZWNpZnkgdGhpcyBiZWhhdmlvciBkaXJlY3RseSB1c2luZyBidWlsZCBvcHRpb25zLgorLkl0IEZsIG8KK1RhcmdldCBkaXJlY3RvcnkgZm9yIEhUTUwgcmVwb3J0IGZpbGVzLiAgU3ViZGlyZWN0b3JpZXMgd2lsbCBiZQorY3JlYXRlZCBhcyBuZWVkZWQgdG8gcmVwcmVzZW50IHNlcGFyYXRlIGludm9jYXRpb25zCitvZiB0aGUgYW5hbHl6ZXIuICBJZiB0aGlzIG9wdGlvbiBpcyBub3Qgc3BlY2lmaWVkLCBhIGRpcmVjdG9yeSBpcworY3JlYXRlZCBpbiAvdG1wIChUTVBESVIgb24gTWFjIE9TIFgpIHRvIHN0b3JlIHRoZSByZXBvcnRzLgorLkl0IEZsIHBsaXN0CitPdXRwdXQgdGhlIHJlc3VsdHMgYXMgYSBzZXQgb2YKKy5MaSAucGxpc3QKK2ZpbGVzLiAoQnkgZGVmYXVsdCB0aGUgb3V0cHV0IG9mCisuTm0KK2lzIGEgc2V0IG9mIEhUTUwgZmlsZXMuKQorLkl0IEZsIHBsaXN0LWh0bWwKK091dHB1dCB0aGUgcmVzdWx0cyBhcyBhIHNldCBvZiBIVE1MIGFuZCAucGxpc3QgZmlsZXMKKy5JdCBGbCBGbCBzdGF0dXMtYnVncworU2V0IGV4aXQgc3RhdHVzIHRvIDEgaWYgaXQgZm91bmQgcG90ZW50aWFsIGJ1Z3MgYW5kIDAgb3RoZXJ3aXNlLiBCeQorZGVmYXVsdCB0aGUgZXhpdCBzdGF0dXMgb2YKKy5ObQoraXMgdGhhdCByZXR1cm5lZCBieQorLkFyIGJ1aWxkX2NvbW1hbmQgLgorLkl0IEZsIEZsIHVzZS1jKysgTnMgT3AgPSBOcyBBciBjb21waWxlcl9wYXRoCitHdWVzcyB0aGUgZGVmYXVsdCBjb21waWxlciBmb3IgeW91ciBDKysgYW5kIE9iamVjdGl2ZS1DKysgY29kZS4gVXNlIHRoaXMKK29wdGlvbiB0byBzcGVjaWZ5IGFuIGFsdGVybmF0ZSBjb21waWxlci4KKy5JdCBGbCBGbCB1c2UtY2MgTnMgT3AgPSBOcyBBciBjb21waWxlcl9wYXRoCitHdWVzcyB0aGUgZGVmYXVsdCBjb21waWxlciBmb3IgeW91ciBDIGFuZCBPYmplY3RpdmUtQyBjb2RlLiBVc2UgdGhpcworb3B0aW9uIHRvIHNwZWNpZnkgYW4gYWx0ZXJuYXRlIGNvbXBpbGVyLgorLkl0IEZsIHYKK1ZlcmJvc2Ugb3V0cHV0IGZyb20KKy5ObQorYW5kIHRoZSBhbmFseXplci4gQSBzZWNvbmQgYW5kCit0aGlyZAorLkFyIHYKK2luY3JlYXNlcyB2ZXJib3NpdHkuCisuSXQgRmwgViAsIEZsIEZsIHZpZXcKK1ZpZXcgYW5hbHlzaXMgcmVzdWx0cyBpbiBhIHdlYiBicm93c2VyIHdoZW4gdGhlIGJ1aWxkIGNvbXBsZXRlcy4KKy5JdCBGbCBjb25zdHJhaW50cyBPcCBBciBtb2RlbAorU3BlY2lmeSB0aGUgY29udHJhaW50IGVuZ2luZSB1c2VkIGJ5IHRoZSBhbmFseXplci4gIEJ5IGRlZmF1bHQgdGhlCisuUWwgcmFuZ2UKK21vZGVsIGlzIHVzZWQuICBTcGVjaWZ5aW5nCisuUWwgYmFzaWMKK3VzZXMgYSBzaW1wbGVyLCBsZXNzIHBvd2VyZnVsIGNvbnN0cmFpbnQgbW9kZWwgdXNlZCBieSBjaGVja2VyLTAuMTYwCithbmQgZWFybGllci4KKy5JdCBGbCBtYXhsb29wIEFyIE4KK1NwZWNpZml5IHRoZSBudW1iZXIgb2YgdGltZXMgYSBibG9jayBjYW4gYmUgdmlzaXRlZCBiZWZvcmUgZ2l2aW5nCit1cC4gRGVmYXVsdCBpcyA0LiBJbmNyZWFzZSBmb3IgbW9yZSBjb21wcmVoZW5zaXZlIGNvdmVyYWdlIGF0IGEKK2Nvc3Qgb2Ygc3BlZWQuCisuSXQgRmwgbm8tZmFpbHVyZS1yZXBvcnRzCitEbyBub3QgY3JlYXRlIGEKKy5RbCBmYWlsdXJlcworc3ViZGlyZWN0b3J5IHRoYXQgaW5jbHVkZXMgYW5hbHl6ZXIgY3Jhc2ggcmVwb3J0cyBhbmQgcHJlcHJvY2Vzc2VkCitzb3VyY2UgZmlsZXMuCisuSXQgRmwgc3RhdHMKK0dlbmVyYXRlcyB2aXNpdGF0aW9uIHN0YXRpc3RpY3MgZm9yIHRoZSBwcm9qZWN0IGJlaW5nIGFuYWx5emVkLgorLkl0IEZsIHN0b3JlIE9wIEFyIG1vZGVsCitTcGVjaWZ5IHRoZSBzdG9yZSBtb2RlbCB1c2VkIGJ5IHRoZSBhbmFseXplci4gQnkgZGVmYXVsdCwgdGhlCisuUWwgcmVnaW9uCitzdG9yZSBtb2RlbCBpcyB1c2VkLgorLlFsIHJlZ2lvbgorc3BlY2lmaWVzIGEgZmllbGQtCitzZW5zaXRpdmUgc3RvcmUgbW9kZWwuIFVzZXJzIGNhbiBhbHNvIHNwZWNpZnkKKy5RbCBiYXNpYword2hpY2ggaXMgZmFyIGxlc3MgcHJlY2lzZSBidXQgY2FuIG1vcmUgcXVpY2tseSBhbmFseXplIGNvZGUuCisuUWwgYmFzaWMKK3dhcyB0aGUgZGVmYXVsdCBzdG9yZSBtb2RlbCBmb3IgY2hlY2tlci0wLjIyMSBhbmQgZWFybGllci4KKy5cIgorLkVsCisuU2ggRVhJVCBTVEFUVVMKKy5ObQorcmV0dXJucyB0aGUgdmFsdWUgcmV0dXJuZWQgYnkKKy5BciBidWlsZF9jb21tYW5kCit1bmxlc3MKKy5GbCBGbCBzdGF0dXMtYnVncworb3IKKy5GbCBGbCBrZWVwLWdvaW5nCitpcyB1c2VkLgorLlwiCisuXCIgT3RoZXIgc2VjdGlvbnMgbm90IHlldCB1c2VkIC4uLgorLlwiIC5TaCBFTlZJUk9OTUVOVAorLlwiIC5TaCBGSUxFUworLlwiIC5TaCBESUFHTk9TVElDUworLlwiIC5TaCBDT01QQVRJQklMSVRZCisuXCIgLlNoIEhJU1RPUlkKKy5cIiAuU2ggQlVHUworLlwiCisuU2ggQ0hFQ0tFUlMKK1RoZSBjaGVja2VycyBsaXN0ZWQgYmVsb3cgbWF5IGJlIGVuYWJsZWQvZGlzYWJsZWQgdXNpbmcgdGhlCisuRmwgZW5hYmxlLWNoZWNrZXIKK2FuZAorLkZsIGRpc2FibGUtY2hlY2tlcgorb3B0aW9ucy4KK0EgZGVmYXVsdCBncm91cCBvZiBjaGVja2VycyBpcyBydW4gdW5sZXNzIGV4cGxpY2l0bHkgZGlzYWJsZWQuCitFeGFjdGx5IHdoaWNoIGNoZWNrZXJzIGNvbnN0aXR1dGUgdGhlIGRlZmF1bHQgZ3JvdXAgaXMgYSBmdW5jdGlvbgorb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0gaW4gdXNlOyB0aGV5IGFyZSBsaXN0ZWQgd2l0aAorLkZsIEZsIGhlbHAtY2hlY2tlcnMgLgorLkJsIC10YWcgLXdpZHRoIGluZGVudC4KKy5JdCBjb3JlLkFkanVzdGVkUmV0dXJuVmFsdWUKK0NoZWNrIHRvIHNlZSBpZiB0aGUgcmV0dXJuIHZhbHVlIG9mIGEgZnVuY3Rpb24gY2FsbCBpcyBkaWZmZXJlbnQgdGhhbgordGhlIGNhbGxlciBleHBlY3RzIChlLmcuLCBmcm9tIGNhbGxzIHRocm91Z2ggZnVuY3Rpb24gcG9pbnRlcnMpLgorLkl0IGNvcmUuQXR0cmlidXRlTm9uTnVsbAorQ2hlY2sgZm9yIG51bGwgcG9pbnRlcnMgcGFzc2VkIGFzIGFyZ3VtZW50cyB0byBhIGZ1bmN0aW9uIHdob3NlIGFyZ3VtZW50cyBhcmUgbWFya2VkIHdpdGggdGhlCisuUWwgbm9ubnVsbAorYXR0cmlidXRlLgorLkl0IGNvcmUuQ2FsbEFuZE1lc3NhZ2UKK0NoZWNrIGZvciBsb2dpY2FsIGVycm9ycyBmb3IgZnVuY3Rpb24gY2FsbHMgYW5kIE9iamVjdGl2ZS1DIG1lc3NhZ2UgZXhwcmVzc2lvbnMgKGUuZy4sIHVuaW5pdGlhbGl6ZWQgYXJndW1lbnRzLCBudWxsIGZ1bmN0aW9uIHBvaW50ZXJzKS4KKy5JdCBjb3JlLkRpdmlkZVplcm8KK0NoZWNrIGZvciBkaXZpc2lvbiBieSB6ZXJvLgorLkl0IGNvcmUuTnVsbERlcmVmZXJlbmNlCitDaGVjayBmb3IgZGVyZWZlcmVuY2VzIG9mIG51bGwgcG9pbnRlcnMuCisuSXQgY29yZS5TdGFja0FkZHJlc3NFc2NhcGUKK0NoZWNrIHRoYXQgYWRkcmVzc2VzIHRvIHN0YWNrIG1lbW9yeSBkbyBub3QgZXNjYXBlIHRoZSBmdW5jdGlvbi4KKy5JdCBjb3JlLlVuZGVmaW5lZEJpbmFyeU9wZXJhdG9yUmVzdWx0CitDaGVjayBmb3IgdW5kZWZpbmVkIHJlc3VsdHMgb2YgYmluYXJ5IG9wZXJhdG9ycy4KKy5JdCBjb3JlLlZMQVNpemUKK0NoZWNrIGZvciBkZWNsYXJhdGlvbnMgb2YgVkxBIG9mIHVuZGVmaW5lZCBvciB6ZXJvIHNpemUuCisuSXQgY29yZS5idWlsdGluLkJ1aWx0aW5GdW5jdGlvbnMKK0V2YWx1YXRlIGNvbXBpbGVyIGJ1aWx0aW4gZnVuY3Rpb25zLCBlLmcuCisuRm4gYWxsb2NhIC4KKy5JdCBjb3JlLmJ1aWx0aW4uTm9SZXR1cm5GdW5jdGlvbnMKK0V2YWx1YXRlCisuUWwgcGFuaWMKK2Z1bmN0aW9ucyB0aGF0IGFyZSBrbm93biB0byBub3QgcmV0dXJuIHRvIHRoZSBjYWxsZXIuCisuSXQgY29yZS51bmluaXRpYWxpemVkLkFycmF5U3Vic2NyaXB0CitDaGVjayBmb3IgdW5pbml0aWFsaXplZCB2YWx1ZXMgdXNlZCBhcyBhcnJheSBzdWJzY3JpcHRzLgorLkl0IGNvcmUudW5pbml0aWFsaXplZC5Bc3NpZ24KK0NoZWNrIGZvciBhc3NpZ25pbmcgdW5pbml0aWFsaXplZCB2YWx1ZXMuCisuSXQgY29yZS51bmluaXRpYWxpemVkLkJyYW5jaAorQ2hlY2sgZm9yIHVuaW5pdGlhbGl6ZWQgdmFsdWVzIHVzZWQgYXMgYnJhbmNoIGNvbmRpdGlvbnMuCisuSXQgY29yZS51bmluaXRpYWxpemVkLkNhcHR1cmVkQmxvY2tWYXJpYWJsZQorQ2hlY2sgZm9yIGJsb2NrcyB0aGF0IGNhcHR1cmUgdW5pbml0aWFsaXplZCB2YWx1ZXMuCisuSXQgY29yZS51bmluaXRpYWxpemVkLlVuZGVmUmV0dXJuCitDaGVjayBmb3IgdW5pbml0aWFsaXplZCB2YWx1ZXMgYmVpbmcgcmV0dXJuZWQgdG8gdGhlIGNhbGxlci4KKy5JdCBkZWFkY29kZS5EZWFkU3RvcmVzCitDaGVjayBmb3IgdmFsdWVzIHN0b3JlZCB0byB2YXJpYWJsZXMgdGhhdCBhcmUgbmV2ZXIgcmVhZCBhZnRlcndhcmRzLgorLkl0IGRlYnVnLkR1bXBDRkcKK0Rpc3BsYXkgQ29udHJvbC1GbG93IEdyYXBocy4KKy5JdCBkZWJ1Zy5EdW1wQ2FsbEdyYXBoCitEaXNwbGF5IENhbGwgR3JhcGguCisuSXQgZGVidWcuRHVtcERvbWluYXRvcnMKK1ByaW50IHRoZSBkb21pbmFuY2UgdHJlZSBmb3IgYSBnaXZlbiBDb250cm9sLUZsb3cgR3JhcGguCisuSXQgZGVidWcuRHVtcExpdmVWYXJzCitQcmludCByZXN1bHRzIG9mIGxpdmUgdmFyaWFibGUgYW5hbHlzaXMuCisuSXQgZGVidWcuU3RhdHMKK0VtaXQgd2FybmluZ3Mgd2l0aCBhbmFseXplciBzdGF0aXN0aWNzLgorLkl0IGRlYnVnLlRhaW50VGVzdAorTWFyayB0YWludGVkIHN5bWJvbHMgYXMgc3VjaC4KKy5JdCBkZWJ1Zy5WaWV3Q0ZHCitWaWV3IENvbnRyb2wtRmxvdyBHcmFwaHMgdXNpbmcKKy5JYyBHcmFwaFZpeiAuCisuSXQgZGVidWcuVmlld0NhbGxHcmFwaAorVmlldyBDYWxsIEdyYXBoIHVzaW5nCisuSWMgR3JhcGhWaXogLgorLkl0IGxsdm0uQ29udmVudGlvbnMKK0NoZWNrIGNvZGUgZm9yIExMVk0gY29kZWJhc2UgY29udmVudGlvbnMuCisuSXQgb3N4LkFQSQorQ2hlY2sgZm9yIHByb3BlciB1c2VzIG9mIHZhcmlvdXMgTWFjIE9TIFggQVBJcy4KKy5JdCBvc3guQXRvbWljQ0FTCitFdmFsdWF0ZSBjYWxscyB0bworLlZ0IE9TQXRvbWljCitmdW5jdGlvbnMuCisuSXQgb3N4LlNlY0tleWNoYWluQVBJCitDaGVjayBmb3IgcHJvcGVyIHVzZXMgb2YgU2VjdXJlIEtleWNoYWluIEFQSXMuCisuSXQgb3N4LmNvY29hLkF0U3luYworQ2hlY2sgZm9yIG51bGwgcG9pbnRlcnMgdXNlZCBhcyBtdXRleGVzIGZvciBAc3luY2hyb25pemVkLgorLkl0IG9zeC5jb2NvYS5DbGFzc1JlbGVhc2UKK0NoZWNrIGZvciBzZW5kaW5nCisuUWwgcmV0YWluICwKKy5RbCByZWxlYXNlLAorb3IKKy5RbCBhdXRvcmVsZWFzZQorZGlyZWN0bHkgdG8gYSBDbGFzcy4KKy5JdCBvc3guY29jb2EuSW5jb21wYXRpYmxlTWV0aG9kVHlwZXMKK1dhcm4gYWJvdXQgT2JqZWN0aXZlLUMgbWV0aG9kIHNpZ25hdHVyZXMgd2l0aCB0eXBlIGluY29tcGF0aWJpbGl0aWVzLgorLkl0IG9zeC5jb2NvYS5OU0F1dG9yZWxlYXNlUG9vbAorV2FybiBmb3Igc3Vib3B0aW1hbCB1c2VzIG9mCisuVnQgTlNBdXRvcmVsZWFzZVBvb2wKK2luIE9iamVjdGl2ZS1DIEdDIG1vZGUuCisuSXQgb3N4LmNvY29hLk5TRXJyb3IKK0NoZWNrIHVzYWdlIG9mIE5TRXJyb3IqKiBwYXJhbWV0ZXJzLgorLkl0IG9zeC5jb2NvYS5OaWxBcmcKK0NoZWNrIGZvciBwcm9oaWJpdGVkIG5pbCBhcmd1bWVudHMgdG8gT2JqZWN0aXZlLUMgbWV0aG9kIGNhbGxzLgorLkl0IG9zeC5jb2NvYS5SZXRhaW5Db3VudAorQ2hlY2sgZm9yIGxlYWtzIGFuZCBpbXByb3BlciByZWZlcmVuY2UgY291bnQgbWFuYWdlbWVudC4KKy5JdCBvc3guY29jb2EuU2VsZkluaXQKK0NoZWNrIHRoYXQKKy5RbCBzZWxmCitpcyBwcm9wZXJseSBpbml0aWFsaXplZCBpbnNpZGUgYW4gaW5pdGlhbGl6ZXIgbWV0aG9kLgorLkl0IG9zeC5jb2NvYS5VbnVzZWRJdmFycworV2FybiBhYm91dCBwcml2YXRlIGl2YXJzIHRoYXQgYXJlIG5ldmVyIHVzZWQuCisuSXQgb3N4LmNvY29hLlZhcmlhZGljTWV0aG9kVHlwZXMKK0NoZWNrIGZvciBwYXNzaW5nIG5vbi1PYmplY3RpdmUtQyB0eXBlcyB0byB2YXJpYWRpYyBtZXRob2RzIHRoYXQgZXhwZWN0IG9ubHkgT2JqZWN0aXZlLUMgdHlwZXMuCisuSXQgb3N4LmNvcmVGb3VuZGF0aW9uLkNGRXJyb3IKK0NoZWNrIHVzYWdlIG9mIENGRXJyb3JSZWYqIHBhcmFtZXRlcnMuCisuSXQgb3N4LmNvcmVGb3VuZGF0aW9uLkNGTnVtYmVyCitDaGVjayBmb3IgcHJvcGVyIHVzZXMgb2YKKy5GbiBDRk51bWJlckNyZWF0ZSAuCisuSXQgb3N4LmNvcmVGb3VuZGF0aW9uLkNGUmV0YWluUmVsZWFzZQorQ2hlY2sgZm9yIG51bGwgYXJndW1lbnRzIHRvCisuRm4gQ0ZSZXRhaW4gLAorLkZuIENGUmVsZWFzZSAsCithbmQKKy5GbiBDRk1ha2VDb2xsZWN0YWJsZSAuCisuSXQgb3N4LmNvcmVGb3VuZGF0aW9uLmNvbnRhaW5lcnMuT3V0T2ZCb3VuZHMKK0NoZWNrcyBmb3IgaW5kZXggb3V0LW9mLWJvdW5kcyB3aGVuIHVzaW5nIHRoZQorLlZ0IENGQXJyYXkKK0FQSS4KKy5JdCBvc3guY29yZUZvdW5kYXRpb24uY29udGFpbmVycy5Qb2ludGVyU2l6ZWRWYWx1ZXMKK1dhcm5zIGlmCisuVnQgQ0ZBcnJheSAsCisuVnQgQ0ZEaWN0aW9uYXJ5ICwKK29yCisuVnQgQ0ZTZXQKK2FyZSBjcmVhdGVkIHdpdGggbm9uLXBvaW50ZXItc2l6ZSB2YWx1ZXMuCisuSXQgc2VjdXJpdHkuRmxvYXRMb29wQ291bnRlcgorV2FybiBvbiB1c2luZyBhIGZsb2F0aW5nIHBvaW50IHZhbHVlIGFzIGEgbG9vcCBjb3VudGVyIChDRVJUOiBGTFAzMC1DLCBGTFAzMC1DUFApLgorLkl0IHNlY3VyaXR5Lmluc2VjdXJlQVBJLlVuY2hlY2tlZFJldHVybgorV2FybiBvbiB1c2VzIG9mIGZ1bmN0aW9ucyB3aG9zZSByZXR1cm4gdmFsdWVzIG11c3QgYmUgYWx3YXlzIGNoZWNrZWQuCisuSXQgc2VjdXJpdHkuaW5zZWN1cmVBUEkuZ2V0cHcKK1dhcm4gb24gdXNlcyBvZgorLkZuIGdldHB3IC4KKy5JdCBzZWN1cml0eS5pbnNlY3VyZUFQSS5nZXRzCitXYXJuIG9uIHVzZXMgb2YKKy5GbiBnZXRzIC4KKy5JdCBzZWN1cml0eS5pbnNlY3VyZUFQSS5ta3N0ZW1wCitXYXJuIHdoZW4KKy5GbiBta3N0ZW1wCitpcyBwYXNzZWQgZmV3ZXIgdGhhbiA2IFgncyBpbiB0aGUgZm9ybWF0IHN0cmluZy4KKy5JdCBzZWN1cml0eS5pbnNlY3VyZUFQSS5ta3RlbXAKK1dhcm4gb24gdXNlcyBvZgorLkZuIG1rdGVtcCAuCisuSXQgc2VjdXJpdHkuaW5zZWN1cmVBUEkucmFuZAorV2FybiBvbiB1c2VzIG9mCisuRm4gcmFuZCAsCisuRm4gcmFuZG9tICwKK2FuZCByZWxhdGVkIGZ1bmN0aW9ucy4KKy5JdCBzZWN1cml0eS5pbnNlY3VyZUFQSS5zdHJjcHkKK1dhcm4gb24gdXNlcyBvZgorLkZuIHN0cmNweQorYW5kCisuRm4gc3RyY2F0IC4KKy5JdCBzZWN1cml0eS5pbnNlY3VyZUFQSS52Zm9yaworV2FybiBvbiB1c2VzIG9mCisuRm4gdmZvcmsgLgorLkl0IHVuaXguQVBJCitDaGVjayBjYWxscyB0byB2YXJpb3VzIFVOSVgvUG9zaXggZnVuY3Rpb25zLgorLkl0IHVuaXguTWFsbG9jCitDaGVjayBmb3IgbWVtb3J5IGxlYWtzLCBkb3VibGUgZnJlZSwgYW5kIHVzZS1hZnRlci1mcmVlLgorLkl0IHVuaXguY3N0cmluZy5CYWRTaXplQXJnCitDaGVjayB0aGUgc2l6ZSBhcmd1bWVudCBwYXNzZWQgaW50byBDIHN0cmluZyBmdW5jdGlvbnMgZm9yIGNvbW1vbgorZXJyb25lb3VzIHBhdHRlcm5zLgorLkl0IHVuaXguY3N0cmluZy5OdWxsQXJnCitDaGVjayBmb3IgbnVsbCBwb2ludGVycyBiZWluZyBwYXNzZWQgYXMgYXJndW1lbnRzIHRvIEMgc3RyaW5nIGZ1bmN0aW9ucy4KKy5FbAorLlwiCisuU2ggRVhBTVBMRQorLkljIHNjYW4tYnVpbGQgLW8gL3RtcC9teWh0bWxkaXIgbWFrZSAtajQKKy5QcAorVGhlIGFib3ZlIGV4YW1wbGUgY2F1c2VzIGFuYWx5c2lzIHJlcG9ydHMgdG8gYmUgZGVwb3NpdGVkIGludG8KK2Egc3ViZGlyZWN0b3J5IG9mCisuUGEgL3RtcC9teWh0bWxkaXIKK2FuZCB0byBydW4KKy5JYyBtYWtlCit3aXRoIHRoZQorLkZsIGo0CitvcHRpb24uCitBIGRpZmZlcmVudCBzdWJkaXJlY3RvcnkgaXMgY3JlYXRlZCBlYWNoIHRpbWUKKy5ObQorYW5hbHl6ZXMgYSBwcm9qZWN0LgorVGhlIGFuYWx5emVyIHNob3VsZCBzdXBwb3J0IG1vc3QgcGFyYWxsZWwgYnVpbGRzLCBidXQgbm90IGRpc3RyaWJ1dGVkIGJ1aWxkcy4KKy5TaCBBVVRIT1JTCisuTm0KK3dhcyB3cml0dGVuIGJ5CisuQW4gIlRlZCBLcmVtZW5layIgLgorRG9jdW1lbnRhdGlvbiBjb250cmlidXRlZCBieQorLkFuICJKYW1lcyBLLiBMb3dkZW4iIEFxIGprbG93ZGVuQHNjaGVtYW1hbmlhLm9yZyAuCmRpZmYgLS1naXQgYS90b29scy9zY2FuLWJ1aWxkL3NjYW4tYnVpbGQuYmF0IGIvdG9vbHMvc2Nhbi1idWlsZC9zY2FuLWJ1aWxkLmJhdApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43N2JlNjc0Ci0tLSAvZGV2L251bGwKKysrIGIvdG9vbHMvc2Nhbi1idWlsZC9zY2FuLWJ1aWxkLmJhdApAQCAtMCwwICsxIEBACitwZXJsIC1TIHNjYW4tYnVpbGQgJSoNCmRpZmYgLS1naXQgYS90b29scy9zY2FuLWJ1aWxkL3NjYW52aWV3LmNzcyBiL3Rvb2xzL3NjYW4tYnVpbGQvc2NhbnZpZXcuY3NzCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEwNDA2ZjMKLS0tIC9kZXYvbnVsbAorKysgYi90b29scy9zY2FuLWJ1aWxkL3NjYW52aWV3LmNzcwpAQCAtMCwwICsxLDYyIEBACitib2R5IHsgY29sb3I6IzAwMDAwMDsgYmFja2dyb3VuZC1jb2xvcjojZmZmZmZmIH0KK2JvZHkgeyBmb250LWZhbWlseTogSGVsdmV0aWNhLCBzYW5zLXNlcmlmOyBmb250LXNpemU6OXB0IH0KK2gxIHsgZm9udC1zaXplOiAxNHB0OyB9CitoMiB7IGZvbnQtc2l6ZTogMTJwdDsgfQordGFibGUgeyBmb250LXNpemU6OXB0IH0KK3RhYmxlIHsgYm9yZGVyLXNwYWNpbmc6IDBweDsgYm9yZGVyOiAxcHggc29saWQgYmxhY2sgfQordGgsIHRhYmxlIHRoZWFkIHsKKyAgYmFja2dyb3VuZC1jb2xvcjojZWVlOyBjb2xvcjojNjY2NjY2OworICBmb250LXdlaWdodDogYm9sZDsgY3Vyc29yOiBkZWZhdWx0OworICB0ZXh0LWFsaWduOmNlbnRlcjsKKyAgZm9udC13ZWlnaHQ6IGJvbGQ7IGZvbnQtZmFtaWx5OiBWZXJkYW5hOworICB3aGl0ZS1zcGFjZTpub3dyYXA7Cit9IAorLlcgeyBmb250LXNpemU6MHB4IH0KK3RoLCB0ZCB7IHBhZGRpbmc6NXB4OyBwYWRkaW5nLWxlZnQ6OHB4OyB0ZXh0LWFsaWduOmxlZnQgfQordGQuU1VNTV9ERVNDIHsgcGFkZGluZy1sZWZ0OjEycHggfQordGQuREVTQyB7IHdoaXRlLXNwYWNlOnByZSB9Cit0ZC5RIHsgdGV4dC1hbGlnbjpyaWdodCB9Cit0ZCB7IHRleHQtYWxpZ246bGVmdCB9Cit0Ym9keS5zY3JvbGxDb250ZW50IHsgb3ZlcmZsb3c6YXV0byB9CisKK3RhYmxlLmZvcm1fZ3JvdXAgeworICAgIGJhY2tncm91bmQtY29sb3I6ICNjY2M7CisgICAgYm9yZGVyOiAxcHggc29saWQgIzMzMzsgCisgICAgcGFkZGluZzogMnB4OworfQorCit0YWJsZS5mb3JtX2lubmVyX2dyb3VwIHsKKyAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjY2NjOworICAgIGJvcmRlcjogMXB4IHNvbGlkICMzMzM7CisgICAgcGFkZGluZzogMHB4OworfQorCit0YWJsZS5mb3JtIHsKKyAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjOTk5OworICAgIGJvcmRlcjogMXB4IHNvbGlkICMzMzM7IAorICAgIHBhZGRpbmc6IDJweDsKK30KKwordGQuZm9ybV9sYWJlbCB7CisgICAgdGV4dC1hbGlnbjogcmlnaHQ7CisgICAgdmVydGljYWwtYWxpZ246IHRvcDsKK30KKy8qIEZvciBvbmUgbGluZSBlbnRpcmVzICovCit0ZC5mb3JtX2NsYWJlbCB7CisgICAgdGV4dC1hbGlnbjogcmlnaHQ7CisgICAgdmVydGljYWwtYWxpZ246IGNlbnRlcjsKK30KK3RkLmZvcm1fdmFsdWUgeworICAgIHRleHQtYWxpZ246IGxlZnQ7CisgICAgdmVydGljYWwtYWxpZ246IHRvcDsKK30KK3RkLmZvcm1fc3VibWl0IHsKKyAgICB0ZXh0LWFsaWduOiByaWdodDsKKyAgICB2ZXJ0aWNhbC1hbGlnbjogdG9wOworfQorCitoMS5TdWJtaXRGYWlsIHsKKyAgICBjb2xvcjogI2YwMDsKK30KK2gxLlN1Ym1pdE9rIHsKK30KZGlmZiAtLWdpdCBhL3Rvb2xzL3NjYW4tYnVpbGQvc2V0LXhjb2RlLWFuYWx5emVyIGIvdG9vbHMvc2Nhbi1idWlsZC9zZXQteGNvZGUtYW5hbHl6ZXIKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uMzA3NmIzOQotLS0gL2Rldi9udWxsCisrKyBiL3Rvb2xzL3NjYW4tYnVpbGQvc2V0LXhjb2RlLWFuYWx5emVyCkBAIC0wLDAgKzEsMTE1IEBACisjIS91c3IvYmluL3B5dGhvbgorCisjIFtQUiAxMTY2MV0gTm90ZSB0aGF0IHdlIGhhcmR3aXJlIHRvIC91c3IvYmluL3B5dGhvbiBiZWNhdXNlIHdlCisjIHdhbnQgdG8gdGhlIHVzZSB0aGUgc3lzdGVtIHZlcnNpb24gb2YgUHl0aG9uIG9uIE1hYyBPUyBYLgorIyBUaGlzIG9uZSBoYXMgdGhlIHNjcmlwdGluZyBicmlkZ2UgZW5hYmxlZC4KKworaW1wb3J0IHN5cworaWYgc3lzLnZlcnNpb25faW5mbyA8ICgyLCA3KToKKyAgICBwcmludCAic2V0LXhjb2RlLWFuYWx5emVyIHJlcXVpcmVzIFB5dGhvbiAyLjcgb3IgbGF0ZXIiCisgICAgc3lzLmV4aXQoMSkKKyAgICAKK2ltcG9ydCBvcworaW1wb3J0IHN1YnByb2Nlc3MKK2ltcG9ydCByZQoraW1wb3J0IHRlbXBmaWxlCitpbXBvcnQgc2h1dGlsCitpbXBvcnQgc3RhdAorZnJvbSBBcHBLaXQgaW1wb3J0ICoKKworZGVmIEZpbmRDbGFuZ1NwZWNzKHBhdGgpOgorICBwcmludCAiKCspIFNlYXJjaGluZyBmb3IgeGNzcGVjIGZpbGUgaW46ICIsIHBhdGgKKyAgZm9yIHJvb3QsIGRpcnMsIGZpbGVzIGluIG9zLndhbGsocGF0aCk6CisgICAgZm9yIGYgaW4gZmlsZXM6CisgICAgICBpZiBmLmVuZHN3aXRoKCIueGNzcGVjIikgYW5kIGYuc3RhcnRzd2l0aCgiQ2xhbmcgTExWTSIpOgorICAgICAgICB5aWVsZCBvcy5wYXRoLmpvaW4ocm9vdCwgZikKKworZGVmIE1vZGlmeVNwZWMocGF0aCwgaXNCdWlsdGluQW5hbHl6ZXIsIHBhdGhUb0NoZWNrZXIpOgorICB0ID0gdGVtcGZpbGUuTmFtZWRUZW1wb3JhcnlGaWxlKGRlbGV0ZT1GYWxzZSkKKyAgZm91bmRBbmFseXplciA9IEZhbHNlCisgIHdpdGggb3BlbihwYXRoKSBhcyBmOgorICAgIGlmIGlzQnVpbHRpbkFuYWx5emVyOgorICAgICAgIyBGaXJzdCBzZWFyY2ggZm9yIENMQU5HX0FOQUxZWkVSX0VYRUMuICBOZXdlcgorICAgICAgIyB2ZXJzaW9ucyBvZiBYY29kZSBzZXQgRVhFQ19QQVRIIHRvIGJlIENMQU5HX0FOQUxZWkVSX0VYRUMuCisgICAgICB3aXRoIG9wZW4ocGF0aCkgYXMgZjI6CisgICAgICAgIGZvciBsaW5lIGluIGYyOgorICAgICAgICAgIGlmIGxpbmUuZmluZCgiQ0xBTkdfQU5BTFlaRVJfRVhFQyIpID49IDA6CisgICAgICAgICAgICBwYXRoVG9DaGVja2VyID0gIiQoQ0xBTkdfQU5BTFlaRVJfRVhFQykiCisgICAgICAgICAgICBicmVhaworICAgICMgTm93IGNyZWF0ZSBhIG5ldyBmaWxlLgorICAgIGZvciBsaW5lIGluIGY6CisgICAgICBpZiBub3QgZm91bmRBbmFseXplcjoKKyAgICAgICAgaWYgbGluZS5maW5kKCJTdGF0aWMgQW5hbHl6ZXIiKSA+PSAwOgorICAgICAgICAgIGZvdW5kQW5hbHl6ZXIgPSBUcnVlCisgICAgICBlbHNlOgorICAgICAgICBtID0gcmUuc2VhcmNoKCdeKFxzKkV4ZWNQYXRoXHMqPVxzKiIpJywgbGluZSkKKyAgICAgICAgaWYgbToKKyAgICAgICAgICBsaW5lID0gIiIuam9pbihbbS5ncm91cCgwKSwgcGF0aFRvQ2hlY2tlciwgJyI7XG4nXSkKKyAgICAgICAgICAjIERvIG5vdCBtb2RpZnkgZnVydGhlciBFeGVjUGF0aCdzIGxhdGVyIGluIHRoZSB4Y3NwZWMuCisgICAgICAgICAgZm91bmRBbmFseXplciA9IEZhbHNlCisgICAgICB0LndyaXRlKGxpbmUpCisgIHQuY2xvc2UoKQorICBwcmludCAiKCspIHByb2Nlc3Npbmc6IiwgcGF0aAorICB0cnk6CisgICAgc2h1dGlsLmNvcHkodC5uYW1lLCBwYXRoKQorICAgIG9zLmNobW9kKHBhdGgsIHN0YXQuU19JUlVTUiB8IHN0YXQuU19JV1VTUiB8IHN0YXQuU19JUkdSUCB8IHN0YXQuU19JUk9USCkKKyAgZXhjZXB0IElPRXJyb3IsIHdoeToKKyAgICBwcmludCAiICAgICgtKSBDYW5ub3QgdXBkYXRlIGZpbGU6Iiwgd2h5LCAiXG4iCisgIGV4Y2VwdCBPU0Vycm9yLCB3aHk6CisgICAgcHJpbnQgIiAgICAoLSkgQ2Fubm90IHVwZGF0ZSBmaWxlOiIsIHdoeSwgIlxuIgorICBvcy51bmxpbmsodC5uYW1lKQorCitkZWYgbWFpbigpOgorICBmcm9tIG9wdHBhcnNlIGltcG9ydCBPcHRpb25QYXJzZXIKKyAgcGFyc2VyID0gT3B0aW9uUGFyc2VyKCd1c2FnZTogJXByb2cgW29wdGlvbnNdJykKKyAgcGFyc2VyLnNldF9kZXNjcmlwdGlvbihfX2RvY19fKQorICBwYXJzZXIuYWRkX29wdGlvbigiLS11c2UtY2hlY2tlci1idWlsZCIsIGRlc3Q9InBhdGgiLAorICAgICAgICAgICAgICAgICAgICBoZWxwPSJVc2UgdGhlIENsYW5nIGxvY2F0ZWQgYXQgdGhlIHByb3ZpZGVkIGFic29sdXRlIHBhdGgsIGUuZy4gL1VzZXJzL2Zvby9jaGVja2VyLTEiKQorICBwYXJzZXIuYWRkX29wdGlvbigiLS11c2UteGNvZGUtY2xhbmciLCBhY3Rpb249InN0b3JlX2NvbnN0IiwgCisgICAgICAgICAgICAgICAgICAgIGNvbnN0PSIkKENMQU5HKSIsIGRlc3Q9ImRlZmF1bHQiLAorICAgICAgICAgICAgICAgICAgICBoZWxwPSJVc2UgdGhlIENsYW5nIGJ1bmRsZWQgd2l0aCBYY29kZSIpCisgIChvcHRpb25zLCBhcmdzKSA9IHBhcnNlci5wYXJzZV9hcmdzKCkKKyAgaWYgb3B0aW9ucy5wYXRoIGlzIE5vbmUgYW5kIG9wdGlvbnMuZGVmYXVsdCBpcyBOb25lOgorICAgIHBhcnNlci5lcnJvcigiWW91IG11c3Qgc3BlY2lmeSBhIHZlcnNpb24gb2YgQ2xhbmcgdG8gdXNlIGZvciBzdGF0aWMgYW5hbHlzaXMuICBTcGVjaWZ5ICctaCcgZm9yIGRldGFpbHMiKQorCisgICMgZGV0ZXJtaW5lIGlmIFhjb2RlIGlzIHJ1bm5pbmcKKyAgZm9yIHggaW4gTlNXb3Jrc3BhY2Uuc2hhcmVkV29ya3NwYWNlKCkucnVubmluZ0FwcGxpY2F0aW9ucygpOgorICAgIGlmIHgubG9jYWxpemVkTmFtZSgpLmZpbmQoIlhjb2RlIikgPj0gMDoKKyAgICAgIHByaW50ICIoLSkgWW91IG11c3QgcXVpdCBYY29kZSBmaXJzdCBiZWZvcmUgbW9kaWZ5aW5nIGl0cyBjb25maWd1cmF0aW9uIGZpbGVzLiIKKyAgICAgIHN5cy5leGl0KDEpCisKKyAgaXNCdWlsdGluQW5hbHl6ZXIgPSBGYWxzZQorICBpZiBvcHRpb25zLnBhdGg6CisgICAgIyBFeHBhbmQgdGlsZGVzLgorICAgIHBhdGggPSBvcy5wYXRoLmV4cGFuZHVzZXIob3B0aW9ucy5wYXRoKQorICAgIGlmIG5vdCBwYXRoLmVuZHN3aXRoKCJjbGFuZyIpOgorICAgICAgcHJpbnQgIigrKSBVc2luZyBDbGFuZyBidW5kbGVkIHdpdGggY2hlY2tlciBidWlsZDoiLCBwYXRoCisgICAgICBwYXRoID0gb3MucGF0aC5qb2luKHBhdGgsICJiaW4iLCAiY2xhbmciKTsKKyAgICBlbHNlOgorICAgICAgcHJpbnQgIigrKSBVc2luZyBDbGFuZyBsb2NhdGVkIGF0OiIsIHBhdGgKKyAgZWxzZToKKyAgICBwcmludCAiKCspIFVzaW5nIHRoZSBDbGFuZyBidW5kbGVkIHdpdGggWGNvZGUiCisgICAgcGF0aCA9IG9wdGlvbnMuZGVmYXVsdAorICAgIGlzQnVpbHRpbkFuYWx5emVyID0gVHJ1ZQorICAKKyAgdHJ5OgorICAgIHhjb2RlX3BhdGggPSBzdWJwcm9jZXNzLmNoZWNrX291dHB1dChbInhjb2RlLXNlbGVjdCIsICItcHJpbnQtcGF0aCJdKQorICBleGNlcHQgQXR0cmlidXRlRXJyb3I6CisgICAgIyBGYWxsIGJhY2sgdG8gdGhlIGRlZmF1bHQgaW5zdGFsbCBsb2NhdGlvbiB3aGVuIHVzaW5nIFB5dGhvbiA8IDIuNy4wCisgICAgeGNvZGVfcGF0aCA9ICIvRGV2ZWxvcGVyIgorICBpZiAoeGNvZGVfcGF0aC5maW5kKCIuYXBwLyIpICE9IC0xKToKKyAgICAjIEN1dCBvZmYgdGhlICdEZXZlbG9wZXInIGRpciwgYXMgdGhlIHhjc3BlYyBsaWVzIGluIGFub3RoZXIgcGFydAorICAgICMgb2YgdGhlIFhjb2RlLmFwcCBzdWJ0cmVlLgorICAgIHhjb2RlX3BhdGggPSBvcy5wYXRoLmRpcm5hbWUoeGNvZGVfcGF0aCkKKyAgCisgIGZvdW5kU3BlYyA9IEZhbHNlCisgIGZvciB4IGluIEZpbmRDbGFuZ1NwZWNzKHhjb2RlX3BhdGgpOgorICAgIGZvdW5kU3BlYyA9IFRydWUKKyAgICBNb2RpZnlTcGVjKHgsIGlzQnVpbHRpbkFuYWx5emVyLCBwYXRoKQorICAgIAorICBpZiBmb3VuZFNwZWMgPT0gRmFsc2U6CisgICAgICBwcmludCAiKC0pIE5vIGNvbXBpbGVyIGNvbmZpZ3VyYXRpb24gZmlsZSB3YXMgZm91bmQuICBYY29kZSdzIGFuYWx5emVyIGhhcyBub3QgYmVlbiB1cGRhdGVkLiIKKworaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzoKKyAgbWFpbigpCisKZGlmZiAtLWdpdCBhL3Rvb2xzL3NjYW4tYnVpbGQvc29ydHRhYmxlLmpzIGIvdG9vbHMvc2Nhbi1idWlsZC9zb3J0dGFibGUuanMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDM1MmQzYgotLS0gL2Rldi9udWxsCisrKyBiL3Rvb2xzL3NjYW4tYnVpbGQvc29ydHRhYmxlLmpzCkBAIC0wLDAgKzEsNDkzIEBACisvKgorICBTb3J0VGFibGUKKyAgdmVyc2lvbiAyCisgIDd0aCBBcHJpbCAyMDA3CisgIFN0dWFydCBMYW5ncmlkZ2UsIGh0dHA6Ly93d3cua3J5b2dlbml4Lm9yZy9jb2RlL2Jyb3dzZXIvc29ydHRhYmxlLworICAKKyAgSW5zdHJ1Y3Rpb25zOgorICBEb3dubG9hZCB0aGlzIGZpbGUKKyAgQWRkIDxzY3JpcHQgc3JjPSJzb3J0dGFibGUuanMiPjwvc2NyaXB0PiB0byB5b3VyIEhUTUwKKyAgQWRkIGNsYXNzPSJzb3J0YWJsZSIgdG8gYW55IHRhYmxlIHlvdSdkIGxpa2UgdG8gbWFrZSBzb3J0YWJsZQorICBDbGljayBvbiB0aGUgaGVhZGVycyB0byBzb3J0CisgIAorICBUaGFua3MgdG8gbWFueSwgbWFueSBwZW9wbGUgZm9yIGNvbnRyaWJ1dGlvbnMgYW5kIHN1Z2dlc3Rpb25zLgorICBMaWNlbmNlZCBhcyBYMTE6IGh0dHA6Ly93d3cua3J5b2dlbml4Lm9yZy9jb2RlL2Jyb3dzZXIvbGljZW5jZS5odG1sCisgIFRoaXMgYmFzaWNhbGx5IG1lYW5zOiBkbyB3aGF0IHlvdSB3YW50IHdpdGggaXQuCisqLworCisgCit2YXIgc3RJc0lFID0gLypAY2Nfb24hQCovZmFsc2U7CisKK3NvcnR0YWJsZSA9IHsKKyAgaW5pdDogZnVuY3Rpb24oKSB7CisgICAgLy8gcXVpdCBpZiB0aGlzIGZ1bmN0aW9uIGhhcyBhbHJlYWR5IGJlZW4gY2FsbGVkCisgICAgaWYgKGFyZ3VtZW50cy5jYWxsZWUuZG9uZSkgcmV0dXJuOworICAgIC8vIGZsYWcgdGhpcyBmdW5jdGlvbiBzbyB3ZSBkb24ndCBkbyB0aGUgc2FtZSB0aGluZyB0d2ljZQorICAgIGFyZ3VtZW50cy5jYWxsZWUuZG9uZSA9IHRydWU7CisgICAgLy8ga2lsbCB0aGUgdGltZXIKKyAgICBpZiAoX3RpbWVyKSBjbGVhckludGVydmFsKF90aW1lcik7CisgICAgCisgICAgaWYgKCFkb2N1bWVudC5jcmVhdGVFbGVtZW50IHx8ICFkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSkgcmV0dXJuOworICAgIAorICAgIHNvcnR0YWJsZS5EQVRFX1JFID0gL14oXGRcZD8pW1wvXC4tXShcZFxkPylbXC9cLi1dKChcZFxkKT9cZFxkKSQvOworICAgIAorICAgIGZvckVhY2goZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3RhYmxlJyksIGZ1bmN0aW9uKHRhYmxlKSB7CisgICAgICBpZiAodGFibGUuY2xhc3NOYW1lLnNlYXJjaCgvXGJzb3J0YWJsZVxiLykgIT0gLTEpIHsKKyAgICAgICAgc29ydHRhYmxlLm1ha2VTb3J0YWJsZSh0YWJsZSk7CisgICAgICB9CisgICAgfSk7CisgICAgCisgIH0sCisgIAorICBtYWtlU29ydGFibGU6IGZ1bmN0aW9uKHRhYmxlKSB7CisgICAgaWYgKHRhYmxlLmdldEVsZW1lbnRzQnlUYWdOYW1lKCd0aGVhZCcpLmxlbmd0aCA9PSAwKSB7CisgICAgICAvLyB0YWJsZSBkb2Vzbid0IGhhdmUgYSB0SGVhZC4gU2luY2UgaXQgc2hvdWxkIGhhdmUsIGNyZWF0ZSBvbmUgYW5kCisgICAgICAvLyBwdXQgdGhlIGZpcnN0IHRhYmxlIHJvdyBpbiBpdC4KKyAgICAgIHRoZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RoZWFkJyk7CisgICAgICB0aGUuYXBwZW5kQ2hpbGQodGFibGUucm93c1swXSk7CisgICAgICB0YWJsZS5pbnNlcnRCZWZvcmUodGhlLHRhYmxlLmZpcnN0Q2hpbGQpOworICAgIH0KKyAgICAvLyBTYWZhcmkgZG9lc24ndCBzdXBwb3J0IHRhYmxlLnRIZWFkLCBzaWdoCisgICAgaWYgKHRhYmxlLnRIZWFkID09IG51bGwpIHRhYmxlLnRIZWFkID0gdGFibGUuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3RoZWFkJylbMF07CisgICAgCisgICAgaWYgKHRhYmxlLnRIZWFkLnJvd3MubGVuZ3RoICE9IDEpIHJldHVybjsgLy8gY2FuJ3QgY29wZSB3aXRoIHR3byBoZWFkZXIgcm93cworICAgIAorICAgIC8vIFNvcnR0YWJsZSB2MSBwdXQgcm93cyB3aXRoIGEgY2xhc3Mgb2YgInNvcnRib3R0b20iIGF0IHRoZSBib3R0b20gKGFzCisgICAgLy8gInRvdGFsIiByb3dzLCBmb3IgZXhhbXBsZSkuIFRoaXMgaXMgQiZSLCBzaW5jZSB3aGF0IHlvdSdyZSBzdXBwb3NlZAorICAgIC8vIHRvIGRvIGlzIHB1dCB0aGVtIGluIGEgdGZvb3QuIFNvLCBpZiB0aGVyZSBhcmUgc29ydGJvdHRvbSByb3dzLAorICAgIC8vIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSwgbW92ZSB0aGVtIHRvIHRmb290IChjcmVhdGluZyBpdCBpZiBuZWVkZWQpLgorICAgIHNvcnRib3R0b21yb3dzID0gW107CisgICAgZm9yICh2YXIgaT0wOyBpPHRhYmxlLnJvd3MubGVuZ3RoOyBpKyspIHsKKyAgICAgIGlmICh0YWJsZS5yb3dzW2ldLmNsYXNzTmFtZS5zZWFyY2goL1xic29ydGJvdHRvbVxiLykgIT0gLTEpIHsKKyAgICAgICAgc29ydGJvdHRvbXJvd3Nbc29ydGJvdHRvbXJvd3MubGVuZ3RoXSA9IHRhYmxlLnJvd3NbaV07CisgICAgICB9CisgICAgfQorICAgIGlmIChzb3J0Ym90dG9tcm93cykgeworICAgICAgaWYgKHRhYmxlLnRGb290ID09IG51bGwpIHsKKyAgICAgICAgLy8gdGFibGUgZG9lc24ndCBoYXZlIGEgdGZvb3QuIENyZWF0ZSBvbmUuCisgICAgICAgIHRmbyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3Rmb290Jyk7CisgICAgICAgIHRhYmxlLmFwcGVuZENoaWxkKHRmbyk7CisgICAgICB9CisgICAgICBmb3IgKHZhciBpPTA7IGk8c29ydGJvdHRvbXJvd3MubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgdGZvLmFwcGVuZENoaWxkKHNvcnRib3R0b21yb3dzW2ldKTsKKyAgICAgIH0KKyAgICAgIGRlbGV0ZSBzb3J0Ym90dG9tcm93czsKKyAgICB9CisgICAgCisgICAgLy8gd29yayB0aHJvdWdoIGVhY2ggY29sdW1uIGFuZCBjYWxjdWxhdGUgaXRzIHR5cGUKKyAgICBoZWFkcm93ID0gdGFibGUudEhlYWQucm93c1swXS5jZWxsczsKKyAgICBmb3IgKHZhciBpPTA7IGk8aGVhZHJvdy5sZW5ndGg7IGkrKykgeworICAgICAgLy8gbWFudWFsbHkgb3ZlcnJpZGUgdGhlIHR5cGUgd2l0aCBhIHNvcnR0YWJsZV90eXBlIGF0dHJpYnV0ZQorICAgICAgaWYgKCFoZWFkcm93W2ldLmNsYXNzTmFtZS5tYXRjaCgvXGJzb3J0dGFibGVfbm9zb3J0XGIvKSkgeyAvLyBza2lwIHRoaXMgY29sCisgICAgICAgIG10Y2ggPSBoZWFkcm93W2ldLmNsYXNzTmFtZS5tYXRjaCgvXGJzb3J0dGFibGVfKFthLXowLTldKylcYi8pOworICAgICAgICBpZiAobXRjaCkgeyBvdmVycmlkZSA9IG10Y2hbMV07IH0KKwkgICAgICBpZiAobXRjaCAmJiB0eXBlb2Ygc29ydHRhYmxlWyJzb3J0XyIrb3ZlcnJpZGVdID09ICdmdW5jdGlvbicpIHsKKwkgICAgICAgIGhlYWRyb3dbaV0uc29ydHRhYmxlX3NvcnRmdW5jdGlvbiA9IHNvcnR0YWJsZVsic29ydF8iK292ZXJyaWRlXTsKKwkgICAgICB9IGVsc2UgeworCSAgICAgICAgaGVhZHJvd1tpXS5zb3J0dGFibGVfc29ydGZ1bmN0aW9uID0gc29ydHRhYmxlLmd1ZXNzVHlwZSh0YWJsZSxpKTsKKwkgICAgICB9CisJICAgICAgLy8gbWFrZSBpdCBjbGlja2FibGUgdG8gc29ydAorCSAgICAgIGhlYWRyb3dbaV0uc29ydHRhYmxlX2NvbHVtbmluZGV4ID0gaTsKKwkgICAgICBoZWFkcm93W2ldLnNvcnR0YWJsZV90Ym9keSA9IHRhYmxlLnRCb2RpZXNbMF07CisJICAgICAgZGVhbl9hZGRFdmVudChoZWFkcm93W2ldLCJjbGljayIsIGZ1bmN0aW9uKGUpIHsKKworICAgICAgICAgIGlmICh0aGlzLmNsYXNzTmFtZS5zZWFyY2goL1xic29ydHRhYmxlX3NvcnRlZFxiLykgIT0gLTEpIHsKKyAgICAgICAgICAgIC8vIGlmIHdlJ3JlIGFscmVhZHkgc29ydGVkIGJ5IHRoaXMgY29sdW1uLCBqdXN0IAorICAgICAgICAgICAgLy8gcmV2ZXJzZSB0aGUgdGFibGUsIHdoaWNoIGlzIHF1aWNrZXIKKyAgICAgICAgICAgIHNvcnR0YWJsZS5yZXZlcnNlKHRoaXMuc29ydHRhYmxlX3Rib2R5KTsKKyAgICAgICAgICAgIHRoaXMuY2xhc3NOYW1lID0gdGhpcy5jbGFzc05hbWUucmVwbGFjZSgnc29ydHRhYmxlX3NvcnRlZCcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NvcnR0YWJsZV9zb3J0ZWRfcmV2ZXJzZScpOworICAgICAgICAgICAgdGhpcy5yZW1vdmVDaGlsZChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc29ydHRhYmxlX3NvcnRmd2RpbmQnKSk7CisgICAgICAgICAgICBzb3J0cmV2aW5kID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpOworICAgICAgICAgICAgc29ydHJldmluZC5pZCA9ICJzb3J0dGFibGVfc29ydHJldmluZCI7CisgICAgICAgICAgICBzb3J0cmV2aW5kLmlubmVySFRNTCA9IHN0SXNJRSA/ICcmbmJzcDxmb250IGZhY2U9IndlYmRpbmdzIj41PC9mb250PicgOiAnJm5ic3A7JiN4MjVCNDsnOworICAgICAgICAgICAgdGhpcy5hcHBlbmRDaGlsZChzb3J0cmV2aW5kKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICB9CisgICAgICAgICAgaWYgKHRoaXMuY2xhc3NOYW1lLnNlYXJjaCgvXGJzb3J0dGFibGVfc29ydGVkX3JldmVyc2VcYi8pICE9IC0xKSB7CisgICAgICAgICAgICAvLyBpZiB3ZSdyZSBhbHJlYWR5IHNvcnRlZCBieSB0aGlzIGNvbHVtbiBpbiByZXZlcnNlLCBqdXN0IAorICAgICAgICAgICAgLy8gcmUtcmV2ZXJzZSB0aGUgdGFibGUsIHdoaWNoIGlzIHF1aWNrZXIKKyAgICAgICAgICAgIHNvcnR0YWJsZS5yZXZlcnNlKHRoaXMuc29ydHRhYmxlX3Rib2R5KTsKKyAgICAgICAgICAgIHRoaXMuY2xhc3NOYW1lID0gdGhpcy5jbGFzc05hbWUucmVwbGFjZSgnc29ydHRhYmxlX3NvcnRlZF9yZXZlcnNlJywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc29ydHRhYmxlX3NvcnRlZCcpOworICAgICAgICAgICAgdGhpcy5yZW1vdmVDaGlsZChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc29ydHRhYmxlX3NvcnRyZXZpbmQnKSk7CisgICAgICAgICAgICBzb3J0ZndkaW5kID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpOworICAgICAgICAgICAgc29ydGZ3ZGluZC5pZCA9ICJzb3J0dGFibGVfc29ydGZ3ZGluZCI7CisgICAgICAgICAgICBzb3J0ZndkaW5kLmlubmVySFRNTCA9IHN0SXNJRSA/ICcmbmJzcDxmb250IGZhY2U9IndlYmRpbmdzIj42PC9mb250PicgOiAnJm5ic3A7JiN4MjVCRTsnOworICAgICAgICAgICAgdGhpcy5hcHBlbmRDaGlsZChzb3J0ZndkaW5kKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICB9CisgICAgICAgICAgCisgICAgICAgICAgLy8gcmVtb3ZlIHNvcnR0YWJsZV9zb3J0ZWQgY2xhc3NlcworICAgICAgICAgIHRoZWFkcm93ID0gdGhpcy5wYXJlbnROb2RlOworICAgICAgICAgIGZvckVhY2godGhlYWRyb3cuY2hpbGROb2RlcywgZnVuY3Rpb24oY2VsbCkgeworICAgICAgICAgICAgaWYgKGNlbGwubm9kZVR5cGUgPT0gMSkgeyAvLyBhbiBlbGVtZW50CisgICAgICAgICAgICAgIGNlbGwuY2xhc3NOYW1lID0gY2VsbC5jbGFzc05hbWUucmVwbGFjZSgnc29ydHRhYmxlX3NvcnRlZF9yZXZlcnNlJywnJyk7CisgICAgICAgICAgICAgIGNlbGwuY2xhc3NOYW1lID0gY2VsbC5jbGFzc05hbWUucmVwbGFjZSgnc29ydHRhYmxlX3NvcnRlZCcsJycpOworICAgICAgICAgICAgfQorICAgICAgICAgIH0pOworICAgICAgICAgIHNvcnRmd2RpbmQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc29ydHRhYmxlX3NvcnRmd2RpbmQnKTsKKyAgICAgICAgICBpZiAoc29ydGZ3ZGluZCkgeyBzb3J0ZndkaW5kLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoc29ydGZ3ZGluZCk7IH0KKyAgICAgICAgICBzb3J0cmV2aW5kID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NvcnR0YWJsZV9zb3J0cmV2aW5kJyk7CisgICAgICAgICAgaWYgKHNvcnRyZXZpbmQpIHsgc29ydHJldmluZC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHNvcnRyZXZpbmQpOyB9CisgICAgICAgICAgCisgICAgICAgICAgdGhpcy5jbGFzc05hbWUgKz0gJyBzb3J0dGFibGVfc29ydGVkJzsKKyAgICAgICAgICBzb3J0ZndkaW5kID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpOworICAgICAgICAgIHNvcnRmd2RpbmQuaWQgPSAic29ydHRhYmxlX3NvcnRmd2RpbmQiOworICAgICAgICAgIHNvcnRmd2RpbmQuaW5uZXJIVE1MID0gc3RJc0lFID8gJyZuYnNwPGZvbnQgZmFjZT0id2ViZGluZ3MiPjY8L2ZvbnQ+JyA6ICcmbmJzcDsmI3gyNUJFOyc7CisgICAgICAgICAgdGhpcy5hcHBlbmRDaGlsZChzb3J0ZndkaW5kKTsKKworCSAgICAgICAgLy8gYnVpbGQgYW4gYXJyYXkgdG8gc29ydC4gVGhpcyBpcyBhIFNjaHdhcnR6aWFuIHRyYW5zZm9ybSB0aGluZywKKwkgICAgICAgIC8vIGkuZS4sIHdlICJkZWNvcmF0ZSIgZWFjaCByb3cgd2l0aCB0aGUgYWN0dWFsIHNvcnQga2V5LAorCSAgICAgICAgLy8gc29ydCBiYXNlZCBvbiB0aGUgc29ydCBrZXlzLCBhbmQgdGhlbiBwdXQgdGhlIHJvd3MgYmFjayBpbiBvcmRlcgorCSAgICAgICAgLy8gd2hpY2ggaXMgYSBsb3QgZmFzdGVyIGJlY2F1c2UgeW91IG9ubHkgZG8gZ2V0SW5uZXJUZXh0IG9uY2UgcGVyIHJvdworCSAgICAgICAgcm93X2FycmF5ID0gW107CisJICAgICAgICBjb2wgPSB0aGlzLnNvcnR0YWJsZV9jb2x1bW5pbmRleDsKKwkgICAgICAgIHJvd3MgPSB0aGlzLnNvcnR0YWJsZV90Ym9keS5yb3dzOworCSAgICAgICAgZm9yICh2YXIgaj0wOyBqPHJvd3MubGVuZ3RoOyBqKyspIHsKKwkgICAgICAgICAgcm93X2FycmF5W3Jvd19hcnJheS5sZW5ndGhdID0gW3NvcnR0YWJsZS5nZXRJbm5lclRleHQocm93c1tqXS5jZWxsc1tjb2xdKSwgcm93c1tqXV07CisJICAgICAgICB9CisJICAgICAgICAvKiBJZiB5b3Ugd2FudCBhIHN0YWJsZSBzb3J0LCB1bmNvbW1lbnQgdGhlIGZvbGxvd2luZyBsaW5lICovCisJICAgICAgICBzb3J0dGFibGUuc2hha2VyX3NvcnQocm93X2FycmF5LCB0aGlzLnNvcnR0YWJsZV9zb3J0ZnVuY3Rpb24pOworCSAgICAgICAgLyogYW5kIGNvbW1lbnQgb3V0IHRoaXMgb25lICovCisJICAgICAgICAvL3Jvd19hcnJheS5zb3J0KHRoaXMuc29ydHRhYmxlX3NvcnRmdW5jdGlvbik7CisJICAgICAgICAKKwkgICAgICAgIHRiID0gdGhpcy5zb3J0dGFibGVfdGJvZHk7CisJICAgICAgICBmb3IgKHZhciBqPTA7IGo8cm93X2FycmF5Lmxlbmd0aDsgaisrKSB7CisJICAgICAgICAgIHRiLmFwcGVuZENoaWxkKHJvd19hcnJheVtqXVsxXSk7CisJICAgICAgICB9CisJICAgICAgICAKKwkgICAgICAgIGRlbGV0ZSByb3dfYXJyYXk7CisJICAgICAgfSk7CisJICAgIH0KKyAgICB9CisgIH0sCisgIAorICBndWVzc1R5cGU6IGZ1bmN0aW9uKHRhYmxlLCBjb2x1bW4pIHsKKyAgICAvLyBndWVzcyB0aGUgdHlwZSBvZiBhIGNvbHVtbiBiYXNlZCBvbiBpdHMgZmlyc3Qgbm9uLWJsYW5rIHJvdworICAgIHNvcnRmbiA9IHNvcnR0YWJsZS5zb3J0X2FscGhhOworICAgIGZvciAodmFyIGk9MDsgaTx0YWJsZS50Qm9kaWVzWzBdLnJvd3MubGVuZ3RoOyBpKyspIHsKKyAgICAgIHRleHQgPSBzb3J0dGFibGUuZ2V0SW5uZXJUZXh0KHRhYmxlLnRCb2RpZXNbMF0ucm93c1tpXS5jZWxsc1tjb2x1bW5dKTsKKyAgICAgIGlmICh0ZXh0ICE9ICcnKSB7CisgICAgICAgIGlmICh0ZXh0Lm1hdGNoKC9eLT9boySkXT9bXGQsLl0rJT8kLykpIHsKKyAgICAgICAgICByZXR1cm4gc29ydHRhYmxlLnNvcnRfbnVtZXJpYzsKKyAgICAgICAgfQorICAgICAgICAvLyBjaGVjayBmb3IgYSBkYXRlOiBkZC9tbS95eXl5IG9yIGRkL21tL3l5IAorICAgICAgICAvLyBjYW4gaGF2ZSAvIG9yIC4gb3IgLSBhcyBzZXBhcmF0b3IKKyAgICAgICAgLy8gY2FuIGJlIG1tL2RkIGFzIHdlbGwKKyAgICAgICAgcG9zc2RhdGUgPSB0ZXh0Lm1hdGNoKHNvcnR0YWJsZS5EQVRFX1JFKQorICAgICAgICBpZiAocG9zc2RhdGUpIHsKKyAgICAgICAgICAvLyBsb29rcyBsaWtlIGEgZGF0ZQorICAgICAgICAgIGZpcnN0ID0gcGFyc2VJbnQocG9zc2RhdGVbMV0pOworICAgICAgICAgIHNlY29uZCA9IHBhcnNlSW50KHBvc3NkYXRlWzJdKTsKKyAgICAgICAgICBpZiAoZmlyc3QgPiAxMikgeworICAgICAgICAgICAgLy8gZGVmaW5pdGVseSBkZC9tbQorICAgICAgICAgICAgcmV0dXJuIHNvcnR0YWJsZS5zb3J0X2RkbW07CisgICAgICAgICAgfSBlbHNlIGlmIChzZWNvbmQgPiAxMikgeworICAgICAgICAgICAgcmV0dXJuIHNvcnR0YWJsZS5zb3J0X21tZGQ7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIGxvb2tzIGxpa2UgYSBkYXRlLCBidXQgd2UgY2FuJ3QgdGVsbCB3aGljaCwgc28gYXNzdW1lCisgICAgICAgICAgICAvLyB0aGF0IGl0J3MgZGQvbW0gKEVuZ2xpc2ggaW1wZXJpYWxpc20hKSBhbmQga2VlcCBsb29raW5nCisgICAgICAgICAgICBzb3J0Zm4gPSBzb3J0dGFibGUuc29ydF9kZG1tOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gc29ydGZuOworICB9LAorICAKKyAgZ2V0SW5uZXJUZXh0OiBmdW5jdGlvbihub2RlKSB7CisgICAgLy8gZ2V0cyB0aGUgdGV4dCB3ZSB3YW50IHRvIHVzZSBmb3Igc29ydGluZyBmb3IgYSBjZWxsLgorICAgIC8vIHN0cmlwcyBsZWFkaW5nIGFuZCB0cmFpbGluZyB3aGl0ZXNwYWNlLgorICAgIC8vIHRoaXMgaXMgKm5vdCogYSBnZW5lcmljIGdldElubmVyVGV4dCBmdW5jdGlvbjsgaXQncyBzcGVjaWFsIHRvIHNvcnR0YWJsZS4KKyAgICAvLyBmb3IgZXhhbXBsZSwgeW91IGNhbiBvdmVycmlkZSB0aGUgY2VsbCB0ZXh0IHdpdGggYSBjdXN0b21rZXkgYXR0cmlidXRlLgorICAgIC8vIGl0IGFsc28gZ2V0cyAudmFsdWUgZm9yIDxpbnB1dD4gZmllbGRzLgorICAgIAorICAgIGhhc0lucHV0cyA9ICh0eXBlb2Ygbm9kZS5nZXRFbGVtZW50c0J5VGFnTmFtZSA9PSAnZnVuY3Rpb24nKSAmJgorICAgICAgICAgICAgICAgICBub2RlLmdldEVsZW1lbnRzQnlUYWdOYW1lKCdpbnB1dCcpLmxlbmd0aDsKKyAgICAKKyAgICBpZiAobm9kZS5nZXRBdHRyaWJ1dGUoInNvcnR0YWJsZV9jdXN0b21rZXkiKSAhPSBudWxsKSB7CisgICAgICByZXR1cm4gbm9kZS5nZXRBdHRyaWJ1dGUoInNvcnR0YWJsZV9jdXN0b21rZXkiKTsKKyAgICB9CisgICAgZWxzZSBpZiAodHlwZW9mIG5vZGUudGV4dENvbnRlbnQgIT0gJ3VuZGVmaW5lZCcgJiYgIWhhc0lucHV0cykgeworICAgICAgcmV0dXJuIG5vZGUudGV4dENvbnRlbnQucmVwbGFjZSgvXlxzK3xccyskL2csICcnKTsKKyAgICB9CisgICAgZWxzZSBpZiAodHlwZW9mIG5vZGUuaW5uZXJUZXh0ICE9ICd1bmRlZmluZWQnICYmICFoYXNJbnB1dHMpIHsKKyAgICAgIHJldHVybiBub2RlLmlubmVyVGV4dC5yZXBsYWNlKC9eXHMrfFxzKyQvZywgJycpOworICAgIH0KKyAgICBlbHNlIGlmICh0eXBlb2Ygbm9kZS50ZXh0ICE9ICd1bmRlZmluZWQnICYmICFoYXNJbnB1dHMpIHsKKyAgICAgIHJldHVybiBub2RlLnRleHQucmVwbGFjZSgvXlxzK3xccyskL2csICcnKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICBzd2l0Y2ggKG5vZGUubm9kZVR5cGUpIHsKKyAgICAgICAgY2FzZSAzOgorICAgICAgICAgIGlmIChub2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT0gJ2lucHV0JykgeworICAgICAgICAgICAgcmV0dXJuIG5vZGUudmFsdWUucmVwbGFjZSgvXlxzK3xccyskL2csICcnKTsKKyAgICAgICAgICB9CisgICAgICAgIGNhc2UgNDoKKyAgICAgICAgICByZXR1cm4gbm9kZS5ub2RlVmFsdWUucmVwbGFjZSgvXlxzK3xccyskL2csICcnKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAxOgorICAgICAgICBjYXNlIDExOgorICAgICAgICAgIHZhciBpbm5lclRleHQgPSAnJzsKKyAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5vZGUuY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgaW5uZXJUZXh0ICs9IHNvcnR0YWJsZS5nZXRJbm5lclRleHQobm9kZS5jaGlsZE5vZGVzW2ldKTsKKyAgICAgICAgICB9CisgICAgICAgICAgcmV0dXJuIGlubmVyVGV4dC5yZXBsYWNlKC9eXHMrfFxzKyQvZywgJycpOworICAgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgIHJldHVybiAnJzsKKyAgICAgIH0KKyAgICB9CisgIH0sCisgIAorICByZXZlcnNlOiBmdW5jdGlvbih0Ym9keSkgeworICAgIC8vIHJldmVyc2UgdGhlIHJvd3MgaW4gYSB0Ym9keQorICAgIG5ld3Jvd3MgPSBbXTsKKyAgICBmb3IgKHZhciBpPTA7IGk8dGJvZHkucm93cy5sZW5ndGg7IGkrKykgeworICAgICAgbmV3cm93c1tuZXdyb3dzLmxlbmd0aF0gPSB0Ym9keS5yb3dzW2ldOworICAgIH0KKyAgICBmb3IgKHZhciBpPW5ld3Jvd3MubGVuZ3RoLTE7IGk+PTA7IGktLSkgeworICAgICAgIHRib2R5LmFwcGVuZENoaWxkKG5ld3Jvd3NbaV0pOworICAgIH0KKyAgICBkZWxldGUgbmV3cm93czsKKyAgfSwKKyAgCisgIC8qIHNvcnQgZnVuY3Rpb25zCisgICAgIGVhY2ggc29ydCBmdW5jdGlvbiB0YWtlcyB0d28gcGFyYW1ldGVycywgYSBhbmQgYgorICAgICB5b3UgYXJlIGNvbXBhcmluZyBhWzBdIGFuZCBiWzBdICovCisgIHNvcnRfbnVtZXJpYzogZnVuY3Rpb24oYSxiKSB7CisgICAgYWEgPSBwYXJzZUZsb2F0KGFbMF0ucmVwbGFjZSgvW14wLTkuLV0vZywnJykpOworICAgIGlmIChpc05hTihhYSkpIGFhID0gMDsKKyAgICBiYiA9IHBhcnNlRmxvYXQoYlswXS5yZXBsYWNlKC9bXjAtOS4tXS9nLCcnKSk7IAorICAgIGlmIChpc05hTihiYikpIGJiID0gMDsKKyAgICByZXR1cm4gYWEtYmI7CisgIH0sCisgIHNvcnRfYWxwaGE6IGZ1bmN0aW9uKGEsYikgeworICAgIGlmIChhWzBdPT1iWzBdKSByZXR1cm4gMDsKKyAgICBpZiAoYVswXTxiWzBdKSByZXR1cm4gLTE7CisgICAgcmV0dXJuIDE7CisgIH0sCisgIHNvcnRfZGRtbTogZnVuY3Rpb24oYSxiKSB7CisgICAgbXRjaCA9IGFbMF0ubWF0Y2goc29ydHRhYmxlLkRBVEVfUkUpOworICAgIHkgPSBtdGNoWzNdOyBtID0gbXRjaFsyXTsgZCA9IG10Y2hbMV07CisgICAgaWYgKG0ubGVuZ3RoID09IDEpIG0gPSAnMCcrbTsKKyAgICBpZiAoZC5sZW5ndGggPT0gMSkgZCA9ICcwJytkOworICAgIGR0MSA9IHkrbStkOworICAgIG10Y2ggPSBiWzBdLm1hdGNoKHNvcnR0YWJsZS5EQVRFX1JFKTsKKyAgICB5ID0gbXRjaFszXTsgbSA9IG10Y2hbMl07IGQgPSBtdGNoWzFdOworICAgIGlmIChtLmxlbmd0aCA9PSAxKSBtID0gJzAnK207CisgICAgaWYgKGQubGVuZ3RoID09IDEpIGQgPSAnMCcrZDsKKyAgICBkdDIgPSB5K20rZDsKKyAgICBpZiAoZHQxPT1kdDIpIHJldHVybiAwOworICAgIGlmIChkdDE8ZHQyKSByZXR1cm4gLTE7CisgICAgcmV0dXJuIDE7CisgIH0sCisgIHNvcnRfbW1kZDogZnVuY3Rpb24oYSxiKSB7CisgICAgbXRjaCA9IGFbMF0ubWF0Y2goc29ydHRhYmxlLkRBVEVfUkUpOworICAgIHkgPSBtdGNoWzNdOyBkID0gbXRjaFsyXTsgbSA9IG10Y2hbMV07CisgICAgaWYgKG0ubGVuZ3RoID09IDEpIG0gPSAnMCcrbTsKKyAgICBpZiAoZC5sZW5ndGggPT0gMSkgZCA9ICcwJytkOworICAgIGR0MSA9IHkrbStkOworICAgIG10Y2ggPSBiWzBdLm1hdGNoKHNvcnR0YWJsZS5EQVRFX1JFKTsKKyAgICB5ID0gbXRjaFszXTsgZCA9IG10Y2hbMl07IG0gPSBtdGNoWzFdOworICAgIGlmIChtLmxlbmd0aCA9PSAxKSBtID0gJzAnK207CisgICAgaWYgKGQubGVuZ3RoID09IDEpIGQgPSAnMCcrZDsKKyAgICBkdDIgPSB5K20rZDsKKyAgICBpZiAoZHQxPT1kdDIpIHJldHVybiAwOworICAgIGlmIChkdDE8ZHQyKSByZXR1cm4gLTE7CisgICAgcmV0dXJuIDE7CisgIH0sCisgIAorICBzaGFrZXJfc29ydDogZnVuY3Rpb24obGlzdCwgY29tcF9mdW5jKSB7CisgICAgLy8gQSBzdGFibGUgc29ydCBmdW5jdGlvbiB0byBhbGxvdyBtdWx0aS1sZXZlbCBzb3J0aW5nIG9mIGRhdGEKKyAgICAvLyBzZWU6IGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ29ja3RhaWxfc29ydAorICAgIC8vIHRoYW5rcyB0byBKb3NlcGggTmFobWlhcworICAgIHZhciBiID0gMDsKKyAgICB2YXIgdCA9IGxpc3QubGVuZ3RoIC0gMTsKKyAgICB2YXIgc3dhcCA9IHRydWU7CisKKyAgICB3aGlsZShzd2FwKSB7CisgICAgICAgIHN3YXAgPSBmYWxzZTsKKyAgICAgICAgZm9yKHZhciBpID0gYjsgaSA8IHQ7ICsraSkgeworICAgICAgICAgICAgaWYgKCBjb21wX2Z1bmMobGlzdFtpXSwgbGlzdFtpKzFdKSA+IDAgKSB7CisgICAgICAgICAgICAgICAgdmFyIHEgPSBsaXN0W2ldOyBsaXN0W2ldID0gbGlzdFtpKzFdOyBsaXN0W2krMV0gPSBxOworICAgICAgICAgICAgICAgIHN3YXAgPSB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICB9IC8vIGZvcgorICAgICAgICB0LS07CisKKyAgICAgICAgaWYgKCFzd2FwKSBicmVhazsKKworICAgICAgICBmb3IodmFyIGkgPSB0OyBpID4gYjsgLS1pKSB7CisgICAgICAgICAgICBpZiAoIGNvbXBfZnVuYyhsaXN0W2ldLCBsaXN0W2ktMV0pIDwgMCApIHsKKyAgICAgICAgICAgICAgICB2YXIgcSA9IGxpc3RbaV07IGxpc3RbaV0gPSBsaXN0W2ktMV07IGxpc3RbaS0xXSA9IHE7CisgICAgICAgICAgICAgICAgc3dhcCA9IHRydWU7CisgICAgICAgICAgICB9CisgICAgICAgIH0gLy8gZm9yCisgICAgICAgIGIrKzsKKworICAgIH0gLy8gd2hpbGUoc3dhcCkKKyAgfSAgCit9CisKKy8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICAgU3VwcG9ydGluZyBmdW5jdGlvbnM6IGJ1bmRsZWQgaGVyZSB0byBhdm9pZCBkZXBlbmRpbmcgb24gYSBsaWJyYXJ5CisgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KKworLy8gRGVhbiBFZHdhcmRzL01hdHRoaWFzIE1pbGxlci9Kb2huIFJlc2lnCisKKy8qIGZvciBNb3ppbGxhL09wZXJhOSAqLworaWYgKGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIpIHsKKyAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJET01Db250ZW50TG9hZGVkIiwgc29ydHRhYmxlLmluaXQsIGZhbHNlKTsKK30KKworLyogZm9yIEludGVybmV0IEV4cGxvcmVyICovCisvKkBjY19vbiBAKi8KKy8qQGlmIChAX3dpbjMyKQorICAgIGRvY3VtZW50LndyaXRlKCI8c2NyaXB0IGlkPV9faWVfb25sb2FkIGRlZmVyIHNyYz1qYXZhc2NyaXB0OnZvaWQoMCk+PFwvc2NyaXB0PiIpOworICAgIHZhciBzY3JpcHQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiX19pZV9vbmxvYWQiKTsKKyAgICBzY3JpcHQub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKSB7CisgICAgICAgIGlmICh0aGlzLnJlYWR5U3RhdGUgPT0gImNvbXBsZXRlIikgeworICAgICAgICAgICAgc29ydHRhYmxlLmluaXQoKTsgLy8gY2FsbCB0aGUgb25sb2FkIGhhbmRsZXIKKyAgICAgICAgfQorICAgIH07CisvKkBlbmQgQCovCisKKy8qIGZvciBTYWZhcmkgKi8KK2lmICgvV2ViS2l0L2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSkgeyAvLyBzbmlmZgorICAgIHZhciBfdGltZXIgPSBzZXRJbnRlcnZhbChmdW5jdGlvbigpIHsKKyAgICAgICAgaWYgKC9sb2FkZWR8Y29tcGxldGUvLnRlc3QoZG9jdW1lbnQucmVhZHlTdGF0ZSkpIHsKKyAgICAgICAgICAgIHNvcnR0YWJsZS5pbml0KCk7IC8vIGNhbGwgdGhlIG9ubG9hZCBoYW5kbGVyCisgICAgICAgIH0KKyAgICB9LCAxMCk7Cit9CisKKy8qIGZvciBvdGhlciBicm93c2VycyAqLword2luZG93Lm9ubG9hZCA9IHNvcnR0YWJsZS5pbml0OworCisvLyB3cml0dGVuIGJ5IERlYW4gRWR3YXJkcywgMjAwNQorLy8gd2l0aCBpbnB1dCBmcm9tIFRpbm8gWmlqZGVsLCBNYXR0aGlhcyBNaWxsZXIsIERpZWdvIFBlcmluaQorCisvLyBodHRwOi8vZGVhbi5lZHdhcmRzLm5hbWUvd2VibG9nLzIwMDUvMTAvYWRkLWV2ZW50LworCitmdW5jdGlvbiBkZWFuX2FkZEV2ZW50KGVsZW1lbnQsIHR5cGUsIGhhbmRsZXIpIHsKKwlpZiAoZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKSB7CisJCWVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBoYW5kbGVyLCBmYWxzZSk7CisJfSBlbHNlIHsKKwkJLy8gYXNzaWduIGVhY2ggZXZlbnQgaGFuZGxlciBhIHVuaXF1ZSBJRAorCQlpZiAoIWhhbmRsZXIuJCRndWlkKSBoYW5kbGVyLiQkZ3VpZCA9IGRlYW5fYWRkRXZlbnQuZ3VpZCsrOworCQkvLyBjcmVhdGUgYSBoYXNoIHRhYmxlIG9mIGV2ZW50IHR5cGVzIGZvciB0aGUgZWxlbWVudAorCQlpZiAoIWVsZW1lbnQuZXZlbnRzKSBlbGVtZW50LmV2ZW50cyA9IHt9OworCQkvLyBjcmVhdGUgYSBoYXNoIHRhYmxlIG9mIGV2ZW50IGhhbmRsZXJzIGZvciBlYWNoIGVsZW1lbnQvZXZlbnQgcGFpcgorCQl2YXIgaGFuZGxlcnMgPSBlbGVtZW50LmV2ZW50c1t0eXBlXTsKKwkJaWYgKCFoYW5kbGVycykgeworCQkJaGFuZGxlcnMgPSBlbGVtZW50LmV2ZW50c1t0eXBlXSA9IHt9OworCQkJLy8gc3RvcmUgdGhlIGV4aXN0aW5nIGV2ZW50IGhhbmRsZXIgKGlmIHRoZXJlIGlzIG9uZSkKKwkJCWlmIChlbGVtZW50WyJvbiIgKyB0eXBlXSkgeworCQkJCWhhbmRsZXJzWzBdID0gZWxlbWVudFsib24iICsgdHlwZV07CisJCQl9CisJCX0KKwkJLy8gc3RvcmUgdGhlIGV2ZW50IGhhbmRsZXIgaW4gdGhlIGhhc2ggdGFibGUKKwkJaGFuZGxlcnNbaGFuZGxlci4kJGd1aWRdID0gaGFuZGxlcjsKKwkJLy8gYXNzaWduIGEgZ2xvYmFsIGV2ZW50IGhhbmRsZXIgdG8gZG8gYWxsIHRoZSB3b3JrCisJCWVsZW1lbnRbIm9uIiArIHR5cGVdID0gaGFuZGxlRXZlbnQ7CisJfQorfTsKKy8vIGEgY291bnRlciB1c2VkIHRvIGNyZWF0ZSB1bmlxdWUgSURzCitkZWFuX2FkZEV2ZW50Lmd1aWQgPSAxOworCitmdW5jdGlvbiByZW1vdmVFdmVudChlbGVtZW50LCB0eXBlLCBoYW5kbGVyKSB7CisJaWYgKGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcikgeworCQllbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgaGFuZGxlciwgZmFsc2UpOworCX0gZWxzZSB7CisJCS8vIGRlbGV0ZSB0aGUgZXZlbnQgaGFuZGxlciBmcm9tIHRoZSBoYXNoIHRhYmxlCisJCWlmIChlbGVtZW50LmV2ZW50cyAmJiBlbGVtZW50LmV2ZW50c1t0eXBlXSkgeworCQkJZGVsZXRlIGVsZW1lbnQuZXZlbnRzW3R5cGVdW2hhbmRsZXIuJCRndWlkXTsKKwkJfQorCX0KK307CisKK2Z1bmN0aW9uIGhhbmRsZUV2ZW50KGV2ZW50KSB7CisJdmFyIHJldHVyblZhbHVlID0gdHJ1ZTsKKwkvLyBncmFiIHRoZSBldmVudCBvYmplY3QgKElFIHVzZXMgYSBnbG9iYWwgZXZlbnQgb2JqZWN0KQorCWV2ZW50ID0gZXZlbnQgfHwgZml4RXZlbnQoKCh0aGlzLm93bmVyRG9jdW1lbnQgfHwgdGhpcy5kb2N1bWVudCB8fCB0aGlzKS5wYXJlbnRXaW5kb3cgfHwgd2luZG93KS5ldmVudCk7CisJLy8gZ2V0IGEgcmVmZXJlbmNlIHRvIHRoZSBoYXNoIHRhYmxlIG9mIGV2ZW50IGhhbmRsZXJzCisJdmFyIGhhbmRsZXJzID0gdGhpcy5ldmVudHNbZXZlbnQudHlwZV07CisJLy8gZXhlY3V0ZSBlYWNoIGV2ZW50IGhhbmRsZXIKKwlmb3IgKHZhciBpIGluIGhhbmRsZXJzKSB7CisJCXRoaXMuJCRoYW5kbGVFdmVudCA9IGhhbmRsZXJzW2ldOworCQlpZiAodGhpcy4kJGhhbmRsZUV2ZW50KGV2ZW50KSA9PT0gZmFsc2UpIHsKKwkJCXJldHVyblZhbHVlID0gZmFsc2U7CisJCX0KKwl9CisJcmV0dXJuIHJldHVyblZhbHVlOworfTsKKworZnVuY3Rpb24gZml4RXZlbnQoZXZlbnQpIHsKKwkvLyBhZGQgVzNDIHN0YW5kYXJkIGV2ZW50IG1ldGhvZHMKKwlldmVudC5wcmV2ZW50RGVmYXVsdCA9IGZpeEV2ZW50LnByZXZlbnREZWZhdWx0OworCWV2ZW50LnN0b3BQcm9wYWdhdGlvbiA9IGZpeEV2ZW50LnN0b3BQcm9wYWdhdGlvbjsKKwlyZXR1cm4gZXZlbnQ7Cit9OworZml4RXZlbnQucHJldmVudERlZmF1bHQgPSBmdW5jdGlvbigpIHsKKwl0aGlzLnJldHVyblZhbHVlID0gZmFsc2U7Cit9OworZml4RXZlbnQuc3RvcFByb3BhZ2F0aW9uID0gZnVuY3Rpb24oKSB7CisgIHRoaXMuY2FuY2VsQnViYmxlID0gdHJ1ZTsKK30KKworLy8gRGVhbidzIGZvckVhY2g6IGh0dHA6Ly9kZWFuLmVkd2FyZHMubmFtZS9iYXNlL2ZvckVhY2guanMKKy8qCisJZm9yRWFjaCwgdmVyc2lvbiAxLjAKKwlDb3B5cmlnaHQgMjAwNiwgRGVhbiBFZHdhcmRzCisJTGljZW5zZTogaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5waHAKKyovCisKKy8vIGFycmF5LWxpa2UgZW51bWVyYXRpb24KK2lmICghQXJyYXkuZm9yRWFjaCkgeyAvLyBtb3ppbGxhIGFscmVhZHkgc3VwcG9ydHMgdGhpcworCUFycmF5LmZvckVhY2ggPSBmdW5jdGlvbihhcnJheSwgYmxvY2ssIGNvbnRleHQpIHsKKwkJZm9yICh2YXIgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykgeworCQkJYmxvY2suY2FsbChjb250ZXh0LCBhcnJheVtpXSwgaSwgYXJyYXkpOworCQl9CisJfTsKK30KKworLy8gZ2VuZXJpYyBlbnVtZXJhdGlvbgorRnVuY3Rpb24ucHJvdG90eXBlLmZvckVhY2ggPSBmdW5jdGlvbihvYmplY3QsIGJsb2NrLCBjb250ZXh0KSB7CisJZm9yICh2YXIga2V5IGluIG9iamVjdCkgeworCQlpZiAodHlwZW9mIHRoaXMucHJvdG90eXBlW2tleV0gPT0gInVuZGVmaW5lZCIpIHsKKwkJCWJsb2NrLmNhbGwoY29udGV4dCwgb2JqZWN0W2tleV0sIGtleSwgb2JqZWN0KTsKKwkJfQorCX0KK307CisKKy8vIGNoYXJhY3RlciBlbnVtZXJhdGlvbgorU3RyaW5nLmZvckVhY2ggPSBmdW5jdGlvbihzdHJpbmcsIGJsb2NrLCBjb250ZXh0KSB7CisJQXJyYXkuZm9yRWFjaChzdHJpbmcuc3BsaXQoIiIpLCBmdW5jdGlvbihjaHIsIGluZGV4KSB7CisJCWJsb2NrLmNhbGwoY29udGV4dCwgY2hyLCBpbmRleCwgc3RyaW5nKTsKKwl9KTsKK307CisKKy8vIGdsb2JhbGx5IHJlc29sdmUgZm9yRWFjaCBlbnVtZXJhdGlvbgordmFyIGZvckVhY2ggPSBmdW5jdGlvbihvYmplY3QsIGJsb2NrLCBjb250ZXh0KSB7CisJaWYgKG9iamVjdCkgeworCQl2YXIgcmVzb2x2ZSA9IE9iamVjdDsgLy8gZGVmYXVsdAorCQlpZiAob2JqZWN0IGluc3RhbmNlb2YgRnVuY3Rpb24pIHsKKwkJCS8vIGZ1bmN0aW9ucyBoYXZlIGEgImxlbmd0aCIgcHJvcGVydHkKKwkJCXJlc29sdmUgPSBGdW5jdGlvbjsKKwkJfSBlbHNlIGlmIChvYmplY3QuZm9yRWFjaCBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7CisJCQkvLyB0aGUgb2JqZWN0IGltcGxlbWVudHMgYSBjdXN0b20gZm9yRWFjaCBtZXRob2Qgc28gdXNlIHRoYXQKKwkJCW9iamVjdC5mb3JFYWNoKGJsb2NrLCBjb250ZXh0KTsKKwkJCXJldHVybjsKKwkJfSBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0ID09ICJzdHJpbmciKSB7CisJCQkvLyB0aGUgb2JqZWN0IGlzIGEgc3RyaW5nCisJCQlyZXNvbHZlID0gU3RyaW5nOworCQl9IGVsc2UgaWYgKHR5cGVvZiBvYmplY3QubGVuZ3RoID09ICJudW1iZXIiKSB7CisJCQkvLyB0aGUgb2JqZWN0IGlzIGFycmF5LWxpa2UKKwkJCXJlc29sdmUgPSBBcnJheTsKKwkJfQorCQlyZXNvbHZlLmZvckVhY2gob2JqZWN0LCBibG9jaywgY29udGV4dCk7CisJfQorfTsKKwpkaWZmIC0tZ2l0IGEvdG9vbHMvc2Nhbi12aWV3L1JlcG9ydGVyLnB5IGIvdG9vbHMvc2Nhbi12aWV3L1JlcG9ydGVyLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk1NjBmYzEKLS0tIC9kZXYvbnVsbAorKysgYi90b29scy9zY2FuLXZpZXcvUmVwb3J0ZXIucHkKQEAgLTAsMCArMSwyNDggQEAKKyIiIk1ldGhvZHMgZm9yIHJlcG9ydGluZyBidWdzLiIiIgorCitpbXBvcnQgc3VicHJvY2Vzcywgc3lzLCBvcworCitfX2FsbF9fID0gWydSZXBvcnRGYWlsdXJlJywgJ0J1Z1JlcG9ydCcsICdnZXRSZXBvcnRlcnMnXQorCisjCisKK2NsYXNzIFJlcG9ydEZhaWx1cmUoRXhjZXB0aW9uKToKKyAgICAiIiJHZW5lcmljIGV4Y2VwdGlvbiBmb3IgZmFpbHVyZXMgaW4gYnVnIHJlcG9ydGluZy4iIiIKKyAgICBkZWYgX19pbml0X18oc2VsZiwgdmFsdWUpOiAgICAgICAgCisgICAgICAgIHNlbGYudmFsdWUgPSB2YWx1ZQorCisjIENvbGxlY3QgaW5mb3JtYXRpb24gYWJvdXQgYSBidWcuCisKK2NsYXNzIEJ1Z1JlcG9ydDoKKyAgICBkZWYgX19pbml0X18oc2VsZiwgdGl0bGUsIGRlc2NyaXB0aW9uLCBmaWxlcyk6CisgICAgICAgIHNlbGYudGl0bGUgPSB0aXRsZQorICAgICAgICBzZWxmLmRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb24KKyAgICAgICAgc2VsZi5maWxlcyA9IGZpbGVzCisKKyMgUmVwb3J0ZXIgaW50ZXJmYWNlcy4KKworaW1wb3J0IG9zCisKK2ltcG9ydCBlbWFpbCwgbWltZXR5cGVzLCBzbXRwbGliCitmcm9tIGVtYWlsIGltcG9ydCBlbmNvZGVycworZnJvbSBlbWFpbC5tZXNzYWdlIGltcG9ydCBNZXNzYWdlCitmcm9tIGVtYWlsLm1pbWUuYmFzZSBpbXBvcnQgTUlNRUJhc2UKK2Zyb20gZW1haWwubWltZS5tdWx0aXBhcnQgaW1wb3J0IE1JTUVNdWx0aXBhcnQKK2Zyb20gZW1haWwubWltZS50ZXh0IGltcG9ydCBNSU1FVGV4dAorCisjPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09IworIyBSZXBvcnRlclBhcmFtZXRlcgorIz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PSMKKworY2xhc3MgUmVwb3J0ZXJQYXJhbWV0ZXI6CisgIGRlZiBfX2luaXRfXyhzZWxmLCBuKToKKyAgICBzZWxmLm5hbWUgPSBuCisgIGRlZiBnZXROYW1lKHNlbGYpOgorICAgIHJldHVybiBzZWxmLm5hbWUKKyAgZGVmIGdldFZhbHVlKHNlbGYscixidWd0eXBlLGdldENvbmZpZ09wdGlvbik6CisgICAgIHJldHVybiBnZXRDb25maWdPcHRpb24oci5nZXROYW1lKCksc2VsZi5nZXROYW1lKCkpCisgIGRlZiBzYXZlQ29uZmlnVmFsdWUoc2VsZik6CisgICAgcmV0dXJuIFRydWUKKworY2xhc3MgVGV4dFBhcmFtZXRlciAoUmVwb3J0ZXJQYXJhbWV0ZXIpOgorICBkZWYgZ2V0SFRNTChzZWxmLHIsYnVndHlwZSxnZXRDb25maWdPcHRpb24pOgorICAgIHJldHVybiAiIiJcCis8dHI+Cis8dGQgY2xhc3M9ImZvcm1fY2xhYmVsIj4lczo8L3RkPgorPHRkIGNsYXNzPSJmb3JtX3ZhbHVlIj48aW5wdXQgdHlwZT0idGV4dCIgbmFtZT0iJXNfJXMiIHZhbHVlPSIlcyI+PC90ZD4KKzwvdHI+IiIiJShzZWxmLmdldE5hbWUoKSxyLmdldE5hbWUoKSxzZWxmLmdldE5hbWUoKSxzZWxmLmdldFZhbHVlKHIsYnVndHlwZSxnZXRDb25maWdPcHRpb24pKQorCitjbGFzcyBTZWxlY3Rpb25QYXJhbWV0ZXIgKFJlcG9ydGVyUGFyYW1ldGVyKToKKyAgZGVmIF9faW5pdF9fKHNlbGYsIG4sIHZhbHVlcyk6CisgICAgUmVwb3J0ZXJQYXJhbWV0ZXIuX19pbml0X18oc2VsZixuKQorICAgIHNlbGYudmFsdWVzID0gdmFsdWVzCisgICAgCisgIGRlZiBnZXRIVE1MKHNlbGYscixidWd0eXBlLGdldENvbmZpZ09wdGlvbik6CisgICAgZGVmYXVsdCA9IHNlbGYuZ2V0VmFsdWUocixidWd0eXBlLGdldENvbmZpZ09wdGlvbikKKyAgICByZXR1cm4gIiIiXAorPHRyPgorPHRkIGNsYXNzPSJmb3JtX2NsYWJlbCI+JXM6PC90ZD48dGQgY2xhc3M9ImZvcm1fdmFsdWUiPjxzZWxlY3QgbmFtZT0iJXNfJXMiPgorJXMKKzwvc2VsZWN0PjwvdGQ+IiIiJShzZWxmLmdldE5hbWUoKSxyLmdldE5hbWUoKSxzZWxmLmdldE5hbWUoKSwnXG4nLmpvaW4oWyIiIlwKKzxvcHRpb24gdmFsdWU9IiVzIiVzPiVzPC9vcHRpb24+IiIiJShvWzBdLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9bMF0gPT0gZGVmYXVsdCBhbmQgJyBzZWxlY3RlZD0ic2VsZWN0ZWQiJyBvciAnJywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvWzFdKSBmb3IgbyBpbiBzZWxmLnZhbHVlc10pKQorCisjPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09IworIyBSZXBvcnRlcnMKKyM9PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0jCisKK2NsYXNzIEVtYWlsUmVwb3J0ZXI6CisgICAgZGVmIGdldE5hbWUoc2VsZik6CisgICAgICAgIHJldHVybiAnRW1haWwnCisKKyAgICBkZWYgZ2V0UGFyYW1ldGVycyhzZWxmKToKKyAgICAgICAgcmV0dXJuIG1hcChsYW1iZGEgeDpUZXh0UGFyYW1ldGVyKHgpLFsnVG8nLCAnRnJvbScsICdTTVRQIFNlcnZlcicsICdTTVRQIFBvcnQnXSkKKworICAgICMgTGlmdGVkIGZyb20gcHl0aG9uIGVtYWlsIG1vZHVsZSBleGFtcGxlcy4KKyAgICBkZWYgYXR0YWNoRmlsZShzZWxmLCBvdXRlciwgcGF0aCk6CisgICAgICAgICMgR3Vlc3MgdGhlIGNvbnRlbnQgdHlwZSBiYXNlZCBvbiB0aGUgZmlsZSdzIGV4dGVuc2lvbi4gIEVuY29kaW5nCisgICAgICAgICMgd2lsbCBiZSBpZ25vcmVkLCBhbHRob3VnaCB3ZSBzaG91bGQgY2hlY2sgZm9yIHNpbXBsZSB0aGluZ3MgbGlrZQorICAgICAgICAjIGd6aXAnZCBvciBjb21wcmVzc2VkIGZpbGVzLgorICAgICAgICBjdHlwZSwgZW5jb2RpbmcgPSBtaW1ldHlwZXMuZ3Vlc3NfdHlwZShwYXRoKQorICAgICAgICBpZiBjdHlwZSBpcyBOb25lIG9yIGVuY29kaW5nIGlzIG5vdCBOb25lOgorICAgICAgICAgICAgIyBObyBndWVzcyBjb3VsZCBiZSBtYWRlLCBvciB0aGUgZmlsZSBpcyBlbmNvZGVkIChjb21wcmVzc2VkKSwgc28KKyAgICAgICAgICAgICMgdXNlIGEgZ2VuZXJpYyBiYWctb2YtYml0cyB0eXBlLgorICAgICAgICAgICAgY3R5cGUgPSAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJworICAgICAgICBtYWludHlwZSwgc3VidHlwZSA9IGN0eXBlLnNwbGl0KCcvJywgMSkKKyAgICAgICAgaWYgbWFpbnR5cGUgPT0gJ3RleHQnOgorICAgICAgICAgICAgZnAgPSBvcGVuKHBhdGgpCisgICAgICAgICAgICAjIE5vdGU6IHdlIHNob3VsZCBoYW5kbGUgY2FsY3VsYXRpbmcgdGhlIGNoYXJzZXQKKyAgICAgICAgICAgIG1zZyA9IE1JTUVUZXh0KGZwLnJlYWQoKSwgX3N1YnR5cGU9c3VidHlwZSkKKyAgICAgICAgICAgIGZwLmNsb3NlKCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICAgIGZwID0gb3BlbihwYXRoLCAncmInKQorICAgICAgICAgICAgbXNnID0gTUlNRUJhc2UobWFpbnR5cGUsIHN1YnR5cGUpCisgICAgICAgICAgICBtc2cuc2V0X3BheWxvYWQoZnAucmVhZCgpKQorICAgICAgICAgICAgZnAuY2xvc2UoKQorICAgICAgICAgICAgIyBFbmNvZGUgdGhlIHBheWxvYWQgdXNpbmcgQmFzZTY0CisgICAgICAgICAgICBlbmNvZGVycy5lbmNvZGVfYmFzZTY0KG1zZykKKyAgICAgICAgIyBTZXQgdGhlIGZpbGVuYW1lIHBhcmFtZXRlcgorICAgICAgICBtc2cuYWRkX2hlYWRlcignQ29udGVudC1EaXNwb3NpdGlvbicsICdhdHRhY2htZW50JywgZmlsZW5hbWU9b3MucGF0aC5iYXNlbmFtZShwYXRoKSkKKyAgICAgICAgb3V0ZXIuYXR0YWNoKG1zZykKKworICAgIGRlZiBmaWxlUmVwb3J0KHNlbGYsIHJlcG9ydCwgcGFyYW1ldGVycyk6CisgICAgICAgIG1haW5Nc2cgPSAiIiJcCitCVUcgUkVQT1JUCistLS0KK1RpdGxlOiAlcworRGVzY3JpcHRpb246ICVzCisiIiIlKHJlcG9ydC50aXRsZSwgcmVwb3J0LmRlc2NyaXB0aW9uKQorCisgICAgICAgIGlmIG5vdCBwYXJhbWV0ZXJzLmdldCgnVG8nKToKKyAgICAgICAgICAgIHJhaXNlIFJlcG9ydEZhaWx1cmUoJ05vICJUbyIgYWRkcmVzcyBzcGVjaWZpZWQuJykKKyAgICAgICAgaWYgbm90IHBhcmFtZXRlcnMuZ2V0KCdGcm9tJyk6CisgICAgICAgICAgICByYWlzZSBSZXBvcnRGYWlsdXJlKCdObyAiRnJvbSIgYWRkcmVzcyBzcGVjaWZpZWQuJykKKworICAgICAgICBtc2cgPSBNSU1FTXVsdGlwYXJ0KCkKKyAgICAgICAgbXNnWydTdWJqZWN0J10gPSAnQlVHIFJFUE9SVDogJXMnJShyZXBvcnQudGl0bGUpCisgICAgICAgICMgRklYTUU6IEdldCBjb25maWcgcGFyYW1ldGVycworICAgICAgICBtc2dbJ1RvJ10gPSBwYXJhbWV0ZXJzLmdldCgnVG8nKQorICAgICAgICBtc2dbJ0Zyb20nXSA9IHBhcmFtZXRlcnMuZ2V0KCdGcm9tJykKKyAgICAgICAgbXNnLnByZWFtYmxlID0gbWFpbk1zZworCisgICAgICAgIG1zZy5hdHRhY2goTUlNRVRleHQobWFpbk1zZywgX3N1YnR5cGU9J3RleHQvcGxhaW4nKSkKKyAgICAgICAgZm9yIGZpbGUgaW4gcmVwb3J0LmZpbGVzOgorICAgICAgICAgICAgc2VsZi5hdHRhY2hGaWxlKG1zZywgZmlsZSkKKworICAgICAgICB0cnk6CisgICAgICAgICAgICBzID0gc210cGxpYi5TTVRQKGhvc3Q9cGFyYW1ldGVycy5nZXQoJ1NNVFAgU2VydmVyJyksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcnQ9cGFyYW1ldGVycy5nZXQoJ1NNVFAgUG9ydCcpKQorICAgICAgICAgICAgcy5zZW5kbWFpbChtc2dbJ0Zyb20nXSwgbXNnWydUbyddLCBtc2cuYXNfc3RyaW5nKCkpCisgICAgICAgICAgICBzLmNsb3NlKCkKKyAgICAgICAgZXhjZXB0OgorICAgICAgICAgICAgcmFpc2UgUmVwb3J0RmFpbHVyZSgnVW5hYmxlIHRvIHNlbmQgbWVzc2FnZSB2aWEgU01UUC4nKQorCisgICAgICAgIHJldHVybiAiTWVzc2FnZSBzZW50ISIKKworY2xhc3MgQnVnemlsbGFSZXBvcnRlcjoKKyAgICBkZWYgZ2V0TmFtZShzZWxmKToKKyAgICAgICAgcmV0dXJuICdCdWd6aWxsYScKKyAgICAKKyAgICBkZWYgZ2V0UGFyYW1ldGVycyhzZWxmKToKKyAgICAgICAgcmV0dXJuIG1hcChsYW1iZGEgeDpUZXh0UGFyYW1ldGVyKHgpLFsnVVJMJywnUHJvZHVjdCddKQorCisgICAgZGVmIGZpbGVSZXBvcnQoc2VsZiwgcmVwb3J0LCBwYXJhbWV0ZXJzKToKKyAgICAgICAgcmFpc2UgTm90SW1wbGVtZW50ZWRFcnJvcgorIAorCitjbGFzcyBSYWRhckNsYXNzaWZpY2F0aW9uUGFyYW1ldGVyKFNlbGVjdGlvblBhcmFtZXRlcik6CisgIGRlZiBfX2luaXRfXyhzZWxmKToKKyAgICBTZWxlY3Rpb25QYXJhbWV0ZXIuX19pbml0X18oc2VsZiwiQ2xhc3NpZmljYXRpb24iLAorICAgICAgICAgICAgW1snMScsICdTZWN1cml0eSddLCBbJzInLCAnQ3Jhc2gvSGFuZy9EYXRhIExvc3MnXSwKKyAgICAgICAgICAgICBbJzMnLCAnUGVyZm9ybWFuY2UnXSwgWyc0JywgJ1VJL1VzYWJpbGl0eSddLCAKKyAgICAgICAgICAgICBbJzYnLCAnU2VyaW91cyBCdWcnXSwgWyc3JywgJ090aGVyJ11dKQorCisgIGRlZiBzYXZlQ29uZmlnVmFsdWUoc2VsZik6CisgICAgcmV0dXJuIEZhbHNlCisgICAgCisgIGRlZiBnZXRWYWx1ZShzZWxmLHIsYnVndHlwZSxnZXRDb25maWdPcHRpb24pOgorICAgIGlmIGJ1Z3R5cGUuZmluZCgibGVhayIpICE9IC0xOgorICAgICAgcmV0dXJuICczJworICAgIGVsaWYgYnVndHlwZS5maW5kKCJkZXJlZmVyZW5jZSIpICE9IC0xOgorICAgICAgcmV0dXJuICcyJworICAgIGVsaWYgYnVndHlwZS5maW5kKCJtaXNzaW5nIGl2YXIgcmVsZWFzZSIpICE9IC0xOgorICAgICAgcmV0dXJuICczJworICAgIGVsc2U6CisgICAgICByZXR1cm4gJzcnCisKK2NsYXNzIFJhZGFyUmVwb3J0ZXI6CisgICAgQHN0YXRpY21ldGhvZAorICAgIGRlZiBpc0F2YWlsYWJsZSgpOgorICAgICAgICAjIEZJWE1FOiBGaW5kIHRoaXMgLnNjcHQgYmV0dGVyCisgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4ob3MucGF0aC5kaXJuYW1lKF9fZmlsZV9fKSwnUmVzb3VyY2VzL0dldFJhZGFyVmVyc2lvbi5zY3B0JykKKyAgICAgICAgdHJ5OgorICAgICAgICAgIHAgPSBzdWJwcm9jZXNzLlBvcGVuKFsnb3Nhc2NyaXB0JyxwYXRoXSwgCisgICAgICAgICAgc3Rkb3V0PXN1YnByb2Nlc3MuUElQRSwgc3RkZXJyPXN1YnByb2Nlc3MuUElQRSkKKyAgICAgICAgZXhjZXB0OgorICAgICAgICAgICAgcmV0dXJuIEZhbHNlCisgICAgICAgIGRhdGEsZXJyID0gcC5jb21tdW5pY2F0ZSgpCisgICAgICAgIHJlcyA9IHAud2FpdCgpCisgICAgICAgICMgRklYTUU6IENoZWNrIHZlcnNpb24/IENoZWNrIGZvciBubyBlcnJvcnM/CisgICAgICAgIHJldHVybiByZXMgPT0gMAorCisgICAgZGVmIGdldE5hbWUoc2VsZik6CisgICAgICAgIHJldHVybiAnUmFkYXInCisKKyAgICBkZWYgZ2V0UGFyYW1ldGVycyhzZWxmKToKKyAgICAgICAgcmV0dXJuIFsgVGV4dFBhcmFtZXRlcignQ29tcG9uZW50JyksIFRleHRQYXJhbWV0ZXIoJ0NvbXBvbmVudCBWZXJzaW9uJyksCisgICAgICAgICAgICAgICAgIFJhZGFyQ2xhc3NpZmljYXRpb25QYXJhbWV0ZXIoKSBdCisKKyAgICBkZWYgZmlsZVJlcG9ydChzZWxmLCByZXBvcnQsIHBhcmFtZXRlcnMpOgorICAgICAgICBjb21wb25lbnQgPSBwYXJhbWV0ZXJzLmdldCgnQ29tcG9uZW50JywgJycpCisgICAgICAgIGNvbXBvbmVudFZlcnNpb24gPSBwYXJhbWV0ZXJzLmdldCgnQ29tcG9uZW50IFZlcnNpb24nLCAnJykKKyAgICAgICAgY2xhc3NpZmljYXRpb24gPSBwYXJhbWV0ZXJzLmdldCgnQ2xhc3NpZmljYXRpb24nLCAnJykKKyAgICAgICAgcGVyc29uSUQgPSAiIgorICAgICAgICBkaWFnbm9zaXMgPSAiIgorICAgICAgICBjb25maWcgPSAiIgorCisgICAgICAgIGlmIG5vdCBjb21wb25lbnQuc3RyaXAoKToKKyAgICAgICAgICAgIGNvbXBvbmVudCA9ICdCdWdzIGZvdW5kIGJ5IGNsYW5nIEFuYWx5emVyJworICAgICAgICBpZiBub3QgY29tcG9uZW50VmVyc2lvbi5zdHJpcCgpOgorICAgICAgICAgICAgY29tcG9uZW50VmVyc2lvbiA9ICdYJworCisgICAgICAgIHNjcmlwdCA9IG9zLnBhdGguam9pbihvcy5wYXRoLmRpcm5hbWUoX19maWxlX18pLCdSZXNvdXJjZXMvRmlsZVJhZGFyLnNjcHQnKQorICAgICAgICBhcmdzID0gWydvc2FzY3JpcHQnLCBzY3JpcHQsIGNvbXBvbmVudCwgY29tcG9uZW50VmVyc2lvbiwgY2xhc3NpZmljYXRpb24sIHBlcnNvbklELCByZXBvcnQudGl0bGUsCisgICAgICAgICAgICAgICAgcmVwb3J0LmRlc2NyaXB0aW9uLCBkaWFnbm9zaXMsIGNvbmZpZ10gKyBtYXAob3MucGF0aC5hYnNwYXRoLCByZXBvcnQuZmlsZXMpCisjICAgICAgICBwcmludCA+PnN5cy5zdGRlcnIsIGFyZ3MKKyAgICAgICAgdHJ5OgorICAgICAgICAgIHAgPSBzdWJwcm9jZXNzLlBvcGVuKGFyZ3MsIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHN0ZGVycj1zdWJwcm9jZXNzLlBJUEUpCisgICAgICAgIGV4Y2VwdDoKKyAgICAgICAgICAgIHJhaXNlIFJlcG9ydEZhaWx1cmUoIlVuYWJsZSB0byBmaWxlIHJhZGFyIChBcHBsZVNjcmlwdCBmYWlsdXJlKS4iKQorICAgICAgICBkYXRhLCBlcnIgPSBwLmNvbW11bmljYXRlKCkKKyAgICAgICAgcmVzID0gcC53YWl0KCkKKworICAgICAgICBpZiByZXM6CisgICAgICAgICAgICByYWlzZSBSZXBvcnRGYWlsdXJlKCJVbmFibGUgdG8gZmlsZSByYWRhciAoQXBwbGVTY3JpcHQgZmFpbHVyZSkuIikKKworICAgICAgICB0cnk6CisgICAgICAgICAgICB2YWx1ZXMgPSBldmFsKGRhdGEpCisgICAgICAgIGV4Y2VwdDoKKyAgICAgICAgICAgIHJhaXNlIFJlcG9ydEZhaWx1cmUoIlVuYWJsZSB0byBwcm9jZXNzIHJhZGFyIHJlc3VsdHMuIikKKworICAgICAgICAjIFdlIGV4cGVjdCAoaW50OiBidWdJRCwgc3RyOiBtZXNzYWdlKQorICAgICAgICBpZiBsZW4odmFsdWVzKSAhPSAyIG9yIG5vdCBpc2luc3RhbmNlKHZhbHVlc1swXSwgaW50KToKKyAgICAgICAgICAgIHJhaXNlIFJlcG9ydEZhaWx1cmUoIlVuYWJsZSB0byBwcm9jZXNzIHJhZGFyIHJlc3VsdHMuIikKKworICAgICAgICBidWdJRCxtZXNzYWdlID0gdmFsdWVzCisgICAgICAgIGJ1Z0lEID0gaW50KGJ1Z0lEKQorICAgICAgICAKKyAgICAgICAgaWYgbm90IGJ1Z0lEOgorICAgICAgICAgICAgcmFpc2UgUmVwb3J0RmFpbHVyZShtZXNzYWdlKQorICAgICAgICAKKyAgICAgICAgcmV0dXJuICJGaWxlZDogPGEgaHJlZj1cInJkYXI6Ly8lZC9cIj4lZDwvYT4iJShidWdJRCxidWdJRCkKKworIyMjCisKK2RlZiBnZXRSZXBvcnRlcnMoKToKKyAgICByZXBvcnRlcnMgPSBbXQorICAgIGlmIFJhZGFyUmVwb3J0ZXIuaXNBdmFpbGFibGUoKToKKyAgICAgICAgcmVwb3J0ZXJzLmFwcGVuZChSYWRhclJlcG9ydGVyKCkpCisgICAgcmVwb3J0ZXJzLmFwcGVuZChFbWFpbFJlcG9ydGVyKCkpCisgICAgcmV0dXJuIHJlcG9ydGVycworCmRpZmYgLS1naXQgYS90b29scy9zY2FuLXZpZXcvUmVzb3VyY2VzL0ZpbGVSYWRhci5zY3B0IGIvdG9vbHMvc2Nhbi12aWV3L1Jlc291cmNlcy9GaWxlUmFkYXIuc2NwdApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYzc0NTUyCi0tLSAvZGV2L251bGwKKysrIGIvdG9vbHMvc2Nhbi12aWV3L1Jlc291cmNlcy9GaWxlUmFkYXIuc2NwdApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS90b29scy9zY2FuLXZpZXcvUmVzb3VyY2VzL0dldFJhZGFyVmVyc2lvbi5zY3B0IGIvdG9vbHMvc2Nhbi12aWV3L1Jlc291cmNlcy9HZXRSYWRhclZlcnNpb24uc2NwdApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNjlkZTI5Ci0tLSAvZGV2L251bGwKKysrIGIvdG9vbHMvc2Nhbi12aWV3L1Jlc291cmNlcy9HZXRSYWRhclZlcnNpb24uc2NwdApkaWZmIC0tZ2l0IGEvdG9vbHMvc2Nhbi12aWV3L1Jlc291cmNlcy9idWdjYXRjaGVyLmljbyBiL3Rvb2xzL3NjYW4tdmlldy9SZXNvdXJjZXMvYnVnY2F0Y2hlci5pY28KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjJkMzliNQotLS0gL2Rldi9udWxsCisrKyBiL3Rvb2xzL3NjYW4tdmlldy9SZXNvdXJjZXMvYnVnY2F0Y2hlci5pY28KQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvdG9vbHMvc2Nhbi12aWV3L1NjYW5WaWV3LnB5IGIvdG9vbHMvc2Nhbi12aWV3L1NjYW5WaWV3LnB5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVlMDhiYWEKLS0tIC9kZXYvbnVsbAorKysgYi90b29scy9zY2FuLXZpZXcvU2NhblZpZXcucHkKQEAgLTAsMCArMSw3NjcgQEAKK2ltcG9ydCBCYXNlSFRUUFNlcnZlcgoraW1wb3J0IFNpbXBsZUhUVFBTZXJ2ZXIKK2ltcG9ydCBvcworaW1wb3J0IHN5cworaW1wb3J0IHVybGxpYiwgdXJscGFyc2UKK2ltcG9ydCBwb3NpeHBhdGgKK2ltcG9ydCBTdHJpbmdJTworaW1wb3J0IHJlCitpbXBvcnQgc2h1dGlsCitpbXBvcnQgdGhyZWFkaW5nCitpbXBvcnQgdGltZQoraW1wb3J0IHNvY2tldAoraW1wb3J0IGl0ZXJ0b29scworCitpbXBvcnQgUmVwb3J0ZXIKK2ltcG9ydCBDb25maWdQYXJzZXIKKworIyMjCisjIFZhcmlvdXMgcGF0dGVybnMgbWF0Y2hlZCBvciByZXBsYWNlZCBieSBzZXJ2ZXIuCisKK2tSZXBvcnRGaWxlUkUgPSByZS5jb21waWxlKCcoLiovKT9yZXBvcnQtKC4qKVxcLmh0bWwnKQorCitrQnVnS2V5VmFsdWVSRSA9IHJlLmNvbXBpbGUoJzwhLS0gQlVHKFteIF0qKSAoLiopIC0tPicpCisKKyMgIDwhLS0gUkVQT1JUUFJPQkxFTSBmaWxlPSJjcmFzaGVzL2NsYW5nX2NyYXNoX25kU0dGOS5taSIgc3RkZXJyPSJjcmFzaGVzL2NsYW5nX2NyYXNoX25kU0dGOS5taS5zdGRlcnIudHh0IiBpbmZvPSJjcmFzaGVzL2NsYW5nX2NyYXNoX25kU0dGOS5taS5pbmZvIiAtLT4KKwora1JlcG9ydENyYXNoRW50cnlSRSA9IHJlLmNvbXBpbGUoJzwhLS0gUkVQT1JUUFJPQkxFTSAoLio/KS0tPicpCitrUmVwb3J0Q3Jhc2hFbnRyeUtleVZhbHVlUkUgPSByZS5jb21waWxlKCcgPyhbXj1dKyk9IiguKj8pIicpCisKK2tSZXBvcnRSZXBsYWNlbWVudHMgPSBbXQorCisjIEFkZCBjdXN0b20gamF2YXNjcmlwdC4KK2tSZXBvcnRSZXBsYWNlbWVudHMuYXBwZW5kKChyZS5jb21waWxlKCc8IS0tIFNVTU1BUllFTkRIRUFEIC0tPicpLCAiIiJcCis8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPgorZnVuY3Rpb24gbG9hZCh1cmwpIHsKKyAgaWYgKHdpbmRvdy5YTUxIdHRwUmVxdWVzdCkgeworICAgIHJlcSA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpOworICB9IGVsc2UgaWYgKHdpbmRvdy5BY3RpdmVYT2JqZWN0KSB7CisgICAgcmVxID0gbmV3IEFjdGl2ZVhPYmplY3QoIk1pY3Jvc29mdC5YTUxIVFRQIik7CisgIH0KKyAgaWYgKHJlcSAhPSB1bmRlZmluZWQpIHsKKyAgICByZXEub3BlbigiR0VUIiwgdXJsLCB0cnVlKTsKKyAgICByZXEuc2VuZCgiIik7CisgIH0KK30KKzwvc2NyaXB0PiIiIikpCisKKyMgSW5zZXJ0IGFkZGl0aW9uYWwgY29sdW1ucy4KK2tSZXBvcnRSZXBsYWNlbWVudHMuYXBwZW5kKChyZS5jb21waWxlKCc8IS0tIFJFUE9SVEJVR0NPTCAtLT4nKSwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzx0ZD48L3RkPjx0ZD48L3RkPicpKQorCisjIEluc2VydCByZXBvcnQgYnVnIGFuZCBvcGVuIGZpbGUgbGlua3MuCitrUmVwb3J0UmVwbGFjZW1lbnRzLmFwcGVuZCgocmUuY29tcGlsZSgnPCEtLSBSRVBPUlRCVUcgaWQ9InJlcG9ydC0oLiopXFwuaHRtbCIgLS0+JyksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCc8dGQgY2xhc3M9IkJ1dHRvbiI+PGEgaHJlZj0icmVwb3J0L1xcMSI+UmVwb3J0IEJ1ZzwvYT48L3RkPicgKyAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzx0ZCBjbGFzcz0iQnV0dG9uIj48YSBocmVmPSJqYXZhc2NyaXB0OmxvYWQoXCdvcGVuL1xcMVwnKSI+T3BlbiBGaWxlPC9hPjwvdGQ+JykpKQorCitrUmVwb3J0UmVwbGFjZW1lbnRzLmFwcGVuZCgocmUuY29tcGlsZSgnPCEtLSBSRVBPUlRIRUFERVIgLS0+JyksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGgzPjxhIGhyZWY9Ii8iPlN1bW1hcnk8L2E+ID4gUmVwb3J0ICUocmVwb3J0KXM8L2gzPicpKQorCitrUmVwb3J0UmVwbGFjZW1lbnRzLmFwcGVuZCgocmUuY29tcGlsZSgnPCEtLSBSRVBPUlRTVU1NQVJZRVhUUkEgLS0+JyksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzx0ZCBjbGFzcz0iQnV0dG9uIj48YSBocmVmPSJyZXBvcnQvJShyZXBvcnQpcyI+UmVwb3J0IEJ1ZzwvYT48L3RkPicpKQorCisjIEluc2VydCByZXBvcnQgY3Jhc2hlcyBsaW5rLgorCisjIERpc2FibGVkIGZvciB0aGUgdGltZSBiZWluZyB1bnRpbCB3ZSBkZWNpZGUgZXhhY3RseSB3aGVuIHRoaXMgc2hvdWxkCisjIGJlIGVuYWJsZWQuIEFsc28gdGhlIHJhZGFyIHJlcG9ydGVyIG5lZWRzIHRvIGJlIGZpeGVkIHRvIHJlcG9ydAorIyBtdWx0aXBsZSBmaWxlcy4KKworI2tSZXBvcnRSZXBsYWNlbWVudHMuYXBwZW5kKChyZS5jb21waWxlKCc8IS0tIFJFUE9SVENSQVNIRVMgLS0+JyksCisjICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8YnI+VGhlc2UgZmlsZXMgd2lsbCBhdXRvbWF0aWNhbGx5IGJlIGF0dGFjaGVkIHRvICcgKworIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAncmVwb3J0cyBmaWxlZCBoZXJlOiA8YSBocmVmPSJyZXBvcnRfY3Jhc2hlcyI+UmVwb3J0IENyYXNoZXM8L2E+LicpKQorCisjIyMKKyMgT3RoZXIgc2ltcGxlIHBhcmFtZXRlcnMKKwora1Jlc291cmNlcyA9IHBvc2l4cGF0aC5qb2luKHBvc2l4cGF0aC5kaXJuYW1lKF9fZmlsZV9fKSwgJ1Jlc291cmNlcycpCitrQ29uZmlnUGF0aCA9IG9zLnBhdGguZXhwYW5kdXNlcignfi8uc2NhbnZpZXcuY2ZnJykKKworIyMjCisKK19fdmVyc2lvbl9fID0gIjAuMSIKKworX19hbGxfXyA9IFsiY3JlYXRlX3NlcnZlciJdCisKK2NsYXNzIFJlcG9ydGVyVGhyZWFkKHRocmVhZGluZy5UaHJlYWQpOgorICAgIGRlZiBfX2luaXRfXyhzZWxmLCByZXBvcnQsIHJlcG9ydGVyLCBwYXJhbWV0ZXJzLCBzZXJ2ZXIpOgorICAgICAgICB0aHJlYWRpbmcuVGhyZWFkLl9faW5pdF9fKHNlbGYpCisgICAgICAgIHNlbGYucmVwb3J0ID0gcmVwb3J0CisgICAgICAgIHNlbGYuc2VydmVyID0gc2VydmVyCisgICAgICAgIHNlbGYucmVwb3J0ZXIgPSByZXBvcnRlcgorICAgICAgICBzZWxmLnBhcmFtZXRlcnMgPSBwYXJhbWV0ZXJzCisgICAgICAgIHNlbGYuc3VjY2VzcyA9IEZhbHNlCisgICAgICAgIHNlbGYuc3RhdHVzID0gTm9uZQorCisgICAgZGVmIHJ1bihzZWxmKToKKyAgICAgICAgcmVzdWx0ID0gTm9uZQorICAgICAgICB0cnk6CisgICAgICAgICAgICBpZiBzZWxmLnNlcnZlci5vcHRpb25zLmRlYnVnOgorICAgICAgICAgICAgICAgIHByaW50ID4+c3lzLnN0ZGVyciwgIiVzOiBTRVJWRVI6IHN1Ym1pdHRpbmcgYnVnLiIlKHN5cy5hcmd2WzBdLCkKKyAgICAgICAgICAgIHNlbGYuc3RhdHVzID0gc2VsZi5yZXBvcnRlci5maWxlUmVwb3J0KHNlbGYucmVwb3J0LCBzZWxmLnBhcmFtZXRlcnMpCisgICAgICAgICAgICBzZWxmLnN1Y2Nlc3MgPSBUcnVlCisgICAgICAgICAgICB0aW1lLnNsZWVwKDMpCisgICAgICAgICAgICBpZiBzZWxmLnNlcnZlci5vcHRpb25zLmRlYnVnOgorICAgICAgICAgICAgICAgIHByaW50ID4+c3lzLnN0ZGVyciwgIiVzOiBTRVJWRVI6IHN1Ym1pc3Npb24gY29tcGxldGUuIiUoc3lzLmFyZ3ZbMF0sKQorICAgICAgICBleGNlcHQgUmVwb3J0ZXIuUmVwb3J0RmFpbHVyZSxlOgorICAgICAgICAgICAgc2VsZi5zdGF0dXMgPSBlLnZhbHVlCisgICAgICAgIGV4Y2VwdCBFeGNlcHRpb24sZToKKyAgICAgICAgICAgIHMgPSBTdHJpbmdJTy5TdHJpbmdJTygpCisgICAgICAgICAgICBpbXBvcnQgdHJhY2ViYWNrCisgICAgICAgICAgICBwcmludCA+PnMsJzxiPlVuaGFuZGxlZCBFeGNlcHRpb248L2I+PGJyPjxwcmU+JworICAgICAgICAgICAgdHJhY2ViYWNrLnByaW50X2V4YyhlLGZpbGU9cykKKyAgICAgICAgICAgIHByaW50ID4+cywnPC9wcmU+JworICAgICAgICAgICAgc2VsZi5zdGF0dXMgPSBzLmdldHZhbHVlKCkKKworY2xhc3MgU2NhblZpZXdTZXJ2ZXIoQmFzZUhUVFBTZXJ2ZXIuSFRUUFNlcnZlcik6CisgICAgZGVmIF9faW5pdF9fKHNlbGYsIGFkZHJlc3MsIGhhbmRsZXIsIHJvb3QsIHJlcG9ydGVycywgb3B0aW9ucyk6CisgICAgICAgIEJhc2VIVFRQU2VydmVyLkhUVFBTZXJ2ZXIuX19pbml0X18oc2VsZiwgYWRkcmVzcywgaGFuZGxlcikKKyAgICAgICAgc2VsZi5yb290ID0gcm9vdAorICAgICAgICBzZWxmLnJlcG9ydGVycyA9IHJlcG9ydGVycworICAgICAgICBzZWxmLm9wdGlvbnMgPSBvcHRpb25zICAgICAgICAKKyAgICAgICAgc2VsZi5oYWx0ZWQgPSBGYWxzZQorICAgICAgICBzZWxmLmNvbmZpZyA9IE5vbmUKKyAgICAgICAgc2VsZi5sb2FkX2NvbmZpZygpCisKKyAgICBkZWYgbG9hZF9jb25maWcoc2VsZik6CisgICAgICAgIHNlbGYuY29uZmlnID0gQ29uZmlnUGFyc2VyLlJhd0NvbmZpZ1BhcnNlcigpCisKKyAgICAgICAgIyBBZGQgZGVmYXVsdHMKKyAgICAgICAgc2VsZi5jb25maWcuYWRkX3NlY3Rpb24oJ1NjYW5WaWV3JykKKyAgICAgICAgZm9yIHIgaW4gc2VsZi5yZXBvcnRlcnM6CisgICAgICAgICAgICBzZWxmLmNvbmZpZy5hZGRfc2VjdGlvbihyLmdldE5hbWUoKSkKKyAgICAgICAgICAgIGZvciBwIGluIHIuZ2V0UGFyYW1ldGVycygpOgorICAgICAgICAgICAgICBpZiBwLnNhdmVDb25maWdWYWx1ZSgpOgorICAgICAgICAgICAgICAgIHNlbGYuY29uZmlnLnNldChyLmdldE5hbWUoKSwgcC5nZXROYW1lKCksICcnKQorCisgICAgICAgICMgSWdub3JlIHBhcnNlIGVycm9ycworICAgICAgICB0cnk6CisgICAgICAgICAgICBzZWxmLmNvbmZpZy5yZWFkKFtrQ29uZmlnUGF0aF0pCisgICAgICAgIGV4Y2VwdDoKKyAgICAgICAgICAgIHBhc3MKKworICAgICAgICAjIFNhdmUgb24gZXhpdAorICAgICAgICBpbXBvcnQgYXRleGl0CisgICAgICAgIGF0ZXhpdC5yZWdpc3RlcihsYW1iZGE6IHNlbGYuc2F2ZV9jb25maWcoKSkKKyAgICAgICAgCisgICAgZGVmIHNhdmVfY29uZmlnKHNlbGYpOgorICAgICAgICAjIElnbm9yZSBlcnJvcnMgKG9ubHkgY2FsbGVkIG9uIGV4aXQpLgorICAgICAgICB0cnk6CisgICAgICAgICAgICBmID0gb3BlbihrQ29uZmlnUGF0aCwndycpCisgICAgICAgICAgICBzZWxmLmNvbmZpZy53cml0ZShmKQorICAgICAgICAgICAgZi5jbG9zZSgpCisgICAgICAgIGV4Y2VwdDoKKyAgICAgICAgICAgIHBhc3MKKyAgICAgICAgCisgICAgZGVmIGhhbHQoc2VsZik6CisgICAgICAgIHNlbGYuaGFsdGVkID0gVHJ1ZQorICAgICAgICBpZiBzZWxmLm9wdGlvbnMuZGVidWc6CisgICAgICAgICAgICBwcmludCA+PnN5cy5zdGRlcnIsICIlczogU0VSVkVSOiBoYWx0aW5nLiIgJSAoc3lzLmFyZ3ZbMF0sKQorCisgICAgZGVmIHNlcnZlX2ZvcmV2ZXIoc2VsZik6CisgICAgICAgIHdoaWxlIG5vdCBzZWxmLmhhbHRlZDoKKyAgICAgICAgICAgIGlmIHNlbGYub3B0aW9ucy5kZWJ1ZyA+IDE6CisgICAgICAgICAgICAgICAgcHJpbnQgPj5zeXMuc3RkZXJyLCAiJXM6IFNFUlZFUjogd2FpdGluZy4uLiIgJSAoc3lzLmFyZ3ZbMF0sKQorICAgICAgICAgICAgdHJ5OgorICAgICAgICAgICAgICAgIHNlbGYuaGFuZGxlX3JlcXVlc3QoKQorICAgICAgICAgICAgZXhjZXB0IE9TRXJyb3IsZToKKyAgICAgICAgICAgICAgICBwcmludCAnT1NFcnJvcicsZS5lcnJubworCisgICAgZGVmIGZpbmlzaF9yZXF1ZXN0KHNlbGYsIHJlcXVlc3QsIGNsaWVudF9hZGRyZXNzKToKKyAgICAgICAgaWYgc2VsZi5vcHRpb25zLmF1dG9SZWxvYWQ6CisgICAgICAgICAgICBpbXBvcnQgU2NhblZpZXcKKyAgICAgICAgICAgIHNlbGYuUmVxdWVzdEhhbmRsZXJDbGFzcyA9IHJlbG9hZChTY2FuVmlldykuU2NhblZpZXdSZXF1ZXN0SGFuZGxlcgorICAgICAgICBCYXNlSFRUUFNlcnZlci5IVFRQU2VydmVyLmZpbmlzaF9yZXF1ZXN0KHNlbGYsIHJlcXVlc3QsIGNsaWVudF9hZGRyZXNzKQorCisgICAgZGVmIGhhbmRsZV9lcnJvcihzZWxmLCByZXF1ZXN0LCBjbGllbnRfYWRkcmVzcyk6CisgICAgICAgICMgSWdub3JlIHNvY2tldCBlcnJvcnMKKyAgICAgICAgaW5mbyA9IHN5cy5leGNfaW5mbygpCisgICAgICAgIGlmIGluZm8gYW5kIGlzaW5zdGFuY2UoaW5mb1sxXSwgc29ja2V0LmVycm9yKToKKyAgICAgICAgICAgIGlmIHNlbGYub3B0aW9ucy5kZWJ1ZyA+IDE6CisgICAgICAgICAgICAgICAgcHJpbnQgPj5zeXMuc3RkZXJyLCAiJXM6IFNFUlZFUjogaWdub3JlZCBzb2NrZXQgZXJyb3IuIiAlIChzeXMuYXJndlswXSwpCisgICAgICAgICAgICByZXR1cm4KKyAgICAgICAgQmFzZUhUVFBTZXJ2ZXIuSFRUUFNlcnZlci5oYW5kbGVfZXJyb3Ioc2VsZiwgcmVxdWVzdCwgY2xpZW50X2FkZHJlc3MpCisKKyMgQm9ycm93ZWQgZnJvbSBRdWl4b3RlLCB3aXRoIHNpbXBsaWZpY2F0aW9ucy4KK2RlZiBwYXJzZV9xdWVyeShxcywgZmllbGRzPU5vbmUpOgorICAgIGlmIGZpZWxkcyBpcyBOb25lOgorICAgICAgICBmaWVsZHMgPSB7fQorICAgIGZvciBjaHVuayBpbiBmaWx0ZXIoTm9uZSwgcXMuc3BsaXQoJyYnKSk6CisgICAgICAgIGlmICc9JyBub3QgaW4gY2h1bms6CisgICAgICAgICAgICBuYW1lID0gY2h1bmsKKyAgICAgICAgICAgIHZhbHVlID0gJycKKyAgICAgICAgZWxzZToKKyAgICAgICAgICAgIG5hbWUsIHZhbHVlID0gY2h1bmsuc3BsaXQoJz0nLCAxKQorICAgICAgICBuYW1lID0gdXJsbGliLnVucXVvdGUobmFtZS5yZXBsYWNlKCcrJywgJyAnKSkKKyAgICAgICAgdmFsdWUgPSB1cmxsaWIudW5xdW90ZSh2YWx1ZS5yZXBsYWNlKCcrJywgJyAnKSkKKyAgICAgICAgaXRlbSA9IGZpZWxkcy5nZXQobmFtZSkKKyAgICAgICAgaWYgaXRlbSBpcyBOb25lOgorICAgICAgICAgICAgZmllbGRzW25hbWVdID0gW3ZhbHVlXQorICAgICAgICBlbHNlOgorICAgICAgICAgICAgaXRlbS5hcHBlbmQodmFsdWUpCisgICAgcmV0dXJuIGZpZWxkcworCitjbGFzcyBTY2FuVmlld1JlcXVlc3RIYW5kbGVyKFNpbXBsZUhUVFBTZXJ2ZXIuU2ltcGxlSFRUUFJlcXVlc3RIYW5kbGVyKToKKyAgICBzZXJ2ZXJfdmVyc2lvbiA9ICJTY2FuVmlld1NlcnZlci8iICsgX192ZXJzaW9uX18KKyAgICBkeW5hbWljX210aW1lID0gdGltZS50aW1lKCkKKworICAgIGRlZiBkb19IRUFEKHNlbGYpOgorICAgICAgICB0cnk6CisgICAgICAgICAgICBTaW1wbGVIVFRQU2VydmVyLlNpbXBsZUhUVFBSZXF1ZXN0SGFuZGxlci5kb19IRUFEKHNlbGYpCisgICAgICAgIGV4Y2VwdCBFeGNlcHRpb24sZToKKyAgICAgICAgICAgIHNlbGYuaGFuZGxlX2V4Y2VwdGlvbihlKQorICAgICAgICAgICAgCisgICAgZGVmIGRvX0dFVChzZWxmKToKKyAgICAgICAgdHJ5OgorICAgICAgICAgICAgU2ltcGxlSFRUUFNlcnZlci5TaW1wbGVIVFRQUmVxdWVzdEhhbmRsZXIuZG9fR0VUKHNlbGYpCisgICAgICAgIGV4Y2VwdCBFeGNlcHRpb24sZToKKyAgICAgICAgICAgIHNlbGYuaGFuZGxlX2V4Y2VwdGlvbihlKQorICAgICAgICAgICAgCisgICAgZGVmIGRvX1BPU1Qoc2VsZik6CisgICAgICAgICIiIlNlcnZlIGEgUE9TVCByZXF1ZXN0LiIiIgorICAgICAgICB0cnk6CisgICAgICAgICAgICBsZW5ndGggPSBzZWxmLmhlYWRlcnMuZ2V0aGVhZGVyKCdjb250ZW50LWxlbmd0aCcpIG9yICIwIgorICAgICAgICAgICAgdHJ5OgorICAgICAgICAgICAgICAgIGxlbmd0aCA9IGludChsZW5ndGgpCisgICAgICAgICAgICBleGNlcHQ6CisgICAgICAgICAgICAgICAgbGVuZ3RoID0gMAorICAgICAgICAgICAgY29udGVudCA9IHNlbGYucmZpbGUucmVhZChsZW5ndGgpCisgICAgICAgICAgICBmaWVsZHMgPSBwYXJzZV9xdWVyeShjb250ZW50KQorICAgICAgICAgICAgZiA9IHNlbGYuc2VuZF9oZWFkKGZpZWxkcykKKyAgICAgICAgICAgIGlmIGY6CisgICAgICAgICAgICAgICAgc2VsZi5jb3B5ZmlsZShmLCBzZWxmLndmaWxlKQorICAgICAgICAgICAgICAgIGYuY2xvc2UoKQorICAgICAgICBleGNlcHQgRXhjZXB0aW9uLGU6CisgICAgICAgICAgICBzZWxmLmhhbmRsZV9leGNlcHRpb24oZSkgICAgICAgICAgICAKKworICAgIGRlZiBsb2dfbWVzc2FnZShzZWxmLCBmb3JtYXQsICphcmdzKToKKyAgICAgICAgaWYgc2VsZi5zZXJ2ZXIub3B0aW9ucy5kZWJ1ZzoKKyAgICAgICAgICAgIHN5cy5zdGRlcnIud3JpdGUoIiVzOiBTRVJWRVI6ICVzIC0gLSBbJXNdICVzXG4iICUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHN5cy5hcmd2WzBdLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5hZGRyZXNzX3N0cmluZygpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5sb2dfZGF0ZV90aW1lX3N0cmluZygpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0JWFyZ3MpKQorCisgICAgZGVmIGxvYWRfcmVwb3J0KHNlbGYsIHJlcG9ydCk6CisgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4oc2VsZi5zZXJ2ZXIucm9vdCwgJ3JlcG9ydC0lcy5odG1sJyVyZXBvcnQpCisgICAgICAgIGRhdGEgPSBvcGVuKHBhdGgpLnJlYWQoKQorICAgICAgICBrZXlzID0ge30KKyAgICAgICAgZm9yIGl0ZW0gaW4ga0J1Z0tleVZhbHVlUkUuZmluZGl0ZXIoZGF0YSk6CisgICAgICAgICAgICBrLHYgPSBpdGVtLmdyb3VwcygpCisgICAgICAgICAgICBrZXlzW2tdID0gdgorICAgICAgICByZXR1cm4ga2V5cworCisgICAgZGVmIGxvYWRfY3Jhc2hlcyhzZWxmKToKKyAgICAgICAgcGF0aCA9IHBvc2l4cGF0aC5qb2luKHNlbGYuc2VydmVyLnJvb3QsICdpbmRleC5odG1sJykKKyAgICAgICAgZGF0YSA9IG9wZW4ocGF0aCkucmVhZCgpCisgICAgICAgIHByb2JsZW1zID0gW10KKyAgICAgICAgZm9yIGl0ZW0gaW4ga1JlcG9ydENyYXNoRW50cnlSRS5maW5kaXRlcihkYXRhKToKKyAgICAgICAgICAgIGZpZWxkRGF0YSA9IGl0ZW0uZ3JvdXAoMSkKKyAgICAgICAgICAgIGZpZWxkcyA9IGRpY3QoW2kuZ3JvdXBzKCkgZm9yIGkgaW4gCisgICAgICAgICAgICAgICAgICAgICAgICAgICBrUmVwb3J0Q3Jhc2hFbnRyeUtleVZhbHVlUkUuZmluZGl0ZXIoZmllbGREYXRhKV0pCisgICAgICAgICAgICBwcm9ibGVtcy5hcHBlbmQoZmllbGRzKQorICAgICAgICByZXR1cm4gcHJvYmxlbXMKKworICAgIGRlZiBoYW5kbGVfZXhjZXB0aW9uKHNlbGYsIGV4Yyk6CisgICAgICAgIGltcG9ydCB0cmFjZWJhY2sKKyAgICAgICAgcyA9IFN0cmluZ0lPLlN0cmluZ0lPKCkKKyAgICAgICAgcHJpbnQgPj5zLCAiSU5URVJOQUwgRVJST1JcbiIKKyAgICAgICAgdHJhY2ViYWNrLnByaW50X2V4YyhleGMsIHMpCisgICAgICAgIGYgPSBzZWxmLnNlbmRfc3RyaW5nKHMuZ2V0dmFsdWUoKSwgJ3RleHQvcGxhaW4nKQorICAgICAgICBpZiBmOgorICAgICAgICAgICAgc2VsZi5jb3B5ZmlsZShmLCBzZWxmLndmaWxlKQorICAgICAgICAgICAgZi5jbG9zZSgpICAgICAgICAKKyAgICAgICAgICAgIAorICAgIGRlZiBnZXRfc2NhbGFyX2ZpZWxkKHNlbGYsIG5hbWUpOgorICAgICAgICBpZiBuYW1lIGluIHNlbGYuZmllbGRzOgorICAgICAgICAgICAgcmV0dXJuIHNlbGYuZmllbGRzW25hbWVdWzBdCisgICAgICAgIGVsc2U6CisgICAgICAgICAgICByZXR1cm4gTm9uZQorCisgICAgZGVmIHN1Ym1pdF9idWcoc2VsZiwgYyk6CisgICAgICAgIHRpdGxlID0gc2VsZi5nZXRfc2NhbGFyX2ZpZWxkKCd0aXRsZScpCisgICAgICAgIGRlc2NyaXB0aW9uID0gc2VsZi5nZXRfc2NhbGFyX2ZpZWxkKCdkZXNjcmlwdGlvbicpCisgICAgICAgIHJlcG9ydCA9IHNlbGYuZ2V0X3NjYWxhcl9maWVsZCgncmVwb3J0JykKKyAgICAgICAgcmVwb3J0ZXJJbmRleCA9IHNlbGYuZ2V0X3NjYWxhcl9maWVsZCgncmVwb3J0ZXInKQorICAgICAgICBmaWxlcyA9IFtdCisgICAgICAgIGZvciBmaWxlSUQgaW4gc2VsZi5maWVsZHMuZ2V0KCdmaWxlcycsW10pOgorICAgICAgICAgICAgdHJ5OgorICAgICAgICAgICAgICAgIGkgPSBpbnQoZmlsZUlEKQorICAgICAgICAgICAgZXhjZXB0OgorICAgICAgICAgICAgICAgIGkgPSBOb25lCisgICAgICAgICAgICBpZiBpIGlzIE5vbmUgb3IgaTwwIG9yIGk+PWxlbihjLmZpbGVzKToKKyAgICAgICAgICAgICAgICByZXR1cm4gKEZhbHNlLCAnSW52YWxpZCBmaWxlIElEJykKKyAgICAgICAgICAgIGZpbGVzLmFwcGVuZChjLmZpbGVzW2ldKQorICAgICAgICAKKyAgICAgICAgaWYgbm90IHRpdGxlOgorICAgICAgICAgICAgcmV0dXJuIChGYWxzZSwgIk1pc3NpbmcgdGl0bGUuIikKKyAgICAgICAgaWYgbm90IGRlc2NyaXB0aW9uOgorICAgICAgICAgICAgcmV0dXJuIChGYWxzZSwgIk1pc3NpbmcgZGVzY3JpcHRpb24uIikKKyAgICAgICAgdHJ5OgorICAgICAgICAgICAgcmVwb3J0ZXJJbmRleCA9IGludChyZXBvcnRlckluZGV4KQorICAgICAgICBleGNlcHQ6CisgICAgICAgICAgICByZXR1cm4gKEZhbHNlLCAiSW52YWxpZCByZXBvcnQgbWV0aG9kLiIpCisgICAgICAgIAorICAgICAgICAjIEdldCB0aGUgcmVwb3J0ZXIgYW5kIHBhcmFtZXRlcnMuCisgICAgICAgIHJlcG9ydGVyID0gc2VsZi5zZXJ2ZXIucmVwb3J0ZXJzW3JlcG9ydGVySW5kZXhdCisgICAgICAgIHBhcmFtZXRlcnMgPSB7fQorICAgICAgICBmb3IgbyBpbiByZXBvcnRlci5nZXRQYXJhbWV0ZXJzKCk6CisgICAgICAgICAgICBuYW1lID0gJyVzXyVzJyUocmVwb3J0ZXIuZ2V0TmFtZSgpLG8uZ2V0TmFtZSgpKQorICAgICAgICAgICAgaWYgbmFtZSBub3QgaW4gc2VsZi5maWVsZHM6CisgICAgICAgICAgICAgICAgcmV0dXJuIChGYWxzZSwgCisgICAgICAgICAgICAgICAgICAgICAgICAnTWlzc2luZyBmaWVsZCAiJXMiIGZvciAlcyByZXBvcnQgbWV0aG9kLiclKG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydGVyLmdldE5hbWUoKSkpCisgICAgICAgICAgICBwYXJhbWV0ZXJzW28uZ2V0TmFtZSgpXSA9IHNlbGYuZ2V0X3NjYWxhcl9maWVsZChuYW1lKQorCisgICAgICAgICMgVXBkYXRlIGNvbmZpZyBkZWZhdWx0cy4KKyAgICAgICAgaWYgcmVwb3J0ICE9ICdOb25lJzoKKyAgICAgICAgICAgIHNlbGYuc2VydmVyLmNvbmZpZy5zZXQoJ1NjYW5WaWV3JywgJ3JlcG9ydGVyJywgcmVwb3J0ZXJJbmRleCkKKyAgICAgICAgICAgIGZvciBvIGluIHJlcG9ydGVyLmdldFBhcmFtZXRlcnMoKToKKyAgICAgICAgICAgICAgaWYgby5zYXZlQ29uZmlnVmFsdWUoKToKKyAgICAgICAgICAgICAgICBuYW1lID0gby5nZXROYW1lKCkKKyAgICAgICAgICAgICAgICBzZWxmLnNlcnZlci5jb25maWcuc2V0KHJlcG9ydGVyLmdldE5hbWUoKSwgbmFtZSwgcGFyYW1ldGVyc1tuYW1lXSkKKworICAgICAgICAjIENyZWF0ZSB0aGUgcmVwb3J0LgorICAgICAgICBidWcgPSBSZXBvcnRlci5CdWdSZXBvcnQodGl0bGUsIGRlc2NyaXB0aW9uLCBmaWxlcykKKworICAgICAgICAjIEtpY2sgb2ZmIGEgcmVwb3J0aW5nIHRocmVhZC4KKyAgICAgICAgdCA9IFJlcG9ydGVyVGhyZWFkKGJ1ZywgcmVwb3J0ZXIsIHBhcmFtZXRlcnMsIHNlbGYuc2VydmVyKQorICAgICAgICB0LnN0YXJ0KCkKKworICAgICAgICAjIFdhaXQgZm9yIHRocmVhZCB0byBkaWUuLi4KKyAgICAgICAgd2hpbGUgdC5pc0FsaXZlKCk6CisgICAgICAgICAgICB0aW1lLnNsZWVwKC4yNSkKKyAgICAgICAgc3VibWl0U3RhdHVzID0gdC5zdGF0dXMKKworICAgICAgICByZXR1cm4gKHQuc3VjY2VzcywgdC5zdGF0dXMpCisKKyAgICBkZWYgc2VuZF9yZXBvcnRfc3VibWl0KHNlbGYpOgorICAgICAgICByZXBvcnQgPSBzZWxmLmdldF9zY2FsYXJfZmllbGQoJ3JlcG9ydCcpCisgICAgICAgIGMgPSBzZWxmLmdldF9yZXBvcnRfY29udGV4dChyZXBvcnQpCisgICAgICAgIGlmIGMucmVwb3J0U291cmNlIGlzIE5vbmU6CisgICAgICAgICAgICByZXBvcnRpbmdGb3IgPSAiUmVwb3J0IENyYXNoZXMgPiAiCisgICAgICAgICAgICBmaWxlQnVnID0gIiIiXAorPGEgaHJlZj0iL3JlcG9ydF9jcmFzaGVzIj5GaWxlIEJ1ZzwvYT4gPiAiIiIlbG9jYWxzKCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICAgIHJlcG9ydGluZ0ZvciA9ICc8YSBocmVmPSIvJXMiPlJlcG9ydCAlczwvYT4gPiAnICUgKGMucmVwb3J0U291cmNlLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnQpCisgICAgICAgICAgICBmaWxlQnVnID0gJzxhIGhyZWY9Ii9yZXBvcnQvJXMiPkZpbGUgQnVnPC9hPiA+ICcgJSByZXBvcnQKKyAgICAgICAgdGl0bGUgPSBzZWxmLmdldF9zY2FsYXJfZmllbGQoJ3RpdGxlJykKKyAgICAgICAgZGVzY3JpcHRpb24gPSBzZWxmLmdldF9zY2FsYXJfZmllbGQoJ2Rlc2NyaXB0aW9uJykKKworICAgICAgICByZXMsbWVzc2FnZSA9IHNlbGYuc3VibWl0X2J1ZyhjKQorCisgICAgICAgIGlmIHJlczoKKyAgICAgICAgICAgIHN0YXR1c0NsYXNzID0gJ1N1Ym1pdE9rJworICAgICAgICAgICAgc3RhdHVzTmFtZSA9ICdTdWNjZWVkZWQnCisgICAgICAgIGVsc2U6CisgICAgICAgICAgICBzdGF0dXNDbGFzcyA9ICdTdWJtaXRGYWlsJworICAgICAgICAgICAgc3RhdHVzTmFtZSA9ICdGYWlsZWQnCisKKyAgICAgICAgcmVzdWx0ID0gIiIiCis8aGVhZD4KKyAgPHRpdGxlPkJ1ZyBTdWJtaXNzaW9uPC90aXRsZT4KKyAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiB0eXBlPSJ0ZXh0L2NzcyIgaHJlZj0iL3NjYW52aWV3LmNzcyIgLz4KKzwvaGVhZD4KKzxib2R5PgorPGgzPgorPGEgaHJlZj0iLyI+U3VtbWFyeTwvYT4gPiAKKyUocmVwb3J0aW5nRm9yKXMKKyUoZmlsZUJ1ZylzCitTdWJtaXQ8L2gzPgorPGZvcm0gbmFtZT0iZm9ybSIgYWN0aW9uPSIiPgorPHRhYmxlIGNsYXNzPSJmb3JtIj4KKzx0cj48dGQ+Cis8dGFibGUgY2xhc3M9ImZvcm1fZ3JvdXAiPgorPHRyPgorICA8dGQgY2xhc3M9ImZvcm1fY2xhYmVsIj5UaXRsZTo8L3RkPgorICA8dGQgY2xhc3M9ImZvcm1fdmFsdWUiPgorICAgIDxpbnB1dCB0eXBlPSJ0ZXh0IiBuYW1lPSJ0aXRsZSIgc2l6ZT0iNTAiIHZhbHVlPSIlKHRpdGxlKXMiIGRpc2FibGVkPgorICA8L3RkPgorPC90cj4KKzx0cj4KKyAgPHRkIGNsYXNzPSJmb3JtX2xhYmVsIj5EZXNjcmlwdGlvbjo8L3RkPgorICA8dGQgY2xhc3M9ImZvcm1fdmFsdWUiPgorPHRleHRhcmVhIHJvd3M9IjEwIiBjb2xzPSI4MCIgbmFtZT0iZGVzY3JpcHRpb24iIGRpc2FibGVkPgorJShkZXNjcmlwdGlvbilzCis8L3RleHRhcmVhPgorICA8L3RkPgorPC90YWJsZT4KKzwvdGQ+PC90cj4KKzwvdGFibGU+Cis8L2Zvcm0+Cis8aDEgY2xhc3M9IiUoc3RhdHVzQ2xhc3MpcyI+U3VibWlzc2lvbiAlKHN0YXR1c05hbWUpczwvaDE+CislKG1lc3NhZ2UpcworPHA+Cis8aHI+Cis8YSBocmVmPSIvIj5SZXR1cm4gdG8gU3VtbWFyeTwvYT4KKzwvYm9keT4KKzwvaHRtbD4iIiIlbG9jYWxzKCkKKyAgICAgICAgcmV0dXJuIHNlbGYuc2VuZF9zdHJpbmcocmVzdWx0KQorCisgICAgZGVmIHNlbmRfb3Blbl9yZXBvcnQoc2VsZiwgcmVwb3J0KToKKyAgICAgICAgdHJ5OgorICAgICAgICAgICAga2V5cyA9IHNlbGYubG9hZF9yZXBvcnQocmVwb3J0KQorICAgICAgICBleGNlcHQgSU9FcnJvcjoKKyAgICAgICAgICAgIHJldHVybiBzZWxmLnNlbmRfZXJyb3IoNDAwLCAnSW52YWxpZCByZXBvcnQuJykKKworICAgICAgICBmaWxlID0ga2V5cy5nZXQoJ0ZJTEUnKQorICAgICAgICBpZiBub3QgZmlsZSBvciBub3QgcG9zaXhwYXRoLmV4aXN0cyhmaWxlKToKKyAgICAgICAgICAgIHJldHVybiBzZWxmLnNlbmRfZXJyb3IoNDAwLCAnRmlsZSBkb2VzIG5vdCBleGlzdDogIiVzIicgJSBmaWxlKQorCisgICAgICAgIGltcG9ydCBzdGFydGZpbGUKKyAgICAgICAgaWYgc2VsZi5zZXJ2ZXIub3B0aW9ucy5kZWJ1ZzoKKyAgICAgICAgICAgIHByaW50ID4+c3lzLnN0ZGVyciwgJyVzOiBTRVJWRVI6IG9wZW5pbmcgIiVzIiclKHN5cy5hcmd2WzBdLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZSkKKworICAgICAgICBzdGF0dXMgPSBzdGFydGZpbGUub3BlbihmaWxlKQorICAgICAgICBpZiBzdGF0dXM6CisgICAgICAgICAgICByZXMgPSAnT3BlbmVkOiAiJXMiJyAlIGZpbGUKKyAgICAgICAgZWxzZToKKyAgICAgICAgICAgIHJlcyA9ICdPcGVuIGZhaWxlZDogIiVzIicgJSBmaWxlCisKKyAgICAgICAgcmV0dXJuIHNlbGYuc2VuZF9zdHJpbmcocmVzLCAndGV4dC9wbGFpbicpCisKKyAgICBkZWYgZ2V0X3JlcG9ydF9jb250ZXh0KHNlbGYsIHJlcG9ydCk6CisgICAgICAgIGNsYXNzIENvbnRleHQ6CisgICAgICAgICAgICBwYXNzCisgICAgICAgIGlmIHJlcG9ydCBpcyBOb25lIG9yIHJlcG9ydCA9PSAnTm9uZSc6CisgICAgICAgICAgICBkYXRhID0gc2VsZi5sb2FkX2NyYXNoZXMoKQorICAgICAgICAgICAgIyBEb24ndCBhbGxvdyBlbXB0eSByZXBvcnRzLgorICAgICAgICAgICAgaWYgbm90IGRhdGE6CisgICAgICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvciwgJ05vIGNyYXNoZXMgZGV0ZWN0ZWQhJworICAgICAgICAgICAgYyA9IENvbnRleHQoKQorICAgICAgICAgICAgYy50aXRsZSA9ICdjbGFuZyBzdGF0aWMgYW5hbHl6ZXIgZmFpbHVyZXMnCisKKyAgICAgICAgICAgIHN0ZGVyclN1bW1hcnkgPSAiIgorICAgICAgICAgICAgZm9yIGl0ZW0gaW4gZGF0YToKKyAgICAgICAgICAgICAgICBpZiAnc3RkZXJyJyBpbiBpdGVtOgorICAgICAgICAgICAgICAgICAgICBwYXRoID0gcG9zaXhwYXRoLmpvaW4oc2VsZi5zZXJ2ZXIucm9vdCwgaXRlbVsnc3RkZXJyJ10pCisgICAgICAgICAgICAgICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKHBhdGgpOgorICAgICAgICAgICAgICAgICAgICAgICAgbG5zID0gaXRlcnRvb2xzLmlzbGljZShvcGVuKHBhdGgpLCAwLCAxMCkKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0ZGVyclN1bW1hcnkgKz0gJyVzXG4tLVxuJXMnICUgKGl0ZW0uZ2V0KCdzcmMnLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8dW5rbm93bj4nKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcnLmpvaW4obG5zKSkKKworICAgICAgICAgICAgYy5kZXNjcmlwdGlvbiA9ICIiIlwKK1RoZSBjbGFuZyBzdGF0aWMgYW5hbHl6ZXIgZmFpbGVkIG9uIHRoZXNlIGlucHV0czoKKyVzCisKK1NUREVSUiBTdW1tYXJ5CistLS0tLS0tLS0tLS0tLQorJXMKKyIiIiAlICgnXG4nLmpvaW4oW2l0ZW0uZ2V0KCdzcmMnLCc8dW5rbm93bj4nKSBmb3IgaXRlbSBpbiBkYXRhXSksCisgICAgICAgc3RkZXJyU3VtbWFyeSkKKyAgICAgICAgICAgIGMucmVwb3J0U291cmNlID0gTm9uZQorICAgICAgICAgICAgYy5uYXZNYXJrdXAgPSAiUmVwb3J0IENyYXNoZXMgPiAiCisgICAgICAgICAgICBjLmZpbGVzID0gW10KKyAgICAgICAgICAgIGZvciBpdGVtIGluIGRhdGE6ICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgIGMuZmlsZXMuYXBwZW5kKGl0ZW0uZ2V0KCdzcmMnLCcnKSkKKyAgICAgICAgICAgICAgICBjLmZpbGVzLmFwcGVuZChwb3NpeHBhdGguam9pbihzZWxmLnNlcnZlci5yb290LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0uZ2V0KCdmaWxlJywnJykpKQorICAgICAgICAgICAgICAgIGMuZmlsZXMuYXBwZW5kKHBvc2l4cGF0aC5qb2luKHNlbGYuc2VydmVyLnJvb3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS5nZXQoJ2NsYW5nZmlsZScsJycpKSkKKyAgICAgICAgICAgICAgICBjLmZpbGVzLmFwcGVuZChwb3NpeHBhdGguam9pbihzZWxmLnNlcnZlci5yb290LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0uZ2V0KCdzdGRlcnInLCcnKSkpCisgICAgICAgICAgICAgICAgYy5maWxlcy5hcHBlbmQocG9zaXhwYXRoLmpvaW4oc2VsZi5zZXJ2ZXIucm9vdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtLmdldCgnaW5mbycsJycpKSkKKyAgICAgICAgICAgICMgSnVzdCBpbiBjYXNlIHNvbWV0aGluZyBmYWlsZWQsIGlnbm9yZSBmaWxlcyB3aGljaCBkb24ndAorICAgICAgICAgICAgIyBleGlzdC4KKyAgICAgICAgICAgIGMuZmlsZXMgPSBbZiBmb3IgZiBpbiBjLmZpbGVzCisgICAgICAgICAgICAgICAgICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKGYpIGFuZCBvcy5wYXRoLmlzZmlsZShmKV0KKyAgICAgICAgZWxzZToKKyAgICAgICAgICAgICMgQ2hlY2sgdGhhdCB0aGlzIGlzIGEgdmFsaWQgcmVwb3J0LiAgICAgICAgICAgIAorICAgICAgICAgICAgcGF0aCA9IHBvc2l4cGF0aC5qb2luKHNlbGYuc2VydmVyLnJvb3QsICdyZXBvcnQtJXMuaHRtbCcgJSByZXBvcnQpCisgICAgICAgICAgICBpZiBub3QgcG9zaXhwYXRoLmV4aXN0cyhwYXRoKToKKyAgICAgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAnSW52YWxpZCByZXBvcnQgSUQnCisgICAgICAgICAgICBrZXlzID0gc2VsZi5sb2FkX3JlcG9ydChyZXBvcnQpCisgICAgICAgICAgICBjID0gQ29udGV4dCgpCisgICAgICAgICAgICBjLnRpdGxlID0ga2V5cy5nZXQoJ0RFU0MnLCdjbGFuZyBlcnJvciAodW5yZWNvZ25pemVkJykKKyAgICAgICAgICAgIGMuZGVzY3JpcHRpb24gPSAiIiJcCitCdWcgcmVwb3J0ZWQgYnkgdGhlIGNsYW5nIHN0YXRpYyBhbmFseXplci4KKworRGVzY3JpcHRpb246ICVzCitGaWxlOiAlcworTGluZTogJXMKKyIiIiUoYy50aXRsZSwga2V5cy5nZXQoJ0ZJTEUnLCc8dW5rbm93bj4nKSwga2V5cy5nZXQoJ0xJTkUnLCAnPHVua25vd24+JykpCisgICAgICAgICAgICBjLnJlcG9ydFNvdXJjZSA9ICdyZXBvcnQtJXMuaHRtbCcgJSByZXBvcnQKKyAgICAgICAgICAgIGMubmF2TWFya3VwID0gIiIiPGEgaHJlZj0iLyVzIj5SZXBvcnQgJXM8L2E+ID4gIiIiICUgKGMucmVwb3J0U291cmNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0KQorCisgICAgICAgICAgICBjLmZpbGVzID0gW3BhdGhdCisgICAgICAgIHJldHVybiBjCisKKyAgICBkZWYgc2VuZF9yZXBvcnQoc2VsZiwgcmVwb3J0LCBjb25maWdPdmVycmlkZXM9Tm9uZSk6CisgICAgICAgIGRlZiBnZXRDb25maWdPcHRpb24oc2VjdGlvbiwgZmllbGQpOiAgICAgICAgICAgIAorICAgICAgICAgICAgaWYgKGNvbmZpZ092ZXJyaWRlcyBpcyBub3QgTm9uZSBhbmQKKyAgICAgICAgICAgICAgICBzZWN0aW9uIGluIGNvbmZpZ092ZXJyaWRlcyBhbmQKKyAgICAgICAgICAgICAgICBmaWVsZCBpbiBjb25maWdPdmVycmlkZXNbc2VjdGlvbl0pOgorICAgICAgICAgICAgICAgIHJldHVybiBjb25maWdPdmVycmlkZXNbc2VjdGlvbl1bZmllbGRdCisgICAgICAgICAgICByZXR1cm4gc2VsZi5zZXJ2ZXIuY29uZmlnLmdldChzZWN0aW9uLCBmaWVsZCkKKworICAgICAgICAjIHJlcG9ydCBpcyBOb25lIGlzIHVzZWQgZm9yIGNyYXNoZXMKKyAgICAgICAgdHJ5OgorICAgICAgICAgICAgYyA9IHNlbGYuZ2V0X3JlcG9ydF9jb250ZXh0KHJlcG9ydCkKKyAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3IsIGU6CisgICAgICAgICAgICByZXR1cm4gc2VsZi5zZW5kX2Vycm9yKDQwMCwgZS5tZXNzYWdlKQorCisgICAgICAgIHRpdGxlID0gYy50aXRsZQorICAgICAgICBkZXNjcmlwdGlvbj0gYy5kZXNjcmlwdGlvbgorICAgICAgICByZXBvcnRpbmdGb3IgPSBjLm5hdk1hcmt1cAorICAgICAgICBpZiBjLnJlcG9ydFNvdXJjZSBpcyBOb25lOgorICAgICAgICAgICAgZXh0cmFJRnJhbWUgPSAiIgorICAgICAgICBlbHNlOgorICAgICAgICAgICAgZXh0cmFJRnJhbWUgPSAiIiJcCis8aWZyYW1lIHNyYz0iLyVzIiB3aWR0aD0iMTAwJSUiIGhlaWdodD0iNDAlJSIKKyAgICAgICAgc2Nyb2xsaW5nPSJhdXRvIiBmcmFtZWJvcmRlcj0iMSI+CisgIDxhIGhyZWY9Ii8lcyI+VmlldyBCdWcgUmVwb3J0PC9hPgorPC9pZnJhbWU+IiIiICUgKGMucmVwb3J0U291cmNlLCBjLnJlcG9ydFNvdXJjZSkKKworICAgICAgICByZXBvcnRlclNlbGVjdGlvbnMgPSBbXQorICAgICAgICByZXBvcnRlck9wdGlvbnMgPSBbXQorCisgICAgICAgIHRyeToKKyAgICAgICAgICAgIGFjdGl2ZSA9IGludChnZXRDb25maWdPcHRpb24oJ1NjYW5WaWV3JywncmVwb3J0ZXInKSkKKyAgICAgICAgZXhjZXB0OgorICAgICAgICAgICAgYWN0aXZlID0gMAorICAgICAgICBmb3IgaSxyIGluIGVudW1lcmF0ZShzZWxmLnNlcnZlci5yZXBvcnRlcnMpOgorICAgICAgICAgICAgc2VsZWN0ZWQgPSAoaSA9PSBhY3RpdmUpCisgICAgICAgICAgICBpZiBzZWxlY3RlZDoKKyAgICAgICAgICAgICAgICBzZWxlY3RlZFN0ciA9ICcgc2VsZWN0ZWQnCisgICAgICAgICAgICBlbHNlOgorICAgICAgICAgICAgICAgIHNlbGVjdGVkU3RyID0gJycKKyAgICAgICAgICAgIHJlcG9ydGVyU2VsZWN0aW9ucy5hcHBlbmQoJzxvcHRpb24gdmFsdWU9IiVkIiVzPiVzPC9vcHRpb24+JyUoaSxzZWxlY3RlZFN0cixyLmdldE5hbWUoKSkpCisgICAgICAgICAgICBvcHRpb25zID0gJ1xuJy5qb2luKFsgby5nZXRIVE1MKHIsdGl0bGUsZ2V0Q29uZmlnT3B0aW9uKSBmb3IgbyBpbiByLmdldFBhcmFtZXRlcnMoKV0pCisgICAgICAgICAgICBkaXNwbGF5ID0gKCdub25lJywnJylbc2VsZWN0ZWRdCisgICAgICAgICAgICByZXBvcnRlck9wdGlvbnMuYXBwZW5kKCIiIlwKKzx0ciBpZD0iJXNSZXBvcnRlck9wdGlvbnMiIHN0eWxlPSJkaXNwbGF5OiVzIj4KKyAgPHRkIGNsYXNzPSJmb3JtX2xhYmVsIj4lcyBPcHRpb25zPC90ZD4KKyAgPHRkIGNsYXNzPSJmb3JtX3ZhbHVlIj4KKyAgICA8dGFibGUgY2xhc3M9ImZvcm1faW5uZXJfZ3JvdXAiPgorJXMKKyAgICA8L3RhYmxlPgorICA8L3RkPgorPC90cj4KKyIiIiUoci5nZXROYW1lKCksZGlzcGxheSxyLmdldE5hbWUoKSxvcHRpb25zKSkKKyAgICAgICAgcmVwb3J0ZXJTZWxlY3Rpb25zID0gJ1xuJy5qb2luKHJlcG9ydGVyU2VsZWN0aW9ucykKKyAgICAgICAgcmVwb3J0ZXJPcHRpb25zRGl2cyA9ICdcbicuam9pbihyZXBvcnRlck9wdGlvbnMpCisgICAgICAgIHJlcG9ydGVyc0FycmF5ID0gJ1slc10nJSgnLCcuam9pbihbYHIuZ2V0TmFtZSgpYCBmb3IgciBpbiBzZWxmLnNlcnZlci5yZXBvcnRlcnNdKSkKKworICAgICAgICBpZiBjLmZpbGVzOgorICAgICAgICAgICAgZmllbGRTaXplID0gbWluKDUsIGxlbihjLmZpbGVzKSkKKyAgICAgICAgICAgIGF0dGFjaEZpbGVPcHRpb25zID0gJ1xuJy5qb2luKFsiIiJcCis8b3B0aW9uIHZhbHVlPSIlZCIgc2VsZWN0ZWQ+JXM8L29wdGlvbj4iIiIgJSAoaSx2KSBmb3IgaSx2IGluIGVudW1lcmF0ZShjLmZpbGVzKV0pCisgICAgICAgICAgICBhdHRhY2hGaWxlUm93ID0gIiIiXAorPHRyPgorICA8dGQgY2xhc3M9ImZvcm1fbGFiZWwiPkF0dGFjaDo8L3RkPgorICA8dGQgY2xhc3M9ImZvcm1fdmFsdWUiPgorPHNlbGVjdCBzdHlsZT0id2lkdGg6MTAwJSUiIG5hbWU9ImZpbGVzIiBtdWx0aXBsZSBzaXplPSVkPgorJXMKKzwvc2VsZWN0PgorICA8L3RkPgorPC90cj4KKyIiIiAlIChtaW4oNSwgbGVuKGMuZmlsZXMpKSwgYXR0YWNoRmlsZU9wdGlvbnMpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgICBhdHRhY2hGaWxlUm93ID0gIiIKKworICAgICAgICByZXN1bHQgPSAiIiI8aHRtbD4KKzxoZWFkPgorICA8dGl0bGU+RmlsZSBCdWc8L3RpdGxlPgorICA8bGluayByZWw9InN0eWxlc2hlZXQiIHR5cGU9InRleHQvY3NzIiBocmVmPSIvc2NhbnZpZXcuY3NzIiAvPgorPC9oZWFkPgorPHNjcmlwdCBsYW5ndWFnZT0iamF2YXNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij4KK3ZhciByZXBvcnRlcnMgPSAlKHJlcG9ydGVyc0FycmF5KXM7CitmdW5jdGlvbiB1cGRhdGVSZXBvcnRlck9wdGlvbnMoKSB7CisgIGluZGV4ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3JlcG9ydGVyJykuc2VsZWN0ZWRJbmRleDsKKyAgZm9yICh2YXIgaT0wOyBpIDwgcmVwb3J0ZXJzLmxlbmd0aDsgKytpKSB7CisgICAgbyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHJlcG9ydGVyc1tpXSArICJSZXBvcnRlck9wdGlvbnMiKTsKKyAgICBpZiAoaSA9PSBpbmRleCkgeworICAgICAgby5zdHlsZS5kaXNwbGF5ID0gIiI7CisgICAgfSBlbHNlIHsKKyAgICAgIG8uc3R5bGUuZGlzcGxheSA9ICJub25lIjsKKyAgICB9CisgIH0KK30KKzwvc2NyaXB0PgorPGJvZHkgb25Mb2FkPSJ1cGRhdGVSZXBvcnRlck9wdGlvbnMoKSI+Cis8aDM+Cis8YSBocmVmPSIvIj5TdW1tYXJ5PC9hPiA+IAorJShyZXBvcnRpbmdGb3IpcworRmlsZSBCdWc8L2gzPgorPGZvcm0gbmFtZT0iZm9ybSIgYWN0aW9uPSIvcmVwb3J0X3N1Ym1pdCIgbWV0aG9kPSJwb3N0Ij4KKzxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9InJlcG9ydCIgdmFsdWU9IiUocmVwb3J0KXMiPgorCis8dGFibGUgY2xhc3M9ImZvcm0iPgorPHRyPjx0ZD4KKzx0YWJsZSBjbGFzcz0iZm9ybV9ncm91cCI+Cis8dHI+CisgIDx0ZCBjbGFzcz0iZm9ybV9jbGFiZWwiPlRpdGxlOjwvdGQ+CisgIDx0ZCBjbGFzcz0iZm9ybV92YWx1ZSI+CisgICAgPGlucHV0IHR5cGU9InRleHQiIG5hbWU9InRpdGxlIiBzaXplPSI1MCIgdmFsdWU9IiUodGl0bGUpcyI+CisgIDwvdGQ+Cis8L3RyPgorPHRyPgorICA8dGQgY2xhc3M9ImZvcm1fbGFiZWwiPkRlc2NyaXB0aW9uOjwvdGQ+CisgIDx0ZCBjbGFzcz0iZm9ybV92YWx1ZSI+Cis8dGV4dGFyZWEgcm93cz0iMTAiIGNvbHM9IjgwIiBuYW1lPSJkZXNjcmlwdGlvbiI+CislKGRlc2NyaXB0aW9uKXMKKzwvdGV4dGFyZWE+CisgIDwvdGQ+Cis8L3RyPgorCislKGF0dGFjaEZpbGVSb3cpcworCis8L3RhYmxlPgorPGJyPgorPHRhYmxlIGNsYXNzPSJmb3JtX2dyb3VwIj4KKzx0cj4KKyAgPHRkIGNsYXNzPSJmb3JtX2NsYWJlbCI+TWV0aG9kOjwvdGQ+CisgIDx0ZCBjbGFzcz0iZm9ybV92YWx1ZSI+CisgICAgPHNlbGVjdCBpZD0icmVwb3J0ZXIiIG5hbWU9InJlcG9ydGVyIiBvbkNoYW5nZT0idXBkYXRlUmVwb3J0ZXJPcHRpb25zKCkiPgorICAgICUocmVwb3J0ZXJTZWxlY3Rpb25zKXMKKyAgICA8L3NlbGVjdD4KKyAgPC90ZD4KKzwvdHI+CislKHJlcG9ydGVyT3B0aW9uc0RpdnMpcworPC90YWJsZT4KKzxicj4KKzwvdGQ+PC90cj4KKzx0cj48dGQgY2xhc3M9ImZvcm1fc3VibWl0Ij4KKyAgPGlucHV0IGFsaWduPSJyaWdodCIgdHlwZT0ic3VibWl0IiBuYW1lPSJTdWJtaXQiIHZhbHVlPSJTdWJtaXQiPgorPC90ZD48L3RyPgorPC90YWJsZT4KKzwvZm9ybT4KKworJShleHRyYUlGcmFtZSlzCisKKzwvYm9keT4KKzwvaHRtbD4iIiIlbG9jYWxzKCkKKworICAgICAgICByZXR1cm4gc2VsZi5zZW5kX3N0cmluZyhyZXN1bHQpCisKKyAgICBkZWYgc2VuZF9oZWFkKHNlbGYsIGZpZWxkcz1Ob25lKToKKyAgICAgICAgaWYgKHNlbGYuc2VydmVyLm9wdGlvbnMub25seVNlcnZlTG9jYWwgYW5kCisgICAgICAgICAgICBzZWxmLmNsaWVudF9hZGRyZXNzWzBdICE9ICcxMjcuMC4wLjEnKToKKyAgICAgICAgICAgIHJldHVybiBzZWxmLnNlbmRfZXJyb3IoNDAxLCAnVW5hdXRob3JpemVkIGhvc3QuJykKKworICAgICAgICBpZiBmaWVsZHMgaXMgTm9uZToKKyAgICAgICAgICAgIGZpZWxkcyA9IHt9CisgICAgICAgIHNlbGYuZmllbGRzID0gZmllbGRzCisKKyAgICAgICAgbyA9IHVybHBhcnNlLnVybHBhcnNlKHNlbGYucGF0aCkKKyAgICAgICAgc2VsZi5maWVsZHMgPSBwYXJzZV9xdWVyeShvLnF1ZXJ5LCBmaWVsZHMpCisgICAgICAgIHBhdGggPSBwb3NpeHBhdGgubm9ybXBhdGgodXJsbGliLnVucXVvdGUoby5wYXRoKSkKKworICAgICAgICAjIFNwbGl0IHRoZSBjb21wb25lbnRzIGFuZCBzdHJpcCB0aGUgcm9vdCBwcmVmaXguCisgICAgICAgIGNvbXBvbmVudHMgPSBwYXRoLnNwbGl0KCcvJylbMTpdCisgICAgICAgIAorICAgICAgICAjIFNwZWNpYWwgY2FzZSBzb21lIHRvcC1sZXZlbCBlbnRyaWVzLgorICAgICAgICBpZiBjb21wb25lbnRzOgorICAgICAgICAgICAgbmFtZSA9IGNvbXBvbmVudHNbMF0KKyAgICAgICAgICAgIGlmIGxlbihjb21wb25lbnRzKT09MjoKKyAgICAgICAgICAgICAgICBpZiBuYW1lPT0ncmVwb3J0JzoKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYuc2VuZF9yZXBvcnQoY29tcG9uZW50c1sxXSkKKyAgICAgICAgICAgICAgICBlbGlmIG5hbWU9PSdvcGVuJzoKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYuc2VuZF9vcGVuX3JlcG9ydChjb21wb25lbnRzWzFdKQorICAgICAgICAgICAgZWxpZiBsZW4oY29tcG9uZW50cyk9PTE6CisgICAgICAgICAgICAgICAgaWYgbmFtZT09J3F1aXQnOgorICAgICAgICAgICAgICAgICAgICBzZWxmLnNlcnZlci5oYWx0KCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYuc2VuZF9zdHJpbmcoJ0dvb2RieWUuJywgJ3RleHQvcGxhaW4nKQorICAgICAgICAgICAgICAgIGVsaWYgbmFtZT09J3JlcG9ydF9zdWJtaXQnOgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2VsZi5zZW5kX3JlcG9ydF9zdWJtaXQoKQorICAgICAgICAgICAgICAgIGVsaWYgbmFtZT09J3JlcG9ydF9jcmFzaGVzJzoKKyAgICAgICAgICAgICAgICAgICAgb3ZlcnJpZGVzID0geyAnU2NhblZpZXcnIDoge30sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1JhZGFyJyA6IHt9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdFbWFpbCcgOiB7fSB9CisgICAgICAgICAgICAgICAgICAgIGZvciBpLHIgaW4gZW51bWVyYXRlKHNlbGYuc2VydmVyLnJlcG9ydGVycyk6CisgICAgICAgICAgICAgICAgICAgICAgICBpZiByLmdldE5hbWUoKSA9PSAnUmFkYXInOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJyaWRlc1snU2NhblZpZXcnXVsncmVwb3J0ZXInXSA9IGkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaworICAgICAgICAgICAgICAgICAgICBvdmVycmlkZXNbJ1JhZGFyJ11bJ0NvbXBvbmVudCddID0gJ2xsdm0gLSBjaGVja2VyJworICAgICAgICAgICAgICAgICAgICBvdmVycmlkZXNbJ1JhZGFyJ11bJ0NvbXBvbmVudCBWZXJzaW9uJ10gPSAnWCcKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYuc2VuZF9yZXBvcnQoTm9uZSwgb3ZlcnJpZGVzKQorICAgICAgICAgICAgICAgIGVsaWYgbmFtZT09J2Zhdmljb24uaWNvJzoKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYuc2VuZF9wYXRoKHBvc2l4cGF0aC5qb2luKGtSZXNvdXJjZXMsJ2J1Z2NhdGNoZXIuaWNvJykpCisgICAgICAgIAorICAgICAgICAjIE1hdGNoIGRpcmVjdG9yeSBlbnRyaWVzLgorICAgICAgICBpZiBjb21wb25lbnRzWy0xXSA9PSAnJzoKKyAgICAgICAgICAgIGNvbXBvbmVudHNbLTFdID0gJ2luZGV4Lmh0bWwnCisKKyAgICAgICAgcmVscGF0aCA9ICcvJy5qb2luKGNvbXBvbmVudHMpCisgICAgICAgIHBhdGggPSBwb3NpeHBhdGguam9pbihzZWxmLnNlcnZlci5yb290LCByZWxwYXRoKQorCisgICAgICAgIGlmIHNlbGYuc2VydmVyLm9wdGlvbnMuZGVidWcgPiAxOgorICAgICAgICAgICAgcHJpbnQgPj5zeXMuc3RkZXJyLCAnJXM6IFNFUlZFUjogc2VuZGluZyBwYXRoICIlcyInJShzeXMuYXJndlswXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aCkKKyAgICAgICAgcmV0dXJuIHNlbGYuc2VuZF9wYXRoKHBhdGgpCisKKyAgICBkZWYgc2VuZF80MDQoc2VsZik6CisgICAgICAgIHNlbGYuc2VuZF9lcnJvcig0MDQsICJGaWxlIG5vdCBmb3VuZCIpCisgICAgICAgIHJldHVybiBOb25lCisKKyAgICBkZWYgc2VuZF9wYXRoKHNlbGYsIHBhdGgpOgorICAgICAgICAjIElmIHRoZSByZXF1ZXN0ZWQgcGF0aCBpcyBvdXRzaWRlIHRoZSByb290IGRpcmVjdG9yeSwgZG8gbm90IG9wZW4gaXQKKyAgICAgICAgcmVsID0gb3MucGF0aC5hYnNwYXRoKHBhdGgpCisgICAgICAgIGlmIG5vdCByZWwuc3RhcnRzd2l0aChvcy5wYXRoLmFic3BhdGgoc2VsZi5zZXJ2ZXIucm9vdCkpOgorICAgICAgICAgIHJldHVybiBzZWxmLnNlbmRfNDA0KCkKKyAgICAgICAgCisgICAgICAgIGN0eXBlID0gc2VsZi5ndWVzc190eXBlKHBhdGgpCisgICAgICAgIGlmIGN0eXBlLnN0YXJ0c3dpdGgoJ3RleHQvJyk6CisgICAgICAgICAgICAjIFBhdGNoIGZpbGUgaW5zdGVhZAorICAgICAgICAgICAgcmV0dXJuIHNlbGYuc2VuZF9wYXRjaGVkX2ZpbGUocGF0aCwgY3R5cGUpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgICBtb2RlID0gJ3JiJworICAgICAgICB0cnk6CisgICAgICAgICAgICBmID0gb3BlbihwYXRoLCBtb2RlKQorICAgICAgICBleGNlcHQgSU9FcnJvcjoKKyAgICAgICAgICAgIHJldHVybiBzZWxmLnNlbmRfNDA0KCkKKyAgICAgICAgcmV0dXJuIHNlbGYuc2VuZF9maWxlKGYsIGN0eXBlKQorCisgICAgZGVmIHNlbmRfZmlsZShzZWxmLCBmLCBjdHlwZSk6CisgICAgICAgICMgUGF0Y2ggZmlsZXMgdG8gYWRkIGxpbmtzLCBidXQgc2tpcCBiaW5hcnkgZmlsZXMuCisgICAgICAgIHNlbGYuc2VuZF9yZXNwb25zZSgyMDApCisgICAgICAgIHNlbGYuc2VuZF9oZWFkZXIoIkNvbnRlbnQtdHlwZSIsIGN0eXBlKQorICAgICAgICBmcyA9IG9zLmZzdGF0KGYuZmlsZW5vKCkpCisgICAgICAgIHNlbGYuc2VuZF9oZWFkZXIoIkNvbnRlbnQtTGVuZ3RoIiwgc3RyKGZzWzZdKSkKKyAgICAgICAgc2VsZi5zZW5kX2hlYWRlcigiTGFzdC1Nb2RpZmllZCIsIHNlbGYuZGF0ZV90aW1lX3N0cmluZyhmcy5zdF9tdGltZSkpCisgICAgICAgIHNlbGYuZW5kX2hlYWRlcnMoKQorICAgICAgICByZXR1cm4gZgorCisgICAgZGVmIHNlbmRfc3RyaW5nKHNlbGYsIHMsIGN0eXBlPSd0ZXh0L2h0bWwnLCBoZWFkZXJzPVRydWUsIG10aW1lPU5vbmUpOgorICAgICAgICBpZiBoZWFkZXJzOgorICAgICAgICAgICAgc2VsZi5zZW5kX3Jlc3BvbnNlKDIwMCkKKyAgICAgICAgICAgIHNlbGYuc2VuZF9oZWFkZXIoIkNvbnRlbnQtdHlwZSIsIGN0eXBlKQorICAgICAgICAgICAgc2VsZi5zZW5kX2hlYWRlcigiQ29udGVudC1MZW5ndGgiLCBzdHIobGVuKHMpKSkKKyAgICAgICAgICAgIGlmIG10aW1lIGlzIE5vbmU6CisgICAgICAgICAgICAgICAgbXRpbWUgPSBzZWxmLmR5bmFtaWNfbXRpbWUKKyAgICAgICAgICAgIHNlbGYuc2VuZF9oZWFkZXIoIkxhc3QtTW9kaWZpZWQiLCBzZWxmLmRhdGVfdGltZV9zdHJpbmcobXRpbWUpKQorICAgICAgICAgICAgc2VsZi5lbmRfaGVhZGVycygpCisgICAgICAgIHJldHVybiBTdHJpbmdJTy5TdHJpbmdJTyhzKQorCisgICAgZGVmIHNlbmRfcGF0Y2hlZF9maWxlKHNlbGYsIHBhdGgsIGN0eXBlKToKKyAgICAgICAgIyBBbGxvdyBhIHZlcnkgbGltaXRlZCBzZXQgb2YgdmFyaWFibGVzLiBUaGlzIGlzIHByZXR0eSBncm9zcy4KKyAgICAgICAgdmFyaWFibGVzID0ge30KKyAgICAgICAgdmFyaWFibGVzWydyZXBvcnQnXSA9ICcnCisgICAgICAgIG0gPSBrUmVwb3J0RmlsZVJFLm1hdGNoKHBhdGgpCisgICAgICAgIGlmIG06CisgICAgICAgICAgICB2YXJpYWJsZXNbJ3JlcG9ydCddID0gbS5ncm91cCgyKQorCisgICAgICAgIHRyeToKKyAgICAgICAgICAgIGYgPSBvcGVuKHBhdGgsJ3InKQorICAgICAgICBleGNlcHQgSU9FcnJvcjoKKyAgICAgICAgICAgIHJldHVybiBzZWxmLnNlbmRfNDA0KCkKKyAgICAgICAgZnMgPSBvcy5mc3RhdChmLmZpbGVubygpKQorICAgICAgICBkYXRhID0gZi5yZWFkKCkKKyAgICAgICAgZm9yIGEsYiBpbiBrUmVwb3J0UmVwbGFjZW1lbnRzOgorICAgICAgICAgICAgZGF0YSA9IGEuc3ViKGIgJSB2YXJpYWJsZXMsIGRhdGEpCisgICAgICAgIHJldHVybiBzZWxmLnNlbmRfc3RyaW5nKGRhdGEsIGN0eXBlLCBtdGltZT1mcy5zdF9tdGltZSkKKworCitkZWYgY3JlYXRlX3NlcnZlcihhZGRyZXNzLCBvcHRpb25zLCByb290KToKKyAgICBpbXBvcnQgUmVwb3J0ZXIKKworICAgIHJlcG9ydGVycyA9IFJlcG9ydGVyLmdldFJlcG9ydGVycygpCisKKyAgICByZXR1cm4gU2NhblZpZXdTZXJ2ZXIoYWRkcmVzcywgU2NhblZpZXdSZXF1ZXN0SGFuZGxlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgcm9vdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0ZXJzLAorICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zKQpkaWZmIC0tZ2l0IGEvdG9vbHMvc2Nhbi12aWV3L3NjYW4tdmlldyBiL3Rvb2xzL3NjYW4tdmlldy9zY2FuLXZpZXcKbmV3IGZpbGUgbW9kZSAxMDA3NTUKaW5kZXggMDAwMDAwMC4uZmIyN2RhNgotLS0gL2Rldi9udWxsCisrKyBiL3Rvb2xzL3NjYW4tdmlldy9zY2FuLXZpZXcKQEAgLTAsMCArMSwxMzEgQEAKKyMhL3Vzci9iaW4vZW52IHB5dGhvbgorCisiIiJUaGUgY2xhbmcgc3RhdGljIGFuYWx5emVyIHJlc3VsdHMgdmlld2VyLgorIiIiCisKK2ltcG9ydCBzeXMKK2ltcG9ydCBwb3NpeHBhdGgKK2ltcG9ydCB0aHJlYWQKK2ltcG9ydCB0aW1lCitpbXBvcnQgdXJsbGliCitpbXBvcnQgd2ViYnJvd3NlcgorCisjIEhvdyBsb25nIHRvIHdhaXQgZm9yIHNlcnZlciB0byBzdGFydC4KK2tTbGVlcFRpbWVvdXQgPSAuMDUKK2tNYXhTbGVlcHMgPSBpbnQoNjAgLyBrU2xlZXBUaW1lb3V0KQorCisjIERlZmF1bHQgc2VydmVyIHBhcmFtZXRlcnMKKwora0RlZmF1bHRIb3N0ID0gJzEyNy4wLjAuMScKK2tEZWZhdWx0UG9ydCA9IDgxODEKK2tNYXhQb3J0c1RvVHJ5ID0gMTAwCisKKyMjIworCitkZWYgdXJsX2lzX3VwKHVybCk6CisgICAgdHJ5OgorICAgICAgICBvID0gdXJsbGliLnVybG9wZW4odXJsKQorICAgIGV4Y2VwdCBJT0Vycm9yOgorICAgICAgICByZXR1cm4gRmFsc2UKKyAgICBvLmNsb3NlKCkKKyAgICByZXR1cm4gVHJ1ZQorCitkZWYgc3RhcnRfYnJvd3Nlcihwb3J0LCBvcHRpb25zKToKKyAgICBpbXBvcnQgdXJsbGliLCB3ZWJicm93c2VyCisKKyAgICB1cmwgPSAnaHR0cDovLyVzOiVkJyUob3B0aW9ucy5ob3N0LCBwb3J0KQorICAgIAorICAgICMgV2FpdCBmb3Igc2VydmVyIHRvIHN0YXJ0Li4uCisgICAgaWYgb3B0aW9ucy5kZWJ1ZzoKKyAgICAgICAgc3lzLnN0ZGVyci53cml0ZSgnJXM6IFdhaXRpbmcgZm9yIHNlcnZlci4nICUgc3lzLmFyZ3ZbMF0pCisgICAgICAgIHN5cy5zdGRlcnIuZmx1c2goKQorICAgIGZvciBpIGluIHJhbmdlKGtNYXhTbGVlcHMpOgorICAgICAgICBpZiB1cmxfaXNfdXAodXJsKToKKyAgICAgICAgICAgIGJyZWFrCisgICAgICAgIGlmIG9wdGlvbnMuZGVidWc6CisgICAgICAgICAgICBzeXMuc3RkZXJyLndyaXRlKCcuJykKKyAgICAgICAgICAgIHN5cy5zdGRlcnIuZmx1c2goKQorICAgICAgICB0aW1lLnNsZWVwKGtTbGVlcFRpbWVvdXQpCisgICAgZWxzZToKKyAgICAgICAgcHJpbnQgPj5zeXMuc3RkZXJyLCdXQVJOSU5HOiBVbmFibGUgdG8gZGV0ZWN0IHRoYXQgc2VydmVyIHN0YXJ0ZWQuJworCisgICAgaWYgb3B0aW9ucy5kZWJ1ZzoKKyAgICAgICAgcHJpbnQgPj5zeXMuc3RkZXJyLCclczogU3RhcnRpbmcgd2ViYnJvd3Nlci4uLicgJSBzeXMuYXJndlswXQorICAgIHdlYmJyb3dzZXIub3Blbih1cmwpCisKK2RlZiBydW4ocG9ydCwgb3B0aW9ucywgcm9vdCk6CisgICAgaW1wb3J0IFNjYW5WaWV3CisgICAgdHJ5OgorICAgICAgICBwcmludCAnU3RhcnRpbmcgc2Nhbi12aWV3IGF0OiBodHRwOi8vJXM6JWQnJShvcHRpb25zLmhvc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcnQpCisgICAgICAgIHByaW50ICcgIFVzZSBDdHJsLUMgdG8gZXhpdC4nCisgICAgICAgIGh0dHBkID0gU2NhblZpZXcuY3JlYXRlX3NlcnZlcigob3B0aW9ucy5ob3N0LCBwb3J0KSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMsIHJvb3QpCisgICAgICAgIGh0dHBkLnNlcnZlX2ZvcmV2ZXIoKQorICAgIGV4Y2VwdCBLZXlib2FyZEludGVycnVwdDoKKyAgICAgICAgcGFzcworCitkZWYgcG9ydF9pc19vcGVuKHBvcnQpOgorICAgIGltcG9ydCBTb2NrZXRTZXJ2ZXIKKyAgICB0cnk6CisgICAgICAgIHQgPSBTb2NrZXRTZXJ2ZXIuVENQU2VydmVyKChrRGVmYXVsdEhvc3QscG9ydCksTm9uZSkKKyAgICBleGNlcHQ6CisgICAgICAgIHJldHVybiBGYWxzZQorICAgIHQuc2VydmVyX2Nsb3NlKCkKKyAgICByZXR1cm4gVHJ1ZQorCitkZWYgbWFpbigpOiAgICAKKyAgICBmcm9tIG9wdHBhcnNlIGltcG9ydCBPcHRpb25QYXJzZXIKKyAgICBwYXJzZXIgPSBPcHRpb25QYXJzZXIoJ3VzYWdlOiAlcHJvZyBbb3B0aW9uc10gPHJlc3VsdHMgZGlyZWN0b3J5PicpCisgICAgcGFyc2VyLnNldF9kZXNjcmlwdGlvbihfX2RvY19fKQorICAgIHBhcnNlci5hZGRfb3B0aW9uKAorICAgICAgICAnLS1ob3N0JywgZGVzdD0iaG9zdCIsIGRlZmF1bHQ9a0RlZmF1bHRIb3N0LCB0eXBlPSJzdHJpbmciLAorICAgICAgICBoZWxwPSJIb3N0IGludGVyZmFjZSB0byBsaXN0ZW4gb24uIChkZWZhdWx0PSVzKSIgJSBrRGVmYXVsdEhvc3QpCisgICAgcGFyc2VyLmFkZF9vcHRpb24oCisgICAgICAgICctLXBvcnQnLCBkZXN0PSJwb3J0IiwgZGVmYXVsdD1Ob25lLCB0eXBlPSJpbnQiLAorICAgICAgICBoZWxwPSJQb3J0IHRvIGxpc3RlbiBvbi4gKGRlZmF1bHQ9JXMpIiAlIGtEZWZhdWx0UG9ydCkKKyAgICBwYXJzZXIuYWRkX29wdGlvbigiLS1kZWJ1ZyIsIGRlc3Q9ImRlYnVnIiwgZGVmYXVsdD0wLCAKKyAgICAgICAgICAgICAgICAgICAgICBhY3Rpb249ImNvdW50IiwKKyAgICAgICAgICAgICAgICAgICAgICBoZWxwPSJQcmludCBhZGRpdGlvbmFsIGRlYnVnZ2luZyBpbmZvcm1hdGlvbi4iKQorICAgIHBhcnNlci5hZGRfb3B0aW9uKCItLWF1dG8tcmVsb2FkIiwgZGVzdD0iYXV0b1JlbG9hZCIsIGRlZmF1bHQ9RmFsc2UsIAorICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbj0ic3RvcmVfdHJ1ZSIsCisgICAgICAgICAgICAgICAgICAgICAgaGVscD0iQXV0b21hdGljYWxseSB1cGRhdGUgbW9kdWxlIGZvciBlYWNoIHJlcXVlc3QuIikKKyAgICBwYXJzZXIuYWRkX29wdGlvbigiLS1uby1icm93c2VyIiwgZGVzdD0ic3RhcnRCcm93c2VyIiwgZGVmYXVsdD1UcnVlLCAKKyAgICAgICAgICAgICAgICAgICAgICBhY3Rpb249InN0b3JlX2ZhbHNlIiwKKyAgICAgICAgICAgICAgICAgICAgICBoZWxwPSJEb24ndCBvcGVuIGEgd2ViYnJvd3NlciBvbiBzdGFydHVwLiIpCisgICAgcGFyc2VyLmFkZF9vcHRpb24oIi0tYWxsb3ctYWxsLWhvc3RzIiwgZGVzdD0ib25seVNlcnZlTG9jYWwiLCBkZWZhdWx0PVRydWUsIAorICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbj0ic3RvcmVfZmFsc2UiLAorICAgICAgICAgICAgICAgICAgICAgIGhlbHA9J0FsbG93IGNvbm5lY3Rpb25zIGZyb20gYW55IGhvc3QgKGFjY2VzcyByZXN0cmljdGVkIHRvICIxMjcuMC4wLjEiIGJ5IGRlZmF1bHQpJykKKyAgICAob3B0aW9ucywgYXJncykgPSBwYXJzZXIucGFyc2VfYXJncygpCisKKyAgICBpZiBsZW4oYXJncykgIT0gMToKKyAgICAgICAgcGFyc2VyLmVycm9yKCdObyByZXN1bHRzIGRpcmVjdG9yeSBzcGVjaWZpZWQuJykKKyAgICByb290LCA9IGFyZ3MKKworICAgICMgTWFrZSBzdXJlIHRoaXMgZGlyZWN0b3J5IGlzIGluIGEgcmVhc29uYWJsZSBzdGF0ZSB0byB2aWV3LgorICAgIGlmIG5vdCBwb3NpeHBhdGguZXhpc3RzKHBvc2l4cGF0aC5qb2luKHJvb3QsJ2luZGV4Lmh0bWwnKSk6CisgICAgICAgIHBhcnNlci5lcnJvcignSW52YWxpZCBkaXJlY3RvcnksIGFuYWx5c2lzIHJlc3VsdHMgbm90IGZvdW5kIScpCisKKyAgICAjIEZpbmQgYW4gb3BlbiBwb3J0LiBXZSBhcmVuJ3QgcGFydGljdWxhcmx5IHdvcnJpZWQgYWJvdXQgcmFjZQorICAgICMgY29uZGl0aW9ucyBoZXJlLiBOb3RlIHRoYXQgaWYgdGhlIHVzZXIgc3BlY2lmaWVkIGEgcG9ydCB3ZSBvbmx5CisgICAgIyB1c2UgdGhhdCBvbmUuCisgICAgaWYgb3B0aW9ucy5wb3J0IGlzIG5vdCBOb25lOgorICAgICAgICBwb3J0ID0gb3B0aW9ucy5wb3J0CisgICAgZWxzZTogICAgCisgICAgICAgIGZvciBpIGluIHJhbmdlKGtNYXhQb3J0c1RvVHJ5KToKKyAgICAgICAgICAgIGlmIHBvcnRfaXNfb3BlbihrRGVmYXVsdFBvcnQgKyBpKToKKyAgICAgICAgICAgICAgICBwb3J0ID0ga0RlZmF1bHRQb3J0ICsgaQorICAgICAgICAgICAgICAgIGJyZWFrCisgICAgICAgIGVsc2U6CisgICAgICAgICAgICBwYXJzZXIuZXJyb3IoJ1VuYWJsZSB0byBmaW5kIHVzYWJsZSBwb3J0IGluIFslZCwlZCknJShrRGVmYXVsdFBvcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrRGVmYXVsdFBvcnQra01heFBvcnRzVG9UcnkpKQorCisgICAgIyBLaWNrIG9mZiB0aHJlYWQgdG8gd2FpdCBmb3Igc2VydmVyIGFuZCBzdGFydCB3ZWIgYnJvd3NlciwgaWYKKyAgICAjIHJlcXVlc3RlZC4KKyAgICBpZiBvcHRpb25zLnN0YXJ0QnJvd3NlcjoKKyAgICAgICAgdCA9IHRocmVhZC5zdGFydF9uZXdfdGhyZWFkKHN0YXJ0X2Jyb3dzZXIsIChwb3J0LG9wdGlvbnMpKQorCisgICAgcnVuKHBvcnQsIG9wdGlvbnMsIHJvb3QpCisKK2lmIF9fbmFtZV9fID09ICdfX21haW5fXyc6CisgICAgbWFpbigpCmRpZmYgLS1naXQgYS90b29scy9zY2FuLXZpZXcvc3RhcnRmaWxlLnB5IGIvdG9vbHMvc2Nhbi12aWV3L3N0YXJ0ZmlsZS5weQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lOGZiZTJkCi0tLSAvZGV2L251bGwKKysrIGIvdG9vbHMvc2Nhbi12aWV3L3N0YXJ0ZmlsZS5weQpAQCAtMCwwICsxLDIwMyBAQAorIiIiVXRpbGl0eSBmb3Igb3BlbmluZyBhIGZpbGUgdXNpbmcgdGhlIGRlZmF1bHQgYXBwbGljYXRpb24gaW4gYSBjcm9zcy1wbGF0Zm9ybQorbWFubmVyLiBNb2RpZmllZCBmcm9tIGh0dHA6Ly9jb2RlLmFjdGl2ZXN0YXRlLmNvbS9yZWNpcGVzLzUxMTQ0My8uCisiIiIKKworX192ZXJzaW9uX18gPSAnMS4xeCcKK19fYWxsX18gPSBbJ29wZW4nXQorCitpbXBvcnQgb3MKK2ltcG9ydCBzeXMKK2ltcG9ydCB3ZWJicm93c2VyCitpbXBvcnQgc3VicHJvY2VzcworCitfY29udHJvbGxlcnMgPSB7fQorX29wZW4gPSBOb25lCisKKworY2xhc3MgQmFzZUNvbnRyb2xsZXIob2JqZWN0KToKKyAgICAnJydCYXNlIGNsYXNzIGZvciBvcGVuIHByb2dyYW0gY29udHJvbGxlcnMuJycnCisKKyAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSk6CisgICAgICAgIHNlbGYubmFtZSA9IG5hbWUKKworICAgIGRlZiBvcGVuKHNlbGYsIGZpbGVuYW1lKToKKyAgICAgICAgcmFpc2UgTm90SW1wbGVtZW50ZWRFcnJvcgorCisKK2NsYXNzIENvbnRyb2xsZXIoQmFzZUNvbnRyb2xsZXIpOgorICAgICcnJ0NvbnRyb2xsZXIgZm9yIGEgZ2VuZXJpYyBvcGVuIHByb2dyYW0uJycnCisKKyAgICBkZWYgX19pbml0X18oc2VsZiwgKmFyZ3MpOgorICAgICAgICBzdXBlcihDb250cm9sbGVyLCBzZWxmKS5fX2luaXRfXyhvcy5wYXRoLmJhc2VuYW1lKGFyZ3NbMF0pKQorICAgICAgICBzZWxmLmFyZ3MgPSBsaXN0KGFyZ3MpCisKKyAgICBkZWYgX2ludm9rZShzZWxmLCBjbWRsaW5lKToKKyAgICAgICAgaWYgc3lzLnBsYXRmb3JtWzozXSA9PSAnd2luJzoKKyAgICAgICAgICAgIGNsb3NlZmRzID0gRmFsc2UKKyAgICAgICAgICAgIHN0YXJ0dXBpbmZvID0gc3VicHJvY2Vzcy5TVEFSVFVQSU5GTygpCisgICAgICAgICAgICBzdGFydHVwaW5mby5kd0ZsYWdzIHw9IHN1YnByb2Nlc3MuU1RBUlRGX1VTRVNIT1dXSU5ET1cKKyAgICAgICAgZWxzZToKKyAgICAgICAgICAgIGNsb3NlZmRzID0gVHJ1ZQorICAgICAgICAgICAgc3RhcnR1cGluZm8gPSBOb25lCisKKyAgICAgICAgaWYgKG9zLmVudmlyb24uZ2V0KCdESVNQTEFZJykgb3Igc3lzLnBsYXRmb3JtWzozXSA9PSAnd2luJyBvcgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5cy5wbGF0Zm9ybSA9PSAnZGFyd2luJyk6CisgICAgICAgICAgICBpbm91dCA9IGZpbGUob3MuZGV2bnVsbCwgJ3IrJykKKyAgICAgICAgZWxzZToKKyAgICAgICAgICAgICMgZm9yIFRUWSBwcm9ncmFtcywgd2UgbmVlZCBzdGRpbi9vdXQKKyAgICAgICAgICAgIGlub3V0ID0gTm9uZQorCisgICAgICAgICMgaWYgcG9zc2libGUsIHB1dCB0aGUgY2hpbGQgcHJlY2VzcyBpbiBzZXBhcmF0ZSBwcm9jZXNzIGdyb3VwLAorICAgICAgICAjIHNvIGtleWJvYXJkIGludGVycnVwdHMgZG9uJ3QgYWZmZWN0IGNoaWxkIHByZWNlc3MgYXMgd2VsbCBhcworICAgICAgICAjIFB5dGhvbgorICAgICAgICBzZXRzaWQgPSBnZXRhdHRyKG9zLCAnc2V0c2lkJywgTm9uZSkKKyAgICAgICAgaWYgbm90IHNldHNpZDoKKyAgICAgICAgICAgIHNldHNpZCA9IGdldGF0dHIob3MsICdzZXRwZ3JwJywgTm9uZSkKKworICAgICAgICBwaXBlID0gc3VicHJvY2Vzcy5Qb3BlbihjbWRsaW5lLCBzdGRpbj1pbm91dCwgc3Rkb3V0PWlub3V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGRlcnI9aW5vdXQsIGNsb3NlX2Zkcz1jbG9zZWZkcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZXhlY19mbj1zZXRzaWQsIHN0YXJ0dXBpbmZvPXN0YXJ0dXBpbmZvKQorCisgICAgICAgICMgSXQgaXMgYXNzdW1lZCB0aGF0IHRoaXMga2luZCBvZiB0b29scyAoZ25vbWUtb3Blbiwga2ZtY2xpZW50LAorICAgICAgICAjIGV4by1vcGVuLCB4ZGctb3BlbiBhbmQgb3BlbiBmb3IgT1NYKSBpbW1lZGlhdGVseSBleGl0IGFmdGVyIGxhdWNoaW5nCisgICAgICAgICMgdGhlIHNwZWNpZmljIGFwcGxpY2F0aW9uCisgICAgICAgIHJldHVybmNvZGUgPSBwaXBlLndhaXQoKQorICAgICAgICBpZiBoYXNhdHRyKHNlbGYsICdmaXhyZXR1cm5jb2RlJyk6CisgICAgICAgICAgICByZXR1cm5jb2RlID0gc2VsZi5maXhyZXR1cm5jb2RlKHJldHVybmNvZGUpCisgICAgICAgIHJldHVybiBub3QgcmV0dXJuY29kZQorCisgICAgZGVmIG9wZW4oc2VsZiwgZmlsZW5hbWUpOgorICAgICAgICBpZiBpc2luc3RhbmNlKGZpbGVuYW1lLCBiYXNlc3RyaW5nKToKKyAgICAgICAgICAgIGNtZGxpbmUgPSBzZWxmLmFyZ3MgKyBbZmlsZW5hbWVdCisgICAgICAgIGVsc2U6CisgICAgICAgICAgICAjIGFzc3VtZSBpdCBpcyBhIHNlcXVlbmNlCisgICAgICAgICAgICBjbWRsaW5lID0gc2VsZi5hcmdzICsgZmlsZW5hbWUKKyAgICAgICAgdHJ5OgorICAgICAgICAgICAgcmV0dXJuIHNlbGYuX2ludm9rZShjbWRsaW5lKQorICAgICAgICBleGNlcHQgT1NFcnJvcjoKKyAgICAgICAgICAgIHJldHVybiBGYWxzZQorCisKKyMgUGxhdGZvcm0gc3VwcG9ydCBmb3IgV2luZG93cworaWYgc3lzLnBsYXRmb3JtWzozXSA9PSAnd2luJzoKKworICAgIGNsYXNzIFN0YXJ0KEJhc2VDb250cm9sbGVyKToKKyAgICAgICAgJycnQ29udHJvbGxlciBmb3IgdGhlIHdpbjMyIHN0YXJ0IHByb2dhbSB0aHJvdWdoIG9zLnN0YXJ0ZmlsZS4nJycKKworICAgICAgICBkZWYgb3BlbihzZWxmLCBmaWxlbmFtZSk6CisgICAgICAgICAgICB0cnk6CisgICAgICAgICAgICAgICAgb3Muc3RhcnRmaWxlKGZpbGVuYW1lKQorICAgICAgICAgICAgZXhjZXB0IFdpbmRvd3NFcnJvcjoKKyAgICAgICAgICAgICAgICAjIFtFcnJvciAyMl0gTm8gYXBwbGljYXRpb24gaXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgICAgICAgICAgICAgICAjIGZpbGUgZm9yIHRoaXMgb3BlcmF0aW9uOiAnPFVSTD4nCisgICAgICAgICAgICAgICAgcmV0dXJuIEZhbHNlCisgICAgICAgICAgICBlbHNlOgorICAgICAgICAgICAgICAgIHJldHVybiBUcnVlCisKKyAgICBfY29udHJvbGxlcnNbJ3dpbmRvd3MtZGVmYXVsdCddID0gU3RhcnQoJ3N0YXJ0JykKKyAgICBfb3BlbiA9IF9jb250cm9sbGVyc1snd2luZG93cy1kZWZhdWx0J10ub3BlbgorCisKKyMgUGxhdGZvcm0gc3VwcG9ydCBmb3IgTWFjT1MKK2VsaWYgc3lzLnBsYXRmb3JtID09ICdkYXJ3aW4nOgorICAgIF9jb250cm9sbGVyc1snb3BlbiddPSBDb250cm9sbGVyKCdvcGVuJykKKyAgICBfb3BlbiA9IF9jb250cm9sbGVyc1snb3BlbiddLm9wZW4KKworCisjIFBsYXRmb3JtIHN1cHBvcnQgZm9yIFVuaXgKK2Vsc2U6CisKKyAgICBpbXBvcnQgY29tbWFuZHMKKworICAgICMgQFdBUk5JTkc6IHVzZSB0aGUgcHJpdmF0ZSBBUEkgb2YgdGhlIHdlYmJyb3dzZXIgbW9kdWxlCisgICAgZnJvbSB3ZWJicm93c2VyIGltcG9ydCBfaXNjb21tYW5kCisKKyAgICBjbGFzcyBLZm1DbGllbnQoQ29udHJvbGxlcik6CisgICAgICAgICcnJ0NvbnRyb2xsZXIgZm9yIHRoZSBLREUga2ZtY2xpZW50IHByb2dyYW0uJycnCisKKyAgICAgICAgZGVmIF9faW5pdF9fKHNlbGYsIGtmbWNsaWVudD0na2ZtY2xpZW50Jyk6CisgICAgICAgICAgICBzdXBlcihLZm1DbGllbnQsIHNlbGYpLl9faW5pdF9fKGtmbWNsaWVudCwgJ2V4ZWMnKQorICAgICAgICAgICAgc2VsZi5rZGVfdmVyc2lvbiA9IHNlbGYuZGV0ZWN0X2tkZV92ZXJzaW9uKCkKKworICAgICAgICBkZWYgZGV0ZWN0X2tkZV92ZXJzaW9uKHNlbGYpOgorICAgICAgICAgICAga2RlX3ZlcnNpb24gPSBOb25lCisgICAgICAgICAgICB0cnk6CisgICAgICAgICAgICAgICAgaW5mbyA9IGNvbW1hbmRzLmdldG91dHB1dCgna2RlLWNvbmZpZyAtLXZlcnNpb24nKQorCisgICAgICAgICAgICAgICAgZm9yIGxpbmUgaW4gaW5mby5zcGxpdGxpbmVzKCk6CisgICAgICAgICAgICAgICAgICAgIGlmIGxpbmUuc3RhcnRzd2l0aCgnS0RFJyk6CisgICAgICAgICAgICAgICAgICAgICAgICBrZGVfdmVyc2lvbiA9IGxpbmUuc3BsaXQoJzonKVstMV0uc3RyaXAoKQorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsKKyAgICAgICAgICAgIGV4Y2VwdCAoT1NFcnJvciwgUnVudGltZUVycm9yKToKKyAgICAgICAgICAgICAgICBwYXNzCisKKyAgICAgICAgICAgIHJldHVybiBrZGVfdmVyc2lvbgorCisgICAgICAgIGRlZiBmaXhyZXR1cm5jb2RlKHNlbGYsIHJldHVybmNvZGUpOgorICAgICAgICAgICAgaWYgcmV0dXJuY29kZSBpcyBub3QgTm9uZSBhbmQgc2VsZi5rZGVfdmVyc2lvbiA+ICczLjUuNCc6CisgICAgICAgICAgICAgICAgcmV0dXJuIHJldHVybmNvZGUKKyAgICAgICAgICAgIGVsc2U6CisgICAgICAgICAgICAgICAgcmV0dXJuIG9zLkVYX09LCisKKyAgICBkZWYgZGV0ZWN0X2Rlc2t0b3BfZW52aXJvbm1lbnQoKToKKyAgICAgICAgJycnQ2hlY2tzIGZvciBrbm93biBkZXNrdG9wIGVudmlyb25tZW50cworCisgICAgICAgIFJldHVybiB0aGUgZGVza3RvcCBlbnZpcm9ubWVudHMgbmFtZSwgbG93ZXJjYXNlIChrZGUsIGdub21lLCB4ZmNlKQorICAgICAgICBvciAiZ2VuZXJpYyIKKworICAgICAgICAnJycKKworICAgICAgICBkZXNrdG9wX2Vudmlyb25tZW50ID0gJ2dlbmVyaWMnCisKKyAgICAgICAgaWYgb3MuZW52aXJvbi5nZXQoJ0tERV9GVUxMX1NFU1NJT04nKSA9PSAndHJ1ZSc6CisgICAgICAgICAgICBkZXNrdG9wX2Vudmlyb25tZW50ID0gJ2tkZScKKyAgICAgICAgZWxpZiBvcy5lbnZpcm9uLmdldCgnR05PTUVfREVTS1RPUF9TRVNTSU9OX0lEJyk6CisgICAgICAgICAgICBkZXNrdG9wX2Vudmlyb25tZW50ID0gJ2dub21lJworICAgICAgICBlbHNlOgorICAgICAgICAgICAgdHJ5OgorICAgICAgICAgICAgICAgIGluZm8gPSBjb21tYW5kcy5nZXRvdXRwdXQoJ3hwcm9wIC1yb290IF9EVF9TQVZFX01PREUnKQorICAgICAgICAgICAgICAgIGlmICcgPSAieGZjZTQiJyBpbiBpbmZvOgorICAgICAgICAgICAgICAgICAgICBkZXNrdG9wX2Vudmlyb25tZW50ID0gJ3hmY2UnCisgICAgICAgICAgICBleGNlcHQgKE9TRXJyb3IsIFJ1bnRpbWVFcnJvcik6CisgICAgICAgICAgICAgICAgcGFzcworCisgICAgICAgIHJldHVybiBkZXNrdG9wX2Vudmlyb25tZW50CisKKworICAgIGRlZiByZWdpc3Rlcl9YX2NvbnRyb2xsZXJzKCk6CisgICAgICAgIGlmIF9pc2NvbW1hbmQoJ2tmbWNsaWVudCcpOgorICAgICAgICAgICAgX2NvbnRyb2xsZXJzWydrZGUtb3BlbiddID0gS2ZtQ2xpZW50KCkKKworICAgICAgICBmb3IgY29tbWFuZCBpbiAoJ2dub21lLW9wZW4nLCAnZXhvLW9wZW4nLCAneGRnLW9wZW4nKToKKyAgICAgICAgICAgIGlmIF9pc2NvbW1hbmQoY29tbWFuZCk6CisgICAgICAgICAgICAgICAgX2NvbnRyb2xsZXJzW2NvbW1hbmRdID0gQ29udHJvbGxlcihjb21tYW5kKQorCisgICAgZGVmIGdldCgpOgorICAgICAgICBjb250cm9sbGVyc19tYXAgPSB7CisgICAgICAgICAgICAnZ25vbWUnOiAnZ25vbWUtb3BlbicsCisgICAgICAgICAgICAna2RlJzogJ2tkZS1vcGVuJywKKyAgICAgICAgICAgICd4ZmNlJzogJ2V4by1vcGVuJywKKyAgICAgICAgfQorCisgICAgICAgIGRlc2t0b3BfZW52aXJvbm1lbnQgPSBkZXRlY3RfZGVza3RvcF9lbnZpcm9ubWVudCgpCisKKyAgICAgICAgdHJ5OgorICAgICAgICAgICAgY29udHJvbGxlcl9uYW1lID0gY29udHJvbGxlcnNfbWFwW2Rlc2t0b3BfZW52aXJvbm1lbnRdCisgICAgICAgICAgICByZXR1cm4gX2NvbnRyb2xsZXJzW2NvbnRyb2xsZXJfbmFtZV0ub3BlbgorCisgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKKyAgICAgICAgICAgIGlmIF9jb250cm9sbGVycy5oYXNfa2V5KCd4ZGctb3BlbicpOgorICAgICAgICAgICAgICAgIHJldHVybiBfY29udHJvbGxlcnNbJ3hkZy1vcGVuJ10ub3BlbgorICAgICAgICAgICAgZWxzZToKKyAgICAgICAgICAgICAgICByZXR1cm4gd2ViYnJvd3Nlci5vcGVuCisKKworICAgIGlmIG9zLmVudmlyb24uZ2V0KCJESVNQTEFZIik6CisgICAgICAgIHJlZ2lzdGVyX1hfY29udHJvbGxlcnMoKQorICAgIF9vcGVuID0gZ2V0KCkKKworCitkZWYgb3BlbihmaWxlbmFtZSk6CisgICAgJycnT3BlbiBhIGZpbGUgb3IgYW4gVVJMIGluIHRoZSByZWdpc3RlcmVkIGRlZmF1bHQgYXBwbGljYXRpb24uJycnCisKKyAgICByZXR1cm4gX29wZW4oZmlsZW5hbWUpCg==