LyoKICogQ29weXJpZ2h0IChjKSAyMDE2IFNvYXBCb3ggSW5ub3ZhdGlvbnMgSW5jLgogKgogKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5CiAqIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLCB0byBkZWFsCiAqIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMKICogdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbAogKiBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMKICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKICoKICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4KICogYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCiAqCiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCiAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLAogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKICogQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUgogKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLAogKiBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOCiAqIFRIRSBTT0ZUV0FSRS4KKi8KCjsoZnVuY3Rpb24gKCkgewondXNlIHN0cmljdCc7Cgp2YXIgX3R5cGVvZiA9IHR5cGVvZiBTeW1ib2wgPT09ICJmdW5jdGlvbiIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gInN5bWJvbCIgPyBmdW5jdGlvbiAob2JqKSB7IHJldHVybiB0eXBlb2Ygb2JqOyB9IDogZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09ICJmdW5jdGlvbiIgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgPyAic3ltYm9sIiA6IHR5cGVvZiBvYmo7IH07CgooZnVuY3Rpb24gKGV4cG9ydHMpIHsKCSd1c2Ugc3RyaWN0JzsKCglmdW5jdGlvbiBpbmhlcml0cyhwYXJlbnQsIGNoaWxkKSB7CgkJdmFyIHByb3BzID0gYXJndW1lbnRzLmxlbmd0aCA8PSAyIHx8IGFyZ3VtZW50c1syXSA9PT0gdW5kZWZpbmVkID8ge30gOiBhcmd1bWVudHNbMl07CgoJCXZhciBleHRlbmRlZCA9IE9iamVjdC5jcmVhdGUocGFyZW50LnByb3RvdHlwZSk7CgkJZm9yICh2YXIgcCBpbiBwcm9wcykgewoJCQlleHRlbmRlZFtwXSA9IHByb3BzW3BdOwoJCX0KCQlleHRlbmRlZC5jb25zdHJ1Y3RvciA9IGNoaWxkOwoJCWNoaWxkLnByb3RvdHlwZSA9IGV4dGVuZGVkOwoJCXJldHVybiBjaGlsZDsKCX0KCgl2YXIgZGVmYXVsdHMgPSB7CgkJZGVmYXVsdFByb3RvY29sOiAnaHR0cCcsCgkJZXZlbnRzOiBudWxsLAoJCWZvcm1hdDogbm9vcCwKCQlmb3JtYXRIcmVmOiBub29wLAoJCW5sMmJyOiBmYWxzZSwKCQl0YWdOYW1lOiAnYScsCgkJdGFyZ2V0OiB0eXBlVG9UYXJnZXQsCgkJdmFsaWRhdGU6IHRydWUsCgkJaWdub3JlVGFnczogW10sCgkJYXR0cmlidXRlczogbnVsbCwKCQljbGFzc05hbWU6ICdsaW5raWZpZWQnIH07CgoJZnVuY3Rpb24gT3B0aW9ucyhvcHRzKSB7CgkJb3B0cyA9IG9wdHMgfHwge307CgoJCXRoaXMuZGVmYXVsdFByb3RvY29sID0gb3B0cy5kZWZhdWx0UHJvdG9jb2wgfHwgZGVmYXVsdHMuZGVmYXVsdFByb3RvY29sOwoJCXRoaXMuZXZlbnRzID0gb3B0cy5ldmVudHMgfHwgZGVmYXVsdHMuZXZlbnRzOwoJCXRoaXMuZm9ybWF0ID0gb3B0cy5mb3JtYXQgfHwgZGVmYXVsdHMuZm9ybWF0OwoJCXRoaXMuZm9ybWF0SHJlZiA9IG9wdHMuZm9ybWF0SHJlZiB8fCBkZWZhdWx0cy5mb3JtYXRIcmVmOwoJCXRoaXMubmwyYnIgPSBvcHRzLm5sMmJyIHx8IGRlZmF1bHRzLm5sMmJyOwoJCXRoaXMudGFnTmFtZSA9IG9wdHMudGFnTmFtZSB8fCBkZWZhdWx0cy50YWdOYW1lOwoJCXRoaXMudGFyZ2V0ID0gb3B0cy50YXJnZXQgfHwgZGVmYXVsdHMudGFyZ2V0OwoJCXRoaXMudmFsaWRhdGUgPSBvcHRzLnZhbGlkYXRlIHx8IGRlZmF1bHRzLnZhbGlkYXRlOwoJCXRoaXMuaWdub3JlVGFncyA9IFtdOwoKCQkvLyBsaW5rQXR0cmlidXRlcyBhbmQgbGlua0NsYXNzIGlzIGRlcHJlY2F0ZWQKCQl0aGlzLmF0dHJpYnV0ZXMgPSBvcHRzLmF0dHJpYnV0ZXMgfHwgb3B0cy5saW5rQXR0cmlidXRlcyB8fCBkZWZhdWx0cy5hdHRyaWJ1dGVzOwoJCXRoaXMuY2xhc3NOYW1lID0gb3B0cy5jbGFzc05hbWUgfHwgb3B0cy5saW5rQ2xhc3MgfHwgZGVmYXVsdHMuY2xhc3NOYW1lOwoKCQkvLyBNYWtlIGFsbCB0YWdzIG5hbWVzIHVwcGVyIGNhc2UKCgkJdmFyIGlnbm9yZWRUYWdzID0gb3B0cy5pZ25vcmVUYWdzIHx8IGRlZmF1bHRzLmlnbm9yZVRhZ3M7CgkJZm9yICh2YXIgaSA9IDA7IGkgPCBpZ25vcmVkVGFncy5sZW5ndGg7IGkrKykgewoJCQl0aGlzLmlnbm9yZVRhZ3MucHVzaChpZ25vcmVkVGFnc1tpXS50b1VwcGVyQ2FzZSgpKTsKCQl9Cgl9CgoJT3B0aW9ucy5wcm90b3R5cGUgPSB7CgkJLyoqCiAgICogR2l2ZW4gdGhlIHRva2VuLCByZXR1cm4gYWxsIG9wdGlvbnMgZm9yIGhvdyBpdCBzaG91bGQgYmUgZGlzcGxheWVkCiAgICovCgkJcmVzb2x2ZTogZnVuY3Rpb24gcmVzb2x2ZSh0b2tlbikgewoJCQl2YXIgaHJlZiA9IHRva2VuLnRvSHJlZih0aGlzLmRlZmF1bHRQcm90b2NvbCk7CgkJCXJldHVybiB7CgkJCQlmb3JtYXR0ZWQ6IHRoaXMuZ2V0KCdmb3JtYXQnLCB0b2tlbi50b1N0cmluZygpLCB0b2tlbiksCgkJCQlmb3JtYXR0ZWRIcmVmOiB0aGlzLmdldCgnZm9ybWF0SHJlZicsIGhyZWYsIHRva2VuKSwKCQkJCXRhZ05hbWU6IHRoaXMuZ2V0KCd0YWdOYW1lJywgaHJlZiwgdG9rZW4pLAoJCQkJY2xhc3NOYW1lOiB0aGlzLmdldCgnY2xhc3NOYW1lJywgaHJlZiwgdG9rZW4pLAoJCQkJdGFyZ2V0OiB0aGlzLmdldCgndGFyZ2V0JywgaHJlZiwgdG9rZW4pLAoJCQkJZXZlbnRzOiB0aGlzLmdldE9iamVjdCgnZXZlbnRzJywgaHJlZiwgdG9rZW4pLAoJCQkJYXR0cmlidXRlczogdGhpcy5nZXRPYmplY3QoJ2F0dHJpYnV0ZXMnLCBocmVmLCB0b2tlbikKCQkJfTsKCQl9LAoKCgkJLyoqCiAgICogUmV0dXJucyB0cnVlIG9yIGZhbHNlIGJhc2VkIG9uIHdoZXRoZXIgYSB0b2tlbiBzaG91bGQgYmUgZGlzcGxheWVkIGFzIGEKICAgKiBsaW5rIGJhc2VkIG9uIHRoZSB1c2VyIG9wdGlvbnMuIEJ5IGRlZmF1bHQsCiAgICovCgkJY2hlY2s6IGZ1bmN0aW9uIGNoZWNrKHRva2VuKSB7CgkJCXJldHVybiB0aGlzLmdldCgndmFsaWRhdGUnLCB0b2tlbi50b1N0cmluZygpLCB0b2tlbik7CgkJfSwKCgoJCS8vIFByaXZhdGUgbWV0aG9kcwoKCQkvKioKICAgKiBSZXNvbHZlIGFuIG9wdGlvbidzIHZhbHVlIGJhc2VkIG9uIHRoZSB2YWx1ZSBvZiB0aGUgb3B0aW9uIGFuZCB0aGUgZ2l2ZW4KICAgKiBwYXJhbXMuCiAgICogQHBhcmFtIFtTdHJpbmddIGtleSBOYW1lIG9mIG9wdGlvbiB0byB1c2UKICAgKiBAcGFyYW0gb3BlcmF0b3Igd2lsbCBiZSBwYXNzZWQgdG8gdGhlIHRhcmdldCBvcHRpb24gaWYgaXQncyBtZXRob2QKICAgKiBAcGFyYW0gW011bHRpVG9rZW5dIHRva2VuIFRoZSB0b2tlbiBmcm9tIGxpbmtpZnkudG9rZW5pemUKICAgKi8KCQlnZXQ6IGZ1bmN0aW9uIGdldChrZXksIG9wZXJhdG9yLCB0b2tlbikgewoJCQl2YXIgb3B0aW9uID0gdGhpc1trZXldOwoKCQkJaWYgKCFvcHRpb24pIHsKCQkJCXJldHVybiBvcHRpb247CgkJCX0KCgkJCXN3aXRjaCAodHlwZW9mIG9wdGlvbiA9PT0gJ3VuZGVmaW5lZCcgPyAndW5kZWZpbmVkJyA6IF90eXBlb2Yob3B0aW9uKSkgewoJCQkJY2FzZSAnZnVuY3Rpb24nOgoJCQkJCXJldHVybiBvcHRpb24ob3BlcmF0b3IsIHRva2VuLnR5cGUpOwoJCQkJY2FzZSAnb2JqZWN0JzoKCQkJCQl2YXIgb3B0aW9uVmFsdWUgPSBvcHRpb25bdG9rZW4udHlwZV0gfHwgZGVmYXVsdHNba2V5XTsKCQkJCQlyZXR1cm4gdHlwZW9mIG9wdGlvblZhbHVlID09PSAnZnVuY3Rpb24nID8gb3B0aW9uVmFsdWUob3BlcmF0b3IsIHRva2VuLnR5cGUpIDogb3B0aW9uVmFsdWU7CgkJCX0KCgkJCXJldHVybiBvcHRpb247CgkJfSwKCQlnZXRPYmplY3Q6IGZ1bmN0aW9uIGdldE9iamVjdChrZXksIG9wZXJhdG9yLCB0b2tlbikgewoJCQl2YXIgb3B0aW9uID0gdGhpc1trZXldOwoJCQlyZXR1cm4gdHlwZW9mIG9wdGlvbiA9PT0gJ2Z1bmN0aW9uJyA/IG9wdGlvbihvcGVyYXRvciwgdG9rZW4udHlwZSkgOiBvcHRpb247CgkJfQoJfTsKCgkvKioKICAqIFF1aWNrIGluZGV4T2YgcmVwbGFjZW1lbnQgZm9yIGNoZWNraW5nIHRoZSBpZ25vcmVUYWdzIG9wdGlvbgogICovCglmdW5jdGlvbiBjb250YWlucyhhcnIsIHZhbHVlKSB7CgkJZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHsKCQkJaWYgKGFycltpXSA9PT0gdmFsdWUpIHsKCQkJCXJldHVybiB0cnVlOwoJCQl9CgkJfQoJCXJldHVybiBmYWxzZTsKCX0KCglmdW5jdGlvbiBub29wKHZhbCkgewoJCXJldHVybiB2YWw7Cgl9CgoJZnVuY3Rpb24gdHlwZVRvVGFyZ2V0KGhyZWYsIHR5cGUpIHsKCQlyZXR1cm4gdHlwZSA9PT0gJ3VybCcgPyAnX2JsYW5rJyA6IG51bGw7Cgl9CgoJdmFyIG9wdGlvbnMgPSBPYmplY3QuZnJlZXplKHsKCQlkZWZhdWx0czogZGVmYXVsdHMsCgkJT3B0aW9uczogT3B0aW9ucywKCQljb250YWluczogY29udGFpbnMKCX0pOwoKCWZ1bmN0aW9uIGNyZWF0ZVN0YXRlQ2xhc3MoKSB7CgkJcmV0dXJuIGZ1bmN0aW9uICh0Q2xhc3MpIHsKCQkJdGhpcy5qID0gW107CgkJCXRoaXMuVCA9IHRDbGFzcyB8fCBudWxsOwoJCX07Cgl9CgoJLyoqCiAJQSBzaW1wbGUgc3RhdGUgbWFjaGluZSB0aGF0IGNhbiBlbWl0IHRva2VuIGNsYXNzZXMKCiAJVGhlIGBqYCBwcm9wZXJ0eSBpbiB0aGlzIGNsYXNzIHJlZmVycyB0byBzdGF0ZSBqdW1wcy4gSXQncyBhCiAJbXVsdGlkaW1lbnNpb25hbCBhcnJheSB3aGVyZSBmb3IgZWFjaCBlbGVtZW50OgoKIAkqIGluZGV4IFswXSBpcyBhIHN5bWJvbCBvciBjbGFzcyBvZiBzeW1ib2xzIHRvIHRyYW5zaXRpb24gdG8uCiAJKiBpbmRleCBbMV0gaXMgYSBTdGF0ZSBpbnN0YW5jZSB3aGljaCBtYXRjaGVzCgogCVRoZSB0eXBlIG9mIHN5bWJvbCB3aWxsIGRlcGVuZCBvbiB0aGUgdGFyZ2V0IGltcGxlbWVudGF0aW9uIGZvciB0aGlzIGNsYXNzLgogCUluIExpbmtpZnksIHdlIGhhdmUgYSB0d28tc3RhZ2Ugc2Nhbm5lci4gRWFjaCBzdGFnZSB1c2VzIHRoaXMgc3RhdGUgbWFjaGluZQogCWJ1dCB3aXRoIGEgc2xpZ2hseSBkaWZmZXJlbnQgKHBvbHltb3JwaGljKSBpbXBsZW1lbnRhdGlvbi4KCiAJVGhlIGBUYCBwcm9wZXJ0eSByZWZlcnMgdG8gdGhlIHRva2VuIGNsYXNzLgoKIAlUT0RPOiBDYW4gdGhlIGBvbmAgYW5kIGBuZXh0YCBtZXRob2RzIGJlIGNvbWJpbmVkPwoKIAlAY2xhc3MgQmFzZVN0YXRlCiAqLwoJdmFyIEJhc2VTdGF0ZSA9IGNyZWF0ZVN0YXRlQ2xhc3MoKTsKCUJhc2VTdGF0ZS5wcm90b3R5cGUgPSB7CgkJZGVmYXVsdFRyYW5zaXRpb246IGZhbHNlLAoKCQkvKioKICAJQG1ldGhvZCBjb25zdHJ1Y3RvcgogIAlAcGFyYW0ge0NsYXNzfSB0Q2xhc3MgUGFzcyBpbiB0aGUga2luZCBvZiB0b2tlbiB0byBlbWl0IGlmIHRoZXJlIGFyZQogIAkJbm8ganVtcHMgYWZ0ZXIgdGhpcyBzdGF0ZSBhbmQgdGhlIHN0YXRlIGlzIGFjY2VwdGluZy4KICAqLwoKCQkvKioKICAJT24gdGhlIGdpdmVuIHN5bWJvbChzKSwgdGhpcyBtYWNoaW5lIHNob3VsZCBnbyB0byB0aGUgZ2l2ZW4gc3RhdGUKICAJCUBtZXRob2Qgb24KICAJQHBhcmFtIHtBcnJheXxNaXhlZH0gc3ltYm9sCiAgCUBwYXJhbSB7QmFzZVN0YXRlfSBzdGF0ZSBOb3RlIHRoYXQgdGhlIHR5cGUgb2YgdGhpcyBzdGF0ZSBzaG91bGQgYmUgdGhlCiAgCQlzYW1lIGFzIHRoZSBjdXJyZW50IGluc3RhbmNlIChpLmUuLCBkb24ndCBwYXNzIGluIGEgZGlmZmVyZW50CiAgCQlzdWJjbGFzcykKICAqLwoJCW9uOiBmdW5jdGlvbiBvbihzeW1ib2wsIHN0YXRlKSB7CgkJCWlmIChzeW1ib2wgaW5zdGFuY2VvZiBBcnJheSkgewoJCQkJZm9yICh2YXIgaSA9IDA7IGkgPCBzeW1ib2wubGVuZ3RoOyBpKyspIHsKCQkJCQl0aGlzLmoucHVzaChbc3ltYm9sW2ldLCBzdGF0ZV0pOwoJCQkJfQoJCQkJcmV0dXJuIHRoaXM7CgkJCX0KCQkJdGhpcy5qLnB1c2goW3N5bWJvbCwgc3RhdGVdKTsKCQkJcmV0dXJuIHRoaXM7CgkJfSwKCgoJCS8qKgogIAlHaXZlbiB0aGUgbmV4dCBpdGVtLCByZXR1cm5zIG5leHQgc3RhdGUgZm9yIHRoYXQgaXRlbQogIAlAbWV0aG9kIG5leHQKICAJQHBhcmFtIHtNaXhlZH0gaXRlbSBTaG91bGQgYmUgYW4gaW5zdGFuY2Ugb2YgdGhlIHN5bWJvbHMgaGFuZGxlZCBieQogIAkJdGhpcyBwYXJ0aWN1bGFyIG1hY2hpbmUuCiAgCUByZXR1cm4ge1N0YXRlfSBzdGF0ZSBSZXR1cm5zIGZhbHNlIGlmIG5vIGp1bXBzIGFyZSBhdmFpbGFibGUKICAqLwoJCW5leHQ6IGZ1bmN0aW9uIG5leHQoaXRlbSkgewoJCQlmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuai5sZW5ndGg7IGkrKykgewoJCQkJdmFyIGp1bXAgPSB0aGlzLmpbaV07CgkJCQl2YXIgc3ltYm9sID0ganVtcFswXTsgLy8gTmV4dCBpdGVtIHRvIGNoZWNrIGZvcgoJCQkJdmFyIHN0YXRlID0ganVtcFsxXTsgLy8gU3RhdGUgdG8ganVtcCB0byBpZiBpdGVtcyBtYXRjaAoKCQkJCS8vIGNvbXBhcmUgaXRlbSB3aXRoIHN5bWJvbAoJCQkJaWYgKHRoaXMudGVzdChpdGVtLCBzeW1ib2wpKSB7CgkJCQkJcmV0dXJuIHN0YXRlOwoJCQkJfQoJCQl9CgoJCQkvLyBOb3doZXJlIGxlZnQgdG8ganVtcCEKCQkJcmV0dXJuIHRoaXMuZGVmYXVsdFRyYW5zaXRpb247CgkJfSwKCgoJCS8qKgogIAlEb2VzIHRoaXMgc3RhdGUgYWNjZXB0PwogIAlgdHJ1ZWAgb25seSBvZiBgdGhpcy5UYCBleGlzdHMKICAJCUBtZXRob2QgYWNjZXB0cwogIAlAcmV0dXJuIHtCb29sZWFufQogICovCgkJYWNjZXB0czogZnVuY3Rpb24gYWNjZXB0cygpIHsKCQkJcmV0dXJuICEhdGhpcy5UOwoJCX0sCgoKCQkvKioKICAJRGV0ZXJtaW5lIHdoZXRoZXIgYSBnaXZlbiBpdGVtICJzeW1ib2xpemVzIiB0aGUgc3ltYm9sLCB3aGVyZSBzeW1ib2wgaXMKICAJYSBjbGFzcyBvZiBpdGVtcyBoYW5kbGVkIGJ5IHRoaXMgc3RhdGUgbWFjaGluZS4KICAJCVRoaXMgbWV0aG9kIHNob3VsZCBiZSBvdmVycmlkZW4gaW4gZXh0ZW5kZWQgY2xhc3Nlcy4KICAJCUBtZXRob2QgdGVzdAogIAlAcGFyYW0ge01peGVkfSBpdGVtIERvZXMgdGhpcyBpdGVtIG1hdGNoIHRoZSBnaXZlbiBzeW1ib2w/CiAgCUBwYXJhbSB7TWl4ZWR9IHN5bWJvbAogIAlAcmV0dXJuIHtCb29sZWFufQogICovCgkJdGVzdDogZnVuY3Rpb24gdGVzdChpdGVtLCBzeW1ib2wpIHsKCQkJcmV0dXJuIGl0ZW0gPT09IHN5bWJvbDsKCQl9LAoKCgkJLyoqCiAgCUVtaXQgdGhlIHRva2VuIGZvciB0aGlzIFN0YXRlIChqdXN0IHJldHVybiBpdCBpbiB0aGlzIGNhc2UpCiAgCUlmIHRoaXMgZW1pdHMgYSB0b2tlbiwgdGhpcyBpbnN0YW5jZSBpcyBhbiBhY2NlcHRpbmcgc3RhdGUKICAJQG1ldGhvZCBlbWl0CiAgCUByZXR1cm4ge0NsYXNzfSBUCiAgKi8KCQllbWl0OiBmdW5jdGlvbiBlbWl0KCkgewoJCQlyZXR1cm4gdGhpcy5UOwoJCX0KCX07CgoJLyoqCiAJU3RhdGUgbWFjaGluZSBmb3Igc3RyaW5nLWJhc2VkIGlucHV0CgogCUBjbGFzcyBDaGFyYWN0ZXJTdGF0ZQogCUBleHRlbmRzIEJhc2VTdGF0ZQogKi8KCXZhciBDaGFyYWN0ZXJTdGF0ZSA9IGluaGVyaXRzKEJhc2VTdGF0ZSwgY3JlYXRlU3RhdGVDbGFzcygpLCB7CgkJLyoqCiAgCURvZXMgdGhlIGdpdmVuIGNoYXJhY3RlciBtYXRjaCB0aGUgZ2l2ZW4gY2hhcmFjdGVyIG9yIHJlZ3VsYXIKICAJZXhwcmVzc2lvbj8KICAJCUBtZXRob2QgdGVzdAogIAlAcGFyYW0ge1N0cmluZ30gY2hhcgogIAlAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGNoYXJPclJlZ0V4cAogIAlAcmV0dXJuIHtCb29sZWFufQogICovCgkJdGVzdDogZnVuY3Rpb24gdGVzdChjaGFyYWN0ZXIsIGNoYXJPclJlZ0V4cCkgewoJCQlyZXR1cm4gY2hhcmFjdGVyID09PSBjaGFyT3JSZWdFeHAgfHwgY2hhck9yUmVnRXhwIGluc3RhbmNlb2YgUmVnRXhwICYmIGNoYXJPclJlZ0V4cC50ZXN0KGNoYXJhY3Rlcik7CgkJfQoJfSk7CgoJLyoqCiAJU3RhdGUgbWFjaGluZSBmb3IgaW5wdXQgaW4gdGhlIGZvcm0gb2YgVGV4dFRva2VucwoKIAlAY2xhc3MgVG9rZW5TdGF0ZQogCUBleHRlbmRzIEJhc2VTdGF0ZQogKi8KCXZhciBTdGF0ZSA9IGluaGVyaXRzKEJhc2VTdGF0ZSwgY3JlYXRlU3RhdGVDbGFzcygpLCB7CgoJCS8qKgogICAqIFNpbWlsYXIgdG8gYG9uYCwgYnV0IHJldHVybnMgdGhlIHN0YXRlIHRoZSByZXN1bHRzIGluIHRoZSB0cmFuc2l0aW9uIGZyb20KICAgKiB0aGUgZ2l2ZW4gaXRlbQogICAqIEBtZXRob2QganVtcAogICAqIEBwYXJhbSB7TWl4ZWR9IGl0ZW0KICAgKiBAcGFyYW0ge1Rva2VufSBbdG9rZW5dCiAgICogQHJldHVybiBzdGF0ZQogICAqLwoJCWp1bXA6IGZ1bmN0aW9uIGp1bXAodG9rZW4pIHsKCQkJdmFyIHRDbGFzcyA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMSB8fCBhcmd1bWVudHNbMV0gPT09IHVuZGVmaW5lZCA/IG51bGwgOiBhcmd1bWVudHNbMV07CgoJCQl2YXIgc3RhdGUgPSB0aGlzLm5leHQobmV3IHRva2VuKCcnKSk7IC8vIGR1bW15IHRlbXAgdG9rZW4KCQkJaWYgKHN0YXRlID09PSB0aGlzLmRlZmF1bHRUcmFuc2l0aW9uKSB7CgkJCQkvLyBNYWtlIGEgbmV3IHN0YXRlIQoJCQkJc3RhdGUgPSBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0Q2xhc3MpOwoJCQkJdGhpcy5vbih0b2tlbiwgc3RhdGUpOwoJCQl9IGVsc2UgaWYgKHRDbGFzcykgewoJCQkJc3RhdGUuVCA9IHRDbGFzczsKCQkJfQoJCQlyZXR1cm4gc3RhdGU7CgkJfSwKCgoJCS8qKgogIAlJcyB0aGUgZ2l2ZW4gdG9rZW4gYW4gaW5zdGFuY2Ugb2YgdGhlIGdpdmVuIHRva2VuIGNsYXNzPwogIAkJQG1ldGhvZCB0ZXN0CiAgCUBwYXJhbSB7VGV4dFRva2VufSB0b2tlbgogIAlAcGFyYW0ge0NsYXNzfSB0b2tlbkNsYXNzCiAgCUByZXR1cm4ge0Jvb2xlYW59CiAgKi8KCQl0ZXN0OiBmdW5jdGlvbiB0ZXN0KHRva2VuLCB0b2tlbkNsYXNzKSB7CgkJCXJldHVybiB0b2tlbiBpbnN0YW5jZW9mIHRva2VuQ2xhc3M7CgkJfQoJfSk7CgoJLyoqCiAJR2l2ZW4gYSBub24tZW1wdHkgdGFyZ2V0IHN0cmluZywgZ2VuZXJhdGVzIHN0YXRlcyAoaWYgcmVxdWlyZWQpIGZvciBlYWNoCiAJY29uc2VjdXRpdmUgc3Vic3RyaW5nIG9mIGNoYXJhY3RlcnMgaW4gc3RyIHN0YXJ0aW5nIGZyb20gdGhlIGJlZ2lubmluZyBvZgogCXRoZSBzdHJpbmcuIFRoZSBmaW5hbCBzdGF0ZSB3aWxsIGhhdmUgYSBzcGVjaWFsIHZhbHVlLCBhcyBzcGVjaWZpZWQgaW4KIAlvcHRpb25zLiBBbGwgb3RoZXIgImluIGJldHdlZW4iIHN1YnN0cmluZ3Mgd2lsbCBoYXZlIGEgZGVmYXVsdCBlbmQgc3RhdGUuCgogCVRoaXMgdHVybnMgdGhlIHN0YXRlIG1hY2hpbmUgaW50byBhIFRyaWUtbGlrZSBkYXRhIHN0cnVjdHVyZSAocmF0aGVyIHRoYW4gYQogCWludGVsbGlnZW50bHktZGVzaWduZWQgREZBKS4KCiAJTm90ZSB0aGF0IEkgaGF2ZW4ndCByZWFsbHkgdHJpZWQgdGhlc2Ugd2l0aCBhbnkgc3RyaW5ncyBvdGhlciB0aGFuCiAJRE9NQUlOLgoKIAlAcGFyYW0ge1N0cmluZ30gc3RyCiAJQHBhcmFtIHtDaGFyYWN0ZXJTdGF0ZX0gc3RhcnQgU3RhdGUgdG8ganVtcCBmcm9tIHRoZSBmaXJzdCBjaGFyYWN0ZXIKIAlAcGFyYW0ge0NsYXNzfSBlbmRUb2tlbiBUb2tlbiBjbGFzcyB0byBlbWl0IHdoZW4gdGhlIGdpdmVuIHN0cmluZyBoYXMgYmVlbgogCQltYXRjaGVkIGFuZCBubyBtb3JlIGp1bXBzIGV4aXN0LgogCUBwYXJhbSB7Q2xhc3N9IGRlZmF1bHRUb2tlbiAiRmlsbGVyIHRva2VuIiwgb3Igd2hpY2ggdG9rZW4gdHlwZSB0byBlbWl0IHdoZW4KIAkJd2UgZG9uJ3QgaGF2ZSBhIGZ1bGwgbWF0Y2gKIAlAcmV0dXJuIHtBcnJheX0gbGlzdCBvZiBuZXdseS1jcmVhdGVkIHN0YXRlcwogKi8KCWZ1bmN0aW9uIHN0YXRlaWZ5KHN0ciwgc3RhcnQsIGVuZFRva2VuLCBkZWZhdWx0VG9rZW4pIHsKCQl2YXIgaSA9IDAsCgkJICAgIGxlbiA9IHN0ci5sZW5ndGgsCgkJICAgIHN0YXRlID0gc3RhcnQsCgkJICAgIG5ld1N0YXRlcyA9IFtdLAoJCSAgICBuZXh0U3RhdGUgPSB2b2lkIDA7CgoJCS8vIEZpbmQgdGhlIG5leHQgc3RhdGUgd2l0aG91dCBhIGp1bXAgdG8gdGhlIG5leHQgY2hhcmFjdGVyCgkJd2hpbGUgKGkgPCBsZW4gJiYgKG5leHRTdGF0ZSA9IHN0YXRlLm5leHQoc3RyW2ldKSkpIHsKCQkJc3RhdGUgPSBuZXh0U3RhdGU7CgkJCWkrKzsKCQl9CgoJCWlmIChpID49IGxlbikgewoJCQlyZXR1cm4gW107CgkJfSAvLyBubyBuZXcgdG9rZW5zIHdlcmUgYWRkZWQKCgkJd2hpbGUgKGkgPCBsZW4gLSAxKSB7CgkJCW5leHRTdGF0ZSA9IG5ldyBDaGFyYWN0ZXJTdGF0ZShkZWZhdWx0VG9rZW4pOwoJCQluZXdTdGF0ZXMucHVzaChuZXh0U3RhdGUpOwoJCQlzdGF0ZS5vbihzdHJbaV0sIG5leHRTdGF0ZSk7CgkJCXN0YXRlID0gbmV4dFN0YXRlOwoJCQlpKys7CgkJfQoKCQluZXh0U3RhdGUgPSBuZXcgQ2hhcmFjdGVyU3RhdGUoZW5kVG9rZW4pOwoJCW5ld1N0YXRlcy5wdXNoKG5leHRTdGF0ZSk7CgkJc3RhdGUub24oc3RyW2xlbiAtIDFdLCBuZXh0U3RhdGUpOwoKCQlyZXR1cm4gbmV3U3RhdGVzOwoJfQoKCWZ1bmN0aW9uIGNyZWF0ZVRva2VuQ2xhc3MoKSB7CgkJcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSkgewoJCQlpZiAodmFsdWUpIHsKCQkJCXRoaXMudiA9IHZhbHVlOwoJCQl9CgkJfTsKCX0KCgkvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAJVGV4dCBUb2tlbnMKIAlUb2tlbnMgY29tcG9zZWQgb2Ygc3RyaW5ncwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCS8qKgogCUFic3RyYWN0IGNsYXNzIHVzZWQgZm9yIG1hbnVmYWN0dXJpbmcgdGV4dCB0b2tlbnMuCiAJUGFzcyBpbiB0aGUgdmFsdWUgdGhpcyB0b2tlbiByZXByZXNlbnRzCgogCUBjbGFzcyBUZXh0VG9rZW4KIAlAYWJzdHJhY3QKICovCgl2YXIgVGV4dFRva2VuID0gY3JlYXRlVG9rZW5DbGFzcygpOwoJVGV4dFRva2VuLnByb3RvdHlwZSA9IHsKCQl0b1N0cmluZzogZnVuY3Rpb24gdG9TdHJpbmcoKSB7CgkJCXJldHVybiB0aGlzLnYgKyAnJzsKCQl9Cgl9OwoKCWZ1bmN0aW9uIGluaGVyaXRzVG9rZW4odmFsdWUpIHsKCQl2YXIgcHJvcHMgPSB2YWx1ZSA/IHsgdjogdmFsdWUgfSA6IHt9OwoJCXJldHVybiBpbmhlcml0cyhUZXh0VG9rZW4sIGNyZWF0ZVRva2VuQ2xhc3MoKSwgcHJvcHMpOwoJfQoKCS8qKgogCUEgdmFsaWQgZG9tYWluIHRva2VuCiAJQGNsYXNzIERPTUFJTgogCUBleHRlbmRzIFRleHRUb2tlbgogKi8KCXZhciBET01BSU4gPSBpbmhlcml0c1Rva2VuKCk7CgoJLyoqCiAJQGNsYXNzIEFUCiAJQGV4dGVuZHMgVGV4dFRva2VuCiAqLwoJdmFyIEFUID0gaW5oZXJpdHNUb2tlbignQCcpOwoKCS8qKgogCVJlcHJlc2VudHMgYSBzaW5nbGUgY29sb24gYDpgIGNoYXJhY3RlcgoKIAlAY2xhc3MgQ09MT04KIAlAZXh0ZW5kcyBUZXh0VG9rZW4KICovCgl2YXIgQ09MT04gPSBpbmhlcml0c1Rva2VuKCc6Jyk7CgoJLyoqCiAJQGNsYXNzIERPVAogCUBleHRlbmRzIFRleHRUb2tlbgogKi8KCXZhciBET1QgPSBpbmhlcml0c1Rva2VuKCcuJyk7CgoJLyoqCiAJQSBjaGFyYWN0ZXIgY2xhc3MgdGhhdCBjYW4gc3Vycm91bmQgdGhlIFVSTCwgYnV0IHdoaWNoIHRoZSBVUkwgY2Fubm90IGJlZ2luCiAJb3IgZW5kIHdpdGguIERvZXMgbm90IGluY2x1ZGUgY2VydGFpbiBFbmdsaXNoIHB1bmN0dWF0aW9uIGxpa2UgcGFyZW50aGVzZXMuCgogCUBjbGFzcyBQVU5DVFVBVElPTgogCUBleHRlbmRzIFRleHRUb2tlbgogKi8KCXZhciBQVU5DVFVBVElPTiA9IGluaGVyaXRzVG9rZW4oKTsKCgkvKioKIAlUaGUgd29yZCBsb2NhbGhvc3QgKGJ5IGl0c2VsZikKIAlAY2xhc3MgTE9DQUxIT1NUCiAJQGV4dGVuZHMgVGV4dFRva2VuCiAqLwoJdmFyIExPQ0FMSE9TVCA9IGluaGVyaXRzVG9rZW4oKTsKCgkvKioKIAlOZXdsaW5lIHRva2VuCiAJQGNsYXNzIE5MCiAJQGV4dGVuZHMgVGV4dFRva2VuCiAqLwoJdmFyIFROTCA9IGluaGVyaXRzVG9rZW4oJ1xuJyk7CgoJLyoqCiAJQGNsYXNzIE5VTQogCUBleHRlbmRzIFRleHRUb2tlbgogKi8KCXZhciBOVU0gPSBpbmhlcml0c1Rva2VuKCk7CgoJLyoqCiAJQGNsYXNzIFBMVVMKIAlAZXh0ZW5kcyBUZXh0VG9rZW4KICovCgl2YXIgUExVUyA9IGluaGVyaXRzVG9rZW4oJysnKTsKCgkvKioKIAlAY2xhc3MgUE9VTkQKIAlAZXh0ZW5kcyBUZXh0VG9rZW4KICovCgl2YXIgUE9VTkQgPSBpbmhlcml0c1Rva2VuKCcjJyk7CgoJLyoqCiAJUmVwcmVzZW50cyBhIHdlYiBVUkwgcHJvdG9jb2wuIFN1cHBvcnRlZCB0eXBlcyBpbmNsdWRlCgogCSogYGh0dHA6YAogCSogYGh0dHBzOmAKIAkqIGBmdHA6YAogCSogYGZ0cHM6YAogCSogVGhlcmUncyBBbm90aGVyIHN1cGVyIHdlaXJkIG9uZQoKIAlAY2xhc3MgUFJPVE9DT0wKIAlAZXh0ZW5kcyBUZXh0VG9rZW4KICovCgl2YXIgUFJPVE9DT0wgPSBpbmhlcml0c1Rva2VuKCk7CgoJLyoqCiAJQGNsYXNzIFFVRVJZCiAJQGV4dGVuZHMgVGV4dFRva2VuCiAqLwoJdmFyIFFVRVJZID0gaW5oZXJpdHNUb2tlbignPycpOwoKCS8qKgogCUBjbGFzcyBTTEFTSAogCUBleHRlbmRzIFRleHRUb2tlbgogKi8KCXZhciBTTEFTSCA9IGluaGVyaXRzVG9rZW4oJy8nKTsKCgkvKioKIAlAY2xhc3MgVU5ERVJTQ09SRQogCUBleHRlbmRzIFRleHRUb2tlbgogKi8KCXZhciBVTkRFUlNDT1JFID0gaW5oZXJpdHNUb2tlbignXycpOwoKCS8qKgogCU9uZSBvcmUgbW9yZSBub24td2hpdGVzcGFjZSBzeW1ib2wuCiAJQGNsYXNzIFNZTQogCUBleHRlbmRzIFRleHRUb2tlbgogKi8KCXZhciBTWU0gPSBpbmhlcml0c1Rva2VuKCk7CgoJLyoqCiAJQGNsYXNzIFRMRAogCUBleHRlbmRzIFRleHRUb2tlbgogKi8KCXZhciBUTEQgPSBpbmhlcml0c1Rva2VuKCk7CgoJLyoqCiAJUmVwcmVzZW50cyBhIHN0cmluZyBvZiBjb25zZWN1dGl2ZSB3aGl0ZXNwYWNlIGNoYXJhY3RlcnMKCiAJQGNsYXNzIFdTCiAJQGV4dGVuZHMgVGV4dFRva2VuCiAqLwoJdmFyIFdTID0gaW5oZXJpdHNUb2tlbigpOwoKCS8qKgogCU9wZW5pbmcvY2xvc2luZyBicmFja2V0IGNsYXNzZXMKICovCgoJdmFyIE9QRU5CUkFDRSA9IGluaGVyaXRzVG9rZW4oJ3snKTsKCXZhciBPUEVOQlJBQ0tFVCA9IGluaGVyaXRzVG9rZW4oJ1snKTsKCXZhciBPUEVOQU5HTEVCUkFDS0VUID0gaW5oZXJpdHNUb2tlbignPCcpOwoJdmFyIE9QRU5QQVJFTiA9IGluaGVyaXRzVG9rZW4oJygnKTsKCXZhciBDTE9TRUJSQUNFID0gaW5oZXJpdHNUb2tlbignfScpOwoJdmFyIENMT1NFQlJBQ0tFVCA9IGluaGVyaXRzVG9rZW4oJ10nKTsKCXZhciBDTE9TRUFOR0xFQlJBQ0tFVCA9IGluaGVyaXRzVG9rZW4oJz4nKTsKCXZhciBDTE9TRVBBUkVOID0gaW5oZXJpdHNUb2tlbignKScpOwoKCXZhciBUT0tFTlMgPSBPYmplY3QuZnJlZXplKHsKCQlCYXNlOiBUZXh0VG9rZW4sCgkJRE9NQUlOOiBET01BSU4sCgkJQVQ6IEFULAoJCUNPTE9OOiBDT0xPTiwKCQlET1Q6IERPVCwKCQlQVU5DVFVBVElPTjogUFVOQ1RVQVRJT04sCgkJTE9DQUxIT1NUOiBMT0NBTEhPU1QsCgkJTkw6IFROTCwKCQlOVU06IE5VTSwKCQlQTFVTOiBQTFVTLAoJCVBPVU5EOiBQT1VORCwKCQlRVUVSWTogUVVFUlksCgkJUFJPVE9DT0w6IFBST1RPQ09MLAoJCVNMQVNIOiBTTEFTSCwKCQlVTkRFUlNDT1JFOiBVTkRFUlNDT1JFLAoJCVNZTTogU1lNLAoJCVRMRDogVExELAoJCVdTOiBXUywKCQlPUEVOQlJBQ0U6IE9QRU5CUkFDRSwKCQlPUEVOQlJBQ0tFVDogT1BFTkJSQUNLRVQsCgkJT1BFTkFOR0xFQlJBQ0tFVDogT1BFTkFOR0xFQlJBQ0tFVCwKCQlPUEVOUEFSRU46IE9QRU5QQVJFTiwKCQlDTE9TRUJSQUNFOiBDTE9TRUJSQUNFLAoJCUNMT1NFQlJBQ0tFVDogQ0xPU0VCUkFDS0VULAoJCUNMT1NFQU5HTEVCUkFDS0VUOiBDTE9TRUFOR0xFQlJBQ0tFVCwKCQlDTE9TRVBBUkVOOiBDTE9TRVBBUkVOCgl9KTsKCgkvKioKIAlUaGUgc2Nhbm5lciBwcm92aWRlcyBhbiBpbnRlcmZhY2UgdGhhdCB0YWtlcyBhIHN0cmluZyBvZiB0ZXh0IGFzIGlucHV0LCBhbmQKIAlvdXRwdXRzIGFuIGFycmF5IG9mIHRva2VucyBpbnN0YW5jZXMgdGhhdCBjYW4gYmUgdXNlZCBmb3IgZWFzeSBVUkwgcGFyc2luZy4KCiAJQG1vZHVsZSBsaW5raWZ5CiAJQHN1Ym1vZHVsZSBzY2FubmVyCiAJQG1haW4gc2Nhbm5lcgogKi8KCgl2YXIgdGxkcyA9ICdhYWF8YWFycHxhYmJ8YWJib3R0fGFib2dhZG98YWN8YWNhZGVteXxhY2NlbnR1cmV8YWNjb3VudGFudHxhY2NvdW50YW50c3xhY298YWN0aXZlfGFjdG9yfGFkfGFkYWN8YWRzfGFkdWx0fGFlfGFlZ3xhZXJvfGFmfGFmbHxhZ3xhZ2VuY3l8YWl8YWlnfGFpcmZvcmNlfGFpcnRlbHxhbHxhbGliYWJhfGFsaXBheXxhbGxmaW5hbnp8YWxzYWNlfGFtfGFtaWNhfGFtc3RlcmRhbXxhbnxhbmFseXRpY3N8YW5kcm9pZHxhb3xhcGFydG1lbnRzfGFwcHxhcHBsZXxhcXxhcXVhcmVsbGV8YXJ8YXJhbWNvfGFyY2hpfGFybXl8YXJwYXxhcnRlfGFzfGFzaWF8YXNzb2NpYXRlc3xhdHxhdHRvcm5leXxhdXxhdWN0aW9ufGF1ZGl8YXVkaW98YXV0aG9yfGF1dG98YXV0b3N8YXZpYW5jYXxhd3xheHxheGF8YXp8YXp1cmV8YmF8YmFpZHV8YmFuZHxiYW5rfGJhcnxiYXJjZWxvbmF8YmFyY2xheWNhcmR8YmFyY2xheXN8YmFyZ2FpbnN8YmF1aGF1c3xiYXllcm58YmJ8YmJjfGJidmF8YmNnfGJjbnxiZHxiZXxiZWF0c3xiZWVyfGJlbnRsZXl8YmVybGlufGJlc3R8YmV0fGJmfGJnfGJofGJoYXJ0aXxiaXxiaWJsZXxiaWR8YmlrZXxiaW5nfGJpbmdvfGJpb3xiaXp8Ymp8YmxhY2t8YmxhY2tmcmlkYXl8Ymxvb21iZXJnfGJsdWV8Ym18Ym1zfGJtd3xibnxibmx8Ym5wcGFyaWJhc3xib3xib2F0c3xib2VocmluZ2VyfGJvbXxib25kfGJvb3xib29rfGJvb3RzfGJvc2NofGJvc3Rpa3xib3R8Ym91dGlxdWV8YnJ8YnJhZGVzY298YnJpZGdlc3RvbmV8YnJvYWR3YXl8YnJva2VyfGJyb3RoZXJ8YnJ1c3NlbHN8YnN8YnR8YnVkYXBlc3R8YnVnYXR0aXxidWlsZHxidWlsZGVyc3xidXNpbmVzc3xidXl8YnV6enxidnxid3xieXxienxiemh8Y2F8Y2FifGNhZmV8Y2FsfGNhbGx8Y2FtZXJhfGNhbXB8Y2FuY2VycmVzZWFyY2h8Y2Fub258Y2FwZXRvd258Y2FwaXRhbHxjYXJ8Y2FyYXZhbnxjYXJkc3xjYXJlfGNhcmVlcnxjYXJlZXJzfGNhcnN8Y2FydGllcnxjYXNhfGNhc2h8Y2FzaW5vfGNhdHxjYXRlcmluZ3xjYmF8Y2JufGNjfGNkfGNlYnxjZW50ZXJ8Y2VvfGNlcm58Y2Z8Y2ZhfGNmZHxjZ3xjaHxjaGFuZWx8Y2hhbm5lbHxjaGFzZXxjaGF0fGNoZWFwfGNobG9lfGNocmlzdG1hc3xjaHJvbWV8Y2h1cmNofGNpfGNpcHJpYW5pfGNpcmNsZXxjaXNjb3xjaXRpY3xjaXR5fGNpdHllYXRzfGNrfGNsfGNsYWltc3xjbGVhbmluZ3xjbGlja3xjbGluaWN8Y2xpbmlxdWV8Y2xvdGhpbmd8Y2xvdWR8Y2x1YnxjbHVibWVkfGNtfGNufGNvfGNvYWNofGNvZGVzfGNvZmZlZXxjb2xsZWdlfGNvbG9nbmV8Y29tfGNvbW1iYW5rfGNvbW11bml0eXxjb21wYW55fGNvbXBhcmV8Y29tcHV0ZXJ8Y29tc2VjfGNvbmRvc3xjb25zdHJ1Y3Rpb258Y29uc3VsdGluZ3xjb250YWN0fGNvbnRyYWN0b3JzfGNvb2tpbmd8Y29vbHxjb29wfGNvcnNpY2F8Y291bnRyeXxjb3Vwb258Y291cG9uc3xjb3Vyc2VzfGNyfGNyZWRpdHxjcmVkaXRjYXJkfGNyZWRpdHVuaW9ufGNyaWNrZXR8Y3Jvd258Y3JzfGNydWlzZXN8Y3NjfGN1fGN1aXNpbmVsbGF8Y3Z8Y3d8Y3h8Y3l8Y3ltcnV8Y3lvdXxjenxkYWJ1cnxkYWR8ZGFuY2V8ZGF0ZXxkYXRpbmd8ZGF0c3VufGRheXxkY2xrfGRlfGRlYWxlcnxkZWFsc3xkZWdyZWV8ZGVsaXZlcnl8ZGVsbHxkZWxvaXR0ZXxkZWx0YXxkZW1vY3JhdHxkZW50YWx8ZGVudGlzdHxkZXNpfGRlc2lnbnxkZXZ8ZGlhbW9uZHN8ZGlldHxkaWdpdGFsfGRpcmVjdHxkaXJlY3Rvcnl8ZGlzY291bnR8ZGp8ZGt8ZG18ZG5wfGRvfGRvY3N8ZG9nfGRvaGF8ZG9tYWluc3xkb3dubG9hZHxkcml2ZXxkdWJhaXxkdXJiYW58ZHZhZ3xkenxlYXJ0aHxlYXR8ZWN8ZWRla2F8ZWR1fGVkdWNhdGlvbnxlZXxlZ3xlbWFpbHxlbWVyY2t8ZW5lcmd5fGVuZ2luZWVyfGVuZ2luZWVyaW5nfGVudGVycHJpc2VzfGVwc29ufGVxdWlwbWVudHxlcnxlcm5pfGVzfGVzcXxlc3RhdGV8ZXR8ZXV8ZXVyb3Zpc2lvbnxldXN8ZXZlbnRzfGV2ZXJiYW5rfGV4Y2hhbmdlfGV4cGVydHxleHBvc2VkfGV4cHJlc3N8ZmFnZXxmYWlsfGZhaXJ3aW5kc3xmYWl0aHxmYW1pbHl8ZmFufGZhbnN8ZmFybXxmYXNoaW9ufGZhc3R8ZmVlZGJhY2t8ZmVycmVyb3xmaXxmaWxtfGZpbmFsfGZpbmFuY2V8ZmluYW5jaWFsfGZpcmVzdG9uZXxmaXJtZGFsZXxmaXNofGZpc2hpbmd8Zml0fGZpdG5lc3N8Zmp8Zmt8ZmxpY2tyfGZsaWdodHN8ZmxvcmlzdHxmbG93ZXJzfGZsc21pZHRofGZseXxmbXxmb3xmb298Zm9vdGJhbGx8Zm9yZHxmb3JleHxmb3JzYWxlfGZvcnVtfGZvdW5kYXRpb258Zm94fGZyfGZyZXNlbml1c3xmcmx8ZnJvZ2Fuc3xmcm9udGllcnxmdW5kfGZ1cm5pdHVyZXxmdXRib2x8ZnlpfGdhfGdhbHxnYWxsZXJ5fGdhbGx1cHxnYW1lfGdhcmRlbnxnYnxnYml6fGdkfGdkbnxnZXxnZWF8Z2VudHxnZW50aW5nfGdmfGdnfGdnZWV8Z2h8Z2l8Z2lmdHxnaWZ0c3xnaXZlc3xnaXZpbmd8Z2x8Z2xhc3N8Z2xlfGdsb2JhbHxnbG9ib3xnbXxnbWFpbHxnbWJofGdtb3xnbXh8Z258Z29sZHxnb2xkcG9pbnR8Z29sZnxnb298Z29vZ3xnb29nbGV8Z29wfGdvdHxnb3Z8Z3B8Z3F8Z3J8Z3JhaW5nZXJ8Z3JhcGhpY3N8Z3JhdGlzfGdyZWVufGdyaXBlfGdyb3VwfGdzfGd0fGd1fGd1Y2NpfGd1Z2V8Z3VpZGV8Z3VpdGFyc3xndXJ1fGd3fGd5fGhhbWJ1cmd8aGFuZ291dHxoYXVzfGhkZmNiYW5rfGhlYWx0aHxoZWFsdGhjYXJlfGhlbHB8aGVsc2lua2l8aGVyZXxoZXJtZXN8aGlwaG9wfGhpdGFjaGl8aGl2fGhrfGhtfGhufGhvY2tleXxob2xkaW5nc3xob2xpZGF5fGhvbWVkZXBvdHxob21lc3xob25kYXxob3JzZXxob3N0fGhvc3Rpbmd8aG90ZWxlc3xob3RtYWlsfGhvdXNlfGhvd3xocnxoc2JjfGh0fGh1fGh5dW5kYWl8aWJtfGljYmN8aWNlfGljdXxpZHxpZXxpZm18aWluZXR8aWx8aW18aW1tb3xpbW1vYmlsaWVufGlufGluZHVzdHJpZXN8aW5maW5pdGl8aW5mb3xpbmd8aW5rfGluc3RpdHV0ZXxpbnN1cmFuY2V8aW5zdXJlfGludHxpbnRlcm5hdGlvbmFsfGludmVzdG1lbnRzfGlvfGlwaXJhbmdhfGlxfGlyfGlyaXNofGlzfGlzZWxlY3R8aXN0fGlzdGFuYnVsfGl0fGl0YXV8aXdjfGphZ3VhcnxqYXZhfGpjYnxqZXxqZXR6dHxqZXdlbHJ5fGpsY3xqbGx8am18am1wfGpvfGpvYnN8am9idXJnfGpvdHxqb3l8anB8anBtb3JnYW58anByc3xqdWVnb3N8a2F1ZmVufGtkZGl8a2V8a2Vycnlob3RlbHN8a2Vycnlsb2dpc3RpY3N8a2Vycnlwcm9wZXJ0aWVzfGtmaHxrZ3xraHxraXxraWF8a2ltfGtpbmRlcnxraXRjaGVufGtpd2l8a218a258a29lbG58a29tYXRzdXxrcHxrcG58a3J8a3JkfGtyZWR8a3Vva2dyb3VwfGt3fGt5fGt5b3RvfGt6fGxhfGxhY2FpeGF8bGFtYm9yZ2hpbml8bGFtZXJ8bGFuY2FzdGVyfGxhbmR8bGFuZHJvdmVyfGxhbnhlc3N8bGFzYWxsZXxsYXR8bGF0cm9iZXxsYXd8bGF3eWVyfGxifGxjfGxkc3xsZWFzZXxsZWNsZXJjfGxlZ2FsfGxleHVzfGxnYnR8bGl8bGlhaXNvbnxsaWRsfGxpZmV8bGlmZWluc3VyYW5jZXxsaWZlc3R5bGV8bGlnaHRpbmd8bGlrZXxsaW1pdGVkfGxpbW98bGluY29sbnxsaW5kZXxsaW5rfGxpdmV8bGl2aW5nfGxpeGlsfGxrfGxvYW58bG9hbnN8bG9jYWx8bG9jdXN8bG9sfGxvbmRvbnxsb3R0ZXxsb3R0b3xsb3ZlfGxyfGxzfGx0fGx0ZHxsdGRhfGx1fGx1cGlufGx1eGV8bHV4dXJ5fGx2fGx5fG1hfG1hZHJpZHxtYWlmfG1haXNvbnxtYWtldXB8bWFufG1hbmFnZW1lbnR8bWFuZ298bWFya2V0fG1hcmtldGluZ3xtYXJrZXRzfG1hcnJpb3R0fG1iYXxtY3xtZHxtZXxtZWR8bWVkaWF8bWVldHxtZWxib3VybmV8bWVtZXxtZW1vcmlhbHxtZW58bWVudXxtZW98bWd8bWh8bWlhbWl8bWljcm9zb2Z0fG1pbHxtaW5pfG1rfG1sfG1tfG1tYXxtbnxtb3xtb2JpfG1vYmlseXxtb2RhfG1vZXxtb2l8bW9tfG1vbmFzaHxtb25leXxtb250YmxhbmN8bW9ybW9ufG1vcnRnYWdlfG1vc2Nvd3xtb3RvcmN5Y2xlc3xtb3Z8bW92aWV8bW92aXN0YXJ8bXB8bXF8bXJ8bXN8bXR8bXRufG10cGN8bXRyfG11fG11c2V1bXxtdXR1ZWxsZXxtdnxtd3xteHxteXxtenxuYXxuYWRleHxuYWdveWF8bmFtZXxuYXR1cmF8bmF2eXxuY3xuZXxuZWN8bmV0fG5ldGJhbmt8bmV0d29ya3xuZXVzdGFyfG5ld3xuZXdzfG5leHVzfG5mfG5nfG5nb3xuaGt8bml8bmljb3xuaWtvbnxuaW5qYXxuaXNzYW58bmx8bm98bm9raWF8bm9ydG9ufG5vd3J1enxucHxucnxucmF8bnJ3fG50dHxudXxueWN8bnp8b2JpfG9mZmljZXxva2luYXdhfG9tfG9tZWdhfG9uZXxvbmd8b25sfG9ubGluZXxvb298b3JhY2xlfG9yYW5nZXxvcmd8b3JnYW5pY3xvcmlnaW5zfG9zYWthfG90c3VrYXxvdmh8cGF8cGFnZXxwYW1wZXJlZGNoZWZ8cGFuZXJhaXxwYXJpc3xwYXJzfHBhcnRuZXJzfHBhcnRzfHBhcnR5fHBhc3NhZ2Vuc3xwZXxwZXR8cGZ8cGd8cGh8cGhhcm1hY3l8cGhpbGlwc3xwaG90b3xwaG90b2dyYXBoeXxwaG90b3N8cGh5c2lvfHBpYWdldHxwaWNzfHBpY3RldHxwaWN0dXJlc3xwaWR8cGlufHBpbmd8cGlua3xwaXp6YXxwa3xwbHxwbGFjZXxwbGF5fHBsYXlzdGF0aW9ufHBsdW1iaW5nfHBsdXN8cG18cG58cG9obHxwb2tlcnxwb3JufHBvc3R8cHJ8cHJheGl8cHJlc3N8cHJvfHByb2R8cHJvZHVjdGlvbnN8cHJvZnxwcm9tb3xwcm9wZXJ0aWVzfHByb3BlcnR5fHByb3RlY3Rpb258cHN8cHR8cHVifHB3fHB3Y3xweXxxYXxxcG9ufHF1ZWJlY3xxdWVzdHxyYWNpbmd8cmV8cmVhZHxyZWFsdG9yfHJlYWx0eXxyZWNpcGVzfHJlZHxyZWRzdG9uZXxyZWR1bWJyZWxsYXxyZWhhYnxyZWlzZXxyZWlzZW58cmVpdHxyZW58cmVudHxyZW50YWxzfHJlcGFpcnxyZXBvcnR8cmVwdWJsaWNhbnxyZXN0fHJlc3RhdXJhbnR8cmV2aWV3fHJldmlld3N8cmV4cm90aHxyaWNofHJpY29ofHJpb3xyaXB8cm98cm9jaGVyfHJvY2tzfHJvZGVvfHJvb218cnN8cnN2cHxydXxydWhyfHJ1bnxyd3xyd2V8cnl1a3l1fHNhfHNhYXJsYW5kfHNhZmV8c2FmZXR5fHNha3VyYXxzYWxlfHNhbG9ufHNhbXN1bmd8c2FuZHZpa3xzYW5kdmlrY29yb21hbnR8c2Fub2ZpfHNhcHxzYXBvfHNhcmx8c2FzfHNheG98c2J8c2JzfHNjfHNjYXxzY2J8c2NoYWVmZmxlcnxzY2htaWR0fHNjaG9sYXJzaGlwc3xzY2hvb2x8c2NodWxlfHNjaHdhcnp8c2NpZW5jZXxzY29yfHNjb3R8c2R8c2V8c2VhdHxzZWN1cml0eXxzZWVrfHNlbGVjdHxzZW5lcnxzZXJ2aWNlc3xzZXZlbnxzZXd8c2V4fHNleHl8c2ZyfHNnfHNofHNoYXJwfHNoZWxsfHNoaWF8c2hpa3NoYXxzaG9lc3xzaG93fHNocmlyYW18c2l8c2luZ2xlc3xzaXRlfHNqfHNrfHNraXxza2lufHNreXxza3lwZXxzbHxzbXxzbWlsZXxzbnxzbmNmfHNvfHNvY2Nlcnxzb2NpYWx8c29mdGJhbmt8c29mdHdhcmV8c29odXxzb2xhcnxzb2x1dGlvbnN8c29uZ3xzb255fHNveXxzcGFjZXxzcGllZ2VsfHNwb3R8c3ByZWFkYmV0dGluZ3xzcnxzcmx8c3R8c3RhZGF8c3RhcnxzdGFyaHVifHN0YXRlZmFybXxzdGF0b2lsfHN0Y3xzdGNncm91cHxzdG9ja2hvbG18c3RvcmFnZXxzdG9yZXxzdHVkaW98c3R1ZHl8c3R5bGV8c3V8c3Vja3N8c3VwcGxpZXN8c3VwcGx5fHN1cHBvcnR8c3VyZnxzdXJnZXJ5fHN1enVraXxzdnxzd2F0Y2h8c3dpc3N8c3h8c3l8c3lkbmV5fHN5bWFudGVjfHN5c3RlbXN8c3p8dGFifHRhaXBlaXx0YW9iYW98dGF0YW1vdG9yc3x0YXRhcnx0YXR0b298dGF4fHRheGl8dGN8dGNpfHRkfHRlYW18dGVjaHx0ZWNobm9sb2d5fHRlbHx0ZWxlY2l0eXx0ZWxlZm9uaWNhfHRlbWFzZWt8dGVubmlzfHRmfHRnfHRofHRoZHx0aGVhdGVyfHRoZWF0cmV8dGlja2V0c3x0aWVuZGF8dGlmZmFueXx0aXBzfHRpcmVzfHRpcm9sfHRqfHRrfHRsfHRtfHRtYWxsfHRufHRvfHRvZGF5fHRva3lvfHRvb2xzfHRvcHx0b3JheXx0b3NoaWJhfHRvdGFsfHRvdXJzfHRvd258dG95b3RhfHRveXN8dHB8dHJ8dHJhZGV8dHJhZGluZ3x0cmFpbmluZ3x0cmF2ZWx8dHJhdmVsZXJzfHRyYXZlbGVyc2luc3VyYW5jZXx0cnVzdHx0cnZ8dHR8dHViZXx0dWl8dHVuZXN8dHVzaHV8dHZ8dHZzfHR3fHR6fHVhfHVic3x1Z3x1a3x1bmljb218dW5pdmVyc2l0eXx1bm98dW9sfHVzfHV5fHV6fHZhfHZhY2F0aW9uc3x2YW5hfHZjfHZlfHZlZ2FzfHZlbnR1cmVzfHZlcmlzaWdufHZlcnNpY2hlcnVuZ3x2ZXR8dmd8dml8dmlhamVzfHZpZGVvfHZpa2luZ3x2aWxsYXN8dmlufHZpcHx2aXJnaW58dmlzaW9ufHZpc3RhfHZpc3RhcHJpbnR8dml2YXx2bGFhbmRlcmVufHZufHZvZGthfHZvbGtzd2FnZW58dm90ZXx2b3Rpbmd8dm90b3x2b3lhZ2V8dnV8dnVlbG9zfHdhbGVzfHdhbHRlcnx3YW5nfHdhbmdnb3V8d2F0Y2h8d2F0Y2hlc3x3ZWF0aGVyfHdlYXRoZXJjaGFubmVsfHdlYmNhbXx3ZWJlcnx3ZWJzaXRlfHdlZHx3ZWRkaW5nfHdlaXJ8d2Z8d2hvc3dob3x3aWVufHdpa2l8d2lsbGlhbWhpbGx8d2lufHdpbmRvd3N8d2luZXx3bWV8d29sdGVyc2tsdXdlcnx3b3JrfHdvcmtzfHdvcmxkfHdzfHd0Y3x3dGZ8eGJveHx4ZXJveHx4aW58eHBlcmlhfHh4eHx4eXp8eWFjaHRzfHlhaG9vfHlhbWF4dW58eWFuZGV4fHllfHlvZG9iYXNoaXx5b2dhfHlva29oYW1hfHlvdXR1YmV8eXR8emF8emFyYXx6ZXJvfHppcHx6bXx6b25lfHp1ZXJpY2h8encnLnNwbGl0KCd8Jyk7IC8vIG1hY3JvLCBzZWUgZ3VscGZpbGUuanMKCgl2YXIgTlVNQkVSUyA9ICcwMTIzNDU2Nzg5Jy5zcGxpdCgnJyk7Cgl2YXIgQUxQSEFOVU0gPSAnMDEyMzQ1Njc4OWFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6Jy5zcGxpdCgnJyk7Cgl2YXIgV0hJVEVTUEFDRSA9IFsnICcsICdcZicsICdccicsICdcdCcsICdcdicsICegJywgJz8nLCAnPyddOyAvLyBleGNsdWRpbmcgbGluZSBicmVha3MKCgl2YXIgZG9tYWluU3RhdGVzID0gW107IC8vIHN0YXRlcyB0aGF0IGp1bXAgdG8gRE9NQUlOIG9uIC9bYS16MC05XS8KCXZhciBtYWtlU3RhdGUgPSBmdW5jdGlvbiBtYWtlU3RhdGUodG9rZW5DbGFzcykgewoJCXJldHVybiBuZXcgQ2hhcmFjdGVyU3RhdGUodG9rZW5DbGFzcyk7Cgl9OwoKCS8vIEZyZXF1ZW50bHkgdXNlZCBzdGF0ZXMKCXZhciBTX1NUQVJUID0gbWFrZVN0YXRlKCk7Cgl2YXIgU19OVU0gPSBtYWtlU3RhdGUoTlVNKTsKCXZhciBTX0RPTUFJTiA9IG1ha2VTdGF0ZShET01BSU4pOwoJdmFyIFNfRE9NQUlOX0hZUEhFTiA9IG1ha2VTdGF0ZSgpOyAvLyBkb21haW4gZm9sbG93ZWQgYnkgMSBvciBtb3JlIGh5cGhlbiBjaGFyYWN0ZXJzCgl2YXIgU19XUyA9IG1ha2VTdGF0ZShXUyk7CgoJLy8gU3RhdGVzIGZvciBzcGVjaWFsIFVSTCBzeW1ib2xzCglTX1NUQVJULm9uKCdAJywgbWFrZVN0YXRlKEFUKSkub24oJy4nLCBtYWtlU3RhdGUoRE9UKSkub24oJysnLCBtYWtlU3RhdGUoUExVUykpLm9uKCcjJywgbWFrZVN0YXRlKFBPVU5EKSkub24oJz8nLCBtYWtlU3RhdGUoUVVFUlkpKS5vbignLycsIG1ha2VTdGF0ZShTTEFTSCkpLm9uKCdfJywgbWFrZVN0YXRlKFVOREVSU0NPUkUpKS5vbignOicsIG1ha2VTdGF0ZShDT0xPTikpLm9uKCd7JywgbWFrZVN0YXRlKE9QRU5CUkFDRSkpLm9uKCdbJywgbWFrZVN0YXRlKE9QRU5CUkFDS0VUKSkub24oJzwnLCBtYWtlU3RhdGUoT1BFTkFOR0xFQlJBQ0tFVCkpLm9uKCcoJywgbWFrZVN0YXRlKE9QRU5QQVJFTikpLm9uKCd9JywgbWFrZVN0YXRlKENMT1NFQlJBQ0UpKS5vbignXScsIG1ha2VTdGF0ZShDTE9TRUJSQUNLRVQpKS5vbignPicsIG1ha2VTdGF0ZShDTE9TRUFOR0xFQlJBQ0tFVCkpLm9uKCcpJywgbWFrZVN0YXRlKENMT1NFUEFSRU4pKS5vbihbJywnLCAnOycsICchJywgJyInLCAnXCcnXSwgbWFrZVN0YXRlKFBVTkNUVUFUSU9OKSk7CgoJLy8gV2hpdGVzcGFjZSBqdW1wcwoJLy8gVG9rZW5zIG9mIG9ubHkgbm9uLW5ld2xpbmUgd2hpdGVzcGFjZSBhcmUgYXJiaXRyYXJpbHkgbG9uZwoJU19TVEFSVC5vbignXG4nLCBtYWtlU3RhdGUoVE5MKSkub24oV0hJVEVTUEFDRSwgU19XUyk7CgoJLy8gSWYgYW55IHdoaXRlc3BhY2UgZXhjZXB0IG5ld2xpbmUsIG1vcmUgd2hpdGVzcGFjZSEKCVNfV1Mub24oV0hJVEVTUEFDRSwgU19XUyk7CgoJLy8gR2VuZXJhdGVzIHN0YXRlcyBmb3IgdG9wLWxldmVsIGRvbWFpbnMKCS8vIE5vdGUgdGhhdCB0aGlzIGlzIG1vc3QgYWNjdXJhdGUgd2hlbiB0bGRzIGFyZSBpbiBhbHBoYWJldGljYWwgb3JkZXIKCWZvciAodmFyIGkgPSAwOyBpIDwgdGxkcy5sZW5ndGg7IGkrKykgewoJCXZhciBuZXdTdGF0ZXMgPSBzdGF0ZWlmeSh0bGRzW2ldLCBTX1NUQVJULCBUTEQsIERPTUFJTik7CgkJZG9tYWluU3RhdGVzLnB1c2guYXBwbHkoZG9tYWluU3RhdGVzLCBuZXdTdGF0ZXMpOwoJfQoKCS8vIENvbGxlY3QgdGhlIHN0YXRlcyBnZW5lcmF0ZWQgYnkgZGlmZmVyZW50IHByb3RvY2xzCgl2YXIgcGFydGlhbFByb3RvY29sRmlsZVN0YXRlcyA9IHN0YXRlaWZ5KCdmaWxlJywgU19TVEFSVCwgRE9NQUlOLCBET01BSU4pOwoJdmFyIHBhcnRpYWxQcm90b2NvbEZ0cFN0YXRlcyA9IHN0YXRlaWZ5KCdmdHAnLCBTX1NUQVJULCBET01BSU4sIERPTUFJTik7Cgl2YXIgcGFydGlhbFByb3RvY29sSHR0cFN0YXRlcyA9IHN0YXRlaWZ5KCdodHRwJywgU19TVEFSVCwgRE9NQUlOLCBET01BSU4pOwoKCS8vIEFkZCB0aGUgc3RhdGVzIHRvIHRoZSBhcnJheSBvZiBET01BSU5lcmljIHN0YXRlcwoJZG9tYWluU3RhdGVzLnB1c2guYXBwbHkoZG9tYWluU3RhdGVzLCBwYXJ0aWFsUHJvdG9jb2xGaWxlU3RhdGVzKTsKCWRvbWFpblN0YXRlcy5wdXNoLmFwcGx5KGRvbWFpblN0YXRlcywgcGFydGlhbFByb3RvY29sRnRwU3RhdGVzKTsKCWRvbWFpblN0YXRlcy5wdXNoLmFwcGx5KGRvbWFpblN0YXRlcywgcGFydGlhbFByb3RvY29sSHR0cFN0YXRlcyk7CgoJLy8gUHJvdG9jb2wgc3RhdGVzCgl2YXIgU19QUk9UT0NPTF9GSUxFID0gcGFydGlhbFByb3RvY29sRmlsZVN0YXRlcy5wb3AoKTsKCXZhciBTX1BST1RPQ09MX0ZUUCA9IHBhcnRpYWxQcm90b2NvbEZ0cFN0YXRlcy5wb3AoKTsKCXZhciBTX1BST1RPQ09MX0hUVFAgPSBwYXJ0aWFsUHJvdG9jb2xIdHRwU3RhdGVzLnBvcCgpOwoJdmFyIFNfUFJPVE9DT0xfU0VDVVJFID0gbWFrZVN0YXRlKERPTUFJTik7Cgl2YXIgU19GVUxMX1BST1RPQ09MID0gbWFrZVN0YXRlKFBST1RPQ09MKTsgLy8gRnVsbCBwcm90b2NvbCBlbmRzIHdpdGggQ09MT04KCgkvLyBTZWN1cmUgcHJvdG9jb2xzIChlbmQgd2l0aCAncycpCglTX1BST1RPQ09MX0ZUUC5vbigncycsIFNfUFJPVE9DT0xfU0VDVVJFKS5vbignOicsIFNfRlVMTF9QUk9UT0NPTCk7CgoJU19QUk9UT0NPTF9IVFRQLm9uKCdzJywgU19QUk9UT0NPTF9TRUNVUkUpLm9uKCc6JywgU19GVUxMX1BST1RPQ09MKTsKCglkb21haW5TdGF0ZXMucHVzaChTX1BST1RPQ09MX1NFQ1VSRSk7CgoJLy8gQmVjb21lIHByb3RvY29sIHRva2VucyBhZnRlciBhIENPTE9OCglTX1BST1RPQ09MX0ZJTEUub24oJzonLCBTX0ZVTExfUFJPVE9DT0wpOwoJU19QUk9UT0NPTF9TRUNVUkUub24oJzonLCBTX0ZVTExfUFJPVE9DT0wpOwoKCS8vIExvY2FsaG9zdAoJdmFyIHBhcnRpYWxMb2NhbGhvc3RTdGF0ZXMgPSBzdGF0ZWlmeSgnbG9jYWxob3N0JywgU19TVEFSVCwgTE9DQUxIT1NULCBET01BSU4pOwoJZG9tYWluU3RhdGVzLnB1c2guYXBwbHkoZG9tYWluU3RhdGVzLCBwYXJ0aWFsTG9jYWxob3N0U3RhdGVzKTsKCgkvLyBFdmVyeXRoaW5nIGVsc2UKCS8vIERPTUFJTnMgbWFrZSBtb3JlIERPTUFJTnMKCS8vIE51bWJlciBhbmQgY2hhcmFjdGVyIHRyYW5zaXRpb25zCglTX1NUQVJULm9uKE5VTUJFUlMsIFNfTlVNKTsKCVNfTlVNLm9uKCctJywgU19ET01BSU5fSFlQSEVOKS5vbihOVU1CRVJTLCBTX05VTSkub24oQUxQSEFOVU0sIFNfRE9NQUlOKTsgLy8gbnVtYmVyIGJlY29tZXMgRE9NQUlOCgoJU19ET01BSU4ub24oJy0nLCBTX0RPTUFJTl9IWVBIRU4pLm9uKEFMUEhBTlVNLCBTX0RPTUFJTik7CgoJLy8gQWxsIHRoZSBnZW5lcmF0ZWQgc3RhdGVzIHNob3VsZCBoYXZlIGEganVtcCB0byBET01BSU4KCWZvciAodmFyIF9pID0gMDsgX2kgPCBkb21haW5TdGF0ZXMubGVuZ3RoOyBfaSsrKSB7CgkJZG9tYWluU3RhdGVzW19pXS5vbignLScsIFNfRE9NQUlOX0hZUEhFTikub24oQUxQSEFOVU0sIFNfRE9NQUlOKTsKCX0KCglTX0RPTUFJTl9IWVBIRU4ub24oJy0nLCBTX0RPTUFJTl9IWVBIRU4pLm9uKE5VTUJFUlMsIFNfRE9NQUlOKS5vbihBTFBIQU5VTSwgU19ET01BSU4pOwoKCS8vIFNldCBkZWZhdWx0IHRyYW5zaXRpb24KCVNfU1RBUlQuZGVmYXVsdFRyYW5zaXRpb24gPSBtYWtlU3RhdGUoU1lNKTsKCgkvKioKIAlHaXZlbiBhIHN0cmluZywgcmV0dXJucyBhbiBhcnJheSBvZiBUT0tFTiBpbnN0YW5jZXMgcmVwcmVzZW50aW5nIHRoZQogCWNvbXBvc2l0aW9uIG9mIHRoYXQgc3RyaW5nLgoKIAlAbWV0aG9kIHJ1bgogCUBwYXJhbSB7U3RyaW5nfSBzdHIgSW5wdXQgc3RyaW5nIHRvIHNjYW4KIAlAcmV0dXJuIHtBcnJheX0gQXJyYXkgb2YgVE9LRU4gaW5zdGFuY2VzCiAqLwoJdmFyIHJ1biA9IGZ1bmN0aW9uIHJ1bihzdHIpIHsKCgkJLy8gVGhlIHN0YXRlIG1hY2hpbmUgb25seSBsb29rcyBhdCBsb3dlcmNhc2Ugc3RyaW5ncy4KCQkvLyBUaGlzIHNlbGVjdGl2ZSBgdG9Mb3dlckNhc2VgIGlzIHVzZWQgYmVjYXVzZSBsb3dlcmNhc2luZyB0aGUgZW50aXJlCgkJLy8gc3RyaW5nIGNhdXNlcyB0aGUgbGVuZ3RoIGFuZCBjaGFyYWN0ZXIgcG9zaXRpb24gdG8gdmFyeSBpbiBzb21lIGluIHNvbWUKCQkvLyBub24tRW5nbGlzaCBzdHJpbmdzLiBUaGlzIGhhcHBlbnMgb25seSBvbiBWOC1iYXNlZCBydW50aW1lcy4KCQl2YXIgbG93ZXJTdHIgPSBzdHIucmVwbGFjZSgvW0EtWl0vZywgZnVuY3Rpb24gKGMpIHsKCQkJcmV0dXJuIGMudG9Mb3dlckNhc2UoKTsKCQl9KTsKCQl2YXIgbGVuID0gc3RyLmxlbmd0aDsKCQl2YXIgdG9rZW5zID0gW107IC8vIHJldHVybiB2YWx1ZQoKCQl2YXIgY3Vyc29yID0gMDsKCgkJLy8gVG9rZW5pemUgdGhlIHN0cmluZwoJCXdoaWxlIChjdXJzb3IgPCBsZW4pIHsKCQkJdmFyIHN0YXRlID0gU19TVEFSVDsKCQkJdmFyIHNlY29uZFN0YXRlID0gbnVsbDsKCQkJdmFyIG5leHRTdGF0ZSA9IG51bGw7CgkJCXZhciB0b2tlbkxlbmd0aCA9IDA7CgkJCXZhciBsYXRlc3RBY2NlcHRpbmcgPSBudWxsOwoJCQl2YXIgc2luY2VBY2NlcHRzID0gLTE7CgoJCQl3aGlsZSAoY3Vyc29yIDwgbGVuICYmIChuZXh0U3RhdGUgPSBzdGF0ZS5uZXh0KGxvd2VyU3RyW2N1cnNvcl0pKSkgewoJCQkJc2Vjb25kU3RhdGUgPSBudWxsOwoJCQkJc3RhdGUgPSBuZXh0U3RhdGU7CgoJCQkJLy8gS2VlcCB0cmFjayBvZiB0aGUgbGF0ZXN0IGFjY2VwdGluZyBzdGF0ZQoJCQkJaWYgKHN0YXRlLmFjY2VwdHMoKSkgewoJCQkJCXNpbmNlQWNjZXB0cyA9IDA7CgkJCQkJbGF0ZXN0QWNjZXB0aW5nID0gc3RhdGU7CgkJCQl9IGVsc2UgaWYgKHNpbmNlQWNjZXB0cyA+PSAwKSB7CgkJCQkJc2luY2VBY2NlcHRzKys7CgkJCQl9CgoJCQkJdG9rZW5MZW5ndGgrKzsKCQkJCWN1cnNvcisrOwoJCQl9CgoJCQlpZiAoc2luY2VBY2NlcHRzIDwgMCkgewoJCQkJY29udGludWU7CgkJCX0gLy8gU2hvdWxkIG5ldmVyIGhhcHBlbgoKCQkJLy8gUm9sbCBiYWNrIHRvIHRoZSBsYXRlc3QgYWNjZXB0aW5nIHN0YXRlCgkJCWN1cnNvciAtPSBzaW5jZUFjY2VwdHM7CgkJCXRva2VuTGVuZ3RoIC09IHNpbmNlQWNjZXB0czsKCgkJCS8vIEdldCB0aGUgY2xhc3MgZm9yIHRoZSBuZXcgdG9rZW4KCQkJdmFyIFRPS0VOID0gbGF0ZXN0QWNjZXB0aW5nLmVtaXQoKTsgLy8gQ3VycmVudCB0b2tlbiBjbGFzcwoKCQkJLy8gTm8gbW9yZSBqdW1wcywganVzdCBtYWtlIGEgbmV3IHRva2VuCgkJCXRva2Vucy5wdXNoKG5ldyBUT0tFTihzdHIuc3Vic3RyKGN1cnNvciAtIHRva2VuTGVuZ3RoLCB0b2tlbkxlbmd0aCkpKTsKCQl9CgoJCXJldHVybiB0b2tlbnM7Cgl9OwoKCXZhciBzdGFydCA9IFNfU1RBUlQ7CgoJdmFyIHNjYW5uZXIgPSBPYmplY3QuZnJlZXplKHsKCQlTdGF0ZTogQ2hhcmFjdGVyU3RhdGUsCgkJVE9LRU5TOiBUT0tFTlMsCgkJcnVuOiBydW4sCgkJc3RhcnQ6IHN0YXJ0Cgl9KTsKCgkvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAJTXVsdGktVG9rZW5zCiAJVG9rZW5zIGNvbXBvc2VkIG9mIGFycmF5cyBvZiBUZXh0VG9rZW5zCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoJLy8gSXMgdGhlIGdpdmVuIHRva2VuIGEgdmFsaWQgZG9tYWluIHRva2VuPwoJLy8gU2hvdWxkIG51bXMgYmUgaW5jbHVkZWQgaGVyZT8KCWZ1bmN0aW9uIGlzRG9tYWluVG9rZW4odG9rZW4pIHsKCQlyZXR1cm4gdG9rZW4gaW5zdGFuY2VvZiBET01BSU4gfHwgdG9rZW4gaW5zdGFuY2VvZiBUTEQ7Cgl9CgoJLyoqCiAJQWJzdHJhY3QgY2xhc3MgdXNlZCBmb3IgbWFudWZhY3R1cmluZyB0b2tlbnMgb2YgdGV4dCB0b2tlbnMuIFRoYXQgaXMgcmF0aGVyCiAJdGhhbiB0aGUgdmFsdWUgZm9yIGEgdG9rZW4gYmVpbmcgYSBzbWFsbCBzdHJpbmcgb2YgdGV4dCwgaXQncyB2YWx1ZSBhbiBhcnJheQogCW9mIHRleHQgdG9rZW5zLgoKIAlVc2VkIGZvciBncm91cGluZyB0b2dldGhlciBVUkxzLCBlbWFpbHMsIGhhc2h0YWdzLCBhbmQgb3RoZXIgcG90ZW50aWFsCiAJY3JlYXRpb25zLgoKIAlAY2xhc3MgTXVsdGlUb2tlbgogCUBhYnN0cmFjdAogKi8KCXZhciBNdWx0aVRva2VuID0gY3JlYXRlVG9rZW5DbGFzcygpOwoKCU11bHRpVG9rZW4ucHJvdG90eXBlID0gewoJCS8qKgogIAlTdHJpbmcgcmVwcmVzZW50aW5nIHRoZSB0eXBlIGZvciB0aGlzIHRva2VuCiAgCUBwcm9wZXJ0eSB0eXBlCiAgCUBkZWZhdWx0ICdUT0tFTicKICAqLwoJCXR5cGU6ICd0b2tlbicsCgoJCS8qKgogIAlJcyB0aGlzIG11bHRpdG9rZW4gYSBsaW5rPwogIAlAcHJvcGVydHkgaXNMaW5rCiAgCUBkZWZhdWx0IGZhbHNlCiAgKi8KCQlpc0xpbms6IGZhbHNlLAoKCQkvKioKICAJUmV0dXJuIHRoZSBzdHJpbmcgdGhpcyB0b2tlbiByZXByZXNlbnRzLgogIAlAbWV0aG9kIHRvU3RyaW5nCiAgCUByZXR1cm4ge1N0cmluZ30KICAqLwoJCXRvU3RyaW5nOiBmdW5jdGlvbiB0b1N0cmluZygpIHsKCQkJdmFyIHJlc3VsdCA9IFtdOwoJCQlmb3IgKHZhciBfaTIgPSAwOyBfaTIgPCB0aGlzLnYubGVuZ3RoOyBfaTIrKykgewoJCQkJcmVzdWx0LnB1c2godGhpcy52W19pMl0udG9TdHJpbmcoKSk7CgkJCX0KCQkJcmV0dXJuIHJlc3VsdC5qb2luKCcnKTsKCQl9LAoKCgkJLyoqCiAgCVdoYXQgc2hvdWxkIHRoZSB2YWx1ZSBmb3IgdGhpcyB0b2tlbiBiZSBpbiB0aGUgYGhyZWZgIEhUTUwgYXR0cmlidXRlPwogIAlSZXR1cm5zIHRoZSBgLnRvU3RyaW5nYCB2YWx1ZSBieSBkZWZhdWx0LgogIAkJQG1ldGhvZCB0b0hyZWYKICAJQHJldHVybiB7U3RyaW5nfQogICovCgkJdG9IcmVmOiBmdW5jdGlvbiB0b0hyZWYoKSB7CgkJCXJldHVybiB0aGlzLnRvU3RyaW5nKCk7CgkJfSwKCgoJCS8qKgogIAlSZXR1cm5zIGEgaGFzaCBvZiByZWxldmFudCB2YWx1ZXMgZm9yIHRoaXMgdG9rZW4sIHdoaWNoIGluY2x1ZGVzIGtleXMKICAJKiB0eXBlIC0gS2luZCBvZiB0b2tlbiAoJ3VybCcsICdlbWFpbCcsIGV0Yy4pCiAgCSogdmFsdWUgLSBPcmlnaW5hbCB0ZXh0CiAgCSogaHJlZiAtIFRoZSB2YWx1ZSB0aGF0IHNob3VsZCBiZSBhZGRlZCB0byB0aGUgYW5jaG9yIHRhZydzIGhyZWYKICAJCWF0dHJpYnV0ZQogIAkJQG1ldGhvZCB0b09iamVjdAogIAlAcGFyYW0ge1N0cmluZ30gW3Byb3RvY29sXSBgJ2h0dHAnYCBieSBkZWZhdWx0CiAgCUByZXR1cm4ge09iamVjdH0KICAqLwoJCXRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdCgpIHsKCQkJdmFyIHByb3RvY29sID0gYXJndW1lbnRzLmxlbmd0aCA8PSAwIHx8IGFyZ3VtZW50c1swXSA9PT0gdW5kZWZpbmVkID8gJ2h0dHAnIDogYXJndW1lbnRzWzBdOwoKCQkJcmV0dXJuIHsKCQkJCXR5cGU6IHRoaXMudHlwZSwKCQkJCXZhbHVlOiB0aGlzLnRvU3RyaW5nKCksCgkJCQlocmVmOiB0aGlzLnRvSHJlZihwcm90b2NvbCkKCQkJfTsKCQl9Cgl9OwoKCS8qKgogCVJlcHJlc2VudHMgYSBsaXN0IG9mIHRva2VucyBtYWtpbmcgdXAgYSB2YWxpZCBlbWFpbCBhZGRyZXNzCiAJQGNsYXNzIEVNQUlMCiAJQGV4dGVuZHMgTXVsdGlUb2tlbgogKi8KCXZhciBFTUFJTCA9IGluaGVyaXRzKE11bHRpVG9rZW4sIGNyZWF0ZVRva2VuQ2xhc3MoKSwgewoJCXR5cGU6ICdlbWFpbCcsCgkJaXNMaW5rOiB0cnVlLAoJCXRvSHJlZjogZnVuY3Rpb24gdG9IcmVmKCkgewoJCQlyZXR1cm4gJ21haWx0bzonICsgdGhpcy50b1N0cmluZygpOwoJCX0KCX0pOwoKCS8qKgogCVJlcHJlc2VudHMgc29tZSBwbGFpbiB0ZXh0CiAJQGNsYXNzIFRFWFQKIAlAZXh0ZW5kcyBNdWx0aVRva2VuCiAqLwoJdmFyIFRFWFQgPSBpbmhlcml0cyhNdWx0aVRva2VuLCBjcmVhdGVUb2tlbkNsYXNzKCksIHsgdHlwZTogJ3RleHQnIH0pOwoKCS8qKgogCU11bHRpLWxpbmVicmVhayB0b2tlbiAtIHJlcHJlc2VudHMgYSBsaW5lIGJyZWFrCiAJQGNsYXNzIE5MCiAJQGV4dGVuZHMgTXVsdGlUb2tlbgogKi8KCXZhciBOTCA9IGluaGVyaXRzKE11bHRpVG9rZW4sIGNyZWF0ZVRva2VuQ2xhc3MoKSwgeyB0eXBlOiAnbmwnIH0pOwoKCS8qKgogCVJlcHJlc2VudHMgYSBsaXN0IG9mIHRva2VucyBtYWtpbmcgdXAgYSB2YWxpZCBVUkwKIAlAY2xhc3MgVVJMCiAJQGV4dGVuZHMgTXVsdGlUb2tlbgogKi8KCXZhciBVUkwgPSBpbmhlcml0cyhNdWx0aVRva2VuLCBjcmVhdGVUb2tlbkNsYXNzKCksIHsKCQl0eXBlOiAndXJsJywKCQlpc0xpbms6IHRydWUsCgoJCS8qKgogIAlMb3dlcmNhc2VzIHJlbGV2YW50IHBhcnRzIG9mIHRoZSBkb21haW4gYW5kIGFkZHMgdGhlIHByb3RvY29sIGlmCiAgCXJlcXVpcmVkLiBOb3RlIHRoYXQgdGhpcyB3aWxsIG5vdCBlc2NhcGUgdW5zYWZlIEhUTUwgY2hhcmFjdGVycyBpbiB0aGUKICAJVVJMLgogIAkJQG1ldGhvZCBocmVmCiAgCUBwYXJhbSB7U3RyaW5nfSBwcm90b2NvbAogIAlAcmV0dXJuIHtTdHJpbmd9CiAgKi8KCQl0b0hyZWY6IGZ1bmN0aW9uIHRvSHJlZigpIHsKCQkJdmFyIHByb3RvY29sID0gYXJndW1lbnRzLmxlbmd0aCA8PSAwIHx8IGFyZ3VtZW50c1swXSA9PT0gdW5kZWZpbmVkID8gJ2h0dHAnIDogYXJndW1lbnRzWzBdOwoKCQkJdmFyIGhhc1Byb3RvY29sID0gZmFsc2U7CgkJCXZhciBoYXNTbGFzaFNsYXNoID0gZmFsc2U7CgkJCXZhciB0b2tlbnMgPSB0aGlzLnY7CgkJCXZhciByZXN1bHQgPSBbXTsKCQkJdmFyIGkgPSAwOwoKCQkJLy8gTWFrZSB0aGUgZmlyc3QgcGFydCBvZiB0aGUgZG9tYWluIGxvd2VyY2FzZQoJCQkvLyBMb3dlcmNhc2UgcHJvdG9jb2wKCQkJd2hpbGUgKHRva2Vuc1tpXSBpbnN0YW5jZW9mIFBST1RPQ09MKSB7CgkJCQloYXNQcm90b2NvbCA9IHRydWU7CgkJCQlyZXN1bHQucHVzaCh0b2tlbnNbaV0udG9TdHJpbmcoKS50b0xvd2VyQ2FzZSgpKTsKCQkJCWkrKzsKCQkJfQoKCQkJLy8gU2tpcCBzbGFzaC1zbGFzaAoJCQl3aGlsZSAodG9rZW5zW2ldIGluc3RhbmNlb2YgU0xBU0gpIHsKCQkJCWhhc1NsYXNoU2xhc2ggPSB0cnVlOwoJCQkJcmVzdWx0LnB1c2godG9rZW5zW2ldLnRvU3RyaW5nKCkpOwoJCQkJaSsrOwoJCQl9CgoJCQkvLyBMb3dlcmNhc2UgYWxsIG90aGVyIGNoYXJhY3RlcnMgaW4gdGhlIGRvbWFpbgoJCQl3aGlsZSAoaXNEb21haW5Ub2tlbih0b2tlbnNbaV0pKSB7CgkJCQlyZXN1bHQucHVzaCh0b2tlbnNbaV0udG9TdHJpbmcoKS50b0xvd2VyQ2FzZSgpKTsKCQkJCWkrKzsKCQkJfQoKCQkJLy8gTGVhdmUgYWxsIG90aGVyIGNoYXJhY3RlcnMgYXMgdGhleSB3ZXJlIHdyaXR0ZW4KCQkJZm9yICg7IGkgPCB0b2tlbnMubGVuZ3RoOyBpKyspIHsKCQkJCXJlc3VsdC5wdXNoKHRva2Vuc1tpXS50b1N0cmluZygpKTsKCQkJfQoKCQkJcmVzdWx0ID0gcmVzdWx0LmpvaW4oJycpOwoKCQkJaWYgKCEoaGFzUHJvdG9jb2wgfHwgaGFzU2xhc2hTbGFzaCkpIHsKCQkJCXJlc3VsdCA9IHByb3RvY29sICsgJzovLycgKyByZXN1bHQ7CgkJCX0KCgkJCXJldHVybiByZXN1bHQ7CgkJfSwKCQloYXNQcm90b2NvbDogZnVuY3Rpb24gaGFzUHJvdG9jb2woKSB7CgkJCXJldHVybiB0aGlzLnZbMF0gaW5zdGFuY2VvZiBQUk9UT0NPTDsKCQl9Cgl9KTsKCgl2YXIgVE9LRU5TJDEgPSBPYmplY3QuZnJlZXplKHsKCQlCYXNlOiBNdWx0aVRva2VuLAoJCUVNQUlMOiBFTUFJTCwKCQlOTDogTkwsCgkJVEVYVDogVEVYVCwKCQlVUkw6IFVSTAoJfSk7CgoJLyoqCiAJTm90IGV4YWN0bHkgcGFyc2VyLCBtb3JlIGxpa2UgdGhlIHNlY29uZC1zdGFnZSBzY2FubmVyIChhbHRob3VnaCB3ZSBjYW4KIAl0aGVvcmV0aWNhbGx5IGhvdHN3YXAgdGhlIGNvZGUgaGVyZSB3aXRoIGEgcmVhbCBwYXJzZXIgaW4gdGhlIGZ1dHVyZS4uLiBidXQKIAlmb3IgYSBsaXR0bGUgVVJMLWZpbmRpbmcgdXRpbGl0eSBhYnN0cmFjdCBzeW50YXggdHJlZXMgbWF5IGJlIGEgbGl0dGxlCiAJb3ZlcmtpbGwpLgoKIAlVUkwgZm9ybWF0OiBodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1VSSV9zY2hlbWUKIAlFbWFpbCBmb3JtYXQ6IGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRW1haWxfYWRkcmVzcyAobGlua3MgdG8gUkZDIGluCiAJcmVmZXJlbmNlKQoKIAlAbW9kdWxlIGxpbmtpZnkKIAlAc3VibW9kdWxlIHBhcnNlcgogCUBtYWluIHBhcnNlcgogKi8KCgl2YXIgbWFrZVN0YXRlJDEgPSBmdW5jdGlvbiBtYWtlU3RhdGUkMSh0b2tlbkNsYXNzKSB7CgkJcmV0dXJuIG5ldyBTdGF0ZSh0b2tlbkNsYXNzKTsKCX07CgoJLy8gVGhlIHVuaXZlcnNhbCBzdGFydGluZyBzdGF0ZS4KCXZhciBTX1NUQVJUJDEgPSBtYWtlU3RhdGUkMSgpOwoKCS8vIEludGVybWVkaWF0ZSBzdGF0ZXMgZm9yIFVSTHMuIE5vdGUgdGhhdCBkb21haW5zIHRoYXQgYmVnaW4gd2l0aCBhIHByb3RvY29sCgkvLyBhcmUgdHJlYXRlZCBzbGlnaGx5IGRpZmZlcmVudGx5IGZyb20gdGhvc2UgdGhhdCBkb24ndC4KCXZhciBTX1BST1RPQ09MID0gbWFrZVN0YXRlJDEoKTsgLy8gZS5nLiwgJ2h0dHA6JwoJdmFyIFNfUFJPVE9DT0xfU0xBU0ggPSBtYWtlU3RhdGUkMSgpOyAvLyBlLmcuLCAnLycsICdodHRwOi8nJwoJdmFyIFNfUFJPVE9DT0xfU0xBU0hfU0xBU0ggPSBtYWtlU3RhdGUkMSgpOyAvLyBlLmcuLCAnLy8nLCAnaHR0cDovLycKCXZhciBTX0RPTUFJTiQxID0gbWFrZVN0YXRlJDEoKTsgLy8gcGFyc2VkIHN0cmluZyBlbmRzIHdpdGggYSBwb3RlbnRpYWwgZG9tYWluIG5hbWUgKEEpCgl2YXIgU19ET01BSU5fRE9UID0gbWFrZVN0YXRlJDEoKTsgLy8gKEEpIGRvbWFpbiBmb2xsb3dlZCBieSBET1QKCXZhciBTX1RMRCA9IG1ha2VTdGF0ZSQxKFVSTCk7IC8vIChBKSBTaW1wbGVzdCBwb3NzaWJsZSBVUkwgd2l0aCBubyBxdWVyeSBzdHJpbmcKCXZhciBTX1RMRF9DT0xPTiA9IG1ha2VTdGF0ZSQxKCk7IC8vIChBKSBVUkwgZm9sbG93ZWQgYnkgY29sb24gKHBvdGVudGlhbCBwb3J0IG51bWJlciBoZXJlKQoJdmFyIFNfVExEX1BPUlQgPSBtYWtlU3RhdGUkMShVUkwpOyAvLyBUTEQgZm9sbG93ZWQgYnkgYSBwb3J0IG51bWJlcgoJdmFyIFNfVVJMID0gbWFrZVN0YXRlJDEoVVJMKTsgLy8gTG9uZyBVUkwgd2l0aCBvcHRpb25hbCBwb3J0IGFuZCBtYXliZSBxdWVyeSBzdHJpbmcKCXZhciBTX1VSTF9OT05fQUNDRVBUSU5HID0gbWFrZVN0YXRlJDEoKTsgLy8gVVJMIGZvbGxvd2VkIGJ5IHNvbWUgc3ltYm9scyAod2lsbCBub3QgYmUgcGFydCBvZiB0aGUgZmluYWwgVVJMKQoJdmFyIFNfVVJMX09QRU5CUkFDRSA9IG1ha2VTdGF0ZSQxKCk7IC8vIFVSTCBmb2xsb3dlZCBieSB7Cgl2YXIgU19VUkxfT1BFTkJSQUNLRVQgPSBtYWtlU3RhdGUkMSgpOyAvLyBVUkwgZm9sbG93ZWQgYnkgWwoJdmFyIFNfVVJMX09QRU5BTkdMRUJSQUNLRVQgPSBtYWtlU3RhdGUkMSgpOyAvLyBVUkwgZm9sbG93ZWQgYnkgPAoJdmFyIFNfVVJMX09QRU5QQVJFTiA9IG1ha2VTdGF0ZSQxKCk7IC8vIFVSTCBmb2xsb3dlZCBieSAoCgl2YXIgU19VUkxfT1BFTkJSQUNFX1EgPSBtYWtlU3RhdGUkMShVUkwpOyAvLyBVUkwgZm9sbG93ZWQgYnkgeyBhbmQgc29tZSBzeW1ib2xzIHRoYXQgdGhlIFVSTCBjYW4gZW5kIGl0Cgl2YXIgU19VUkxfT1BFTkJSQUNLRVRfUSA9IG1ha2VTdGF0ZSQxKFVSTCk7IC8vIFVSTCBmb2xsb3dlZCBieSBbIGFuZCBzb21lIHN5bWJvbHMgdGhhdCB0aGUgVVJMIGNhbiBlbmQgaXQKCXZhciBTX1VSTF9PUEVOQU5HTEVCUkFDS0VUX1EgPSBtYWtlU3RhdGUkMShVUkwpOyAvLyBVUkwgZm9sbG93ZWQgYnkgPCBhbmQgc29tZSBzeW1ib2xzIHRoYXQgdGhlIFVSTCBjYW4gZW5kIGl0Cgl2YXIgU19VUkxfT1BFTlBBUkVOX1EgPSBtYWtlU3RhdGUkMShVUkwpOyAvLyBVUkwgZm9sbG93ZWQgYnkgKCBhbmQgc29tZSBzeW1ib2xzIHRoYXQgdGhlIFVSTCBjYW4gZW5kIGl0Cgl2YXIgU19VUkxfT1BFTkJSQUNFX1NZTVMgPSBtYWtlU3RhdGUkMSgpOyAvLyBTX1VSTF9PUEVOQlJBQ0VfUSBmb2xsb3dlZCBieSBzb21lIHN5bWJvbHMgaXQgY2Fubm90IGVuZCBpdAoJdmFyIFNfVVJMX09QRU5CUkFDS0VUX1NZTVMgPSBtYWtlU3RhdGUkMSgpOyAvLyBTX1VSTF9PUEVOQlJBQ0tFVF9RIGZvbGxvd2VkIGJ5IHNvbWUgc3ltYm9scyBpdCBjYW5ub3QgZW5kIGl0Cgl2YXIgU19VUkxfT1BFTkFOR0xFQlJBQ0tFVF9TWU1TID0gbWFrZVN0YXRlJDEoKTsgLy8gU19VUkxfT1BFTkFOR0xFQlJBQ0tFVF9RIGZvbGxvd2VkIGJ5IHNvbWUgc3ltYm9scyBpdCBjYW5ub3QgZW5kIGl0Cgl2YXIgU19VUkxfT1BFTlBBUkVOX1NZTVMgPSBtYWtlU3RhdGUkMSgpOyAvLyBTX1VSTF9PUEVOUEFSRU5fUSBmb2xsb3dlZCBieSBzb21lIHN5bWJvbHMgaXQgY2Fubm90IGVuZCBpdAoJdmFyIFNfRU1BSUxfRE9NQUlOID0gbWFrZVN0YXRlJDEoKTsgLy8gcGFyc2VkIHN0cmluZyBzdGFydHMgd2l0aCBsb2NhbCBlbWFpbCBpbmZvICsgQCB3aXRoIGEgcG90ZW50aWFsIGRvbWFpbiBuYW1lIChDKQoJdmFyIFNfRU1BSUxfRE9NQUlOX0RPVCA9IG1ha2VTdGF0ZSQxKCk7IC8vIChDKSBkb21haW4gZm9sbG93ZWQgYnkgRE9UCgl2YXIgU19FTUFJTCA9IG1ha2VTdGF0ZSQxKEVNQUlMKTsgLy8gKEMpIFBvc3NpYmxlIGVtYWlsIGFkZHJlc3MgKGNvdWxkIGhhdmUgbW9yZSB0bGRzKQoJdmFyIFNfRU1BSUxfQ09MT04gPSBtYWtlU3RhdGUkMSgpOyAvLyAoQykgVVJMIGZvbGxvd2VkIGJ5IGNvbG9uIChwb3RlbnRpYWwgcG9ydCBudW1iZXIgaGVyZSkKCXZhciBTX0VNQUlMX1BPUlQgPSBtYWtlU3RhdGUkMShFTUFJTCk7IC8vIChDKSBFbWFpbCBhZGRyZXNzIHdpdGggYSBwb3J0Cgl2YXIgU19MT0NBTFBBUlQgPSBtYWtlU3RhdGUkMSgpOyAvLyBMb2NhbCBwYXJ0IG9mIHRoZSBlbWFpbCBhZGRyZXNzCgl2YXIgU19MT0NBTFBBUlRfQVQgPSBtYWtlU3RhdGUkMSgpOyAvLyBMb2NhbCBwYXJ0IG9mIHRoZSBlbWFpbCBhZGRyZXNzIHBsdXMgQAoJdmFyIFNfTE9DQUxQQVJUX0RPVCA9IG1ha2VTdGF0ZSQxKCk7IC8vIExvY2FsIHBhcnQgb2YgdGhlIGVtYWlsIGFkZHJlc3MgcGx1cyAnLicgKGxvY2FscGFydCBjYW5ub3QgZW5kIGluIC4pCgl2YXIgU19OTCA9IG1ha2VTdGF0ZSQxKE5MKTsgLy8gc2luZ2xlIG5ldyBsaW5lCgoJLy8gTWFrZSBwYXRoIGZyb20gc3RhcnQgdG8gcHJvdG9jb2wgKHdpdGggJy8vJykKCVNfU1RBUlQkMS5vbihUTkwsIFNfTkwpLm9uKFBST1RPQ09MLCBTX1BST1RPQ09MKS5vbihTTEFTSCwgU19QUk9UT0NPTF9TTEFTSCk7CgoJU19QUk9UT0NPTC5vbihTTEFTSCwgU19QUk9UT0NPTF9TTEFTSCk7CglTX1BST1RPQ09MX1NMQVNILm9uKFNMQVNILCBTX1BST1RPQ09MX1NMQVNIX1NMQVNIKTsKCgkvLyBUaGUgdmVyeSBmaXJzdCBwb3RlbnRpYWwgZG9tYWluIG5hbWUKCVNfU1RBUlQkMS5vbihUTEQsIFNfRE9NQUlOJDEpLm9uKERPTUFJTiwgU19ET01BSU4kMSkub24oTE9DQUxIT1NULCBTX1RMRCkub24oTlVNLCBTX0RPTUFJTiQxKTsKCgkvLyBGb3JjZSBVUkwgZm9yIGFueXRoaW5nIHNhbmUgZm9sbG93ZWQgYnkgcHJvdG9jb2wKCVNfUFJPVE9DT0xfU0xBU0hfU0xBU0gub24oVExELCBTX1VSTCkub24oRE9NQUlOLCBTX1VSTCkub24oTlVNLCBTX1VSTCkub24oTE9DQUxIT1NULCBTX1VSTCk7CgoJLy8gQWNjb3VudCBmb3IgZG90cyBhbmQgaHlwaGVucwoJLy8gaHlwaGVucyBhcmUgdXN1YWxseSBwYXJ0cyBvZiBkb21haW4gbmFtZXMKCVNfRE9NQUlOJDEub24oRE9ULCBTX0RPTUFJTl9ET1QpOwoJU19FTUFJTF9ET01BSU4ub24oRE9ULCBTX0VNQUlMX0RPTUFJTl9ET1QpOwoKCS8vIEh5cGhlbiBjYW4ganVtcCBiYWNrIHRvIGEgZG9tYWluIG5hbWUKCgkvLyBBZnRlciB0aGUgZmlyc3QgZG9tYWluIGFuZCBhIGRvdCwgd2UgY2FuIGZpbmQgZWl0aGVyIGEgVVJMIG9yIGFub3RoZXIgZG9tYWluCglTX0RPTUFJTl9ET1Qub24oVExELCBTX1RMRCkub24oRE9NQUlOLCBTX0RPTUFJTiQxKS5vbihOVU0sIFNfRE9NQUlOJDEpLm9uKExPQ0FMSE9TVCwgU19ET01BSU4kMSk7CgoJU19FTUFJTF9ET01BSU5fRE9ULm9uKFRMRCwgU19FTUFJTCkub24oRE9NQUlOLCBTX0VNQUlMX0RPTUFJTikub24oTlVNLCBTX0VNQUlMX0RPTUFJTikub24oTE9DQUxIT1NULCBTX0VNQUlMX0RPTUFJTik7CgoJLy8gU19UTEQgYWNjZXB0cyEgQnV0IHRoZSBVUkwgY291bGQgYmUgbG9uZ2VyLCB0cnkgdG8gZmluZCBhIG1hdGNoIGdyZWVkaWx5CgkvLyBUaGUgYHJ1bmAgZnVuY3Rpb24gc2hvdWxkIGJlIGFibGUgdG8gInJvbGxiYWNrIiB0byB0aGUgYWNjZXB0aW5nIHN0YXRlCglTX1RMRC5vbihET1QsIFNfRE9NQUlOX0RPVCk7CglTX0VNQUlMLm9uKERPVCwgU19FTUFJTF9ET01BSU5fRE9UKTsKCgkvLyBCZWNvbWUgcmVhbCBVUkxzIGFmdGVyIGBTTEFTSGAgb3IgYENPTE9OIE5VTSBTTEFTSGAKCS8vIEhlcmUgUFNTIGFuZCBub24tUFNTIGNvbnZlcmdlCglTX1RMRC5vbihDT0xPTiwgU19UTERfQ09MT04pLm9uKFNMQVNILCBTX1VSTCk7CglTX1RMRF9DT0xPTi5vbihOVU0sIFNfVExEX1BPUlQpOwoJU19UTERfUE9SVC5vbihTTEFTSCwgU19VUkwpOwoJU19FTUFJTC5vbihDT0xPTiwgU19FTUFJTF9DT0xPTik7CglTX0VNQUlMX0NPTE9OLm9uKE5VTSwgU19FTUFJTF9QT1JUKTsKCgkvLyBUeXBlcyBvZiBjaGFyYWN0ZXJzIHRoZSBVUkwgY2FuIGRlZmluaXRlbHkgZW5kIGluCgl2YXIgcXNBY2NlcHRpbmcgPSBbRE9NQUlOLCBBVCwgTE9DQUxIT1NULCBOVU0sIFBMVVMsIFBPVU5ELCBQUk9UT0NPTCwgU0xBU0gsIFRMRCwgVU5ERVJTQ09SRSwgU1lNXTsKCgkvLyBUeXBlcyBvZiB0b2tlbnMgdGhhdCBjYW4gZm9sbG93IGEgVVJMIGFuZCBiZSBwYXJ0IG9mIHRoZSBxdWVyeSBzdHJpbmcKCS8vIGJ1dCBjYW5ub3QgYmUgdGhlIHZlcnkgbGFzdCBjaGFyYWN0ZXJzCgkvLyBDaGFyYWN0ZXJzIHRoYXQgY2Fubm90IGFwcGVhciBpbiB0aGUgVVJMIGF0IGFsbCBzaG91bGQgYmUgZXhjbHVkZWQKCXZhciBxc05vbkFjY2VwdGluZyA9IFtDT0xPTiwgRE9ULCBRVUVSWSwgUFVOQ1RVQVRJT04sIENMT1NFQlJBQ0UsIENMT1NFQlJBQ0tFVCwgQ0xPU0VBTkdMRUJSQUNLRVQsIENMT1NFUEFSRU4sIE9QRU5CUkFDRSwgT1BFTkJSQUNLRVQsIE9QRU5BTkdMRUJSQUNLRVQsIE9QRU5QQVJFTl07CgoJLy8gVGhlc2Ugc3RhdGVzIGFyZSByZXNwb25zaWJsZSBwcmltYXJpbHkgZm9yIGRldGVybWluaW5nIHdoZXRoZXIgb3Igbm90IHRvCgkvLyBpbmNsdWRlIHRoZSBmaW5hbCByb3VuZCBicmFja2V0LgoKCS8vIFVSTCwgZm9sbG93ZWQgYnkgYW4gb3BlbmluZyBicmFja2V0CglTX1VSTC5vbihPUEVOQlJBQ0UsIFNfVVJMX09QRU5CUkFDRSkub24oT1BFTkJSQUNLRVQsIFNfVVJMX09QRU5CUkFDS0VUKS5vbihPUEVOQU5HTEVCUkFDS0VULCBTX1VSTF9PUEVOQU5HTEVCUkFDS0VUKS5vbihPUEVOUEFSRU4sIFNfVVJMX09QRU5QQVJFTik7CgoJLy8gVVJMIHdpdGggZXh0cmEgc3ltYm9scyBhdCB0aGUgZW5kLCBmb2xsb3dlZCBieSBhbiBvcGVuaW5nIGJyYWNrZXQKCVNfVVJMX05PTl9BQ0NFUFRJTkcub24oT1BFTkJSQUNFLCBTX1VSTF9PUEVOQlJBQ0UpLm9uKE9QRU5CUkFDS0VULCBTX1VSTF9PUEVOQlJBQ0tFVCkub24oT1BFTkFOR0xFQlJBQ0tFVCwgU19VUkxfT1BFTkFOR0xFQlJBQ0tFVCkub24oT1BFTlBBUkVOLCBTX1VSTF9PUEVOUEFSRU4pOwoKCS8vIENsb3NpbmcgYnJhY2tldCBjb21wb25lbnQuIFRoaXMgY2hhcmFjdGVyIFdJTEwgYmUgaW5jbHVkZWQgaW4gdGhlIFVSTAoJU19VUkxfT1BFTkJSQUNFLm9uKENMT1NFQlJBQ0UsIFNfVVJMKTsKCVNfVVJMX09QRU5CUkFDS0VULm9uKENMT1NFQlJBQ0tFVCwgU19VUkwpOwoJU19VUkxfT1BFTkFOR0xFQlJBQ0tFVC5vbihDTE9TRUFOR0xFQlJBQ0tFVCwgU19VUkwpOwoJU19VUkxfT1BFTlBBUkVOLm9uKENMT1NFUEFSRU4sIFNfVVJMKTsKCVNfVVJMX09QRU5CUkFDRV9RLm9uKENMT1NFQlJBQ0UsIFNfVVJMKTsKCVNfVVJMX09QRU5CUkFDS0VUX1Eub24oQ0xPU0VCUkFDS0VULCBTX1VSTCk7CglTX1VSTF9PUEVOQU5HTEVCUkFDS0VUX1Eub24oQ0xPU0VBTkdMRUJSQUNLRVQsIFNfVVJMKTsKCVNfVVJMX09QRU5QQVJFTl9RLm9uKENMT1NFUEFSRU4sIFNfVVJMKTsKCVNfVVJMX09QRU5CUkFDRV9TWU1TLm9uKENMT1NFQlJBQ0UsIFNfVVJMKTsKCVNfVVJMX09QRU5CUkFDS0VUX1NZTVMub24oQ0xPU0VCUkFDS0VULCBTX1VSTCk7CglTX1VSTF9PUEVOQU5HTEVCUkFDS0VUX1NZTVMub24oQ0xPU0VBTkdMRUJSQUNLRVQsIFNfVVJMKTsKCVNfVVJMX09QRU5QQVJFTl9TWU1TLm9uKENMT1NFUEFSRU4sIFNfVVJMKTsKCgkvLyBVUkwgdGhhdCBiZWluZ3Mgd2l0aCBhbiBvcGVuaW5nIGJyYWNrZXQsIGZvbGxvd2VkIGJ5IGEgc3ltYm9scy4KCS8vIE5vdGUgdGhhdCB0aGUgZmluYWwgc3RhdGUgY2FuIHN0aWxsIGJlIGBTX1VSTF9PUEVOQlJBQ0VfUWAgKGlmIHRoZSBVUkwgb25seQoJLy8gaGFzIGEgc2luZ2xlIG9wZW5pbmcgYnJhY2tldCBmb3Igc29tZSByZWFzb24pLgoJU19VUkxfT1BFTkJSQUNFLm9uKHFzQWNjZXB0aW5nLCBTX1VSTF9PUEVOQlJBQ0VfUSk7CglTX1VSTF9PUEVOQlJBQ0tFVC5vbihxc0FjY2VwdGluZywgU19VUkxfT1BFTkJSQUNLRVRfUSk7CglTX1VSTF9PUEVOQU5HTEVCUkFDS0VULm9uKHFzQWNjZXB0aW5nLCBTX1VSTF9PUEVOQU5HTEVCUkFDS0VUX1EpOwoJU19VUkxfT1BFTlBBUkVOLm9uKHFzQWNjZXB0aW5nLCBTX1VSTF9PUEVOUEFSRU5fUSk7CglTX1VSTF9PUEVOQlJBQ0Uub24ocXNOb25BY2NlcHRpbmcsIFNfVVJMX09QRU5CUkFDRV9TWU1TKTsKCVNfVVJMX09QRU5CUkFDS0VULm9uKHFzTm9uQWNjZXB0aW5nLCBTX1VSTF9PUEVOQlJBQ0tFVF9TWU1TKTsKCVNfVVJMX09QRU5BTkdMRUJSQUNLRVQub24ocXNOb25BY2NlcHRpbmcsIFNfVVJMX09QRU5BTkdMRUJSQUNLRVRfU1lNUyk7CglTX1VSTF9PUEVOUEFSRU4ub24ocXNOb25BY2NlcHRpbmcsIFNfVVJMX09QRU5QQVJFTl9TWU1TKTsKCgkvLyBVUkwgdGhhdCBiZWdpbnMgd2l0aCBhbiBvcGVuaW5nIGJyYWNrZXQsIGZvbGxvd2VkIGJ5IHNvbWUgc3ltYm9scwoJU19VUkxfT1BFTkJSQUNFX1Eub24ocXNBY2NlcHRpbmcsIFNfVVJMX09QRU5CUkFDRV9RKTsKCVNfVVJMX09QRU5CUkFDS0VUX1Eub24ocXNBY2NlcHRpbmcsIFNfVVJMX09QRU5CUkFDS0VUX1EpOwoJU19VUkxfT1BFTkFOR0xFQlJBQ0tFVF9RLm9uKHFzQWNjZXB0aW5nLCBTX1VSTF9PUEVOQU5HTEVCUkFDS0VUX1EpOwoJU19VUkxfT1BFTlBBUkVOX1Eub24ocXNBY2NlcHRpbmcsIFNfVVJMX09QRU5QQVJFTl9RKTsKCVNfVVJMX09QRU5CUkFDRV9RLm9uKHFzTm9uQWNjZXB0aW5nLCBTX1VSTF9PUEVOQlJBQ0VfUSk7CglTX1VSTF9PUEVOQlJBQ0tFVF9RLm9uKHFzTm9uQWNjZXB0aW5nLCBTX1VSTF9PUEVOQlJBQ0tFVF9RKTsKCVNfVVJMX09QRU5BTkdMRUJSQUNLRVRfUS5vbihxc05vbkFjY2VwdGluZywgU19VUkxfT1BFTkFOR0xFQlJBQ0tFVF9RKTsKCVNfVVJMX09QRU5QQVJFTl9RLm9uKHFzTm9uQWNjZXB0aW5nLCBTX1VSTF9PUEVOUEFSRU5fUSk7CgoJU19VUkxfT1BFTkJSQUNFX1NZTVMub24ocXNBY2NlcHRpbmcsIFNfVVJMX09QRU5CUkFDRV9RKTsKCVNfVVJMX09QRU5CUkFDS0VUX1NZTVMub24ocXNBY2NlcHRpbmcsIFNfVVJMX09QRU5CUkFDS0VUX1EpOwoJU19VUkxfT1BFTkFOR0xFQlJBQ0tFVF9TWU1TLm9uKHFzQWNjZXB0aW5nLCBTX1VSTF9PUEVOQU5HTEVCUkFDS0VUX1EpOwoJU19VUkxfT1BFTlBBUkVOX1NZTVMub24ocXNBY2NlcHRpbmcsIFNfVVJMX09QRU5QQVJFTl9RKTsKCVNfVVJMX09QRU5CUkFDRV9TWU1TLm9uKHFzTm9uQWNjZXB0aW5nLCBTX1VSTF9PUEVOQlJBQ0VfU1lNUyk7CglTX1VSTF9PUEVOQlJBQ0tFVF9TWU1TLm9uKHFzTm9uQWNjZXB0aW5nLCBTX1VSTF9PUEVOQlJBQ0tFVF9TWU1TKTsKCVNfVVJMX09QRU5BTkdMRUJSQUNLRVRfU1lNUy5vbihxc05vbkFjY2VwdGluZywgU19VUkxfT1BFTkFOR0xFQlJBQ0tFVF9TWU1TKTsKCVNfVVJMX09QRU5QQVJFTl9TWU1TLm9uKHFzTm9uQWNjZXB0aW5nLCBTX1VSTF9PUEVOUEFSRU5fU1lNUyk7CgoJLy8gQWNjb3VudCBmb3IgdGhlIHF1ZXJ5IHN0cmluZwoJU19VUkwub24ocXNBY2NlcHRpbmcsIFNfVVJMKTsKCVNfVVJMX05PTl9BQ0NFUFRJTkcub24ocXNBY2NlcHRpbmcsIFNfVVJMKTsKCglTX1VSTC5vbihxc05vbkFjY2VwdGluZywgU19VUkxfTk9OX0FDQ0VQVElORyk7CglTX1VSTF9OT05fQUNDRVBUSU5HLm9uKHFzTm9uQWNjZXB0aW5nLCBTX1VSTF9OT05fQUNDRVBUSU5HKTsKCgkvLyBFbWFpbCBhZGRyZXNzLXNwZWNpZmljIHN0YXRlIGRlZmluaXRpb25zCgkvLyBOb3RlOiBXZSBhcmUgbm90IGFsbG93aW5nICcvJyBpbiBlbWFpbCBhZGRyZXNzZXMgc2luY2UgdGhpcyB3b3VsZCBpbnRlcmZlcmUKCS8vIHdpdGggcmVhbCBVUkxzCgoJLy8gVG9rZW5zIGFsbG93ZWQgaW4gdGhlIGxvY2FscGFydCBvZiB0aGUgZW1haWwKCXZhciBsb2NhbHBhcnRBY2NlcHRpbmcgPSBbRE9NQUlOLCBOVU0sIFBMVVMsIFBPVU5ELCBRVUVSWSwgVU5ERVJTQ09SRSwgU1lNLCBUTERdOwoKCS8vIFNvbWUgb2YgdGhlIHRva2VucyBpbiBgbG9jYWxwYXJ0QWNjZXB0aW5nYCBhcmUgYWxyZWFkeSBhY2NvdW50ZWQgZm9yIGhlcmUgYW5kCgkvLyB3aWxsIG5vdCBiZSBvdmVyd3JpdHRlbiAoZG9uJ3Qgd29ycnkpCglTX0RPTUFJTiQxLm9uKGxvY2FscGFydEFjY2VwdGluZywgU19MT0NBTFBBUlQpLm9uKEFULCBTX0xPQ0FMUEFSVF9BVCk7CglTX1RMRC5vbihsb2NhbHBhcnRBY2NlcHRpbmcsIFNfTE9DQUxQQVJUKS5vbihBVCwgU19MT0NBTFBBUlRfQVQpOwoJU19ET01BSU5fRE9ULm9uKGxvY2FscGFydEFjY2VwdGluZywgU19MT0NBTFBBUlQpOwoKCS8vIE9rYXkgd2UncmUgb24gYSBsb2NhbHBhcnQuIE5vdyB3aGF0PwoJLy8gVE9ETzogSVAgYWRkcmVzc2VzIGFuZCB3aGF0IGlmIHRoZSBlbWFpbCBzdGFydHMgd2l0aCBudW1iZXJzPwoJU19MT0NBTFBBUlQub24obG9jYWxwYXJ0QWNjZXB0aW5nLCBTX0xPQ0FMUEFSVCkub24oQVQsIFNfTE9DQUxQQVJUX0FUKSAvLyBjbG9zZSB0byBhbiBlbWFpbCBhZGRyZXNzIG5vdwoJLm9uKERPVCwgU19MT0NBTFBBUlRfRE9UKTsKCVNfTE9DQUxQQVJUX0RPVC5vbihsb2NhbHBhcnRBY2NlcHRpbmcsIFNfTE9DQUxQQVJUKTsKCVNfTE9DQUxQQVJUX0FULm9uKFRMRCwgU19FTUFJTF9ET01BSU4pLm9uKERPTUFJTiwgU19FTUFJTF9ET01BSU4pLm9uKExPQ0FMSE9TVCwgU19FTUFJTCk7CgkvLyBTdGF0ZXMgZm9sbG93aW5nIGBAYCBkZWZpbmVkIGFib3ZlCgoJdmFyIHJ1biQxID0gZnVuY3Rpb24gcnVuJDEodG9rZW5zKSB7CgkJdmFyIGxlbiA9IHRva2Vucy5sZW5ndGg7CgkJdmFyIGN1cnNvciA9IDA7CgkJdmFyIG11bHRpcyA9IFtdOwoJCXZhciB0ZXh0VG9rZW5zID0gW107CgoJCXdoaWxlIChjdXJzb3IgPCBsZW4pIHsKCQkJdmFyIHN0YXRlID0gU19TVEFSVCQxOwoJCQl2YXIgc2Vjb25kU3RhdGUgPSBudWxsOwoJCQl2YXIgbmV4dFN0YXRlID0gbnVsbDsKCQkJdmFyIG11bHRpTGVuZ3RoID0gMDsKCQkJdmFyIGxhdGVzdEFjY2VwdGluZyA9IG51bGw7CgkJCXZhciBzaW5jZUFjY2VwdHMgPSAtMTsKCgkJCXdoaWxlIChjdXJzb3IgPCBsZW4gJiYgIShzZWNvbmRTdGF0ZSA9IHN0YXRlLm5leHQodG9rZW5zW2N1cnNvcl0pKSkgewoJCQkJLy8gU3RhcnRpbmcgdG9rZW5zIHdpdGggbm93aGVyZSB0byBqdW1wIHRvLgoJCQkJLy8gQ29uc2lkZXIgdGhlc2UgdG8gYmUganVzdCBwbGFpbiB0ZXh0CgkJCQl0ZXh0VG9rZW5zLnB1c2godG9rZW5zW2N1cnNvcisrXSk7CgkJCX0KCgkJCXdoaWxlIChjdXJzb3IgPCBsZW4gJiYgKG5leHRTdGF0ZSA9IHNlY29uZFN0YXRlIHx8IHN0YXRlLm5leHQodG9rZW5zW2N1cnNvcl0pKSkgewoKCQkJCS8vIEdldCB0aGUgbmV4dCBzdGF0ZQoJCQkJc2Vjb25kU3RhdGUgPSBudWxsOwoJCQkJc3RhdGUgPSBuZXh0U3RhdGU7CgoJCQkJLy8gS2VlcCB0cmFjayBvZiB0aGUgbGF0ZXN0IGFjY2VwdGluZyBzdGF0ZQoJCQkJaWYgKHN0YXRlLmFjY2VwdHMoKSkgewoJCQkJCXNpbmNlQWNjZXB0cyA9IDA7CgkJCQkJbGF0ZXN0QWNjZXB0aW5nID0gc3RhdGU7CgkJCQl9IGVsc2UgaWYgKHNpbmNlQWNjZXB0cyA+PSAwKSB7CgkJCQkJc2luY2VBY2NlcHRzKys7CgkJCQl9CgoJCQkJY3Vyc29yKys7CgkJCQltdWx0aUxlbmd0aCsrOwoJCQl9CgoJCQlpZiAoc2luY2VBY2NlcHRzIDwgMCkgewoKCQkJCS8vIE5vIGFjY2VwdGluZyBzdGF0ZSB3YXMgZm91bmQsIHBhcnQgb2YgYSByZWd1bGFyIHRleHQgdG9rZW4KCQkJCS8vIEFkZCBhbGwgdGhlIHRva2VucyB3ZSBsb29rZWQgYXQgdG8gdGhlIHRleHQgdG9rZW5zIGFycmF5CgkJCQlmb3IgKHZhciBfaTMgPSBjdXJzb3IgLSBtdWx0aUxlbmd0aDsgX2kzIDwgY3Vyc29yOyBfaTMrKykgewoJCQkJCXRleHRUb2tlbnMucHVzaCh0b2tlbnNbX2kzXSk7CgkJCQl9CgkJCX0gZWxzZSB7CgoJCQkJLy8gQWNjZXB0aW5nIHN0YXRlIQoKCQkJCS8vIEZpcnN0IGNsb3NlIG9mZiB0aGUgdGV4dFRva2VucyAoaWYgYXZhaWxhYmxlKQoJCQkJaWYgKHRleHRUb2tlbnMubGVuZ3RoID4gMCkgewoJCQkJCW11bHRpcy5wdXNoKG5ldyBURVhUKHRleHRUb2tlbnMpKTsKCQkJCQl0ZXh0VG9rZW5zID0gW107CgkJCQl9CgoJCQkJLy8gUm9sbCBiYWNrIHRvIHRoZSBsYXRlc3QgYWNjZXB0aW5nIHN0YXRlCgkJCQljdXJzb3IgLT0gc2luY2VBY2NlcHRzOwoJCQkJbXVsdGlMZW5ndGggLT0gc2luY2VBY2NlcHRzOwoKCQkJCS8vIENyZWF0ZSBhIG5ldyBtdWx0aXRva2VuCgkJCQl2YXIgTVVMVEkgPSBsYXRlc3RBY2NlcHRpbmcuZW1pdCgpOwoJCQkJbXVsdGlzLnB1c2gobmV3IE1VTFRJKHRva2Vucy5zbGljZShjdXJzb3IgLSBtdWx0aUxlbmd0aCwgY3Vyc29yKSkpOwoJCQl9CgkJfQoKCQkvLyBGaW5hbGx5IGNsb3NlIG9mZiB0aGUgdGV4dFRva2VucyAoaWYgYXZhaWxhYmxlKQoJCWlmICh0ZXh0VG9rZW5zLmxlbmd0aCA+IDApIHsKCQkJbXVsdGlzLnB1c2gobmV3IFRFWFQodGV4dFRva2VucykpOwoJCX0KCgkJcmV0dXJuIG11bHRpczsKCX07CgoJdmFyIHBhcnNlciA9IE9iamVjdC5mcmVlemUoewoJCVN0YXRlOiBTdGF0ZSwKCQlUT0tFTlM6IFRPS0VOUyQxLAoJCXJ1bjogcnVuJDEsCgkJc3RhcnQ6IFNfU1RBUlQkMQoJfSk7CgoJaWYgKCFBcnJheS5pc0FycmF5KSB7CgkJQXJyYXkuaXNBcnJheSA9IGZ1bmN0aW9uIChhcmcpIHsKCQkJcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhcmcpID09PSAnW29iamVjdCBBcnJheV0nOwoJCX07Cgl9CgoJLyoqCiAJQ29udmVydHMgYSBzdHJpbmcgaW50byB0b2tlbnMgdGhhdCByZXByZXNlbnQgbGlua2FibGUgYW5kIG5vbi1saW5rYWJsZSBiaXRzCiAJQG1ldGhvZCB0b2tlbml6ZQogCUBwYXJhbSB7U3RyaW5nfSBzdHIKIAlAcmV0dXJuIHtBcnJheX0gdG9rZW5zCiAqLwoJdmFyIHRva2VuaXplID0gZnVuY3Rpb24gdG9rZW5pemUoc3RyKSB7CgkJcmV0dXJuIHJ1biQxKHJ1bihzdHIpKTsKCX07CgoJLyoqCiAJUmV0dXJucyBhIGxpc3Qgb2YgbGlua2FibGUgaXRlbXMgaW4gdGhlIGdpdmVuIHN0cmluZy4KICovCgl2YXIgZmluZCA9IGZ1bmN0aW9uIGZpbmQoc3RyKSB7CgkJdmFyIHR5cGUgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDEgfHwgYXJndW1lbnRzWzFdID09PSB1bmRlZmluZWQgPyBudWxsIDogYXJndW1lbnRzWzFdOwoKCQl2YXIgdG9rZW5zID0gdG9rZW5pemUoc3RyKTsKCQl2YXIgZmlsdGVyZWQgPSBbXTsKCgkJZm9yICh2YXIgaSA9IDA7IGkgPCB0b2tlbnMubGVuZ3RoOyBpKyspIHsKCQkJdmFyIHRva2VuID0gdG9rZW5zW2ldOwoJCQlpZiAodG9rZW4uaXNMaW5rICYmICghdHlwZSB8fCB0b2tlbi50eXBlID09PSB0eXBlKSkgewoJCQkJZmlsdGVyZWQucHVzaCh0b2tlbi50b09iamVjdCgpKTsKCQkJfQoJCX0KCgkJcmV0dXJuIGZpbHRlcmVkOwoJfTsKCgkvKioKIAlJcyB0aGUgZ2l2ZW4gc3RyaW5nIHZhbGlkIGxpbmthYmxlIHRleHQgb2Ygc29tZSBzb3J0CiAJTm90ZSB0aGF0IHRoaXMgZG9lcyBub3QgdHJpbSB0aGUgdGV4dCBmb3IgeW91LgoKIAlPcHRpb25hbGx5IHBhc3MgaW4gYSBzZWNvbmQgYHR5cGVgIHBhcmFtLCB3aGljaCBpcyB0aGUgdHlwZSBvZiBsaW5rIHRvIHRlc3QKIAlmb3IuCgogCUZvciBleGFtcGxlLAoKIAkJdGVzdChzdHIsICdlbWFpbCcpOwoKIAlXaWxsIHJldHVybiBgdHJ1ZWAgaWYgc3RyIGlzIGEgdmFsaWQgZW1haWwuCiAqLwoJdmFyIHRlc3QgPSBmdW5jdGlvbiB0ZXN0KHN0cikgewoJCXZhciB0eXBlID0gYXJndW1lbnRzLmxlbmd0aCA8PSAxIHx8IGFyZ3VtZW50c1sxXSA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGFyZ3VtZW50c1sxXTsKCgkJdmFyIHRva2VucyA9IHRva2VuaXplKHN0cik7CgkJcmV0dXJuIHRva2Vucy5sZW5ndGggPT09IDEgJiYgdG9rZW5zWzBdLmlzTGluayAmJiAoIXR5cGUgfHwgdG9rZW5zWzBdLnR5cGUgPT09IHR5cGUpOwoJfTsKCglleHBvcnRzLmZpbmQgPSBmaW5kOwoJZXhwb3J0cy5pbmhlcml0cyA9IGluaGVyaXRzOwoJZXhwb3J0cy5vcHRpb25zID0gb3B0aW9uczsKCWV4cG9ydHMucGFyc2VyID0gcGFyc2VyOwoJZXhwb3J0cy5zY2FubmVyID0gc2Nhbm5lcjsKCWV4cG9ydHMudGVzdCA9IHRlc3Q7CglleHBvcnRzLnRva2VuaXplID0gdG9rZW5pemU7Cn0pKHdpbmRvdy5saW5raWZ5ID0gd2luZG93LmxpbmtpZnkgfHwge30pOwp9KSgpOwo=