diff --git a/addons/cetmix_tower_server/models/cx_tower_reference_mixin.py b/addons/cetmix_tower_server/models/cx_tower_reference_mixin.py new file mode 100644 index 0000000..2a257c5 --- /dev/null +++ b/addons/cetmix_tower_server/models/cx_tower_reference_mixin.py @@ -0,0 +1 @@ +IyBDb3B5cmlnaHQgKEMpIDIwMjQgQ2V0bWl4IE/DnAojIExpY2Vuc2UgQUdQTC0zLjAgb3IgbGF0ZXIgKGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsKS4KaW1wb3J0IHJlCmZyb20gY29sbGVjdGlvbnMgaW1wb3J0IGRlZmF1bHRkaWN0Cgpmcm9tIG9kb28gaW1wb3J0IF8sIGFwaSwgZmllbGRzLCBtb2RlbHMKZnJvbSBvZG9vLm9zdiBpbXBvcnQgZXhwcmVzc2lvbgpmcm9tIG9kb28udG9vbHMgaW1wb3J0IG9ybWNhY2hlCgoKY2xhc3MgQ3hUb3dlclJlZmVyZW5jZU1peGluKG1vZGVscy5BYnN0cmFjdE1vZGVsKToKICAgICIiIgogICAgVXNlZCB0byBjcmVhdGUgYW5kIG1hbmFnZSB1bmlxdWUgcmVjb3JkIHJlZmVyZW5jZXMuCiAgICAiIiIKCiAgICBfbmFtZSA9ICJjeC50b3dlci5yZWZlcmVuY2UubWl4aW4iCiAgICBfZGVzY3JpcHRpb24gPSAiQ2V0bWl4IFRvd2VyIHJlZmVyZW5jZSBtaXhpbiIKICAgIF9yZWNfbmFtZXNfc2VhcmNoID0gWyJuYW1lIiwgInJlZmVyZW5jZSJdCgogICAgIyBVc2VkIHRvIGNoZWNrIHRoZSByZWZlcmVuY2UgYmVmb3JlIGl0J3MgYmVpbmcgZml4ZWQuCiAgICAjIEVuc3VyZXMgdGhlcmUncyBhdCBsZWFzdCBvbmUgdmFsaWQgc3ltYm9sCiAgICAjIHRoYXQgY2FuIGJlIHVzZWQgbGF0ZXIgYXMgYSBuZXcgcmVmZXJlbmNlIGJhc2lzLgogICAgUkVGRVJFTkNFX1BSRUxJTUlOQVJZX1BBVFRFUk4gPSByIltcZGEtekEtWl0iCgogICAgbmFtZSA9IGZpZWxkcy5DaGFyKHJlcXVpcmVkPVRydWUsIGluZGV4PSJ0cmlncmFtIikKICAgIHJlZmVyZW5jZSA9IGZpZWxkcy5DaGFyKAogICAgICAgIGluZGV4PVRydWUsCiAgICAgICAgdW5hY2NlbnQ9RmFsc2UsCiAgICAgICAgaGVscD0iQ2FuIGNvbnRhaW4gRW5nbGlzaCBsZXR0ZXJzLCBkaWdpdHMgYW5kICdfJy4gTGVhdmUgYmxhbmsgdG8gYXV0b2dlbmVyYXRlIiwKICAgICkKCiAgICBfc3FsX2NvbnN0cmFpbnRzID0gWwogICAgICAgICgicmVmZXJlbmNlX3VuaXF1ZSIsICJVTklRVUUocmVmZXJlbmNlKSIsICJSZWZlcmVuY2UgbXVzdCBiZSB1bmlxdWUiKQogICAgXQoKICAgIEBhcGkubW9kZWxfY3JlYXRlX211bHRpCiAgICBkZWYgY3JlYXRlKHNlbGYsIHZhbHNfbGlzdCk6CiAgICAgICAgIiIiCiAgICAgICAgT3ZlcnJpZGVzIGNyZWF0ZSB0byBlbnN1cmUgJ3JlZmVyZW5jZScgaXMgYXV0by1jb3JyZWN0ZWQKICAgICAgICBvciB2YWxpZGF0ZWQgZm9yIGVhY2ggcmVjb3JkLgoKICAgICAgICBBZGQgYHJlZmVyZW5jZV9taXhpbl9vdmVycmlkZWAgY29udGV4dCBrZXkgdG8gc2tpcCB0aGUgcmVmZXJlbmNlIGNoZWNrCgogICAgICAgIEFyZ3M6CiAgICAgICAgICAgIHZhbHNfbGlzdCAobGlzdFtkaWN0XSk6IExpc3Qgb2YgZGljdGlvbmFyaWVzIHdpdGggcmVjb3JkIHZhbHVlcy4KCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgUmVjb3JkczogVGhlIGNyZWF0ZWQgcmVjb3JkKHMpLgogICAgICAgICIiIgoKICAgICAgICBpZiB2YWxzX2xpc3QgYW5kIG5vdCBzZWxmLl9jb250ZXh0LmdldCgicmVmZXJlbmNlX21peGluX292ZXJyaWRlIik6CiAgICAgICAgICAgICMgQ2hlY2sgaWYgd2UgbmVlZCB0byBwb3B1bGF0ZSByZWZlcmVuY2VzIGJhc2VkIG9uIHBhcmVudCByZWNvcmQKICAgICAgICAgICAgYXV0b19nZW5lcmF0ZV9zZXR0aW5ncyA9IHNlbGYuX2dldF9wcmVfcG9wdWxhdGVkX21vZGVsX2RhdGEoKS5nZXQoCiAgICAgICAgICAgICAgICBzZWxmLl9uYW1lCiAgICAgICAgICAgICkKICAgICAgICAgICAgaWYgYXV0b19nZW5lcmF0ZV9zZXR0aW5nczoKICAgICAgICAgICAgICAgIHBhcmVudF9tb2RlbCwgcmVsYXRpb25fZmllbGQgPSBhdXRvX2dlbmVyYXRlX3NldHRpbmdzCiAgICAgICAgICAgICAgICB2YWxzX2xpc3QgPSBzZWxmLl9wcmVfcG9wdWxhdGVfcmVmZXJlbmNlcygKICAgICAgICAgICAgICAgICAgICBwYXJlbnRfbW9kZWwsIHJlbGF0aW9uX2ZpZWxkLCB2YWxzX2xpc3QKICAgICAgICAgICAgICAgICkKCiAgICAgICAgICAgICMgRml4IG9yIGNyZWF0ZSByZWZlcmVuY2VzCiAgICAgICAgICAgIGZvciB2YWxzIGluIHZhbHNfbGlzdDoKICAgICAgICAgICAgICAgIGlmIG5vdCB2YWxzOgogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICAgICAgICAgIyBSZW1vdmUgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZXMgZnJvbSBuYW1lCiAgICAgICAgICAgICAgICB2YWxzX25hbWUgPSB2YWxzLmdldCgibmFtZSIpCiAgICAgICAgICAgICAgICBuYW1lID0gdmFsc19uYW1lLnN0cmlwKCkgaWYgdmFsc19uYW1lIGVsc2UgdmFsc19uYW1lCgogICAgICAgICAgICAgICAgIyBSZW1vdmUgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZXMgZnJvbSByZWZlcmVuY2UKICAgICAgICAgICAgICAgIHZhbHNfcmVmZXJlbmNlID0gdmFscy5nZXQoInJlZmVyZW5jZSIpCiAgICAgICAgICAgICAgICByZWZlcmVuY2UgPSB2YWxzX3JlZmVyZW5jZS5zdHJpcCgpIGlmIHZhbHNfcmVmZXJlbmNlIGVsc2UgdmFsc19yZWZlcmVuY2UKCiAgICAgICAgICAgICAgICAjIE5vdGhpbmcgY2FuIGJlIGRvbmUgaWYgbm8gbmFtZSBvciByZWZlcmVuY2UgaXMgcHJvdmlkZWQKICAgICAgICAgICAgICAgIGlmIG5vdCBuYW1lIGFuZCBub3QgcmVmZXJlbmNlOgogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICAgICAgICAgIyBTYXZlIG5hbWUgYmFjayB0byB2YWxzIGlmIGl0IHdhcyBtb2RpZmllZAogICAgICAgICAgICAgICAgaWYgdmFsc19uYW1lICE9IG5hbWU6CiAgICAgICAgICAgICAgICAgICAgdmFsc1sibmFtZSJdID0gbmFtZQoKICAgICAgICAgICAgICAgICMgR2VuZXJhdGUgcmVmZXJlbmNlCiAgICAgICAgICAgICAgICB2YWxzLnVwZGF0ZSgKICAgICAgICAgICAgICAgICAgICB7InJlZmVyZW5jZSI6IHNlbGYuX2dlbmVyYXRlX29yX2ZpeF9yZWZlcmVuY2UocmVmZXJlbmNlIG9yIG5hbWUpfQogICAgICAgICAgICAgICAgKQoKICAgICAgICByZXMgPSBzdXBlcigpLmNyZWF0ZSh2YWxzX2xpc3QpCiAgICAgICAgc2VsZi5jbGVhcl9jYWNoZXMoKQogICAgICAgIHJldHVybiByZXMKCiAgICBkZWYgd3JpdGUoc2VsZiwgdmFscyk6CiAgICAgICAgIiIiCiAgICAgICAgVXBkYXRlcyByZWNvcmQsIGF1dG8tY29ycmVjdGluZyBvciB2YWxpZGF0aW5nICdyZWZlcmVuY2UnCiAgICAgICAgYmFzZWQgb24gJ25hbWUnIG9yIGV4aXN0aW5nIHZhbHVlLgoKICAgICAgICBBZGQgYHJlZmVyZW5jZV9taXhpbl9vdmVycmlkZWAgY29udGV4dCBrZXkgdG8gc2tpcCB0aGUgcmVmZXJlbmNlIGNoZWNrCgogICAgICAgIEFyZ3M6CiAgICAgICAgICAgIHZhbHMgKGRpY3QpOiBWYWx1ZXMgdG8gdXBkYXRlLCBtYXkgaW5jbHVkZSAncmVmZXJlbmNlJy4KCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgUmVzdWx0IG9mIHRoZSBzdXBlciBgd3JpdGVgIGNhbGwuCiAgICAgICAgIiIiCiAgICAgICAgaWYgbm90IHNlbGYuX2NvbnRleHQuZ2V0KCJyZWZlcmVuY2VfbWl4aW5fb3ZlcnJpZGUiKSBhbmQgInJlZmVyZW5jZSIgaW4gdmFsczoKICAgICAgICAgICAgcmVmZXJlbmNlID0gdmFscy5nZXQoInJlZmVyZW5jZSIsIEZhbHNlKQogICAgICAgICAgICBpZiBub3QgcmVmZXJlbmNlOgogICAgICAgICAgICAgICAgIyBHZXQgbmFtZSBmcm9tIHZhbHMKICAgICAgICAgICAgICAgIHVwZGF0ZWRfbmFtZSA9IHZhbHMuZ2V0KCJuYW1lIikKCiAgICAgICAgICAgICAgICAjIE5vIG5hbWUgaW4gdmFscy4gVXBkYXRlIHJlY29yZHMgb25lIGJ5IG9uZQogICAgICAgICAgICAgICAgaWYgbm90IHVwZGF0ZWRfbmFtZToKICAgICAgICAgICAgICAgICAgICBmb3IgcmVjb3JkIGluIHNlbGY6CiAgICAgICAgICAgICAgICAgICAgICAgIHJlY29yZF92YWxzID0gdmFscy5jb3B5KCkKICAgICAgICAgICAgICAgICAgICAgICAgcmVjb3JkX3ZhbHMudXBkYXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgeyJyZWZlcmVuY2UiOiBzZWxmLl9nZW5lcmF0ZV9vcl9maXhfcmVmZXJlbmNlKHJlY29yZC5uYW1lKX0KICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICBzdXBlcihDeFRvd2VyUmVmZXJlbmNlTWl4aW4sIHJlY29yZCkud3JpdGUocmVjb3JkX3ZhbHMpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRydWUKICAgICAgICAgICAgICAgICMgTmFtZSBpcyBwcmVzZW50IGluIHZhbHMKICAgICAgICAgICAgICAgIHJlZmVyZW5jZSA9IHNlbGYuX2dlbmVyYXRlX29yX2ZpeF9yZWZlcmVuY2UodXBkYXRlZF9uYW1lKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgcmVmZXJlbmNlID0gc2VsZi5fZ2VuZXJhdGVfb3JfZml4X3JlZmVyZW5jZShyZWZlcmVuY2UpCiAgICAgICAgICAgIHZhbHMudXBkYXRlKHsicmVmZXJlbmNlIjogcmVmZXJlbmNlfSkKCiAgICAgICAgcmVzID0gc3VwZXIoKS53cml0ZSh2YWxzKQoKICAgICAgICAjIFVwZGF0ZSByZWZlcmVuY2VzIG9mIGRlcGVuZGVudCBtb2RlbHMKICAgICAgICBpZiAicmVmZXJlbmNlIiBpbiB2YWxzOgogICAgICAgICAgICBzZWxmLl91cGRhdGVfZGVwZW5kZW50X21vZGVsX3JlZmVyZW5jZXMoKQogICAgICAgICAgICAjIENsZWFyIGNhY2hlcwogICAgICAgICAgICBzZWxmLmNsZWFyX2NhY2hlcygpCiAgICAgICAgcmV0dXJuIHJlcwoKICAgIGRlZiB1bmxpbmsoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgT3ZlcnJpZGVzIHVubGluayB0byBjbGVhciBjYWNoZSBmb3IgdGhpcyBtZXRob2QKICAgICAgICAiIiIKICAgICAgICByZXMgPSBzdXBlcigpLnVubGluaygpCiAgICAgICAgc2VsZi5jbGVhcl9jYWNoZXMoKQogICAgICAgIHJldHVybiByZXMKCiAgICBkZWYgY29weShzZWxmLCBkZWZhdWx0PU5vbmUpOgogICAgICAgICIiIgogICAgICAgIE92ZXJyaWRlcyB0aGUgY29weSBtZXRob2QgdG8gZW5zdXJlIHVuaXF1ZSByZWZlcmVuY2UgdmFsdWVzCiAgICAgICAgZm9yIGR1cGxpY2F0ZWQgcmVjb3Jkcy4KCiAgICAgICAgQXJnczoKICAgICAgICAgICAgZGVmYXVsdCAoZGljdCwgb3B0aW9uYWwpOiBEZWZhdWx0IHZhbHVlcyBmb3IgdGhlIG5ldyByZWNvcmQuCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIFJlY29yZDogVGhlIG5ld2x5IGNvcGllZCByZWNvcmQgd2l0aCBhZGp1c3RlZCBkZWZhdWx0cy4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmVuc3VyZV9vbmUoKQogICAgICAgIGlmIGRlZmF1bHQgaXMgTm9uZToKICAgICAgICAgICAgZGVmYXVsdCA9IHt9CgogICAgICAgICMgc2tpcCBjb3B5aW5nICduYW1lJyBiZWNhdXNlIHRoaXMgZnVuY3Rpb24gY2FuIGJlIHVzZWQgaW4gbW9kZWxzCiAgICAgICAgIyB3aGVyZSAnbmFtZScgZmllbGQgaXMgbm90IHN0b3JlZAogICAgICAgIGlmIG5vdCBzZWxmLmVudi5jb250ZXh0LmdldCgicmVmZXJlbmNlX21peGluX3NraXBfY29weSIpOgogICAgICAgICAgICBkZWZhdWx0WyJuYW1lIl0gPSBzZWxmLl9nZXRfY29waWVkX25hbWUoZm9yY2VfbmFtZT1kZWZhdWx0LmdldCgibmFtZSIpKQogICAgICAgIGlmICJyZWZlcmVuY2UiIG5vdCBpbiBkZWZhdWx0OgogICAgICAgICAgICBkZWZhdWx0WyJyZWZlcmVuY2UiXSA9IHNlbGYuX2dlbmVyYXRlX29yX2ZpeF9yZWZlcmVuY2UoZGVmYXVsdFsibmFtZSJdKQogICAgICAgIHJldHVybiBzdXBlcigpLmNvcHkoZGVmYXVsdD1kZWZhdWx0KQoKICAgIGRlZiBfZ2V0X3JlZmVyZW5jZV9wYXR0ZXJuKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFJldHVybnMgdGhlIHJlZ2V4IHBhdHRlcm4gdXNlZCBmb3IgdmFsaWRhdGluZyBhbmQgY29ycmVjdGluZyByZWZlcmVuY2VzLgogICAgICAgIFRoaXMgYWxsb3dzIGZvciBlYXN5IG1vZGlmaWNhdGlvbiBvZiB0aGUgcGF0dGVybiBpbiBvbmUgcGxhY2UuCgogICAgICAgIEltcG9ydGFudDogcGF0dGVybiBtdXN0IGJlIGVuY2xvc2VkIGluIHNxdWFyZSBicmFja2V0cyEKCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgc3RyOiBBIHJlZ2V4IHBhdHRlcm4KICAgICAgICAiIiIKICAgICAgICByZXR1cm4gIlthLXowLTlfXSIKCiAgICBkZWYgX2dldF9wcmVfcG9wdWxhdGVkX21vZGVsX2RhdGEoc2VsZik6CiAgICAgICAgIiIiUmV0dXJucyBMaXN0IG9mIG1vZGVscyB0aGF0IHNob3VsZCB0cnkgdG8gZ2VuZXJhdGUKICAgICAgICByZWZlcmVuY2VzIGJhc2VkIG9uIHRoZSByZWxhdGVkIG1vZGVsIHJlZmVyZW5jZS4KCiAgICAgICAgRWcgZmxpZ2h0IHBsYW4gbGluZXMgcmVmZXJlbmNlcyBhcmUgZ2VuZXJhdGVkIGJhc2VkIG9uIHRoZSBmbGlnaHQgcGxhbiBvbmUuCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIGRpY3Q6IE1vZGVsIHZhbHVlcyBkaWN0aW9uYXJ5OgogICAgICAgICAgICB7bW9kZWxfbmFtZTogW3BhcmVudF9tb2RlbCwgcmVsYXRpb25fZmllbGRdfQogICAgICAgICIiIgogICAgICAgIHJldHVybiB7fQoKICAgIGRlZiBfZ2V0X2V4dHJhX3ZhbHNfZmllbGRzKHNlbGYpOgogICAgICAgICIiIlJldHVybnMgbGlzdCBvZiBleHRyYSBmaWVsZHMgdGhhdCBhcmUgbmVlZGVkIGZvciByZWZlcmVuY2UgZ2VuZXJhdGlvbi4KICAgICAgICBUaGlzIG1ldGhvZCBpZiB1c2VkIHRvIG1ha2UgY3VzdG9tIHJlZmVyZW5jZSBnZW5lcmF0aW9uIGxvZ2ljIG1vcmUgZmxleGlibGUuCiAgICAgICAgRWcgZm9yICdjeC50b3dlci52YXJpYWJsZS52YWx1ZSc6CiAgICAgICAgICAgICdzZXJ2ZXJfaWQnLCAnc2VydmVyX3RlbXBsYXRlX2lkJywgJ3BsYW5fbGluZV9hY3Rpb25faWQnLgogICAgICAgIFNvIGZvciBjb21tb24gbW9kZWxzIGxpa2UgJ2N4LnRvd2VyLnNlcnZlcicgdGhpcyBtZXRob2QgaXMgbm90IG5lZWRlZC4KCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgbGlzdDogTGlzdCBvZiBmaWVsZHM6CiAgICAgICAgICAgIFtmaWVsZF9uYW1lMSwgZmllbGRfbmFtZTIsIC4uLl0KICAgICAgICAiIiIKICAgICAgICByZXR1cm4gW10KCiAgICBkZWYgX2dldF9kZXBlbmRlbnRfbW9kZWxfcmVsYXRpb25fZmllbGRzKHNlbGYpOgogICAgICAgICIiIlJldHVybnMgbGlzdCBvZiBmaWVsZHMgdGhhdCByZWZlcmVuY2UgZGVwZW5kZW50IG1vZGVscy4KCiAgICAgICAgRWcgZmxpZ2h0IHBsYW4gbGluZXMgcmVmZXJlbmNlcyBhcmUgZ2VuZXJhdGVkIGJhc2VkIG9uIHRoZSBmbGlnaHQgcGxhbiBvbmUuCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIGxpc3Q6IExpc3Qgb2YgZmllbGRzOgogICAgICAgICAgICBbZmllbGRfbmFtZTEsIGZpZWxkX25hbWUyLCAuLi5dCiAgICAgICAgIiIiCiAgICAgICAgcmV0dXJuIFtdCgogICAgZGVmIF91cGRhdGVfZGVwZW5kZW50X21vZGVsX3JlZmVyZW5jZXMoc2VsZik6CiAgICAgICAgIiIiVXBkYXRlIHJlZmVyZW5jZXMgb2YgZGVwZW5kZW50IG1vZGVscyIiIgogICAgICAgIGRlcGVuZGVudF9tb2RlbF9yZWxhdGlvbl9maWVsZHMgPSBzZWxmLl9nZXRfZGVwZW5kZW50X21vZGVsX3JlbGF0aW9uX2ZpZWxkcygpCiAgICAgICAgaWYgZGVwZW5kZW50X21vZGVsX3JlbGF0aW9uX2ZpZWxkczoKICAgICAgICAgICAgZm9yIGZpZWxkIGluIGRlcGVuZGVudF9tb2RlbF9yZWxhdGlvbl9maWVsZHM6CiAgICAgICAgICAgICAgICByZWxhdGVkX21vZGVsX25hbWUgPSBzZWxmW2ZpZWxkXS5fbmFtZQoKICAgICAgICAgICAgICAgICMgQ2hlY2sgaWYgdGhlIHJlbGF0ZWQgbW9kZWwgaGFzIGF1dG8tZ2VuZXJhdGUgc2V0dGluZ3MKICAgICAgICAgICAgICAgIGF1dG9fZ2VuZXJhdGVfc2V0dGluZ3MgPSAoCiAgICAgICAgICAgICAgICAgICAgc2VsZltmaWVsZF0uX2dldF9wcmVfcG9wdWxhdGVkX21vZGVsX2RhdGEoKS5nZXQocmVsYXRlZF9tb2RlbF9uYW1lKQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgaWYgYXV0b19nZW5lcmF0ZV9zZXR0aW5nczoKICAgICAgICAgICAgICAgICAgICBwYXJlbnRfbW9kZWwsIHJlbGF0aW9uX2ZpZWxkID0gYXV0b19nZW5lcmF0ZV9zZXR0aW5ncwogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBjb250aW51ZQoKICAgICAgICAgICAgICAgICMgUGFyc2UgdGhlIGZpZWxkIGZvciBhbGwgcmVjb3JkcwogICAgICAgICAgICAgICAgZm9yIHJlY29yZCBpbiBzZWxmOgogICAgICAgICAgICAgICAgICAgIHJlbGF0ZWRfcmVjb3JkcyA9IHJlY29yZFtmaWVsZF0KICAgICAgICAgICAgICAgICAgICAjIEdldCB2YWxzIGxpc3QKICAgICAgICAgICAgICAgICAgICByZWNfdmFsc19saXN0ID0gcmVsYXRlZF9yZWNvcmRzLnJlYWQoCiAgICAgICAgICAgICAgICAgICAgICAgIFtyZWxhdGlvbl9maWVsZF0gKyByZWxhdGVkX3JlY29yZHMuX2dldF9leHRyYV92YWxzX2ZpZWxkcygpCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICMgVHJhbnNmb3JtIE1hbnkyb25lIHR1cGxlcyB0byBJRHMKICAgICAgICAgICAgICAgICAgICBmb3IgcnYgaW4gcmVjX3ZhbHNfbGlzdDoKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIGssIHYgaW4gcnYuaXRlbXMoKToKICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgVHJhbnNmb3JtIG0ybyBmaWVsZHMgZnJvbSAoaWQsIG5hbWUpIHRvIGlkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBpc2luc3RhbmNlKHYsIHR1cGxlKToKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBydltrXSA9IHZbMF0KICAgICAgICAgICAgICAgICAgICByZWxhdGVkX3JlY29yZHMuX3ByZV9wb3B1bGF0ZV9yZWZlcmVuY2VzKAogICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRfbW9kZWwsIHJlbGF0aW9uX2ZpZWxkLCByZWNfdmFsc19saXN0CiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgIHJlZl9ieV9pZCA9IHtydlsiaWQiXTogcnZbInJlZmVyZW5jZSJdIGZvciBydiBpbiByZWNfdmFsc19saXN0fQogICAgICAgICAgICAgICAgICAgIGZvciByZWxhdGVkX3JlY29yZCBpbiByZWxhdGVkX3JlY29yZHM6CiAgICAgICAgICAgICAgICAgICAgICAgIHJlbGF0ZWRfcmVjb3JkLnJlZmVyZW5jZSA9IHJlZl9ieV9pZFtyZWxhdGVkX3JlY29yZC5pZF0KCiAgICBkZWYgX2dlbmVyYXRlX29yX2ZpeF9yZWZlcmVuY2Uoc2VsZiwgcmVmZXJlbmNlX3NvdXJjZSk6CiAgICAgICAgIiIiCiAgICAgICAgR2VuZXJhdGUgYSBuZXcgcmVmZXJlbmNlIG9mIGZpeCBhbiBleGlzdGluZyBvbmUuCgogICAgICAgIEFyZ3M6CiAgICAgICAgICAgIHJlZmVyZW5jZV9zb3VyY2UgKHN0cik6IE9yaWdpbmFsIHN0cmluZy4KCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgc3RyOiBHZW5lcmF0ZWQgb3IgZml4ZWQgcmVmZXJlbmNlLgogICAgICAgICIiIgoKICAgICAgICAjIENoZWNrIGlmIHJlZmVyZW5jZSBtYXRjaGVzIHRoZSBwYXR0ZXJuCiAgICAgICAgcmVmZXJlbmNlX3BhdHRlcm4gPSBzZWxmLl9nZXRfcmVmZXJlbmNlX3BhdHRlcm4oKQoKICAgICAgICBpZiByZS5mdWxsbWF0Y2gocmYie3JlZmVyZW5jZV9wYXR0ZXJufSsiLCByZWZlcmVuY2Vfc291cmNlKToKICAgICAgICAgICAgcmVmZXJlbmNlID0gcmVmZXJlbmNlX3NvdXJjZQoKICAgICAgICAjIEZpeCByZWZlcmVuY2UgaWYgaXQgZG9lc24ndCBtYXRjaAogICAgICAgIGVsc2U6CiAgICAgICAgICAgICMgTW9kaWZ5IHRoZSBwYXR0ZXJuIHRvIGJlIHVzZWQgaW4gYHN1YmAKICAgICAgICAgICAgaW5uZXJfcGF0dGVybiA9IHJlZmVyZW5jZV9wYXR0ZXJuWzE6LTFdCiAgICAgICAgICAgIHJlZmVyZW5jZSA9ICgKICAgICAgICAgICAgICAgIHJlLnN1YigKICAgICAgICAgICAgICAgICAgICByZiJbXntpbm5lcl9wYXR0ZXJufV0iLAogICAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICAgIHJlZmVyZW5jZV9zb3VyY2Uuc3RyaXAoKS5yZXBsYWNlKCIgIiwgIl8iKS5sb3dlcigpLAogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgb3Igc2VsZi5fZ2V0X21vZGVsX2dlbmVyaWNfcmVmZXJlbmNlKCkKICAgICAgICAgICAgKQoKICAgICAgICAjIENoZWNrIGlmIHRoZSBzYW1lIHJlZmVyZW5jZSBhbHJlYWR5IGV4aXN0cyBhbmQgYWRkIGEgc3VmZml4IGlmIHllcwogICAgICAgIGNvdW50ZXIgPSAxCiAgICAgICAgZmluYWxfcmVmZXJlbmNlID0gcmVmZXJlbmNlCgogICAgICAgICMgSWYgZXhjbHVkZSBzYW1lIHJlY29yZHMgZnJvbSBzZWFyY2ggcmVzdWx0cwogICAgICAgIGlmIHNlbGYgYW5kIG5vdCBzZWxmLmVudi5jb250ZXh0LmdldCgicmVmZXJlbmNlX21peGluX3NraXBfc2VsZiIpOgogICAgICAgICAgICBkb21haW4gPSBbKCJpZCIsICJub3QgaW4iLCBzZWxmLmlkcyldCiAgICAgICAgZWxzZToKICAgICAgICAgICAgZG9tYWluID0gW10KICAgICAgICBmaW5hbF9kb21haW4gPSBleHByZXNzaW9uLkFORChbZG9tYWluLCBbKCJyZWZlcmVuY2UiLCAiPSIsIGZpbmFsX3JlZmVyZW5jZSldXSkKCiAgICAgICAgIyBTZWFyY2ggYWxsIHJlY29yZHMgd2l0aG91dCByZXN0cmljdGlvbnMgaW5jbHVkaW5nIGFyY2hpdmVkCiAgICAgICAgc2VsZl93aXRoX3N1ZG9fYW5kX2NvbnRleHQgPSBzZWxmLnN1ZG8oKS53aXRoX2NvbnRleHQoYWN0aXZlX3Rlc3Q9RmFsc2UpCiAgICAgICAgd2hpbGUgc2VsZl93aXRoX3N1ZG9fYW5kX2NvbnRleHQuc2VhcmNoX2NvdW50KGZpbmFsX2RvbWFpbikgPiAwOgogICAgICAgICAgICBjb3VudGVyICs9IDEKICAgICAgICAgICAgZmluYWxfcmVmZXJlbmNlID0gZiJ7cmVmZXJlbmNlfV97Y291bnRlcn0iCiAgICAgICAgICAgIGZpbmFsX2RvbWFpbiA9IGV4cHJlc3Npb24uQU5EKAogICAgICAgICAgICAgICAgW2RvbWFpbiwgWygicmVmZXJlbmNlIiwgIj0iLCBmaW5hbF9yZWZlcmVuY2UpXV0KICAgICAgICAgICAgKQoKICAgICAgICByZXR1cm4gZmluYWxfcmVmZXJlbmNlCgogICAgZGVmIF9nZXRfY29waWVkX25hbWUoc2VsZiwgZm9yY2VfbmFtZT1Ob25lKToKICAgICAgICAiIiIKICAgICAgICBSZXR1cm4gYSBjb3BpZWQgbmFtZSBvZiB0aGUgcmVjb3JkCiAgICAgICAgYnkgYWRkaW5nIHRoZSBzdWZmaXggKGNvcHkpIGF0IHRoZSBlbmQKICAgICAgICBhbmQgY291bnRlciB1bnRpbCB0aGUgbmFtZSBpcyB1bmlxdWUuCgogICAgICAgIEFyZ3M6CiAgICAgICAgICAgIGZvcmNlX25hbWUgKHN0cik6IFVzZWQgdG8gdXNlIGZvcmNlIG5hbWUgaW5zdGVhZCBvZiByZWNvcmQgbmFtZS4KCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgQW4gdW5pcXVlIG5hbWUgZm9yIHRoZSBjb3BpZWQgcmVjb3JkCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5lbnN1cmVfb25lKCkKICAgICAgICBvcmlnaW5hbF9uYW1lID0gZm9yY2VfbmFtZSBvciBzZWxmLm5hbWUKICAgICAgICBjb3B5X25hbWUgPSBfKCIlKG5hbWUpcyAoY29weSkiLCBuYW1lPW9yaWdpbmFsX25hbWUpCgogICAgICAgIGNvdW50ZXIgPSAxCiAgICAgICAgIyBFbnN1cmVzIHRoYXQgdGhlIGdlbmVyYXRlZCBjb3B5IG5hbWUgaXMgdW5pcXVlIGJ5CiAgICAgICAgIyBhcHBlbmRpbmcgYSBjb3VudGVyIHVudGlsIGEgdW5pcXVlIG5hbWUgaXMgZm91bmQuCiAgICAgICAgd2hpbGUgc2VsZi5zZWFyY2hfY291bnQoWygibmFtZSIsICI9IiwgY29weV9uYW1lKV0pID4gMDoKICAgICAgICAgICAgY291bnRlciArPSAxCiAgICAgICAgICAgIGNvcHlfbmFtZSA9IF8oCiAgICAgICAgICAgICAgICAiJShuYW1lKXMgKGNvcHkgJShudW1iZXIpcykiLAogICAgICAgICAgICAgICAgbmFtZT1vcmlnaW5hbF9uYW1lLAogICAgICAgICAgICAgICAgbnVtYmVyPXN0cihjb3VudGVyKSwKICAgICAgICAgICAgKQoKICAgICAgICByZXR1cm4gY29weV9uYW1lCgogICAgZGVmIF9nZXRfbW9kZWxfZ2VuZXJpY19yZWZlcmVuY2Uoc2VsZik6CiAgICAgICAgIiIiR2V0IGdlbmVyaWMgcmVmZXJlbmNlIGZvciBjdXJyZW50IG1vZGVsLgogICAgICAgIEdlbmVyaWMgcmVmZXJlbmNlcyBhcmUgdXNlZCBhcyBhIGZhbGxiYWNrIGluIHRoZSBhdXRvbWF0aWMKICAgICAgICByZWZlcmVuY2UgZ2VuZXJhdGlvbi4KICAgICAgICBXaGVuIGEgcmVmZXJlbmNlIGNhbm5vdCBiZSBnZW5lcmF0ZWQgbmVpdGhlciBmcm9tIHRoZSAncmVmZXJlbmNlJwogICAgICAgIG5vciBmcm9tIHRoZSAnbmFtZScgZmllbGQgdmFsdWVzLgoKICAgICAgICBFZyBmb3IgdGhlICdjeC50b3dlci5wbGFuJyBtb2RlbCBzdWNoIHJlZmVyZW5jZSB3aWxsIGxvb2sgbGlrZQogICAgICAgICd0b3dlcl9wbGFuJy4KCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgQ2hhcjogZ2VuZXJhdGVkIHByZWZpeAogICAgICAgICIiIgogICAgICAgIG1vZGVsX3ByZWZpeCA9IHNlbGYuX25hbWUucmVwbGFjZSgiY3gudG93ZXIuIiwgIiIpLnJlcGxhY2UoIi4iLCAiXyIpCiAgICAgICAgcmV0dXJuIG1vZGVsX3ByZWZpeAoKICAgIGRlZiBnZXRfYnlfcmVmZXJlbmNlKHNlbGYsIHJlZmVyZW5jZSk6CiAgICAgICAgIiIiR2V0IHJlY29yZCBiYXNlZCBvbiBpdHMgcmVmZXJlbmNlLgoKICAgICAgICBJbXBvcnRhbnQ6IHJlZmVyZW5jZXMgYXJlIGNhc2Ugc2Vuc2l0aXZlIQoKICAgICAgICBBcmdzOgogICAgICAgICAgICByZWZlcmVuY2UgKENoYXIpOiByZWNvcmQgcmVmZXJlbmNlCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIFJlY29yZDogUmVjb3JkIHRoYXQgbWF0Y2hlcyBwcm92aWRlZCByZWZlcmVuY2UKICAgICAgICAiIiIKICAgICAgICByZXR1cm4gc2VsZi5icm93c2Uoc2VsZi5fZ2V0X2lkX2J5X3JlZmVyZW5jZShyZWZlcmVuY2UpKQoKICAgIEBvcm1jYWNoZSgic2VsZi5lbnYudWlkIiwgInNlbGYuZW52LnN1IiwgInJlZmVyZW5jZSIpCiAgICBkZWYgX2dldF9pZF9ieV9yZWZlcmVuY2Uoc2VsZiwgcmVmZXJlbmNlKToKICAgICAgICAiIiJHZXQgcmVjb3JkIGlkIGJhc2VkIG9uIGl0cyByZWZlcmVuY2UuCgogICAgICAgIEltcG9ydGFudDogcmVmZXJlbmNlcyBhcmUgY2FzZSBzZW5zaXRpdmUhCgogICAgICAgIEFyZ3M6CiAgICAgICAgICAgIHJlZmVyZW5jZSAoQ2hhcik6IHJlY29yZCByZWZlcmVuY2UKCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgUmVjb3JkOiBSZWNvcmQgaWQgdGhhdCBtYXRjaGVzIHByb3ZpZGVkIHJlZmVyZW5jZQogICAgICAgICIiIgogICAgICAgIHJlY29yZHMgPSBzZWxmLnNlYXJjaChbKCJyZWZlcmVuY2UiLCAiPSIsIHJlZmVyZW5jZSldKQoKICAgICAgICAjIFRoaXMgaXMgaW4gY2FzZSBzb21lIG1vZGVscyB3aWxsIHJlbW92ZSByZWZlcmVuY2UgdW5pcXVlbmVzcyBjb25zdHJhaW50CiAgICAgICAgcmV0dXJuIHJlY29yZHMgYW5kIHJlY29yZHNbMF0uaWQKCiAgICBAYXBpLm1vZGVsCiAgICBkZWYgX3ByZXBhcmVfcmVmZXJlbmNlcyhzZWxmLCBtb2RlbCwga2V5X25hbWUsIHZhbHNfbGlzdCk6CiAgICAgICAgIiIiCiAgICAgICAgUHJlcGFyZSBhIGRpY3Rpb25hcnkgb2YgcmVmZXJlbmNlcyBmb3IgZ2l2ZW4gbW9kZWwgcmVjb3Jkcy4KCiAgICAgICAgVGhpcyBmdW5jdGlvbiBleHRyYWN0cyB1bmlxdWUgSURzIGZyb20gYSBsaXN0IG9mIGRpY3Rpb25hcmllcyAodmFsc19saXN0KQogICAgICAgIGJhc2VkIG9uIGEgc3BlY2lmaWVkIGtleSAoa2V5X25hbWUpLCBmZXRjaGVzIHRoZSBjb3JyZXNwb25kaW5nIHJlY29yZHMKICAgICAgICBmcm9tIHRoZSBzcGVjaWZpZWQgbW9kZWwsIGFuZCByZXR1cm5zIGEgZGljdGlvbmFyeSBtYXBwaW5nIHJlY29yZCBJRHMgdG8KICAgICAgICB0aGVpciByZWZlcmVuY2VzLgoKICAgICAgICBBcmdzOgogICAgICAgICAgICBtb2RlbCAoc3RyKTogVGhlIG5hbWUgb2YgdGhlIG1vZGVsIHRvIGZldGNoIHJlY29yZHMgZnJvbS4KICAgICAgICAgICAga2V5X25hbWUgKHN0cik6IFRoZSBrZXkgaW4gdGhlIGRpY3Rpb25hcmllcyBvZiB2YWxzX2xpc3QgdGhhdCBjb250YWlucwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIHJlY29yZCBJRHMuCiAgICAgICAgICAgIHZhbHNfbGlzdCAobGlzdCBvZiBkaWN0KTogQSBsaXN0IG9mIGRpY3Rpb25hcmllcyBjb250YWluaW5nIHRoZSB2YWx1ZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gYmUgcHJvY2Vzc2VkLgoKICAgICAgICBSZXR1cm5zOgogICAgICAgICAgICBkaWN0OiBBIGRpY3Rpb25hcnkgbWFwcGluZyByZWNvcmQgSURzIHRvIHRoZWlyIHJlZmVyZW5jZXMuCiAgICAgICAgIiIiCiAgICAgICAgaWYgbm90IHZhbHNfbGlzdDoKICAgICAgICAgICAgIyBObyBlbnRyaWVzIHRvIHByb2Nlc3MsIHJldHVybiBhbiBlbXB0eSBkaWN0aW9uYXJ5CiAgICAgICAgICAgIHJldHVybiB7fQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIEN4TW9kZWwgPSBzZWxmLmVudlttb2RlbF0KICAgICAgICBleGNlcHQgS2V5RXJyb3IgYXMgZXJyOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKAogICAgICAgICAgICAgICAgXygKICAgICAgICAgICAgICAgICAgICAoCiAgICAgICAgICAgICAgICAgICAgICAgICJNb2RlbCAnJShtb2RlbClzJyBkb2VzIG5vdCBleGlzdC4gIgogICAgICAgICAgICAgICAgICAgICAgICAiUGxlYXNlIHByb3ZpZGUgYSB2YWxpZCBtb2RlbCBuYW1lLiIKICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgIG1vZGVsPW1vZGVsLAogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApIGZyb20gZXJyCgogICAgICAgICMgRXh0cmFjdCBhbGwgdW5pcXVlIGlkcyBmcm9tIHZhbHNfbGlzdAogICAgICAgIGxpbmVfaWRzID0gewogICAgICAgICAgICB2YWxzLmdldChrZXlfbmFtZSkKICAgICAgICAgICAgZm9yIHZhbHMgaW4gdmFsc19saXN0CiAgICAgICAgICAgIGlmIHZhbHMuZ2V0KGtleV9uYW1lKSBhbmQgbm90IHZhbHMuZ2V0KCJyZWZlcmVuY2UiKQogICAgICAgIH0KCiAgICAgICAgIyBGZXRjaCBhbGwgbGluZSByZWZlcmVuY2VzIGluIGEgc2luZ2xlIHF1ZXJ5CiAgICAgICAgbGluZXMgPSBDeE1vZGVsLmJyb3dzZShsaW5lX2lkcykKICAgICAgICByZXR1cm4ge2xpbmUuaWQ6IGxpbmUucmVmZXJlbmNlIGZvciBsaW5lIGluIGxpbmVzIGlmIGxpbmUucmVmZXJlbmNlfQoKICAgIEBhcGkubW9kZWwKICAgIGRlZiBfcHJlX3BvcHVsYXRlX3JlZmVyZW5jZXMoc2VsZiwgbW9kZWxfbmFtZSwgZmllbGRfbmFtZSwgdmFsc19saXN0KToKICAgICAgICAiIiIKICAgICAgICBQb3B1bGF0ZXMgcmVmZXJlbmNlIGZpZWxkcyBpbiBhIGxpc3Qgb2YgZGljdGlvbmFyaWVzICh2YWxzX2xpc3QpCiAgICAgICAgaW50ZW5kZWQgZm9yIHJlY29yZCBjcmVhdGlvbi4KCiAgICAgICAgVGhpcyBtZXRob2QgZ2VuZXJhdGVzIHVuaXF1ZSByZWZlcmVuY2VzIGZvciBlYWNoIGRpY3Rpb25hcnkgZW50cnkgaW4KICAgICAgICBgdmFsc19saXN0YCBiYXNlZCBvbiBhIHNwZWNpZmllZCBmaWVsZCB0aGF0IGxpbmtzIHRvIHJlY29yZHMgaW4KICAgICAgICBhbm90aGVyIG1vZGVsIChpbmRpY2F0ZWQgYnkgYG1vZGVsX25hbWVgKS4gSXQgdXNlcyBleGlzdGluZyByZWZlcmVuY2VzCiAgICAgICAgZnJvbSB0aGUgcmVsYXRlZCByZWNvcmRzIGFzIGEgYmFzaXMgYW5kIGFwcGVuZHMgYSBzdWZmaXggYW5kIGFuCiAgICAgICAgaW5jcmVtZW50aW5nIGluZGV4IHRvIGVuc3VyZSB1bmlxdWVuZXNzLgogICAgICAgIElmIHJlZmVyZW5jZSBpcyBwcmVzZW50IGluIHZhbHVlcyBpdCB3aWxsIG5vdCBiZSBvdmVyd3JpdHRlbi4KCiAgICAgICAgQXJnczoKICAgICAgICAgICAgbW9kZWxfbmFtZSAoc3RyKTogVGhlIG5hbWUgb2YgdGhlIHJlbGF0ZWQgbW9kZWwgdG8gZXh0cmFjdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2UgZGF0YSBmcm9tLgogICAgICAgICAgICBmaWVsZF9uYW1lIChzdHIpOiBUaGUga2V5IGluIGVhY2ggZGljdGlvbmFyeSBpbiBgdmFsc19saXN0YAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250YWluaW5nIHRoZSByZWxhdGVkIHJlY29yZCdzIElELgogICAgICAgICAgICB2YWxzX2xpc3QgKGxpc3Qgb2YgZGljdCk6IEEgbGlzdCBvZiBkaWN0aW9uYXJpZXMgd2hlcmUgZWFjaCBkaWN0aW9uYXJ5CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXByZXNlbnRzIHZhbHVlcyBmb3IgYSBuZXcgcmVjb3JkLgoKICAgICAgICBSZXR1cm5zOgogICAgICAgICAgICBsaXN0OiBUaGUgbW9kaWZpZWQgYHZhbHNfbGlzdGAsIHdpdGggYSB1bmlxdWUgJ3JlZmVyZW5jZScKICAgICAgICAgICAgICAgICAgZW50cnkgaW4gZWFjaCBkaWN0aW9uYXJ5LgogICAgICAgICIiIgoKICAgICAgICAjIEV4dHJhY3QgcGFyZW50IHJlY29yZCByZWZlcmVuY2VzIGZyb20gdmFsc19saXN0CiAgICAgICAgcGFyZW50X3JlY29yZF9yZWZzID0gc2VsZi5fcHJlcGFyZV9yZWZlcmVuY2VzKG1vZGVsX25hbWUsIGZpZWxkX25hbWUsIHZhbHNfbGlzdCkKICAgICAgICBsaW5lX2luZGV4X2RpY3QgPSBkZWZhdWx0ZGljdChpbnQpCgogICAgICAgICMgVXNlZCB0byBtYWtlIHJlZmVyZW5jZSBtb3JlIHJlYWRhYmxlCiAgICAgICAgbW9kZWxfcmVmZXJlbmNlID0gc2VsZi5fZ2V0X21vZGVsX2dlbmVyaWNfcmVmZXJlbmNlKCkKCiAgICAgICAgIyBQb3B1bGF0ZSB2YWxzIHdpdGggcmVmZXJlbmNlcwogICAgICAgIGZvciB2YWxzIGluIHZhbHNfbGlzdDoKICAgICAgICAgICAgIyBTa2lwIGlmIHJlZmVyZW5jZSBpcyBwcm92aWRlZCBleHBsaWNpdGx5IGFuZCBoYXMgc3ltYm9scwogICAgICAgICAgICBleGlzdGluZ19yZWZlcmVuY2UgPSB2YWxzLmdldCgicmVmZXJlbmNlIikKICAgICAgICAgICAgaWYgZXhpc3RpbmdfcmVmZXJlbmNlIGFuZCBib29sKAogICAgICAgICAgICAgICAgcmUuc2VhcmNoKHNlbGYuUkVGRVJFTkNFX1BSRUxJTUlOQVJZX1BBVFRFUk4sIGV4aXN0aW5nX3JlZmVyZW5jZSkKICAgICAgICAgICAgKToKICAgICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICAgICAjIENvbXBvc2UgYmFzZWQgb24gcmVsYXRlZCByZWNvcmQgcmVmZXJlbmNlIGlmIGV4aXN0cwogICAgICAgICAgICByZWNvcmRfaWQgPSB2YWxzLmdldChmaWVsZF9uYW1lKQogICAgICAgICAgICBpZiByZWNvcmRfaWQgYW5kIHBhcmVudF9yZWNvcmRfcmVmcy5nZXQocmVjb3JkX2lkKToKICAgICAgICAgICAgICAgIGxpbmVfaW5kZXhfZGljdFtyZWNvcmRfaWRdICs9IDEKICAgICAgICAgICAgICAgIGxpbmVfaW5kZXggPSBsaW5lX2luZGV4X2RpY3RbcmVjb3JkX2lkXQogICAgICAgICAgICAgICAgdmFsc1sKICAgICAgICAgICAgICAgICAgICAicmVmZXJlbmNlIgogICAgICAgICAgICAgICAgXSA9IGYie3BhcmVudF9yZWNvcmRfcmVmc1tyZWNvcmRfaWRdfV97bW9kZWxfcmVmZXJlbmNlfV97bGluZV9pbmRleH0iCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAjIEhhbmRsZSBjYXNlcyB3aGVyZSB0aGUgZmllbGQgaXMgbm90IHByZXNlbnQKICAgICAgICAgICAgICAgIGxpbmVfaW5kZXhfZGljdFsibm9fcmVjb3JkIl0gKz0gMQogICAgICAgICAgICAgICAgbGluZV9pbmRleCA9IGxpbmVfaW5kZXhfZGljdFsibm9fcmVjb3JkIl0KICAgICAgICAgICAgICAgIHZhbHNbInJlZmVyZW5jZSJdID0gZiJub197bW9kZWxfcmVmZXJlbmNlfV97bGluZV9pbmRleH0iCgogICAgICAgIHJldHVybiB2YWxzX2xpc3QK \ No newline at end of file