Skip to content

Instantly share code, notes, and snippets.

@noamtm
Created January 19, 2015 10:36
Show Gist options
  • Save noamtm/a30f3f5cfe17ad03a510 to your computer and use it in GitHub Desktop.
Save noamtm/a30f3f5cfe17ad03a510 to your computer and use it in GitHub Desktop.
HTML/JS QR Generator. See inside.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!--
Usage: put text as the query string.
http://path/to/qr.html?text-to-encode
Based on https://github.com/davidshimjs/qrcodejs (and embeds it).
-->
<head>
<title>Cross-Browser QRCode generator for Javascript</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no" />
<script type="text/javascript" src="data:text/javascript;base64,LyoqCiAqIEBmaWxlb3ZlcnZpZXcKICogLSBVc2luZyB0aGUgJ1FSQ29kZSBmb3IgSmF2YXNjcmlwdCBsaWJyYXJ5JwogKiAtIEZpeGVkIGRhdGFzZXQgb2YgJ1FSQ29kZSBmb3IgSmF2YXNjcmlwdCBsaWJyYXJ5JyBmb3Igc3VwcG9ydCBmdWxsLXNwZWMuCiAqIC0gdGhpcyBsaWJyYXJ5IGhhcyBubyBkZXBlbmRlbmNpZXMuCiAqIAogKiBAYXV0aG9yIGRhdmlkc2hpbWpzCiAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy5kLXByb2plY3QuY29tLyIgdGFyZ2V0PSJfYmxhbmsiPmh0dHA6Ly93d3cuZC1wcm9qZWN0LmNvbS88L2E+CiAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2plcm9tZWV0aWVubmUuZ2l0aHViLmNvbS9qcXVlcnktcXJjb2RlLyIgdGFyZ2V0PSJfYmxhbmsiPmh0dHA6Ly9qZXJvbWVldGllbm5lLmdpdGh1Yi5jb20vanF1ZXJ5LXFyY29kZS88L2E+CiAqLwp2YXIgUVJDb2RlOwoKKGZ1bmN0aW9uICgpIHsKCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkvLyBRUkNvZGUgZm9yIEphdmFTY3JpcHQKCS8vCgkvLyBDb3B5cmlnaHQgKGMpIDIwMDkgS2F6dWhpa28gQXJhc2UKCS8vCgkvLyBVUkw6IGh0dHA6Ly93d3cuZC1wcm9qZWN0LmNvbS8KCS8vCgkvLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2U6CgkvLyAgIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwCgkvLwoJLy8gVGhlIHdvcmQgIlFSIENvZGUiIGlzIHJlZ2lzdGVyZWQgdHJhZGVtYXJrIG9mIAoJLy8gREVOU08gV0FWRSBJTkNPUlBPUkFURUQKCS8vICAgaHR0cDovL3d3dy5kZW5zby13YXZlLmNvbS9xcmNvZGUvZmFxcGF0ZW50LWUuaHRtbAoJLy8KCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCglmdW5jdGlvbiBRUjhiaXRCeXRlKGRhdGEpIHsKCQl0aGlzLm1vZGUgPSBRUk1vZGUuTU9ERV84QklUX0JZVEU7CgkJdGhpcy5kYXRhID0gZGF0YTsKCQl0aGlzLnBhcnNlZERhdGEgPSBbXTsKCgkJLy8gQWRkZWQgdG8gc3VwcG9ydCBVVEYtOCBDaGFyYWN0ZXJzCgkJZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLmRhdGEubGVuZ3RoOyBpIDwgbDsgaSsrKSB7CgkJCXZhciBieXRlQXJyYXkgPSBbXTsKCQkJdmFyIGNvZGUgPSB0aGlzLmRhdGEuY2hhckNvZGVBdChpKTsKCgkJCWlmIChjb2RlID4gMHgxMDAwMCkgewoJCQkJYnl0ZUFycmF5WzBdID0gMHhGMCB8ICgoY29kZSAmIDB4MUMwMDAwKSA+Pj4gMTgpOwoJCQkJYnl0ZUFycmF5WzFdID0gMHg4MCB8ICgoY29kZSAmIDB4M0YwMDApID4+PiAxMik7CgkJCQlieXRlQXJyYXlbMl0gPSAweDgwIHwgKChjb2RlICYgMHhGQzApID4+PiA2KTsKCQkJCWJ5dGVBcnJheVszXSA9IDB4ODAgfCAoY29kZSAmIDB4M0YpOwoJCQl9IGVsc2UgaWYgKGNvZGUgPiAweDgwMCkgewoJCQkJYnl0ZUFycmF5WzBdID0gMHhFMCB8ICgoY29kZSAmIDB4RjAwMCkgPj4+IDEyKTsKCQkJCWJ5dGVBcnJheVsxXSA9IDB4ODAgfCAoKGNvZGUgJiAweEZDMCkgPj4+IDYpOwoJCQkJYnl0ZUFycmF5WzJdID0gMHg4MCB8IChjb2RlICYgMHgzRik7CgkJCX0gZWxzZSBpZiAoY29kZSA+IDB4ODApIHsKCQkJCWJ5dGVBcnJheVswXSA9IDB4QzAgfCAoKGNvZGUgJiAweDdDMCkgPj4+IDYpOwoJCQkJYnl0ZUFycmF5WzFdID0gMHg4MCB8IChjb2RlICYgMHgzRik7CgkJCX0gZWxzZSB7CgkJCQlieXRlQXJyYXlbMF0gPSBjb2RlOwoJCQl9CgoJCQl0aGlzLnBhcnNlZERhdGEucHVzaChieXRlQXJyYXkpOwoJCX0KCgkJdGhpcy5wYXJzZWREYXRhID0gQXJyYXkucHJvdG90eXBlLmNvbmNhdC5hcHBseShbXSwgdGhpcy5wYXJzZWREYXRhKTsKCgkJaWYgKHRoaXMucGFyc2VkRGF0YS5sZW5ndGggIT0gdGhpcy5kYXRhLmxlbmd0aCkgewoJCQl0aGlzLnBhcnNlZERhdGEudW5zaGlmdCgxOTEpOwoJCQl0aGlzLnBhcnNlZERhdGEudW5zaGlmdCgxODcpOwoJCQl0aGlzLnBhcnNlZERhdGEudW5zaGlmdCgyMzkpOwoJCX0KCX0KCglRUjhiaXRCeXRlLnByb3RvdHlwZSA9IHsKCQlnZXRMZW5ndGg6IGZ1bmN0aW9uIChidWZmZXIpIHsKCQkJcmV0dXJuIHRoaXMucGFyc2VkRGF0YS5sZW5ndGg7CgkJfSwKCQl3cml0ZTogZnVuY3Rpb24gKGJ1ZmZlcikgewoJCQlmb3IgKHZhciBpID0gMCwgbCA9IHRoaXMucGFyc2VkRGF0YS5sZW5ndGg7IGkgPCBsOyBpKyspIHsKCQkJCWJ1ZmZlci5wdXQodGhpcy5wYXJzZWREYXRhW2ldLCA4KTsKCQkJfQoJCX0KCX07CgoJZnVuY3Rpb24gUVJDb2RlTW9kZWwodHlwZU51bWJlciwgZXJyb3JDb3JyZWN0TGV2ZWwpIHsKCQl0aGlzLnR5cGVOdW1iZXIgPSB0eXBlTnVtYmVyOwoJCXRoaXMuZXJyb3JDb3JyZWN0TGV2ZWwgPSBlcnJvckNvcnJlY3RMZXZlbDsKCQl0aGlzLm1vZHVsZXMgPSBudWxsOwoJCXRoaXMubW9kdWxlQ291bnQgPSAwOwoJCXRoaXMuZGF0YUNhY2hlID0gbnVsbDsKCQl0aGlzLmRhdGFMaXN0ID0gW107Cgl9CgoJUVJDb2RlTW9kZWwucHJvdG90eXBlPXthZGREYXRhOmZ1bmN0aW9uKGRhdGEpe3ZhciBuZXdEYXRhPW5ldyBRUjhiaXRCeXRlKGRhdGEpO3RoaXMuZGF0YUxpc3QucHVzaChuZXdEYXRhKTt0aGlzLmRhdGFDYWNoZT1udWxsO30saXNEYXJrOmZ1bmN0aW9uKHJvdyxjb2wpe2lmKHJvdzwwfHx0aGlzLm1vZHVsZUNvdW50PD1yb3d8fGNvbDwwfHx0aGlzLm1vZHVsZUNvdW50PD1jb2wpe3Rocm93IG5ldyBFcnJvcihyb3crIiwiK2NvbCk7fQoJcmV0dXJuIHRoaXMubW9kdWxlc1tyb3ddW2NvbF07fSxnZXRNb2R1bGVDb3VudDpmdW5jdGlvbigpe3JldHVybiB0aGlzLm1vZHVsZUNvdW50O30sbWFrZTpmdW5jdGlvbigpe3RoaXMubWFrZUltcGwoZmFsc2UsdGhpcy5nZXRCZXN0TWFza1BhdHRlcm4oKSk7fSxtYWtlSW1wbDpmdW5jdGlvbih0ZXN0LG1hc2tQYXR0ZXJuKXt0aGlzLm1vZHVsZUNvdW50PXRoaXMudHlwZU51bWJlcio0KzE3O3RoaXMubW9kdWxlcz1uZXcgQXJyYXkodGhpcy5tb2R1bGVDb3VudCk7Zm9yKHZhciByb3c9MDtyb3c8dGhpcy5tb2R1bGVDb3VudDtyb3crKyl7dGhpcy5tb2R1bGVzW3Jvd109bmV3IEFycmF5KHRoaXMubW9kdWxlQ291bnQpO2Zvcih2YXIgY29sPTA7Y29sPHRoaXMubW9kdWxlQ291bnQ7Y29sKyspe3RoaXMubW9kdWxlc1tyb3ddW2NvbF09bnVsbDt9fQoJdGhpcy5zZXR1cFBvc2l0aW9uUHJvYmVQYXR0ZXJuKDAsMCk7dGhpcy5zZXR1cFBvc2l0aW9uUHJvYmVQYXR0ZXJuKHRoaXMubW9kdWxlQ291bnQtNywwKTt0aGlzLnNldHVwUG9zaXRpb25Qcm9iZVBhdHRlcm4oMCx0aGlzLm1vZHVsZUNvdW50LTcpO3RoaXMuc2V0dXBQb3NpdGlvbkFkanVzdFBhdHRlcm4oKTt0aGlzLnNldHVwVGltaW5nUGF0dGVybigpO3RoaXMuc2V0dXBUeXBlSW5mbyh0ZXN0LG1hc2tQYXR0ZXJuKTtpZih0aGlzLnR5cGVOdW1iZXI+PTcpe3RoaXMuc2V0dXBUeXBlTnVtYmVyKHRlc3QpO30KCWlmKHRoaXMuZGF0YUNhY2hlPT1udWxsKXt0aGlzLmRhdGFDYWNoZT1RUkNvZGVNb2RlbC5jcmVhdGVEYXRhKHRoaXMudHlwZU51bWJlcix0aGlzLmVycm9yQ29ycmVjdExldmVsLHRoaXMuZGF0YUxpc3QpO30KCXRoaXMubWFwRGF0YSh0aGlzLmRhdGFDYWNoZSxtYXNrUGF0dGVybik7fSxzZXR1cFBvc2l0aW9uUHJvYmVQYXR0ZXJuOmZ1bmN0aW9uKHJvdyxjb2wpe2Zvcih2YXIgcj0tMTtyPD03O3IrKyl7aWYocm93K3I8PS0xfHx0aGlzLm1vZHVsZUNvdW50PD1yb3crciljb250aW51ZTtmb3IodmFyIGM9LTE7Yzw9NztjKyspe2lmKGNvbCtjPD0tMXx8dGhpcy5tb2R1bGVDb3VudDw9Y29sK2MpY29udGludWU7aWYoKDA8PXImJnI8PTYmJihjPT0wfHxjPT02KSl8fCgwPD1jJiZjPD02JiYocj09MHx8cj09NikpfHwoMjw9ciYmcjw9NCYmMjw9YyYmYzw9NCkpe3RoaXMubW9kdWxlc1tyb3crcl1bY29sK2NdPXRydWU7fWVsc2V7dGhpcy5tb2R1bGVzW3JvdytyXVtjb2wrY109ZmFsc2U7fX19fSxnZXRCZXN0TWFza1BhdHRlcm46ZnVuY3Rpb24oKXt2YXIgbWluTG9zdFBvaW50PTA7dmFyIHBhdHRlcm49MDtmb3IodmFyIGk9MDtpPDg7aSsrKXt0aGlzLm1ha2VJbXBsKHRydWUsaSk7dmFyIGxvc3RQb2ludD1RUlV0aWwuZ2V0TG9zdFBvaW50KHRoaXMpO2lmKGk9PTB8fG1pbkxvc3RQb2ludD5sb3N0UG9pbnQpe21pbkxvc3RQb2ludD1sb3N0UG9pbnQ7cGF0dGVybj1pO319CglyZXR1cm4gcGF0dGVybjt9LGNyZWF0ZU1vdmllQ2xpcDpmdW5jdGlvbih0YXJnZXRfbWMsaW5zdGFuY2VfbmFtZSxkZXB0aCl7dmFyIHFyX21jPXRhcmdldF9tYy5jcmVhdGVFbXB0eU1vdmllQ2xpcChpbnN0YW5jZV9uYW1lLGRlcHRoKTt2YXIgY3M9MTt0aGlzLm1ha2UoKTtmb3IodmFyIHJvdz0wO3Jvdzx0aGlzLm1vZHVsZXMubGVuZ3RoO3JvdysrKXt2YXIgeT1yb3cqY3M7Zm9yKHZhciBjb2w9MDtjb2w8dGhpcy5tb2R1bGVzW3Jvd10ubGVuZ3RoO2NvbCsrKXt2YXIgeD1jb2wqY3M7dmFyIGRhcms9dGhpcy5tb2R1bGVzW3Jvd11bY29sXTtpZihkYXJrKXtxcl9tYy5iZWdpbkZpbGwoMCwxMDApO3FyX21jLm1vdmVUbyh4LHkpO3FyX21jLmxpbmVUbyh4K2NzLHkpO3FyX21jLmxpbmVUbyh4K2NzLHkrY3MpO3FyX21jLmxpbmVUbyh4LHkrY3MpO3FyX21jLmVuZEZpbGwoKTt9fX0KCXJldHVybiBxcl9tYzt9LHNldHVwVGltaW5nUGF0dGVybjpmdW5jdGlvbigpe2Zvcih2YXIgcj04O3I8dGhpcy5tb2R1bGVDb3VudC04O3IrKyl7aWYodGhpcy5tb2R1bGVzW3JdWzZdIT1udWxsKXtjb250aW51ZTt9Cgl0aGlzLm1vZHVsZXNbcl1bNl09KHIlMj09MCk7fQoJZm9yKHZhciBjPTg7Yzx0aGlzLm1vZHVsZUNvdW50LTg7YysrKXtpZih0aGlzLm1vZHVsZXNbNl1bY10hPW51bGwpe2NvbnRpbnVlO30KCXRoaXMubW9kdWxlc1s2XVtjXT0oYyUyPT0wKTt9fSxzZXR1cFBvc2l0aW9uQWRqdXN0UGF0dGVybjpmdW5jdGlvbigpe3ZhciBwb3M9UVJVdGlsLmdldFBhdHRlcm5Qb3NpdGlvbih0aGlzLnR5cGVOdW1iZXIpO2Zvcih2YXIgaT0wO2k8cG9zLmxlbmd0aDtpKyspe2Zvcih2YXIgaj0wO2o8cG9zLmxlbmd0aDtqKyspe3ZhciByb3c9cG9zW2ldO3ZhciBjb2w9cG9zW2pdO2lmKHRoaXMubW9kdWxlc1tyb3ddW2NvbF0hPW51bGwpe2NvbnRpbnVlO30KCWZvcih2YXIgcj0tMjtyPD0yO3IrKyl7Zm9yKHZhciBjPS0yO2M8PTI7YysrKXtpZihyPT0tMnx8cj09Mnx8Yz09LTJ8fGM9PTJ8fChyPT0wJiZjPT0wKSl7dGhpcy5tb2R1bGVzW3JvdytyXVtjb2wrY109dHJ1ZTt9ZWxzZXt0aGlzLm1vZHVsZXNbcm93K3JdW2NvbCtjXT1mYWxzZTt9fX19fX0sc2V0dXBUeXBlTnVtYmVyOmZ1bmN0aW9uKHRlc3Qpe3ZhciBiaXRzPVFSVXRpbC5nZXRCQ0hUeXBlTnVtYmVyKHRoaXMudHlwZU51bWJlcik7Zm9yKHZhciBpPTA7aTwxODtpKyspe3ZhciBtb2Q9KCF0ZXN0JiYoKGJpdHM+PmkpJjEpPT0xKTt0aGlzLm1vZHVsZXNbTWF0aC5mbG9vcihpLzMpXVtpJTMrdGhpcy5tb2R1bGVDb3VudC04LTNdPW1vZDt9Cglmb3IodmFyIGk9MDtpPDE4O2krKyl7dmFyIG1vZD0oIXRlc3QmJigoYml0cz4+aSkmMSk9PTEpO3RoaXMubW9kdWxlc1tpJTMrdGhpcy5tb2R1bGVDb3VudC04LTNdW01hdGguZmxvb3IoaS8zKV09bW9kO319LHNldHVwVHlwZUluZm86ZnVuY3Rpb24odGVzdCxtYXNrUGF0dGVybil7dmFyIGRhdGE9KHRoaXMuZXJyb3JDb3JyZWN0TGV2ZWw8PDMpfG1hc2tQYXR0ZXJuO3ZhciBiaXRzPVFSVXRpbC5nZXRCQ0hUeXBlSW5mbyhkYXRhKTtmb3IodmFyIGk9MDtpPDE1O2krKyl7dmFyIG1vZD0oIXRlc3QmJigoYml0cz4+aSkmMSk9PTEpO2lmKGk8Nil7dGhpcy5tb2R1bGVzW2ldWzhdPW1vZDt9ZWxzZSBpZihpPDgpe3RoaXMubW9kdWxlc1tpKzFdWzhdPW1vZDt9ZWxzZXt0aGlzLm1vZHVsZXNbdGhpcy5tb2R1bGVDb3VudC0xNStpXVs4XT1tb2Q7fX0KCWZvcih2YXIgaT0wO2k8MTU7aSsrKXt2YXIgbW9kPSghdGVzdCYmKChiaXRzPj5pKSYxKT09MSk7aWYoaTw4KXt0aGlzLm1vZHVsZXNbOF1bdGhpcy5tb2R1bGVDb3VudC1pLTFdPW1vZDt9ZWxzZSBpZihpPDkpe3RoaXMubW9kdWxlc1s4XVsxNS1pLTErMV09bW9kO31lbHNle3RoaXMubW9kdWxlc1s4XVsxNS1pLTFdPW1vZDt9fQoJdGhpcy5tb2R1bGVzW3RoaXMubW9kdWxlQ291bnQtOF1bOF09KCF0ZXN0KTt9LG1hcERhdGE6ZnVuY3Rpb24oZGF0YSxtYXNrUGF0dGVybil7dmFyIGluYz0tMTt2YXIgcm93PXRoaXMubW9kdWxlQ291bnQtMTt2YXIgYml0SW5kZXg9Nzt2YXIgYnl0ZUluZGV4PTA7Zm9yKHZhciBjb2w9dGhpcy5tb2R1bGVDb3VudC0xO2NvbD4wO2NvbC09Mil7aWYoY29sPT02KWNvbC0tO3doaWxlKHRydWUpe2Zvcih2YXIgYz0wO2M8MjtjKyspe2lmKHRoaXMubW9kdWxlc1tyb3ddW2NvbC1jXT09bnVsbCl7dmFyIGRhcms9ZmFsc2U7aWYoYnl0ZUluZGV4PGRhdGEubGVuZ3RoKXtkYXJrPSgoKGRhdGFbYnl0ZUluZGV4XT4+PmJpdEluZGV4KSYxKT09MSk7fQoJdmFyIG1hc2s9UVJVdGlsLmdldE1hc2sobWFza1BhdHRlcm4scm93LGNvbC1jKTtpZihtYXNrKXtkYXJrPSFkYXJrO30KCXRoaXMubW9kdWxlc1tyb3ddW2NvbC1jXT1kYXJrO2JpdEluZGV4LS07aWYoYml0SW5kZXg9PS0xKXtieXRlSW5kZXgrKztiaXRJbmRleD03O319fQoJcm93Kz1pbmM7aWYocm93PDB8fHRoaXMubW9kdWxlQ291bnQ8PXJvdyl7cm93LT1pbmM7aW5jPS1pbmM7YnJlYWs7fX19fX07UVJDb2RlTW9kZWwuUEFEMD0weEVDO1FSQ29kZU1vZGVsLlBBRDE9MHgxMTtRUkNvZGVNb2RlbC5jcmVhdGVEYXRhPWZ1bmN0aW9uKHR5cGVOdW1iZXIsZXJyb3JDb3JyZWN0TGV2ZWwsZGF0YUxpc3Qpe3ZhciByc0Jsb2Nrcz1RUlJTQmxvY2suZ2V0UlNCbG9ja3ModHlwZU51bWJlcixlcnJvckNvcnJlY3RMZXZlbCk7dmFyIGJ1ZmZlcj1uZXcgUVJCaXRCdWZmZXIoKTtmb3IodmFyIGk9MDtpPGRhdGFMaXN0Lmxlbmd0aDtpKyspe3ZhciBkYXRhPWRhdGFMaXN0W2ldO2J1ZmZlci5wdXQoZGF0YS5tb2RlLDQpO2J1ZmZlci5wdXQoZGF0YS5nZXRMZW5ndGgoKSxRUlV0aWwuZ2V0TGVuZ3RoSW5CaXRzKGRhdGEubW9kZSx0eXBlTnVtYmVyKSk7ZGF0YS53cml0ZShidWZmZXIpO30KCXZhciB0b3RhbERhdGFDb3VudD0wO2Zvcih2YXIgaT0wO2k8cnNCbG9ja3MubGVuZ3RoO2krKyl7dG90YWxEYXRhQ291bnQrPXJzQmxvY2tzW2ldLmRhdGFDb3VudDt9CglpZihidWZmZXIuZ2V0TGVuZ3RoSW5CaXRzKCk+dG90YWxEYXRhQ291bnQqOCl7dGhyb3cgbmV3IEVycm9yKCJjb2RlIGxlbmd0aCBvdmVyZmxvdy4gKCIKCStidWZmZXIuZ2V0TGVuZ3RoSW5CaXRzKCkKCSsiPiIKCSt0b3RhbERhdGFDb3VudCo4CgkrIikiKTt9CglpZihidWZmZXIuZ2V0TGVuZ3RoSW5CaXRzKCkrNDw9dG90YWxEYXRhQ291bnQqOCl7YnVmZmVyLnB1dCgwLDQpO30KCXdoaWxlKGJ1ZmZlci5nZXRMZW5ndGhJbkJpdHMoKSU4IT0wKXtidWZmZXIucHV0Qml0KGZhbHNlKTt9Cgl3aGlsZSh0cnVlKXtpZihidWZmZXIuZ2V0TGVuZ3RoSW5CaXRzKCk+PXRvdGFsRGF0YUNvdW50Kjgpe2JyZWFrO30KCWJ1ZmZlci5wdXQoUVJDb2RlTW9kZWwuUEFEMCw4KTtpZihidWZmZXIuZ2V0TGVuZ3RoSW5CaXRzKCk+PXRvdGFsRGF0YUNvdW50Kjgpe2JyZWFrO30KCWJ1ZmZlci5wdXQoUVJDb2RlTW9kZWwuUEFEMSw4KTt9CglyZXR1cm4gUVJDb2RlTW9kZWwuY3JlYXRlQnl0ZXMoYnVmZmVyLHJzQmxvY2tzKTt9O1FSQ29kZU1vZGVsLmNyZWF0ZUJ5dGVzPWZ1bmN0aW9uKGJ1ZmZlcixyc0Jsb2Nrcyl7dmFyIG9mZnNldD0wO3ZhciBtYXhEY0NvdW50PTA7dmFyIG1heEVjQ291bnQ9MDt2YXIgZGNkYXRhPW5ldyBBcnJheShyc0Jsb2Nrcy5sZW5ndGgpO3ZhciBlY2RhdGE9bmV3IEFycmF5KHJzQmxvY2tzLmxlbmd0aCk7Zm9yKHZhciByPTA7cjxyc0Jsb2Nrcy5sZW5ndGg7cisrKXt2YXIgZGNDb3VudD1yc0Jsb2Nrc1tyXS5kYXRhQ291bnQ7dmFyIGVjQ291bnQ9cnNCbG9ja3Nbcl0udG90YWxDb3VudC1kY0NvdW50O21heERjQ291bnQ9TWF0aC5tYXgobWF4RGNDb3VudCxkY0NvdW50KTttYXhFY0NvdW50PU1hdGgubWF4KG1heEVjQ291bnQsZWNDb3VudCk7ZGNkYXRhW3JdPW5ldyBBcnJheShkY0NvdW50KTtmb3IodmFyIGk9MDtpPGRjZGF0YVtyXS5sZW5ndGg7aSsrKXtkY2RhdGFbcl1baV09MHhmZiZidWZmZXIuYnVmZmVyW2krb2Zmc2V0XTt9CglvZmZzZXQrPWRjQ291bnQ7dmFyIHJzUG9seT1RUlV0aWwuZ2V0RXJyb3JDb3JyZWN0UG9seW5vbWlhbChlY0NvdW50KTt2YXIgcmF3UG9seT1uZXcgUVJQb2x5bm9taWFsKGRjZGF0YVtyXSxyc1BvbHkuZ2V0TGVuZ3RoKCktMSk7dmFyIG1vZFBvbHk9cmF3UG9seS5tb2QocnNQb2x5KTtlY2RhdGFbcl09bmV3IEFycmF5KHJzUG9seS5nZXRMZW5ndGgoKS0xKTtmb3IodmFyIGk9MDtpPGVjZGF0YVtyXS5sZW5ndGg7aSsrKXt2YXIgbW9kSW5kZXg9aSttb2RQb2x5LmdldExlbmd0aCgpLWVjZGF0YVtyXS5sZW5ndGg7ZWNkYXRhW3JdW2ldPShtb2RJbmRleD49MCk/bW9kUG9seS5nZXQobW9kSW5kZXgpOjA7fX0KCXZhciB0b3RhbENvZGVDb3VudD0wO2Zvcih2YXIgaT0wO2k8cnNCbG9ja3MubGVuZ3RoO2krKyl7dG90YWxDb2RlQ291bnQrPXJzQmxvY2tzW2ldLnRvdGFsQ291bnQ7fQoJdmFyIGRhdGE9bmV3IEFycmF5KHRvdGFsQ29kZUNvdW50KTt2YXIgaW5kZXg9MDtmb3IodmFyIGk9MDtpPG1heERjQ291bnQ7aSsrKXtmb3IodmFyIHI9MDtyPHJzQmxvY2tzLmxlbmd0aDtyKyspe2lmKGk8ZGNkYXRhW3JdLmxlbmd0aCl7ZGF0YVtpbmRleCsrXT1kY2RhdGFbcl1baV07fX19Cglmb3IodmFyIGk9MDtpPG1heEVjQ291bnQ7aSsrKXtmb3IodmFyIHI9MDtyPHJzQmxvY2tzLmxlbmd0aDtyKyspe2lmKGk8ZWNkYXRhW3JdLmxlbmd0aCl7ZGF0YVtpbmRleCsrXT1lY2RhdGFbcl1baV07fX19CglyZXR1cm4gZGF0YTt9O3ZhciBRUk1vZGU9e01PREVfTlVNQkVSOjE8PDAsTU9ERV9BTFBIQV9OVU06MTw8MSxNT0RFXzhCSVRfQllURToxPDwyLE1PREVfS0FOSkk6MTw8M307dmFyIFFSRXJyb3JDb3JyZWN0TGV2ZWw9e0w6MSxNOjAsUTozLEg6Mn07dmFyIFFSTWFza1BhdHRlcm49e1BBVFRFUk4wMDA6MCxQQVRURVJOMDAxOjEsUEFUVEVSTjAxMDoyLFBBVFRFUk4wMTE6MyxQQVRURVJOMTAwOjQsUEFUVEVSTjEwMTo1LFBBVFRFUk4xMTA6NixQQVRURVJOMTExOjd9O3ZhciBRUlV0aWw9e1BBVFRFUk5fUE9TSVRJT05fVEFCTEU6W1tdLFs2LDE4XSxbNiwyMl0sWzYsMjZdLFs2LDMwXSxbNiwzNF0sWzYsMjIsMzhdLFs2LDI0LDQyXSxbNiwyNiw0Nl0sWzYsMjgsNTBdLFs2LDMwLDU0XSxbNiwzMiw1OF0sWzYsMzQsNjJdLFs2LDI2LDQ2LDY2XSxbNiwyNiw0OCw3MF0sWzYsMjYsNTAsNzRdLFs2LDMwLDU0LDc4XSxbNiwzMCw1Niw4Ml0sWzYsMzAsNTgsODZdLFs2LDM0LDYyLDkwXSxbNiwyOCw1MCw3Miw5NF0sWzYsMjYsNTAsNzQsOThdLFs2LDMwLDU0LDc4LDEwMl0sWzYsMjgsNTQsODAsMTA2XSxbNiwzMiw1OCw4NCwxMTBdLFs2LDMwLDU4LDg2LDExNF0sWzYsMzQsNjIsOTAsMTE4XSxbNiwyNiw1MCw3NCw5OCwxMjJdLFs2LDMwLDU0LDc4LDEwMiwxMjZdLFs2LDI2LDUyLDc4LDEwNCwxMzBdLFs2LDMwLDU2LDgyLDEwOCwxMzRdLFs2LDM0LDYwLDg2LDExMiwxMzhdLFs2LDMwLDU4LDg2LDExNCwxNDJdLFs2LDM0LDYyLDkwLDExOCwxNDZdLFs2LDMwLDU0LDc4LDEwMiwxMjYsMTUwXSxbNiwyNCw1MCw3NiwxMDIsMTI4LDE1NF0sWzYsMjgsNTQsODAsMTA2LDEzMiwxNThdLFs2LDMyLDU4LDg0LDExMCwxMzYsMTYyXSxbNiwyNiw1NCw4MiwxMTAsMTM4LDE2Nl0sWzYsMzAsNTgsODYsMTE0LDE0MiwxNzBdXSxHMTU6KDE8PDEwKXwoMTw8OCl8KDE8PDUpfCgxPDw0KXwoMTw8Mil8KDE8PDEpfCgxPDwwKSxHMTg6KDE8PDEyKXwoMTw8MTEpfCgxPDwxMCl8KDE8PDkpfCgxPDw4KXwoMTw8NSl8KDE8PDIpfCgxPDwwKSxHMTVfTUFTSzooMTw8MTQpfCgxPDwxMil8KDE8PDEwKXwoMTw8NCl8KDE8PDEpLGdldEJDSFR5cGVJbmZvOmZ1bmN0aW9uKGRhdGEpe3ZhciBkPWRhdGE8PDEwO3doaWxlKFFSVXRpbC5nZXRCQ0hEaWdpdChkKS1RUlV0aWwuZ2V0QkNIRGlnaXQoUVJVdGlsLkcxNSk+PTApe2RePShRUlV0aWwuRzE1PDwoUVJVdGlsLmdldEJDSERpZ2l0KGQpLVFSVXRpbC5nZXRCQ0hEaWdpdChRUlV0aWwuRzE1KSkpO30KCXJldHVybigoZGF0YTw8MTApfGQpXlFSVXRpbC5HMTVfTUFTSzt9LGdldEJDSFR5cGVOdW1iZXI6ZnVuY3Rpb24oZGF0YSl7dmFyIGQ9ZGF0YTw8MTI7d2hpbGUoUVJVdGlsLmdldEJDSERpZ2l0KGQpLVFSVXRpbC5nZXRCQ0hEaWdpdChRUlV0aWwuRzE4KT49MCl7ZF49KFFSVXRpbC5HMTg8PChRUlV0aWwuZ2V0QkNIRGlnaXQoZCktUVJVdGlsLmdldEJDSERpZ2l0KFFSVXRpbC5HMTgpKSk7fQoJcmV0dXJuKGRhdGE8PDEyKXxkO30sZ2V0QkNIRGlnaXQ6ZnVuY3Rpb24oZGF0YSl7dmFyIGRpZ2l0PTA7d2hpbGUoZGF0YSE9MCl7ZGlnaXQrKztkYXRhPj4+PTE7fQoJcmV0dXJuIGRpZ2l0O30sZ2V0UGF0dGVyblBvc2l0aW9uOmZ1bmN0aW9uKHR5cGVOdW1iZXIpe3JldHVybiBRUlV0aWwuUEFUVEVSTl9QT1NJVElPTl9UQUJMRVt0eXBlTnVtYmVyLTFdO30sZ2V0TWFzazpmdW5jdGlvbihtYXNrUGF0dGVybixpLGope3N3aXRjaChtYXNrUGF0dGVybil7Y2FzZSBRUk1hc2tQYXR0ZXJuLlBBVFRFUk4wMDA6cmV0dXJuKGkraiklMj09MDtjYXNlIFFSTWFza1BhdHRlcm4uUEFUVEVSTjAwMTpyZXR1cm4gaSUyPT0wO2Nhc2UgUVJNYXNrUGF0dGVybi5QQVRURVJOMDEwOnJldHVybiBqJTM9PTA7Y2FzZSBRUk1hc2tQYXR0ZXJuLlBBVFRFUk4wMTE6cmV0dXJuKGkraiklMz09MDtjYXNlIFFSTWFza1BhdHRlcm4uUEFUVEVSTjEwMDpyZXR1cm4oTWF0aC5mbG9vcihpLzIpK01hdGguZmxvb3Ioai8zKSklMj09MDtjYXNlIFFSTWFza1BhdHRlcm4uUEFUVEVSTjEwMTpyZXR1cm4oaSpqKSUyKyhpKmopJTM9PTA7Y2FzZSBRUk1hc2tQYXR0ZXJuLlBBVFRFUk4xMTA6cmV0dXJuKChpKmopJTIrKGkqaiklMyklMj09MDtjYXNlIFFSTWFza1BhdHRlcm4uUEFUVEVSTjExMTpyZXR1cm4oKGkqaiklMysoaStqKSUyKSUyPT0wO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJiYWQgbWFza1BhdHRlcm46IittYXNrUGF0dGVybik7fX0sZ2V0RXJyb3JDb3JyZWN0UG9seW5vbWlhbDpmdW5jdGlvbihlcnJvckNvcnJlY3RMZW5ndGgpe3ZhciBhPW5ldyBRUlBvbHlub21pYWwoWzFdLDApO2Zvcih2YXIgaT0wO2k8ZXJyb3JDb3JyZWN0TGVuZ3RoO2krKyl7YT1hLm11bHRpcGx5KG5ldyBRUlBvbHlub21pYWwoWzEsUVJNYXRoLmdleHAoaSldLDApKTt9CglyZXR1cm4gYTt9LGdldExlbmd0aEluQml0czpmdW5jdGlvbihtb2RlLHR5cGUpe2lmKDE8PXR5cGUmJnR5cGU8MTApe3N3aXRjaChtb2RlKXtjYXNlIFFSTW9kZS5NT0RFX05VTUJFUjpyZXR1cm4gMTA7Y2FzZSBRUk1vZGUuTU9ERV9BTFBIQV9OVU06cmV0dXJuIDk7Y2FzZSBRUk1vZGUuTU9ERV84QklUX0JZVEU6cmV0dXJuIDg7Y2FzZSBRUk1vZGUuTU9ERV9LQU5KSTpyZXR1cm4gODtkZWZhdWx0OnRocm93IG5ldyBFcnJvcigibW9kZToiK21vZGUpO319ZWxzZSBpZih0eXBlPDI3KXtzd2l0Y2gobW9kZSl7Y2FzZSBRUk1vZGUuTU9ERV9OVU1CRVI6cmV0dXJuIDEyO2Nhc2UgUVJNb2RlLk1PREVfQUxQSEFfTlVNOnJldHVybiAxMTtjYXNlIFFSTW9kZS5NT0RFXzhCSVRfQllURTpyZXR1cm4gMTY7Y2FzZSBRUk1vZGUuTU9ERV9LQU5KSTpyZXR1cm4gMTA7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoIm1vZGU6Iittb2RlKTt9fWVsc2UgaWYodHlwZTw0MSl7c3dpdGNoKG1vZGUpe2Nhc2UgUVJNb2RlLk1PREVfTlVNQkVSOnJldHVybiAxNDtjYXNlIFFSTW9kZS5NT0RFX0FMUEhBX05VTTpyZXR1cm4gMTM7Y2FzZSBRUk1vZGUuTU9ERV84QklUX0JZVEU6cmV0dXJuIDE2O2Nhc2UgUVJNb2RlLk1PREVfS0FOSkk6cmV0dXJuIDEyO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJtb2RlOiIrbW9kZSk7fX1lbHNle3Rocm93IG5ldyBFcnJvcigidHlwZToiK3R5cGUpO319LGdldExvc3RQb2ludDpmdW5jdGlvbihxckNvZGUpe3ZhciBtb2R1bGVDb3VudD1xckNvZGUuZ2V0TW9kdWxlQ291bnQoKTt2YXIgbG9zdFBvaW50PTA7Zm9yKHZhciByb3c9MDtyb3c8bW9kdWxlQ291bnQ7cm93Kyspe2Zvcih2YXIgY29sPTA7Y29sPG1vZHVsZUNvdW50O2NvbCsrKXt2YXIgc2FtZUNvdW50PTA7dmFyIGRhcms9cXJDb2RlLmlzRGFyayhyb3csY29sKTtmb3IodmFyIHI9LTE7cjw9MTtyKyspe2lmKHJvdytyPDB8fG1vZHVsZUNvdW50PD1yb3crcil7Y29udGludWU7fQoJZm9yKHZhciBjPS0xO2M8PTE7YysrKXtpZihjb2wrYzwwfHxtb2R1bGVDb3VudDw9Y29sK2Mpe2NvbnRpbnVlO30KCWlmKHI9PTAmJmM9PTApe2NvbnRpbnVlO30KCWlmKGRhcms9PXFyQ29kZS5pc0Rhcmsocm93K3IsY29sK2MpKXtzYW1lQ291bnQrKzt9fX0KCWlmKHNhbWVDb3VudD41KXtsb3N0UG9pbnQrPSgzK3NhbWVDb3VudC01KTt9fX0KCWZvcih2YXIgcm93PTA7cm93PG1vZHVsZUNvdW50LTE7cm93Kyspe2Zvcih2YXIgY29sPTA7Y29sPG1vZHVsZUNvdW50LTE7Y29sKyspe3ZhciBjb3VudD0wO2lmKHFyQ29kZS5pc0Rhcmsocm93LGNvbCkpY291bnQrKztpZihxckNvZGUuaXNEYXJrKHJvdysxLGNvbCkpY291bnQrKztpZihxckNvZGUuaXNEYXJrKHJvdyxjb2wrMSkpY291bnQrKztpZihxckNvZGUuaXNEYXJrKHJvdysxLGNvbCsxKSljb3VudCsrO2lmKGNvdW50PT0wfHxjb3VudD09NCl7bG9zdFBvaW50Kz0zO319fQoJZm9yKHZhciByb3c9MDtyb3c8bW9kdWxlQ291bnQ7cm93Kyspe2Zvcih2YXIgY29sPTA7Y29sPG1vZHVsZUNvdW50LTY7Y29sKyspe2lmKHFyQ29kZS5pc0Rhcmsocm93LGNvbCkmJiFxckNvZGUuaXNEYXJrKHJvdyxjb2wrMSkmJnFyQ29kZS5pc0Rhcmsocm93LGNvbCsyKSYmcXJDb2RlLmlzRGFyayhyb3csY29sKzMpJiZxckNvZGUuaXNEYXJrKHJvdyxjb2wrNCkmJiFxckNvZGUuaXNEYXJrKHJvdyxjb2wrNSkmJnFyQ29kZS5pc0Rhcmsocm93LGNvbCs2KSl7bG9zdFBvaW50Kz00MDt9fX0KCWZvcih2YXIgY29sPTA7Y29sPG1vZHVsZUNvdW50O2NvbCsrKXtmb3IodmFyIHJvdz0wO3Jvdzxtb2R1bGVDb3VudC02O3JvdysrKXtpZihxckNvZGUuaXNEYXJrKHJvdyxjb2wpJiYhcXJDb2RlLmlzRGFyayhyb3crMSxjb2wpJiZxckNvZGUuaXNEYXJrKHJvdysyLGNvbCkmJnFyQ29kZS5pc0Rhcmsocm93KzMsY29sKSYmcXJDb2RlLmlzRGFyayhyb3crNCxjb2wpJiYhcXJDb2RlLmlzRGFyayhyb3crNSxjb2wpJiZxckNvZGUuaXNEYXJrKHJvdys2LGNvbCkpe2xvc3RQb2ludCs9NDA7fX19Cgl2YXIgZGFya0NvdW50PTA7Zm9yKHZhciBjb2w9MDtjb2w8bW9kdWxlQ291bnQ7Y29sKyspe2Zvcih2YXIgcm93PTA7cm93PG1vZHVsZUNvdW50O3JvdysrKXtpZihxckNvZGUuaXNEYXJrKHJvdyxjb2wpKXtkYXJrQ291bnQrKzt9fX0KCXZhciByYXRpbz1NYXRoLmFicygxMDAqZGFya0NvdW50L21vZHVsZUNvdW50L21vZHVsZUNvdW50LTUwKS81O2xvc3RQb2ludCs9cmF0aW8qMTA7cmV0dXJuIGxvc3RQb2ludDt9fTt2YXIgUVJNYXRoPXtnbG9nOmZ1bmN0aW9uKG4pe2lmKG48MSl7dGhyb3cgbmV3IEVycm9yKCJnbG9nKCIrbisiKSIpO30KCXJldHVybiBRUk1hdGguTE9HX1RBQkxFW25dO30sZ2V4cDpmdW5jdGlvbihuKXt3aGlsZShuPDApe24rPTI1NTt9Cgl3aGlsZShuPj0yNTYpe24tPTI1NTt9CglyZXR1cm4gUVJNYXRoLkVYUF9UQUJMRVtuXTt9LEVYUF9UQUJMRTpuZXcgQXJyYXkoMjU2KSxMT0dfVEFCTEU6bmV3IEFycmF5KDI1Nil9O2Zvcih2YXIgaT0wO2k8ODtpKyspe1FSTWF0aC5FWFBfVEFCTEVbaV09MTw8aTt9Cglmb3IodmFyIGk9ODtpPDI1NjtpKyspe1FSTWF0aC5FWFBfVEFCTEVbaV09UVJNYXRoLkVYUF9UQUJMRVtpLTRdXlFSTWF0aC5FWFBfVEFCTEVbaS01XV5RUk1hdGguRVhQX1RBQkxFW2ktNl1eUVJNYXRoLkVYUF9UQUJMRVtpLThdO30KCWZvcih2YXIgaT0wO2k8MjU1O2krKyl7UVJNYXRoLkxPR19UQUJMRVtRUk1hdGguRVhQX1RBQkxFW2ldXT1pO30KCWZ1bmN0aW9uIFFSUG9seW5vbWlhbChudW0sc2hpZnQpe2lmKG51bS5sZW5ndGg9PXVuZGVmaW5lZCl7dGhyb3cgbmV3IEVycm9yKG51bS5sZW5ndGgrIi8iK3NoaWZ0KTt9Cgl2YXIgb2Zmc2V0PTA7d2hpbGUob2Zmc2V0PG51bS5sZW5ndGgmJm51bVtvZmZzZXRdPT0wKXtvZmZzZXQrKzt9Cgl0aGlzLm51bT1uZXcgQXJyYXkobnVtLmxlbmd0aC1vZmZzZXQrc2hpZnQpO2Zvcih2YXIgaT0wO2k8bnVtLmxlbmd0aC1vZmZzZXQ7aSsrKXt0aGlzLm51bVtpXT1udW1baStvZmZzZXRdO319CglRUlBvbHlub21pYWwucHJvdG90eXBlPXtnZXQ6ZnVuY3Rpb24oaW5kZXgpe3JldHVybiB0aGlzLm51bVtpbmRleF07fSxnZXRMZW5ndGg6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5udW0ubGVuZ3RoO30sbXVsdGlwbHk6ZnVuY3Rpb24oZSl7dmFyIG51bT1uZXcgQXJyYXkodGhpcy5nZXRMZW5ndGgoKStlLmdldExlbmd0aCgpLTEpO2Zvcih2YXIgaT0wO2k8dGhpcy5nZXRMZW5ndGgoKTtpKyspe2Zvcih2YXIgaj0wO2o8ZS5nZXRMZW5ndGgoKTtqKyspe251bVtpK2pdXj1RUk1hdGguZ2V4cChRUk1hdGguZ2xvZyh0aGlzLmdldChpKSkrUVJNYXRoLmdsb2coZS5nZXQoaikpKTt9fQoJcmV0dXJuIG5ldyBRUlBvbHlub21pYWwobnVtLDApO30sbW9kOmZ1bmN0aW9uKGUpe2lmKHRoaXMuZ2V0TGVuZ3RoKCktZS5nZXRMZW5ndGgoKTwwKXtyZXR1cm4gdGhpczt9Cgl2YXIgcmF0aW89UVJNYXRoLmdsb2codGhpcy5nZXQoMCkpLVFSTWF0aC5nbG9nKGUuZ2V0KDApKTt2YXIgbnVtPW5ldyBBcnJheSh0aGlzLmdldExlbmd0aCgpKTtmb3IodmFyIGk9MDtpPHRoaXMuZ2V0TGVuZ3RoKCk7aSsrKXtudW1baV09dGhpcy5nZXQoaSk7fQoJZm9yKHZhciBpPTA7aTxlLmdldExlbmd0aCgpO2krKyl7bnVtW2ldXj1RUk1hdGguZ2V4cChRUk1hdGguZ2xvZyhlLmdldChpKSkrcmF0aW8pO30KCXJldHVybiBuZXcgUVJQb2x5bm9taWFsKG51bSwwKS5tb2QoZSk7fX07ZnVuY3Rpb24gUVJSU0Jsb2NrKHRvdGFsQ291bnQsZGF0YUNvdW50KXt0aGlzLnRvdGFsQ291bnQ9dG90YWxDb3VudDt0aGlzLmRhdGFDb3VudD1kYXRhQ291bnQ7fQoJUVJSU0Jsb2NrLlJTX0JMT0NLX1RBQkxFPVtbMSwyNiwxOV0sWzEsMjYsMTZdLFsxLDI2LDEzXSxbMSwyNiw5XSxbMSw0NCwzNF0sWzEsNDQsMjhdLFsxLDQ0LDIyXSxbMSw0NCwxNl0sWzEsNzAsNTVdLFsxLDcwLDQ0XSxbMiwzNSwxN10sWzIsMzUsMTNdLFsxLDEwMCw4MF0sWzIsNTAsMzJdLFsyLDUwLDI0XSxbNCwyNSw5XSxbMSwxMzQsMTA4XSxbMiw2Nyw0M10sWzIsMzMsMTUsMiwzNCwxNl0sWzIsMzMsMTEsMiwzNCwxMl0sWzIsODYsNjhdLFs0LDQzLDI3XSxbNCw0MywxOV0sWzQsNDMsMTVdLFsyLDk4LDc4XSxbNCw0OSwzMV0sWzIsMzIsMTQsNCwzMywxNV0sWzQsMzksMTMsMSw0MCwxNF0sWzIsMTIxLDk3XSxbMiw2MCwzOCwyLDYxLDM5XSxbNCw0MCwxOCwyLDQxLDE5XSxbNCw0MCwxNCwyLDQxLDE1XSxbMiwxNDYsMTE2XSxbMyw1OCwzNiwyLDU5LDM3XSxbNCwzNiwxNiw0LDM3LDE3XSxbNCwzNiwxMiw0LDM3LDEzXSxbMiw4Niw2OCwyLDg3LDY5XSxbNCw2OSw0MywxLDcwLDQ0XSxbNiw0MywxOSwyLDQ0LDIwXSxbNiw0MywxNSwyLDQ0LDE2XSxbNCwxMDEsODFdLFsxLDgwLDUwLDQsODEsNTFdLFs0LDUwLDIyLDQsNTEsMjNdLFszLDM2LDEyLDgsMzcsMTNdLFsyLDExNiw5MiwyLDExNyw5M10sWzYsNTgsMzYsMiw1OSwzN10sWzQsNDYsMjAsNiw0NywyMV0sWzcsNDIsMTQsNCw0MywxNV0sWzQsMTMzLDEwN10sWzgsNTksMzcsMSw2MCwzOF0sWzgsNDQsMjAsNCw0NSwyMV0sWzEyLDMzLDExLDQsMzQsMTJdLFszLDE0NSwxMTUsMSwxNDYsMTE2XSxbNCw2NCw0MCw1LDY1LDQxXSxbMTEsMzYsMTYsNSwzNywxN10sWzExLDM2LDEyLDUsMzcsMTNdLFs1LDEwOSw4NywxLDExMCw4OF0sWzUsNjUsNDEsNSw2Niw0Ml0sWzUsNTQsMjQsNyw1NSwyNV0sWzExLDM2LDEyXSxbNSwxMjIsOTgsMSwxMjMsOTldLFs3LDczLDQ1LDMsNzQsNDZdLFsxNSw0MywxOSwyLDQ0LDIwXSxbMyw0NSwxNSwxMyw0NiwxNl0sWzEsMTM1LDEwNyw1LDEzNiwxMDhdLFsxMCw3NCw0NiwxLDc1LDQ3XSxbMSw1MCwyMiwxNSw1MSwyM10sWzIsNDIsMTQsMTcsNDMsMTVdLFs1LDE1MCwxMjAsMSwxNTEsMTIxXSxbOSw2OSw0Myw0LDcwLDQ0XSxbMTcsNTAsMjIsMSw1MSwyM10sWzIsNDIsMTQsMTksNDMsMTVdLFszLDE0MSwxMTMsNCwxNDIsMTE0XSxbMyw3MCw0NCwxMSw3MSw0NV0sWzE3LDQ3LDIxLDQsNDgsMjJdLFs5LDM5LDEzLDE2LDQwLDE0XSxbMywxMzUsMTA3LDUsMTM2LDEwOF0sWzMsNjcsNDEsMTMsNjgsNDJdLFsxNSw1NCwyNCw1LDU1LDI1XSxbMTUsNDMsMTUsMTAsNDQsMTZdLFs0LDE0NCwxMTYsNCwxNDUsMTE3XSxbMTcsNjgsNDJdLFsxNyw1MCwyMiw2LDUxLDIzXSxbMTksNDYsMTYsNiw0NywxN10sWzIsMTM5LDExMSw3LDE0MCwxMTJdLFsxNyw3NCw0Nl0sWzcsNTQsMjQsMTYsNTUsMjVdLFszNCwzNywxM10sWzQsMTUxLDEyMSw1LDE1MiwxMjJdLFs0LDc1LDQ3LDE0LDc2LDQ4XSxbMTEsNTQsMjQsMTQsNTUsMjVdLFsxNiw0NSwxNSwxNCw0NiwxNl0sWzYsMTQ3LDExNyw0LDE0OCwxMThdLFs2LDczLDQ1LDE0LDc0LDQ2XSxbMTEsNTQsMjQsMTYsNTUsMjVdLFszMCw0NiwxNiwyLDQ3LDE3XSxbOCwxMzIsMTA2LDQsMTMzLDEwN10sWzgsNzUsNDcsMTMsNzYsNDhdLFs3LDU0LDI0LDIyLDU1LDI1XSxbMjIsNDUsMTUsMTMsNDYsMTZdLFsxMCwxNDIsMTE0LDIsMTQzLDExNV0sWzE5LDc0LDQ2LDQsNzUsNDddLFsyOCw1MCwyMiw2LDUxLDIzXSxbMzMsNDYsMTYsNCw0NywxN10sWzgsMTUyLDEyMiw0LDE1MywxMjNdLFsyMiw3Myw0NSwzLDc0LDQ2XSxbOCw1MywyMywyNiw1NCwyNF0sWzEyLDQ1LDE1LDI4LDQ2LDE2XSxbMywxNDcsMTE3LDEwLDE0OCwxMThdLFszLDczLDQ1LDIzLDc0LDQ2XSxbNCw1NCwyNCwzMSw1NSwyNV0sWzExLDQ1LDE1LDMxLDQ2LDE2XSxbNywxNDYsMTE2LDcsMTQ3LDExN10sWzIxLDczLDQ1LDcsNzQsNDZdLFsxLDUzLDIzLDM3LDU0LDI0XSxbMTksNDUsMTUsMjYsNDYsMTZdLFs1LDE0NSwxMTUsMTAsMTQ2LDExNl0sWzE5LDc1LDQ3LDEwLDc2LDQ4XSxbMTUsNTQsMjQsMjUsNTUsMjVdLFsyMyw0NSwxNSwyNSw0NiwxNl0sWzEzLDE0NSwxMTUsMywxNDYsMTE2XSxbMiw3NCw0NiwyOSw3NSw0N10sWzQyLDU0LDI0LDEsNTUsMjVdLFsyMyw0NSwxNSwyOCw0NiwxNl0sWzE3LDE0NSwxMTVdLFsxMCw3NCw0NiwyMyw3NSw0N10sWzEwLDU0LDI0LDM1LDU1LDI1XSxbMTksNDUsMTUsMzUsNDYsMTZdLFsxNywxNDUsMTE1LDEsMTQ2LDExNl0sWzE0LDc0LDQ2LDIxLDc1LDQ3XSxbMjksNTQsMjQsMTksNTUsMjVdLFsxMSw0NSwxNSw0Niw0NiwxNl0sWzEzLDE0NSwxMTUsNiwxNDYsMTE2XSxbMTQsNzQsNDYsMjMsNzUsNDddLFs0NCw1NCwyNCw3LDU1LDI1XSxbNTksNDYsMTYsMSw0NywxN10sWzEyLDE1MSwxMjEsNywxNTIsMTIyXSxbMTIsNzUsNDcsMjYsNzYsNDhdLFszOSw1NCwyNCwxNCw1NSwyNV0sWzIyLDQ1LDE1LDQxLDQ2LDE2XSxbNiwxNTEsMTIxLDE0LDE1MiwxMjJdLFs2LDc1LDQ3LDM0LDc2LDQ4XSxbNDYsNTQsMjQsMTAsNTUsMjVdLFsyLDQ1LDE1LDY0LDQ2LDE2XSxbMTcsMTUyLDEyMiw0LDE1MywxMjNdLFsyOSw3NCw0NiwxNCw3NSw0N10sWzQ5LDU0LDI0LDEwLDU1LDI1XSxbMjQsNDUsMTUsNDYsNDYsMTZdLFs0LDE1MiwxMjIsMTgsMTUzLDEyM10sWzEzLDc0LDQ2LDMyLDc1LDQ3XSxbNDgsNTQsMjQsMTQsNTUsMjVdLFs0Miw0NSwxNSwzMiw0NiwxNl0sWzIwLDE0NywxMTcsNCwxNDgsMTE4XSxbNDAsNzUsNDcsNyw3Niw0OF0sWzQzLDU0LDI0LDIyLDU1LDI1XSxbMTAsNDUsMTUsNjcsNDYsMTZdLFsxOSwxNDgsMTE4LDYsMTQ5LDExOV0sWzE4LDc1LDQ3LDMxLDc2LDQ4XSxbMzQsNTQsMjQsMzQsNTUsMjVdLFsyMCw0NSwxNSw2MSw0NiwxNl1dO1FSUlNCbG9jay5nZXRSU0Jsb2Nrcz1mdW5jdGlvbih0eXBlTnVtYmVyLGVycm9yQ29ycmVjdExldmVsKXt2YXIgcnNCbG9jaz1RUlJTQmxvY2suZ2V0UnNCbG9ja1RhYmxlKHR5cGVOdW1iZXIsZXJyb3JDb3JyZWN0TGV2ZWwpO2lmKHJzQmxvY2s9PXVuZGVmaW5lZCl7dGhyb3cgbmV3IEVycm9yKCJiYWQgcnMgYmxvY2sgQCB0eXBlTnVtYmVyOiIrdHlwZU51bWJlcisiL2Vycm9yQ29ycmVjdExldmVsOiIrZXJyb3JDb3JyZWN0TGV2ZWwpO30KCXZhciBsZW5ndGg9cnNCbG9jay5sZW5ndGgvMzt2YXIgbGlzdD1bXTtmb3IodmFyIGk9MDtpPGxlbmd0aDtpKyspe3ZhciBjb3VudD1yc0Jsb2NrW2kqMyswXTt2YXIgdG90YWxDb3VudD1yc0Jsb2NrW2kqMysxXTt2YXIgZGF0YUNvdW50PXJzQmxvY2tbaSozKzJdO2Zvcih2YXIgaj0wO2o8Y291bnQ7aisrKXtsaXN0LnB1c2gobmV3IFFSUlNCbG9jayh0b3RhbENvdW50LGRhdGFDb3VudCkpO319CglyZXR1cm4gbGlzdDt9O1FSUlNCbG9jay5nZXRSc0Jsb2NrVGFibGU9ZnVuY3Rpb24odHlwZU51bWJlcixlcnJvckNvcnJlY3RMZXZlbCl7c3dpdGNoKGVycm9yQ29ycmVjdExldmVsKXtjYXNlIFFSRXJyb3JDb3JyZWN0TGV2ZWwuTDpyZXR1cm4gUVJSU0Jsb2NrLlJTX0JMT0NLX1RBQkxFWyh0eXBlTnVtYmVyLTEpKjQrMF07Y2FzZSBRUkVycm9yQ29ycmVjdExldmVsLk06cmV0dXJuIFFSUlNCbG9jay5SU19CTE9DS19UQUJMRVsodHlwZU51bWJlci0xKSo0KzFdO2Nhc2UgUVJFcnJvckNvcnJlY3RMZXZlbC5ROnJldHVybiBRUlJTQmxvY2suUlNfQkxPQ0tfVEFCTEVbKHR5cGVOdW1iZXItMSkqNCsyXTtjYXNlIFFSRXJyb3JDb3JyZWN0TGV2ZWwuSDpyZXR1cm4gUVJSU0Jsb2NrLlJTX0JMT0NLX1RBQkxFWyh0eXBlTnVtYmVyLTEpKjQrM107ZGVmYXVsdDpyZXR1cm4gdW5kZWZpbmVkO319O2Z1bmN0aW9uIFFSQml0QnVmZmVyKCl7dGhpcy5idWZmZXI9W107dGhpcy5sZW5ndGg9MDt9CglRUkJpdEJ1ZmZlci5wcm90b3R5cGU9e2dldDpmdW5jdGlvbihpbmRleCl7dmFyIGJ1ZkluZGV4PU1hdGguZmxvb3IoaW5kZXgvOCk7cmV0dXJuKCh0aGlzLmJ1ZmZlcltidWZJbmRleF0+Pj4oNy1pbmRleCU4KSkmMSk9PTE7fSxwdXQ6ZnVuY3Rpb24obnVtLGxlbmd0aCl7Zm9yKHZhciBpPTA7aTxsZW5ndGg7aSsrKXt0aGlzLnB1dEJpdCgoKG51bT4+PihsZW5ndGgtaS0xKSkmMSk9PTEpO319LGdldExlbmd0aEluQml0czpmdW5jdGlvbigpe3JldHVybiB0aGlzLmxlbmd0aDt9LHB1dEJpdDpmdW5jdGlvbihiaXQpe3ZhciBidWZJbmRleD1NYXRoLmZsb29yKHRoaXMubGVuZ3RoLzgpO2lmKHRoaXMuYnVmZmVyLmxlbmd0aDw9YnVmSW5kZXgpe3RoaXMuYnVmZmVyLnB1c2goMCk7fQoJaWYoYml0KXt0aGlzLmJ1ZmZlcltidWZJbmRleF18PSgweDgwPj4+KHRoaXMubGVuZ3RoJTgpKTt9Cgl0aGlzLmxlbmd0aCsrO319O3ZhciBRUkNvZGVMaW1pdExlbmd0aD1bWzE3LDE0LDExLDddLFszMiwyNiwyMCwxNF0sWzUzLDQyLDMyLDI0XSxbNzgsNjIsNDYsMzRdLFsxMDYsODQsNjAsNDRdLFsxMzQsMTA2LDc0LDU4XSxbMTU0LDEyMiw4Niw2NF0sWzE5MiwxNTIsMTA4LDg0XSxbMjMwLDE4MCwxMzAsOThdLFsyNzEsMjEzLDE1MSwxMTldLFszMjEsMjUxLDE3NywxMzddLFszNjcsMjg3LDIwMywxNTVdLFs0MjUsMzMxLDI0MSwxNzddLFs0NTgsMzYyLDI1OCwxOTRdLFs1MjAsNDEyLDI5MiwyMjBdLFs1ODYsNDUwLDMyMiwyNTBdLFs2NDQsNTA0LDM2NCwyODBdLFs3MTgsNTYwLDM5NCwzMTBdLFs3OTIsNjI0LDQ0MiwzMzhdLFs4NTgsNjY2LDQ4MiwzODJdLFs5MjksNzExLDUwOSw0MDNdLFsxMDAzLDc3OSw1NjUsNDM5XSxbMTA5MSw4NTcsNjExLDQ2MV0sWzExNzEsOTExLDY2MSw1MTFdLFsxMjczLDk5Nyw3MTUsNTM1XSxbMTM2NywxMDU5LDc1MSw1OTNdLFsxNDY1LDExMjUsODA1LDYyNV0sWzE1MjgsMTE5MCw4NjgsNjU4XSxbMTYyOCwxMjY0LDkwOCw2OThdLFsxNzMyLDEzNzAsOTgyLDc0Ml0sWzE4NDAsMTQ1MiwxMDMwLDc5MF0sWzE5NTIsMTUzOCwxMTEyLDg0Ml0sWzIwNjgsMTYyOCwxMTY4LDg5OF0sWzIxODgsMTcyMiwxMjI4LDk1OF0sWzIzMDMsMTgwOSwxMjgzLDk4M10sWzI0MzEsMTkxMSwxMzUxLDEwNTFdLFsyNTYzLDE5ODksMTQyMywxMDkzXSxbMjY5OSwyMDk5LDE0OTksMTEzOV0sWzI4MDksMjIxMywxNTc5LDEyMTldLFsyOTUzLDIzMzEsMTY2MywxMjczXV07CgkKCWZ1bmN0aW9uIF9pc1N1cHBvcnRDYW52YXMoKSB7CgkJcmV0dXJuIHR5cGVvZiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQgIT0gInVuZGVmaW5lZCI7Cgl9CgkKCS8vIGFuZHJvaWQgMi54IGRvZXNuJ3Qgc3VwcG9ydCBEYXRhLVVSSSBzcGVjCglmdW5jdGlvbiBfZ2V0QW5kcm9pZCgpIHsKCQl2YXIgYW5kcm9pZCA9IGZhbHNlOwoJCXZhciBzQWdlbnQgPSBuYXZpZ2F0b3IudXNlckFnZW50OwoJCQoJCWlmICgvYW5kcm9pZC9pLnRlc3Qoc0FnZW50KSkgeyAvLyBhbmRyb2lkCgkJCWFuZHJvaWQgPSB0cnVlOwoJCQl2YXIgYU1hdCA9IHNBZ2VudC50b1N0cmluZygpLm1hdGNoKC9hbmRyb2lkIChbMC05XVwuWzAtOV0pL2kpOwoJCQkKCQkJaWYgKGFNYXQgJiYgYU1hdFsxXSkgewoJCQkJYW5kcm9pZCA9IHBhcnNlRmxvYXQoYU1hdFsxXSk7CgkJCX0KCQl9CgkJCgkJcmV0dXJuIGFuZHJvaWQ7Cgl9CgkKCXZhciBzdmdEcmF3ZXIgPSAoZnVuY3Rpb24oKSB7CgoJCXZhciBEcmF3aW5nID0gZnVuY3Rpb24gKGVsLCBodE9wdGlvbikgewoJCQl0aGlzLl9lbCA9IGVsOwoJCQl0aGlzLl9odE9wdGlvbiA9IGh0T3B0aW9uOwoJCX07CgoJCURyYXdpbmcucHJvdG90eXBlLmRyYXcgPSBmdW5jdGlvbiAob1FSQ29kZSkgewoJCQl2YXIgX2h0T3B0aW9uID0gdGhpcy5faHRPcHRpb247CgkJCXZhciBfZWwgPSB0aGlzLl9lbDsKCQkJdmFyIG5Db3VudCA9IG9RUkNvZGUuZ2V0TW9kdWxlQ291bnQoKTsKCQkJdmFyIG5XaWR0aCA9IE1hdGguZmxvb3IoX2h0T3B0aW9uLndpZHRoIC8gbkNvdW50KTsKCQkJdmFyIG5IZWlnaHQgPSBNYXRoLmZsb29yKF9odE9wdGlvbi5oZWlnaHQgLyBuQ291bnQpOwoKCQkJdGhpcy5jbGVhcigpOwoKCQkJZnVuY3Rpb24gbWFrZVNWRyh0YWcsIGF0dHJzKSB7CgkJCQl2YXIgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJywgdGFnKTsKCQkJCWZvciAodmFyIGsgaW4gYXR0cnMpCgkJCQkJaWYgKGF0dHJzLmhhc093blByb3BlcnR5KGspKSBlbC5zZXRBdHRyaWJ1dGUoaywgYXR0cnNba10pOwoJCQkJcmV0dXJuIGVsOwoJCQl9CgoJCQl2YXIgc3ZnID0gbWFrZVNWRygic3ZnIiAsIHsndmlld0JveCc6ICcwIDAgJyArIFN0cmluZyhuQ291bnQpICsgIiAiICsgU3RyaW5nKG5Db3VudCksICd3aWR0aCc6ICcxMDAlJywgJ2hlaWdodCc6ICcxMDAlJywgJ2ZpbGwnOiBfaHRPcHRpb24uY29sb3JMaWdodH0pOwoJCQlzdmcuc2V0QXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvIiwgInhtbG5zOnhsaW5rIiwgImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiKTsKCQkJX2VsLmFwcGVuZENoaWxkKHN2Zyk7CgoJCQlzdmcuYXBwZW5kQ2hpbGQobWFrZVNWRygicmVjdCIsIHsiZmlsbCI6IF9odE9wdGlvbi5jb2xvckxpZ2h0LCAid2lkdGgiOiAiMTAwJSIsICJoZWlnaHQiOiAiMTAwJSJ9KSk7CgkJCXN2Zy5hcHBlbmRDaGlsZChtYWtlU1ZHKCJyZWN0IiwgeyJmaWxsIjogX2h0T3B0aW9uLmNvbG9yRGFyaywgIndpZHRoIjogIjEiLCAiaGVpZ2h0IjogIjEiLCAiaWQiOiAidGVtcGxhdGUifSkpOwoKCQkJZm9yICh2YXIgcm93ID0gMDsgcm93IDwgbkNvdW50OyByb3crKykgewoJCQkJZm9yICh2YXIgY29sID0gMDsgY29sIDwgbkNvdW50OyBjb2wrKykgewoJCQkJCWlmIChvUVJDb2RlLmlzRGFyayhyb3csIGNvbCkpIHsKCQkJCQkJdmFyIGNoaWxkID0gbWFrZVNWRygidXNlIiwgeyJ4IjogU3RyaW5nKHJvdyksICJ5IjogU3RyaW5nKGNvbCl9KTsKCQkJCQkJY2hpbGQuc2V0QXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiLCAiaHJlZiIsICIjdGVtcGxhdGUiKQoJCQkJCQlzdmcuYXBwZW5kQ2hpbGQoY2hpbGQpOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX07CgkJRHJhd2luZy5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7CgkJCXdoaWxlICh0aGlzLl9lbC5oYXNDaGlsZE5vZGVzKCkpCgkJCQl0aGlzLl9lbC5yZW1vdmVDaGlsZCh0aGlzLl9lbC5sYXN0Q2hpbGQpOwoJCX07CgkJcmV0dXJuIERyYXdpbmc7Cgl9KSgpOwoKCXZhciB1c2VTVkcgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQudGFnTmFtZS50b0xvd2VyQ2FzZSgpID09PSAic3ZnIjsKCgkvLyBEcmF3aW5nIGluIERPTSBieSB1c2luZyBUYWJsZSB0YWcKCXZhciBEcmF3aW5nID0gdXNlU1ZHID8gc3ZnRHJhd2VyIDogIV9pc1N1cHBvcnRDYW52YXMoKSA/IChmdW5jdGlvbiAoKSB7CgkJdmFyIERyYXdpbmcgPSBmdW5jdGlvbiAoZWwsIGh0T3B0aW9uKSB7CgkJCXRoaXMuX2VsID0gZWw7CgkJCXRoaXMuX2h0T3B0aW9uID0gaHRPcHRpb247CgkJfTsKCQkJCgkJLyoqCgkJICogRHJhdyB0aGUgUVJDb2RlCgkJICogCgkJICogQHBhcmFtIHtRUkNvZGV9IG9RUkNvZGUKCQkgKi8KCQlEcmF3aW5nLnByb3RvdHlwZS5kcmF3ID0gZnVuY3Rpb24gKG9RUkNvZGUpIHsKICAgICAgICAgICAgdmFyIF9odE9wdGlvbiA9IHRoaXMuX2h0T3B0aW9uOwogICAgICAgICAgICB2YXIgX2VsID0gdGhpcy5fZWw7CgkJCXZhciBuQ291bnQgPSBvUVJDb2RlLmdldE1vZHVsZUNvdW50KCk7CgkJCXZhciBuV2lkdGggPSBNYXRoLmZsb29yKF9odE9wdGlvbi53aWR0aCAvIG5Db3VudCk7CgkJCXZhciBuSGVpZ2h0ID0gTWF0aC5mbG9vcihfaHRPcHRpb24uaGVpZ2h0IC8gbkNvdW50KTsKCQkJdmFyIGFIVE1MID0gWyc8dGFibGUgc3R5bGU9ImJvcmRlcjowO2JvcmRlci1jb2xsYXBzZTpjb2xsYXBzZTsiPiddOwoJCQkKCQkJZm9yICh2YXIgcm93ID0gMDsgcm93IDwgbkNvdW50OyByb3crKykgewoJCQkJYUhUTUwucHVzaCgnPHRyPicpOwoJCQkJCgkJCQlmb3IgKHZhciBjb2wgPSAwOyBjb2wgPCBuQ291bnQ7IGNvbCsrKSB7CgkJCQkJYUhUTUwucHVzaCgnPHRkIHN0eWxlPSJib3JkZXI6MDtib3JkZXItY29sbGFwc2U6Y29sbGFwc2U7cGFkZGluZzowO21hcmdpbjowO3dpZHRoOicgKyBuV2lkdGggKyAncHg7aGVpZ2h0OicgKyBuSGVpZ2h0ICsgJ3B4O2JhY2tncm91bmQtY29sb3I6JyArIChvUVJDb2RlLmlzRGFyayhyb3csIGNvbCkgPyBfaHRPcHRpb24uY29sb3JEYXJrIDogX2h0T3B0aW9uLmNvbG9yTGlnaHQpICsgJzsiPjwvdGQ+Jyk7CgkJCQl9CgkJCQkKCQkJCWFIVE1MLnB1c2goJzwvdHI+Jyk7CgkJCX0KCQkJCgkJCWFIVE1MLnB1c2goJzwvdGFibGU+Jyk7CgkJCV9lbC5pbm5lckhUTUwgPSBhSFRNTC5qb2luKCcnKTsKCQkJCgkJCS8vIEZpeCB0aGUgbWFyZ2luIHZhbHVlcyBhcyByZWFsIHNpemUuCgkJCXZhciBlbFRhYmxlID0gX2VsLmNoaWxkTm9kZXNbMF07CgkJCXZhciBuTGVmdE1hcmdpblRhYmxlID0gKF9odE9wdGlvbi53aWR0aCAtIGVsVGFibGUub2Zmc2V0V2lkdGgpIC8gMjsKCQkJdmFyIG5Ub3BNYXJnaW5UYWJsZSA9IChfaHRPcHRpb24uaGVpZ2h0IC0gZWxUYWJsZS5vZmZzZXRIZWlnaHQpIC8gMjsKCQkJCgkJCWlmIChuTGVmdE1hcmdpblRhYmxlID4gMCAmJiBuVG9wTWFyZ2luVGFibGUgPiAwKSB7CgkJCQllbFRhYmxlLnN0eWxlLm1hcmdpbiA9IG5Ub3BNYXJnaW5UYWJsZSArICJweCAiICsgbkxlZnRNYXJnaW5UYWJsZSArICJweCI7CQoJCQl9CgkJfTsKCQkKCQkvKioKCQkgKiBDbGVhciB0aGUgUVJDb2RlCgkJICovCgkJRHJhd2luZy5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7CgkJCXRoaXMuX2VsLmlubmVySFRNTCA9ICcnOwoJCX07CgkJCgkJcmV0dXJuIERyYXdpbmc7Cgl9KSgpIDogKGZ1bmN0aW9uICgpIHsgLy8gRHJhd2luZyBpbiBDYW52YXMKCQlmdW5jdGlvbiBfb25NYWtlSW1hZ2UoKSB7CgkJCXRoaXMuX2VsSW1hZ2Uuc3JjID0gdGhpcy5fZWxDYW52YXMudG9EYXRhVVJMKCJpbWFnZS9wbmciKTsKCQkJdGhpcy5fZWxJbWFnZS5zdHlsZS5kaXNwbGF5ID0gImJsb2NrIjsKCQkJdGhpcy5fZWxDYW52YXMuc3R5bGUuZGlzcGxheSA9ICJub25lIjsJCQkKCQl9CgkJCgkJLy8gQW5kcm9pZCAyLjEgYnVnIHdvcmthcm91bmQKCQkvLyBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvYW5kcm9pZC9pc3N1ZXMvZGV0YWlsP2lkPTUxNDEKCQlpZiAodGhpcy5fYW5kcm9pZCAmJiB0aGlzLl9hbmRyb2lkIDw9IDIuMSkgewoJICAgIAl2YXIgZmFjdG9yID0gMSAvIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvOwoJICAgICAgICB2YXIgZHJhd0ltYWdlID0gQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELnByb3RvdHlwZS5kcmF3SW1hZ2U7IAoJICAgIAlDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQucHJvdG90eXBlLmRyYXdJbWFnZSA9IGZ1bmN0aW9uIChpbWFnZSwgc3gsIHN5LCBzdywgc2gsIGR4LCBkeSwgZHcsIGRoKSB7CgkgICAgCQlpZiAoKCJub2RlTmFtZSIgaW4gaW1hZ2UpICYmIC9pbWcvaS50ZXN0KGltYWdlLm5vZGVOYW1lKSkgewoJCSAgICAgICAgCWZvciAodmFyIGkgPSBhcmd1bWVudHMubGVuZ3RoIC0gMTsgaSA+PSAxOyBpLS0pIHsKCQkgICAgICAgICAgICAJYXJndW1lbnRzW2ldID0gYXJndW1lbnRzW2ldICogZmFjdG9yOwoJCSAgICAgICAgCX0KCSAgICAJCX0gZWxzZSBpZiAodHlwZW9mIGR3ID09ICJ1bmRlZmluZWQiKSB7CgkgICAgCQkJYXJndW1lbnRzWzFdICo9IGZhY3RvcjsKCSAgICAJCQlhcmd1bWVudHNbMl0gKj0gZmFjdG9yOwoJICAgIAkJCWFyZ3VtZW50c1szXSAqPSBmYWN0b3I7CgkgICAgCQkJYXJndW1lbnRzWzRdICo9IGZhY3RvcjsKCSAgICAJCX0KCSAgICAJCQoJICAgICAgICAJZHJhd0ltYWdlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IAoJICAgIAl9OwoJCX0KCQkKCQkvKioKCQkgKiBDaGVjayB3aGV0aGVyIHRoZSB1c2VyJ3MgYnJvd3NlciBzdXBwb3J0cyBEYXRhIFVSSSBvciBub3QKCQkgKiAKCQkgKiBAcHJpdmF0ZQoJCSAqIEBwYXJhbSB7RnVuY3Rpb259IGZTdWNjZXNzIE9jY3VycyBpZiBpdCBzdXBwb3J0cyBEYXRhIFVSSQoJCSAqIEBwYXJhbSB7RnVuY3Rpb259IGZGYWlsIE9jY3VycyBpZiBpdCBkb2Vzbid0IHN1cHBvcnQgRGF0YSBVUkkKCQkgKi8KCQlmdW5jdGlvbiBfc2FmZVNldERhdGFVUkkoZlN1Y2Nlc3MsIGZGYWlsKSB7CiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpczsKICAgICAgICAgICAgc2VsZi5fZkZhaWwgPSBmRmFpbDsKICAgICAgICAgICAgc2VsZi5fZlN1Y2Nlc3MgPSBmU3VjY2VzczsKCiAgICAgICAgICAgIC8vIENoZWNrIGl0IGp1c3Qgb25jZQogICAgICAgICAgICBpZiAoc2VsZi5fYlN1cHBvcnREYXRhVVJJID09PSBudWxsKSB7CiAgICAgICAgICAgICAgICB2YXIgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJpbWciKTsKICAgICAgICAgICAgICAgIHZhciBmT25FcnJvciA9IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgIHNlbGYuX2JTdXBwb3J0RGF0YVVSSSA9IGZhbHNlOwoKICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5fZkZhaWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fZkZhaWwuY2FsbChzZWxmKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgdmFyIGZPblN1Y2Nlc3MgPSBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICBzZWxmLl9iU3VwcG9ydERhdGFVUkkgPSB0cnVlOwoKICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5fZlN1Y2Nlc3MpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fZlN1Y2Nlc3MuY2FsbChzZWxmKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgIGVsLm9uYWJvcnQgPSBmT25FcnJvcjsKICAgICAgICAgICAgICAgIGVsLm9uZXJyb3IgPSBmT25FcnJvcjsKICAgICAgICAgICAgICAgIGVsLm9ubG9hZCA9IGZPblN1Y2Nlc3M7CiAgICAgICAgICAgICAgICBlbC5zcmMgPSAiZGF0YTppbWFnZS9naWY7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFBVUFBQUFGQ0FZQUFBQ05ieWJsQUFBQUhFbEVRVlFJMTJQNC8vOC93MzhHSUFYRElCS0UwREh4Z2xqTkJBQU85VFhMMFk0T0h3QUFBQUJKUlU1RXJrSmdnZz09IjsgLy8gdGhlIEltYWdlIGNvbnRhaW5zIDFweCBkYXRhLgogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9IGVsc2UgaWYgKHNlbGYuX2JTdXBwb3J0RGF0YVVSSSA9PT0gdHJ1ZSAmJiBzZWxmLl9mU3VjY2VzcykgewogICAgICAgICAgICAgICAgc2VsZi5fZlN1Y2Nlc3MuY2FsbChzZWxmKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChzZWxmLl9iU3VwcG9ydERhdGFVUkkgPT09IGZhbHNlICYmIHNlbGYuX2ZGYWlsKSB7CiAgICAgICAgICAgICAgICBzZWxmLl9mRmFpbC5jYWxsKHNlbGYpOwogICAgICAgICAgICB9CgkJfTsKCQkKCQkvKioKCQkgKiBEcmF3aW5nIFFSQ29kZSBieSB1c2luZyBjYW52YXMKCQkgKiAKCQkgKiBAY29uc3RydWN0b3IKCQkgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbAoJCSAqIEBwYXJhbSB7T2JqZWN0fSBodE9wdGlvbiBRUkNvZGUgT3B0aW9ucyAKCQkgKi8KCQl2YXIgRHJhd2luZyA9IGZ1bmN0aW9uIChlbCwgaHRPcHRpb24pIHsKICAgIAkJdGhpcy5fYklzUGFpbnRlZCA9IGZhbHNlOwogICAgCQl0aGlzLl9hbmRyb2lkID0gX2dldEFuZHJvaWQoKTsKCQkKCQkJdGhpcy5faHRPcHRpb24gPSBodE9wdGlvbjsKCQkJdGhpcy5fZWxDYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJjYW52YXMiKTsKCQkJdGhpcy5fZWxDYW52YXMud2lkdGggPSBodE9wdGlvbi53aWR0aDsKCQkJdGhpcy5fZWxDYW52YXMuaGVpZ2h0ID0gaHRPcHRpb24uaGVpZ2h0OwoJCQllbC5hcHBlbmRDaGlsZCh0aGlzLl9lbENhbnZhcyk7CgkJCXRoaXMuX2VsID0gZWw7CgkJCXRoaXMuX29Db250ZXh0ID0gdGhpcy5fZWxDYW52YXMuZ2V0Q29udGV4dCgiMmQiKTsKCQkJdGhpcy5fYklzUGFpbnRlZCA9IGZhbHNlOwoJCQl0aGlzLl9lbEltYWdlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiaW1nIik7CgkJCXRoaXMuX2VsSW1hZ2UuYWx0ID0gIlNjYW4gbWUhIjsKCQkJdGhpcy5fZWxJbWFnZS5zdHlsZS5kaXNwbGF5ID0gIm5vbmUiOwoJCQl0aGlzLl9lbC5hcHBlbmRDaGlsZCh0aGlzLl9lbEltYWdlKTsKCQkJdGhpcy5fYlN1cHBvcnREYXRhVVJJID0gbnVsbDsKCQl9OwoJCQkKCQkvKioKCQkgKiBEcmF3IHRoZSBRUkNvZGUKCQkgKiAKCQkgKiBAcGFyYW0ge1FSQ29kZX0gb1FSQ29kZSAKCQkgKi8KCQlEcmF3aW5nLnByb3RvdHlwZS5kcmF3ID0gZnVuY3Rpb24gKG9RUkNvZGUpIHsKICAgICAgICAgICAgdmFyIF9lbEltYWdlID0gdGhpcy5fZWxJbWFnZTsKICAgICAgICAgICAgdmFyIF9vQ29udGV4dCA9IHRoaXMuX29Db250ZXh0OwogICAgICAgICAgICB2YXIgX2h0T3B0aW9uID0gdGhpcy5faHRPcHRpb247CiAgICAgICAgICAgIAoJCQl2YXIgbkNvdW50ID0gb1FSQ29kZS5nZXRNb2R1bGVDb3VudCgpOwoJCQl2YXIgbldpZHRoID0gX2h0T3B0aW9uLndpZHRoIC8gbkNvdW50OwoJCQl2YXIgbkhlaWdodCA9IF9odE9wdGlvbi5oZWlnaHQgLyBuQ291bnQ7CgkJCXZhciBuUm91bmRlZFdpZHRoID0gTWF0aC5yb3VuZChuV2lkdGgpOwoJCQl2YXIgblJvdW5kZWRIZWlnaHQgPSBNYXRoLnJvdW5kKG5IZWlnaHQpOwoKCQkJX2VsSW1hZ2Uuc3R5bGUuZGlzcGxheSA9ICJub25lIjsKCQkJdGhpcy5jbGVhcigpOwoJCQkKCQkJZm9yICh2YXIgcm93ID0gMDsgcm93IDwgbkNvdW50OyByb3crKykgewoJCQkJZm9yICh2YXIgY29sID0gMDsgY29sIDwgbkNvdW50OyBjb2wrKykgewoJCQkJCXZhciBiSXNEYXJrID0gb1FSQ29kZS5pc0Rhcmsocm93LCBjb2wpOwoJCQkJCXZhciBuTGVmdCA9IGNvbCAqIG5XaWR0aDsKCQkJCQl2YXIgblRvcCA9IHJvdyAqIG5IZWlnaHQ7CgkJCQkJX29Db250ZXh0LnN0cm9rZVN0eWxlID0gYklzRGFyayA/IF9odE9wdGlvbi5jb2xvckRhcmsgOiBfaHRPcHRpb24uY29sb3JMaWdodDsKCQkJCQlfb0NvbnRleHQubGluZVdpZHRoID0gMTsKCQkJCQlfb0NvbnRleHQuZmlsbFN0eWxlID0gYklzRGFyayA/IF9odE9wdGlvbi5jb2xvckRhcmsgOiBfaHRPcHRpb24uY29sb3JMaWdodDsJCQkJCQoJCQkJCV9vQ29udGV4dC5maWxsUmVjdChuTGVmdCwgblRvcCwgbldpZHRoLCBuSGVpZ2h0KTsKCQkJCQkKCQkJCQkvLyDslYjti7Ag7JWo66as7Ja07IuxIOuwqeyngCDsspjrpqwKCQkJCQlfb0NvbnRleHQuc3Ryb2tlUmVjdCgKCQkJCQkJTWF0aC5mbG9vcihuTGVmdCkgKyAwLjUsCgkJCQkJCU1hdGguZmxvb3IoblRvcCkgKyAwLjUsCgkJCQkJCW5Sb3VuZGVkV2lkdGgsCgkJCQkJCW5Sb3VuZGVkSGVpZ2h0CgkJCQkJKTsKCQkJCQkKCQkJCQlfb0NvbnRleHQuc3Ryb2tlUmVjdCgKCQkJCQkJTWF0aC5jZWlsKG5MZWZ0KSAtIDAuNSwKCQkJCQkJTWF0aC5jZWlsKG5Ub3ApIC0gMC41LAoJCQkJCQluUm91bmRlZFdpZHRoLAoJCQkJCQluUm91bmRlZEhlaWdodAoJCQkJCSk7CgkJCQl9CgkJCX0KCQkJCgkJCXRoaXMuX2JJc1BhaW50ZWQgPSB0cnVlOwoJCX07CgkJCQoJCS8qKgoJCSAqIE1ha2UgdGhlIGltYWdlIGZyb20gQ2FudmFzIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIERhdGEgVVJJLgoJCSAqLwoJCURyYXdpbmcucHJvdG90eXBlLm1ha2VJbWFnZSA9IGZ1bmN0aW9uICgpIHsKCQkJaWYgKHRoaXMuX2JJc1BhaW50ZWQpIHsKCQkJCV9zYWZlU2V0RGF0YVVSSS5jYWxsKHRoaXMsIF9vbk1ha2VJbWFnZSk7CgkJCX0KCQl9OwoJCQkKCQkvKioKCQkgKiBSZXR1cm4gd2hldGhlciB0aGUgUVJDb2RlIGlzIHBhaW50ZWQgb3Igbm90CgkJICogCgkJICogQHJldHVybiB7Qm9vbGVhbn0KCQkgKi8KCQlEcmF3aW5nLnByb3RvdHlwZS5pc1BhaW50ZWQgPSBmdW5jdGlvbiAoKSB7CgkJCXJldHVybiB0aGlzLl9iSXNQYWludGVkOwoJCX07CgkJCgkJLyoqCgkJICogQ2xlYXIgdGhlIFFSQ29kZQoJCSAqLwoJCURyYXdpbmcucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkgewoJCQl0aGlzLl9vQ29udGV4dC5jbGVhclJlY3QoMCwgMCwgdGhpcy5fZWxDYW52YXMud2lkdGgsIHRoaXMuX2VsQ2FudmFzLmhlaWdodCk7CgkJCXRoaXMuX2JJc1BhaW50ZWQgPSBmYWxzZTsKCQl9OwoJCQoJCS8qKgoJCSAqIEBwcml2YXRlCgkJICogQHBhcmFtIHtOdW1iZXJ9IG5OdW1iZXIKCQkgKi8KCQlEcmF3aW5nLnByb3RvdHlwZS5yb3VuZCA9IGZ1bmN0aW9uIChuTnVtYmVyKSB7CgkJCWlmICghbk51bWJlcikgewoJCQkJcmV0dXJuIG5OdW1iZXI7CgkJCX0KCQkJCgkJCXJldHVybiBNYXRoLmZsb29yKG5OdW1iZXIgKiAxMDAwKSAvIDEwMDA7CgkJfTsKCQkKCQlyZXR1cm4gRHJhd2luZzsKCX0pKCk7CgkKCS8qKgoJICogR2V0IHRoZSB0eXBlIGJ5IHN0cmluZyBsZW5ndGgKCSAqIAoJICogQHByaXZhdGUKCSAqIEBwYXJhbSB7U3RyaW5nfSBzVGV4dAoJICogQHBhcmFtIHtOdW1iZXJ9IG5Db3JyZWN0TGV2ZWwKCSAqIEByZXR1cm4ge051bWJlcn0gdHlwZQoJICovCglmdW5jdGlvbiBfZ2V0VHlwZU51bWJlcihzVGV4dCwgbkNvcnJlY3RMZXZlbCkgewkJCQoJCXZhciBuVHlwZSA9IDE7CgkJdmFyIGxlbmd0aCA9IF9nZXRVVEY4TGVuZ3RoKHNUZXh0KTsKCQkKCQlmb3IgKHZhciBpID0gMCwgbGVuID0gUVJDb2RlTGltaXRMZW5ndGgubGVuZ3RoOyBpIDw9IGxlbjsgaSsrKSB7CgkJCXZhciBuTGltaXQgPSAwOwoJCQkKCQkJc3dpdGNoIChuQ29ycmVjdExldmVsKSB7CgkJCQljYXNlIFFSRXJyb3JDb3JyZWN0TGV2ZWwuTCA6CgkJCQkJbkxpbWl0ID0gUVJDb2RlTGltaXRMZW5ndGhbaV1bMF07CgkJCQkJYnJlYWs7CgkJCQljYXNlIFFSRXJyb3JDb3JyZWN0TGV2ZWwuTSA6CgkJCQkJbkxpbWl0ID0gUVJDb2RlTGltaXRMZW5ndGhbaV1bMV07CgkJCQkJYnJlYWs7CgkJCQljYXNlIFFSRXJyb3JDb3JyZWN0TGV2ZWwuUSA6CgkJCQkJbkxpbWl0ID0gUVJDb2RlTGltaXRMZW5ndGhbaV1bMl07CgkJCQkJYnJlYWs7CgkJCQljYXNlIFFSRXJyb3JDb3JyZWN0TGV2ZWwuSCA6CgkJCQkJbkxpbWl0ID0gUVJDb2RlTGltaXRMZW5ndGhbaV1bM107CgkJCQkJYnJlYWs7CgkJCX0KCQkJCgkJCWlmIChsZW5ndGggPD0gbkxpbWl0KSB7CgkJCQlicmVhazsKCQkJfSBlbHNlIHsKCQkJCW5UeXBlKys7CgkJCX0KCQl9CgkJCgkJaWYgKG5UeXBlID4gUVJDb2RlTGltaXRMZW5ndGgubGVuZ3RoKSB7CgkJCXRocm93IG5ldyBFcnJvcigiVG9vIGxvbmcgZGF0YSIpOwoJCX0KCQkKCQlyZXR1cm4gblR5cGU7Cgl9CgoJZnVuY3Rpb24gX2dldFVURjhMZW5ndGgoc1RleHQpIHsKCQl2YXIgcmVwbGFjZWRUZXh0ID0gZW5jb2RlVVJJKHNUZXh0KS50b1N0cmluZygpLnJlcGxhY2UoL1wlWzAtOWEtZkEtRl17Mn0vZywgJ2EnKTsKCQlyZXR1cm4gcmVwbGFjZWRUZXh0Lmxlbmd0aCArIChyZXBsYWNlZFRleHQubGVuZ3RoICE9IHNUZXh0ID8gMyA6IDApOwoJfQoJCgkvKioKCSAqIEBjbGFzcyBRUkNvZGUKCSAqIEBjb25zdHJ1Y3RvcgoJICogQGV4YW1wbGUgCgkgKiBuZXcgUVJDb2RlKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJ0ZXN0IiksICJodHRwOi8vamluZG8uZGV2Lm5hdmVyLmNvbS9jb2xsaWUiKTsKCSAqCgkgKiBAZXhhbXBsZQoJICogdmFyIG9RUkNvZGUgPSBuZXcgUVJDb2RlKCJ0ZXN0IiwgewoJICogICAgdGV4dCA6ICJodHRwOi8vbmF2ZXIuY29tIiwKCSAqICAgIHdpZHRoIDogMTI4LAoJICogICAgaGVpZ2h0IDogMTI4CgkgKiB9KTsKCSAqIAoJICogb1FSQ29kZS5jbGVhcigpOyAvLyBDbGVhciB0aGUgUVJDb2RlLgoJICogb1FSQ29kZS5tYWtlQ29kZSgiaHR0cDovL21hcC5uYXZlci5jb20iKTsgLy8gUmUtY3JlYXRlIHRoZSBRUkNvZGUuCgkgKgoJICogQHBhcmFtIHtIVE1MRWxlbWVudHxTdHJpbmd9IGVsIHRhcmdldCBlbGVtZW50IG9yICdpZCcgYXR0cmlidXRlIG9mIGVsZW1lbnQuCgkgKiBAcGFyYW0ge09iamVjdHxTdHJpbmd9IHZPcHRpb24KCSAqIEBwYXJhbSB7U3RyaW5nfSB2T3B0aW9uLnRleHQgUVJDb2RlIGxpbmsgZGF0YQoJICogQHBhcmFtIHtOdW1iZXJ9IFt2T3B0aW9uLndpZHRoPTI1Nl0KCSAqIEBwYXJhbSB7TnVtYmVyfSBbdk9wdGlvbi5oZWlnaHQ9MjU2XQoJICogQHBhcmFtIHtTdHJpbmd9IFt2T3B0aW9uLmNvbG9yRGFyaz0iIzAwMDAwMCJdCgkgKiBAcGFyYW0ge1N0cmluZ30gW3ZPcHRpb24uY29sb3JMaWdodD0iI2ZmZmZmZiJdCgkgKiBAcGFyYW0ge1FSQ29kZS5Db3JyZWN0TGV2ZWx9IFt2T3B0aW9uLmNvcnJlY3RMZXZlbD1RUkNvZGUuQ29ycmVjdExldmVsLkhdIFtMfE18UXxIXSAKCSAqLwoJUVJDb2RlID0gZnVuY3Rpb24gKGVsLCB2T3B0aW9uKSB7CgkJdGhpcy5faHRPcHRpb24gPSB7CgkJCXdpZHRoIDogMjU2LCAKCQkJaGVpZ2h0IDogMjU2LAoJCQl0eXBlTnVtYmVyIDogNCwKCQkJY29sb3JEYXJrIDogIiMwMDAwMDAiLAoJCQljb2xvckxpZ2h0IDogIiNmZmZmZmYiLAoJCQljb3JyZWN0TGV2ZWwgOiBRUkVycm9yQ29ycmVjdExldmVsLkgKCQl9OwoJCQoJCWlmICh0eXBlb2Ygdk9wdGlvbiA9PT0gJ3N0cmluZycpIHsKCQkJdk9wdGlvbgk9IHsKCQkJCXRleHQgOiB2T3B0aW9uCgkJCX07CgkJfQoJCQoJCS8vIE92ZXJ3cml0ZXMgb3B0aW9ucwoJCWlmICh2T3B0aW9uKSB7CgkJCWZvciAodmFyIGkgaW4gdk9wdGlvbikgewoJCQkJdGhpcy5faHRPcHRpb25baV0gPSB2T3B0aW9uW2ldOwoJCQl9CgkJfQoJCQoJCWlmICh0eXBlb2YgZWwgPT0gInN0cmluZyIpIHsKCQkJZWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbCk7CgkJfQoKCQlpZiAodGhpcy5faHRPcHRpb24udXNlU1ZHKSB7CgkJCURyYXdpbmcgPSBzdmdEcmF3ZXI7CgkJfQoJCQoJCXRoaXMuX2FuZHJvaWQgPSBfZ2V0QW5kcm9pZCgpOwoJCXRoaXMuX2VsID0gZWw7CgkJdGhpcy5fb1FSQ29kZSA9IG51bGw7CgkJdGhpcy5fb0RyYXdpbmcgPSBuZXcgRHJhd2luZyh0aGlzLl9lbCwgdGhpcy5faHRPcHRpb24pOwoJCQoJCWlmICh0aGlzLl9odE9wdGlvbi50ZXh0KSB7CgkJCXRoaXMubWFrZUNvZGUodGhpcy5faHRPcHRpb24udGV4dCk7CQoJCX0KCX07CgkKCS8qKgoJICogTWFrZSB0aGUgUVJDb2RlCgkgKiAKCSAqIEBwYXJhbSB7U3RyaW5nfSBzVGV4dCBsaW5rIGRhdGEKCSAqLwoJUVJDb2RlLnByb3RvdHlwZS5tYWtlQ29kZSA9IGZ1bmN0aW9uIChzVGV4dCkgewoJCXRoaXMuX29RUkNvZGUgPSBuZXcgUVJDb2RlTW9kZWwoX2dldFR5cGVOdW1iZXIoc1RleHQsIHRoaXMuX2h0T3B0aW9uLmNvcnJlY3RMZXZlbCksIHRoaXMuX2h0T3B0aW9uLmNvcnJlY3RMZXZlbCk7CgkJdGhpcy5fb1FSQ29kZS5hZGREYXRhKHNUZXh0KTsKCQl0aGlzLl9vUVJDb2RlLm1ha2UoKTsKCQl0aGlzLl9lbC50aXRsZSA9IHNUZXh0OwoJCXRoaXMuX29EcmF3aW5nLmRyYXcodGhpcy5fb1FSQ29kZSk7CQkJCgkJdGhpcy5tYWtlSW1hZ2UoKTsKCX07CgkKCS8qKgoJICogTWFrZSB0aGUgSW1hZ2UgZnJvbSBDYW52YXMgZWxlbWVudAoJICogLSBJdCBvY2N1cnMgYXV0b21hdGljYWxseQoJICogLSBBbmRyb2lkIGJlbG93IDMgZG9lc24ndCBzdXBwb3J0IERhdGEtVVJJIHNwZWMuCgkgKiAKCSAqIEBwcml2YXRlCgkgKi8KCVFSQ29kZS5wcm90b3R5cGUubWFrZUltYWdlID0gZnVuY3Rpb24gKCkgewoJCWlmICh0eXBlb2YgdGhpcy5fb0RyYXdpbmcubWFrZUltYWdlID09ICJmdW5jdGlvbiIgJiYgKCF0aGlzLl9hbmRyb2lkIHx8IHRoaXMuX2FuZHJvaWQgPj0gMykpIHsKCQkJdGhpcy5fb0RyYXdpbmcubWFrZUltYWdlKCk7CgkJfQoJfTsKCQoJLyoqCgkgKiBDbGVhciB0aGUgUVJDb2RlCgkgKi8KCVFSQ29kZS5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7CgkJdGhpcy5fb0RyYXdpbmcuY2xlYXIoKTsKCX07CgkKCS8qKgoJICogQG5hbWUgUVJDb2RlLkNvcnJlY3RMZXZlbAoJICovCglRUkNvZGUuQ29ycmVjdExldmVsID0gUVJFcnJvckNvcnJlY3RMZXZlbDsKfSkoKTsK
"></script>
</head>
<body>
<div id="qrcode" style="width:100px; height:100px; margin-top:15px;"></div>
<script type="text/javascript">
var qrcode = new QRCode(document.getElementById("qrcode"), {
width : 300,
height : 300
});
function makeCode () {
var href;
if (location.search) {
href = location.search.substr(1);
} else {
href = location.hash.substr(1);
}
qrcode.makeCode(href);
}
makeCode();
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment