IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCiMgLSotIGNvZGluZzogaXNvLTg4NTktMSAtKi0KIwojICRJZDogMzE0NmU3ODA1NzU4MmU5NmMyZDBlYTlmMjc2MTY2YmFkZDk2NjhmZSAkCgoiIiIKQ29uZmlndXJhdGlvbiBjbGFzc2VzIGZvciAqc3FsY21kKi4KCkNPUFlSSUdIVCBBTkQgTElDRU5TRQoKQ29weXJpZ2h0IKkgMjAwOCBCcmlhbiBNLiBDbGFwcGVyCgpUaGlzIGlzIGZyZWUgc29mdHdhcmUsIHJlbGVhc2VkIHVuZGVyIHRoZSBmb2xsb3dpbmcgQlNELWxpa2UgbGljZW5zZToKClJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAptb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDoKCjEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwKICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KCjIuIFRoZSBlbmQtdXNlciBkb2N1bWVudGF0aW9uIGluY2x1ZGVkIHdpdGggdGhlIHJlZGlzdHJpYnV0aW9uLCBpZiBhbnksCiAgIG11c3QgaW5jbHVkZSB0aGUgZm9sbG93aW5nIGFja25vd2xlZ2VtZW50OgoKICAgICAgVGhpcyBwcm9kdWN0IGluY2x1ZGVzIHNvZnR3YXJlIGRldmVsb3BlZCBieSBCcmlhbiBNLiBDbGFwcGVyCiAgICAgIChibWNAY2xhcHBlci5vcmcsIGh0dHA6Ly93d3cuY2xhcHBlci5vcmcvYm1jLykuIFRoYXQgc29mdHdhcmUgaXMKICAgICAgY29weXJpZ2h0IKkgMjAwOCBCcmlhbiBNLiBDbGFwcGVyLgoKICAgIEFsdGVybmF0ZWx5LCB0aGlzIGFja25vd2xlZ2VtZW50IG1heSBhcHBlYXIgaW4gdGhlIHNvZnR3YXJlIGl0c2VsZiwgaWYKICAgIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZ2VtZW50cyBub3JtYWxseSBhcHBlYXIuCgpUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECldBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GCk1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PCkVWRU5UIFNIQUxMIEJSSUFOIE0uIENMQVBQRVIgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwKSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUCk5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZClRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GClRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCgokSWQ6IDMxNDZlNzgwNTc1ODJlOTZjMmQwZWE5ZjI3NjE2NmJhZGQ5NjY4ZmUgJAoiIiIKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgSW1wb3J0cwojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKaW1wb3J0IGxvZ2dpbmcKaW1wb3J0IG9zCmltcG9ydCByZQppbXBvcnQgc3lzCgpmcm9tIGdyaXp6bGVkIGltcG9ydCBkYiwgc3lzdGVtCmZyb20gZ3JpenpsZWQuY29uZmlnIGltcG9ydCBDb25maWd1cmF0aW9uCgpmcm9tIHNxbGNtZC5leGNlcHRpb24gaW1wb3J0ICoKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgRXhwb3J0cwojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKX19hbGxfXyA9IFsnU1FMQ21kQ29uZmlnJ10KCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgQ29uc3RhbnRzCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIEdsb2JhbHMKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmxvZyA9IGxvZ2dpbmcuZ2V0TG9nZ2VyKCdzcWxjbWQuY29uZmlnJykKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgQ2xhc3NlcwojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKY2xhc3MgREJJbnN0YW5jZUNvbmZpZ0l0ZW0ob2JqZWN0KToKICAgICIiIgogICAgQ2FwdHVyZXMgaW5mb3JtYXRpb24gYWJvdXQgYSBkYXRhYmFzZSBjb25maWd1cmF0aW9uIGl0ZW0gcmVhZCBmcm9tIHRoZQogICAgLnNxbGNtZCBmaWxlIGluIHRoZSB1c2VyJ3MgaG9tZSBkaXJlY3RvcnkuCiAgICAiIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmLAogICAgICAgICAgICAgICAgIHNlY3Rpb24sCiAgICAgICAgICAgICAgICAgYWxpYXNlcywKICAgICAgICAgICAgICAgICBob3N0LAogICAgICAgICAgICAgICAgIGRhdGFiYXNlLAogICAgICAgICAgICAgICAgIHVzZXIsCiAgICAgICAgICAgICAgICAgcGFzc3dvcmQsCiAgICAgICAgICAgICAgICAgdHlwZSwKICAgICAgICAgICAgICAgICBwb3J0LAogICAgICAgICAgICAgICAgIG9uX2Nvbm5lY3QsCiAgICAgICAgICAgICAgICAgY29uZmlnX2Rpcik6CiAgICAgICAgc2VsZi5zZWN0aW9uID0gc2VjdGlvbgogICAgICAgIHNlbGYuYWxpYXNlcyA9IGFsaWFzZXMKICAgICAgICBzZWxmLnByaW1hcnlfYWxpYXMgPSBhbGlhc2VzWzBdCiAgICAgICAgc2VsZi5ob3N0ID0gaG9zdAogICAgICAgIHNlbGYuZGF0YWJhc2UgPSBkYXRhYmFzZQogICAgICAgIHNlbGYudXNlciA9IHVzZXIKICAgICAgICBzZWxmLnBhc3N3b3JkID0gcGFzc3dvcmQKICAgICAgICBzZWxmLnBvcnQgPSBwb3J0CiAgICAgICAgc2VsZi5kYl90eXBlID0gdHlwZQogICAgICAgIHNlbGYub25fY29ubmVjdCA9IE5vbmUKCiAgICAgICAgaWYgb25fY29ubmVjdDoKICAgICAgICAgICAgaWYgb25fY29ubmVjdFswXSA9PSAnfic6CiAgICAgICAgICAgICAgICBvbl9jb25uZWN0ID0gb3MucGF0aC5leHBhbmR1c2VyKG9uX2Nvbm5lY3QpCgogICAgICAgICAgICBpZiBub3Qgb3MucGF0aC5pc2Ficyhvbl9jb25uZWN0KToKICAgICAgICAgICAgICAgIG9uX2Nvbm5lY3QgPSBvcy5wYXRoLmFic3BhdGgob3MucGF0aC5qb2luKGNvbmZpZ19kaXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbl9jb25uZWN0KSkKICAgICAgICAgICAgaWYgbm90IG9zLmFjY2Vzcyhvbl9jb25uZWN0LCBvcy5SX09LfG9zLkZfT0spOgogICAgICAgICAgICAgICAgbG9nLndhcm5pbmcoJ0RhdGFiYXNlICIlcyI6IG9uLWNvbm5lY3Qgc2NyaXB0ICIlcyIgZWl0aGVyICcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdkb2VzIG5vdCBleGlzdCwgaXMgbm90IHJlYWRhYmxlLCBvciBpcyBub3QgYSAnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZmlsZS4nICUgKGRhdGFiYXNlLCBvbl9jb25uZWN0KSkKICAgICAgICAgICAgICAgIG9uX2Nvbm5lY3QgPSBOb25lCgogICAgICAgICAgICBzZWxmLm9uX2Nvbm5lY3QgPSBvbl9jb25uZWN0CgogICAgQHByb3BlcnR5CiAgICBkZWYgZGJfa2V5KHNlbGYpOgogICAgICAgIHBvcnQgPSBzZWxmLnBvcnQgaWYgc2VsZi5wb3J0IGVsc2UgJycKICAgICAgICByZXR1cm4gJyVzfCVzfCVzfCVzJyAlXAogICAgICAgICAgICAgICAoc2VsZi5ob3N0LCBzZWxmLmRiX3R5cGUsIHNlbGYucG9ydCwgc2VsZi5kYXRhYmFzZSkKCiAgICBkZWYgX19oYXNoX18oc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYucHJpbWFyeV9hbGlhcy5fX2hhc2hfXygpCgogICAgZGVmIF9fc3RyX18oc2VsZik6CiAgICAgICAgcmV0dXJuICdob3N0PSVzLCBkYj0lcywgdHlwZT0lcycgJVwKICAgICAgICAgICAgICAgKHNlbGYuaG9zdCwgc2VsZi5kYXRhYmFzZSwgc2VsZi5kYl90eXBlKQoKICAgIGRlZiBfX3JlcHJfXyhzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5fX3N0cl9fKCkKCmNsYXNzIFNRTENtZENvbmZpZyhvYmplY3QpOgogICAgIiIiIERhdGEgZnJvbSB0aGUgLnNxbGNtZCBmaWxlIGluIHRoZSB1c2VyJ3MgaG9tZSBkaXJlY3RvcnkiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgY29uZmlnX2Rpcik6CiAgICAgICAgc2VsZi5fX2NvbmZpZyA9IHt9CiAgICAgICAgc2VsZi5fX2NvbmZpZ19kaXIgPSBjb25maWdfZGlyCiAgICAgICAgc2VsZi5zZXR0aW5ncyA9IHt9CgogICAgZGVmIHRvdGFsX2RhdGFiYXNlcyhzZWxmKToKICAgICAgICByZXR1cm4gbGVuKHNlbGYuX19jb25maWcua2V5cygpKQoKICAgIGRlZiBsb2FkX2ZpbGUoc2VsZiwgcGF0aCk6CiAgICAgICAgc2VsZi5wYXRoID0gcGF0aAogICAgICAgIGlmIG9zLmFjY2VzcyhwYXRoLCBvcy5SX09LfG9zLkZfT0spOgogICAgICAgICAgICBjZmcgPSBDb25maWd1cmF0aW9uKCkKICAgICAgICAgICAgY2ZnLnJlYWQocGF0aCkKCiAgICAgICAgICAgIGhhbmRsZXJfdGFibGUgPSAoCiAgICAgICAgICAgICAgICAjIHNlY3Rpb24gbmFtZSByZWdleCAgICAgICBmdW5jdGlvbgogICAgICAgICAgICAgICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgICAgICAgICAgKHJlLmNvbXBpbGUoJ15kYlwuJyksICAgICAgc2VsZi5fX2NvbmZpZ19kYiksCiAgICAgICAgICAgICAgICAocmUuY29tcGlsZSgnXmRyaXZlclwuJyksICBzZWxmLl9fY29uZmlnX2RyaXZlciksCiAgICAgICAgICAgICAgICAocmUuY29tcGlsZSgnXnNldHRpbmdzJCcpLCBzZWxmLl9fc2V0X3ZhcnMpLAogICAgICAgICAgICApCgogICAgICAgICAgICBmb3Igc2VjdGlvbiBpbiBjZmcuc2VjdGlvbnM6CiAgICAgICAgICAgICAgICBmb3IgcmVnZXgsIGhhbmRsZXIgaW4gaGFuZGxlcl90YWJsZToKICAgICAgICAgICAgICAgICAgICBpZiByZWdleC5tYXRjaChzZWN0aW9uKToKICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlcihjZmcsIHNlY3Rpb24pCgogICAgZGVmIF9fY29uZmlnX2RiKHNlbGYsIGNmZywgc2VjdGlvbik6CiAgICAgICAgcHJpbWFyeV9uYW1lID0gc2VjdGlvblszOl0gIyBhc3N1bWVzIGl0IHN0YXJ0cyB3aXRoICdkYi4nCiAgICAgICAgaWYgbGVuKHByaW1hcnlfbmFtZSkgPT0gMDoKICAgICAgICAgICAgcmFpc2UgQ29uZmlndXJhdGlvbkVycm9yKCdCYWQgZGF0YWJhc2Ugc2VjdGlvbiBuYW1lICIlcyInICUgc2VjdGlvbikKCiAgICAgICAgYWxpYXNlcyA9IGNmZy5nZXRsaXN0KHNlY3Rpb24sICdhbGlhc2VzJywgc2VwPScsJywgb3B0aW9uYWw9VHJ1ZSkKICAgICAgICBpZiBhbGlhc2VzOgogICAgICAgICAgICBhbGlhc2VzID0gW3ByaW1hcnlfbmFtZV0gKyBbYS5zdHJpcCgpIGZvciBhIGluIGFsaWFzZXNdCiAgICAgICAgZWxzZToKICAgICAgICAgICAgYWxpYXNlcyA9IFtdCgogICAgICAgIGhvc3QgPSBjZmcuZ2V0KHNlY3Rpb24sICdob3N0Jywgb3B0aW9uYWw9VHJ1ZSkKICAgICAgICBwb3J0ID0gY2ZnLmdldChzZWN0aW9uLCAncG9ydCcsIG9wdGlvbmFsPVRydWUpCiAgICAgICAgZGJfbmFtZSA9IGNmZy5nZXQoc2VjdGlvbiwgJ2RhdGFiYXNlJykKICAgICAgICB1c2VyID0gY2ZnLmdldChzZWN0aW9uLCAndXNlcicsIG9wdGlvbmFsPVRydWUpCiAgICAgICAgcGFzc3dvcmQgPSBjZmcuZ2V0KHNlY3Rpb24sICdwYXNzd29yZCcsIG9wdGlvbmFsPVRydWUpCiAgICAgICAgZGJfdHlwZSA9IGNmZy5nZXQoc2VjdGlvbiwgJ3R5cGUnKQogICAgICAgIG9uX2Nvbm5lY3QgPSBjZmcuZ2V0KHNlY3Rpb24sICdvbmNvbm5lY3QnLCBvcHRpb25hbD1UcnVlKQoKICAgICAgICBhbGlhc2VzICs9IFtkYl9uYW1lXQogICAgICAgIHRyeToKICAgICAgICAgICAgY2ZnX2l0ZW0gPSBEQkluc3RhbmNlQ29uZmlnSXRlbShzZWN0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsaWFzZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG9zdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYl9uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFzc3dvcmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGJfdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3J0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uX2Nvbm5lY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fX2NvbmZpZ19kaXIpCiAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3IsIG1zZzoKICAgICAgICAgICAgcmFpc2UgQ29uZmlndXJhdGlvbkVycm9yKAogICAgICAgICAgICAgICAgICAnQ29uZmlndXJhdGlvbiBzZWN0aW9uIFslc106ICVzJyAlIChzZWN0aW9uLCBtc2cpCiAgICAgICAgICAgICkKCiAgICAgICAgZm9yIGFsaWFzIGluIGFsaWFzZXM6CiAgICAgICAgICAgIHNlbGYuX19jb25maWdbYWxpYXNdID0gY2ZnX2l0ZW0KCiAgICBkZWYgX19jb25maWdfZHJpdmVyKHNlbGYsIGNmZywgc2VjdGlvbik6CiAgICAgICAgY2xhc3NfbmFtZSA9IGNmZy5nZXQoc2VjdGlvbiwgJ2NsYXNzJykKICAgICAgICBjbHMgPSBzeXN0ZW0uY2xhc3NfZm9yX25hbWUoY2xhc3NfbmFtZSkKICAgICAgICBuYW1lID0gY2ZnLmdldChzZWN0aW9uLCAnbmFtZScpCiAgICAgICAgZGIuYWRkX2RyaXZlcihuYW1lLCBjbHMpCgogICAgZGVmIF9fc2V0X3ZhcnMoc2VsZiwgY2ZnLCBzZWN0aW9uKToKICAgICAgICBzZWxmLnNldHRpbmdzX3NlY3Rpb24gPSBzZWN0aW9uCiAgICAgICAgZm9yIG9wdGlvbiBpbiBjZmcub3B0aW9ucyhzZWN0aW9uKToKICAgICAgICAgICAgc2VsZi5zZXR0aW5nc1tvcHRpb25dID0gY2ZnLmdldChzZWN0aW9uLCBvcHRpb24pCgogICAgZGVmIGFkZChzZWxmLCBzZWN0aW9uLCBhbGlhcywgaG9zdCwgcG9ydCwgZGF0YWJhc2UsIHR5cGUsIHVzZXIsIHBhc3N3b3JkKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIHNlbGYuX19jb25maWdbYWxpYXNdCiAgICAgICAgICAgIHJhaXNlIENvbmZpZ3VyYXRpb25FcnJvcigKICAgICAgICAgICAgICAgICdBbGlhcyAiJXMiIGlzIGFscmVhZHkgaW4gdGhlIGNvbmZpZ3VyYXRpb24nICUgYWxpYXMKICAgICAgICAgICAgKQoKICAgICAgICBleGNlcHQgS2V5RXJyb3I6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGNmZyA9IERCSW5zdGFuY2VDb25maWdJdGVtKHNlY3Rpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYWxpYXNdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG9zdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFiYXNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhc3N3b3JkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb25lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fX2NvbmZpZ19kaXIpCiAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yLCBtc2c6CiAgICAgICAgICAgICAgICByYWlzZSBDb25maWd1cmF0aW9uRXJyb3IoCiAgICAgICAgICAgICAgICAgICAgJ0Vycm9yIGluIGNvbmZpZ3VyYXRpb24gZm9yIGFsaWFzICIlcyI6ICVzJyAlIChhbGlhcywgbXNnKQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICBzZWxmLl9fY29uZmlnW2FsaWFzXSA9IGNmZwoKICAgIGRlZiBnZXQoc2VsZiwgYWxpYXMpOgogICAgICAgIHJldHVybiBzZWxmLl9fY29uZmlnW2FsaWFzXQoKICAgIGRlZiBnZXRfYWxpYXNlcyhzZWxmKToKICAgICAgICBhbGlhc2VzID0gc2VsZi5fX2NvbmZpZy5rZXlzKCkKICAgICAgICBhbGlhc2VzLnNvcnQoKQogICAgICAgIHJldHVybiBhbGlhc2VzCgogICAgZGVmIGZpbmRfbWF0Y2goc2VsZiwgYWxpYXMpOgogICAgICAgIHRyeToKICAgICAgICAgICAgY29uZmlnX2l0ZW0gPSBzZWxmLl9fY29uZmlnW2FsaWFzXQogICAgICAgICAgICAjIEV4YWN0IG1hdGNoLiBVc2UgdGhhdCBvbmUuCiAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICAjIE5vIG1hdGNoLiBUcnkgdG8gZmluZCBvbmUgb3IgbW9yZSB0aGF0IGNvbWUgY2xvc2UuCiAgICAgICAgICAgIG1hdGNoZXMgPSB7fQogICAgICAgICAgICBmb3IgYSBpbiBzZWxmLl9fY29uZmlnLmtleXMoKToKICAgICAgICAgICAgICAgIGlmIGEuc3RhcnRzd2l0aChhbGlhcyk6CiAgICAgICAgICAgICAgICAgICAgY29uZmlnX2l0ZW0gPSBzZWxmLl9fY29uZmlnW2FdCiAgICAgICAgICAgICAgICAgICAgbWF0Y2hlc1tjb25maWdfaXRlbS5kYl9rZXldID0gY29uZmlnX2l0ZW0KCiAgICAgICAgICAgIHRvdGFsX21hdGNoZXMgPSBsZW4obWF0Y2hlcykKICAgICAgICAgICAgaWYgdG90YWxfbWF0Y2hlcyA9PSAwOgogICAgICAgICAgICAgICAgcmFpc2UgQ29uZmlndXJhdGlvbkVycm9yKAogICAgICAgICAgICAgICAgICAgICdObyBjb25maWd1cmF0aW9uIGl0ZW0gZm9yIGRhdGFiYXNlICIlcyInICUgYWxpYXMpCiAgICAgICAgICAgIGlmIHRvdGFsX21hdGNoZXMgPiAxOgogICAgICAgICAgICAgICAgcmFpc2UgQ29uZmlndXJhdGlvbkVycm9yKAogICAgICAgICAgICAgICAgICAgICclZCBkYXRhYmFzZXMgbWF0Y2ggcGFydGlhbCBhbGlhcyAiJXMiOiAlcycgJVwKICAgICAgICAgICAgICAgICAgICAodG90YWxfbWF0Y2hlcywgYWxpYXMsIFwKICAgICAgICAgICAgICAgICAgICAgJywgJy5qb2luKFtjZmcuc2VjdGlvbiBmb3IgY2ZnIGluIG1hdGNoZXMudmFsdWVzKCldKSkKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgY29uZmlnX2l0ZW0gPSBtYXRjaGVzLnZhbHVlcygpWzBdCgogICAgICAgIHJldHVybiBjb25maWdfaXRlbQo=