haskell-relational-record/doc/slide/tsukuba-201412/DSL.html
2016-09-17 16:01:05 +09:00

442 lines
257 KiB
HTML

<!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">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta name="generator" content="pandoc" />
<meta name="version" content="S5 1.1" />
<meta name="author" content="2014-12-25 (Updated 2014-12-29)" />
<title>Haskell Relational Record's Query-Building DSL</title>
<style type="text/css">code{white-space: pre;}</style>
<!-- configuration parameters -->
<meta name="defaultView" content="slideshow" />
<meta name="controlVis" content="hidden" />
<style type="text/css">
div.sourceCode { overflow-x: auto; }
table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
margin: 0; padding: 0; vertical-align: baseline; border: none; }
table.sourceCode { width: 100%; line-height: 100%; }
td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
td.sourceCode { padding-left: 5px; }
code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
code > span.dt { color: #902000; } /* DataType */
code > span.dv { color: #40a070; } /* DecVal */
code > span.bn { color: #40a070; } /* BaseN */
code > span.fl { color: #40a070; } /* Float */
code > span.ch { color: #4070a0; } /* Char */
code > span.st { color: #4070a0; } /* String */
code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
code > span.ot { color: #007020; } /* Other */
code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
code > span.fu { color: #06287e; } /* Function */
code > span.er { color: #ff0000; font-weight: bold; } /* Error */
code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
code > span.cn { color: #880000; } /* Constant */
code > span.sc { color: #4070a0; } /* SpecialChar */
code > span.vs { color: #4070a0; } /* VerbatimString */
code > span.ss { color: #bb6688; } /* SpecialString */
code > span.im { } /* Import */
code > span.va { color: #19177c; } /* Variable */
code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code > span.op { color: #666666; } /* Operator */
code > span.bu { } /* BuiltIn */
code > span.ex { } /* Extension */
code > span.pp { color: #bc7a00; } /* Preprocessor */
code > span.at { color: #7d9029; } /* Attribute */
code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
</style>
<!-- style sheet links -->
<link href="data:text/css;charset=utf-8,%40import%20url%28data%3Atext%2Fcss%3Bcharset%3Dutf%2D8%2C%250Adiv%2523header%252C%2520div%2523footer%252C%2520div%2523controls%252C%2520%252Eslide%2520%257Bposition%253A%2520absolute%253B%257D%250Ahtml%253Ebody%2520div%2523header%252C%2520html%253Ebody%2520div%2523footer%252C%2520html%253Ebody%2520div%2523controls%252C%2520html%253Ebody%2520%252Eslide%2520%257Bposition%253A%2520fixed%253B%257D%250A%252Ehandout%2520%257Bdisplay%253A%2520none%253B%257D%250A%252Elayout%2520%257Bdisplay%253A%2520block%253B%257D%250A%252Eslide%252C%2520%252Ehideme%252C%2520%252Eincremental%2520%257Bvisibility%253A%2520hidden%253B%257D%250A%2523slide0%2520%257Bvisibility%253A%2520visible%253B%257D%250A%29%3B%20%0A%40import%20url%28data%3Atext%2Fcss%3Bcharset%3Dutf%2D8%2C%250A%250Adiv%2523header%252C%2520div%2523footer%252C%2520%252Eslide%2520%257Bwidth%253A%2520100%2525%253B%2520top%253A%25200%253B%2520left%253A%25200%253B%257D%250Adiv%2523header%2520%257Btop%253A%25200%253B%2520height%253A%25203em%253B%2520z%252Dindex%253A%25201%253B%257D%250Adiv%2523footer%2520%257Btop%253A%2520auto%253B%2520bottom%253A%25200%253B%2520height%253A%25202%252E5em%253B%2520z%252Dindex%253A%25205%253B%257D%250A%252Eslide%2520%257Btop%253A%25200%253B%2520width%253A%252092%2525%253B%2520padding%253A%25203%252E5em%25204%2525%25204%2525%253B%2520z%252Dindex%253A%25202%253B%2520list%252Dstyle%253A%2520none%253B%257D%250Adiv%2523controls%2520%257Bleft%253A%252050%2525%253B%2520bottom%253A%25200%253B%2520width%253A%252050%2525%253B%2520z%252Dindex%253A%2520100%253B%257D%250Adiv%2523controls%2520form%2520%257Bposition%253A%2520absolute%253B%2520bottom%253A%25200%253B%2520right%253A%25200%253B%2520width%253A%2520100%2525%253B%250Amargin%253A%25200%253B%257D%250A%2523currentSlide%2520%257Bposition%253A%2520absolute%253B%2520width%253A%252010%2525%253B%2520left%253A%252045%2525%253B%2520bottom%253A%25201em%253B%2520z%252Dindex%253A%252010%253B%257D%250Ahtml%253Ebody%2520%2523currentSlide%2520%257Bposition%253A%2520fixed%253B%257D%250A%250A%29%3B%20%0A%40import%20url%28data%3Atext%2Fcss%3Bcharset%3Dutf%2D8%2C%250Abody%2520%257Bbackground%253A%2520%2523FFF%2520url%2528data%253Aimage%252Fgif%253Bbase64%252CR0lGODlh5gBOAcT%252FAMDAwLW1tb29vcbGxs7OztbW1t7e3ufn5%252B%252Fv7%252Ff39%252Bfv7%252B%252F39%252Ff%252F%252F8bOzs7W1tbe3t7n57W9vb3Gxuf3987e3tbn597v78bW1r3Ozs7n5wAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAADmAE4BAAX%252F4CEez3UZ1PNAjppCpALM9GxNgLXUfD8pC6BC1mMoLApGb7nUMRaWBLOmwAGOREVlqK38LNNwbQIWm2fH2aLScJzf8NqI1Lg8Cqq6w9EoOAwPZT0KFBkIcVhkSwlQh3E8EDhrOmELFEQ5VTMJRwwQDTtXFRlbj2hRWwkZhZhMDBVINQsZMrMUgqa5PHMiDw0qdg8igIAOUjxrVo9YEE0VFaG6sZ5Imj2zuFxFFBQ1Smm5UAATzeJhnkEV1%252BqWF8268DO8JA8GbcIjD3%252FvsrQIuGegKFkyJJ4NIhAoUULGb8aEZwQlDER2a0o0WdDeLYCQACCNIwsflqKxZpyECx4N%252F77hpW9ePgcirkEwF2cjE3DxfhxUB43HK48bdRyjQeFCD1W3KjSkUW3JxlcAStZgFATLUACMMvBQFVVCCpWm5rR02Qvmga3qdEnt10pt2iGcgPBQOhHjz2gVKAx8liEDBHUJ0m5FogxZ2sAAGCRQTMpCLCaq%252BAVe%252FAlDW7Bi5hgwS3ZzTBpQ4a3dJNggggqcyhjxhrru1JmMLCB4CMrCsyiLEWMtDfqyKwqjZrYCqSChT1I0WkPIIME35iUjDFwgOwLC9LPJXT9ayyBDynC3tTbhaOYZrISELDhYsEA31kK8VfJGwi3D1RoV9krh1kD78x7DcEadZ9h5cl84YECEWf9oNvUQyYFidHPFBSWh9p8YF7EHIVEcWlAIAReGIYJ11FV33SbiGcTAAwBIiJmEDLhYw0JiDMRIdx%252FpYGGIUyxlRoqUfNJAfDwCIMJ1JR5gjwgyhKaSVk6qeBhA2pgR2BNKVSWDBRDMVCQcxk2R31470NKAjzwegGSSJOwhXooGvfkiDXAG8RgTyCGn1HvoVXPRl2JM8GcPD9g3g3AWMLfhfwc0wKZYhc4gIzx5SQpWik4GxQRfacGJpSDOASpfKN0oIEEGDYhq5JqPHiAhnNIsNgOsuZQmISOlcWnbM7JqFxiRPQCrKhw9FWQmi4Ce0Ooc4nVkkIy0miKjOq%252Bw8wP%252FF%252By1N0WUNQ777KwA%252FDMBKIAasGw%252BjrQYD43qxlOaVpOxp2uoc0XrrUH5NYFDQYRkIACg546QKp3xwCrsGxnUxeszaIZh773uApDfjjQ8IEUa3jnwHVgBHzmRe9LykDA85M11sJiLQkzpZPmSiYYCCBQSQcrxdNzoVVeacsNcNIeRL37%252BldezyivPsIURBUlcLapBG9SxCj3otcxlFJvSU3JDB5s10e7GVRUq7S3nwMm6dIyHdlULjQavEm89YytXI5LBoFyHGAs5SUABxWKFSEC30x1TCEncZ%252FSExGLQEP7GnYf%252BPQXj3u6NhuMqgXPtEAlx8pfUjHa83oxBUS6L%252FwVI19Cl6INsGQ27ZiT95ROu6coIBRcRgjocR0ihJRSOISHAxmUHfMd9OnCJ%252BlMAQNCWh7c7BAbMCtHbhPS5ODbQaVIg7Vhi1isw9xUT%252FKAYaG4jI5sSenPyTBANUB%252BH58iqkZcMkZixMwJJzKg85Ew0WI0MrgsI8OCgk48AJ38vs8ommAJAMMxiC%252FLawRPCkZBQaKIjGZgANzq3rM3EjwyyOogY0rC9jwzBMdSTXEHo4z6SNMwUQwjCKa4QBd6JzntA4McslGenIzRvKyeskmMWcKbnnKsYyFrAAVyjAI1NoSOMQOAMmzjAyUyxKW9AXjwC08BZCEF%252BigsDTq6QhP8E8JCMKNzEADdxhGZoAROEKN8U8PGoFBjAADOkQhW44ZviXGEpaWjjxqCoBggw4B9AWKMam%252FYGKD4kh1F5oSmgEECmwKgiWUwLezTSBswIKEljyaMayvCPZzCgLkKJAg%252FAUUpDLuEhi4RCBSWJEYM45hgJIEeRnNU%252FhmHpDUZQXlQEY4kWiuEOrQplJFdZhjVcADjs0UI54rOWZLjSG3J5BSNmwg1FJqZkcNjBCR9Ut2uEMDJvCN80N3GBgTltLKA0i%252FzWQYNfUSAhqaRbg4aZM5JQy0JrSMAFyEYDL4UTC34q5xlAxshhOhQrDgAR4OA5oBN1xD%252F93M1CRmOevAj%252FwoyooZiXDHqlbp7BoJkEoEIfESNSWLESgKEWBSKgkpckCQJ4OMtofAIc002jOEmg2GheoRVoVEVi0dDmwsRYyW39cqX4QmrKbKIbCkgAcMNg1TxItJswuCeaXGhjR1eRF%252BQkBqnJU54PpzIx%252B9irh02lkzoy8IA9QRUzo4iQpVoUAKweqQ4VPQu3iGJWT9SHC4WwRF64UYhVMJZ2WggFFkHTjUJI7JXKk1O9OnVXHoVkCThqVwX6Co%252FqOEpN7jDXPKaDFYOZNTECxUAhKCBbxtY2UX2hQACAM1sBYCAwCyAD3QBjWZmQ8QoXMSVm%252BkIKJZySWOAqEjS8J6boBqCh%252FyKaw2n1cEdeOGqvRkMLN4LigKLMLbJreMYDurGKALjUEplAKC4ktEG0BLcMQGoNXmsAnPdGs7p9aZdnJ8uDVxmNtLnQbjtH0M4TqOAOFyhADoYimNm6lwIC8FsFT5OGvyRgMbAqVAAE4J2%252FEKeU0SXFpOwDi5cRRY5iWAUAXsswFFJNmwRDBhouNQXNCgC7TGCwS0zQgCJjQB8sgpMqkMONvOQnAbSzjlVpp4NQPGO2q5hIBSQggSEdtz22IUpxN%252FEXrEQ3Bz98BLLs82EqfCEHC4PTKD4mnALGA5FMoG93jJJgEZxWu0fawx5UQIiEmAfKAXDvjPVyZVj066gS0%252F%252BvxGZbiDbPQABD8IsFJBAABS0aNBCBMngnJd31yZCM6ZMChFyklUuMUTScE5kSUAMBAcBYYKvtbj58oSPeXvkY3Th0My9wQjhbmmDwGQVYPVSU3y0gAj1tkYRG0SmtnHrGEJvXEcjxDzGgBswzThoYcEHQGhhKa2itAJ8fIeR5OIBVvhgCBSbw4aIcQyvNEs8CLEOGIyBgUKMADq9sY5whTKCU0GjyrDYomD25KK6qSoMMd9qDXZ0CB%252FiTDenaNmeJnVsWk%252BtEsHaQkQCkWR5%252BhoG766GZDBDb2HqqVHTXMBPjANzJKZpPsc0oAVXsVmmjwKV4fjayu2bUFXpMmBT%252F7EMjCFBACoSjpJ9oN3KjmcqbcjgSdd6tWhIEAAczYYBtgv0zpQXGjSn5C4txqRiqREWQhoRyBBywZwqHzVA7SptCzdjcIkCZEcmRwSPbpoWO9KRqMAsr65JDciiYnN0jUtaQux6I9WwkLxf41VAMZVnJ8QAVyzkGtTuKBS7YBn0SMEbQmcITqFv55KI6pRkv4glYbCSsWAiFJ3BgOKqDhpJRwcric3AIJGwa6ygXwR9cQiDlW3UHH1Z3evFCmWY8veJQ6Mlyrr%252FKq2S%252FNeoOzPfw03ijwd5biWrsjvK2vWvPoC4zoVFHxo0JCKTr81vSArngMAfJz4EFKicdGTYE%252FwMhAcYTN6jwZBtHBcDHPHHwYbZBcgnjdNFASF7ifp3lWfcXQ6ehDDszPWSkABiAfHPQArzAAqolHalXfhZwAf%252BAUocHZvcRVjVRF2uwETsAAQMABZdgfmB2CGGUgaLSBRAkQgRRBkcgfXDQdSZYginYTg2AR8lDP452Jxxhe7JRBEgAZGp0QlzCWKuwJRIwARcgHsaHBZkghICyhSb0YR0hQRCXO3rzC3CwfMpHR01oHXrwADsQC2lUP2l4S9NwLf%252FTQkFAc07XUWUFQBKwBUBwGhkHQMakho9wOTSgCGqEAC3lHBL3hc3DAviQU3d4R1BoBw6Qf2mYitXgJTqgBf%252F1cQmOISgYshxq1TsashiuYyqX4FiOOG7IR4k1IQilU0%252B5syiSQwYnsBKuUgAkwIwHgAe%252BcAF8EAw9yC9ImAWOlgkodHDsoRiWIHCjsDyF0DswQzeEAEAUUAeEkFi6xAnnB4yIcBnjgyHsYB1ucAYj0ALwpA%252BmiAFIhHY0hAasoCP%252BloWgxQmrkJCr4EC293bjxD%252B28Ax18CtnJArw%252BCV6owtmBIFKaAZz4Af4UAIPlnoH8Ad0F5B%252BFEnfKIn7lBj3937%252BdBvSJBdxUQXp8AyYYBMLYALscQs5SUsXuUXDdwavoBh5IVGZIR3PRAdtgAcm%252BQv1wIeRNH8PVWiwhIn%252FRuNNAhEXkPFh2DBPUOY3tjEUNBGUPIJS0vITA3AGDSAARdYHLFCS0IYCvoAPBsAOCagGsxVS62QDXAIHv1IYXuUXu%252FEE41Vm82SWX%252FIwYoAYR9AfZnACAdgGnxBhkvluw8AOt9ARzRAZa1AtD3U45QYPS7Yc6mACMxYKIKOY%252FwFxZ1BlWhA%252FPcJ8GPAHEVYCZqFWWJFe8AIYhhRq6lAQ3ZES3TGaZ0AKG0Fs3nMIg8WaPBYPxoFhHsl8e3BkjVICI8AVSlVPoYYckyEexVGWkXZZ%252F2FKEIABlgAvjOmcuiAXgmkK40IznyQWEWAATrckMdFtfFNPAbYiUEILRBBl%252F3jxZMZJLN3wCZaAcb%252FInuVBnu5yj1OglJ9kD3tgLvcQEzGSlYJBVwsnKeApXFgzEKT2SitkHjG2AwKgQZrFoJgxBMG5BJ7mMwgWZKR4ggHgKH9QFI4iYQ41W%252BaWGJGSPOLhk0RQduXmo%252BdmHmQ1OEHQHPTFoq0JBWTgGH8RZg4qJv%252BSXY3CCwYQANMhHY0SDESwESy2oezlIlRnCDREMWM2QuyxG3zBWJKiF9HnIS2SSNgGpf9xCO2xAEZ5WWSzk%252B%252BZdWriXQsmjXTpKGiKb3KWkHRCCwOAAw4YXqZQDotRKMwlcPCRPORCCzy0oHoaB%252BrwFzzBSJ%252BgpX8mAl7qDv932AApgAm%252FMp5EoRReyQ2neAsIcFUzMDNE0nbZAjppUXYeRwrfZgtXMIaVFaprqA5hdk1NYGtToHwqt6U3uqVHIgwNoGRXBiv4dhsFJwMXIAECIABrQGrVAgvRVkiqmReyaTRXxkcA0Ffe8Y7Kaj%252BGV6petYPRaq1aV612IAIgma11IX6x1iKriRfVgBpF5671BBTeYDTccBW24QBZpm4I8HH1eiFRsLHOuimhUpJn8lcHcKMs0ITXaa4zBnUJWRpBUBHecxhsU1b1RHHlMTdSwBH0AQadRq8Z%252B5qc0DMKAJlLQAH2eSQXEAAQEAFR6GeqRWgbQ21TIS%252BOcQs1BxH%252Fh3cMbWelufAXEXRU0ghjPYs77jiUV7B%252FPaAs70ZkmyF5rNoLurIpPUE72dclsmFwu0msOdgXmCqs0uCIgJgAlhG2qrIRi8IADvCSNDAdJikdZwIT%252F4oH04o%252FwOEaSlFWhVBXTwBpbHURy8Gz03OxOzAuQQC2gvsGcvE4D%252BAfHrQHuqUPm8EHwuB%252FUXGDH6Fsa3M1hNCLXIK1ppODnusDVBYYB0S2pWsQsmgRh7sE5lIAJ%252BAAc1eS%252BlBedwABLFdPA%252BE9vldQuudAifd9xJO9%252F6E3e6Sck1i8B1UJBeAbRWEHREuSJvhuKsC8wjAIhdEv87abHLEGtABNsYG4GIke%252FwmgjqBqvhhCOQtQAClRAN2lj%252FrYvPUAv%252BZSSKgRV8bHNt00UBSYihaxALNRBQpwILNwPLe0ZeVLwAGhiWFgAVK4C%252FnwCznqlCvgC%252FsQFUKBQ8tTHOkCZQkJHB6iid4zfjlAOkagFEjgdIm1Sj1oJQZXXyaMGbn0hhbRsclHB49rAoCgwBQwjVEUukmMBrQwDRGUAQNQB890jnk0TpjEwTbZHor4xQEpRrDABk38H1z5RDAAIC%252BBTPvYAsVgVLKxQ6uEEmsDGx6CBCZwC4Kckl%252BwsUFQQYWUG8%252BlQUBQCIbkH0bAJRgwx3RMOZ7gIybbJvSQD9JYDwbwwV5JF0jsRv%252BA8U3QZyrNkR400SCBMUS9YRtjWg5JMT%252BMcB9BoauarBKrIQYQsMJEMZ%252FzAAigbAUXdQ3EOl0%252B9IGJQXM7mTj9UyUkwR6joAOEGRk6cAs3EEP8JMi%252FXDlmMMwAso9tMAxcagdtRFYtppcfzEd6E23BvJMUclXodBShUquYBKcfnDz%252FE1DpOs4w9BGNyTpKwhnSARMLbZ8PxryzuxgIEK5OMZbegwSHoAqOYAG7NVBd9X5yBGXUIjGO%252FH5P5xceTdAFnQUNBTO7QCLDgAH1CYDttAd1gMCoyMQo4kpKoQU5UAgXi4QJF1LyU0Ow51JGc0aUYAk0q9IjNA6JcbxBk5L%252FBbV8C80HAVCC5VUHD4A5JRYjCgLW2tStXZEqTwcGqqDD4gHWv0K8KJOV%252F0M6ejGiTv3UV7AJwTwIxGwkf%252BYO7RQBvNACdZCt6RgBHvVhr3VZlrUck0MJMNIiHGop%252BgaUmxIKmXUF%252F0Cmda0WavDPr8SjBXUdlYlaqdoorFsfQjGkvAHWOwZA7pAXmTxpATYr8WJU53c1xifZdL3ZTKAMRDCoNLDXfMBgjuIoSCsWIwDO5MlcwdIQYCABs8EefeWjopU4y%252BFYJYxWaDRjHLGevE0Dh%252FDbaiBGV%252FFuZrFdalLaI4AW72IGM9pXr2Bgs5IWauWawpwFR2BZu%252F3dOqYG%252F3ndPw3BuOmtdSPbdXNwJ3xh2JW1nuIcr3MqYIvDG3kFgi2SnnnK3zWhLRZBzKgVptehBxgwD13dDbvyF7tVVAfzAy5CWjJ24UKzNEX1MLGgv%252BbBhRgefIC34XIQhURW3CoXAM7IYBdNqhnweKv3ft7oEJA9MomYF0rgKVPlYSL6I3q5Hvt948iAPpWwRDRQqETWYI7CAgEgDKHoFQ0gARHwTKQyWl66CmPjx%252FK2ZrTDDbNGYSfDxu5KMwSozUeO5RiyUAcwFGrCdf23tvDLGYulPMeWF1CniNrWBdLG6MlB53BQLeJHM%252FaBPwiQAM3h51ZCFYuSAIFOA3%252BwtLygLP%252FSKAF0NA4Al3nZkbLhuW21ed0O8J56dw4xa8ByrQQRkN28TRV%252B6gpvOgP86Cp1oFpcZ5IkiR0wCr4HEU19kXoPkcWtsH02jh8TE4SMZ3iC4%252BmNuUCQMeyr4kFHYi6WaS5bHYWDEHB%252Fw1gu2g37RjGJ8ifeyMF2timsGCrFMhLe%252FkRDk%252BNGsg%252F5KAwmaIqAgAFmOwNFpu375kxKQQ52MBEGOSPwgU%252B3lMJUxz9qxJnA3e9Ifmzh3uWfDL3QC8MicBJXUQEREAApwem14AAjuF4dC4gMIe68kzLCpPHigB4e71XBfg6bLg%252FUC%252BajTA8lKwyAsD7eEMDBSXWAKwO59Ez%252FpNBHQXh7uJTZjyOJTiEEGt%252FzSG4GRnAM0dEL7eSMMEwB0FsFhsYGyoMSK7SOQZABY%252FOzWQ8ZKIRLZBtIKVENXe%252F14B4GQW8kJUjwtXmHUdkCYdVNVpUFapoDESAA93RKpzsIG2N6C1HHRyiebFTEfl8JTXNIoSDKQf4AJKkPROu6b%252FoEW%252FjvfG9o0fBqyGB6FrQxWgIhqn%252Ftfg7yS4AAjhAg00oHMBG9rvoZvZGTYagdh8gJgpIO9AaUWhILsC8LOJsbq0TZ3g47NMPBh7IHLvEAtakC5QWNkz9DDYINIZSYU3EajYTRWyhJWwkNGLuanQ%252Fu4u4UjmCHIj5obSBo%252FxoDAgo0AeVSAWdZJpWVrImyrEzlspm18jyjKCYWl23XM2VSGUiGBmC8jtIptWq9YrPaHuyZYHSlCETpYD6jDQ7Hw3Fov4EKREVhgqRQvITFCRiWQEB8nagkUOgwMEglJClQVLQk4B3xJcgsUAQBtGx5foKGiqYshFEt2AGgrR6oQThQGKg9HDwp9E3gLSwB6HmVQtBYzFgEf%252BE1Qvi2QCz2%252FOws7DT6ciVRA1BwJo12e39%252FmlIl1KqynqmdrTk0PKSK5JUwQObcBA8DDdPYtKD0%252B0SSAqQCJEpUgvXShiIKuIYOH5qQV2UBGXPnDFw4A6ENBXYUjHA7kQGFDRs8Kv9IA%252BJkxzVDGbSd9MODAsUI1aag1DQBBUyIPn%252BCcpZAZo8F5c6ZeYWmgToFF4r5iURhKiRnK7ThgxowRwluPBD24HbBapUmj1B4Bap27ZQuDEqNO3oOAtMzcM4AcAqT540aeob%252BWTDhVp8U1gA8SBtIJkp%252FI28emZHh5Qy2li%252BvKHWJbNGKSA9kbJUOTQkFj5MkQfTS10gYU%252BUImqKtJ4%252B0C5TdmKpYCgUINHdjDv6T6JEFcJHWBR2a9J1D2RKqpgAGj6PKpCADSFJht5zMJ%252BaltuKIQkXh5n%252BKY0TjXPLRq2pzqrDI6%252Fbti7PTVtEDpvQjGVKtcA1MwAVYQgCcnZf%252F4DcLIFhUGUstd4ADEJzDgzSc9OJfGPgo1klYCR1BGwvU6UFgXo%252BIqKCKo3xRBRiLoHEBhatEiNdMzqTYix87pGjSSTBkQBYqUqSWAQxbEXnBikt2Q1wlx0l4gQGsJPfeSc7IR2QPg3G2WxIPhHHbFAw0018v6ZWQI5NrYgGDkzUcsIgDUk65CgRSVvhjV2giuScXWa4gH0oFUiHoVkZKMSibi17xFoNoxoAADG3UaEalNga6SJ96XqnhlUx0AUSDZ97gBFgWGsGoqoyw4MRbCA61SAG04GkGO3XmGSgNih7Bawmb%252FhrGoBVM4MSgCnAmnzJRyTTJqs8eAYYXYMAV%252Fy2DiElIy5wNzPgZD0D8%252BqavAJwa0woI2WPHoNUGygevFiBg1bjQPitti6OCAQMEsz5wAS2fMRfuiVSIyoMFJBxR2LkuxPvfvOeKIJNpdkDxJr2rSjsOXGw4UADArBisrsXkygQBgF8hTG4fvvUGAUNSODOMwQwOcrHNe7w4BQI0bPTvxwFf%252BMfJPYywhwUNylyCBX1YQNMWSf9BBtQ332wxA5Ii5vHPVkoDA7gEnzz1twDekk8eqVbxtcw%252FDE01tBnrTIPPW9t4S2loPzO13RZup8kKZYugwA1tFzWMEeCa7LbbkJawMwCzvtHABe38zAlDe0dGENqYp%252FACZwhktf8D58Xdg0cuQitO9ReQXj2p5AXMeNdnlpiA99%252FRnAx6DC5PcZs0uti%252B5QjAD5b6xS8q0qIUFKnSrV1ufCZ4ZtjpZyEAO8mztEhD3%252FZP9b0Ho4eYxtO7umFtXQ3AGhdobQZGE67ygPwzyDAJmuOvoL0MdmTSRyTff6cv36tEY8inOBiYb3kAIIMsDCA7913AAQ1swxoYxDTsNOIFegBCI%252FJCAwVEoBM%252B2l1KOGEdRkQCOwaElqvaAiUIQs8MlJrTckgWvgBthxc1kAQH%252F6MMB9ygL9GyD1fGZCQVrnBVhDhFi2h4gcnF0BVrUENdmFYMPvSCegThA8VUshPNUIEBD%252FD%252FS6FaYKIkquoSp0iFASAwJeclZULpoICEgAAqlCijg9moykJsJ4IzEuoJajJJBsaIRqpdixFy%252BVgEZSi%252FvCwtCoiahy9ylA%252FTMG4m33oTJCZzSKrBrSiL3FobPGaCEwwhRyM0AWFooCYu4A049gnAJ6s2jgU%252B6GeykKADy2YMMNQHEYgw5EzINrJAXgVmDzhQLW0GgwatJ5efaWMEX9ERwihjCJEYVWbQ9soPgdNg28lkM5nUwkoAxiKfaeQrKKiSUhiJnF3ZZBYgsxsKKK%252Bc0MqkDFbASEutwwx3K9dEDJKdLFgybMfUp4LC5KJyqDNGknOjlGJYi2EUKwurHBIW%252FwAVlpiVh6GLWkQX%252BAkgGjUgOXOa0ypGZ4VVPqee4tiV1wgnUiYpTxFjWmAXVvpEXE0ONKxwhydShKgqRCJIhZOD2G6qRI35oYEz2ta24BgHbkbrZSmwaaZuIA7pIGAwXHXqmvJprTCo46dzsio6jnaFYYnjYQaDRHoGEzSyHm9UCcBaCfrFhgL8FGAYWaiygCVXpfGBoHfAq81CGZkwPMCB%252FmJrGtiQSdOQ6WHwooLMDsvYmzGudStYQ2Q%252F5kb4EYxY5FKs5SAFrmKk7LOpMysX2CULXRYAfhDtQcGWRjgyuVZ0TZXtzRzrg1j5c2tsCNj03jFcMr0paC4lruqeEP83HgCsYwboyNz24IJQDTcwvTtceKlLL%252BPuMKSfmRVG5nYAkxFGYag0aMh6B4%252Ffmdd4OoUZGJM7VIumoQD44Kvv6Ju%252FtkEBvoLTQX6NNzLmfWVyAmDfGwCMhjYQ8K68HVo%252BdrYI6TXYweNIHw8A668GSCACkoOeICaIYYDkhsE80B0pUnJCiYR4ttHFJQ8i2ADoYQQDKpYcAZ4YwQdoApsu2EUOjPCdBOSCIDfOsQFpQFsTqJEHDYjA5ALAZTcYQHKzSOmUHODLPrhpGXqg5AuME1Mqr5CfIe3rA1JMUQwEgIZsyDMFJCDQxjXrJSM5ydlQEVs4ky%252Bdz2DAbh%252B0rwD%252F5Bmg733iA378Z09UgBLlRbTboJll7CIgKWGGdABEowYBxJDTcI7unFlADjRQCAKkllJpL62FS7hZ1WiEFDmksAZGRkAAP57cVFLagEbZQ2G6TvROG10CdpCa1Cl9r1QdIAEJNAARLlCABH51g0EXKF%252FBW3Z1i6No7PYsstS8QLRVPKuOEGROGNiBRw8aqCCSu8ptiZcU6CahYF%252F7Atr%252By7fpke9mss7Z0vS3wjmB1YPre3mtXri%252FIS7bnHHh3NhlOKYs7lQ38RdSHO%252B4x0WaPM7AgK9HGLmtS25y4jhqVCxvuMtr%252BekasGvlLK%252F5xzlDLYvNnOcMHQpt88W4oAu9%252F5ZwC6WjqoD0pNeyWlbJ18T9y3Gol9O4RHf6zrGO8GdoXOcj93rUi0NiKjyd7HGO1l6vkHa1k484MKC51RkO9xU66QtV3%252FjY727AmS7w4RGtuN9TVwqi6B0Lby%252F8xUpqPX67veuMr1p6vJaFxU%252F%252BqTBru%252BIln3l60UAmH9QC5j8%252F0srzuPN9Nz3GWJVzK5Se9UtqkSnmLvi6E172jMr72VV%252Fdd2nkSx6vz3u6Qb8kTrcB1cjPsWNf3wmkZQsi8g16T3%252F%252FIb6POXy7EHsrx8cs37hLZ%252Fovvcxk09qbZ%252F71i%252F%252FeeCWcuYXf2vsX1EYkrd3rq9%252B%252FubJJwIX2u%252F16x9bOP%252BDqyQeKJBfAD4EAlkFAt0f%252Fv0eAloGtVjID4jCAUJgQ7CLEzSgA9rdBbKFOMzdKFigB47CfkVE6hkgAJJgQwAe3fleB64gRIBg43TDCMbgFpgghqiCN9jgDWKBY1mZ%252F8GeCvpgUHBBaXxDDxbhKRQHJwjhEObfEobCDOYFOCihFB6h8vGUFRIhFlqBE4TBM21g9UWhF2aBW8jD%252BzXEFZphDjIg%252FEHhA5rhGYJdCqTf5XXhHGbhHpDCQ7DhEtLWZrweD%252BahHj4BgkzfE5KhHLbh5sEKJ4zh%252BBUiCUqLUCwCerXIICbhJJKgGumUBLKdE%252F7EH5af%252Bzkeq3CeT5Di9dH%252FnnWBHMwkIlCs4vGVlLQYRyJVwhNEYijMouzZi3G4SRcMoi3eYQqWISX2n4Xc3BGm4ihyYik%252BE8xp4j5Aniw%252BIyu%252BxRLp4Ak6yBauRS9mHkkpD2BoIgv0IVuAY%252BYBBhp%252BoS5eRjqGo%252Fi1SRlgBjwWXvRtnxPgIjpe4%252FO14hUIYzES4jGyXxhOC3rFwN8Ihz1i3T4copWlADehlXkwJNQFJK5lIxMiIUX24%252BedoheEVmYIJBcS5PPJozzCRQ7ijCieR0XWXP8dXhoi5H5V40J2ZOE5ZBo6XNglnze25E0WHvgZHSIOoCJChEuSHcblIksqCFJiHe094hOUYz0C5ecl%252F88%252BeoE81GSCOOVTwow8YCVXVqXfXeJmRKUdrklXWhxcVEvlDeBIWmNJ%252BqICXpk5ntKiqCXEBeOYCIVR8qNc6h5C9iSE4eVYql1olVRYLkleQhzvtcqzMCa5QSQXOMOrQKZheqXc1cAu%252FiRgqiP1WQ9YwqFNeibjgeFSOiFcBkdkcpqT%252BEHvQQtrwhma1B9nqohs5tiV1abb4GaDwYofEObN9CZ1Td8eniNvYqbFkZRxTmVsJufB2aIW3qXxDKdTVWJ6wI3jkE913tTqiINSqhx1PqeuFV1tqmZajqeqgaBVUMRoMgp3ltO9HFdlaicawafSTZ8pTF1zKs59flJOxf%252BAUISnfaYncSWSYy2dbdqMf6bOJyLXfJqAgi5ogX5W7a1kq7jnxTCo4aHPCtSnPm3o4jiih57nhJbmsuWdPFyNX%252FYnhZIVdobBzrBoi54olV3CUCCeW%252FBnLYWoqlyidTVhq5QojTLiJ2UoM7pmmAwoWfXoN%252FxoCT7pHtTfjuoTZd1WGrSRCxqPd2YoQoreAQzpduKK%252B9QJrpSplnYaC5zcrVlZgygaMIZYK6DDGzWQDKEDmjaWJ%252FpBXZpdT%252FqA6PGkbL0XhZhplk7JG1Hbf2KZhTYKbZ5foBKX%252B8jppNLCoYqGGSimcaoF%252FFUmPlbiZKoHX%252B4BaMap%252BxDqjNBpK3T%252Fyza2BasCBZ%252FmIhjmjDhW4nGVY75Eyowy1JyKBhxZ6p8xiEpGhDwCBajiGKvUQBM%252BqKuCXU7tTJg2EytkqZ1E1ozEwGb8qSie5kt5AvI8E4bQJjdZYraOiSlQBLSWE92kqrPVnzkiELi6CLOWq6ut6ZUtZ1tYKGLWZqZSGcPhCqtkJO25Gayq6TziXJatjtzpFUgeomU%252Bg0y8xVbqGuZhq%252FjhaMF%252Bwz%252FK5x46LCd8mtQtI84VBamSW%252BnBBf9FnzesabMKZWIaR1m%252BCL9Kpa2GbMkS4T6uqWAyUfh9ayAKq70oTymk7NaZm5BQhK5SVw%252Fi6iF%252BZSimYRjWngm2osOu%252F86LZNLr7RWVqpoSYlytVu35%252BSlyPVPy7CTRKcK12AuGTkvvCB9FSGzJXWHGGN21yOpmVOxyXqfdZuXWPZPdWi360NbRHmm%252FdiHBFsWNHquUotOj6CTe9i1a4msOGseSJp0Fbp9bACjOEeXYRgRbhonQsp1KHi26Em6N4mA0aiq95kvaUstbOmLtHe3kySZb3uIhmo%252FFgpFgru611m7mMebWnSbi2uE65mS55tzPIa3FMWbo3Vz99S2x9s7N5cvL6t7yCuMtNsuoMhHY3SLpQlxemqsOuspCEa13nKv3Kq%252BL%252BoAoCmMM9Jd6pEf3oi%252Fcqq%252F5YlkQNgpRHB6Yzm%252FNuf%252BkUrbvDyrlVl0sBLokrn3CyYVh7K7g%252F8Kh0aUXyV6gfwqvw8lo%252F94dd4KiVMovFvZm0%252BHcyxquB7Lm0oLl%252BRri4DkfUEwvFygA%252F6Zw%252FFWOT6xsq4Ra8k4whf4tznlYDE%252BBPQ7wXs2BzMZwOpolro2B1hYxUGajZlxl9w6uF9qgZvSXIoDBs2LwDWKe1d6oz01uEkfxEnMcJVix3IIl0RnHAUjKCPswHvpbGxnAjSqgZgyFjAJjFqewYDXQHguUFU8u9uJwGyveHhPyXLhRHZ9vGAvyFsRaUohaZMlPJBfAJEuKsC6yZTiQA83KJKsbHLuRGYzBJavI4VWtKJvyKaMEsieEAAA7%2529%2520%252D16px%25200%2520no%252Drepeat%253B%2520color%253A%2520%2523000%253B%2520font%252Dsize%253A%25202em%253B%257D%250A%253Alink%252C%2520%253Avisited%2520%257Btext%252Ddecoration%253A%2520none%253B%2520color%253A%2520%252300C%253B%257D%250A%2523controls%2520%253Aactive%2520%257Bcolor%253A%2520%252388A%2520%2521important%253B%257D%250A%2523controls%2520%253Afocus%2520%257Boutline%253A%25201px%2520dotted%2520%2523227%253B%257D%250Ah1%252C%2520h2%252C%2520h3%252C%2520h4%2520%257Bfont%252Dsize%253A%2520100%2525%253B%2520margin%253A%25200%253B%2520padding%253A%25200%253B%2520font%252Dweight%253A%2520inherit%253B%257D%250Aul%252C%2520pre%2520%257Bmargin%253A%25200%253B%2520line%252Dheight%253A%25201em%253B%257D%250Ahtml%252C%2520body%2520%257Bmargin%253A%25200%253B%2520padding%253A%25200%253B%257D%250Ablockquote%252C%2520q%2520%257Bfont%252Dstyle%253A%2520italic%253B%257D%250Ablockquote%2520%257Bpadding%253A%25200%25202em%25200%252E5em%253B%2520margin%253A%25200%25201%252E5em%25200%252E5em%253B%2520text%252Dalign%253A%2520center%253B%2520font%252Dsize%253A%25201em%253B%257D%250Ablockquote%2520p%2520%257Bmargin%253A%25200%253B%257D%250Ablockquote%2520i%2520%257Bfont%252Dstyle%253A%2520normal%253B%257D%250Ablockquote%2520b%2520%257Bdisplay%253A%2520block%253B%2520margin%252Dtop%253A%25200%252E5em%253B%2520font%252Dweight%253A%2520normal%253B%2520font%252Dsize%253A%2520smaller%253B%2520font%252Dstyle%253A%2520normal%253B%257D%250Ablockquote%2520b%2520i%2520%257Bfont%252Dstyle%253A%2520italic%253B%257D%250Akbd%2520%257Bfont%252Dweight%253A%2520bold%253B%2520font%252Dsize%253A%25201em%253B%257D%250Asup%2520%257Bfont%252Dsize%253A%2520smaller%253B%2520line%252Dheight%253A%25201px%253B%257D%250A%252Eslide%2520code%2520%257Bpadding%253A%25202px%25200%252E25em%253B%2520font%252Dweight%253A%2520bold%253B%2520color%253A%2520%2523533%253B%257D%250A%252Eslide%2520code%252Ebad%252C%2520code%2520del%2520%257Bcolor%253A%2520red%253B%257D%250A%252Eslide%2520code%252Eold%2520%257Bcolor%253A%2520silver%253B%257D%250A%252Eslide%2520pre%2520%257Bpadding%253A%25200%253B%2520margin%253A%25200%252E25em%25200%25200%252E5em%25200%252E5em%253B%2520color%253A%2520%2523533%253B%2520font%252Dsize%253A%252090%2525%253B%257D%250A%252Eslide%2520pre%2520code%2520%257Bdisplay%253A%2520block%253B%257D%250A%252Eslide%2520ul%2520%257Bmargin%252Dleft%253A%25205%2525%253B%2520margin%252Dright%253A%25207%2525%253B%2520list%252Dstyle%253A%2520disc%253B%257D%250A%252Eslide%2520li%2520%257Bmargin%252Dtop%253A%25200%252E75em%253B%2520margin%252Dright%253A%25200%253B%257D%250A%252Eslide%2520ul%2520ul%2520%257Bline%252Dheight%253A%25201%253B%257D%250A%252Eslide%2520ul%2520ul%2520li%2520%257Bmargin%253A%2520%252E2em%253B%2520font%252Dsize%253A%252085%2525%253B%2520list%252Dstyle%253A%2520square%253B%257D%250A%252Eslide%2520img%252Eleader%2520%257Bdisplay%253A%2520block%253B%2520margin%253A%25200%2520auto%253B%257D%250Adiv%2523header%252C%2520div%2523footer%2520%257Bbackground%253A%2520%2523005%253B%2520color%253A%2520%2523AAB%253B%250Afont%252Dfamily%253A%2520Verdana%252C%2520Helvetica%252C%2520sans%252Dserif%253B%257D%250Adiv%2523header%2520%257Bbackground%253A%2520%2523005%2520url%2528data%253Aimage%252Fgif%253Bbase64%252CR0lGODlh5gBOAcT%252FAMDAwLW1tb29vcbGxs7OztbW1t7e3ufn5%252B%252Fv7%252Ff39%252Bfv7%252B%252F39%252Ff%252F%252F8bOzs7W1tbe3t7n57W9vb3Gxuf3987e3tbn597v78bW1r3Ozs7n5wAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAADmAE4BAAX%252F4CEez3UZ1PNAjppCpALM9GxNgLXUfD8pC6BC1mMoLApGb7nUMRaWBLOmwAGOREVlqK38LNNwbQIWm2fH2aLScJzf8NqI1Lg8Cqq6w9EoOAwPZT0KFBkIcVhkSwlQh3E8EDhrOmELFEQ5VTMJRwwQDTtXFRlbj2hRWwkZhZhMDBVINQsZMrMUgqa5PHMiDw0qdg8igIAOUjxrVo9YEE0VFaG6sZ5Imj2zuFxFFBQ1Smm5UAATzeJhnkEV1%252BqWF8268DO8JA8GbcIjD3%252FvsrQIuGegKFkyJJ4NIhAoUULGb8aEZwQlDER2a0o0WdDeLYCQACCNIwsflqKxZpyECx4N%252F77hpW9ePgcirkEwF2cjE3DxfhxUB43HK48bdRyjQeFCD1W3KjSkUW3JxlcAStZgFATLUACMMvBQFVVCCpWm5rR02Qvmga3qdEnt10pt2iGcgPBQOhHjz2gVKAx8liEDBHUJ0m5FogxZ2sAAGCRQTMpCLCaq%252BAVe%252FAlDW7Bi5hgwS3ZzTBpQ4a3dJNggggqcyhjxhrru1JmMLCB4CMrCsyiLEWMtDfqyKwqjZrYCqSChT1I0WkPIIME35iUjDFwgOwLC9LPJXT9ayyBDynC3tTbhaOYZrISELDhYsEA31kK8VfJGwi3D1RoV9krh1kD78x7DcEadZ9h5cl84YECEWf9oNvUQyYFidHPFBSWh9p8YF7EHIVEcWlAIAReGIYJ11FV33SbiGcTAAwBIiJmEDLhYw0JiDMRIdx%252FpYGGIUyxlRoqUfNJAfDwCIMJ1JR5gjwgyhKaSVk6qeBhA2pgR2BNKVSWDBRDMVCQcxk2R31470NKAjzwegGSSJOwhXooGvfkiDXAG8RgTyCGn1HvoVXPRl2JM8GcPD9g3g3AWMLfhfwc0wKZYhc4gIzx5SQpWik4GxQRfacGJpSDOASpfKN0oIEEGDYhq5JqPHiAhnNIsNgOsuZQmISOlcWnbM7JqFxiRPQCrKhw9FWQmi4Ce0Ooc4nVkkIy0miKjOq%252Bw8wP%252FF%252By1N0WUNQ777KwA%252FDMBKIAasGw%252BjrQYD43qxlOaVpOxp2uoc0XrrUH5NYFDQYRkIACg546QKp3xwCrsGxnUxeszaIZh773uApDfjjQ8IEUa3jnwHVgBHzmRe9LykDA85M11sJiLQkzpZPmSiYYCCBQSQcrxdNzoVVeacsNcNIeRL37%252BldezyivPsIURBUlcLapBG9SxCj3otcxlFJvSU3JDB5s10e7GVRUq7S3nwMm6dIyHdlULjQavEm89YytXI5LBoFyHGAs5SUABxWKFSEC30x1TCEncZ%252FSExGLQEP7GnYf%252BPQXj3u6NhuMqgXPtEAlx8pfUjHa83oxBUS6L%252FwVI19Cl6INsGQ27ZiT95ROu6coIBRcRgjocR0ihJRSOISHAxmUHfMd9OnCJ%252BlMAQNCWh7c7BAbMCtHbhPS5ODbQaVIg7Vhi1isw9xUT%252FKAYaG4jI5sSenPyTBANUB%252BH58iqkZcMkZixMwJJzKg85Ew0WI0MrgsI8OCgk48AJ38vs8ommAJAMMxiC%252FLawRPCkZBQaKIjGZgANzq3rM3EjwyyOogY0rC9jwzBMdSTXEHo4z6SNMwUQwjCKa4QBd6JzntA4McslGenIzRvKyeskmMWcKbnnKsYyFrAAVyjAI1NoSOMQOAMmzjAyUyxKW9AXjwC08BZCEF%252BigsDTq6QhP8E8JCMKNzEADdxhGZoAROEKN8U8PGoFBjAADOkQhW44ZviXGEpaWjjxqCoBggw4B9AWKMam%252FYGKD4kh1F5oSmgEECmwKgiWUwLezTSBswIKEljyaMayvCPZzCgLkKJAg%252FAUUpDLuEhi4RCBSWJEYM45hgJIEeRnNU%252FhmHpDUZQXlQEY4kWiuEOrQplJFdZhjVcADjs0UI54rOWZLjSG3J5BSNmwg1FJqZkcNjBCR9Ut2uEMDJvCN80N3GBgTltLKA0i%252FzWQYNfUSAhqaRbg4aZM5JQy0JrSMAFyEYDL4UTC34q5xlAxshhOhQrDgAR4OA5oBN1xD%252F93M1CRmOevAj%252FwoyooZiXDHqlbp7BoJkEoEIfESNSWLESgKEWBSKgkpckCQJ4OMtofAIc002jOEmg2GheoRVoVEVi0dDmwsRYyW39cqX4QmrKbKIbCkgAcMNg1TxItJswuCeaXGhjR1eRF%252BQkBqnJU54PpzIx%252B9irh02lkzoy8IA9QRUzo4iQpVoUAKweqQ4VPQu3iGJWT9SHC4WwRF64UYhVMJZ2WggFFkHTjUJI7JXKk1O9OnVXHoVkCThqVwX6Co%252FqOEpN7jDXPKaDFYOZNTECxUAhKCBbxtY2UX2hQACAM1sBYCAwCyAD3QBjWZmQ8QoXMSVm%252BkIKJZySWOAqEjS8J6boBqCh%252FyKaw2n1cEdeOGqvRkMLN4LigKLMLbJreMYDurGKALjUEplAKC4ktEG0BLcMQGoNXmsAnPdGs7p9aZdnJ8uDVxmNtLnQbjtH0M4TqOAOFyhADoYimNm6lwIC8FsFT5OGvyRgMbAqVAAE4J2%252FEKeU0SXFpOwDi5cRRY5iWAUAXsswFFJNmwRDBhouNQXNCgC7TGCwS0zQgCJjQB8sgpMqkMONvOQnAbSzjlVpp4NQPGO2q5hIBSQggSEdtz22IUpxN%252FEXrEQ3Bz98BLLs82EqfCEHC4PTKD4mnALGA5FMoG93jJJgEZxWu0fawx5UQIiEmAfKAXDvjPVyZVj066gS0%252F%252BvxGZbiDbPQABD8IsFJBAABS0aNBCBMngnJd31yZCM6ZMChFyklUuMUTScE5kSUAMBAcBYYKvtbj58oSPeXvkY3Th0My9wQjhbmmDwGQVYPVSU3y0gAj1tkYRG0SmtnHrGEJvXEcjxDzGgBswzThoYcEHQGhhKa2itAJ8fIeR5OIBVvhgCBSbw4aIcQyvNEs8CLEOGIyBgUKMADq9sY5whTKCU0GjyrDYomD25KK6qSoMMd9qDXZ0CB%252FiTDenaNmeJnVsWk%252BtEsHaQkQCkWR5%252BhoG766GZDBDb2HqqVHTXMBPjANzJKZpPsc0oAVXsVmmjwKV4fjayu2bUFXpMmBT%252F7EMjCFBACoSjpJ9oN3KjmcqbcjgSdd6tWhIEAAczYYBtgv0zpQXGjSn5C4txqRiqREWQhoRyBBywZwqHzVA7SptCzdjcIkCZEcmRwSPbpoWO9KRqMAsr65JDciiYnN0jUtaQux6I9WwkLxf41VAMZVnJ8QAVyzkGtTuKBS7YBn0SMEbQmcITqFv55KI6pRkv4glYbCSsWAiFJ3BgOKqDhpJRwcric3AIJGwa6ygXwR9cQiDlW3UHH1Z3evFCmWY8veJQ6Mlyrr%252FKq2S%252FNeoOzPfw03ijwd5biWrsjvK2vWvPoC4zoVFHxo0JCKTr81vSArngMAfJz4EFKicdGTYE%252FwMhAcYTN6jwZBtHBcDHPHHwYbZBcgnjdNFASF7ifp3lWfcXQ6ehDDszPWSkABiAfHPQArzAAqolHalXfhZwAf%252BAUocHZvcRVjVRF2uwETsAAQMABZdgfmB2CGGUgaLSBRAkQgRRBkcgfXDQdSZYginYTg2AR8lDP452Jxxhe7JRBEgAZGp0QlzCWKuwJRIwARcgHsaHBZkghICyhSb0YR0hQRCXO3rzC3CwfMpHR01oHXrwADsQC2lUP2l4S9NwLf%252FTQkFAc07XUWUFQBKwBUBwGhkHQMakho9wOTSgCGqEAC3lHBL3hc3DAviQU3d4R1BoBw6Qf2mYitXgJTqgBf%252F1cQmOISgYshxq1TsashiuYyqX4FiOOG7IR4k1IQilU0%252B5syiSQwYnsBKuUgAkwIwHgAe%252BcAF8EAw9yC9ImAWOlgkodHDsoRiWIHCjsDyF0DswQzeEAEAUUAeEkFi6xAnnB4yIcBnjgyHsYB1ucAYj0ALwpA%252BmiAFIhHY0hAasoCP%252BloWgxQmrkJCr4EC293bjxD%252B28Ax18CtnJArw%252BCV6owtmBIFKaAZz4Af4UAIPlnoH8Ad0F5B%252BFEnfKIn7lBj3937%252BdBvSJBdxUQXp8AyYYBMLYALscQs5SUsXuUXDdwavoBh5IVGZIR3PRAdtgAcm%252BQv1wIeRNH8PVWiwhIn%252FRuNNAhEXkPFh2DBPUOY3tjEUNBGUPIJS0vITA3AGDSAARdYHLFCS0IYCvoAPBsAOCagGsxVS62QDXAIHv1IYXuUXu%252FEE41Vm82SWX%252FIwYoAYR9AfZnACAdgGnxBhkvluw8AOt9ARzRAZa1AtD3U45QYPS7Yc6mACMxYKIKOY%252FwFxZ1BlWhA%252FPcJ8GPAHEVYCZqFWWJFe8AIYhhRq6lAQ3ZES3TGaZ0AKG0Fs3nMIg8WaPBYPxoFhHsl8e3BkjVICI8AVSlVPoYYckyEexVGWkXZZ%252F2FKEIABlgAvjOmcuiAXgmkK40IznyQWEWAATrckMdFtfFNPAbYiUEILRBBl%252F3jxZMZJLN3wCZaAcb%252FInuVBnu5yj1OglJ9kD3tgLvcQEzGSlYJBVwsnKeApXFgzEKT2SitkHjG2AwKgQZrFoJgxBMG5BJ7mMwgWZKR4ggHgKH9QFI4iYQ41W%252BaWGJGSPOLhk0RQduXmo%252BdmHmQ1OEHQHPTFoq0JBWTgGH8RZg4qJv%252BSXY3CCwYQANMhHY0SDESwESy2oezlIlRnCDREMWM2QuyxG3zBWJKiF9HnIS2SSNgGpf9xCO2xAEZ5WWSzk%252B%252BZdWriXQsmjXTpKGiKb3KWkHRCCwOAAw4YXqZQDotRKMwlcPCRPORCCzy0oHoaB%252BrwFzzBSJ%252BgpX8mAl7qDv932AApgAm%252FMp5EoRReyQ2neAsIcFUzMDNE0nbZAjppUXYeRwrfZgtXMIaVFaprqA5hdk1NYGtToHwqt6U3uqVHIgwNoGRXBiv4dhsFJwMXIAECIABrQGrVAgvRVkiqmReyaTRXxkcA0Ffe8Y7Kaj%252BGV6petYPRaq1aV612IAIgma11IX6x1iKriRfVgBpF5671BBTeYDTccBW24QBZpm4I8HH1eiFRsLHOuimhUpJn8lcHcKMs0ITXaa4zBnUJWRpBUBHecxhsU1b1RHHlMTdSwBH0AQadRq8Z%252B5qc0DMKAJlLQAH2eSQXEAAQEAFR6GeqRWgbQ21TIS%252BOcQs1BxH%252Fh3cMbWelufAXEXRU0ghjPYs77jiUV7B%252FPaAs70ZkmyF5rNoLurIpPUE72dclsmFwu0msOdgXmCqs0uCIgJgAlhG2qrIRi8IADvCSNDAdJikdZwIT%252F4oH04o%252FwOEaSlFWhVBXTwBpbHURy8Gz03OxOzAuQQC2gvsGcvE4D%252BAfHrQHuqUPm8EHwuB%252FUXGDH6Fsa3M1hNCLXIK1ppODnusDVBYYB0S2pWsQsmgRh7sE5lIAJ%252BAAc1eS%252BlBedwABLFdPA%252BE9vldQuudAifd9xJO9%252F6E3e6Sck1i8B1UJBeAbRWEHREuSJvhuKsC8wjAIhdEv87abHLEGtABNsYG4GIke%252FwmgjqBqvhhCOQtQAClRAN2lj%252FrYvPUAv%252BZSSKgRV8bHNt00UBSYihaxALNRBQpwILNwPLe0ZeVLwAGhiWFgAVK4C%252FnwCznqlCvgC%252FsQFUKBQ8tTHOkCZQkJHB6iid4zfjlAOkagFEjgdIm1Sj1oJQZXXyaMGbn0hhbRsclHB49rAoCgwBQwjVEUukmMBrQwDRGUAQNQB890jnk0TpjEwTbZHor4xQEpRrDABk38H1z5RDAAIC%252BBTPvYAsVgVLKxQ6uEEmsDGx6CBCZwC4Kckl%252BwsUFQQYWUG8%252BlQUBQCIbkH0bAJRgwx3RMOZ7gIybbJvSQD9JYDwbwwV5JF0jsRv%252BA8U3QZyrNkR400SCBMUS9YRtjWg5JMT%252BMcB9BoauarBKrIQYQsMJEMZ%252FzAAigbAUXdQ3EOl0%252B9IGJQXM7mTj9UyUkwR6joAOEGRk6cAs3EEP8JMi%252FXDlmMMwAso9tMAxcagdtRFYtppcfzEd6E23BvJMUclXodBShUquYBKcfnDz%252FE1DpOs4w9BGNyTpKwhnSARMLbZ8PxryzuxgIEK5OMZbegwSHoAqOYAG7NVBd9X5yBGXUIjGO%252FH5P5xceTdAFnQUNBTO7QCLDgAH1CYDttAd1gMCoyMQo4kpKoQU5UAgXi4QJF1LyU0Ow51JGc0aUYAk0q9IjNA6JcbxBk5L%252FBbV8C80HAVCC5VUHD4A5JRYjCgLW2tStXZEqTwcGqqDD4gHWv0K8KJOV%252F0M6ejGiTv3UV7AJwTwIxGwkf%252BYO7RQBvNACdZCt6RgBHvVhr3VZlrUck0MJMNIiHGop%252BgaUmxIKmXUF%252F0Cmda0WavDPr8SjBXUdlYlaqdoorFsfQjGkvAHWOwZA7pAXmTxpATYr8WJU53c1xifZdL3ZTKAMRDCoNLDXfMBgjuIoSCsWIwDO5MlcwdIQYCABs8EefeWjopU4y%252BFYJYxWaDRjHLGevE0Dh%252FDbaiBGV%252FFuZrFdalLaI4AW72IGM9pXr2Bgs5IWauWawpwFR2BZu%252F3dOqYG%252F3ndPw3BuOmtdSPbdXNwJ3xh2JW1nuIcr3MqYIvDG3kFgi2SnnnK3zWhLRZBzKgVptehBxgwD13dDbvyF7tVVAfzAy5CWjJ24UKzNEX1MLGgv%252BbBhRgefIC34XIQhURW3CoXAM7IYBdNqhnweKv3ft7oEJA9MomYF0rgKVPlYSL6I3q5Hvt948iAPpWwRDRQqETWYI7CAgEgDKHoFQ0gARHwTKQyWl66CmPjx%252FK2ZrTDDbNGYSfDxu5KMwSozUeO5RiyUAcwFGrCdf23tvDLGYulPMeWF1CniNrWBdLG6MlB53BQLeJHM%252FaBPwiQAM3h51ZCFYuSAIFOA3%252BwtLygLP%252FSKAF0NA4Al3nZkbLhuW21ed0O8J56dw4xa8ByrQQRkN28TRV%252B6gpvOgP86Cp1oFpcZ5IkiR0wCr4HEU19kXoPkcWtsH02jh8TE4SMZ3iC4%252BmNuUCQMeyr4kFHYi6WaS5bHYWDEHB%252Fw1gu2g37RjGJ8ifeyMF2timsGCrFMhLe%252FkRDk%252BNGsg%252F5KAwmaIqAgAFmOwNFpu375kxKQQ52MBEGOSPwgU%252B3lMJUxz9qxJnA3e9Ifmzh3uWfDL3QC8MicBJXUQEREAApwem14AAjuF4dC4gMIe68kzLCpPHigB4e71XBfg6bLg%252FUC%252BajTA8lKwyAsD7eEMDBSXWAKwO59Ez%252FpNBHQXh7uJTZjyOJTiEEGt%252FzSG4GRnAM0dEL7eSMMEwB0FsFhsYGyoMSK7SOQZABY%252FOzWQ8ZKIRLZBtIKVENXe%252F14B4GQW8kJUjwtXmHUdkCYdVNVpUFapoDESAA93RKpzsIG2N6C1HHRyiebFTEfl8JTXNIoSDKQf4AJKkPROu6b%252FoEW%252FjvfG9o0fBqyGB6FrQxWgIhqn%252Ftfg7yS4AAjhAg00oHMBG9rvoZvZGTYagdh8gJgpIO9AaUWhILsC8LOJsbq0TZ3g47NMPBh7IHLvEAtakC5QWNkz9DDYINIZSYU3EajYTRWyhJWwkNGLuanQ%252Fu4u4UjmCHIj5obSBo%252FxoDAgo0AeVSAWdZJpWVrImyrEzlspm18jyjKCYWl23XM2VSGUiGBmC8jtIptWq9YrPaHuyZYHSlCETpYD6jDQ7Hw3Fov4EKREVhgqRQvITFCRiWQEB8nagkUOgwMEglJClQVLQk4B3xJcgsUAQBtGx5foKGiqYshFEt2AGgrR6oQThQGKg9HDwp9E3gLSwB6HmVQtBYzFgEf%252BE1Qvi2QCz2%252FOws7DT6ciVRA1BwJo12e39%252FmlIl1KqynqmdrTk0PKSK5JUwQObcBA8DDdPYtKD0%252B0SSAqQCJEpUgvXShiIKuIYOH5qQV2UBGXPnDFw4A6ENBXYUjHA7kQGFDRs8Kv9IA%252BJkxzVDGbSd9MODAsUI1aag1DQBBUyIPn%252BCcpZAZo8F5c6ZeYWmgToFF4r5iURhKiRnK7ThgxowRwluPBD24HbBapUmj1B4Bap27ZQuDEqNO3oOAtMzcM4AcAqT540aeob%252BWTDhVp8U1gA8SBtIJkp%252FI28emZHh5Qy2li%252BvKHWJbNGKSA9kbJUOTQkFj5MkQfTS10gYU%252BUImqKtJ4%252B0C5TdmKpYCgUINHdjDv6T6JEFcJHWBR2a9J1D2RKqpgAGj6PKpCADSFJht5zMJ%252BaltuKIQkXh5n%252BKY0TjXPLRq2pzqrDI6%252Fbti7PTVtEDpvQjGVKtcA1MwAVYQgCcnZf%252F4DcLIFhUGUstd4ADEJzDgzSc9OJfGPgo1klYCR1BGwvU6UFgXo%252BIqKCKo3xRBRiLoHEBhatEiNdMzqTYix87pGjSSTBkQBYqUqSWAQxbEXnBikt2Q1wlx0l4gQGsJPfeSc7IR2QPg3G2WxIPhHHbFAw0018v6ZWQI5NrYgGDkzUcsIgDUk65CgRSVvhjV2giuScXWa4gH0oFUiHoVkZKMSibi17xFoNoxoAADG3UaEalNga6SJ96XqnhlUx0AUSDZ97gBFgWGsGoqoyw4MRbCA61SAG04GkGO3XmGSgNih7Bawmb%252FhrGoBVM4MSgCnAmnzJRyTTJqs8eAYYXYMAV%252Fy2DiElIy5wNzPgZD0D8%252BqavAJwa0woI2WPHoNUGygevFiBg1bjQPitti6OCAQMEsz5wAS2fMRfuiVSIyoMFJBxR2LkuxPvfvOeKIJNpdkDxJr2rSjsOXGw4UADArBisrsXkygQBgF8hTG4fvvUGAUNSODOMwQwOcrHNe7w4BQI0bPTvxwFf%252BMfJPYywhwUNylyCBX1YQNMWSf9BBtQ332wxA5Ii5vHPVkoDA7gEnzz1twDekk8eqVbxtcw%252FDE01tBnrTIPPW9t4S2loPzO13RZup8kKZYugwA1tFzWMEeCa7LbbkJawMwCzvtHABe38zAlDe0dGENqYp%252FACZwhktf8D58Xdg0cuQitO9ReQXj2p5AXMeNdnlpiA99%252FRnAx6DC5PcZs0uti%252B5QjAD5b6xS8q0qIUFKnSrV1ufCZ4ZtjpZyEAO8mztEhD3%252FZP9b0Ho4eYxtO7umFtXQ3AGhdobQZGE67ygPwzyDAJmuOvoL0MdmTSRyTff6cv36tEY8inOBiYb3kAIIMsDCA7913AAQ1swxoYxDTsNOIFegBCI%252FJCAwVEoBM%252B2l1KOGEdRkQCOwaElqvaAiUIQs8MlJrTckgWvgBthxc1kAQH%252F6MMB9ygL9GyD1fGZCQVrnBVhDhFi2h4gcnF0BVrUENdmFYMPvSCegThA8VUshPNUIEBD%252FD%252FS6FaYKIkquoSp0iFASAwJeclZULpoICEgAAqlCijg9moykJsJ4IzEuoJajJJBsaIRqpdixFy%252BVgEZSi%252FvCwtCoiahy9ylA%252FTMG4m33oTJCZzSKrBrSiL3FobPGaCEwwhRyM0AWFooCYu4A049gnAJ6s2jgU%252B6GeykKADy2YMMNQHEYgw5EzINrJAXgVmDzhQLW0GgwatJ5efaWMEX9ERwihjCJEYVWbQ9soPgdNg28lkM5nUwkoAxiKfaeQrKKiSUhiJnF3ZZBYgsxsKKK%252Bc0MqkDFbASEutwwx3K9dEDJKdLFgybMfUp4LC5KJyqDNGknOjlGJYi2EUKwurHBIW%252FwAVlpiVh6GLWkQX%252BAkgGjUgOXOa0ypGZ4VVPqee4tiV1wgnUiYpTxFjWmAXVvpEXE0ONKxwhydShKgqRCJIhZOD2G6qRI35oYEz2ta24BgHbkbrZSmwaaZuIA7pIGAwXHXqmvJprTCo46dzsio6jnaFYYnjYQaDRHoGEzSyHm9UCcBaCfrFhgL8FGAYWaiygCVXpfGBoHfAq81CGZkwPMCB%252FmJrGtiQSdOQ6WHwooLMDsvYmzGudStYQ2Q%252F5kb4EYxY5FKs5SAFrmKk7LOpMysX2CULXRYAfhDtQcGWRjgyuVZ0TZXtzRzrg1j5c2tsCNj03jFcMr0paC4lruqeEP83HgCsYwboyNz24IJQDTcwvTtceKlLL%252BPuMKSfmRVG5nYAkxFGYag0aMh6B4%252Ffmdd4OoUZGJM7VIumoQD44Kvv6Ju%252FtkEBvoLTQX6NNzLmfWVyAmDfGwCMhjYQ8K68HVo%252BdrYI6TXYweNIHw8A668GSCACkoOeICaIYYDkhsE80B0pUnJCiYR4ttHFJQ8i2ADoYQQDKpYcAZ4YwQdoApsu2EUOjPCdBOSCIDfOsQFpQFsTqJEHDYjA5ALAZTcYQHKzSOmUHODLPrhpGXqg5AuME1Mqr5CfIe3rA1JMUQwEgIZsyDMFJCDQxjXrJSM5ydlQEVs4ky%252Bdz2DAbh%252B0rwD%252F5Bmg733iA378Z09UgBLlRbTboJll7CIgKWGGdABEowYBxJDTcI7unFlADjRQCAKkllJpL62FS7hZ1WiEFDmksAZGRkAAP57cVFLagEbZQ2G6TvROG10CdpCa1Cl9r1QdIAEJNAARLlCABH51g0EXKF%252FBW3Z1i6No7PYsstS8QLRVPKuOEGROGNiBRw8aqCCSu8ptiZcU6CahYF%252F7Atr%252By7fpke9mss7Z0vS3wjmB1YPre3mtXri%252FIS7bnHHh3NhlOKYs7lQ38RdSHO%252B4x0WaPM7AgK9HGLmtS25y4jhqVCxvuMtr%252BekasGvlLK%252F5xzlDLYvNnOcMHQpt88W4oAu9%252F5ZwC6WjqoD0pNeyWlbJ18T9y3Gol9O4RHf6zrGO8GdoXOcj93rUi0NiKjyd7HGO1l6vkHa1k484MKC51RkO9xU66QtV3%252FjY727AmS7w4RGtuN9TVwqi6B0Lby%252F8xUpqPX67veuMr1p6vJaFxU%252F%252BqTBru%252BIln3l60UAmH9QC5j8%252F0srzuPN9Nz3GWJVzK5Se9UtqkSnmLvi6E172jMr72VV%252Fdd2nkSx6vz3u6Qb8kTrcB1cjPsWNf3wmkZQsi8g16T3%252F%252FIb6POXy7EHsrx8cs37hLZ%252Fovvcxk09qbZ%252F71i%252F%252FeeCWcuYXf2vsX1EYkrd3rq9%252B%252FubJJwIX2u%252F16x9bOP%252BDqyQeKJBfAD4EAlkFAt0f%252Fv0eAloGtVjID4jCAUJgQ7CLEzSgA9rdBbKFOMzdKFigB47CfkVE6hkgAJJgQwAe3fleB64gRIBg43TDCMbgFpgghqiCN9jgDWKBY1mZ%252F8GeCvpgUHBBaXxDDxbhKRQHJwjhEObfEobCDOYFOCihFB6h8vGUFRIhFlqBE4TBM21g9UWhF2aBW8jD%252BzXEFZphDjIg%252FEHhA5rhGYJdCqTf5XXhHGbhHpDCQ7DhEtLWZrweD%252BahHj4BgkzfE5KhHLbh5sEKJ4zh%252BBUiCUqLUCwCerXIICbhJJKgGumUBLKdE%252F7EH5af%252Bzkeq3CeT5Di9dH%252FnnWBHMwkIlCs4vGVlLQYRyJVwhNEYijMouzZi3G4SRcMoi3eYQqWISX2n4Xc3BGm4ihyYik%252BE8xp4j5Aniw%252BIyu%252BxRLp4Ak6yBauRS9mHkkpD2BoIgv0IVuAY%252BYBBhp%252BoS5eRjqGo%252Fi1SRlgBjwWXvRtnxPgIjpe4%252FO14hUIYzES4jGyXxhOC3rFwN8Ihz1i3T4copWlADehlXkwJNQFJK5lIxMiIUX24%252BedoheEVmYIJBcS5PPJozzCRQ7ijCieR0XWXP8dXhoi5H5V40J2ZOE5ZBo6XNglnze25E0WHvgZHSIOoCJChEuSHcblIksqCFJiHe094hOUYz0C5ecl%252F88%252BeoE81GSCOOVTwow8YCVXVqXfXeJmRKUdrklXWhxcVEvlDeBIWmNJ%252BqICXpk5ntKiqCXEBeOYCIVR8qNc6h5C9iSE4eVYql1olVRYLkleQhzvtcqzMCa5QSQXOMOrQKZheqXc1cAu%252FiRgqiP1WQ9YwqFNeibjgeFSOiFcBkdkcpqT%252BEHvQQtrwhma1B9nqohs5tiV1abb4GaDwYofEObN9CZ1Td8eniNvYqbFkZRxTmVsJufB2aIW3qXxDKdTVWJ6wI3jkE913tTqiINSqhx1PqeuFV1tqmZajqeqgaBVUMRoMgp3ltO9HFdlaicawafSTZ8pTF1zKs59flJOxf%252BAUISnfaYncSWSYy2dbdqMf6bOJyLXfJqAgi5ogX5W7a1kq7jnxTCo4aHPCtSnPm3o4jiih57nhJbmsuWdPFyNX%252FYnhZIVdobBzrBoi54olV3CUCCeW%252FBnLYWoqlyidTVhq5QojTLiJ2UoM7pmmAwoWfXoN%252FxoCT7pHtTfjuoTZd1WGrSRCxqPd2YoQoreAQzpduKK%252B9QJrpSplnYaC5zcrVlZgygaMIZYK6DDGzWQDKEDmjaWJ%252FpBXZpdT%252FqA6PGkbL0XhZhplk7JG1Hbf2KZhTYKbZ5foBKX%252B8jppNLCoYqGGSimcaoF%252FFUmPlbiZKoHX%252B4BaMap%252BxDqjNBpK3T%252Fyza2BasCBZ%252FmIhjmjDhW4nGVY75Eyowy1JyKBhxZ6p8xiEpGhDwCBajiGKvUQBM%252BqKuCXU7tTJg2EytkqZ1E1ozEwGb8qSie5kt5AvI8E4bQJjdZYraOiSlQBLSWE92kqrPVnzkiELi6CLOWq6ut6ZUtZ1tYKGLWZqZSGcPhCqtkJO25Gayq6TziXJatjtzpFUgeomU%252Bg0y8xVbqGuZhq%252FjhaMF%252Bwz%252FK5x46LCd8mtQtI84VBamSW%252BnBBf9FnzesabMKZWIaR1m%252BCL9Kpa2GbMkS4T6uqWAyUfh9ayAKq70oTymk7NaZm5BQhK5SVw%252Fi6iF%252BZSimYRjWngm2osOu%252F86LZNLr7RWVqpoSYlytVu35%252BSlyPVPy7CTRKcK12AuGTkvvCB9FSGzJXWHGGN21yOpmVOxyXqfdZuXWPZPdWi360NbRHmm%252FdiHBFsWNHquUotOj6CTe9i1a4msOGseSJp0Fbp9bACjOEeXYRgRbhonQsp1KHi26Em6N4mA0aiq95kvaUstbOmLtHe3kySZb3uIhmo%252FFgpFgru611m7mMebWnSbi2uE65mS55tzPIa3FMWbo3Vz99S2x9s7N5cvL6t7yCuMtNsuoMhHY3SLpQlxemqsOuspCEa13nKv3Kq%252BL%252BoAoCmMM9Jd6pEf3oi%252Fcqq%252F5YlkQNgpRHB6Yzm%252FNuf%252BkUrbvDyrlVl0sBLokrn3CyYVh7K7g%252F8Kh0aUXyV6gfwqvw8lo%252F94dd4KiVMovFvZm0%252BHcyxquB7Lm0oLl%252BRri4DkfUEwvFygA%252F6Zw%252FFWOT6xsq4Ra8k4whf4tznlYDE%252BBPQ7wXs2BzMZwOpolro2B1hYxUGajZlxl9w6uF9qgZvSXIoDBs2LwDWKe1d6oz01uEkfxEnMcJVix3IIl0RnHAUjKCPswHvpbGxnAjSqgZgyFjAJjFqewYDXQHguUFU8u9uJwGyveHhPyXLhRHZ9vGAvyFsRaUohaZMlPJBfAJEuKsC6yZTiQA83KJKsbHLuRGYzBJavI4VWtKJvyKaMEsieEAAA7%2529%2520%252D16px%25200%2520no%252Drepeat%253B%250Aline%252Dheight%253A%25201px%253B%257D%250Adiv%2523footer%2520%257Bfont%252Dsize%253A%25200%252E5em%253B%2520font%252Dweight%253A%2520bold%253B%2520padding%253A%25201em%25200%253B%257D%250A%2523footer%2520h1%252C%2520%2523footer%2520h2%2520%257Bdisplay%253A%2520block%253B%2520padding%253A%25200%25201em%253B%257D%250A%2523footer%2520h2%2520%257Bfont%252Dstyle%253A%2520italic%253B%257D%250Adiv%252Elong%2520%257Bfont%252Dsize%253A%25200%252E75em%253B%257D%250A%252Eslide%2520h1%2520%257Bposition%253A%2520absolute%253B%2520top%253A%25200%252E7em%253B%2520left%253A%252087px%253B%2520z%252Dindex%253A%25201%253B%250Amargin%253A%25200%253B%2520padding%253A%25200%252E3em%25200%25200%252050px%253B%2520white%252Dspace%253A%2520nowrap%253B%250Afont%253A%2520bold%2520150%2525%252F1em%2520Helvetica%252C%2520sans%252Dserif%253B%2520text%252Dtransform%253A%2520capitalize%253B%250Acolor%253A%2520%2523DDE%253B%2520background%253A%2520%2523005%253B%257D%250A%252Eslide%2520h3%2520%257Bfont%252Dsize%253A%2520130%2525%253B%257D%250Ah1%2520abbr%2520%257Bfont%252Dvariant%253A%2520small%252Dcaps%253B%257D%250Adiv%2523controls%2520%257Bposition%253A%2520absolute%253B%2520left%253A%252050%2525%253B%2520bottom%253A%25200%253B%250Awidth%253A%252050%2525%253B%250Atext%252Dalign%253A%2520right%253B%2520font%253A%2520bold%25200%252E9em%2520Verdana%252C%2520Helvetica%252C%2520sans%252Dserif%253B%257D%250Ahtml%253Ebody%2520div%2523controls%2520%257Bposition%253A%2520fixed%253B%2520padding%253A%25200%25200%25201em%25200%253B%250Atop%253A%2520auto%253B%257D%250Adiv%2523controls%2520form%2520%257Bposition%253A%2520absolute%253B%2520bottom%253A%25200%253B%2520right%253A%25200%253B%2520width%253A%2520100%2525%253B%250Amargin%253A%25200%253B%2520padding%253A%25200%253B%257D%250A%2523controls%2520%2523navLinks%2520a%2520%257Bpadding%253A%25200%253B%2520margin%253A%25200%25200%252E5em%253B%2520background%253A%2520%2523005%253B%2520border%253A%2520none%253B%2520color%253A%2520%2523779%253B%2520cursor%253A%2520pointer%253B%257D%250A%2523controls%2520%2523navList%2520%257Bheight%253A%25201em%253B%257D%250A%2523controls%2520%2523navList%2520%2523jumplist%2520%257Bposition%253A%2520absolute%253B%2520bottom%253A%25200%253B%2520right%253A%25200%253B%2520background%253A%2520%2523DDD%253B%2520color%253A%2520%2523227%253B%257D%250A%2523currentSlide%2520%257Btext%252Dalign%253A%2520center%253B%2520font%252Dsize%253A%25200%252E5em%253B%2520color%253A%2520%2523449%253B%257D%250A%2523slide0%2520%257Bpadding%252Dtop%253A%25203%252E5em%253B%2520font%252Dsize%253A%252090%2525%253B%257D%250A%2523slide0%2520h1%2520%257Bposition%253A%2520static%253B%2520margin%253A%25201em%25200%25200%253B%2520padding%253A%25200%253B%250Afont%253A%2520bold%25202em%2520Helvetica%252C%2520sans%252Dserif%253B%2520white%252Dspace%253A%2520normal%253B%250Acolor%253A%2520%2523000%253B%2520background%253A%2520transparent%253B%257D%250A%2523slide0%2520h2%2520%257Bfont%253A%2520bold%2520italic%25201em%2520Helvetica%252C%2520sans%252Dserif%253B%2520margin%253A%25200%252E25em%253B%257D%250A%2523slide0%2520h3%2520%257Bmargin%252Dtop%253A%25201%252E5em%253B%2520font%252Dsize%253A%25201%252E5em%253B%257D%250A%2523slide0%2520h4%2520%257Bmargin%252Dtop%253A%25200%253B%2520font%252Dsize%253A%25201em%253B%257D%250Aul%252Eurls%2520%257Blist%252Dstyle%253A%2520none%253B%2520display%253A%2520inline%253B%2520margin%253A%25200%253B%257D%250A%252Eurls%2520li%2520%257Bdisplay%253A%2520inline%253B%2520margin%253A%25200%253B%257D%250A%252Enote%2520%257Bdisplay%253A%2520none%253B%257D%250A%252Eexternal%2520%257Bborder%252Dbottom%253A%25201px%2520dotted%2520gray%253B%257D%250Ahtml%253Ebody%2520%252Eexternal%2520%257Bborder%252Dbottom%253A%2520none%253B%257D%250A%252Eexternal%253Aafter%2520%257Bcontent%253A%2520%2522%2520%255C274F%2522%253B%2520font%252Dsize%253A%2520smaller%253B%2520color%253A%2520%252377B%253B%257D%250A%252Eincremental%252C%2520%252Eincremental%2520%252A%252C%2520%252Eincremental%2520%252A%253Aafter%2520%257Bcolor%253A%2520%2523DDE%253B%2520visibility%253A%2520visible%253B%257D%250Aimg%252Eincremental%2520%257Bvisibility%253A%2520hidden%253B%257D%250A%252Eslide%2520%252Ecurrent%2520%257Bcolor%253A%2520%2523B02%253B%257D%250A%29%3B%20" rel="stylesheet" type="text/css" media="projection" id="slideProj" />
<link href="data:text/css;charset=utf-8,%0A%2Elayout%20div%2C%20%23footer%20%2A%2C%20%23controlForm%20%2A%20%7Bdisplay%3A%20none%3B%7D%0A%23footer%2C%20%23controls%2C%20%23controlForm%2C%20%23navLinks%2C%20%23toggle%20%7B%0Adisplay%3A%20block%3B%20visibility%3A%20visible%3B%20margin%3A%200%3B%20padding%3A%200%3B%7D%0A%23toggle%20%7Bfloat%3A%20right%3B%20padding%3A%200%2E5em%3B%7D%0Ahtml%3Ebody%20%23toggle%20%7Bposition%3A%20fixed%3B%20top%3A%200%3B%20right%3A%200%3B%7D%0A%0A%23slide0%20h1%2C%20%23slide0%20h2%2C%20%23slide0%20h3%2C%20%23slide0%20h4%20%7Bborder%3A%20none%3B%20margin%3A%200%3B%7D%0A%23slide0%20h1%20%7Bpadding%2Dtop%3A%201%2E5em%3B%7D%0A%2Eslide%20h1%20%7Bmargin%3A%201%2E5em%200%200%3B%20padding%2Dtop%3A%200%2E25em%3B%0Aborder%2Dtop%3A%201px%20solid%20%23888%3B%20border%2Dbottom%3A%201px%20solid%20%23AAA%3B%7D%0A%23toggle%20%7Bborder%3A%201px%20solid%3B%20border%2Dwidth%3A%200%200%201px%201px%3B%20background%3A%20%23FFF%3B%7D%0A" rel="stylesheet" type="text/css" media="screen" id="outlineStyle" />
<link href="data:text/css;charset=utf-8,%0A%2Eslide%2C%20ul%20%7Bpage%2Dbreak%2Dinside%3A%20avoid%3B%20visibility%3A%20visible%20%21important%3B%7D%0Ah1%20%7Bpage%2Dbreak%2Dafter%3A%20avoid%3B%7D%0Abody%20%7Bfont%2Dsize%3A%2012pt%3B%20background%3A%20white%3B%7D%0A%2A%20%7Bcolor%3A%20black%3B%7D%0A%23slide0%20h1%20%7Bfont%2Dsize%3A%20200%25%3B%20border%3A%20none%3B%20margin%3A%200%2E5em%200%200%2E25em%3B%7D%0A%23slide0%20h3%20%7Bmargin%3A%200%3B%20padding%3A%200%3B%7D%0A%23slide0%20h4%20%7Bmargin%3A%200%200%200%2E5em%3B%20padding%3A%200%3B%7D%0A%23slide0%20%7Bmargin%2Dbottom%3A%203em%3B%7D%0Ah1%20%7Bborder%2Dtop%3A%202pt%20solid%20gray%3B%20border%2Dbottom%3A%201px%20dotted%20silver%3B%7D%0A%2Eextra%20%7Bbackground%3A%20transparent%20%21important%3B%7D%0Adiv%2Eextra%2C%20pre%2Eextra%2C%20%2Eexample%20%7Bfont%2Dsize%3A%2010pt%3B%20color%3A%20%23333%3B%7D%0Aul%2Eextra%20a%20%7Bfont%2Dweight%3A%20bold%3B%7D%0Ap%2Eexample%20%7Bdisplay%3A%20none%3B%7D%0A%23header%20%7Bdisplay%3A%20none%3B%7D%0A%23footer%20h1%20%7Bmargin%3A%200%3B%20border%2Dbottom%3A%201px%20solid%3B%20color%3A%20gray%3B%20font%2Dstyle%3A%20italic%3B%7D%0A%23footer%20h2%2C%20%23controls%20%7Bdisplay%3A%20none%3B%7D%0A%0A%2Elayout%2C%20%2Elayout%20%2A%20%7Bdisplay%3A%20none%20%21important%3B%7D" rel="stylesheet" type="text/css" media="print" id="slidePrint" />
<link href="data:text/css;charset=utf-8,%0A%2Eslide%20%7B%0Avisibility%3A%20visible%20%21important%3B%0Aposition%3A%20static%20%21important%3B%0Apage%2Dbreak%2Dbefore%3A%20always%3B%0A%7D%0A%23slide0%20%7Bpage%2Dbreak%2Dbefore%3A%20avoid%3B%7D%0A" rel="stylesheet" type="text/css" media="projection" id="operaFix" />
<!-- S5 JS -->
<script src="data:application/x-javascript;base64,Ly8gUzUgdjEuMSBzbGlkZXMuanMgLS0gcmVsZWFzZWQgaW50byB0aGUgUHVibGljIERvbWFpbgovLwovLyBQbGVhc2Ugc2VlIGh0dHA6Ly93d3cubWV5ZXJ3ZWIuY29tL2VyaWMvdG9vbHMvczUvY3JlZGl0cy5odG1sIGZvciBpbmZvcm1hdGlvbiAKLy8gYWJvdXQgYWxsIHRoZSB3b25kZXJmdWwgYW5kIHRhbGVudGVkIGNvbnRyaWJ1dG9ycyB0byB0aGlzIGNvZGUhCgp2YXIgdW5kZWY7CnZhciBzbGlkZUNTUyA9ICcnOwp2YXIgc251bSA9IDA7CnZhciBzbWF4ID0gMTsKdmFyIGluY3BvcyA9IDA7CnZhciBudW1iZXIgPSB1bmRlZjsKdmFyIHM1bW9kZSA9IHRydWU7CnZhciBkZWZhdWx0VmlldyA9ICdzbGlkZXNob3cnOwp2YXIgY29udHJvbFZpcyA9ICd2aXNpYmxlJzsKCnZhciBpc0lFID0gbmF2aWdhdG9yLmFwcE5hbWUgPT0gJ01pY3Jvc29mdCBJbnRlcm5ldCBFeHBsb3JlcicgPyAxIDogMDsKdmFyIGlzT3AgPSBuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoJ09wZXJhJykgPiAtMSA/IDEgOiAwOwp2YXIgaXNHZSA9IG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignR2Vja28nKSA+IC0xICYmIG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignU2FmYXJpJykgPCAxID8gMSA6IDA7CgpmdW5jdGlvbiBoYXNDbGFzcyhvYmplY3QsIGNsYXNzTmFtZSkgewoJaWYgKCFvYmplY3QuY2xhc3NOYW1lKSByZXR1cm4gZmFsc2U7CglyZXR1cm4gKG9iamVjdC5jbGFzc05hbWUuc2VhcmNoKCcoXnxcXHMpJyArIGNsYXNzTmFtZSArICcoXFxzfCQpJykgIT0gLTEpOwp9CgpmdW5jdGlvbiBoYXNWYWx1ZShvYmplY3QsIHZhbHVlKSB7CglpZiAoIW9iamVjdCkgcmV0dXJuIGZhbHNlOwoJcmV0dXJuIChvYmplY3Quc2VhcmNoKCcoXnxcXHMpJyArIHZhbHVlICsgJyhcXHN8JCknKSAhPSAtMSk7Cn0KCmZ1bmN0aW9uIHJlbW92ZUNsYXNzKG9iamVjdCxjbGFzc05hbWUpIHsKCWlmICghb2JqZWN0KSByZXR1cm47CglvYmplY3QuY2xhc3NOYW1lID0gb2JqZWN0LmNsYXNzTmFtZS5yZXBsYWNlKG5ldyBSZWdFeHAoJyhefFxccyknK2NsYXNzTmFtZSsnKFxcc3wkKScpLCBSZWdFeHAuJDErUmVnRXhwLiQyKTsKfQoKZnVuY3Rpb24gYWRkQ2xhc3Mob2JqZWN0LGNsYXNzTmFtZSkgewoJaWYgKCFvYmplY3QgfHwgaGFzQ2xhc3Mob2JqZWN0LCBjbGFzc05hbWUpKSByZXR1cm47CglpZiAob2JqZWN0LmNsYXNzTmFtZSkgewoJCW9iamVjdC5jbGFzc05hbWUgKz0gJyAnK2NsYXNzTmFtZTsKCX0gZWxzZSB7CgkJb2JqZWN0LmNsYXNzTmFtZSA9IGNsYXNzTmFtZTsKCX0KfQoKZnVuY3Rpb24gR2V0RWxlbWVudHNXaXRoQ2xhc3NOYW1lKGVsZW1lbnROYW1lLGNsYXNzTmFtZSkgewoJdmFyIGFsbEVsZW1lbnRzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoZWxlbWVudE5hbWUpOwoJdmFyIGVsZW1Db2xsID0gbmV3IEFycmF5KCk7Cglmb3IgKHZhciBpID0gMDsgaTwgYWxsRWxlbWVudHMubGVuZ3RoOyBpKyspIHsKCQlpZiAoaGFzQ2xhc3MoYWxsRWxlbWVudHNbaV0sIGNsYXNzTmFtZSkpIHsKCQkJZWxlbUNvbGxbZWxlbUNvbGwubGVuZ3RoXSA9IGFsbEVsZW1lbnRzW2ldOwoJCX0KCX0KCXJldHVybiBlbGVtQ29sbDsKfQoKZnVuY3Rpb24gaXNQYXJlbnRPclNlbGYoZWxlbWVudCwgaWQpIHsKCWlmIChlbGVtZW50ID09IG51bGwgfHwgZWxlbWVudC5ub2RlTmFtZT09J0JPRFknKSByZXR1cm4gZmFsc2U7CgllbHNlIGlmIChlbGVtZW50LmlkID09IGlkKSByZXR1cm4gdHJ1ZTsKCWVsc2UgcmV0dXJuIGlzUGFyZW50T3JTZWxmKGVsZW1lbnQucGFyZW50Tm9kZSwgaWQpOwp9CgpmdW5jdGlvbiBub2RlVmFsdWUobm9kZSkgewoJdmFyIHJlc3VsdCA9ICIiOwoJaWYgKG5vZGUubm9kZVR5cGUgPT0gMSkgewoJCXZhciBjaGlsZHJlbiA9IG5vZGUuY2hpbGROb2RlczsKCQlmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgKytpKSB7CgkJCXJlc3VsdCArPSBub2RlVmFsdWUoY2hpbGRyZW5baV0pOwoJCX0JCQoJfQoJZWxzZSBpZiAobm9kZS5ub2RlVHlwZSA9PSAzKSB7CgkJcmVzdWx0ID0gbm9kZS5ub2RlVmFsdWU7Cgl9CglyZXR1cm4ocmVzdWx0KTsKfQoKZnVuY3Rpb24gc2xpZGVMYWJlbCgpIHsKCXZhciBzbGlkZUNvbGwgPSBHZXRFbGVtZW50c1dpdGhDbGFzc05hbWUoJyonLCdzbGlkZScpOwoJdmFyIGxpc3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnanVtcGxpc3QnKTsKCXNtYXggPSBzbGlkZUNvbGwubGVuZ3RoOwoJZm9yICh2YXIgbiA9IDA7IG4gPCBzbWF4OyBuKyspIHsKCQl2YXIgb2JqID0gc2xpZGVDb2xsW25dOwoKCQl2YXIgZGlkID0gJ3NsaWRlJyArIG4udG9TdHJpbmcoKTsKCQlvYmouc2V0QXR0cmlidXRlKCdpZCcsZGlkKTsKCQlpZiAoaXNPcCkgY29udGludWU7CgoJCXZhciBvdGV4dCA9ICcnOwoJCXZhciBtZW51ID0gb2JqLmZpcnN0Q2hpbGQ7CgkJaWYgKCFtZW51KSBjb250aW51ZTsgLy8gdG8gY29wZSB3aXRoIGVtcHR5IHNsaWRlcwoJCXdoaWxlIChtZW51ICYmIG1lbnUubm9kZVR5cGUgPT0gMykgewoJCQltZW51ID0gbWVudS5uZXh0U2libGluZzsKCQl9CgkgCWlmICghbWVudSkgY29udGludWU7IC8vIHRvIGNvcGUgd2l0aCBzbGlkZXMgd2l0aCBvbmx5IHRleHQgbm9kZXMKCgkJdmFyIG1lbnVub2RlcyA9IG1lbnUuY2hpbGROb2RlczsKCQlmb3IgKHZhciBvID0gMDsgbyA8IG1lbnVub2Rlcy5sZW5ndGg7IG8rKykgewoJCQlvdGV4dCArPSBub2RlVmFsdWUobWVudW5vZGVzW29dKTsKCQl9CgkJbGlzdC5vcHRpb25zW2xpc3QubGVuZ3RoXSA9IG5ldyBPcHRpb24obiArICcgOiAnICArIG90ZXh0LCBuKTsKCX0KfQoKZnVuY3Rpb24gY3VycmVudFNsaWRlKCkgewoJdmFyIGNzOwoJaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKSB7CgkJY3MgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY3VycmVudFNsaWRlJyk7Cgl9IGVsc2UgewoJCWNzID0gZG9jdW1lbnQuY3VycmVudFNsaWRlOwoJfQoJY3MuaW5uZXJIVE1MID0gJzxzcGFuIGlkPSJjc0hlcmUiPicgKyBzbnVtICsgJzxcL3NwYW4+ICcgKyAKCQknPHNwYW4gaWQ9ImNzU2VwIj5cLzxcL3NwYW4+ICcgKyAKCQknPHNwYW4gaWQ9ImNzVG90YWwiPicgKyAoc21heC0xKSArICc8XC9zcGFuPic7CglpZiAoc251bSA9PSAwKSB7CgkJY3Muc3R5bGUudmlzaWJpbGl0eSA9ICdoaWRkZW4nOwoJfSBlbHNlIHsKCQljcy5zdHlsZS52aXNpYmlsaXR5ID0gJ3Zpc2libGUnOwoJfQp9CgpmdW5jdGlvbiBnbyhzdGVwKSB7CglpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NsaWRlUHJvaicpLmRpc2FibGVkIHx8IHN0ZXAgPT0gMCkgcmV0dXJuOwoJdmFyIGpsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2p1bXBsaXN0Jyk7Cgl2YXIgY2lkID0gJ3NsaWRlJyArIHNudW07Cgl2YXIgY2UgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChjaWQpOwoJaWYgKGluY3JlbWVudGFsc1tzbnVtXS5sZW5ndGggPiAwKSB7CgkJZm9yICh2YXIgaSA9IDA7IGkgPCBpbmNyZW1lbnRhbHNbc251bV0ubGVuZ3RoOyBpKyspIHsKCQkJcmVtb3ZlQ2xhc3MoaW5jcmVtZW50YWxzW3NudW1dW2ldLCAnY3VycmVudCcpOwoJCQlyZW1vdmVDbGFzcyhpbmNyZW1lbnRhbHNbc251bV1baV0sICdpbmNyZW1lbnRhbCcpOwoJCX0KCX0KCWlmIChzdGVwICE9ICdqJykgewoJCXNudW0gKz0gc3RlcDsKCQlsbWF4ID0gc21heCAtIDE7CgkJaWYgKHNudW0gPiBsbWF4KSBzbnVtID0gbG1heDsKCQlpZiAoc251bSA8IDApIHNudW0gPSAwOwoJfSBlbHNlCgkJc251bSA9IHBhcnNlSW50KGpsLnZhbHVlKTsKCXZhciBuaWQgPSAnc2xpZGUnICsgc251bTsKCXZhciBuZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKG5pZCk7CglpZiAoIW5lKSB7CgkJbmUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2xpZGUwJyk7CgkJc251bSA9IDA7Cgl9CglpZiAoc3RlcCA8IDApIHtpbmNwb3MgPSBpbmNyZW1lbnRhbHNbc251bV0ubGVuZ3RofSBlbHNlIHtpbmNwb3MgPSAwO30KCWlmIChpbmNyZW1lbnRhbHNbc251bV0ubGVuZ3RoID4gMCAmJiBpbmNwb3MgPT0gMCkgewoJCWZvciAodmFyIGkgPSAwOyBpIDwgaW5jcmVtZW50YWxzW3NudW1dLmxlbmd0aDsgaSsrKSB7CgkJCWlmIChoYXNDbGFzcyhpbmNyZW1lbnRhbHNbc251bV1baV0sICdjdXJyZW50JykpCgkJCQlpbmNwb3MgPSBpICsgMTsKCQkJZWxzZQoJCQkJYWRkQ2xhc3MoaW5jcmVtZW50YWxzW3NudW1dW2ldLCAnaW5jcmVtZW50YWwnKTsKCQl9Cgl9CglpZiAoaW5jcmVtZW50YWxzW3NudW1dLmxlbmd0aCA+IDAgJiYgaW5jcG9zID4gMCkKCQlhZGRDbGFzcyhpbmNyZW1lbnRhbHNbc251bV1baW5jcG9zIC0gMV0sICdjdXJyZW50Jyk7CgljZS5zdHlsZS52aXNpYmlsaXR5ID0gJ2hpZGRlbic7CgluZS5zdHlsZS52aXNpYmlsaXR5ID0gJ3Zpc2libGUnOwoJamwuc2VsZWN0ZWRJbmRleCA9IHNudW07CgljdXJyZW50U2xpZGUoKTsKCW51bWJlciA9IDA7Cn0KCmZ1bmN0aW9uIGdvVG8odGFyZ2V0KSB7CglpZiAodGFyZ2V0ID49IHNtYXggfHwgdGFyZ2V0ID09IHNudW0pIHJldHVybjsKCWdvKHRhcmdldCAtIHNudW0pOwp9CgpmdW5jdGlvbiBzdWJnbyhzdGVwKSB7CglpZiAoc3RlcCA+IDApIHsKCQlyZW1vdmVDbGFzcyhpbmNyZW1lbnRhbHNbc251bV1baW5jcG9zIC0gMV0sJ2N1cnJlbnQnKTsKCQlyZW1vdmVDbGFzcyhpbmNyZW1lbnRhbHNbc251bV1baW5jcG9zXSwgJ2luY3JlbWVudGFsJyk7CgkJYWRkQ2xhc3MoaW5jcmVtZW50YWxzW3NudW1dW2luY3Bvc10sJ2N1cnJlbnQnKTsKCQlpbmNwb3MrKzsKCX0gZWxzZSB7CgkJaW5jcG9zLS07CgkJcmVtb3ZlQ2xhc3MoaW5jcmVtZW50YWxzW3NudW1dW2luY3Bvc10sJ2N1cnJlbnQnKTsKCQlhZGRDbGFzcyhpbmNyZW1lbnRhbHNbc251bV1baW5jcG9zXSwgJ2luY3JlbWVudGFsJyk7CgkJYWRkQ2xhc3MoaW5jcmVtZW50YWxzW3NudW1dW2luY3BvcyAtIDFdLCdjdXJyZW50Jyk7Cgl9Cn0KCmZ1bmN0aW9uIHRvZ2dsZSgpIHsKCXZhciBzbGlkZUNvbGwgPSBHZXRFbGVtZW50c1dpdGhDbGFzc05hbWUoJyonLCdzbGlkZScpOwoJdmFyIHNsaWRlcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbGlkZVByb2onKTsKCXZhciBvdXRsaW5lID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ291dGxpbmVTdHlsZScpOwoJaWYgKCFzbGlkZXMuZGlzYWJsZWQpIHsKCQlzbGlkZXMuZGlzYWJsZWQgPSB0cnVlOwoJCW91dGxpbmUuZGlzYWJsZWQgPSBmYWxzZTsKCQlzNW1vZGUgPSBmYWxzZTsKCQlmb250U2l6ZSgnMWVtJyk7CgkJZm9yICh2YXIgbiA9IDA7IG4gPCBzbWF4OyBuKyspIHsKCQkJdmFyIHNsaWRlID0gc2xpZGVDb2xsW25dOwoJCQlzbGlkZS5zdHlsZS52aXNpYmlsaXR5ID0gJ3Zpc2libGUnOwoJCX0KCX0gZWxzZSB7CgkJc2xpZGVzLmRpc2FibGVkID0gZmFsc2U7CgkJb3V0bGluZS5kaXNhYmxlZCA9IHRydWU7CgkJczVtb2RlID0gdHJ1ZTsKCQlmb250U2NhbGUoKTsKCQlmb3IgKHZhciBuID0gMDsgbiA8IHNtYXg7IG4rKykgewoJCQl2YXIgc2xpZGUgPSBzbGlkZUNvbGxbbl07CgkJCXNsaWRlLnN0eWxlLnZpc2liaWxpdHkgPSAnaGlkZGVuJzsKCQl9CgkJc2xpZGVDb2xsW3NudW1dLnN0eWxlLnZpc2liaWxpdHkgPSAndmlzaWJsZSc7Cgl9Cn0KCmZ1bmN0aW9uIHNob3dIaWRlKGFjdGlvbikgewoJdmFyIG9iaiA9IEdldEVsZW1lbnRzV2l0aENsYXNzTmFtZSgnKicsJ2hpZGVtZScpWzBdOwoJc3dpdGNoIChhY3Rpb24pIHsKCWNhc2UgJ3MnOiBvYmouc3R5bGUudmlzaWJpbGl0eSA9ICd2aXNpYmxlJzsgYnJlYWs7CgljYXNlICdoJzogb2JqLnN0eWxlLnZpc2liaWxpdHkgPSAnaGlkZGVuJzsgYnJlYWs7CgljYXNlICdrJzoKCQlpZiAob2JqLnN0eWxlLnZpc2liaWxpdHkgIT0gJ3Zpc2libGUnKSB7CgkJCW9iai5zdHlsZS52aXNpYmlsaXR5ID0gJ3Zpc2libGUnOwoJCX0gZWxzZSB7CgkJCW9iai5zdHlsZS52aXNpYmlsaXR5ID0gJ2hpZGRlbic7CgkJfQoJYnJlYWs7Cgl9Cn0KCi8vICdrZXlzJyBjb2RlIGFkYXB0ZWQgZnJvbSBNb3pQb2ludCAoaHR0cDovL21venBvaW50Lm1vemRldi5vcmcvKQpmdW5jdGlvbiBrZXlzKGtleSkgewoJaWYgKCFrZXkpIHsKCQlrZXkgPSBldmVudDsKCQlrZXkud2hpY2ggPSBrZXkua2V5Q29kZTsKCX0KCWlmIChrZXkud2hpY2ggPT0gODQpIHsKCQl0b2dnbGUoKTsKCQlyZXR1cm47Cgl9CglpZiAoczVtb2RlKSB7CgkJc3dpdGNoIChrZXkud2hpY2gpIHsKCQkJY2FzZSAxMDogLy8gcmV0dXJuCgkJCWNhc2UgMTM6IC8vIGVudGVyCgkJCQlpZiAod2luZG93LmV2ZW50ICYmIGlzUGFyZW50T3JTZWxmKHdpbmRvdy5ldmVudC5zcmNFbGVtZW50LCAnY29udHJvbHMnKSkgcmV0dXJuOwoJCQkJaWYgKGtleS50YXJnZXQgJiYgaXNQYXJlbnRPclNlbGYoa2V5LnRhcmdldCwgJ2NvbnRyb2xzJykpIHJldHVybjsKCQkJCWlmKG51bWJlciAhPSB1bmRlZikgewoJCQkJCWdvVG8obnVtYmVyKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJY2FzZSAzMjogLy8gc3BhY2ViYXIKCQkJY2FzZSAzNDogLy8gcGFnZSBkb3duCgkJCWNhc2UgMzk6IC8vIHJpZ2h0a2V5CgkJCWNhc2UgNDA6IC8vIGRvd25rZXkKCQkJCWlmKG51bWJlciAhPSB1bmRlZikgewoJCQkJCWdvKG51bWJlcik7CgkJCQl9IGVsc2UgaWYgKCFpbmNyZW1lbnRhbHNbc251bV0gfHwgaW5jcG9zID49IGluY3JlbWVudGFsc1tzbnVtXS5sZW5ndGgpIHsKCQkJCQlnbygxKTsKCQkJCX0gZWxzZSB7CgkJCQkJc3ViZ28oMSk7CgkJCQl9CgkJCQlicmVhazsKCQkJY2FzZSAzMzogLy8gcGFnZSB1cAoJCQljYXNlIDM3OiAvLyBsZWZ0a2V5CgkJCWNhc2UgMzg6IC8vIHVwa2V5CgkJCQlpZihudW1iZXIgIT0gdW5kZWYpIHsKCQkJCQlnbygtMSAqIG51bWJlcik7CgkJCQl9IGVsc2UgaWYgKCFpbmNyZW1lbnRhbHNbc251bV0gfHwgaW5jcG9zIDw9IDApIHsKCQkJCQlnbygtMSk7CgkJCQl9IGVsc2UgewoJCQkJCXN1YmdvKC0xKTsKCQkJCX0KCQkJCWJyZWFrOwoJCQljYXNlIDM2OiAvLyBob21lCgkJCQlnb1RvKDApOwoJCQkJYnJlYWs7CgkJCWNhc2UgMzU6IC8vIGVuZAoJCQkJZ29UbyhzbWF4LTEpOwoJCQkJYnJlYWs7CgkJCWNhc2UgNjc6IC8vIGMKCQkJCXNob3dIaWRlKCdrJyk7CgkJCQlicmVhazsKCQl9CgkJaWYgKGtleS53aGljaCA8IDQ4IHx8IGtleS53aGljaCA+IDU3KSB7CgkJCW51bWJlciA9IHVuZGVmOwoJCX0gZWxzZSB7CgkJCWlmICh3aW5kb3cuZXZlbnQgJiYgaXNQYXJlbnRPclNlbGYod2luZG93LmV2ZW50LnNyY0VsZW1lbnQsICdjb250cm9scycpKSByZXR1cm47CgkJCWlmIChrZXkudGFyZ2V0ICYmIGlzUGFyZW50T3JTZWxmKGtleS50YXJnZXQsICdjb250cm9scycpKSByZXR1cm47CgkJCW51bWJlciA9ICgoKG51bWJlciAhPSB1bmRlZikgPyBudW1iZXIgOiAwKSAqIDEwKSArIChrZXkud2hpY2ggLSA0OCk7CgkJfQoJfQoJcmV0dXJuIGZhbHNlOwp9CgpmdW5jdGlvbiBjbGlja2VyKGUpIHsKCW51bWJlciA9IHVuZGVmOwoJdmFyIHRhcmdldDsKCWlmICh3aW5kb3cuZXZlbnQpIHsKCQl0YXJnZXQgPSB3aW5kb3cuZXZlbnQuc3JjRWxlbWVudDsKCQllID0gd2luZG93LmV2ZW50OwoJfSBlbHNlIHRhcmdldCA9IGUudGFyZ2V0OwoJaWYgKHRhcmdldC5nZXRBdHRyaWJ1dGUoJ2hyZWYnKSAhPSBudWxsIHx8IGhhc1ZhbHVlKHRhcmdldC5yZWwsICdleHRlcm5hbCcpIHx8IGlzUGFyZW50T3JTZWxmKHRhcmdldCwgJ2NvbnRyb2xzJykgfHwgaXNQYXJlbnRPclNlbGYodGFyZ2V0LCdlbWJlZCcpIHx8IGlzUGFyZW50T3JTZWxmKHRhcmdldCwnb2JqZWN0JykpIHJldHVybiB0cnVlOwoJaWYgKCFlLndoaWNoIHx8IGUud2hpY2ggPT0gMSkgewoJCWlmICghaW5jcmVtZW50YWxzW3NudW1dIHx8IGluY3BvcyA+PSBpbmNyZW1lbnRhbHNbc251bV0ubGVuZ3RoKSB7CgkJCWdvKDEpOwoJCX0gZWxzZSB7CgkJCXN1YmdvKDEpOwoJCX0KCX0KfQoKZnVuY3Rpb24gZmluZFNsaWRlKGhhc2gpIHsKCXZhciB0YXJnZXQgPSBudWxsOwoJdmFyIHNsaWRlcyA9IEdldEVsZW1lbnRzV2l0aENsYXNzTmFtZSgnKicsJ3NsaWRlJyk7Cglmb3IgKHZhciBpID0gMDsgaSA8IHNsaWRlcy5sZW5ndGg7IGkrKykgewoJCXZhciB0YXJnZXRTbGlkZSA9IHNsaWRlc1tpXTsKCQlpZiAoICh0YXJnZXRTbGlkZS5uYW1lICYmIHRhcmdldFNsaWRlLm5hbWUgPT0gaGFzaCkKCQkgfHwgKHRhcmdldFNsaWRlLmlkICYmIHRhcmdldFNsaWRlLmlkID09IGhhc2gpICkgewoJCQl0YXJnZXQgPSB0YXJnZXRTbGlkZTsKCQkJYnJlYWs7CgkJfQoJfQoJd2hpbGUodGFyZ2V0ICE9IG51bGwgJiYgdGFyZ2V0Lm5vZGVOYW1lICE9ICdCT0RZJykgewoJCWlmIChoYXNDbGFzcyh0YXJnZXQsICdzbGlkZScpKSB7CgkJCXJldHVybiBwYXJzZUludCh0YXJnZXQuaWQuc2xpY2UoNSkpOwoJCX0KCQl0YXJnZXQgPSB0YXJnZXQucGFyZW50Tm9kZTsKCX0KCXJldHVybiBudWxsOwp9CgpmdW5jdGlvbiBzbGlkZUp1bXAoKSB7CglpZiAod2luZG93LmxvY2F0aW9uLmhhc2ggPT0gbnVsbCkgcmV0dXJuOwoJdmFyIHNyZWdleCA9IC9eI3NsaWRlKFxkKykkLzsKCXZhciBtYXRjaGVzID0gc3JlZ2V4LmV4ZWMod2luZG93LmxvY2F0aW9uLmhhc2gpOwoJdmFyIGRlc3QgPSBudWxsOwoJaWYgKG1hdGNoZXMgIT0gbnVsbCkgewoJCWRlc3QgPSBwYXJzZUludChtYXRjaGVzWzFdKTsKCX0gZWxzZSB7CgkJZGVzdCA9IGZpbmRTbGlkZSh3aW5kb3cubG9jYXRpb24uaGFzaC5zbGljZSgxKSk7Cgl9CglpZiAoZGVzdCAhPSBudWxsKQoJCWdvKGRlc3QgLSBzbnVtKTsKfQoKZnVuY3Rpb24gZml4TGlua3MoKSB7Cgl2YXIgdGhpc1VyaSA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmOwoJdGhpc1VyaSA9IHRoaXNVcmkuc2xpY2UoMCwgdGhpc1VyaS5sZW5ndGggLSB3aW5kb3cubG9jYXRpb24uaGFzaC5sZW5ndGgpOwoJdmFyIGFlbGVtZW50cyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdBJyk7Cglmb3IgKHZhciBpID0gMDsgaSA8IGFlbGVtZW50cy5sZW5ndGg7IGkrKykgewoJCXZhciBhID0gYWVsZW1lbnRzW2ldLmhyZWY7CgkJdmFyIHNsaWRlSUQgPSBhLm1hdGNoKCdcI3NsaWRlWzAtOV17MSwyfScpOwoJCWlmICgoc2xpZGVJRCkgJiYgKHNsaWRlSURbMF0uc2xpY2UoMCwxKSA9PSAnIycpKSB7CgkJCXZhciBkZXN0ID0gZmluZFNsaWRlKHNsaWRlSURbMF0uc2xpY2UoMSkpOwoJCQlpZiAoZGVzdCAhPSBudWxsKSB7CgkJCQlpZiAoYWVsZW1lbnRzW2ldLmFkZEV2ZW50TGlzdGVuZXIpIHsKCQkJCQlhZWxlbWVudHNbaV0uYWRkRXZlbnRMaXN0ZW5lcigiY2xpY2siLCBuZXcgRnVuY3Rpb24oImUiLAoJCQkJCQkiaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbGlkZVByb2onKS5kaXNhYmxlZCkgcmV0dXJuOyIgKwoJCQkJCQkiZ28oIitkZXN0KyIgLSBzbnVtKTsgIiArCgkJCQkJCSJpZiAoZS5wcmV2ZW50RGVmYXVsdCkgZS5wcmV2ZW50RGVmYXVsdCgpOyIpLCB0cnVlKTsKCQkJCX0gZWxzZSBpZiAoYWVsZW1lbnRzW2ldLmF0dGFjaEV2ZW50KSB7CgkJCQkJYWVsZW1lbnRzW2ldLmF0dGFjaEV2ZW50KCJvbmNsaWNrIiwgbmV3IEZ1bmN0aW9uKCIiLAoJCQkJCQkiaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbGlkZVByb2onKS5kaXNhYmxlZCkgcmV0dXJuOyIgKwoJCQkJCQkiZ28oIitkZXN0KyIgLSBzbnVtKTsgIiArCgkJCQkJCSJldmVudC5yZXR1cm5WYWx1ZSA9IGZhbHNlOyIpKTsKCQkJCX0KCQkJfQoJCX0KCX0KfQoKZnVuY3Rpb24gZXh0ZXJuYWxMaW5rcygpIHsKCWlmICghZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUpIHJldHVybjsKCXZhciBhbmNob3JzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2EnKTsKCWZvciAodmFyIGk9MDsgaTxhbmNob3JzLmxlbmd0aDsgaSsrKSB7CgkJdmFyIGFuY2hvciA9IGFuY2hvcnNbaV07CgkJaWYgKGFuY2hvci5nZXRBdHRyaWJ1dGUoJ2hyZWYnKSAmJiBoYXNWYWx1ZShhbmNob3IucmVsLCAnZXh0ZXJuYWwnKSkgewoJCQlhbmNob3IudGFyZ2V0ID0gJ19ibGFuayc7CgkJCWFkZENsYXNzKGFuY2hvciwnZXh0ZXJuYWwnKTsKCQl9Cgl9Cn0KCmZ1bmN0aW9uIGNyZWF0ZUNvbnRyb2xzKCkgewoJdmFyIGNvbnRyb2xzRGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImNvbnRyb2xzIik7CglpZiAoIWNvbnRyb2xzRGl2KSByZXR1cm47Cgl2YXIgaGlkZXIgPSAnIG9ubW91c2VvdmVyPSJzaG93SGlkZShcJ3NcJyk7IiBvbm1vdXNlb3V0PSJzaG93SGlkZShcJ2hcJyk7Iic7Cgl2YXIgaGlkZURpdiwgaGlkZUxpc3QgPSAnJzsKCWlmIChjb250cm9sVmlzID09ICdoaWRkZW4nKSB7CgkJaGlkZURpdiA9IGhpZGVyOwoJfSBlbHNlIHsKCQloaWRlTGlzdCA9IGhpZGVyOwoJfQoJY29udHJvbHNEaXYuaW5uZXJIVE1MID0gJzxmb3JtIGFjdGlvbj0iIyIgaWQ9ImNvbnRyb2xGb3JtIicgKyBoaWRlRGl2ICsgJz4nICsKCSc8ZGl2IGlkPSJuYXZMaW5rcyI+JyArCgknPGEgYWNjZXNza2V5PSJ0IiBpZD0idG9nZ2xlIiBocmVmPSJqYXZhc2NyaXB0OnRvZ2dsZSgpOyI+JiMyMTY7PFwvYT4nICsKCSc8YSBhY2Nlc3NrZXk9InoiIGlkPSJwcmV2IiBocmVmPSJqYXZhc2NyaXB0OmdvKC0xKTsiPiZsYXF1bzs8XC9hPicgKwoJJzxhIGFjY2Vzc2tleT0ieCIgaWQ9Im5leHQiIGhyZWY9ImphdmFzY3JpcHQ6Z28oMSk7Ij4mcmFxdW87PFwvYT4nICsKCSc8ZGl2IGlkPSJuYXZMaXN0IicgKyBoaWRlTGlzdCArICc+PHNlbGVjdCBpZD0ianVtcGxpc3QiIG9uY2hhbmdlPSJnbyhcJ2pcJyk7Ij48XC9zZWxlY3Q+PFwvZGl2PicgKwoJJzxcL2Rpdj48XC9mb3JtPic7CglpZiAoY29udHJvbFZpcyA9PSAnaGlkZGVuJykgewoJCXZhciBoaWRkZW4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbmF2TGlua3MnKTsKCX0gZWxzZSB7CgkJdmFyIGhpZGRlbiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdqdW1wbGlzdCcpOwoJfQoJYWRkQ2xhc3MoaGlkZGVuLCdoaWRlbWUnKTsKfQoKZnVuY3Rpb24gZm9udFNjYWxlKCkgeyAgLy8gY2F1c2VzIGxheW91dCBwcm9ibGVtcyBpbiBGaXJlRm94IHRoYXQgZ2V0IGZpeGVkIGlmIGJyb3dzZXIncyBSZWxvYWQgaXMgdXNlZDsgc2FtZSBtYXkgYmUgdHJ1ZSBvZiBvdGhlciBHZWNrby1iYXNlZCBicm93c2VycwoJaWYgKCFzNW1vZGUpIHJldHVybiBmYWxzZTsKCXZhciB2U2NhbGUgPSAyMjsgIC8vIGJvdGggeWllbGQgMzIgKGFmdGVyIHJvdW5kaW5nKSBhdCAxMDI0eDc2OAoJdmFyIGhTY2FsZSA9IDMyOyAgLy8gcGVyaGFwcyBzaG91bGQgYXV0by1jYWxjdWxhdGUgYmFzZWQgb24gdGhlbWUncyBkZWNsYXJlZCB2YWx1ZT8KCWlmICh3aW5kb3cuaW5uZXJIZWlnaHQpIHsKCQl2YXIgdlNpemUgPSB3aW5kb3cuaW5uZXJIZWlnaHQ7CgkJdmFyIGhTaXplID0gd2luZG93LmlubmVyV2lkdGg7Cgl9IGVsc2UgaWYgKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQpIHsKCQl2YXIgdlNpemUgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0OwoJCXZhciBoU2l6ZSA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aDsKCX0gZWxzZSBpZiAoZG9jdW1lbnQuYm9keS5jbGllbnRIZWlnaHQpIHsKCQl2YXIgdlNpemUgPSBkb2N1bWVudC5ib2R5LmNsaWVudEhlaWdodDsKCQl2YXIgaFNpemUgPSBkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoOwoJfSBlbHNlIHsKCQl2YXIgdlNpemUgPSA3MDA7ICAvLyBhc3N1bWluZyAxMDI0eDc2OCwgbWludXMgY2hyb21lIGFuZCBzdWNoCgkJdmFyIGhTaXplID0gMTAyNDsgLy8gdGhlc2UgZG8gbm90IGFjY291bnQgZm9yIGtpb3NrIG1vZGUgb3IgT3BlcmEgU2hvdwoJfQoJdmFyIG5ld1NpemUgPSBNYXRoLm1pbihNYXRoLnJvdW5kKHZTaXplL3ZTY2FsZSksTWF0aC5yb3VuZChoU2l6ZS9oU2NhbGUpKTsKCWZvbnRTaXplKG5ld1NpemUgKyAncHgnKTsKCWlmIChpc0dlKSB7ICAvLyBoYWNrIHRvIGNvdW50ZXIgaW5jcmVtZW50YWwgcmVmbG93IGJ1Z3MKCQl2YXIgb2JqID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2JvZHknKVswXTsKCQlvYmouc3R5bGUuZGlzcGxheSA9ICdub25lJzsKCQlvYmouc3R5bGUuZGlzcGxheSA9ICdibG9jayc7Cgl9Cn0KCmZ1bmN0aW9uIGZvbnRTaXplKHZhbHVlKSB7CglpZiAoIShzNXNzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3M1c3MnKSkpIHsKCQlpZiAoIWlzSUUpIHsKCQkJZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2hlYWQnKVswXS5hcHBlbmRDaGlsZChzNXNzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKSk7CgkJCXM1c3Muc2V0QXR0cmlidXRlKCdtZWRpYScsJ3NjcmVlbiwgcHJvamVjdGlvbicpOwoJCQlzNXNzLnNldEF0dHJpYnV0ZSgnaWQnLCdzNXNzJyk7CgkJfSBlbHNlIHsKCQkJZG9jdW1lbnQuY3JlYXRlU3R5bGVTaGVldCgpOwoJCQlkb2N1bWVudC5zNXNzID0gZG9jdW1lbnQuc3R5bGVTaGVldHNbZG9jdW1lbnQuc3R5bGVTaGVldHMubGVuZ3RoIC0gMV07CgkJfQoJfQoJaWYgKCFpc0lFKSB7CgkJd2hpbGUgKHM1c3MubGFzdENoaWxkKSBzNXNzLnJlbW92ZUNoaWxkKHM1c3MubGFzdENoaWxkKTsKCQlzNXNzLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCdib2R5IHtmb250LXNpemU6ICcgKyB2YWx1ZSArICcgIWltcG9ydGFudDt9JykpOwoJfSBlbHNlIHsKCQlkb2N1bWVudC5zNXNzLmFkZFJ1bGUoJ2JvZHknLCdmb250LXNpemU6ICcgKyB2YWx1ZSArICcgIWltcG9ydGFudDsnKTsKCX0KfQoKZnVuY3Rpb24gbm90T3BlcmFGaXgoKSB7CglzbGlkZUNTUyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbGlkZVByb2onKS5ocmVmOwoJdmFyIHNsaWRlcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbGlkZVByb2onKTsKCXZhciBvdXRsaW5lID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ291dGxpbmVTdHlsZScpOwoJc2xpZGVzLnNldEF0dHJpYnV0ZSgnbWVkaWEnLCdzY3JlZW4nKTsKCW91dGxpbmUuZGlzYWJsZWQgPSB0cnVlOwoJaWYgKGlzR2UpIHsKCQlzbGlkZXMuc2V0QXR0cmlidXRlKCdocmVmJywnbnVsbCcpOyAgIC8vIEdlY2tvIGZpeAoJCXNsaWRlcy5zZXRBdHRyaWJ1dGUoJ2hyZWYnLHNsaWRlQ1NTKTsgLy8gR2Vja28gZml4Cgl9CglpZiAoaXNJRSAmJiBkb2N1bWVudC5zdHlsZVNoZWV0cyAmJiBkb2N1bWVudC5zdHlsZVNoZWV0c1swXSkgewoJCWRvY3VtZW50LnN0eWxlU2hlZXRzWzBdLmFkZFJ1bGUoJ2ltZycsICdiZWhhdmlvcjogdXJsKHVpL2RlZmF1bHQvaWVwbmdmaXguaHRjKScpOwoJCWRvY3VtZW50LnN0eWxlU2hlZXRzWzBdLmFkZFJ1bGUoJ2RpdicsICdiZWhhdmlvcjogdXJsKHVpL2RlZmF1bHQvaWVwbmdmaXguaHRjKScpOwoJCWRvY3VtZW50LnN0eWxlU2hlZXRzWzBdLmFkZFJ1bGUoJy5zbGlkZScsICdiZWhhdmlvcjogdXJsKHVpL2RlZmF1bHQvaWVwbmdmaXguaHRjKScpOwoJfQp9CgpmdW5jdGlvbiBnZXRJbmNyZW1lbnRhbHMob2JqKSB7Cgl2YXIgaW5jcmVtZW50YWxzID0gbmV3IEFycmF5KCk7CglpZiAoIW9iaikgCgkJcmV0dXJuIGluY3JlbWVudGFsczsKCXZhciBjaGlsZHJlbiA9IG9iai5jaGlsZE5vZGVzOwoJZm9yICh2YXIgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykgewoJCXZhciBjaGlsZCA9IGNoaWxkcmVuW2ldOwoJCWlmIChoYXNDbGFzcyhjaGlsZCwgJ2luY3JlbWVudGFsJykpIHsKCQkJaWYgKGNoaWxkLm5vZGVOYW1lID09ICdPTCcgfHwgY2hpbGQubm9kZU5hbWUgPT0gJ1VMJykgewoJCQkJcmVtb3ZlQ2xhc3MoY2hpbGQsICdpbmNyZW1lbnRhbCcpOwoJCQkJZm9yICh2YXIgaiA9IDA7IGogPCBjaGlsZC5jaGlsZE5vZGVzLmxlbmd0aDsgaisrKSB7CgkJCQkJaWYgKGNoaWxkLmNoaWxkTm9kZXNbal0ubm9kZVR5cGUgPT0gMSkgewoJCQkJCQlhZGRDbGFzcyhjaGlsZC5jaGlsZE5vZGVzW2pdLCAnaW5jcmVtZW50YWwnKTsKCQkJCQl9CgkJCQl9CgkJCX0gZWxzZSB7CgkJCQlpbmNyZW1lbnRhbHNbaW5jcmVtZW50YWxzLmxlbmd0aF0gPSBjaGlsZDsKCQkJCXJlbW92ZUNsYXNzKGNoaWxkLCdpbmNyZW1lbnRhbCcpOwoJCQl9CgkJfQoJCWlmIChoYXNDbGFzcyhjaGlsZCwgJ3Nob3ctZmlyc3QnKSkgewoJCQlpZiAoY2hpbGQubm9kZU5hbWUgPT0gJ09MJyB8fCBjaGlsZC5ub2RlTmFtZSA9PSAnVUwnKSB7CgkJCQlyZW1vdmVDbGFzcyhjaGlsZCwgJ3Nob3ctZmlyc3QnKTsKCQkJCWlmIChjaGlsZC5jaGlsZE5vZGVzW2lzR2VdLm5vZGVUeXBlID09IDEpIHsKCQkJCQlyZW1vdmVDbGFzcyhjaGlsZC5jaGlsZE5vZGVzW2lzR2VdLCAnaW5jcmVtZW50YWwnKTsKCQkJCX0KCQkJfSBlbHNlIHsKCQkJCWluY3JlbWVudGFsc1tpbmNyZW1lbnRhbHMubGVuZ3RoXSA9IGNoaWxkOwoJCQl9CgkJfQoJCWluY3JlbWVudGFscyA9IGluY3JlbWVudGFscy5jb25jYXQoZ2V0SW5jcmVtZW50YWxzKGNoaWxkKSk7Cgl9CglyZXR1cm4gaW5jcmVtZW50YWxzOwp9CgpmdW5jdGlvbiBjcmVhdGVJbmNyZW1lbnRhbHMoKSB7Cgl2YXIgaW5jcmVtZW50YWxzID0gbmV3IEFycmF5KCk7Cglmb3IgKHZhciBpID0gMDsgaSA8IHNtYXg7IGkrKykgewoJCWluY3JlbWVudGFsc1tpXSA9IGdldEluY3JlbWVudGFscyhkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2xpZGUnK2kpKTsKCX0KCXJldHVybiBpbmNyZW1lbnRhbHM7Cn0KCmZ1bmN0aW9uIGRlZmF1bHRDaGVjaygpIHsKCXZhciBhbGxNZXRhcyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdtZXRhJyk7Cglmb3IgKHZhciBpID0gMDsgaTwgYWxsTWV0YXMubGVuZ3RoOyBpKyspIHsKCQlpZiAoYWxsTWV0YXNbaV0ubmFtZSA9PSAnZGVmYXVsdFZpZXcnKSB7CgkJCWRlZmF1bHRWaWV3ID0gYWxsTWV0YXNbaV0uY29udGVudDsKCQl9CgkJaWYgKGFsbE1ldGFzW2ldLm5hbWUgPT0gJ2NvbnRyb2xWaXMnKSB7CgkJCWNvbnRyb2xWaXMgPSBhbGxNZXRhc1tpXS5jb250ZW50OwoJCX0KCX0KfQoKLy8gS2V5IHRyYXAgZml4LCBuZXcgZnVuY3Rpb24gYm9keSBmb3IgdHJhcCgpCmZ1bmN0aW9uIHRyYXAoZSkgewoJaWYgKCFlKSB7CgkJZSA9IGV2ZW50OwoJCWUud2hpY2ggPSBlLmtleUNvZGU7Cgl9Cgl0cnkgewoJCW1vZGlmaWVyS2V5ID0gZS5jdHJsS2V5IHx8IGUuYWx0S2V5IHx8IGUubWV0YUtleTsKCX0KCWNhdGNoKGUpIHsKCQltb2RpZmllcktleSA9IGZhbHNlOwoJfQoJcmV0dXJuIG1vZGlmaWVyS2V5IHx8IGUud2hpY2ggPT0gMDsKfQoKZnVuY3Rpb24gc3RhcnR1cCgpIHsKCWRlZmF1bHRDaGVjaygpOwoJaWYgKCFpc09wKSBjcmVhdGVDb250cm9scygpOwoJc2xpZGVMYWJlbCgpOwoJZml4TGlua3MoKTsKCWV4dGVybmFsTGlua3MoKTsKCWZvbnRTY2FsZSgpOwoJaWYgKCFpc09wKSB7CgkJbm90T3BlcmFGaXgoKTsKCQlpbmNyZW1lbnRhbHMgPSBjcmVhdGVJbmNyZW1lbnRhbHMoKTsKCQlzbGlkZUp1bXAoKTsKCQlpZiAoZGVmYXVsdFZpZXcgPT0gJ291dGxpbmUnKSB7CgkJCXRvZ2dsZSgpOwoJCX0KCQlkb2N1bWVudC5vbmtleXVwID0ga2V5czsKCQlkb2N1bWVudC5vbmtleXByZXNzID0gdHJhcDsKCQlkb2N1bWVudC5vbmNsaWNrID0gY2xpY2tlcjsKCX0KfQoKd2luZG93Lm9ubG9hZCA9IHN0YXJ0dXA7CndpbmRvdy5vbnJlc2l6ZSA9IGZ1bmN0aW9uKCl7c2V0VGltZW91dCgnZm9udFNjYWxlKCknLCA1MCk7fQ==" type="text/javascript"></script>
<script src="data:application/x-javascript;base64,LyoNCkxhVGVYTWF0aE1MLmpzDQo9PT09PT09PT09PT09PQ0KDQpUaGlzIGZpbGUsIGluIHRoaXMgZm9ybSwgaXMgZHVlIHRvIERvdWdsYXMgV29vZGFsbCwgSnVuZSAyMDA2Lg0KSXQgY29udGFpbnMgSmF2YVNjcmlwdCBmdW5jdGlvbnMgdG8gY29udmVydCAobW9zdCBzaW1wbGUpIExhVGVYDQptYXRoIG5vdGF0aW9uIHRvIFByZXNlbnRhdGlvbiBNYXRoTUwuICBJdCB3YXMgb2J0YWluZWQgYnkNCmRvd25sb2FkaW5nIHRoZSBmaWxlIEFTQ0lJTWF0aE1MLmpzIGZyb20NCglodHRwOi8vd3d3MS5jaGFwbWFuLmVkdS9+amlwc2VuL21hdGhtbC9hc2NpaW1hdGhkb3dubG9hZC8NCmFuZCBtb2RpZnlpbmcgaXQgc28gdGhhdCBpdCBjYXJyaWVzIG91dCBPTkxZIHRob3NlIGNvbnZlcnNpb25zDQp0aGF0IHdvdWxkIGJlIGNhcnJpZWQgb3V0IGluIExhVGVYLiAgQSBkZXNjcmlwdGlvbiBvZiB0aGUgb3JpZ2luYWwNCmZpbGUsIHdpdGggZXhhbXBsZXMsIGNhbiBiZSBmb3VuZCBhdA0KCXd3dzEuY2hhcG1hbi5lZHUvfmppcHNlbi9tYXRobWwvYXNjaWltYXRoLmh0bWwNCglBU0NJSU1hdGhNTDogTWF0aCBvbiB0aGUgd2ViIGZvciBldmVyeW9uZQ0KDQpIZXJlIGlzIHRoZSBoZWFkZXIgbm90aWNlIGZyb20gdGhlIG9yaWdpbmFsIGZpbGU6DQoNCkFTQ0lJTWF0aE1MLmpzDQo9PT09PT09PT09PT09PQ0KVGhpcyBmaWxlIGNvbnRhaW5zIEphdmFTY3JpcHQgZnVuY3Rpb25zIHRvIGNvbnZlcnQgQVNDSUkgbWF0aCBub3RhdGlvbg0KdG8gUHJlc2VudGF0aW9uIE1hdGhNTC4gVGhlIGNvbnZlcnNpb24gaXMgZG9uZSB3aGlsZSB0aGUgKFgpSFRNTCBwYWdlDQpsb2FkcywgYW5kIHNob3VsZCB3b3JrIHdpdGggRmlyZWZveC9Nb3ppbGxhL05ldHNjYXBlIDcrIGFuZCBJbnRlcm5ldA0KRXhwbG9yZXIgNitNYXRoUGxheWVyIChodHRwOi8vd3d3LmRlc3NjaS5jb20vZW4vcHJvZHVjdHMvbWF0aHBsYXllci8pLg0KSnVzdCBhZGQgdGhlIG5leHQgbGluZSB0byB5b3VyIChYKUhUTUwgcGFnZSB3aXRoIHRoaXMgZmlsZSBpbiB0aGUgc2FtZSBmb2xkZXI6DQo8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJBU0NJSU1hdGhNTC5qcyI+PC9zY3JpcHQ+DQpUaGlzIGlzIGEgY29udmVuaWVudCBhbmQgaW5leHBlbnNpdmUgc29sdXRpb24gZm9yIGF1dGhvcmluZyBNYXRoTUwuDQoNClZlcnNpb24gMS40LjcgRGVjIDE1LCAyMDA1LCAoYykgUGV0ZXIgSmlwc2VuIGh0dHA6Ly93d3cuY2hhcG1hbi5lZHUvfmppcHNlbg0KTGF0ZXN0IHZlcnNpb24gYXQgaHR0cDovL3d3dy5jaGFwbWFuLmVkdS9+amlwc2VuL21hdGhtbC9BU0NJSU1hdGhNTC5qcw0KRm9yIGNoYW5nZXMgc2VlIGh0dHA6Ly93d3cuY2hhcG1hbi5lZHUvfmppcHNlbi9tYXRobWwvYXNjaWltYXRoY2hhbmdlcy50eHQNCklmIHlvdSB1c2UgaXQgb24gYSB3ZWJwYWdlLCBwbGVhc2Ugc2VuZCB0aGUgVVJMIHRvIGppcHNlbkBjaGFwbWFuLmVkdQ0KDQpUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQ0KaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkNCnRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdA0KeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLg0KDQpUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwNCmJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mDQpNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSB0aGUgR05VDQpHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIChhdCBodHRwOi8vd3d3LmdudS5vcmcvY29weWxlZnQvZ3BsLmh0bWwpDQpmb3IgbW9yZSBkZXRhaWxzLg0KDQpMYVRlWE1hdGhNTC5qcyAoY3RkKQ0KPT09PT09PT09PT09PT0NCg0KVGhlIGluc3RydWN0aW9ucyBmb3IgdXNlIGFyZSB0aGUgc2FtZSBhcyBmb3IgdGhlIG9yaWdpbmFsDQpBU0NJSU1hdGhNTC5qcywgZXhjZXB0IHRoYXQgb2YgY291cnNlIHRoZSBsaW5lIHlvdSBhZGQgdG8geW91cg0KZmlsZSBzaG91bGQgYmUNCjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9IkxhVGVYTWF0aE1MLmpzIj48L3NjcmlwdD4NCk9yIHVzZSBhYnNvbHV0ZSBwYXRoIG5hbWVzIGlmIHRoZSBmaWxlIGlzIG5vdCBpbiB0aGUgc2FtZSBmb2xkZXINCmFzIHlvdXIgKFgpSFRNTCBwYWdlLg0KKi8NCg0KdmFyIGNoZWNrRm9yTWF0aE1MID0gdHJ1ZTsgICAvLyBjaGVjayBpZiBicm93c2VyIGNhbiBkaXNwbGF5IE1hdGhNTA0KdmFyIG5vdGlmeUlmTm9NYXRoTUwgPSB0cnVlOyAvLyBkaXNwbGF5IG5vdGUgaWYgbm8gTWF0aE1MIGNhcGFiaWxpdHkNCnZhciBhbGVydElmTm9NYXRoTUwgPSBmYWxzZTsgIC8vIHNob3cgYWxlcnQgYm94IGlmIG5vIE1hdGhNTCBjYXBhYmlsaXR5DQovLyB3YXMgInJlZCI6DQp2YXIgbWF0aGNvbG9yID0gIiI7CSAgICAgLy8gY2hhbmdlIGl0IHRvICIiICh0byBpbmhlcml0KSBvciBhbnkgb3RoZXIgY29sb3INCi8vIHdhcyAic2VyaWYiOg0KdmFyIG1hdGhmb250ZmFtaWx5ID0gIiI7ICAgICAgLy8gY2hhbmdlIHRvICIiIHRvIGluaGVyaXQgKHdvcmtzIGluIElFKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3IgYW5vdGhlciBmYW1pbHkgKGUuZy4gImFyaWFsIikNCnZhciBzaG93YXNjaWlmb3JtdWxhb25ob3ZlciA9IHRydWU7IC8vIGhlbHBzIHN0dWRlbnRzIGxlYXJuIEFTQ0lJTWF0aA0KLyoNCi8vIENvbW1lbnRlZCBvdXQgYnkgRFJXIC0tIG5vdCBub3cgdXNlZCAtLSBzZWUgREVMSU1JVEVSUyAodHdpY2UpIG5lYXIgdGhlIGVuZA0KdmFyIGRpc3BsYXlzdHlsZSA9IGZhbHNlOyAgICAgLy8gcHV0cyBsaW1pdHMgYWJvdmUgYW5kIGJlbG93IGxhcmdlIG9wZXJhdG9ycw0KdmFyIGRlY2ltYWxzaWduID0gIi4iOyAgICAgICAgLy8gY2hhbmdlIHRvICIsIiBpZiB5b3UgbGlrZSwgYmV3YXJlIG9mIGAoMSwyKWAhDQp2YXIgQU1kZWxpbWl0ZXIxID0gImAiLCBBTWVzY2FwZTEgPSAiXFxcXGAiOyAvLyBjYW4gdXNlIG90aGVyIGNoYXJhY3RlcnMNCnZhciBBTWRlbGltaXRlcjIgPSAiJCIsIEFNZXNjYXBlMiA9ICJcXFxcXFwkIiwgQU1kZWxpbWl0ZXIycmVnZXhwID0gIlxcJCI7DQp2YXIgZG91YmxlYmxhbmttYXRoZGVsaW1pdGVyID0gZmFsc2U7IC8vIGlmIHRydWUsICB4KzEgIGlzIGVxdWFsIHRvIGB4KzFgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvciBJRSB0aGlzIHdvcmtzIG9ubHkgaW4gPCEtLSAgIC0tPg0KLy92YXIgc2VwYXJhdGV0b2tlbnM7Ly8gaGFzIGJlZW4gcmVtb3ZlZCAoZW1haWwgbWUgaWYgdGhpcyBpcyBhIHByb2JsZW0pDQoqLw0KdmFyIGlzSUUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlM9PW51bGw7DQoNCmlmIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZD09bnVsbCkNCiAgYWxlcnQoIlRoaXMgd2VicGFnZSByZXF1aXJlcyBhIHJlY2VudCBicm93c2VyIHN1Y2ggYXMgXG5Nb3ppbGxhL05ldHNjYXBlIDcrIG9yIEludGVybmV0IEV4cGxvcmVyIDYrTWF0aFBsYXllciIpDQoNCi8vIGFsbCBmdXJ0aGVyIGdsb2JhbCB2YXJpYWJsZXMgc3RhcnQgd2l0aCAiQU0iDQoNCmZ1bmN0aW9uIEFNY3JlYXRlRWxlbWVudFhIVE1MKHQpIHsNCiAgaWYgKGlzSUUpIHJldHVybiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHQpOw0KICBlbHNlIHJldHVybiBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiLHQpOw0KfQ0KDQpmdW5jdGlvbiBBTW5vTWF0aE1MTm90ZSgpIHsNCiAgdmFyIG5kID0gQU1jcmVhdGVFbGVtZW50WEhUTUwoImgzIik7DQogIG5kLnNldEF0dHJpYnV0ZSgiYWxpZ24iLCJjZW50ZXIiKQ0KICBuZC5hcHBlbmRDaGlsZChBTWNyZWF0ZUVsZW1lbnRYSFRNTCgicCIpKTsNCiAgbmQuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoIlRvIHZpZXcgdGhlICIpKTsNCiAgdmFyIGFuID0gQU1jcmVhdGVFbGVtZW50WEhUTUwoImEiKTsNCiAgYW4uYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoIkxhVGVYTWF0aE1MIikpOw0KICBhbi5zZXRBdHRyaWJ1dGUoImhyZWYiLCJodHRwOi8vd3d3Lm1hdGhzLm5vdHQuYWMudWsvcGVyc29uYWwvZHJ3L2xtLmh0bWwiKTsNCiAgbmQuYXBwZW5kQ2hpbGQoYW4pOw0KICBuZC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgiIG5vdGF0aW9uIHVzZSBJbnRlcm5ldCBFeHBsb3JlciA2KyIpKTsgDQogIGFuID0gQU1jcmVhdGVFbGVtZW50WEhUTUwoImEiKTsNCiAgYW4uYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoIk1hdGhQbGF5ZXIiKSk7DQogIGFuLnNldEF0dHJpYnV0ZSgiaHJlZiIsImh0dHA6Ly93d3cuZGVzc2NpLmNvbS9lbi9wcm9kdWN0cy9tYXRocGxheWVyL2Rvd25sb2FkLmh0bSIpOw0KICBuZC5hcHBlbmRDaGlsZChhbik7DQogIG5kLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCIgb3IgTmV0c2NhcGUvTW96aWxsYS9GaXJlZm94IikpOw0KICBuZC5hcHBlbmRDaGlsZChBTWNyZWF0ZUVsZW1lbnRYSFRNTCgicCIpKTsNCiAgcmV0dXJuIG5kOw0KfQ0KDQpmdW5jdGlvbiBBTWlzTWF0aE1MYXZhaWxhYmxlKCkgew0KICBpZiAobmF2aWdhdG9yLmFwcE5hbWUuc2xpY2UoMCw4KT09Ik5ldHNjYXBlIikNCiAgICBpZiAobmF2aWdhdG9yLmFwcFZlcnNpb24uc2xpY2UoMCwxKT49IjUiKSByZXR1cm4gbnVsbDsNCiAgICBlbHNlIHJldHVybiBBTW5vTWF0aE1MTm90ZSgpOw0KICBlbHNlIGlmIChuYXZpZ2F0b3IuYXBwTmFtZS5zbGljZSgwLDkpPT0iTWljcm9zb2Z0IikNCiAgICB0cnkgew0KICAgICAgICB2YXIgQWN0aXZlWCA9IG5ldyBBY3RpdmVYT2JqZWN0KCJNYXRoUGxheWVyLkZhY3RvcnkuMSIpOw0KICAgICAgICByZXR1cm4gbnVsbDsNCiAgICB9IGNhdGNoIChlKSB7DQogICAgICAgIHJldHVybiBBTW5vTWF0aE1MTm90ZSgpOw0KICAgIH0NCiAgZWxzZSByZXR1cm4gQU1ub01hdGhNTE5vdGUoKTsNCn0NCg0KLy8gY2hhcmFjdGVyIGxpc3RzIGZvciBNb3ppbGxhL05ldHNjYXBlIGZvbnRzDQp2YXIgQU1jYWwgPSBbIlx1RDgzNVx1REM5QyIsICJcdUQ4MzVcdURDOUQiLCAiXHVEODM1XHVEQzlFIiwgIlx1RDgzNVx1REM5RiIsICJcdUQ4MzVcdURDQTAiLCAiXHVEODM1XHVEQ0ExIiwgIlx1RDgzNVx1RENBMiIsICJcdUQ4MzVcdURDQTMiLCAiXHVEODM1XHVEQ0E0IiwgIlx1RDgzNVx1RENBNSIsICJcdUQ4MzVcdURDQTYiLCAiXHVEODM1XHVEQ0E3IiwgIlx1RDgzNVx1RENBOCIsICJcdUQ4MzVcdURDQTkiLCAiXHVEODM1XHVEQ0FBIiwgIlx1RDgzNVx1RENBQiIsICJcdUQ4MzVcdURDQUMiLCAiXHVEODM1XHVEQ0FEIiwgIlx1RDgzNVx1RENBRSIsICJcdUQ4MzVcdURDQUYiLCAiXHVEODM1XHVEQ0IwIiwgIlx1RDgzNVx1RENCMSIsICJcdUQ4MzVcdURDQjIiLCAiXHVEODM1XHVEQ0IzIiwgIlx1RDgzNVx1RENCNCIsICJcdUQ4MzVcdURDQjUiXTsNCnZhciBBTWZyayA9IFsiXHVEODM1XHVERDA0IiwgIlx1RDgzNVx1REQwNSIsICJcdUQ4MzVcdUREMDYiLCAiXHVEODM1XHVERDA3IiwgIlx1RDgzNVx1REQwOCIsICJcdUQ4MzVcdUREMDkiLCAiXHVEODM1XHVERDBBIiwgIlx1RDgzNVx1REQwQiIsICJcdUQ4MzVcdUREMEMiLCAiXHVEODM1XHVERDBEIiwgIlx1RDgzNVx1REQwRSIsICJcdUQ4MzVcdUREMEYiLCAiXHVEODM1XHVERDEwIiwgIlx1RDgzNVx1REQxMSIsICJcdUQ4MzVcdUREMTIiLCAiXHVEODM1XHVERDEzIiwgIlx1RDgzNVx1REQxNCIsICJcdUQ4MzVcdUREMTUiLCAiXHVEODM1XHVERDE2IiwgIlx1RDgzNVx1REQxNyIsICJcdUQ4MzVcdUREMTgiLCAiXHVEODM1XHVERDE5IiwgIlx1RDgzNVx1REQxQSIsICJcdUQ4MzVcdUREMUIiLCAiXHVEODM1XHVERDFDIiwgIlx1RDgzNVx1REQxRCJdOw0KdmFyIEFNYmJiID0gWyJcdUQ4MzVcdUREMzgiLCAiXHVEODM1XHVERDM5IiwgIlx1RDgzNVx1REQzQSIsICJcdUQ4MzVcdUREM0IiLCAiXHVEODM1XHVERDNDIiwgIlx1RDgzNVx1REQzRCIsICJcdUQ4MzVcdUREM0UiLCAiXHVEODM1XHVERDNGIiwgIlx1RDgzNVx1REQ0MCIsICJcdUQ4MzVcdURENDEiLCAiXHVEODM1XHVERDQyIiwgIlx1RDgzNVx1REQ0MyIsICJcdUQ4MzVcdURENDQiLCAiXHVEODM1XHVERDQ1IiwgIlx1RDgzNVx1REQ0NiIsICJcdUQ4MzVcdURENDciLCAiXHVEODM1XHVERDQ4IiwgIlx1RDgzNVx1REQ0OSIsICJcdUQ4MzVcdURENEEiLCAiXHVEODM1XHVERDRCIiwgIlx1RDgzNVx1REQ0QyIsICJcdUQ4MzVcdURENEQiLCAiXHVEODM1XHVERDRFIiwgIlx1RDgzNVx1REQ0RiIsICJcdUQ4MzVcdURENTAiLCAiXHVEODM1XHVERDUxIl07DQoNCnZhciBDT05TVCA9IDAsIFVOQVJZID0gMSwgQklOQVJZID0gMiwgSU5GSVggPSAzLCBMRUZUQlJBQ0tFVCA9IDQsDQogICAgUklHSFRCUkFDS0VUID0gNSwgU1BBQ0UgPSA2LCBVTkRFUk9WRVIgPSA3LCBERUZJTklUSU9OID0gOCwNCiAgICBURVhUID0gOSwgQklHID0gMTAsIExPTkcgPSAxMSwgU1RSRVRDSFkgPSAxMiwgTUFUUklYID0gMTM7IC8vIHRva2VuIHR5cGVzDQoNCnZhciBBTXNxcnQgPSB7aW5wdXQ6Ilxcc3FydCIsCXRhZzoibXNxcnQiLCBvdXRwdXQ6InNxcnQiLAl0dHlwZTpVTkFSWX0sDQogIEFNbm90ID0ge2lucHV0OiJcXG5vdCIsCXRhZzoibW5vdCIsIG91dHB1dDoibm90IiwJdHR5cGU6VU5BUll9LA0KICBBTXJvb3QgPSB7aW5wdXQ6Ilxccm9vdCIsCXRhZzoibXJvb3QiLCBvdXRwdXQ6InJvb3QiLAl0dHlwZTpCSU5BUll9LA0KICBBTWZyYWMgPSB7aW5wdXQ6IlxcZnJhYyIsCXRhZzoibWZyYWMiLCBvdXRwdXQ6Ii8iLAl0dHlwZTpCSU5BUll9LA0KICBBTW92ZXIgPSB7aW5wdXQ6Ilxcc3RhY2tyZWwiLCB0YWc6Im1vdmVyIiwgb3V0cHV0OiJzdGFja3JlbCIsIHR0eXBlOkJJTkFSWX0sDQogIEFNYXRvcCA9IHtpbnB1dDoiXFxhdG9wIiwJdGFnOiJtZnJhYyIsIG91dHB1dDoiIiwJCXR0eXBlOklORklYfSwNCiAgQU1jaG9vc2UgPSB7aW5wdXQ6IlxcY2hvb3NlIiwgdGFnOiJtZnJhYyIsIG91dHB1dDoiIiwJCXR0eXBlOklORklYfSwNCiAgQU1zdWIgID0ge2lucHV0OiJfIiwJCXRhZzoibXN1YiIsICBvdXRwdXQ6Il8iLAl0dHlwZTpJTkZJWH0sDQogIEFNc3VwICA9IHtpbnB1dDoiXiIsCQl0YWc6Im1zdXAiLCAgb3V0cHV0OiJeIiwJdHR5cGU6SU5GSVh9LA0KICBBTXRleHQgPSB7aW5wdXQ6IlxcbWF0aHJtIiwJdGFnOiJtdGV4dCIsIG91dHB1dDoidGV4dCIsCXR0eXBlOlRFWFR9LA0KICBBTW1ib3ggPSB7aW5wdXQ6IlxcbWJveCIsCXRhZzoibXRleHQiLCBvdXRwdXQ6Im1ib3giLAl0dHlwZTpURVhUfTsNCg0KLy8gQ29tbWVudGVkIG91dCBieSBEUlcgdG8gcHJldmVudCAxLzIgdHVybmluZyBpbnRvIGEgMi1saW5lIGZyYWN0aW9uDQovLyBBTWRpdiAgID0ge2lucHV0OiIvIiwJIHRhZzoibWZyYWMiLCBvdXRwdXQ6Ii8iLCAgICB0dHlwZTpJTkZJWH0sDQovLyBDb21tZW50ZWQgb3V0IGJ5IERSVyBzbyB0aGF0ICIgcHJpbnRzIGxpdGVyYWxseSBpbiBlcXVhdGlvbnMNCi8vIEFNcXVvdGUgPSB7aW5wdXQ6IlwiIiwJIHRhZzoibXRleHQiLCBvdXRwdXQ6Im1ib3giLCB0dHlwZTpURVhUfTsNCg0KLy8gTGlzdCBvZiBuZWdhdGlvbnMgb2J0YWluZWQgZnJvbSBodHRwOi8vZnJvZG8uZWxvbi5lZHUvdHV0b3JpYWwvdHV0b3JpYWwucGRmDQp2YXIgQU1SZWxhdGlvbk5lZ2F0aW9ucyA9IHsNCiAgIlx1MDAzQyI6Ilx1MjI2RSIsICJcdTAwM0UiOiJcdTIyNkYiLCAiXHUyMjY0IjoiXHUyMjcwIiwgIlx1MjI2NSI6Ilx1MjI3MSIsDQogICJcdTAwM0QiOiJcdTIyNjAiLCAiXHUyMjYxIjoiXHUyMjYyIiwgIlx1MjI3QSI6Ilx1MjI4MCIsICJcdTIyN0IiOiJcdTIyODEiLA0KICAiXHUyMjdDIjoiXHUyMkUwIiwgIlx1MjI3RCI6Ilx1MjJFMSIsICJcdTIyM0MiOiJcdTIyNDEiLCAiXHUyMjQzIjoiXHUyMjQ0IiwNCiAgIlx1MjI4MiI6Ilx1MjI4NCIsICJcdTIyODMiOiJcdTIyODUiLCAiXHUyMjg2IjoiXHUyMjg4IiwgIlx1MjI4NyI6Ilx1MjI4OSIsDQogICJcdTIyNDgiOiJcdTIyNDkiLCAiXHUyMjQ1IjoiXHUyMjQ3IiwgIlx1MjI5MSI6Ilx1MjJFMiIsICJcdTIyOTIiOiJcdTIyRTMiLA0KICAiXHUyMjREIjoiXHUyMjZEIg0KfQ0KDQp2YXIgQU1zeW1ib2xzID0gWw0KLy9HcmVlayBsZXR0ZXJzDQp7aW5wdXQ6IlxcYWxwaGEiLAl0YWc6Im1pIiwgb3V0cHV0OiJcdTAzQjEiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcYmV0YSIsCXRhZzoibWkiLCBvdXRwdXQ6Ilx1MDNCMiIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxnYW1tYSIsCXRhZzoibWkiLCBvdXRwdXQ6Ilx1MDNCMyIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxkZWx0YSIsCXRhZzoibWkiLCBvdXRwdXQ6Ilx1MDNCNCIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxlcHNpbG9uIiwJdGFnOiJtaSIsIG91dHB1dDoiXHUwM0I1IiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHZhcmVwc2lsb24iLCAgdGFnOiJtaSIsIG91dHB1dDoiXHUwMjVCIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHpldGEiLAl0YWc6Im1pIiwgb3V0cHV0OiJcdTAzQjYiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcZXRhIiwJCXRhZzoibWkiLCBvdXRwdXQ6Ilx1MDNCNyIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFx0aGV0YSIsCXRhZzoibWkiLCBvdXRwdXQ6Ilx1MDNCOCIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFx2YXJ0aGV0YSIsCXRhZzoibWkiLCBvdXRwdXQ6Ilx1MDNEMSIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxpb3RhIiwJdGFnOiJtaSIsIG91dHB1dDoiXHUwM0I5IiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGthcHBhIiwJdGFnOiJtaSIsIG91dHB1dDoiXHUwM0JBIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGxhbWJkYSIsCXRhZzoibWkiLCBvdXRwdXQ6Ilx1MDNCQiIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxtdSIsCQl0YWc6Im1pIiwgb3V0cHV0OiJcdTAzQkMiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcbnUiLAkJdGFnOiJtaSIsIG91dHB1dDoiXHUwM0JEIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHhpIiwJCXRhZzoibWkiLCBvdXRwdXQ6Ilx1MDNCRSIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxwaSIsCQl0YWc6Im1pIiwgb3V0cHV0OiJcdTAzQzAiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcdmFycGkiLAl0YWc6Im1pIiwgb3V0cHV0OiJcdTAzRDYiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxccmhvIiwJCXRhZzoibWkiLCBvdXRwdXQ6Ilx1MDNDMSIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFx2YXJyaG8iLAl0YWc6Im1pIiwgb3V0cHV0OiJcdTAzRjEiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcdmFyc2lnbWEiLAl0YWc6Im1pIiwgb3V0cHV0OiJcdTAzQzIiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6Ilxcc2lnbWEiLAl0YWc6Im1pIiwgb3V0cHV0OiJcdTAzQzMiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcdGF1IiwJCXRhZzoibWkiLCBvdXRwdXQ6Ilx1MDNDNCIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFx1cHNpbG9uIiwJdGFnOiJtaSIsIG91dHB1dDoiXHUwM0M1IiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHBoaSIsCQl0YWc6Im1pIiwgb3V0cHV0OiJcdTAzQzYiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcdmFycGhpIiwJdGFnOiJtaSIsIG91dHB1dDoiXHUwM0Q1IiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGNoaSIsCQl0YWc6Im1pIiwgb3V0cHV0OiJcdTAzQzciLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxccHNpIiwJCXRhZzoibWkiLCBvdXRwdXQ6Ilx1MDNDOCIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxvbWVnYSIsCXRhZzoibWkiLCBvdXRwdXQ6Ilx1MDNDOSIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxHYW1tYSIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MDM5MyIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxEZWx0YSIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MDM5NCIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxUaGV0YSIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MDM5OCIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxMYW1iZGEiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTAzOUIiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcWGkiLAkJdGFnOiJtbyIsIG91dHB1dDoiXHUwMzlFIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXFBpIiwJCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MDNBMCIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxTaWdtYSIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MDNBMyIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxVcHNpbG9uIiwJdGFnOiJtbyIsIG91dHB1dDoiXHUwM0E1IiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXFBoaSIsCQl0YWc6Im1vIiwgb3V0cHV0OiJcdTAzQTYiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcUHNpIiwJCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MDNBOCIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxPbWVnYSIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MDNBOSIsIHR0eXBlOkNPTlNUfSwNCg0KLy9mcmFjdGlvbnMNCntpbnB1dDoiXFxmcmFjMTIiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTAwQkQiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcZnJhYzE0IiwJdGFnOiJtbyIsIG91dHB1dDoiXHUwMEJDIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGZyYWMzNCIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MDBCRSIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxmcmFjMTMiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIxNTMiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcZnJhYzIzIiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMTU0IiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGZyYWMxNSIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjE1NSIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxmcmFjMjUiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIxNTYiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcZnJhYzM1IiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMTU3IiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGZyYWM0NSIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjE1OCIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxmcmFjMTYiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIxNTkiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcZnJhYzU2IiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMTVBIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGZyYWMxOCIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjE1QiIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxmcmFjMzgiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIxNUMiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcZnJhYzU4IiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMTVEIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGZyYWM3OCIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjE1RSIsIHR0eXBlOkNPTlNUfSwNCg0KLy9iaW5hcnkgb3BlcmF0aW9uIHN5bWJvbHMNCntpbnB1dDoiXFxwbSIsCQl0YWc6Im1vIiwgb3V0cHV0OiJcdTAwQjEiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcbXAiLAkJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjEzIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHRyaWFuZ2xlbGVmdCIsdGFnOiJtbyIsIG91dHB1dDoiXHUyMkIyIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHRyaWFuZ2xlcmlnaHQiLHRhZzoibW8iLG91dHB1dDoiXHUyMkIzIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGNkb3QiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIyQzUiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6Ilxcc3RhciIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjJDNiIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxhc3QiLAkJdGFnOiJtbyIsIG91dHB1dDoiXHUwMDJBIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHRpbWVzIiwJdGFnOiJtbyIsIG91dHB1dDoiXHUwMEQ3IiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGRpdiIsCQl0YWc6Im1vIiwgb3V0cHV0OiJcdTAwRjciLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcY2lyYyIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjIxOCIsIHR0eXBlOkNPTlNUfSwNCi8ve2lucHV0OiJcXGJ1bGxldCIsCSAgdGFnOiJtbyIsIG91dHB1dDoiXHUyMjE5IiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGJ1bGxldCIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjAyMiIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxvcGx1cyIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjI5NSIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxvbWludXMiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIyOTYiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6Ilxcb3RpbWVzIiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjk3IiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGJpZ2NpcmMiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTI1Q0IiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6Ilxcb3NsYXNoIiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjk4IiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXG9kb3QiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIyOTkiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcbGFuZCIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjIyNyIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFx3ZWRnZSIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjIyNyIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxsb3IiLAkJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjI4IiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHZlZSIsCQl0YWc6Im1vIiwgb3V0cHV0OiJcdTIyMjgiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcY2FwIiwJCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjIyOSIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxjdXAiLAkJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjJBIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHNxY2FwIiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjkzIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHNxY3VwIiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjk0IiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHVwbHVzIiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjhFIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGFtYWxnIiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjEwIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGJpZ3RyaWFuZ2xldXAiLHRhZzoibW8iLG91dHB1dDoiXHUyNUIzIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGJpZ3RyaWFuZ2xlZG93biIsdGFnOiJtbyIsb3V0cHV0OiJcdTI1QkQiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcZGFnIiwJCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjAyMCIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxkYWdnZXIiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIwMjAiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcZGRhZyIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjAyMSIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxkZGFnZ2VyIiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMDIxIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGxoZCIsCQl0YWc6Im1vIiwgb3V0cHV0OiJcdTIyQjIiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxccmhkIiwJCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjJCMyIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFx1bmxoZCIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjJCNCIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFx1bnJoZCIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjJCNSIsIHR0eXBlOkNPTlNUfSwNCg0KDQovL0JJRyBPcGVyYXRvcnMNCntpbnB1dDoiXFxzdW0iLAkJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjExIiwgdHR5cGU6VU5ERVJPVkVSfSwNCntpbnB1dDoiXFxwcm9kIiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjBGIiwgdHR5cGU6VU5ERVJPVkVSfSwNCntpbnB1dDoiXFxiaWdjYXAiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIyQzIiLCB0dHlwZTpVTkRFUk9WRVJ9LA0Ke2lucHV0OiJcXGJpZ2N1cCIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjJDMyIsIHR0eXBlOlVOREVST1ZFUn0sDQp7aW5wdXQ6IlxcYmlnd2VkZ2UiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIyQzAiLCB0dHlwZTpVTkRFUk9WRVJ9LA0Ke2lucHV0OiJcXGJpZ3ZlZSIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjJDMSIsIHR0eXBlOlVOREVST1ZFUn0sDQp7aW5wdXQ6IlxcYmlnc3FjYXAiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTJBMDUiLCB0dHlwZTpVTkRFUk9WRVJ9LA0Ke2lucHV0OiJcXGJpZ3NxY3VwIiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyQTA2IiwgdHR5cGU6VU5ERVJPVkVSfSwNCntpbnB1dDoiXFxjb3Byb2QiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIyMTAiLCB0dHlwZTpVTkRFUk9WRVJ9LA0Ke2lucHV0OiJcXGJpZ29wbHVzIiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyQTAxIiwgdHR5cGU6VU5ERVJPVkVSfSwNCntpbnB1dDoiXFxiaWdvdGltZXMiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTJBMDIiLCB0dHlwZTpVTkRFUk9WRVJ9LA0Ke2lucHV0OiJcXGJpZ29kb3QiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTJBMDAiLCB0dHlwZTpVTkRFUk9WRVJ9LA0Ke2lucHV0OiJcXGJpZ3VwbHVzIiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyQTA0IiwgdHR5cGU6VU5ERVJPVkVSfSwNCntpbnB1dDoiXFxpbnQiLAkJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjJCIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXG9pbnQiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIyMkUiLCB0dHlwZTpDT05TVH0sDQoNCi8vYmluYXJ5IHJlbGF0aW9uIHN5bWJvbHMNCntpbnB1dDoiOj0iLAkJdGFnOiJtbyIsIG91dHB1dDoiOj0iLAkgICB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcbHQiLAkJdGFnOiJtbyIsIG91dHB1dDoiPCIsCSAgIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxndCIsCQl0YWc6Im1vIiwgb3V0cHV0OiI+IiwJICAgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXG5lIiwJCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjI2MCIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxuZXEiLAkJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjYwIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGxlIiwJCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjI2NCIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxsZXEiLAkJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjY0IiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGxlcXNsYW50IiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjY0IiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGdlIiwJCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjI2NSIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxnZXEiLAkJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjY1IiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGdlcXNsYW50IiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjY1IiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGVxdWl2IiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjYxIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGxsIiwJCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjI2QSIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxnZyIsCQl0YWc6Im1vIiwgb3V0cHV0OiJcdTIyNkIiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcZG90ZXEiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIyNTAiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxccHJlYyIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjI3QSIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxzdWNjIiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjdCIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHByZWNlcSIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjI3QyIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxzdWNjZXEiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIyN0QiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6Ilxcc3Vic2V0IiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjgyIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHN1cHNldCIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjI4MyIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxzdWJzZXRlcSIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjI4NiIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxzdXBzZXRlcSIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjI4NyIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxzdWJzZXRuZXEiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIyOEEiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6Ilxcc3Vwc2V0bmVxIiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjhCIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHNxc3Vic2V0IiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjhGIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHNxc3Vwc2V0IiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjkwIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHNxc3Vic2V0ZXEiLCAgdGFnOiJtbyIsIG91dHB1dDoiXHUyMjkxIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHNxc3Vwc2V0ZXEiLCAgdGFnOiJtbyIsIG91dHB1dDoiXHUyMjkyIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHNpbSIsCQl0YWc6Im1vIiwgb3V0cHV0OiJcdTIyM0MiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6Ilxcc2ltZXEiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIyNDMiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcYXBwcm94IiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjQ4IiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGNvbmciLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIyNDUiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcSm9pbiIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjJDOCIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxib3d0aWUiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIyQzgiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcaW4iLAkJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjA4IiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXG5pIiwJCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjIwQiIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxvd25zIiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjBCIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHByb3B0byIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjIxRCIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFx2ZGFzaCIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjJBMiIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxkYXNodiIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjJBMyIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxtb2RlbHMiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIyQTgiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxccGVycCIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjJBNSIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxzbWlsZSIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjMyMyIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxmcm93biIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjMyMiIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxhc3ltcCIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjI0RCIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxub3RpbiIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjIwOSIsIHR0eXBlOkNPTlNUfSwNCg0KLy9tYXRyaWNlcw0Ke2lucHV0OiJcXGJlZ2lue2VxbmFycmF5fSIsCW91dHB1dDoiWCIsCXR0eXBlOk1BVFJJWCwgaW52aXNpYmxlOnRydWV9LA0Ke2lucHV0OiJcXGJlZ2lue2FycmF5fSIsCW91dHB1dDoiWCIsCXR0eXBlOk1BVFJJWCwgaW52aXNpYmxlOnRydWV9LA0Ke2lucHV0OiJcXFxcIiwJCQlvdXRwdXQ6In0meyIsCXR0eXBlOkRFRklOSVRJT059LA0Ke2lucHV0OiJcXGVuZHtlcW5hcnJheX0iLAlvdXRwdXQ6In19IiwJdHR5cGU6REVGSU5JVElPTn0sDQp7aW5wdXQ6IlxcZW5ke2FycmF5fSIsCQlvdXRwdXQ6In19IiwJdHR5cGU6REVGSU5JVElPTn0sDQoNCi8vZ3JvdXBpbmcgYW5kIGxpdGVyYWwgYnJhY2tldHMgLS0gaWV2YWwgaXMgZm9yIElFDQp7aW5wdXQ6IlxcYmlnIiwJICAgdGFnOiJtbyIsIG91dHB1dDoiWCIsIGF0dmFsOiIxLjIiLCBpZXZhbDoiMi4yIiwgdHR5cGU6QklHfSwNCntpbnB1dDoiXFxCaWciLAkgICB0YWc6Im1vIiwgb3V0cHV0OiJYIiwgYXR2YWw6IjEuNiIsIGlldmFsOiIyLjYiLCB0dHlwZTpCSUd9LA0Ke2lucHV0OiJcXGJpZ2ciLCAgIHRhZzoibW8iLCBvdXRwdXQ6IlgiLCBhdHZhbDoiMi4yIiwgaWV2YWw6IjMuMiIsIHR0eXBlOkJJR30sDQp7aW5wdXQ6IlxcQmlnZyIsICAgdGFnOiJtbyIsIG91dHB1dDoiWCIsIGF0dmFsOiIyLjkiLCBpZXZhbDoiMy45IiwgdHR5cGU6QklHfSwNCntpbnB1dDoiXFxsZWZ0IiwgICB0YWc6Im1vIiwgb3V0cHV0OiJYIiwgdHR5cGU6TEVGVEJSQUNLRVR9LA0Ke2lucHV0OiJcXHJpZ2h0IiwgIHRhZzoibW8iLCBvdXRwdXQ6IlgiLCB0dHlwZTpSSUdIVEJSQUNLRVR9LA0Ke2lucHV0OiJ7IiwJICAgb3V0cHV0OiJ7IiwgdHR5cGU6TEVGVEJSQUNLRVQsICBpbnZpc2libGU6dHJ1ZX0sDQp7aW5wdXQ6In0iLAkgICBvdXRwdXQ6In0iLCB0dHlwZTpSSUdIVEJSQUNLRVQsIGludmlzaWJsZTp0cnVlfSwNCg0Ke2lucHV0OiIoIiwJICAgdGFnOiJtbyIsIG91dHB1dDoiKCIsICAgICAgYXR2YWw6IjEiLCB0dHlwZTpTVFJFVENIWX0sDQp7aW5wdXQ6IlsiLAkgICB0YWc6Im1vIiwgb3V0cHV0OiJbIiwgICAgICBhdHZhbDoiMSIsIHR0eXBlOlNUUkVUQ0hZfSwNCntpbnB1dDoiXFxsYnJhY2siLCB0YWc6Im1vIiwgb3V0cHV0OiJbIiwgICAgICBhdHZhbDoiMSIsIHR0eXBlOlNUUkVUQ0hZfSwNCntpbnB1dDoiXFx7IiwJICAgdGFnOiJtbyIsIG91dHB1dDoieyIsICAgICAgYXR2YWw6IjEiLCB0dHlwZTpTVFJFVENIWX0sDQp7aW5wdXQ6IlxcbGJyYWNlIiwgdGFnOiJtbyIsIG91dHB1dDoieyIsICAgICAgYXR2YWw6IjEiLCB0dHlwZTpTVFJFVENIWX0sDQp7aW5wdXQ6IlxcbGFuZ2xlIiwgdGFnOiJtbyIsIG91dHB1dDoiXHUyMzI5IiwgYXR2YWw6IjEiLCB0dHlwZTpTVFJFVENIWX0sDQp7aW5wdXQ6IlxcbGZsb29yIiwgdGFnOiJtbyIsIG91dHB1dDoiXHUyMzBBIiwgYXR2YWw6IjEiLCB0dHlwZTpTVFJFVENIWX0sDQp7aW5wdXQ6IlxcbGNlaWwiLCAgdGFnOiJtbyIsIG91dHB1dDoiXHUyMzA4IiwgYXR2YWw6IjEiLCB0dHlwZTpTVFJFVENIWX0sDQoNCi8vIHJ0YWc6Im1pIiBjYXVzZXMgc3BhY2UgdG8gYmUgaW5zZXJ0ZWQgYmVmb3JlIGEgZm9sbG93aW5nIHNpbiwgY29zLCBldGMuDQovLyAoc2VlIGZ1bmN0aW9uIEFNcGFyc2VFeHByKCkgKQ0Ke2lucHV0OiIpIiwJICB0YWc6Im1vIixvdXRwdXQ6IikiLAkgICAgcnRhZzoibWkiLGF0dmFsOiIxIix0dHlwZTpTVFJFVENIWX0sDQp7aW5wdXQ6Il0iLAkgIHRhZzoibW8iLG91dHB1dDoiXSIsCSAgICBydGFnOiJtaSIsYXR2YWw6IjEiLHR0eXBlOlNUUkVUQ0hZfSwNCntpbnB1dDoiXFxyYnJhY2siLHRhZzoibW8iLG91dHB1dDoiXSIsCSAgICBydGFnOiJtaSIsYXR2YWw6IjEiLHR0eXBlOlNUUkVUQ0hZfSwNCntpbnB1dDoiXFx9IiwJICB0YWc6Im1vIixvdXRwdXQ6In0iLAkgICAgcnRhZzoibWkiLGF0dmFsOiIxIix0dHlwZTpTVFJFVENIWX0sDQp7aW5wdXQ6IlxccmJyYWNlIix0YWc6Im1vIixvdXRwdXQ6In0iLAkgICAgcnRhZzoibWkiLGF0dmFsOiIxIix0dHlwZTpTVFJFVENIWX0sDQp7aW5wdXQ6IlxccmFuZ2xlIix0YWc6Im1vIixvdXRwdXQ6Ilx1MjMyQSIsIHJ0YWc6Im1pIixhdHZhbDoiMSIsdHR5cGU6U1RSRVRDSFl9LA0Ke2lucHV0OiJcXHJmbG9vciIsdGFnOiJtbyIsb3V0cHV0OiJcdTIzMEIiLCBydGFnOiJtaSIsYXR2YWw6IjEiLHR0eXBlOlNUUkVUQ0hZfSwNCntpbnB1dDoiXFxyY2VpbCIsIHRhZzoibW8iLG91dHB1dDoiXHUyMzA5IiwgcnRhZzoibWkiLGF0dmFsOiIxIix0dHlwZTpTVFJFVENIWX0sDQoNCi8vICJ8IiwgIlxcfCIsICJcXHZlcnQiIGFuZCAiXFxWZXJ0IiBtb2RpZmllZCBsYXRlcjogbHNwYWNlID0gcnNwYWNlID0gMGVtDQp7aW5wdXQ6InwiLAkJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjIzIiwgYXR2YWw6IjEiLCB0dHlwZTpTVFJFVENIWX0sDQp7aW5wdXQ6IlxcfCIsCQl0YWc6Im1vIiwgb3V0cHV0OiJcdTIyMjUiLCBhdHZhbDoiMSIsIHR0eXBlOlNUUkVUQ0hZfSwNCntpbnB1dDoiXFx2ZXJ0IiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjIzIiwgYXR2YWw6IjEiLCB0dHlwZTpTVFJFVENIWX0sDQp7aW5wdXQ6IlxcVmVydCIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjIyNSIsIGF0dmFsOiIxIiwgdHR5cGU6U1RSRVRDSFl9LA0Ke2lucHV0OiJcXG1pZCIsCQl0YWc6Im1vIiwgb3V0cHV0OiJcdTIyMjMiLCBhdHZhbDoiMSIsIHR0eXBlOlNUUkVUQ0hZfSwNCntpbnB1dDoiXFxwYXJhbGxlbCIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjIyNSIsIGF0dmFsOiIxIiwgdHR5cGU6U1RSRVRDSFl9LA0Ke2lucHV0OiIvIiwJCXRhZzoibW8iLCBvdXRwdXQ6Ii8iLAlhdHZhbDoiMS4wMSIsIHR0eXBlOlNUUkVUQ0hZfSwNCntpbnB1dDoiXFxiYWNrc2xhc2giLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIyMTYiLCBhdHZhbDoiMSIsIHR0eXBlOlNUUkVUQ0hZfSwNCntpbnB1dDoiXFxzZXRtaW51cyIsCXRhZzoibW8iLCBvdXRwdXQ6IlxcIiwJICAgdHR5cGU6Q09OU1R9LA0KDQovL21pc2NlbGxhbmVvdXMgc3ltYm9scw0Ke2lucHV0OiJcXCEiLAkgIHRhZzoibXNwYWNlIiwgYXRuYW1lOiJ3aWR0aCIsIGF0dmFsOiItMC4xNjdlbSIsIHR0eXBlOlNQQUNFfSwNCntpbnB1dDoiXFwsIiwJICB0YWc6Im1zcGFjZSIsIGF0bmFtZToid2lkdGgiLCBhdHZhbDoiMC4xNjdlbSIsIHR0eXBlOlNQQUNFfSwNCntpbnB1dDoiXFw+IiwJICB0YWc6Im1zcGFjZSIsIGF0bmFtZToid2lkdGgiLCBhdHZhbDoiMC4yMjJlbSIsIHR0eXBlOlNQQUNFfSwNCntpbnB1dDoiXFw6IiwJICB0YWc6Im1zcGFjZSIsIGF0bmFtZToid2lkdGgiLCBhdHZhbDoiMC4yMjJlbSIsIHR0eXBlOlNQQUNFfSwNCntpbnB1dDoiXFw7IiwJICB0YWc6Im1zcGFjZSIsIGF0bmFtZToid2lkdGgiLCBhdHZhbDoiMC4yNzhlbSIsIHR0eXBlOlNQQUNFfSwNCntpbnB1dDoifiIsCSAgdGFnOiJtc3BhY2UiLCBhdG5hbWU6IndpZHRoIiwgYXR2YWw6IjAuMzMzZW0iLCB0dHlwZTpTUEFDRX0sDQp7aW5wdXQ6IlxccXVhZCIsICB0YWc6Im1zcGFjZSIsIGF0bmFtZToid2lkdGgiLCBhdHZhbDoiMWVtIiwgdHR5cGU6U1BBQ0V9LA0Ke2lucHV0OiJcXHFxdWFkIiwgdGFnOiJtc3BhY2UiLCBhdG5hbWU6IndpZHRoIiwgYXR2YWw6IjJlbSIsIHR0eXBlOlNQQUNFfSwNCi8ve2lucHV0OiJ7fSIsCQkgIHRhZzoibW8iLCBvdXRwdXQ6Ilx1MjAwQiIsIHR0eXBlOkNPTlNUfSwgLy8gemVyby13aWR0aA0Ke2lucHV0OiJcXHByaW1lIiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMDMyIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiInIiwJCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MDJCOSIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiJyciLAkJdGFnOiJtbyIsIG91dHB1dDoiXHUwMkJBIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiInJyciLAkJdGFnOiJtbyIsIG91dHB1dDoiXHUyMDM0IiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiInJycnIiwJCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjA1NyIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxsZG90cyIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjAyNiIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxjZG90cyIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjJFRiIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFx2ZG90cyIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjJFRSIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxkZG90cyIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjJGMSIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxmb3JhbGwiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIyMDAiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcZXhpc3RzIiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjAzIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXFJlIiwJCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjExQyIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxJbSIsCQl0YWc6Im1vIiwgb3V0cHV0OiJcdTIxMTEiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcYWxlcGgiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIxMzUiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcaGJhciIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjEwRiIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxlbGwiLAkJdGFnOiJtbyIsIG91dHB1dDoiXHUyMTEzIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHdwIiwJCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjExOCIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxlbXB0eXNldCIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjIwNSIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxpbmZ0eSIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjIxRSIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxzdXJkIiwJdGFnOiJtbyIsIG91dHB1dDoiXFxzcXJ0e30iLCB0dHlwZTpERUZJTklUSU9OfSwNCntpbnB1dDoiXFxwYXJ0aWFsIiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjAyIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXG5hYmxhIiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMjA3IiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHRyaWFuZ2xlIiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyNUIzIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHRoZXJlZm9yZSIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjIzNCIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxhbmdsZSIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjIyMCIsIHR0eXBlOkNPTlNUfSwNCi8ve2lucHV0OiJcXFxcICIsCSAgdGFnOiJtbyIsIG91dHB1dDoiXHUwMEEwIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGRpYW1vbmQiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIyQzQiLCB0dHlwZTpDT05TVH0sDQovL3tpbnB1dDoiXFxEaWFtb25kIiwJICB0YWc6Im1vIiwgb3V0cHV0OiJcdTI1Q0EiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcRGlhbW9uZCIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjVDNyIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxuZWciLAkJdGFnOiJtbyIsIG91dHB1dDoiXHUwMEFDIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXGxub3QiLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTAwQUMiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcYm90IiwJCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjJBNSIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFx0b3AiLAkJdGFnOiJtbyIsIG91dHB1dDoiXHUyMkE0IiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHNxdWFyZSIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjVBQiIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxCb3giLAkJdGFnOiJtbyIsIG91dHB1dDoiXHUyNUExIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHdyIiwJCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjI0MCIsIHR0eXBlOkNPTlNUfSwNCg0KLy9zdGFuZGFyZCBmdW5jdGlvbnMNCi8vTm90ZSBVTkRFUk9WRVIgKm11c3QqIGhhdmUgdGFnOiJtbyIgdG8gd29yayBwcm9wZXJseQ0Ke2lucHV0OiJcXGFyY2NvcyIsIHRhZzoibWkiLCBvdXRwdXQ6ImFyY2NvcyIsIHR0eXBlOlVOQVJZLCBmdW5jOnRydWV9LA0Ke2lucHV0OiJcXGFyY3NpbiIsIHRhZzoibWkiLCBvdXRwdXQ6ImFyY3NpbiIsIHR0eXBlOlVOQVJZLCBmdW5jOnRydWV9LA0Ke2lucHV0OiJcXGFyY3RhbiIsIHRhZzoibWkiLCBvdXRwdXQ6ImFyY3RhbiIsIHR0eXBlOlVOQVJZLCBmdW5jOnRydWV9LA0Ke2lucHV0OiJcXGFyZyIsCSAgIHRhZzoibWkiLCBvdXRwdXQ6ImFyZyIsICAgIHR0eXBlOlVOQVJZLCBmdW5jOnRydWV9LA0Ke2lucHV0OiJcXGNvcyIsCSAgIHRhZzoibWkiLCBvdXRwdXQ6ImNvcyIsICAgIHR0eXBlOlVOQVJZLCBmdW5jOnRydWV9LA0Ke2lucHV0OiJcXGNvc2giLCAgIHRhZzoibWkiLCBvdXRwdXQ6ImNvc2giLCAgIHR0eXBlOlVOQVJZLCBmdW5jOnRydWV9LA0Ke2lucHV0OiJcXGNvdCIsCSAgIHRhZzoibWkiLCBvdXRwdXQ6ImNvdCIsICAgIHR0eXBlOlVOQVJZLCBmdW5jOnRydWV9LA0Ke2lucHV0OiJcXGNvdGgiLCAgIHRhZzoibWkiLCBvdXRwdXQ6ImNvdGgiLCAgIHR0eXBlOlVOQVJZLCBmdW5jOnRydWV9LA0Ke2lucHV0OiJcXGNzYyIsCSAgIHRhZzoibWkiLCBvdXRwdXQ6ImNzYyIsICAgIHR0eXBlOlVOQVJZLCBmdW5jOnRydWV9LA0Ke2lucHV0OiJcXGRlZyIsCSAgIHRhZzoibWkiLCBvdXRwdXQ6ImRlZyIsICAgIHR0eXBlOlVOQVJZLCBmdW5jOnRydWV9LA0Ke2lucHV0OiJcXGRldCIsCSAgIHRhZzoibWkiLCBvdXRwdXQ6ImRldCIsICAgIHR0eXBlOlVOQVJZLCBmdW5jOnRydWV9LA0Ke2lucHV0OiJcXGRpbSIsCSAgIHRhZzoibWkiLCBvdXRwdXQ6ImRpbSIsICAgIHR0eXBlOlVOQVJZLCBmdW5jOnRydWV9LCAvL0NPTlNUPw0Ke2lucHV0OiJcXGV4cCIsCSAgIHRhZzoibWkiLCBvdXRwdXQ6ImV4cCIsICAgIHR0eXBlOlVOQVJZLCBmdW5jOnRydWV9LA0Ke2lucHV0OiJcXGdjZCIsCSAgIHRhZzoibWkiLCBvdXRwdXQ6ImdjZCIsICAgIHR0eXBlOlVOQVJZLCBmdW5jOnRydWV9LCAvL0NPTlNUPw0Ke2lucHV0OiJcXGhvbSIsCSAgIHRhZzoibWkiLCBvdXRwdXQ6ImhvbSIsICAgIHR0eXBlOlVOQVJZLCBmdW5jOnRydWV9LA0Ke2lucHV0OiJcXGluZiIsCSAgICAgIHRhZzoibW8iLCBvdXRwdXQ6ImluZiIsCSB0dHlwZTpVTkRFUk9WRVJ9LA0Ke2lucHV0OiJcXGtlciIsCSAgIHRhZzoibWkiLCBvdXRwdXQ6ImtlciIsICAgIHR0eXBlOlVOQVJZLCBmdW5jOnRydWV9LA0Ke2lucHV0OiJcXGxnIiwJICAgdGFnOiJtaSIsIG91dHB1dDoibGciLCAgICAgdHR5cGU6VU5BUlksIGZ1bmM6dHJ1ZX0sDQp7aW5wdXQ6IlxcbGltIiwJICAgICAgdGFnOiJtbyIsIG91dHB1dDoibGltIiwJIHR0eXBlOlVOREVST1ZFUn0sDQp7aW5wdXQ6IlxcbGltaW5mIiwgICAgdGFnOiJtbyIsIG91dHB1dDoibGltaW5mIiwgdHR5cGU6VU5ERVJPVkVSfSwNCntpbnB1dDoiXFxsaW1zdXAiLCAgICB0YWc6Im1vIiwgb3V0cHV0OiJsaW1zdXAiLCB0dHlwZTpVTkRFUk9WRVJ9LA0Ke2lucHV0OiJcXGxuIiwJICAgdGFnOiJtaSIsIG91dHB1dDoibG4iLCAgICAgdHR5cGU6VU5BUlksIGZ1bmM6dHJ1ZX0sDQp7aW5wdXQ6IlxcbG9nIiwJICAgdGFnOiJtaSIsIG91dHB1dDoibG9nIiwgICAgdHR5cGU6VU5BUlksIGZ1bmM6dHJ1ZX0sDQp7aW5wdXQ6IlxcbWF4IiwJICAgICAgdGFnOiJtbyIsIG91dHB1dDoibWF4IiwJIHR0eXBlOlVOREVST1ZFUn0sDQp7aW5wdXQ6IlxcbWluIiwJICAgICAgdGFnOiJtbyIsIG91dHB1dDoibWluIiwJIHR0eXBlOlVOREVST1ZFUn0sDQp7aW5wdXQ6IlxcUHIiLAkgICB0YWc6Im1pIiwgb3V0cHV0OiJQciIsICAgICB0dHlwZTpVTkFSWSwgZnVuYzp0cnVlfSwNCntpbnB1dDoiXFxzZWMiLAkgICB0YWc6Im1pIiwgb3V0cHV0OiJzZWMiLCAgICB0dHlwZTpVTkFSWSwgZnVuYzp0cnVlfSwNCntpbnB1dDoiXFxzaW4iLAkgICB0YWc6Im1pIiwgb3V0cHV0OiJzaW4iLCAgICB0dHlwZTpVTkFSWSwgZnVuYzp0cnVlfSwNCntpbnB1dDoiXFxzaW5oIiwgICB0YWc6Im1pIiwgb3V0cHV0OiJzaW5oIiwgICB0dHlwZTpVTkFSWSwgZnVuYzp0cnVlfSwNCntpbnB1dDoiXFxzdXAiLAkgICAgICB0YWc6Im1vIiwgb3V0cHV0OiJzdXAiLAkgdHR5cGU6VU5ERVJPVkVSfSwNCntpbnB1dDoiXFx0YW4iLAkgICB0YWc6Im1pIiwgb3V0cHV0OiJ0YW4iLCAgICB0dHlwZTpVTkFSWSwgZnVuYzp0cnVlfSwNCntpbnB1dDoiXFx0YW5oIiwgICB0YWc6Im1pIiwgb3V0cHV0OiJ0YW5oIiwgICB0dHlwZTpVTkFSWSwgZnVuYzp0cnVlfSwNCg0KLy9hcnJvd3MNCntpbnB1dDoiXFxnZXRzIiwJCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjE5MCIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxsZWZ0YXJyb3ciLAkJdGFnOiJtbyIsIG91dHB1dDoiXHUyMTkwIiwgdHR5cGU6Q09OU1R9LA0Ke2lucHV0OiJcXHRvIiwJCQl0YWc6Im1vIiwgb3V0cHV0OiJcdTIxOTIiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxccmlnaHRhcnJvdyIsCQl0YWc6Im1vIiwgb3V0cHV0OiJcdTIxOTIiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcbGVmdHJpZ2h0YXJyb3ciLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIxOTQiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcdXBhcnJvdyIsCQl0YWc6Im1vIiwgb3V0cHV0OiJcdTIxOTEiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcZG93bmFycm93IiwJCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjE5MyIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFx1cGRvd25hcnJvdyIsCQl0YWc6Im1vIiwgb3V0cHV0OiJcdTIxOTUiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcTGVmdGFycm93IiwJCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjFEMCIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxSaWdodGFycm93IiwJCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjFEMiIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxMZWZ0cmlnaHRhcnJvdyIsCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjFENCIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxpZmYiLCB0YWc6Im1vIiwgb3V0cHV0OiJ+XFxMb25nbGVmdHJpZ2h0YXJyb3d+IiwgdHR5cGU6REVGSU5JVElPTn0sDQp7aW5wdXQ6IlxcVXBhcnJvdyIsCQl0YWc6Im1vIiwgb3V0cHV0OiJcdTIxRDEiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcRG93bmFycm93IiwJCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjFEMyIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxVcGRvd25hcnJvdyIsCQl0YWc6Im1vIiwgb3V0cHV0OiJcdTIxRDUiLCB0dHlwZTpDT05TVH0sDQp7aW5wdXQ6IlxcbWFwc3RvIiwJCXRhZzoibW8iLCBvdXRwdXQ6Ilx1MjFBNiIsIHR0eXBlOkNPTlNUfSwNCntpbnB1dDoiXFxsb25nbGVmdGFycm93IiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMTkwIiwgdHR5cGU6TE9OR30sDQp7aW5wdXQ6IlxcbG9uZ3JpZ2h0YXJyb3ciLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIxOTIiLCB0dHlwZTpMT05HfSwNCntpbnB1dDoiXFxsb25nbGVmdHJpZ2h0YXJyb3ciLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIxOTQiLCB0dHlwZTpMT05HfSwNCntpbnB1dDoiXFxMb25nbGVmdGFycm93IiwJdGFnOiJtbyIsIG91dHB1dDoiXHUyMUQwIiwgdHR5cGU6TE9OR30sDQp7aW5wdXQ6IlxcTG9uZ3JpZ2h0YXJyb3ciLAl0YWc6Im1vIiwgb3V0cHV0OiJcdTIxRDIiLCB0dHlwZTpMT05HfSwNCntpbnB1dDoiXFxMb25nbGVmdHJpZ2h0YXJyb3ciLCAgdGFnOiJtbyIsIG91dHB1dDoiXHUyMUQ0IiwgdHR5cGU6TE9OR30sDQp7aW5wdXQ6IlxcbG9uZ21hcHN0byIsCQl0YWc6Im1vIiwgb3V0cHV0OiJcdTIxQTYiLCB0dHlwZTpDT05TVH0sDQoJCQkJCQkJLy8gZGlzYXN0ZXIgaWYgTE9ORw0KDQovL2NvbW1hbmRzIHdpdGggYXJndW1lbnQNCkFNc3FydCwgQU1ub3QsIEFNcm9vdCwgQU1mcmFjLCBBTW92ZXIsIEFNc3ViLCBBTXN1cCwgQU10ZXh0LCBBTW1ib3gsIEFNYXRvcCwgQU1jaG9vc2UsDQoNCi8vQU1kaXYsIEFNcXVvdGUsDQoNCi8vZGlhY3JpdGljYWwgbWFya3MNCntpbnB1dDoiXFxhY3V0ZSIsCXRhZzoibW92ZXIiLCAgb3V0cHV0OiJcdTAwQjQiLCB0dHlwZTpVTkFSWSwgYWNjOnRydWV9LA0KLy97aW5wdXQ6IlxcYWN1dGUiLAkgIHRhZzoibW92ZXIiLCAgb3V0cHV0OiJcdTAzMTciLCB0dHlwZTpVTkFSWSwgYWNjOnRydWV9LA0KLy97aW5wdXQ6IlxcYWN1dGUiLAkgIHRhZzoibW92ZXIiLCAgb3V0cHV0OiJcdTAzMDEiLCB0dHlwZTpVTkFSWSwgYWNjOnRydWV9LA0KLy97aW5wdXQ6IlxcZ3JhdmUiLAkgIHRhZzoibW92ZXIiLCAgb3V0cHV0OiJcdTAzMDAiLCB0dHlwZTpVTkFSWSwgYWNjOnRydWV9LA0KLy97aW5wdXQ6IlxcZ3JhdmUiLAkgIHRhZzoibW92ZXIiLCAgb3V0cHV0OiJcdTAzMTYiLCB0dHlwZTpVTkFSWSwgYWNjOnRydWV9LA0Ke2lucHV0OiJcXGdyYXZlIiwJdGFnOiJtb3ZlciIsICBvdXRwdXQ6Ilx1MDA2MCIsIHR0eXBlOlVOQVJZLCBhY2M6dHJ1ZX0sDQp7aW5wdXQ6IlxcYnJldmUiLAl0YWc6Im1vdmVyIiwgIG91dHB1dDoiXHUwMkQ4IiwgdHR5cGU6VU5BUlksIGFjYzp0cnVlfSwNCntpbnB1dDoiXFxjaGVjayIsCXRhZzoibW92ZXIiLCAgb3V0cHV0OiJcdTAyQzciLCB0dHlwZTpVTkFSWSwgYWNjOnRydWV9LA0Ke2lucHV0OiJcXGRvdCIsCQl0YWc6Im1vdmVyIiwgIG91dHB1dDoiLiIsICAgICAgdHR5cGU6VU5BUlksIGFjYzp0cnVlfSwNCntpbnB1dDoiXFxkZG90IiwJdGFnOiJtb3ZlciIsICBvdXRwdXQ6Ii4uIiwgICAgIHR0eXBlOlVOQVJZLCBhY2M6dHJ1ZX0sDQovL3tpbnB1dDoiXFxkZG90IiwJICB0YWc6Im1vdmVyIiwgIG91dHB1dDoiXHUwMEE4IiwgdHR5cGU6VU5BUlksIGFjYzp0cnVlfSwNCntpbnB1dDoiXFxtYXRocmluZyIsCXRhZzoibW92ZXIiLCAgb3V0cHV0OiJcdTAwQjAiLCB0dHlwZTpVTkFSWSwgYWNjOnRydWV9LA0Ke2lucHV0OiJcXHZlYyIsCQl0YWc6Im1vdmVyIiwgIG91dHB1dDoiXHUyMEQ3IiwgdHR5cGU6VU5BUlksIGFjYzp0cnVlfSwNCntpbnB1dDoiXFxvdmVycmlnaHRhcnJvdyIsdGFnOiJtb3ZlciIsb3V0cHV0OiJcdTIwRDciLCB0dHlwZTpVTkFSWSwgYWNjOnRydWV9LA0Ke2lucHV0OiJcXG92ZXJsZWZ0YXJyb3ciLHRhZzoibW92ZXIiLCBvdXRwdXQ6Ilx1MjBENiIsIHR0eXBlOlVOQVJZLCBhY2M6dHJ1ZX0sDQp7aW5wdXQ6IlxcaGF0IiwJCXRhZzoibW92ZXIiLCAgb3V0cHV0OiJcdTAwNUUiLCB0dHlwZTpVTkFSWSwgYWNjOnRydWV9LA0Ke2lucHV0OiJcXHdpZGVoYXQiLAl0YWc6Im1vdmVyIiwgIG91dHB1dDoiXHUwMzAyIiwgdHR5cGU6VU5BUlksIGFjYzp0cnVlfSwNCntpbnB1dDoiXFx0aWxkZSIsCXRhZzoibW92ZXIiLCAgb3V0cHV0OiJ+IiwgICAgICB0dHlwZTpVTkFSWSwgYWNjOnRydWV9LA0KLy97aW5wdXQ6IlxcdGlsZGUiLAkgIHRhZzoibW92ZXIiLCAgb3V0cHV0OiJcdTAzMDMiLCB0dHlwZTpVTkFSWSwgYWNjOnRydWV9LA0Ke2lucHV0OiJcXHdpZGV0aWxkZSIsCXRhZzoibW92ZXIiLCAgb3V0cHV0OiJcdTAyREMiLCB0dHlwZTpVTkFSWSwgYWNjOnRydWV9LA0Ke2lucHV0OiJcXGJhciIsCQl0YWc6Im1vdmVyIiwgIG91dHB1dDoiXHUyMDNFIiwgdHR5cGU6VU5BUlksIGFjYzp0cnVlfSwNCntpbnB1dDoiXFxvdmVyYnJhY2UiLAl0YWc6Im1vdmVyIiwgIG91dHB1dDoiXHVGRTM3IiwgdHR5cGU6VU5BUlksIGFjYzp0cnVlfSwgLy9DaGFuZ2VkIHVuaWNvZGUgb3ZlcmJyYWNlDQp7aW5wdXQ6Ilxcb3ZlcmJyYWNrZXQiLCB0YWc6Im1vdmVyIiwgIG91dHB1dDoiXHUyM0I0IiwgdHR5cGU6VU5BUlksIGFjYzp0cnVlfSwgLy9vbGQgb3ZlcmJyYWNlID0gb3ZlcmJyYWNrZXQNCntpbnB1dDoiXFxvdmVybGluZSIsCXRhZzoibW92ZXIiLCAgb3V0cHV0OiJcdTAwQUYiLCB0dHlwZTpVTkFSWSwgYWNjOnRydWV9LA0Ke2lucHV0OiJcXHVuZGVyYnJhY2UiLCAgdGFnOiJtdW5kZXIiLCBvdXRwdXQ6Ilx1RkUzOCIsIHR0eXBlOlVOQVJZLCBhY2M6dHJ1ZX0sIC8vQ2hhbmdlZCB1bmljb2RlIHVuZGVyYnJhY2UNCntpbnB1dDoiXFx1bmRlcmJyYWNrZXQiLHRhZzoibXVuZGVyIiwgb3V0cHV0OiJcdTIzQjUiLCB0dHlwZTpVTkFSWSwgYWNjOnRydWV9LCAvL29sZCB1bmRlcmJyYWNlID0gdW5kZXJicmFja2V0DQp7aW5wdXQ6IlxcdW5kZXJsaW5lIiwJdGFnOiJtdW5kZXIiLCBvdXRwdXQ6Ilx1MDBBRiIsIHR0eXBlOlVOQVJZLCBhY2M6dHJ1ZX0sDQovL3tpbnB1dDoidW5kZXJsaW5lIiwJdGFnOiJtdW5kZXIiLCBvdXRwdXQ6Ilx1MDMzMiIsIHR0eXBlOlVOQVJZLCBhY2M6dHJ1ZX0sDQoNCi8vdHlwZXN0eWxlcyBhbmQgZm9udHMNCntpbnB1dDoiXFxkaXNwbGF5c3R5bGUiLHRhZzoibXN0eWxlIixhdG5hbWU6ImRpc3BsYXlzdHlsZSIsYXR2YWw6InRydWUiLCB0dHlwZTpVTkFSWX0sDQp7aW5wdXQ6IlxcdGV4dHN0eWxlIix0YWc6Im1zdHlsZSIsYXRuYW1lOiJkaXNwbGF5c3R5bGUiLGF0dmFsOiJmYWxzZSIsIHR0eXBlOlVOQVJZfSwNCntpbnB1dDoiXFxzY3JpcHRzdHlsZSIsdGFnOiJtc3R5bGUiLGF0bmFtZToic2NyaXB0bGV2ZWwiLGF0dmFsOiIxIiwgdHR5cGU6VU5BUll9LA0Ke2lucHV0OiJcXHNjcmlwdHNjcmlwdHN0eWxlIix0YWc6Im1zdHlsZSIsYXRuYW1lOiJzY3JpcHRsZXZlbCIsYXR2YWw6IjIiLCB0dHlwZTpVTkFSWX0sDQp7aW5wdXQ6IlxcdGV4dHJtIiwgdGFnOiJtc3R5bGUiLCBvdXRwdXQ6IlxcbWF0aHJtIiwgdHR5cGU6IERFRklOSVRJT059LA0Ke2lucHV0OiJcXG1hdGhiZiIsIHRhZzoibXN0eWxlIiwgYXRuYW1lOiJtYXRodmFyaWFudCIsIGF0dmFsOiJib2xkIiwgdHR5cGU6VU5BUll9LA0Ke2lucHV0OiJcXHRleHRiZiIsIHRhZzoibXN0eWxlIiwgYXRuYW1lOiJtYXRodmFyaWFudCIsIGF0dmFsOiJib2xkIiwgdHR5cGU6VU5BUll9LA0Ke2lucHV0OiJcXG1hdGhpdCIsIHRhZzoibXN0eWxlIiwgYXRuYW1lOiJtYXRodmFyaWFudCIsIGF0dmFsOiJpdGFsaWMiLCB0dHlwZTpVTkFSWX0sDQp7aW5wdXQ6IlxcdGV4dGl0IiwgdGFnOiJtc3R5bGUiLCBhdG5hbWU6Im1hdGh2YXJpYW50IiwgYXR2YWw6Iml0YWxpYyIsIHR0eXBlOlVOQVJZfSwNCntpbnB1dDoiXFxtYXRodHQiLCB0YWc6Im1zdHlsZSIsIGF0bmFtZToibWF0aHZhcmlhbnQiLCBhdHZhbDoibW9ub3NwYWNlIiwgdHR5cGU6VU5BUll9LA0Ke2lucHV0OiJcXHRleHR0dCIsIHRhZzoibXN0eWxlIiwgYXRuYW1lOiJtYXRodmFyaWFudCIsIGF0dmFsOiJtb25vc3BhY2UiLCB0dHlwZTpVTkFSWX0sDQp7aW5wdXQ6IlxcbWF0aHNmIiwgdGFnOiJtc3R5bGUiLCBhdG5hbWU6Im1hdGh2YXJpYW50IiwgYXR2YWw6InNhbnMtc2VyaWYiLCB0dHlwZTpVTkFSWX0sDQp7aW5wdXQ6IlxcbWF0aGJiIiwgdGFnOiJtc3R5bGUiLCBhdG5hbWU6Im1hdGh2YXJpYW50IiwgYXR2YWw6ImRvdWJsZS1zdHJ1Y2siLCB0dHlwZTpVTkFSWSwgY29kZXM6QU1iYmJ9LA0Ke2lucHV0OiJcXG1hdGhjYWwiLHRhZzoibXN0eWxlIiwgYXRuYW1lOiJtYXRodmFyaWFudCIsIGF0dmFsOiJzY3JpcHQiLCB0dHlwZTpVTkFSWSwgY29kZXM6QU1jYWx9LA0Ke2lucHV0OiJcXG1hdGhmcmFrIix0YWc6Im1zdHlsZSIsYXRuYW1lOiJtYXRodmFyaWFudCIsIGF0dmFsOiJmcmFrdHVyIix0dHlwZTpVTkFSWSwgY29kZXM6QU1mcmt9LA0Ke2lucHV0OiJcXHRleHRjb2xvciIsdGFnOiJtc3R5bGUiLGF0bmFtZToibWF0aHZhcmlhbnQiLCBhdHZhbDoibWF0aGNvbG9yIiwgdHR5cGU6QklOQVJZfSwNCntpbnB1dDoiXFxjb2xvcmJveCIsdGFnOiJtc3R5bGUiLGF0bmFtZToibWF0aHZhcmlhbnQiLCBhdHZhbDoiYmFja2dyb3VuZCIsIHR0eXBlOkJJTkFSWX0NCl07IA0KDQpmdW5jdGlvbiBjb21wYXJlTmFtZXMoczEsczIpIHsNCiAgaWYgKHMxLmlucHV0ID4gczIuaW5wdXQpIHJldHVybiAxDQogIGVsc2UgcmV0dXJuIC0xOw0KfQ0KDQp2YXIgQU1uYW1lcyA9IFtdOyAvL2xpc3Qgb2YgaW5wdXQgc3ltYm9scw0KDQpmdW5jdGlvbiBBTWluaXRTeW1ib2xzKCkgew0KICBBTXN5bWJvbHMuc29ydChjb21wYXJlTmFtZXMpOw0KICBmb3IgKGk9MDsgaTxBTXN5bWJvbHMubGVuZ3RoOyBpKyspIEFNbmFtZXNbaV0gPSBBTXN5bWJvbHNbaV0uaW5wdXQ7DQp9DQoNCnZhciBBTW1hdGhtbCA9ICJodHRwOi8vd3d3LnczLm9yZy8xOTk4L01hdGgvTWF0aE1MIjsNCg0KZnVuY3Rpb24gQU1jcmVhdGVFbGVtZW50TWF0aE1MKHQpIHsNCiAgaWYgKGlzSUUpIHJldHVybiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJtOiIrdCk7DQogIGVsc2UgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhBTW1hdGhtbCx0KTsNCn0NCg0KZnVuY3Rpb24gQU1jcmVhdGVNbWxOb2RlKHQsZnJhZykgew0KLy8gIHZhciBub2RlID0gQU1jcmVhdGVFbGVtZW50TWF0aE1MKG5hbWUpOw0KICBpZiAoaXNJRSkgdmFyIG5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJtOiIrdCk7DQogIGVsc2UgdmFyIG5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoQU1tYXRobWwsdCk7DQogIG5vZGUuYXBwZW5kQ2hpbGQoZnJhZyk7DQogIHJldHVybiBub2RlOw0KfQ0KDQpmdW5jdGlvbiBuZXdjb21tYW5kKG9sZHN0cixuZXdzdHIpIHsNCiAgQU1zeW1ib2xzID0gQU1zeW1ib2xzLmNvbmNhdChbe2lucHV0Om9sZHN0ciwgdGFnOiJtbyIsIG91dHB1dDpuZXdzdHIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0dHlwZTpERUZJTklUSU9OfV0pOw0KfQ0KDQpmdW5jdGlvbiBBTXJlbW92ZUNoYXJzQW5kQmxhbmtzKHN0cixuKSB7DQovL3JlbW92ZSBuIGNoYXJhY3RlcnMgYW5kIGFueSBmb2xsb3dpbmcgYmxhbmtzDQogIHZhciBzdDsNCiAgc3QgPSBzdHIuc2xpY2Uobik7DQogIGZvciAodmFyIGk9MDsgaTxzdC5sZW5ndGggJiYgc3QuY2hhckNvZGVBdChpKTw9MzI7IGk9aSsxKTsNCiAgcmV0dXJuIHN0LnNsaWNlKGkpOw0KfQ0KDQpmdW5jdGlvbiBBTXBvc2l0aW9uKGFyciwgc3RyLCBuKSB7DQovLyByZXR1cm4gcG9zaXRpb24gPj1uIHdoZXJlIHN0ciBhcHBlYXJzIG9yIHdvdWxkIGJlIGluc2VydGVkDQovLyBhc3N1bWVzIGFyciBpcyBzb3J0ZWQNCiAgaWYgKG49PTApIHsNCiAgICB2YXIgaCxtOw0KICAgIG4gPSAtMTsNCiAgICBoID0gYXJyLmxlbmd0aDsNCiAgICB3aGlsZSAobisxPGgpIHsNCiAgICAgIG0gPSAobitoKSA+PiAxOw0KICAgICAgaWYgKGFyclttXTxzdHIpIG4gPSBtOyBlbHNlIGggPSBtOw0KICAgIH0NCiAgICByZXR1cm4gaDsNCiAgfSBlbHNlDQogICAgZm9yICh2YXIgaT1uOyBpPGFyci5sZW5ndGggJiYgYXJyW2ldPHN0cjsgaSsrKTsNCiAgcmV0dXJuIGk7IC8vIGk9YXJyLmxlbmd0aCB8fCBhcnJbaV0+PXN0cg0KfQ0KDQpmdW5jdGlvbiBBTWdldFN5bWJvbChzdHIpIHsNCi8vcmV0dXJuIG1heGltYWwgaW5pdGlhbCBzdWJzdHJpbmcgb2Ygc3RyIHRoYXQgYXBwZWFycyBpbiBuYW1lcw0KLy9yZXR1cm4gbnVsbCBpZiB0aGVyZSBpcyBub25lDQogIHZhciBrID0gMDsgLy9uZXcgcG9zDQogIHZhciBqID0gMDsgLy9vbGQgcG9zDQogIHZhciBtazsgLy9tYXRjaCBwb3MNCiAgdmFyIHN0Ow0KICB2YXIgdGFnc3Q7DQogIHZhciBtYXRjaCA9ICIiOw0KICB2YXIgbW9yZSA9IHRydWU7DQogIGZvciAodmFyIGk9MTsgaTw9c3RyLmxlbmd0aCAmJiBtb3JlOyBpKyspIHsNCiAgICBzdCA9IHN0ci5zbGljZSgwLGkpOyAvL2luaXRpYWwgc3Vic3RyaW5nIG9mIGxlbmd0aCBpDQogICAgaiA9IGs7DQogICAgayA9IEFNcG9zaXRpb24oQU1uYW1lcywgc3QsIGopOw0KICAgIGlmIChrPEFNbmFtZXMubGVuZ3RoICYmIHN0ci5zbGljZSgwLEFNbmFtZXNba10ubGVuZ3RoKT09QU1uYW1lc1trXSl7DQogICAgICBtYXRjaCA9IEFNbmFtZXNba107DQogICAgICBtayA9IGs7DQogICAgICBpID0gbWF0Y2gubGVuZ3RoOw0KICAgIH0NCiAgICBtb3JlID0gazxBTW5hbWVzLmxlbmd0aCAmJiBzdHIuc2xpY2UoMCxBTW5hbWVzW2tdLmxlbmd0aCk+PUFNbmFtZXNba107DQogIH0NCiAgQU1wcmV2aW91c1N5bWJvbD1BTWN1cnJlbnRTeW1ib2w7DQogIGlmIChtYXRjaCE9IiIpew0KICAgIEFNY3VycmVudFN5bWJvbD1BTXN5bWJvbHNbbWtdLnR0eXBlOw0KICAgIHJldHVybiBBTXN5bWJvbHNbbWtdOw0KICB9DQogIEFNY3VycmVudFN5bWJvbD1DT05TVDsNCiAgayA9IDE7DQogIHN0ID0gc3RyLnNsaWNlKDAsMSk7IC8vdGFrZSAxIGNoYXJhY3Rlcg0KICBpZiAoIjAiPD1zdCAmJiBzdDw9IjkiKSB0YWdzdCA9ICJtbiI7DQogIGVsc2UgdGFnc3QgPSAoKCJBIj5zdCB8fCBzdD4iWiIpICYmICgiYSI+c3QgfHwgc3Q+InoiKT8ibW8iOiJtaSIpOw0KLyoNCi8vIENvbW1lbnRlZCBvdXQgYnkgRFJXIChub3QgZnVsbHkgdW5kZXJzdG9vZCwgYnV0IHByb2JhYmx5IHRvIGRvIHdpdGgNCi8vIHVzZSBvZiAiLyIgYXMgYW4gSU5GSVggdmVyc2lvbiBvZiAiXFxmcmFjIiwgd2hpY2ggd2UgZG9uJ3Qgd2FudCk6DQovL30NCi8vaWYgKHN0PT0iLSIgJiYgQU1wcmV2aW91c1N5bWJvbD09SU5GSVgpIHsNCi8vICBBTWN1cnJlbnRTeW1ib2wgPSBJTkZJWDsgIC8vdHJpY2sgIi8iIGludG8gcmVjb2duaXppbmcgIi0iIG9uIHNlY29uZCBwYXJzZQ0KLy8gIHJldHVybiB7aW5wdXQ6c3QsIHRhZzp0YWdzdCwgb3V0cHV0OnN0LCB0dHlwZTpVTkFSWSwgZnVuYzp0cnVlfTsNCi8vfQ0KKi8NCiAgcmV0dXJuIHtpbnB1dDpzdCwgdGFnOnRhZ3N0LCBvdXRwdXQ6c3QsIHR0eXBlOkNPTlNUfTsNCn0NCg0KDQovKlBhcnNpbmcgQVNDSUkgbWF0aCBleHByZXNzaW9ucyB3aXRoIHRoZSBmb2xsb3dpbmcgZ3JhbW1hcg0KdiA6Oj0gW0EtWmEtel0gfCBncmVlayBsZXR0ZXJzIHwgbnVtYmVycyB8IG90aGVyIGNvbnN0YW50IHN5bWJvbHMNCnUgOjo9IHNxcnQgfCB0ZXh0IHwgYmIgfCBvdGhlciB1bmFyeSBzeW1ib2xzIGZvciBmb250IGNvbW1hbmRzDQpiIDo6PSBmcmFjIHwgcm9vdCB8IHN0YWNrcmVsCWJpbmFyeSBzeW1ib2xzDQpsIDo6PSB7IHwgXGxlZnQJCQlsZWZ0IGJyYWNrZXRzDQpyIDo6PSB9IHwgXHJpZ2h0CQlyaWdodCBicmFja2V0cw0KUyA6Oj0gdiB8IGxFciB8IHVTIHwgYlNTCVNpbXBsZSBleHByZXNzaW9uDQpJIDo6PSBTX1MgfCBTXlMgfCBTX1NeUyB8IFMJSW50ZXJtZWRpYXRlIGV4cHJlc3Npb24NCkUgOjo9IElFIHwgSS9JCQkJRXhwcmVzc2lvbg0KRWFjaCB0ZXJtaW5hbCBzeW1ib2wgaXMgdHJhbnNsYXRlZCBpbnRvIGEgY29ycmVzcG9uZGluZyBtYXRobWwgbm9kZS4qLw0KDQp2YXIgQU1wcmV2aW91c1N5bWJvbCxBTWN1cnJlbnRTeW1ib2w7DQoNCmZ1bmN0aW9uIEFNcGFyc2VTZXhwcihzdHIpIHsgLy9wYXJzZXMgc3RyIGFuZCByZXR1cm5zIFtub2RlLHRhaWxzdHIsKG5vZGUpdGFnXQ0KICB2YXIgc3ltYm9sLCBub2RlLCByZXN1bHQsIHJlc3VsdDIsIGksIHN0LC8vIHJpZ2h0dmVydCA9IGZhbHNlLA0KICAgIG5ld0ZyYWcgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7DQogIHN0ciA9IEFNcmVtb3ZlQ2hhcnNBbmRCbGFua3Moc3RyLDApOw0KICBzeW1ib2wgPSBBTWdldFN5bWJvbChzdHIpOyAgICAgICAgICAgICAvL2VpdGhlciBhIHRva2VuIG9yIGEgYnJhY2tldCBvciBlbXB0eQ0KICBpZiAoc3ltYm9sID09IG51bGwgfHwgc3ltYm9sLnR0eXBlID09IFJJR0hUQlJBQ0tFVCkNCiAgICByZXR1cm4gW251bGwsc3RyLG51bGxdOw0KICBpZiAoc3ltYm9sLnR0eXBlID09IERFRklOSVRJT04pIHsNCiAgICBzdHIgPSBzeW1ib2wub3V0cHV0K0FNcmVtb3ZlQ2hhcnNBbmRCbGFua3Moc3RyLHN5bWJvbC5pbnB1dC5sZW5ndGgpOw0KICAgIHN5bWJvbCA9IEFNZ2V0U3ltYm9sKHN0cik7DQogICAgaWYgKHN5bWJvbCA9PSBudWxsIHx8IHN5bWJvbC50dHlwZSA9PSBSSUdIVEJSQUNLRVQpDQogICAgICByZXR1cm4gW251bGwsc3RyLG51bGxdOw0KICB9DQogIHN0ciA9IEFNcmVtb3ZlQ2hhcnNBbmRCbGFua3Moc3RyLHN5bWJvbC5pbnB1dC5sZW5ndGgpOw0KICBzd2l0Y2ggKHN5bWJvbC50dHlwZSkgew0KICBjYXNlIFNQQUNFOg0KICAgIG5vZGUgPSBBTWNyZWF0ZUVsZW1lbnRNYXRoTUwoc3ltYm9sLnRhZyk7DQogICAgbm9kZS5zZXRBdHRyaWJ1dGUoc3ltYm9sLmF0bmFtZSxzeW1ib2wuYXR2YWwpOw0KICAgIHJldHVybiBbbm9kZSxzdHIsc3ltYm9sLnRhZ107DQogIGNhc2UgVU5ERVJPVkVSOg0KICAgIGlmIChpc0lFKSB7DQogICAgICBpZiAoc3ltYm9sLmlucHV0LnN1YnN0cigwLDQpID09ICJcXGJpZyIpIHsgICAvLyBib3RjaCBmb3IgbWlzc2luZyBzeW1ib2xzDQoJc3RyID0gIlxcIitzeW1ib2wuaW5wdXQuc3Vic3RyKDQpK3N0cjsJICAgLy8gbWFrZSBcYmlnY3VwID0gXGN1cCBldGMuDQoJc3ltYm9sID0gQU1nZXRTeW1ib2woc3RyKTsNCglzeW1ib2wudHR5cGUgPSBVTkRFUk9WRVI7DQoJc3RyID0gQU1yZW1vdmVDaGFyc0FuZEJsYW5rcyhzdHIsc3ltYm9sLmlucHV0Lmxlbmd0aCk7DQogICAgICB9DQogICAgfQ0KICAgIHJldHVybiBbQU1jcmVhdGVNbWxOb2RlKHN5bWJvbC50YWcsDQoJCQlkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShzeW1ib2wub3V0cHV0KSksc3RyLHN5bWJvbC50YWddOw0KICBjYXNlIENPTlNUOg0KICAgIHZhciBvdXRwdXQgPSBzeW1ib2wub3V0cHV0Ow0KICAgIGlmIChpc0lFKSB7DQogICAgICBpZiAoc3ltYm9sLmlucHV0ID09ICInIikNCglvdXRwdXQgPSAiXHUyMDMyIjsNCiAgICAgIGVsc2UgaWYgKHN5bWJvbC5pbnB1dCA9PSAiJyciKQ0KCW91dHB1dCA9ICJcdTIwMzMiOw0KICAgICAgZWxzZSBpZiAoc3ltYm9sLmlucHV0ID09ICInJyciKQ0KCW91dHB1dCA9ICJcdTIwMzNcdTIwMzIiOw0KICAgICAgZWxzZSBpZiAoc3ltYm9sLmlucHV0ID09ICInJycnIikNCglvdXRwdXQgPSAiXHUyMDMzXHUyMDMzIjsNCiAgICAgIGVsc2UgaWYgKHN5bWJvbC5pbnB1dCA9PSAiXFxzcXVhcmUiKQ0KCW91dHB1dCA9ICJcdTI1QTEiOwkvLyBzYW1lIGFzIFxCb3gNCiAgICAgIGVsc2UgaWYgKHN5bWJvbC5pbnB1dC5zdWJzdHIoMCw1KSA9PSAiXFxmcmFjIikgew0KCQkJCQkJLy8gYm90Y2ggZm9yIG1pc3NpbmcgZnJhY3Rpb25zDQoJdmFyIGRlbm9tID0gc3ltYm9sLmlucHV0LnN1YnN0cig2LDEpOw0KCWlmIChkZW5vbSA9PSAiNSIgfHwgZGVub20gPT0gIjYiKSB7DQoJICBzdHIgPSBzeW1ib2wuaW5wdXQucmVwbGFjZSgvXFxmcmFjLywiXFxmcmFjICIpK3N0cjsNCgkgIHJldHVybiBbbm9kZSxzdHIsc3ltYm9sLnRhZ107DQoJfQ0KICAgICAgfQ0KICAgIH0NCiAgICBub2RlID0gQU1jcmVhdGVNbWxOb2RlKHN5bWJvbC50YWcsZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUob3V0cHV0KSk7DQogICAgcmV0dXJuIFtub2RlLHN0cixzeW1ib2wudGFnXTsNCiAgY2FzZSBMT05HOiAgLy8gYWRkZWQgYnkgRFJXDQogICAgbm9kZSA9IEFNY3JlYXRlTW1sTm9kZShzeW1ib2wudGFnLGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHN5bWJvbC5vdXRwdXQpKTsNCiAgICBub2RlLnNldEF0dHJpYnV0ZSgibWluc2l6ZSIsIjEuNSIpOw0KICAgIG5vZGUuc2V0QXR0cmlidXRlKCJtYXhzaXplIiwiMS41Iik7DQogICAgbm9kZSA9IEFNY3JlYXRlTW1sTm9kZSgibW92ZXIiLG5vZGUpOw0KICAgIG5vZGUuYXBwZW5kQ2hpbGQoQU1jcmVhdGVFbGVtZW50TWF0aE1MKCJtc3BhY2UiKSk7DQogICAgcmV0dXJuIFtub2RlLHN0cixzeW1ib2wudGFnXTsNCiAgY2FzZSBTVFJFVENIWTogIC8vIGFkZGVkIGJ5IERSVw0KICAgIGlmIChpc0lFICYmIHN5bWJvbC5pbnB1dCA9PSAiXFxiYWNrc2xhc2giKQ0KCXN5bWJvbC5vdXRwdXQgPSAiXFwiOwkvLyBkb2Vzbid0IGV4cGFuZCwgYnV0IHRoZW4gbm9yIGRvZXMgIlx1MjIxNiINCiAgICBub2RlID0gQU1jcmVhdGVNbWxOb2RlKHN5bWJvbC50YWcsZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoc3ltYm9sLm91dHB1dCkpOw0KICAgIGlmIChzeW1ib2wuaW5wdXQgPT0gInwiIHx8IHN5bWJvbC5pbnB1dCA9PSAiXFx2ZXJ0IiB8fA0KCXN5bWJvbC5pbnB1dCA9PSAiXFx8IiB8fCBzeW1ib2wuaW5wdXQgPT0gIlxcVmVydCIpIHsNCgkgIG5vZGUuc2V0QXR0cmlidXRlKCJsc3BhY2UiLCIwZW0iKTsNCgkgIG5vZGUuc2V0QXR0cmlidXRlKCJyc3BhY2UiLCIwZW0iKTsNCiAgICB9DQogICAgbm9kZS5zZXRBdHRyaWJ1dGUoIm1heHNpemUiLHN5bWJvbC5hdHZhbCk7ICAvLyBkb24ndCBhbGxvdyB0byBzdHJldGNoIGhlcmUNCiAgICBpZiAoc3ltYm9sLnJ0YWcgIT0gbnVsbCkNCiAgICAgIHJldHVybiBbbm9kZSxzdHIsc3ltYm9sLnJ0YWddOw0KICAgIGVsc2UNCiAgICAgIHJldHVybiBbbm9kZSxzdHIsc3ltYm9sLnRhZ107DQogIGNhc2UgQklHOiAgLy8gYWRkZWQgYnkgRFJXDQogICAgdmFyIGF0dmFsID0gc3ltYm9sLmF0dmFsOw0KICAgIGlmIChpc0lFKQ0KICAgICAgYXR2YWwgPSBzeW1ib2wuaWV2YWw7DQogICAgc3ltYm9sID0gQU1nZXRTeW1ib2woc3RyKTsNCiAgICBpZiAoc3ltYm9sID09IG51bGwpDQoJcmV0dXJuIFtudWxsLHN0cixudWxsXTsNCiAgICBzdHIgPSBBTXJlbW92ZUNoYXJzQW5kQmxhbmtzKHN0cixzeW1ib2wuaW5wdXQubGVuZ3RoKTsNCiAgICBub2RlID0gQU1jcmVhdGVNbWxOb2RlKHN5bWJvbC50YWcsZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoc3ltYm9sLm91dHB1dCkpOw0KICAgIGlmIChpc0lFKSB7CQkvLyB0byBnZXQgYnJhY2tldHMgdG8gZXhwYW5kDQogICAgICB2YXIgc3BhY2UgPSBBTWNyZWF0ZUVsZW1lbnRNYXRoTUwoIm1zcGFjZSIpOw0KICAgICAgc3BhY2Uuc2V0QXR0cmlidXRlKCJoZWlnaHQiLGF0dmFsKyJleCIpOw0KICAgICAgbm9kZSA9IEFNY3JlYXRlTW1sTm9kZSgibXJvdyIsbm9kZSk7DQogICAgICBub2RlLmFwcGVuZENoaWxkKHNwYWNlKTsNCiAgICB9IGVsc2UgewkJLy8gaWdub3JlZCBpbiBJRQ0KICAgICAgbm9kZS5zZXRBdHRyaWJ1dGUoIm1pbnNpemUiLGF0dmFsKTsNCiAgICAgIG5vZGUuc2V0QXR0cmlidXRlKCJtYXhzaXplIixhdHZhbCk7DQogICAgfQ0KICAgIHJldHVybiBbbm9kZSxzdHIsc3ltYm9sLnRhZ107DQogIGNhc2UgTEVGVEJSQUNLRVQ6ICAgLy9yZWFkIChleHByKykNCiAgICBpZiAoc3ltYm9sLmlucHV0ID09ICJcXGxlZnQiKSB7IC8vIGxlZnQgd2hhdD8NCiAgICAgIHN5bWJvbCA9IEFNZ2V0U3ltYm9sKHN0cik7DQogICAgICBpZiAoc3ltYm9sICE9IG51bGwpIHsNCglpZiAoc3ltYm9sLmlucHV0ID09ICIuIikNCgkgIHN5bWJvbC5pbnZpc2libGUgPSB0cnVlOw0KCXN0ciA9IEFNcmVtb3ZlQ2hhcnNBbmRCbGFua3Moc3RyLHN5bWJvbC5pbnB1dC5sZW5ndGgpOw0KICAgICAgfQ0KICAgIH0NCiAgICByZXN1bHQgPSBBTXBhcnNlRXhwcihzdHIsdHJ1ZSxmYWxzZSk7DQogICAgaWYgKHN5bWJvbD09bnVsbCB8fA0KCSh0eXBlb2Ygc3ltYm9sLmludmlzaWJsZSA9PSAiYm9vbGVhbiIgJiYgc3ltYm9sLmludmlzaWJsZSkpDQogICAgICBub2RlID0gQU1jcmVhdGVNbWxOb2RlKCJtcm93IixyZXN1bHRbMF0pOw0KICAgIGVsc2Ugew0KICAgICAgbm9kZSA9IEFNY3JlYXRlTW1sTm9kZSgibW8iLGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHN5bWJvbC5vdXRwdXQpKTsNCiAgICAgIG5vZGUgPSBBTWNyZWF0ZU1tbE5vZGUoIm1yb3ciLG5vZGUpOw0KICAgICAgbm9kZS5hcHBlbmRDaGlsZChyZXN1bHRbMF0pOw0KICAgIH0NCiAgICByZXR1cm4gW25vZGUscmVzdWx0WzFdLHJlc3VsdFsyXV07DQogIGNhc2UgTUFUUklYOgkgLy9yZWFkIChleHByKykNCiAgICBpZiAoc3ltYm9sLmlucHV0ID09ICJcXGJlZ2lue2FycmF5fSIpIHsNCiAgICAgIHZhciBtYXNrID0gIiI7DQogICAgICBzeW1ib2wgPSBBTWdldFN5bWJvbChzdHIpOw0KICAgICAgc3RyID0gQU1yZW1vdmVDaGFyc0FuZEJsYW5rcyhzdHIsMCk7DQogICAgICBpZiAoc3ltYm9sID09IG51bGwpDQoJbWFzayA9ICJsIjsNCiAgICAgIGVsc2Ugew0KCXN0ciA9IEFNcmVtb3ZlQ2hhcnNBbmRCbGFua3Moc3RyLHN5bWJvbC5pbnB1dC5sZW5ndGgpOw0KCWlmIChzeW1ib2wuaW5wdXQgIT0gInsiKQ0KCSAgbWFzayA9ICJsIjsNCgllbHNlIGRvIHsNCgkgIHN5bWJvbCA9IEFNZ2V0U3ltYm9sKHN0cik7DQoJICBpZiAoc3ltYm9sICE9IG51bGwpIHsNCgkgICAgc3RyID0gQU1yZW1vdmVDaGFyc0FuZEJsYW5rcyhzdHIsc3ltYm9sLmlucHV0Lmxlbmd0aCk7DQoJICAgIGlmIChzeW1ib2wuaW5wdXQgIT0gIn0iKQ0KCSAgICAgIG1hc2sgPSBtYXNrK3N5bWJvbC5pbnB1dDsNCgkgIH0NCgl9IHdoaWxlIChzeW1ib2wgIT0gbnVsbCAmJiBzeW1ib2wuaW5wdXQgIT0gIiIgJiYgc3ltYm9sLmlucHV0ICE9ICJ9Iik7DQogICAgICB9DQogICAgICByZXN1bHQgPSBBTXBhcnNlRXhwcigieyIrc3RyLHRydWUsdHJ1ZSk7DQovLyAgICBpZiAocmVzdWx0WzBdPT1udWxsKSByZXR1cm4gW0FNY3JlYXRlTW1sTm9kZSgibW8iLA0KLy8JCQkgICBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShzeW1ib2wuaW5wdXQpKSxzdHJdOw0KICAgICAgbm9kZSA9IEFNY3JlYXRlTW1sTm9kZSgibXRhYmxlIixyZXN1bHRbMF0pOw0KICAgICAgbWFzayA9IG1hc2sucmVwbGFjZSgvbC9nLCJsZWZ0ICIpOw0KICAgICAgbWFzayA9IG1hc2sucmVwbGFjZSgvci9nLCJyaWdodCAiKTsNCiAgICAgIG1hc2sgPSBtYXNrLnJlcGxhY2UoL2MvZywiY2VudGVyICIpOw0KICAgICAgbm9kZS5zZXRBdHRyaWJ1dGUoImNvbHVtbmFsaWduIixtYXNrKTsNCiAgICAgIG5vZGUuc2V0QXR0cmlidXRlKCJkaXNwbGF5c3R5bGUiLCJmYWxzZSIpOw0KICAgICAgaWYgKGlzSUUpDQoJcmV0dXJuIFtub2RlLHJlc3VsdFsxXSxudWxsXTsNCi8vIHRyeWluZyB0byBnZXQgYSAqbGl0dGxlKiBiaXQgb2Ygc3BhY2UgYXJvdW5kIHRoZSBhcnJheQ0KLy8gKElFIGFscmVhZHkgaW5jbHVkZXMgaXQpDQogICAgICB2YXIgbHNwYWNlID0gQU1jcmVhdGVFbGVtZW50TWF0aE1MKCJtc3BhY2UiKTsNCiAgICAgIGxzcGFjZS5zZXRBdHRyaWJ1dGUoIndpZHRoIiwiMC4xNjdlbSIpOw0KICAgICAgdmFyIHJzcGFjZSA9IEFNY3JlYXRlRWxlbWVudE1hdGhNTCgibXNwYWNlIik7DQogICAgICByc3BhY2Uuc2V0QXR0cmlidXRlKCJ3aWR0aCIsIjAuMTY3ZW0iKTsNCiAgICAgIHZhciBub2RlMSA9IEFNY3JlYXRlTW1sTm9kZSgibXJvdyIsbHNwYWNlKTsNCiAgICAgIG5vZGUxLmFwcGVuZENoaWxkKG5vZGUpOw0KICAgICAgbm9kZTEuYXBwZW5kQ2hpbGQocnNwYWNlKTsNCiAgICAgIHJldHVybiBbbm9kZTEscmVzdWx0WzFdLG51bGxdOw0KICAgIH0gZWxzZSB7CS8vIGVxbmFycmF5DQogICAgICByZXN1bHQgPSBBTXBhcnNlRXhwcigieyIrc3RyLHRydWUsdHJ1ZSk7DQogICAgICBub2RlID0gQU1jcmVhdGVNbWxOb2RlKCJtdGFibGUiLHJlc3VsdFswXSk7DQogICAgICBpZiAoaXNJRSkNCglub2RlLnNldEF0dHJpYnV0ZSgiY29sdW1uc3BhY2luZyIsIjAuMjVlbSIpOyAvLyBiZXN0IGluIHByYWN0aWNlPw0KICAgICAgZWxzZQ0KCW5vZGUuc2V0QXR0cmlidXRlKCJjb2x1bW5zcGFjaW5nIiwiMC4xNjdlbSIpOyAvLyBjb3JyZWN0IChidXQgaWdub3JlZD8pDQogICAgICBub2RlLnNldEF0dHJpYnV0ZSgiY29sdW1uYWxpZ24iLCJyaWdodCBjZW50ZXIgbGVmdCIpOw0KICAgICAgbm9kZS5zZXRBdHRyaWJ1dGUoImRpc3BsYXlzdHlsZSIsInRydWUiKTsNCiAgICAgIG5vZGUgPSBBTWNyZWF0ZU1tbE5vZGUoIm1yb3ciLG5vZGUpOw0KICAgICAgcmV0dXJuIFtub2RlLHJlc3VsdFsxXSxudWxsXTsNCiAgICB9DQogIGNhc2UgVEVYVDoNCiAgICAgIGlmIChzdHIuY2hhckF0KDApPT0ieyIpIGk9c3RyLmluZGV4T2YoIn0iKTsNCiAgICAgIGVsc2UgaSA9IDA7DQogICAgICBpZiAoaT09LTEpDQoJCSBpID0gc3RyLmxlbmd0aDsNCiAgICAgIHN0ID0gc3RyLnNsaWNlKDEsaSk7DQogICAgICBpZiAoc3QuY2hhckF0KDApID09ICIgIikgew0KCW5vZGUgPSBBTWNyZWF0ZUVsZW1lbnRNYXRoTUwoIm1zcGFjZSIpOw0KCW5vZGUuc2V0QXR0cmlidXRlKCJ3aWR0aCIsIjAuMzNlbSIpOwkvLyB3YXMgMWV4DQoJbmV3RnJhZy5hcHBlbmRDaGlsZChub2RlKTsNCiAgICAgIH0NCiAgICAgIG5ld0ZyYWcuYXBwZW5kQ2hpbGQoDQogICAgICAgIEFNY3JlYXRlTW1sTm9kZShzeW1ib2wudGFnLGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHN0KSkpOw0KICAgICAgaWYgKHN0LmNoYXJBdChzdC5sZW5ndGgtMSkgPT0gIiAiKSB7DQoJbm9kZSA9IEFNY3JlYXRlRWxlbWVudE1hdGhNTCgibXNwYWNlIik7DQoJbm9kZS5zZXRBdHRyaWJ1dGUoIndpZHRoIiwiMC4zM2VtIik7CS8vIHdhcyAxZXgNCgluZXdGcmFnLmFwcGVuZENoaWxkKG5vZGUpOw0KICAgICAgfQ0KICAgICAgc3RyID0gQU1yZW1vdmVDaGFyc0FuZEJsYW5rcyhzdHIsaSsxKTsNCiAgICAgIHJldHVybiBbQU1jcmVhdGVNbWxOb2RlKCJtcm93IixuZXdGcmFnKSxzdHIsbnVsbF07DQogIGNhc2UgVU5BUlk6DQogICAgICByZXN1bHQgPSBBTXBhcnNlU2V4cHIoc3RyKTsNCiAgICAgIGlmIChyZXN1bHRbMF09PW51bGwpIHJldHVybiBbQU1jcmVhdGVNbWxOb2RlKHN5bWJvbC50YWcsZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoc3ltYm9sLm91dHB1dCkpLHN0cl07DQogICAgICBpZiAodHlwZW9mIHN5bWJvbC5mdW5jID09ICJib29sZWFuIiAmJiBzeW1ib2wuZnVuYykgeyAvLyBmdW5jdGlvbnMgaGFjaw0KCQlzdCA9IHN0ci5jaGFyQXQoMCk7DQovLwkJaWYgKHN0PT0iXiIgfHwgc3Q9PSJfIiB8fCBzdD09Ii8iIHx8IHN0PT0ifCIgfHwgc3Q9PSIsIikgew0KCQlpZiAoc3Q9PSJeIiB8fCBzdD09Il8iIHx8IHN0PT0iLCIpIHsNCgkJICByZXR1cm4gW0FNY3JlYXRlTW1sTm9kZShzeW1ib2wudGFnLGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHN5bWJvbC5vdXRwdXQpKSxzdHIsc3ltYm9sLnRhZ107DQogICAgICAgIH0gZWxzZSB7DQoJCSAgbm9kZSA9IEFNY3JlYXRlTW1sTm9kZSgibXJvdyIsQU1jcmVhdGVNbWxOb2RlKHN5bWJvbC50YWcsZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoc3ltYm9sLm91dHB1dCkpKTsNCgkgIAkgIGlmIChpc0lFKSB7DQoJICAgICAgICB2YXIgc3BhY2UgPSBBTWNyZWF0ZUVsZW1lbnRNYXRoTUwoIm1zcGFjZSIpOw0KCSAgICAJc3BhY2Uuc2V0QXR0cmlidXRlKCJ3aWR0aCIsIjAuMTY3ZW0iKTsNCgkgICAgCW5vZGUuYXBwZW5kQ2hpbGQoc3BhY2UpOw0KCSAgCSAgfQ0KCSAgCSAgbm9kZS5hcHBlbmRDaGlsZChyZXN1bHRbMF0pOw0KCSAgCSAgcmV0dXJuIFtub2RlLHJlc3VsdFsxXSxzeW1ib2wudGFnXTsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgaWYgKHN5bWJvbC5pbnB1dCA9PSAiXFxzcXJ0IikgewkJLy8gc3FydA0KCSAgICAgaWYgKGlzSUUpIHsJLy8gc2V0IG1pbnNpemUsIGZvciBcc3VyZA0KCSAgICAgICAgdmFyIHNwYWNlID0gQU1jcmVhdGVFbGVtZW50TWF0aE1MKCJtc3BhY2UiKTsNCgkgICAgICAgIHNwYWNlLnNldEF0dHJpYnV0ZSgiaGVpZ2h0IiwiMS4yZXgiKTsNCgkgICAgICAgIHNwYWNlLnNldEF0dHJpYnV0ZSgid2lkdGgiLCIwZW0iKTsJLy8gcHJvYmFibHkgbm8gZWZmZWN0DQoJICAgICAgICBub2RlID0gQU1jcmVhdGVNbWxOb2RlKHN5bWJvbC50YWcscmVzdWx0WzBdKQ0KLy8JICAgICAgICBub2RlLnNldEF0dHJpYnV0ZSgibWluc2l6ZSIsIjEiKTsJLy8gaWdub3JlZA0KLy8gICAgICAgICAJbm9kZSA9IEFNY3JlYXRlTW1sTm9kZSgibXJvdyIsbm9kZSk7ICAvLyBob3BlZnVsbHkgdW5uZWNlc3NhcnkNCgkgIAkJbm9kZS5hcHBlbmRDaGlsZChzcGFjZSk7DQoJICAJCXJldHVybiBbbm9kZSxyZXN1bHRbMV0sc3ltYm9sLnRhZ107DQoJCX0gZWxzZQ0KCQkgIHJldHVybiBbQU1jcmVhdGVNbWxOb2RlKHN5bWJvbC50YWcscmVzdWx0WzBdKSxyZXN1bHRbMV0sc3ltYm9sLnRhZ107DQogICAgICB9IGVsc2UgaWYgKHR5cGVvZiBzeW1ib2wuYWNjID09ICJib29sZWFuIiAmJiBzeW1ib2wuYWNjKSB7ICAgLy8gYWNjZW50DQogIAkgICAgICBub2RlID0gQU1jcmVhdGVNbWxOb2RlKHN5bWJvbC50YWcscmVzdWx0WzBdKTsNCgkgICAgICB2YXIgb3V0cHV0ID0gc3ltYm9sLm91dHB1dDsNCgkJICBpZiAoaXNJRSkgew0KCQkJaWYgKHN5bWJvbC5pbnB1dCA9PSAiXFxoYXQiKQ0KCQkJCW91dHB1dCA9ICJcdTAzMDIiOw0KCQkJZWxzZSBpZiAoc3ltYm9sLmlucHV0ID09ICJcXHdpZGVoYXQiKQ0KCQkJCW91dHB1dCA9ICJcdTAwNUUiOw0KCQkJZWxzZSBpZiAoc3ltYm9sLmlucHV0ID09ICJcXGJhciIpDQoJCQkJb3V0cHV0ID0gIlx1MDBBRiI7DQoJCQllbHNlIGlmIChzeW1ib2wuaW5wdXQgPT0gIlxcZ3JhdmUiKQ0KCQkJCW91dHB1dCA9ICJcdTAzMDAiOw0KCQkJZWxzZSBpZiAoc3ltYm9sLmlucHV0ID09ICJcXHRpbGRlIikNCgkJCQlvdXRwdXQgPSAiXHUwMzAzIjsNCgkJfQ0KCQl2YXIgbm9kZTEgPSBBTWNyZWF0ZU1tbE5vZGUoIm1vIixkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShvdXRwdXQpKTsNCgkJaWYgKHN5bWJvbC5pbnB1dCA9PSAiXFx2ZWMiIHx8IHN5bWJvbC5pbnB1dCA9PSAiXFxjaGVjayIpDQoJCQkJCQkvLyBkb24ndCBhbGxvdyB0byBzdHJldGNoDQoJCSAgICBub2RlMS5zZXRBdHRyaWJ1dGUoIm1heHNpemUiLCIxLjIiKTsNCgkJIC8vIHdoeSBkb2Vzbid0ICIxIiB3b3JrPyAgXHZlYyBuZWFybHkgZGlzYXBwZWFycyBpbiBmaXJlZm94DQoJCWlmIChpc0lFICYmIHN5bWJvbC5pbnB1dCA9PSAiXFxiYXIiKQ0KCSAgICBub2RlMS5zZXRBdHRyaWJ1dGUoIm1heHNpemUiLCIwLjUiKTsNCgkJaWYgKHN5bWJvbC5pbnB1dCA9PSAiXFx1bmRlcmJyYWNlIiB8fCBzeW1ib2wuaW5wdXQgPT0gIlxcdW5kZXJsaW5lIikNCgkJICBub2RlMS5zZXRBdHRyaWJ1dGUoImFjY2VudHVuZGVyIiwidHJ1ZSIpOw0KCQllbHNlDQoJCSAgbm9kZTEuc2V0QXR0cmlidXRlKCJhY2NlbnQiLCJ0cnVlIik7DQoJCW5vZGUuYXBwZW5kQ2hpbGQobm9kZTEpOw0KCQlpZiAoc3ltYm9sLmlucHV0ID09ICJcXG92ZXJicmFjZSIgfHwgc3ltYm9sLmlucHV0ID09ICJcXHVuZGVyYnJhY2UiKQ0KCQkgIG5vZGUudHR5cGUgPSBVTkRFUk9WRVI7DQoJCXJldHVybiBbbm9kZSxyZXN1bHRbMV0sc3ltYm9sLnRhZ107DQoJICAgfSBlbHNlIGlmIChzeW1ib2wuaW5wdXQgPT0gIlxcbm90IikgewkJLy8gbm90DQogICAgICAgIC8vIGFkZGVkIGJ5IGluZmluaXR5MCBvbiAyMDA5LTEyLTE1IHRvIGltcGxlbWVudCBcbm90IGNvbW1hbmQNCiAgICAgICAgdGV4dCA9IHJlc3VsdFswXS5jaGlsZE5vZGVzWzBdLm5vZGVWYWx1ZTsNCiAgICAgICAgaWYgKHR5cGVvZiB0ZXh0ID09ICJzdHJpbmciICYmIHRleHQubGVuZ3RoID09IDEgJiYgdGV4dCBpbiBBTVJlbGF0aW9uTmVnYXRpb25zKSB7DQogICAgICAgICAgcmVzdWx0WzBdLmNoaWxkTm9kZXNbMF0ubm9kZVZhbHVlID0gQU1SZWxhdGlvbk5lZ2F0aW9uc1t0ZXh0XTsNCiAgICAgICAgICByZXR1cm4gW0FNY3JlYXRlTW1sTm9kZShzeW1ib2wudGFnLHJlc3VsdFswXSkscmVzdWx0WzFdLHN5bWJvbC50YWddOw0KICAgICAgICB9DQogICAgICAgIHJldHVybiBbQU1jcmVhdGVNbWxOb2RlKCJtbyIsZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoIlxcIikpLCJub3QgIiArIHN0cixzeW1ib2wudGFnXTsNCiAgICAgIH0gZWxzZSB7CQkJICAgICAgLy8gZm9udCBjaGFuZ2Ugb3IgZGlzcGxheXN0eWxlIGNvbW1hbmQNCiAgICAgICAgaWYgKCFpc0lFICYmIHR5cGVvZiBzeW1ib2wuY29kZXMgIT0gInVuZGVmaW5lZCIpIHsNCiAgICAgICAgICBmb3IgKGk9MDsgaTxyZXN1bHRbMF0uY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykNCiAgICAgICAgICAgIGlmIChyZXN1bHRbMF0uY2hpbGROb2Rlc1tpXS5ub2RlTmFtZT09Im1pIiB8fCByZXN1bHRbMF0ubm9kZU5hbWU9PSJtaSIpIHsNCiAgICAgICAgICAgICAgc3QgPSAocmVzdWx0WzBdLm5vZGVOYW1lPT0ibWkiP3Jlc3VsdFswXS5maXJzdENoaWxkLm5vZGVWYWx1ZToNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdFswXS5jaGlsZE5vZGVzW2ldLmZpcnN0Q2hpbGQubm9kZVZhbHVlKTsNCiAgICAgICAgICAgICAgdmFyIG5ld3N0ID0gW107DQogICAgICAgICAgICAgIGZvciAodmFyIGo9MDsgajxzdC5sZW5ndGg7IGorKykNCiAgICAgICAgICAgICAgICBpZiAoc3QuY2hhckNvZGVBdChqKT42NCAmJiBzdC5jaGFyQ29kZUF0KGopPDkxKSANCgkJCQl7ICBuZXdzdCA9IG5ld3N0ICsgc3ltYm9sLmNvZGVzW3N0LmNoYXJDb2RlQXQoaiktNjVdIH0NCiAgICAgICAgICAgICAgICAgICAvLyBTdHJpbmcuZnJvbUNoYXJDb2RlKHN5bWJvbC5jb2Rlc1tzdC5jaGFyQ29kZUF0KGopLTY1XSk7IGFsZXJ0KG5ld3N0KTsgfQ0KICAgICAgICAgICAgICAgIGVsc2UgbmV3c3QgPSBuZXdzdCArIHN0LmNoYXJBdChqKTsNCiAgICAgICAgICAgICAgaWYgKHJlc3VsdFswXS5ub2RlTmFtZT09Im1pIikNCiAgICAgICAgICAgICAgICByZXN1bHRbMF09QU1jcmVhdGVFbGVtZW50TWF0aE1MKCJtbyIpLg0KICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShuZXdzdCkpOw0KICAgICAgICAgICAgICBlbHNlIHJlc3VsdFswXS5yZXBsYWNlQ2hpbGQoQU1jcmVhdGVFbGVtZW50TWF0aE1MKCJtbyIpLg0KICAgICAgICAgIGFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKG5ld3N0KSkscmVzdWx0WzBdLmNoaWxkTm9kZXNbaV0pOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIG5vZGUgPSBBTWNyZWF0ZU1tbE5vZGUoc3ltYm9sLnRhZyxyZXN1bHRbMF0pOw0KICAgICAgICBub2RlLnNldEF0dHJpYnV0ZShzeW1ib2wuYXRuYW1lLHN5bWJvbC5hdHZhbCk7DQoJaWYgKHN5bWJvbC5pbnB1dCA9PSAiXFxzY3JpcHRzdHlsZSIgfHwNCgkgICAgc3ltYm9sLmlucHV0ID09ICJcXHNjcmlwdHNjcmlwdHN0eWxlIikNCgkJbm9kZS5zZXRBdHRyaWJ1dGUoImRpc3BsYXlzdHlsZSIsImZhbHNlIik7DQoJcmV0dXJuIFtub2RlLHJlc3VsdFsxXSxzeW1ib2wudGFnXTsNCiAgICAgIH0NCiAgY2FzZSBCSU5BUlk6DQogICAgcmVzdWx0ID0gQU1wYXJzZVNleHByKHN0cik7DQogICAgaWYgKHJlc3VsdFswXT09bnVsbCkgcmV0dXJuIFtBTWNyZWF0ZU1tbE5vZGUoIm1vIixkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShzeW1ib2wuaW5wdXQpKSxzdHIsbnVsbF07DQogICAgcmVzdWx0MiA9IEFNcGFyc2VTZXhwcihyZXN1bHRbMV0pOw0KICAgIGlmIChyZXN1bHQyWzBdPT1udWxsKSByZXR1cm4gW0FNY3JlYXRlTW1sTm9kZSgibW8iLGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHN5bWJvbC5pbnB1dCkpLHN0cixudWxsXTsNCiAgICAvL2FkZGVkIGJ5IEouIEtuaXNsZXkgdG8gYWxsb3cgXHRleHRjb2xvciBhbmQgXGNvbG9yYm94IHdpdGhpbiBlcXVhdGlvbnMNCiAgICBpZiAoc3ltYm9sLmlucHV0PT0iXFx0ZXh0Y29sb3IiIHx8IHN5bWJvbC5pbnB1dD09IlxcY29sb3Jib3giKSB7IA0KICAgICAgdmFyIHRjbHIgPSBzdHIubWF0Y2goL1x7XHMqKFsjXHddKylccypcfS8pOyAvL2dldCdzIGNvbG9yIGZyb20gYmVnaW5uaW5nIG9mIHN0cg0KICAgICAgc3RyID0gc3RyLnJlcGxhY2UoL1x7XHMqWyNcd10rXHMqXH0vLCIiKTsgDQogICAgICBpZih0Y2xyIT1udWxsKSB7DQogICAgICAgICBpZihJc0NvbG9yTmFtZS50ZXN0KHRjbHJbMV0udG9Mb3dlckNhc2UoKSkpIHsNCiAgIAkgICAgICAgdGNscj1MYVRlWENvbG9yW3RjbHJbMV0udG9Mb3dlckNhc2UoKV07DQogICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICB0Y2xyPXRjbHJbMV07IC8vIG5vIGNoZWNraW5nIGZvciB2YWxpZCBjb2xvciEhDQogICAgICAgICB9IA0KICAgICAgICAgbm9kZSA9IEFNY3JlYXRlRWxlbWVudE1hdGhNTCgibXN0eWxlIik7DQogICAgICAgICBub2RlLnNldEF0dHJpYnV0ZShzeW1ib2wuYXR2YWwsdGNscik7DQogICAgICAgICBub2RlLmFwcGVuZENoaWxkKHJlc3VsdDJbMF0pOyANCiAgICAgICAgIHJldHVybiBbbm9kZSxyZXN1bHQyWzFdLHN5bWJvbC50YWddOyAgDQogICAgICB9IA0KICAgIH0gIA0KICAgIGlmIChzeW1ib2wuaW5wdXQ9PSJcXHJvb3QiIHx8IHN5bWJvbC5pbnB1dD09Ilxcc3RhY2tyZWwiKSBuZXdGcmFnLmFwcGVuZENoaWxkKHJlc3VsdDJbMF0pOw0KICAgIG5ld0ZyYWcuYXBwZW5kQ2hpbGQocmVzdWx0WzBdKTsNCiAgICBpZiAoc3ltYm9sLmlucHV0PT0iXFxmcmFjIikgbmV3RnJhZy5hcHBlbmRDaGlsZChyZXN1bHQyWzBdKTsNCiAgICByZXR1cm4gW0FNY3JlYXRlTW1sTm9kZShzeW1ib2wudGFnLG5ld0ZyYWcpLHJlc3VsdDJbMV0sc3ltYm9sLnRhZ107DQogIGNhc2UgSU5GSVg6DQogICAgc3RyID0gQU1yZW1vdmVDaGFyc0FuZEJsYW5rcyhzdHIsc3ltYm9sLmlucHV0Lmxlbmd0aCk7DQogICAgcmV0dXJuIFtBTWNyZWF0ZU1tbE5vZGUoIm1vIixkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShzeW1ib2wub3V0cHV0KSksDQoJc3RyLHN5bWJvbC50YWddOw0KICBkZWZhdWx0Og0KICAgIHJldHVybiBbQU1jcmVhdGVNbWxOb2RlKHN5bWJvbC50YWcsICAgICAgICAvL2l0cyBhIGNvbnN0YW50DQoJZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoc3ltYm9sLm91dHB1dCkpLHN0cixzeW1ib2wudGFnXTsNCiAgfQ0KfQ0KDQpmdW5jdGlvbiBBTXBhcnNlSWV4cHIoc3RyKSB7DQogIHZhciBzeW1ib2wsIHN5bTEsIHN5bTIsIG5vZGUsIHJlc3VsdCwgdGFnLCB1bmRlcm92ZXI7DQogIHN0ciA9IEFNcmVtb3ZlQ2hhcnNBbmRCbGFua3Moc3RyLDApOw0KICBzeW0xID0gQU1nZXRTeW1ib2woc3RyKTsNCiAgcmVzdWx0ID0gQU1wYXJzZVNleHByKHN0cik7DQogIG5vZGUgPSByZXN1bHRbMF07DQogIHN0ciA9IHJlc3VsdFsxXTsNCiAgdGFnID0gcmVzdWx0WzJdOw0KICBzeW1ib2wgPSBBTWdldFN5bWJvbChzdHIpOw0KICBpZiAoc3ltYm9sLnR0eXBlID09IElORklYKSB7DQogICAgc3RyID0gQU1yZW1vdmVDaGFyc0FuZEJsYW5rcyhzdHIsc3ltYm9sLmlucHV0Lmxlbmd0aCk7DQogICAgcmVzdWx0ID0gQU1wYXJzZVNleHByKHN0cik7DQogICAgaWYgKHJlc3VsdFswXSA9PSBudWxsKSAvLyBzaG93IGJveCBpbiBwbGFjZSBvZiBtaXNzaW5nIGFyZ3VtZW50DQogICAgICByZXN1bHRbMF0gPSBBTWNyZWF0ZU1tbE5vZGUoIm1vIixkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgiXHUyNUExIikpOw0KICAgIHN0ciA9IHJlc3VsdFsxXTsNCiAgICB0YWcgPSByZXN1bHRbMl07DQogICAgaWYgKHN5bWJvbC5pbnB1dCA9PSAiXyIgfHwgc3ltYm9sLmlucHV0ID09ICJeIikgew0KICAgICAgc3ltMiA9IEFNZ2V0U3ltYm9sKHN0cik7DQogICAgICB0YWcgPSBudWxsOwkvLyBubyBzcGFjZSBiZXR3ZWVuIHheMiBhbmQgYSBmb2xsb3dpbmcgc2luLCBjb3MsIGV0Yy4NCi8vIFRoaXMgaXMgZm9yIFx1bmRlcmJyYWNlIGFuZCBcb3ZlcmJyYWNlDQogICAgICB1bmRlcm92ZXIgPSAoKHN5bTEudHR5cGUgPT0gVU5ERVJPVkVSKSB8fCAobm9kZS50dHlwZSA9PSBVTkRFUk9WRVIpKTsNCi8vICAgIHVuZGVyb3ZlciA9IChzeW0xLnR0eXBlID09IFVOREVST1ZFUik7DQogICAgICBpZiAoc3ltYm9sLmlucHV0ID09ICJfIiAmJiBzeW0yLmlucHV0ID09ICJeIikgew0KICAgICAgICBzdHIgPSBBTXJlbW92ZUNoYXJzQW5kQmxhbmtzKHN0cixzeW0yLmlucHV0Lmxlbmd0aCk7DQogICAgICAgIHZhciByZXMyID0gQU1wYXJzZVNleHByKHN0cik7DQoJc3RyID0gcmVzMlsxXTsNCgl0YWcgPSByZXMyWzJdOyAgLy8gbGVhdmUgc3BhY2UgYmV0d2VlbiB4XzFeMiBhbmQgYSBmb2xsb3dpbmcgc2luIGV0Yy4NCiAgICAgICAgbm9kZSA9IEFNY3JlYXRlTW1sTm9kZSgodW5kZXJvdmVyPyJtdW5kZXJvdmVyIjoibXN1YnN1cCIpLG5vZGUpOw0KICAgICAgICBub2RlLmFwcGVuZENoaWxkKHJlc3VsdFswXSk7DQogICAgICAgIG5vZGUuYXBwZW5kQ2hpbGQocmVzMlswXSk7DQogICAgICB9IGVsc2UgaWYgKHN5bWJvbC5pbnB1dCA9PSAiXyIpIHsNCglub2RlID0gQU1jcmVhdGVNbWxOb2RlKCh1bmRlcm92ZXI/Im11bmRlciI6Im1zdWIiKSxub2RlKTsNCiAgICAgICAgbm9kZS5hcHBlbmRDaGlsZChyZXN1bHRbMF0pOw0KICAgICAgfSBlbHNlIHsNCglub2RlID0gQU1jcmVhdGVNbWxOb2RlKCh1bmRlcm92ZXI/Im1vdmVyIjoibXN1cCIpLG5vZGUpOw0KICAgICAgICBub2RlLmFwcGVuZENoaWxkKHJlc3VsdFswXSk7DQogICAgICB9DQogICAgICBub2RlID0gQU1jcmVhdGVNbWxOb2RlKCJtcm93Iixub2RlKTsgLy8gc28gc3VtIGRvZXMgbm90IHN0cmV0Y2gNCiAgICB9IGVsc2Ugew0KICAgICAgbm9kZSA9IEFNY3JlYXRlTW1sTm9kZShzeW1ib2wudGFnLG5vZGUpOw0KICAgICAgaWYgKHN5bWJvbC5pbnB1dCA9PSAiXFxhdG9wIiB8fCBzeW1ib2wuaW5wdXQgPT0gIlxcY2hvb3NlIikNCglub2RlLnNldEF0dHJpYnV0ZSgibGluZXRoaWNrbmVzcyIsIjBleCIpOw0KICAgICAgbm9kZS5hcHBlbmRDaGlsZChyZXN1bHRbMF0pOw0KICAgICAgaWYgKHN5bWJvbC5pbnB1dCA9PSAiXFxjaG9vc2UiKQ0KCW5vZGUgPSBBTWNyZWF0ZU1tbE5vZGUoIm1mZW5jZWQiLG5vZGUpOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gW25vZGUsc3RyLHRhZ107DQp9DQoNCmZ1bmN0aW9uIEFNcGFyc2VFeHByKHN0cixyaWdodGJyYWNrZXQsbWF0cml4KSB7DQogIHZhciBzeW1ib2wsIG5vZGUsIHJlc3VsdCwgaSwgdGFnLA0KICBuZXdGcmFnID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOw0KICBkbyB7DQogICAgc3RyID0gQU1yZW1vdmVDaGFyc0FuZEJsYW5rcyhzdHIsMCk7DQogICAgcmVzdWx0ID0gQU1wYXJzZUlleHByKHN0cik7DQogICAgbm9kZSA9IHJlc3VsdFswXTsNCiAgICBzdHIgPSByZXN1bHRbMV07DQogICAgdGFnID0gcmVzdWx0WzJdOw0KICAgIHN5bWJvbCA9IEFNZ2V0U3ltYm9sKHN0cik7DQogICAgaWYgKG5vZGUhPXVuZGVmaW5lZCkgew0KICAgICAgaWYgKCh0YWcgPT0gIm1uIiB8fCB0YWcgPT0gIm1pIikgJiYgc3ltYm9sIT1udWxsICYmDQoJdHlwZW9mIHN5bWJvbC5mdW5jID09ICJib29sZWFuIiAmJiBzeW1ib2wuZnVuYykgew0KCQkJLy8gQWRkIHNwYWNlIGJlZm9yZSBcc2luIGluIDJcc2luIHggb3IgeFxzaW4geA0KCSAgdmFyIHNwYWNlID0gQU1jcmVhdGVFbGVtZW50TWF0aE1MKCJtc3BhY2UiKTsNCgkgIHNwYWNlLnNldEF0dHJpYnV0ZSgid2lkdGgiLCIwLjE2N2VtIik7DQoJICBub2RlID0gQU1jcmVhdGVNbWxOb2RlKCJtcm93Iixub2RlKTsNCgkgIG5vZGUuYXBwZW5kQ2hpbGQoc3BhY2UpOw0KICAgICAgfQ0KICAgICAgbmV3RnJhZy5hcHBlbmRDaGlsZChub2RlKTsNCiAgICB9DQogIH0gd2hpbGUgKChzeW1ib2wudHR5cGUgIT0gUklHSFRCUkFDS0VUKQ0KICAgICAgICAmJiBzeW1ib2whPW51bGwgJiYgc3ltYm9sLm91dHB1dCE9IiIpOw0KICB0YWcgPSBudWxsOw0KICBpZiAoc3ltYm9sLnR0eXBlID09IFJJR0hUQlJBQ0tFVCkgew0KICAgIGlmIChzeW1ib2wuaW5wdXQgPT0gIlxccmlnaHQiKSB7IC8vIHJpZ2h0IHdoYXQ/DQogICAgICBzdHIgPSBBTXJlbW92ZUNoYXJzQW5kQmxhbmtzKHN0cixzeW1ib2wuaW5wdXQubGVuZ3RoKTsNCiAgICAgIHN5bWJvbCA9IEFNZ2V0U3ltYm9sKHN0cik7DQogICAgICBpZiAoc3ltYm9sICE9IG51bGwgJiYgc3ltYm9sLmlucHV0ID09ICIuIikNCglzeW1ib2wuaW52aXNpYmxlID0gdHJ1ZTsNCiAgICAgIGlmIChzeW1ib2wgIT0gbnVsbCkNCgl0YWcgPSBzeW1ib2wucnRhZzsNCiAgICB9DQogICAgaWYgKHN5bWJvbCE9bnVsbCkNCiAgICAgIHN0ciA9IEFNcmVtb3ZlQ2hhcnNBbmRCbGFua3Moc3RyLHN5bWJvbC5pbnB1dC5sZW5ndGgpOyAvLyByZWFkeSB0byByZXR1cm4NCiAgICB2YXIgbGVuID0gbmV3RnJhZy5jaGlsZE5vZGVzLmxlbmd0aDsNCiAgICBpZiAobWF0cml4ICYmDQogICAgICBsZW4+MCAmJiBuZXdGcmFnLmNoaWxkTm9kZXNbbGVuLTFdLm5vZGVOYW1lID09ICJtcm93IiAmJiBsZW4+MSAmJg0KICAgICAgbmV3RnJhZy5jaGlsZE5vZGVzW2xlbi0yXS5ub2RlTmFtZSA9PSAibW8iICYmDQogICAgICBuZXdGcmFnLmNoaWxkTm9kZXNbbGVuLTJdLmZpcnN0Q2hpbGQubm9kZVZhbHVlID09ICImIikgeyAvL21hdHJpeA0KCXZhciBwb3MgPSBbXTsgLy8gcG9zaXRpb25zIG9mIGFtcGVyc2FuZHMNCiAgICAgICAgdmFyIG0gPSBuZXdGcmFnLmNoaWxkTm9kZXMubGVuZ3RoOw0KICAgICAgICBmb3IgKGk9MDsgbWF0cml4ICYmIGk8bTsgaT1pKzIpIHsNCiAgICAgICAgICBwb3NbaV0gPSBbXTsNCiAgICAgICAgICBub2RlID0gbmV3RnJhZy5jaGlsZE5vZGVzW2ldOw0KCSAgZm9yICh2YXIgaj0wOyBqPG5vZGUuY2hpbGROb2Rlcy5sZW5ndGg7IGorKykNCgkgICAgaWYgKG5vZGUuY2hpbGROb2Rlc1tqXS5maXJzdENoaWxkLm5vZGVWYWx1ZT09IiYiKQ0KCSAgICAgIHBvc1tpXVtwb3NbaV0ubGVuZ3RoXT1qOw0KICAgICAgICB9DQoJdmFyIHJvdywgZnJhZywgbiwgaywgdGFibGUgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7DQoJZm9yIChpPTA7IGk8bTsgaT1pKzIpIHsNCgkgIHJvdyA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsNCgkgIGZyYWcgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7DQoJICBub2RlID0gbmV3RnJhZy5maXJzdENoaWxkOyAvLyA8bXJvdz4gLSYtJi4uLiYtJi0gPC9tcm93Pg0KCSAgbiA9IG5vZGUuY2hpbGROb2Rlcy5sZW5ndGg7DQoJICBrID0gMDsNCgkgIGZvciAoaj0wOyBqPG47IGorKykgew0KCSAgICBpZiAodHlwZW9mIHBvc1tpXVtrXSAhPSAidW5kZWZpbmVkIiAmJiBqPT1wb3NbaV1ba10pew0KCSAgICAgIG5vZGUucmVtb3ZlQ2hpbGQobm9kZS5maXJzdENoaWxkKTsgLy9yZW1vdmUgJg0KCSAgICAgIHJvdy5hcHBlbmRDaGlsZChBTWNyZWF0ZU1tbE5vZGUoIm10ZCIsZnJhZykpOw0KCSAgICAgIGsrKzsNCgkgICAgfSBlbHNlIGZyYWcuYXBwZW5kQ2hpbGQobm9kZS5maXJzdENoaWxkKTsNCgkgIH0NCgkgIHJvdy5hcHBlbmRDaGlsZChBTWNyZWF0ZU1tbE5vZGUoIm10ZCIsZnJhZykpOw0KCSAgaWYgKG5ld0ZyYWcuY2hpbGROb2Rlcy5sZW5ndGg+Mikgew0KCSAgICBuZXdGcmFnLnJlbW92ZUNoaWxkKG5ld0ZyYWcuZmlyc3RDaGlsZCk7IC8vcmVtb3ZlIDxtcm93PiA8L21yb3c+DQoJICAgIG5ld0ZyYWcucmVtb3ZlQ2hpbGQobmV3RnJhZy5maXJzdENoaWxkKTsgLy9yZW1vdmUgPG1vPiY8L21vPg0KCSAgfQ0KCSAgdGFibGUuYXBwZW5kQ2hpbGQoQU1jcmVhdGVNbWxOb2RlKCJtdHIiLHJvdykpOw0KCX0NCglyZXR1cm4gW3RhYmxlLHN0cl07DQogICAgfQ0KICAgIGlmICh0eXBlb2Ygc3ltYm9sLmludmlzaWJsZSAhPSAiYm9vbGVhbiIgfHwgIXN5bWJvbC5pbnZpc2libGUpIHsNCiAgICAgIG5vZGUgPSBBTWNyZWF0ZU1tbE5vZGUoIm1vIixkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShzeW1ib2wub3V0cHV0KSk7DQogICAgICBuZXdGcmFnLmFwcGVuZENoaWxkKG5vZGUpOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gW25ld0ZyYWcsc3RyLHRhZ107DQp9DQoNCmZ1bmN0aW9uIEFNcGFyc2VNYXRoKHN0cikgew0KICB2YXIgcmVzdWx0LCBub2RlID0gQU1jcmVhdGVFbGVtZW50TWF0aE1MKCJtc3R5bGUiKTsNCiAgLy9hZGRlZCBieSBKLiBLbmlzbGV5IHRvIGFsbG93IGxpbWl0ZWQgaW1wbGVtZW50YXRpb24gb2YgXGNvbG9yIA0KICB2YXIgY2NsciA9IHN0ci5tYXRjaCgvXFxjb2xvclxzKlx7XHMqKFsjXHddKylccypcfS8pOw0KICBzdHIgPSBzdHIucmVwbGFjZSgvXFxjb2xvclxzKlx7XHMqWyNcd10rXHMqXH0vZywiIik7DQogIGlmKGNjbHIhPW51bGwpIHsNCiAgICAgaWYoSXNDb2xvck5hbWUudGVzdChjY2xyWzFdLnRvTG93ZXJDYXNlKCkpKSB7DQogICAJICAgIGNjbHI9TGFUZVhDb2xvcltjY2xyWzFdLnRvTG93ZXJDYXNlKCldOw0KICAgICB9IGVsc2Ugew0KICAgICAgICBjY2xyPWNjbHJbMV07IC8vIG5vIGNoZWNraW5nIGZvciB2YWxpZCBjb2xvciEhDQogICAgIH0NCiAgICAgbm9kZS5zZXRBdHRyaWJ1dGUoIm1hdGhjb2xvciIsY2Nscik7DQogIH0gZWxzZSB7IA0KICAgIGlmIChtYXRoY29sb3IgIT0gIiIpIG5vZGUuc2V0QXR0cmlidXRlKCJtYXRoY29sb3IiLG1hdGhjb2xvcik7DQogIH07DQogIGlmIChtYXRoZm9udGZhbWlseSAhPSAiIikgbm9kZS5zZXRBdHRyaWJ1dGUoImZvbnRmYW1pbHkiLG1hdGhmb250ZmFtaWx5KTsNCiAgbm9kZS5hcHBlbmRDaGlsZChBTXBhcnNlRXhwcihzdHIucmVwbGFjZSgvXlxzKy9nLCIiKSxmYWxzZSxmYWxzZSlbMF0pOw0KICBub2RlID0gQU1jcmVhdGVNbWxOb2RlKCJtYXRoIixub2RlKTsNCiAgaWYgKHNob3dhc2NpaWZvcm11bGFvbmhvdmVyKSAgICAgICAgICAgICAgICAgICAgICAvL2ZpeGVkIGJ5IGRqaHN1IHNvIG5ld2xpbmUNCiAgICBub2RlLnNldEF0dHJpYnV0ZSgidGl0bGUiLHN0ci5yZXBsYWNlKC9ccysvZywiICIpKTsvL2RvZXMgbm90IHNob3cgaW4gR2Vja28NCiAgaWYgKGZhbHNlICkgeyAvLyYmIG1hdGhmb250ZmFtaWx5ICE9ICIiICYmIChpc0lFIHx8IG1hdGhmb250ZmFtaWx5ICE9ICJzZXJpZiIpKSB7DQogICAgdmFyIGZub2RlID0gQU1jcmVhdGVFbGVtZW50WEhUTUwoImZvbnQiKTsNCiAgICBmbm9kZS5zZXRBdHRyaWJ1dGUoImZhY2UiLG1hdGhmb250ZmFtaWx5KTsNCiAgICBmbm9kZS5hcHBlbmRDaGlsZChub2RlKTsNCiAgICByZXR1cm4gZm5vZGU7DQogIH0NCiAgcmV0dXJuIG5vZGU7DQp9DQoNCmZ1bmN0aW9uIEFNc3RyYXJyMmRvY0ZyYWcoYXJyLCBsaW5lYnJlYWtzKSB7DQogIHZhciBuZXdGcmFnPWRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsNCiAgdmFyIGV4cHIgPSBmYWxzZTsNCiAgZm9yICh2YXIgaT0wOyBpPGFyci5sZW5ndGg7IGkrKykgew0KICAgIGlmIChleHByKSBuZXdGcmFnLmFwcGVuZENoaWxkKEFNcGFyc2VNYXRoKGFycltpXSkpOw0KICAgIGVsc2Ugew0KICAgICAgdmFyIGFycmkgPSAobGluZWJyZWFrcyA/IGFycltpXS5zcGxpdCgiXG5cbiIpIDogW2FycltpXV0pOw0KICAgICAgbmV3RnJhZy5hcHBlbmRDaGlsZChBTWNyZWF0ZUVsZW1lbnRYSFRNTCgic3BhbiIpLg0KICAgICAgYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoYXJyaVswXSkpKTsNCiAgICAgIGZvciAodmFyIGo9MTsgajxhcnJpLmxlbmd0aDsgaisrKSB7DQogICAgICAgIG5ld0ZyYWcuYXBwZW5kQ2hpbGQoQU1jcmVhdGVFbGVtZW50WEhUTUwoInAiKSk7DQogICAgICAgIG5ld0ZyYWcuYXBwZW5kQ2hpbGQoQU1jcmVhdGVFbGVtZW50WEhUTUwoInNwYW4iKS4NCiAgICAgICAgYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoYXJyaVtqXSkpKTsNCiAgICAgIH0NCiAgICB9DQogICAgZXhwciA9ICFleHByOw0KICB9DQogIHJldHVybiBuZXdGcmFnOw0KfQ0KDQpmdW5jdGlvbiBBTXByb2Nlc3NOb2RlUihuLCBsaW5lYnJlYWtzKSB7DQogIHZhciBtdGNoLCBzdHIsIGFyciwgZnJnLCBpOw0KICBpZiAobi5jaGlsZE5vZGVzLmxlbmd0aCA9PSAwKSB7DQogICBpZiAoKG4ubm9kZVR5cGUhPTggfHwgbGluZWJyZWFrcykgJiYNCiAgICBuLnBhcmVudE5vZGUubm9kZU5hbWUhPSJmb3JtIiAmJiBuLnBhcmVudE5vZGUubm9kZU5hbWUhPSJGT1JNIiAmJg0KICAgIG4ucGFyZW50Tm9kZS5ub2RlTmFtZSE9InRleHRhcmVhIiAmJiBuLnBhcmVudE5vZGUubm9kZU5hbWUhPSJURVhUQVJFQSIgJiYNCiAgICBuLnBhcmVudE5vZGUubm9kZU5hbWUhPSJwcmUiICYmIG4ucGFyZW50Tm9kZS5ub2RlTmFtZSE9IlBSRSIpIHsNCiAgICBzdHIgPSBuLm5vZGVWYWx1ZTsNCiAgICBpZiAoIShzdHIgPT0gbnVsbCkpIHsNCiAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKC9cclxuXHJcbi9nLCJcblxuIik7DQogICAgICBzdHIgPSBzdHIucmVwbGFjZSgvXHgyMCsvZywiICIpOw0KICAgICAgc3RyID0gc3RyLnJlcGxhY2UoL1xzKlxyXG4vZywiICIpOw0KLy8gREVMSU1JVEVSUzoNCiAgICAgIG10Y2ggPSAoc3RyLmluZGV4T2YoIlwkIik9PS0xID8gZmFsc2UgOiB0cnVlKTsNCiAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKC8oW15cXF0pXCQvZywiJDEgXCQiKTsNCiAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKC9eXCQvLCIgXCQiKTsJLy8gaW4gY2FzZSBcJCBhdCBzdGFydCBvZiBzdHJpbmcNCiAgICAgIGFyciA9IHN0ci5zcGxpdCgiIFwkIik7DQogICAgICBmb3IgKGk9MDsgaTxhcnIubGVuZ3RoOyBpKyspDQogICAgICAgICBhcnJbaV09YXJyW2ldLnJlcGxhY2UoL1xcXCQvZywiXCQiKTsNCiAgICAgICAgIGlmIChhcnIubGVuZ3RoPjEgfHwgbXRjaCkgew0KICAgICAgICAgICBpZiAoY2hlY2tGb3JNYXRoTUwpIHsNCiAgICAgICAgICAgICBjaGVja0Zvck1hdGhNTCA9IGZhbHNlOw0KICAgICAgICAgICAgIHZhciBuZCA9IEFNaXNNYXRoTUxhdmFpbGFibGUoKTsNCiAgICAgICAgICAgICBBTW5vTWF0aE1MID0gbmQgIT0gbnVsbDsNCiAgICAgICAgICAgICAgICBpZiAoQU1ub01hdGhNTCAmJiBub3RpZnlJZk5vTWF0aE1MKQ0KICAgICAgICAgICAgICAgICAgIGlmIChhbGVydElmTm9NYXRoTUwpDQogICAgICAgICAgICAgICAgICAgICAgIGFsZXJ0KCJUbyB2aWV3IHRoZSBBU0NJSU1hdGhNTCBub3RhdGlvbiB1c2UgSW50ZXJuZXQgRXhwbG9yZXIgNiArXG5NYXRoUGxheWVyIChmcmVlIGZyb20gd3d3LmRlc3NjaS5jb20pXG5cDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvciBGaXJlZm94L01vemlsbGEvTmV0c2NhcGUiKTsNCiAgICAgICAgICAgIGVsc2UgQU1ib2R5Lmluc2VydEJlZm9yZShuZCxBTWJvZHkuY2hpbGROb2Rlc1swXSk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKCFBTW5vTWF0aE1MKSB7DQogICAgICAgICAgZnJnID0gQU1zdHJhcnIyZG9jRnJhZyhhcnIsbi5ub2RlVHlwZT09OCk7DQogICAgICAgICAgdmFyIGxlbiA9IGZyZy5jaGlsZE5vZGVzLmxlbmd0aDsNCiAgICAgICAgICBuLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGZyZyxuKTsNCiAgICAgICAgICByZXR1cm4gbGVuLTE7DQogICAgICAgIH0gZWxzZSByZXR1cm4gMDsNCiAgICAgIH0NCiAgICB9DQogICB9IGVsc2UgcmV0dXJuIDA7DQogIH0gZWxzZSBpZiAobi5ub2RlTmFtZSE9Im1hdGgiKSB7DQogICAgZm9yIChpPTA7IGk8bi5jaGlsZE5vZGVzLmxlbmd0aDsgaSsrKQ0KICAgICAgaSArPSBBTXByb2Nlc3NOb2RlUihuLmNoaWxkTm9kZXNbaV0sIGxpbmVicmVha3MpOw0KICB9DQogIHJldHVybiAwOw0KfQ0KDQpmdW5jdGlvbiBBTXByb2Nlc3NOb2RlKG4sIGxpbmVicmVha3MsIHNwYW5jbGFzc0FNKSB7DQogIHZhciBmcmFnLHN0Ow0KICBpZiAoc3BhbmNsYXNzQU0hPW51bGwpIHsNCiAgICBmcmFnID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInNwYW4iKQ0KICAgIGZvciAodmFyIGk9MDtpPGZyYWcubGVuZ3RoO2krKykNCiAgICAgIGlmIChmcmFnW2ldLmNsYXNzTmFtZSA9PSAiQU0iKQ0KICAgICAgICBBTXByb2Nlc3NOb2RlUihmcmFnW2ldLGxpbmVicmVha3MpOw0KICB9IGVsc2Ugew0KICAgIHRyeSB7DQogICAgICBzdCA9IG4uaW5uZXJIVE1MOw0KICAgIH0gY2F0Y2goZXJyKSB7fQ0KLy8gREVMSU1JVEVSUzoNCiAgICBpZiAoc3Q9PW51bGwgfHwgc3QuaW5kZXhPZigiXCQiKSE9LTEpDQogICAgICBBTXByb2Nlc3NOb2RlUihuLGxpbmVicmVha3MpOw0KICB9DQogIGlmIChpc0lFKSB7IC8vbmVlZGVkIHRvIG1hdGNoIHNpemUgYW5kIGZvbnQgb2YgZm9ybXVsYSB0byBzdXJyb3VuZGluZyB0ZXh0DQogICAgZnJhZyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdtYXRoJyk7DQogICAgZm9yICh2YXIgaT0wO2k8ZnJhZy5sZW5ndGg7aSsrKSBmcmFnW2ldLnVwZGF0ZSgpDQogIH0NCn0NCg0KLyogQmVsb3cgaXMgTGFUZVggcHJlLXByb2Nlc3NpbmcgdG8gcHJvZHVjZSBDU1Mgc3VwcG9ydGVkICovDQovKiBzdGFuZGFyZCBsYXRleCBzdHJ1Y3R1cmVzKi8NCi8qIEplZmYgS25pc2xleSAoa25pc2xleWpAZXRzdS5lZHUpDQovKiBTdXBwb3J0ZWQgaW4gcGFydCBieSB0aGUgSG93YXJkIEh1Z2hlcyBNZWRpY2FsIEluc3RpdHV0ZSAqLw0KLyogYXMgcGFydCBvZiB0aGUgU3ltYmlvc2lzIFByb2plY3Q6IEhITUkgIzUyMDA1ODcyICovDQoNCnZhciBpbkFwcGVuZGl4ID0gZmFsc2U7DQp2YXIgc2VjdGlvbkNudHIgPSAwOw0KdmFyIElFY29tbWVudFdhcm5pbmcgPSB0cnVlOw0KdmFyIGJpYmxpc3QgPSBbXTsNCnZhciBiaWJjbnRyID0gMDsNCg0KdmFyIExhVGVYQ291bnRlciA9IFtdOw0KTGFUZVhDb3VudGVyWyJkZWZpbml0aW9uIl0gPSAwOw0KTGFUZVhDb3VudGVyWyJwcm9wb3NpdGlvbiJdID0gMDsNCkxhVGVYQ291bnRlclsibGVtbWEiXSA9IDA7DQpMYVRlWENvdW50ZXJbInRoZW9yZW0iXSA9IDA7DQpMYVRlWENvdW50ZXJbImNvcm9sbGFyeSJdID0gMDsNCkxhVGVYQ291bnRlclsiZXhhbXBsZSJdID0gMDsNCkxhVGVYQ291bnRlclsiZXhlcmNpc2UiXSA9IDA7DQpMYVRlWENvdW50ZXJbInN1YnNlY3Rpb24iXSA9IDA7DQpMYVRlWENvdW50ZXJbInN1YnN1YnNlY3Rpb24iXSA9IDA7DQpMYVRlWENvdW50ZXJbImZpZ3VyZSJdID0gMDsNCkxhVGVYQ291bnRlclsiZXF1YXRpb24iXSA9IDA7DQpMYVRlWENvdW50ZXJbInRhYmxlIl0gPSAwOw0KTGFUZVhDb3VudGVyWyJsYWJlbCJdID0gMDsNCg0KdmFyIExhVGVYQ29sb3IgPSBbXTsNCkxhVGVYQ29sb3JbImdyZWVueWVsbG93Il0gICAgPSAiI0Q5RkY0RiI7DQpMYVRlWENvbG9yWyJ5ZWxsb3ciXSAgICAgICAgID0gIiNGRkZGMDAiOw0KTGFUZVhDb2xvclsiZ29sZGVucm9kIl0gICAgICA9ICIjRkZFNTI5IjsNCkxhVGVYQ29sb3JbImRhbmRlbGlvbiJdICAgICAgPSAiI0ZGQjUyOSI7DQpMYVRlWENvbG9yWyJhcHJpY290Il0gICAgICAgID0gIiNGRkFEN0EiOw0KTGFUZVhDb2xvclsicGVhY2giXSAgICAgICAgICA9ICIjRkY4MDREIjsNCkxhVGVYQ29sb3JbIm1lbG9uIl0gICAgICAgICAgPSAiI0ZGOEE4MCI7DQpMYVRlWENvbG9yWyJ5ZWxsb3dvcmFuZ2UiXSAgID0gIiNGRjk0MDAiOw0KTGFUZVhDb2xvclsib3JhbmdlIl0gICAgICAgICA9ICIjRkY2MzIxIjsNCkxhVGVYQ29sb3JbImJ1cm50b3JhbmdlIl0gICAgPSAiI0ZGN0QwMCI7DQpMYVRlWENvbG9yWyJiaXR0ZXJzd2VldCJdICAgID0gIiNDMjAzMDAiOw0KTGFUZVhDb2xvclsicmVkb3JhbmdlIl0gICAgICA9ICIjRkYzQjIxIjsNCkxhVGVYQ29sb3JbIm1haG9nYW55Il0gICAgICAgPSAiI0E2MDAwMCI7DQpMYVRlWENvbG9yWyJtYXJvb24iXSAgICAgICAgID0gIiNBRDAwMDAiOw0KTGFUZVhDb2xvclsiYnJpY2tyZWQiXSAgICAgICA9ICIjQjgwMDAwIjsNCkxhVGVYQ29sb3JbInJlZCJdICAgICAgICAgICAgPSAiI0ZGMDAwMCI7DQpMYVRlWENvbG9yWyJvcmFuZ2VyZWQiXSAgICAgID0gIiNGRjAwODAiOw0KTGFUZVhDb2xvclsicnViaW5lcmVkIl0gICAgICA9ICIjRkYwMERFIjsNCkxhVGVYQ29sb3JbIndpbGRzdHJhd2JlcnJ5Il0gPSAiI0ZGMEE5QyI7DQpMYVRlWENvbG9yWyJzYWxtb24iXSAgICAgICAgID0gIiNGRjc4OUUiOw0KTGFUZVhDb2xvclsiY2FybmF0aW9ucGluayJdICA9ICIjRkY1RUZGIjsNCkxhVGVYQ29sb3JbIm1hZ2VudGEiXSAgICAgICAgPSAiI0ZGMDBGRiI7DQpMYVRlWENvbG9yWyJ2aW9sZXRyZWQiXSAgICAgID0gIiNGRjMwRkYiOw0KTGFUZVhDb2xvclsicmhvZGFtaW5lIl0gICAgICA9ICIjRkYyRUZGIjsNCkxhVGVYQ29sb3JbIm11bGJlcnJ5Il0gICAgICAgPSAiI0EzMTRGQSI7DQpMYVRlWENvbG9yWyJyZWR2aW9sZXQiXSAgICAgID0gIiM5NjAwQTgiOw0KTGFUZVhDb2xvclsiZnVjaHNpYSJdICAgICAgICA9ICIjNzMwM0VCIjsNCkxhVGVYQ29sb3JbImxhdmVuZGVyIl0gICAgICAgPSAiI0ZGODVGRiI7DQpMYVRlWENvbG9yWyJ0aGlzdGxlIl0gICAgICAgID0gIiNFMDY5RkYiOw0KTGFUZVhDb2xvclsib3JjaGlkIl0gICAgICAgICA9ICIjQUQ1Q0ZGIjsNCkxhVGVYQ29sb3JbImRhcmtvcmNoaWQiXSAgICAgPSAiIzk5MzNDQyI7DQpMYVRlWENvbG9yWyJwdXJwbGUiXSAgICAgICAgID0gIiM4QzI0RkYiOw0KTGFUZVhDb2xvclsicGx1bSJdICAgICAgICAgICA9ICIjODAwMEZGIjsNCkxhVGVYQ29sb3JbInZpb2xldCJdICAgICAgICAgPSAiIzM2MUZGRiI7DQpMYVRlWENvbG9yWyJyb3lhbHB1cnBsZSJdICAgID0gIiM0MDFBRkYiOw0KTGFUZVhDb2xvclsiYmx1ZXZpb2xldCJdICAgICA9ICIjMUEwREY1IjsNCkxhVGVYQ29sb3JbInBlcml3aW5rbGUiXSAgICAgPSAiIzZFNzNGRiI7DQpMYVRlWENvbG9yWyJjYWRldGJsdWUiXSAgICAgID0gIiM2MTZFQzQiOw0KTGFUZVhDb2xvclsiY29ybmZsb3dlcmJsdWUiXSA9ICIjNTlERUZGIjsNCkxhVGVYQ29sb3JbIm1pZG5pZ2h0Ymx1ZSJdICAgPSAiIzAwNzA5MSI7DQpMYVRlWENvbG9yWyJuYXZ5Ymx1ZSJdICAgICAgID0gIiMwRjc1RkYiOw0KTGFUZVhDb2xvclsicm95YWxibHVlIl0gICAgICA9ICIjMDA4MEZGIjsNCkxhVGVYQ29sb3JbImJsdWUiXSAgICAgICAgICAgPSAiIzAwMDBGRiI7DQpMYVRlWENvbG9yWyJjZXJ1bGVhbiJdICAgICAgID0gIiMwRkUzRkYiOw0KTGFUZVhDb2xvclsiY3lhbiJdICAgICAgICAgICA9ICIjMDBGRkZGIjsNCkxhVGVYQ29sb3JbInByb2Nlc3NibHVlIl0gICAgPSAiIzBBRkZGRiI7DQpMYVRlWENvbG9yWyJza3libHVlIl0gICAgICAgID0gIiM2MUZGRTAiOw0KTGFUZVhDb2xvclsidHVycXVvaXNlIl0gICAgICA9ICIjMjZGRkNDIjsNCkxhVGVYQ29sb3JbInRlYWxibHVlIl0gICAgICAgPSAiIzFGRkFBMyI7DQpMYVRlWENvbG9yWyJhcXVhbWFyaW5lIl0gICAgID0gIiMyRUZGQjIiOw0KTGFUZVhDb2xvclsiYmx1ZWdyZWVuIl0gICAgICA9ICIjMjZGRkFCIjsNCkxhVGVYQ29sb3JbImVtZXJhbGQiXSAgICAgICAgPSAiIzAwRkY4MCI7DQpMYVRlWENvbG9yWyJqdW5nbGVncmVlbiJdICAgID0gIiMwM0ZGN0EiOw0KTGFUZVhDb2xvclsic2VhZ3JlZW4iXSAgICAgICA9ICIjNEZGRjgwIjsNCkxhVGVYQ29sb3JbImdyZWVuIl0gICAgICAgICAgPSAiIzAwRkYwMCI7DQpMYVRlWENvbG9yWyJmb3Jlc3RncmVlbiJdICAgID0gIiMwMEUwMDAiOw0KTGFUZVhDb2xvclsicGluZWdyZWVuIl0gICAgICA9ICIjMDBCRjI5IjsNCkxhVGVYQ29sb3JbImxpbWVncmVlbiJdICAgICAgPSAiIzgwRkYwMCI7DQpMYVRlWENvbG9yWyJ5ZWxsb3dncmVlbiJdICAgID0gIiM4RkZGNDIiOw0KTGFUZVhDb2xvclsic3ByaW5nZ3JlZW4iXSAgICA9ICIjQkRGRjNEIjsNCkxhVGVYQ29sb3JbIm9saXZlZ3JlZW4iXSAgICAgPSAiIzAwOTkwMCI7DQpMYVRlWENvbG9yWyJyYXdzaWVubmEiXSAgICAgID0gIiM4QzAwMDAiOw0KTGFUZVhDb2xvclsic2VwaWEiXSAgICAgICAgICA9ICIjNEQwMDAwIjsNCkxhVGVYQ29sb3JbImJyb3duIl0gICAgICAgICAgPSAiIzY2MDAwMCI7DQpMYVRlWENvbG9yWyJ0YW4iXSAgICAgICAgICAgID0gIiNEQjk0NzAiOw0KTGFUZVhDb2xvclsiZ3JheSJdICAgICAgICAgICA9ICIjODA4MDgwIjsNCkxhVGVYQ29sb3JbImdyZXkiXSAgICAgICAgICAgPSAiIzgwODA4MCI7DQpMYVRlWENvbG9yWyJibGFjayJdICAgICAgICAgID0gIiMwMDAwMDAiOw0KTGFUZVhDb2xvclsid2hpdGUiXSAgICAgICAgICA9ICIjRkZGRkZGIjsNCg0KdmFyIElzQ29sb3JOYW1lID0gL14oPzpncmVlbnllbGxvd3x5ZWxsb3d8Z29sZGVucm9kfGRhbmRlbGlvbnxhcHJpY290fHBlYWNofG1lbG9ufHllbGxvd29yYW5nZXxvcmFuZ2V8YnVybnRvcmFuZ2V8Yml0dGVyc3dlZXR8cmVkb3JhbmdlfG1haG9nYW55fG1hcm9vbnxicmlja3JlZHxyZWR8b3JhbmdlcmVkfHJ1YmluZXJlZHx3aWxkc3RyYXdiZXJyeXxzYWxtb258Y2FybmF0aW9ucGlua3xtYWdlbnRhfHZpb2xldHJlZHxyaG9kYW1pbmV8bXVsYmVycnl8cmVkdmlvbGV0fGZ1Y2hzaWF8bGF2ZW5kZXJ8dGhpc3RsZXxvcmNoaWR8ZGFya29yY2hpZHxwdXJwbGV8cGx1bXx2aW9sZXR8cm95YWxwdXJwbGV8Ymx1ZXZpb2xldHxwZXJpd2lua2xlfGNhZGV0Ymx1ZXxjb3JuZmxvd2VyYmx1ZXxtaWRuaWdodGJsdWV8bmF2eWJsdWV8cm95YWxibHVlfGJsdWV8Y2VydWxlYW58Y3lhbnxwcm9jZXNzYmx1ZXxza3libHVlfHR1cnF1b2lzZXx0ZWFsYmx1ZXxhcXVhbWFyaW5lfGJsdWVncmVlbnxlbWVyYWxkfGp1bmdsZWdyZWVufHNlYWdyZWVufGdyZWVufGZvcmVzdGdyZWVufHBpbmVncmVlbnxsaW1lZ3JlZW58eWVsbG93Z3JlZW58c3ByaW5nZ3JlZW58b2xpdmVncmVlbnxyYXdzaWVubmF8c2VwaWF8YnJvd258dGFufGdyYXl8Z3JleXxibGFja3x3aGl0ZSkkLzsNCnZhciBJc0NvdW50ZXIgPSAgL14oPzpkZWZpbml0aW9ufHByb3Bvc2l0aW9ufGxlbW1hfHRoZW9yZW18Y29yb2xsYXJ5fGV4YW1wbGV8ZXhlcmNpc2V8c3Vic2VjdGlvbnxzdWJzdWJzZWN0aW9ufGZpZ3VyZXxlcXVhdGlvbnx0YWJsZSkkLyA7DQp2YXIgSXNMYVRlWEVsZW1lbnQgPSAvXig/OmRpc3BsYXllcXVhdGlvbnx0aXRsZXxhdXRob3J8YWRkcmVzc3xkYXRlfGFic3RyYWN0fGtleXdvcmR8c2VjdGlvbnxzdWJzZWN0aW9ufHN1YnN1YnNlY3Rpb258cmVmfGNpdGV8dGhlYmlibGlvZ3JhcGh5fGRlZmluaXRpb258cHJvcG9zaXRpb258bGVtbWF8dGhlb3JlbXxjb3JvbGxhcnl8ZXhhbXBsZXxleGVyY2lzZXxpdGVtaXplfGVudW1lcmF0ZXxlbmRkZWZpbml0aW9ufGVuZHByb3Bvc2l0aW9ufGVuZGxlbW1hfGVuZHRoZW9yZW18ZW5kY29yb2xsYXJ5fGVuZGV4YW1wbGV8ZW5kZXhlcmNpc2V8ZW5kaXRlbWl6ZXxlbmRlbnVtZXJhdGV8TGFUZVhNYXRoTUxsYWJlbHxMYVRlWE1hdGhNTHxzbWFsbHNraXB8bWVkc2tpcHxiaWdza2lwfHF1b3RlfHF1b3RhdGlvbnxlbmRxdW90ZXxlbmRxdW90YXRpb258Y2VudGVyfGVuZGNlbnRlcnxkZXNjcmlwdGlvbnxlbmRkZXNjcmlwdGlvbnxpbmxpbmVtYXRoKSQvOyANCnZhciBJc1RleHRPbmx5QXJlYSA9IC9eKD86Zm9ybXx0ZXh0YXJlYXxwcmUpJC9pOw0KdmFyIHRhYmxlaWQgPSAwOw0KDQpmdW5jdGlvbiBtYWtlTnVtYmVyU3RyaW5nKGNudHIpIHsNCiAgaWYoc2VjdGlvbkNudHIgPiAwKSB7DQogICAgIGlmKGluQXBwZW5kaXgpIHsNCiAgICAgICAgcmV0dXJuICJBIitzZWN0aW9uQ250cisiLiIrY250cjsNCiAgICAgfSBlbHNlIHsNCglyZXR1cm4gc2VjdGlvbkNudHIrIi4iK2NudHI7ICAgDQogICAgIH0NCiAgfSBlbHNlIHsNCiAgICAgcmV0dXJuICIiK2NudHI7CSAgICAgDQogIH0NCn07DQoNCg0KZnVuY3Rpb24gTGFUZVhwcmVQcm9jZXNzKHRoZWJvZHkpIHsNCiAgIHZhciBUaGVCb2R5ID0gdGhlYm9keTsNCiAgIGlmKFRoZUJvZHkuaGFzQ2hpbGROb2RlcygpKSB7DQogICAgICBpZighKElzTGFUZVhFbGVtZW50LnRlc3QoVGhlQm9keS5jbGFzc05hbWUpKSkgDQogICAgICB7DQogICAgICAgICBmb3IodmFyIGk9MDsgaTxUaGVCb2R5LmNoaWxkTm9kZXMubGVuZ3RoOyBpKyspIHsgDQogICAgICAgICAgICBMYVRlWHByZVByb2Nlc3MoVGhlQm9keS5jaGlsZE5vZGVzW2ldKSAgfQ0KICAgICAgfQkgICAgIA0KICAgfSANCiAgIGVsc2UgeyANCiAgICAgIGlmKCAgVGhlQm9keS5ub2RlVHlwZT09MyAmJiAgDQoJICAhKElzVGV4dE9ubHlBcmVhLnRlc3QoVGhlQm9keS5wYXJlbnROb2RlLm5vZGVOYW1lKSApICkgDQogICAgICB7DQogICAgICAgICB2YXIgc3RyID0gVGhlQm9keS5ub2RlVmFsdWU7DQogICAgICAgICBpZiggIShzdHI9PW51bGwpKSB7IA0KICAgICAgICAgICAgDQoJICAgICAgICBzdHIgPSBzdHIucmVwbGFjZSgvXFwlL2csICI8cGVyPiIpOyAvLyAlIHNpZ24NCgkgICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKC8lW15cbl0qKD89XG4pL2csIiIpOw0KCSAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UoLyVbXlxyXSooPz1ccikvZywiIik7IC8vVXNlZCBieSBFeHBsb3Jlcg0KCSAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UoLyVbXlxuXSokLywiIikgLy8gRW5kIG9mIHRleHQgc2VnbWVudCBjb21tZW50IA0KDQoJICAgICAgICBpZihpc0lFICYmIHN0ci5tYXRjaCgvJS9nKSAhPSBudWxsICYmIElFY29tbWVudFdhcm5pbmcpIHsNCgkgICAgICAgICAgIGFsZXJ0KCJDb21tZW50cyBtYXkgbm90IGhhdmUgcGFyc2VkIHByb3Blcmx5LiAgVHJ5IHB1dHRpbmcgaW4gPHByZSBjbGFzcz0nTGFUZVg+PGRpdj4uLjwvZGl2PjwvcHJlPiBzdHJ1Y3R1cmUuIik7DQoJICAgICAgICAgICBJRWNvbW1lbnRXYXJuaW5nID0gZmFsc2U7DQoJICAgICAgICB9DQoJICAgICAgICBzdHIgPSBzdHIucmVwbGFjZSgvPHBlcj4vZywiJSIpOw0KCSAgICAgICAgDQoJICAgICAgICAvL2lmKHN0ci5tYXRjaCgvWFhYW1xzXFNdKi8pIT1udWxsKSB7DQoJICAgICAgICAvLyAgdmFyIHRtcCA9IHN0ci5tYXRjaCgvWFhYW1xzXFNdKi8pWzBdOw0KCSAgICAgICAgLy8gIHZhciB0bXBzdHIgPSB0bXAuY2hhckNvZGVBdCg3KSsiOjoiK3RtcC5jaGFyQ29kZUF0KDgpKyI6OiIrdG1wLmNoYXJDb2RlQXQoOSkrIjo6Iit0bXAuY2hhckNvZGVBdCgxMCkrIjo6Iit0bXAuY2hhckNvZGVBdCgxMSkrIjo6Iit0bXAuY2hhckNvZGVBdCgxMikrIjo6Iit0bXAuY2hhckNvZGVBdCgxMyk7DQoJICAgICAgICAvLyAgYWxlcnQodG1wc3RyKTsNCgkgICAgICAgIC8vfQ0KDQogICAgICAgICAgICAvL3NwYWNpbmcgdGhhdCBpbiBMYVRlWE1hdGhNTCBtYXkgY2F1c2UgcHJvYmxlbXMgYmVjYXVzZSBvZiBvdXIgYXBwcm9hY2guIFdlIHVzZSBwdXJlbHkgdW5pY29kZQ0KICAgICAgICAgICAvLyAgRmlyc3Qgd2UgcmVtb3ZlIHNpbmdsZXRvbiAvIHN5bWJvbHMNCiAgICAgICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKC8oW15cXF0pXFwoXHMpL2csIiQxXHUwMEEwJDIiKTsgLy8gbXVzdCBiZSBhIHNwYWNlIGFmdGVyIFwgZm9yIGl0IHRvIG1ha2UgYW4gbmJzcCAgICAgICAgDQogDQogICAgICAgICAgICBzdHIgPSBzdHIucmVwbGFjZSgvXFxxdWFkL2csIlx1MjAwMSIpOw0KICAgICAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UoL1xccXF1YWQvZywiXHUyMDAxXHUyMDAxIik7DQogICAgICAgICAgICBzdHIgPSBzdHIucmVwbGFjZSgvXFxlbnNwYWNlL2csIlx1MjAwMiIpOw0KICAgICAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UoL1xcOy9nLCJcdTIwMDQiKTsNCiAgICAgICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKC9cXDovZywiXHUyMDA1Iik7DQogICAgICAgICAgICBzdHIgPSBzdHIucmVwbGFjZSgvXFwsL2csIlx1MjAwNiIpOw0KICAgICAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UoL1xcdGhpbnNwYWNlL2csIlx1MjAwQSIpOw0KICAgICAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UoLyhbXlxcXSl+L2csIiQxXHUwMEEwIik7DQogICAgICAgICAgICBzdHIgPSBzdHIucmVwbGFjZSgvXFx+L2csIn4iKTsNCgkJIA0KICAgICAgICAgICAgLy9BZGRlZCBcWyAuLi4gXF0gYW5kICQkLi4kJCBmdW5jdGlvbmFsaXR5LiAgDQogICAgICAgICAgICBzdHIgPSBzdHIucmVwbGFjZSgvXFxcWy9nLCIgPERFUT4gJFxcZGlzcGxheXN0eWxleyIpOw0KICAgICAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UoL1xcXF0vZywifSQgPERFUT4gIik7DQogICAgICAgICAgICBzdHIgPSBzdHIucmVwbGFjZSgvXCRcJC9nLCIkeyQ8REVRPiR9JCIpOw0KICAgICAgICAgICAgDQogICAgICAgICAgICAvLyBTZXBhcmF0ZSByZXBsYWNlbWVudHMgZm9yIGJlZ2luIC4uIGVuZCB0byAoZXZlbnR1YWxseSkgYWxsb3cgTGFUZVggZXF1YXRpb25zIHdpdGggaHRtbCBjb2RlcyBtaXhlZCBpbiANCiAgICAgICAgICAgIC8vIChhcyBpcyB0aGUgY2FzZSBmb3IgdGhlb3JlbSwgZXRjLg0KICAgICAgICAgICAgLy8gYWxsIHZhcmlhdGlvbnMgb2Ygc3BhY2VzIHdpdGggXGJlZ2lue2FycmF5fSAuLiBcZW5ke2FycmF5fSAtLSBub3QgZGlzcGxheWVkLCBob3dldmVyDQogICAgICAgICAgICBzdHIgPSBzdHIucmVwbGFjZSgvXFxiZWdpblxzKlx7XHMqYXJyYXlccypcfS9nLCJcXGJlZ2lue2FycmF5fSIpOw0KICAgICAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UoL1xcZW5kXHMqXHtccyphcnJheVxzKlx9L2csIlxcZW5ke2FycmF5fSIpOw0KICAgICAgICAgICANCiAgICAgICAgICAgIC8vIGFsbCB2YXJpYXRpb25zIG9mIHNwYWNlcyB3aXRoIFxiZWdpbntlcW5hcnJheX0gLi4gXGVuZHtlcW5hcnJheX0NCiAgICAgICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKC9cXGJlZ2luXHMqXHtccyplcW5hcnJheVxzKlx9L2csIiAgPERFUT5lcW5vJFxcYmVnaW57ZXFuYXJyYXl9Iik7DQogICAgICAgICAgICBzdHIgPSBzdHIucmVwbGFjZSgvXFxlbmRccypce1xzKmVxbmFycmF5XHMqXH0vZywiXFxlbmR7ZXFuYXJyYXl9JDxERVE+ICAiKTsNCg0KICAgICAgICAgICAvLyBhbGwgdmFyaWF0aW9ucyBvZiBzcGFjZXMgd2l0aCBcYmVnaW57ZXFuYXJyYXkqfSAuLiBcZW5ke2VxbmFycmF5Kn0NCiAgICAgICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKC9cXGJlZ2luXHMqXHtccyplcW5hcnJheVwqXHMqXH0vZywiICA8REVRPiRcXGJlZ2lue2VxbmFycmF5fSIpOw0KICAgICAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UoL1xcZW5kXHMqXHtccyplcW5hcnJheVwqXHMqXH0vZywiXFxlbmR7ZXFuYXJyYXl9JDxERVE+ICAiKTsNCg0KICAgICAgICAgICAgLy8gYWxsIHZhcmlhdGlvbnMgb2Ygc3BhY2VzIHdpdGggXGJlZ2lue2Rpc3BsYXltYXRofSAuLiBcZW5ke2Rpc3BsYXltYXRofQ0KICAgICAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UoL1xcYmVnaW5ccypce1xzKmRpc3BsYXltYXRoXHMqXH0vZywiIDxERVE+ICRcXGRpc3BsYXlzdHlsZXsiKTsNCiAgICAgICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKC9cXGVuZFxzKlx7XHMqZGlzcGxheW1hdGhccypcfS9nLCJ9JCA8REVRPiAiKTsNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgLy8gYWxsIHZhcmlhdGlvbnMgb2Ygc3BhY2VzIHdpdGggXGJlZ2lue2VxdWF0aW9uKn0gLi4gXGVuZHtlcXVhdGlvbip9DQogICAgICAgICAgICBzdHIgPSBzdHIucmVwbGFjZSgvXFxiZWdpblxzKlx7XHMqZXF1YXRpb25ccypcKlxzKlx9L2csIiA8REVRPiAkXFxkaXNwbGF5c3R5bGV7Iik7DQogICAgICAgICAgICBzdHIgPSBzdHIucmVwbGFjZSgvXFxlbmRccypce1xzKmVxdWF0aW9uXHMqXCpccypcfS9nLCJ9JCA8REVRPiAiKTsNCiAgDQogICAgICAgICAgICAgLy8gYWxsIHZhcmlhdGlvbnMgb2Ygc3BhY2VzIHdpdGggXGJlZ2lue2VxdWF0aW9ufSAuLiBcZW5ke2VxdWF0aW9ufQ0KICAgICAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UoL1xcYmVnaW5ccypce1xzKmVxdWF0aW9uXHMqXH0vZywiIDxERVE+ZXFubyRcXGRpc3BsYXlzdHlsZXsiKTsNCiAgICAgICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKC9cXGVuZFxzKlx7XHMqZXF1YXRpb25ccypcfS9nLCJ9JCA8REVRPiAiKTsNCgkgICAgDQoNCgkgICAgDQogICAgICAgICAgICAvL25vdyBwYXJzZSB0byB0cmFuc2xhdGUgPERFUT4gc3RydWN0dXJlcyB0byA8dGFibGUgY2xhc3MgPSAnZGlzcGVxJz4gc3R1ZmYNCiAgICAgICAgICAgIC8vYW5kIHRvIGlkZW50aWZ5IG5vbi1kaXNwbGF5IG1hdGggY29udGVudCAoc2VjdGlvbnMsIGV0YykuICANCiAgICAgICAgICAgICANCiAgICAgICAgICAgIHN0ciA9IHN0ci5zcGxpdCgiPERFUT4iKTsNCiAgICAgICAgICAgIC8vIHZhciBudHlwZSA9IFRoZUJvZHkubm9kZVR5cGU7DQogICAgICAgICAgICB2YXIgbmV3RnJhZyA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTsNCgkgICAgIA0KICAgICAgICAgICAgZm9yKHZhciBpPTA7aTxzdHIubGVuZ3RoO2krKykgew0KICAgICAgICAgICAgICAgaWYoaSAlIDIpIHsgDQogICAgICAgICAgICAgICAgICAvL29kZCA9IHRhYmxlIG9mIHR5cGUgZGlzcGxheWVxdWF0aW9uDQogICAgICAgICAgICAgICAgICB2YXIgREVRdGFibGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJ0YWJsZSIpOw0KICAgICAgICAgICAgICAgICAgREVRdGFibGUuY2xhc3NOYW1lPSdkaXNwbGF5ZXF1YXRpb24nOw0KICAgICAgICAgICAgICAgICAgdmFyIERFUXRib2R5ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidGJvZHkiKTsNCiAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgIHZhciBERVF0ciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInRyIik7DQogICAgICAgICAgICAgICAgICB2YXIgREVRdGRlcSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInRkIik7DQogICAgICAgICAgICAgICAgICAgICAgREVRdGRlcS5jbGFzc05hbWU9J2VxJzsNCiAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgIC8vIEFmdGVyRml4IHRvIHJlcGFpciBmb3IgJCQuLi4kJCAgIA0KICAgICAgICAgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1wkXH1cJC9nLCIkXFxkaXNwbGF5c3R5bGV7Iik7DQogICAgICAgICAgICAgICAgICBzdHJbaV0gPSBzdHJbaV0ucmVwbGFjZSgvXCRce1wkL2csIn0iKTsNCgkJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgLy9jaGVjayBmb3IgZXF1YXRpb24gbnVtYmVyIHZpYSBlaXRoZXIgbGFiZWwgb3IgZXFubyBhdCBiZWdpbm5pbmcgLS0gXG5vbnVtYmVyIGlzIHJlbW92ZWQNCiAgICAgICAgICAgICAgICAgIHZhciBsYmwgPSBzdHJbaV0ubWF0Y2goL1xcbGFiZWxccypce1xzKihcdyspXHMqXH0vKTsNCiAgICAgICAgICAgICAgICAgIHZhciBJU2Vxbm8gPSBzdHJbaV0ubWF0Y2goL15lcW5vLyk7DQogICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAvLyBhcHBlbmQgbm9kZXMgaW50byByb3cgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL15lcW5vLywiICIpOw0KICAgICAgICAgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1xcbGFiZWxccypce1xzKlx3K1xzKlx9LywiICIpOw0KICAgICAgICAgICAgICAgICAgREVRdGRlcS5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSggc3RyW2ldICkgKTsNCiAgICAgICAgICAgICAgICAgIERFUXRyLmFwcGVuZENoaWxkKERFUXRkZXEpOw0KDQogICAgICAgICAgICAgICAgICBzdHJbaV0gPSBzdHJbaV0ucmVwbGFjZSgvXFxub251bWJlci9nLCIiKTsNCiAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgaWYoSVNlcW5vIT1udWxsIHx8IGxibCAhPW51bGwpIHsNCiAgICAgICAgICAgICAgICAgICAgIHZhciBERVF0ZG5vID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidGQiKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICBERVF0ZG5vLmNsYXNzTmFtZT0nZXFubyc7DQogICAgICAgICAgICAgICAgICAgICBMYVRlWENvdW50ZXJbImVxdWF0aW9uIl0rKzsNCgkJICAgICAgICAgICAgIHZhciBlcW5vU3RyaW5nID0gbWFrZU51bWJlclN0cmluZyhMYVRlWENvdW50ZXJbImVxdWF0aW9uIl0pOw0KICAgICAgICAgICAgICAgICAgICAgDQoJCSAgICAgICAgICAgICB2YXIgREVRYW5jaG9yID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpOw0KCQkgICAgICAgICAgICAgaWYobGJsIT1udWxsKSB7IERFUWFuY2hvci5pZCA9IGxibFsxXSB9Ow0KCQkgICAgICAgICAgICAgREVRYW5jaG9yLmNsYXNzTmFtZSA9ICJlcW5vIjsNCgkJICAgICAgICAgICAgIHZhciBhbmNob3JTcGFuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3BhbiIpOw0KCQkgICAgICAgICAgICAgYW5jaG9yU3Bhbi5jbGFzc05hbWUgPSAiZXFubyI7DQoJCSAgICAgICAgICAgICBhbmNob3JTcGFuLnN0eWxlLmRpc3BsYXkgPSAibm9uZSI7DQoJCSAgICAgICAgICAgICBhbmNob3JTcGFuLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGVxbm9TdHJpbmcpKTsNCgkJICAgICAgICAgICAgIERFUWFuY2hvci5hcHBlbmRDaGlsZChhbmNob3JTcGFuKTsNCiAgICAgICAgICAgICAgICAgICAgIERFUXRkbm8uYXBwZW5kQ2hpbGQoREVRYW5jaG9yKTsNCgkJICAgICAgICAgICAgIHZhciBERVFzcGFuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3BhbiIpOyANCgkJICAgICAgICAgICAgIERFUXNwYW4uY2xhc3NOYW1lID0gImVxbm8iOyANCgkJICAgICAgICAgICAgIERFUXNwYW4uYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoIigiK2Vxbm9TdHJpbmcrIikiICkpOyANCiAgICAgICAgICAgICAgICAgICAgIERFUXRkbm8uYXBwZW5kQ2hpbGQoREVRc3Bhbik7IA0KICAgICAgICAgICAgICAgICAgICAgREVRdHIuYXBwZW5kQ2hpbGQoREVRdGRubyk7DQogICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICBERVF0Ym9keS5hcHBlbmRDaGlsZChERVF0cik7DQoJCSAgICAgICAgICBERVF0YWJsZS5hcHBlbmRDaGlsZChERVF0Ym9keSk7DQogICAgICAgICAgICAgICAgICBuZXdGcmFnLmFwcGVuZENoaWxkKERFUXRhYmxlKTsNCiAgICAgICAgICAgICAgIH0gDQogICAgICAgICAgICAgICBlbHNlIHsgDQogICAgICAgICAgICAgICAgICAvL2V2ZW4gPSB0aGlzIGlzIHRleHQsIHdoZXJlIHdlIG1heSBoYXZlIHNlY3Rpb25zLCBsYWJlbHMsIHN1YnNlY3Rpb25zLCBhbmQgc28gb24gDQogDQogICAgICAgICAgICAgICAgICAvLyBBZnRlckZpeCB0byByZXBhaXIgZm9yICQkLi4uJCQgICANCiAgICAgICAgICAgICAgICAgIHN0cltpXSA9IHN0cltpXS5yZXBsYWNlKC9cJFx9XCQvZywiIik7DQogICAgICAgICAgICAgICAgICBzdHJbaV0gPSBzdHJbaV0ucmVwbGFjZSgvXCRce1wkL2csIiIpOw0KCQkJICANCgkJICAgICAgICAgIC8vU29tZSBzdHVmZiB3ZSBqdXN0IHdhbnQgdG8gcmVtb3ZlDQogICAgICAgICAgICAgICAgICBzdHJbaV0gPSBzdHJbaV0ucmVwbGFjZSgvXFxtYWtldGl0bGUvZywiIik7DQogICAgICAgICAgICAgICAgICBzdHJbaV0gPSBzdHJbaV0ucmVwbGFjZSgvXFxiZWdpblxzKlx7XHMqZG9jdW1lbnRccypcfS9nLCIiKTsNCiAgICAgICAJICAgIAkgIHN0cltpXSA9IHN0cltpXS5yZXBsYWNlKC9cXGVuZFxzKlx7XHMqZG9jdW1lbnRccypcfS9nLCIiKTsNCiAgICAgICAJICAgIAkgIHN0cltpXSA9IHN0cltpXS5yZXBsYWNlKC9cXGRvY3VtZW50Y2xhc3NbXlx9XSo/XH0vZywiIik7DQoJCSAgICAgICAgICBzdHJbaV0gPSBzdHJbaV0ucmVwbGFjZSgvXFx1c2VwYWNrYWdlW15cfV0qP1x9L2csIiIpOyAvL2lnbm9yZXMgcGFja2FnZXMgYW5kIHRoZWlyIG9wdGlvbnMNCgkJICAgICAgICAgIHN0cltpXSA9IHN0cltpXS5yZXBsYWNlKC9cXG5vaW5kZW50L2csIiIpOw0KCQkgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1xcbm90YWcvZywiIik7DQogICAgICAgICAgICAgICAgICAgICAgICAgIAkJIA0KICAgICAgICAgICAgICAgICAgLy9OZXh0OiBsYWJlbHMsIHJlZidzLCBocmVmcywgdXJscywgYW5kIGNpdGVzDQogICAgICAgICAgICAgICAgICBzdHJbaV0gPSBzdHJbaV0ucmVwbGFjZSgvXFxyZWZccypce1xzKihcdyspXH0vZywiIFxcW3JlZlxcXSQxXFxbICIpOw0KCQkgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UgKC9cXHVybFxzKlx7XHMqKFteXH1cbl0rKVx9L2csIiBcXFt1cmxcXF0kMVxcWyAiKTsNCiAgICAgICAgICAgICAgICAgIHN0cltpXSA9IHN0cltpXS5yZXBsYWNlKC9cXGhyZWZccypce1xzKihbXlx9XSspXH1ccypce1xzKihbXlx9XSspXH0vZywiIFxcW2hyZWZcXF0kMVxcXSQyXFxbICIpOw0KICAgICAgICAgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1xcY2l0ZVxzKlx7XHMqKFx3KylcfS9nLCIgXFxbY2l0ZVxcXSQxXFxbICIpOw0KCQkgIA0KCQkgICAgICAgICAgLy9NaXNjZWxsYW5lb3VzIHN0dWZmISENCgkJICAgICAgICAgIHN0cltpXSA9IHN0cltpXS5yZXBsYWNlKC9cXHFlZC9nLCJcdTIyMEUiKTsNCgkJICAgICAgICAgIHN0cltpXSA9IHN0cltpXS5yZXBsYWNlKC9cXGVuZHByb29mL2csIlx1MjIwRSIpOw0KCQkgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1xccHJvb2YvZywiXFx0ZXh0YmZ7UHJvb2Y6IH0iKTsNCg0KCQkgICAgICAgICAgLy9icmVha3MgYW5kIHNraXBzDQoJICAgICAgICAgICAgICBzdHJbaV0gPSBzdHJbaV0ucmVwbGFjZSgvXFxuKD89XHMpL2csICIgXFxbYnJcXF0gXFxbICIpOw0KCQkgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1xcbmV3bGluZS9nLCIgXFxbYnJcXF0gXFxbICIpOw0KCQkgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1xcbGluZWJyZWFrL2csIiBcXFticlxcXSBcXFsgIik7DQogICAgICAgICAgICAgICAJICBzdHJbaV0gPSBzdHJbaV0ucmVwbGFjZSgvXFxzbWFsbHNraXAvZywiIFxcW2xvZ2ljYWxicmVha1xcXXNtYWxsc2tpcFxcWyAiKTsgDQoJICAgICAgICAgICAgICBzdHJbaV0gPSBzdHJbaV0ucmVwbGFjZSgvXFxtZWRza2lwL2csIiBcXFtsb2dpY2FsYnJlYWtcXF1tZWRza2lwXFxbICIpOw0KCSAgICAgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1xcYmlnc2tpcC9nLCIgXFxbbG9naWNhbGJyZWFrXFxdYmlnc2tpcFxcWyAiKTsNCgkJICAgICAgICAgIHN0cltpXSA9IHN0cltpXS5yZXBsYWNlKC9bXG5ccl0rWyBcZlxuXHJcdFx2XHUyMDI4XHUyMDI5XSpbXG5ccl0rL2csIiBcXFtsb2dpY2FsYnJlYWtcXF1MYVRlWE1hdGhNTFxcWyAiKTsgIC8vIGV4dHJhIHJldHVybiByZXBsYWNlZCBieSA8cD4NCgkJICAgICAgICAgIGlmKGlzSUUpIHsNCgkJICAgICAgICAgICAgIHN0cltpXSA9IHN0cltpXS5yZXBsYWNlKC9cci9nLCIgIik7ICAvLyByZXBsYWNlIFxyIGJ5IGEgc3BhY2UgdG8gYWlkIHNwYWNpbmchDQoJCSAgICAgICAgICB9DQoNCgkJICANCgkJICAgICAgICAgIC8vaXRlbXMgYW5kIGFwcGVuZGl4DQoJCSAgICAgICAgICBzdHJbaV0gPSBzdHJbaV0ucmVwbGFjZSgvXFxiaWJpdGVtXHMqKFteXHtdKlx7XHMqXHcqXHMqXH0pL2csIiBcXFtiaWJpdGVtXFxdJDFcXFsgIik7DQogICAgICAgICAgICAgICAgICBzdHJbaV0gPSBzdHJbaV0ucmVwbGFjZSgvXFxiaWJpdGVtXHMqL2csIiBcXFtiaWJpdGVtXFxdIFxcWyAiKTsNCgkJICAgICAgICAgIHN0cltpXSA9IHN0cltpXS5yZXBsYWNlKC9cXGl0ZW1ccypcW1xzKihcdyspXHMqXF0vZywiIFxcW2FsaXN0aXRlbVxcXSQxXFxbICIpOw0KCQkgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1xcaXRlbVxzKi9nLCIgXFxbYWxpc3RpdGVtXFxdIFxcWyAiKTsNCiAgCQkgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1xcYXBwZW5kaXgvZywiIFxcW2FwcGVuZGl4XFxdIFxcWyAiKTsNCg0KDQogICAgICAgICAgICAgICAgICAvLyBcaW5jbHVkZWdyYXBoaWNzW11bXXtpbWFnZX0gLS0gbm8gcHJvY2Vzc2luZyBvZiBvcHRpb25zLiAgVGhpcyB0cmVhdG1lbnQgaXMgREFOR0VST1VTLiAgSXQgYXNzdW1lcyBubyBodG1sIHdpbGwgYmUNCgkJICAgICAgICAgIC8vIHBsYWNlZCB3aXRoaW4gdGhlIFxiZWdpbntmaWd1cmV9IC4uLiBcZW5ke2ZpZ3VyZX0gc3RydWN0dXJlLCBhbmQgdGhlIFtcc1xTXSBjaGFyYWN0ZXIgY2xhc3MgY291bGQgbGVhZCB0byBzdHJhbmdlIG1hdGNoZXMNCgkgICAgICAgICAgICAgIHN0cltpXSA9IHN0cltpXS5yZXBsYWNlKC9cXGJlZ2luXHMqXHtccypmaWd1cmVccypcfShbXHNcU10rPylcXGVuZFxzKlx7XHMqZmlndXJlXHMqXH0vZywiIFxcW2ZpZ3VyZVxcXSQxXFxbICIpOw0KICAgICAgICAgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1xcYmVnaW5ccypce1xzKnRhYmxlXHMqXH0oW1xzXFNdKz8pXFxlbmRccypce1xzKnRhYmxlXHMqXH0vZywiIFxcW3RhYmxlXFxdJDFcXFsgIik7DQoJCSAgICAgICAgICAvL3N0cltpXSA9IHN0cltpXS5yZXBsYWNlKC9cXGJlZ2luXHMqXHtccyphcnJheVxzKlx9KFtcc1xTXSs/KVxcZW5kXHMqXHtccyphcnJheVxzKlx9L2csIiBcXFthcnJheVxcXSQxXFxbICIpOw0KICAgICAgICAgICAgICAgICAgLy9nb2FsIGlzIHRvIHByb3RlY3QgYXJyYXkgXFwgZnJvbSBiZWluZyBjb252ZXJ0ZWQgaW50byBsaW5lYnJlYWtzDQogICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgIC8vVGhpcyBjb25zdHJ1Y3Rpb24gYWxsb3dzIGNzcyBjbGFzc2VzIGZvciBkaXZzIGZvciB0aGVzZSBlbGVtZW50cywgYnV0IHRoZSBDU1Mgd2lsbCBoYXZlIHRvIGJlIHN1cHBsaWVkIHRocm91Z2ggYSANCiAgICAgICAgICAgICAgICAgIC8vY3NzIGZpbGUgb3IgPHNjcmlwdD4gLi4gPC9zY3JpcHQ+IGluIHRoZSBoZWFkZXIuICAoSXQgbWFrZXMgc2Vuc2UgdG8gbWUgdGhhdCBzdHlsZSBmaWxlcyBpbiBMYVRlWCBzaG91bGQgY29ycmVzcG9uZA0KICAgICAgICAgICAgICAgICAgLy90byBjc3MgYW5kL29yIHhzbHQgd2hlbiB0cmFuc2xhdGluZyB0byBtYXRobWwsIGJ1dCBccmVmJ3MgYXJlIGEgcHJvYmxlbSkuDQogICAgICAgICAgICAgICAgICBzdHJbaV0gPSBzdHJbaV0ucmVwbGFjZSgvXFxiZWdpblxzKlx7XHMqdGhlb3JlbVxzKlx9L2csIiBcXFt0aGVvcmVtXFxdVGhlb3JlbSBcXFsgIik7IA0KICAgICAgICAgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1xcZW5kXHMqXHtccyp0aGVvcmVtXHMqXH0vZywiIFxcW2VuZHRoZW9yZW1cXF0gXFxbICIpOw0KDQogICAgICAgICAgICAgICAgICBzdHJbaV0gPSBzdHJbaV0ucmVwbGFjZSgvXFxiZWdpblxzKlx7XHMqZGVmaW5pdGlvblxzKlx9L2csIiBcXFtkZWZpbml0aW9uXFxdRGVmaW5pdGlvbiBcXFsgIik7IA0KICAgICAgICAgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1xcZW5kXHMqXHtccypkZWZpbml0aW9uXHMqXH0vZywiIFxcW2VuZGRlZmluaXRpb25cXF0gXFxbICIpOw0KICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgIHN0cltpXSA9IHN0cltpXS5yZXBsYWNlKC9cXGJlZ2luXHMqXHtccypsZW1tYVxzKlx9L2csIiBcXFtsZW1tYVxcXUxlbW1hIFxcWyAiKTsgDQogICAgICAgICAgICAgICAgICBzdHJbaV0gPSBzdHJbaV0ucmVwbGFjZSgvXFxlbmRccypce1xzKmxlbW1hXHMqXH0vZywiIFxcW2VuZGxlbW1hXFxdIFxcWyAiKTsNCg0KICAgICAgICAgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1xcYmVnaW5ccypce1xzKmNvcm9sbGFyeVxzKlx9L2csIiBcXFtjb3JvbGxhcnlcXF1Db3JvbGxhcnkgXFxbICIpOyANCiAgICAgICAgICAgICAgICAgIHN0cltpXSA9IHN0cltpXS5yZXBsYWNlKC9cXGVuZFxzKlx7XHMqY29yb2xsYXJ5XHMqXH0vZywiIFxcW2VuZGNvcm9sbGFyeVxcXSBcXFsgIik7DQogICAgICAgICAgDQogICAgICAgICAgICAgICAgICBzdHJbaV0gPSBzdHJbaV0ucmVwbGFjZSgvXFxiZWdpblxzKlx7XHMqcHJvcG9zaXRpb25ccypcfS9nLCIgXFxbcHJvcG9zaXRpb25cXF1Qcm9wb3NpdGlvbiBcXFsgIik7IA0KICAgICAgICAgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1xcZW5kXHMqXHtccypwcm9wb3NpdGlvblxzKlx9L2csIiBcXFtlbmRwcm9wb3NpdGlvblxcXSBcXFsgIik7DQoNCiAgICAgICAgICAgICAgICAgIHN0cltpXSA9IHN0cltpXS5yZXBsYWNlKC9cXGJlZ2luXHMqXHtccypleGFtcGxlXHMqXH0vZywiIFxcW2V4YW1wbGVcXF1FeGFtcGxlIFxcWyAiKTsgDQogICAgICAgICAgICAgICAgICBzdHJbaV0gPSBzdHJbaV0ucmVwbGFjZSgvXFxlbmRccypce1xzKmV4YW1wbGVccypcfS9nLCIgXFxbZW5kZXhhbXBsZVxcXSBcXFsgIik7DQoJICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgIHN0cltpXSA9IHN0cltpXS5yZXBsYWNlKC9cXGJlZ2luXHMqXHtccypleGVyY2lzZVxzKlx9L2csIiBcXFtleGVyY2lzZVxcXUV4ZXJjaXNlIFxcWyAiKTsgDQogICAgICAgICAgICAgICAgICBzdHJbaV0gPSBzdHJbaV0ucmVwbGFjZSgvXFxlbmRccypce1xzKmV4ZXJjaXNlXHMqXH0vZywiIFxcW2VuZGV4ZXJjaXNlXFxdIFxcWyAiKTsNCg0KICAgICAgICAgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1xcYmVnaW5ccypce1xzKnRoZWJpYmxpb2dyYXBoeVxzKlx9XHMqXHtccypcdytccypcfS9nLCIgXFxbdGhlYmlibGlvZ3JhcGh5XFxdUmVmZXJlbmNlcyBcXFsgIik7IA0KICAgICAgICAgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1xcYmVnaW5ccypce1xzKnRoZWJpYmxpb2dyYXBoeVxzKlx9L2csIiBcXFt0aGViaWJsaW9ncmFwaHlcXF1SZWZlcmVuY2VzIFxcWyAiKTsgDQogICAgICAgICAgICAgICAgICBzdHJbaV0gPSBzdHJbaV0ucmVwbGFjZSgvXFxlbmRccypce1xzKnRoZWJpYmxpb2dyYXBoeVxzKlx9L2csIiBcXFtlbmR0aGViaWJsaW9ncmFwaHlcXF1SZWZlcmVuY2VzIFxcWyAiKTsNCgkJICANCg0KICAgICAgICAgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1xcYmVnaW5ccypce1xzKnByb29mXHMqXH0vZywiIFxcW3Byb29mXFxdUHJvb2Y6IFxcWyAiKTsgDQogICAgICAgICAgICAgICAgICBpZihpc0lFKSB7ICAvL0lFIGlzIGp1c3Qgc28gd2VpcmQNCiAgICAgICAgICAgICAgICAgICAgIHN0cltpXSA9IHN0cltpXS5yZXBsYWNlKC9cXGVuZFxzKlx7XHMqcHJvb2ZccypcfS9nLCJcdTIyMEUgXFxbZW5kcHJvb2ZcXF0gXFxbICIpOw0KICAgICAgICAgICAgICAgICAgfSBlbHNlIHsgDQogICAgICAgICAgICAgICAgICAgICBzdHJbaV0gPSBzdHJbaV0ucmVwbGFjZSgvXFxlbmRccypce1xzKnByb29mXHMqXH0vZywiIFxcW2VuZHByb29mXFxdIFxcWyAiKTsNCiAgICAgICAgICAgICAgICAgIH0NCgkJICANCiAgICAgICAgICAgICAgICAgIC8vVGhlIGZyb250bWF0dGVyIC0tIGFsbCB0cmFuc2xhdGVkIHRvIGRpdidzIHRvIGJlIGhhbmRsZWQgYnkgQ1NTDQogICAgICAgICAgICAgICAgICBzdHJbaV0gPSBzdHJbaV0ucmVwbGFjZSgvXFx0aXRsZVxzKlx7XHMqKFteXH1dKylcfS9nLCIgXFxbdGl0bGVcXF0gXFxbJDEgXFxbZW5kdGl0bGVcXF0gXFxbICIpOw0KICAgICAgICAgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1xcYXV0aG9yXHMqXHtccyooW15cfV0rKVx9L2csIiBcXFthdXRob3JcXF0gXFxbJDEgXFxbZW5kYXV0aG9yXFxdIFxcWyAiKTsNCiAgICAgICAgICAgICAgICAgIHN0cltpXSA9IHN0cltpXS5yZXBsYWNlKC9cXGFkZHJlc3Nccypce1xzKihbXlx9XSspXH0vZywiIFxcW2FkZHJlc3NcXF0gXFxbJDEgXFxbZW5kYWRkcmVzc1xcXSBcXFsgIik7DQogICAgICAgICAgICAgICAgICBzdHJbaV0gPSBzdHJbaV0ucmVwbGFjZSgvXFxkYXRlXHMqXHtccyooW15cfV0rKVx9L2csIiBcXFtkYXRlXFxdIFxcWyQxIFxcW2VuZGRhdGVcXF0gXFxbICIpOw0KICAgICAgICAgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1xcYmVnaW5ccypce1xzKmtleXdvcmRccypcfS9nLCIgXFxba2V5d29yZFxcXSBcXFsgIik7IA0KICAgICAgICAgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1xcZW5kXHMqXHtccyprZXl3b3JkXHMqXH0vZywiIFxcW2VuZGtleXdvcmRcXF0gXFxbICIpOw0KICAgICAgICAgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1xcYmVnaW5ccypce1xzKmFic3RyYWN0XHMqXH0vZywiIFxcW2Fic3RyYWN0XFxdIFxcWyAiKTsgDQoJICAgICAgICAgICAgICBzdHJbaV0gPSBzdHJbaV0ucmVwbGFjZSgvXFxlbmRccypce1xzKmFic3RyYWN0XHMqXH0vZywiIFxcW2VuZGFic3RyYWN0XFxdIFxcWyAiKTsNCgkJICANCiAgICAgICAgICAgICAgICAgIC8vVGhlIHJlc3Qgb2YgdGhlIGVudmlyb25tZW50cyAtLSBVc2VycyBjYW4gZXZlbiAibWFrZSB1cCB0aGVpciBvd24iIC0tIGJ1dCBpdCBhdm9pZHMgdGhlIGFycmF5IGFuZCB0YWJ1bGFyIGVudmlyb25tZW50cw0KICAgICAgICAgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1xcYmVnaW5ccypce1xzKig/IWFycmF5fHRhYnVsYXIpKFx3KylccypcfS9nLCIgXFxbJDFcXF0gXFxbICIpOw0KICAgICAgICAgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1xcZW5kXHMqXHtccyooPyFhcnJheXx0YWJ1bGFyKShcdyspXHMqXH0vZywiIFxcW2VuZCQxXFxdIFxcWyAiKTsNCg0KICAgICAgICAgICAgICAgICAgLy9OZXh0LCB3ZSBsb29rIGF0IHNlY3Rpb24tLXN1YnNlY3Rpb24gc3R1ZmYuICBUaGlzIGlzIG5lc3RlZCAtLSB0aGlzIHdvdWxkIGJlIHNvIG11Y2ggYmV0dGVyIGlmIExhVGVYIHVzZWQgDQogICAgICAgICAgICAgICAgICAvL3NvbWUgdHlwZSBvZiBcYmVnaW57c2VjdGlvbmhlYWR9Li4uXGVuZHtzZWN0aW9uaGVhZH0gc3RydWN0dXJlDQogICAgICAgICAgICAgICAgICB2YXIgc2VjdGlvbkluZGV4ID0gc3RyW2ldLnNlYXJjaCgvXFxzZWN0aW9uXHMqXHtccypbXHNcU10rXH0vKTsgDQoJCSAgDQogICAgICAgICAgICAgICAgICB3aGlsZShzZWN0aW9uSW5kZXggPj0gMCkgeyANCiAgICAgICAgICAgICAgICAgICAgIHN0cltpXSA9IHN0cltpXS5yZXBsYWNlKC9cXHNlY3Rpb25ccypcey8gLCIgXFxbc2VjdGlvblxcXSIpOw0KICAgICAgICAgICAgICAgICAgICAgdmFyIGRlbGltY250ID0gMTsNCiAgICAgICAgICAgICAgICAgICAgIGZvcih2YXIgaWk9c2VjdGlvbkluZGV4O2lpPHN0cltpXS5sZW5ndGg7aWkrKykgeyANCiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHN0cltpXS5jaGFyQXQoaWkpID09ICJ7IikgeyBkZWxpbWNudCsrIH07DQogICAgICAgICAgICAgICAgICAgICAgICBpZihzdHJbaV0uY2hhckF0KGlpKSA9PSAifSIpIHsgZGVsaW1jbnQtLSB9Ow0KICAgICAgICAgICAgICAgICAgICAgICAgaWYoZGVsaW1jbnQgPT0gMCkgeyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cltpXSA9IHN0cltpXS5zdWJzdHJpbmcoMCxpaSkrIlxcWyAiK3N0cltpXS5zdWJzdHJpbmcoaWkrMSxzdHJbaV0ubGVuZ3RoKSA7DQogICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgIH07DQogICAgICAgICAgICAgICAgICAgICBzZWN0aW9uSW5kZXggPSBzdHJbaV0uc2VhcmNoKC9cXHNlY3Rpb25ccypce1xzKltcc1xTXStcfS8pOyAvL2xvb2sgZm9yIG5leHQNCiAgICAgICAgICAgICAgICAgIH0NCgkJICANCgkgICAgICAgICAgICAgIHNlY3Rpb25JbmRleCA9IHN0cltpXS5zZWFyY2goL1xcc3Vic2VjdGlvblxzKlx7XHMqW1xzXFNdK1x9Lyk7IA0KCQkgIA0KICAgICAgICAgICAgICAgICAgd2hpbGUoc2VjdGlvbkluZGV4ID49IDApIHsgDQogICAgICAgICAgICAgICAgICAgICBzdHJbaV0gPSBzdHJbaV0ucmVwbGFjZSgvXFxzdWJzZWN0aW9uXHMqXHsvICwiIFxcW3N1YnNlY3Rpb25cXF0iKTsNCiAgICAgICAgICAgICAgICAgICAgIHZhciBkZWxpbWNudCA9IDE7DQogICAgICAgICAgICAgICAgICAgICBmb3IodmFyIGlpPXNlY3Rpb25JbmRleDtpaTxzdHJbaV0ubGVuZ3RoO2lpKyspIHsgDQogICAgICAgICAgICAgICAgICAgICAgICBpZihzdHJbaV0uY2hhckF0KGlpKSA9PSAieyIpIHsgZGVsaW1jbnQrKyB9Ow0KICAgICAgICAgICAgICAgICAgICAgICAgaWYoc3RyW2ldLmNoYXJBdChpaSkgPT0gIn0iKSB7IGRlbGltY250LS0gfTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmKGRlbGltY250ID09IDApIHsgDQogICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJbaV0gPSBzdHJbaV0uc3Vic3RyaW5nKDAsaWkpKyJcXFsgIitzdHJbaV0uc3Vic3RyaW5nKGlpKzEsc3RyW2ldLmxlbmd0aCkgOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICB9Ow0KICAgICAgICAgICAgICAgICAgICAgc2VjdGlvbkluZGV4ID0gc3RyW2ldLnNlYXJjaCgvXFxzdWJzZWN0aW9uXHMqXHtccypbXHNcU10rXH0vKTsgLy9sb29rIGZvciBuZXh0DQogICAgICAgICAgICAgICAgICB9DQoJDQogICAgICAgICAgICAgICAgICBzZWN0aW9uSW5kZXggPSBzdHJbaV0uc2VhcmNoKC9cXHN1YnN1YnNlY3Rpb25ccypce1xzKltcc1xTXStcfS8pOyANCgkJICANCiAgICAgICAgICAgICAgICAgIHdoaWxlKHNlY3Rpb25JbmRleCA+PSAwKSB7IA0KICAgICAgICAgICAgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnJlcGxhY2UoL1xcc3Vic3Vic2VjdGlvblxzKlx7LyAsIiBcXFtzdWJzdWJzZWN0aW9uXFxdIik7DQogICAgICAgICAgICAgICAgICAgICB2YXIgZGVsaW1jbnQgPSAxOw0KICAgICAgICAgICAgICAgICAgICAgZm9yKHZhciBpaT1zZWN0aW9uSW5kZXg7aWk8c3RyW2ldLmxlbmd0aDtpaSsrKSB7IA0KICAgICAgICAgICAgICAgICAgICAgICAgaWYoc3RyW2ldLmNoYXJBdChpaSkgPT0gInsiKSB7IGRlbGltY250KysgfTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHN0cltpXS5jaGFyQXQoaWkpID09ICJ9IikgeyBkZWxpbWNudC0tIH07DQogICAgICAgICAgICAgICAgICAgICAgICBpZihkZWxpbWNudCA9PSAwKSB7IA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyW2ldID0gc3RyW2ldLnN1YnN0cmluZygwLGlpKSsiXFxbICIrc3RyW2ldLnN1YnN0cmluZyhpaSsxLHN0cltpXS5sZW5ndGgpIDsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgfTsNCiAgICAgICAgICAgICAgICAgICAgIHNlY3Rpb25JbmRleCA9IHN0cltpXS5zZWFyY2goL1xcc3Vic3Vic2VjdGlvblxzKlx7XHMqW1xzXFNdK1x9Lyk7IC8vbG9vayBmb3IgbmV4dA0KICAgICAgICAgICAgICAgICAgIH0JCSAgDQoNCiAgICAgICAgICAgICAgICAgIHZhciBDYXRUb05leHRFdmVuID0gIiI7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAvL3NwbGl0IGludG8gYWx0ZXJuYXRpbmcgdGV4dCBlbGVtZW50cyBhbmQgIm1hcmtlZCIgZWxlbWVudHMgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICB2YXIgc3RydG1wID0gc3RyW2ldLnNwbGl0KCJcXFsiKTsNCiAgICAgICAgICAgICAgICAgIC8vZG9jdW1lbnQud3JpdGUoc3RydG1wWzBdKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICBmb3IodmFyIGo9MDtqPHN0cnRtcC5sZW5ndGg7aisrKSB7DQogICAgICAgICAgICAgICAgICAgICBpZihqICUgMikgeyANCiAgICAgICAgICAgICAgICAgICAgICAgIC8vb2RkID0gc3BsaXQgb24gXFxdDQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RydG1wYXJyYXkgPSBzdHJ0bXBbal0uc3BsaXQoIlxcXSIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChzdHJ0bXBhcnJheVswXSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAic2VjdGlvbiI6DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZVRtcCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIkgyIik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlVG1wLmNsYXNzTmFtZSA9ICdzZWN0aW9uJzsgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3Jlc2V0IGNvdW50ZXJzICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VjdGlvbkNudHIrKzsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgZGl2IGluIExhVGVYQ291bnRlcikgeyBMYVRlWENvdW50ZXJbZGl2XSA9IDAgfTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vQ3JlYXRlIFRpdGxlIG9mIHNlY3Rpb24NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlQW5jaG9yID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoaW5BcHBlbmRpeCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZUFuY2hvci5jbGFzc05hbWU9J2FwcGVuZGl4c2VjdGlvbic7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZUFuY2hvci5jbGFzc05hbWU9J3NlY3Rpb24nOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGVOdW1TdHJpbmcgPSBtYWtlTnVtYmVyU3RyaW5nKCIiKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhbmNob3JTcGFuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3BhbiIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jaG9yU3Bhbi5jbGFzc05hbWUgPSAic2VjdGlvbiI7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmNob3JTcGFuLnN0eWxlLmRpc3BsYXkgPSAibm9uZSI7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmNob3JTcGFuLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKG5vZGVOdW1TdHJpbmcpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVBbmNob3IuYXBwZW5kQ2hpbGQoYW5jaG9yU3Bhbik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlVG1wLmFwcGVuZENoaWxkKG5vZGVBbmNob3IpOw0KCQkJICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZVNwYW4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJzcGFuIik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlU3Bhbi5jbGFzc05hbWUgPSAnc2VjdGlvbic7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlU3Bhbi5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShub2RlTnVtU3RyaW5nKyIgIikpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVRtcC5hcHBlbmRDaGlsZChub2RlU3Bhbik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlVG1wLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCBzdHJ0bXBhcnJheVsxXSApICk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdGcmFnLmFwcGVuZENoaWxkKG5vZGVUbXApOyAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgInN1YnNlY3Rpb24iOg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGVUbXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJIMyIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVRtcC5jbGFzc05hbWUgPSAnc3Vic2VjdGlvbic7IA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9jb3VudGVycyAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExhVGVYQ291bnRlclsic3Vic2VjdGlvbiJdKys7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExhVGVYQ291bnRlclsic3Vic3Vic2VjdGlvbiJdPTA7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vQ3JlYXRlIFRpdGxlIG9mIHNlY3Rpb24NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlQW5jaG9yID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZUFuY2hvci5jbGFzc05hbWUgPSAnc3Vic2VjdGlvbic7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZU51bVN0cmluZyA9IG1ha2VOdW1iZXJTdHJpbmcoTGFUZVhDb3VudGVyWyJzdWJzZWN0aW9uIl0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFuY2hvclNwYW4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJzcGFuIik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmNob3JTcGFuLmNsYXNzTmFtZSA9ICJzdWJzZWN0aW9uIjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuY2hvclNwYW4uc3R5bGUuZGlzcGxheSA9ICJub25lIjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuY2hvclNwYW4uYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUobm9kZU51bVN0cmluZykpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZUFuY2hvci5hcHBlbmRDaGlsZChhbmNob3JTcGFuKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVUbXAuYXBwZW5kQ2hpbGQobm9kZUFuY2hvcik7CQkJICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZVNwYW4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJzcGFuIik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlU3Bhbi5jbGFzc05hbWUgPSAnc3Vic2VjdGlvbic7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlU3Bhbi5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShub2RlTnVtU3RyaW5nKyIuICIpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVUbXAuYXBwZW5kQ2hpbGQobm9kZVNwYW4pOwkJCSAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVRtcC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSggc3RydG1wYXJyYXlbMV0gKSApOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3RnJhZy5hcHBlbmRDaGlsZChub2RlVG1wKTsgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJzdWJzdWJzZWN0aW9uIjoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlVG1wID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiSDQiKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVUbXAuY2xhc3NOYW1lID0gJ3N1YnN1YnNlY3Rpb24nOyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2NvdW50ZXJzICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGFUZVhDb3VudGVyWyJzdWJzdWJzZWN0aW9uIl0rKzsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vQ3JlYXRlIFRpdGxlIG9mIHNlY3Rpb24NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlQW5jaG9yID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZUFuY2hvci5jbGFzc05hbWUgPSAnc3Vic3Vic2VjdGlvbic7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZU51bVN0cmluZyA9IG1ha2VOdW1iZXJTdHJpbmcoTGFUZVhDb3VudGVyWyJzdWJzZWN0aW9uIl0rIi4iK0xhVGVYQ291bnRlclsic3Vic3Vic2VjdGlvbiJdKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhbmNob3JTcGFuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3BhbiIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jaG9yU3Bhbi5jbGFzc05hbWUgPSAic3Vic3Vic2VjdGlvbiI7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmNob3JTcGFuLnN0eWxlLmRpc3BsYXkgPSAibm9uZSI7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmNob3JTcGFuLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKG5vZGVOdW1TdHJpbmcpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVBbmNob3IuYXBwZW5kQ2hpbGQoYW5jaG9yU3Bhbik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlVG1wLmFwcGVuZENoaWxkKG5vZGVBbmNob3IpOwkJCSAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGVTcGFuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3BhbiIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVNwYW4uY2xhc3NOYW1lID0gJ3N1YnN1YnNlY3Rpb24nOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVNwYW4uYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUobm9kZU51bVN0cmluZysiLiAiKSk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlVG1wLmFwcGVuZENoaWxkKG5vZGVTcGFuKTsJCQkgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVUbXAuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoIHN0cnRtcGFycmF5WzFdICkgKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0ZyYWcuYXBwZW5kQ2hpbGQobm9kZVRtcCk7ICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAiaHJlZiI6DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZVRtcCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImEiKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVUbXAuY2xhc3NOYW1lID0gJ0xhVGVYTWF0aE1MJzsgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlVG1wLmhyZWYgPSBzdHJ0bXBhcnJheVsxXTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVUbXAuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoIHN0cnRtcGFycmF5WzJdKSk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdGcmFnLmFwcGVuZENoaWxkKG5vZGVUbXApOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAidXJsIjoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlVG1wID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVRtcC5jbGFzc05hbWUgPSAnTGFUZVhNYXRoTUwnOyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVUbXAuaHJlZiA9IHN0cnRtcGFycmF5WzFdOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVRtcC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSggc3RydG1wYXJyYXlbMV0pKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0ZyYWcuYXBwZW5kQ2hpbGQobm9kZVRtcCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAiZmlndXJlIjoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlVG1wID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidGFibGUiKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVUbXAuY2xhc3NOYW1lID0gJ2ZpZ3VyZSc7IA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIEZJR3Rib2R5ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidGJvZHkiKTsNCiANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBGSUdsYmwgPSBzdHJ0bXBhcnJheVsxXS5tYXRjaCgvXFxsYWJlbFxzKlx7XHMqKFx3KylccypcfS8pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydG1wYXJyYXlbMV09c3RydG1wYXJyYXlbMV0ucmVwbGFjZSgvXFxsYWJlbFxzKlx7XHcrXH0vZywiIik7CQ0KCQkJICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2FwSW5kZXggPSBzdHJ0bXBhcnJheVsxXS5zZWFyY2goL1xcY2FwdGlvblxzKlx7W1xzXFNdK1x9Lyk7ICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBGSUdjYXAgPSAiIjsNCgkJCSAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoY2FwSW5kZXggPj0gMCkgeyAvLyBjYXB0aW9uIG1heSBjb250YWluIG90aGVyIHsgIH0gc3RydWN0dXJlcyAtLSBidXQgbm90IGRpc3BsYXltYXRoISENCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0bXAgPSBzdHJ0bXBhcnJheVsxXTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkZWxpbWNudCA9IDA7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAJIHZhciBjYXBzdGFydCA9IC0xOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yKHZhciBwb3M9Y2FwSW5kZXg7cG9zPHRtcC5sZW5ndGg7cG9zKyspIHsgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZih0bXAuY2hhckF0KHBvcykgPT0gInsiKSB7IGRlbGltY250KysgfTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRtcC5jaGFyQXQocG9zKSA9PSAifSIpIHsgZGVsaW1jbnQtLSB9Ow0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoZGVsaW1jbnQgPT0gMSAmJiBjYXBzdGFydDwwKSB7IGNhcHN0YXJ0ID0gcG9zKzEgfTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGRlbGltY250ID09IDAgJiYgY2Fwc3RhcnQ+MCkgeyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcGVuZCA9IHBvcy0xOyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJR2NhcCA9IHRtcC5zdWJzdHJpbmcoY2Fwc3RhcnQscG9zKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgRklHdHIyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidHIiKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBGSUd0ZDIgID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidGQiKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJR3RkMi5jbGFzc05hbWU9ImNhcHRpb24iOw0KICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgRklHYW5jaG9yID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklHYW5jaG9yLmNsYXNzTmFtZSA9ICJmaWd1cmUiOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoRklHbGJsIT1udWxsKSB7ICBGSUdhbmNob3IuaWQgPSBGSUdsYmxbMV07IH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExhVGVYQ291bnRlclsiZmlndXJlIl0rKzsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmaWdubWJyID0gbWFrZU51bWJlclN0cmluZyhMYVRlWENvdW50ZXJbImZpZ3VyZSJdKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhbmNob3JTcGFuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3BhbiIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jaG9yU3Bhbi5jbGFzc05hbWUgPSAiZmlndXJlIjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuY2hvclNwYW4uc3R5bGUuZGlzcGxheSA9ICJub25lIjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuY2hvclNwYW4uYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoZmlnbm1icikpOyAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSUdhbmNob3IuYXBwZW5kQ2hpbGQoYW5jaG9yU3Bhbik7IAkJCSAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSUd0ZDIuYXBwZW5kQ2hpbGQoRklHYW5jaG9yKTsNCgkJCSAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIEZJR3NwYW4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJzcGFuIik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSUdzcGFuLmNsYXNzTmFtZSA9ICJmaWd1cmUiOyAvL0ZvciBDU1MgY291bnRlcnMsIGNvbW1lbnQgdGhpcyBsaW5lDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSUdzcGFuLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCJGaWd1cmUgIitmaWdubWJyKyIuICIgKSApOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklHdGQyLmFwcGVuZENoaWxkKEZJR3NwYW4pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklHdGQyLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCIiK0ZJR2NhcCkpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklHdHIyLmFwcGVuZENoaWxkKEZJR3RkMik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSUd0Ym9keS5hcHBlbmRDaGlsZChGSUd0cjIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIElzU3BlY2lhbCA9IGZhbHNlOw0KCQkJICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgRklHaW5mbyA9IHN0cnRtcGFycmF5WzFdLm1hdGNoKC9cXGluY2x1ZGVncmFwaGljc1xzKlx7KFteXH1dKylcfS8pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoRklHaW5mbz09bnVsbCkgeyAvL29wdGlvbnMgbm90IHByb2Nlc3NlZCwgZm9yIG5vdw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklHaW5mbyA9IHN0cnRtcGFycmF5WzFdLm1hdGNoKC9cXGluY2x1ZGVncmFwaGljc1xzKlxbW15cXV0qXF1ccypce1xzKihbXlx9XSspXHMqXH0vKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKEZJR2luZm89PW51bGwpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJR2luZm8gPSBzdHJ0bXBhcnJheVsxXS5tYXRjaCgvXFxzcGVjaWFsXHMqXHtccyooW15cfV0rKVx9Lyk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJc1NwZWNpYWw9dHJ1ZSAvL0hvb2s6IExhdGVyIGNhbiBpbmNsdWRlICJzcGVjaWFsIiBncmFwaGljcyBjb21tYW5kcw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTsNCiAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKEZJR2luZm8hPW51bGwpIHsgLy9DYXB0aW9uIHdpbGwgYmUgYWJvdmUgdGhlIGltYWdlDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgRklHdHIxID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidHIiKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBGSUd0ZDEgID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidGQiKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJR3RkMS5jbGFzc05hbWU9ImltYWdlIjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBGSUdpbWcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJpbWciKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBGSUdzcmMgPSBGSUdpbmZvWzFdOyAvL29wdGlvbnMgbm90IHByb2Nlc3NlZCwgZm9yIG5vdw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklHaW1nLnNyYyA9IEZJR3NyYzsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJR2ltZy5hbHQgPSAiRmlndXJlICIrRklHc3JjKyIgZGlkIG5vdCBsb2FkIjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJR2ltZy50aXRsZSA9ICJGaWd1cmUgIitmaWdubWJyKyIuICIrRklHY2FwOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklHaW1nLmlkID0gImZpZ3VyZSIrZmlnbm1icjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJR3RkMS5hcHBlbmRDaGlsZChGSUdpbWcpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklHdHIxLmFwcGVuZENoaWxkKEZJR3RkMSk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSUd0Ym9keS5hcHBlbmRDaGlsZChGSUd0cjEpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVRtcC5hcHBlbmRDaGlsZChGSUd0Ym9keSk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdGcmFnLmFwcGVuZENoaWxkKG5vZGVUbXApOyAJCSAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJ0YWJsZSI6IA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGVUbXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJ0YWJsZSIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoc3RydG1wYXJyYXlbMV0uc2VhcmNoKC9cXGNlbnRlcmluZy8pID49IDApIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVUbXAuY2xhc3NOYW1lID0gJ0xhVGVYdGFibGUgY2VudGVyZWQnOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVRtcC5hbGlnbiA9ICJjZW50ZXIiOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVUbXAuY2xhc3NOYW1lID0gJ0xhVGVYdGFibGUnOyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWJsZWlkKys7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlVG1wLmlkID0gIkxhVGVYdGFibGUiK3RhYmxlaWQ7IC8vdW5pcXVlIGlkIGZvciBlYWNoIHRhYmxlDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBUQUJsYmwgPSBzdHJ0bXBhcnJheVsxXS5tYXRjaCgvXFxsYWJlbFxzKlx7XHMqKFx3KylccypcfS8pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydG1wYXJyYXlbMV09c3RydG1wYXJyYXlbMV0ucmVwbGFjZSgvXFxsYWJlbFxzKlx7XHcrXH0vZywiIik7CQ0KCQkJICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2FwSW5kZXggPSBzdHJ0bXBhcnJheVsxXS5zZWFyY2goL1xcY2FwdGlvblxzKlx7W1xzXFNdK1x9Lyk7ICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBUQUJjYXAgPSAiIjsNCgkJCSAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoY2FwSW5kZXggPj0gMCkgeyAvLyBjYXB0aW9uIG1heSBjb250YWluIG90aGVyIHsgIH0gc3RydWN0dXJlcyAtLSBidXQgbm90IGRpc3BsYXltYXRoISENCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0bXAgPSBzdHJ0bXBhcnJheVsxXTsgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGVsaW1jbnQgPSAwOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNhcHN0YXJ0ID0gLTE7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IodmFyIHBvcz1jYXBJbmRleDtwb3M8dG1wLmxlbmd0aDtwb3MrKykgeyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRtcC5jaGFyQXQocG9zKSA9PSAieyIpIHsgZGVsaW1jbnQrKyB9Ow0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYodG1wLmNoYXJBdChwb3MpID09ICJ9IikgeyBkZWxpbWNudC0tIH07DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihkZWxpbWNudCA9PSAxICYmIGNhcHN0YXJ0PDApIHsgY2Fwc3RhcnQgPSBwb3MrMSB9Ow0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoZGVsaW1jbnQgPT0gMCAmJiBjYXBzdGFydD4wKSB7IA0KCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwZW5kID0gcG9zLTE7IA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgCQkgICAgICAgVEFCY2FwID0gdG1wLnN1YnN0cmluZyhjYXBzdGFydCxwb3MpOw0KCQkJCQkJCQkgICAgICAgYnJlYWsgDQoJCQkJCQkJCSAgICB9DQoJCQkJCQkJCSB9DQoJCQkgIAkJCQkgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoVEFCY2FwIT0iIikgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIFRBQnRib2R5ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidGJvZHkiKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBUQUJjYXB0aW9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiY2FwdGlvbiIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVEFCY2FwdGlvbi5jbGFzc05hbWU9IkxhVGVYdGFibGUgY2VudGVyZWQiOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIFRBQmFuY2hvciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImEiKTsNCiAgIAkJCSAgICAgICAgCQkJIFRBQmFuY2hvci5jbGFzc05hbWUgPSAiTGFUZVh0YWJsZSI7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihUQUJsYmwhPW51bGwpIHsgIFRBQmFuY2hvci5pZCA9IFRBQmxibFsxXTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGFUZVhDb3VudGVyWyJ0YWJsZSJdKys7DQoJICAgCQkJCQkgICAgICAgICB2YXIgdGFibm1iciA9IG1ha2VOdW1iZXJTdHJpbmcoTGFUZVhDb3VudGVyWyJ0YWJsZSJdKTsNCgkJCQkJCSAgICAgICAgIHZhciBhbmNob3JTcGFuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3BhbiIpOw0KCQkJCQkJICAgICAgICAgYW5jaG9yU3Bhbi5jbGFzc05hbWUgPSAiTGFUZVh0YWJsZSI7DQoJCQkJCQkgICAgICAgICBhbmNob3JTcGFuLnN0eWxlLmRpc3BsYXkgPSAibm9uZSI7DQoJCQkJCQkgICAgICAgICBhbmNob3JTcGFuLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRhYm5tYnIpKTsgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVEFCYW5jaG9yLmFwcGVuZENoaWxkKGFuY2hvclNwYW4pOyAJCQkgICAgIA0KCQkJCQkJICAgICAgICAgVEFCY2FwdGlvbi5hcHBlbmRDaGlsZChUQUJhbmNob3IpOw0KCQkJICAgICAgDQoJCQkJCQkgICAgICAgICB2YXIgVEFCc3BhbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInNwYW4iKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRBQnNwYW4uY2xhc3NOYW1lID0gIkxhVGVYdGFibGUiOyAvL0ZvciBDU1MgY291bnRlcnMsIGNvbW1lbnQgdGhpcyBsaW5lDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUQUJzcGFuLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCJUYWJsZSAiK3RhYm5tYnIrIi4gIiApICk7DQoJCQkJCQkgICAgICAgICBUQUJjYXB0aW9uLmFwcGVuZENoaWxkKFRBQnNwYW4pOw0KCQkJCQkJICAgICAgICAgVEFCY2FwdGlvbi5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgiIitUQUJjYXApKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVUbXAuYXBwZW5kQ2hpbGQoVEFCY2FwdGlvbik7DQoJCQkJCQkgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgVEFCaW5mbyA9IHN0cnRtcGFycmF5WzFdLm1hdGNoKC9cXGJlZ2luXHMqXHtccyp0YWJ1bGFyXHMqXH0oW1xzXFNdKylcXGVuZFxzKlx7XHMqdGFidWxhclxzKlx9Lyk7DQoJCQkJCQkgICAgICBpZihUQUJpbmZvIT1udWxsKSB7IA0KCQkJCQkJCQkgdmFyIFRBQnRib2R5ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGJvZHknKTsNCgkJCQkJCQkJIHZhciBUQUJyb3cgPSBudWxsOw0KCQkJCQkJCQkgdmFyIFRBQmNlbGwgPSBudWxsOw0KCQkJCQkJCQkgdmFyIHJvdz0wOw0KCQkJCQkJCQkgdmFyIGNvbD0wOw0KCQkJCSANCgkJCQkJCQkJIHZhciBUQUJhbGlnbiA9IFRBQmluZm9bMV0ubWF0Y2goL15ccypceyhbXlx9XSspXH0vKTsNCgkJCQkJCQkJIFRBQmluZm8gPSBUQUJpbmZvWzFdLnJlcGxhY2UoL15ccypce1teXH1dK1x9LywiIik7DQoJCQkJCQkJCSBUQUJpbmZvID0gVEFCaW5mby5yZXBsYWNlKC9cXGhsaW5lL2csIiIpOyAvL25vIGhvcml6b250YWwgYmFycw0KCQkJCQkJCQkgVEFCYWxpZ25bMV0gPSBUQUJhbGlnblsxXS5yZXBsYWNlKC9cfC9nLCIiKTsgLy9ubyB2ZXJ0aWNhbCBiYXJzDQoJCQkJCQkJCSBUQUJhbGlnblsxXSA9IFRBQmFsaWduWzFdLnJlcGxhY2UoL1xzL2csIiIpOyANCgkJCQkJCQkJIFRBQmluZm8gPSBUQUJpbmZvLnNwbGl0KCJcXFxcIik7IC8vIGludG8gcm93cw0KCQkJCQkJCQkgZm9yKHJvdz0wO3JvdzxUQUJpbmZvLmxlbmd0aDtyb3crKykgew0KCQkJCQkJICAgICAgICAgICAgVEFCcm93ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidHIiKTsNCgkJCQkJCQkJICAgIFRBQmluZm9bcm93XSA9IFRBQmluZm9bcm93XS5zcGxpdCgiJiIpOw0KCQkJCQkJCQkgICAgZm9yKGNvbD0wO2NvbDxUQUJpbmZvW3Jvd10ubGVuZ3RoO2NvbCsrKSB7DQoJCQkJCQkJCSAgICAgICBUQUJjZWxsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidGQiKTsNCgkJCQkJCQkJICAgICAgIHN3aXRjaCAoVEFCYWxpZ25bMV0uY2hhckF0KGNvbCkpIHsNCgkJCQkJCSAgICAgICAgICAgICAgICAgIGNhc2UgImwiOg0KCQkJCQkJCQkJCSAgICAgVEFCY2VsbC5zdHlsZS50ZXh0QWxpZ24gPSAibGVmdCI7DQoJCQkJCQkJCSAgICAgICAgICBicmVhazsNCgkJCQkJCSAgICAgICAgICAgICAgICAgIGNhc2UgImMiOg0KCQkJCQkJCQkJCSAgICAgVEFCY2VsbC5zdHlsZS50ZXh0QWxpZ24gPSAiY2VudGVyIjsNCgkJCQkJCQkJICAgICAgICAgIGJyZWFrOw0KCQkJCQkJICAgICAgICAgICAgICAgICAgY2FzZSAiciI6DQoJCQkJCQkJCQkJICAgICBUQUJjZWxsLnN0eWxlLnRleHRBbGlnbiA9ICJyaWdodCI7DQoJCQkJCQkJCSAgICAgICAgICBicmVhazsNCgkJCQkJCSAgICAgICAgICAgICAgICAgIGRlZmF1bHQgOg0KCQkJCQkJCQkJCSAgICAgVEFCY2VsbC5zdHlsZS50ZXh0QWxpZ24gPSAibGVmdCI7DQoJCQkJCQkJCSAgICAgICB9Ow0KCQkJCQkJCQkgICAgICAgVEFCY2VsbC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShUQUJpbmZvW3Jvd11bY29sXSkpOw0KCQkJCQkJCQkgICAgICAgVEFCcm93LmFwcGVuZENoaWxkKFRBQmNlbGwpOw0KCQkJCQkJCQkgICAgfQ0KCQkJCQkJCQkgICAgVEFCdGJvZHkuYXBwZW5kQ2hpbGQoVEFCcm93KTsNCgkJCQkJCSAgICAgICAgIH0NCgkJCQkJCSAgICAgICAgIG5vZGVUbXAuYXBwZW5kQ2hpbGQoVEFCdGJvZHkpOw0KCQkJCQkJICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3RnJhZy5hcHBlbmRDaGlsZChub2RlVG1wKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KCQkJCQkJICAgY2FzZSAibG9naWNhbGJyZWFrIjoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlVG1wID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgicCIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVRtcC5jbGFzc05hbWUgPSBzdHJ0bXBhcnJheVsxXTsgDQoJCQkJCQkgICAgICBub2RlVG1wLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCJcdTAwQTAiKSk7DQoJCQkJCQkgICAgICBuZXdGcmFnLmFwcGVuZENoaWxkKG5vZGVUbXApOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQoJCQkJCQkgICBjYXNlICJhcHBlbmRpeCI6DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbkFwcGVuZGl4PXRydWU7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWN0aW9uQ250cj0wOw0KCQkJCQkJICAgYnJlYWs7DQoJCQkJCQkgICBjYXNlICJhbGlzdGl0ZW0iOg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIEVuZERpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIpOw0KCQkJCQkJICAgICAgRW5kRGl2LmNsYXNzTmFtZSA9ICJlbmRsaXN0aXRlbSI7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdGcmFnLmFwcGVuZENoaWxkKEVuZERpdik7DQoJCQkJCQkgICAgICB2YXIgQmVnRGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2Iik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCZWdEaXYuY2xhc3NOYW1lID0gImxpc3RpdGVtIjsgDQoJCQkJCQkgICAgICBpZihzdHJ0bXBhcnJheVsxXSE9IiAiKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgQmVnU3BhbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInNwYW4iKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJlZ1NwYW4uY2xhc3NOYW1lPSJsaXN0aXRlbW1hcmtlciI7DQoJCQkJCQkJCSB2YXIgYm9sZEJlZ1NwYW4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJiIik7DQoJCQkJCQkJCSBib2xkQmVnU3Bhbi5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShzdHJ0bXBhcnJheVsxXSsiICIpKTsNCgkJCQkJCQkJIEJlZ1NwYW4uYXBwZW5kQ2hpbGQoYm9sZEJlZ1NwYW4pOw0KCQkJCQkJCQkgQmVnRGl2LmFwcGVuZENoaWxkKEJlZ1NwYW4pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KCQkJCQkJICAgICAgbmV3RnJhZy5hcHBlbmRDaGlsZChCZWdEaXYpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJiciI6DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdGcmFnLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImJyIikpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJiaWJpdGVtIjoNCgkJCQkJCSAgICAgIG5ld0ZyYWcuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYnIiKSk7DQoJCQkJCQkgICAgICB2YXIgbm9kZVRtcCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImEiKTsNCiAJCQkJCQkgICAgICBub2RlVG1wLmNsYXNzTmFtZSA9ICdiaWJpdGVtJzsgDQogIAkJICAgIAkJCSAgICAgIHZhciBub2RlU3BhbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInNwYW4iKTsNCiAJCQkJCQkgICAgICBub2RlU3Bhbi5jbGFzc05hbWUgPSAnYmliaXRlbSc7IA0KDQoJCQkJCQkgICAgICBiaWJjbnRyKys7DQoJCQkgICAgICANCgkJCQkJCSAgICAgIHZhciBsYmwgPSBzdHJ0bXBhcnJheVsxXS5tYXRjaCgvXHtccyooXHcrKVxzKlx9Lyk7IA0KCQkJCQkJICAgICAgc3RydG1wYXJyYXlbMV0gPSBzdHJ0bXBhcnJheVsxXS5yZXBsYWNlKC9ccypce1xzKlx3K1xzKlx9L2csIiIpOwkJCSAgICAgDQoJCQkJCQkgICAgICBzdHJ0bXBhcnJheVsxXSA9IHN0cnRtcGFycmF5WzFdLnJlcGxhY2UoL15ccypcWy8sIiIpOw0KCQkJCQkJICAgICAgc3RydG1wYXJyYXlbMV0gPSBzdHJ0bXBhcnJheVsxXS5yZXBsYWNlKC9ccypcXSQvLCIiKTsgDQogIAkJICAgIAkJCSAgICAgIHN0cnRtcGFycmF5WzFdID0gc3RydG1wYXJyYXlbMV0ucmVwbGFjZSgvXlxzK3xccyskL2csIiIpOw0KCQkJCQkJICAgICAgLy9XZSBjcmVhdGUgYSBsaXN0IG9mIGlkJ3MgZm9yIHRoZSBiaWJpdGVtcyAtLSBpdCBzZWVtZWQgaW1wb3J0YW50IGF0IG9uZSB0aW1lPz8NCgkJCQkJCSAgICAgIGlmKGxibD09bnVsbCkgew0KCQkJCQkJCQkgYmlibGlzdFtiaWJjbnRyXSA9ICJiaWJpdGVtIitiaWJjbnRyDQoJCQkJCQkgICAgICB9IGVsc2Ugew0KCQkJCQkJICAgICAgICAgYmlibGlzdFtiaWJjbnRyXSA9IGxibFsxXTsNCgkJCQkJCSAgICAgIH07IA0KCQkJCQkJICAgICAgbm9kZVRtcC5uYW1lID0gYmlibGlzdFtiaWJjbnRyXTsNCgkJCQkJCSAgICAgIG5vZGVUbXAuaWQgPSBiaWJsaXN0W2JpYmNudHJdOw0KCQkJCQkJICAgICAgLy8gV2UgcGxhY2UgY29udGVudCBpbnRvIDxhPiAtLSBhY2Nlc3MgaXQgd2l0aCBcY2l0ZSwgdGh1cyBhbGxvd2luZyBhcHByb3ByaWF0ZSBsYWJlbHMhDQoJCQkJCQkgICAgICBpZihzdHJ0bXBhcnJheVsxXSE9IiIpIHsNCgkJCQkJCQkJIG5vZGVTcGFuLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHN0cnRtcGFycmF5WzFdKSk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVTcGFuLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCJbIitiaWJjbnRyKyJdIikpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KCQkJCQkJICAgICAgbm9kZVRtcC5hcHBlbmRDaGlsZChub2RlU3Bhbik7DQoJCQkJCQkgICAgICBuZXdGcmFnLmFwcGVuZENoaWxkKG5vZGVUbXApOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJjaXRlIjoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlVG1wID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVRtcC5jbGFzc05hbWUgPSAnY2l0ZSc7IA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVRtcC5uYW1lID0gJ2NpdGUnOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVRtcC5ocmVmID0gIiMiK3N0cnRtcGFycmF5WzFdOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3RnJhZy5hcHBlbmRDaGlsZChub2RlVG1wKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAicmVmIjoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlVG1wID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpOyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVUbXAuY2xhc3NOYW1lID0gJ3JlZic7IA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVRtcC5uYW1lID0gJ3JlZic7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlVG1wLmhyZWYgPSAiIyIrc3RydG1wYXJyYXlbMV07DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdGcmFnLmFwcGVuZENoaWxkKG5vZGVUbXApOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQgOiANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlVG1wID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2Iik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlVG1wLmNsYXNzTmFtZSA9IHN0cnRtcGFycmF5WzBdOyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCBJc0NvdW50ZXIudGVzdChzdHJ0bXBhcnJheVswXSkgKSB7IA0KCQkJCQkJCQkgTGFUZVhDb3VudGVyW3N0cnRtcGFycmF5WzBdXSsrOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGVBbmNob3IgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJhIik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlQW5jaG9yLmNsYXNzTmFtZSA9IHN0cnRtcGFycmF5WzBdOw0KCQkJCQkJCQkgdmFyIGRpdm51bSA9IG1ha2VOdW1iZXJTdHJpbmcoTGFUZVhDb3VudGVyW3N0cnRtcGFycmF5WzBdXSk7DQoJCQkJIAkJCQkgdmFyIGFuY2hvclNwYW4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJzcGFuIik7DQoJCQkJCQkJCSBhbmNob3JTcGFuLmNsYXNzTmFtZSA9IHN0cnRtcGFycmF5WzBdOw0KCQkJCQkJCQkgYW5jaG9yU3Bhbi5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShkaXZudW0pKTsNCgkJCQkJCQkJIGFuY2hvclNwYW4uc3R5bGUuZGlzcGxheT0ibm9uZSI7DQoJCQkJCQkJCSBub2RlQW5jaG9yLmFwcGVuZENoaWxkKGFuY2hvclNwYW4pOw0KCQkJCQkJCQkgbm9kZVRtcC5hcHBlbmRDaGlsZChub2RlQW5jaG9yKTsNCgkJCQkgDQoJCQkJCQkJCSB2YXIgbm9kZVNwYW4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJzcGFuIik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlU3Bhbi5jbGFzc05hbWUgPSBzdHJ0bXBhcnJheVswXTsNCgkJCQkJCQkJIG5vZGVTcGFuLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHN0cnRtcGFycmF5WzFdKyIgIitkaXZudW0rIi4gIikpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVRtcC5hcHBlbmRDaGlsZChub2RlU3Bhbik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQoJCQkJCQkgICAgICBpZihpc0lFKSB7IC8vcmVtb3ZlIGlmIElFIHN1cHBvcnRzIDpiZWZvcmUgYW5kIDphZnRlcg0KCQkJCQkJCQkgaWYoc3RydG1wYXJyYXlbMF09PSgidGhlYmlibGlvZ3JhcGh5Inx8ImFic3RyYWN0Inx8ImtleXdvcmQifHwicHJvb2YiKSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGVTcGFuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3BhbiIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVNwYW4uY2xhc3NOYW1lID0gc3RydG1wYXJyYXlbMF07DQoJCQkJCQkJCSAgICBub2RlU3Bhbi5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShzdHJ0bXBhcnJheVsxXSkpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVRtcC5hcHBlbmRDaGlsZChub2RlU3Bhbik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IC8vZW5kIG9mIElFIDpiZWZvcmUgYW5kIDphZnRlciBmaXhlcw0KCQkJICAgIAkJCSAgaWYoc3RydG1wYXJyYXlbMF09PSJlbmRlbnVtZXJhdGUiIHx8IHN0cnRtcGFycmF5WzBdPT0iZW5kaXRlbWl6ZSIgfHwgc3RydG1wYXJyYXlbMF09PSJlbmRkZXNjcmlwdGlvbiIpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbmREaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJkaXYiKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZERpdi5jbGFzc05hbWUgPSAiZW5kbGlzdGl0ZW0iOw0KCQkJCQkJCQkgbmV3RnJhZy5hcHBlbmRDaGlsZChlbmREaXYpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3RnJhZy5hcHBlbmRDaGlsZChub2RlVG1wKTsNCgkJCSAgICAJCQkgIGlmKHN0cnRtcGFycmF5WzBdPT0iZW51bWVyYXRlIiB8fCBzdHJ0bXBhcnJheVswXT09Iml0ZW1pemUiIHx8IHN0cnRtcGFycmF5WzBdPT0iZGVzY3JpcHRpb24iKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZW5kRGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2Iik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmREaXYuY2xhc3NOYW1lID0gImxpc3RpdGVtIjsNCgkJCQkJCQkJIG5ld0ZyYWcuYXBwZW5kQ2hpbGQoZW5kRGl2KTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsgDQogICAgICAgICAgICAgICAgICAgICAgCSAvL2V2ZW4gPSB0ZXh0LCBsYWJlbHMsIGJmLCBhbmQgaXRhbGljcywgYW5kIGxpbmVicmVha3MsIGFuZCBtYXRoIC0tIHdlIG5vdyByZW1vdmUgdGhlIG1hdGgNCiAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ0bXBbal0gPSBzdHJ0bXBbal0ucmVwbGFjZSgvXFxcJC9nLCI8cGVyPiIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnRtcFtqXSA9IHN0cnRtcFtqXS5yZXBsYWNlKC9cJChbXlwkXSspXCQvZywiIFxcWyQxXFxbICIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnRtcFtqXSA9IHN0cnRtcFtqXS5yZXBsYWNlKC88cGVyPi9nLCJcXCQiKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ0bXBbal0gPSBzdHJ0bXBbal0ucmVwbGFjZSgvXFxiZWdpblxzKlx7XHMqbWF0aFxzKlx9KFtcc1xTXSs/KVxcZW5kXHMqXHtccyptYXRoXHMqXH0vZywiIFxcWyQxXFxbICIpOw0KDQoJCQkJCQkgdmFyIHN0cnRtcHRtcCA9IHN0cnRtcFtqXS5zcGxpdCgiXFxbIik7DQogICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgZm9yKHZhciBqamo9MDtqamo8c3RydG1wdG1wLmxlbmd0aDtqamorKykgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGpqaiAlIDIpIHsgLy9vZGQgPSBtYXRoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZVRtcCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInNwYW4iKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVUbXAuY2xhc3NOYW1lID0gJ2lubGluZW1hdGgnOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVRtcC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgiJCIrc3RydG1wdG1wW2pqal0rIiQiKSk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdGcmFnLmFwcGVuZENoaWxkKG5vZGVUbXApOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7DQoJCSAgICAgIAkJCSAJICAvL2FsbCBvdGhlciB0YWdzIHdpbGwgYmUgbWFwcGVkIHRvIHNwYW4ncyAobW9zdCBzaG91bGQgYmUgZm9udC1mYWNlIHRhZ3MpIHdpdGggY2xhc3MtbmFtZXMgbWF0Y2hpbmcgdGhlIHRhZyBuYW1lLiANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vRXhjZXB0aW9ucyB3aWxsIGJlIHRleHRjb2xvciwgY29sb3Jib3gsIHRleHRiZiwgdGV4dGl0LCBhbmQgZW1waC4gIFRoZXNlIGNhbm5vdCBpbmNsdWRlIGFueSBodG1sIHRhZ3MuICANCgkJICAgICAgCQkJIAkgICAgdmFyIFRhZ0luZGV4ID0gc3RydG1wdG1wW2pqal0uc2VhcmNoKC9cXFx3Ky8pOw0KCQkgICAgICAJCQkgCSAgICB2YXIgdG1wSW5kZXggPSBUYWdJbmRleDsgDQoJCSAgICAgIAkJCSAJICAgIHdoaWxlKHRtcEluZGV4Pi0xKSB7DQoJCSAgICAgIAkJCSAJICAgICAgIGlmKC9eXFx0ZXh0Y29sb3IvLnRlc3Qoc3RydG1wdG1wW2pqal0uc3Vic3RyaW5nKFRhZ0luZGV4LHN0cnRtcHRtcFtqampdLmxlbmd0aCkpKSB7IA0KCQkgICAgICAJCQkgCSAgICAgICAgICBzdHJ0bXB0bXBbampqXSA9IHN0cnRtcHRtcFtqampdLnJlcGxhY2UoL1xcdGV4dGNvbG9yXHMqXHtccyooXHcrKVxzKlx9XHMqLywiIFxcW3RleHRjb2xvclxcXSQxXFxdfCIpOw0KCQkgICAgICAJCQkgCSAgICAgICB9IGVsc2UgeyANCgkJICAgICAgCQkJIAkgICAgICAgICAgaWYoL15cXGNvbG9yYm94Ly50ZXN0KHN0cnRtcHRtcFtqampdLnN1YnN0cmluZyhUYWdJbmRleCxzdHJ0bXB0bXBbampqXS5sZW5ndGgpKSkgeyANCgkJICAgICAgCQkJIAkgICAgICAgICAgICAgc3RydG1wdG1wW2pqal0gPSBzdHJ0bXB0bXBbampqXS5yZXBsYWNlKC9cXGNvbG9yYm94XHMqXHtccyooXHcrKVxzKlx9XHMqLywiIFxcW2NvbG9yYm94XFxdJDFcXF18Iik7DQoJCSAgICAgIAkJCSAJICAgICAgICAgIH0gZWxzZSB7DQoJCSAgICAgIAkJCSAJICAgICAgICAgICAgIHN0cnRtcHRtcFtqampdID0gc3RydG1wdG1wW2pqal0uc3Vic3RyaW5nKDAsVGFnSW5kZXgpK3N0cnRtcHRtcFtqampdLnN1YnN0cmluZyhUYWdJbmRleCxzdHJ0bXB0bXBbampqXS5sZW5ndGgpLnJlcGxhY2UoL1xcXHMqKFx3KylccyovLCIgXFxbJDFcXF18Iik7DQoJCSAgICAgIAkJCSAJICAgICAgICAgIH0NCgkJICAgICAgCQkJIAkgICAgICAgfQ0KCQkgICAgICAJCQkgCSAgICAgICBUYWdJbmRleCArPXN0cnRtcHRtcFtqampdLnN1YnN0cmluZyhUYWdJbmRleCxzdHJ0bXB0bXBbampqXS5sZW5ndGgpLnNlYXJjaCgvXHwvKTsNCgkJICAgICAgCQkJIAkgICAgICAgVGFnSW5kZXgrKzsNCgkJICAgICAgCQkJIAkgICAgICAgc3RydG1wdG1wW2pqal0gPSBzdHJ0bXB0bXBbampqXS5yZXBsYWNlKC9cXFxdXHwvLCJcXF0gIik7DQoJCSAgICAgIAkJCSAJICAgICAgIGlmKHN0cnRtcHRtcFtqampdLmNoYXJBdChUYWdJbmRleCkgPT0gInsiKSB7DQoJCSAgICAgIAkJCSAJICAgICAgICAgIHN0cnRtcHRtcFtqampdID0gc3RydG1wdG1wW2pqal0uc3Vic3RyaW5nKDAsVGFnSW5kZXgpK3N0cnRtcHRtcFtqampdLnN1YnN0cmluZyhUYWdJbmRleCsxLHN0cnRtcHRtcFtqampdLmxlbmd0aCk7IA0KCQkgICAgICAJCQkgCSAgICAgICAgICB2YXIgZGVsaW1jbnQgPSAxOw0KCQkgICAgICAJCQkgCSAgICAgICAgICBmb3IodmFyIGtrID0gVGFnSW5kZXg7a2s8c3RydG1wdG1wW2pqal0ubGVuZ3RoO2trKyspIHsNCgkJICAgICAgCQkJIAkgICAgICAgICAgICAgaWYoc3RydG1wdG1wW2pqal0uY2hhckF0KGtrKSA9PSAieyIpIHsgZGVsaW1jbnQrKyB9Ow0KCQkgICAgICAJCQkgCSAgICAgICAgICAgICBpZihzdHJ0bXB0bXBbampqXS5jaGFyQXQoa2spID09ICJ9IikgeyBkZWxpbWNudC0tIH07DQoJCSAgICAgIAkJCSAJICAgICAgICAgICAgIGlmKGRlbGltY250PT0wKSB7IGJyZWFrOyB9DQoJCSAgICAgIAkJCSAJICAgICAgICAgIH0NCgkJICAgICAgCQkJIAkgICAgICAgICAgICAgc3RydG1wdG1wW2pqal0gPSBzdHJ0bXB0bXBbampqXS5zdWJzdHJpbmcoMCxraykrIlxcWyAiK3N0cnRtcHRtcFtqampdLnN1YnN0cmluZyhraysxLHN0cnRtcHRtcFtqampdLmxlbmd0aCk7DQoJCSAgICAgIAkJCSAJICAgICAgICAgICAgIFRhZ0luZGV4ID0ga2srMzsNCgkJICAgICAgCQkJIAkgICAgICAgfSBlbHNlIHsgDQoJCSAgICAgIAkJCSAJICAgICAgICAgIHN0cnRtcHRtcFtqampdID0gc3RydG1wdG1wW2pqal0uc3Vic3RyaW5nKDAsVGFnSW5kZXgpKyJcXFsgIitzdHJ0bXB0bXBbampqXS5zdWJzdHJpbmcoVGFnSW5kZXgrMSxzdHJ0bXB0bXBbampqXS5sZW5ndGgpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUYWdJbmRleCA9IFRhZ0luZGV4ICsgMzsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihUYWdJbmRleDxzdHJ0bXB0bXBbampqXS5sZW5ndGgpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wSW5kZXggPSBzdHJ0bXB0bXBbampqXS5zdWJzdHJpbmcoVGFnSW5kZXgsc3RydG1wdG1wW2pqal0ubGVuZ3RoKS5zZWFyY2goL1xcXHcrLyk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCgkJICAgICAgCQkJIAkgICAgICAgZWxzZSB7IA0KCQkgICAgICAJCQkgCSAgICAgICAgICB0bXBJbmRleCA9IC0xIH07DQoJCSAgICAgIAkJCSAJICAgICAgIFRhZ0luZGV4ICs9IHRtcEluZGV4Ow0KCQkgICAgICAJCQkgCSAgICB9DQoNCgkgICAgIAkgICAgICAgICAgIAkgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnRtcHRtcFtqampdID0gc3RydG1wdG1wW2pqal0ucmVwbGFjZSgvXFxcXFxzKlxcXFwvZywiXFxcXCIpOw0KCQkJCSAgICAgICAgIAkJc3RydG1wdG1wW2pqal0gPSBzdHJ0bXB0bXBbampqXS5yZXBsYWNlKC9cXFxcL2csIiBcXFticlxcXSBcXFsgIik7DQoJCQkJCQkgCQlzdHJ0bXB0bXBbampqXSA9IHN0cnRtcHRtcFtqampdLnJlcGxhY2UoL1xcbGFiZWxccypce1xzKihcdyspXHMqXH0vZywiIFxcW2xhYmVsXFxdJDFcXFsgIik7CQkJIA0KCQkJCQkJIAkJdmFyIHN0cmxibHMgPSBzdHJ0bXB0bXBbampqXS5zcGxpdCgiXFxbIik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgIAkJZm9yKHZhciBqaj0wO2pqPHN0cmxibHMubGVuZ3RoO2pqKyspIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAJCSAgIGlmKGpqICUgMikgeyAvL29kZCA9IGxhYmVscywgYm9sZGZhY2UsIGFuZCBicmVha3MNCgkJCQkJCSAJCSAgICAgdmFyIHN0cnRtcGFycmF5ID0gc3RybGJsc1tqal0uc3BsaXQoIlxcXSIpOw0KCQkJCQkJICAgICAgICAgICAgICBzd2l0Y2goc3RydG1wYXJyYXlbMF0pIHsNCgkJCQkJCQkJICAgICAgICBjYXNlICJ0ZXh0Y29sb3IiOg0KICAgICAgICAJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZVRtcCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInNwYW4iKTsgDQogICAgICAgIAkJICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVUbXAuY2xhc3NOYW1lID0gJ0xhVGVYQ29sb3InOw0KCQkJCQkJCQkJCSAgICBpZihJc0NvbG9yTmFtZS50ZXN0KHN0cnRtcGFycmF5WzFdLnRvTG93ZXJDYXNlKCkpKSB7DQogICAJCQkJCQkJCQkJICAgICAgIG5vZGVUbXAuc3R5bGUuY29sb3I9TGFUZVhDb2xvcltzdHJ0bXBhcnJheVsxXS50b0xvd2VyQ2FzZSgpXTsNCgkJCQkJCQkJCQkgICAgfSBlbHNlIHsgDQoJCQkJCQkJCQkJICAgICAgIG5vZGVUbXAuc3R5bGUuY29sb3I9c3RydG1wYXJyYXlbMV07DQogICAgICAgIAkJICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07DQogICAgICAgIAkJICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVUbXAuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoc3RydG1wYXJyYXlbMl0pKTsNCiAgICAgICAgCQkgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3RnJhZy5hcHBlbmRDaGlsZChub2RlVG1wKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAJCSAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgCQkgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAiY29sb3Jib3giOg0KICAgICAgICAJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZVRtcCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInNwYW4iKTsgDQogICAgICAgIAkJICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVUbXAuY2xhc3NOYW1lID0gJ0xhVGVYQ29sb3InOw0KCQkJCQkJCQkJCSAgICBpZihJc0NvbG9yTmFtZS50ZXN0KHN0cnRtcGFycmF5WzFdLnRvTG93ZXJDYXNlKCkpKSB7DQogICAJCQkJCQkJCQkJICAgICAgIG5vZGVUbXAuc3R5bGUuYmFja2dyb3VuZD1MYVRlWENvbG9yW3N0cnRtcGFycmF5WzFdLnRvTG93ZXJDYXNlKCldOw0KCQkJCQkJCQkJCSAgICB9IGVsc2UgeyANCgkJCQkJCQkJCQkgICAgICAgbm9kZVRtcC5zdHlsZS5iYWNrZ3JvdW5kPXN0cnRtcGFycmF5WzFdOw0KICAgICAgICAJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ow0KICAgICAgICAJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlVG1wLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHN0cnRtcGFycmF5WzJdKSk7DQogICAgICAgIAkJICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0ZyYWcuYXBwZW5kQ2hpbGQobm9kZVRtcCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgCQkgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgIAkJICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgImJyIjoNCgkJCQkJCQkJICAgICAgICAgICAgbmV3RnJhZy5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJiciIpKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgIAkJCQkJCQkJICAgICAgICAgYnJlYWs7DQoJCQkJCSAgICAJCQkgICAgIGNhc2UgImxhYmVsIiA6DQoJCQkJCQkJCSAgICAgICAgICAgdmFyIG5vZGVUbXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJhIik7DQoJCQkJCQkJCSAgICAgICAgICAgIG5vZGVUbXAuY2xhc3NOYW1lID0gJ0xhVGVYTWF0aE1MbGFiZWwnOw0KCQkJCQkJCQkgICAgICAgICAgICB2YXIgbGJsaWQgPSBzdHJ0bXBhcnJheVsxXS5tYXRjaCgvXHMqKFx3KylccyovKTsgDQoJCQkJCQkJCSAgICAgICAgICAgIGlmKGxibGlkICE9IG51bGwpIHsgbm9kZVRtcC5pZCA9IGxibGlkWzFdIH07DQoJCQkJCQkJCSAgICAgICAgICAgIG5vZGVUbXAuc3R5bGUuZGlzcGxheSA9ICJub25lIjsNCgkJCQkJCQkJICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExhVGVYQ291bnRlclsnbGFiZWwnXSsrOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbGJsbnVtID0gbWFrZU51bWJlclN0cmluZyhMYVRlWENvdW50ZXJbJ2xhYmVsJ10pOw0KCQkJCSAJCQkJICAgICAgICAgICAgDQoJCQkJCQkJCSAgICAgICAgICAgIHZhciBhbmNob3JTcGFuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3BhbiIpOw0KCQkJCQkJCQkgICAgICAgICAgICBhbmNob3JTcGFuLmNsYXNzTmFtZSA9ICdMYVRlWE1hdGhNTGxhYmVsJzsNCgkJCQkJCQkJICAgICAgICAgICAgYW5jaG9yU3Bhbi5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShsYmxudW0pKTsNCgkJCQkJCQkJICAgICAgICAgICAgYW5jaG9yU3Bhbi5zdHlsZS5kaXNwbGF5PSJub25lIjsNCgkJCQkJCQkJICAgICAgICAgICAgbm9kZVRtcC5hcHBlbmRDaGlsZChhbmNob3JTcGFuKTsNCgkJCQkJCQkJICAgICAgICAgICAgbmV3RnJhZy5hcHBlbmRDaGlsZChub2RlVG1wKTsJCQkJCSAgICAgICAgICAgIA0KCQkJCQkJCQkgICAgICAgICBicmVhazsNCiAgICAgICAgCQkgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdCA6DQogICAgICAgIAkJICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlVG1wID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3BhbiIpOyANCiAgICAgICAgCQkgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVRtcC5jbGFzc05hbWUgPSBzdHJ0bXBhcnJheVswXTsNCiAgICAgICAgCQkgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVRtcC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShzdHJ0bXBhcnJheVsxXSkpDQogICAgICAgIAkJICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0ZyYWcuYXBwZW5kQ2hpbGQobm9kZVRtcCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCgkJCQkJIAkJCSAgICAgICB9DQoJCQkJCQkJICAgICAgICAgfSBlbHNlIHsNCgkJCQkgICAgIAkJICAgICAgICAgbmV3RnJhZy5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShzdHJsYmxzW2pqXSkpOw0KCQkJCQkgCQkJICAgfQ0KCQkJCQkgCQkJfQ0KCQkJCQkgCSAgIH0NCgkJCQkJIAl9DQoJCSAgICAgIAkJfSAvLyBlbmQgZWxzZSBmb3IgZXZlbiBzcGxpdHMgb2Ygc3RydG1wDQoJCSAgCQkgfQ0KCSAgICAgICAgICAgfSANCiAgICAgICAgICAgIH07IC8vZWxzZSBzZWN0aW9ucyBhbmQgbGFiZWxzDQogICAgICAgICAgICBUaGVCb2R5LnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKG5ld0ZyYWcsVGhlQm9keSk7IA0KICAgICAgICAgfSAvL3N0ciBub2RldmFsdWUgaXMgbm90IGVtcHR5DQogICAgICB9DQogICB9IC8vIHNwbGl0IG9mZiByZWN1cnNpb24NCiAgIHJldHVybiBUaGVCb2R5Ow0KfQ0KDQpmdW5jdGlvbiBMYVRlWERpdnNBbmRSZWZzKHRoZWJvZHkpIHsNCiAgIHZhciBUaGVCb2R5ID0gdGhlYm9keTsNCg0KICAgdmFyIEVuZERpdkNsYXNzID0gbnVsbDsgDQogICB2YXIgQWxsRGl2cyA9IFRoZUJvZHkuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImRpdiIpOw0KICAgdmFyIGxibDJpZCA9ICIiOw0KICAgdmFyIGxibG5vZGUgPSBudWxsOw0KICAgZm9yKHZhciBpPUFsbERpdnMubGVuZ3RoLTE7aT49MDtpLS0pIHsNCiAgICAgIEVuZERpdkNsYXNzID0gQWxsRGl2c1tpXS5jbGFzc05hbWUubWF0Y2goL2VuZFx3Ky8gKTsgDQogICAgICBpZihFbmREaXZDbGFzcyE9bnVsbCkgew0KICAgICAgICAgRW5kRGl2Q2xhc3MgPSBFbmREaXZDbGFzc1swXTsgDQoJIHZhciBEaXZDbGFzcyA9IEVuZERpdkNsYXNzLnN1YnN0cmluZygzLEVuZERpdkNsYXNzLmxlbmd0aCk7DQogICAgICAgICB2YXIgRW5kRGl2Tm9kZSA9IEFsbERpdnNbaV07DQogICAgICAgICBicmVhazsgDQogICAgICB9IA0KICAgfSAgDQogICB3aGlsZShFbmREaXZDbGFzcyE9bnVsbCkgew0KICAgICAgLy8gVHJhY2tCYWNrIHRvIEJlZ2lubmluZywgYXBwZW5kaW5nIHRvIG5ld2ZyYWcgYXMgd2UgZ28NCiAgICAgIHZhciBuZXdGcmFnID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOw0KICAgICAgdmFyIFJvb3ROb2RlID0gRW5kRGl2Tm9kZS5wYXJlbnROb2RlOw0KICAgICAgdmFyIENsYXNzQ291bnQgPSAxOyAvLyBiZWNhdXNlIG9mIEVuZERpdk5vZGUNCiAgICAgIHdoaWxlKEVuZERpdk5vZGUucHJldmlvdXNTaWJsaW5nIT1udWxsICYmIENsYXNzQ291bnQ+MCkgew0KCSBzd2l0Y2goRW5kRGl2Tm9kZS5wcmV2aW91c1NpYmxpbmcuY2xhc3NOYW1lKSB7DQoJICAgIGNhc2UgRW5kRGl2Q2xhc3M6CSANCgkgICAgICAgQ2xhc3NDb3VudCsrOw0KCSAgICAgICBuZXdGcmFnLmluc2VydEJlZm9yZShFbmREaXZOb2RlLnByZXZpb3VzU2libGluZyxuZXdGcmFnLmZpcnN0Q2hpbGQpOw0KCSAgICAgICBicmVhazsNCgkgICAgY2FzZSBEaXZDbGFzczogDQoJICAgICAgIGlmKEVuZERpdk5vZGUucHJldmlvdXNTaWJsaW5nLm5vZGVOYW1lPT0iRElWIikgeyANCgkgICAgICAgICAgQ2xhc3NDb3VudC0tIDsNCgkJICAvL011c3QgY2hlY2sgdG8gc2VlIGlmIHdlIG5lZWQgYSBsYWJlbCBoZXJlIQ0KCQkgaWYobGJsMmlkICE9IiIgKSB7IA0KCQkgICAgRW5kRGl2Tm9kZS5wcmV2aW91c1NpYmxpbmcuaWQgPSBsYmwyaWQ7DQoJCSAgICBsYmwyaWQgPSAiIiANCgkJIH0NCgkJIGlmKENsYXNzQ291bnQ9PTApIHsgDQoJICAgICAgICAgICAgIFJvb3ROb2RlID0gRW5kRGl2Tm9kZS5wcmV2aW91c1NpYmxpbmc7IA0KCQkgIH0gZWxzZSB7DQoJICAgICAgICAgICAgIG5ld0ZyYWcuaW5zZXJ0QmVmb3JlKEVuZERpdk5vZGUucHJldmlvdXNTaWJsaW5nLG5ld0ZyYWcuZmlyc3RDaGlsZCk7DQoJCSAgfQ0KCSAgICAgICB9Ow0KCSAgICAgICBicmVhazsNCiAgICAgICAgICAgY2FzZSAnTGFUZVhNYXRoTUxsYWJlbCc6DQogICAgICAgICAgICAgICBsYmwyaWQgPSBFbmREaXZOb2RlLnByZXZpb3VzU2libGluZy5pZDsgDQoJICAgICAgICAgIEVuZERpdk5vZGUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChFbmREaXZOb2RlLnByZXZpb3VzU2libGluZyk7DQoJICAgICAgIGJyZWFrOw0KCSAgICBkZWZhdWx0Og0KCSAgICAgICBuZXdGcmFnLmluc2VydEJlZm9yZShFbmREaXZOb2RlLnByZXZpb3VzU2libGluZyxuZXdGcmFnLmZpcnN0Q2hpbGQpOw0KICAgICAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgUm9vdE5vZGUuYXBwZW5kQ2hpbGQobmV3RnJhZyk7DQogICAgICBFbmREaXZOb2RlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoRW5kRGl2Tm9kZSk7DQogICAgICANCiAgICAgIC8vTG9vayBmb3IgbW9yZSBlbmQgZGl2IGl0ZW1zDQogICAgICBBbGxEaXZzID0gVGhlQm9keS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiRElWIik7DQogICAgICBmb3IoaT1BbGxEaXZzLmxlbmd0aC0xO2k+PTA7aS0tKSB7DQogICAgICAgICBFbmREaXZDbGFzcyA9IEFsbERpdnNbaV0uY2xhc3NOYW1lLm1hdGNoKC9lbmRcdysvICk7DQogICAgICAgICBpZihFbmREaXZDbGFzcyE9bnVsbCkgew0KCSAgICBDbGFzc0NvdW50ID0gMDsNCiAgICAgICAgICAgIEVuZERpdkNsYXNzID0gRW5kRGl2Q2xhc3NbMF07IA0KCSAgICBEaXZDbGFzcyA9IEVuZERpdkNsYXNzLnN1YnN0cmluZygzLEVuZERpdkNsYXNzLmxlbmd0aCk7DQogICAgICAgICAgICBFbmREaXZOb2RlID0gQWxsRGl2c1tpXTsNCgkgICAgUm9vdE5vZGUgPSBFbmREaXZOb2RlLnBhcmVudE5vZGU7DQogICAgICAgICAgICBicmVhazsgDQogICAgICAgICB9IA0KICAgICAgIH0gICAgIA0KICAgfSAvLyBlbmQgd2hpbGUhDQogICANCiAgIA0KDQogICANCiAgIHZhciBBbGxEaXZzID0gVGhlQm9keS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZGl2Iik7IC8vQ29udmVydCBpdGVtaXplIGFuZCBlbnVtZXJhdGUgdG8gaHRtbCBsaXN0czoNCiAgIHZhciBESVYyTEkgPSBudWxsOw0KICAgDQogICBmb3IodmFyIGk9MDtpPEFsbERpdnMubGVuZ3RoO2krKykgew0KICAgICAgaWYoIEFsbERpdnNbaV0uY2xhc3NOYW1lPT0iaXRlbWl6ZSIgfHwgQWxsRGl2c1tpXS5jbGFzc05hbWU9PSJlbnVtZXJhdGUiIHx8IEFsbERpdnNbaV0uY2xhc3NOYW1lPT0iZGVzY3JpcHRpb24iKSAgeyANCiAJICAgIGlmKEFsbERpdnNbaV0uY2xhc3NOYW1lPT0iaXRlbWl6ZSIpIHsgDQoJCVJvb3ROb2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiVUwiKTsNCiAgICAgICAgICAgIH0gZWxzZSB7IA0KCQlSb290Tm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIk9MIik7DQogICAgICAgICAgICB9DQoJICAgIFJvb3ROb2RlLmNsYXNzTmFtZSA9ICdMYVRlWE1hdGhNTCc7DQoJICAgIGlmKEFsbERpdnNbaV0uaGFzQ2hpbGROb2RlcygpKSB7IEFsbERpdnNbaV0ucmVtb3ZlQ2hpbGQoQWxsRGl2c1tpXS5maXJzdENoaWxkKSB9Ow0KCSAgICB3aGlsZShBbGxEaXZzW2ldLmhhc0NoaWxkTm9kZXMoKSkgew0KCSAgICAgICBpZihBbGxEaXZzW2ldLmZpcnN0Q2hpbGQuaGFzQ2hpbGROb2RlcygpKSB7IA0KCQkgICAgICBESVYyTEkgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJMSSIpOw0KCQkgICB3aGlsZShBbGxEaXZzW2ldLmZpcnN0Q2hpbGQuaGFzQ2hpbGROb2RlcygpKSB7DQoJCSAgICAgIERJVjJMSS5hcHBlbmRDaGlsZChBbGxEaXZzW2ldLmZpcnN0Q2hpbGQuZmlyc3RDaGlsZCk7DQoJCSAgfQ0KCQkgIGlmKERJVjJMSS5maXJzdENoaWxkLmNsYXNzTmFtZT09Imxpc3RpdGVtbWFya2VyIikgew0KCQkgICAgIERJVjJMSS5zdHlsZS5saXN0U3R5bGVUeXBlID0gIm5vbmUiOyANCgkgICAgICAgICAgfQ0KCQkgIFJvb3ROb2RlLmFwcGVuZENoaWxkKERJVjJMSSkNCgkgICAgICAgfQ0KCSAgICAgICBBbGxEaXZzW2ldLnJlbW92ZUNoaWxkKEFsbERpdnNbaV0uZmlyc3RDaGlsZCk7DQogICAgICAgICAgICB9DQoJICAgIEFsbERpdnNbaV0uYXBwZW5kQ2hpbGQoUm9vdE5vZGUpOw0KICAgICAgfQ0KICAgfQ0KCQ0KICAgLy8gRnJvbSBoZXJlIHRvICdlbmQgZm9yIEFsbEFuY2hvcnMgaXMgbmVjZXNzYXJ5IG9ubHkgYmVjYXVzZSBDU1MzIGlzIG5vdCBpbXBsZW1lbnRlZCB5ZXQuDQogICAvLyBPbmNlIENTUzMgdGFyZ2V0LXRleHQgaXMgYXZhaWxhYmxlLCB0aGlzIGNhbiBiZSBkb25lIHVzaW5nIENTUw0KICAgdmFyIEFsbEFuY2hvcnMgPSBUaGVCb2R5LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhIik7DQogICBmb3IodmFyIGk9MDtpPEFsbEFuY2hvcnMubGVuZ3RoO2krKykgew0KICAgICAgaWYoQWxsQW5jaG9yc1tpXS5jbGFzc05hbWUgPT0gInJlZiIgfHwgQWxsQW5jaG9yc1tpXS5jbGFzc05hbWUgPT0gImNpdGUiICkgew0KICAgICAgICAgdmFyIGxhYmVsID0gQWxsQW5jaG9yc1tpXS5ocmVmLm1hdGNoKC9cIyhcdyspLyk7IA0KICAgICAgICAgaWYobGFiZWwhPW51bGwpIHsgDQogICAgICAgICAgICB2YXIgbGFiZWxOb2RlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQobGFiZWxbMV0pOw0KICAgICAgICAgICAgaWYobGFiZWxOb2RlIT1udWxsKSB7DQogICAgICAgICAgICAgICB2YXIgVGhlU3BhbnMgPSBsYWJlbE5vZGUuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIlNQQU4iKTsNCgkgICAgICAgaWYoVGhlU3BhbnMhPW51bGwpIHsgDQoJCSAgdmFyIHJlZk5vZGUgPSBUaGVTcGFuc1swXS5jbG9uZU5vZGUodHJ1ZSk7DQogICAgCSAgICAgICAgICByZWZOb2RlLnN0eWxlLmRpc3BsYXk9ImlubGluZSINCgkJICByZWZOb2RlLmNsYXNzTmFtZSA9IEFsbEFuY2hvcnNbaV0uY2xhc3NOYW1lOw0KCQkgIEFsbEFuY2hvcnNbaV0uYXBwZW5kQ2hpbGQocmVmTm9kZSk7DQoJCSAgLy9icmVhazsNCgkgICAgICAgfSAgICAgICANCiAgICAgICAgICAgIH0NCiAgICAgICAgIH0NCiAgICAgIH0NCiAgIH0gLy8gZW5kIGZvciBBbGxBbmNob3JzDQoNCiAgIC8vIEV2ZW50dWFsbHk6IENvbGxhcHNpYmxlIFNlY3Rpb25zDQogICANCiAgIHJldHVybiBUaGVCb2R5Ow0KfQ0KDQp2YXIgQU1ib2R5Ow0KdmFyIEFNbm9NYXRoTUwgPSBmYWxzZSwgQU10cmFuc2xhdGVkID0gZmFsc2U7DQoNCmZ1bmN0aW9uIHRyYW5zbGF0ZShzcGFuY2xhc3NBTSkgew0KICBpZiAoIUFNdHJhbnNsYXRlZCkgeyAvLyBydW4gdGhpcyBvbmx5IG9uY2UNCiAgICAgQU10cmFuc2xhdGVkID0gdHJ1ZTsNCiAgICAgQU1pbml0U3ltYm9scygpOw0KICAgICB2YXIgTGFUZVhDb250YWluZXJzID0gW107DQogICAgIHZhciBBbGxDb250YWluZXJzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJyonKTsNCiAgICAgdmFyIEV4dGVuZE5hbWUgPSAiIjsNCiAgICANCiAgICAgZm9yICh2YXIgayA9IDAsbD0wOyBrIDwgQWxsQ29udGFpbmVycy5sZW5ndGg7IGsrKykgew0KICAgICAgICBFeHRlbmROYW1lID0gIiAiK0FsbENvbnRhaW5lcnNba10uY2xhc3NOYW1lKyIgIjsgICAgICAgIA0KICAgICAgICBpZihFeHRlbmROYW1lLm1hdGNoKC9cc0xhVGVYXHMvKSE9bnVsbCkgeyANCiAgICAgICAgICAgTGFUZVhDb250YWluZXJzW2xdID0gQWxsQ29udGFpbmVyc1trXTsNCiAgICAgICAgICAgbCsrOw0KICAgICAgICB9DQogICAgIH07IA0KICAgICBpZihMYVRlWENvbnRhaW5lcnMubGVuZ3RoPjApIHsgDQogICAgICAgIGZvcih2YXIgbT0wO208TGFUZVhDb250YWluZXJzLmxlbmd0aDttKyspIHsNCiAgICAgICAgICAgQU1ib2R5ID0gTGFUZVhDb250YWluZXJzW21dOw0KICAgICAgICAgICB0cnkgew0KICAgICAgICAgICAgICBBTWJvZHkgPSBMYVRlWERpdnNBbmRSZWZzKExhVGVYcHJlUHJvY2VzcyhBTWJvZHkpKTsgLy8NCiAgICAgICAgICAgfSBjYXRjaChlcnIpIHsgDQogICAgICAgICAgICAgICBhbGVydCgiVW5rbm93biBFcnJvcjogRGVmYXVsdGluZyB0byBPcmlnaW5hbCBMYVRlWE1hdGhNTCIpOw0KICAgICAgICAgICB9DQogICAgICAgICAgIGlmKEFNYm9keS50YWdOYW1lPT0iUFJFIikgew0KICAgICAgICAgICAgICB2YXIgUHJlQ2hpbGRzID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpOw0KICAgICAgICAgICAgICB2YXIgRGl2Q2hpbGRzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiRElWIik7IA0KICAgICAgICAgICAgICB3aGlsZShBTWJvZHkuaGFzQ2hpbGROb2RlcygpKSB7DQogICAgICAgICAgICAgICAgIERpdkNoaWxkcy5hcHBlbmRDaGlsZChBTWJvZHkuZmlyc3RDaGlsZCk7DQogICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgUHJlQ2hpbGRzLmFwcGVuZENoaWxkKERpdkNoaWxkcyk7DQogICAgICAgICAgICAgIEFNYm9keS5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChQcmVDaGlsZHMsQU1ib2R5KTsNCiAgICAgICAgICAgICAgQU1ib2R5ID0gRGl2Q2hpbGRzOyAvL0xlYXZlcyBlbXB0eSBwcmUgLS0gbWF5IGJlIHVzZWZ1bD8/DQogICAgICAgICAgICAgIA0KICAgICAgICAgICB9DQogICAgICAgICAgIEFNcHJvY2Vzc05vZGUoQU1ib2R5LCBmYWxzZSwgc3BhbmNsYXNzQU0pOw0KICAgICAgICB9DQogICAgIH0gZWxzZSB7IC8vRGVmYXVsdCB0byBlbnRpcmUgcGFnZSAgDQogICAgICAgIEFNYm9keSA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJib2R5IilbMF07DQogICAgICAgIHRyeSB7DQogICAgICAgICAgIEFNYm9keSA9IExhVGVYRGl2c0FuZFJlZnMoTGFUZVhwcmVQcm9jZXNzKEFNYm9keSkpOyAvLw0KICAgICAgICB9IGNhdGNoKGVycikgeyANCiAgICAgICAgICAgYWxlcnQoIlVua25vd24gRXJyb3I6IERlZmF1bHRpbmcgdG8gT3JpZ2luYWwgTGFUZVhNYXRoTUwiKTsNCiAgICAgICAgfQ0KICAgICAgICAgICBBTXByb2Nlc3NOb2RlKEFNYm9keSwgZmFsc2UsIHNwYW5jbGFzc0FNKTsNCiAgICAgfQ0KICB9DQp9DQogIA0KaWYgKGlzSUUpIHsgDQogIC8vIGF2b2lkIGFkZGluZyBNYXRoUGxheWVyIGluZm8gZXhwbGljaXRseSB0byBlYWNoIHdlYnBhZ2UNCiAgZG9jdW1lbnQud3JpdGUoIjxvYmplY3QgaWQ9XCJtYXRocGxheWVyXCJcDQogIGNsYXNzaWQ9XCJjbHNpZDozMkY2NkEyMC03NjE0LTExRDQtQkQxMS0wMDEwNEJEM0Y5ODdcIj48L29iamVjdD4iKTsNCiAgZG9jdW1lbnQud3JpdGUoIjw/aW1wb3J0IG5hbWVzcGFjZT1cIm1cIiBpbXBsZW1lbnRhdGlvbj1cIiNtYXRocGxheWVyXCI/PiIpOw0KfQ0KDQovLyBHTzEuMSBHZW5lcmljIG9ubG9hZCBieSBCcm90aGVyY2FrZQ0KLy8gaHR0cDovL3d3dy5icm90aGVyY2FrZS5jb20vDQovL29ubG9hZCBmdW5jdGlvbiAocmVwbGFjZXMgdGhlIG9ubG9hZD0idHJhbnNsYXRlKCkiIGluIHRoZSA8Ym9keT4gdGFnKQ0KZnVuY3Rpb24gZ2VuZXJpYygpDQp7DQogIHRyYW5zbGF0ZSgpOw0KfTsNCi8vc2V0dXAgb25sb2FkIGZ1bmN0aW9uDQppZih0eXBlb2Ygd2luZG93LmFkZEV2ZW50TGlzdGVuZXIgIT0gJ3VuZGVmaW5lZCcpDQp7DQogIC8vLi4gZ2Vja28sIHNhZmFyaSwga29ucXVlcm9yIGFuZCBzdGFuZGFyZA0KICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbG9hZCcsIGdlbmVyaWMsIGZhbHNlKTsNCn0NCmVsc2UgaWYodHlwZW9mIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIgIT0gJ3VuZGVmaW5lZCcpDQp7DQogIC8vLi4gb3BlcmEgNw0KICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgZ2VuZXJpYywgZmFsc2UpOw0KfQ0KZWxzZSBpZih0eXBlb2Ygd2luZG93LmF0dGFjaEV2ZW50ICE9ICd1bmRlZmluZWQnKQ0Kew0KICAvLy4uIHdpbi9pZQ0KICB3aW5kb3cuYXR0YWNoRXZlbnQoJ29ubG9hZCcsIGdlbmVyaWMpOw0KfQ0KLy8qKiByZW1vdmUgdGhpcyBjb25kaXRpb24gdG8gZGVncmFkZSBvbGRlciBicm93c2Vycw0KZWxzZQ0Kew0KICAvLy4uIG1hYy9pZTUgYW5kIGFueXRoaW5nIGVsc2UgdGhhdCBnZXRzIHRoaXMgZmFyDQogIC8vaWYgdGhlcmUncyBhbiBleGlzdGluZyBvbmxvYWQgZnVuY3Rpb24NCiAgaWYodHlwZW9mIHdpbmRvdy5vbmxvYWQgPT0gJ2Z1bmN0aW9uJykNCiAgew0KICAgIC8vc3RvcmUgaXQNCiAgICB2YXIgZXhpc3RpbmcgPSBvbmxvYWQ7DQogICAgLy9hZGQgbmV3IG9ubG9hZCBoYW5kbGVyDQogICAgd2luZG93Lm9ubG9hZCA9IGZ1bmN0aW9uKCkNCiAgICB7DQogICAgICAvL2NhbGwgZXhpc3Rpbmcgb25sb2FkIGZ1bmN0aW9uDQogICAgICBleGlzdGluZygpOw0KICAgICAgLy9jYWxsIGdlbmVyaWMgb25sb2FkIGZ1bmN0aW9uDQogICAgICBnZW5lcmljKCk7DQogICAgfTsNCiAgfQ0KICBlbHNlDQogIHsNCiAgICAvL3NldHVwIG9ubG9hZCBmdW5jdGlvbg0KICAgIHdpbmRvdy5vbmxvYWQgPSBnZW5lcmljOw0KICB9DQp9DQo=" type="text/javascript"></script>
</head>
<body>
<div class="layout">
<div id="controls"></div>
<div id="currentSlide"></div>
<div id="header"></div>
<div id="footer">
<h1>Kei Hibino</h1>
<h2>Haskell Relational Record's Query-Building DSL</h2>
</div>
</div>
<div class="presentation">
<div class="titleslide slide">
<h1 class="title">Haskell Relational Record's Query-Building DSL</h1>
<h3 class="author">2014-12-25 (Updated 2014-12-29)</h3>
<h4 class="date">Kei Hibino</h4>
</div>
<div id="rough-design" class="titleslide slide section level1"><h1>Rough Design</h1></div><div id="query-dsl-basics" class="slide section level2">
<h1>Query DSL Basics</h1>
<p><span class="LaTeX">$$\{ (x, y) | x \in X, y \in Y, \pi_1(x) = \pi_2(y) \}$$</span></p>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell">[ (x, y) <span class="fu">|</span> x <span class="ot">&lt;-</span> xs, y <span class="ot">&lt;-</span> ys, fst x <span class="fu">==</span> snd y ] <span class="co">-- Comprehension</span>
<span class="kw">do</span> { x <span class="ot">&lt;-</span> xs; y <span class="ot">&lt;-</span> ys; guard (fst x <span class="fu">==</span> snd y); return (x, y) } <span class="co">-- List Monad</span></code></pre></div>
<p>Building a joined query like list comprehension or list Monad:</p>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">personAndBirthday ::</span> <span class="dt">Relation</span> () (<span class="dt">Person</span>, <span class="dt">Birthday</span>)
personAndBirthday <span class="fu">=</span> relation <span class="fu">$</span> <span class="kw">do</span>
p <span class="ot">&lt;-</span> query person <span class="co">-- Join product accumulated</span>
b <span class="ot">&lt;-</span> query birthday
on <span class="fu">$</span> p <span class="fu">!</span> Person.name' <span class="fu">.=.</span> b <span class="fu">!</span> Birthday.name'
return <span class="fu">$</span> p <span class="fu">&gt;&lt;</span> b</code></pre></div>
</div><div id="typing" class="slide section level2">
<h1>Typing</h1>
<p>A simple and useful method:</p>
<ul>
<li>Untype and accumulate from typeful DSL terms into a state monad context</li>
<li>Typeful result</li>
<li>Phantom context and result type</li>
</ul>
</div><div id="state-stack" class="slide section level2">
<h1>State Stack</h1>
<p>Haskell Relational Record's query-building DSL accumulates various context in a state monad context stack.</p>
<ul>
<li>Join product</li>
<li>Aggregate terms</li>
<li>Ordering terms</li>
<li>Restrict predicates</li>
</ul>
</div>
<div id="contexts-in-state" class="titleslide slide section level1"><h1>Contexts in State</h1></div><div id="join-product" class="slide section level2">
<h1>Join Product</h1>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">query ::</span> (<span class="dt">MonadQualify</span> <span class="dt">ConfigureQuery</span> m, <span class="dt">MonadQuery</span> m)
<span class="ot">=&gt;</span> <span class="dt">Relation</span> () r
<span class="ot">-&gt;</span> m (<span class="dt">Projection</span> <span class="dt">Flat</span> r)
<span class="co">-- Used for outer join</span>
<span class="ot">queryMaybe ::</span> (<span class="dt">MonadQualify</span> <span class="dt">ConfigureQuery</span> m, <span class="dt">MonadQuery</span> m)
<span class="ot">=&gt;</span> <span class="dt">Relation</span> () r
<span class="ot">-&gt;</span> m (<span class="dt">Projection</span> <span class="dt">Flat</span> (<span class="dt">Maybe</span> r))
<span class="ot">on ::</span> <span class="dt">MonadQuery</span> m <span class="ot">=&gt;</span> <span class="dt">Projection</span> <span class="dt">Flat</span> (<span class="dt">Maybe</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> m ()</code></pre></div>
<p>'query' and 'queryMaybe' return a Projection type of table form results.</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> .. <span class="kw">FROM</span> ...
<span class="co">-- Accumulating uniquely qualified</span>
<span class="co">-- ( like 'as T0', 'as T1' ... )</span>
<span class="co">-- table forms of SQL FROM clause</span></code></pre></div>
</div><div id="join-example" class="slide section level2">
<h1>Join Example</h1>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">personAndBirthdayL ::</span> <span class="dt">Relation</span> () (<span class="dt">Person</span>, <span class="dt">Maybe</span> <span class="dt">Birthday</span>)
personAndBirthdayL <span class="fu">=</span> relation <span class="fu">$</span> <span class="kw">do</span>
p <span class="ot">&lt;-</span> query person
b <span class="ot">&lt;-</span> queryMaybe birthday
on <span class="fu">$</span> just (p <span class="fu">!</span> Person.name') <span class="fu">.=.</span> b <span class="fu">?!</span> Birthday.name'
return <span class="fu">$</span> p <span class="fu">&gt;&lt;</span> b</code></pre></div>
<p>generates left-joined SQL:</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> <span class="kw">ALL</span> T0.name <span class="kw">AS</span> f0, T0.age <span class="kw">AS</span> f1, T0.address <span class="kw">AS</span> f2,
T1.name <span class="kw">AS</span> f3, T1.day <span class="kw">AS</span> f4
<span class="kw">FROM</span> PUBLIC.person T0 <span class="kw">LEFT</span> <span class="kw">JOIN</span>
PUBLIC.birthday T1
<span class="kw">ON</span> (T0.name = T1.name)</code></pre></div>
</div><div id="aggregation" class="slide section level2">
<h1>Aggregation</h1>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">groupBy ::</span> <span class="dt">MonadAggregate</span> m
<span class="ot">=&gt;</span> <span class="dt">Projection</span> <span class="dt">Flat</span> r
<span class="co">-- ^ Projection to add into group by</span>
<span class="ot">-&gt;</span> m (<span class="dt">Projection</span> <span class="dt">Aggregated</span> r)
<span class="co">-- ^ Result context and aggregated projection</span>
<span class="ot">count ::</span> <span class="dt">Projection</span> <span class="dt">Flat</span> a <span class="ot">-&gt;</span> <span class="dt">Projection</span> <span class="dt">Aggregated</span> <span class="dt">Int64</span>
<span class="ot">max' ::</span> <span class="dt">Ord</span> a
<span class="ot">=&gt;</span> <span class="dt">Projection</span> <span class="dt">Flat</span> a <span class="ot">-&gt;</span> <span class="dt">Projection</span> <span class="dt">Aggregated</span> (<span class="dt">Maybe</span> a)</code></pre></div>
<p>'groupBy' can be used under only 'MonadAggregate' monad constraint, narrower than 'MonadQuery'.</p>
<p>'groupBy' returns a Projection value with an Aggregated context type:</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> .. <span class="kw">GROUP</span> <span class="kw">BY</span> ...
<span class="co">-- Accumulating keys</span>
<span class="co">-- of SQL GROUP BY clause</span></code></pre></div>
</div><div id="aggregation-example" class="slide section level2">
<h1>Aggregation Example</h1>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">agesOfFamilies ::</span> <span class="dt">Relation</span> () (<span class="dt">String</span>, <span class="dt">Maybe</span> <span class="dt">Int32</span>)
agesOfFamilies <span class="fu">=</span> aggregateRelation <span class="fu">$</span> <span class="kw">do</span>
my <span class="ot">&lt;-</span> query myTable
gFam <span class="ot">&lt;-</span> groupBy <span class="fu">$</span> my <span class="fu">!</span> family' <span class="co">-- Specify grouping key</span>
return <span class="fu">$</span> gFam <span class="fu">&gt;&lt;</span> sum' (my <span class="fu">!</span> age') <span class="co">-- Aggregated results</span></code></pre></div>
<p>sums ages per family.</p>
<p>Generated SQL:</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> <span class="kw">ALL</span> T0.family <span class="kw">AS</span> f0, <span class="fu">SUM</span> (T0.age) <span class="kw">AS</span> f1
<span class="kw">FROM</span> PUBLIC.my_table T0
<span class="kw">GROUP</span> <span class="kw">BY</span> T0.family</code></pre></div>
</div><div id="restrict" class="slide section level2">
<h1>Restrict</h1>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">restrict ::</span> <span class="dt">MonadRestrict</span> c m
<span class="ot">=&gt;</span> <span class="dt">Projection</span> c (<span class="dt">Maybe</span> <span class="dt">Bool</span>)
<span class="ot">-&gt;</span> m ()
<span class="ot">wheres ::</span> <span class="dt">MonadRestrict</span> <span class="dt">Flat</span> m
<span class="ot">=&gt;</span> <span class="dt">Projection</span> <span class="dt">Flat</span> (<span class="dt">Maybe</span> <span class="dt">Bool</span>)
<span class="ot">-&gt;</span> m ()</code></pre></div>
<p>adds a WHERE clause restriction:</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> .. <span class="kw">WHERE</span> x <span class="kw">AND</span> y <span class="kw">AND</span> ...
<span class="co">-- Accumulating AND predicates</span>
<span class="co">-- of SQL WHERE clause</span></code></pre></div>
</div><div id="restrict-1" class="slide section level2">
<h1>Restrict</h1>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">restrict ::</span> <span class="dt">MonadRestrict</span> c m
<span class="ot">=&gt;</span> <span class="dt">Projection</span> c (<span class="dt">Maybe</span> <span class="dt">Bool</span>)
<span class="ot">-&gt;</span> m ()
<span class="ot">having ::</span> <span class="dt">MonadRestrict</span> <span class="dt">Aggregated</span> m
<span class="ot">=&gt;</span> <span class="dt">Projection</span> <span class="dt">Aggregated</span> (<span class="dt">Maybe</span> <span class="dt">Bool</span>)
<span class="ot">-&gt;</span> m ()</code></pre></div>
<p>adds a HAVING clause restriction, in which only Projection type values with aggregated context are allowed:</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> .. <span class="kw">HAVING</span> x <span class="kw">AND</span> y <span class="kw">AND</span> ...
<span class="co">-- Accumulating AND predicates</span>
<span class="co">-- of SQL HAVING clause</span></code></pre></div>
</div><div id="restrict-example" class="slide section level2">
<h1>Restrict Example</h1>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">sameBirthdayHeisei' ::</span> <span class="dt">Relation</span> () (<span class="dt">Day</span>, <span class="dt">Int64</span>)
sameBirthdayHeisei' <span class="fu">=</span> aggregateRelation <span class="fu">$</span> <span class="kw">do</span>
p <span class="ot">&lt;-</span> query person
b <span class="ot">&lt;-</span> query birthday
on <span class="fu">$</span> p <span class="fu">!</span> Person.name' <span class="fu">.=.</span> b <span class="fu">!</span> Birthday.name'
wheres <span class="fu">$</span> b <span class="fu">!</span> Birthday.day' <span class="fu">.&gt;=.</span> value (fromGregorian <span class="dv">1989</span> <span class="dv">1</span> <span class="dv">8</span>)
gbd <span class="ot">&lt;-</span> groupBy <span class="fu">$</span> b <span class="fu">!</span> Birthday.day'
having <span class="fu">$</span> count (p <span class="fu">!</span> Person.name') <span class="fu">.&gt;.</span> value <span class="dv">1</span>
return <span class="fu">$</span> gbd <span class="fu">&gt;&lt;</span> count (p <span class="fu">!</span> Person.name')</code></pre></div>
<p>counts people with the same birthday, who were born in the Heisei period.</p>
<p>Generated SQL:</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> <span class="kw">ALL</span> T1.day <span class="kw">AS</span> f0, <span class="fu">COUNT</span> (T0.name) <span class="kw">AS</span> f1
<span class="kw">FROM</span> PUBLIC.person T0 <span class="kw">INNER</span> <span class="kw">JOIN</span> PUBLIC.birthday T1
<span class="kw">ON</span> (T0.name = T1.name)
<span class="kw">WHERE</span> (T1.day &gt;= <span class="dt">DATE</span> <span class="st">'1989-01-08'</span>)
<span class="kw">GROUP</span> <span class="kw">BY</span> T1.day <span class="kw">HAVING</span> (<span class="fu">COUNT</span> (T0.name) &gt; <span class="dv">1</span>)</code></pre></div>
</div><div id="restrict-example-1" class="slide section level2">
<h1>Restrict Example</h1>
<p>Generated SQL:</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> <span class="kw">ALL</span> T1.day <span class="kw">AS</span> f0, <span class="fu">COUNT</span> (T0.name) <span class="kw">AS</span> f1
<span class="kw">FROM</span> PUBLIC.person T0 <span class="kw">INNER</span> <span class="kw">JOIN</span> PUBLIC.birthday T1
<span class="kw">ON</span> (T0.name = T1.name)
<span class="kw">WHERE</span> (T1.day &gt;= <span class="dt">DATE</span> <span class="st">'1989-01-08'</span>)
<span class="kw">GROUP</span> <span class="kw">BY</span> T1.day <span class="kw">HAVING</span> (<span class="fu">COUNT</span> (T0.name) &gt; <span class="dv">1</span>)</code></pre></div>
</div><div id="restrict-example-2" class="slide section level2">
<h1>Restrict Example</h1>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">sameBirthdayHeisei ::</span> <span class="dt">Relation</span> () (<span class="dt">Day</span>, <span class="dt">Int64</span>)
sameBirthdayHeisei <span class="fu">=</span> aggregateRelation <span class="fu">$</span> <span class="kw">do</span>
p <span class="ot">&lt;-</span> query person
b <span class="ot">&lt;-</span> query birthday
on <span class="fu">$</span> p <span class="fu">!</span> Person.name' <span class="fu">.=.</span> b <span class="fu">!</span> Birthday.name'
<span class="kw">let</span> birthDay <span class="fu">=</span> b <span class="fu">!</span> Birthday.day'
wheres <span class="fu">$</span> birthDay <span class="fu">.&gt;=.</span> value (fromGregorian <span class="dv">1989</span> <span class="dv">1</span> <span class="dv">8</span>)
gbd <span class="ot">&lt;-</span> groupBy birthDay
<span class="kw">let</span> personCount <span class="fu">=</span> count <span class="fu">$</span> p <span class="fu">!</span> Person.name'
having <span class="fu">$</span> personCount <span class="fu">.&gt;.</span> value <span class="dv">1</span>
return <span class="fu">$</span> gbd <span class="fu">&gt;&lt;</span> personCount</code></pre></div>
<p>binds using let.</p>
</div><div id="ordering" class="slide section level2">
<h1>Ordering</h1>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">orderBy ::</span> <span class="dt">Monad</span> m
<span class="ot">=&gt;</span> <span class="dt">Projection</span> c t
<span class="co">-- ^ Ordering terms to add</span>
<span class="ot">-&gt;</span> <span class="dt">Order</span>
<span class="co">-- ^ Order direction -- Asc | Desc</span>
<span class="ot">-&gt;</span> <span class="dt">Orderings</span> c m ()
<span class="co">-- ^ Result context with ordering</span></code></pre></div>
<p>Only Projection type values with specified (Flat, Aggregated, ...) context are allowed.</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> .. <span class="kw">ORDER</span> <span class="kw">BY</span> ...
<span class="co">-- Accumulating terms of ORDER BY clause</span></code></pre></div>
</div><div id="ordering-example" class="slide section level2">
<h1>Ordering Example</h1>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">personAndBirthdayO ::</span> <span class="dt">Relation</span> () (<span class="dt">Person</span>, <span class="dt">Birthday</span>)
personAndBirthdayO <span class="fu">=</span> relation <span class="fu">$</span> <span class="kw">do</span>
p <span class="ot">&lt;-</span> query person
b <span class="ot">&lt;-</span> query birthday
on <span class="fu">$</span> p <span class="fu">!</span> Person.name' <span class="fu">.=.</span> b <span class="fu">!</span> Birthday.name'
orderBy (b <span class="fu">!</span> Birthday.day') <span class="dt">Asc</span> <span class="co">-- Specify ordering key</span>
orderBy (p <span class="fu">!</span> Person.name') <span class="dt">Asc</span>
return <span class="fu">$</span> p <span class="fu">&gt;&lt;</span> b</code></pre></div>
<p>orders by birthday and then name:</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> <span class="kw">ALL</span> T0.name <span class="kw">AS</span> f0, T0.age <span class="kw">AS</span> f1, T0.address <span class="kw">AS</span> f2,
T1.name <span class="kw">AS</span> f3, T1.day <span class="kw">AS</span> f4
<span class="kw">FROM</span> PUBLIC.person T0 <span class="kw">INNER</span> <span class="kw">JOIN</span> PUBLIC.birthday T1
<span class="kw">ON</span> (T0.name = T1.name)
<span class="kw">ORDER</span> <span class="kw">BY</span> T1.day <span class="kw">ASC</span>, T0.name <span class="kw">ASC</span></code></pre></div>
</div><div id="ordering-example-1" class="slide section level2">
<h1>Ordering Example</h1>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">birthdayHeiseiDesc ::</span> <span class="dt">Relation</span> () (<span class="dt">Day</span>, <span class="dt">Int64</span>)
birthdayHeiseiDesc <span class="fu">=</span> aggregateRelation <span class="fu">$</span> <span class="kw">do</span>
p <span class="ot">&lt;-</span> query person
b <span class="ot">&lt;-</span> query birthday
on <span class="fu">$</span> p <span class="fu">!</span> Person.name' <span class="fu">.=.</span> b <span class="fu">!</span> Birthday.name'
<span class="kw">let</span> birthDay <span class="fu">=</span> b <span class="fu">!</span> Birthday.day'
wheres <span class="fu">$</span> birthDay <span class="fu">.&gt;=.</span> value (fromGregorian <span class="dv">1989</span> <span class="dv">1</span> <span class="dv">8</span>)
gbd <span class="ot">&lt;-</span> groupBy birthDay
<span class="kw">let</span> personCount <span class="fu">=</span> count <span class="fu">$</span> p <span class="fu">!</span> Person.name'
orderBy personCount <span class="dt">Desc</span>
return <span class="fu">$</span> gbd <span class="fu">&gt;&lt;</span> personCount</code></pre></div>
<p>orders by the number of people born on the same Heisei period dates:</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> <span class="kw">ALL</span> T1.day <span class="kw">AS</span> f0, <span class="fu">COUNT</span> (T0.name) <span class="kw">AS</span> f1
<span class="kw">FROM</span> PUBLIC.person T0 <span class="kw">INNER</span> <span class="kw">JOIN</span> PUBLIC.birthday T1
<span class="kw">ON</span> (T0.name = T1.name)
<span class="kw">WHERE</span> (T1.day &gt;= <span class="dt">DATE</span> <span class="st">'1989-01-08'</span>)
<span class="kw">GROUP</span> <span class="kw">BY</span> T1.day <span class="kw">ORDER</span> <span class="kw">BY</span> <span class="fu">COUNT</span> (T0.name) <span class="kw">DESC</span></code></pre></div>
</div><div id="ordering-example-2" class="slide section level2">
<h1>Ordering Example</h1>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> <span class="kw">ALL</span> T1.day <span class="kw">AS</span> f0, <span class="fu">COUNT</span> (T0.name) <span class="kw">AS</span> f1
<span class="kw">FROM</span> PUBLIC.person T0 <span class="kw">INNER</span> <span class="kw">JOIN</span> PUBLIC.birthday T1
<span class="kw">ON</span> (T0.name = T1.name)
<span class="kw">WHERE</span> (T1.day &gt;= <span class="dt">DATE</span> <span class="st">'1989-01-08'</span>)
<span class="kw">GROUP</span> <span class="kw">BY</span> T1.day <span class="kw">ORDER</span> <span class="kw">BY</span> <span class="fu">COUNT</span> (T0.name) <span class="kw">DESC</span></code></pre></div>
</div>
<div id="other-features" class="titleslide slide section level1"><h1>Other Features</h1></div><div id="placeholders" class="slide section level2">
<h1>Placeholders</h1>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">specifyPerson ::</span> <span class="dt">Relation</span> <span class="dt">String</span> (<span class="dt">Person</span>, <span class="dt">Birthday</span>)
specifyPerson <span class="fu">=</span> relation' <span class="fu">$</span> <span class="kw">do</span>
pb <span class="ot">&lt;-</span> query personAndBirthday <span class="co">-- Re-use predefined</span>
(ph, ()) <span class="ot">&lt;-</span> placeholder
(\ph' <span class="ot">-&gt;</span> wheres <span class="fu">$</span> pb <span class="fu">!</span> fst' <span class="fu">!</span> Person.name' <span class="fu">.=.</span> ph')
return (ph, pb)</code></pre></div>
<p>specifies a person name using a placeholder:</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> <span class="kw">ALL</span> T2.f0 <span class="kw">AS</span> f0, T2.f1 <span class="kw">AS</span> f1, T2.f2 <span class="kw">AS</span> f2,
T2.f3 <span class="kw">AS</span> f3, T2.f4 <span class="kw">AS</span> f4
<span class="kw">FROM</span> (<span class="kw">SELECT</span> <span class="kw">ALL</span>
T0.name <span class="kw">AS</span> f0, T0.age <span class="kw">AS</span> f1, T0.address <span class="kw">AS</span> f2,
T1.name <span class="kw">AS</span> f3, T1.day <span class="kw">AS</span> f4
<span class="kw">FROM</span> PUBLIC.person T0 <span class="kw">INNER</span> <span class="kw">JOIN</span>
PUBLIC.birthday T1
<span class="kw">ON</span> (T0.name = T1.name)) T2
<span class="kw">WHERE</span> (T2.f0 = ?)</code></pre></div>
</div><div id="map-sql-values-to-a-haskell-record" class="slide section level2">
<h1>Map SQL Values to a Haskell Record</h1>
<p>Mapping to records using Applicative style:</p>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">(|$|) ::</span> (<span class="dt">ProjectableFunctor</span> p, <span class="dt">ProductConstructor</span> (a <span class="ot">-&gt;</span> b))
<span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b)
<span class="ot">-&gt;</span> p a
<span class="ot">-&gt;</span> p b
<span class="ot">(|*|) ::</span> <span class="dt">ProjectableApplicative</span> p
<span class="ot">=&gt;</span> p (a <span class="ot">-&gt;</span> b)
<span class="ot">-&gt;</span> p a
<span class="ot">-&gt;</span> p b</code></pre></div>
</div><div id="record-mapping---projections" class="slide section level2">
<h1>Record Mapping - Projections</h1>
<p>Assign record types to an SQL projection:</p>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">personAndBirthdayT ::</span> <span class="dt">Relation</span> () <span class="dt">PersonAndBirthday</span>
personAndBirthdayT <span class="fu">=</span> relation <span class="fu">$</span> <span class="kw">do</span>
p <span class="ot">&lt;-</span> query person
b <span class="ot">&lt;-</span> query birthday
wheres <span class="fu">$</span> p <span class="fu">!</span> Person.name' <span class="fu">.=.</span> b <span class="fu">!</span> Birthday.name'
<span class="co">-- Build record phantom type</span>
return <span class="fu">$</span> <span class="dt">PersonAndBirthday</span> <span class="fu">|$|</span> p <span class="fu">|*|</span> b
<span class="ot">(|$|) ::</span> <span class="dt">ProductConstructor</span> (a <span class="ot">-&gt;</span> b)
<span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Projection</span> c a <span class="ot">-&gt;</span> <span class="dt">Projection</span> c b
<span class="ot">(|*|) ::</span> <span class="dt">Projection</span> c (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Projection</span> c a <span class="ot">-&gt;</span> <span class="dt">Projection</span> c b</code></pre></div>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> <span class="kw">ALL</span> T0.name <span class="kw">AS</span> f0, T0.age <span class="kw">AS</span> f1, T0.address <span class="kw">AS</span> f2,
T1.name <span class="kw">AS</span> f3, T1.day <span class="kw">AS</span> f4
<span class="kw">FROM</span> PUBLIC.person T0 <span class="kw">INNER</span> <span class="kw">JOIN</span> PUBLIC.birthday T1
<span class="kw">ON</span> (T0.name = T1.name)</code></pre></div>
</div><div id="record-mapping---column-selectors" class="slide section level2">
<h1>Record Mapping - Column Selectors</h1>
<p>Column selectors can be mapped to a record:</p>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell">Birthday.day'<span class="ot"> ::</span> <span class="dt">Pi</span> <span class="dt">Birthday</span> <span class="dt">Day</span>
<span class="ot">uncurryPB ::</span> <span class="dt">Pi</span> (<span class="dt">Person</span>, <span class="dt">Birthday</span>) <span class="dt">PersonAndBirthday</span>
uncurryPB <span class="fu">=</span> <span class="dt">PersonAndBirthday</span> <span class="fu">|$|</span> fst' <span class="fu">|*|</span> snd'
<span class="ot">(|$|) ::</span> <span class="dt">ProductConstructor</span> (a <span class="ot">-&gt;</span> b)
<span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Pi</span> r a <span class="ot">-&gt;</span> <span class="dt">Pi</span> r b
<span class="ot">(|*|) ::</span> <span class="dt">Pi</span> r (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Pi</span> r a <span class="ot">-&gt;</span> <span class="dt">Pi</span> r b</code></pre></div>
</div><div id="record-mapping---placeholders" class="slide section level2">
<h1>Record Mapping - Placeholders</h1>
<p>Placeholders can be mapped to a record:</p>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">personAndBirthdayP2 ::</span> <span class="dt">Relation</span> <span class="dt">Person</span> <span class="dt">PersonAndBirthday</span>
personAndBirthdayP2 <span class="fu">=</span> relation' <span class="fu">$</span> <span class="kw">do</span>
p <span class="ot">&lt;-</span> query person
b <span class="ot">&lt;-</span> query birthday
(ph0, ()) <span class="ot">&lt;-</span> placeholder (\ph0' <span class="ot">-&gt;</span> on <span class="fu">$</span> p <span class="fu">!</span> Person.name' <span class="fu">.=.</span> ph0')
(ph1, ()) <span class="ot">&lt;-</span> placeholder (\ph1' <span class="ot">-&gt;</span> on <span class="fu">$</span> p <span class="fu">!</span> Person.age' <span class="fu">.=.</span> ph1')
(ph2, ()) <span class="ot">&lt;-</span> placeholder (\ph2' <span class="ot">-&gt;</span> on <span class="fu">$</span> p <span class="fu">!</span> Person.address' <span class="fu">.=.</span> ph2')
return (<span class="dt">Person</span> <span class="fu">|$|</span> ph0 <span class="fu">|*|</span> ph1 <span class="fu">|*|</span> ph2,
<span class="dt">PersonAndBirthday</span> <span class="fu">|$|</span> p <span class="fu">|*|</span> b)
<span class="ot">(|$|) ::</span> <span class="dt">ProductConstructor</span> (a <span class="ot">-&gt;</span> b)
<span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Placeholders</span> a <span class="ot">-&gt;</span> <span class="dt">Placeholders</span> b
<span class="ot">(|*|) ::</span> <span class="dt">Placeholders</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Placeholders</span> a <span class="ot">-&gt;</span> <span class="dt">Placeholders</span> b</code></pre></div>
<p>Generated SQL:</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> <span class="kw">ALL</span> T0.name <span class="kw">AS</span> f0, T0.age <span class="kw">AS</span> f1, T0.address <span class="kw">AS</span> f2,
T1.name <span class="kw">AS</span> f3, T1.day <span class="kw">AS</span> f4
<span class="kw">FROM</span> PUBLIC.person T0 <span class="kw">INNER</span> <span class="kw">JOIN</span> PUBLIC.birthday T1
<span class="kw">ON</span> (((T0.name = ?) <span class="kw">AND</span> (T0.age = ?)) <span class="kw">AND</span> (T0.address = ?))</code></pre></div>
</div><div id="record-mapping---placeholders-1" class="slide section level2">
<h1>Record Mapping - Placeholders</h1>
<p>Generated SQL:</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> <span class="kw">ALL</span> T0.name <span class="kw">AS</span> f0, T0.age <span class="kw">AS</span> f1, T0.address <span class="kw">AS</span> f2,
T1.name <span class="kw">AS</span> f3, T1.day <span class="kw">AS</span> f4
<span class="kw">FROM</span> PUBLIC.person T0 <span class="kw">INNER</span> <span class="kw">JOIN</span> PUBLIC.birthday T1
<span class="kw">ON</span> (((T0.name = ?) <span class="kw">AND</span> (T0.age = ?)) <span class="kw">AND</span> (T0.address = ?))</code></pre></div>
</div><div id="record-mapping---record-placeholders" class="slide section level2">
<h1>Record Mapping - Record Placeholders</h1>
<p>Record-typed placeholder:</p>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">placeholder ::</span> (<span class="dt">PersistableWidth</span> t, <span class="dt">Monad</span> m)
<span class="ot">=&gt;</span> (<span class="dt">Projection</span> c t <span class="ot">-&gt;</span> m a) <span class="ot">-&gt;</span> m (<span class="dt">PlaceHolders</span> t, a)
<span class="ot">personAndBirthdayP ::</span> <span class="dt">Relation</span> <span class="dt">Person</span> <span class="dt">PersonAndBirthday</span>
personAndBirthdayP <span class="fu">=</span> relation' <span class="fu">$</span> <span class="kw">do</span>
p <span class="ot">&lt;-</span> query person
b <span class="ot">&lt;-</span> query birthday
(ph, ()) <span class="ot">&lt;-</span> placeholder (\ph' <span class="ot">-&gt;</span> wheres <span class="fu">$</span> p <span class="fu">.=.</span> ph')
return <span class="fu">$</span> (ph, <span class="dt">PersonAndBirthday</span> <span class="fu">|$|</span> p <span class="fu">|*|</span> b)</code></pre></div>
<p>row value of Placeholders:</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> <span class="kw">ALL</span> T0.name <span class="kw">AS</span> f0, T0.age <span class="kw">AS</span> f1, T0.address <span class="kw">AS</span> f2,
T1.name <span class="kw">AS</span> f3, T1.day <span class="kw">AS</span> f4
<span class="kw">FROM</span> PUBLIC.person T0 <span class="kw">INNER</span> <span class="kw">JOIN</span> PUBLIC.birthday T1
<span class="kw">ON</span> ((T0.name, T0.age, T0.address) = (?, ?, ?))</code></pre></div>
</div><div id="questions" class="slide section level2">
<h1>Questions?</h1>
</div><div id="window-function" class="slide section level2">
<h1>Window Function</h1>
<p>Monadic-style window building:</p>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">ageRankOfFamilies ::</span> <span class="dt">Relation</span> () ((<span class="dt">Int64</span>, <span class="dt">String</span>), <span class="dt">Int32</span>)
ageRankOfFamilies <span class="fu">=</span> relation <span class="fu">$</span> <span class="kw">do</span>
my <span class="ot">&lt;-</span> query myTable
return <span class="fu">$</span>
rank <span class="ot">`over`</span> <span class="kw">do</span>
partitionBy <span class="fu">$</span> my <span class="fu">!</span> family' <span class="co">-- Monad to build window</span>
orderBy (my <span class="fu">!</span> age') <span class="dt">Desc</span>
<span class="fu">&gt;&lt;</span>
my <span class="fu">!</span> family' <span class="fu">&gt;&lt;</span> my <span class="fu">!</span> age'</code></pre></div>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> <span class="kw">ALL</span>
<span class="fu">RANK</span>() <span class="kw">OVER</span> (<span class="kw">PARTITION</span> <span class="kw">BY</span> T0.family
<span class="kw">ORDER</span> <span class="kw">BY</span> T0.age <span class="kw">DESC</span>) <span class="kw">AS</span> f0,
T0.family <span class="kw">AS</span> f1, T0.age <span class="kw">AS</span> f2
<span class="kw">FROM</span> PUBLIC.my_table T0</code></pre></div>
</div><div id="discussion" class="slide section level2">
<h1>Discussion</h1>
</div>
<div id="others" class="titleslide slide section level1"><h1>Others</h1></div><div id="exists-operator" class="slide section level2">
<h1>exists Operator</h1>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">exists ::</span> (<span class="dt">SqlProjectable</span> p, <span class="dt">ProjectableShowSql</span> p)
<span class="ot">=&gt;</span> <span class="dt">ListProjection</span> (<span class="dt">Projection</span> <span class="dt">Exists</span>) r <span class="ot">-&gt;</span> p (<span class="dt">Maybe</span> <span class="dt">Bool</span>)
<span class="ot">queryList ::</span> <span class="dt">MonadQualify</span> <span class="dt">ConfigureQuery</span> m
<span class="ot">=&gt;</span> <span class="dt">Relation</span> () r
<span class="ot">-&gt;</span> m (<span class="dt">ListProjection</span> (<span class="dt">Projection</span> c) r)</code></pre></div>
</div><div id="in-operator" class="slide section level2">
<h1>in' Operator</h1>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">in' ::</span> (<span class="dt">SqlProjectable</span> p, <span class="dt">ProjectableShowSql</span> p)
<span class="ot">=&gt;</span> p t <span class="ot">-&gt;</span> <span class="dt">ListProjection</span> p t <span class="ot">-&gt;</span> p (<span class="dt">Maybe</span> <span class="dt">Bool</span>)
<span class="ot">queryList ::</span> <span class="dt">MonadQualify</span> <span class="dt">ConfigureQuery</span> m
<span class="ot">=&gt;</span> <span class="dt">Relation</span> () r
<span class="ot">-&gt;</span> m (<span class="dt">ListProjection</span> (<span class="dt">Projection</span> c) r)
<span class="ot">values ::</span> (<span class="dt">ShowConstantTermsSQL</span> t, <span class="dt">SqlProjectable</span> p)
<span class="ot">=&gt;</span> [t] <span class="ot">-&gt;</span> <span class="dt">ListProjection</span> p t</code></pre></div>
</div><div id="scalar-queries" class="slide section level2">
<h1>Scalar Queries</h1>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">queryScalar ::</span> (<span class="dt">MonadQualify</span> <span class="dt">ConfigureQuery</span> m, <span class="dt">ScalarDegree</span> r)
<span class="ot">=&gt;</span> <span class="dt">UniqueRelation</span> () c r
<span class="ot">-&gt;</span> m (<span class="dt">Projection</span> c (<span class="dt">Maybe</span> r))</code></pre></div>
</div>
</div>
</body>
</html>