aW1wb3J0IHRyYWNlYmFjawppbXBvcnQgc3lzCmltcG9ydCBXCmltcG9ydCBvcwppbXBvcnQgdHlwZXMKaW1wb3J0IExpc3QKCgpjbGFzcyBUcmFjZUJhY2s6CgkKCWRlZiBfX2luaXRfXyhzZWxmLCB0aXRsZSA9ICJUcmFjZWJhY2siKToKCQlhcHAgPSBXLmdldGFwcGxpY2F0aW9uKCkgICMgY2hlY2tzIGlmIFcgaXMgcHJvcGVybHkgaW5pdGlhbGl6ZWQKCQlzZWxmLnRpdGxlID0gdGl0bGUKCQlzZWxmLncgPSBOb25lCgkJc2VsZi5jbG9zZWQgPSAxCgkJc2VsZi5zdGFydCA9IDAKCQlzZWxmLmxhc3R3aW5kb3d0aXRsZSA9ICIiCgkJc2VsZi5ib3VuZHMgPSAoMzYwLCAyOTgpCgkKCWRlZiB0cmFjZWJhY2soc2VsZiwgc3RhcnQgPSAwLCBsYXN0d2luZG93dGl0bGUgPSAiIik6CgkJdHJ5OgoJCQlzZWxmLmxhc3R3aW5kb3d0aXRsZSA9IGxhc3R3aW5kb3d0aXRsZQoJCQlzZWxmLnN0YXJ0ID0gc3RhcnQKCQkJc2VsZi50eXBlLCBzZWxmLnZhbHVlLCBzZWxmLnRiID0gc3lzLmV4Y19pbmZvKCkKCQkJaWYgc2VsZi50eXBlIGlzIG5vdCBTeW50YXhFcnJvcjoKCQkJCXNlbGYuc2hvdygpCgkJCQlpZiB0eXBlKHNlbGYudHlwZSkgPT0gdHlwZXMuQ2xhc3NUeXBlOgoJCQkJCWVycm9ydGV4dCA9IHNlbGYudHlwZS5fX25hbWVfXwoJCQkJZWxzZToKCQkJCQllcnJvcnRleHQgPSBzdHIoc2VsZi50eXBlKQoJCQkJdmFsdWUgPSBzdHIoc2VsZi52YWx1ZSkKCQkJCWlmIHNlbGYudmFsdWUgYW5kIHZhbHVlOgoJCQkJCWVycm9ydGV4dCA9IGVycm9ydGV4dCArICI6ICIgKyB2YWx1ZQoJCQkJc2VsZi53LnRleHQuc2V0KGVycm9ydGV4dCkKCQkJCXNlbGYuYnVpbGR0Ymxpc3QoKQoJCQkJc2VsZi53Lmxpc3Quc2V0KHNlbGYudGV4dGxpc3QpCgkJCQlzZWxmLncubGlzdC5zZXRzZWxlY3Rpb24oW2xlbihzZWxmLnRleHRsaXN0KSAtIDFdKQoJCQkJc2VsZi53LndpZC5TZWxlY3RXaW5kb3coKQoJCQkJc2VsZi5jbG9zZWQgPSAwCgkJCWVsc2U6CgkJCQlzZWxmLnN5bnRheGVycm9yKCkKCQlleGNlcHQ6CgkJCXRyYWNlYmFjay5wcmludF9leGMoKQoJCglkZWYgc3ludGF4ZXJyb3Ioc2VsZik6CgkJdHJ5OgoJCQl2YWx1ZSwgKGZpbGVuYW1lLCBsaW5lbm8sIGNoYXJubywgbGluZSkgPSBzZWxmLnZhbHVlCgkJZXhjZXB0OgoJCQlmaWxlbmFtZSA9ICIiCgkJCWxpbmVubyA9IE5vbmUKCQkJdmFsdWUgPSBzZWxmLnZhbHVlCgkJaWYgbm90IGZpbGVuYW1lIGFuZCBzZWxmLmxhc3R3aW5kb3d0aXRsZToKCQkJZmlsZW5hbWUgPSBzZWxmLmxhc3R3aW5kb3d0aXRsZQoJCWVsaWYgbm90IGZpbGVuYW1lOgoJCQlmaWxlbmFtZSA9ICI8dW5rbm93bj4iCgkJaWYgZmlsZW5hbWUgYW5kIG9zLnBhdGguZXhpc3RzKGZpbGVuYW1lKToKCQkJZmlsZW5hbWUgPSBvcy5wYXRoLnNwbGl0KGZpbGVuYW1lKVsxXQoJCWlmIGxpbmVubzoKCQkJY2hhcm5vID0gY2hhcm5vIC0gMQoJCQl0ZXh0ID0gc3RyKHZhbHVlKSArICdcckZpbGU6ICInICsgc3RyKGZpbGVuYW1lKSArICciLCBsaW5lICcgKyBzdHIobGluZW5vKSArICdcclxyJyArIGxpbmVbOmNoYXJub10gKyAigCIgKyBsaW5lW2NoYXJubzotMV0KCQllbHNlOgoJCQl0ZXh0ID0gc3RyKHZhbHVlKSArICdcckZpbGU6ICInICsgc3RyKGZpbGVuYW1lKSArICciJwoJCXNlbGYuc3ludGF4ZGlhbG9nID0gVy5Nb2RhbERpYWxvZygoMzYwLCAxMjApLCAiU3ludGF4IEVycm9yIikKCQlzZWxmLnN5bnRheGRpYWxvZy50ZXh0ID0gVy5UZXh0Qm94KCgxMCwgMTAsIC0xMCwgLTQwKSwgdGV4dCkKCQlzZWxmLnN5bnRheGRpYWxvZy5jYW5jZWwgPSBXLkJ1dHRvbigoLTE5MCwgLTMyLCA4MCwgMTYpLCAiQ2FuY2VsIiwgc2VsZi5zeW50YXhjbG9zZSkKCQlzZWxmLnN5bnRheGRpYWxvZy5lZGl0ID0gVy5CdXR0b24oKC0xMDAsIC0zMiwgODAsIDE2KSwgIkVkaXQiLCBzZWxmLnN5bnRheGVkaXQpCgkJc2VsZi5zeW50YXhkaWFsb2cuc2V0ZGVmYXVsdGJ1dHRvbihzZWxmLnN5bnRheGRpYWxvZy5lZGl0KQoJCXNlbGYuc3ludGF4ZGlhbG9nLmJpbmQoImNtZC4iLCBzZWxmLnN5bnRheGRpYWxvZy5jYW5jZWwucHVzaCkKCQlzZWxmLnN5bnRheGRpYWxvZy5vcGVuKCkKCQoJZGVmIHN5bnRheGNsb3NlKHNlbGYpOgoJCXNlbGYuc3ludGF4ZGlhbG9nLmNsb3NlKCkKCQlkZWwgc2VsZi5zeW50YXhkaWFsb2cKCQoJZGVmIHN5bnRheGVkaXQoc2VsZik6CgkJdHJ5OgoJCQl2YWx1ZSwgKGZpbGVuYW1lLCBsaW5lbm8sIGNoYXJubywgbGluZSkgPSBzZWxmLnZhbHVlCgkJZXhjZXB0OgoJCQlmaWxlbmFtZSA9ICIiCgkJCWxpbmVubyA9IE5vbmUKCQlpZiBub3QgZmlsZW5hbWUgYW5kIHNlbGYubGFzdHdpbmRvd3RpdGxlOgoJCQlmaWxlbmFtZSA9IHNlbGYubGFzdHdpbmRvd3RpdGxlCgkJZWxpZiBub3QgZmlsZW5hbWU6CgkJCWZpbGVuYW1lID0gIjx1bmtub3duPiIKCQlzZWxmLnN5bnRheGNsb3NlKCkKCQlpZiBsaW5lbm86CgkJCVcuZ2V0YXBwbGljYXRpb24oKS5vcGVuc2NyaXB0KGZpbGVuYW1lLCBsaW5lbm8sIGNoYXJubyAtIDEpCgkJZWxzZToKCQkJVy5nZXRhcHBsaWNhdGlvbigpLm9wZW5zY3JpcHQoZmlsZW5hbWUpCgkKCWRlZiBzaG93KHNlbGYpOgoJCWlmIHNlbGYuY2xvc2VkOgoJCQlzZWxmLnNldHVwd2lkZ2V0cygpCgkJCXNlbGYudy5vcGVuKCkKCQllbHNlOgoJCQlzZWxmLncud2lkLlNob3dXaW5kb3coKQoJCQlzZWxmLncud2lkLlNlbGVjdFdpbmRvdygpCgkKCWRlZiBoaWRlKHNlbGYpOgoJCWlmIHNlbGYuY2xvc2VkOgoJCQlyZXR1cm4KCQlzZWxmLncuY2xvc2UoKQoJCglkZWYgY2xvc2Uoc2VsZik6CgkJc2VsZi5ib3VuZHMgPSBzZWxmLncuZ2V0Ym91bmRzKCkKCQlzZWxmLmNsb3NlZCA9IDEKCQlzZWxmLnR5cGUsIHNlbGYudmFsdWUsIHNlbGYudGIgPSBOb25lLCBOb25lLCBOb25lCgkJc2VsZi50Ymxpc3QgPSBOb25lCgkKCWRlZiBhY3RpdmF0ZShzZWxmLCBvbm9mZik6CgkJaWYgb25vZmY6CgkJCWlmIHNlbGYuY2xvc2VkOgoJCQkJc2VsZi50cmFjZWJhY2soKQoJCQlzZWxmLmNsb3NlZCA9IDAKCQkJc2VsZi5jaGVja2J1dHRvbnMoKQoJCglkZWYgc2V0dXB3aWRnZXRzKHNlbGYpOgoJCXNlbGYudyA9IFcuV2luZG93KHNlbGYuYm91bmRzLCBzZWxmLnRpdGxlLCBtaW5zaXplID0gKDMxNiwgMTY4KSkKCQlzZWxmLncudGV4dCA9IFcuVGV4dEJveCgoMTAsIDEwLCAtMTAsIDMwKSkKCQlzZWxmLncudGJ0aXRsZSA9IFcuVGV4dEJveCgoMTAsIDQwLCAtMTAsIDEwKSwgIlRyYWNlYmFjayAoaW5uZXJtb3N0IGxhc3QpOiIpCgkJc2VsZi53Lmxpc3QgPSBXLlR3b0xpbmVMaXN0KCgxMCwgNjAsIC0xMCwgLTQwKSwgY2FsbGJhY2sgPSBzZWxmLmxpc3RoaXQpCgkJCgkJc2VsZi53LmVkaXRidXR0b24gPSBXLkJ1dHRvbigoMTAsIC0zMCwgNjAsIDE2KSwgIkVkaXQiLCBzZWxmLmVkaXQpCgkJc2VsZi53LmVkaXRidXR0b24uZW5hYmxlKDApCgkJCgkJc2VsZi53LmJyb3dzZWxvY2Fsc2J1dHRvbiA9IFcuQnV0dG9uKCg4MCwgLTMwLCAxMDAsIDE2KSwgIkJyb3dzZSBsb2NhbHOKIiwgc2VsZi5icm93c2Vsb2NhbHMpCgkJc2VsZi53LmJyb3dzZWxvY2Fsc2J1dHRvbi5lbmFibGUoMCkKCQkKCQlzZWxmLncucG9zdG1vcnRlbWJ1dHRvbiA9IFcuQnV0dG9uKCgxOTAsIC0zMCwgMTAwLCAxNiksICJQb3N0IG1vcnRlbYoiLCBzZWxmLnBvc3Rtb3J0ZW0pCgkJCgkJc2VsZi53LnNldGRlZmF1bHRidXR0b24oc2VsZi53LmVkaXRidXR0b24pCgkJc2VsZi53LmJpbmQoImNtZGIiLCBzZWxmLncuYnJvd3NlbG9jYWxzYnV0dG9uLnB1c2gpCgkJc2VsZi53LmJpbmQoIjxjbG9zZT4iLCBzZWxmLmNsb3NlKQoJCXNlbGYudy5iaW5kKCI8YWN0aXZhdGU+Iiwgc2VsZi5hY3RpdmF0ZSkKCQoJZGVmIGJ1aWxkdGJsaXN0KHNlbGYpOgoJCXRiID0gc2VsZi50YgoJCWZvciBpIGluIHJhbmdlKHNlbGYuc3RhcnQpOgoJCQlpZiB0Yi50Yl9uZXh0IGlzIE5vbmU6CgkJCQlicmVhawoJCQl0YiA9IHRiLnRiX25leHQKCQlzZWxmLnRibGlzdCA9IHRyYWNlYmFjay5leHRyYWN0X3RiKHRiKQoJCXNlbGYudGV4dGxpc3QgPSBbXQoJCWZvciBmaWxlbmFtZSwgbGluZW5vLCBmdW5jLCBsaW5lIGluIHNlbGYudGJsaXN0OgoJCQl0YmxpbmUgPSAiIgoJCQlpZiBvcy5wYXRoLmV4aXN0cyhmaWxlbmFtZSk6CgkJCQlmaWxlbmFtZSA9IG9zLnBhdGguc3BsaXQoZmlsZW5hbWUpWzFdCgkJCQl0YmxpbmUgPSAnRmlsZSAiJyArIGZpbGVuYW1lICsgJyIsIGxpbmUgJyArIGBsaW5lbm9gICsgJywgaW4gJyArIGZ1bmMKCQkJZWxzZToKCQkJCXRibGluZSA9ICdGaWxlICInICsgZmlsZW5hbWUgKyAnIiwgbGluZSAnICsgYGxpbmVub2AgKyAnLCBpbiAnICsgZnVuYwoJCQlpZiBsaW5lOgoJCQkJdGJsaW5lID0gdGJsaW5lICsgJ1xyICAgICAgJyArIGxpbmUKCQkJc2VsZi50ZXh0bGlzdC5hcHBlbmQodGJsaW5lWzoyNTVdKQoJCglkZWYgZWRpdChzZWxmKToKCQlzZWwgPSBzZWxmLncubGlzdC5nZXRzZWxlY3Rpb24oKQoJCWZvciBpIGluIHNlbDoKCQkJZmlsZW5hbWUsIGxpbmVubywgZnVuYywgbGluZSA9IHNlbGYudGJsaXN0W2ldCgkJCVcuZ2V0YXBwbGljYXRpb24oKS5vcGVuc2NyaXB0KGZpbGVuYW1lLCBsaW5lbm8pCgkKCWRlZiBicm93c2Vsb2NhbHMoc2VsZik6CgkJc2VsID0gc2VsZi53Lmxpc3QuZ2V0c2VsZWN0aW9uKCkKCQlmb3IgaSBpbiBzZWw6CgkJCXRiID0gc2VsZi50YgoJCQlmb3IgaiBpbiByYW5nZShpICsgc2VsZi5zdGFydCk6CgkJCQl0YiA9IHRiLnRiX25leHQKCQkJc2VsZi5icm93c2UodGIudGJfZnJhbWUuZl9sb2NhbHMpCgkKCWRlZiBicm93c2Uoc2VsZiwgb2JqZWN0KToKCQlpbXBvcnQgUHlCcm93c2VyCgkJUHlCcm93c2VyLkJyb3dzZXIob2JqZWN0KQoJCglkZWYgcG9zdG1vcnRlbShzZWxmKToKCQlpbXBvcnQgUHlEZWJ1Z2dlcgoJCVB5RGVidWdnZXIucG9zdG1vcnRlbShzZWxmLnR5cGUsIHNlbGYudmFsdWUsIHNlbGYudGIpCgkKCWRlZiBsaXN0aGl0KHNlbGYsIGlzZGJsKToKCQlpZiBpc2RibDoKCQkJc2VsZi53LmVkaXRidXR0b24ucHVzaCgpCgkJZWxzZToKCQkJc2VsZi5jaGVja2J1dHRvbnMoKQoJCglkZWYgY2hlY2tidXR0b25zKHNlbGYpOgoJCWhhdmVmaWxlID0gbGVuKHNlbGYudy5saXN0LmdldHNlbGVjdGlvbigpKSA+IDAKCQlzZWxmLncuZWRpdGJ1dHRvbi5lbmFibGUoaGF2ZWZpbGUpCgkJc2VsZi53LmJyb3dzZWxvY2Fsc2J1dHRvbi5lbmFibGUoaGF2ZWZpbGUpCgkJc2VsZi53LnNldGRlZmF1bHRidXR0b24oaGF2ZWZpbGUgYW5kIHNlbGYudy5lZGl0YnV0dG9uIG9yIHNlbGYudy5wb3N0bW9ydGVtYnV0dG9uKQoK