DIR : /home/kozerus/public_html/jaxgrid.html

/home/kozerus/public_html

<html>
<head>
	<title>jaxgrid.html 20200503_2200</title>

	<link href="../_assets/css/shared.css" rel="stylesheet" type="text/css"/>
	<link href="../_assets/css/examples.css" rel="stylesheet" type="text/css"/>
<!--
	<script src="../_assets/js/examples.js"></script>
	-->

	<style id="style_jasgrid_gridbox" >
		.gridBox {
			float: left;
			width: 150px;
			height: 112px;
			background-color: #363535;
			border-width: thin;
			color: #FFF0EE;
			margin: 1px;
			overflow: hidden;
		}

		.gridBox:hover {
			background-color: #111111;
		}

		.gridBox.error {
			background-color: #992222;
		}

		.gridBox.error LABEL {
			color: #ffffff !important;
		}

		#imageGrid {
			width: 960px;
		}

		#controls {
			height: 25px;
			padding: 5px;
			background-color: rgba(255, 255, 255, 0.2);
		}

		LABEL {
			position: relative;
			top: 10px;
			left: 10px;
			font-family: sans-serif;
			font-size: 12px;
			word-wrap: break-word;
		}

		XMP {
			color: #ffffff;
			font-size: 10px;
		}
	</style>
</head>

<body onload="init_jaxgrid()">

<header class="PreloadJS">
	<h1>Example: Media Grid</h1>

	<p>PreloadJS can load a variety of media. In this example, click each
		example to load its related item.
		Once the item is loaded, it will display (image, svg), play (sound),
		apply to the document (css), or display
		an alert (script). Note that when loading images, sounds, css, scripts,
		or svg locally, you need to ensure
		that PreloadJS uses tag loading to avoid cross-origin errors. Other
		media types will not load locally.</p>
</header>

<div id="controls">
	Click an item to load it. <input type="button"
									 value="Load the entire manifest"
									 onclick="loadManifest()">
</div>

<div id="imageGrid">
	<div id="art/Texas.jpg" onclick="loadAsset(this)" class="gridBox"
		 style="width: 300px; height: 375px;">
		<label>Image</label>
	</div>

	<div id="static/bg.css" onclick="loadAsset(this)" class="gridBox">
		<label>CSS - Background</label>
	</div>

	<div id="static/alert1.js" onclick="loadAsset(this)" class="gridBox">
		<label>JavaScript</label>
	</div>

	<div id="static/grant.xml" onclick="loadAsset(this)" class="gridBox">
		<label>XML</label>
	</div>

	<div id="art/gbot.svg" onclick="loadAsset(this)" class="gridBox"
		 style="width:200px; height:226px; float: right; overflow:hidden">
		<label>SVG</label>
	</div>

	<div id="static/grant.json" onclick="loadAsset(this)" class="gridBox">
		<label>JSON</label>
	</div>

	<div id="static/font.css" onclick="loadAsset(this)" class="gridBox">
		<label>CSS - Font Color</label>
	</div>

	<div id="audio/Thunder.mp3" onclick="loadAsset(this)"
		 class="gridBox">
		<label>Audio</label>
	</div>

	<div id="//gskinner.com/assets/createjs/mapsJSONP.json" type="jsonp"
		 onclick="loadAsset(this)" class="gridBox"
		 style="width:200px; height:73px; float: right; overflow:hidden">
		<label>JSONP<br/>(loaded from gskinner.com)</label>
	</div>

	<div id="art/Autumn.png" onclick="loadAsset(this)" class="gridBox"
		 style="width:454px; height:147px">
		<label>Image</label>
	</div>

	<div id="NoFileHere.png" onclick="loadAsset(this)" class="gridBox"
		 style="width:200px; height:72px;">
		<label>Intentionally missing file<br/>to generate error.</label>
	</div>
</div>


<!--
	<script type="text/javascript" src="../_assets/libs/soundjs-NEXT.min.js"></script>
	-->

	<script id="script_soundjs_next_min_js" 
src="data:/text/plain;base64,LyohCiogQGxpY2Vuc2UgU291bmRKUwoqIFZpc2l0IGh0dHA6Ly9jcmVhdGVqcy5jb20vIGZvciBkb2N1bWVudGF0aW9uLCB1cGRhdGVzIGFuZCBleGFtcGxlcy4KKgoqIENvcHlyaWdodCAoYykgMjAxMS0yMDEzIGdza2lubmVyLmNvbSwgaW5jLgoqCiogRGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBNSVQgbGljZW5zZS4KKiBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLmh0bWwKKgoqIFRoaXMgbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgoqLwoKLyoqIQogKiBTb3VuZEpTIEZsYXNoQXVkaW9QbHVnaW4gYWxzbyBpbmNsdWRlcyBzd2ZvYmplY3QgKGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9zd2ZvYmplY3QvKQogKi8KCnRoaXMuY3JlYXRlanM9dGhpcy5jcmVhdGVqc3x8e30sZnVuY3Rpb24oKXt2YXIgYT1jcmVhdGVqcy5Tb3VuZEpTPWNyZWF0ZWpzLlNvdW5kSlN8fHt9O2EudmVyc2lvbj0iTkVYVCIsYS5idWlsZERhdGU9IlRodSwgMTEgRGVjIDIwMTQgMjM6MTY6MTUgR01UIn0oKSx0aGlzLmNyZWF0ZWpzPXRoaXMuY3JlYXRlanN8fHt9LGNyZWF0ZWpzLmV4dGVuZD1mdW5jdGlvbihhLGIpeyJ1c2Ugc3RyaWN0IjtmdW5jdGlvbiBjKCl7dGhpcy5jb25zdHJ1Y3Rvcj1hfXJldHVybiBjLnByb3RvdHlwZT1iLnByb3RvdHlwZSxhLnByb3RvdHlwZT1uZXcgY30sdGhpcy5jcmVhdGVqcz10aGlzLmNyZWF0ZWpzfHx7fSxjcmVhdGVqcy5wcm9tb3RlPWZ1bmN0aW9uKGEsYil7InVzZSBzdHJpY3QiO3ZhciBjPWEucHJvdG90eXBlLGQ9T2JqZWN0LmdldFByb3RvdHlwZU9mJiZPYmplY3QuZ2V0UHJvdG90eXBlT2YoYyl8fGMuX19wcm90b19fO2lmKGQpe2NbKGIrPSJfIikrImNvbnN0cnVjdG9yIl09ZC5jb25zdHJ1Y3Rvcjtmb3IodmFyIGUgaW4gZCljLmhhc093blByb3BlcnR5KGUpJiYiZnVuY3Rpb24iPT10eXBlb2YgZFtlXSYmKGNbYitlXT1kW2VdKX1yZXR1cm4gYX0sdGhpcy5jcmVhdGVqcz10aGlzLmNyZWF0ZWpzfHx7fSxjcmVhdGVqcy5pbmRleE9mPWZ1bmN0aW9uKGEsYil7InVzZSBzdHJpY3QiO2Zvcih2YXIgYz0wLGQ9YS5sZW5ndGg7ZD5jO2MrKylpZihiPT09YVtjXSlyZXR1cm4gYztyZXR1cm4tMX0sdGhpcy5jcmVhdGVqcz10aGlzLmNyZWF0ZWpzfHx7fSxmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjtjcmVhdGVqcy5wcm94eT1mdW5jdGlvbihhLGIpe3ZhciBjPUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywyKTtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gYS5hcHBseShiLEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywwKS5jb25jYXQoYykpfX19KCksdGhpcy5jcmVhdGVqcz10aGlzLmNyZWF0ZWpzfHx7fSxmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0Ijt2YXIgYT1PYmplY3QuZGVmaW5lUHJvcGVydHk/ITA6ITEsYj17fTt0cnl7T2JqZWN0LmRlZmluZVByb3BlcnR5KGIsImJhciIse2dldDpmdW5jdGlvbigpe3JldHVybiB0aGlzLl9iYXJ9LHNldDpmdW5jdGlvbihhKXt0aGlzLl9iYXI9YX19KX1jYXRjaChjKXthPSExfWNyZWF0ZWpzLmRlZmluZVByb3BlcnR5U3VwcG9ydGVkPWF9KCksdGhpcy5jcmVhdGVqcz10aGlzLmNyZWF0ZWpzfHx7fSxmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjtmdW5jdGlvbiBhKCl7dGhyb3ciQnJvd3NlckRldGVjdCBjYW5ub3QgYmUgaW5zdGFudGlhdGVkIn12YXIgYj1hLmFnZW50PXdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50O2EuaXNXaW5kb3dQaG9uZT1iLmluZGV4T2YoIklFTW9iaWxlIik+LTF8fGIuaW5kZXhPZigiV2luZG93cyBQaG9uZSIpPi0xLGEuaXNGaXJlZm94PWIuaW5kZXhPZigiRmlyZWZveCIpPi0xLGEuaXNPcGVyYT1udWxsIT13aW5kb3cub3BlcmEsYS5pc0Nocm9tZT1iLmluZGV4T2YoIkNocm9tZSIpPi0xLGEuaXNJT1M9KGIuaW5kZXhPZigiaVBvZCIpPi0xfHxiLmluZGV4T2YoImlQaG9uZSIpPi0xfHxiLmluZGV4T2YoImlQYWQiKT4tMSkmJiFhLmlzV2luZG93UGhvbmUsYS5pc0FuZHJvaWQ9Yi5pbmRleE9mKCJBbmRyb2lkIik+LTEmJiFhLmlzV2luZG93UGhvbmUsYS5pc0JsYWNrYmVycnk9Yi5pbmRleE9mKCJCbGFja2JlcnJ5Iik+LTEsY3JlYXRlanMuQnJvd3NlckRldGVjdD1hfSgpLHRoaXMuY3JlYXRlanM9dGhpcy5jcmVhdGVqc3x8e30sZnVuY3Rpb24oKXsidXNlIHN0cmljdCI7ZnVuY3Rpb24gYSgpe3RoaXMuX2xpc3RlbmVycz1udWxsLHRoaXMuX2NhcHR1cmVMaXN0ZW5lcnM9bnVsbH12YXIgYj1hLnByb3RvdHlwZTthLmluaXRpYWxpemU9ZnVuY3Rpb24oYSl7YS5hZGRFdmVudExpc3RlbmVyPWIuYWRkRXZlbnRMaXN0ZW5lcixhLm9uPWIub24sYS5yZW1vdmVFdmVudExpc3RlbmVyPWEub2ZmPWIucmVtb3ZlRXZlbnRMaXN0ZW5lcixhLnJlbW92ZUFsbEV2ZW50TGlzdGVuZXJzPWIucmVtb3ZlQWxsRXZlbnRMaXN0ZW5lcnMsYS5oYXNFdmVudExpc3RlbmVyPWIuaGFzRXZlbnRMaXN0ZW5lcixhLmRpc3BhdGNoRXZlbnQ9Yi5kaXNwYXRjaEV2ZW50LGEuX2Rpc3BhdGNoRXZlbnQ9Yi5fZGlzcGF0Y2hFdmVudCxhLndpbGxUcmlnZ2VyPWIud2lsbFRyaWdnZXJ9LGIuYWRkRXZlbnRMaXN0ZW5lcj1mdW5jdGlvbihhLGIsYyl7dmFyIGQ7ZD1jP3RoaXMuX2NhcHR1cmVMaXN0ZW5lcnM9dGhpcy5fY2FwdHVyZUxpc3RlbmVyc3x8e306dGhpcy5fbGlzdGVuZXJzPXRoaXMuX2xpc3RlbmVyc3x8e307dmFyIGU9ZFthXTtyZXR1cm4gZSYmdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKGEsYixjKSxlPWRbYV0sZT9lLnB1c2goYik6ZFthXT1bYl0sYn0sYi5vbj1mdW5jdGlvbihhLGIsYyxkLGUsZil7cmV0dXJuIGIuaGFuZGxlRXZlbnQmJihjPWN8fGIsYj1iLmhhbmRsZUV2ZW50KSxjPWN8fHRoaXMsdGhpcy5hZGRFdmVudExpc3RlbmVyKGEsZnVuY3Rpb24oYSl7Yi5jYWxsKGMsYSxlKSxkJiZhLnJlbW92ZSgpfSxmKX0sYi5yZW1vdmVFdmVudExpc3RlbmVyPWZ1bmN0aW9uKGEsYixjKXt2YXIgZD1jP3RoaXMuX2NhcHR1cmVMaXN0ZW5lcnM6dGhpcy5fbGlzdGVuZXJzO2lmKGQpe3ZhciBlPWRbYV07aWYoZSlmb3IodmFyIGY9MCxnPWUubGVuZ3RoO2c+ZjtmKyspaWYoZVtmXT09Yil7MT09Zz9kZWxldGUgZFthXTplLnNwbGljZShmLDEpO2JyZWFrfX19LGIub2ZmPWIucmVtb3ZlRXZlbnRMaXN0ZW5lcixiLnJlbW92ZUFsbEV2ZW50TGlzdGVuZXJzPWZ1bmN0aW9uKGEpe2E/KHRoaXMuX2xpc3RlbmVycyYmZGVsZXRlIHRoaXMuX2xpc3RlbmVyc1thXSx0aGlzLl9jYXB0dXJlTGlzdGVuZXJzJiZkZWxldGUgdGhpcy5fY2FwdHVyZUxpc3RlbmVyc1thXSk6dGhpcy5fbGlzdGVuZXJzPXRoaXMuX2NhcHR1cmVMaXN0ZW5lcnM9bnVsbH0sYi5kaXNwYXRjaEV2ZW50PWZ1bmN0aW9uKGEpe2lmKCJzdHJpbmciPT10eXBlb2YgYSl7dmFyIGI9dGhpcy5fbGlzdGVuZXJzO2lmKCFifHwhYlthXSlyZXR1cm4hMTthPW5ldyBjcmVhdGVqcy5FdmVudChhKX1lbHNlIGEudGFyZ2V0JiZhLmNsb25lJiYoYT1hLmNsb25lKCkpO3RyeXthLnRhcmdldD10aGlzfWNhdGNoKGMpe31pZihhLmJ1YmJsZXMmJnRoaXMucGFyZW50KXtmb3IodmFyIGQ9dGhpcyxlPVtkXTtkLnBhcmVudDspZS5wdXNoKGQ9ZC5wYXJlbnQpO3ZhciBmLGc9ZS5sZW5ndGg7Zm9yKGY9Zy0xO2Y+PTAmJiFhLnByb3BhZ2F0aW9uU3RvcHBlZDtmLS0pZVtmXS5fZGlzcGF0Y2hFdmVudChhLDErKDA9PWYpKTtmb3IoZj0xO2c+ZiYmIWEucHJvcGFnYXRpb25TdG9wcGVkO2YrKyllW2ZdLl9kaXNwYXRjaEV2ZW50KGEsMyl9ZWxzZSB0aGlzLl9kaXNwYXRjaEV2ZW50KGEsMik7cmV0dXJuIGEuZGVmYXVsdFByZXZlbnRlZH0sYi5oYXNFdmVudExpc3RlbmVyPWZ1bmN0aW9uKGEpe3ZhciBiPXRoaXMuX2xpc3RlbmVycyxjPXRoaXMuX2NhcHR1cmVMaXN0ZW5lcnM7cmV0dXJuISEoYiYmYlthXXx8YyYmY1thXSl9LGIud2lsbFRyaWdnZXI9ZnVuY3Rpb24oYSl7Zm9yKHZhciBiPXRoaXM7Yjspe2lmKGIuaGFzRXZlbnRMaXN0ZW5lcihhKSlyZXR1cm4hMDtiPWIucGFyZW50fXJldHVybiExfSxiLnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIltFdmVudERpc3BhdGNoZXJdIn0sYi5fZGlzcGF0Y2hFdmVudD1mdW5jdGlvbihhLGIpe3ZhciBjLGQ9MT09Yj90aGlzLl9jYXB0dXJlTGlzdGVuZXJzOnRoaXMuX2xpc3RlbmVycztpZihhJiZkKXt2YXIgZT1kW2EudHlwZV07aWYoIWV8fCEoYz1lLmxlbmd0aCkpcmV0dXJuO3RyeXthLmN1cnJlbnRUYXJnZXQ9dGhpc31jYXRjaChmKXt9dHJ5e2EuZXZlbnRQaGFzZT1ifWNhdGNoKGYpe31hLnJlbW92ZWQ9ITEsZT1lLnNsaWNlKCk7Zm9yKHZhciBnPTA7Yz5nJiYhYS5pbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQ7ZysrKXt2YXIgaD1lW2ddO2guaGFuZGxlRXZlbnQ/aC5oYW5kbGVFdmVudChhKTpoKGEpLGEucmVtb3ZlZCYmKHRoaXMub2ZmKGEudHlwZSxoLDE9PWIpLGEucmVtb3ZlZD0hMSl9fX0sY3JlYXRlanMuRXZlbnREaXNwYXRjaGVyPWF9KCksdGhpcy5jcmVhdGVqcz10aGlzLmNyZWF0ZWpzfHx7fSxmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjtmdW5jdGlvbiBhKGEsYixjKXt0aGlzLnR5cGU9YSx0aGlzLnRhcmdldD1udWxsLHRoaXMuY3VycmVudFRhcmdldD1udWxsLHRoaXMuZXZlbnRQaGFzZT0wLHRoaXMuYnViYmxlcz0hIWIsdGhpcy5jYW5jZWxhYmxlPSEhYyx0aGlzLnRpbWVTdGFtcD0obmV3IERhdGUpLmdldFRpbWUoKSx0aGlzLmRlZmF1bHRQcmV2ZW50ZWQ9ITEsdGhpcy5wcm9wYWdhdGlvblN0b3BwZWQ9ITEsdGhpcy5pbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQ9ITEsdGhpcy5yZW1vdmVkPSExfXZhciBiPWEucHJvdG90eXBlO2IucHJldmVudERlZmF1bHQ9ZnVuY3Rpb24oKXt0aGlzLmRlZmF1bHRQcmV2ZW50ZWQ9dGhpcy5jYW5jZWxhYmxlJiYhMH0sYi5zdG9wUHJvcGFnYXRpb249ZnVuY3Rpb24oKXt0aGlzLnByb3BhZ2F0aW9uU3RvcHBlZD0hMH0sYi5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb249ZnVuY3Rpb24oKXt0aGlzLmltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZD10aGlzLnByb3BhZ2F0aW9uU3RvcHBlZD0hMH0sYi5yZW1vdmU9ZnVuY3Rpb24oKXt0aGlzLnJlbW92ZWQ9ITB9LGIuY2xvbmU9ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IGEodGhpcy50eXBlLHRoaXMuYnViYmxlcyx0aGlzLmNhbmNlbGFibGUpfSxiLnNldD1mdW5jdGlvbihhKXtmb3IodmFyIGIgaW4gYSl0aGlzW2JdPWFbYl07cmV0dXJuIHRoaXN9LGIudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4iW0V2ZW50ICh0eXBlPSIrdGhpcy50eXBlKyIpXSJ9LGNyZWF0ZWpzLkV2ZW50PWF9KCksdGhpcy5jcmVhdGVqcz10aGlzLmNyZWF0ZWpzfHx7fSxmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjtmdW5jdGlvbiBhKGEsYixjKXt0aGlzLkV2ZW50X2NvbnN0cnVjdG9yKCJlcnJvciIpLHRoaXMudGl0bGU9YSx0aGlzLm1lc3NhZ2U9Yix0aGlzLmRhdGE9Y312YXIgYj1jcmVhdGVqcy5leHRlbmQoYSxjcmVhdGVqcy5FdmVudCk7Yi5jbG9uZT1mdW5jdGlvbigpe3JldHVybiBuZXcgY3JlYXRlanMuRXJyb3JFdmVudCh0aGlzLnRpdGxlLHRoaXMubWVzc2FnZSx0aGlzLmRhdGEpfSxjcmVhdGVqcy5FcnJvckV2ZW50PWNyZWF0ZWpzLnByb21vdGUoYSwiRXZlbnQiKX0oKSx0aGlzLmNyZWF0ZWpzPXRoaXMuY3JlYXRlanN8fHt9LGZ1bmN0aW9uKCl7InVzZSBzdHJpY3QiO2Z1bmN0aW9uIGEoYSxiKXt0aGlzLkV2ZW50X2NvbnN0cnVjdG9yKCJwcm9ncmVzcyIpLHRoaXMubG9hZGVkPWEsdGhpcy50b3RhbD1udWxsPT1iPzE6Yix0aGlzLnByb2dyZXNzPTA9PWI/MDp0aGlzLmxvYWRlZC90aGlzLnRvdGFsfXZhciBiPWNyZWF0ZWpzLmV4dGVuZChhLGNyZWF0ZWpzLkV2ZW50KTtiLmNsb25lPWZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBjcmVhdGVqcy5Qcm9ncmVzc0V2ZW50KHRoaXMubG9hZGVkLHRoaXMudG90YWwpfSxjcmVhdGVqcy5Qcm9ncmVzc0V2ZW50PWNyZWF0ZWpzLnByb21vdGUoYSwiRXZlbnQiKX0od2luZG93KSx0aGlzLmNyZWF0ZWpzPXRoaXMuY3JlYXRlanN8fHt9LGZ1bmN0aW9uKCl7InVzZSBzdHJpY3QiO2Z1bmN0aW9uIGEoKXt0aGlzLnNyYz1udWxsLHRoaXMudHlwZT1udWxsLHRoaXMuaWQ9bnVsbCx0aGlzLm1haW50YWluT3JkZXI9ITEsdGhpcy5jYWxsYmFjaz1udWxsLHRoaXMuZGF0YT1udWxsLHRoaXMubWV0aG9kPWNyZWF0ZWpzLkxvYWRJdGVtLkdFVCx0aGlzLnZhbHVlcz1udWxsLHRoaXMuaGVhZGVycz1udWxsLHRoaXMud2l0aENyZWRlbnRpYWxzPSExLHRoaXMubWltZVR5cGU9bnVsbCx0aGlzLmNyb3NzT3JpZ2luPSJBbm9ueW1vdXMiLHRoaXMubG9hZFRpbWVvdXQ9OGUzfXZhciBiPWEucHJvdG90eXBlPXt9LGM9YTtjLmNyZWF0ZT1mdW5jdGlvbihiKXtpZigic3RyaW5nIj09dHlwZW9mIGIpe3ZhciBkPW5ldyBhO3JldHVybiBkLnNyYz1iLGR9aWYoYiBpbnN0YW5jZW9mIGMpcmV0dXJuIGI7aWYoYiBpbnN0YW5jZW9mIE9iamVjdClyZXR1cm4gYjt0aHJvdyBuZXcgRXJyb3IoIlR5cGUgbm90IHJlY29nbml6ZWQuIil9LGIuc2V0PWZ1bmN0aW9uKGEpe2Zvcih2YXIgYiBpbiBhKXRoaXNbYl09YVtiXTtyZXR1cm4gdGhpc30sY3JlYXRlanMuTG9hZEl0ZW09Y30oKSxmdW5jdGlvbigpe3ZhciBhPXt9O2EuQUJTT0xVVEVfUEFUVD0vXig/Olx3KzopP1wvezJ9L2ksYS5SRUxBVElWRV9QQVRUPS9eWy4vXSo/XC8vaSxhLkVYVEVOU0lPTl9QQVRUPS9cLz9bXi9dK1wuKFx3ezEsNX0pJC9pLGEucGFyc2VVUkk9ZnVuY3Rpb24oYil7dmFyIGM9e2Fic29sdXRlOiExLHJlbGF0aXZlOiExfTtpZihudWxsPT1iKXJldHVybiBjO3ZhciBkPWIuaW5kZXhPZigiPyIpO2Q+LTEmJihiPWIuc3Vic3RyKDAsZCkpO3ZhciBlO3JldHVybiBhLkFCU09MVVRFX1BBVFQudGVzdChiKT9jLmFic29sdXRlPSEwOmEuUkVMQVRJVkVfUEFUVC50ZXN0KGIpJiYoYy5yZWxhdGl2ZT0hMCksKGU9Yi5tYXRjaChhLkVYVEVOU0lPTl9QQVRUKSkmJihjLmV4dGVuc2lvbj1lWzFdLnRvTG93ZXJDYXNlKCkpLGN9LGEuZm9ybWF0UXVlcnlTdHJpbmc9ZnVuY3Rpb24oYSxiKXtpZihudWxsPT1hKXRocm93IG5ldyBFcnJvcigiWW91IG11c3Qgc3BlY2lmeSBkYXRhLiIpO3ZhciBjPVtdO2Zvcih2YXIgZCBpbiBhKWMucHVzaChkKyI9Iitlc2NhcGUoYVtkXSkpO3JldHVybiBiJiYoYz1jLmNvbmNhdChiKSksYy5qb2luKCImIil9LGEuYnVpbGRQYXRoPWZ1bmN0aW9uKGEsYil7aWYobnVsbD09YilyZXR1cm4gYTt2YXIgYz1bXSxkPWEuaW5kZXhPZigiPyIpO2lmKC0xIT1kKXt2YXIgZT1hLnNsaWNlKGQrMSk7Yz1jLmNvbmNhdChlLnNwbGl0KCImIikpfXJldHVybi0xIT1kP2Euc2xpY2UoMCxkKSsiPyIrdGhpcy5fZm9ybWF0UXVlcnlTdHJpbmcoYixjKTphKyI/Iit0aGlzLl9mb3JtYXRRdWVyeVN0cmluZyhiLGMpfSxhLmlzQ3Jvc3NEb21haW49ZnVuY3Rpb24oYSl7dmFyIGI9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpO2IuaHJlZj1hLnNyYzt2YXIgYz1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJhIik7Yy5ocmVmPWxvY2F0aW9uLmhyZWY7dmFyIGQ9IiIhPWIuaG9zdG5hbWUmJihiLnBvcnQhPWMucG9ydHx8Yi5wcm90b2NvbCE9Yy5wcm90b2NvbHx8Yi5ob3N0bmFtZSE9Yy5ob3N0bmFtZSk7cmV0dXJuIGR9LGEuaXNMb2NhbD1mdW5jdGlvbihhKXt2YXIgYj1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJhIik7cmV0dXJuIGIuaHJlZj1hLnNyYywiIj09Yi5ob3N0bmFtZSYmImZpbGU6Ij09Yi5wcm90b2NvbH0sYS5pc0JpbmFyeT1mdW5jdGlvbihhKXtzd2l0Y2goYSl7Y2FzZSBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5JTUFHRTpjYXNlIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLkJJTkFSWTpyZXR1cm4hMDtkZWZhdWx0OnJldHVybiExfX0sYS5pc0ltYWdlVGFnPWZ1bmN0aW9uKGEpe3JldHVybiBhIGluc3RhbmNlb2YgSFRNTEltYWdlRWxlbWVudH0sYS5pc0F1ZGlvVGFnPWZ1bmN0aW9uKGEpe3JldHVybiB3aW5kb3cuSFRNTEF1ZGlvRWxlbWVudD9hIGluc3RhbmNlb2YgSFRNTEF1ZGlvRWxlbWVudDohMX0sYS5pc1ZpZGVvVGFnPWZ1bmN0aW9uKGEpe3JldHVybiB3aW5kb3cuSFRNTFZpZGVvRWxlbWVudD9hIGluc3RhbmNlb2YgSFRNTFZpZGVvRWxlbWVudDp2b2lkIDB9LGEuaXNUZXh0PWZ1bmN0aW9uKGEpe3N3aXRjaChhKXtjYXNlIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLlRFWFQ6Y2FzZSBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5KU09OOmNhc2UgY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuTUFOSUZFU1Q6Y2FzZSBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5YTUw6Y2FzZSBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5DU1M6Y2FzZSBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5TVkc6Y2FzZSBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5KQVZBU0NSSVBUOnJldHVybiEwO2RlZmF1bHQ6cmV0dXJuITF9fSxhLmdldFR5cGVCeUV4dGVuc2lvbj1mdW5jdGlvbihhKXtpZihudWxsPT1hKXJldHVybiBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5URVhUO3N3aXRjaChhLnRvTG93ZXJDYXNlKCkpe2Nhc2UianBlZyI6Y2FzZSJqcGciOmNhc2UiZ2lmIjpjYXNlInBuZyI6Y2FzZSJ3ZWJwIjpjYXNlImJtcCI6cmV0dXJuIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLklNQUdFO2Nhc2Uib2dnIjpjYXNlIm1wMyI6Y2FzZSJ3ZWJtIjpyZXR1cm4gY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuU09VTkQ7Y2FzZSJtcDQiOmNhc2Uid2VibSI6Y2FzZSJ0cyI6cmV0dXJuIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLlZJREVPO2Nhc2UianNvbiI6cmV0dXJuIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLkpTT047Y2FzZSJ4bWwiOnJldHVybiBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5YTUw7Y2FzZSJjc3MiOnJldHVybiBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5DU1M7Y2FzZSJqcyI6cmV0dXJuIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLkpBVkFTQ1JJUFQ7Y2FzZSJzdmciOnJldHVybiBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5TVkc7ZGVmYXVsdDpyZXR1cm4gY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuVEVYVH19LGNyZWF0ZWpzLlJlcXVlc3RVdGlscz1hfSgpLHRoaXMuY3JlYXRlanM9dGhpcy5jcmVhdGVqc3x8e30sZnVuY3Rpb24oKXsidXNlIHN0cmljdCI7ZnVuY3Rpb24gYShhLGIsYyl7dGhpcy5FdmVudERpc3BhdGNoZXJfY29uc3RydWN0b3IoKSx0aGlzLmxvYWRlZD0hMSx0aGlzLmNhbmNlbGVkPSExLHRoaXMucHJvZ3Jlc3M9MCx0aGlzLnR5cGU9Yyx0aGlzLnJlc3VsdEZvcm1hdHRlcj1udWxsLHRoaXMuX2l0ZW09YT9jcmVhdGVqcy5Mb2FkSXRlbS5jcmVhdGUoYSk6bnVsbCx0aGlzLl9wcmVmZXJYSFI9Yix0aGlzLl9yZXN1bHQ9bnVsbCx0aGlzLl9yYXdSZXN1bHQ9bnVsbCx0aGlzLl9sb2FkZWRJdGVtcz1udWxsLHRoaXMuX3RhZ1NyY0F0dHJpYnV0ZT1udWxsLHRoaXMuX3RhZz1udWxsfXZhciBiPWNyZWF0ZWpzLmV4dGVuZChhLGNyZWF0ZWpzLkV2ZW50RGlzcGF0Y2hlciksYz1hO2MuUE9TVD0iUE9TVCIsYy5HRVQ9IkdFVCIsYy5CSU5BUlk9ImJpbmFyeSIsYy5DU1M9ImNzcyIsYy5JTUFHRT0iaW1hZ2UiLGMuSkFWQVNDUklQVD0iamF2YXNjcmlwdCIsYy5KU09OPSJqc29uIixjLkpTT05QPSJqc29ucCIsYy5NQU5JRkVTVD0ibWFuaWZlc3QiLGMuU09VTkQ9InNvdW5kIixjLlZJREVPPSJ2aWRlbyIsYy5TUFJJVEVTSEVFVD0ic3ByaXRlc2hlZXQiLGMuU1ZHPSJzdmciLGMuVEVYVD0idGV4dCIsYy5YTUw9InhtbCIsYi5nZXRJdGVtPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuX2l0ZW19LGIuZ2V0UmVzdWx0PWZ1bmN0aW9uKGEpe3JldHVybiBhP3RoaXMuX3Jhd1Jlc3VsdDp0aGlzLl9yZXN1bHR9LGIuZ2V0VGFnPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuX3RhZ30sYi5zZXRUYWc9ZnVuY3Rpb24oYSl7dGhpcy5fdGFnPWF9LGIubG9hZD1mdW5jdGlvbigpe3RoaXMuX2NyZWF0ZVJlcXVlc3QoKSx0aGlzLl9yZXF1ZXN0Lm9uKCJjb21wbGV0ZSIsdGhpcyx0aGlzKSx0aGlzLl9yZXF1ZXN0Lm9uKCJwcm9ncmVzcyIsdGhpcyx0aGlzKSx0aGlzLl9yZXF1ZXN0Lm9uKCJsb2FkU3RhcnQiLHRoaXMsdGhpcyksdGhpcy5fcmVxdWVzdC5vbigiYWJvcnQiLHRoaXMsdGhpcyksdGhpcy5fcmVxdWVzdC5vbigidGltZW91dCIsdGhpcyx0aGlzKSx0aGlzLl9yZXF1ZXN0Lm9uKCJlcnJvciIsdGhpcyx0aGlzKTt2YXIgYT1uZXcgY3JlYXRlanMuRXZlbnQoImluaXRpYWxpemUiKTthLmxvYWRlcj10aGlzLl9yZXF1ZXN0LHRoaXMuZGlzcGF0Y2hFdmVudChhKSx0aGlzLl9yZXF1ZXN0LmxvYWQoKX0sYi5jYW5jZWw9ZnVuY3Rpb24oKXt0aGlzLmNhbmNlbGVkPSEwLHRoaXMuZGVzdHJveSgpfSxiLmRlc3Ryb3k9ZnVuY3Rpb24oKXt0aGlzLl9yZXF1ZXN0JiYodGhpcy5fcmVxdWVzdC5yZW1vdmVBbGxFdmVudExpc3RlbmVycygpLHRoaXMuX3JlcXVlc3QuZGVzdHJveSgpKSx0aGlzLl9yZXF1ZXN0PW51bGwsdGhpcy5faXRlbT1udWxsLHRoaXMuX3Jhd1Jlc3VsdD1udWxsLHRoaXMuX3Jlc3VsdD1udWxsLHRoaXMuX2xvYWRJdGVtcz1udWxsLHRoaXMucmVtb3ZlQWxsRXZlbnRMaXN0ZW5lcnMoKX0sYi5nZXRMb2FkZWRJdGVtcz1mdW5jdGlvbigpe3JldHVybiB0aGlzLl9sb2FkZWRJdGVtc30sYi5fY3JlYXRlUmVxdWVzdD1mdW5jdGlvbigpe3RoaXMuX3JlcXVlc3Q9dGhpcy5fcHJlZmVyWEhSP25ldyBjcmVhdGVqcy5YSFJSZXF1ZXN0KHRoaXMuX2l0ZW0pOm5ldyBjcmVhdGVqcy5UYWdSZXF1ZXN0KHRoaXMuX2l0ZW0sdGhpcy5fdGFnfHx0aGlzLl9jcmVhdGVUYWcoKSx0aGlzLl90YWdTcmNBdHRyaWJ1dGUpfSxiLl9jcmVhdGVUYWc9ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH0sYi5fc2VuZExvYWRTdGFydD1mdW5jdGlvbigpe3RoaXMuX2lzQ2FuY2VsZWQoKXx8dGhpcy5kaXNwYXRjaEV2ZW50KCJsb2Fkc3RhcnQiKX0sYi5fc2VuZFByb2dyZXNzPWZ1bmN0aW9uKGEpe2lmKCF0aGlzLl9pc0NhbmNlbGVkKCkpe3ZhciBiPW51bGw7Im51bWJlciI9PXR5cGVvZiBhPyh0aGlzLnByb2dyZXNzPWEsYj1uZXcgY3JlYXRlanMuUHJvZ3Jlc3NFdmVudCh0aGlzLnByb2dyZXNzKSk6KGI9YSx0aGlzLnByb2dyZXNzPWEubG9hZGVkL2EudG90YWwsYi5wcm9ncmVzcz10aGlzLnByb2dyZXNzLChpc05hTih0aGlzLnByb2dyZXNzKXx8MS8wPT10aGlzLnByb2dyZXNzKSYmKHRoaXMucHJvZ3Jlc3M9MCkpLHRoaXMuaGFzRXZlbnRMaXN0ZW5lcigicHJvZ3Jlc3MiKSYmdGhpcy5kaXNwYXRjaEV2ZW50KGIpfX0sYi5fc2VuZENvbXBsZXRlPWZ1bmN0aW9uKCl7aWYoIXRoaXMuX2lzQ2FuY2VsZWQoKSl7dGhpcy5sb2FkZWQ9ITA7dmFyIGE9bmV3IGNyZWF0ZWpzLkV2ZW50KCJjb21wbGV0ZSIpO2EucmF3UmVzdWx0PXRoaXMuX3Jhd1Jlc3VsdCxudWxsIT10aGlzLl9yZXN1bHQmJihhLnJlc3VsdD10aGlzLl9yZXN1bHQpLHRoaXMuZGlzcGF0Y2hFdmVudChhKX19LGIuX3NlbmRFcnJvcj1mdW5jdGlvbihhKXshdGhpcy5faXNDYW5jZWxlZCgpJiZ0aGlzLmhhc0V2ZW50TGlzdGVuZXIoImVycm9yIikmJihudWxsPT1hJiYoYT1uZXcgY3JlYXRlanMuRXJyb3JFdmVudCgiUFJFTE9BRF9FUlJPUl9FTVBUWSIpKSx0aGlzLmRpc3BhdGNoRXZlbnQoYSkpfSxiLl9pc0NhbmNlbGVkPWZ1bmN0aW9uKCl7cmV0dXJuIG51bGw9PXdpbmRvdy5jcmVhdGVqc3x8dGhpcy5jYW5jZWxlZD8hMDohMX0sYi5yZXN1bHRGb3JtYXR0ZXI9bnVsbCxiLmhhbmRsZUV2ZW50PWZ1bmN0aW9uKGEpe3N3aXRjaChhLnR5cGUpe2Nhc2UiY29tcGxldGUiOnRoaXMuX3Jhd1Jlc3VsdD1hLnRhcmdldC5fcmVzcG9uc2U7dmFyIGI9dGhpcy5yZXN1bHRGb3JtYXR0ZXImJnRoaXMucmVzdWx0Rm9ybWF0dGVyKHRoaXMpLGM9dGhpcztiIGluc3RhbmNlb2YgRnVuY3Rpb24/YihmdW5jdGlvbihhKXtjLl9yZXN1bHQ9YSxjLl9zZW5kQ29tcGxldGUoKX0pOih0aGlzLl9yZXN1bHQ9Ynx8dGhpcy5fcmF3UmVzdWx0LHRoaXMuX3NlbmRDb21wbGV0ZSgpKTticmVhaztjYXNlInByb2dyZXNzIjp0aGlzLl9zZW5kUHJvZ3Jlc3MoYSk7YnJlYWs7Y2FzZSJlcnJvciI6dGhpcy5fc2VuZEVycm9yKGEpO2JyZWFrO2Nhc2UibG9hZHN0YXJ0Ijp0aGlzLl9zZW5kTG9hZFN0YXJ0KCk7YnJlYWs7Y2FzZSJhYm9ydCI6Y2FzZSJ0aW1lb3V0Ijp0aGlzLl9pc0NhbmNlbGVkKCl8fHRoaXMuZGlzcGF0Y2hFdmVudChhLnR5cGUpfX0sYi5idWlsZFBhdGg9ZnVuY3Rpb24oYSxiKXtyZXR1cm4gY3JlYXRlanMuUmVxdWVzdFV0aWxzLmJ1aWxkUGF0aChhLGIpfSxiLnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIltQcmVsb2FkSlMgQWJzdHJhY3RMb2FkZXJdIn0sY3JlYXRlanMuQWJzdHJhY3RMb2FkZXI9Y3JlYXRlanMucHJvbW90ZShhLCJFdmVudERpc3BhdGNoZXIiKX0oKSx0aGlzLmNyZWF0ZWpzPXRoaXMuY3JlYXRlanN8fHt9LGZ1bmN0aW9uKCl7InVzZSBzdHJpY3QiO2Z1bmN0aW9uIGEoYSxiLGMpe3RoaXMuQWJzdHJhY3RMb2FkZXJfY29uc3RydWN0b3IoYSxiLGMpLHRoaXMucmVzdWx0Rm9ybWF0dGVyPXRoaXMuX2Zvcm1hdFJlc3VsdCx0aGlzLl90YWdTcmNBdHRyaWJ1dGU9InNyYyJ9dmFyIGI9Y3JlYXRlanMuZXh0ZW5kKGEsY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIpO2IubG9hZD1mdW5jdGlvbigpe3RoaXMuX3RhZ3x8KHRoaXMuX3RhZz10aGlzLl9jcmVhdGVUYWcodGhpcy5faXRlbS5zcmMpKSx0aGlzLl90YWcucHJlbG9hZD0iYXV0byIsdGhpcy5fdGFnLmxvYWQoKSx0aGlzLkFic3RyYWN0TG9hZGVyX2xvYWQoKX0sYi5fY3JlYXRlVGFnPWZ1bmN0aW9uKCl7fSxiLl9jcmVhdGVSZXF1ZXN0PWZ1bmN0aW9uKCl7dGhpcy5fcmVxdWVzdD10aGlzLl9wcmVmZXJYSFI/bmV3IGNyZWF0ZWpzLlhIUlJlcXVlc3QodGhpcy5faXRlbSk6bmV3IGNyZWF0ZWpzLk1lZGlhVGFnUmVxdWVzdCh0aGlzLl9pdGVtLHRoaXMuX3RhZ3x8dGhpcy5fY3JlYXRlVGFnKCksdGhpcy5fdGFnU3JjQXR0cmlidXRlKX0sYi5fZm9ybWF0UmVzdWx0PWZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLl90YWcucmVtb3ZlRXZlbnRMaXN0ZW5lciYmdGhpcy5fdGFnLnJlbW92ZUV2ZW50TGlzdGVuZXIoImNhbnBsYXl0aHJvdWdoIix0aGlzLl9sb2FkZWRIYW5kbGVyKSx0aGlzLl90YWcub25zdGFsbGVkPW51bGwsdGhpcy5fcHJlZmVyWEhSJiYoYS5nZXRUYWcoKS5zcmM9YS5nZXRSZXN1bHQoITApKSxhLmdldFRhZygpfSxjcmVhdGVqcy5BYnN0cmFjdE1lZGlhTG9hZGVyPWNyZWF0ZWpzLnByb21vdGUoYSwiQWJzdHJhY3RMb2FkZXIiKX0oKSx0aGlzLmNyZWF0ZWpzPXRoaXMuY3JlYXRlanN8fHt9LGZ1bmN0aW9uKCl7InVzZSBzdHJpY3QiO3ZhciBhPWZ1bmN0aW9uKGEpe3RoaXMuX2l0ZW09YX0sYj1jcmVhdGVqcy5leHRlbmQoYSxjcmVhdGVqcy5FdmVudERpc3BhdGNoZXIpO2IubG9hZD1mdW5jdGlvbigpe30sYi5kZXN0cm95PWZ1bmN0aW9uKCl7fSxiLmNhbmNlbD1mdW5jdGlvbigpe30sY3JlYXRlanMuQWJzdHJhY3RSZXF1ZXN0PWNyZWF0ZWpzLnByb21vdGUoYSwiRXZlbnREaXNwYXRjaGVyIil9KCksdGhpcy5jcmVhdGVqcz10aGlzLmNyZWF0ZWpzfHx7fSxmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjtmdW5jdGlvbiBhKGEsYixjKXt0aGlzLkFic3RyYWN0UmVxdWVzdF9jb25zdHJ1Y3RvcihhKSx0aGlzLl90YWc9Yix0aGlzLl90YWdTcmNBdHRyaWJ1dGU9Yyx0aGlzLl9sb2FkZWRIYW5kbGVyPWNyZWF0ZWpzLnByb3h5KHRoaXMuX2hhbmRsZVRhZ0NvbXBsZXRlLHRoaXMpLHRoaXMuX2FkZGVkVG9ET009ITEsdGhpcy5fc3RhcnRUYWdWaXNpYmlsaXR5PW51bGx9dmFyIGI9Y3JlYXRlanMuZXh0ZW5kKGEsY3JlYXRlanMuQWJzdHJhY3RSZXF1ZXN0KTtiLmxvYWQ9ZnVuY3Rpb24oKXtudWxsPT10aGlzLl90YWcucGFyZW50Tm9kZSYmKHdpbmRvdy5kb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMuX3RhZyksdGhpcy5fYWRkZWRUb0RPTT0hMCksdGhpcy5fdGFnLm9ubG9hZD1jcmVhdGVqcy5wcm94eSh0aGlzLl9oYW5kbGVUYWdDb21wbGV0ZSx0aGlzKSx0aGlzLl90YWcub25yZWFkeXN0YXRlY2hhbmdlPWNyZWF0ZWpzLnByb3h5KHRoaXMuX2hhbmRsZVJlYWR5U3RhdGVDaGFuZ2UsdGhpcyk7dmFyIGE9bmV3IGNyZWF0ZWpzLkV2ZW50KCJpbml0aWFsaXplIik7YS5sb2FkZXI9dGhpcy5fdGFnLHRoaXMuZGlzcGF0Y2hFdmVudChhKSx0aGlzLl9oaWRlVGFnKCksdGhpcy5fdGFnW3RoaXMuX3RhZ1NyY0F0dHJpYnV0ZV09dGhpcy5faXRlbS5zcmN9LGIuZGVzdHJveT1mdW5jdGlvbigpe3RoaXMuX2NsZWFuKCksdGhpcy5fdGFnPW51bGwsdGhpcy5BYnN0cmFjdFJlcXVlc3RfZGVzdHJveSgpfSxiLl9oYW5kbGVSZWFkeVN0YXRlQ2hhbmdlPWZ1bmN0aW9uKCl7Y2xlYXJUaW1lb3V0KHRoaXMuX2xvYWRUaW1lb3V0KTt2YXIgYT10aGlzLl90YWc7KCJsb2FkZWQiPT1hLnJlYWR5U3RhdGV8fCJjb21wbGV0ZSI9PWEucmVhZHlTdGF0ZSkmJnRoaXMuX2hhbmRsZVRhZ0NvbXBsZXRlKCl9LGIuX2hhbmRsZVRhZ0NvbXBsZXRlPWZ1bmN0aW9uKCl7dGhpcy5fcmF3UmVzdWx0PXRoaXMuX3RhZyx0aGlzLl9yZXN1bHQ9dGhpcy5yZXN1bHRGb3JtYXR0ZXImJnRoaXMucmVzdWx0Rm9ybWF0dGVyKHRoaXMpfHx0aGlzLl9yYXdSZXN1bHQsdGhpcy5fY2xlYW4oKSx0aGlzLl9zaG93VGFnKCksdGhpcy5kaXNwYXRjaEV2ZW50KCJjb21wbGV0ZSIpfSxiLl9jbGVhbj1mdW5jdGlvbigpe3RoaXMuX3RhZy5vbmxvYWQ9bnVsbCx0aGlzLl90YWcub25yZWFkeXN0YXRlY2hhbmdlPW51bGwsdGhpcy5fYWRkZWRUb0RPTSYmbnVsbCE9dGhpcy5fdGFnLnBhcmVudE5vZGUmJnRoaXMuX3RhZy5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRoaXMuX3RhZyl9LGIuX2hpZGVUYWc9ZnVuY3Rpb24oKXt0aGlzLl9zdGFydFRhZ1Zpc2liaWxpdHk9dGhpcy5fdGFnLnN0eWxlLnZpc2liaWxpdHksdGhpcy5fdGFnLnN0eWxlLnZpc2liaWxpdHk9ImhpZGRlbiJ9LGIuX3Nob3dUYWc9ZnVuY3Rpb24oKXt0aGlzLl90YWcuc3R5bGUudmlzaWJpbGl0eT10aGlzLl9zdGFydFRhZ1Zpc2liaWxpdHl9LGIuX2hhbmRsZVN0YWxsZWQ9ZnVuY3Rpb24oKXt9LGNyZWF0ZWpzLlRhZ1JlcXVlc3Q9Y3JlYXRlanMucHJvbW90ZShhLCJBYnN0cmFjdFJlcXVlc3QiKX0oKSx0aGlzLmNyZWF0ZWpzPXRoaXMuY3JlYXRlanN8fHt9LGZ1bmN0aW9uKCl7InVzZSBzdHJpY3QiO2Z1bmN0aW9uIGEoYSxiLGMpe3RoaXMuQWJzdHJhY3RSZXF1ZXN0X2NvbnN0cnVjdG9yKGEpLHRoaXMuX3RhZz1iLHRoaXMuX3RhZ1NyY0F0dHJpYnV0ZT1jLHRoaXMuX2xvYWRlZEhhbmRsZXI9Y3JlYXRlanMucHJveHkodGhpcy5faGFuZGxlVGFnQ29tcGxldGUsdGhpcyl9dmFyIGI9Y3JlYXRlanMuZXh0ZW5kKGEsY3JlYXRlanMuVGFnUmVxdWVzdCk7Yi5sb2FkPWZ1bmN0aW9uKCl7dGhpcy5fdGFnLm9uc3RhbGxlZD1jcmVhdGVqcy5wcm94eSh0aGlzLl9oYW5kbGVTdGFsbGVkLHRoaXMpLHRoaXMuX3RhZy5vbnByb2dyZXNzPWNyZWF0ZWpzLnByb3h5KHRoaXMuX2hhbmRsZVByb2dyZXNzLHRoaXMpLHRoaXMuX3RhZy5hZGRFdmVudExpc3RlbmVyJiZ0aGlzLl90YWcuYWRkRXZlbnRMaXN0ZW5lcigiY2FucGxheXRocm91Z2giLHRoaXMuX2xvYWRlZEhhbmRsZXIsITEpLHRoaXMuVGFnUmVxdWVzdF9sb2FkKCl9LGIuX2hhbmRsZVJlYWR5U3RhdGVDaGFuZ2U9ZnVuY3Rpb24oKXtjbGVhclRpbWVvdXQodGhpcy5fbG9hZFRpbWVvdXQpO3ZhciBhPXRoaXMuX3RhZzsoImxvYWRlZCI9PWEucmVhZHlTdGF0ZXx8ImNvbXBsZXRlIj09YS5yZWFkeVN0YXRlKSYmdGhpcy5faGFuZGxlVGFnQ29tcGxldGUoKX0sYi5faGFuZGxlU3RhbGxlZD1mdW5jdGlvbigpe30sYi5faGFuZGxlUHJvZ3Jlc3M9ZnVuY3Rpb24oYSl7aWYoYSYmIShhLmxvYWRlZD4wJiYwPT1hLnRvdGFsKSl7dmFyIGI9bmV3IGNyZWF0ZWpzLlByb2dyZXNzRXZlbnQoYS5sb2FkZWQsYS50b3RhbCk7dGhpcy5kaXNwYXRjaEV2ZW50KGIpfX0sYi5fY2xlYW49ZnVuY3Rpb24oKXt0aGlzLl90YWcucmVtb3ZlRXZlbnRMaXN0ZW5lciYmdGhpcy5fdGFnLnJlbW92ZUV2ZW50TGlzdGVuZXIoImNhbnBsYXl0aHJvdWdoIix0aGlzLl9sb2FkZWRIYW5kbGVyKSx0aGlzLl90YWcub25zdGFsbGVkPW51bGwsdGhpcy5fdGFnLm9ucHJvZ3Jlc3M9bnVsbCx0aGlzLlRhZ1JlcXVlc3RfX2NsZWFuKCl9LGNyZWF0ZWpzLk1lZGlhVGFnUmVxdWVzdD1jcmVhdGVqcy5wcm9tb3RlKGEsIlRhZ1JlcXVlc3QiKX0oKSx0aGlzLmNyZWF0ZWpzPXRoaXMuY3JlYXRlanN8fHt9LGZ1bmN0aW9uKCl7InVzZSBzdHJpY3QiO2Z1bmN0aW9uIGEoYSl7dGhpcy5BYnN0cmFjdFJlcXVlc3RfY29uc3RydWN0b3IoYSksdGhpcy5fcmVxdWVzdD1udWxsLHRoaXMuX2xvYWRUaW1lb3V0PW51bGwsdGhpcy5feGhyTGV2ZWw9MSx0aGlzLl9yZXNwb25zZT1udWxsLHRoaXMuX3Jhd1Jlc3BvbnNlPW51bGwsdGhpcy5fY2FuY2VsZWQ9ITEsdGhpcy5faGFuZGxlTG9hZFN0YXJ0UHJveHk9Y3JlYXRlanMucHJveHkodGhpcy5faGFuZGxlTG9hZFN0YXJ0LHRoaXMpLHRoaXMuX2hhbmRsZVByb2dyZXNzUHJveHk9Y3JlYXRlanMucHJveHkodGhpcy5faGFuZGxlUHJvZ3Jlc3MsdGhpcyksdGhpcy5faGFuZGxlQWJvcnRQcm94eT1jcmVhdGVqcy5wcm94eSh0aGlzLl9oYW5kbGVBYm9ydCx0aGlzKSx0aGlzLl9oYW5kbGVFcnJvclByb3h5PWNyZWF0ZWpzLnByb3h5KHRoaXMuX2hhbmRsZUVycm9yLHRoaXMpLHRoaXMuX2hhbmRsZVRpbWVvdXRQcm94eT1jcmVhdGVqcy5wcm94eSh0aGlzLl9oYW5kbGVUaW1lb3V0LHRoaXMpLHRoaXMuX2hhbmRsZUxvYWRQcm94eT1jcmVhdGVqcy5wcm94eSh0aGlzLl9oYW5kbGVMb2FkLHRoaXMpLHRoaXMuX2hhbmRsZVJlYWR5U3RhdGVDaGFuZ2VQcm94eT1jcmVhdGVqcy5wcm94eSh0aGlzLl9oYW5kbGVSZWFkeVN0YXRlQ2hhbmdlLHRoaXMpLCF0aGlzLl9jcmVhdGVYSFIoYSl9dmFyIGI9Y3JlYXRlanMuZXh0ZW5kKGEsY3JlYXRlanMuQWJzdHJhY3RSZXF1ZXN0KTthLkFDVElWRVhfVkVSU0lPTlM9WyJNc3htbDIuWE1MSFRUUC42LjAiLCJNc3htbDIuWE1MSFRUUC41LjAiLCJNc3htbDIuWE1MSFRUUC40LjAiLCJNU1hNTDIuWE1MSFRUUC4zLjAiLCJNU1hNTDIuWE1MSFRUUCIsIk1pY3Jvc29mdC5YTUxIVFRQIl0sYi5nZXRSZXN1bHQ9ZnVuY3Rpb24oYSl7cmV0dXJuIGEmJnRoaXMuX3Jhd1Jlc3BvbnNlP3RoaXMuX3Jhd1Jlc3BvbnNlOnRoaXMuX3Jlc3BvbnNlfSxiLmNhbmNlbD1mdW5jdGlvbigpe3RoaXMuY2FuY2VsZWQ9ITAsdGhpcy5fY2xlYW4oKSx0aGlzLl9yZXF1ZXN0LmFib3J0KCl9LGIubG9hZD1mdW5jdGlvbigpe2lmKG51bGw9PXRoaXMuX3JlcXVlc3QpcmV0dXJuIHZvaWQgdGhpcy5faGFuZGxlRXJyb3IoKTt0aGlzLl9yZXF1ZXN0LmFkZEV2ZW50TGlzdGVuZXIoImxvYWRzdGFydCIsdGhpcy5faGFuZGxlTG9hZFN0YXJ0UHJveHksITEpLHRoaXMuX3JlcXVlc3QuYWRkRXZlbnRMaXN0ZW5lcigicHJvZ3Jlc3MiLHRoaXMuX2hhbmRsZVByb2dyZXNzUHJveHksITEpLHRoaXMuX3JlcXVlc3QuYWRkRXZlbnRMaXN0ZW5lcigiYWJvcnQiLHRoaXMuX2hhbmRsZUFib3J0UHJveHksITEpLHRoaXMuX3JlcXVlc3QuYWRkRXZlbnRMaXN0ZW5lcigiZXJyb3IiLHRoaXMuX2hhbmRsZUVycm9yUHJveHksITEpLHRoaXMuX3JlcXVlc3QuYWRkRXZlbnRMaXN0ZW5lcigidGltZW91dCIsdGhpcy5faGFuZGxlVGltZW91dFByb3h5LCExKSx0aGlzLl9yZXF1ZXN0LmFkZEV2ZW50TGlzdGVuZXIoImxvYWQiLHRoaXMuX2hhbmRsZUxvYWRQcm94eSwhMSksdGhpcy5fcmVxdWVzdC5hZGRFdmVudExpc3RlbmVyKCJyZWFkeXN0YXRlY2hhbmdlIix0aGlzLl9oYW5kbGVSZWFkeVN0YXRlQ2hhbmdlUHJveHksITEpLDE9PXRoaXMuX3hockxldmVsJiYodGhpcy5fbG9hZFRpbWVvdXQ9c2V0VGltZW91dChjcmVhdGVqcy5wcm94eSh0aGlzLl9oYW5kbGVUaW1lb3V0LHRoaXMpLHRoaXMuX2l0ZW0ubG9hZFRpbWVvdXQpKTt0cnl7dGhpcy5faXRlbS52YWx1ZXMmJnRoaXMuX2l0ZW0ubWV0aG9kIT1jcmVhdGVqcy5BYnN0cmFjdExvYWRlci5HRVQ/dGhpcy5faXRlbS5tZXRob2Q9PWNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLlBPU1QmJnRoaXMuX3JlcXVlc3Quc2VuZChjcmVhdGVqcy5SZXF1ZXN0VXRpbHMuZm9ybWF0UXVlcnlTdHJpbmcodGhpcy5faXRlbS52YWx1ZXMpKTp0aGlzLl9yZXF1ZXN0LnNlbmQoKX1jYXRjaChhKXt0aGlzLmRpc3BhdGNoRXZlbnQobmV3IGNyZWF0ZWpzLkVycm9yRXZlbnQoIlhIUl9TRU5EIixudWxsLGEpKX19LGIuc2V0UmVzcG9uc2VUeXBlPWZ1bmN0aW9uKGEpe3RoaXMuX3JlcXVlc3QucmVzcG9uc2VUeXBlPWF9LGIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuX3JlcXVlc3QuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzIGluc3RhbmNlb2YgRnVuY3Rpb24/dGhpcy5fcmVxdWVzdC5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKTpudWxsfSxiLmdldFJlc3BvbnNlSGVhZGVyPWZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLl9yZXF1ZXN0LmdldFJlc3BvbnNlSGVhZGVyIGluc3RhbmNlb2YgRnVuY3Rpb24/dGhpcy5fcmVxdWVzdC5nZXRSZXNwb25zZUhlYWRlcihhKTpudWxsfSxiLl9oYW5kbGVQcm9ncmVzcz1mdW5jdGlvbihhKXtpZihhJiYhKGEubG9hZGVkPjAmJjA9PWEudG90YWwpKXt2YXIgYj1uZXcgY3JlYXRlanMuUHJvZ3Jlc3NFdmVudChhLmxvYWRlZCxhLnRvdGFsKTt0aGlzLmRpc3BhdGNoRXZlbnQoYil9fSxiLl9oYW5kbGVMb2FkU3RhcnQ9ZnVuY3Rpb24oKXtjbGVhclRpbWVvdXQodGhpcy5fbG9hZFRpbWVvdXQpLHRoaXMuZGlzcGF0Y2hFdmVudCgibG9hZHN0YXJ0Iil9LGIuX2hhbmRsZUFib3J0PWZ1bmN0aW9uKGEpe3RoaXMuX2NsZWFuKCksdGhpcy5kaXNwYXRjaEV2ZW50KG5ldyBjcmVhdGVqcy5FcnJvckV2ZW50KCJYSFJfQUJPUlRFRCIsbnVsbCxhKSl9LGIuX2hhbmRsZUVycm9yPWZ1bmN0aW9uKGEpe3RoaXMuX2NsZWFuKCksdGhpcy5kaXNwYXRjaEV2ZW50KG5ldyBjcmVhdGVqcy5FcnJvckV2ZW50KGEubWVzc2FnZSkpfSxiLl9oYW5kbGVSZWFkeVN0YXRlQ2hhbmdlPWZ1bmN0aW9uKCl7ND09dGhpcy5fcmVxdWVzdC5yZWFkeVN0YXRlJiZ0aGlzLl9oYW5kbGVMb2FkKCl9LGIuX2hhbmRsZUxvYWQ9ZnVuY3Rpb24oKXtpZighdGhpcy5sb2FkZWQpe3RoaXMubG9hZGVkPSEwO3ZhciBhPXRoaXMuX2NoZWNrRXJyb3IoKTtpZihhKXJldHVybiB2b2lkIHRoaXMuX2hhbmRsZUVycm9yKGEpO3RoaXMuX3Jlc3BvbnNlPXRoaXMuX2dldFJlc3BvbnNlKCksdGhpcy5fY2xlYW4oKSx0aGlzLmRpc3BhdGNoRXZlbnQobmV3IGNyZWF0ZWpzLkV2ZW50KCJjb21wbGV0ZSIpKX19LGIuX2hhbmRsZVRpbWVvdXQ9ZnVuY3Rpb24oYSl7dGhpcy5fY2xlYW4oKSx0aGlzLmRpc3BhdGNoRXZlbnQobmV3IGNyZWF0ZWpzLkVycm9yRXZlbnQoIlBSRUxPQURfVElNRU9VVCIsbnVsbCxhKSl9LGIuX2NoZWNrRXJyb3I9ZnVuY3Rpb24oKXt2YXIgYT1wYXJzZUludCh0aGlzLl9yZXF1ZXN0LnN0YXR1cyk7c3dpdGNoKGEpe2Nhc2UgNDA0OmNhc2UgMDpyZXR1cm4gbmV3IEVycm9yKGEpfXJldHVybiBudWxsfSxiLl9nZXRSZXNwb25zZT1mdW5jdGlvbigpe2lmKG51bGwhPXRoaXMuX3Jlc3BvbnNlKXJldHVybiB0aGlzLl9yZXNwb25zZTtpZihudWxsIT10aGlzLl9yZXF1ZXN0LnJlc3BvbnNlKXJldHVybiB0aGlzLl9yZXF1ZXN0LnJlc3BvbnNlO3RyeXtpZihudWxsIT10aGlzLl9yZXF1ZXN0LnJlc3BvbnNlVGV4dClyZXR1cm4gdGhpcy5fcmVxdWVzdC5yZXNwb25zZVRleHR9Y2F0Y2goYSl7fXRyeXtpZihudWxsIT10aGlzLl9yZXF1ZXN0LnJlc3BvbnNlWE1MKXJldHVybiB0aGlzLl9yZXF1ZXN0LnJlc3BvbnNlWE1MfWNhdGNoKGEpe31yZXR1cm4gbnVsbH0sYi5fY3JlYXRlWEhSPWZ1bmN0aW9uKGEpe3ZhciBiPWNyZWF0ZWpzLlJlcXVlc3RVdGlscy5pc0Nyb3NzRG9tYWluKGEpLGM9e30sZD1udWxsO2lmKHdpbmRvdy5YTUxIdHRwUmVxdWVzdClkPW5ldyBYTUxIdHRwUmVxdWVzdCxiJiZ2b2lkIDA9PT1kLndpdGhDcmVkZW50aWFscyYmd2luZG93LlhEb21haW5SZXF1ZXN0JiYoZD1uZXcgWERvbWFpblJlcXVlc3QpO2Vsc2V7Zm9yKHZhciBlPTAsZj1zLkFDVElWRVhfVkVSU0lPTlMubGVuZ3RoO2Y+ZTtlKyspe3tzLkFDVElWRVhfVkVSU0lPTlNbZV19dHJ5e2Q9bmV3IEFjdGl2ZVhPYmplY3QoYXhWZXJzaW9ucyk7YnJlYWt9Y2F0Y2goZyl7fX1pZihudWxsPT1kKXJldHVybiExfWEubWltZVR5cGUmJmQub3ZlcnJpZGVNaW1lVHlwZSYmZC5vdmVycmlkZU1pbWVUeXBlKGEubWltZVR5cGUpLHRoaXMuX3hockxldmVsPSJzdHJpbmciPT10eXBlb2YgZC5yZXNwb25zZVR5cGU/MjoxO3ZhciBoPW51bGw7aWYoaD1hLm1ldGhvZD09Y3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuR0VUP2NyZWF0ZWpzLlJlcXVlc3RVdGlscy5idWlsZFBhdGgoYS5zcmMsYS52YWx1ZXMpOmEuc3JjLGQub3BlbihhLm1ldGhvZHx8Y3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuR0VULGgsITApLGImJmQgaW5zdGFuY2VvZiBYTUxIdHRwUmVxdWVzdCYmMT09dGhpcy5feGhyTGV2ZWwmJihjLk9yaWdpbj1sb2NhdGlvbi5vcmlnaW4pLGEudmFsdWVzJiZhLm1ldGhvZD09Y3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuUE9TVCYmKGNbIkNvbnRlbnQtVHlwZSJdPSJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQiKSxifHxjWyJYLVJlcXVlc3RlZC1XaXRoIl18fChjWyJYLVJlcXVlc3RlZC1XaXRoIl09IlhNTEh0dHBSZXF1ZXN0IiksYS5oZWFkZXJzKWZvcih2YXIgaSBpbiBhLmhlYWRlcnMpY1tpXT1hLmhlYWRlcnNbaV07Zm9yKGkgaW4gYylkLnNldFJlcXVlc3RIZWFkZXIoaSxjW2ldKTtyZXR1cm4gZCBpbnN0YW5jZW9mIFhNTEh0dHBSZXF1ZXN0JiZ2b2lkIDAhPT1hLndpdGhDcmVkZW50aWFscyYmKGQud2l0aENyZWRlbnRpYWxzPWEud2l0aENyZWRlbnRpYWxzKSx0aGlzLl9yZXF1ZXN0PWQsITB9LGIuX2NsZWFuPWZ1bmN0aW9uKCl7Y2xlYXJUaW1lb3V0KHRoaXMuX2xvYWRUaW1lb3V0KSx0aGlzLl9yZXF1ZXN0LnJlbW92ZUV2ZW50TGlzdGVuZXIoImxvYWRzdGFydCIsdGhpcy5faGFuZGxlTG9hZFN0YXJ0UHJveHkpLHRoaXMuX3JlcXVlc3QucmVtb3ZlRXZlbnRMaXN0ZW5lcigicHJvZ3Jlc3MiLHRoaXMuX2hhbmRsZVByb2dyZXNzUHJveHkpLHRoaXMuX3JlcXVlc3QucmVtb3ZlRXZlbnRMaXN0ZW5lcigiYWJvcnQiLHRoaXMuX2hhbmRsZUFib3J0UHJveHkpLHRoaXMuX3JlcXVlc3QucmVtb3ZlRXZlbnRMaXN0ZW5lcigiZXJyb3IiLHRoaXMuX2hhbmRsZUVycm9yUHJveHkpLHRoaXMuX3JlcXVlc3QucmVtb3ZlRXZlbnRMaXN0ZW5lcigidGltZW91dCIsdGhpcy5faGFuZGxlVGltZW91dFByb3h5KSx0aGlzLl9yZXF1ZXN0LnJlbW92ZUV2ZW50TGlzdGVuZXIoImxvYWQiLHRoaXMuX2hhbmRsZUxvYWRQcm94eSksdGhpcy5fcmVxdWVzdC5yZW1vdmVFdmVudExpc3RlbmVyKCJyZWFkeXN0YXRlY2hhbmdlIix0aGlzLl9oYW5kbGVSZWFkeVN0YXRlQ2hhbmdlUHJveHkpfSxiLnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIltQcmVsb2FkSlMgWEhSUmVxdWVzdF0ifSxjcmVhdGVqcy5YSFJSZXF1ZXN0PWNyZWF0ZWpzLnByb21vdGUoYSwiQWJzdHJhY3RSZXF1ZXN0Iil9KCksdGhpcy5jcmVhdGVqcz10aGlzLmNyZWF0ZWpzfHx7fSxmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjtmdW5jdGlvbiBhKGEsYil7dGhpcy5BYnN0cmFjdE1lZGlhTG9hZGVyX2NvbnN0cnVjdG9yKGEsYixjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5TT1VORCksY3JlYXRlanMuUmVxdWVzdFV0aWxzLmlzQXVkaW9UYWcoYSk/dGhpcy5fdGFnPWE6Y3JlYXRlanMuUmVxdWVzdFV0aWxzLmlzQXVkaW9UYWcoYS5zcmMpP3RoaXMuX3RhZz1hOmNyZWF0ZWpzLlJlcXVlc3RVdGlscy5pc0F1ZGlvVGFnKGEudGFnKSYmKHRoaXMuX3RhZz1jcmVhdGVqcy5SZXF1ZXN0VXRpbHMuaXNBdWRpb1RhZyhhKT9hOmEuc3JjKSxudWxsIT10aGlzLl90YWcmJih0aGlzLl9wcmVmZXJYSFI9ITEpfXZhciBiPWNyZWF0ZWpzLmV4dGVuZChhLGNyZWF0ZWpzLkFic3RyYWN0TWVkaWFMb2FkZXIpLGM9YTtjLmNhbkxvYWRJdGVtPWZ1bmN0aW9uKGEpe3JldHVybiBhLnR5cGU9PWNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLlNPVU5EfSxiLl9jcmVhdGVUYWc9ZnVuY3Rpb24oYSl7dmFyIGI9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYXVkaW8iKTtyZXR1cm4gYi5hdXRvcGxheT0hMSxiLnByZWxvYWQ9Im5vbmUiLGIuc3JjPWEsYn0sY3JlYXRlanMuU291bmRMb2FkZXI9Y3JlYXRlanMucHJvbW90ZShhLCJBYnN0cmFjdE1lZGlhTG9hZGVyIil9KCksdGhpcy5jcmVhdGVqcz10aGlzLmNyZWF0ZWpzfHx7fSxmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjtmdW5jdGlvbiBhKCl7dGhyb3ciU291bmQgY2Fubm90IGJlIGluc3RhbnRpYXRlZCJ9ZnVuY3Rpb24gYihhLGIpe3RoaXMuaW5pdChhLGIpfXZhciBjPWE7Yy5JTlRFUlJVUFRfQU5ZPSJhbnkiLGMuSU5URVJSVVBUX0VBUkxZPSJlYXJseSIsYy5JTlRFUlJVUFRfTEFURT0ibGF0ZSIsYy5JTlRFUlJVUFRfTk9ORT0ibm9uZSIsYy5QTEFZX0lOSVRFRD0icGxheUluaXRlZCIsYy5QTEFZX1NVQ0NFRURFRD0icGxheVN1Y2NlZWRlZCIsYy5QTEFZX0lOVEVSUlVQVEVEPSJwbGF5SW50ZXJydXB0ZWQiLGMuUExBWV9GSU5JU0hFRD0icGxheUZpbmlzaGVkIixjLlBMQVlfRkFJTEVEPSJwbGF5RmFpbGVkIixjLlNVUFBPUlRFRF9FWFRFTlNJT05TPVsibXAzIiwib2dnIiwibXBlZyIsIndhdiIsIm00YSIsIm1wNCIsImFpZmYiLCJ3bWEiLCJtaWQiXSxjLkVYVEVOU0lPTl9NQVA9e200YToibXA0In0sYy5GSUxFX1BBVFRFUk49L14oPzooXHcrOilcL3syfShcdysoPzpcLlx3KykqXC8/KSk/KFsvLl0qPyg/OlteP10rKT9cLyk/KCg/OlteLz9dKylcLihcdyspKSg/Olw/KFxTKyk/KT8kLyxjLmRlZmF1bHRJbnRlcnJ1cHRCZWhhdmlvcj1jLklOVEVSUlVQVF9OT05FLGMuYWx0ZXJuYXRlRXh0ZW5zaW9ucz1bXSxjLmFjdGl2ZVBsdWdpbj1udWxsLGMuX3BsdWdpbnNSZWdpc3RlcmVkPSExLGMuX2xhc3RJRD0wLGMuX21hc3RlclZvbHVtZT0xLGMuX21hc3Rlck11dGU9ITEsYy5faW5zdGFuY2VzPVtdLGMuX2lkSGFzaD17fSxjLl9wcmVsb2FkSGFzaD17fSxjLmFkZEV2ZW50TGlzdGVuZXI9bnVsbCxjLnJlbW92ZUV2ZW50TGlzdGVuZXI9bnVsbCxjLnJlbW92ZUFsbEV2ZW50TGlzdGVuZXJzPW51bGwsYy5kaXNwYXRjaEV2ZW50PW51bGwsYy5oYXNFdmVudExpc3RlbmVyPW51bGwsYy5fbGlzdGVuZXJzPW51bGwsY3JlYXRlanMuRXZlbnREaXNwYXRjaGVyLmluaXRpYWxpemUoYyksYy5nZXRQcmVsb2FkSGFuZGxlcnM9ZnVuY3Rpb24oKXtyZXR1cm57Y2FsbGJhY2s6Y3JlYXRlanMucHJveHkoYy5pbml0TG9hZCxjKSx0eXBlczpbInNvdW5kIl0sZXh0ZW5zaW9uczpjLlNVUFBPUlRFRF9FWFRFTlNJT05TfX0sYy5faGFuZGxlTG9hZENvbXBsZXRlPWZ1bmN0aW9uKGEpe3ZhciBiPWEudGFyZ2V0LmdldEl0ZW0oKS5zcmM7aWYoYy5fcHJlbG9hZEhhc2hbYl0pZm9yKHZhciBkPTAsZT1jLl9wcmVsb2FkSGFzaFtiXS5sZW5ndGg7ZT5kO2QrKyl7dmFyIGY9Yy5fcHJlbG9hZEhhc2hbYl1bZF07aWYoYy5fcHJlbG9hZEhhc2hbYl1bZF09ITAsYy5oYXNFdmVudExpc3RlbmVyKCJmaWxlbG9hZCIpKXt2YXIgYT1uZXcgY3JlYXRlanMuRXZlbnQoImZpbGVsb2FkIik7YS5zcmM9Zi5zcmMsYS5pZD1mLmlkLGEuZGF0YT1mLmRhdGEsYS5zcHJpdGU9Zi5zcHJpdGUsYy5kaXNwYXRjaEV2ZW50KGEpfX19LGMuX2hhbmRsZUxvYWRFcnJvcj1mdW5jdGlvbihhKXt2YXIgYj1hLnRhcmdldC5nZXRJdGVtKCkuc3JjO2lmKGMuX3ByZWxvYWRIYXNoW2JdKWZvcih2YXIgZD0wLGU9Yy5fcHJlbG9hZEhhc2hbYl0ubGVuZ3RoO2U+ZDtkKyspe3ZhciBmPWMuX3ByZWxvYWRIYXNoW2JdW2RdO2lmKGMuX3ByZWxvYWRIYXNoW2JdW2RdPSExLGMuaGFzRXZlbnRMaXN0ZW5lcigiZmlsZWVycm9yIikpe3ZhciBhPW5ldyBjcmVhdGVqcy5FdmVudCgiZmlsZWVycm9yIik7YS5zcmM9Zi5zcmMsYS5pZD1mLmlkLGEuZGF0YT1mLmRhdGEsYS5zcHJpdGU9Zi5zcHJpdGUsYy5kaXNwYXRjaEV2ZW50KGEpfX19LGMuX3JlZ2lzdGVyUGx1Z2luPWZ1bmN0aW9uKGEpe3JldHVybiBhLmlzU3VwcG9ydGVkKCk/KGMuYWN0aXZlUGx1Z2luPW5ldyBhLCEwKTohMX0sYy5yZWdpc3RlclBsdWdpbnM9ZnVuY3Rpb24oYSl7Yy5fcGx1Z2luc1JlZ2lzdGVyZWQ9ITA7Zm9yKHZhciBiPTAsZD1hLmxlbmd0aDtkPmI7YisrKWlmKGMuX3JlZ2lzdGVyUGx1Z2luKGFbYl0pKXJldHVybiEwO3JldHVybiExfSxjLmluaXRpYWxpemVEZWZhdWx0UGx1Z2lucz1mdW5jdGlvbigpe3JldHVybiBudWxsIT1jLmFjdGl2ZVBsdWdpbj8hMDpjLl9wbHVnaW5zUmVnaXN0ZXJlZD8hMTpjLnJlZ2lzdGVyUGx1Z2lucyhbY3JlYXRlanMuV2ViQXVkaW9QbHVnaW4sY3JlYXRlanMuSFRNTEF1ZGlvUGx1Z2luXSk/ITA6ITF9LGMuaXNSZWFkeT1mdW5jdGlvbigpe3JldHVybiBudWxsIT1jLmFjdGl2ZVBsdWdpbn0sYy5nZXRDYXBhYmlsaXRpZXM9ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbD09Yy5hY3RpdmVQbHVnaW4/bnVsbDpjLmFjdGl2ZVBsdWdpbi5fY2FwYWJpbGl0aWVzfSxjLmdldENhcGFiaWxpdHk9ZnVuY3Rpb24oYSl7cmV0dXJuIG51bGw9PWMuYWN0aXZlUGx1Z2luP251bGw6Yy5hY3RpdmVQbHVnaW4uX2NhcGFiaWxpdGllc1thXX0sYy5pbml0TG9hZD1mdW5jdGlvbihhKXtyZXR1cm4gYy5fcmVnaXN0ZXJTb3VuZChhKX0sYy5fcmVnaXN0ZXJTb3VuZD1mdW5jdGlvbihhKXtpZighYy5pbml0aWFsaXplRGVmYXVsdFBsdWdpbnMoKSlyZXR1cm4hMTt2YXIgZD1jLl9wYXJzZVBhdGgoYS5zcmMpO2lmKG51bGw9PWQpcmV0dXJuITE7YS5zcmM9ZC5zcmMsYS50eXBlPSJzb3VuZCI7dmFyIGU9YS5kYXRhLGY9Yy5hY3RpdmVQbHVnaW4uZGVmYXVsdE51bUNoYW5uZWxzfHxudWxsO2lmKG51bGwhPWUmJihpc05hTihlLmNoYW5uZWxzKT9pc05hTihlKXx8KGY9cGFyc2VJbnQoZSkpOmY9cGFyc2VJbnQoZS5jaGFubmVscyksZS5hdWRpb1Nwcml0ZSkpZm9yKHZhciBnLGg9ZS5hdWRpb1Nwcml0ZS5sZW5ndGg7aC0tOylnPWUuYXVkaW9TcHJpdGVbaF0sYy5faWRIYXNoW2cuaWRdPXtzcmM6YS5zcmMsc3RhcnRUaW1lOnBhcnNlSW50KGcuc3RhcnRUaW1lKSxkdXJhdGlvbjpwYXJzZUludChnLmR1cmF0aW9uKX07bnVsbCE9YS5pZCYmKGMuX2lkSGFzaFthLmlkXT17c3JjOmEuc3JjfSk7dmFyIGk9Yy5hY3RpdmVQbHVnaW4ucmVnaXN0ZXIoYSxmKTtyZXR1cm4gYi5jcmVhdGUoYS5zcmMsZiksbnVsbCE9ZSYmaXNOYU4oZSk/YS5kYXRhLmNoYW5uZWxzPWZ8fGIubWF4UGVyQ2hhbm5lbCgpOmEuZGF0YT1mfHxiLm1heFBlckNoYW5uZWwoKSxpLnR5cGUmJihhLnR5cGU9aS50eXBlKSxpfSxjLnJlZ2lzdGVyU291bmQ9ZnVuY3Rpb24oYSxiLGQsZSl7dmFyIGY9e3NyYzphLGlkOmIsZGF0YTpkfTthIGluc3RhbmNlb2YgT2JqZWN0JiYoZT1iLGY9YSksZj1jcmVhdGVqcy5Mb2FkSXRlbS5jcmVhdGUoZiksbnVsbCE9ZSYmKGYuc3JjPWUrYSk7dmFyIGc9Yy5fcmVnaXN0ZXJTb3VuZChmKTtpZighZylyZXR1cm4hMTtpZihjLl9wcmVsb2FkSGFzaFtmLnNyY118fChjLl9wcmVsb2FkSGFzaFtmLnNyY109W10pLGMuX3ByZWxvYWRIYXNoW2Yuc3JjXS5wdXNoKGYpLDE9PWMuX3ByZWxvYWRIYXNoW2Yuc3JjXS5sZW5ndGgpZy5vbigiY29tcGxldGUiLGNyZWF0ZWpzLnByb3h5KHRoaXMuX2hhbmRsZUxvYWRDb21wbGV0ZSx0aGlzKSksZy5vbigiZXJyb3IiLGNyZWF0ZWpzLnByb3h5KHRoaXMuX2hhbmRsZUxvYWRFcnJvcix0aGlzKSksYy5hY3RpdmVQbHVnaW4ucHJlbG9hZChnKTtlbHNlIGlmKDE9PWMuX3ByZWxvYWRIYXNoW2Yuc3JjXVswXSlyZXR1cm4hMDtyZXR1cm4gZn0sYy5yZWdpc3RlclNvdW5kcz1mdW5jdGlvbihhLGIpe3ZhciBjPVtdO2EucGF0aCYmKGI/Yis9YS5wYXRoOmI9YS5wYXRoKTtmb3IodmFyIGQ9MCxlPWEubGVuZ3RoO2U+ZDtkKyspY1tkXT1jcmVhdGVqcy5Tb3VuZC5yZWdpc3RlclNvdW5kKGFbZF0uc3JjLGFbZF0uaWQsYVtkXS5kYXRhLGIpO3JldHVybiBjfSxjLnJlZ2lzdGVyTWFuaWZlc3Q9ZnVuY3Rpb24oYSxiKXt0cnl7Y29uc29sZS5sb2coImNyZWF0ZWpzLlNvdW5kLnJlZ2lzdGVyTWFuaWZlc3QgaXMgZGVwcmVjYXRlZCwgcGxlYXNlIHVzZSBjcmVhdGVqcy5Tb3VuZC5yZWdpc3RlclNvdW5kcy4iKX1jYXRjaChjKXt9cmV0dXJuIHRoaXMucmVnaXN0ZXJTb3VuZHMoYSxiKX0sYy5yZW1vdmVTb3VuZD1mdW5jdGlvbihhLGQpe2lmKG51bGw9PWMuYWN0aXZlUGx1Z2luKXJldHVybiExO2EgaW5zdGFuY2VvZiBPYmplY3QmJihhPWEuc3JjKSxhPWMuX2dldFNyY0J5SWQoYSkuc3JjLG51bGwhPWQmJihhPWQrYSk7dmFyIGU9Yy5fcGFyc2VQYXRoKGEpO2lmKG51bGw9PWUpcmV0dXJuITE7YT1lLnNyYztmb3IodmFyIGYgaW4gYy5faWRIYXNoKWMuX2lkSGFzaFtmXS5zcmM9PWEmJmRlbGV0ZSBjLl9pZEhhc2hbZl07cmV0dXJuIGIucmVtb3ZlU3JjKGEpLGRlbGV0ZSBjLl9wcmVsb2FkSGFzaFthXSxjLmFjdGl2ZVBsdWdpbi5yZW1vdmVTb3VuZChhKSwhMH0sYy5yZW1vdmVTb3VuZHM9ZnVuY3Rpb24oYSxiKXt2YXIgYz1bXTthLnBhdGgmJihiP2IrPWEucGF0aDpiPWEucGF0aCk7Zm9yKHZhciBkPTAsZT1hLmxlbmd0aDtlPmQ7ZCsrKWNbZF09Y3JlYXRlanMuU291bmQucmVtb3ZlU291bmQoYVtkXS5zcmMsYik7cmV0dXJuIGN9LGMucmVtb3ZlTWFuaWZlc3Q9ZnVuY3Rpb24oYSxiKXt0cnl7Y29uc29sZS5sb2coImNyZWF0ZWpzLlNvdW5kLnJlbW92ZU1hbmlmZXN0IGlzIGRlcHJlY2F0ZWQsIHBsZWFzZSB1c2UgY3JlYXRlanMuU291bmQucmVtb3ZlU291bmRzLiIpfWNhdGNoKGQpe31yZXR1cm4gYy5yZW1vdmVTb3VuZHMoYSxiKX0sYy5yZW1vdmVBbGxTb3VuZHM9ZnVuY3Rpb24oKXtjLl9pZEhhc2g9e30sYy5fcHJlbG9hZEhhc2g9e30sYi5yZW1vdmVBbGwoKSxjLmFjdGl2ZVBsdWdpbiYmYy5hY3RpdmVQbHVnaW4ucmVtb3ZlQWxsU291bmRzKCl9LGMubG9hZENvbXBsZXRlPWZ1bmN0aW9uKGEpe2lmKCFjLmlzUmVhZHkoKSlyZXR1cm4hMTt2YXIgYj1jLl9wYXJzZVBhdGgoYSk7cmV0dXJuIGE9Yj9jLl9nZXRTcmNCeUlkKGIuc3JjKS5zcmM6Yy5fZ2V0U3JjQnlJZChhKS5zcmMsMT09Yy5fcHJlbG9hZEhhc2hbYV1bMF19LGMuX3BhcnNlUGF0aD1mdW5jdGlvbihhKXsic3RyaW5nIiE9dHlwZW9mIGEmJihhPWEudG9TdHJpbmcoKSk7dmFyIGI9YS5tYXRjaChjLkZJTEVfUEFUVEVSTik7aWYobnVsbD09YilyZXR1cm4hMTtmb3IodmFyIGQ9Yls0XSxlPWJbNV0sZj1jLmdldENhcGFiaWxpdGllcygpLGc9MDshZltlXTspaWYoZT1jLmFsdGVybmF0ZUV4dGVuc2lvbnNbZysrXSxnPmMuYWx0ZXJuYXRlRXh0ZW5zaW9ucy5sZW5ndGgpcmV0dXJuIG51bGw7YT1hLnJlcGxhY2UoIi4iK2JbNV0sIi4iK2UpO3ZhciBoPXtuYW1lOmQsc3JjOmEsZXh0ZW5zaW9uOmV9O3JldHVybiBofSxjLnBsYXk9ZnVuY3Rpb24oYSxiLGQsZSxmLGcsaCxpLGope2IgaW5zdGFuY2VvZiBPYmplY3QmJihkPWIuZGVsYXksZT1iLm9mZnNldCxmPWIubG9vcCxnPWIudm9sdW1lLGg9Yi5wYW4saT1iLnN0YXJ0VGltZSxqPWIuZHVyYXRpb24sYj1iLmludGVycnVwdCk7dmFyIGs9Yy5jcmVhdGVJbnN0YW5jZShhLGksaiksbD1jLl9wbGF5SW5zdGFuY2UoayxiLGQsZSxmLGcsaCk7cmV0dXJuIGx8fGsuX3BsYXlGYWlsZWQoKSxrfSxjLmNyZWF0ZUluc3RhbmNlPWZ1bmN0aW9uKGEsZCxlKXtpZighYy5pbml0aWFsaXplRGVmYXVsdFBsdWdpbnMoKSlyZXR1cm4gbmV3IGNyZWF0ZWpzLkRlZmF1bHRTb3VuZEluc3RhbmNlKGEsZCxlKTthPWMuX2dldFNyY0J5SWQoYSk7dmFyIGY9Yy5fcGFyc2VQYXRoKGEuc3JjKSxnPW51bGw7cmV0dXJuIG51bGwhPWYmJm51bGwhPWYuc3JjPyhiLmNyZWF0ZShmLnNyYyksbnVsbD09ZCYmKGQ9YS5zdGFydFRpbWUpLGc9Yy5hY3RpdmVQbHVnaW4uY3JlYXRlKGYuc3JjLGQsZXx8YS5kdXJhdGlvbikpOmc9bmV3IGNyZWF0ZWpzLkRlZmF1bHRTb3VuZEluc3RhbmNlKGEsZCxlKSxnLnVuaXF1ZUlkPWMuX2xhc3RJRCsrLGd9LGMuc2V0Vm9sdW1lPWZ1bmN0aW9uKGEpe2lmKG51bGw9PU51bWJlcihhKSlyZXR1cm4hMTtpZihhPU1hdGgubWF4KDAsTWF0aC5taW4oMSxhKSksYy5fbWFzdGVyVm9sdW1lPWEsIXRoaXMuYWN0aXZlUGx1Z2lufHwhdGhpcy5hY3RpdmVQbHVnaW4uc2V0Vm9sdW1lfHwhdGhpcy5hY3RpdmVQbHVnaW4uc2V0Vm9sdW1lKGEpKWZvcih2YXIgYj10aGlzLl9pbnN0YW5jZXMsZD0wLGU9Yi5sZW5ndGg7ZT5kO2QrKyliW2RdLnNldE1hc3RlclZvbHVtZShhKX0sYy5nZXRWb2x1bWU9ZnVuY3Rpb24oKXtyZXR1cm4gYy5fbWFzdGVyVm9sdW1lfSxjLnNldE11dGU9ZnVuY3Rpb24oYSl7aWYobnVsbD09YSlyZXR1cm4hMTtpZih0aGlzLl9tYXN0ZXJNdXRlPWEsIXRoaXMuYWN0aXZlUGx1Z2lufHwhdGhpcy5hY3RpdmVQbHVnaW4uc2V0TXV0ZXx8IXRoaXMuYWN0aXZlUGx1Z2luLnNldE11dGUoYSkpZm9yKHZhciBiPXRoaXMuX2luc3RhbmNlcyxjPTAsZD1iLmxlbmd0aDtkPmM7YysrKWJbY10uc2V0TWFzdGVyTXV0ZShhKTtyZXR1cm4hMH0sYy5nZXRNdXRlPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuX21hc3Rlck11dGV9LGMuc3RvcD1mdW5jdGlvbigpe2Zvcih2YXIgYT10aGlzLl9pbnN0YW5jZXMsYj1hLmxlbmd0aDtiLS07KWFbYl0uc3RvcCgpfSxjLl9wbGF5SW5zdGFuY2U9ZnVuY3Rpb24oYSxiLGQsZSxmLGcsaCl7aWYoYiBpbnN0YW5jZW9mIE9iamVjdCYmKGQ9Yi5kZWxheSxlPWIub2Zmc2V0LGY9Yi5sb29wLGc9Yi52b2x1bWUsaD1iLnBhbixiPWIuaW50ZXJydXB0KSxiPWJ8fGMuZGVmYXVsdEludGVycnVwdEJlaGF2aW9yLG51bGw9PWQmJihkPTApLG51bGw9PWUmJihlPWEuZ2V0UG9zaXRpb24oKSksbnVsbD09ZiYmKGY9YS5sb29wKSxudWxsPT1nJiYoZz1hLnZvbHVtZSksbnVsbD09aCYmKGg9YS5wYW4pLDA9PWQpe3ZhciBpPWMuX2JlZ2luUGxheWluZyhhLGIsZSxmLGcsaCk7aWYoIWkpcmV0dXJuITF9ZWxzZXt2YXIgaj1zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7Yy5fYmVnaW5QbGF5aW5nKGEsYixlLGYsZyxoKX0sZCk7YS5kZWxheVRpbWVvdXRJZD1qfXJldHVybiB0aGlzLl9pbnN0YW5jZXMucHVzaChhKSwhMH0sYy5fYmVnaW5QbGF5aW5nPWZ1bmN0aW9uKGEsYyxkLGUsZixnKXtpZighYi5hZGQoYSxjKSlyZXR1cm4hMTt2YXIgaD1hLl9iZWdpblBsYXlpbmcoZCxlLGYsZyk7aWYoIWgpe3ZhciBpPWNyZWF0ZWpzLmluZGV4T2YodGhpcy5faW5zdGFuY2VzLGEpO3JldHVybiBpPi0xJiZ0aGlzLl9pbnN0YW5jZXMuc3BsaWNlKGksMSksITF9cmV0dXJuITB9LGMuX2dldFNyY0J5SWQ9ZnVuY3Rpb24oYSl7cmV0dXJuIGMuX2lkSGFzaFthXXx8e3NyYzphfX0sYy5fcGxheUZpbmlzaGVkPWZ1bmN0aW9uKGEpe2IucmVtb3ZlKGEpO3ZhciBjPWNyZWF0ZWpzLmluZGV4T2YodGhpcy5faW5zdGFuY2VzLGEpO2M+LTEmJnRoaXMuX2luc3RhbmNlcy5zcGxpY2UoYywxKX0sY3JlYXRlanMuU291bmQ9YSxiLmNoYW5uZWxzPXt9LGIuY3JlYXRlPWZ1bmN0aW9uKGEsYyl7dmFyIGQ9Yi5nZXQoYSk7cmV0dXJuIG51bGw9PWQ/KGIuY2hhbm5lbHNbYV09bmV3IGIoYSxjKSwhMCk6ITF9LGIucmVtb3ZlU3JjPWZ1bmN0aW9uKGEpe3ZhciBjPWIuZ2V0KGEpO3JldHVybiBudWxsPT1jPyExOihjLl9yZW1vdmVBbGwoKSxkZWxldGUgYi5jaGFubmVsc1thXSwhMCl9LGIucmVtb3ZlQWxsPWZ1bmN0aW9uKCl7Zm9yKHZhciBhIGluIGIuY2hhbm5lbHMpYi5jaGFubmVsc1thXS5fcmVtb3ZlQWxsKCk7Yi5jaGFubmVscz17fX0sYi5hZGQ9ZnVuY3Rpb24oYSxjKXt2YXIgZD1iLmdldChhLnNyYyk7cmV0dXJuIG51bGw9PWQ/ITE6ZC5fYWRkKGEsYyl9LGIucmVtb3ZlPWZ1bmN0aW9uKGEpe3ZhciBjPWIuZ2V0KGEuc3JjKTtyZXR1cm4gbnVsbD09Yz8hMTooYy5fcmVtb3ZlKGEpLCEwKX0sYi5tYXhQZXJDaGFubmVsPWZ1bmN0aW9uKCl7cmV0dXJuIGQubWF4RGVmYXVsdH0sYi5nZXQ9ZnVuY3Rpb24oYSl7cmV0dXJuIGIuY2hhbm5lbHNbYV19O3ZhciBkPWIucHJvdG90eXBlO2QuY29uc3RydWN0b3I9YixkLnNyYz1udWxsLGQubWF4PW51bGwsZC5tYXhEZWZhdWx0PTEwMCxkLmxlbmd0aD0wLGQuaW5pdD1mdW5jdGlvbihhLGIpe3RoaXMuc3JjPWEsdGhpcy5tYXg9Ynx8dGhpcy5tYXhEZWZhdWx0LC0xPT10aGlzLm1heCYmKHRoaXMubWF4PXRoaXMubWF4RGVmYXVsdCksdGhpcy5faW5zdGFuY2VzPVtdfSxkLl9nZXQ9ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuX2luc3RhbmNlc1thXX0sZC5fYWRkPWZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuX2dldFNsb3QoYixhKT8odGhpcy5faW5zdGFuY2VzLnB1c2goYSksdGhpcy5sZW5ndGgrKywhMCk6ITF9LGQuX3JlbW92ZT1mdW5jdGlvbihhKXt2YXIgYj1jcmVhdGVqcy5pbmRleE9mKHRoaXMuX2luc3RhbmNlcyxhKTtyZXR1cm4tMT09Yj8hMToodGhpcy5faW5zdGFuY2VzLnNwbGljZShiLDEpLHRoaXMubGVuZ3RoLS0sITApfSxkLl9yZW1vdmVBbGw9ZnVuY3Rpb24oKXtmb3IodmFyIGE9dGhpcy5sZW5ndGgtMTthPj0wO2EtLSl0aGlzLl9pbnN0YW5jZXNbYV0uc3RvcCgpfSxkLl9nZXRTbG90PWZ1bmN0aW9uKGIpe3ZhciBjLGQ7aWYoYiE9YS5JTlRFUlJVUFRfTk9ORSYmKGQ9dGhpcy5fZ2V0KDApLG51bGw9PWQpKXJldHVybiEwO2Zvcih2YXIgZT0wLGY9dGhpcy5tYXg7Zj5lO2UrKyl7aWYoYz10aGlzLl9nZXQoZSksbnVsbD09YylyZXR1cm4hMDtpZihjLnBsYXlTdGF0ZT09YS5QTEFZX0ZJTklTSEVEfHxjLnBsYXlTdGF0ZT09YS5QTEFZX0lOVEVSUlVQVEVEfHxjLnBsYXlTdGF0ZT09YS5QTEFZX0ZBSUxFRCl7ZD1jO2JyZWFrfWIhPWEuSU5URVJSVVBUX05PTkUmJihiPT1hLklOVEVSUlVQVF9FQVJMWSYmYy5nZXRQb3NpdGlvbigpPGQuZ2V0UG9zaXRpb24oKXx8Yj09YS5JTlRFUlJVUFRfTEFURSYmYy5nZXRQb3NpdGlvbigpPmQuZ2V0UG9zaXRpb24oKSkmJihkPWMpfXJldHVybiBudWxsIT1kPyhkLl9pbnRlcnJ1cHQoKSx0aGlzLl9yZW1vdmUoZCksITApOiExfSxkLnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIltTb3VuZCBTb3VuZENoYW5uZWxdIn19KCksdGhpcy5jcmVhdGVqcz10aGlzLmNyZWF0ZWpzfHx7fSxmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0Ijt2YXIgYT1mdW5jdGlvbihhLGIsYyxkKXt0aGlzLkV2ZW50RGlzcGF0Y2hlcl9jb25zdHJ1Y3RvcigpLHRoaXMuc3JjPWEsdGhpcy51bmlxdWVJZD0tMSx0aGlzLnBsYXlTdGF0ZT1udWxsLHRoaXMuZGVsYXlUaW1lb3V0SWQ9bnVsbCx0aGlzLl9zdGFydFRpbWU9TWF0aC5tYXgoMCxifHwwKSx0aGlzLl92b2x1bWU9MSxjcmVhdGVqcy5kZWZpbmVQcm9wZXJ0eVN1cHBvcnRlZCYmT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsInZvbHVtZSIse2dldDp0aGlzLmdldFZvbHVtZSxzZXQ6dGhpcy5zZXRWb2x1bWV9KSx0aGlzLl9wYW49MCxjcmVhdGVqcy5kZWZpbmVQcm9wZXJ0eVN1cHBvcnRlZCYmT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsInBhbiIse2dldDp0aGlzLmdldFBhbixzZXQ6dGhpcy5zZXRQYW59KSx0aGlzLl9kdXJhdGlvbj1NYXRoLm1heCgwLGN8fDApLGNyZWF0ZWpzLmRlZmluZVByb3BlcnR5U3VwcG9ydGVkJiZPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywiZHVyYXRpb24iLHtnZXQ6dGhpcy5nZXREdXJhdGlvbixzZXQ6dGhpcy5zZXREdXJhdGlvbn0pLHRoaXMuX3BsYXliYWNrUmVzb3VyY2U9bnVsbCxjcmVhdGVqcy5kZWZpbmVQcm9wZXJ0eVN1cHBvcnRlZCYmT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsInBsYXliYWNrUmVzb3VyY2UiLHtnZXQ6dGhpcy5nZXRQbGF5YmFja1Jlc291cmNlLHNldDp0aGlzLnNldFBsYXliYWNrUmVzb3VyY2V9KSxkIT09ITEmJmQhPT0hMCYmdGhpcy5zZXRQbGF5YmFja1Jlc291cmNlKGQpLHRoaXMuX3Bvc2l0aW9uPTAsY3JlYXRlanMuZGVmaW5lUHJvcGVydHlTdXBwb3J0ZWQmJk9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCJwb3NpdGlvbiIse2dldDp0aGlzLmdldFBvc2l0aW9uLHNldDp0aGlzLnNldFBvc2l0aW9ufSksdGhpcy5fbG9vcD0wLGNyZWF0ZWpzLmRlZmluZVByb3BlcnR5U3VwcG9ydGVkJiZPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywibG9vcCIse2dldDp0aGlzLmdldExvb3Asc2V0OnRoaXMuc2V0TG9vcH0pLHRoaXMuX211dGVkPSExLGNyZWF0ZWpzLmRlZmluZVByb3BlcnR5U3VwcG9ydGVkJiZPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywibXV0ZWQiLHtnZXQ6dGhpcy5nZXRNdXRlZCxzZXQ6dGhpcy5zZXRNdXRlZH0pLHRoaXMuX3BhdXNlZD0hMSxjcmVhdGVqcy5kZWZpbmVQcm9wZXJ0eVN1cHBvcnRlZCYmT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsInBhdXNlZCIse2dldDp0aGlzLmdldFBhdXNlZCxzZXQ6dGhpcy5zZXRQYXVzZWR9KQp9LGI9Y3JlYXRlanMuZXh0ZW5kKGEsY3JlYXRlanMuRXZlbnREaXNwYXRjaGVyKTtiLnBsYXk9ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe3JldHVybiB0aGlzLnBsYXlTdGF0ZT09Y3JlYXRlanMuU291bmQuUExBWV9TVUNDRUVERUQ/KGEgaW5zdGFuY2VvZiBPYmplY3QmJihjPWEub2Zmc2V0LGQ9YS5sb29wLGU9YS52b2x1bWUsZj1hLnBhbiksbnVsbCE9YyYmdGhpcy5zZXRQb3NpdGlvbihjKSxudWxsIT1kJiZ0aGlzLnNldExvb3AoZCksbnVsbCE9ZSYmdGhpcy5zZXRWb2x1bWUoZSksbnVsbCE9ZiYmdGhpcy5zZXRQYW4oZiksdm9pZCh0aGlzLl9wYXVzZWQmJnRoaXMuc2V0UGF1c2VkKCExKSkpOih0aGlzLl9jbGVhblVwKCksY3JlYXRlanMuU291bmQuX3BsYXlJbnN0YW5jZSh0aGlzLGEsYixjLGQsZSxmKSx0aGlzKX0sYi5wYXVzZT1mdW5jdGlvbigpe3JldHVybiB0aGlzLl9wYXVzZWR8fHRoaXMucGxheVN0YXRlIT1jcmVhdGVqcy5Tb3VuZC5QTEFZX1NVQ0NFRURFRD8hMToodGhpcy5zZXRQYXVzZWQoITApLCEwKX0sYi5yZXN1bWU9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5fcGF1c2VkPyh0aGlzLnNldFBhdXNlZCghMSksITApOiExfSxiLnN0b3A9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5fcG9zaXRpb249MCx0aGlzLl9wYXVzZWQ9ITEsdGhpcy5faGFuZGxlU3RvcCgpLHRoaXMuX2NsZWFuVXAoKSx0aGlzLnBsYXlTdGF0ZT1jcmVhdGVqcy5Tb3VuZC5QTEFZX0ZJTklTSEVELHRoaXN9LGIuZGVzdHJveT1mdW5jdGlvbigpe3RoaXMuX2NsZWFuVXAoKSx0aGlzLnNyYz1udWxsLHRoaXMucGxheWJhY2tSZXNvdXJjZT1udWxsLHRoaXMucmVtb3ZlQWxsRXZlbnRMaXN0ZW5lcnMoKX0sYi50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiJbQWJzdHJhY3RTb3VuZEluc3RhbmNlXSJ9LGIuZ2V0UGF1c2VkPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuX3BhdXNlZH0sYi5zZXRQYXVzZWQ9ZnVuY3Rpb24oYSl7cmV0dXJuIGEhPT0hMCYmYSE9PSExfHx0aGlzLl9wYXVzZWQ9PWF8fDE9PWEmJnRoaXMucGxheVN0YXRlIT1jcmVhdGVqcy5Tb3VuZC5QTEFZX1NVQ0NFRURFRD92b2lkIDA6KHRoaXMuX3BhdXNlZD1hLGE/dGhpcy5fcGF1c2UoKTp0aGlzLl9yZXN1bWUoKSxjbGVhclRpbWVvdXQodGhpcy5kZWxheVRpbWVvdXRJZCksdGhpcyl9LGIuc2V0Vm9sdW1lPWZ1bmN0aW9uKGEpe3JldHVybiBhPT10aGlzLl92b2x1bWU/dGhpczoodGhpcy5fdm9sdW1lPU1hdGgubWF4KDAsTWF0aC5taW4oMSxhKSksdGhpcy5fbXV0ZWR8fHRoaXMuX3VwZGF0ZVZvbHVtZSgpLHRoaXMpfSxiLmdldFZvbHVtZT1mdW5jdGlvbigpe3JldHVybiB0aGlzLl92b2x1bWV9LGIuc2V0TXV0ZT1mdW5jdGlvbihhKXt0aGlzLnNldE11dGVkKGEpfSxiLmdldE11dGU9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5fbXV0ZWR9LGIuc2V0TXV0ZWQ9ZnVuY3Rpb24oYSl7cmV0dXJuIGE9PT0hMHx8YT09PSExPyh0aGlzLl9tdXRlZD1hLHRoaXMuX3VwZGF0ZVZvbHVtZSgpLHRoaXMpOnZvaWQgMH0sYi5nZXRNdXRlZD1mdW5jdGlvbigpe3JldHVybiB0aGlzLl9tdXRlZH0sYi5zZXRQYW49ZnVuY3Rpb24oYSl7cmV0dXJuIGE9PXRoaXMuX3Bhbj90aGlzOih0aGlzLl9wYW49TWF0aC5tYXgoLTEsTWF0aC5taW4oMSxhKSksdGhpcy5fdXBkYXRlUGFuKCksdGhpcyl9LGIuZ2V0UGFuPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuX3Bhbn0sYi5nZXRQb3NpdGlvbj1mdW5jdGlvbigpe3JldHVybiB0aGlzLl9wYXVzZWR8fHRoaXMucGxheVN0YXRlIT1jcmVhdGVqcy5Tb3VuZC5QTEFZX1NVQ0NFRURFRD90aGlzLl9wb3NpdGlvbjp0aGlzLl9jYWxjdWxhdGVDdXJyZW50UG9zaXRpb24oKX0sYi5zZXRQb3NpdGlvbj1mdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5fcG9zaXRpb249TWF0aC5tYXgoMCxhKSx0aGlzLnBsYXlTdGF0ZT09Y3JlYXRlanMuU291bmQuUExBWV9TVUNDRUVERUQmJnRoaXMuX3VwZGF0ZVBvc2l0aW9uKCksdGhpc30sYi5nZXREdXJhdGlvbj1mdW5jdGlvbigpe3JldHVybiB0aGlzLl9kdXJhdGlvbn0sYi5zZXREdXJhdGlvbj1mdW5jdGlvbihhKXtyZXR1cm4gYT09dGhpcy5fZHVyYXRpb24/dGhpczoodGhpcy5fZHVyYXRpb249TWF0aC5tYXgoMCxhfHwwKSx0aGlzLl91cGRhdGVEdXJhdGlvbigpLHRoaXMpfSxiLnNldFBsYXliYWNrUmVzb3VyY2U9ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuX3BsYXliYWNrUmVzb3VyY2U9YSwwPT10aGlzLl9kdXJhdGlvbiYmdGhpcy5fc2V0RHVyYXRpb25Gcm9tU291cmNlKCksdGhpc30sYi5nZXRQbGF5YmFja1Jlc291cmNlPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuX3BsYXliYWNrUmVzb3VyY2V9LGIuZ2V0TG9vcD1mdW5jdGlvbigpe3JldHVybiB0aGlzLl9sb29wfSxiLnNldExvb3A9ZnVuY3Rpb24oYSl7bnVsbCE9dGhpcy5fcGxheWJhY2tSZXNvdXJjZSYmKDAhPXRoaXMuX2xvb3AmJjA9PWEmJnRoaXMuX3JlbW92ZUxvb3BpbmcoYSksMD09dGhpcy5fbG9vcCYmMCE9YSYmdGhpcy5fYWRkTG9vcGluZyhhKSksdGhpcy5fbG9vcD1hfSxiLl9zZW5kRXZlbnQ9ZnVuY3Rpb24oYSl7dmFyIGI9bmV3IGNyZWF0ZWpzLkV2ZW50KGEpO3RoaXMuZGlzcGF0Y2hFdmVudChiKX0sYi5fY2xlYW5VcD1mdW5jdGlvbigpe2NsZWFyVGltZW91dCh0aGlzLmRlbGF5VGltZW91dElkKSx0aGlzLl9oYW5kbGVDbGVhblVwKCksdGhpcy5fcGF1c2VkPSExLGNyZWF0ZWpzLlNvdW5kLl9wbGF5RmluaXNoZWQodGhpcyl9LGIuX2ludGVycnVwdD1mdW5jdGlvbigpe3RoaXMuX2NsZWFuVXAoKSx0aGlzLnBsYXlTdGF0ZT1jcmVhdGVqcy5Tb3VuZC5QTEFZX0lOVEVSUlVQVEVELHRoaXMuX3NlbmRFdmVudCgiaW50ZXJydXB0ZWQiKX0sYi5fYmVnaW5QbGF5aW5nPWZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiB0aGlzLnNldFBvc2l0aW9uKGEpLHRoaXMuc2V0TG9vcChiKSx0aGlzLnNldFZvbHVtZShjKSx0aGlzLnNldFBhbihkKSxudWxsIT10aGlzLl9wbGF5YmFja1Jlc291cmNlJiZ0aGlzLl9wb3NpdGlvbjx0aGlzLl9kdXJhdGlvbj8odGhpcy5fcGF1c2VkPSExLHRoaXMuX2hhbmRsZVNvdW5kUmVhZHkoKSx0aGlzLnBsYXlTdGF0ZT1jcmVhdGVqcy5Tb3VuZC5QTEFZX1NVQ0NFRURFRCx0aGlzLl9zZW5kRXZlbnQoInN1Y2NlZWRlZCIpLCEwKToodGhpcy5fcGxheUZhaWxlZCgpLCExKX0sYi5fcGxheUZhaWxlZD1mdW5jdGlvbigpe3RoaXMuX2NsZWFuVXAoKSx0aGlzLnBsYXlTdGF0ZT1jcmVhdGVqcy5Tb3VuZC5QTEFZX0ZBSUxFRCx0aGlzLl9zZW5kRXZlbnQoImZhaWxlZCIpfSxiLl9oYW5kbGVTb3VuZENvbXBsZXRlPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuX3Bvc2l0aW9uPTAsMCE9dGhpcy5fbG9vcD8odGhpcy5fbG9vcC0tLHRoaXMuX2hhbmRsZUxvb3AoKSx2b2lkIHRoaXMuX3NlbmRFdmVudCgibG9vcCIpKToodGhpcy5fY2xlYW5VcCgpLHRoaXMucGxheVN0YXRlPWNyZWF0ZWpzLlNvdW5kLlBMQVlfRklOSVNIRUQsdm9pZCB0aGlzLl9zZW5kRXZlbnQoImNvbXBsZXRlIikpfSxiLl9oYW5kbGVTb3VuZFJlYWR5PWZ1bmN0aW9uKCl7fSxiLl91cGRhdGVWb2x1bWU9ZnVuY3Rpb24oKXt9LGIuX3VwZGF0ZVBhbj1mdW5jdGlvbigpe30sYi5fdXBkYXRlRHVyYXRpb249ZnVuY3Rpb24oKXt9LGIuX3NldER1cmF0aW9uRnJvbVNvdXJjZT1mdW5jdGlvbigpe30sYi5fY2FsY3VsYXRlQ3VycmVudFBvc2l0aW9uPWZ1bmN0aW9uKCl7fSxiLl91cGRhdGVQb3NpdGlvbj1mdW5jdGlvbigpe30sYi5fcmVtb3ZlTG9vcGluZz1mdW5jdGlvbigpe30sYi5fYWRkTG9vcGluZz1mdW5jdGlvbigpe30sYi5fcGF1c2U9ZnVuY3Rpb24oKXt9LGIuX3Jlc3VtZT1mdW5jdGlvbigpe30sYi5faGFuZGxlU3RvcD1mdW5jdGlvbigpe30sYi5faGFuZGxlQ2xlYW5VcD1mdW5jdGlvbigpe30sYi5faGFuZGxlTG9vcD1mdW5jdGlvbigpe30sY3JlYXRlanMuQWJzdHJhY3RTb3VuZEluc3RhbmNlPWNyZWF0ZWpzLnByb21vdGUoYSwiRXZlbnREaXNwYXRjaGVyIiksY3JlYXRlanMuRGVmYXVsdFNvdW5kSW5zdGFuY2U9Y3JlYXRlanMuQWJzdHJhY3RTb3VuZEluc3RhbmNlfSgpLHRoaXMuY3JlYXRlanM9dGhpcy5jcmVhdGVqc3x8e30sZnVuY3Rpb24oKXsidXNlIHN0cmljdCI7dmFyIGE9ZnVuY3Rpb24oKXt0aGlzLl9jYXBhYmlsaXRpZXM9bnVsbCx0aGlzLl9sb2FkZXJzPXt9LHRoaXMuX2F1ZGlvU291cmNlcz17fSx0aGlzLl9zb3VuZEluc3RhbmNlcz17fSx0aGlzLl9sb2FkZXJDbGFzcyx0aGlzLl9zb3VuZEluc3RhbmNlQ2xhc3N9LGI9YS5wcm90b3R5cGU7YS5fY2FwYWJpbGl0aWVzPW51bGwsYS5pc1N1cHBvcnRlZD1mdW5jdGlvbigpe3JldHVybiEwfSxiLnJlZ2lzdGVyPWZ1bmN0aW9uKGEpe2lmKHRoaXMuX2F1ZGlvU291cmNlc1thLnNyY109ITAsdGhpcy5fc291bmRJbnN0YW5jZXNbYS5zcmNdPVtdLHRoaXMuX2xvYWRlcnNbYS5zcmNdKXJldHVybiB0aGlzLl9sb2FkZXJzW2Euc3JjXTt2YXIgYj1uZXcgdGhpcy5fbG9hZGVyQ2xhc3MoYSk7cmV0dXJuIGIub24oImNvbXBsZXRlIixjcmVhdGVqcy5wcm94eSh0aGlzLl9oYW5kbGVQcmVsb2FkQ29tcGxldGUsdGhpcykpLHRoaXMuX2xvYWRlcnNbYS5zcmNdPWIsYn0sYi5wcmVsb2FkPWZ1bmN0aW9uKGEpe2Eub24oImVycm9yIixjcmVhdGVqcy5wcm94eSh0aGlzLl9oYW5kbGVQcmVsb2FkRXJyb3IsdGhpcykpLGEubG9hZCgpfSxiLmlzUHJlbG9hZFN0YXJ0ZWQ9ZnVuY3Rpb24oYSl7cmV0dXJuIG51bGwhPXRoaXMuX2F1ZGlvU291cmNlc1thXX0sYi5pc1ByZWxvYWRDb21wbGV0ZT1mdW5jdGlvbihhKXtyZXR1cm4hKG51bGw9PXRoaXMuX2F1ZGlvU291cmNlc1thXXx8MT09dGhpcy5fYXVkaW9Tb3VyY2VzW2FdKX0sYi5yZW1vdmVTb3VuZD1mdW5jdGlvbihhKXtpZih0aGlzLl9zb3VuZEluc3RhbmNlc1thXSl7Zm9yKHZhciBiPXRoaXMuX3NvdW5kSW5zdGFuY2VzW2FdLmxlbmd0aDtiLS07KXt2YXIgYz10aGlzLl9zb3VuZEluc3RhbmNlc1thXVtiXTtjLmRlc3Ryb3koKX1kZWxldGUgdGhpcy5fc291bmRJbnN0YW5jZXNbYV0sZGVsZXRlIHRoaXMuX2F1ZGlvU291cmNlc1thXSx0aGlzLl9sb2FkZXJzW2FdJiZ0aGlzLl9sb2FkZXJzW2FdLmRlc3Ryb3koKSxkZWxldGUgdGhpcy5fbG9hZGVyc1thXX19LGIucmVtb3ZlQWxsU291bmRzPWZ1bmN0aW9uKCl7Zm9yKHZhciBhIGluIHRoaXMuX2F1ZGlvU291cmNlcyl0aGlzLnJlbW92ZVNvdW5kKGEpfSxiLmNyZWF0ZT1mdW5jdGlvbihhLGIsYyl7dGhpcy5pc1ByZWxvYWRTdGFydGVkKGEpfHx0aGlzLnByZWxvYWQodGhpcy5yZWdpc3RlcihhKSk7dmFyIGQ9bmV3IHRoaXMuX3NvdW5kSW5zdGFuY2VDbGFzcyhhLGIsYyx0aGlzLl9hdWRpb1NvdXJjZXNbYV0pO3JldHVybiB0aGlzLl9zb3VuZEluc3RhbmNlc1thXS5wdXNoKGQpLGR9LGIuc2V0Vm9sdW1lPWZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLl92b2x1bWU9YSx0aGlzLl91cGRhdGVWb2x1bWUoKSwhMH0sYi5nZXRWb2x1bWU9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5fdm9sdW1lfSxiLnNldE11dGU9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5fdXBkYXRlVm9sdW1lKCksITB9LGIudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4iW0Fic3RyYWN0UGx1Z2luXSJ9LGIuX2hhbmRsZVByZWxvYWRDb21wbGV0ZT1mdW5jdGlvbihhKXt2YXIgYj1hLnRhcmdldC5nZXRJdGVtKCkuc3JjO3RoaXMuX2F1ZGlvU291cmNlc1tiXT1hLnJlc3VsdDtmb3IodmFyIGM9MCxkPXRoaXMuX3NvdW5kSW5zdGFuY2VzW2JdLmxlbmd0aDtkPmM7YysrKXt2YXIgZT10aGlzLl9zb3VuZEluc3RhbmNlc1tiXVtjXTtlLnNldFBsYXliYWNrUmVzb3VyY2UodGhpcy5fYXVkaW9Tb3VyY2VzW2JdKX19LGIuX2hhbmRsZVByZWxvYWRFcnJvcj1mdW5jdGlvbigpe30sYi5fdXBkYXRlVm9sdW1lPWZ1bmN0aW9uKCl7fSxjcmVhdGVqcy5BYnN0cmFjdFBsdWdpbj1hfSgpLHRoaXMuY3JlYXRlanM9dGhpcy5jcmVhdGVqc3x8e30sZnVuY3Rpb24oKXsidXNlIHN0cmljdCI7ZnVuY3Rpb24gYShhKXt0aGlzLkFic3RyYWN0TG9hZGVyX2NvbnN0cnVjdG9yKGEsITAsY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuU09VTkQpfXZhciBiPWNyZWF0ZWpzLmV4dGVuZChhLGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyKTthLmNvbnRleHQ9bnVsbCxiLnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIltXZWJBdWRpb0xvYWRlcl0ifSxiLl9jcmVhdGVSZXF1ZXN0PWZ1bmN0aW9uKCl7dGhpcy5fcmVxdWVzdD1uZXcgY3JlYXRlanMuWEhSUmVxdWVzdCh0aGlzLl9pdGVtLCExKSx0aGlzLl9yZXF1ZXN0LnNldFJlc3BvbnNlVHlwZSgiYXJyYXlidWZmZXIiKX0sYi5fc2VuZENvbXBsZXRlPWZ1bmN0aW9uKCl7YS5jb250ZXh0LmRlY29kZUF1ZGlvRGF0YSh0aGlzLl9yYXdSZXN1bHQsY3JlYXRlanMucHJveHkodGhpcy5faGFuZGxlQXVkaW9EZWNvZGVkLHRoaXMpLGNyZWF0ZWpzLnByb3h5KHRoaXMuX2hhbmRsZUVycm9yLHRoaXMpKX0sYi5faGFuZGxlQXVkaW9EZWNvZGVkPWZ1bmN0aW9uKGEpe3RoaXMuX3Jlc3VsdD1hLHRoaXMuQWJzdHJhY3RMb2FkZXJfX3NlbmRDb21wbGV0ZSgpfSxjcmVhdGVqcy5XZWJBdWRpb0xvYWRlcj1jcmVhdGVqcy5wcm9tb3RlKGEsIkFic3RyYWN0TG9hZGVyIil9KCksdGhpcy5jcmVhdGVqcz10aGlzLmNyZWF0ZWpzfHx7fSxmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjtmdW5jdGlvbiBhKGEsYixkLGUpe3RoaXMuQWJzdHJhY3RTb3VuZEluc3RhbmNlX2NvbnN0cnVjdG9yKGEsYixkLGUpLHRoaXMuZ2Fpbk5vZGU9Yy5jb250ZXh0LmNyZWF0ZUdhaW4oKSx0aGlzLnBhbk5vZGU9Yy5jb250ZXh0LmNyZWF0ZVBhbm5lcigpLHRoaXMucGFuTm9kZS5wYW5uaW5nTW9kZWw9Yy5fcGFubmluZ01vZGVsLHRoaXMucGFuTm9kZS5jb25uZWN0KHRoaXMuZ2Fpbk5vZGUpLHRoaXMuc291cmNlTm9kZT1udWxsLHRoaXMuX3NvdW5kQ29tcGxldGVUaW1lb3V0PW51bGwsdGhpcy5fc291cmNlTm9kZU5leHQ9bnVsbCx0aGlzLl9wbGF5YmFja1N0YXJ0VGltZT0wLHRoaXMuX2VuZGVkSGFuZGxlcj1jcmVhdGVqcy5wcm94eSh0aGlzLl9oYW5kbGVTb3VuZENvbXBsZXRlLHRoaXMpfXZhciBiPWNyZWF0ZWpzLmV4dGVuZChhLGNyZWF0ZWpzLkFic3RyYWN0U291bmRJbnN0YW5jZSksYz1hO2MuY29udGV4dD1udWxsLGMuZGVzdGluYXRpb25Ob2RlPW51bGwsYy5fcGFubmluZ01vZGVsPSJlcXVhbHBvd2VyIixiLmRlc3Ryb3k9ZnVuY3Rpb24oKXt0aGlzLkFic3RyYWN0U291bmRJbnN0YW5jZV9kZXN0cm95KCksdGhpcy5wYW5Ob2RlLmRpc2Nvbm5lY3QoMCksdGhpcy5wYW5Ob2RlPW51bGwsdGhpcy5nYWluTm9kZS5kaXNjb25uZWN0KDApLHRoaXMuZ2Fpbk5vZGU9bnVsbH0sYi50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiJbV2ViQXVkaW9Tb3VuZEluc3RhbmNlXSJ9LGIuX3VwZGF0ZVBhbj1mdW5jdGlvbigpe3RoaXMucGFuTm9kZS5zZXRQb3NpdGlvbih0aGlzLl9wYW4sMCwtLjUpfSxiLl9yZW1vdmVMb29waW5nPWZ1bmN0aW9uKCl7dGhpcy5fc291cmNlTm9kZU5leHQ9dGhpcy5fY2xlYW5VcEF1ZGlvTm9kZSh0aGlzLl9zb3VyY2VOb2RlTmV4dCl9LGIuX2FkZExvb3Bpbmc9ZnVuY3Rpb24oKXt0aGlzLnBsYXlTdGF0ZT09Y3JlYXRlanMuU291bmQuUExBWV9TVUNDRUVERUQmJih0aGlzLl9zb3VyY2VOb2RlTmV4dD10aGlzLl9jcmVhdGVBbmRQbGF5QXVkaW9Ob2RlKHRoaXMuX3BsYXliYWNrU3RhcnRUaW1lLDApKX0sYi5fc2V0RHVyYXRpb25Gcm9tU291cmNlPWZ1bmN0aW9uKCl7dGhpcy5fZHVyYXRpb249MWUzKnRoaXMucGxheWJhY2tSZXNvdXJjZS5kdXJhdGlvbn0sYi5faGFuZGxlQ2xlYW5VcD1mdW5jdGlvbigpe3RoaXMuc291cmNlTm9kZSYmdGhpcy5wbGF5U3RhdGU9PWNyZWF0ZWpzLlNvdW5kLlBMQVlfU1VDQ0VFREVEJiYodGhpcy5zb3VyY2VOb2RlPXRoaXMuX2NsZWFuVXBBdWRpb05vZGUodGhpcy5zb3VyY2VOb2RlKSx0aGlzLl9zb3VyY2VOb2RlTmV4dD10aGlzLl9jbGVhblVwQXVkaW9Ob2RlKHRoaXMuX3NvdXJjZU5vZGVOZXh0KSksMCE9dGhpcy5nYWluTm9kZS5udW1iZXJPZk91dHB1dHMmJnRoaXMuZ2Fpbk5vZGUuZGlzY29ubmVjdCgwKSxjbGVhclRpbWVvdXQodGhpcy5fc291bmRDb21wbGV0ZVRpbWVvdXQpLHRoaXMuX3BsYXliYWNrU3RhcnRUaW1lPTB9LGIuX2NsZWFuVXBBdWRpb05vZGU9ZnVuY3Rpb24oYSl7cmV0dXJuIGEmJihhLnN0b3AoMCksYS5kaXNjb25uZWN0KDApLGE9bnVsbCksYX0sYi5faGFuZGxlU291bmRSZWFkeT1mdW5jdGlvbigpe3RoaXMuZ2Fpbk5vZGUuY29ubmVjdChjLmRlc3RpbmF0aW9uTm9kZSk7dmFyIGE9LjAwMSp0aGlzLl9kdXJhdGlvbixiPS4wMDEqdGhpcy5fcG9zaXRpb247dGhpcy5zb3VyY2VOb2RlPXRoaXMuX2NyZWF0ZUFuZFBsYXlBdWRpb05vZGUoYy5jb250ZXh0LmN1cnJlbnRUaW1lLWEsYiksdGhpcy5fcGxheWJhY2tTdGFydFRpbWU9dGhpcy5zb3VyY2VOb2RlLnN0YXJ0VGltZS1iLHRoaXMuX3NvdW5kQ29tcGxldGVUaW1lb3V0PXNldFRpbWVvdXQodGhpcy5fZW5kZWRIYW5kbGVyLDFlMyooYS1iKSksMCE9dGhpcy5fbG9vcCYmKHRoaXMuX3NvdXJjZU5vZGVOZXh0PXRoaXMuX2NyZWF0ZUFuZFBsYXlBdWRpb05vZGUodGhpcy5fcGxheWJhY2tTdGFydFRpbWUsMCkpfSxiLl9jcmVhdGVBbmRQbGF5QXVkaW9Ob2RlPWZ1bmN0aW9uKGEsYil7dmFyIGQ9Yy5jb250ZXh0LmNyZWF0ZUJ1ZmZlclNvdXJjZSgpO2QuYnVmZmVyPXRoaXMucGxheWJhY2tSZXNvdXJjZSxkLmNvbm5lY3QodGhpcy5wYW5Ob2RlKTt2YXIgZT0uMDAxKnRoaXMuX2R1cmF0aW9uO3JldHVybiBkLnN0YXJ0VGltZT1hK2UsZC5zdGFydChkLnN0YXJ0VGltZSxiKy4wMDEqdGhpcy5fc3RhcnRUaW1lLGUtYiksZH0sYi5fcGF1c2U9ZnVuY3Rpb24oKXt0aGlzLl9wb3NpdGlvbj0xZTMqKGMuY29udGV4dC5jdXJyZW50VGltZS10aGlzLl9wbGF5YmFja1N0YXJ0VGltZSksdGhpcy5zb3VyY2VOb2RlPXRoaXMuX2NsZWFuVXBBdWRpb05vZGUodGhpcy5zb3VyY2VOb2RlKSx0aGlzLl9zb3VyY2VOb2RlTmV4dD10aGlzLl9jbGVhblVwQXVkaW9Ob2RlKHRoaXMuX3NvdXJjZU5vZGVOZXh0KSwwIT10aGlzLmdhaW5Ob2RlLm51bWJlck9mT3V0cHV0cyYmdGhpcy5nYWluTm9kZS5kaXNjb25uZWN0KDApLGNsZWFyVGltZW91dCh0aGlzLl9zb3VuZENvbXBsZXRlVGltZW91dCl9LGIuX3Jlc3VtZT1mdW5jdGlvbigpe3RoaXMuX2hhbmRsZVNvdW5kUmVhZHkoKX0sYi5fdXBkYXRlVm9sdW1lPWZ1bmN0aW9uKCl7dmFyIGE9dGhpcy5fbXV0ZWQ/MDp0aGlzLl92b2x1bWU7YSE9dGhpcy5nYWluTm9kZS5nYWluLnZhbHVlJiYodGhpcy5nYWluTm9kZS5nYWluLnZhbHVlPWEpfSxiLl9jYWxjdWxhdGVDdXJyZW50UG9zaXRpb249ZnVuY3Rpb24oKXtyZXR1cm4gMWUzKihjLmNvbnRleHQuY3VycmVudFRpbWUtdGhpcy5fcGxheWJhY2tTdGFydFRpbWUpfSxiLl91cGRhdGVQb3NpdGlvbj1mdW5jdGlvbigpe3RoaXMuc291cmNlTm9kZT10aGlzLl9jbGVhblVwQXVkaW9Ob2RlKHRoaXMuc291cmNlTm9kZSksdGhpcy5fc291cmNlTm9kZU5leHQ9dGhpcy5fY2xlYW5VcEF1ZGlvTm9kZSh0aGlzLl9zb3VyY2VOb2RlTmV4dCksY2xlYXJUaW1lb3V0KHRoaXMuX3NvdW5kQ29tcGxldGVUaW1lb3V0KSx0aGlzLl9wYXVzZWR8fHRoaXMuX2hhbmRsZVNvdW5kUmVhZHkoKX0sYi5faGFuZGxlTG9vcD1mdW5jdGlvbigpe3RoaXMuX2NsZWFuVXBBdWRpb05vZGUodGhpcy5zb3VyY2VOb2RlKSx0aGlzLnNvdXJjZU5vZGU9dGhpcy5fc291cmNlTm9kZU5leHQsdGhpcy5fcGxheWJhY2tTdGFydFRpbWU9dGhpcy5zb3VyY2VOb2RlLnN0YXJ0VGltZSx0aGlzLl9zb3VyY2VOb2RlTmV4dD10aGlzLl9jcmVhdGVBbmRQbGF5QXVkaW9Ob2RlKHRoaXMuX3BsYXliYWNrU3RhcnRUaW1lLDApLHRoaXMuX3NvdW5kQ29tcGxldGVUaW1lb3V0PXNldFRpbWVvdXQodGhpcy5fZW5kZWRIYW5kbGVyLHRoaXMuX2R1cmF0aW9uKX0sYi5fdXBkYXRlRHVyYXRpb249ZnVuY3Rpb24oKXt0aGlzLl9wYXVzZSgpLHRoaXMuX3Jlc3VtZSgpfSxjcmVhdGVqcy5XZWJBdWRpb1NvdW5kSW5zdGFuY2U9Y3JlYXRlanMucHJvbW90ZShhLCJBYnN0cmFjdFNvdW5kSW5zdGFuY2UiKX0oKSx0aGlzLmNyZWF0ZWpzPXRoaXMuY3JlYXRlanN8fHt9LGZ1bmN0aW9uKCl7InVzZSBzdHJpY3QiO2Z1bmN0aW9uIGEoKXt0aGlzLkFic3RyYWN0UGx1Z2luX2NvbnN0cnVjdG9yKCksdGhpcy5fcGFubmluZ01vZGVsPWMuX3Bhbm5pbmdNb2RlbCx0aGlzLl92b2x1bWU9MSx0aGlzLmNvbnRleHQ9Yy5jb250ZXh0LHRoaXMuZHluYW1pY3NDb21wcmVzc29yTm9kZT10aGlzLmNvbnRleHQuY3JlYXRlRHluYW1pY3NDb21wcmVzc29yKCksdGhpcy5keW5hbWljc0NvbXByZXNzb3JOb2RlLmNvbm5lY3QodGhpcy5jb250ZXh0LmRlc3RpbmF0aW9uKSx0aGlzLmdhaW5Ob2RlPXRoaXMuY29udGV4dC5jcmVhdGVHYWluKCksdGhpcy5nYWluTm9kZS5jb25uZWN0KHRoaXMuZHluYW1pY3NDb21wcmVzc29yTm9kZSksY3JlYXRlanMuV2ViQXVkaW9Tb3VuZEluc3RhbmNlLmRlc3RpbmF0aW9uTm9kZT10aGlzLmdhaW5Ob2RlLHRoaXMuX2NhcGFiaWxpdGllcz1jLl9jYXBhYmlsaXRpZXMsdGhpcy5fbG9hZGVyQ2xhc3M9Y3JlYXRlanMuV2ViQXVkaW9Mb2FkZXIsdGhpcy5fc291bmRJbnN0YW5jZUNsYXNzPWNyZWF0ZWpzLldlYkF1ZGlvU291bmRJbnN0YW5jZSx0aGlzLl9hZGRQcm9wc1RvQ2xhc3NlcygpfXZhciBiPWNyZWF0ZWpzLmV4dGVuZChhLGNyZWF0ZWpzLkFic3RyYWN0UGx1Z2luKSxjPWE7Yy5fY2FwYWJpbGl0aWVzPW51bGwsYy5fcGFubmluZ01vZGVsPSJlcXVhbHBvd2VyIixjLmNvbnRleHQ9bnVsbCxjLmlzU3VwcG9ydGVkPWZ1bmN0aW9uKCl7dmFyIGE9Y3JlYXRlanMuQnJvd3NlckRldGVjdC5pc0lPU3x8Y3JlYXRlanMuQnJvd3NlckRldGVjdC5pc0FuZHJvaWR8fGNyZWF0ZWpzLkJyb3dzZXJEZXRlY3QuaXNCbGFja2JlcnJ5O3JldHVybiJmaWxlOiIhPWxvY2F0aW9uLnByb3RvY29sfHxhfHx0aGlzLl9pc0ZpbGVYSFJTdXBwb3J0ZWQoKT8oYy5fZ2VuZXJhdGVDYXBhYmlsaXRpZXMoKSxudWxsPT1jLmNvbnRleHQ/ITE6ITApOiExfSxjLnBsYXlFbXB0eVNvdW5kPWZ1bmN0aW9uKCl7dmFyIGE9Yy5jb250ZXh0LmNyZWF0ZUJ1ZmZlclNvdXJjZSgpO2EuYnVmZmVyPWMuY29udGV4dC5jcmVhdGVCdWZmZXIoMSwxLDIyMDUwKSxhLmNvbm5lY3QoYy5jb250ZXh0LmRlc3RpbmF0aW9uKSxhLnN0YXJ0KDAsMCwwKX0sYy5faXNGaWxlWEhSU3VwcG9ydGVkPWZ1bmN0aW9uKCl7dmFyIGE9ITAsYj1uZXcgWE1MSHR0cFJlcXVlc3Q7dHJ5e2Iub3BlbigiR0VUIiwiV2ViQXVkaW9QbHVnaW5UZXN0LmZhaWwiLCExKX1jYXRjaChjKXtyZXR1cm4gYT0hMX1iLm9uZXJyb3I9ZnVuY3Rpb24oKXthPSExfSxiLm9ubG9hZD1mdW5jdGlvbigpe2E9NDA0PT10aGlzLnN0YXR1c3x8MjAwPT10aGlzLnN0YXR1c3x8MD09dGhpcy5zdGF0dXMmJiIiIT10aGlzLnJlc3BvbnNlfTt0cnl7Yi5zZW5kKCl9Y2F0Y2goYyl7YT0hMX1yZXR1cm4gYX0sYy5fZ2VuZXJhdGVDYXBhYmlsaXRpZXM9ZnVuY3Rpb24oKXtpZihudWxsPT1jLl9jYXBhYmlsaXRpZXMpe3ZhciBhPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImF1ZGlvIik7aWYobnVsbD09YS5jYW5QbGF5VHlwZSlyZXR1cm4gbnVsbDtpZihudWxsPT1jLmNvbnRleHQpaWYod2luZG93LkF1ZGlvQ29udGV4dCljLmNvbnRleHQ9bmV3IEF1ZGlvQ29udGV4dDtlbHNle2lmKCF3aW5kb3cud2Via2l0QXVkaW9Db250ZXh0KXJldHVybiBudWxsO2MuY29udGV4dD1uZXcgd2Via2l0QXVkaW9Db250ZXh0fWMuX2NvbXBhdGliaWxpdHlTZXRVcCgpLGMucGxheUVtcHR5U291bmQoKSxjLl9jYXBhYmlsaXRpZXM9e3Bhbm5pbmc6ITAsdm9sdW1lOiEwLHRyYWNrczotMX07Zm9yKHZhciBiPWNyZWF0ZWpzLlNvdW5kLlNVUFBPUlRFRF9FWFRFTlNJT05TLGQ9Y3JlYXRlanMuU291bmQuRVhURU5TSU9OX01BUCxlPTAsZj1iLmxlbmd0aDtmPmU7ZSsrKXt2YXIgZz1iW2VdLGg9ZFtnXXx8ZztjLl9jYXBhYmlsaXRpZXNbZ109Im5vIiE9YS5jYW5QbGF5VHlwZSgiYXVkaW8vIitnKSYmIiIhPWEuY2FuUGxheVR5cGUoImF1ZGlvLyIrZyl8fCJubyIhPWEuY2FuUGxheVR5cGUoImF1ZGlvLyIraCkmJiIiIT1hLmNhblBsYXlUeXBlKCJhdWRpby8iK2gpfWMuY29udGV4dC5kZXN0aW5hdGlvbi5udW1iZXJPZkNoYW5uZWxzPDImJihjLl9jYXBhYmlsaXRpZXMucGFubmluZz0hMSl9fSxjLl9jb21wYXRpYmlsaXR5U2V0VXA9ZnVuY3Rpb24oKXtpZihjLl9wYW5uaW5nTW9kZWw9ImVxdWFscG93ZXIiLCFjLmNvbnRleHQuY3JlYXRlR2Fpbil7Yy5jb250ZXh0LmNyZWF0ZUdhaW49Yy5jb250ZXh0LmNyZWF0ZUdhaW5Ob2RlO3ZhciBhPWMuY29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTthLl9fcHJvdG9fXy5zdGFydD1hLl9fcHJvdG9fXy5ub3RlR3JhaW5PbixhLl9fcHJvdG9fXy5zdG9wPWEuX19wcm90b19fLm5vdGVPZmYsYy5fcGFubmluZ01vZGVsPTB9fSxiLnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIltXZWJBdWRpb1BsdWdpbl0ifSxiLl9hZGRQcm9wc1RvQ2xhc3Nlcz1mdW5jdGlvbigpe3ZhciBhPXRoaXMuX3NvdW5kSW5zdGFuY2VDbGFzczthLmNvbnRleHQ9dGhpcy5jb250ZXh0LGEuZGVzdGluYXRpb25Ob2RlPXRoaXMuZ2Fpbk5vZGUsYS5fcGFubmluZ01vZGVsPXRoaXMuX3Bhbm5pbmdNb2RlbCx0aGlzLl9sb2FkZXJDbGFzcy5jb250ZXh0PXRoaXMuY29udGV4dH0sYi5fdXBkYXRlVm9sdW1lPWZ1bmN0aW9uKCl7dmFyIGE9Y3JlYXRlanMuU291bmQuX21hc3Rlck11dGU/MDp0aGlzLl92b2x1bWU7YSE9dGhpcy5nYWluTm9kZS5nYWluLnZhbHVlJiYodGhpcy5nYWluTm9kZS5nYWluLnZhbHVlPWEpfSxjcmVhdGVqcy5XZWJBdWRpb1BsdWdpbj1jcmVhdGVqcy5wcm9tb3RlKGEsIkFic3RyYWN0UGx1Z2luIil9KCksdGhpcy5jcmVhdGVqcz10aGlzLmNyZWF0ZWpzfHx7fSxmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjtmdW5jdGlvbiBhKGEpe3RoaXMuc3JjPWEsdGhpcy5sZW5ndGg9MCx0aGlzLmF2YWlsYWJsZT0wLHRoaXMudGFncz1bXSx0aGlzLmR1cmF0aW9uPTB9dmFyIGI9YS5wcm90b3R5cGU7Yi5jb25zdHJ1Y3Rvcj1hO3ZhciBjPWE7Yy50YWdzPXt9LGMuZ2V0PWZ1bmN0aW9uKGIpe3ZhciBkPWMudGFnc1tiXTtyZXR1cm4gbnVsbD09ZCYmKGQ9Yy50YWdzW2JdPW5ldyBhKGIpKSxkfSxjLnJlbW92ZT1mdW5jdGlvbihhKXt2YXIgYj1jLnRhZ3NbYV07cmV0dXJuIG51bGw9PWI/ITE6KGIucmVtb3ZlQWxsKCksZGVsZXRlIGMudGFnc1thXSwhMCl9LGMuZ2V0SW5zdGFuY2U9ZnVuY3Rpb24oYSl7dmFyIGI9Yy50YWdzW2FdO3JldHVybiBudWxsPT1iP251bGw6Yi5nZXQoKX0sYy5zZXRJbnN0YW5jZT1mdW5jdGlvbihhLGIpe3ZhciBkPWMudGFnc1thXTtyZXR1cm4gbnVsbD09ZD9udWxsOmQuc2V0KGIpfSxjLmdldER1cmF0aW9uPWZ1bmN0aW9uKGEpe3ZhciBiPWMudGFnc1thXTtyZXR1cm4gbnVsbD09Yj8wOmIuZ2V0RHVyYXRpb24oKX0sYi5hZGQ9ZnVuY3Rpb24oYSl7dGhpcy50YWdzLnB1c2goYSksdGhpcy5sZW5ndGgrKyx0aGlzLmF2YWlsYWJsZSsrfSxiLnJlbW92ZUFsbD1mdW5jdGlvbigpe2Zvcih2YXIgYTt0aGlzLmxlbmd0aC0tOylhPXRoaXMudGFnc1t0aGlzLmxlbmd0aF0sYS5wYXJlbnROb2RlJiZhLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoYSksZGVsZXRlIHRoaXMudGFnc1t0aGlzLmxlbmd0aF07dGhpcy5zcmM9bnVsbCx0aGlzLnRhZ3MubGVuZ3RoPTB9LGIuZ2V0PWZ1bmN0aW9uKCl7aWYoMD09dGhpcy50YWdzLmxlbmd0aClyZXR1cm4gbnVsbDt0aGlzLmF2YWlsYWJsZT10aGlzLnRhZ3MubGVuZ3RoO3ZhciBhPXRoaXMudGFncy5wb3AoKTtyZXR1cm4gbnVsbD09YS5wYXJlbnROb2RlJiZkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGEpLGF9LGIuc2V0PWZ1bmN0aW9uKGEpe3ZhciBiPWNyZWF0ZWpzLmluZGV4T2YodGhpcy50YWdzLGEpOy0xPT1iJiZ0aGlzLnRhZ3MucHVzaChhKSx0aGlzLmF2YWlsYWJsZT10aGlzLnRhZ3MubGVuZ3RofSxiLmdldER1cmF0aW9uPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZHVyYXRpb258fCh0aGlzLmR1cmF0aW9uPTFlMyp0aGlzLnRhZ3NbdGhpcy50YWdzLmxlbmd0aC0xXS5kdXJhdGlvbiksdGhpcy5kdXJhdGlvbn0sYi50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiJbSFRNTEF1ZGlvVGFnUG9vbF0ifSxjcmVhdGVqcy5IVE1MQXVkaW9UYWdQb29sPWF9KCksdGhpcy5jcmVhdGVqcz10aGlzLmNyZWF0ZWpzfHx7fSxmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjtmdW5jdGlvbiBhKGEsYixjLGQpe3RoaXMuQWJzdHJhY3RTb3VuZEluc3RhbmNlX2NvbnN0cnVjdG9yKGEsYixjLGQpLHRoaXMuX2F1ZGlvU3ByaXRlU3RvcFRpbWU9bnVsbCx0aGlzLl9kZWxheVRpbWVvdXRJZD1udWxsLHRoaXMuX2VuZGVkSGFuZGxlcj1jcmVhdGVqcy5wcm94eSh0aGlzLl9oYW5kbGVTb3VuZENvbXBsZXRlLHRoaXMpLHRoaXMuX3JlYWR5SGFuZGxlcj1jcmVhdGVqcy5wcm94eSh0aGlzLl9oYW5kbGVUYWdSZWFkeSx0aGlzKSx0aGlzLl9zdGFsbGVkSGFuZGxlcj1jcmVhdGVqcy5wcm94eSh0aGlzLnBsYXlGYWlsZWQsdGhpcyksdGhpcy5fYXVkaW9TcHJpdGVFbmRIYW5kbGVyPWNyZWF0ZWpzLnByb3h5KHRoaXMuX2hhbmRsZUF1ZGlvU3ByaXRlTG9vcCx0aGlzKSx0aGlzLl9sb29wSGFuZGxlcj1jcmVhdGVqcy5wcm94eSh0aGlzLl9oYW5kbGVTb3VuZENvbXBsZXRlLHRoaXMpLGM/dGhpcy5fYXVkaW9TcHJpdGVTdG9wVGltZT0uMDAxKihiK2MpOnRoaXMuX2R1cmF0aW9uPWNyZWF0ZWpzLkhUTUxBdWRpb1RhZ1Bvb2wuZ2V0RHVyYXRpb24odGhpcy5zcmMpfXZhciBiPWNyZWF0ZWpzLmV4dGVuZChhLGNyZWF0ZWpzLkFic3RyYWN0U291bmRJbnN0YW5jZSk7Yi5zZXRNYXN0ZXJWb2x1bWU9ZnVuY3Rpb24oKXt0aGlzLl91cGRhdGVWb2x1bWUoKX0sYi5zZXRNYXN0ZXJNdXRlPWZ1bmN0aW9uKCl7dGhpcy5fdXBkYXRlVm9sdW1lKCl9LGIudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4iW0hUTUxBdWRpb1NvdW5kSW5zdGFuY2VdIn0sYi5fcmVtb3ZlTG9vcGluZz1mdW5jdGlvbigpe251bGwhPXRoaXMuX3BsYXliYWNrUmVzb3VyY2UmJih0aGlzLl9wbGF5YmFja1Jlc291cmNlLmxvb3A9ITEsdGhpcy5fcGxheWJhY2tSZXNvdXJjZS5yZW1vdmVFdmVudExpc3RlbmVyKGNyZWF0ZWpzLkhUTUxBdWRpb1BsdWdpbi5fQVVESU9fU0VFS0VELHRoaXMuX2xvb3BIYW5kbGVyLCExKSl9LGIuX2FkZExvb3Bpbmc9ZnVuY3Rpb24oKXtudWxsPT10aGlzLl9wbGF5YmFja1Jlc291cmNlfHx0aGlzLl9hdWRpb1Nwcml0ZVN0b3BUaW1lfHwodGhpcy5fcGxheWJhY2tSZXNvdXJjZS5hZGRFdmVudExpc3RlbmVyKGNyZWF0ZWpzLkhUTUxBdWRpb1BsdWdpbi5fQVVESU9fU0VFS0VELHRoaXMuX2xvb3BIYW5kbGVyLCExKSx0aGlzLl9wbGF5YmFja1Jlc291cmNlLmxvb3A9ITApfSxiLl9oYW5kbGVDbGVhblVwPWZ1bmN0aW9uKCl7dmFyIGE9dGhpcy5fcGxheWJhY2tSZXNvdXJjZTtpZihudWxsIT1hKXthLnBhdXNlKCksYS5sb29wPSExLGEucmVtb3ZlRXZlbnRMaXN0ZW5lcihjcmVhdGVqcy5IVE1MQXVkaW9QbHVnaW4uX0FVRElPX0VOREVELHRoaXMuX2VuZGVkSGFuZGxlciwhMSksYS5yZW1vdmVFdmVudExpc3RlbmVyKGNyZWF0ZWpzLkhUTUxBdWRpb1BsdWdpbi5fQVVESU9fUkVBRFksdGhpcy5fcmVhZHlIYW5kbGVyLCExKSxhLnJlbW92ZUV2ZW50TGlzdGVuZXIoY3JlYXRlanMuSFRNTEF1ZGlvUGx1Z2luLl9BVURJT19TVEFMTEVELHRoaXMuX3N0YWxsZWRIYW5kbGVyLCExKSxhLnJlbW92ZUV2ZW50TGlzdGVuZXIoY3JlYXRlanMuSFRNTEF1ZGlvUGx1Z2luLl9BVURJT19TRUVLRUQsdGhpcy5fbG9vcEhhbmRsZXIsITEpLGEucmVtb3ZlRXZlbnRMaXN0ZW5lcihjcmVhdGVqcy5IVE1MQXVkaW9QbHVnaW4uX1RJTUVfVVBEQVRFLHRoaXMuX2F1ZGlvU3ByaXRlRW5kSGFuZGxlciwhMSk7dHJ5e2EuY3VycmVudFRpbWU9dGhpcy5fc3RhcnRUaW1lfWNhdGNoKGIpe31jcmVhdGVqcy5IVE1MQXVkaW9UYWdQb29sLnNldEluc3RhbmNlKHRoaXMuc3JjLGEpLHRoaXMuX3BsYXliYWNrUmVzb3VyY2U9bnVsbH19LGIuX2JlZ2luUGxheWluZz1mdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gdGhpcy5fcGxheWJhY2tSZXNvdXJjZT1jcmVhdGVqcy5IVE1MQXVkaW9UYWdQb29sLmdldEluc3RhbmNlKHRoaXMuc3JjKSx0aGlzLkFic3RyYWN0U291bmRJbnN0YW5jZV9fYmVnaW5QbGF5aW5nKGEsYixjLGQpfSxiLl9oYW5kbGVTb3VuZFJlYWR5PWZ1bmN0aW9uKCl7aWYoNCE9PXRoaXMuX3BsYXliYWNrUmVzb3VyY2UucmVhZHlTdGF0ZSl7dmFyIGE9dGhpcy5fcGxheWJhY2tSZXNvdXJjZTtyZXR1cm4gYS5hZGRFdmVudExpc3RlbmVyKGNyZWF0ZWpzLkhUTUxBdWRpb1BsdWdpbi5fQVVESU9fUkVBRFksdGhpcy5fcmVhZHlIYW5kbGVyLCExKSxhLmFkZEV2ZW50TGlzdGVuZXIoY3JlYXRlanMuSFRNTEF1ZGlvUGx1Z2luLl9BVURJT19TVEFMTEVELHRoaXMuX3N0YWxsZWRIYW5kbGVyLCExKSxhLnByZWxvYWQ9ImF1dG8iLHZvaWQgYS5sb2FkKCl9dGhpcy5fdXBkYXRlVm9sdW1lKCksdGhpcy5fcGxheWJhY2tSZXNvdXJjZS5jdXJyZW50VGltZT0uMDAxKih0aGlzLl9zdGFydFRpbWUrdGhpcy5fcG9zaXRpb24pLHRoaXMuX2F1ZGlvU3ByaXRlU3RvcFRpbWU/dGhpcy5fcGxheWJhY2tSZXNvdXJjZS5hZGRFdmVudExpc3RlbmVyKGNyZWF0ZWpzLkhUTUxBdWRpb1BsdWdpbi5fVElNRV9VUERBVEUsdGhpcy5fYXVkaW9TcHJpdGVFbmRIYW5kbGVyLCExKToodGhpcy5fcGxheWJhY2tSZXNvdXJjZS5hZGRFdmVudExpc3RlbmVyKGNyZWF0ZWpzLkhUTUxBdWRpb1BsdWdpbi5fQVVESU9fRU5ERUQsdGhpcy5fZW5kZWRIYW5kbGVyLCExKSwwIT10aGlzLl9sb29wJiYodGhpcy5fcGxheWJhY2tSZXNvdXJjZS5hZGRFdmVudExpc3RlbmVyKGNyZWF0ZWpzLkhUTUxBdWRpb1BsdWdpbi5fQVVESU9fU0VFS0VELHRoaXMuX2xvb3BIYW5kbGVyLCExKSx0aGlzLl9wbGF5YmFja1Jlc291cmNlLmxvb3A9ITApKSx0aGlzLl9wbGF5YmFja1Jlc291cmNlLnBsYXkoKX0sYi5faGFuZGxlVGFnUmVhZHk9ZnVuY3Rpb24oKXt0aGlzLl9wbGF5YmFja1Jlc291cmNlLnJlbW92ZUV2ZW50TGlzdGVuZXIoY3JlYXRlanMuSFRNTEF1ZGlvUGx1Z2luLl9BVURJT19SRUFEWSx0aGlzLl9yZWFkeUhhbmRsZXIsITEpLHRoaXMuX3BsYXliYWNrUmVzb3VyY2UucmVtb3ZlRXZlbnRMaXN0ZW5lcihjcmVhdGVqcy5IVE1MQXVkaW9QbHVnaW4uX0FVRElPX1NUQUxMRUQsdGhpcy5fc3RhbGxlZEhhbmRsZXIsITEpLHRoaXMuX2hhbmRsZVNvdW5kUmVhZHkoKX0sYi5fcGF1c2U9ZnVuY3Rpb24oKXt0aGlzLl9wbGF5YmFja1Jlc291cmNlLnBhdXNlKCl9LGIuX3Jlc3VtZT1mdW5jdGlvbigpe3RoaXMuX3BsYXliYWNrUmVzb3VyY2UucGxheSgpfSxiLl91cGRhdGVWb2x1bWU9ZnVuY3Rpb24oKXtpZihudWxsIT10aGlzLl9wbGF5YmFja1Jlc291cmNlKXt2YXIgYT10aGlzLl9tdXRlZHx8Y3JlYXRlanMuU291bmQuX21hc3Rlck11dGU/MDp0aGlzLl92b2x1bWUqY3JlYXRlanMuU291bmQuX21hc3RlclZvbHVtZTthIT10aGlzLl9wbGF5YmFja1Jlc291cmNlLnZvbHVtZSYmKHRoaXMuX3BsYXliYWNrUmVzb3VyY2Uudm9sdW1lPWEpfX0sYi5fY2FsY3VsYXRlQ3VycmVudFBvc2l0aW9uPWZ1bmN0aW9uKCl7cmV0dXJuIDFlMyp0aGlzLl9wbGF5YmFja1Jlc291cmNlLmN1cnJlbnRUaW1lLXRoaXMuX3N0YXJ0VGltZX0sYi5fdXBkYXRlUG9zaXRpb249ZnVuY3Rpb24oKXt0aGlzLl9wbGF5YmFja1Jlc291cmNlLnJlbW92ZUV2ZW50TGlzdGVuZXIoY3JlYXRlanMuSFRNTEF1ZGlvUGx1Z2luLl9BVURJT19TRUVLRUQsdGhpcy5fbG9vcEhhbmRsZXIsITEpLHRoaXMuX3BsYXliYWNrUmVzb3VyY2UuYWRkRXZlbnRMaXN0ZW5lcihjcmVhdGVqcy5IVE1MQXVkaW9QbHVnaW4uX0FVRElPX1NFRUtFRCx0aGlzLl9oYW5kbGVTZXRQb3NpdGlvblNlZWssITEpO3RyeXt0aGlzLl9wbGF5YmFja1Jlc291cmNlLmN1cnJlbnRUaW1lPS4wMDEqKHRoaXMuX3Bvc2l0aW9uK3RoaXMuX3N0YXJ0VGltZSl9Y2F0Y2goYSl7dGhpcy5faGFuZGxlU2V0UG9zaXRpb25TZWVrKG51bGwpfX0sYi5faGFuZGxlU2V0UG9zaXRpb25TZWVrPWZ1bmN0aW9uKCl7bnVsbCE9dGhpcy5fcGxheWJhY2tSZXNvdXJjZSYmKHRoaXMuX3BsYXliYWNrUmVzb3VyY2UucmVtb3ZlRXZlbnRMaXN0ZW5lcihjcmVhdGVqcy5IVE1MQXVkaW9QbHVnaW4uX0FVRElPX1NFRUtFRCx0aGlzLl9oYW5kbGVTZXRQb3NpdGlvblNlZWssITEpLHRoaXMuX3BsYXliYWNrUmVzb3VyY2UuYWRkRXZlbnRMaXN0ZW5lcihjcmVhdGVqcy5IVE1MQXVkaW9QbHVnaW4uX0FVRElPX1NFRUtFRCx0aGlzLl9sb29wSGFuZGxlciwhMSkpfSxiLl9oYW5kbGVBdWRpb1Nwcml0ZUxvb3A9ZnVuY3Rpb24oKXt0aGlzLl9wbGF5YmFja1Jlc291cmNlLmN1cnJlbnRUaW1lPD10aGlzLl9hdWRpb1Nwcml0ZVN0b3BUaW1lfHwodGhpcy5fcGxheWJhY2tSZXNvdXJjZS5wYXVzZSgpLDA9PXRoaXMuX2xvb3A/dGhpcy5faGFuZGxlU291bmRDb21wbGV0ZShudWxsKToodGhpcy5fcG9zaXRpb249MCx0aGlzLl9sb29wLS0sdGhpcy5fcGxheWJhY2tSZXNvdXJjZS5jdXJyZW50VGltZT0uMDAxKnRoaXMuX3N0YXJ0VGltZSx0aGlzLl9wYXVzZWR8fHRoaXMuX3BsYXliYWNrUmVzb3VyY2UucGxheSgpLHRoaXMuX3NlbmRFdmVudCgibG9vcCIpKSl9LGIuX2hhbmRsZUxvb3A9ZnVuY3Rpb24oKXswPT10aGlzLl9sb29wJiYodGhpcy5fcGxheWJhY2tSZXNvdXJjZS5sb29wPSExLHRoaXMuX3BsYXliYWNrUmVzb3VyY2UucmVtb3ZlRXZlbnRMaXN0ZW5lcihjcmVhdGVqcy5IVE1MQXVkaW9QbHVnaW4uX0FVRElPX1NFRUtFRCx0aGlzLl9sb29wSGFuZGxlciwhMSkpfSxiLl91cGRhdGVEdXJhdGlvbj1mdW5jdGlvbigpe3RoaXMuX2F1ZGlvU3ByaXRlU3RvcFRpbWU9LjAwMSooc3RhcnRUaW1lK2R1cmF0aW9uKSx0aGlzLnBsYXlTdGF0ZT09Y3JlYXRlanMuU291bmQuUExBWV9TVUNDRUVERUQmJih0aGlzLl9wbGF5YmFja1Jlc291cmNlLnJlbW92ZUV2ZW50TGlzdGVuZXIoY3JlYXRlanMuSFRNTEF1ZGlvUGx1Z2luLl9BVURJT19FTkRFRCx0aGlzLl9lbmRlZEhhbmRsZXIsITEpLHRoaXMuX3BsYXliYWNrUmVzb3VyY2UuYWRkRXZlbnRMaXN0ZW5lcihjcmVhdGVqcy5IVE1MQXVkaW9QbHVnaW4uX1RJTUVfVVBEQVRFLHRoaXMuX2F1ZGlvU3ByaXRlRW5kSGFuZGxlciwhMSkpfSxjcmVhdGVqcy5IVE1MQXVkaW9Tb3VuZEluc3RhbmNlPWNyZWF0ZWpzLnByb21vdGUoYSwiQWJzdHJhY3RTb3VuZEluc3RhbmNlIil9KCksdGhpcy5jcmVhdGVqcz10aGlzLmNyZWF0ZWpzfHx7fSxmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjtmdW5jdGlvbiBhKCl7dGhpcy5BYnN0cmFjdFBsdWdpbl9jb25zdHJ1Y3RvcigpLHRoaXMuZGVmYXVsdE51bUNoYW5uZWxzPTIsdGhpcy5fY2FwYWJpbGl0aWVzPWMuX2NhcGFiaWxpdGllcyx0aGlzLl9sb2FkZXJDbGFzcz1jcmVhdGVqcy5Tb3VuZExvYWRlcix0aGlzLl9zb3VuZEluc3RhbmNlQ2xhc3M9Y3JlYXRlanMuSFRNTEF1ZGlvU291bmRJbnN0YW5jZX12YXIgYj1jcmVhdGVqcy5leHRlbmQoYSxjcmVhdGVqcy5BYnN0cmFjdFBsdWdpbiksYz1hO2MuTUFYX0lOU1RBTkNFUz0zMCxjLl9BVURJT19SRUFEWT0iY2FucGxheXRocm91Z2giLGMuX0FVRElPX0VOREVEPSJlbmRlZCIsYy5fQVVESU9fU0VFS0VEPSJzZWVrZWQiLGMuX0FVRElPX1NUQUxMRUQ9InN0YWxsZWQiLGMuX1RJTUVfVVBEQVRFPSJ0aW1ldXBkYXRlIixjLl9jYXBhYmlsaXRpZXM9bnVsbCxjLmVuYWJsZUlPUz0hMSxjLmlzU3VwcG9ydGVkPWZ1bmN0aW9uKCl7cmV0dXJuIGMuX2dlbmVyYXRlQ2FwYWJpbGl0aWVzKCksbnVsbD09Yy5fY2FwYWJpbGl0aWVzPyExOiEwfSxjLl9nZW5lcmF0ZUNhcGFiaWxpdGllcz1mdW5jdGlvbigpe2lmKG51bGw9PWMuX2NhcGFiaWxpdGllcyl7dmFyIGE9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYXVkaW8iKTtpZihudWxsPT1hLmNhblBsYXlUeXBlKXJldHVybiBudWxsO2MuX2NhcGFiaWxpdGllcz17cGFubmluZzohMCx2b2x1bWU6ITAsdHJhY2tzOi0xfTtmb3IodmFyIGI9Y3JlYXRlanMuU291bmQuU1VQUE9SVEVEX0VYVEVOU0lPTlMsZD1jcmVhdGVqcy5Tb3VuZC5FWFRFTlNJT05fTUFQLGU9MCxmPWIubGVuZ3RoO2Y+ZTtlKyspe3ZhciBnPWJbZV0saD1kW2ddfHxnO2MuX2NhcGFiaWxpdGllc1tnXT0ibm8iIT1hLmNhblBsYXlUeXBlKCJhdWRpby8iK2cpJiYiIiE9YS5jYW5QbGF5VHlwZSgiYXVkaW8vIitnKXx8Im5vIiE9YS5jYW5QbGF5VHlwZSgiYXVkaW8vIitoKSYmIiIhPWEuY2FuUGxheVR5cGUoImF1ZGlvLyIraCl9fX0sYi5yZWdpc3Rlcj1mdW5jdGlvbihhLGIpe2Zvcih2YXIgYz1jcmVhdGVqcy5IVE1MQXVkaW9UYWdQb29sLmdldChhLnNyYyksZD1udWxsLGU9MDtiPmU7ZSsrKWQ9dGhpcy5fY3JlYXRlVGFnKGEuc3JjKSxjLmFkZChkKTt2YXIgZj10aGlzLkFic3RyYWN0UGx1Z2luX3JlZ2lzdGVyKGEsYik7cmV0dXJuIGYuc2V0VGFnKGQpLGZ9LGIucmVtb3ZlU291bmQ9ZnVuY3Rpb24oYSl7dGhpcy5BYnN0cmFjdFBsdWdpbl9yZW1vdmVTb3VuZChhKSxjcmVhdGVqcy5IVE1MQXVkaW9UYWdQb29sLnJlbW92ZShhKX0sYi5jcmVhdGU9ZnVuY3Rpb24oYSxiLGMpe3ZhciBkPXRoaXMuQWJzdHJhY3RQbHVnaW5fY3JlYXRlKGEsYixjKTtyZXR1cm4gZC5zZXRQbGF5YmFja1Jlc291cmNlKG51bGwpLGR9LGIudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4iW0hUTUxBdWRpb1BsdWdpbl0ifSxiLnNldFZvbHVtZT1iLmdldFZvbHVtZT1iLnNldE11dGU9bnVsbCxiLl9jcmVhdGVUYWc9ZnVuY3Rpb24oYSl7dmFyIGI9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYXVkaW8iKTtyZXR1cm4gYi5hdXRvcGxheT0hMSxiLnByZWxvYWQ9Im5vbmUiLGIuc3JjPWEsYn0sY3JlYXRlanMuSFRNTEF1ZGlvUGx1Z2luPWNyZWF0ZWpzLnByb21vdGUoYSwiQWJzdHJhY3RQbHVnaW4iKX0oKTs=" ></script>



<!--
	<script type="text/javascript" src="../lib/preloadjs-NEXT.combined.js"></script>
	-->
	<script id="script_preloadjs_next_combined_js" src="data:/text/plain;base64,LyohCiogUHJlbG9hZEpTCiogVmlzaXQgaHR0cDovL2NyZWF0ZWpzLmNvbS8gZm9yIGRvY3VtZW50YXRpb24sIHVwZGF0ZXMgYW5kIGV4YW1wbGVzLgoqCiogQ29weXJpZ2h0IChjKSAyMDEwIGdza2lubmVyLmNvbSwgaW5jLgoqCiogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24KKiBvYnRhaW5pbmcgYSBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbgoqIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQKKiByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwKKiBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbAoqIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZQoqIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nCiogY29uZGl0aW9uczoKKgoqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlCiogaW5jbHVkZWQgaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCioKKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwKKiBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMKKiBPRiBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORAoqIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUCiogSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksCiogV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HCiogRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUgoqIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KKi8KCgovLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwovLyB2ZXJzaW9uLmpzCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgp0aGlzLmNyZWF0ZWpzID0gdGhpcy5jcmVhdGVqcyB8fCB7fTsKCihmdW5jdGlvbiAoKSB7CgkidXNlIHN0cmljdCI7CgoJLyoqCgkgKiBTdGF0aWMgY2xhc3MgaG9sZGluZyBsaWJyYXJ5IHNwZWNpZmljIGluZm9ybWF0aW9uIHN1Y2ggYXMgdGhlIHZlcnNpb24gYW5kIGJ1aWxkRGF0ZSBvZiB0aGUgbGlicmFyeS4KCSAqIEBjbGFzcyBQcmVsb2FkSlMKCSAqKi8KCXZhciBzID0gY3JlYXRlanMuUHJlbG9hZEpTID0gY3JlYXRlanMuUHJlbG9hZEpTIHx8IHt9OwoKCS8qKgoJICogVGhlIHZlcnNpb24gc3RyaW5nIGZvciB0aGlzIHJlbGVhc2UuCgkgKiBAcHJvcGVydHkgdmVyc2lvbgoJICogQHR5cGUge1N0cmluZ30KCSAqIEBzdGF0aWMKCSAqKi8KCXMudmVyc2lvbiA9IC8qPXZlcnNpb24qLyJORVhUIjsgLy8gaW5qZWN0ZWQgYnkgYnVpbGQgcHJvY2VzcwoKCS8qKgoJICogVGhlIGJ1aWxkIGRhdGUgZm9yIHRoaXMgcmVsZWFzZSBpbiBVVEMgZm9ybWF0LgoJICogQHByb3BlcnR5IGJ1aWxkRGF0ZQoJICogQHR5cGUge1N0cmluZ30KCSAqIEBzdGF0aWMKCSAqKi8KCXMuYnVpbGREYXRlID0gLyo9ZGF0ZSovIkZyaSwgMDIgSmFuIDIwMTUgMTY6Mjk6NTkgR01UIjsgLy8gaW5qZWN0ZWQgYnkgYnVpbGQgcHJvY2VzcwoKfSkoKTsKCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi8vIGV4dGVuZC5qcwovLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoKdGhpcy5jcmVhdGVqcyA9IHRoaXMuY3JlYXRlanN8fHt9OwoKLyoqCiAqIEBjbGFzcyBVdGlsaXR5IE1ldGhvZHMKICovCgovKioKICogU2V0cyB1cCB0aGUgcHJvdG90eXBlIGNoYWluIGFuZCBjb25zdHJ1Y3RvciBwcm9wZXJ0eSBmb3IgYSBuZXcgY2xhc3MuCiAqCiAqIFRoaXMgc2hvdWxkIGJlIGNhbGxlZCByaWdodCBhZnRlciBjcmVhdGluZyB0aGUgY2xhc3MgY29uc3RydWN0b3IuCiAqCiAqIAlmdW5jdGlvbiBNeVN1YkNsYXNzKCkge30KICogCWNyZWF0ZWpzLmV4dGVuZChNeVN1YkNsYXNzLCBNeVN1cGVyQ2xhc3MpOwogKiAJQ2xhc3NCLnByb3RvdHlwZS5kb1NvbWV0aGluZyA9IGZ1bmN0aW9uKCkgeyB9CiAqCiAqIAl2YXIgZm9vID0gbmV3IE15U3ViQ2xhc3MoKTsKICogCWNvbnNvbGUubG9nKGZvbyBpbnN0YW5jZW9mIE15U3VwZXJDbGFzcyk7IC8vIHRydWUKICogCWNvbnNvbGUubG9nKGZvby5wcm90b3R5cGUuY29uc3RydWN0b3IgPT09IE15U3ViQ2xhc3MpOyAvLyB0cnVlCiAqCiAqIEBtZXRob2QgZXh0ZW5kCiAqIEBwYXJhbSB7RnVuY3Rpb259IHN1YmNsYXNzIFRoZSBzdWJjbGFzcy4KICogQHBhcmFtIHtGdW5jdGlvbn0gc3VwZXJjbGFzcyBUaGUgc3VwZXJjbGFzcyB0byBleHRlbmQuCiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBzdWJjbGFzcydzIG5ldyBwcm90b3R5cGUuCiAqLwpjcmVhdGVqcy5leHRlbmQgPSBmdW5jdGlvbihzdWJjbGFzcywgc3VwZXJjbGFzcykgewoJInVzZSBzdHJpY3QiOwoKCWZ1bmN0aW9uIG8oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBzdWJjbGFzczsgfQoJby5wcm90b3R5cGUgPSBzdXBlcmNsYXNzLnByb3RvdHlwZTsKCXJldHVybiAoc3ViY2xhc3MucHJvdG90eXBlID0gbmV3IG8oKSk7Cn07CgovLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwovLyBwcm9tb3RlLmpzCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgp0aGlzLmNyZWF0ZWpzID0gdGhpcy5jcmVhdGVqc3x8e307CgovKioKICogQGNsYXNzIFV0aWxpdHkgTWV0aG9kcwogKi8KCi8qKgogKiBQcm9tb3RlcyBhbnkgbWV0aG9kcyBvbiB0aGUgc3VwZXIgY2xhc3MgdGhhdCB3ZXJlIG92ZXJyaWRkZW4sIGJ5IGNyZWF0aW5nIGFuIGFsaWFzIGluIHRoZSBmb3JtYXQgYHByZWZpeF9tZXRob2ROYW1lYC4KICogSXQgaXMgcmVjb21tZW5kZWQgdG8gdXNlIHRoZSBzdXBlciBjbGFzcydzIG5hbWUgYXMgdGhlIHByZWZpeC4KICogQW4gYWxpYXMgdG8gdGhlIHN1cGVyIGNsYXNzJ3MgY29uc3RydWN0b3IgaXMgYWx3YXlzIGFkZGVkIGluIHRoZSBmb3JtYXQgYHByZWZpeF9jb25zdHJ1Y3RvcmAuCiAqIFRoaXMgYWxsb3dzIHRoZSBzdWJjbGFzcyB0byBjYWxsIHN1cGVyIGNsYXNzIG1ldGhvZHMgd2l0aG91dCB1c2luZyBgZnVuY3Rpb24uY2FsbGAsIHByb3ZpZGluZyBiZXR0ZXIgcGVyZm9ybWFuY2UuCiAqCiAqIEZvciBleGFtcGxlLCBpZiBgTXlTdWJDbGFzc2AgZXh0ZW5kcyBgTXlTdXBlckNsYXNzYCwgYW5kIGJvdGggZGVmaW5lIGEgYGRyYXdgIG1ldGhvZCwgdGhlbiBjYWxsaW5nIGBwcm9tb3RlKE15U3ViQ2xhc3MsICJNeVN1cGVyQ2xhc3MiKWAKICogd291bGQgYWRkIGEgYE15U3VwZXJDbGFzc19jb25zdHJ1Y3RvcmAgbWV0aG9kIHRvIE15U3ViQ2xhc3MgYW5kIHByb21vdGUgdGhlIGBkcmF3YCBtZXRob2Qgb24gYE15U3VwZXJDbGFzc2AgdG8gdGhlCiAqIHByb3RvdHlwZSBvZiBgTXlTdWJDbGFzc2AgYXMgYE15U3VwZXJDbGFzc19kcmF3YC4KICoKICogVGhpcyBzaG91bGQgYmUgY2FsbGVkIGFmdGVyIHRoZSBjbGFzcydzIHByb3RvdHlwZSBpcyBmdWxseSBkZWZpbmVkLgogKgogKiAJZnVuY3Rpb24gQ2xhc3NBKG5hbWUpIHsKICogCQl0aGlzLm5hbWUgPSBuYW1lOwogKiAJfQogKiAJQ2xhc3NBLnByb3RvdHlwZS5ncmVldCA9IGZ1bmN0aW9uKCkgewogKiAJCXJldHVybiAiSGVsbG8gIit0aGlzLm5hbWU7CiAqIAl9CiAqCiAqIAlmdW5jdGlvbiBDbGFzc0IobmFtZSwgcHVuY3R1YXRpb24pIHsKICogCQl0aGlzLkNsYXNzQV9jb25zdHJ1Y3RvcihuYW1lKTsKICogCQl0aGlzLnB1bmN0dWF0aW9uID0gcHVuY3R1YXRpb247CiAqIAl9CiAqIAljcmVhdGVqcy5leHRlbmQoQ2xhc3NCLCBDbGFzc0EpOwogKiAJQ2xhc3NCLnByb3RvdHlwZS5ncmVldCA9IGZ1bmN0aW9uKCkgewogKiAJCXJldHVybiB0aGlzLkNsYXNzQV9ncmVldCgpK3RoaXMucHVuY3R1YXRpb247CiAqIAl9CiAqIAljcmVhdGVqcy5wcm9tb3RlKENsYXNzQiwgIkNsYXNzQSIpOwogKgogKiAJdmFyIGZvbyA9IG5ldyBDbGFzc0IoIldvcmxkIiwgIiE/ISIpOwogKiAJY29uc29sZS5sb2coZm9vLmdyZWV0KCkpOyAvLyBIZWxsbyBXb3JsZCE/IQogKgogKiBAbWV0aG9kIHByb21vdGUKICogQHBhcmFtIHtGdW5jdGlvbn0gc3ViY2xhc3MgVGhlIGNsYXNzIHRvIHByb21vdGUgc3VwZXIgY2xhc3MgbWV0aG9kcyBvbi4KICogQHBhcmFtIHtTdHJpbmd9IHByZWZpeCBUaGUgcHJlZml4IHRvIGFkZCB0byB0aGUgcHJvbW90ZWQgbWV0aG9kIG5hbWVzLiBVc3VhbGx5IHRoZSBuYW1lIG9mIHRoZSBzdXBlcmNsYXNzLgogKiBAcmV0dXJuIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgc3ViY2xhc3MuCiAqLwpjcmVhdGVqcy5wcm9tb3RlID0gZnVuY3Rpb24oc3ViY2xhc3MsIHByZWZpeCkgewoJInVzZSBzdHJpY3QiOwoKCXZhciBzdWJQID0gc3ViY2xhc3MucHJvdG90eXBlLCBzdXBQID0gKE9iamVjdC5nZXRQcm90b3R5cGVPZiYmT2JqZWN0LmdldFByb3RvdHlwZU9mKHN1YlApKXx8c3ViUC5fX3Byb3RvX187CglpZiAoc3VwUCkgewoJCXN1YlBbKHByZWZpeCs9Il8iKSArICJjb25zdHJ1Y3RvciJdID0gc3VwUC5jb25zdHJ1Y3RvcjsgLy8gY29uc3RydWN0b3IgaXMgbm90IGFsd2F5cyBpbm51bWVyYWJsZQoJCWZvciAodmFyIG4gaW4gc3VwUCkgewoJCQlpZiAoc3ViUC5oYXNPd25Qcm9wZXJ0eShuKSAmJiAodHlwZW9mIHN1cFBbbl0gPT0gImZ1bmN0aW9uIikpIHsgc3ViUFtwcmVmaXggKyBuXSA9IHN1cFBbbl07IH0KCQl9Cgl9CglyZXR1cm4gc3ViY2xhc3M7Cn07CgovLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwovLyBpbmRleE9mLmpzCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgp0aGlzLmNyZWF0ZWpzID0gdGhpcy5jcmVhdGVqc3x8e307CgovKioKICogQGNsYXNzIFV0aWxpdHkgTWV0aG9kcwogKi8KCi8qKgogKiBGaW5kcyB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiBhIHNwZWNpZmllZCB2YWx1ZSBzZWFyY2hFbGVtZW50IGluIHRoZSBwYXNzZWQgaW4gYXJyYXksIGFuZCByZXR1cm5zIHRoZSBpbmRleCBvZgogKiB0aGF0IHZhbHVlLiAgUmV0dXJucyAtMSBpZiB2YWx1ZSBpcyBub3QgZm91bmQuCiAqCiAqICAgICAgdmFyIGkgPSBjcmVhdGVqcy5pbmRleE9mKG15QXJyYXksIG15RWxlbWVudFRvRmluZCk7CiAqCiAqIEBtZXRob2QgaW5kZXhPZgogKiBAcGFyYW0ge0FycmF5fSBhcnJheSBBcnJheSB0byBzZWFyY2ggZm9yIHNlYXJjaEVsZW1lbnQKICogQHBhcmFtIHNlYXJjaEVsZW1lbnQgRWxlbWVudCB0byBmaW5kIGluIGFycmF5LgogKiBAcmV0dXJuIHtOdW1iZXJ9IFRoZSBmaXJzdCBpbmRleCBvZiBzZWFyY2hFbGVtZW50IGluIGFycmF5LgogKi8KY3JlYXRlanMuaW5kZXhPZiA9IGZ1bmN0aW9uIChhcnJheSwgc2VhcmNoRWxlbWVudCl7CgkidXNlIHN0cmljdCI7CgoJZm9yICh2YXIgaSA9IDAsbD1hcnJheS5sZW5ndGg7IGkgPCBsOyBpKyspIHsKCQlpZiAoc2VhcmNoRWxlbWVudCA9PT0gYXJyYXlbaV0pIHsKCQkJcmV0dXJuIGk7CgkJfQoJfQoJcmV0dXJuIC0xOwp9OwoKLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLy8gcHJveHkuanMKLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCnRoaXMuY3JlYXRlanMgPSB0aGlzLmNyZWF0ZWpzfHx7fTsKCi8qKgogKiBWYXJpb3VzIHV0aWxpdGllcyB0aGF0IHRoZSBDcmVhdGVKUyBTdWl0ZSB1c2VzLiBVdGlsaXRpZXMgYXJlIGNyZWF0ZWQgYXMgc2VwYXJhdGUgZmlsZXMsIGFuZCB3aWxsIGJlIGF2YWlsYWJsZSBvbiB0aGUKICogY3JlYXRlanMgbmFtZXNwYWNlIGRpcmVjdGx5LgogKgogKiA8aDQ+RXhhbXBsZTwvaDQ+CiAqCiAqICAgICAgbXlPYmplY3QuYWRkRXZlbnRMaXN0ZW5lcigiY2hhbmdlIiwgY3JlYXRlanMucHJveHkobXlNZXRob2QsIHNjb3BlKSk7CiAqCiAqIEBjbGFzcyBVdGlsaXR5IE1ldGhvZHMKICogQG1haW4gVXRpbGl0eSBNZXRob2RzCiAqLwoKKGZ1bmN0aW9uKCkgewoJInVzZSBzdHJpY3QiOwoKCS8qKgoJICogQSBmdW5jdGlvbiBwcm94eSBmb3IgbWV0aG9kcy4gQnkgZGVmYXVsdCwgSmF2YVNjcmlwdCBtZXRob2RzIGRvIG5vdCBtYWludGFpbiBzY29wZSwgc28gcGFzc2luZyBhIG1ldGhvZCBhcyBhCgkgKiBjYWxsYmFjayB3aWxsIHJlc3VsdCBpbiB0aGUgbWV0aG9kIGdldHRpbmcgY2FsbGVkIGluIHRoZSBzY29wZSBvZiB0aGUgY2FsbGVyLiBVc2luZyBhIHByb3h5IGVuc3VyZXMgdGhhdCB0aGUKCSAqIG1ldGhvZCBnZXRzIGNhbGxlZCBpbiB0aGUgY29ycmVjdCBzY29wZS4KCSAqCgkgKiBBZGRpdGlvbmFsIGFyZ3VtZW50cyBjYW4gYmUgcGFzc2VkIHRoYXQgd2lsbCBiZSBhcHBsaWVkIHRvIHRoZSBmdW5jdGlvbiB3aGVuIGl0IGlzIGNhbGxlZC4KCSAqCgkgKiA8aDQ+RXhhbXBsZTwvaDQ+CgkgKgoJICogICAgICBteU9iamVjdC5hZGRFdmVudExpc3RlbmVyKCJldmVudCIsIGNyZWF0ZWpzLnByb3h5KG15SGFuZGxlciwgdGhpcywgYXJnMSwgYXJnMikpOwoJICoKCSAqICAgICAgZnVuY3Rpb24gbXlIYW5kbGVyKGFyZzEsIGFyZzIpIHsKCSAqICAgICAgICAgICAvLyBUaGlzIGdldHMgY2FsbGVkIHdoZW4gbXlPYmplY3QubXlDYWxsYmFjayBpcyBleGVjdXRlZC4KCSAqICAgICAgfQoJICoKCSAqIEBtZXRob2QgcHJveHkKCSAqIEBwYXJhbSB7RnVuY3Rpb259IG1ldGhvZCBUaGUgZnVuY3Rpb24gdG8gY2FsbAoJICogQHBhcmFtIHtPYmplY3R9IHNjb3BlIFRoZSBzY29wZSB0byBjYWxsIHRoZSBtZXRob2QgbmFtZSBvbgoJICogQHBhcmFtIHttaXhlZH0gW2FyZ10gKiBBcmd1bWVudHMgdGhhdCBhcmUgYXBwZW5kZWQgdG8gdGhlIGNhbGxiYWNrIGZvciBhZGRpdGlvbmFsIHBhcmFtcy4KCSAqIEBwdWJsaWMKCSAqIEBzdGF0aWMKCSAqLwoJY3JlYXRlanMucHJveHkgPSBmdW5jdGlvbiAobWV0aG9kLCBzY29wZSkgewoJCXZhciBhQXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMik7CgkJcmV0dXJuIGZ1bmN0aW9uICgpIHsKCQkJcmV0dXJuIG1ldGhvZC5hcHBseShzY29wZSwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKS5jb25jYXQoYUFyZ3MpKTsKCQl9OwoJfQoKfSgpKTsKCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi8vIEJyb3dzZXJEZXRlY3QuanMKLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCnRoaXMuY3JlYXRlanMgPSB0aGlzLmNyZWF0ZWpzfHx7fTsKCi8qKgogKiBAY2xhc3MgVXRpbGl0eSBNZXRob2RzCiAqLwooZnVuY3Rpb24oKSB7CgkidXNlIHN0cmljdCI7CgoJLyoqCgkgKiBBbiBvYmplY3QgdGhhdCBkZXRlcm1pbmVzIHRoZSBjdXJyZW50IGJyb3dzZXIsIHZlcnNpb24sIG9wZXJhdGluZyBzeXN0ZW0sIGFuZCBvdGhlciBlbnZpcm9ubWVudAoJICogdmFyaWFibGVzIHZpYSB1c2VyIGFnZW50IHN0cmluZy4KCSAqCgkgKiBVc2VkIGZvciBhdWRpbyBiZWNhdXNlIGZlYXR1cmUgZGV0ZWN0aW9uIGlzIHVuYWJsZSB0byBkZXRlY3QgdGhlIG1hbnkgbGltaXRhdGlvbnMgb2YgbW9iaWxlIGRldmljZXMuCgkgKgoJICogPGg0PkV4YW1wbGU8L2g0PgoJICoKCSAqICAgICAgaWYgKGNyZWF0ZWpzLkJyb3dzZXJEZXRlY3QuaXNJT1MpIHsgLy8gZG8gc3R1ZmYgfQoJICoKCSAqIEBwcm9wZXJ0eSBCcm93c2VyRGV0ZWN0CgkgKiBAdHlwZSB7T2JqZWN0fQoJICogQHBhcmFtIHtCb29sZWFufSBpc0ZpcmVmb3ggVHJ1ZSBpZiBvdXIgYnJvd3NlciBpcyBGaXJlZm94LgoJICogQHBhcmFtIHtCb29sZWFufSBpc09wZXJhIFRydWUgaWYgb3VyIGJyb3dzZXIgaXMgb3BlcmEuCgkgKiBAcGFyYW0ge0Jvb2xlYW59IGlzQ2hyb21lIFRydWUgaWYgb3VyIGJyb3dzZXIgaXMgQ2hyb21lLiAgTm90ZSB0aGF0IENocm9tZSBmb3IgQW5kcm9pZCByZXR1cm5zIHRydWUsIGJ1dCBpcyBhCgkgKiBjb21wbGV0ZWx5IGRpZmZlcmVudCBicm93c2VyIHdpdGggZGlmZmVyZW50IGFiaWxpdGllcy4KCSAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNJT1MgVHJ1ZSBpZiBvdXIgYnJvd3NlciBpcyBzYWZhcmkgZm9yIGlPUyBkZXZpY2VzIChpUGFkLCBpUGhvbmUsIGFuZCBpUG9kKS4KCSAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNBbmRyb2lkIFRydWUgaWYgb3VyIGJyb3dzZXIgaXMgQW5kcm9pZC4KCSAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNCbGFja2JlcnJ5IFRydWUgaWYgb3VyIGJyb3dzZXIgaXMgQmxhY2tiZXJyeS4KCSAqIEBjb25zdHJ1Y3RvcgoJICogQHN0YXRpYwoJICovCglmdW5jdGlvbiBCcm93c2VyRGV0ZWN0KCkgewoJCXRocm93ICJCcm93c2VyRGV0ZWN0IGNhbm5vdCBiZSBpbnN0YW50aWF0ZWQiOwoJfTsKCgl2YXIgYWdlbnQgPSBCcm93c2VyRGV0ZWN0LmFnZW50ID0gd2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQ7CglCcm93c2VyRGV0ZWN0LmlzV2luZG93UGhvbmUgPSAoYWdlbnQuaW5kZXhPZigiSUVNb2JpbGUiKSA+IC0xKSB8fCAoYWdlbnQuaW5kZXhPZigiV2luZG93cyBQaG9uZSIpID4gLTEpOwoJQnJvd3NlckRldGVjdC5pc0ZpcmVmb3ggPSAoYWdlbnQuaW5kZXhPZigiRmlyZWZveCIpID4gLTEpOwoJQnJvd3NlckRldGVjdC5pc09wZXJhID0gKHdpbmRvdy5vcGVyYSAhPSBudWxsKTsKCUJyb3dzZXJEZXRlY3QuaXNDaHJvbWUgPSAoYWdlbnQuaW5kZXhPZigiQ2hyb21lIikgPiAtMSk7ICAvLyBOT1RFIHRoYXQgQ2hyb21lIG9uIEFuZHJvaWQgcmV0dXJucyB0cnVlIGJ1dCBpcyBhIGNvbXBsZXRlbHkgZGlmZmVyZW50IGJyb3dzZXIgd2l0aCBkaWZmZXJlbnQgYWJpbGl0aWVzCglCcm93c2VyRGV0ZWN0LmlzSU9TID0gKGFnZW50LmluZGV4T2YoImlQb2QiKSA+IC0xIHx8IGFnZW50LmluZGV4T2YoImlQaG9uZSIpID4gLTEgfHwgYWdlbnQuaW5kZXhPZigiaVBhZCIpID4gLTEpICYmICFCcm93c2VyRGV0ZWN0LmlzV2luZG93UGhvbmU7CglCcm93c2VyRGV0ZWN0LmlzQW5kcm9pZCA9IChhZ2VudC5pbmRleE9mKCJBbmRyb2lkIikgPiAtMSkgJiYgIUJyb3dzZXJEZXRlY3QuaXNXaW5kb3dQaG9uZTsKCUJyb3dzZXJEZXRlY3QuaXNCbGFja2JlcnJ5ID0gKGFnZW50LmluZGV4T2YoIkJsYWNrYmVycnkiKSA+IC0xKTsKCgljcmVhdGVqcy5Ccm93c2VyRGV0ZWN0ID0gQnJvd3NlckRldGVjdDsKCn0oKSk7CgovLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwovLyBFdmVudC5qcwovLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoKdGhpcy5jcmVhdGVqcyA9IHRoaXMuY3JlYXRlanN8fHt9OwoKKGZ1bmN0aW9uKCkgewoJInVzZSBzdHJpY3QiOwoKLy8gY29uc3RydWN0b3I6CgkvKioKCSAqIENvbnRhaW5zIHByb3BlcnRpZXMgYW5kIG1ldGhvZHMgc2hhcmVkIGJ5IGFsbCBldmVudHMgZm9yIHVzZSB3aXRoCgkgKiB7eyNjcm9zc0xpbmsgIkV2ZW50RGlzcGF0Y2hlciJ9fXt7L2Nyb3NzTGlua319LgoJICogCgkgKiBOb3RlIHRoYXQgRXZlbnQgb2JqZWN0cyBhcmUgb2Z0ZW4gcmV1c2VkLCBzbyB5b3Ugc2hvdWxkIG5ldmVyCgkgKiByZWx5IG9uIGFuIGV2ZW50IG9iamVjdCdzIHN0YXRlIG91dHNpZGUgb2YgdGhlIGNhbGwgc3RhY2sgaXQgd2FzIHJlY2VpdmVkIGluLgoJICogQGNsYXNzIEV2ZW50CgkgKiBAcGFyYW0ge1N0cmluZ30gdHlwZSBUaGUgZXZlbnQgdHlwZS4KCSAqIEBwYXJhbSB7Qm9vbGVhbn0gYnViYmxlcyBJbmRpY2F0ZXMgd2hldGhlciB0aGUgZXZlbnQgd2lsbCBidWJibGUgdGhyb3VnaCB0aGUgZGlzcGxheSBsaXN0LgoJICogQHBhcmFtIHtCb29sZWFufSBjYW5jZWxhYmxlIEluZGljYXRlcyB3aGV0aGVyIHRoZSBkZWZhdWx0IGJlaGF2aW91ciBvZiB0aGlzIGV2ZW50IGNhbiBiZSBjYW5jZWxsZWQuCgkgKiBAY29uc3RydWN0b3IKCSAqKi8KCWZ1bmN0aW9uIEV2ZW50KHR5cGUsIGJ1YmJsZXMsIGNhbmNlbGFibGUpIHsKCQkKCQoJLy8gcHVibGljIHByb3BlcnRpZXM6CgkJLyoqCgkJICogVGhlIHR5cGUgb2YgZXZlbnQuCgkJICogQHByb3BlcnR5IHR5cGUKCQkgKiBAdHlwZSBTdHJpbmcKCQkgKiovCgkJdGhpcy50eXBlID0gdHlwZTsKCQoJCS8qKgoJCSAqIFRoZSBvYmplY3QgdGhhdCBnZW5lcmF0ZWQgYW4gZXZlbnQuCgkJICogQHByb3BlcnR5IHRhcmdldAoJCSAqIEB0eXBlIE9iamVjdAoJCSAqIEBkZWZhdWx0IG51bGwKCQkgKiBAcmVhZG9ubHkKCQkqLwoJCXRoaXMudGFyZ2V0ID0gbnVsbDsKCQoJCS8qKgoJCSAqIFRoZSBjdXJyZW50IHRhcmdldCB0aGF0IGEgYnViYmxpbmcgZXZlbnQgaXMgYmVpbmcgZGlzcGF0Y2hlZCBmcm9tLiBGb3Igbm9uLWJ1YmJsaW5nIGV2ZW50cywgdGhpcyB3aWxsCgkJICogYWx3YXlzIGJlIHRoZSBzYW1lIGFzIHRhcmdldC4gRm9yIGV4YW1wbGUsIGlmIGNoaWxkT2JqLnBhcmVudCA9IHBhcmVudE9iaiwgYW5kIGEgYnViYmxpbmcgZXZlbnQKCQkgKiBpcyBnZW5lcmF0ZWQgZnJvbSBjaGlsZE9iaiwgdGhlbiBhIGxpc3RlbmVyIG9uIHBhcmVudE9iaiB3b3VsZCByZWNlaXZlIHRoZSBldmVudCB3aXRoCgkJICogdGFyZ2V0PWNoaWxkT2JqICh0aGUgb3JpZ2luYWwgdGFyZ2V0KSBhbmQgY3VycmVudFRhcmdldD1wYXJlbnRPYmogKHdoZXJlIHRoZSBsaXN0ZW5lciB3YXMgYWRkZWQpLgoJCSAqIEBwcm9wZXJ0eSBjdXJyZW50VGFyZ2V0CgkJICogQHR5cGUgT2JqZWN0CgkJICogQGRlZmF1bHQgbnVsbAoJCSAqIEByZWFkb25seQoJCSovCgkJdGhpcy5jdXJyZW50VGFyZ2V0ID0gbnVsbDsKCQoJCS8qKgoJCSAqIEZvciBidWJibGluZyBldmVudHMsIHRoaXMgaW5kaWNhdGVzIHRoZSBjdXJyZW50IGV2ZW50IHBoYXNlOjxPTD4KCQkgKiAJPExJPiBjYXB0dXJlIHBoYXNlOiBzdGFydGluZyBmcm9tIHRoZSB0b3AgcGFyZW50IHRvIHRoZSB0YXJnZXQ8L0xJPgoJCSAqIAk8TEk+IGF0IHRhcmdldCBwaGFzZTogY3VycmVudGx5IGJlaW5nIGRpc3BhdGNoZWQgZnJvbSB0aGUgdGFyZ2V0PC9MST4KCQkgKiAJPExJPiBidWJibGluZyBwaGFzZTogZnJvbSB0aGUgdGFyZ2V0IHRvIHRoZSB0b3AgcGFyZW50PC9MST4KCQkgKiA8L09MPgoJCSAqIEBwcm9wZXJ0eSBldmVudFBoYXNlCgkJICogQHR5cGUgTnVtYmVyCgkJICogQGRlZmF1bHQgMAoJCSAqIEByZWFkb25seQoJCSovCgkJdGhpcy5ldmVudFBoYXNlID0gMDsKCQoJCS8qKgoJCSAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBldmVudCB3aWxsIGJ1YmJsZSB0aHJvdWdoIHRoZSBkaXNwbGF5IGxpc3QuCgkJICogQHByb3BlcnR5IGJ1YmJsZXMKCQkgKiBAdHlwZSBCb29sZWFuCgkJICogQGRlZmF1bHQgZmFsc2UKCQkgKiBAcmVhZG9ubHkKCQkqLwoJCXRoaXMuYnViYmxlcyA9ICEhYnViYmxlczsKCQoJCS8qKgoJCSAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBkZWZhdWx0IGJlaGF2aW91ciBvZiB0aGlzIGV2ZW50IGNhbiBiZSBjYW5jZWxsZWQgdmlhCgkJICoge3sjY3Jvc3NMaW5rICJFdmVudC9wcmV2ZW50RGVmYXVsdCJ9fXt7L2Nyb3NzTGlua319LiBUaGlzIGlzIHNldCB2aWEgdGhlIEV2ZW50IGNvbnN0cnVjdG9yLgoJCSAqIEBwcm9wZXJ0eSBjYW5jZWxhYmxlCgkJICogQHR5cGUgQm9vbGVhbgoJCSAqIEBkZWZhdWx0IGZhbHNlCgkJICogQHJlYWRvbmx5CgkJKi8KCQl0aGlzLmNhbmNlbGFibGUgPSAhIWNhbmNlbGFibGU7CgkKCQkvKioKCQkgKiBUaGUgZXBvY2ggdGltZSBhdCB3aGljaCB0aGlzIGV2ZW50IHdhcyBjcmVhdGVkLgoJCSAqIEBwcm9wZXJ0eSB0aW1lU3RhbXAKCQkgKiBAdHlwZSBOdW1iZXIKCQkgKiBAZGVmYXVsdCAwCgkJICogQHJlYWRvbmx5CgkJKi8KCQl0aGlzLnRpbWVTdGFtcCA9IChuZXcgRGF0ZSgpKS5nZXRUaW1lKCk7CgkKCQkvKioKCQkgKiBJbmRpY2F0ZXMgaWYge3sjY3Jvc3NMaW5rICJFdmVudC9wcmV2ZW50RGVmYXVsdCJ9fXt7L2Nyb3NzTGlua319IGhhcyBiZWVuIGNhbGxlZAoJCSAqIG9uIHRoaXMgZXZlbnQuCgkJICogQHByb3BlcnR5IGRlZmF1bHRQcmV2ZW50ZWQKCQkgKiBAdHlwZSBCb29sZWFuCgkJICogQGRlZmF1bHQgZmFsc2UKCQkgKiBAcmVhZG9ubHkKCQkqLwoJCXRoaXMuZGVmYXVsdFByZXZlbnRlZCA9IGZhbHNlOwoJCgkJLyoqCgkJICogSW5kaWNhdGVzIGlmIHt7I2Nyb3NzTGluayAiRXZlbnQvc3RvcFByb3BhZ2F0aW9uIn19e3svY3Jvc3NMaW5rfX0gb3IKCQkgKiB7eyNjcm9zc0xpbmsgIkV2ZW50L3N0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiJ9fXt7L2Nyb3NzTGlua319IGhhcyBiZWVuIGNhbGxlZCBvbiB0aGlzIGV2ZW50LgoJCSAqIEBwcm9wZXJ0eSBwcm9wYWdhdGlvblN0b3BwZWQKCQkgKiBAdHlwZSBCb29sZWFuCgkJICogQGRlZmF1bHQgZmFsc2UKCQkgKiBAcmVhZG9ubHkKCQkqLwoJCXRoaXMucHJvcGFnYXRpb25TdG9wcGVkID0gZmFsc2U7CgkKCQkvKioKCQkgKiBJbmRpY2F0ZXMgaWYge3sjY3Jvc3NMaW5rICJFdmVudC9zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24ifX17ey9jcm9zc0xpbmt9fSBoYXMgYmVlbiBjYWxsZWQKCQkgKiBvbiB0aGlzIGV2ZW50LgoJCSAqIEBwcm9wZXJ0eSBpbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQKCQkgKiBAdHlwZSBCb29sZWFuCgkJICogQGRlZmF1bHQgZmFsc2UKCQkgKiBAcmVhZG9ubHkKCQkqLwoJCXRoaXMuaW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkID0gZmFsc2U7CgkJCgkJLyoqCgkJICogSW5kaWNhdGVzIGlmIHt7I2Nyb3NzTGluayAiRXZlbnQvcmVtb3ZlIn19e3svY3Jvc3NMaW5rfX0gaGFzIGJlZW4gY2FsbGVkIG9uIHRoaXMgZXZlbnQuCgkJICogQHByb3BlcnR5IHJlbW92ZWQKCQkgKiBAdHlwZSBCb29sZWFuCgkJICogQGRlZmF1bHQgZmFsc2UKCQkgKiBAcmVhZG9ubHkKCQkqLwoJCXRoaXMucmVtb3ZlZCA9IGZhbHNlOwoJfQoJdmFyIHAgPSBFdmVudC5wcm90b3R5cGU7CgoJLyoqCgkgKiA8c3Ryb25nPlJFTU9WRUQ8L3N0cm9uZz4uIFJlbW92ZWQgaW4gZmF2b3Igb2YgdXNpbmcgYE15U3VwZXJDbGFzc19jb25zdHJ1Y3RvcmAuCgkgKiBTZWUge3sjY3Jvc3NMaW5rICJVdGlsaXR5IE1ldGhvZHMvZXh0ZW5kIn19e3svY3Jvc3NMaW5rfX0gYW5kIHt7I2Nyb3NzTGluayAiVXRpbGl0eSBNZXRob2RzL3Byb21vdGUifX17ey9jcm9zc0xpbmt9fQoJICogZm9yIGRldGFpbHMuCgkgKgoJICogVGhlcmUgaXMgYW4gaW5oZXJpdGFuY2UgdHV0b3JpYWwgZGlzdHJpYnV0ZWQgd2l0aCBFYXNlbEpTIGluIC90dXRvcmlhbHMvSW5oZXJpdGFuY2UuCgkgKgoJICogQG1ldGhvZCBpbml0aWFsaXplCgkgKiBAcHJvdGVjdGVkCgkgKiBAZGVwcmVjYXRlZAoJICovCgkvLyBwLmluaXRpYWxpemUgPSBmdW5jdGlvbigpIHt9OyAvLyBzZWFyY2hhYmxlIGZvciBkZXZzIHdvbmRlcmluZyB3aGVyZSBpdCBpcy4KCQoKLy8gcHVibGljIG1ldGhvZHM6CgkvKioKCSAqIFNldHMge3sjY3Jvc3NMaW5rICJFdmVudC9kZWZhdWx0UHJldmVudGVkIn19e3svY3Jvc3NMaW5rfX0gdG8gdHJ1ZS4KCSAqIE1pcnJvcnMgdGhlIERPTSBldmVudCBzdGFuZGFyZC4KCSAqIEBtZXRob2QgcHJldmVudERlZmF1bHQKCSAqKi8KCXAucHJldmVudERlZmF1bHQgPSBmdW5jdGlvbigpIHsKCQl0aGlzLmRlZmF1bHRQcmV2ZW50ZWQgPSB0aGlzLmNhbmNlbGFibGUmJnRydWU7Cgl9OwoKCS8qKgoJICogU2V0cyB7eyNjcm9zc0xpbmsgIkV2ZW50L3Byb3BhZ2F0aW9uU3RvcHBlZCJ9fXt7L2Nyb3NzTGlua319IHRvIHRydWUuCgkgKiBNaXJyb3JzIHRoZSBET00gZXZlbnQgc3RhbmRhcmQuCgkgKiBAbWV0aG9kIHN0b3BQcm9wYWdhdGlvbgoJICoqLwoJcC5zdG9wUHJvcGFnYXRpb24gPSBmdW5jdGlvbigpIHsKCQl0aGlzLnByb3BhZ2F0aW9uU3RvcHBlZCA9IHRydWU7Cgl9OwoKCS8qKgoJICogU2V0cyB7eyNjcm9zc0xpbmsgIkV2ZW50L3Byb3BhZ2F0aW9uU3RvcHBlZCJ9fXt7L2Nyb3NzTGlua319IGFuZAoJICoge3sjY3Jvc3NMaW5rICJFdmVudC9pbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQifX17ey9jcm9zc0xpbmt9fSB0byB0cnVlLgoJICogTWlycm9ycyB0aGUgRE9NIGV2ZW50IHN0YW5kYXJkLgoJICogQG1ldGhvZCBzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24KCSAqKi8KCXAuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uID0gZnVuY3Rpb24oKSB7CgkJdGhpcy5pbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQgPSB0aGlzLnByb3BhZ2F0aW9uU3RvcHBlZCA9IHRydWU7Cgl9OwoJCgkvKioKCSAqIENhdXNlcyB0aGUgYWN0aXZlIGxpc3RlbmVyIHRvIGJlIHJlbW92ZWQgdmlhIHJlbW92ZUV2ZW50TGlzdGVuZXIoKTsKCSAqIAoJICogCQlteUJ0bi5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsIGZ1bmN0aW9uKGV2dCkgewoJICogCQkJLy8gZG8gc3R1ZmYuLi4KCSAqIAkJCWV2dC5yZW1vdmUoKTsgLy8gcmVtb3ZlcyB0aGlzIGxpc3RlbmVyLgoJICogCQl9KTsKCSAqIAoJICogQG1ldGhvZCByZW1vdmUKCSAqKi8KCXAucmVtb3ZlID0gZnVuY3Rpb24oKSB7CgkJdGhpcy5yZW1vdmVkID0gdHJ1ZTsKCX07CgkKCS8qKgoJICogUmV0dXJucyBhIGNsb25lIG9mIHRoZSBFdmVudCBpbnN0YW5jZS4KCSAqIEBtZXRob2QgY2xvbmUKCSAqIEByZXR1cm4ge0V2ZW50fSBhIGNsb25lIG9mIHRoZSBFdmVudCBpbnN0YW5jZS4KCSAqKi8KCXAuY2xvbmUgPSBmdW5jdGlvbigpIHsKCQlyZXR1cm4gbmV3IEV2ZW50KHRoaXMudHlwZSwgdGhpcy5idWJibGVzLCB0aGlzLmNhbmNlbGFibGUpOwoJfTsKCQoJLyoqCgkgKiBQcm92aWRlcyBhIGNoYWluYWJsZSBzaG9ydGN1dCBtZXRob2QgZm9yIHNldHRpbmcgYSBudW1iZXIgb2YgcHJvcGVydGllcyBvbiB0aGUgaW5zdGFuY2UuCgkgKgoJICogQG1ldGhvZCBzZXQKCSAqIEBwYXJhbSB7T2JqZWN0fSBwcm9wcyBBIGdlbmVyaWMgb2JqZWN0IGNvbnRhaW5pbmcgcHJvcGVydGllcyB0byBjb3B5IHRvIHRoZSBpbnN0YW5jZS4KCSAqIEByZXR1cm4ge0V2ZW50fSBSZXR1cm5zIHRoZSBpbnN0YW5jZSB0aGUgbWV0aG9kIGlzIGNhbGxlZCBvbiAodXNlZnVsIGZvciBjaGFpbmluZyBjYWxscy4pCgkgKiBAY2hhaW5hYmxlCgkqLwoJcC5zZXQgPSBmdW5jdGlvbihwcm9wcykgewoJCWZvciAodmFyIG4gaW4gcHJvcHMpIHsgdGhpc1tuXSA9IHByb3BzW25dOyB9CgkJcmV0dXJuIHRoaXM7Cgl9OwoKCS8qKgoJICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIG9iamVjdC4KCSAqIEBtZXRob2QgdG9TdHJpbmcKCSAqIEByZXR1cm4ge1N0cmluZ30gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGluc3RhbmNlLgoJICoqLwoJcC50b1N0cmluZyA9IGZ1bmN0aW9uKCkgewoJCXJldHVybiAiW0V2ZW50ICh0eXBlPSIrdGhpcy50eXBlKyIpXSI7Cgl9OwoKCWNyZWF0ZWpzLkV2ZW50ID0gRXZlbnQ7Cn0oKSk7CgovLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwovLyBFcnJvckV2ZW50LmpzCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgp0aGlzLmNyZWF0ZWpzID0gdGhpcy5jcmVhdGVqc3x8e307CgooZnVuY3Rpb24oKSB7CgkidXNlIHN0cmljdCI7CgoJLyoqCgkgKiBBIGdlbmVyYWwgZXJyb3Ige3sjY3Jvc3NMaW5rICJFdmVudCJ9fXt7L2Nyb3NzTGlua319LCB0aGF0IGRlc2NyaWJlcyBhbiBlcnJvciB0aGF0IG9jY3VycmVkLCBhcyB3ZWxsIGFzIGFueSBkZXRhaWxzLgoJICogQGNsYXNzIEVycm9yRXZlbnQKCSAqIEBwYXJhbSB7U3RyaW5nfSBbdGl0bGVdIFRoZSBlcnJvciB0aXRsZQoJICogQHBhcmFtIHtTdHJpbmd9IFttZXNzYWdlXSBUaGUgZXJyb3IgZGVzY3JpcHRpb24KCSAqIEBwYXJhbSB7T2JqZWN0fSBbZGF0YV0gQWRkaXRpb25hbCBlcnJvciBkYXRhCgkgKiBAY29uc3RydWN0b3IKCSAqLwoJZnVuY3Rpb24gRXJyb3JFdmVudCh0aXRsZSwgbWVzc2FnZSwgZGF0YSkgewoJCXRoaXMuRXZlbnRfY29uc3RydWN0b3IoImVycm9yIik7CgoJCS8qKgoJCSAqIFRoZSBzaG9ydCBlcnJvciB0aXRsZSwgd2hpY2ggaW5kaWNhdGVzIHRoZSB0eXBlIG9mIGVycm9yIHRoYXQgb2NjdXJyZWQuCgkJICogQHByb3BlcnR5IHRpdGxlCgkJICogQHR5cGUgU3RyaW5nCgkJICovCgkJdGhpcy50aXRsZSA9IHRpdGxlOwoKCQkvKioKCQkgKiBUaGUgdmVyYm9zZSBlcnJvciBtZXNzYWdlLCBjb250YWluaW5nIGRldGFpbHMgYWJvdXQgdGhlIGVycm9yLgoJCSAqIEBwcm9wZXJ0eSBtZXNzYWdlCgkJICogQHR5cGUgU3RyaW5nCgkJICovCgkJdGhpcy5tZXNzYWdlID0gbWVzc2FnZTsKCgkJLyoqCgkJICogQWRkaXRpb25hbCBkYXRhIGF0dGFjaGVkIHRvIGFuIGVycm9yLgoJCSAqIEBwcm9wZXJ0eSBkYXRhCgkJICogQHR5cGUge09iamVjdH0KCQkgKi8KCQl0aGlzLmRhdGEgPSBkYXRhOwoJfQoKCXZhciBwID0gY3JlYXRlanMuZXh0ZW5kKEVycm9yRXZlbnQsIGNyZWF0ZWpzLkV2ZW50KTsKCglwLmNsb25lID0gZnVuY3Rpb24oKSB7CgkJcmV0dXJuIG5ldyBjcmVhdGVqcy5FcnJvckV2ZW50KHRoaXMudGl0bGUsIHRoaXMubWVzc2FnZSwgdGhpcy5kYXRhKTsKCX07CgoJY3JlYXRlanMuRXJyb3JFdmVudCA9IGNyZWF0ZWpzLnByb21vdGUoRXJyb3JFdmVudCwgIkV2ZW50Iik7Cgp9KCkpOwoKLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLy8gRXZlbnREaXNwYXRjaGVyLmpzCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgp0aGlzLmNyZWF0ZWpzID0gdGhpcy5jcmVhdGVqc3x8e307DQoNCihmdW5jdGlvbigpIHsNCgkidXNlIHN0cmljdCI7DQoNCg0KLy8gY29uc3RydWN0b3I6DQoJLyoqDQoJICogRXZlbnREaXNwYXRjaGVyIHByb3ZpZGVzIG1ldGhvZHMgZm9yIG1hbmFnaW5nIHF1ZXVlcyBvZiBldmVudCBsaXN0ZW5lcnMgYW5kIGRpc3BhdGNoaW5nIGV2ZW50cy4NCgkgKg0KCSAqIFlvdSBjYW4gZWl0aGVyIGV4dGVuZCBFdmVudERpc3BhdGNoZXIgb3IgbWl4IGl0cyBtZXRob2RzIGludG8gYW4gZXhpc3RpbmcgcHJvdG90eXBlIG9yIGluc3RhbmNlIGJ5IHVzaW5nIHRoZQ0KCSAqIEV2ZW50RGlzcGF0Y2hlciB7eyNjcm9zc0xpbmsgIkV2ZW50RGlzcGF0Y2hlci9pbml0aWFsaXplIn19e3svY3Jvc3NMaW5rfX0gbWV0aG9kLg0KCSAqIA0KCSAqIFRvZ2V0aGVyIHdpdGggdGhlIENyZWF0ZUpTIEV2ZW50IGNsYXNzLCBFdmVudERpc3BhdGNoZXIgcHJvdmlkZXMgYW4gZXh0ZW5kZWQgZXZlbnQgbW9kZWwgdGhhdCBpcyBiYXNlZCBvbiB0aGUNCgkgKiBET00gTGV2ZWwgMiBldmVudCBtb2RlbCwgaW5jbHVkaW5nIGFkZEV2ZW50TGlzdGVuZXIsIHJlbW92ZUV2ZW50TGlzdGVuZXIsIGFuZCBkaXNwYXRjaEV2ZW50LiBJdCBzdXBwb3J0cw0KCSAqIGJ1YmJsaW5nIC8gY2FwdHVyZSwgcHJldmVudERlZmF1bHQsIHN0b3BQcm9wYWdhdGlvbiwgc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uLCBhbmQgaGFuZGxlRXZlbnQuDQoJICogDQoJICogRXZlbnREaXNwYXRjaGVyIGFsc28gZXhwb3NlcyBhIHt7I2Nyb3NzTGluayAiRXZlbnREaXNwYXRjaGVyL29uIn19e3svY3Jvc3NMaW5rfX0gbWV0aG9kLCB3aGljaCBtYWtlcyBpdCBlYXNpZXINCgkgKiB0byBjcmVhdGUgc2NvcGVkIGxpc3RlbmVycywgbGlzdGVuZXJzIHRoYXQgb25seSBydW4gb25jZSwgYW5kIGxpc3RlbmVycyB3aXRoIGFzc29jaWF0ZWQgYXJiaXRyYXJ5IGRhdGEuIFRoZSANCgkgKiB7eyNjcm9zc0xpbmsgIkV2ZW50RGlzcGF0Y2hlci9vZmYifX17ey9jcm9zc0xpbmt9fSBtZXRob2QgaXMgbWVyZWx5IGFuIGFsaWFzIHRvDQoJICoge3sjY3Jvc3NMaW5rICJFdmVudERpc3BhdGNoZXIvcmVtb3ZlRXZlbnRMaXN0ZW5lciJ9fXt7L2Nyb3NzTGlua319Lg0KCSAqIA0KCSAqIEFub3RoZXIgYWRkaXRpb24gdG8gdGhlIERPTSBMZXZlbCAyIG1vZGVsIGlzIHRoZSB7eyNjcm9zc0xpbmsgIkV2ZW50RGlzcGF0Y2hlci9yZW1vdmVBbGxFdmVudExpc3RlbmVycyJ9fXt7L2Nyb3NzTGlua319DQoJICogbWV0aG9kLCB3aGljaCBjYW4gYmUgdXNlZCB0byBsaXN0ZW5lcnMgZm9yIGFsbCBldmVudHMsIG9yIGxpc3RlbmVycyBmb3IgYSBzcGVjaWZpYyBldmVudC4gVGhlIEV2ZW50IG9iamVjdCBhbHNvIA0KCSAqIGluY2x1ZGVzIGEge3sjY3Jvc3NMaW5rICJFdmVudC9yZW1vdmUifX17ey9jcm9zc0xpbmt9fSBtZXRob2Qgd2hpY2ggcmVtb3ZlcyB0aGUgYWN0aXZlIGxpc3RlbmVyLg0KCSAqDQoJICogPGg0PkV4YW1wbGU8L2g0Pg0KCSAqIEFkZCBFdmVudERpc3BhdGNoZXIgY2FwYWJpbGl0aWVzIHRvIHRoZSAiTXlDbGFzcyIgY2xhc3MuDQoJICoNCgkgKiAgICAgIEV2ZW50RGlzcGF0Y2hlci5pbml0aWFsaXplKE15Q2xhc3MucHJvdG90eXBlKTsNCgkgKg0KCSAqIEFkZCBhbiBldmVudCAoc2VlIHt7I2Nyb3NzTGluayAiRXZlbnREaXNwYXRjaGVyL2FkZEV2ZW50TGlzdGVuZXIifX17ey9jcm9zc0xpbmt9fSkuDQoJICoNCgkgKiAgICAgIGluc3RhbmNlLmFkZEV2ZW50TGlzdGVuZXIoImV2ZW50TmFtZSIsIGhhbmRsZXJNZXRob2QpOw0KCSAqICAgICAgZnVuY3Rpb24gaGFuZGxlck1ldGhvZChldmVudCkgew0KCSAqICAgICAgICAgIGNvbnNvbGUubG9nKGV2ZW50LnRhcmdldCArICIgV2FzIENsaWNrZWQiKTsNCgkgKiAgICAgIH0NCgkgKg0KCSAqIDxiPk1haW50YWluaW5nIHByb3BlciBzY29wZTwvYj48YnIgLz4NCgkgKiBTY29wZSAoaWUuICJ0aGlzIikgY2FuIGJlIGJlIGEgY2hhbGxlbmdlIHdpdGggZXZlbnRzLiBVc2luZyB0aGUge3sjY3Jvc3NMaW5rICJFdmVudERpc3BhdGNoZXIvb24ifX17ey9jcm9zc0xpbmt9fQ0KCSAqIG1ldGhvZCB0byBzdWJzY3JpYmUgdG8gZXZlbnRzIHNpbXBsaWZpZXMgdGhpcy4NCgkgKg0KCSAqICAgICAgaW5zdGFuY2UuYWRkRXZlbnRMaXN0ZW5lcigiY2xpY2siLCBmdW5jdGlvbihldmVudCkgew0KCSAqICAgICAgICAgIGNvbnNvbGUubG9nKGluc3RhbmNlID09IHRoaXMpOyAvLyBmYWxzZSwgc2NvcGUgaXMgYW1iaWd1b3VzLg0KCSAqICAgICAgfSk7DQoJICogICAgICANCgkgKiAgICAgIGluc3RhbmNlLm9uKCJjbGljayIsIGZ1bmN0aW9uKGV2ZW50KSB7DQoJICogICAgICAgICAgY29uc29sZS5sb2coaW5zdGFuY2UgPT0gdGhpcyk7IC8vIHRydWUsICJvbiIgdXNlcyBkaXNwYXRjaGVyIHNjb3BlIGJ5IGRlZmF1bHQuDQoJICogICAgICB9KTsNCgkgKiANCgkgKiBJZiB5b3Ugd2FudCB0byB1c2UgYWRkRXZlbnRMaXN0ZW5lciBpbnN0ZWFkLCB5b3UgbWF5IHdhbnQgdG8gdXNlIGZ1bmN0aW9uLmJpbmQoKSBvciBhIHNpbWlsYXIgcHJveHkgdG8gbWFuYWdlIHNjb3BlLg0KCSAqICAgICAgDQoJICoNCgkgKiBAY2xhc3MgRXZlbnREaXNwYXRjaGVyDQoJICogQGNvbnN0cnVjdG9yDQoJICoqLw0KCWZ1bmN0aW9uIEV2ZW50RGlzcGF0Y2hlcigpIHsNCgkNCgkNCgkvLyBwcml2YXRlIHByb3BlcnRpZXM6DQoJCS8qKg0KCQkgKiBAcHJvdGVjdGVkDQoJCSAqIEBwcm9wZXJ0eSBfbGlzdGVuZXJzDQoJCSAqIEB0eXBlIE9iamVjdA0KCQkgKiovDQoJCXRoaXMuX2xpc3RlbmVycyA9IG51bGw7DQoJCQ0KCQkvKioNCgkJICogQHByb3RlY3RlZA0KCQkgKiBAcHJvcGVydHkgX2NhcHR1cmVMaXN0ZW5lcnMNCgkJICogQHR5cGUgT2JqZWN0DQoJCSAqKi8NCgkJdGhpcy5fY2FwdHVyZUxpc3RlbmVycyA9IG51bGw7DQoJfQ0KCXZhciBwID0gRXZlbnREaXNwYXRjaGVyLnByb3RvdHlwZTsNCg0KCS8qKg0KCSAqIDxzdHJvbmc+UkVNT1ZFRDwvc3Ryb25nPi4gUmVtb3ZlZCBpbiBmYXZvciBvZiB1c2luZyBgTXlTdXBlckNsYXNzX2NvbnN0cnVjdG9yYC4NCgkgKiBTZWUge3sjY3Jvc3NMaW5rICJVdGlsaXR5IE1ldGhvZHMvZXh0ZW5kIn19e3svY3Jvc3NMaW5rfX0gYW5kIHt7I2Nyb3NzTGluayAiVXRpbGl0eSBNZXRob2RzL3Byb21vdGUifX17ey9jcm9zc0xpbmt9fQ0KCSAqIGZvciBkZXRhaWxzLg0KCSAqDQoJICogVGhlcmUgaXMgYW4gaW5oZXJpdGFuY2UgdHV0b3JpYWwgZGlzdHJpYnV0ZWQgd2l0aCBFYXNlbEpTIGluIC90dXRvcmlhbHMvSW5oZXJpdGFuY2UuDQoJICoNCgkgKiBAbWV0aG9kIGluaXRpYWxpemUNCgkgKiBAcHJvdGVjdGVkDQoJICogQGRlcHJlY2F0ZWQNCgkgKi8NCgkvLyBwLmluaXRpYWxpemUgPSBmdW5jdGlvbigpIHt9OyAvLyBzZWFyY2hhYmxlIGZvciBkZXZzIHdvbmRlcmluZyB3aGVyZSBpdCBpcy4NCg0KDQovLyBzdGF0aWMgcHVibGljIG1ldGhvZHM6DQoJLyoqDQoJICogU3RhdGljIGluaXRpYWxpemVyIHRvIG1peCBFdmVudERpc3BhdGNoZXIgbWV0aG9kcyBpbnRvIGEgdGFyZ2V0IG9iamVjdCBvciBwcm90b3R5cGUuDQoJICogDQoJICogCQlFdmVudERpc3BhdGNoZXIuaW5pdGlhbGl6ZShNeUNsYXNzLnByb3RvdHlwZSk7IC8vIGFkZCB0byB0aGUgcHJvdG90eXBlIG9mIHRoZSBjbGFzcw0KCSAqIAkJRXZlbnREaXNwYXRjaGVyLmluaXRpYWxpemUobXlPYmplY3QpOyAvLyBhZGQgdG8gYSBzcGVjaWZpYyBpbnN0YW5jZQ0KCSAqIA0KCSAqIEBtZXRob2QgaW5pdGlhbGl6ZQ0KCSAqIEBzdGF0aWMNCgkgKiBAcGFyYW0ge09iamVjdH0gdGFyZ2V0IFRoZSB0YXJnZXQgb2JqZWN0IHRvIGluamVjdCBFdmVudERpc3BhdGNoZXIgbWV0aG9kcyBpbnRvLiBUaGlzIGNhbiBiZSBhbiBpbnN0YW5jZSBvciBhDQoJICogcHJvdG90eXBlLg0KCSAqKi8NCglFdmVudERpc3BhdGNoZXIuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uKHRhcmdldCkgew0KCQl0YXJnZXQuYWRkRXZlbnRMaXN0ZW5lciA9IHAuYWRkRXZlbnRMaXN0ZW5lcjsNCgkJdGFyZ2V0Lm9uID0gcC5vbjsNCgkJdGFyZ2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIgPSB0YXJnZXQub2ZmID0gIHAucmVtb3ZlRXZlbnRMaXN0ZW5lcjsNCgkJdGFyZ2V0LnJlbW92ZUFsbEV2ZW50TGlzdGVuZXJzID0gcC5yZW1vdmVBbGxFdmVudExpc3RlbmVyczsNCgkJdGFyZ2V0Lmhhc0V2ZW50TGlzdGVuZXIgPSBwLmhhc0V2ZW50TGlzdGVuZXI7DQoJCXRhcmdldC5kaXNwYXRjaEV2ZW50ID0gcC5kaXNwYXRjaEV2ZW50Ow0KCQl0YXJnZXQuX2Rpc3BhdGNoRXZlbnQgPSBwLl9kaXNwYXRjaEV2ZW50Ow0KCQl0YXJnZXQud2lsbFRyaWdnZXIgPSBwLndpbGxUcmlnZ2VyOw0KCX07DQoJDQoNCi8vIHB1YmxpYyBtZXRob2RzOg0KCS8qKg0KCSAqIEFkZHMgdGhlIHNwZWNpZmllZCBldmVudCBsaXN0ZW5lci4gTm90ZSB0aGF0IGFkZGluZyBtdWx0aXBsZSBsaXN0ZW5lcnMgdG8gdGhlIHNhbWUgZnVuY3Rpb24gd2lsbCByZXN1bHQgaW4NCgkgKiBtdWx0aXBsZSBjYWxsYmFja3MgZ2V0dGluZyBmaXJlZC4NCgkgKg0KCSAqIDxoND5FeGFtcGxlPC9oND4NCgkgKg0KCSAqICAgICAgZGlzcGxheU9iamVjdC5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsIGhhbmRsZUNsaWNrKTsNCgkgKiAgICAgIGZ1bmN0aW9uIGhhbmRsZUNsaWNrKGV2ZW50KSB7DQoJICogICAgICAgICAvLyBDbGljayBoYXBwZW5lZC4NCgkgKiAgICAgIH0NCgkgKg0KCSAqIEBtZXRob2QgYWRkRXZlbnRMaXN0ZW5lcg0KCSAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlIFRoZSBzdHJpbmcgdHlwZSBvZiB0aGUgZXZlbnQuDQoJICogQHBhcmFtIHtGdW5jdGlvbiB8IE9iamVjdH0gbGlzdGVuZXIgQW4gb2JqZWN0IHdpdGggYSBoYW5kbGVFdmVudCBtZXRob2QsIG9yIGEgZnVuY3Rpb24gdGhhdCB3aWxsIGJlIGNhbGxlZCB3aGVuDQoJICogdGhlIGV2ZW50IGlzIGRpc3BhdGNoZWQuDQoJICogQHBhcmFtIHtCb29sZWFufSBbdXNlQ2FwdHVyZV0gRm9yIGV2ZW50cyB0aGF0IGJ1YmJsZSwgaW5kaWNhdGVzIHdoZXRoZXIgdG8gbGlzdGVuIGZvciB0aGUgZXZlbnQgaW4gdGhlIGNhcHR1cmUgb3IgYnViYmxpbmcvdGFyZ2V0IHBoYXNlLg0KCSAqIEByZXR1cm4ge0Z1bmN0aW9uIHwgT2JqZWN0fSBSZXR1cm5zIHRoZSBsaXN0ZW5lciBmb3IgY2hhaW5pbmcgb3IgYXNzaWdubWVudC4NCgkgKiovDQoJcC5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIsIHVzZUNhcHR1cmUpIHsNCgkJdmFyIGxpc3RlbmVyczsNCgkJaWYgKHVzZUNhcHR1cmUpIHsNCgkJCWxpc3RlbmVycyA9IHRoaXMuX2NhcHR1cmVMaXN0ZW5lcnMgPSB0aGlzLl9jYXB0dXJlTGlzdGVuZXJzfHx7fTsNCgkJfSBlbHNlIHsNCgkJCWxpc3RlbmVycyA9IHRoaXMuX2xpc3RlbmVycyA9IHRoaXMuX2xpc3RlbmVyc3x8e307DQoJCX0NCgkJdmFyIGFyciA9IGxpc3RlbmVyc1t0eXBlXTsNCgkJaWYgKGFycikgeyB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgbGlzdGVuZXIsIHVzZUNhcHR1cmUpOyB9DQoJCWFyciA9IGxpc3RlbmVyc1t0eXBlXTsgLy8gcmVtb3ZlIG1heSBoYXZlIGRlbGV0ZWQgdGhlIGFycmF5DQoJCWlmICghYXJyKSB7IGxpc3RlbmVyc1t0eXBlXSA9IFtsaXN0ZW5lcl07ICB9DQoJCWVsc2UgeyBhcnIucHVzaChsaXN0ZW5lcik7IH0NCgkJcmV0dXJuIGxpc3RlbmVyOw0KCX07DQoJDQoJLyoqDQoJICogQSBzaG9ydGN1dCBtZXRob2QgZm9yIHVzaW5nIGFkZEV2ZW50TGlzdGVuZXIgdGhhdCBtYWtlcyBpdCBlYXNpZXIgdG8gc3BlY2lmeSBhbiBleGVjdXRpb24gc2NvcGUsIGhhdmUgYSBsaXN0ZW5lcg0KCSAqIG9ubHkgcnVuIG9uY2UsIGFzc29jaWF0ZSBhcmJpdHJhcnkgZGF0YSB3aXRoIHRoZSBsaXN0ZW5lciwgYW5kIHJlbW92ZSB0aGUgbGlzdGVuZXIuDQoJICogDQoJICogVGhpcyBtZXRob2Qgd29ya3MgYnkgY3JlYXRpbmcgYW4gYW5vbnltb3VzIHdyYXBwZXIgZnVuY3Rpb24gYW5kIHN1YnNjcmliaW5nIGl0IHdpdGggYWRkRXZlbnRMaXN0ZW5lci4NCgkgKiBUaGUgY3JlYXRlZCBhbm9ueW1vdXMgZnVuY3Rpb24gaXMgcmV0dXJuZWQgZm9yIHVzZSB3aXRoIC5yZW1vdmVFdmVudExpc3RlbmVyIChvciAub2ZmKS4NCgkgKiANCgkgKiA8aDQ+RXhhbXBsZTwvaDQ+DQoJICogDQoJICogCQl2YXIgbGlzdGVuZXIgPSBteUJ0bi5vbigiY2xpY2siLCBoYW5kbGVDbGljaywgbnVsbCwgZmFsc2UsIHtjb3VudDozfSk7DQoJICogCQlmdW5jdGlvbiBoYW5kbGVDbGljayhldnQsIGRhdGEpIHsNCgkgKiAJCQlkYXRhLmNvdW50IC09IDE7DQoJICogCQkJY29uc29sZS5sb2codGhpcyA9PSBteUJ0bik7IC8vIHRydWUgLSBzY29wZSBkZWZhdWx0cyB0byB0aGUgZGlzcGF0Y2hlcg0KCSAqIAkJCWlmIChkYXRhLmNvdW50ID09IDApIHsNCgkgKiAJCQkJYWxlcnQoImNsaWNrZWQgMyB0aW1lcyEiKTsNCgkgKiAJCQkJbXlCdG4ub2ZmKCJjbGljayIsIGxpc3RlbmVyKTsNCgkgKiAJCQkJLy8gYWx0ZXJuYXRlbHk6IGV2dC5yZW1vdmUoKTsNCgkgKiAJCQl9DQoJICogCQl9DQoJICogDQoJICogQG1ldGhvZCBvbg0KCSAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlIFRoZSBzdHJpbmcgdHlwZSBvZiB0aGUgZXZlbnQuDQoJICogQHBhcmFtIHtGdW5jdGlvbiB8IE9iamVjdH0gbGlzdGVuZXIgQW4gb2JqZWN0IHdpdGggYSBoYW5kbGVFdmVudCBtZXRob2QsIG9yIGEgZnVuY3Rpb24gdGhhdCB3aWxsIGJlIGNhbGxlZCB3aGVuDQoJICogdGhlIGV2ZW50IGlzIGRpc3BhdGNoZWQuDQoJICogQHBhcmFtIHtPYmplY3R9IFtzY29wZV0gVGhlIHNjb3BlIHRvIGV4ZWN1dGUgdGhlIGxpc3RlbmVyIGluLiBEZWZhdWx0cyB0byB0aGUgZGlzcGF0Y2hlci9jdXJyZW50VGFyZ2V0IGZvciBmdW5jdGlvbiBsaXN0ZW5lcnMsIGFuZCB0byB0aGUgbGlzdGVuZXIgaXRzZWxmIGZvciBvYmplY3QgbGlzdGVuZXJzIChpZS4gdXNpbmcgaGFuZGxlRXZlbnQpLg0KCSAqIEBwYXJhbSB7Qm9vbGVhbn0gW29uY2U9ZmFsc2VdIElmIHRydWUsIHRoZSBsaXN0ZW5lciB3aWxsIHJlbW92ZSBpdHNlbGYgYWZ0ZXIgdGhlIGZpcnN0IHRpbWUgaXQgaXMgdHJpZ2dlcmVkLg0KCSAqIEBwYXJhbSB7Kn0gW2RhdGFdIEFyYml0cmFyeSBkYXRhIHRoYXQgd2lsbCBiZSBpbmNsdWRlZCBhcyB0aGUgc2Vjb25kIHBhcmFtZXRlciB3aGVuIHRoZSBsaXN0ZW5lciBpcyBjYWxsZWQuDQoJICogQHBhcmFtIHtCb29sZWFufSBbdXNlQ2FwdHVyZT1mYWxzZV0gRm9yIGV2ZW50cyB0aGF0IGJ1YmJsZSwgaW5kaWNhdGVzIHdoZXRoZXIgdG8gbGlzdGVuIGZvciB0aGUgZXZlbnQgaW4gdGhlIGNhcHR1cmUgb3IgYnViYmxpbmcvdGFyZ2V0IHBoYXNlLg0KCSAqIEByZXR1cm4ge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBhbm9ueW1vdXMgZnVuY3Rpb24gdGhhdCB3YXMgY3JlYXRlZCBhbmQgYXNzaWduZWQgYXMgdGhlIGxpc3RlbmVyLiBUaGlzIGlzIG5lZWRlZCB0byByZW1vdmUgdGhlIGxpc3RlbmVyIGxhdGVyIHVzaW5nIC5yZW1vdmVFdmVudExpc3RlbmVyLg0KCSAqKi8NCglwLm9uID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIsIHNjb3BlLCBvbmNlLCBkYXRhLCB1c2VDYXB0dXJlKSB7DQoJCWlmIChsaXN0ZW5lci5oYW5kbGVFdmVudCkgew0KCQkJc2NvcGUgPSBzY29wZXx8bGlzdGVuZXI7DQoJCQlsaXN0ZW5lciA9IGxpc3RlbmVyLmhhbmRsZUV2ZW50Ow0KCQl9DQoJCXNjb3BlID0gc2NvcGV8fHRoaXM7DQoJCXJldHVybiB0aGlzLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgZnVuY3Rpb24oZXZ0KSB7DQoJCQkJbGlzdGVuZXIuY2FsbChzY29wZSwgZXZ0LCBkYXRhKTsNCgkJCQlvbmNlJiZldnQucmVtb3ZlKCk7DQoJCQl9LCB1c2VDYXB0dXJlKTsNCgl9Ow0KDQoJLyoqDQoJICogUmVtb3ZlcyB0aGUgc3BlY2lmaWVkIGV2ZW50IGxpc3RlbmVyLg0KCSAqDQoJICogPGI+SW1wb3J0YW50IE5vdGU6PC9iPiB0aGF0IHlvdSBtdXN0IHBhc3MgdGhlIGV4YWN0IGZ1bmN0aW9uIHJlZmVyZW5jZSB1c2VkIHdoZW4gdGhlIGV2ZW50IHdhcyBhZGRlZC4gSWYgYSBwcm94eQ0KCSAqIGZ1bmN0aW9uLCBvciBmdW5jdGlvbiBjbG9zdXJlIGlzIHVzZWQgYXMgdGhlIGNhbGxiYWNrLCB0aGUgcHJveHkvY2xvc3VyZSByZWZlcmVuY2UgbXVzdCBiZSB1c2VkIC0gYSBuZXcgcHJveHkgb3INCgkgKiBjbG9zdXJlIHdpbGwgbm90IHdvcmsuDQoJICoNCgkgKiA8aDQ+RXhhbXBsZTwvaDQ+DQoJICoNCgkgKiAgICAgIGRpc3BsYXlPYmplY3QucmVtb3ZlRXZlbnRMaXN0ZW5lcigiY2xpY2siLCBoYW5kbGVDbGljayk7DQoJICoNCgkgKiBAbWV0aG9kIHJlbW92ZUV2ZW50TGlzdGVuZXINCgkgKiBAcGFyYW0ge1N0cmluZ30gdHlwZSBUaGUgc3RyaW5nIHR5cGUgb2YgdGhlIGV2ZW50Lg0KCSAqIEBwYXJhbSB7RnVuY3Rpb24gfCBPYmplY3R9IGxpc3RlbmVyIFRoZSBsaXN0ZW5lciBmdW5jdGlvbiBvciBvYmplY3QuDQoJICogQHBhcmFtIHtCb29sZWFufSBbdXNlQ2FwdHVyZV0gRm9yIGV2ZW50cyB0aGF0IGJ1YmJsZSwgaW5kaWNhdGVzIHdoZXRoZXIgdG8gbGlzdGVuIGZvciB0aGUgZXZlbnQgaW4gdGhlIGNhcHR1cmUgb3IgYnViYmxpbmcvdGFyZ2V0IHBoYXNlLg0KCSAqKi8NCglwLnJlbW92ZUV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lciwgdXNlQ2FwdHVyZSkgew0KCQl2YXIgbGlzdGVuZXJzID0gdXNlQ2FwdHVyZSA/IHRoaXMuX2NhcHR1cmVMaXN0ZW5lcnMgOiB0aGlzLl9saXN0ZW5lcnM7DQoJCWlmICghbGlzdGVuZXJzKSB7IHJldHVybjsgfQ0KCQl2YXIgYXJyID0gbGlzdGVuZXJzW3R5cGVdOw0KCQlpZiAoIWFycikgeyByZXR1cm47IH0NCgkJZm9yICh2YXIgaT0wLGw9YXJyLmxlbmd0aDsgaTxsOyBpKyspIHsNCgkJCWlmIChhcnJbaV0gPT0gbGlzdGVuZXIpIHsNCgkJCQlpZiAobD09MSkgeyBkZWxldGUobGlzdGVuZXJzW3R5cGVdKTsgfSAvLyBhbGxvd3MgZm9yIGZhc3RlciBjaGVja3MuDQoJCQkJZWxzZSB7IGFyci5zcGxpY2UoaSwxKTsgfQ0KCQkJCWJyZWFrOw0KCQkJfQ0KCQl9DQoJfTsNCgkNCgkvKioNCgkgKiBBIHNob3J0Y3V0IHRvIHRoZSByZW1vdmVFdmVudExpc3RlbmVyIG1ldGhvZCwgd2l0aCB0aGUgc2FtZSBwYXJhbWV0ZXJzIGFuZCByZXR1cm4gdmFsdWUuIFRoaXMgaXMgYSBjb21wYW5pb24gdG8gdGhlDQoJICogLm9uIG1ldGhvZC4NCgkgKg0KCSAqIEBtZXRob2Qgb2ZmDQoJICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgVGhlIHN0cmluZyB0eXBlIG9mIHRoZSBldmVudC4NCgkgKiBAcGFyYW0ge0Z1bmN0aW9uIHwgT2JqZWN0fSBsaXN0ZW5lciBUaGUgbGlzdGVuZXIgZnVuY3Rpb24gb3Igb2JqZWN0Lg0KCSAqIEBwYXJhbSB7Qm9vbGVhbn0gW3VzZUNhcHR1cmVdIEZvciBldmVudHMgdGhhdCBidWJibGUsIGluZGljYXRlcyB3aGV0aGVyIHRvIGxpc3RlbiBmb3IgdGhlIGV2ZW50IGluIHRoZSBjYXB0dXJlIG9yIGJ1YmJsaW5nL3RhcmdldCBwaGFzZS4NCgkgKiovDQoJcC5vZmYgPSBwLnJlbW92ZUV2ZW50TGlzdGVuZXI7DQoNCgkvKioNCgkgKiBSZW1vdmVzIGFsbCBsaXN0ZW5lcnMgZm9yIHRoZSBzcGVjaWZpZWQgdHlwZSwgb3IgYWxsIGxpc3RlbmVycyBvZiBhbGwgdHlwZXMuDQoJICoNCgkgKiA8aDQ+RXhhbXBsZTwvaDQ+DQoJICoNCgkgKiAgICAgIC8vIFJlbW92ZSBhbGwgbGlzdGVuZXJzDQoJICogICAgICBkaXNwbGF5T2JqZWN0LnJlbW92ZUFsbEV2ZW50TGlzdGVuZXJzKCk7DQoJICoNCgkgKiAgICAgIC8vIFJlbW92ZSBhbGwgY2xpY2sgbGlzdGVuZXJzDQoJICogICAgICBkaXNwbGF5T2JqZWN0LnJlbW92ZUFsbEV2ZW50TGlzdGVuZXJzKCJjbGljayIpOw0KCSAqDQoJICogQG1ldGhvZCByZW1vdmVBbGxFdmVudExpc3RlbmVycw0KCSAqIEBwYXJhbSB7U3RyaW5nfSBbdHlwZV0gVGhlIHN0cmluZyB0eXBlIG9mIHRoZSBldmVudC4gSWYgb21pdHRlZCwgYWxsIGxpc3RlbmVycyBmb3IgYWxsIHR5cGVzIHdpbGwgYmUgcmVtb3ZlZC4NCgkgKiovDQoJcC5yZW1vdmVBbGxFdmVudExpc3RlbmVycyA9IGZ1bmN0aW9uKHR5cGUpIHsNCgkJaWYgKCF0eXBlKSB7IHRoaXMuX2xpc3RlbmVycyA9IHRoaXMuX2NhcHR1cmVMaXN0ZW5lcnMgPSBudWxsOyB9DQoJCWVsc2Ugew0KCQkJaWYgKHRoaXMuX2xpc3RlbmVycykgeyBkZWxldGUodGhpcy5fbGlzdGVuZXJzW3R5cGVdKTsgfQ0KCQkJaWYgKHRoaXMuX2NhcHR1cmVMaXN0ZW5lcnMpIHsgZGVsZXRlKHRoaXMuX2NhcHR1cmVMaXN0ZW5lcnNbdHlwZV0pOyB9DQoJCX0NCgl9Ow0KDQoJLyoqDQoJICogRGlzcGF0Y2hlcyB0aGUgc3BlY2lmaWVkIGV2ZW50IHRvIGFsbCBsaXN0ZW5lcnMuDQoJICoNCgkgKiA8aDQ+RXhhbXBsZTwvaDQ+DQoJICoNCgkgKiAgICAgIC8vIFVzZSBhIHN0cmluZyBldmVudA0KCSAqICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KCJjb21wbGV0ZSIpOw0KCSAqDQoJICogICAgICAvLyBVc2UgYW4gRXZlbnQgaW5zdGFuY2UNCgkgKiAgICAgIHZhciBldmVudCA9IG5ldyBjcmVhdGVqcy5FdmVudCgicHJvZ3Jlc3MiKTsNCgkgKiAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChldmVudCk7DQoJICoNCgkgKiBAbWV0aG9kIGRpc3BhdGNoRXZlbnQNCgkgKiBAcGFyYW0ge09iamVjdCB8IFN0cmluZyB8IEV2ZW50fSBldmVudE9iaiBBbiBvYmplY3Qgd2l0aCBhICJ0eXBlIiBwcm9wZXJ0eSwgb3IgYSBzdHJpbmcgdHlwZS4NCgkgKiBXaGlsZSBhIGdlbmVyaWMgb2JqZWN0IHdpbGwgd29yaywgaXQgaXMgcmVjb21tZW5kZWQgdG8gdXNlIGEgQ3JlYXRlSlMgRXZlbnQgaW5zdGFuY2UuIElmIGEgc3RyaW5nIGlzIHVzZWQsDQoJICogZGlzcGF0Y2hFdmVudCB3aWxsIGNvbnN0cnVjdCBhbiBFdmVudCBpbnN0YW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQgdHlwZS4NCgkgKiBAcmV0dXJuIHtCb29sZWFufSBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBldmVudE9iai5kZWZhdWx0UHJldmVudGVkLg0KCSAqKi8NCglwLmRpc3BhdGNoRXZlbnQgPSBmdW5jdGlvbihldmVudE9iaikgew0KCQlpZiAodHlwZW9mIGV2ZW50T2JqID09ICJzdHJpbmciKSB7DQoJCQkvLyB3b24ndCBidWJibGUsIHNvIHNraXAgZXZlcnl0aGluZyBpZiB0aGVyZSdzIG5vIGxpc3RlbmVyczoNCgkJCXZhciBsaXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnM7DQoJCQlpZiAoIWxpc3RlbmVycyB8fCAhbGlzdGVuZXJzW2V2ZW50T2JqXSkgeyByZXR1cm4gZmFsc2U7IH0NCgkJCWV2ZW50T2JqID0gbmV3IGNyZWF0ZWpzLkV2ZW50KGV2ZW50T2JqKTsNCgkJfSBlbHNlIGlmIChldmVudE9iai50YXJnZXQgJiYgZXZlbnRPYmouY2xvbmUpIHsNCgkJCS8vIHJlZGlzcGF0Y2hpbmcgYW4gYWN0aXZlIGV2ZW50IG9iamVjdCwgc28gY2xvbmUgaXQ6DQoJCQlldmVudE9iaiA9IGV2ZW50T2JqLmNsb25lKCk7DQoJCX0NCgkJdHJ5IHsgZXZlbnRPYmoudGFyZ2V0ID0gdGhpczsgfSBjYXRjaCAoZSkge30gLy8gdHJ5L2NhdGNoIGFsbG93cyByZWRpc3BhdGNoaW5nIG9mIG5hdGl2ZSBldmVudHMNCg0KCQlpZiAoIWV2ZW50T2JqLmJ1YmJsZXMgfHwgIXRoaXMucGFyZW50KSB7DQoJCQl0aGlzLl9kaXNwYXRjaEV2ZW50KGV2ZW50T2JqLCAyKTsNCgkJfSBlbHNlIHsNCgkJCXZhciB0b3A9dGhpcywgbGlzdD1bdG9wXTsNCgkJCXdoaWxlICh0b3AucGFyZW50KSB7IGxpc3QucHVzaCh0b3AgPSB0b3AucGFyZW50KTsgfQ0KCQkJdmFyIGksIGw9bGlzdC5sZW5ndGg7DQoNCgkJCS8vIGNhcHR1cmUgJiBhdFRhcmdldA0KCQkJZm9yIChpPWwtMTsgaT49MCAmJiAhZXZlbnRPYmoucHJvcGFnYXRpb25TdG9wcGVkOyBpLS0pIHsNCgkJCQlsaXN0W2ldLl9kaXNwYXRjaEV2ZW50KGV2ZW50T2JqLCAxKyhpPT0wKSk7DQoJCQl9DQoJCQkvLyBidWJibGluZw0KCQkJZm9yIChpPTE7IGk8bCAmJiAhZXZlbnRPYmoucHJvcGFnYXRpb25TdG9wcGVkOyBpKyspIHsNCgkJCQlsaXN0W2ldLl9kaXNwYXRjaEV2ZW50KGV2ZW50T2JqLCAzKTsNCgkJCX0NCgkJfQ0KCQlyZXR1cm4gZXZlbnRPYmouZGVmYXVsdFByZXZlbnRlZDsNCgl9Ow0KDQoJLyoqDQoJICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlcmUgaXMgYXQgbGVhc3Qgb25lIGxpc3RlbmVyIGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50IHR5cGUuDQoJICogQG1ldGhvZCBoYXNFdmVudExpc3RlbmVyDQoJICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgVGhlIHN0cmluZyB0eXBlIG9mIHRoZSBldmVudC4NCgkgKiBAcmV0dXJuIHtCb29sZWFufSBSZXR1cm5zIHRydWUgaWYgdGhlcmUgaXMgYXQgbGVhc3Qgb25lIGxpc3RlbmVyIGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50Lg0KCSAqKi8NCglwLmhhc0V2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbih0eXBlKSB7DQoJCXZhciBsaXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnMsIGNhcHR1cmVMaXN0ZW5lcnMgPSB0aGlzLl9jYXB0dXJlTGlzdGVuZXJzOw0KCQlyZXR1cm4gISEoKGxpc3RlbmVycyAmJiBsaXN0ZW5lcnNbdHlwZV0pIHx8IChjYXB0dXJlTGlzdGVuZXJzICYmIGNhcHR1cmVMaXN0ZW5lcnNbdHlwZV0pKTsNCgl9Ow0KCQ0KCS8qKg0KCSAqIEluZGljYXRlcyB3aGV0aGVyIHRoZXJlIGlzIGF0IGxlYXN0IG9uZSBsaXN0ZW5lciBmb3IgdGhlIHNwZWNpZmllZCBldmVudCB0eXBlIG9uIHRoaXMgb2JqZWN0IG9yIGFueSBvZiBpdHMNCgkgKiBhbmNlc3RvcnMgKHBhcmVudCwgcGFyZW50J3MgcGFyZW50LCBldGMpLiBBIHJldHVybiB2YWx1ZSBvZiB0cnVlIGluZGljYXRlcyB0aGF0IGlmIGEgYnViYmxpbmcgZXZlbnQgb2YgdGhlDQoJICogc3BlY2lmaWVkIHR5cGUgaXMgZGlzcGF0Y2hlZCBmcm9tIHRoaXMgb2JqZWN0LCBpdCB3aWxsIHRyaWdnZXIgYXQgbGVhc3Qgb25lIGxpc3RlbmVyLg0KCSAqIA0KCSAqIFRoaXMgaXMgc2ltaWxhciB0byB7eyNjcm9zc0xpbmsgIkV2ZW50RGlzcGF0Y2hlci9oYXNFdmVudExpc3RlbmVyIn19e3svY3Jvc3NMaW5rfX0sIGJ1dCBpdCBzZWFyY2hlcyB0aGUgZW50aXJlDQoJICogZXZlbnQgZmxvdyBmb3IgYSBsaXN0ZW5lciwgbm90IGp1c3QgdGhpcyBvYmplY3QuDQoJICogQG1ldGhvZCB3aWxsVHJpZ2dlcg0KCSAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlIFRoZSBzdHJpbmcgdHlwZSBvZiB0aGUgZXZlbnQuDQoJICogQHJldHVybiB7Qm9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlcmUgaXMgYXQgbGVhc3Qgb25lIGxpc3RlbmVyIGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50Lg0KCSAqKi8NCglwLndpbGxUcmlnZ2VyID0gZnVuY3Rpb24odHlwZSkgew0KCQl2YXIgbyA9IHRoaXM7DQoJCXdoaWxlIChvKSB7DQoJCQlpZiAoby5oYXNFdmVudExpc3RlbmVyKHR5cGUpKSB7IHJldHVybiB0cnVlOyB9DQoJCQlvID0gby5wYXJlbnQ7DQoJCX0NCgkJcmV0dXJuIGZhbHNlOw0KCX07DQoNCgkvKioNCgkgKiBAbWV0aG9kIHRvU3RyaW5nDQoJICogQHJldHVybiB7U3RyaW5nfSBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgaW5zdGFuY2UuDQoJICoqLw0KCXAudG9TdHJpbmcgPSBmdW5jdGlvbigpIHsNCgkJcmV0dXJuICJbRXZlbnREaXNwYXRjaGVyXSI7DQoJfTsNCg0KDQovLyBwcml2YXRlIG1ldGhvZHM6DQoJLyoqDQoJICogQG1ldGhvZCBfZGlzcGF0Y2hFdmVudA0KCSAqIEBwYXJhbSB7T2JqZWN0IHwgU3RyaW5nIHwgRXZlbnR9IGV2ZW50T2JqDQoJICogQHBhcmFtIHtPYmplY3R9IGV2ZW50UGhhc2UNCgkgKiBAcHJvdGVjdGVkDQoJICoqLw0KCXAuX2Rpc3BhdGNoRXZlbnQgPSBmdW5jdGlvbihldmVudE9iaiwgZXZlbnRQaGFzZSkgew0KCQl2YXIgbCwgbGlzdGVuZXJzID0gKGV2ZW50UGhhc2U9PTEpID8gdGhpcy5fY2FwdHVyZUxpc3RlbmVycyA6IHRoaXMuX2xpc3RlbmVyczsNCgkJaWYgKGV2ZW50T2JqICYmIGxpc3RlbmVycykgew0KCQkJdmFyIGFyciA9IGxpc3RlbmVyc1tldmVudE9iai50eXBlXTsNCgkJCWlmICghYXJyfHwhKGw9YXJyLmxlbmd0aCkpIHsgcmV0dXJuOyB9DQoJCQl0cnkgeyBldmVudE9iai5jdXJyZW50VGFyZ2V0ID0gdGhpczsgfSBjYXRjaCAoZSkge30NCgkJCXRyeSB7IGV2ZW50T2JqLmV2ZW50UGhhc2UgPSBldmVudFBoYXNlOyB9IGNhdGNoIChlKSB7fQ0KCQkJZXZlbnRPYmoucmVtb3ZlZCA9IGZhbHNlOw0KCQkJDQoJCQlhcnIgPSBhcnIuc2xpY2UoKTsgLy8gdG8gYXZvaWQgaXNzdWVzIHdpdGggaXRlbXMgYmVpbmcgcmVtb3ZlZCBvciBhZGRlZCBkdXJpbmcgdGhlIGRpc3BhdGNoDQoJCQlmb3IgKHZhciBpPTA7IGk8bCAmJiAhZXZlbnRPYmouaW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkOyBpKyspIHsNCgkJCQl2YXIgbyA9IGFycltpXTsNCgkJCQlpZiAoby5oYW5kbGVFdmVudCkgeyBvLmhhbmRsZUV2ZW50KGV2ZW50T2JqKTsgfQ0KCQkJCWVsc2UgeyBvKGV2ZW50T2JqKTsgfQ0KCQkJCWlmIChldmVudE9iai5yZW1vdmVkKSB7DQoJCQkJCXRoaXMub2ZmKGV2ZW50T2JqLnR5cGUsIG8sIGV2ZW50UGhhc2U9PTEpOw0KCQkJCQlldmVudE9iai5yZW1vdmVkID0gZmFsc2U7DQoJCQkJfQ0KCQkJfQ0KCQl9DQoJfTsNCg0KDQoJY3JlYXRlanMuRXZlbnREaXNwYXRjaGVyID0gRXZlbnREaXNwYXRjaGVyOw0KfSgpKTsKCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi8vIFByb2dyZXNzRXZlbnQuanMKLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCnRoaXMuY3JlYXRlanMgPSB0aGlzLmNyZWF0ZWpzIHx8IHt9OwoKKGZ1bmN0aW9uIChzY29wZSkgewoJInVzZSBzdHJpY3QiOwoKCS8vIGNvbnN0cnVjdG9yCgkvKioKCSAqIEEgY3JlYXRlanMge3sjY3Jvc3NMaW5rICJFdmVudCJ9fXt7L2Nyb3NzTGlua319IHRoYXQgaXMgZGlzcGF0Y2hlZCB3aGVuIHByb2dyZXNzIGNoYW5nZXMuCgkgKiBAY2xhc3MgUHJvZ3Jlc3NFdmVudAoJICogQHBhcmFtIHtOdW1iZXJ9IGxvYWRlZCBUaGUgYW1vdW50IHRoYXQgaGFzIGJlZW4gbG9hZGVkLiBUaGlzIGNhbiBiZSBhbnkgbnVtYmVyIHJlbGF0aXZlIHRvIHRoZSB0b3RhbC4KCSAqIEBwYXJhbSB7TnVtYmVyfSBbdG90YWxdIFRoZSB0b3RhbCBhbW91bnQgdGhhdCB3aWxsIGxvYWQuIFRoaXMgd2lsbCBkZWZhdWx0IHRvIDAsIHNvIGRvZXMgbm90IG5lZWQgdG8gYmUgcGFzc2VkIGluLAoJICogYXMgbG9uZyBhcyB0aGUgbG9hZGVkIHZhbHVlIGlzIGEgcHJvZ3Jlc3MgdmFsdWUgKGJldHdlZW4gMCBhbmQgMSkuCgkgKiBAdG9kbyBDb25zaWRlciBoYXZpbmcgdGhpcyBldmVudCBiZSBhICJmaWxlcHJvZ3Jlc3MiIGV2ZW50IGFzIHdlbGwKCSAqIEBjb25zdHJ1Y3RvcgoJICovCglmdW5jdGlvbiBQcm9ncmVzc0V2ZW50KGxvYWRlZCwgdG90YWwpIHsKCQl0aGlzLkV2ZW50X2NvbnN0cnVjdG9yKCJwcm9ncmVzcyIpOwoKCQkvKioKCQkgKiBUaGUgYW1vdW50IHRoYXQgaGFzIGJlZW4gbG9hZGVkIChvdXQgb2YgYSB0b3RhbCBhbW91bnQpCgkJICogQHByb3BlcnR5IGxvYWRlZAoJCSAqIEB0eXBlIHtOdW1iZXJ9CgkJICovCgkJdGhpcy5sb2FkZWQgPSBsb2FkZWQ7CgoJCS8qKgoJCSAqIFRoZSB0b3RhbCAic2l6ZSIgb2YgdGhlIGxvYWQuCgkJICogQHByb3BlcnR5IHRvdGFsCgkJICogQHR5cGUge051bWJlcn0KCQkgKiBAZGVmYXVsdCAxCgkJICovCgkJdGhpcy50b3RhbCA9ICh0b3RhbCA9PSBudWxsKSA/IDEgOiB0b3RhbDsKCgkJLyoqCgkJICogVGhlIHBlcmNlbnRhZ2UgKG91dCBvZiAxKSB0aGF0IHRoZSBsb2FkIGhhcyBiZWVuIGNvbXBsZXRlZC4gVGhpcyBpcyBjYWxjdWxhdGVkIHVzaW5nIGBsb2FkZWQvdG90YWxgLgoJCSAqIEBwcm9wZXJ0eSBwcm9ncmVzcwoJCSAqIEB0eXBlIHtOdW1iZXJ9CgkJICogQGRlZmF1bHQgMAoJCSAqLwoJCXRoaXMucHJvZ3Jlc3MgPSAodG90YWwgPT0gMCkgPyAwIDogdGhpcy5sb2FkZWQgLyB0aGlzLnRvdGFsOwoJfTsKCgl2YXIgcCA9IGNyZWF0ZWpzLmV4dGVuZChQcm9ncmVzc0V2ZW50LCBjcmVhdGVqcy5FdmVudCk7CgoJLyoqCgkgKiBSZXR1cm5zIGEgY2xvbmUgb2YgdGhlIFByb2dyZXNzRXZlbnQgaW5zdGFuY2UuCgkgKiBAbWV0aG9kIGNsb25lCgkgKiBAcmV0dXJuIHtQcm9ncmVzc0V2ZW50fSBhIGNsb25lIG9mIHRoZSBFdmVudCBpbnN0YW5jZS4KCSAqKi8KCXAuY2xvbmUgPSBmdW5jdGlvbigpIHsKCQlyZXR1cm4gbmV3IGNyZWF0ZWpzLlByb2dyZXNzRXZlbnQodGhpcy5sb2FkZWQsIHRoaXMudG90YWwpOwoJfTsKCgljcmVhdGVqcy5Qcm9ncmVzc0V2ZW50ID0gY3JlYXRlanMucHJvbW90ZShQcm9ncmVzc0V2ZW50LCAiRXZlbnQiKTsKCn0od2luZG93KSk7CgovLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwovLyBqc29uMy5qcwovLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoKLyohIEpTT04gdjMuMy4yIHwgaHR0cDovL2Jlc3RpZWpzLmdpdGh1Yi5pby9qc29uMyB8IENvcHlyaWdodCAyMDEyLTIwMTQsIEtpdCBDYW1icmlkZ2UgfCBodHRwOi8va2l0Lm1pdC1saWNlbnNlLm9yZyAqLwo7KGZ1bmN0aW9uICgpIHsKICAvLyBEZXRlY3QgdGhlIGBkZWZpbmVgIGZ1bmN0aW9uIGV4cG9zZWQgYnkgYXN5bmNocm9ub3VzIG1vZHVsZSBsb2FkZXJzLiBUaGUKICAvLyBzdHJpY3QgYGRlZmluZWAgY2hlY2sgaXMgbmVjZXNzYXJ5IGZvciBjb21wYXRpYmlsaXR5IHdpdGggYHIuanNgLgogIHZhciBpc0xvYWRlciA9IHR5cGVvZiBkZWZpbmUgPT09ICJmdW5jdGlvbiIgJiYgZGVmaW5lLmFtZDsKCiAgLy8gQSBzZXQgb2YgdHlwZXMgdXNlZCB0byBkaXN0aW5ndWlzaCBvYmplY3RzIGZyb20gcHJpbWl0aXZlcy4KICB2YXIgb2JqZWN0VHlwZXMgPSB7CiAgICAiZnVuY3Rpb24iOiB0cnVlLAogICAgIm9iamVjdCI6IHRydWUKICB9OwoKICAvLyBEZXRlY3QgdGhlIGBleHBvcnRzYCBvYmplY3QgZXhwb3NlZCBieSBDb21tb25KUyBpbXBsZW1lbnRhdGlvbnMuCiAgdmFyIGZyZWVFeHBvcnRzID0gb2JqZWN0VHlwZXNbdHlwZW9mIGV4cG9ydHNdICYmIGV4cG9ydHMgJiYgIWV4cG9ydHMubm9kZVR5cGUgJiYgZXhwb3J0czsKCiAgLy8gVXNlIHRoZSBgZ2xvYmFsYCBvYmplY3QgZXhwb3NlZCBieSBOb2RlIChpbmNsdWRpbmcgQnJvd3NlcmlmeSB2aWEKICAvLyBgaW5zZXJ0LW1vZHVsZS1nbG9iYWxzYCksIE5hcndoYWwsIGFuZCBSaW5nbyBhcyB0aGUgZGVmYXVsdCBjb250ZXh0LAogIC8vIGFuZCB0aGUgYHdpbmRvd2Agb2JqZWN0IGluIGJyb3dzZXJzLiBSaGlubyBleHBvcnRzIGEgYGdsb2JhbGAgZnVuY3Rpb24KICAvLyBpbnN0ZWFkLgogIHZhciByb290ID0gb2JqZWN0VHlwZXNbdHlwZW9mIHdpbmRvd10gJiYgd2luZG93IHx8IHRoaXMsCiAgICAgIGZyZWVHbG9iYWwgPSBmcmVlRXhwb3J0cyAmJiBvYmplY3RUeXBlc1t0eXBlb2YgbW9kdWxlXSAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiB0eXBlb2YgZ2xvYmFsID09ICJvYmplY3QiICYmIGdsb2JhbDsKCiAgaWYgKGZyZWVHbG9iYWwgJiYgKGZyZWVHbG9iYWxbImdsb2JhbCJdID09PSBmcmVlR2xvYmFsIHx8IGZyZWVHbG9iYWxbIndpbmRvdyJdID09PSBmcmVlR2xvYmFsIHx8IGZyZWVHbG9iYWxbInNlbGYiXSA9PT0gZnJlZUdsb2JhbCkpIHsKICAgIHJvb3QgPSBmcmVlR2xvYmFsOwogIH0KCiAgLy8gUHVibGljOiBJbml0aWFsaXplcyBKU09OIDMgdXNpbmcgdGhlIGdpdmVuIGBjb250ZXh0YCBvYmplY3QsIGF0dGFjaGluZyB0aGUKICAvLyBgc3RyaW5naWZ5YCBhbmQgYHBhcnNlYCBmdW5jdGlvbnMgdG8gdGhlIHNwZWNpZmllZCBgZXhwb3J0c2Agb2JqZWN0LgogIGZ1bmN0aW9uIHJ1bkluQ29udGV4dChjb250ZXh0LCBleHBvcnRzKSB7CiAgICBjb250ZXh0IHx8IChjb250ZXh0ID0gcm9vdFsiT2JqZWN0Il0oKSk7CiAgICBleHBvcnRzIHx8IChleHBvcnRzID0gcm9vdFsiT2JqZWN0Il0oKSk7CgogICAgLy8gTmF0aXZlIGNvbnN0cnVjdG9yIGFsaWFzZXMuCiAgICB2YXIgTnVtYmVyID0gY29udGV4dFsiTnVtYmVyIl0gfHwgcm9vdFsiTnVtYmVyIl0sCiAgICAgICAgU3RyaW5nID0gY29udGV4dFsiU3RyaW5nIl0gfHwgcm9vdFsiU3RyaW5nIl0sCiAgICAgICAgT2JqZWN0ID0gY29udGV4dFsiT2JqZWN0Il0gfHwgcm9vdFsiT2JqZWN0Il0sCiAgICAgICAgRGF0ZSA9IGNvbnRleHRbIkRhdGUiXSB8fCByb290WyJEYXRlIl0sCiAgICAgICAgU3ludGF4RXJyb3IgPSBjb250ZXh0WyJTeW50YXhFcnJvciJdIHx8IHJvb3RbIlN5bnRheEVycm9yIl0sCiAgICAgICAgVHlwZUVycm9yID0gY29udGV4dFsiVHlwZUVycm9yIl0gfHwgcm9vdFsiVHlwZUVycm9yIl0sCiAgICAgICAgTWF0aCA9IGNvbnRleHRbIk1hdGgiXSB8fCByb290WyJNYXRoIl0sCiAgICAgICAgbmF0aXZlSlNPTiA9IGNvbnRleHRbIkpTT04iXSB8fCByb290WyJKU09OIl07CgogICAgLy8gRGVsZWdhdGUgdG8gdGhlIG5hdGl2ZSBgc3RyaW5naWZ5YCBhbmQgYHBhcnNlYCBpbXBsZW1lbnRhdGlvbnMuCiAgICBpZiAodHlwZW9mIG5hdGl2ZUpTT04gPT0gIm9iamVjdCIgJiYgbmF0aXZlSlNPTikgewogICAgICBleHBvcnRzLnN0cmluZ2lmeSA9IG5hdGl2ZUpTT04uc3RyaW5naWZ5OwogICAgICBleHBvcnRzLnBhcnNlID0gbmF0aXZlSlNPTi5wYXJzZTsKICAgIH0KCiAgICAvLyBDb252ZW5pZW5jZSBhbGlhc2VzLgogICAgdmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZSwKICAgICAgICBnZXRDbGFzcyA9IG9iamVjdFByb3RvLnRvU3RyaW5nLAogICAgICAgIGlzUHJvcGVydHksIGZvckVhY2gsIHVuZGVmOwoKICAgIC8vIFRlc3QgdGhlIGBEYXRlI2dldFVUQypgIG1ldGhvZHMuIEJhc2VkIG9uIHdvcmsgYnkgQFlhZmZsZS4KICAgIHZhciBpc0V4dGVuZGVkID0gbmV3IERhdGUoLTM1MDk4MjczMzQ1NzMyOTIpOwogICAgdHJ5IHsKICAgICAgLy8gVGhlIGBnZXRVVENGdWxsWWVhcmAsIGBNb250aGAsIGFuZCBgRGF0ZWAgbWV0aG9kcyByZXR1cm4gbm9uc2Vuc2ljYWwKICAgICAgLy8gcmVzdWx0cyBmb3IgY2VydGFpbiBkYXRlcyBpbiBPcGVyYSA+PSAxMC41My4KICAgICAgaXNFeHRlbmRlZCA9IGlzRXh0ZW5kZWQuZ2V0VVRDRnVsbFllYXIoKSA9PSAtMTA5MjUyICYmIGlzRXh0ZW5kZWQuZ2V0VVRDTW9udGgoKSA9PT0gMCAmJiBpc0V4dGVuZGVkLmdldFVUQ0RhdGUoKSA9PT0gMSAmJgogICAgICAgIC8vIFNhZmFyaSA8IDIuMC4yIHN0b3JlcyB0aGUgaW50ZXJuYWwgbWlsbGlzZWNvbmQgdGltZSB2YWx1ZSBjb3JyZWN0bHksCiAgICAgICAgLy8gYnV0IGNsaXBzIHRoZSB2YWx1ZXMgcmV0dXJuZWQgYnkgdGhlIGRhdGUgbWV0aG9kcyB0byB0aGUgcmFuZ2Ugb2YKICAgICAgICAvLyBzaWduZWQgMzItYml0IGludGVnZXJzIChbLTIgKiogMzEsIDIgKiogMzEgLSAxXSkuCiAgICAgICAgaXNFeHRlbmRlZC5nZXRVVENIb3VycygpID09IDEwICYmIGlzRXh0ZW5kZWQuZ2V0VVRDTWludXRlcygpID09IDM3ICYmIGlzRXh0ZW5kZWQuZ2V0VVRDU2Vjb25kcygpID09IDYgJiYgaXNFeHRlbmRlZC5nZXRVVENNaWxsaXNlY29uZHMoKSA9PSA3MDg7CiAgICB9IGNhdGNoIChleGNlcHRpb24pIHt9CgogICAgLy8gSW50ZXJuYWw6IERldGVybWluZXMgd2hldGhlciB0aGUgbmF0aXZlIGBKU09OLnN0cmluZ2lmeWAgYW5kIGBwYXJzZWAKICAgIC8vIGltcGxlbWVudGF0aW9ucyBhcmUgc3BlYy1jb21wbGlhbnQuIEJhc2VkIG9uIHdvcmsgYnkgS2VuIFNueWRlci4KICAgIGZ1bmN0aW9uIGhhcyhuYW1lKSB7CiAgICAgIGlmIChoYXNbbmFtZV0gIT09IHVuZGVmKSB7CiAgICAgICAgLy8gUmV0dXJuIGNhY2hlZCBmZWF0dXJlIHRlc3QgcmVzdWx0LgogICAgICAgIHJldHVybiBoYXNbbmFtZV07CiAgICAgIH0KICAgICAgdmFyIGlzU3VwcG9ydGVkOwogICAgICBpZiAobmFtZSA9PSAiYnVnLXN0cmluZy1jaGFyLWluZGV4IikgewogICAgICAgIC8vIElFIDw9IDcgZG9lc24ndCBzdXBwb3J0IGFjY2Vzc2luZyBzdHJpbmcgY2hhcmFjdGVycyB1c2luZyBzcXVhcmUKICAgICAgICAvLyBicmFja2V0IG5vdGF0aW9uLiBJRSA4IG9ubHkgc3VwcG9ydHMgdGhpcyBmb3IgcHJpbWl0aXZlcy4KICAgICAgICBpc1N1cHBvcnRlZCA9ICJhIlswXSAhPSAiYSI7CiAgICAgIH0gZWxzZSBpZiAobmFtZSA9PSAianNvbiIpIHsKICAgICAgICAvLyBJbmRpY2F0ZXMgd2hldGhlciBib3RoIGBKU09OLnN0cmluZ2lmeWAgYW5kIGBKU09OLnBhcnNlYCBhcmUKICAgICAgICAvLyBzdXBwb3J0ZWQuCiAgICAgICAgaXNTdXBwb3J0ZWQgPSBoYXMoImpzb24tc3RyaW5naWZ5IikgJiYgaGFzKCJqc29uLXBhcnNlIik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdmFyIHZhbHVlLCBzZXJpYWxpemVkID0gJ3siYSI6WzEsdHJ1ZSxmYWxzZSxudWxsLCJcXHUwMDAwXFxiXFxuXFxmXFxyXFx0Il19JzsKICAgICAgICAvLyBUZXN0IGBKU09OLnN0cmluZ2lmeWAuCiAgICAgICAgaWYgKG5hbWUgPT0gImpzb24tc3RyaW5naWZ5IikgewogICAgICAgICAgdmFyIHN0cmluZ2lmeSA9IGV4cG9ydHMuc3RyaW5naWZ5LCBzdHJpbmdpZnlTdXBwb3J0ZWQgPSB0eXBlb2Ygc3RyaW5naWZ5ID09ICJmdW5jdGlvbiIgJiYgaXNFeHRlbmRlZDsKICAgICAgICAgIGlmIChzdHJpbmdpZnlTdXBwb3J0ZWQpIHsKICAgICAgICAgICAgLy8gQSB0ZXN0IGZ1bmN0aW9uIG9iamVjdCB3aXRoIGEgY3VzdG9tIGB0b0pTT05gIG1ldGhvZC4KICAgICAgICAgICAgKHZhbHVlID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICB9KS50b0pTT04gPSB2YWx1ZTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICBzdHJpbmdpZnlTdXBwb3J0ZWQgPQogICAgICAgICAgICAgICAgLy8gRmlyZWZveCAzLjFiMSBhbmQgYjIgc2VyaWFsaXplIHN0cmluZywgbnVtYmVyLCBhbmQgYm9vbGVhbgogICAgICAgICAgICAgICAgLy8gcHJpbWl0aXZlcyBhcyBvYmplY3QgbGl0ZXJhbHMuCiAgICAgICAgICAgICAgICBzdHJpbmdpZnkoMCkgPT09ICIwIiAmJgogICAgICAgICAgICAgICAgLy8gRkYgMy4xYjEsIGIyLCBhbmQgSlNPTiAyIHNlcmlhbGl6ZSB3cmFwcGVkIHByaW1pdGl2ZXMgYXMgb2JqZWN0CiAgICAgICAgICAgICAgICAvLyBsaXRlcmFscy4KICAgICAgICAgICAgICAgIHN0cmluZ2lmeShuZXcgTnVtYmVyKCkpID09PSAiMCIgJiYKICAgICAgICAgICAgICAgIHN0cmluZ2lmeShuZXcgU3RyaW5nKCkpID09ICciIicgJiYKICAgICAgICAgICAgICAgIC8vIEZGIDMuMWIxLCAyIHRocm93IGFuIGVycm9yIGlmIHRoZSB2YWx1ZSBpcyBgbnVsbGAsIGB1bmRlZmluZWRgLCBvcgogICAgICAgICAgICAgICAgLy8gZG9lcyBub3QgZGVmaW5lIGEgY2Fub25pY2FsIEpTT04gcmVwcmVzZW50YXRpb24gKHRoaXMgYXBwbGllcyB0bwogICAgICAgICAgICAgICAgLy8gb2JqZWN0cyB3aXRoIGB0b0pTT05gIHByb3BlcnRpZXMgYXMgd2VsbCwgKnVubGVzcyogdGhleSBhcmUgbmVzdGVkCiAgICAgICAgICAgICAgICAvLyB3aXRoaW4gYW4gb2JqZWN0IG9yIGFycmF5KS4KICAgICAgICAgICAgICAgIHN0cmluZ2lmeShnZXRDbGFzcykgPT09IHVuZGVmICYmCiAgICAgICAgICAgICAgICAvLyBJRSA4IHNlcmlhbGl6ZXMgYHVuZGVmaW5lZGAgYXMgYCJ1bmRlZmluZWQiYC4gU2FmYXJpIDw9IDUuMS43IGFuZAogICAgICAgICAgICAgICAgLy8gRkYgMy4xYjMgcGFzcyB0aGlzIHRlc3QuCiAgICAgICAgICAgICAgICBzdHJpbmdpZnkodW5kZWYpID09PSB1bmRlZiAmJgogICAgICAgICAgICAgICAgLy8gU2FmYXJpIDw9IDUuMS43IGFuZCBGRiAzLjFiMyB0aHJvdyBgRXJyb3JgcyBhbmQgYFR5cGVFcnJvcmBzLAogICAgICAgICAgICAgICAgLy8gcmVzcGVjdGl2ZWx5LCBpZiB0aGUgdmFsdWUgaXMgb21pdHRlZCBlbnRpcmVseS4KICAgICAgICAgICAgICAgIHN0cmluZ2lmeSgpID09PSB1bmRlZiAmJgogICAgICAgICAgICAgICAgLy8gRkYgMy4xYjEsIDIgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIGdpdmVuIHZhbHVlIGlzIG5vdCBhIG51bWJlciwKICAgICAgICAgICAgICAgIC8vIHN0cmluZywgYXJyYXksIG9iamVjdCwgQm9vbGVhbiwgb3IgYG51bGxgIGxpdGVyYWwuIFRoaXMgYXBwbGllcyB0bwogICAgICAgICAgICAgICAgLy8gb2JqZWN0cyB3aXRoIGN1c3RvbSBgdG9KU09OYCBtZXRob2RzIGFzIHdlbGwsIHVubGVzcyB0aGV5IGFyZSBuZXN0ZWQKICAgICAgICAgICAgICAgIC8vIGluc2lkZSBvYmplY3Qgb3IgYXJyYXkgbGl0ZXJhbHMuIFlVSSAzLjAuMGIxIGlnbm9yZXMgY3VzdG9tIGB0b0pTT05gCiAgICAgICAgICAgICAgICAvLyBtZXRob2RzIGVudGlyZWx5LgogICAgICAgICAgICAgICAgc3RyaW5naWZ5KHZhbHVlKSA9PT0gIjEiICYmCiAgICAgICAgICAgICAgICBzdHJpbmdpZnkoW3ZhbHVlXSkgPT0gIlsxXSIgJiYKICAgICAgICAgICAgICAgIC8vIFByb3RvdHlwZSA8PSAxLjYuMSBzZXJpYWxpemVzIGBbdW5kZWZpbmVkXWAgYXMgYCJbXSJgIGluc3RlYWQgb2YKICAgICAgICAgICAgICAgIC8vIGAiW251bGxdImAuCiAgICAgICAgICAgICAgICBzdHJpbmdpZnkoW3VuZGVmXSkgPT0gIltudWxsXSIgJiYKICAgICAgICAgICAgICAgIC8vIFlVSSAzLjAuMGIxIGZhaWxzIHRvIHNlcmlhbGl6ZSBgbnVsbGAgbGl0ZXJhbHMuCiAgICAgICAgICAgICAgICBzdHJpbmdpZnkobnVsbCkgPT0gIm51bGwiICYmCiAgICAgICAgICAgICAgICAvLyBGRiAzLjFiMSwgMiBoYWx0cyBzZXJpYWxpemF0aW9uIGlmIGFuIGFycmF5IGNvbnRhaW5zIGEgZnVuY3Rpb246CiAgICAgICAgICAgICAgICAvLyBgWzEsIHRydWUsIGdldENsYXNzLCAxXWAgc2VyaWFsaXplcyBhcyAiWzEsdHJ1ZSxdLCIuIEZGIDMuMWIzCiAgICAgICAgICAgICAgICAvLyBlbGlkZXMgbm9uLUpTT04gdmFsdWVzIGZyb20gb2JqZWN0cyBhbmQgYXJyYXlzLCB1bmxlc3MgdGhleQogICAgICAgICAgICAgICAgLy8gZGVmaW5lIGN1c3RvbSBgdG9KU09OYCBtZXRob2RzLgogICAgICAgICAgICAgICAgc3RyaW5naWZ5KFt1bmRlZiwgZ2V0Q2xhc3MsIG51bGxdKSA9PSAiW251bGwsbnVsbCxudWxsXSIgJiYKICAgICAgICAgICAgICAgIC8vIFNpbXBsZSBzZXJpYWxpemF0aW9uIHRlc3QuIEZGIDMuMWIxIHVzZXMgVW5pY29kZSBlc2NhcGUgc2VxdWVuY2VzCiAgICAgICAgICAgICAgICAvLyB3aGVyZSBjaGFyYWN0ZXIgZXNjYXBlIGNvZGVzIGFyZSBleHBlY3RlZCAoZS5nLiwgYFxiYCA9PiBgXHUwMDA4YCkuCiAgICAgICAgICAgICAgICBzdHJpbmdpZnkoeyAiYSI6IFt2YWx1ZSwgdHJ1ZSwgZmFsc2UsIG51bGwsICJceDAwXGJcblxmXHJcdCJdIH0pID09IHNlcmlhbGl6ZWQgJiYKICAgICAgICAgICAgICAgIC8vIEZGIDMuMWIxIGFuZCBiMiBpZ25vcmUgdGhlIGBmaWx0ZXJgIGFuZCBgd2lkdGhgIGFyZ3VtZW50cy4KICAgICAgICAgICAgICAgIHN0cmluZ2lmeShudWxsLCB2YWx1ZSkgPT09ICIxIiAmJgogICAgICAgICAgICAgICAgc3RyaW5naWZ5KFsxLCAyXSwgbnVsbCwgMSkgPT0gIltcbiAxLFxuIDJcbl0iICYmCiAgICAgICAgICAgICAgICAvLyBKU09OIDIsIFByb3RvdHlwZSA8PSAxLjcsIGFuZCBvbGRlciBXZWJLaXQgYnVpbGRzIGluY29ycmVjdGx5CiAgICAgICAgICAgICAgICAvLyBzZXJpYWxpemUgZXh0ZW5kZWQgeWVhcnMuCiAgICAgICAgICAgICAgICBzdHJpbmdpZnkobmV3IERhdGUoLTguNjRlMTUpKSA9PSAnIi0yNzE4MjEtMDQtMjBUMDA6MDA6MDAuMDAwWiInICYmCiAgICAgICAgICAgICAgICAvLyBUaGUgbWlsbGlzZWNvbmRzIGFyZSBvcHRpb25hbCBpbiBFUyA1LCBidXQgcmVxdWlyZWQgaW4gNS4xLgogICAgICAgICAgICAgICAgc3RyaW5naWZ5KG5ldyBEYXRlKDguNjRlMTUpKSA9PSAnIisyNzU3NjAtMDktMTNUMDA6MDA6MDAuMDAwWiInICYmCiAgICAgICAgICAgICAgICAvLyBGaXJlZm94IDw9IDExLjAgaW5jb3JyZWN0bHkgc2VyaWFsaXplcyB5ZWFycyBwcmlvciB0byAwIGFzIG5lZ2F0aXZlCiAgICAgICAgICAgICAgICAvLyBmb3VyLWRpZ2l0IHllYXJzIGluc3RlYWQgb2Ygc2l4LWRpZ2l0IHllYXJzLiBDcmVkaXRzOiBAWWFmZmxlLgogICAgICAgICAgICAgICAgc3RyaW5naWZ5KG5ldyBEYXRlKC02MjE5ODc1NTJlNSkpID09ICciLTAwMDAwMS0wMS0wMVQwMDowMDowMC4wMDBaIicgJiYKICAgICAgICAgICAgICAgIC8vIFNhZmFyaSA8PSA1LjEuNSBhbmQgT3BlcmEgPj0gMTAuNTMgaW5jb3JyZWN0bHkgc2VyaWFsaXplIG1pbGxpc2Vjb25kCiAgICAgICAgICAgICAgICAvLyB2YWx1ZXMgbGVzcyB0aGFuIDEwMDAuIENyZWRpdHM6IEBZYWZmbGUuCiAgICAgICAgICAgICAgICBzdHJpbmdpZnkobmV3IERhdGUoLTEpKSA9PSAnIjE5NjktMTItMzFUMjM6NTk6NTkuOTk5WiInOwogICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHsKICAgICAgICAgICAgICBzdHJpbmdpZnlTdXBwb3J0ZWQgPSBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgaXNTdXBwb3J0ZWQgPSBzdHJpbmdpZnlTdXBwb3J0ZWQ7CiAgICAgICAgfQogICAgICAgIC8vIFRlc3QgYEpTT04ucGFyc2VgLgogICAgICAgIGlmIChuYW1lID09ICJqc29uLXBhcnNlIikgewogICAgICAgICAgdmFyIHBhcnNlID0gZXhwb3J0cy5wYXJzZTsKICAgICAgICAgIGlmICh0eXBlb2YgcGFyc2UgPT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgIC8vIEZGIDMuMWIxLCBiMiB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbiBpZiBhIGJhcmUgbGl0ZXJhbCBpcyBwcm92aWRlZC4KICAgICAgICAgICAgICAvLyBDb25mb3JtaW5nIGltcGxlbWVudGF0aW9ucyBzaG91bGQgYWxzbyBjb2VyY2UgdGhlIGluaXRpYWwgYXJndW1lbnQgdG8KICAgICAgICAgICAgICAvLyBhIHN0cmluZyBwcmlvciB0byBwYXJzaW5nLgogICAgICAgICAgICAgIGlmIChwYXJzZSgiMCIpID09PSAwICYmICFwYXJzZShmYWxzZSkpIHsKICAgICAgICAgICAgICAgIC8vIFNpbXBsZSBwYXJzaW5nIHRlc3QuCiAgICAgICAgICAgICAgICB2YWx1ZSA9IHBhcnNlKHNlcmlhbGl6ZWQpOwogICAgICAgICAgICAgICAgdmFyIHBhcnNlU3VwcG9ydGVkID0gdmFsdWVbImEiXS5sZW5ndGggPT0gNSAmJiB2YWx1ZVsiYSJdWzBdID09PSAxOwogICAgICAgICAgICAgICAgaWYgKHBhcnNlU3VwcG9ydGVkKSB7CiAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIDw9IDUuMS4yIGFuZCBGRiAzLjFiMSBhbGxvdyB1bmVzY2FwZWQgdGFicyBpbiBzdHJpbmdzLgogICAgICAgICAgICAgICAgICAgIHBhcnNlU3VwcG9ydGVkID0gIXBhcnNlKCciXHQiJyk7CiAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge30KICAgICAgICAgICAgICAgICAgaWYgKHBhcnNlU3VwcG9ydGVkKSB7CiAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgIC8vIEZGIDQuMCBhbmQgNC4wLjEgYWxsb3cgbGVhZGluZyBgK2Agc2lnbnMgYW5kIGxlYWRpbmcKICAgICAgICAgICAgICAgICAgICAgIC8vIGRlY2ltYWwgcG9pbnRzLiBGRiA0LjAsIDQuMC4xLCBhbmQgSUUgOS0xMCBhbHNvIGFsbG93CiAgICAgICAgICAgICAgICAgICAgICAvLyBjZXJ0YWluIG9jdGFsIGxpdGVyYWxzLgogICAgICAgICAgICAgICAgICAgICAgcGFyc2VTdXBwb3J0ZWQgPSBwYXJzZSgiMDEiKSAhPT0gMTsKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHt9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgaWYgKHBhcnNlU3VwcG9ydGVkKSB7CiAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgIC8vIEZGIDQuMCwgNC4wLjEsIGFuZCBSaGlubyAxLjdSMy1SNCBhbGxvdyB0cmFpbGluZyBkZWNpbWFsCiAgICAgICAgICAgICAgICAgICAgICAvLyBwb2ludHMuIFRoZXNlIGVudmlyb25tZW50cywgYWxvbmcgd2l0aCBGRiAzLjFiMSBhbmQgMiwKICAgICAgICAgICAgICAgICAgICAgIC8vIGFsc28gYWxsb3cgdHJhaWxpbmcgY29tbWFzIGluIEpTT04gb2JqZWN0cyBhbmQgYXJyYXlzLgogICAgICAgICAgICAgICAgICAgICAgcGFyc2VTdXBwb3J0ZWQgPSBwYXJzZSgiMS4iKSAhPT0gMTsKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHt9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikgewogICAgICAgICAgICAgIHBhcnNlU3VwcG9ydGVkID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGlzU3VwcG9ydGVkID0gcGFyc2VTdXBwb3J0ZWQ7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiBoYXNbbmFtZV0gPSAhIWlzU3VwcG9ydGVkOwogICAgfQoKICAgIGlmICghaGFzKCJqc29uIikpIHsKICAgICAgLy8gQ29tbW9uIGBbW0NsYXNzXV1gIG5hbWUgYWxpYXNlcy4KICAgICAgdmFyIGZ1bmN0aW9uQ2xhc3MgPSAiW29iamVjdCBGdW5jdGlvbl0iLAogICAgICAgICAgZGF0ZUNsYXNzID0gIltvYmplY3QgRGF0ZV0iLAogICAgICAgICAgbnVtYmVyQ2xhc3MgPSAiW29iamVjdCBOdW1iZXJdIiwKICAgICAgICAgIHN0cmluZ0NsYXNzID0gIltvYmplY3QgU3RyaW5nXSIsCiAgICAgICAgICBhcnJheUNsYXNzID0gIltvYmplY3QgQXJyYXldIiwKICAgICAgICAgIGJvb2xlYW5DbGFzcyA9ICJbb2JqZWN0IEJvb2xlYW5dIjsKCiAgICAgIC8vIERldGVjdCBpbmNvbXBsZXRlIHN1cHBvcnQgZm9yIGFjY2Vzc2luZyBzdHJpbmcgY2hhcmFjdGVycyBieSBpbmRleC4KICAgICAgdmFyIGNoYXJJbmRleEJ1Z2d5ID0gaGFzKCJidWctc3RyaW5nLWNoYXItaW5kZXgiKTsKCiAgICAgIC8vIERlZmluZSBhZGRpdGlvbmFsIHV0aWxpdHkgbWV0aG9kcyBpZiB0aGUgYERhdGVgIG1ldGhvZHMgYXJlIGJ1Z2d5LgogICAgICBpZiAoIWlzRXh0ZW5kZWQpIHsKICAgICAgICB2YXIgZmxvb3IgPSBNYXRoLmZsb29yOwogICAgICAgIC8vIEEgbWFwcGluZyBiZXR3ZWVuIHRoZSBtb250aHMgb2YgdGhlIHllYXIgYW5kIHRoZSBudW1iZXIgb2YgZGF5cyBiZXR3ZWVuCiAgICAgICAgLy8gSmFudWFyeSAxc3QgYW5kIHRoZSBmaXJzdCBvZiB0aGUgcmVzcGVjdGl2ZSBtb250aC4KICAgICAgICB2YXIgTW9udGhzID0gWzAsIDMxLCA1OSwgOTAsIDEyMCwgMTUxLCAxODEsIDIxMiwgMjQzLCAyNzMsIDMwNCwgMzM0XTsKICAgICAgICAvLyBJbnRlcm5hbDogQ2FsY3VsYXRlcyB0aGUgbnVtYmVyIG9mIGRheXMgYmV0d2VlbiB0aGUgVW5peCBlcG9jaCBhbmQgdGhlCiAgICAgICAgLy8gZmlyc3QgZGF5IG9mIHRoZSBnaXZlbiBtb250aC4KICAgICAgICB2YXIgZ2V0RGF5ID0gZnVuY3Rpb24gKHllYXIsIG1vbnRoKSB7CiAgICAgICAgICByZXR1cm4gTW9udGhzW21vbnRoXSArIDM2NSAqICh5ZWFyIC0gMTk3MCkgKyBmbG9vcigoeWVhciAtIDE5NjkgKyAobW9udGggPSArKG1vbnRoID4gMSkpKSAvIDQpIC0gZmxvb3IoKHllYXIgLSAxOTAxICsgbW9udGgpIC8gMTAwKSArIGZsb29yKCh5ZWFyIC0gMTYwMSArIG1vbnRoKSAvIDQwMCk7CiAgICAgICAgfTsKICAgICAgfQoKICAgICAgLy8gSW50ZXJuYWw6IERldGVybWluZXMgaWYgYSBwcm9wZXJ0eSBpcyBhIGRpcmVjdCBwcm9wZXJ0eSBvZiB0aGUgZ2l2ZW4KICAgICAgLy8gb2JqZWN0LiBEZWxlZ2F0ZXMgdG8gdGhlIG5hdGl2ZSBgT2JqZWN0I2hhc093blByb3BlcnR5YCBtZXRob2QuCiAgICAgIGlmICghKGlzUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eSkpIHsKICAgICAgICBpc1Byb3BlcnR5ID0gZnVuY3Rpb24gKHByb3BlcnR5KSB7CiAgICAgICAgICB2YXIgbWVtYmVycyA9IHt9LCBjb25zdHJ1Y3RvcjsKICAgICAgICAgIGlmICgobWVtYmVycy5fX3Byb3RvX18gPSBudWxsLCBtZW1iZXJzLl9fcHJvdG9fXyA9IHsKICAgICAgICAgICAgLy8gVGhlICpwcm90byogcHJvcGVydHkgY2Fubm90IGJlIHNldCBtdWx0aXBsZSB0aW1lcyBpbiByZWNlbnQKICAgICAgICAgICAgLy8gdmVyc2lvbnMgb2YgRmlyZWZveCBhbmQgU2VhTW9ua2V5LgogICAgICAgICAgICAidG9TdHJpbmciOiAxCiAgICAgICAgICB9LCBtZW1iZXJzKS50b1N0cmluZyAhPSBnZXRDbGFzcykgewogICAgICAgICAgICAvLyBTYWZhcmkgPD0gMi4wLjMgZG9lc24ndCBpbXBsZW1lbnQgYE9iamVjdCNoYXNPd25Qcm9wZXJ0eWAsIGJ1dAogICAgICAgICAgICAvLyBzdXBwb3J0cyB0aGUgbXV0YWJsZSAqcHJvdG8qIHByb3BlcnR5LgogICAgICAgICAgICBpc1Byb3BlcnR5ID0gZnVuY3Rpb24gKHByb3BlcnR5KSB7CiAgICAgICAgICAgICAgLy8gQ2FwdHVyZSBhbmQgYnJlYWsgdGhlIG9iamVjdCdzIHByb3RvdHlwZSBjaGFpbiAoc2VlIHNlY3Rpb24gOC42LjIKICAgICAgICAgICAgICAvLyBvZiB0aGUgRVMgNS4xIHNwZWMpLiBUaGUgcGFyZW50aGVzaXplZCBleHByZXNzaW9uIHByZXZlbnRzIGFuCiAgICAgICAgICAgICAgLy8gdW5zYWZlIHRyYW5zZm9ybWF0aW9uIGJ5IHRoZSBDbG9zdXJlIENvbXBpbGVyLgogICAgICAgICAgICAgIHZhciBvcmlnaW5hbCA9IHRoaXMuX19wcm90b19fLCByZXN1bHQgPSBwcm9wZXJ0eSBpbiAodGhpcy5fX3Byb3RvX18gPSBudWxsLCB0aGlzKTsKICAgICAgICAgICAgICAvLyBSZXN0b3JlIHRoZSBvcmlnaW5hbCBwcm90b3R5cGUgY2hhaW4uCiAgICAgICAgICAgICAgdGhpcy5fX3Byb3RvX18gPSBvcmlnaW5hbDsKICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgICAgICB9OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gQ2FwdHVyZSBhIHJlZmVyZW5jZSB0byB0aGUgdG9wLWxldmVsIGBPYmplY3RgIGNvbnN0cnVjdG9yLgogICAgICAgICAgICBjb25zdHJ1Y3RvciA9IG1lbWJlcnMuY29uc3RydWN0b3I7CiAgICAgICAgICAgIC8vIFVzZSB0aGUgYGNvbnN0cnVjdG9yYCBwcm9wZXJ0eSB0byBzaW11bGF0ZSBgT2JqZWN0I2hhc093blByb3BlcnR5YCBpbgogICAgICAgICAgICAvLyBvdGhlciBlbnZpcm9ubWVudHMuCiAgICAgICAgICAgIGlzUHJvcGVydHkgPSBmdW5jdGlvbiAocHJvcGVydHkpIHsKICAgICAgICAgICAgICB2YXIgcGFyZW50ID0gKHRoaXMuY29uc3RydWN0b3IgfHwgY29uc3RydWN0b3IpLnByb3RvdHlwZTsKICAgICAgICAgICAgICByZXR1cm4gcHJvcGVydHkgaW4gdGhpcyAmJiAhKHByb3BlcnR5IGluIHBhcmVudCAmJiB0aGlzW3Byb3BlcnR5XSA9PT0gcGFyZW50W3Byb3BlcnR5XSk7CiAgICAgICAgICAgIH07CiAgICAgICAgICB9CiAgICAgICAgICBtZW1iZXJzID0gbnVsbDsKICAgICAgICAgIHJldHVybiBpc1Byb3BlcnR5LmNhbGwodGhpcywgcHJvcGVydHkpOwogICAgICAgIH07CiAgICAgIH0KCiAgICAgIC8vIEludGVybmFsOiBOb3JtYWxpemVzIHRoZSBgZm9yLi4uaW5gIGl0ZXJhdGlvbiBhbGdvcml0aG0gYWNyb3NzCiAgICAgIC8vIGVudmlyb25tZW50cy4gRWFjaCBlbnVtZXJhdGVkIGtleSBpcyB5aWVsZGVkIHRvIGEgYGNhbGxiYWNrYCBmdW5jdGlvbi4KICAgICAgZm9yRWFjaCA9IGZ1bmN0aW9uIChvYmplY3QsIGNhbGxiYWNrKSB7CiAgICAgICAgdmFyIHNpemUgPSAwLCBQcm9wZXJ0aWVzLCBtZW1iZXJzLCBwcm9wZXJ0eTsKCiAgICAgICAgLy8gVGVzdHMgZm9yIGJ1Z3MgaW4gdGhlIGN1cnJlbnQgZW52aXJvbm1lbnQncyBgZm9yLi4uaW5gIGFsZ29yaXRobS4gVGhlCiAgICAgICAgLy8gYHZhbHVlT2ZgIHByb3BlcnR5IGluaGVyaXRzIHRoZSBub24tZW51bWVyYWJsZSBmbGFnIGZyb20KICAgICAgICAvLyBgT2JqZWN0LnByb3RvdHlwZWAgaW4gb2xkZXIgdmVyc2lvbnMgb2YgSUUsIE5ldHNjYXBlLCBhbmQgTW96aWxsYS4KICAgICAgICAoUHJvcGVydGllcyA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgIHRoaXMudmFsdWVPZiA9IDA7CiAgICAgICAgfSkucHJvdG90eXBlLnZhbHVlT2YgPSAwOwoKICAgICAgICAvLyBJdGVyYXRlIG92ZXIgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIGBQcm9wZXJ0aWVzYCBjbGFzcy4KICAgICAgICBtZW1iZXJzID0gbmV3IFByb3BlcnRpZXMoKTsKICAgICAgICBmb3IgKHByb3BlcnR5IGluIG1lbWJlcnMpIHsKICAgICAgICAgIC8vIElnbm9yZSBhbGwgcHJvcGVydGllcyBpbmhlcml0ZWQgZnJvbSBgT2JqZWN0LnByb3RvdHlwZWAuCiAgICAgICAgICBpZiAoaXNQcm9wZXJ0eS5jYWxsKG1lbWJlcnMsIHByb3BlcnR5KSkgewogICAgICAgICAgICBzaXplKys7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIFByb3BlcnRpZXMgPSBtZW1iZXJzID0gbnVsbDsKCiAgICAgICAgLy8gTm9ybWFsaXplIHRoZSBpdGVyYXRpb24gYWxnb3JpdGhtLgogICAgICAgIGlmICghc2l6ZSkgewogICAgICAgICAgLy8gQSBsaXN0IG9mIG5vbi1lbnVtZXJhYmxlIHByb3BlcnRpZXMgaW5oZXJpdGVkIGZyb20gYE9iamVjdC5wcm90b3R5cGVgLgogICAgICAgICAgbWVtYmVycyA9IFsidmFsdWVPZiIsICJ0b1N0cmluZyIsICJ0b0xvY2FsZVN0cmluZyIsICJwcm9wZXJ0eUlzRW51bWVyYWJsZSIsICJpc1Byb3RvdHlwZU9mIiwgImhhc093blByb3BlcnR5IiwgImNvbnN0cnVjdG9yIl07CiAgICAgICAgICAvLyBJRSA8PSA4LCBNb3ppbGxhIDEuMCwgYW5kIE5ldHNjYXBlIDYuMiBpZ25vcmUgc2hhZG93ZWQgbm9uLWVudW1lcmFibGUKICAgICAgICAgIC8vIHByb3BlcnRpZXMuCiAgICAgICAgICBmb3JFYWNoID0gZnVuY3Rpb24gKG9iamVjdCwgY2FsbGJhY2spIHsKICAgICAgICAgICAgdmFyIGlzRnVuY3Rpb24gPSBnZXRDbGFzcy5jYWxsKG9iamVjdCkgPT0gZnVuY3Rpb25DbGFzcywgcHJvcGVydHksIGxlbmd0aDsKICAgICAgICAgICAgdmFyIGhhc1Byb3BlcnR5ID0gIWlzRnVuY3Rpb24gJiYgdHlwZW9mIG9iamVjdC5jb25zdHJ1Y3RvciAhPSAiZnVuY3Rpb24iICYmIG9iamVjdFR5cGVzW3R5cGVvZiBvYmplY3QuaGFzT3duUHJvcGVydHldICYmIG9iamVjdC5oYXNPd25Qcm9wZXJ0eSB8fCBpc1Byb3BlcnR5OwogICAgICAgICAgICBmb3IgKHByb3BlcnR5IGluIG9iamVjdCkgewogICAgICAgICAgICAgIC8vIEdlY2tvIDw9IDEuMCBlbnVtZXJhdGVzIHRoZSBgcHJvdG90eXBlYCBwcm9wZXJ0eSBvZiBmdW5jdGlvbnMgdW5kZXIKICAgICAgICAgICAgICAvLyBjZXJ0YWluIGNvbmRpdGlvbnM7IElFIGRvZXMgbm90LgogICAgICAgICAgICAgIGlmICghKGlzRnVuY3Rpb24gJiYgcHJvcGVydHkgPT0gInByb3RvdHlwZSIpICYmIGhhc1Byb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSkpIHsKICAgICAgICAgICAgICAgIGNhbGxiYWNrKHByb3BlcnR5KTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gTWFudWFsbHkgaW52b2tlIHRoZSBjYWxsYmFjayBmb3IgZWFjaCBub24tZW51bWVyYWJsZSBwcm9wZXJ0eS4KICAgICAgICAgICAgZm9yIChsZW5ndGggPSBtZW1iZXJzLmxlbmd0aDsgcHJvcGVydHkgPSBtZW1iZXJzWy0tbGVuZ3RoXTsgaGFzUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KSAmJiBjYWxsYmFjayhwcm9wZXJ0eSkpOwogICAgICAgICAgfTsKICAgICAgICB9IGVsc2UgaWYgKHNpemUgPT0gMikgewogICAgICAgICAgLy8gU2FmYXJpIDw9IDIuMC40IGVudW1lcmF0ZXMgc2hhZG93ZWQgcHJvcGVydGllcyB0d2ljZS4KICAgICAgICAgIGZvckVhY2ggPSBmdW5jdGlvbiAob2JqZWN0LCBjYWxsYmFjaykgewogICAgICAgICAgICAvLyBDcmVhdGUgYSBzZXQgb2YgaXRlcmF0ZWQgcHJvcGVydGllcy4KICAgICAgICAgICAgdmFyIG1lbWJlcnMgPSB7fSwgaXNGdW5jdGlvbiA9IGdldENsYXNzLmNhbGwob2JqZWN0KSA9PSBmdW5jdGlvbkNsYXNzLCBwcm9wZXJ0eTsKICAgICAgICAgICAgZm9yIChwcm9wZXJ0eSBpbiBvYmplY3QpIHsKICAgICAgICAgICAgICAvLyBTdG9yZSBlYWNoIHByb3BlcnR5IG5hbWUgdG8gcHJldmVudCBkb3VibGUgZW51bWVyYXRpb24uIFRoZQogICAgICAgICAgICAgIC8vIGBwcm90b3R5cGVgIHByb3BlcnR5IG9mIGZ1bmN0aW9ucyBpcyBub3QgZW51bWVyYXRlZCBkdWUgdG8gY3Jvc3MtCiAgICAgICAgICAgICAgLy8gZW52aXJvbm1lbnQgaW5jb25zaXN0ZW5jaWVzLgogICAgICAgICAgICAgIGlmICghKGlzRnVuY3Rpb24gJiYgcHJvcGVydHkgPT0gInByb3RvdHlwZSIpICYmICFpc1Byb3BlcnR5LmNhbGwobWVtYmVycywgcHJvcGVydHkpICYmIChtZW1iZXJzW3Byb3BlcnR5XSA9IDEpICYmIGlzUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KSkgewogICAgICAgICAgICAgICAgY2FsbGJhY2socHJvcGVydHkpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgLy8gTm8gYnVncyBkZXRlY3RlZDsgdXNlIHRoZSBzdGFuZGFyZCBgZm9yLi4uaW5gIGFsZ29yaXRobS4KICAgICAgICAgIGZvckVhY2ggPSBmdW5jdGlvbiAob2JqZWN0LCBjYWxsYmFjaykgewogICAgICAgICAgICB2YXIgaXNGdW5jdGlvbiA9IGdldENsYXNzLmNhbGwob2JqZWN0KSA9PSBmdW5jdGlvbkNsYXNzLCBwcm9wZXJ0eSwgaXNDb25zdHJ1Y3RvcjsKICAgICAgICAgICAgZm9yIChwcm9wZXJ0eSBpbiBvYmplY3QpIHsKICAgICAgICAgICAgICBpZiAoIShpc0Z1bmN0aW9uICYmIHByb3BlcnR5ID09ICJwcm90b3R5cGUiKSAmJiBpc1Byb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSkgJiYgIShpc0NvbnN0cnVjdG9yID0gcHJvcGVydHkgPT09ICJjb25zdHJ1Y3RvciIpKSB7CiAgICAgICAgICAgICAgICBjYWxsYmFjayhwcm9wZXJ0eSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIE1hbnVhbGx5IGludm9rZSB0aGUgY2FsbGJhY2sgZm9yIHRoZSBgY29uc3RydWN0b3JgIHByb3BlcnR5IGR1ZSB0bwogICAgICAgICAgICAvLyBjcm9zcy1lbnZpcm9ubWVudCBpbmNvbnNpc3RlbmNpZXMuCiAgICAgICAgICAgIGlmIChpc0NvbnN0cnVjdG9yIHx8IGlzUHJvcGVydHkuY2FsbChvYmplY3QsIChwcm9wZXJ0eSA9ICJjb25zdHJ1Y3RvciIpKSkgewogICAgICAgICAgICAgIGNhbGxiYWNrKHByb3BlcnR5KTsKICAgICAgICAgICAgfQogICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZvckVhY2gob2JqZWN0LCBjYWxsYmFjayk7CiAgICAgIH07CgogICAgICAvLyBQdWJsaWM6IFNlcmlhbGl6ZXMgYSBKYXZhU2NyaXB0IGB2YWx1ZWAgYXMgYSBKU09OIHN0cmluZy4gVGhlIG9wdGlvbmFsCiAgICAgIC8vIGBmaWx0ZXJgIGFyZ3VtZW50IG1heSBzcGVjaWZ5IGVpdGhlciBhIGZ1bmN0aW9uIHRoYXQgYWx0ZXJzIGhvdyBvYmplY3QgYW5kCiAgICAgIC8vIGFycmF5IG1lbWJlcnMgYXJlIHNlcmlhbGl6ZWQsIG9yIGFuIGFycmF5IG9mIHN0cmluZ3MgYW5kIG51bWJlcnMgdGhhdAogICAgICAvLyBpbmRpY2F0ZXMgd2hpY2ggcHJvcGVydGllcyBzaG91bGQgYmUgc2VyaWFsaXplZC4gVGhlIG9wdGlvbmFsIGB3aWR0aGAKICAgICAgLy8gYXJndW1lbnQgbWF5IGJlIGVpdGhlciBhIHN0cmluZyBvciBudW1iZXIgdGhhdCBzcGVjaWZpZXMgdGhlIGluZGVudGF0aW9uCiAgICAgIC8vIGxldmVsIG9mIHRoZSBvdXRwdXQuCiAgICAgIGlmICghaGFzKCJqc29uLXN0cmluZ2lmeSIpKSB7CiAgICAgICAgLy8gSW50ZXJuYWw6IEEgbWFwIG9mIGNvbnRyb2wgY2hhcmFjdGVycyBhbmQgdGhlaXIgZXNjYXBlZCBlcXVpdmFsZW50cy4KICAgICAgICB2YXIgRXNjYXBlcyA9IHsKICAgICAgICAgIDkyOiAiXFxcXCIsCiAgICAgICAgICAzNDogJ1xcIicsCiAgICAgICAgICA4OiAiXFxiIiwKICAgICAgICAgIDEyOiAiXFxmIiwKICAgICAgICAgIDEwOiAiXFxuIiwKICAgICAgICAgIDEzOiAiXFxyIiwKICAgICAgICAgIDk6ICJcXHQiCiAgICAgICAgfTsKCiAgICAgICAgLy8gSW50ZXJuYWw6IENvbnZlcnRzIGB2YWx1ZWAgaW50byBhIHplcm8tcGFkZGVkIHN0cmluZyBzdWNoIHRoYXQgaXRzCiAgICAgICAgLy8gbGVuZ3RoIGlzIGF0IGxlYXN0IGVxdWFsIHRvIGB3aWR0aGAuIFRoZSBgd2lkdGhgIG11c3QgYmUgPD0gNi4KICAgICAgICB2YXIgbGVhZGluZ1plcm9lcyA9ICIwMDAwMDAiOwogICAgICAgIHZhciB0b1BhZGRlZFN0cmluZyA9IGZ1bmN0aW9uICh3aWR0aCwgdmFsdWUpIHsKICAgICAgICAgIC8vIFRoZSBgfHwgMGAgZXhwcmVzc2lvbiBpcyBuZWNlc3NhcnkgdG8gd29yayBhcm91bmQgYSBidWcgaW4KICAgICAgICAgIC8vIE9wZXJhIDw9IDcuNTR1MiB3aGVyZSBgMCA9PSAtMGAsIGJ1dCBgU3RyaW5nKC0wKSAhPT0gIjAiYC4KICAgICAgICAgIHJldHVybiAobGVhZGluZ1plcm9lcyArICh2YWx1ZSB8fCAwKSkuc2xpY2UoLXdpZHRoKTsKICAgICAgICB9OwoKICAgICAgICAvLyBJbnRlcm5hbDogRG91YmxlLXF1b3RlcyBhIHN0cmluZyBgdmFsdWVgLCByZXBsYWNpbmcgYWxsIEFTQ0lJIGNvbnRyb2wKICAgICAgICAvLyBjaGFyYWN0ZXJzIChjaGFyYWN0ZXJzIHdpdGggY29kZSB1bml0IHZhbHVlcyBiZXR3ZWVuIDAgYW5kIDMxKSB3aXRoCiAgICAgICAgLy8gdGhlaXIgZXNjYXBlZCBlcXVpdmFsZW50cy4gVGhpcyBpcyBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUKICAgICAgICAvLyBgUXVvdGUodmFsdWUpYCBvcGVyYXRpb24gZGVmaW5lZCBpbiBFUyA1LjEgc2VjdGlvbiAxNS4xMi4zLgogICAgICAgIHZhciB1bmljb2RlUHJlZml4ID0gIlxcdTAwIjsKICAgICAgICB2YXIgcXVvdGUgPSBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgIHZhciByZXN1bHQgPSAnIicsIGluZGV4ID0gMCwgbGVuZ3RoID0gdmFsdWUubGVuZ3RoLCB1c2VDaGFySW5kZXggPSAhY2hhckluZGV4QnVnZ3kgfHwgbGVuZ3RoID4gMTA7CiAgICAgICAgICB2YXIgc3ltYm9scyA9IHVzZUNoYXJJbmRleCAmJiAoY2hhckluZGV4QnVnZ3kgPyB2YWx1ZS5zcGxpdCgiIikgOiB2YWx1ZSk7CiAgICAgICAgICBmb3IgKDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KyspIHsKICAgICAgICAgICAgdmFyIGNoYXJDb2RlID0gdmFsdWUuY2hhckNvZGVBdChpbmRleCk7CiAgICAgICAgICAgIC8vIElmIHRoZSBjaGFyYWN0ZXIgaXMgYSBjb250cm9sIGNoYXJhY3RlciwgYXBwZW5kIGl0cyBVbmljb2RlIG9yCiAgICAgICAgICAgIC8vIHNob3J0aGFuZCBlc2NhcGUgc2VxdWVuY2U7IG90aGVyd2lzZSwgYXBwZW5kIHRoZSBjaGFyYWN0ZXIgYXMtaXMuCiAgICAgICAgICAgIHN3aXRjaCAoY2hhckNvZGUpIHsKICAgICAgICAgICAgICBjYXNlIDg6IGNhc2UgOTogY2FzZSAxMDogY2FzZSAxMjogY2FzZSAxMzogY2FzZSAzNDogY2FzZSA5MjoKICAgICAgICAgICAgICAgIHJlc3VsdCArPSBFc2NhcGVzW2NoYXJDb2RlXTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBpZiAoY2hhckNvZGUgPCAzMikgewogICAgICAgICAgICAgICAgICByZXN1bHQgKz0gdW5pY29kZVByZWZpeCArIHRvUGFkZGVkU3RyaW5nKDIsIGNoYXJDb2RlLnRvU3RyaW5nKDE2KSk7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmVzdWx0ICs9IHVzZUNoYXJJbmRleCA/IHN5bWJvbHNbaW5kZXhdIDogdmFsdWUuY2hhckF0KGluZGV4KTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdCArICciJzsKICAgICAgICB9OwoKICAgICAgICAvLyBJbnRlcm5hbDogUmVjdXJzaXZlbHkgc2VyaWFsaXplcyBhbiBvYmplY3QuIEltcGxlbWVudHMgdGhlCiAgICAgICAgLy8gYFN0cihrZXksIGhvbGRlcilgLCBgSk8odmFsdWUpYCwgYW5kIGBKQSh2YWx1ZSlgIG9wZXJhdGlvbnMuCiAgICAgICAgdmFyIHNlcmlhbGl6ZSA9IGZ1bmN0aW9uIChwcm9wZXJ0eSwgb2JqZWN0LCBjYWxsYmFjaywgcHJvcGVydGllcywgd2hpdGVzcGFjZSwgaW5kZW50YXRpb24sIHN0YWNrKSB7CiAgICAgICAgICB2YXIgdmFsdWUsIGNsYXNzTmFtZSwgeWVhciwgbW9udGgsIGRhdGUsIHRpbWUsIGhvdXJzLCBtaW51dGVzLCBzZWNvbmRzLCBtaWxsaXNlY29uZHMsIHJlc3VsdHMsIGVsZW1lbnQsIGluZGV4LCBsZW5ndGgsIHByZWZpeCwgcmVzdWx0OwogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgLy8gTmVjZXNzYXJ5IGZvciBob3N0IG9iamVjdCBzdXBwb3J0LgogICAgICAgICAgICB2YWx1ZSA9IG9iamVjdFtwcm9wZXJ0eV07CiAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHt9CiAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09ICJvYmplY3QiICYmIHZhbHVlKSB7CiAgICAgICAgICAgIGNsYXNzTmFtZSA9IGdldENsYXNzLmNhbGwodmFsdWUpOwogICAgICAgICAgICBpZiAoY2xhc3NOYW1lID09IGRhdGVDbGFzcyAmJiAhaXNQcm9wZXJ0eS5jYWxsKHZhbHVlLCAidG9KU09OIikpIHsKICAgICAgICAgICAgICBpZiAodmFsdWUgPiAtMSAvIDAgJiYgdmFsdWUgPCAxIC8gMCkgewogICAgICAgICAgICAgICAgLy8gRGF0ZXMgYXJlIHNlcmlhbGl6ZWQgYWNjb3JkaW5nIHRvIHRoZSBgRGF0ZSN0b0pTT05gIG1ldGhvZAogICAgICAgICAgICAgICAgLy8gc3BlY2lmaWVkIGluIEVTIDUuMSBzZWN0aW9uIDE1LjkuNS40NC4gU2VlIHNlY3Rpb24gMTUuOS4xLjE1CiAgICAgICAgICAgICAgICAvLyBmb3IgdGhlIElTTyA4NjAxIGRhdGUgdGltZSBzdHJpbmcgZm9ybWF0LgogICAgICAgICAgICAgICAgaWYgKGdldERheSkgewogICAgICAgICAgICAgICAgICAvLyBNYW51YWxseSBjb21wdXRlIHRoZSB5ZWFyLCBtb250aCwgZGF0ZSwgaG91cnMsIG1pbnV0ZXMsCiAgICAgICAgICAgICAgICAgIC8vIHNlY29uZHMsIGFuZCBtaWxsaXNlY29uZHMgaWYgdGhlIGBnZXRVVEMqYCBtZXRob2RzIGFyZQogICAgICAgICAgICAgICAgICAvLyBidWdneS4gQWRhcHRlZCBmcm9tIEBZYWZmbGUncyBgZGF0ZS1zaGltYCBwcm9qZWN0LgogICAgICAgICAgICAgICAgICBkYXRlID0gZmxvb3IodmFsdWUgLyA4NjRlNSk7CiAgICAgICAgICAgICAgICAgIGZvciAoeWVhciA9IGZsb29yKGRhdGUgLyAzNjUuMjQyNSkgKyAxOTcwIC0gMTsgZ2V0RGF5KHllYXIgKyAxLCAwKSA8PSBkYXRlOyB5ZWFyKyspOwogICAgICAgICAgICAgICAgICBmb3IgKG1vbnRoID0gZmxvb3IoKGRhdGUgLSBnZXREYXkoeWVhciwgMCkpIC8gMzAuNDIpOyBnZXREYXkoeWVhciwgbW9udGggKyAxKSA8PSBkYXRlOyBtb250aCsrKTsKICAgICAgICAgICAgICAgICAgZGF0ZSA9IDEgKyBkYXRlIC0gZ2V0RGF5KHllYXIsIG1vbnRoKTsKICAgICAgICAgICAgICAgICAgLy8gVGhlIGB0aW1lYCB2YWx1ZSBzcGVjaWZpZXMgdGhlIHRpbWUgd2l0aGluIHRoZSBkYXkgKHNlZSBFUwogICAgICAgICAgICAgICAgICAvLyA1LjEgc2VjdGlvbiAxNS45LjEuMikuIFRoZSBmb3JtdWxhIGAoQSAlIEIgKyBCKSAlIEJgIGlzIHVzZWQKICAgICAgICAgICAgICAgICAgLy8gdG8gY29tcHV0ZSBgQSBtb2R1bG8gQmAsIGFzIHRoZSBgJWAgb3BlcmF0b3IgZG9lcyBub3QKICAgICAgICAgICAgICAgICAgLy8gY29ycmVzcG9uZCB0byB0aGUgYG1vZHVsb2Agb3BlcmF0aW9uIGZvciBuZWdhdGl2ZSBudW1iZXJzLgogICAgICAgICAgICAgICAgICB0aW1lID0gKHZhbHVlICUgODY0ZTUgKyA4NjRlNSkgJSA4NjRlNTsKICAgICAgICAgICAgICAgICAgLy8gVGhlIGhvdXJzLCBtaW51dGVzLCBzZWNvbmRzLCBhbmQgbWlsbGlzZWNvbmRzIGFyZSBvYnRhaW5lZCBieQogICAgICAgICAgICAgICAgICAvLyBkZWNvbXBvc2luZyB0aGUgdGltZSB3aXRoaW4gdGhlIGRheS4gU2VlIHNlY3Rpb24gMTUuOS4xLjEwLgogICAgICAgICAgICAgICAgICBob3VycyA9IGZsb29yKHRpbWUgLyAzNmU1KSAlIDI0OwogICAgICAgICAgICAgICAgICBtaW51dGVzID0gZmxvb3IodGltZSAvIDZlNCkgJSA2MDsKICAgICAgICAgICAgICAgICAgc2Vjb25kcyA9IGZsb29yKHRpbWUgLyAxZTMpICUgNjA7CiAgICAgICAgICAgICAgICAgIG1pbGxpc2Vjb25kcyA9IHRpbWUgJSAxZTM7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICB5ZWFyID0gdmFsdWUuZ2V0VVRDRnVsbFllYXIoKTsKICAgICAgICAgICAgICAgICAgbW9udGggPSB2YWx1ZS5nZXRVVENNb250aCgpOwogICAgICAgICAgICAgICAgICBkYXRlID0gdmFsdWUuZ2V0VVRDRGF0ZSgpOwogICAgICAgICAgICAgICAgICBob3VycyA9IHZhbHVlLmdldFVUQ0hvdXJzKCk7CiAgICAgICAgICAgICAgICAgIG1pbnV0ZXMgPSB2YWx1ZS5nZXRVVENNaW51dGVzKCk7CiAgICAgICAgICAgICAgICAgIHNlY29uZHMgPSB2YWx1ZS5nZXRVVENTZWNvbmRzKCk7CiAgICAgICAgICAgICAgICAgIG1pbGxpc2Vjb25kcyA9IHZhbHVlLmdldFVUQ01pbGxpc2Vjb25kcygpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gU2VyaWFsaXplIGV4dGVuZGVkIHllYXJzIGNvcnJlY3RseS4KICAgICAgICAgICAgICAgIHZhbHVlID0gKHllYXIgPD0gMCB8fCB5ZWFyID49IDFlNCA/ICh5ZWFyIDwgMCA/ICItIiA6ICIrIikgKyB0b1BhZGRlZFN0cmluZyg2LCB5ZWFyIDwgMCA/IC15ZWFyIDogeWVhcikgOiB0b1BhZGRlZFN0cmluZyg0LCB5ZWFyKSkgKwogICAgICAgICAgICAgICAgICAiLSIgKyB0b1BhZGRlZFN0cmluZygyLCBtb250aCArIDEpICsgIi0iICsgdG9QYWRkZWRTdHJpbmcoMiwgZGF0ZSkgKwogICAgICAgICAgICAgICAgICAvLyBNb250aHMsIGRhdGVzLCBob3VycywgbWludXRlcywgYW5kIHNlY29uZHMgc2hvdWxkIGhhdmUgdHdvCiAgICAgICAgICAgICAgICAgIC8vIGRpZ2l0czsgbWlsbGlzZWNvbmRzIHNob3VsZCBoYXZlIHRocmVlLgogICAgICAgICAgICAgICAgICAiVCIgKyB0b1BhZGRlZFN0cmluZygyLCBob3VycykgKyAiOiIgKyB0b1BhZGRlZFN0cmluZygyLCBtaW51dGVzKSArICI6IiArIHRvUGFkZGVkU3RyaW5nKDIsIHNlY29uZHMpICsKICAgICAgICAgICAgICAgICAgLy8gTWlsbGlzZWNvbmRzIGFyZSBvcHRpb25hbCBpbiBFUyA1LjAsIGJ1dCByZXF1aXJlZCBpbiA1LjEuCiAgICAgICAgICAgICAgICAgICIuIiArIHRvUGFkZGVkU3RyaW5nKDMsIG1pbGxpc2Vjb25kcykgKyAiWiI7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHZhbHVlID0gbnVsbDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlLnRvSlNPTiA9PSAiZnVuY3Rpb24iICYmICgoY2xhc3NOYW1lICE9IG51bWJlckNsYXNzICYmIGNsYXNzTmFtZSAhPSBzdHJpbmdDbGFzcyAmJiBjbGFzc05hbWUgIT0gYXJyYXlDbGFzcykgfHwgaXNQcm9wZXJ0eS5jYWxsKHZhbHVlLCAidG9KU09OIikpKSB7CiAgICAgICAgICAgICAgLy8gUHJvdG90eXBlIDw9IDEuNi4xIGFkZHMgbm9uLXN0YW5kYXJkIGB0b0pTT05gIG1ldGhvZHMgdG8gdGhlCiAgICAgICAgICAgICAgLy8gYE51bWJlcmAsIGBTdHJpbmdgLCBgRGF0ZWAsIGFuZCBgQXJyYXlgIHByb3RvdHlwZXMuIEpTT04gMwogICAgICAgICAgICAgIC8vIGlnbm9yZXMgYWxsIGB0b0pTT05gIG1ldGhvZHMgb24gdGhlc2Ugb2JqZWN0cyB1bmxlc3MgdGhleSBhcmUKICAgICAgICAgICAgICAvLyBkZWZpbmVkIGRpcmVjdGx5IG9uIGFuIGluc3RhbmNlLgogICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUudG9KU09OKHByb3BlcnR5KTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgaWYgKGNhbGxiYWNrKSB7CiAgICAgICAgICAgIC8vIElmIGEgcmVwbGFjZW1lbnQgZnVuY3Rpb24gd2FzIHByb3ZpZGVkLCBjYWxsIGl0IHRvIG9idGFpbiB0aGUgdmFsdWUKICAgICAgICAgICAgLy8gZm9yIHNlcmlhbGl6YXRpb24uCiAgICAgICAgICAgIHZhbHVlID0gY2FsbGJhY2suY2FsbChvYmplY3QsIHByb3BlcnR5LCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAodmFsdWUgPT09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuICJudWxsIjsKICAgICAgICAgIH0KICAgICAgICAgIGNsYXNzTmFtZSA9IGdldENsYXNzLmNhbGwodmFsdWUpOwogICAgICAgICAgaWYgKGNsYXNzTmFtZSA9PSBib29sZWFuQ2xhc3MpIHsKICAgICAgICAgICAgLy8gQm9vbGVhbnMgYXJlIHJlcHJlc2VudGVkIGxpdGVyYWxseS4KICAgICAgICAgICAgcmV0dXJuICIiICsgdmFsdWU7CiAgICAgICAgICB9IGVsc2UgaWYgKGNsYXNzTmFtZSA9PSBudW1iZXJDbGFzcykgewogICAgICAgICAgICAvLyBKU09OIG51bWJlcnMgbXVzdCBiZSBmaW5pdGUuIGBJbmZpbml0eWAgYW5kIGBOYU5gIGFyZSBzZXJpYWxpemVkIGFzCiAgICAgICAgICAgIC8vIGAibnVsbCJgLgogICAgICAgICAgICByZXR1cm4gdmFsdWUgPiAtMSAvIDAgJiYgdmFsdWUgPCAxIC8gMCA/ICIiICsgdmFsdWUgOiAibnVsbCI7CiAgICAgICAgICB9IGVsc2UgaWYgKGNsYXNzTmFtZSA9PSBzdHJpbmdDbGFzcykgewogICAgICAgICAgICAvLyBTdHJpbmdzIGFyZSBkb3VibGUtcXVvdGVkIGFuZCBlc2NhcGVkLgogICAgICAgICAgICByZXR1cm4gcXVvdGUoIiIgKyB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICAvLyBSZWN1cnNpdmVseSBzZXJpYWxpemUgb2JqZWN0cyBhbmQgYXJyYXlzLgogICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAib2JqZWN0IikgewogICAgICAgICAgICAvLyBDaGVjayBmb3IgY3ljbGljIHN0cnVjdHVyZXMuIFRoaXMgaXMgYSBsaW5lYXIgc2VhcmNoOyBwZXJmb3JtYW5jZQogICAgICAgICAgICAvLyBpcyBpbnZlcnNlbHkgcHJvcG9ydGlvbmFsIHRvIHRoZSBudW1iZXIgb2YgdW5pcXVlIG5lc3RlZCBvYmplY3RzLgogICAgICAgICAgICBmb3IgKGxlbmd0aCA9IHN0YWNrLmxlbmd0aDsgbGVuZ3RoLS07KSB7CiAgICAgICAgICAgICAgaWYgKHN0YWNrW2xlbmd0aF0gPT09IHZhbHVlKSB7CiAgICAgICAgICAgICAgICAvLyBDeWNsaWMgc3RydWN0dXJlcyBjYW5ub3QgYmUgc2VyaWFsaXplZCBieSBgSlNPTi5zdHJpbmdpZnlgLgogICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIEFkZCB0aGUgb2JqZWN0IHRvIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cy4KICAgICAgICAgICAgc3RhY2sucHVzaCh2YWx1ZSk7CiAgICAgICAgICAgIHJlc3VsdHMgPSBbXTsKICAgICAgICAgICAgLy8gU2F2ZSB0aGUgY3VycmVudCBpbmRlbnRhdGlvbiBsZXZlbCBhbmQgaW5kZW50IG9uZSBhZGRpdGlvbmFsIGxldmVsLgogICAgICAgICAgICBwcmVmaXggPSBpbmRlbnRhdGlvbjsKICAgICAgICAgICAgaW5kZW50YXRpb24gKz0gd2hpdGVzcGFjZTsKICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSA9PSBhcnJheUNsYXNzKSB7CiAgICAgICAgICAgICAgLy8gUmVjdXJzaXZlbHkgc2VyaWFsaXplIGFycmF5IGVsZW1lbnRzLgogICAgICAgICAgICAgIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSB2YWx1ZS5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7CiAgICAgICAgICAgICAgICBlbGVtZW50ID0gc2VyaWFsaXplKGluZGV4LCB2YWx1ZSwgY2FsbGJhY2ssIHByb3BlcnRpZXMsIHdoaXRlc3BhY2UsIGluZGVudGF0aW9uLCBzdGFjayk7CiAgICAgICAgICAgICAgICByZXN1bHRzLnB1c2goZWxlbWVudCA9PT0gdW5kZWYgPyAibnVsbCIgOiBlbGVtZW50KTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0cy5sZW5ndGggPyAod2hpdGVzcGFjZSA/ICJbXG4iICsgaW5kZW50YXRpb24gKyByZXN1bHRzLmpvaW4oIixcbiIgKyBpbmRlbnRhdGlvbikgKyAiXG4iICsgcHJlZml4ICsgIl0iIDogKCJbIiArIHJlc3VsdHMuam9pbigiLCIpICsgIl0iKSkgOiAiW10iOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIC8vIFJlY3Vyc2l2ZWx5IHNlcmlhbGl6ZSBvYmplY3QgbWVtYmVycy4gTWVtYmVycyBhcmUgc2VsZWN0ZWQgZnJvbQogICAgICAgICAgICAgIC8vIGVpdGhlciBhIHVzZXItc3BlY2lmaWVkIGxpc3Qgb2YgcHJvcGVydHkgbmFtZXMsIG9yIHRoZSBvYmplY3QKICAgICAgICAgICAgICAvLyBpdHNlbGYuCiAgICAgICAgICAgICAgZm9yRWFjaChwcm9wZXJ0aWVzIHx8IHZhbHVlLCBmdW5jdGlvbiAocHJvcGVydHkpIHsKICAgICAgICAgICAgICAgIHZhciBlbGVtZW50ID0gc2VyaWFsaXplKHByb3BlcnR5LCB2YWx1ZSwgY2FsbGJhY2ssIHByb3BlcnRpZXMsIHdoaXRlc3BhY2UsIGluZGVudGF0aW9uLCBzdGFjayk7CiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudCAhPT0gdW5kZWYpIHsKICAgICAgICAgICAgICAgICAgLy8gQWNjb3JkaW5nIHRvIEVTIDUuMSBzZWN0aW9uIDE1LjEyLjM6ICJJZiBgZ2FwYCB7d2hpdGVzcGFjZX0KICAgICAgICAgICAgICAgICAgLy8gaXMgbm90IHRoZSBlbXB0eSBzdHJpbmcsIGxldCBgbWVtYmVyYCB7cXVvdGUocHJvcGVydHkpICsgIjoifQogICAgICAgICAgICAgICAgICAvLyBiZSB0aGUgY29uY2F0ZW5hdGlvbiBvZiBgbWVtYmVyYCBhbmQgdGhlIGBzcGFjZWAgY2hhcmFjdGVyLiIKICAgICAgICAgICAgICAgICAgLy8gVGhlICJgc3BhY2VgIGNoYXJhY3RlciIgcmVmZXJzIHRvIHRoZSBsaXRlcmFsIHNwYWNlCiAgICAgICAgICAgICAgICAgIC8vIGNoYXJhY3Rlciwgbm90IHRoZSBgc3BhY2VgIHt3aWR0aH0gYXJndW1lbnQgcHJvdmlkZWQgdG8KICAgICAgICAgICAgICAgICAgLy8gYEpTT04uc3RyaW5naWZ5YC4KICAgICAgICAgICAgICAgICAgcmVzdWx0cy5wdXNoKHF1b3RlKHByb3BlcnR5KSArICI6IiArICh3aGl0ZXNwYWNlID8gIiAiIDogIiIpICsgZWxlbWVudCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0cy5sZW5ndGggPyAod2hpdGVzcGFjZSA/ICJ7XG4iICsgaW5kZW50YXRpb24gKyByZXN1bHRzLmpvaW4oIixcbiIgKyBpbmRlbnRhdGlvbikgKyAiXG4iICsgcHJlZml4ICsgIn0iIDogKCJ7IiArIHJlc3VsdHMuam9pbigiLCIpICsgIn0iKSkgOiAie30iOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgb2JqZWN0IGZyb20gdGhlIHRyYXZlcnNlZCBvYmplY3Qgc3RhY2suCiAgICAgICAgICAgIHN0YWNrLnBvcCgpOwogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgICAgfQogICAgICAgIH07CgogICAgICAgIC8vIFB1YmxpYzogYEpTT04uc3RyaW5naWZ5YC4gU2VlIEVTIDUuMSBzZWN0aW9uIDE1LjEyLjMuCiAgICAgICAgZXhwb3J0cy5zdHJpbmdpZnkgPSBmdW5jdGlvbiAoc291cmNlLCBmaWx0ZXIsIHdpZHRoKSB7CiAgICAgICAgICB2YXIgd2hpdGVzcGFjZSwgY2FsbGJhY2ssIHByb3BlcnRpZXMsIGNsYXNzTmFtZTsKICAgICAgICAgIGlmIChvYmplY3RUeXBlc1t0eXBlb2YgZmlsdGVyXSAmJiBmaWx0ZXIpIHsKICAgICAgICAgICAgaWYgKChjbGFzc05hbWUgPSBnZXRDbGFzcy5jYWxsKGZpbHRlcikpID09IGZ1bmN0aW9uQ2xhc3MpIHsKICAgICAgICAgICAgICBjYWxsYmFjayA9IGZpbHRlcjsKICAgICAgICAgICAgfSBlbHNlIGlmIChjbGFzc05hbWUgPT0gYXJyYXlDbGFzcykgewogICAgICAgICAgICAgIC8vIENvbnZlcnQgdGhlIHByb3BlcnR5IG5hbWVzIGFycmF5IGludG8gYSBtYWtlc2hpZnQgc2V0LgogICAgICAgICAgICAgIHByb3BlcnRpZXMgPSB7fTsKICAgICAgICAgICAgICBmb3IgKHZhciBpbmRleCA9IDAsIGxlbmd0aCA9IGZpbHRlci5sZW5ndGgsIHZhbHVlOyBpbmRleCA8IGxlbmd0aDsgdmFsdWUgPSBmaWx0ZXJbaW5kZXgrK10sICgoY2xhc3NOYW1lID0gZ2V0Q2xhc3MuY2FsbCh2YWx1ZSkpLCBjbGFzc05hbWUgPT0gc3RyaW5nQ2xhc3MgfHwgY2xhc3NOYW1lID09IG51bWJlckNsYXNzKSAmJiAocHJvcGVydGllc1t2YWx1ZV0gPSAxKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGlmICh3aWR0aCkgewogICAgICAgICAgICBpZiAoKGNsYXNzTmFtZSA9IGdldENsYXNzLmNhbGwod2lkdGgpKSA9PSBudW1iZXJDbGFzcykgewogICAgICAgICAgICAgIC8vIENvbnZlcnQgdGhlIGB3aWR0aGAgdG8gYW4gaW50ZWdlciBhbmQgY3JlYXRlIGEgc3RyaW5nIGNvbnRhaW5pbmcKICAgICAgICAgICAgICAvLyBgd2lkdGhgIG51bWJlciBvZiBzcGFjZSBjaGFyYWN0ZXJzLgogICAgICAgICAgICAgIGlmICgod2lkdGggLT0gd2lkdGggJSAxKSA+IDApIHsKICAgICAgICAgICAgICAgIGZvciAod2hpdGVzcGFjZSA9ICIiLCB3aWR0aCA+IDEwICYmICh3aWR0aCA9IDEwKTsgd2hpdGVzcGFjZS5sZW5ndGggPCB3aWR0aDsgd2hpdGVzcGFjZSArPSAiICIpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmIChjbGFzc05hbWUgPT0gc3RyaW5nQ2xhc3MpIHsKICAgICAgICAgICAgICB3aGl0ZXNwYWNlID0gd2lkdGgubGVuZ3RoIDw9IDEwID8gd2lkdGggOiB3aWR0aC5zbGljZSgwLCAxMCk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIC8vIE9wZXJhIDw9IDcuNTR1MiBkaXNjYXJkcyB0aGUgdmFsdWVzIGFzc29jaWF0ZWQgd2l0aCBlbXB0eSBzdHJpbmcga2V5cwogICAgICAgICAgLy8gKGAiImApIG9ubHkgaWYgdGhleSBhcmUgdXNlZCBkaXJlY3RseSB3aXRoaW4gYW4gb2JqZWN0IG1lbWJlciBsaXN0CiAgICAgICAgICAvLyAoZS5nLiwgYCEoIiIgaW4geyAiIjogMX0pYCkuCiAgICAgICAgICByZXR1cm4gc2VyaWFsaXplKCIiLCAodmFsdWUgPSB7fSwgdmFsdWVbIiJdID0gc291cmNlLCB2YWx1ZSksIGNhbGxiYWNrLCBwcm9wZXJ0aWVzLCB3aGl0ZXNwYWNlLCAiIiwgW10pOwogICAgICAgIH07CiAgICAgIH0KCiAgICAgIC8vIFB1YmxpYzogUGFyc2VzIGEgSlNPTiBzb3VyY2Ugc3RyaW5nLgogICAgICBpZiAoIWhhcygianNvbi1wYXJzZSIpKSB7CiAgICAgICAgdmFyIGZyb21DaGFyQ29kZSA9IFN0cmluZy5mcm9tQ2hhckNvZGU7CgogICAgICAgIC8vIEludGVybmFsOiBBIG1hcCBvZiBlc2NhcGVkIGNvbnRyb2wgY2hhcmFjdGVycyBhbmQgdGhlaXIgdW5lc2NhcGVkCiAgICAgICAgLy8gZXF1aXZhbGVudHMuCiAgICAgICAgdmFyIFVuZXNjYXBlcyA9IHsKICAgICAgICAgIDkyOiAiXFwiLAogICAgICAgICAgMzQ6ICciJywKICAgICAgICAgIDQ3OiAiLyIsCiAgICAgICAgICA5ODogIlxiIiwKICAgICAgICAgIDExNjogIlx0IiwKICAgICAgICAgIDExMDogIlxuIiwKICAgICAgICAgIDEwMjogIlxmIiwKICAgICAgICAgIDExNDogIlxyIgogICAgICAgIH07CgogICAgICAgIC8vIEludGVybmFsOiBTdG9yZXMgdGhlIHBhcnNlciBzdGF0ZS4KICAgICAgICB2YXIgSW5kZXgsIFNvdXJjZTsKCiAgICAgICAgLy8gSW50ZXJuYWw6IFJlc2V0cyB0aGUgcGFyc2VyIHN0YXRlIGFuZCB0aHJvd3MgYSBgU3ludGF4RXJyb3JgLgogICAgICAgIHZhciBhYm9ydCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgIEluZGV4ID0gU291cmNlID0gbnVsbDsKICAgICAgICAgIHRocm93IFN5bnRheEVycm9yKCk7CiAgICAgICAgfTsKCiAgICAgICAgLy8gSW50ZXJuYWw6IFJldHVybnMgdGhlIG5leHQgdG9rZW4sIG9yIGAiJCJgIGlmIHRoZSBwYXJzZXIgaGFzIHJlYWNoZWQKICAgICAgICAvLyB0aGUgZW5kIG9mIHRoZSBzb3VyY2Ugc3RyaW5nLiBBIHRva2VuIG1heSBiZSBhIHN0cmluZywgbnVtYmVyLCBgbnVsbGAKICAgICAgICAvLyBsaXRlcmFsLCBvciBCb29sZWFuIGxpdGVyYWwuCiAgICAgICAgdmFyIGxleCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgIHZhciBzb3VyY2UgPSBTb3VyY2UsIGxlbmd0aCA9IHNvdXJjZS5sZW5ndGgsIHZhbHVlLCBiZWdpbiwgcG9zaXRpb24sIGlzU2lnbmVkLCBjaGFyQ29kZTsKICAgICAgICAgIHdoaWxlIChJbmRleCA8IGxlbmd0aCkgewogICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4KTsKICAgICAgICAgICAgc3dpdGNoIChjaGFyQ29kZSkgewogICAgICAgICAgICAgIGNhc2UgOTogY2FzZSAxMDogY2FzZSAxMzogY2FzZSAzMjoKICAgICAgICAgICAgICAgIC8vIFNraXAgd2hpdGVzcGFjZSB0b2tlbnMsIGluY2x1ZGluZyB0YWJzLCBjYXJyaWFnZSByZXR1cm5zLCBsaW5lCiAgICAgICAgICAgICAgICAvLyBmZWVkcywgYW5kIHNwYWNlIGNoYXJhY3RlcnMuCiAgICAgICAgICAgICAgICBJbmRleCsrOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMjM6IGNhc2UgMTI1OiBjYXNlIDkxOiBjYXNlIDkzOiBjYXNlIDU4OiBjYXNlIDQ0OgogICAgICAgICAgICAgICAgLy8gUGFyc2UgYSBwdW5jdHVhdG9yIHRva2VuIChge2AsIGB9YCwgYFtgLCBgXWAsIGA6YCwgb3IgYCxgKSBhdAogICAgICAgICAgICAgICAgLy8gdGhlIGN1cnJlbnQgcG9zaXRpb24uCiAgICAgICAgICAgICAgICB2YWx1ZSA9IGNoYXJJbmRleEJ1Z2d5ID8gc291cmNlLmNoYXJBdChJbmRleCkgOiBzb3VyY2VbSW5kZXhdOwogICAgICAgICAgICAgICAgSW5kZXgrKzsKICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgICAgICAgICBjYXNlIDM0OgogICAgICAgICAgICAgICAgLy8gYCJgIGRlbGltaXRzIGEgSlNPTiBzdHJpbmc7IGFkdmFuY2UgdG8gdGhlIG5leHQgY2hhcmFjdGVyIGFuZAogICAgICAgICAgICAgICAgLy8gYmVnaW4gcGFyc2luZyB0aGUgc3RyaW5nLiBTdHJpbmcgdG9rZW5zIGFyZSBwcmVmaXhlZCB3aXRoIHRoZQogICAgICAgICAgICAgICAgLy8gc2VudGluZWwgYEBgIGNoYXJhY3RlciB0byBkaXN0aW5ndWlzaCB0aGVtIGZyb20gcHVuY3R1YXRvcnMgYW5kCiAgICAgICAgICAgICAgICAvLyBlbmQtb2Ytc3RyaW5nIHRva2Vucy4KICAgICAgICAgICAgICAgIGZvciAodmFsdWUgPSAiQCIsIEluZGV4Kys7IEluZGV4IDwgbGVuZ3RoOykgewogICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4KTsKICAgICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlIDwgMzIpIHsKICAgICAgICAgICAgICAgICAgICAvLyBVbmVzY2FwZWQgQVNDSUkgY29udHJvbCBjaGFyYWN0ZXJzICh0aG9zZSB3aXRoIGEgY29kZSB1bml0CiAgICAgICAgICAgICAgICAgICAgLy8gbGVzcyB0aGFuIHRoZSBzcGFjZSBjaGFyYWN0ZXIpIGFyZSBub3QgcGVybWl0dGVkLgogICAgICAgICAgICAgICAgICAgIGFib3J0KCk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hhckNvZGUgPT0gOTIpIHsKICAgICAgICAgICAgICAgICAgICAvLyBBIHJldmVyc2Ugc29saWR1cyAoYFxgKSBtYXJrcyB0aGUgYmVnaW5uaW5nIG9mIGFuIGVzY2FwZWQKICAgICAgICAgICAgICAgICAgICAvLyBjb250cm9sIGNoYXJhY3RlciAoaW5jbHVkaW5nIGAiYCwgYFxgLCBhbmQgYC9gKSBvciBVbmljb2RlCiAgICAgICAgICAgICAgICAgICAgLy8gZXNjYXBlIHNlcXVlbmNlLgogICAgICAgICAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoKytJbmRleCk7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChjaGFyQ29kZSkgewogICAgICAgICAgICAgICAgICAgICAgY2FzZSA5MjogY2FzZSAzNDogY2FzZSA0NzogY2FzZSA5ODogY2FzZSAxMTY6IGNhc2UgMTEwOiBjYXNlIDEwMjogY2FzZSAxMTQ6CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJldml2ZSBlc2NhcGVkIGNvbnRyb2wgY2hhcmFjdGVycy4KICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgKz0gVW5lc2NhcGVzW2NoYXJDb2RlXTsKICAgICAgICAgICAgICAgICAgICAgICAgSW5kZXgrKzsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICBjYXNlIDExNzoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gYFx1YCBtYXJrcyB0aGUgYmVnaW5uaW5nIG9mIGEgVW5pY29kZSBlc2NhcGUgc2VxdWVuY2UuCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFkdmFuY2UgdG8gdGhlIGZpcnN0IGNoYXJhY3RlciBhbmQgdmFsaWRhdGUgdGhlCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvdXItZGlnaXQgY29kZSBwb2ludC4KICAgICAgICAgICAgICAgICAgICAgICAgYmVnaW4gPSArK0luZGV4OwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHBvc2l0aW9uID0gSW5kZXggKyA0OyBJbmRleCA8IHBvc2l0aW9uOyBJbmRleCsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdChJbmRleCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQSB2YWxpZCBzZXF1ZW5jZSBjb21wcmlzZXMgZm91ciBoZXhkaWdpdHMgKGNhc2UtCiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW5zZW5zaXRpdmUpIHRoYXQgZm9ybSBhIHNpbmdsZSBoZXhhZGVjaW1hbCB2YWx1ZS4KICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIShjaGFyQ29kZSA+PSA0OCAmJiBjaGFyQ29kZSA8PSA1NyB8fCBjaGFyQ29kZSA+PSA5NyAmJiBjaGFyQ29kZSA8PSAxMDIgfHwgY2hhckNvZGUgPj0gNjUgJiYgY2hhckNvZGUgPD0gNzApKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbnZhbGlkIFVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmV2aXZlIHRoZSBlc2NhcGVkIGNoYXJhY3Rlci4KICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgKz0gZnJvbUNoYXJDb2RlKCIweCIgKyBzb3VyY2Uuc2xpY2UoYmVnaW4sIEluZGV4KSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW52YWxpZCBlc2NhcGUgc2VxdWVuY2UuCiAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0KCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA9PSAzNCkgewogICAgICAgICAgICAgICAgICAgICAgLy8gQW4gdW5lc2NhcGVkIGRvdWJsZS1xdW90ZSBjaGFyYWN0ZXIgbWFya3MgdGhlIGVuZCBvZiB0aGUKICAgICAgICAgICAgICAgICAgICAgIC8vIHN0cmluZy4KICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4KTsKICAgICAgICAgICAgICAgICAgICBiZWdpbiA9IEluZGV4OwogICAgICAgICAgICAgICAgICAgIC8vIE9wdGltaXplIGZvciB0aGUgY29tbW9uIGNhc2Ugd2hlcmUgYSBzdHJpbmcgaXMgdmFsaWQuCiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGNoYXJDb2RlID49IDMyICYmIGNoYXJDb2RlICE9IDkyICYmIGNoYXJDb2RlICE9IDM0KSB7CiAgICAgICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KCsrSW5kZXgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvLyBBcHBlbmQgdGhlIHN0cmluZyBhcy1pcy4KICAgICAgICAgICAgICAgICAgICB2YWx1ZSArPSBzb3VyY2Uuc2xpY2UoYmVnaW4sIEluZGV4KTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4KSA9PSAzNCkgewogICAgICAgICAgICAgICAgICAvLyBBZHZhbmNlIHRvIHRoZSBuZXh0IGNoYXJhY3RlciBhbmQgcmV0dXJuIHRoZSByZXZpdmVkIHN0cmluZy4KICAgICAgICAgICAgICAgICAgSW5kZXgrKzsKICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gVW50ZXJtaW5hdGVkIHN0cmluZy4KICAgICAgICAgICAgICAgIGFib3J0KCk7CiAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIC8vIFBhcnNlIG51bWJlcnMgYW5kIGxpdGVyYWxzLgogICAgICAgICAgICAgICAgYmVnaW4gPSBJbmRleDsKICAgICAgICAgICAgICAgIC8vIEFkdmFuY2UgcGFzdCB0aGUgbmVnYXRpdmUgc2lnbiwgaWYgb25lIGlzIHNwZWNpZmllZC4KICAgICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA9PSA0NSkgewogICAgICAgICAgICAgICAgICBpc1NpZ25lZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoKytJbmRleCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBQYXJzZSBhbiBpbnRlZ2VyIG9yIGZsb2F0aW5nLXBvaW50IHZhbHVlLgogICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlID49IDQ4ICYmIGNoYXJDb2RlIDw9IDU3KSB7CiAgICAgICAgICAgICAgICAgIC8vIExlYWRpbmcgemVyb2VzIGFyZSBpbnRlcnByZXRlZCBhcyBvY3RhbCBsaXRlcmFscy4KICAgICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlID09IDQ4ICYmICgoY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdChJbmRleCArIDEpKSwgY2hhckNvZGUgPj0gNDggJiYgY2hhckNvZGUgPD0gNTcpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gSWxsZWdhbCBvY3RhbCBsaXRlcmFsLgogICAgICAgICAgICAgICAgICAgIGFib3J0KCk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgaXNTaWduZWQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgLy8gUGFyc2UgdGhlIGludGVnZXIgY29tcG9uZW50LgogICAgICAgICAgICAgICAgICBmb3IgKDsgSW5kZXggPCBsZW5ndGggJiYgKChjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4KSksIGNoYXJDb2RlID49IDQ4ICYmIGNoYXJDb2RlIDw9IDU3KTsgSW5kZXgrKyk7CiAgICAgICAgICAgICAgICAgIC8vIEZsb2F0cyBjYW5ub3QgY29udGFpbiBhIGxlYWRpbmcgZGVjaW1hbCBwb2ludDsgaG93ZXZlciwgdGhpcwogICAgICAgICAgICAgICAgICAvLyBjYXNlIGlzIGFscmVhZHkgYWNjb3VudGVkIGZvciBieSB0aGUgcGFyc2VyLgogICAgICAgICAgICAgICAgICBpZiAoc291cmNlLmNoYXJDb2RlQXQoSW5kZXgpID09IDQ2KSB7CiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSArK0luZGV4OwogICAgICAgICAgICAgICAgICAgIC8vIFBhcnNlIHRoZSBkZWNpbWFsIGNvbXBvbmVudC4KICAgICAgICAgICAgICAgICAgICBmb3IgKDsgcG9zaXRpb24gPCBsZW5ndGggJiYgKChjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KHBvc2l0aW9uKSksIGNoYXJDb2RlID49IDQ4ICYmIGNoYXJDb2RlIDw9IDU3KTsgcG9zaXRpb24rKyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uID09IEluZGV4KSB7CiAgICAgICAgICAgICAgICAgICAgICAvLyBJbGxlZ2FsIHRyYWlsaW5nIGRlY2ltYWwuCiAgICAgICAgICAgICAgICAgICAgICBhYm9ydCgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBJbmRleCA9IHBvc2l0aW9uOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIFBhcnNlIGV4cG9uZW50cy4gVGhlIGBlYCBkZW5vdGluZyB0aGUgZXhwb25lbnQgaXMKICAgICAgICAgICAgICAgICAgLy8gY2FzZS1pbnNlbnNpdGl2ZS4KICAgICAgICAgICAgICAgICAgY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdChJbmRleCk7CiAgICAgICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA9PSAxMDEgfHwgY2hhckNvZGUgPT0gNjkpIHsKICAgICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KCsrSW5kZXgpOwogICAgICAgICAgICAgICAgICAgIC8vIFNraXAgcGFzdCB0aGUgc2lnbiBmb2xsb3dpbmcgdGhlIGV4cG9uZW50LCBpZiBvbmUgaXMKICAgICAgICAgICAgICAgICAgICAvLyBzcGVjaWZpZWQuCiAgICAgICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlID09IDQzIHx8IGNoYXJDb2RlID09IDQ1KSB7CiAgICAgICAgICAgICAgICAgICAgICBJbmRleCsrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvLyBQYXJzZSB0aGUgZXhwb25lbnRpYWwgY29tcG9uZW50LgogICAgICAgICAgICAgICAgICAgIGZvciAocG9zaXRpb24gPSBJbmRleDsgcG9zaXRpb24gPCBsZW5ndGggJiYgKChjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KHBvc2l0aW9uKSksIGNoYXJDb2RlID49IDQ4ICYmIGNoYXJDb2RlIDw9IDU3KTsgcG9zaXRpb24rKyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uID09IEluZGV4KSB7CiAgICAgICAgICAgICAgICAgICAgICAvLyBJbGxlZ2FsIGVtcHR5IGV4cG9uZW50LgogICAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgSW5kZXggPSBwb3NpdGlvbjsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyBDb2VyY2UgdGhlIHBhcnNlZCB2YWx1ZSB0byBhIEphdmFTY3JpcHQgbnVtYmVyLgogICAgICAgICAgICAgICAgICByZXR1cm4gK3NvdXJjZS5zbGljZShiZWdpbiwgSW5kZXgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gQSBuZWdhdGl2ZSBzaWduIG1heSBvbmx5IHByZWNlZGUgbnVtYmVycy4KICAgICAgICAgICAgICAgIGlmIChpc1NpZ25lZCkgewogICAgICAgICAgICAgICAgICBhYm9ydCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gYHRydWVgLCBgZmFsc2VgLCBhbmQgYG51bGxgIGxpdGVyYWxzLgogICAgICAgICAgICAgICAgaWYgKHNvdXJjZS5zbGljZShJbmRleCwgSW5kZXggKyA0KSA9PSAidHJ1ZSIpIHsKICAgICAgICAgICAgICAgICAgSW5kZXggKz0gNDsKICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNvdXJjZS5zbGljZShJbmRleCwgSW5kZXggKyA1KSA9PSAiZmFsc2UiKSB7CiAgICAgICAgICAgICAgICAgIEluZGV4ICs9IDU7CiAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc291cmNlLnNsaWNlKEluZGV4LCBJbmRleCArIDQpID09ICJudWxsIikgewogICAgICAgICAgICAgICAgICBJbmRleCArPSA0OwogICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIFVucmVjb2duaXplZCB0b2tlbi4KICAgICAgICAgICAgICAgIGFib3J0KCk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIC8vIFJldHVybiB0aGUgc2VudGluZWwgYCRgIGNoYXJhY3RlciBpZiB0aGUgcGFyc2VyIGhhcyByZWFjaGVkIHRoZSBlbmQKICAgICAgICAgIC8vIG9mIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAgICAgICAgcmV0dXJuICIkIjsKICAgICAgICB9OwoKICAgICAgICAvLyBJbnRlcm5hbDogUGFyc2VzIGEgSlNPTiBgdmFsdWVgIHRva2VuLgogICAgICAgIHZhciBnZXQgPSBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgIHZhciByZXN1bHRzLCBoYXNNZW1iZXJzOwogICAgICAgICAgaWYgKHZhbHVlID09ICIkIikgewogICAgICAgICAgICAvLyBVbmV4cGVjdGVkIGVuZCBvZiBpbnB1dC4KICAgICAgICAgICAgYWJvcnQoKTsKICAgICAgICAgIH0KICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gInN0cmluZyIpIHsKICAgICAgICAgICAgaWYgKChjaGFySW5kZXhCdWdneSA/IHZhbHVlLmNoYXJBdCgwKSA6IHZhbHVlWzBdKSA9PSAiQCIpIHsKICAgICAgICAgICAgICAvLyBSZW1vdmUgdGhlIHNlbnRpbmVsIGBAYCBjaGFyYWN0ZXIuCiAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLnNsaWNlKDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIFBhcnNlIG9iamVjdCBhbmQgYXJyYXkgbGl0ZXJhbHMuCiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSAiWyIpIHsKICAgICAgICAgICAgICAvLyBQYXJzZXMgYSBKU09OIGFycmF5LCByZXR1cm5pbmcgYSBuZXcgSmF2YVNjcmlwdCBhcnJheS4KICAgICAgICAgICAgICByZXN1bHRzID0gW107CiAgICAgICAgICAgICAgZm9yICg7OyBoYXNNZW1iZXJzIHx8IChoYXNNZW1iZXJzID0gdHJ1ZSkpIHsKICAgICAgICAgICAgICAgIHZhbHVlID0gbGV4KCk7CiAgICAgICAgICAgICAgICAvLyBBIGNsb3Npbmcgc3F1YXJlIGJyYWNrZXQgbWFya3MgdGhlIGVuZCBvZiB0aGUgYXJyYXkgbGl0ZXJhbC4KICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSAiXSIpIHsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgYXJyYXkgbGl0ZXJhbCBjb250YWlucyBlbGVtZW50cywgdGhlIGN1cnJlbnQgdG9rZW4KICAgICAgICAgICAgICAgIC8vIHNob3VsZCBiZSBhIGNvbW1hIHNlcGFyYXRpbmcgdGhlIHByZXZpb3VzIGVsZW1lbnQgZnJvbSB0aGUKICAgICAgICAgICAgICAgIC8vIG5leHQuCiAgICAgICAgICAgICAgICBpZiAoaGFzTWVtYmVycykgewogICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gIiwiKSB7CiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBsZXgoKTsKICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gIl0iKSB7CiAgICAgICAgICAgICAgICAgICAgICAvLyBVbmV4cGVjdGVkIHRyYWlsaW5nIGAsYCBpbiBhcnJheSBsaXRlcmFsLgogICAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy8gQSBgLGAgbXVzdCBzZXBhcmF0ZSBlYWNoIGFycmF5IGVsZW1lbnQuCiAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gRWxpc2lvbnMgYW5kIGxlYWRpbmcgY29tbWFzIGFyZSBub3QgcGVybWl0dGVkLgogICAgICAgICAgICAgICAgaWYgKHZhbHVlID09ICIsIikgewogICAgICAgICAgICAgICAgICBhYm9ydCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmVzdWx0cy5wdXNoKGdldCh2YWx1ZSkpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0czsKICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSA9PSAieyIpIHsKICAgICAgICAgICAgICAvLyBQYXJzZXMgYSBKU09OIG9iamVjdCwgcmV0dXJuaW5nIGEgbmV3IEphdmFTY3JpcHQgb2JqZWN0LgogICAgICAgICAgICAgIHJlc3VsdHMgPSB7fTsKICAgICAgICAgICAgICBmb3IgKDs7IGhhc01lbWJlcnMgfHwgKGhhc01lbWJlcnMgPSB0cnVlKSkgewogICAgICAgICAgICAgICAgdmFsdWUgPSBsZXgoKTsKICAgICAgICAgICAgICAgIC8vIEEgY2xvc2luZyBjdXJseSBicmFjZSBtYXJrcyB0aGUgZW5kIG9mIHRoZSBvYmplY3QgbGl0ZXJhbC4KICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSAifSIpIHsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgb2JqZWN0IGxpdGVyYWwgY29udGFpbnMgbWVtYmVycywgdGhlIGN1cnJlbnQgdG9rZW4KICAgICAgICAgICAgICAgIC8vIHNob3VsZCBiZSBhIGNvbW1hIHNlcGFyYXRvci4KICAgICAgICAgICAgICAgIGlmIChoYXNNZW1iZXJzKSB7CiAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSAiLCIpIHsKICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGxleCgpOwogICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSAifSIpIHsKICAgICAgICAgICAgICAgICAgICAgIC8vIFVuZXhwZWN0ZWQgdHJhaWxpbmcgYCxgIGluIG9iamVjdCBsaXRlcmFsLgogICAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy8gQSBgLGAgbXVzdCBzZXBhcmF0ZSBlYWNoIG9iamVjdCBtZW1iZXIuCiAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gTGVhZGluZyBjb21tYXMgYXJlIG5vdCBwZXJtaXR0ZWQsIG9iamVjdCBwcm9wZXJ0eSBuYW1lcyBtdXN0IGJlCiAgICAgICAgICAgICAgICAvLyBkb3VibGUtcXVvdGVkIHN0cmluZ3MsIGFuZCBhIGA6YCBtdXN0IHNlcGFyYXRlIGVhY2ggcHJvcGVydHkKICAgICAgICAgICAgICAgIC8vIG5hbWUgYW5kIHZhbHVlLgogICAgICAgICAgICAgICAgaWYgKHZhbHVlID09ICIsIiB8fCB0eXBlb2YgdmFsdWUgIT0gInN0cmluZyIgfHwgKGNoYXJJbmRleEJ1Z2d5ID8gdmFsdWUuY2hhckF0KDApIDogdmFsdWVbMF0pICE9ICJAIiB8fCBsZXgoKSAhPSAiOiIpIHsKICAgICAgICAgICAgICAgICAgYWJvcnQoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJlc3VsdHNbdmFsdWUuc2xpY2UoMSldID0gZ2V0KGxleCgpKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdHM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gVW5leHBlY3RlZCB0b2tlbiBlbmNvdW50ZXJlZC4KICAgICAgICAgICAgYWJvcnQoKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgICB9OwoKICAgICAgICAvLyBJbnRlcm5hbDogVXBkYXRlcyBhIHRyYXZlcnNlZCBvYmplY3QgbWVtYmVyLgogICAgICAgIHZhciB1cGRhdGUgPSBmdW5jdGlvbiAoc291cmNlLCBwcm9wZXJ0eSwgY2FsbGJhY2spIHsKICAgICAgICAgIHZhciBlbGVtZW50ID0gd2Fsayhzb3VyY2UsIHByb3BlcnR5LCBjYWxsYmFjayk7CiAgICAgICAgICBpZiAoZWxlbWVudCA9PT0gdW5kZWYpIHsKICAgICAgICAgICAgZGVsZXRlIHNvdXJjZVtwcm9wZXJ0eV07CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzb3VyY2VbcHJvcGVydHldID0gZWxlbWVudDsKICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgICAvLyBJbnRlcm5hbDogUmVjdXJzaXZlbHkgdHJhdmVyc2VzIGEgcGFyc2VkIEpTT04gb2JqZWN0LCBpbnZva2luZyB0aGUKICAgICAgICAvLyBgY2FsbGJhY2tgIGZ1bmN0aW9uIGZvciBlYWNoIHZhbHVlLiBUaGlzIGlzIGFuIGltcGxlbWVudGF0aW9uIG9mIHRoZQogICAgICAgIC8vIGBXYWxrKGhvbGRlciwgbmFtZSlgIG9wZXJhdGlvbiBkZWZpbmVkIGluIEVTIDUuMSBzZWN0aW9uIDE1LjEyLjIuCiAgICAgICAgdmFyIHdhbGsgPSBmdW5jdGlvbiAoc291cmNlLCBwcm9wZXJ0eSwgY2FsbGJhY2spIHsKICAgICAgICAgIHZhciB2YWx1ZSA9IHNvdXJjZVtwcm9wZXJ0eV0sIGxlbmd0aDsKICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gIm9iamVjdCIgJiYgdmFsdWUpIHsKICAgICAgICAgICAgLy8gYGZvckVhY2hgIGNhbid0IGJlIHVzZWQgdG8gdHJhdmVyc2UgYW4gYXJyYXkgaW4gT3BlcmEgPD0gOC41NAogICAgICAgICAgICAvLyBiZWNhdXNlIGl0cyBgT2JqZWN0I2hhc093blByb3BlcnR5YCBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIGBmYWxzZWAKICAgICAgICAgICAgLy8gZm9yIGFycmF5IGluZGljZXMgKGUuZy4sIGAhWzEsIDIsIDNdLmhhc093blByb3BlcnR5KCIwIilgKS4KICAgICAgICAgICAgaWYgKGdldENsYXNzLmNhbGwodmFsdWUpID09IGFycmF5Q2xhc3MpIHsKICAgICAgICAgICAgICBmb3IgKGxlbmd0aCA9IHZhbHVlLmxlbmd0aDsgbGVuZ3RoLS07KSB7CiAgICAgICAgICAgICAgICB1cGRhdGUodmFsdWUsIGxlbmd0aCwgY2FsbGJhY2spOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBmb3JFYWNoKHZhbHVlLCBmdW5jdGlvbiAocHJvcGVydHkpIHsKICAgICAgICAgICAgICAgIHVwZGF0ZSh2YWx1ZSwgcHJvcGVydHksIGNhbGxiYWNrKTsKICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmNhbGwoc291cmNlLCBwcm9wZXJ0eSwgdmFsdWUpOwogICAgICAgIH07CgogICAgICAgIC8vIFB1YmxpYzogYEpTT04ucGFyc2VgLiBTZWUgRVMgNS4xIHNlY3Rpb24gMTUuMTIuMi4KICAgICAgICBleHBvcnRzLnBhcnNlID0gZnVuY3Rpb24gKHNvdXJjZSwgY2FsbGJhY2spIHsKICAgICAgICAgIHZhciByZXN1bHQsIHZhbHVlOwogICAgICAgICAgSW5kZXggPSAwOwogICAgICAgICAgU291cmNlID0gIiIgKyBzb3VyY2U7CiAgICAgICAgICByZXN1bHQgPSBnZXQobGV4KCkpOwogICAgICAgICAgLy8gSWYgYSBKU09OIHN0cmluZyBjb250YWlucyBtdWx0aXBsZSB0b2tlbnMsIGl0IGlzIGludmFsaWQuCiAgICAgICAgICBpZiAobGV4KCkgIT0gIiQiKSB7CiAgICAgICAgICAgIGFib3J0KCk7CiAgICAgICAgICB9CiAgICAgICAgICAvLyBSZXNldCB0aGUgcGFyc2VyIHN0YXRlLgogICAgICAgICAgSW5kZXggPSBTb3VyY2UgPSBudWxsOwogICAgICAgICAgcmV0dXJuIGNhbGxiYWNrICYmIGdldENsYXNzLmNhbGwoY2FsbGJhY2spID09IGZ1bmN0aW9uQ2xhc3MgPyB3YWxrKCh2YWx1ZSA9IHt9LCB2YWx1ZVsiIl0gPSByZXN1bHQsIHZhbHVlKSwgIiIsIGNhbGxiYWNrKSA6IHJlc3VsdDsKICAgICAgICB9OwogICAgICB9CiAgICB9CgogICAgZXhwb3J0c1sicnVuSW5Db250ZXh0Il0gPSBydW5JbkNvbnRleHQ7CiAgICByZXR1cm4gZXhwb3J0czsKICB9CgogIGlmIChmcmVlRXhwb3J0cyAmJiAhaXNMb2FkZXIpIHsKICAgIC8vIEV4cG9ydCBmb3IgQ29tbW9uSlMgZW52aXJvbm1lbnRzLgogICAgcnVuSW5Db250ZXh0KHJvb3QsIGZyZWVFeHBvcnRzKTsKICB9IGVsc2UgewogICAgLy8gRXhwb3J0IGZvciB3ZWIgYnJvd3NlcnMgYW5kIEphdmFTY3JpcHQgZW5naW5lcy4KICAgIHZhciBuYXRpdmVKU09OID0gcm9vdC5KU09OLAogICAgICAgIHByZXZpb3VzSlNPTiA9IHJvb3RbIkpTT04zIl0sCiAgICAgICAgaXNSZXN0b3JlZCA9IGZhbHNlOwoKICAgIHZhciBKU09OMyA9IHJ1bkluQ29udGV4dChyb290LCAocm9vdFsiSlNPTjMiXSA9IHsKICAgICAgLy8gUHVibGljOiBSZXN0b3JlcyB0aGUgb3JpZ2luYWwgdmFsdWUgb2YgdGhlIGdsb2JhbCBgSlNPTmAgb2JqZWN0IGFuZAogICAgICAvLyByZXR1cm5zIGEgcmVmZXJlbmNlIHRvIHRoZSBgSlNPTjNgIG9iamVjdC4KICAgICAgIm5vQ29uZmxpY3QiOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgaWYgKCFpc1Jlc3RvcmVkKSB7CiAgICAgICAgICBpc1Jlc3RvcmVkID0gdHJ1ZTsKICAgICAgICAgIHJvb3QuSlNPTiA9IG5hdGl2ZUpTT047CiAgICAgICAgICByb290WyJKU09OMyJdID0gcHJldmlvdXNKU09OOwogICAgICAgICAgbmF0aXZlSlNPTiA9IHByZXZpb3VzSlNPTiA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBKU09OMzsKICAgICAgfQogICAgfSkpOwoKICAgIHJvb3QuSlNPTiA9IHsKICAgICAgInBhcnNlIjogSlNPTjMucGFyc2UsCiAgICAgICJzdHJpbmdpZnkiOiBKU09OMy5zdHJpbmdpZnkKICAgIH07CiAgfQoKICAvLyBFeHBvcnQgZm9yIGFzeW5jaHJvbm91cyBtb2R1bGUgbG9hZGVycy4KICBpZiAoaXNMb2FkZXIpIHsKICAgIGRlZmluZShmdW5jdGlvbiAoKSB7CiAgICAgIHJldHVybiBKU09OMzsKICAgIH0pOwogIH0KfSkuY2FsbCh0aGlzKTsKCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi8vIERhdGFVdGlscy5qcwovLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoKKGZ1bmN0aW9uICgpIHsKCgkvKioKCSAqIEEgZmV3IGRhdGEgdXRpbGl0aWVzIGZvciBmb3JtYXR0aW5nIGRpZmZlcmVudCBkYXRhIHR5cGVzLgoJICogQGNsYXNzIERhdGFVdGlscwoJICovCgl2YXIgcyA9IHt9OwoKCS8vIHN0YXRpYyBtZXRob2RzCgkvKioKCSAqIFBhcnNlIFhNTCB1c2luZyB0aGUgRE9NLiBUaGlzIGlzIHJlcXVpcmVkIHdoZW4gcHJlbG9hZGluZyBYTUwgb3IgU1ZHLgoJICogQG1ldGhvZCBwYXJzZVhNTAoJICogQHBhcmFtIHtTdHJpbmd9IHRleHQgVGhlIHJhdyB0ZXh0IG9yIFhNTCB0aGF0IGlzIGxvYWRlZCBieSBYSFIuCgkgKiBAcGFyYW0ge1N0cmluZ30gdHlwZSBUaGUgbWltZSB0eXBlIG9mIHRoZSBYTUwuIFVzZSAidGV4dC94bWwiIGZvciBYTUwsIGFuZCAgImltYWdlL3N2Zyt4bWwiIGZvciBTVkcgcGFyc2luZy4KCSAqIEByZXR1cm4ge1hNTH0gQW4gWE1MIGRvY3VtZW50CgkgKiBAc3RhdGljCgkgKi8KCXMucGFyc2VYTUwgPSBmdW5jdGlvbiAodGV4dCwgdHlwZSkgewoJCXZhciB4bWwgPSBudWxsOwoJCXRyeSB7CgkJCS8vIENvY29vbkpTIGRvZXMgbm90IHN1cHBvcnQgWE1MIHBhcnNpbmcgd2l0aCBlaXRoZXIgbWV0aG9kLgoJCQlpZiAod2luZG93LkRPTVBhcnNlcikgewoJCQkJdmFyIHBhcnNlciA9IG5ldyBET01QYXJzZXIoKTsKCQkJCXhtbCA9IHBhcnNlci5wYXJzZUZyb21TdHJpbmcodGV4dCwgdHlwZSk7CgkJCX0gZWxzZSB7IC8vIElFCgkJCQl4bWwgPSBuZXcgQWN0aXZlWE9iamVjdCgiTWljcm9zb2Z0LlhNTERPTSIpOwoJCQkJeG1sLmFzeW5jID0gZmFsc2U7CgkJCQl4bWwubG9hZFhNTCh0ZXh0KTsKCQkJfQoJCX0gY2F0Y2ggKGUpIHt9CgkJcmV0dXJuIHhtbDsKCX07CgoJLyoqCgkgKiBQYXJzZSBhIHN0cmluZyBpbnRvIGFuIE9iamVjdC4KCSAqIEBtZXRob2QgcGFyc2VKU09OCgkgKiBAcGFyYW0ge1N0cmluZ30gdmFsdWUgVGhlIGxvYWRlZCBKU09OIHN0cmluZwoJICogQHJldHVybnMge09iamVjdH0gQSBKYXZhU2NyaXB0IG9iamVjdC4KCSAqLwoJcy5wYXJzZUpTT04gPSBmdW5jdGlvbiAodmFsdWUpIHsKCQlpZiAodmFsdWUgPT0gbnVsbCkgewoJCQlyZXR1cm4gbnVsbDsKCQl9CgoJCXRyeSB7CgkJCXJldHVybiBKU09OLnBhcnNlKHZhbHVlKTsKCQl9IGNhdGNoIChlKSB7CgkJCS8vIFRPRE87IEhhbmRsZSB0aGlzIHdpdGggYSBjdXN0b20gZXJyb3I/CgkJCXRocm93IGU7CgkJfQoJfTsKCgljcmVhdGVqcy5EYXRhVXRpbHMgPSBzOwoKfSgpKTsKCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi8vIExvYWRJdGVtLmpzCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgp0aGlzLmNyZWF0ZWpzID0gdGhpcy5jcmVhdGVqcyB8fCB7fTsKCihmdW5jdGlvbiAoKSB7CgkidXNlIHN0cmljdCI7CgoJLyoqCgkgKiBBbGwgbG9hZGVycyBhY2NlcHQgYW4gaXRlbSBjb250YWluaW5nIHRoZSBwcm9wZXJ0aWVzIGRlZmluZWQgaW4gdGhpcyBjbGFzcy4gSWYgYSByYXcgb2JqZWN0IGlzIHBhc3NlZCBpbnN0ZWFkLAoJICogaXQgd2lsbCBub3QgYmUgYWZmZWN0ZWQsIGJ1dCBpdCBtdXN0IGNvbnRhaW4gYXQgbGVhc3QgYSB7eyNjcm9zc0xpbmsgInNyYzpwcm9wZXJ0eSJ9fXt7L2Nyb3NzTGlua319IHByb3BlcnR5LiBBCgkgKiBzdHJpbmcgcGF0aCBvciBIVE1MIHRhZyBpcyBhbHNvIGFjY2VwdGFibGUsIGJ1dCBpdCB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgY29udmVydGVkIHRvIGEgTG9hZEl0ZW0gdXNpbmcgdGhlCgkgKiB7eyNjcm9zc0xpbmsgImNyZWF0ZSJ9fXt7L2Nyb3NzTGlua319IG1ldGhvZCBieSB7eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyIn19e3svY3Jvc3NMaW5rfX0KCSAqIEBjbGFzcyBMb2FkSXRlbQoJICogQGNvbnN0cnVjdG9yCgkgKiBAc2luY2UgMC42LjAKCSAqLwoJZnVuY3Rpb24gTG9hZEl0ZW0oKSB7CgkJLyoqCgkJICogVGhlIHNvdXJjZSBvZiB0aGUgZmlsZSB0aGF0IGlzIGJlaW5nIGxvYWRlZC4gVGhpcyBwcm9wZXJ0eSBpcyA8Yj5yZXF1aXJlZDwvYj4uIFRoZSBzb3VyY2UgY2FuIGVpdGhlciBiZSBhCgkJICogc3RyaW5nIChyZWNvbW1lbmRlZCksIG9yIGFuIEhUTUwgdGFnLjwvbGk+CgkJICogQHByb3BlcnR5IHNyYwoJCSAqIEB0eXBlIHtTdHJpbmd9CgkJICogQGRlZmF1bHQgbnVsbAoJCSAqLwoJCXRoaXMuc3JjID0gbnVsbDsKCgkJLyoqCgkJICogVGhlIHNvdXJjZSBvZiB0aGUgZmlsZSB0aGF0IGlzIGJlaW5nIGxvYWRlZC4gVGhpcyBwcm9wZXJ0eSBpcyA8c3Ryb25nPnJlcXVpcmVkPC9zdHJvbmc+LiBUaGUgc291cmNlIGNhbgoJCSAqIGVpdGhlciBiZSBhIHN0cmluZyAocmVjb21tZW5kZWQpLCBvciBhbiBIVE1MIHRhZy4gU2VlIHRoZSB7eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyIn19e3svY3Jvc3NMaW5rfX0KCQkgKiBjbGFzcyBmb3IgdGhlIGZ1bGwgbGlzdCBvZiBzdXBwb3J0ZWQgdHlwZXMuCgkJICogQHByb3BlcnR5IHR5cGUKCQkgKiBAdHlwZSB7U3RyaW5nfQoJCSAqIEBkZWZhdWx0IG51bGwKCQkgKi8KCQl0aGlzLnR5cGUgPSBudWxsOwoKCQkvKioKCQkgKiBBIHN0cmluZyBpZGVudGlmaWVyIHdoaWNoIGNhbiBiZSB1c2VkIHRvIHJlZmVyZW5jZSB0aGUgbG9hZGVkIG9iamVjdC4gSWYgbm9uZSBpcyBwcm92aWRlZCwgdGhpcyB3aWxsIGJlCgkJICogYXV0b21hdGljYWxseSBzZXQgdG8gdGhlIHt7I2Nyb3NzTGluayAic3JjOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0uCgkJICogQHByb3BlcnR5IGlkCgkJICogQHR5cGUge1N0cmluZ30KCQkgKiBAZGVmYXVsdCBudWxsCgkJICovCgkJdGhpcy5pZCA9IG51bGw7CgoJCS8qKgoJCSAqIERldGVybWluZXMgaWYgYSBtYW5pZmVzdCB3aWxsIG1haW50YWluIHRoZSBvcmRlciBvZiB0aGlzIGl0ZW0sIGluIHJlbGF0aW9uIHRvIG90aGVyIGl0ZW1zIGluIHRoZSBtYW5pZmVzdAoJCSAqIHRoYXQgaGF2ZSBhbHNvIHNldCB0aGUgYG1haW50YWluT3JkZXJgIHByb3BlcnR5IHRvIGB0cnVlYC4gVGhpcyBvbmx5IGFwcGxpZXMgd2hlbiB0aGUgbWF4IGNvbm5lY3Rpb25zIGhhcwoJCSAqIGJlZW4gc2V0IGFib3ZlIDEgKHVzaW5nIHt7I2Nyb3NzTGluayAiTG9hZFF1ZXVlL3NldE1heENvbm5lY3Rpb25zIn19e3svY3Jvc3NMaW5rfX0pLiBFdmVyeXRoaW5nIHdpdGggdGhpcwoJCSAqIHByb3BlcnR5IHNldCB0byBgZmFsc2VgIHdpbGwgZmluaXNoIGFzIGl0IGlzIGxvYWRlZC4gT3JkZXJlZCBpdGVtcyBhcmUgY29tYmluZWQgd2l0aCBzY3JpcHQgdGFncyBsb2FkaW5nIGluCgkJICogb3JkZXIgd2hlbiB7eyNjcm9zc0xpbmsgIkxvYWRRdWV1ZS9tYWludGFpblNjcmlwdE9yZGVyOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0gaXMgc2V0IHRvIGB0cnVlYC4KCQkgKiBAcHJvcGVydHkgbWFpbnRhaW5PcmRlcgoJCSAqIEB0eXBlIHtCb29sZWFufQoJCSAqIEBkZWZhdWx0IGZhbHNlCgkJICovCgkJdGhpcy5tYWludGFpbk9yZGVyID0gZmFsc2U7CgoJCS8qKgoJCSAqIEEgY2FsbGJhY2sgdXNlZCBieSBKU09OUCByZXF1ZXN0cyB0aGF0IGRlZmluZXMgd2hhdCBnbG9iYWwgbWV0aG9kIHRvIGNhbGwgd2hlbiB0aGUgSlNPTlAgY29udGVudCBpcyBsb2FkZWQuCgkJICogQHByb3BlcnR5IGNhbGxiYWNrCgkJICogQHR5cGUge1N0cmluZ30KCQkgKiBAZGVmYXVsdCBudWxsCgkJICovCgkJdGhpcy5jYWxsYmFjayA9IG51bGw7CgoJCS8qKgoJCSAqIEFuIGFyYml0cmFyeSBkYXRhIG9iamVjdCwgd2hpY2ggaXMgaW5jbHVkZWQgd2l0aCB0aGUgbG9hZGVkIG9iamVjdC4KCQkgKiBAcHJvcGVydHkgZGF0YQoJCSAqIEB0eXBlIHtPYmplY3R9CgkJICogQGRlZmF1bHQgbnVsbAoJCSAqLwoJCXRoaXMuZGF0YSA9IG51bGw7CgoJCS8qKgoJCSAqIFRoZSByZXF1ZXN0IG1ldGhvZCB1c2VkIGZvciBIVFRQIGNhbGxzLiBCb3RoIHt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvR0VUOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0gb3IKCQkgKiB7eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyL1BPU1Q6cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fSByZXF1ZXN0IHR5cGVzIGFyZSBzdXBwb3J0ZWQsIGFuZCBhcmUgZGVmaW5lZCBhcwoJCSAqIGNvbnN0YW50cyBvbiB7eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyIn19e3svY3Jvc3NMaW5rfX0uCgkJICogQHByb3BlcnR5IG1ldGhvZAoJCSAqIEB0eXBlIHtTdHJpbmd9CgkJICogQGRlZmF1bHQgZ2V0CgkJICovCgkJdGhpcy5tZXRob2QgPSBjcmVhdGVqcy5Mb2FkSXRlbS5HRVQ7CgoJCS8qKgoJCSAqIEFuIG9iamVjdCBoYXNoIG9mIG5hbWUvdmFsdWUgcGFpcnMgdG8gc2VuZCB0byB0aGUgc2VydmVyLgoJCSAqIEBwcm9wZXJ0eSB2YWx1ZXMKCQkgKiBAdHlwZSB7T2JqZWN0fQoJCSAqIEBkZWZhdWx0IG51bGwKCQkgKi8KCQl0aGlzLnZhbHVlcyA9IG51bGw7CgoJCS8qKgoJCSAqIEFuIG9iamVjdCBoYXNoIG9mIGhlYWRlcnMgdG8gYXR0YWNoIHRvIGFuIFhIUiByZXF1ZXN0LiBQcmVsb2FkSlMgd2lsbCBhdXRvbWF0aWNhbGx5IGF0dGFjaCBzb21lIGRlZmF1bHQKCQkgKiBoZWFkZXJzIHdoZW4gcmVxdWlyZWQsIGluY2x1ZGluZyAiT3JpZ2luIiwgIkNvbnRlbnQtVHlwZSIsIGFuZCAiWC1SZXF1ZXN0ZWQtV2l0aCIuIFlvdSBtYXkgb3ZlcnJpZGUgdGhlCgkJICogZGVmYXVsdCBoZWFkZXJzIGJ5IGluY2x1ZGluZyB0aGVtIGluIHlvdXIgaGVhZGVycyBvYmplY3QuCgkJICogQHByb3BlcnR5IGhlYWRlcnMKCQkgKiBAdHlwZSB7T2JqZWN0fQoJCSAqIEBkZWZhdWx0IG51bGwKCQkgKi8KCQl0aGlzLmhlYWRlcnMgPSBudWxsOwoKCQkvKioKCQkgKiBFbmFibGUgY3JlZGVudGlhbHMgZm9yIFhIUiByZXF1ZXN0cy4KCQkgKiBAcHJvcGVydHkgd2l0aENyZWRlbnRpYWxzCgkJICogQHR5cGUge0Jvb2xlYW59CgkJICogQGRlZmF1bHQgZmFsc2UKCQkgKi8KCQl0aGlzLndpdGhDcmVkZW50aWFscyA9IGZhbHNlOwoKCQkvKioKCQkgKiBTZXQgdGhlIG1pbWUgdHlwZSBvZiBYSFItYmFzZWQgcmVxdWVzdHMuIFRoaXMgaXMgYXV0b21hdGljYWxseSBzZXQgdG8gInRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiIGZvciB0ZXh0CgkJICogYmFzZWQgZmlsZXMgKGpzb24sIHhtbCwgdGV4dCwgY3NzLCBqcykuCgkJICogQHByb3BlcnR5IG1pbWVUeXBlCgkJICogQHR5cGUge1N0cmluZ30KCQkgKiBAZGVmYXVsdCBudWxsCgkJICovCgkJdGhpcy5taW1lVHlwZSA9IG51bGw7CgoJCS8qKgoJCSAqIFNldHMgdGhlIGNyb3NzT3JpZ2luIGF0dHJpYnV0ZSBmb3IgQ09SUy1lbmFibGVkIGltYWdlcyBsb2FkaW5nIGNyb3NzLWRvbWFpbi4KCQkgKiBAcHJvcGVydHkgY3Jvc3NPcmlnaW4KCQkgKiBAdHlwZSB7Ym9vbGVhbn0KCQkgKiBAZGVmYXVsdCBBbm9ueW1vdXMKCQkgKi8KCQl0aGlzLmNyb3NzT3JpZ2luID0gbnVsbDsKCgkJLyoqCgkJICogVGhlIGR1cmF0aW9uIGluIG1pbGxpc2Vjb25kcyB0byB3YWl0IGJlZm9yZSBhIHJlcXVlc3QgdGltZXMgb3V0LiBUaGlzIG9ubHkgYXBwbGllcyB0byB0YWctYmFzZWQgYW5kIGFuZCBYSFIKCQkgKiAobGV2ZWwgb25lKSBsb2FkaW5nLCBhcyBYSFIgKGxldmVsIDIpIHByb3ZpZGVzIGl0cyBvd24gdGltZW91dCBldmVudC4KCQkgKiBAcHJvcGVydHkgbG9hZFRpbWVvdXQKCQkgKiBAdHlwZSB7TnVtYmVyfQoJCSAqIEBkZWZhdWx0IDgwMDAgKDggc2Vjb25kcykKCQkgKi8KCQl0aGlzLmxvYWRUaW1lb3V0ID0gODAwMDsKCX07CgoJdmFyIHAgPSBMb2FkSXRlbS5wcm90b3R5cGUgPSB7fTsKCXZhciBzID0gTG9hZEl0ZW07CgoJLyoqCgkgKiBDcmVhdGUvdmFsaWRhdGUgYSBMb2FkSXRlbS4KCSAqIDx1bD4KCSAqICAgICA8bGk+U3RyaW5nLWJhc2VkIGl0ZW1zIGFyZSBjb252ZXJ0ZWQgdG8gYSBMb2FkSXRlbSB3aXRoIGEgcG9wdWxhdGVkIHt7I2Nyb3NzTGluayAic3JjOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0uPC9saT4KCSAqICAgICA8bGk+TG9hZEl0ZW0gaW5zdGFuY2VzIGFyZSByZXR1cm5lZCBhcy1pczwvbGk+CgkgKiAgICAgPGxpPk9iamVjdHNzIGFyZSByZXR1cm5lZCBhcy1pczwvbGk+CgkgKiA8L3VsPgoJICogQG1ldGhvZCBjcmVhdGUKCSAqIEBwYXJhbSB7TG9hZEl0ZW18U3RyaW5nfE9iamVjdH0gdmFsdWUgVGhlIGxvYWQgaXRlbSB2YWx1ZQoJICogQHJldHVybnMge09iamVjdHxMb2FkSXRlbX0KCSAqIEBzdGF0aWMKCSAqLwoJcy5jcmVhdGUgPSBmdW5jdGlvbiAodmFsdWUpIHsKCQlpZiAodHlwZW9mIHZhbHVlID09ICJzdHJpbmciKSB7CgkJCXZhciBpdGVtID0gbmV3IExvYWRJdGVtKCk7CgkJCWl0ZW0uc3JjID0gdmFsdWU7CgkJCXJldHVybiBpdGVtOwoJCX0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBzKSB7CgkJCXJldHVybiB2YWx1ZTsKCQl9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgT2JqZWN0KSB7IC8vIERvbid0IG1vZGlmeSBvYmplY3QsIGFsbG93cyB1c2VycyB0byBhdHRhY2ggcmFuZG9tIGRhdGEgdG8gdGhlIGl0ZW0uCgkJCS8vIFRPRE86IERpc2FsbG93IG9iamVjdHMgd2l0aCBubyBzcmM/CgkJCXJldHVybiB2YWx1ZTsKCQl9IGVsc2UgewoJCQl0aHJvdyBuZXcgRXJyb3IoIlR5cGUgbm90IHJlY29nbml6ZWQuIik7CgkJfQoJfTsKCgkvKioKCSAqIFByb3ZpZGVzIGEgY2hhaW5hYmxlIHNob3J0Y3V0IG1ldGhvZCBmb3Igc2V0dGluZyBhIG51bWJlciBvZiBwcm9wZXJ0aWVzIG9uIHRoZSBpbnN0YW5jZS4KCSAqCgkgKiA8aDQ+RXhhbXBsZTwvaDQ+CgkgKgoJICogICAgICB2YXIgbG9hZEl0ZW0gPSBuZXcgY3JlYXRlanMuTG9hZEl0ZW0oKS5zZXQoe3NyYzoiaW1hZ2UucG5nIiwgbWFpbnRhaW5PcmRlcjp0cnVlfSk7CgkgKgoJICogQG1ldGhvZCBzZXQKCSAqIEBwYXJhbSB7T2JqZWN0fSBwcm9wcyBBIGdlbmVyaWMgb2JqZWN0IGNvbnRhaW5pbmcgcHJvcGVydGllcyB0byBjb3B5IHRvIHRoZSBMb2FkSXRlbSBpbnN0YW5jZS4KCSAqIEByZXR1cm4ge0xvYWRJdGVtfSBSZXR1cm5zIHRoZSBpbnN0YW5jZSB0aGUgbWV0aG9kIGlzIGNhbGxlZCBvbiAodXNlZnVsIGZvciBjaGFpbmluZyBjYWxscy4pCgkqLwoJcC5zZXQgPSBmdW5jdGlvbihwcm9wcykgewoJCWZvciAodmFyIG4gaW4gcHJvcHMpIHsgdGhpc1tuXSA9IHByb3BzW25dOyB9CgkJcmV0dXJuIHRoaXM7Cgl9OwoKCWNyZWF0ZWpzLkxvYWRJdGVtID0gczsKCn0oKSk7CgovLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwovLyBSZXF1ZXN0VXRpbHMuanMKLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCihmdW5jdGlvbiAoKSB7CgoJLyoqCgkgKiBVdGlsaXRpZXMgdGhhdCBhc3Npc3Qgd2l0aCBwYXJzaW5nIGxvYWQgaXRlbXMsIGFuZCBkZXRlcm1pbmluZyBmaWxlIHR5cGVzLCBldGMuCgkgKiBAY2xhc3MgUmVxdWVzdFV0aWxzCgkgKi8KCXZhciBzID0ge307CgoJLyoqCgkgKiBUaGUgUmVndWxhciBFeHByZXNzaW9uIHVzZWQgdG8gdGVzdCBmaWxlIFVSTFMgZm9yIGFuIGFic29sdXRlIHBhdGguCgkgKiBAcHJvcGVydHkgQUJTT0xVVEVfUEFUSAoJICogQHR5cGUge1JlZ0V4cH0KCSAqIEBzdGF0aWMKCSAqLwoJcy5BQlNPTFVURV9QQVRUID0gL14oPzpcdys6KT9cL3syfS9pOwoKCS8qKgoJICogVGhlIFJlZ3VsYXIgRXhwcmVzc2lvbiB1c2VkIHRvIHRlc3QgZmlsZSBVUkxTIGZvciBhIHJlbGF0aXZlIHBhdGguCgkgKiBAcHJvcGVydHkgUkVMQVRJVkVfUEFUSAoJICogQHR5cGUge1JlZ0V4cH0KCSAqIEBzdGF0aWMKCSAqLwoJcy5SRUxBVElWRV9QQVRUID0gKC9eWy4vXSo/XC8vaSk7CgoJLyoqCgkgKiBUaGUgUmVndWxhciBFeHByZXNzaW9uIHVzZWQgdG8gdGVzdCBmaWxlIFVSTFMgZm9yIGFuIGV4dGVuc2lvbi4gTm90ZSB0aGF0IFVSSXMgbXVzdCBhbHJlYWR5IGhhdmUgdGhlIHF1ZXJ5IHN0cmluZwoJICogcmVtb3ZlZC4KCSAqIEBwcm9wZXJ0eSBFWFRFTlNJT05fUEFUVAoJICogQHR5cGUge1JlZ0V4cH0KCSAqIEBzdGF0aWMKCSAqLwoJcy5FWFRFTlNJT05fUEFUVCA9IC9cLz9bXi9dK1wuKFx3ezEsNX0pJC9pOwoKCS8qKgoJICogUGFyc2UgYSBmaWxlIHBhdGggdG8gZGV0ZXJtaW5lIHRoZSBpbmZvcm1hdGlvbiB3ZSBuZWVkIHRvIHdvcmsgd2l0aCBpdC4gQ3VycmVudGx5LCBQcmVsb2FkSlMgbmVlZHMgdG8ga25vdzoKCSAqIDx1bD4KCSAqICAgICA8bGk+SWYgdGhlIHBhdGggaXMgYWJzb2x1dGUuIEFic29sdXRlIHBhdGhzIHN0YXJ0IHdpdGggYSBwcm90b2NvbCAoc3VjaCBhcyBgaHR0cDovL2AsIGBmaWxlOi8vYCwgb3IKCSAqICAgICBgLy9uZXR3b3JrUGF0aGApPC9saT4KCSAqICAgICA8bGk+SWYgdGhlIHBhdGggaXMgcmVsYXRpdmUuIFJlbGF0aXZlIHBhdGhzIHN0YXJ0IHdpdGggYC4uL2Agb3IgYC9wYXRoYCAob3Igc2ltaWxhcik8L2xpPgoJICogICAgIDxsaT5UaGUgZmlsZSBleHRlbnNpb24uIFRoaXMgaXMgZGV0ZXJtaW5lZCBieSB0aGUgZmlsZW5hbWUgd2l0aCBhbiBleHRlbnNpb24uIFF1ZXJ5IHN0cmluZ3MgYXJlIGRyb3BwZWQsIGFuZAoJICogICAgIHRoZSBmaWxlIHBhdGggaXMgZXhwZWN0ZWQgdG8gZm9sbG93IHRoZSBmb3JtYXQgYG5hbWUuZXh0YC48L2xpPgoJICogPC91bD4KCSAqIEBtZXRob2QgcGFyc2VVUkkKCSAqIEBwYXJhbSB7U3RyaW5nfSBwYXRoCgkgKiBAcmV0dXJucyB7T2JqZWN0fSBBbiBPYmplY3Qgd2l0aCBhbiBgYWJzb2x1dGVgIGFuZCBgcmVsYXRpdmVgIEJvb2xlYW4gdmFsdWVzLCBhcyB3ZWxsIGFzIGFuIG9wdGlvbmFsICdleHRlbnNpb25gCgkgKiBwcm9wZXJ0eSwgd2hpY2ggaXMgdGhlIGxvd2VyY2FzZSBleHRlbnNpb24uCgkgKiBAc3RhdGljCgkgKi8KCXMucGFyc2VVUkkgPSBmdW5jdGlvbiAocGF0aCkgewoJCXZhciBpbmZvID0ge2Fic29sdXRlOiBmYWxzZSwgcmVsYXRpdmU6IGZhbHNlfTsKCQlpZiAocGF0aCA9PSBudWxsKSB7IHJldHVybiBpbmZvOyB9CgoJCS8vIERyb3AgdGhlIHF1ZXJ5IHN0cmluZwoJCXZhciBxdWVyeUluZGV4ID0gcGF0aC5pbmRleE9mKCI/Iik7CgkJaWYgKHF1ZXJ5SW5kZXggPiAtMSkgewoJCQlwYXRoID0gcGF0aC5zdWJzdHIoMCwgcXVlcnlJbmRleCk7CgkJfQoKCQkvLyBBYnNvbHV0ZQoJCXZhciBtYXRjaDsKCQlpZiAocy5BQlNPTFVURV9QQVRULnRlc3QocGF0aCkpIHsKCQkJaW5mby5hYnNvbHV0ZSA9IHRydWU7CgoJCQkvLyBSZWxhdGl2ZQoJCX0gZWxzZSBpZiAocy5SRUxBVElWRV9QQVRULnRlc3QocGF0aCkpIHsKCQkJaW5mby5yZWxhdGl2ZSA9IHRydWU7CgkJfQoKCQkvLyBFeHRlbnNpb24KCQlpZiAobWF0Y2ggPSBwYXRoLm1hdGNoKHMuRVhURU5TSU9OX1BBVFQpKSB7CgkJCWluZm8uZXh0ZW5zaW9uID0gbWF0Y2hbMV0udG9Mb3dlckNhc2UoKTsKCQl9CgkJcmV0dXJuIGluZm87Cgl9OwoKCS8qKgoJICogRm9ybWF0cyBhbiBvYmplY3QgaW50byBhIHF1ZXJ5IHN0cmluZyBmb3IgZWl0aGVyIGEgUE9TVCBvciBHRVQgcmVxdWVzdC4KCSAqIEBtZXRob2QgZm9ybWF0UXVlcnlTdHJpbmcKCSAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhIFRoZSBkYXRhIHRvIGNvbnZlcnQgdG8gYSBxdWVyeSBzdHJpbmcuCgkgKiBAcGFyYW0ge0FycmF5fSBbcXVlcnldIEV4aXN0aW5nIG5hbWUvdmFsdWUgcGFpcnMgdG8gYXBwZW5kIG9uIHRvIHRoaXMgcXVlcnkuCgkgKiBAc3RhdGljCgkgKi8KCXMuZm9ybWF0UXVlcnlTdHJpbmcgPSBmdW5jdGlvbiAoZGF0YSwgcXVlcnkpIHsKCQlpZiAoZGF0YSA9PSBudWxsKSB7CgkJCXRocm93IG5ldyBFcnJvcignWW91IG11c3Qgc3BlY2lmeSBkYXRhLicpOwoJCX0KCQl2YXIgcGFyYW1zID0gW107CgkJZm9yICh2YXIgbiBpbiBkYXRhKSB7CgkJCXBhcmFtcy5wdXNoKG4gKyAnPScgKyBlc2NhcGUoZGF0YVtuXSkpOwoJCX0KCQlpZiAocXVlcnkpIHsKCQkJcGFyYW1zID0gcGFyYW1zLmNvbmNhdChxdWVyeSk7CgkJfQoJCXJldHVybiBwYXJhbXMuam9pbignJicpOwoJfTsKCgkvKioKCSAqIEEgdXRpbGl0eSBtZXRob2QgdGhhdCBidWlsZHMgYSBmaWxlIHBhdGggdXNpbmcgYSBzb3VyY2UgYW5kIGEgZGF0YSBvYmplY3QsIGFuZCBmb3JtYXRzIGl0IGludG8gYSBuZXcgcGF0aC4KCSAqIEBtZXRob2QgYnVpbGRQYXRoCgkgKiBAcGFyYW0ge1N0cmluZ30gc3JjIFRoZSBzb3VyY2UgcGF0aCB0byBhZGQgdmFsdWVzIHRvLgoJICogQHBhcmFtIHtPYmplY3R9IFtkYXRhXSBPYmplY3QgdXNlZCB0byBhcHBlbmQgdmFsdWVzIHRvIHRoaXMgcmVxdWVzdCBhcyBhIHF1ZXJ5IHN0cmluZy4gRXhpc3RpbmcgcGFyYW1ldGVycyBvbiB0aGUKCSAqIHBhdGggd2lsbCBiZSBwcmVzZXJ2ZWQuCgkgKiBAcmV0dXJucyB7c3RyaW5nfSBBIGZvcm1hdHRlZCBzdHJpbmcgdGhhdCBjb250YWlucyB0aGUgcGF0aCBhbmQgdGhlIHN1cHBsaWVkIHBhcmFtZXRlcnMuCgkgKiBAc3RhdGljCgkgKi8KCXMuYnVpbGRQYXRoID0gZnVuY3Rpb24gKHNyYywgZGF0YSkgewoJCWlmIChkYXRhID09IG51bGwpIHsKCQkJcmV0dXJuIHNyYzsKCQl9CgoJCXZhciBxdWVyeSA9IFtdOwoJCXZhciBpZHggPSBzcmMuaW5kZXhPZignPycpOwoKCQlpZiAoaWR4ICE9IC0xKSB7CgkJCXZhciBxID0gc3JjLnNsaWNlKGlkeCArIDEpOwoJCQlxdWVyeSA9IHF1ZXJ5LmNvbmNhdChxLnNwbGl0KCcmJykpOwoJCX0KCgkJaWYgKGlkeCAhPSAtMSkgewoJCQlyZXR1cm4gc3JjLnNsaWNlKDAsIGlkeCkgKyAnPycgKyB0aGlzLl9mb3JtYXRRdWVyeVN0cmluZyhkYXRhLCBxdWVyeSk7CgkJfSBlbHNlIHsKCQkJcmV0dXJuIHNyYyArICc/JyArIHRoaXMuX2Zvcm1hdFF1ZXJ5U3RyaW5nKGRhdGEsIHF1ZXJ5KTsKCQl9Cgl9OwoKCS8qKgoJICogQG1ldGhvZCBpc0Nyb3NzRG9tYWluCgkgKiBAcGFyYW0ge0xvYWRJdGVtfE9iamVjdH0gaXRlbSBBIGxvYWQgaXRlbSB3aXRoIGEgYHNyY2AgcHJvcGVydHkuCgkgKiBAcmV0dXJuIHtCb29sZWFufSBJZiB0aGUgbG9hZCBpdGVtIGlzIGxvYWRpbmcgZnJvbSBhIGRpZmZlcmVudCBkb21haW4gdGhhbiB0aGUgY3VycmVudCBsb2NhdGlvbi4KCSAqIEBzdGF0aWMKCSAqLwoJcy5pc0Nyb3NzRG9tYWluID0gZnVuY3Rpb24gKGl0ZW0pIHsKCQl2YXIgdGFyZ2V0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpOwoJCXRhcmdldC5ocmVmID0gaXRlbS5zcmM7CgoJCXZhciBob3N0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpOwoJCWhvc3QuaHJlZiA9IGxvY2F0aW9uLmhyZWY7CgoJCXZhciBjcm9zc2RvbWFpbiA9ICh0YXJnZXQuaG9zdG5hbWUgIT0gIiIpICYmCgkJCQkJCSAgKHRhcmdldC5wb3J0ICE9IGhvc3QucG9ydCB8fAoJCQkJCQkgICB0YXJnZXQucHJvdG9jb2wgIT0gaG9zdC5wcm90b2NvbCB8fAoJCQkJCQkgICB0YXJnZXQuaG9zdG5hbWUgIT0gaG9zdC5ob3N0bmFtZSk7CgkJcmV0dXJuIGNyb3NzZG9tYWluOwoJfTsKCgkvKioKCSAqIEBtZXRob2QgaXNMb2NhbAoJICogQHBhcmFtIHtMb2FkSXRlbXxPYmplY3R9IGl0ZW0gQSBsb2FkIGl0ZW0gd2l0aCBhIGBzcmNgIHByb3BlcnR5CgkgKiBAcmV0dXJuIHtCb29sZWFufSBJZiB0aGUgbG9hZCBpdGVtIGlzIGxvYWRpbmcgZnJvbSB0aGUgImZpbGU6IiBwcm90b2NvbC4gQXNzdW1lIHRoYXQgdGhlIGhvc3QgbXVzdCBiZSBsb2NhbCBhcwoJICogd2VsbC4KCSAqIEBzdGF0aWMKCSAqLwoJcy5pc0xvY2FsID0gZnVuY3Rpb24gKGl0ZW0pIHsKCQl2YXIgdGFyZ2V0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpOwoJCXRhcmdldC5ocmVmID0gaXRlbS5zcmM7CgkJcmV0dXJuIHRhcmdldC5ob3N0bmFtZSA9PSAiIiAmJiB0YXJnZXQucHJvdG9jb2wgPT0gImZpbGU6IjsKCX07CgoJLyoqCgkgKiBEZXRlcm1pbmUgaWYgYSBzcGVjaWZpYyB0eXBlIHNob3VsZCBiZSBsb2FkZWQgYXMgYSBiaW5hcnkgZmlsZS4gQ3VycmVudGx5LCBvbmx5IGltYWdlcyBhbmQgaXRlbXMgbWFya2VkCgkgKiBzcGVjaWZpY2FsbHkgYXMgImJpbmFyeSIgYXJlIGxvYWRlZCBhcyBiaW5hcnkuIE5vdGUgdGhhdCBhdWRpbyBpcyA8Yj5ub3Q8L2I+IGEgYmluYXJ5IHR5cGUsIGFzIHdlIGNhbiBub3QgcGxheQoJICogYmFjayB1c2luZyBhbiBhdWRpbyB0YWcgaWYgaXQgaXMgbG9hZGVkIGFzIGJpbmFyeS4gUGx1Z2lucyBjYW4gY2hhbmdlIHRoZSBpdGVtIHR5cGUgdG8gYmluYXJ5IHRvIGVuc3VyZSB0aGV5IGdldAoJICogYSBiaW5hcnkgcmVzdWx0IHRvIHdvcmsgd2l0aC4gQmluYXJ5IGZpbGVzIGFyZSBsb2FkZWQgdXNpbmcgWEhSMi4gVHlwZXMgYXJlIGRlZmluZWQgYXMgc3RhdGljIGNvbnN0YW50cyBvbgoJICoge3sjY3Jvc3NMaW5rICJBYnN0cmFjdExvYWRlciJ9fXt7L2Nyb3NzTGlua319LgoJICogQG1ldGhvZCBpc0JpbmFyeQoJICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgVGhlIGl0ZW0gdHlwZS4KCSAqIEByZXR1cm4ge0Jvb2xlYW59IElmIHRoZSBzcGVjaWZpZWQgdHlwZSBpcyBiaW5hcnkuCgkgKiBAc3RhdGljCgkgKi8KCXMuaXNCaW5hcnkgPSBmdW5jdGlvbiAodHlwZSkgewoJCXN3aXRjaCAodHlwZSkgewoJCQljYXNlIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLklNQUdFOgoJCQljYXNlIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLkJJTkFSWToKCQkJCXJldHVybiB0cnVlOwoJCQlkZWZhdWx0OgoJCQkJcmV0dXJuIGZhbHNlOwoJCX0KCX07CgoJLyoqCgkgKiBDaGVjayBpZiBpdGVtIGlzIGEgdmFsaWQgSFRNTEltYWdlRWxlbWVudAoJICogQG1ldGhvZCBpc0ltYWdlVGFnCgkgKiBAcGFyYW0ge09iamVjdH0gaXRlbQoJICogQHJldHVybnMge0Jvb2xlYW59CgkgKiBAc3RhdGljCgkgKi8KCXMuaXNJbWFnZVRhZyA9IGZ1bmN0aW9uKGl0ZW0pIHsKCQlyZXR1cm4gaXRlbSBpbnN0YW5jZW9mIEhUTUxJbWFnZUVsZW1lbnQ7Cgl9OwoKCS8qKgoJICogQ2hlY2sgaWYgaXRlbSBpcyBhIHZhbGlkIEhUTUxBdWRpb0VsZW1lbnQKCSAqIEBtZXRob2QgaXNBdWRpb1RhZwoJICogQHBhcmFtIHtPYmplY3R9IGl0ZW0KCSAqIEByZXR1cm5zIHtCb29sZWFufQoJICogQHN0YXRpYwoJICovCglzLmlzQXVkaW9UYWcgPSBmdW5jdGlvbihpdGVtKSB7CgkJaWYgKHdpbmRvdy5IVE1MQXVkaW9FbGVtZW50KSB7CgkJCXJldHVybiBpdGVtIGluc3RhbmNlb2YgSFRNTEF1ZGlvRWxlbWVudDsKCQl9IGVsc2UgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoJfTsKCgkvKioKCSAqIENoZWNrIGlmIGl0ZW0gaXMgYSB2YWxpZCBIVE1MVmlkZW9FbGVtZW50CgkgKiBAbWV0aG9kIGlzVmlkZW9UYWcKCSAqIEBwYXJhbSB7T2JqZWN0aXRlbQoJICogQHJldHVybnMge0Jvb2xlYW59CgkgKiBAc3RhdGljCgkgKi8KCXMuaXNWaWRlb1RhZyA9IGZ1bmN0aW9uKGl0ZW0pIHsKCQlpZiAod2luZG93LkhUTUxWaWRlb0VsZW1lbnQpIHsKCQkJcmV0dXJuIGl0ZW0gaW5zdGFuY2VvZiBIVE1MVmlkZW9FbGVtZW50OwoJCX0gZWxzZSB7CgkJCWZhbHNlOwoJCX0KCX07CgoJLyoqCgkgKiBEZXRlcm1pbmUgaWYgYSBzcGVjaWZpYyB0eXBlIGlzIGEgdGV4dC1iYXNlZCBhc3NldCwgYW5kIHNob3VsZCBiZSBsb2FkZWQgYXMgVVRGLTguCgkgKiBAbWV0aG9kIGlzVGV4dAoJICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgVGhlIGl0ZW0gdHlwZS4KCSAqIEByZXR1cm4ge0Jvb2xlYW59IElmIHRoZSBzcGVjaWZpZWQgdHlwZSBpcyB0ZXh0LgoJICogQHN0YXRpYwoJICovCglzLmlzVGV4dCA9IGZ1bmN0aW9uICh0eXBlKSB7CgkJc3dpdGNoICh0eXBlKSB7CgkJCWNhc2UgY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuVEVYVDoKCQkJY2FzZSBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5KU09OOgoJCQljYXNlIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLk1BTklGRVNUOgoJCQljYXNlIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLlhNTDoKCQkJY2FzZSBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5DU1M6CgkJCWNhc2UgY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuU1ZHOgoJCQljYXNlIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLkpBVkFTQ1JJUFQ6CgkJCWNhc2UgY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuU1BSSVRFU0hFRVQ6CgkJCQlyZXR1cm4gdHJ1ZTsKCQkJZGVmYXVsdDoKCQkJCXJldHVybiBmYWxzZTsKCQl9Cgl9OwoKCS8qKgoJICogRGV0ZXJtaW5lIHRoZSB0eXBlIG9mIHRoZSBvYmplY3QgdXNpbmcgY29tbW9uIGV4dGVuc2lvbnMuIE5vdGUgdGhhdCB0aGUgdHlwZSBjYW4gYmUgcGFzc2VkIGluIHdpdGggdGhlIGxvYWQgaXRlbQoJICogaWYgaXQgaXMgYW4gdW51c3VhbCBleHRlbnNpb24uCgkgKiBAbWV0aG9kIGdldFR5cGVCeUV4dGVuc2lvbgoJICogQHBhcmFtIHtTdHJpbmd9IGV4dGVuc2lvbiBUaGUgZmlsZSBleHRlbnNpb24gdG8gdXNlIHRvIGRldGVybWluZSB0aGUgbG9hZCB0eXBlLgoJICogQHJldHVybiB7U3RyaW5nfSBUaGUgZGV0ZXJtaW5lZCBsb2FkIHR5cGUgKGZvciBleGFtcGxlLCA8Y29kZT5BYnN0cmFjdExvYWRlci5JTUFHRTwvY29kZT4pLiBXaWxsIHJldHVybiBgbnVsbGAgaWYKCSAqIHRoZSB0eXBlIGNhbiBub3QgYmUgZGV0ZXJtaW5lZCBieSB0aGUgZXh0ZW5zaW9uLgoJICogQHN0YXRpYwoJICovCglzLmdldFR5cGVCeUV4dGVuc2lvbiA9IGZ1bmN0aW9uIChleHRlbnNpb24pIHsKCQlpZiAoZXh0ZW5zaW9uID09IG51bGwpIHsKCQkJcmV0dXJuIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLlRFWFQ7CgkJfQoKCQlzd2l0Y2ggKGV4dGVuc2lvbi50b0xvd2VyQ2FzZSgpKSB7CgkJCWNhc2UgImpwZWciOgoJCQljYXNlICJqcGciOgoJCQljYXNlICJnaWYiOgoJCQljYXNlICJwbmciOgoJCQljYXNlICJ3ZWJwIjoKCQkJY2FzZSAiYm1wIjoKCQkJCXJldHVybiBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5JTUFHRTsKCQkJY2FzZSAib2dnIjoKCQkJY2FzZSAibXAzIjoKCQkJY2FzZSAid2VibSI6CgkJCQlyZXR1cm4gY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuU09VTkQ7CgkJCWNhc2UgIm1wNCI6CgkJCWNhc2UgIndlYm0iOgoJCQljYXNlICJ0cyI6CgkJCQlyZXR1cm4gY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuVklERU87CgkJCWNhc2UgImpzb24iOgoJCQkJcmV0dXJuIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLkpTT047CgkJCWNhc2UgInhtbCI6CgkJCQlyZXR1cm4gY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuWE1MOwoJCQljYXNlICJjc3MiOgoJCQkJcmV0dXJuIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLkNTUzsKCQkJY2FzZSAianMiOgoJCQkJcmV0dXJuIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLkpBVkFTQ1JJUFQ7CgkJCWNhc2UgJ3N2Zyc6CgkJCQlyZXR1cm4gY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuU1ZHOwoJCQlkZWZhdWx0OgoJCQkJcmV0dXJuIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLlRFWFQ7CgkJfQoJfTsKCgljcmVhdGVqcy5SZXF1ZXN0VXRpbHMgPSBzOwoKfSgpKTsKCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi8vIEFic3RyYWN0TG9hZGVyLmpzCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgp0aGlzLmNyZWF0ZWpzID0gdGhpcy5jcmVhdGVqcyB8fCB7fTsKCihmdW5jdGlvbiAoKSB7CgkidXNlIHN0cmljdCI7CgovLyBjb25zdHJ1Y3RvcgoJLyoqCgkgKiBUaGUgYmFzZSBsb2FkZXIsIHdoaWNoIGRlZmluZXMgYWxsIHRoZSBnZW5lcmljIG1ldGhvZHMsIHByb3BlcnRpZXMsIGFuZCBldmVudHMuIEFsbCBsb2FkZXJzIGV4dGVuZCB0aGlzIGNsYXNzLAoJICogaW5jbHVkaW5nIHRoZSB7eyNjcm9zc0xpbmsgIkxvYWRRdWV1ZSJ9fXt7L2Nyb3NzTGlua319LgoJICogQGNsYXNzIEFic3RyYWN0TG9hZGVyCgkgKiBAcGFyYW0ge0xvYWRJdGVtfG9iamVjdHxzdHJpbmd9IFRoZSBpdGVtIHRvIGJlIGxvYWRlZC4KCSAqIEBwYXJhbSB7Qm9vbGVhbn0gW3ByZWZlclhIUl0gRGV0ZXJtaW5lcyBpZiB0aGUgTG9hZEl0ZW0gc2hvdWxkIDxlbT50cnk8L2VtPiBhbmQgbG9hZCB1c2luZyBYSFIsIG9yIHRha2UgYQoJICogdGFnLWJhc2VkIGFwcHJvYWNoLCB3aGljaCBjYW4gYmUgYmV0dGVyIGluIGNyb3NzLWRvbWFpbiBzaXR1YXRpb25zLiBOb3QgYWxsIGxvYWRlcnMgY2FuIGxvYWQgdXNpbmcgb25lIG9yIHRoZQoJICogb3RoZXIsIHNvIHRoaXMgaXMgYSBzdWdnZXN0ZWQgZGlyZWN0aXZlLgoJICogQG9hcmFtIHtTdHJpbmd9IFt0eXBlXSBUaGUgdHlwZSBvZiBsb2FkZXIuIExvYWRlciB0eXBlcyBhcmUgZGVmaW5lZCBhcyBjb25zdGFudHMgb24gdGhlIEFic3RyYWN0TG9hZGVyIGNsYXNzLAoJICogc3VjaCBhcyB7eyNjcm9zc0xpbmsgIklNQUdFOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0sIHt7I2Nyb3NzTGluayAiQ1NTOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0sIGV0Yy4KCSAqIEBleHRlbmRzIEV2ZW50RGlzcGF0Y2hlcgoJICovCglmdW5jdGlvbiBBYnN0cmFjdExvYWRlcihsb2FkSXRlbSwgcHJlZmVyWEhSLCB0eXBlKSB7CgkJdGhpcy5FdmVudERpc3BhdGNoZXJfY29uc3RydWN0b3IoKTsKCgkJLy8gcHVibGljIHByb3BlcnRpZXMKCQkvKioKCQkgKiBJZiB0aGUgbG9hZGVyIGhhcyBjb21wbGV0ZWQgbG9hZGluZy4gVGhpcyBwcm92aWRlcyBhIHF1aWNrIGNoZWNrLCBidXQgYWxzbyBlbnN1cmVzIHRoYXQgdGhlIGRpZmZlcmVudCBhcHByb2FjaGVzCgkJICogdXNlZCBmb3IgbG9hZGluZyBkbyBub3QgcGlsZSB1cCByZXN1bHRpbmcgaW4gbW9yZSB0aGFuIG9uZSBgY29tcGxldGVgIHt7I2Nyb3NzTGluayAiRXZlbnQifX17ey9jcm9zc0xpbmt9fS4KCQkgKiBAcHJvcGVydHkgbG9hZGVkCgkJICogQHR5cGUge0Jvb2xlYW59CgkJICogQGRlZmF1bHQgZmFsc2UKCQkgKi8KCQl0aGlzLmxvYWRlZCA9IGZhbHNlOwoKCQkvKioKCQkgKiBEZXRlcm1pbmUgaWYgdGhlIGxvYWRlciB3YXMgY2FuY2VsZWQuIENhbmNlbGVkIGxvYWRzIHdpbGwgbm90IGZpcmUgY29tcGxldGUgZXZlbnRzLiBOb3RlIHRoYXQgdGhpcyBwcm9wZXJ0eQoJCSAqIGlzIHJlYWRvbmx5LCBzbyB7eyNjcm9zc0xpbmsgIkxvYWRRdWV1ZSJ9fXt7L2Nyb3NzTGlua319IHF1ZXVlcyBzaG91bGQgYmUgY2xvc2VkIHVzaW5nIHt7I2Nyb3NzTGluayAiTG9hZFF1ZXVlL2Nsb3NlIn19e3svY3Jvc3NMaW5rfX0KCQkgKiBpbnN0ZWFkLgoJCSAqIEBwcm9wZXJ0eSBjYW5jZWxlZAoJCSAqIEB0eXBlIHtCb29sZWFufQoJCSAqIEBkZWZhdWx0IGZhbHNlCgkJICovCgkJdGhpcy5jYW5jZWxlZCA9IGZhbHNlOwoKCQkvKioKCQkgKiBUaGUgY3VycmVudCBsb2FkIHByb2dyZXNzIChwZXJjZW50YWdlKSBmb3IgdGhpcyBpdGVtLiBUaGlzIHdpbGwgYmUgYSBudW1iZXIgYmV0d2VlbiAwIGFuZCAxLgoJCSAqCgkJICogPGg0PkV4YW1wbGU8L2g0PgoJCSAqCgkJICogICAgIHZhciBxdWV1ZSA9IG5ldyBjcmVhdGVqcy5Mb2FkUXVldWUoKTsKCQkgKiAgICAgcXVldWUubG9hZEZpbGUoImxhcmdlSW1hZ2UucG5nIik7CgkJICogICAgIHF1ZXVlLm9uKCJwcm9ncmVzcyIsIGZ1bmN0aW9uKCkgewoJCSAqICAgICAgICAgY29uc29sZS5sb2coIlByb2dyZXNzOiIsIHF1ZXVlLnByb2dyZXNzLCBldmVudC5wcm9ncmVzcyk7CgkJICogICAgIH0pOwoJCSAqCgkJICogQHByb3BlcnR5IHByb2dyZXNzCgkJICogQHR5cGUge051bWJlcn0KCQkgKiBAZGVmYXVsdCAwCgkJICovCgkJdGhpcy5wcm9ncmVzcyA9IDA7CgoJCS8qKgoJCSAqIFRoZSB0eXBlIG9mIGl0ZW0gdGhpcyBsb2FkZXIgd2lsbCBsb2FkLiBTZWUge3sjY3Jvc3NMaW5rICJBYnN0cmFjdExvYWRlciJ9fXt7L2Nyb3NzTGlua319IGZvciBhIGZ1bGwgbGlzdCBvZgoJCSAqIHN1cHBvcnRlZCB0eXBlcy4KCQkgKiBAcHJvcGVydHkgdHlwZQoJCSAqIEB0eXBlIHtTdHJpbmd9CgkJICovCgkJdGhpcy50eXBlID0gdHlwZTsKCgkJLyoqCgkJICogQSBmb3JtYXR0ZXIgZnVuY3Rpb24gdGhhdCBjb252ZXJ0cyB0aGUgbG9hZGVkIHJhdyByZXN1bHQgaW50byB0aGUgZmluYWwgcmVzdWx0LiBGb3IgZXhhbXBsZSwgdGhlIEpTT05Mb2FkZXIKCQkgKiBjb252ZXJ0cyBhIHN0cmluZyBvZiB0ZXh0IGludG8gYSBKYXZhU2NyaXB0IG9iamVjdC4gTm90IGFsbCBsb2FkZXJzIGhhdmUgYSByZXN1bHRGb3JtYXR0ZXIsIGFuZCB0aGlzIHByb3BlcnR5CgkJICogY2FuIGJlIG92ZXJyaWRkZW4gdG8gcHJvdmlkZSBjdXN0b20gZm9ybWF0dGluZy4KCQkgKgoJCSAqIE9wdGlvbmFsbHksIGEgcmVzdWx0Rm9ybWF0dGVyIGNhbiByZXR1cm4gYSBjYWxsYmFjayBmdW5jdGlvbiBpbiBjYXNlcyB3aGVyZSB0aGUgZm9ybWF0dGluZyBuZWVkcyB0byBiZQoJCSAqIGFzeW5jaHJvbm91cywgc3VjaCBhcyBjcmVhdGluZyBhIG5ldyBpbWFnZS4KCQkgKiBAcHJvcGVydHkgcmVzdWx0Rm9ybWF0dGVyCgkJICogQHR5cGUge0Z1bmN0aW9ufQoJCSAqIEBkZWZhdWx0IG51bGwKCQkgKi8KCQl0aGlzLnJlc3VsdEZvcm1hdHRlciA9IG51bGw7CgoJCS8vIHByb3RlY3RlZCBwcm9wZXJ0aWVzCgkJLyoqCgkJICogVGhlIHt7I2Nyb3NzTGluayAiTG9hZEl0ZW0ifX17ey9jcm9zc0xpbmt9fSB0aGlzIGxvYWRlciByZXByZXNlbnRzLiBOb3RlIHRoYXQgdGhpcyBpcyBudWxsIGluIGEge3sjY3Jvc3NMaW5rICJMb2FkUXVldWUifX17ey9jcm9zc0xpbmt9fSwKCQkgKiBidXQgd2lsbCBiZSBhdmFpbGFibGUgb24gbG9hZGVycyBzdWNoIGFzIHt7I2Nyb3NzTGluayAiWE1MTG9hZGVyIn19e3svY3Jvc3NMaW5rfX0gYW5kIHt7I2Nyb3NzTGluayAiSW1hZ2VMb2FkZXIifX17ey9jcm9zc0xpbmt9fS4KCQkgKiBAcHJvcGVydHkgX2l0ZW0KCQkgKiBAdHlwZSB7TG9hZEl0ZW18T2JqZWN0fQoJCSAqIEBwcml2YXRlCgkJICovCgkJaWYgKGxvYWRJdGVtKSB7CgkJCXRoaXMuX2l0ZW0gPSBjcmVhdGVqcy5Mb2FkSXRlbS5jcmVhdGUobG9hZEl0ZW0pOwoJCX0gZWxzZSB7CgkJCXRoaXMuX2l0ZW0gPSBudWxsOwoJCX0KCgkJLyoqCgkJICogV2hldGhlciB0aGUgbG9hZGVyIHdpbGwgdHJ5IGFuZCBsb2FkIGNvbnRlbnQgdXNpbmcgWEhSICh0cnVlKSBvciBIVE1MIHRhZ3MgKGZhbHNlKS4KCQkgKiBAcHJvcGVydHkgX3ByZWZlclhIUgoJCSAqIEB0eXBlIHtCb29sZWFufQoJCSAqIEBwcml2YXRlCgkJICovCgkJdGhpcy5fcHJlZmVyWEhSID0gcHJlZmVyWEhSOwoKCQkvKioKCQkgKiBUaGUgbG9hZGVkIHJlc3VsdCBhZnRlciBpdCBpcyBmb3JtYXR0ZWQgYnkgYW4gb3B0aW9uYWwge3sjY3Jvc3NMaW5rICJyZXN1bHRGb3JtYXR0ZXIifX17ey9jcm9zc0xpbmt9fS4gRm9yCgkJICogaXRlbXMgdGhhdCBhcmUgbm90IGZvcm1hdHRlZCwgdGhpcyB3aWxsIGJlIHRoZSBzYW1lIGFzIHRoZSB7eyNjcm9zc0xpbmsgIl9yYXdSZXN1bHQ6cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fS4KCQkgKiBUaGUgcmVzdWx0IGlzIGFjY2Vzc2VkIHVzaW5nIHRoZSB7eyNjcm9zc0xpbmsgImdldFJlc3VsdCJ9fXt7L2Nyb3NzTGlua319IG1ldGhvZC4KCQkgKiBAcHJvcGVydHkgX3Jlc3VsdAoJCSAqIEB0eXBlIHtPYmplY3R8U3RyaW5nfQoJCSAqIEBwcml2YXRlCgkJICovCgkJdGhpcy5fcmVzdWx0ID0gbnVsbDsKCgkJLyoqCgkJICogVGhlIGxvYWRlZCByZXN1bHQgYmVmb3JlIGl0IGlzIGZvcm1hdHRlZC4gVGhlIHJhd1Jlc3VsdCBpcyBhY2Nlc3NlZCB1c2luZyB0aGUge3sjY3Jvc3NMaW5rICJnZXRSZXN1bHQifX17ey9jcm9zc0xpbmt9fQoJCSAqIG1ldGhvZCwgYW5kIHBhc3NpbmcgYHRydWVgLgoJCSAqIEBwcm9wZXJ0eSBfcmF3UmVzdWx0CgkJICogQHR5cGUge09iamVjdHxTdHJpbmd9CgkJICogQHByaXZhdGUKCQkgKi8KCQl0aGlzLl9yYXdSZXN1bHQgPSBudWxsOwoKCQkvKioKCQkgKiBBIGxpc3Qgb2YgaXRlbXMgdGhhdCBsb2FkZXJzIGxvYWQgYmVoaW5kIHRoZSBzY2VuZXMuIFRoaXMgZG9lcyBub3QgaW5jbHVkZSB0aGUgbWFpbiBpdGVtIHRoZSBsb2FkZXIgaXMKCQkgKiByZXNwb25zaWJsZSBmb3IgbG9hZGluZy4gRXhhbXBsZXMgb2YgbG9hZGVycyB0aGF0IGhhdmUgc3ViLWl0ZW1zIGluY2x1ZGUgdGhlIHt7I2Nyb3NzTGluayAiU3ByaXRlU2hlZXRMb2FkZXIifX17ey9jcm9zc0xpbmt9fSBhbmQKCQkgKiB7eyNjcm9zc0xpbmsgIk1hbmlmZXN0TG9hZGVyIn19e3svY3Jvc3NMaW5rfX0uCgkJICogQHByb3BlcnR5IF9sb2FkSXRlbXMKCQkgKiBAdHlwZSB7bnVsbH0KCQkgKiBAcHJvdGVjdGVkCgkJICovCgkJdGhpcy5fbG9hZGVkSXRlbXMgPSBudWxsOwoKCQkvKioKCQkgKiBUaGUgYXR0cmlidXRlIHRoZSBpdGVtcyBsb2FkZWQgdXNpbmcgdGFncyB1c2UgZm9yIHRoZSBzb3VyY2UuCgkJICogQHR5cGUge3N0cmluZ30KCQkgKiBAZGVmYXVsdCBudWxsCgkJICogQHByaXZhdGUKCQkgKi8KCQl0aGlzLl90YWdTcmNBdHRyaWJ1dGUgPSBudWxsOwoKCQkvKioKCQkgKiBBbiBIVE1MIHRhZyAob3Igc2ltaWxhcikgdGhhdCBhIGxvYWRlciBtYXkgdXNlIHRvIGxvYWQgSFRNTCBjb250ZW50LCBzdWNoIGFzIGltYWdlcywgc2NyaXB0cywgZXRjLgoJCSAqIEBwcm9wZXJ0eSBfdGFnCgkJICogQHR5cGUge09iamVjdH0KCQkgKiBAcHJpdmF0ZQoJCSAqLwoJCXRoaXMuX3RhZyA9IG51bGw7Cgl9OwoKCXZhciBwID0gY3JlYXRlanMuZXh0ZW5kKEFic3RyYWN0TG9hZGVyLCBjcmVhdGVqcy5FdmVudERpc3BhdGNoZXIpOwoJdmFyIHMgPSBBYnN0cmFjdExvYWRlcjsKCgkvLyBUT0RPOiBkZXByZWNhdGVkCgkvLyBwLmluaXRpYWxpemUgPSBmdW5jdGlvbigpIHt9OyAvLyBzZWFyY2hhYmxlIGZvciBkZXZzIHdvbmRlcmluZyB3aGVyZSBpdCBpcy4gUkVNT1ZFRC4gU2VlIGRvY3MgZm9yIGRldGFpbHMuCgoKCS8qKgoJICogRGVmaW5lcyBhIFBPU1QgcmVxdWVzdCwgdXNlIGZvciBhIG1ldGhvZCB2YWx1ZSB3aGVuIGxvYWRpbmcgZGF0YS4KCSAqIEBwcm9wZXJ0eSBQT1NUCgkgKiBAdHlwZSB7c3RyaW5nfQoJICogQGRlZmF1bHQgcG9zdAoJICovCglzLlBPU1QgPSAiUE9TVCI7CgoJLyoqCgkgKiBEZWZpbmVzIGEgR0VUIHJlcXVlc3QsIHVzZSBmb3IgYSBtZXRob2QgdmFsdWUgd2hlbiBsb2FkaW5nIGRhdGEuCgkgKiBAcHJvcGVydHkgR0VUCgkgKiBAdHlwZSB7c3RyaW5nfQoJICogQGRlZmF1bHQgZ2V0CgkgKi8KCXMuR0VUID0gIkdFVCI7CgoJLyoqCgkgKiBUaGUgcHJlbG9hZCB0eXBlIGZvciBnZW5lcmljIGJpbmFyeSB0eXBlcy4gTm90ZSB0aGF0IGltYWdlcyBhcmUgbG9hZGVkIGFzIGJpbmFyeSBmaWxlcyB3aGVuIHVzaW5nIFhIUi4KCSAqIEBwcm9wZXJ0eSBCSU5BUlkKCSAqIEB0eXBlIHtTdHJpbmd9CgkgKiBAZGVmYXVsdCBiaW5hcnkKCSAqIEBzdGF0aWMKCSAqIEBzaW5jZSAwLjYuMAoJICovCglzLkJJTkFSWSA9ICJiaW5hcnkiOwoKCS8qKgoJICogVGhlIHByZWxvYWQgdHlwZSBmb3IgY3NzIGZpbGVzLiBDU1MgZmlsZXMgYXJlIGxvYWRlZCB1c2luZyBhICZsdDtsaW5rJmd0OyB3aGVuIGxvYWRlZCB3aXRoIFhIUiwgb3IgYQoJICogJmx0O3N0eWxlJmd0OyB0YWcgd2hlbiBsb2FkZWQgd2l0aCB0YWdzLgoJICogQHByb3BlcnR5IENTUwoJICogQHR5cGUge1N0cmluZ30KCSAqIEBkZWZhdWx0IGNzcwoJICogQHN0YXRpYwoJICogQHNpbmNlIDAuNi4wCgkgKi8KCXMuQ1NTID0gImNzcyI7CgoJLyoqCgkgKiBUaGUgcHJlbG9hZCB0eXBlIGZvciBpbWFnZSBmaWxlcywgdXN1YWxseSBwbmcsIGdpZiwgb3IganBnL2pwZWcuIEltYWdlcyBhcmUgbG9hZGVkIGludG8gYW4gJmx0O2ltYWdlJmd0OyB0YWcuCgkgKiBAcHJvcGVydHkgSU1BR0UKCSAqIEB0eXBlIHtTdHJpbmd9CgkgKiBAZGVmYXVsdCBpbWFnZQoJICogQHN0YXRpYwoJICogQHNpbmNlIDAuNi4wCgkgKi8KCXMuSU1BR0UgPSAiaW1hZ2UiOwoKCS8qKgoJICogVGhlIHByZWxvYWQgdHlwZSBmb3IgamF2YXNjcmlwdCBmaWxlcywgdXN1YWxseSB3aXRoIHRoZSAianMiIGZpbGUgZXh0ZW5zaW9uLiBKYXZhU2NyaXB0IGZpbGVzIGFyZSBsb2FkZWQgaW50byBhCgkgKiAmbHQ7c2NyaXB0Jmd0OyB0YWcuCgkgKgoJICogU2luY2UgdmVyc2lvbiAwLjQuMSssIGR1ZSB0byBob3cgdGFnLWxvYWRlZCBzY3JpcHRzIHdvcmssIGFsbCBKYXZhU2NyaXB0IGZpbGVzIGFyZSBhdXRvbWF0aWNhbGx5IGluamVjdGVkIGludG8KCSAqIHRoZSBib2R5IG9mIHRoZSBkb2N1bWVudCB0byBtYWludGFpbiBwYXJpdHkgYmV0d2VlbiBYSFIgYW5kIHRhZy1sb2FkZWQgc2NyaXB0cy4gSW4gdmVyc2lvbiAwLjQuMCBhbmQgZWFybGllciwKCSAqIG9ubHkgdGFnLWxvYWRlZCBzY3JpcHRzIGFyZSBpbmplY3RlZC4KCSAqIEBwcm9wZXJ0eSBKQVZBU0NSSVBUCgkgKiBAdHlwZSB7U3RyaW5nfQoJICogQGRlZmF1bHQgamF2YXNjcmlwdAoJICogQHN0YXRpYwoJICogQHNpbmNlIDAuNi4wCgkgKi8KCXMuSkFWQVNDUklQVCA9ICJqYXZhc2NyaXB0IjsKCgkvKioKCSAqIFRoZSBwcmVsb2FkIHR5cGUgZm9yIGpzb24gZmlsZXMsIHVzdWFsbHkgd2l0aCB0aGUgImpzb24iIGZpbGUgZXh0ZW5zaW9uLiBKU09OIGRhdGEgaXMgbG9hZGVkIGFuZCBwYXJzZWQgaW50byBhCgkgKiBKYXZhU2NyaXB0IG9iamVjdC4gTm90ZSB0aGF0IGlmIGEgYGNhbGxiYWNrYCBpcyBwcmVzZW50IG9uIHRoZSBsb2FkIGl0ZW0sIHRoZSBmaWxlIHdpbGwgYmUgbG9hZGVkIHdpdGggSlNPTlAsCgkgKiBubyBtYXR0ZXIgd2hhdCB0aGUge3sjY3Jvc3NMaW5rICJMb2FkUXVldWUvcHJlZmVyWEhSOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0gcHJvcGVydHkgaXMgc2V0IHRvLCBhbmQgdGhlIEpTT04KCSAqIG11c3QgY29udGFpbiBhIG1hdGNoaW5nIHdyYXBwZXIgZnVuY3Rpb24uCgkgKiBAcHJvcGVydHkgSlNPTgoJICogQHR5cGUge1N0cmluZ30KCSAqIEBkZWZhdWx0IGpzb24KCSAqIEBzdGF0aWMKCSAqIEBzaW5jZSAwLjYuMAoJICovCglzLkpTT04gPSAianNvbiI7CgoJLyoqCgkgKiBUaGUgcHJlbG9hZCB0eXBlIGZvciBqc29ucCBmaWxlcywgdXN1YWxseSB3aXRoIHRoZSAianNvbiIgZmlsZSBleHRlbnNpb24uIEpTT04gZGF0YSBpcyBsb2FkZWQgYW5kIHBhcnNlZCBpbnRvIGEKCSAqIEphdmFTY3JpcHQgb2JqZWN0LiBZb3UgYXJlIHJlcXVpcmVkIHRvIHBhc3MgYSBjYWxsYmFjayBwYXJhbWV0ZXIgdGhhdCBtYXRjaGVzIHRoZSBmdW5jdGlvbiB3cmFwcGVyIGluIHRoZSBKU09OLgoJICogTm90ZSB0aGF0IEpTT05QIHdpbGwgYWx3YXlzIGJlIHVzZWQgaWYgdGhlcmUgaXMgYSBjYWxsYmFjayBwcmVzZW50LCBubyBtYXR0ZXIgd2hhdCB0aGUge3sjY3Jvc3NMaW5rICJMb2FkUXVldWUvcHJlZmVyWEhSOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0KCSAqIHByb3BlcnR5IGlzIHNldCB0by4KCSAqIEBwcm9wZXJ0eSBKU09OUAoJICogQHR5cGUge1N0cmluZ30KCSAqIEBkZWZhdWx0IGpzb25wCgkgKiBAc3RhdGljCgkgKiBAc2luY2UgMC42LjAKCSAqLwoJcy5KU09OUCA9ICJqc29ucCI7CgoJLyoqCgkgKiBUaGUgcHJlbG9hZCB0eXBlIGZvciBqc29uLWJhc2VkIG1hbmlmZXN0IGZpbGVzLCB1c3VhbGx5IHdpdGggdGhlICJqc29uIiBmaWxlIGV4dGVuc2lvbi4gVGhlIEpTT04gZGF0YSBpcyBsb2FkZWQKCSAqIGFuZCBwYXJzZWQgaW50byBhIEphdmFTY3JpcHQgb2JqZWN0LiBQcmVsb2FkSlMgd2lsbCB0aGVuIGxvb2sgZm9yIGEgIm1hbmlmZXN0IiBwcm9wZXJ0eSBpbiB0aGUgSlNPTiwgd2hpY2ggaXMgYW4KCSAqIEFycmF5IG9mIGZpbGVzIHRvIGxvYWQsIGZvbGxvd2luZyB0aGUgc2FtZSBmb3JtYXQgYXMgdGhlIHt7I2Nyb3NzTGluayAiTG9hZFF1ZXVlL2xvYWRNYW5pZmVzdCJ9fXt7L2Nyb3NzTGlua319CgkgKiBtZXRob2QuIElmIGEgImNhbGxiYWNrIiBpcyBzcGVjaWZpZWQgb24gdGhlIG1hbmlmZXN0IG9iamVjdCwgdGhlbiBpdCB3aWxsIGJlIGxvYWRlZCB1c2luZyBKU09OUCBpbnN0ZWFkLAoJICogcmVnYXJkbGVzcyBvZiB3aGF0IHRoZSB7eyNjcm9zc0xpbmsgIkxvYWRRdWV1ZS9wcmVmZXJYSFI6cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fSBwcm9wZXJ0eSBpcyBzZXQgdG8uCgkgKiBAcHJvcGVydHkgTUFOSUZFU1QKCSAqIEB0eXBlIHtTdHJpbmd9CgkgKiBAZGVmYXVsdCBtYW5pZmVzdAoJICogQHN0YXRpYwoJICogQHNpbmNlIDAuNi4wCgkgKi8KCXMuTUFOSUZFU1QgPSAibWFuaWZlc3QiOwoKCS8qKgoJICogVGhlIHByZWxvYWQgdHlwZSBmb3Igc291bmQgZmlsZXMsIHVzdWFsbHkgbXAzLCBvZ2csIG9yIHdhdi4gV2hlbiBsb2FkaW5nIHZpYSB0YWdzLCBhdWRpbyBpcyBsb2FkZWQgaW50byBhbgoJICogJmx0O2F1ZGlvJmd0OyB0YWcuCgkgKiBAcHJvcGVydHkgU09VTkQKCSAqIEB0eXBlIHtTdHJpbmd9CgkgKiBAZGVmYXVsdCBzb3VuZAoJICogQHN0YXRpYwoJICogQHNpbmNlIDAuNi4wCgkgKi8KCXMuU09VTkQgPSAic291bmQiOwoKCS8qKgoJICogVGhlIHByZWxvYWQgdHlwZSBmb3IgdmlkZW8gZmlsZXMsIHVzdWFsbHkgbXA0LCB0cywgb3Igb2dnLiBXaGVuIGxvYWRpbmcgdmlhIHRhZ3MsIHZpZGVvIGlzIGxvYWRlZCBpbnRvIGFuCgkgKiAmbHQ7dmlkZW8mZ3Q7IHRhZy4KCSAqIEBwcm9wZXJ0eSBWSURFTwoJICogQHR5cGUge1N0cmluZ30KCSAqIEBkZWZhdWx0IHZpZGVvCgkgKiBAc3RhdGljCgkgKiBAc2luY2UgMC42LjAKCSAqLwoJcy5WSURFTyA9ICJ2aWRlbyI7CgoJLyoqCgkgKiBUaGUgcHJlbG9hZCB0eXBlIGZvciBTcHJpdGVTaGVldCBmaWxlcy4gU3ByaXRlU2hlZXQgZmlsZXMgYXJlIEpTT04gZmlsZXMgdGhhdCBjb250YWluIHN0cmluZyBpbWFnZSBwYXRocy4KCSAqIEBwcm9wZXJ0eSBTUFJJVEVTSEVFVAoJICogQHR5cGUge1N0cmluZ30KCSAqIEBkZWZhdWx0IHNwcml0ZXNoZWV0CgkgKiBAc3RhdGljCgkgKiBAc2luY2UgMC42LjAKCSAqLwoJcy5TUFJJVEVTSEVFVCA9ICJzcHJpdGVzaGVldCI7CgoJLyoqCgkgKiBUaGUgcHJlbG9hZCB0eXBlIGZvciBTVkcgZmlsZXMuCgkgKiBAcHJvcGVydHkgU1ZHCgkgKiBAdHlwZSB7U3RyaW5nfQoJICogQGRlZmF1bHQgc3ZnCgkgKiBAc3RhdGljCgkgKiBAc2luY2UgMC42LjAKCSAqLwoJcy5TVkcgPSAic3ZnIjsKCgkvKioKCSAqIFRoZSBwcmVsb2FkIHR5cGUgZm9yIHRleHQgZmlsZXMsIHdoaWNoIGlzIGFsc28gdGhlIGRlZmF1bHQgZmlsZSB0eXBlIGlmIHRoZSB0eXBlIGNhbiBub3QgYmUgZGV0ZXJtaW5lZC4gVGV4dCBpcwoJICogbG9hZGVkIGFzIHJhdyB0ZXh0LgoJICogQHByb3BlcnR5IFRFWFQKCSAqIEB0eXBlIHtTdHJpbmd9CgkgKiBAZGVmYXVsdCB0ZXh0CgkgKiBAc3RhdGljCgkgKiBAc2luY2UgMC42LjAKCSAqLwoJcy5URVhUID0gInRleHQiOwoKCS8qKgoJICogVGhlIHByZWxvYWQgdHlwZSBmb3IgeG1sIGZpbGVzLiBYTUwgaXMgbG9hZGVkIGludG8gYW4gWE1MIGRvY3VtZW50LgoJICogQHByb3BlcnR5IFhNTAoJICogQHR5cGUge1N0cmluZ30KCSAqIEBkZWZhdWx0IHhtbAoJICogQHN0YXRpYwoJICogQHNpbmNlIDAuNi4wCgkgKi8KCXMuWE1MID0gInhtbCI7CgovLyBFdmVudHMKCS8qKgoJICogVGhlIHt7I2Nyb3NzTGluayAiUHJvZ3Jlc3NFdmVudCJ9fXt7L2Nyb3NzTGlua319IHRoYXQgaXMgZmlyZWQgd2hlbiB0aGUgb3ZlcmFsbCBwcm9ncmVzcyBjaGFuZ2VzLiBQcmlvciB0bwoJICogdmVyc2lvbiAwLjYuMCwgdGhpcyB3YXMganVzdCBhIHJlZ3VsYXIge3sjY3Jvc3NMaW5rICJFdmVudCJ9fXt7L2Nyb3NzTGlua319LgoJICogQGV2ZW50IHByb2dyZXNzCgkgKiBAc2luY2UgMC4zLjAKCSAqLwoKCS8qKgoJICogVGhlIHt7I2Nyb3NzTGluayAiRXZlbnQifX17ey9jcm9zc0xpbmt9fSB0aGF0IGlzIGZpcmVkIHdoZW4gYSBsb2FkIHN0YXJ0cy4KCSAqIEBldmVudCBsb2Fkc3RhcnQKCSAqIEBwYXJhbSB7T2JqZWN0fSB0YXJnZXQgVGhlIG9iamVjdCB0aGF0IGRpc3BhdGNoZWQgdGhlIGV2ZW50LgoJICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgVGhlIGV2ZW50IHR5cGUuCgkgKiBAc2luY2UgMC4zLjEKCSAqLwoKCS8qKgoJICogVGhlIHt7I2Nyb3NzTGluayAiRXZlbnQifX17ey9jcm9zc0xpbmt9fSB0aGF0IGlzIGZpcmVkIHdoZW4gdGhlIGVudGlyZSBxdWV1ZSBoYXMgYmVlbiBsb2FkZWQuCgkgKiBAZXZlbnQgY29tcGxldGUKCSAqIEBwYXJhbSB7T2JqZWN0fSB0YXJnZXQgVGhlIG9iamVjdCB0aGF0IGRpc3BhdGNoZWQgdGhlIGV2ZW50LgoJICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgVGhlIGV2ZW50IHR5cGUuCgkgKiBAc2luY2UgMC4zLjAKCSAqLwoKCS8qKgoJICogVGhlIHt7I2Nyb3NzTGluayAiRXJyb3JFdmVudCJ9fXt7L2Nyb3NzTGlua319IHRoYXQgaXMgZmlyZWQgd2hlbiB0aGUgbG9hZGVyIGVuY291bnRlcnMgYW4gZXJyb3IuIElmIHRoZSBlcnJvciB3YXMKCSAqIGVuY291bnRlcmVkIGJ5IGEgZmlsZSwgdGhlIGV2ZW50IHdpbGwgY29udGFpbiB0aGUgaXRlbSB0aGF0IGNhdXNlZCB0aGUgZXJyb3IuIFByaW9yIHRvIHZlcnNpb24gMC42LjAsIHRoaXMgd2FzCgkgKiBqdXN0IGEgcmVndWxhciB7eyNjcm9zc0xpbmsgIkV2ZW50In19e3svY3Jvc3NMaW5rfX0uCgkgKiBAZXZlbnQgZXJyb3IKCSAqIEBzaW5jZSAwLjMuMAoJICovCgoJLyoqCgkgKiBUaGUge3sjY3Jvc3NMaW5rICJFdmVudCJ9fXt7L2Nyb3NzTGlua319IHRoYXQgaXMgZmlyZWQgd2hlbiB0aGUgbG9hZGVyIGVuY291bnRlcnMgYW4gaW50ZXJuYWwgZmlsZSBsb2FkIGVycm9yLgoJICogVGhpcyBlbmFibGVzIGxvYWRlcnMgdG8gbWFpbnRhaW4gaW50ZXJuYWwgcXVldWVzLCBhbmQgc3VyZmFjZSBmaWxlIGxvYWQgZXJyb3JzLgoJICogQGV2ZW50IGZpbGVlcnJvcgoJICogQHBhcmFtIHtPYmplY3R9IHRhcmdldCBUaGUgb2JqZWN0IHRoYXQgZGlzcGF0Y2hlZCB0aGUgZXZlbnQuCgkgKiBAcGFyYW0ge1N0cmluZ30gdHlwZSBUaGUgZXZlbiB0eXBlICgiZmlsZWVycm9yIikKCSAqIEBwYXJhbSB7TG9hZEl0ZW18b2JqZWN0fSBUaGUgaXRlbSB0aGF0IGVuY291bnRlcmVkIHRoZSBlcnJvcgoJICogQHNpbmNlIDAuNi4wCgkgKi8KCgkvKioKCSAqIFRoZSB7eyNjcm9zc0xpbmsgIkV2ZW50In19e3svY3Jvc3NMaW5rfX0gdGhhdCBpcyBmaXJlZCB3aGVuIGEgbG9hZGVyIGludGVybmFsbHkgbG9hZHMgYSBmaWxlLiBUaGlzIGVuYWJsZXMKCSAqIGxvYWRlcnMgc3VjaCBhcyB7eyNjcm9zc0xpbmsgIk1hbmlmZXN0TG9hZGVyIn19e3svY3Jvc3NMaW5rfX0gdG8gbWFpbnRhaW4gaW50ZXJuYWwge3sjY3Jvc3NMaW5rICJMb2FkUXVldWUifX17ey9jcm9zc0xpbmt9fXMKCSAqIGFuZCBub3RpZnkgd2hlbiB0aGV5IGhhdmUgbG9hZGVkIGEgZmlsZS4gVGhlIHt7I2Nyb3NzTGluayAiTG9hZFF1ZXVlIn19e3svY3Jvc3NMaW5rfX0gY2xhc3MgZGlzcGF0Y2hlcyBhCgkgKiBzbGlnaHRseSBkaWZmZXJlbnQge3sjY3Jvc3NMaW5rICJMb2FkUXVldWUvZmlsZWxvYWQ6ZXZlbnQifX17ey9jcm9zc0xpbmt9fSBldmVudC4KCSAqIEBldmVudCBmaWxlbG9hZAoJICogQHBhcmFtIHtPYmplY3R9IHRhcmdldCBUaGUgb2JqZWN0IHRoYXQgZGlzcGF0Y2hlZCB0aGUgZXZlbnQuCgkgKiBAcGFyYW0ge1N0cmluZ30gdHlwZSBUaGUgZXZlbnQgdHlwZSAoImZpbGVsb2FkIikKCSAqIEBwYXJhbSB7T2JqZWN0fSBpdGVtIFRoZSBmaWxlIGl0ZW0gd2hpY2ggd2FzIHNwZWNpZmllZCBpbiB0aGUge3sjY3Jvc3NMaW5rICJMb2FkUXVldWUvbG9hZEZpbGUifX17ey9jcm9zc0xpbmt9fQoJICogb3Ige3sjY3Jvc3NMaW5rICJMb2FkUXVldWUvbG9hZE1hbmlmZXN0In19e3svY3Jvc3NMaW5rfX0gY2FsbC4gSWYgb25seSBhIHN0cmluZyBwYXRoIG9yIHRhZyB3YXMgc3BlY2lmaWVkLCB0aGUKCSAqIG9iamVjdCB3aWxsIGNvbnRhaW4gdGhhdCB2YWx1ZSBhcyBhIGBzcmNgIHByb3BlcnR5LgoJICogQHBhcmFtIHtPYmplY3R9IHJlc3VsdCBUaGUgSFRNTCB0YWcgb3IgcGFyc2VkIHJlc3VsdCBvZiB0aGUgbG9hZGVkIGl0ZW0uCgkgKiBAcGFyYW0ge09iamVjdH0gcmF3UmVzdWx0IFRoZSB1bnByb2Nlc3NlZCByZXN1bHQsIHVzdWFsbHkgdGhlIHJhdyB0ZXh0IG9yIGJpbmFyeSBkYXRhIGJlZm9yZSBpdCBpcyBjb252ZXJ0ZWQKCSAqIHRvIGEgdXNhYmxlIG9iamVjdC4KCSAqIEBzaW5jZSAwLjYuMAoJICovCgoJLyoqCgkgKiBUaGUge3sjY3Jvc3NMaW5rICJFdmVudCJ9fXt7L2Nyb3NzTGlua319IHRoYXQgaXMgZmlyZWQgYWZ0ZXIgdGhlIGludGVybmFsIHJlcXVlc3QgaXMgY3JlYXRlZCwgYnV0IGJlZm9yZSBhIGxvYWQuCgkgKiBUaGlzIGFsbG93cyB1cGRhdGVzIHRvIHRoZSBsb2FkZXIgZm9yIHNwZWNpZmljIGxvYWRpbmcgbmVlZHMsIHN1Y2ggYXMgYmluYXJ5IG9yIFhIUiBpbWFnZSBsb2FkaW5nLgoJICogQGV2ZW50IGluaXRpYWxpemUKCSAqIEBwYXJhbSB7T2JqZWN0fSB0YXJnZXQgVGhlIG9iamVjdCB0aGF0IGRpc3BhdGNoZWQgdGhlIGV2ZW50LgoJICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgVGhlIGV2ZW50IHR5cGUgKCJpbml0aWFsaXplIikKCSAqIEBwYXJhbSB7QWJzdHJhY3RMb2FkZXJ9IGxvYWRlciBUaGUgbG9hZGVyIHRoYXQgaGFzIGJlZW4gaW5pdGlhbGl6ZWQuCgkgKi8KCgoJLyoqCgkgKiBHZXQgYSByZWZlcmVuY2UgdG8gdGhlIG1hbmlmZXN0IGl0ZW0gdGhhdCBpcyBsb2FkZWQgYnkgdGhpcyBsb2FkZXIuIEluIHNvbWUgY2FzZXMgdGhpcyB3aWxsIGJlIHRoZSB2YWx1ZSB0aGF0IHdhcwoJICogcGFzc2VkIGludG8ge3sjY3Jvc3NMaW5rICJMb2FkUXVldWUifX17ey9jcm9zc0xpbmt9fSB1c2luZyB7eyNjcm9zc0xpbmsgIkxvYWRRdWV1ZS9sb2FkRmlsZSJ9fXt7L2Nyb3NzTGlua319IG9yCgkgKiB7eyNjcm9zc0xpbmsgIkxvYWRRdWV1ZS9sb2FkTWFuaWZlc3QifX17ey9jcm9zc0xpbmt9fS4gSG93ZXZlciBpZiBvbmx5IGEgU3RyaW5nIHBhdGggd2FzIHBhc3NlZCBpbiwgdGhlbiBpdCB3aWxsCgkgKiBiZSBhIHt7I2Nyb3NzTGluayAiTG9hZEl0ZW0ifX17ey9jcm9zc0xpbmt9fS4KCSAqIEBtZXRob2QgZ2V0SXRlbQoJICogQHJldHVybiB7T2JqZWN0fSBUaGUgbWFuaWZlc3QgaXRlbSB0aGF0IHRoaXMgbG9hZGVyIGlzIHJlc3BvbnNpYmxlIGZvciBsb2FkaW5nLgoJICogQHNpbmNlIDAuNi4wCgkgKi8KCXAuZ2V0SXRlbSA9IGZ1bmN0aW9uICgpIHsKCQlyZXR1cm4gdGhpcy5faXRlbTsKCX07CgoJLyoqCgkgKiBHZXQgYSByZWZlcmVuY2UgdG8gdGhlIGNvbnRlbnQgdGhhdCB3YXMgbG9hZGVkIGJ5IHRoZSBsb2FkZXIgKG9ubHkgYXZhaWxhYmxlIGFmdGVyIHRoZSB7eyNjcm9zc0xpbmsgImNvbXBsZXRlOmV2ZW50In19e3svY3Jvc3NMaW5rfX0KCSAqIGV2ZW50IGlzIGRpc3BhdGNoZWQuCgkgKiBAbWV0aG9kIGdldFJlc3VsdAoJICogQHBhcmFtIHtCb29sZWFufSBbcmF3PWZhbHNlXSBEZXRlcm1pbmVzIGlmIHRoZSByZXR1cm5lZCByZXN1bHQgd2lsbCBiZSB0aGUgZm9ybWF0dGVkIGNvbnRlbnQsIG9yIHRoZSByYXcgbG9hZGVkCgkgKiBkYXRhIChpZiBpdCBleGlzdHMpLgoJICogQHJldHVybiB7T2JqZWN0fQoJICogQHNpbmNlIDAuNi4wCgkgKi8KCXAuZ2V0UmVzdWx0ID0gZnVuY3Rpb24gKHJhdykgewoJCXJldHVybiByYXcgPyB0aGlzLl9yYXdSZXN1bHQgOiB0aGlzLl9yZXN1bHQ7Cgl9OwoKCS8qKgoJICogUmV0dXJuIHRoZSBgdGFnYCB0aGlzIG9iamVjdCBjcmVhdGVzIG9yIHVzZXMgZm9yIGxvYWRpbmcuCgkgKiBAbWV0aG9kIGdldFRhZwoJICogQHJldHVybiB7T2JqZWN0fSBUaGUgdGFnIGluc3RhbmNlCgkgKiBAc2luY2UgMC42LjAKCSAqLwoJcC5nZXRUYWcgPSBmdW5jdGlvbiAoKSB7CgkJcmV0dXJuIHRoaXMuX3RhZzsKCX07CgoJLyoqCgkgKiBTZXQgdGhlIGB0YWdgIHRoaXMgaXRlbSB1c2VzIGZvciBsb2FkaW5nLgoJICogQG1ldGhvZCBzZXRUYWcKCSAqIEBwYXJhbSB7T2JqZWN0fSB0YWcgVGhlIHRhZyBpbnN0YW5jZQoJICogQHNpbmNlIDAuNi4wCgkgKi8KCXAuc2V0VGFnID0gZnVuY3Rpb24odGFnKSB7CgkgIHRoaXMuX3RhZyA9IHRhZzsKCX07CgoJLyoqCgkgKiBCZWdpbiBsb2FkaW5nIHRoZSBpdGVtLiBUaGlzIG1ldGhvZCBpcyByZXF1aXJlZCB3aGVuIHVzaW5nIGEgbG9hZGVyIGJ5IGl0c2VsZi4KCSAqCgkgKiA8aDQ+RXhhbXBsZTwvaDQ+CgkgKgoJICogICAgICB2YXIgcXVldWUgPSBuZXcgY3JlYXRlanMuTG9hZFF1ZXVlKCk7CgkgKiAgICAgIHF1ZXVlLm9uKCJjb21wbGV0ZSIsIGhhbmRsZUNvbXBsZXRlKTsKCSAqICAgICAgcXVldWUubG9hZE1hbmlmZXN0KGZpbGVBcnJheSwgZmFsc2UpOyAvLyBOb3RlIHRoZSAybmQgYXJndW1lbnQgdGhhdCB0ZWxscyB0aGUgcXVldWUgbm90IHRvIHN0YXJ0IGxvYWRpbmcgeWV0CgkgKiAgICAgIHF1ZXVlLmxvYWQoKTsKCSAqCgkgKiBAbWV0aG9kIGxvYWQKCSAqLwoJcC5sb2FkID0gZnVuY3Rpb24gKCkgewoJCXRoaXMuX2NyZWF0ZVJlcXVlc3QoKTsKCgkJdGhpcy5fcmVxdWVzdC5vbigiY29tcGxldGUiLCB0aGlzLCB0aGlzKTsKCQl0aGlzLl9yZXF1ZXN0Lm9uKCJwcm9ncmVzcyIsIHRoaXMsIHRoaXMpOwoJCXRoaXMuX3JlcXVlc3Qub24oImxvYWRTdGFydCIsIHRoaXMsIHRoaXMpOwoJCXRoaXMuX3JlcXVlc3Qub24oImFib3J0IiwgdGhpcywgdGhpcyk7CgkJdGhpcy5fcmVxdWVzdC5vbigidGltZW91dCIsIHRoaXMsIHRoaXMpOwoJCXRoaXMuX3JlcXVlc3Qub24oImVycm9yIiwgdGhpcywgdGhpcyk7CgoJCXZhciBldnQgPSBuZXcgY3JlYXRlanMuRXZlbnQoImluaXRpYWxpemUiKTsKCQlldnQubG9hZGVyID0gdGhpcy5fcmVxdWVzdDsKCQl0aGlzLmRpc3BhdGNoRXZlbnQoZXZ0KTsKCgkJdGhpcy5fcmVxdWVzdC5sb2FkKCk7Cgl9OwoKCS8qKgoJICogQ2xvc2UgdGhlIHRoZSBpdGVtLiBUaGlzIHdpbGwgc3RvcCBhbnkgb3BlbiByZXF1ZXN0cyAoYWx0aG91Z2ggZG93bmxvYWRzIHVzaW5nIEhUTUwgdGFncyBtYXkgc3RpbGwgY29udGludWUgaW4KCSAqIHRoZSBiYWNrZ3JvdW5kKSwgYnV0IGV2ZW50cyB3aWxsIG5vdCBsb25nZXIgYmUgZGlzcGF0Y2hlZC4KCSAqIEBtZXRob2QgY2FuY2VsCgkgKi8KCXAuY2FuY2VsID0gZnVuY3Rpb24gKCkgewoJCXRoaXMuY2FuY2VsZWQgPSB0cnVlOwoJCXRoaXMuZGVzdHJveSgpOwoJfTsKCgkvKioKCSAqIENsZWFuIHVwIHRoZSBsb2FkZXIuCgkgKiBAbWV0aG9kIGRlc3Ryb3kKCSAqLwoJcC5kZXN0cm95ID0gZnVuY3Rpb24oKSB7CgkJaWYgKHRoaXMuX3JlcXVlc3QpIHsKCQkJdGhpcy5fcmVxdWVzdC5yZW1vdmVBbGxFdmVudExpc3RlbmVycygpOwoJCQl0aGlzLl9yZXF1ZXN0LmRlc3Ryb3koKTsKCQl9CgoJCXRoaXMuX3JlcXVlc3QgPSBudWxsOwoKCQl0aGlzLl9pdGVtID0gbnVsbDsKCQl0aGlzLl9yYXdSZXN1bHQgPSBudWxsOwoJCXRoaXMuX3Jlc3VsdCA9IG51bGw7CgoJCXRoaXMuX2xvYWRJdGVtcyA9IG51bGw7CgoJCXRoaXMucmVtb3ZlQWxsRXZlbnRMaXN0ZW5lcnMoKTsKCX07CgoJLyoqCgkgKiBHZXQgYW55IGl0ZW1zIGxvYWRlZCBpbnRlcm5hbGx5IGJ5IHRoZSBsb2FkZXIuIFRoZSBlbmFibGVzIGxvYWRlcnMgc3VjaCBhcyB7eyNjcm9zc0xpbmsgIk1hbmlmZXN0TG9hZGVyIn19e3svY3Jvc3NMaW5rfX0KCSAqIHRvIGV4cG9zZSBpdGVtcyBpdCBsb2FkcyBpbnRlcm5hbGx5LgoJICogQG1ldGhvZCBnZXRMb2FkZWRJdGVtcwoJICogQHJldHVybiB7QXJyYXl9IEEgbGlzdCBvZiB0aGUgaXRlbXMgbG9hZGVkIGJ5IHRoZSBsb2FkZXIuCgkgKiBAc2luY2UgMC42LjAKCSAqLwoJcC5nZXRMb2FkZWRJdGVtcyA9IGZ1bmN0aW9uICgpIHsKCQlyZXR1cm4gdGhpcy5fbG9hZGVkSXRlbXM7Cgl9OwoKCgkvLyBQcml2YXRlIG1ldGhvZHMKCS8qKgoJICogQ3JlYXRlIGFuIGludGVybmFsIHJlcXVlc3QgdXNlZCBmb3IgbG9hZGluZy4gQnkgZGVmYXVsdCwgYW4ge3sjY3Jvc3NMaW5rICJYSFJSZXF1ZXN0In19e3svY3Jvc3NMaW5rfX0gb3IKCSAqIHt7I2Nyb3NzTGluayAiVGFnUmVxdWVzdCJ9fXt7L2Nyb3NzTGlua319IGlzIGNyZWF0ZWQsIGRlcGVuZGluZyBvbiB0aGUgdmFsdWUgb2Yge3sjY3Jvc3NMaW5rICJwcmVmZXJYSFI6cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fS4KCSAqIE90aGVyIGxvYWRlcnMgbWF5IG92ZXJyaWRlIHRoaXMgdG8gdXNlIGRpZmZlcmVudCByZXF1ZXN0IHR5cGVzLCBzdWNoIGFzIHt7I2Nyb3NzTGluayAiTWFuaWZlc3RMb2FkZXIifX17ey9jcm9zc0xpbmt9fSwKCSAqIHdoaWNoIHVzZXMge3sjY3Jvc3NMaW5rICJKU09OTG9hZGVyIn19e3svY3Jvc3NMaW5rfX0gb3Ige3sjY3Jvc3NMaW5rICJKU09OUExvYWRlciJ9fXt7L2Nyb3NzTGlua319IHVuZGVyIHRoZSBob29kLgoJICogQG1ldGhvZCBfY3JlYXRlUmVxdWVzdAoJICogQHByb3RlY3RlZAoJICovCglwLl9jcmVhdGVSZXF1ZXN0ID0gZnVuY3Rpb24oKSB7CgkJaWYgKCF0aGlzLl9wcmVmZXJYSFIpIHsKCQkJdGhpcy5fcmVxdWVzdCA9IG5ldyBjcmVhdGVqcy5UYWdSZXF1ZXN0KHRoaXMuX2l0ZW0sIHRoaXMuX3RhZyB8fCB0aGlzLl9jcmVhdGVUYWcoKSwgdGhpcy5fdGFnU3JjQXR0cmlidXRlKTsKCQl9IGVsc2UgewoJCQl0aGlzLl9yZXF1ZXN0ID0gbmV3IGNyZWF0ZWpzLlhIUlJlcXVlc3QodGhpcy5faXRlbSk7CgkJfQoJfTsKCgkvKioKCSAqIENyZWF0ZSB0aGUgSFRNTCB0YWcgdXNlZCBmb3IgbG9hZGluZy4gVGhpcyBtZXRob2QgZG9lcyBub3RoaW5nIGJ5IGRlZmF1bHQsIGFuZCBuZWVkcyB0byBiZSBpbXBsZW1lbnRlZAoJICogYnkgbG9hZGVycyB0aGF0IHJlcXVpcmUgdGFnIGxvYWRpbmcuCgkgKiBAbWV0aG9kIF9jcmVhdGVUYWcKCSAqIEBwYXJhbSB7U3RyaW5nfSBzcmMgVGhlIHRhZyBzb3VyY2UKCSAqIEByZXR1cm4ge0hUTUxFbGVtZW50fSBUaGUgdGFnIHRoYXQgd2FzIGNyZWF0ZWQKCSAqIEBwcm90ZWN0ZWQKCSAqLwoJcC5fY3JlYXRlVGFnID0gZnVuY3Rpb24oc3JjKSB7IHJldHVybiBudWxsOyB9OwoKCS8qKgoJICogRGlzcGF0Y2ggYSBsb2Fkc3RhcnQge3sjY3Jvc3NMaW5rICJFdmVudCJ9fXt7L2Nyb3NzTGlua319LiBQbGVhc2Ugc2VlIHRoZSB7eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyL2xvYWRzdGFydDpldmVudCJ9fXt7L2Nyb3NzTGlua319CgkgKiBldmVudCBmb3IgZGV0YWlscyBvbiB0aGUgZXZlbnQgcGF5bG9hZC4KCSAqIEBtZXRob2QgX3NlbmRMb2FkU3RhcnQKCSAqIEBwcm90ZWN0ZWQKCSAqLwoJcC5fc2VuZExvYWRTdGFydCA9IGZ1bmN0aW9uICgpIHsKCQlpZiAodGhpcy5faXNDYW5jZWxlZCgpKSB7IHJldHVybjsgfQoJCXRoaXMuZGlzcGF0Y2hFdmVudCgibG9hZHN0YXJ0Iik7Cgl9OwoKCS8qKgoJICogRGlzcGF0Y2ggYSB7eyNjcm9zc0xpbmsgIlByb2dyZXNzRXZlbnQifX17ey9jcm9zc0xpbmt9fS4KCSAqIEBtZXRob2QgX3NlbmRQcm9ncmVzcwoJICogQHBhcmFtIHtOdW1iZXIgfCBPYmplY3R9IHZhbHVlIFRoZSBwcm9ncmVzcyBvZiB0aGUgbG9hZGVkIGl0ZW0sIG9yIGFuIG9iamVjdCBjb250YWluaW5nIDxjb2RlPmxvYWRlZDwvY29kZT4KCSAqIGFuZCA8Y29kZT50b3RhbDwvY29kZT4gcHJvcGVydGllcy4KCSAqIEBwcm90ZWN0ZWQKCSAqLwoJcC5fc2VuZFByb2dyZXNzID0gZnVuY3Rpb24gKHZhbHVlKSB7CgkJaWYgKHRoaXMuX2lzQ2FuY2VsZWQoKSkgeyByZXR1cm47IH0KCQl2YXIgZXZlbnQgPSBudWxsOwoJCWlmICh0eXBlb2YodmFsdWUpID09ICJudW1iZXIiKSB7CgkJCXRoaXMucHJvZ3Jlc3MgPSB2YWx1ZTsKCQkJZXZlbnQgPSBuZXcgY3JlYXRlanMuUHJvZ3Jlc3NFdmVudCh0aGlzLnByb2dyZXNzKTsKCQl9IGVsc2UgewoJCQlldmVudCA9IHZhbHVlOwoJCQl0aGlzLnByb2dyZXNzID0gdmFsdWUubG9hZGVkIC8gdmFsdWUudG90YWw7CgkJCWV2ZW50LnByb2dyZXNzID0gdGhpcy5wcm9ncmVzczsKCQkJaWYgKGlzTmFOKHRoaXMucHJvZ3Jlc3MpIHx8IHRoaXMucHJvZ3Jlc3MgPT0gSW5maW5pdHkpIHsgdGhpcy5wcm9ncmVzcyA9IDA7IH0KCQl9CgkJdGhpcy5oYXNFdmVudExpc3RlbmVyKCJwcm9ncmVzcyIpICYmIHRoaXMuZGlzcGF0Y2hFdmVudChldmVudCk7Cgl9OwoKCS8qKgoJICogRGlzcGF0Y2ggYSBjb21wbGV0ZSB7eyNjcm9zc0xpbmsgIkV2ZW50In19e3svY3Jvc3NMaW5rfX0uIFBsZWFzZSBzZWUgdGhlIHt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvY29tcGxldGU6ZXZlbnQifX17ey9jcm9zc0xpbmt9fSBldmVudAoJICogQG1ldGhvZCBfc2VuZENvbXBsZXRlCgkgKiBAcHJvdGVjdGVkCgkgKi8KCXAuX3NlbmRDb21wbGV0ZSA9IGZ1bmN0aW9uICgpIHsKCQlpZiAodGhpcy5faXNDYW5jZWxlZCgpKSB7IHJldHVybjsgfQoKCQl0aGlzLmxvYWRlZCA9IHRydWU7CgoJCXZhciBldmVudCA9IG5ldyBjcmVhdGVqcy5FdmVudCgiY29tcGxldGUiKTsKCQlldmVudC5yYXdSZXN1bHQgPSB0aGlzLl9yYXdSZXN1bHQ7CgoJCWlmICh0aGlzLl9yZXN1bHQgIT0gbnVsbCkgewoJCQlldmVudC5yZXN1bHQgPSB0aGlzLl9yZXN1bHQ7CgkJfQoKCQl0aGlzLmRpc3BhdGNoRXZlbnQoZXZlbnQpOwoJfTsKCgkvKioKCSAqIERpc3BhdGNoIGFuIGVycm9yIHt7I2Nyb3NzTGluayAiRXZlbnQifX17ey9jcm9zc0xpbmt9fS4gUGxlYXNlIHNlZSB0aGUge3sjY3Jvc3NMaW5rICJBYnN0cmFjdExvYWRlci9lcnJvcjpldmVudCJ9fXt7L2Nyb3NzTGlua319CgkgKiBldmVudCBmb3IgZGV0YWlscyBvbiB0aGUgZXZlbnQgcGF5bG9hZC4KCSAqIEBtZXRob2QgX3NlbmRFcnJvcgoJICogQHBhcmFtIHtFcnJvckV2ZW50fSBldmVudCBUaGUgZXZlbnQgb2JqZWN0IGNvbnRhaW5pbmcgc3BlY2lmaWMgZXJyb3IgcHJvcGVydGllcy4KCSAqIEBwcm90ZWN0ZWQKCSAqLwoJcC5fc2VuZEVycm9yID0gZnVuY3Rpb24gKGV2ZW50KSB7CgkJaWYgKHRoaXMuX2lzQ2FuY2VsZWQoKSB8fCAhdGhpcy5oYXNFdmVudExpc3RlbmVyKCJlcnJvciIpKSB7IHJldHVybjsgfQoJCWlmIChldmVudCA9PSBudWxsKSB7CgkJCWV2ZW50ID0gbmV3IGNyZWF0ZWpzLkVycm9yRXZlbnQoIlBSRUxPQURfRVJST1JfRU1QVFkiKTsgLy8gVE9ETzogUG9wdWxhdGUgZXJyb3IKCQl9CgkJdGhpcy5kaXNwYXRjaEV2ZW50KGV2ZW50KTsKCX07CgoJLyoqCgkgKiBEZXRlcm1pbmUgaWYgdGhlIGxvYWQgaGFzIGJlZW4gY2FuY2VsZWQuIFRoaXMgaXMgaW1wb3J0YW50IHRvIGVuc3VyZSB0aGF0IG1ldGhvZCBjYWxscyBvciBhc3luY2hyb25vdXMgZXZlbnRzCgkgKiBkbyBub3QgY2F1c2UgaXNzdWVzIGFmdGVyIHRoZSBxdWV1ZSBoYXMgYmVlbiBjbGVhbmVkIHVwLgoJICogQG1ldGhvZCBfaXNDYW5jZWxlZAoJICogQHJldHVybiB7Qm9vbGVhbn0gSWYgdGhlIGxvYWRlciBoYXMgYmVlbiBjYW5jZWxlZC4KCSAqIEBwcm90ZWN0ZWQKCSAqLwoJcC5faXNDYW5jZWxlZCA9IGZ1bmN0aW9uICgpIHsKCQlpZiAod2luZG93LmNyZWF0ZWpzID09IG51bGwgfHwgdGhpcy5jYW5jZWxlZCkgewoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgkJcmV0dXJuIGZhbHNlOwoJfTsKCgkvKioKCSAqIEEgY3VzdG9tIHJlc3VsdCBmb3JtYXR0ZXIgZnVuY3Rpb24sIHdoaWNoIGlzIGNhbGxlZCBqdXN0IGJlZm9yZSBhIHJlcXVlc3QgZGlzcGF0Y2hlcyBpdHMgY29tcGxldGUgZXZlbnQuIE1vc3QKCSAqIGxvYWRlciB0eXBlcyBhbHJlYWR5IGhhdmUgYW4gaW50ZXJuYWwgZm9ybWF0dGVyLCBidXQgdGhpcyBjYW4gYmUgdXNlci1vdmVycmlkZGVuIGZvciBjdXN0b20gZm9ybWF0dGluZy4gVGhlCgkgKiBmb3JtYXR0ZWQgcmVzdWx0IHdpbGwgYmUgYXZhaWxhYmxlIG9uIExvYWRlcnMgdXNpbmcge3sjY3Jvc3NMaW5rICJnZXRSZXN1bHQifX17ey9jcm9zc0xpbmt9fSwgYW5kIHBhc3NpbmcgYHRydWVgLgoJICogQHByb3BlcnR5IHJlc3VsdEZvcm1hdHRlcgoJICogQHR5cGUgRnVuY3Rpb24KCSAqIEByZXR1cm4ge09iamVjdH0gVGhlIGZvcm1hdHRlZCByZXN1bHQKCSAqIEBzaW5jZSAwLjYuMAoJICovCglwLnJlc3VsdEZvcm1hdHRlciA9IG51bGw7IC8vVE9ETzogQWRkIHN1cHBvcnQgZm9yIGFzeW5jIGZvcm1hdHRpbmcuCgoJLyoqCgkgKiBIYW5kbGUgZXZlbnRzIGZyb20gaW50ZXJuYWwgcmVxdWVzdHMuIEJ5IGRlZmF1bHQsIGxvYWRlcnMgd2lsbCBoYW5kbGUsIGFuZCByZWRpc3BhdGNoIHRoZSBuZWNlc3NhcnkgZXZlbnRzLCBidXQKCSAqIHRoaXMgbWV0aG9kIGNhbiBiZSBvdmVycmlkZGVuIGZvciBjdXN0b20gYmVoYXZpb3Vycy4KCSAqIEBtZXRob2QgaGFuZGxlRXZlbnQKCSAqIEBwYXJhbSB7RXZlbnR9IFRoZSBldmVudCB0aGF0IHRoZSBpbnRlcm5hbCByZXF1ZXN0IGRpc3BhdGNoZXMuCgkgKiBAcHJvdGVjdGVkCgkgKiBAc2luY2UgMC42LjAKCSAqLwoJcC5oYW5kbGVFdmVudCA9IGZ1bmN0aW9uIChldmVudCkgewoJCXN3aXRjaCAoZXZlbnQudHlwZSkgewoJCQljYXNlICJjb21wbGV0ZSI6CgkJCQl0aGlzLl9yYXdSZXN1bHQgPSBldmVudC50YXJnZXQuX3Jlc3BvbnNlOwoJCQkJdmFyIHJlc3VsdCA9IHRoaXMucmVzdWx0Rm9ybWF0dGVyICYmIHRoaXMucmVzdWx0Rm9ybWF0dGVyKHRoaXMpOwoJCQkJdmFyIF90aGlzID0gdGhpczsKCQkJCWlmIChyZXN1bHQgaW5zdGFuY2VvZiBGdW5jdGlvbikgewoJCQkJCXJlc3VsdChmdW5jdGlvbihyZXN1bHQpIHsKCQkJCQkJX3RoaXMuX3Jlc3VsdCA9IHJlc3VsdDsKCQkJCQkJX3RoaXMuX3NlbmRDb21wbGV0ZSgpOwoJCQkJCX0pOwoJCQkJfSBlbHNlIHsKCQkJCQl0aGlzLl9yZXN1bHQgPSAgcmVzdWx0IHx8IHRoaXMuX3Jhd1Jlc3VsdDsKCQkJCQl0aGlzLl9zZW5kQ29tcGxldGUoKTsKCQkJCX0KCQkJCWJyZWFrOwoJCQljYXNlICJwcm9ncmVzcyI6CgkJCQl0aGlzLl9zZW5kUHJvZ3Jlc3MoZXZlbnQpOwoJCQkJYnJlYWs7CgkJCWNhc2UgImVycm9yIjoKCQkJCXRoaXMuX3NlbmRFcnJvcihldmVudCk7CgkJCQlicmVhazsKCQkJY2FzZSAibG9hZHN0YXJ0IjoKCQkJCXRoaXMuX3NlbmRMb2FkU3RhcnQoKTsKCQkJCWJyZWFrOwoJCQljYXNlICJhYm9ydCI6CgkJCWNhc2UgInRpbWVvdXQiOgoJCQkJaWYgKCF0aGlzLl9pc0NhbmNlbGVkKCkpIHsKCQkJCQl0aGlzLmRpc3BhdGNoRXZlbnQoZXZlbnQudHlwZSk7CgkJCQl9CgkJCQlicmVhazsKCQl9Cgl9OwoKCS8qKgoJICogQG1ldGhvZCBidWlsZFBhdGgKCSAqIEBwcm90ZWN0ZWQKCSAqIEBkZXByZWNhdGVkIFVzZSB0aGUge3sjY3Jvc3NMaW5rICJSZXF1ZXN0VXRpbHMifX17ey9jcm9zc0xpbmt9fSBtZXRob2Qge3sjY3Jvc3NMaW5rICJSZXF1ZXN0VXRpbHMvYnVpbGRQYXRoIn19e3svY3Jvc3NMaW5rfX0KCSAqIGluc3RlYWQuCgkgKi8KCXAuYnVpbGRQYXRoID0gZnVuY3Rpb24gKHNyYywgZGF0YSkgewoJCXJldHVybiBjcmVhdGVqcy5SZXF1ZXN0VXRpbHMuYnVpbGRQYXRoKHNyYywgZGF0YSk7Cgl9OwoKCS8qKgoJICogQG1ldGhvZCB0b1N0cmluZwoJICogQHJldHVybiB7U3RyaW5nfSBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgaW5zdGFuY2UuCgkgKi8KCXAudG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7CgkJcmV0dXJuICJbUHJlbG9hZEpTIEFic3RyYWN0TG9hZGVyXSI7Cgl9OwoKCWNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyID0gY3JlYXRlanMucHJvbW90ZShBYnN0cmFjdExvYWRlciwgIkV2ZW50RGlzcGF0Y2hlciIpOwoKfSgpKTsKCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi8vIEFic3RyYWN0TWVkaWFMb2FkZXIuanMKLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCnRoaXMuY3JlYXRlanMgPSB0aGlzLmNyZWF0ZWpzIHx8IHt9OwoKKGZ1bmN0aW9uICgpIHsKCSJ1c2Ugc3RyaWN0IjsKCgkvLyBjb25zdHJ1Y3RvcgoJLyoqCgkgKiBUaGUgQWJzdHJhY3RNZWRpYUxvYWRlciBpcyBhIGJhc2UgY2xhc3MgdGhhdCBoYW5kbGVzIHNvbWUgb2YgdGhlIHNoYXJlZCBtZXRob2RzIGFuZCBwcm9wZXJ0aWVzIG9mIGxvYWRlcnMgdGhhdAoJICogaGFuZGxlIEhUTUwgbWVkaWEgZWxlbWVudHMsIHN1Y2ggYXMgVmlkZW8gYW5kIEF1ZGlvLgoJICogQGNsYXNzIEFic3RyYWN0TWVkaWFMb2FkZXIKCSAqIEBwYXJhbSB7TG9hZEl0ZW18T2JqZWN0fSBsb2FkSXRlbQoJICogQHBhcmFtIHtCb29sZWFufSBwcmVmZXJYSFIKCSAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlIFRoZSB0eXBlIG9mIG1lZGlhIHRvIGxvYWQuIFVzdWFsbHkgInZpZGVvIiBvciAiYXVkaW8iLgoJICogQGNvbnN0cnVjdG9yCgkgKi8KCWZ1bmN0aW9uIEFic3RyYWN0TWVkaWFMb2FkZXIobG9hZEl0ZW0sIHByZWZlclhIUiwgdHlwZSkgewoJCXRoaXMuQWJzdHJhY3RMb2FkZXJfY29uc3RydWN0b3IobG9hZEl0ZW0sIHByZWZlclhIUiwgdHlwZSk7CgoJCS8vIHB1YmxpYyBwcm9wZXJ0aWVzCgkJdGhpcy5yZXN1bHRGb3JtYXR0ZXIgPSB0aGlzLl9mb3JtYXRSZXN1bHQ7CgoJCS8vIHByb3RlY3RlZCBwcm9wZXJ0aWVzCgkJdGhpcy5fdGFnU3JjQXR0cmlidXRlID0gInNyYyI7Cgl9OwoKCXZhciBwID0gY3JlYXRlanMuZXh0ZW5kKEFic3RyYWN0TWVkaWFMb2FkZXIsIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyKTsKCgkvLyBzdGF0aWMgcHJvcGVydGllcwoJLy8gcHVibGljIG1ldGhvZHMKCXAubG9hZCA9IGZ1bmN0aW9uICgpIHsKCQkvLyBUYWdSZXF1ZXN0IHdpbGwgaGFuZGxlIG1vc3Qgb2YgdGhpcywgYnV0IFNvdW5kIC8gVmlkZW8gbmVlZCBhIGZldyBjdXN0b20gcHJvcGVydGllcywgc28ganVzdCBoYW5kbGUgdGhlbSBoZXJlLgoJCWlmICghdGhpcy5fdGFnKSB7CgkJCXRoaXMuX3RhZyA9IHRoaXMuX2NyZWF0ZVRhZyh0aGlzLl9pdGVtLnNyYyk7CgkJfQoKCQl0aGlzLl90YWcucHJlbG9hZCA9ICJhdXRvIjsKCQl0aGlzLl90YWcubG9hZCgpOwoKCQl0aGlzLkFic3RyYWN0TG9hZGVyX2xvYWQoKTsKCX07CgoJLy8gcHJvdGVjdGVkIG1ldGhvZHMKCS8qKgoJICogQ3JlYXRlcyBhIG5ldyB0YWcgZm9yIGxvYWRpbmcgaWYgaXQgZG9lc24ndCBleGlzdCB5ZXQuCgkgKiBAbWV0aG9kIF9jcmVhdGVUYWcKCSAqIEBwcml2YXRlCgkgKi8KCXAuX2NyZWF0ZVRhZyA9IGZ1bmN0aW9uICgpIHt9OwoKCglwLl9jcmVhdGVSZXF1ZXN0ID0gZnVuY3Rpb24oKSB7CgkJaWYgKCF0aGlzLl9wcmVmZXJYSFIpIHsKCQkJdGhpcy5fcmVxdWVzdCA9IG5ldyBjcmVhdGVqcy5NZWRpYVRhZ1JlcXVlc3QodGhpcy5faXRlbSwgdGhpcy5fdGFnIHx8IHRoaXMuX2NyZWF0ZVRhZygpLCB0aGlzLl90YWdTcmNBdHRyaWJ1dGUpOwoJCX0gZWxzZSB7CgkJCXRoaXMuX3JlcXVlc3QgPSBuZXcgY3JlYXRlanMuWEhSUmVxdWVzdCh0aGlzLl9pdGVtKTsKCQl9Cgl9OwoKCS8qKgoJICogVGhlIHJlc3VsdCBmb3JtYXR0ZXIgZm9yIG1lZGlhIGZpbGVzLgoJICogQG1ldGhvZCBfZm9ybWF0UmVzdWx0CgkgKiBAcGFyYW0ge0Fic3RyYWN0TG9hZGVyfSBsb2FkZXIKCSAqIEByZXR1cm5zIHtIVE1MVmlkZW9FbGVtZW50fEhUTUxBdWRpb0VsZW1lbnR9CgkgKiBAcHJpdmF0ZQoJICovCglwLl9mb3JtYXRSZXN1bHQgPSBmdW5jdGlvbiAobG9hZGVyKSB7CgkJdGhpcy5fdGFnLnJlbW92ZUV2ZW50TGlzdGVuZXIgJiYgdGhpcy5fdGFnLnJlbW92ZUV2ZW50TGlzdGVuZXIoImNhbnBsYXl0aHJvdWdoIiwgdGhpcy5fbG9hZGVkSGFuZGxlcik7CgkJdGhpcy5fdGFnLm9uc3RhbGxlZCA9IG51bGw7CgkJaWYgKHRoaXMuX3ByZWZlclhIUikgewoJCQlsb2FkZXIuZ2V0VGFnKCkuc3JjID0gbG9hZGVyLmdldFJlc3VsdCh0cnVlKTsKCQl9CgkJcmV0dXJuIGxvYWRlci5nZXRUYWcoKTsKCX07CgoJY3JlYXRlanMuQWJzdHJhY3RNZWRpYUxvYWRlciA9IGNyZWF0ZWpzLnByb21vdGUoQWJzdHJhY3RNZWRpYUxvYWRlciwgIkFic3RyYWN0TG9hZGVyIik7Cgp9KCkpOwoKLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLy8gQWJzdHJhY3RSZXF1ZXN0LmpzCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgp0aGlzLmNyZWF0ZWpzID0gdGhpcy5jcmVhdGVqcyB8fCB7fTsKCihmdW5jdGlvbiAoKSB7CgkidXNlIHN0cmljdCI7CgoJLyoqCgkgKiBBIGJhc2UgY2xhc3MgZm9yIGFjdHVhbCBkYXRhIHJlcXVlc3RzLCBzdWNoIGFzIHt7I2Nyb3NzTGluayAiWEhSUmVxdWVzdCJ9fXt7L2Nyb3NzTGlua319LCB7eyNjcm9zc0xpbmsgIlRhZ1JlcXVlc3QifX17ey9jcm9zc0xpbmt9fSwKCSAqIGFuZCB7eyNjcm9zc0xpbmsgIk1lZGlhUmVxdWVzdCJ9fXt7L2Nyb3NzTGlua319LiBQcmVsb2FkSlMgbG9hZGVycyB3aWxsIHR5cGljYWxseSB1c2UgYSBkYXRhIGxvYWRlciB1bmRlciB0aGUKCSAqIGhvb2QgdG8gZ2V0IGRhdGEuCgkgKiBAY2xhc3MgQWJzdHJhY3RSZXF1ZXN0CgkgKiBAcGFyYW0ge0xvYWRJdGVtfSBpdGVtCgkgKiBAY29uc3RydWN0b3IKCSAqLwoJdmFyIEFic3RyYWN0UmVxdWVzdCA9IGZ1bmN0aW9uIChpdGVtKSB7CgkJdGhpcy5faXRlbSA9IGl0ZW07Cgl9OwoKCXZhciBwID0gY3JlYXRlanMuZXh0ZW5kKEFic3RyYWN0UmVxdWVzdCwgY3JlYXRlanMuRXZlbnREaXNwYXRjaGVyKTsKCgkvLyBwdWJsaWMgbWV0aG9kcwoJLyoqCgkgKiBCZWdpbiBhIGxvYWQuCgkgKiBAbWV0aG9kIGxvYWQKCSAqLwoJcC5sb2FkID0gIGZ1bmN0aW9uKCkge307CgoJLyoqCgkgKiBDbGVhbiB1cCBhIHJlcXVlc3QuCgkgKiBAbWV0aG9kIGRlc3Ryb3kKCSAqLwoJcC5kZXN0cm95ID0gZnVuY3Rpb24oKSB7fTsKCgkvKioKCSAqIENhbmNlbCBhbiBpbi1wcm9ncmVzcyByZXF1ZXN0LgoJICogQG1ldGhvZCBjYW5jZWwKCSAqLwoJcC5jYW5jZWwgPSBmdW5jdGlvbigpIHt9OwoKCWNyZWF0ZWpzLkFic3RyYWN0UmVxdWVzdCA9IGNyZWF0ZWpzLnByb21vdGUoQWJzdHJhY3RSZXF1ZXN0LCAiRXZlbnREaXNwYXRjaGVyIik7Cgp9KCkpOwoKLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLy8gVGFnUmVxdWVzdC5qcwovLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoKdGhpcy5jcmVhdGVqcyA9IHRoaXMuY3JlYXRlanMgfHwge307CgooZnVuY3Rpb24gKCkgewoJInVzZSBzdHJpY3QiOwoKCS8vIGNvbnN0cnVjdG9yCgkvKioKCSAqIEFuIHt7I2Nyb3NzTGluayAiQWJzdHJhY3RSZXF1ZXN0In19e3svY3Jvc3NMaW5rfX0gdGhhdCBsb2FkcyBIVE1MIHRhZ3MsIHN1Y2ggYXMgaW1hZ2VzIGFuZCBzY3JpcHRzLgoJICogQGNsYXNzIFRhZ1JlcXVlc3QKCSAqIEBwYXJhbSB7TG9hZEl0ZW19IGxvYWRJdGVtCgkgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSB0YWcKCSAqIEBwYXJhbSB7U3RyaW5nfSBzcmNBdHRyaWJ1dGUgVGhlIHRhZyBhdHRyaWJ1dGUgdGhhdCBzcGVjaWZpZXMgdGhlIHNvdXJjZSwgc3VjaCBhcyAic3JjIiwgImhyZWYiLCBldGMuCgkgKi8KCWZ1bmN0aW9uIFRhZ1JlcXVlc3QobG9hZEl0ZW0sIHRhZywgc3JjQXR0cmlidXRlKSB7CgkJdGhpcy5BYnN0cmFjdFJlcXVlc3RfY29uc3RydWN0b3IobG9hZEl0ZW0pOwoKCQkvLyBwcm90ZWN0ZWQgcHJvcGVydGllcwoJCS8qKgoJCSAqIFRoZSBIVE1MIHRhZyBpbnN0YW5jZSB0aGF0IGlzIHVzZWQgdG8gbG9hZC4KCQkgKiBAcHJvcGVydHkgX3RhZwoJCSAqIEB0eXBlIHtIVE1MRWxlbWVudH0KCQkgKiBAcHJvdGVjdGVkCgkJICovCgkJdGhpcy5fdGFnID0gdGFnOwoKCQkvKioKCQkgKiBUaGUgdGFnIGF0dHJpYnV0ZSB0aGF0IHNwZWNpZmllcyB0aGUgc291cmNlLCBzdWNoIGFzICJzcmMiLCAiaHJlZiIsIGV0Yy4KCQkgKiBAcHJvcGVydHkgX3RhZ1NyY0F0dHJpYnV0ZQoJCSAqIEB0eXBlIHtTdHJpbmd9CgkJICogQHByb3RlY3RlZAoJCSAqLwoJCXRoaXMuX3RhZ1NyY0F0dHJpYnV0ZSA9IHNyY0F0dHJpYnV0ZTsKCgkJLyoqCgkJICogQSBtZXRob2QgY2xvc3VyZSB1c2VkIGZvciBoYW5kbGluZyB0aGUgdGFnIGxvYWQgZXZlbnQuCgkJICogQHByb3BlcnR5IF9sb2FkZWRIYW5kbGVyCgkJICogQHR5cGUge0Z1bmN0aW9ufQoJCSAqIEBwcml2YXRlCgkJICovCgkJdGhpcy5fbG9hZGVkSGFuZGxlciA9IGNyZWF0ZWpzLnByb3h5KHRoaXMuX2hhbmRsZVRhZ0NvbXBsZXRlLCB0aGlzKTsKCgkJLyoqCgkJICogRGV0ZXJtaW5lcyBpZiB0aGUgZWxlbWVudCB3YXMgYWRkZWQgdG8gdGhlIERPTSBhdXRvbWF0aWNhbGx5IGJ5IFByZWxvYWRKUywgc28gaXQgY2FuIGJlIGNsZWFuZWQgdXAgYWZ0ZXIuCgkJICogQHByb3BlcnR5IF9hZGRlZFRvRE9NCgkJICogQHR5cGUge0Jvb2xlYW59CgkJICogQHByaXZhdGUKCQkgKi8KCQl0aGlzLl9hZGRlZFRvRE9NID0gZmFsc2U7CgoJCS8qKgoJCSAqIERldGVybWluZXMgd2hhdCB0aGUgdGFncyBpbml0aWFsIHN0eWxlLnZpc2liaWxpdHkgd2FzLCBzbyB3ZSBjYW4gc2V0IGl0IGNvcnJlY3RseSBhZnRlciBhIGxvYWQuCgkJICoKCQkgKiBAdHlwZSB7bnVsbH0KCQkgKiBAcHJpdmF0ZQoJCSAqLwoJCXRoaXMuX3N0YXJ0VGFnVmlzaWJpbGl0eSA9IG51bGw7Cgl9OwoKCXZhciBwID0gY3JlYXRlanMuZXh0ZW5kKFRhZ1JlcXVlc3QsIGNyZWF0ZWpzLkFic3RyYWN0UmVxdWVzdCk7CgoJLy8gcHVibGljIG1ldGhvZHMKCXAubG9hZCA9IGZ1bmN0aW9uICgpIHsKCQlpZiAodGhpcy5fdGFnLnBhcmVudE5vZGUgPT0gbnVsbCkgewoJCQl3aW5kb3cuZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh0aGlzLl90YWcpOwoJCQl0aGlzLl9hZGRlZFRvRE9NID0gdHJ1ZTsKCQl9CgoJCXRoaXMuX3RhZy5vbmxvYWQgPSBjcmVhdGVqcy5wcm94eSh0aGlzLl9oYW5kbGVUYWdDb21wbGV0ZSwgdGhpcyk7CgkJdGhpcy5fdGFnLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGNyZWF0ZWpzLnByb3h5KHRoaXMuX2hhbmRsZVJlYWR5U3RhdGVDaGFuZ2UsIHRoaXMpOwoKCQl2YXIgZXZ0ID0gbmV3IGNyZWF0ZWpzLkV2ZW50KCJpbml0aWFsaXplIik7CgkJZXZ0LmxvYWRlciA9IHRoaXMuX3RhZzsKCgkJdGhpcy5kaXNwYXRjaEV2ZW50KGV2dCk7CgoJCXRoaXMuX2hpZGVUYWcoKTsKCgkJdGhpcy5fdGFnW3RoaXMuX3RhZ1NyY0F0dHJpYnV0ZV0gPSB0aGlzLl9pdGVtLnNyYzsKCX07CgoJcC5kZXN0cm95ID0gZnVuY3Rpb24oKSB7CgkJdGhpcy5fY2xlYW4oKTsKCQl0aGlzLl90YWcgPSBudWxsOwoKCQl0aGlzLkFic3RyYWN0UmVxdWVzdF9kZXN0cm95KCk7Cgl9OwoKCS8vIHByaXZhdGUgbWV0aG9kcwoJLyoqCgkgKiBIYW5kbGUgdGhlIHJlYWR5U3RhdGVDaGFuZ2UgZXZlbnQgZnJvbSBhIHRhZy4gV2UgbmVlZCB0aGlzIGluIHBsYWNlIG9mIHRoZSBgb25sb2FkYCBjYWxsYmFjayAobWFpbmx5IFNDUklQVAoJICogYW5kIExJTksgdGFncyksIGJ1dCBvdGhlciBjYXNlcyBtYXkgZXhpc3QuCgkgKiBAbWV0aG9kIF9oYW5kbGVSZWFkeVN0YXRlQ2hhbmdlCgkgKiBAcHJpdmF0ZQoJICovCglwLl9oYW5kbGVSZWFkeVN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKCkgewoJCWNsZWFyVGltZW91dCh0aGlzLl9sb2FkVGltZW91dCk7CgkJLy8gVGhpcyBpcyBzdHJpY3RseSBmb3IgdGFncyBpbiBicm93c2VycyB0aGF0IGRvIG5vdCBzdXBwb3J0IG9ubG9hZC4KCQl2YXIgdGFnID0gdGhpcy5fdGFnOwoKCQkvLyBDb21wbGV0ZSBpcyBmb3Igb2xkIElFIHN1cHBvcnQuCgkJaWYgKHRhZy5yZWFkeVN0YXRlID09ICJsb2FkZWQiIHx8IHRhZy5yZWFkeVN0YXRlID09ICJjb21wbGV0ZSIpIHsKCQkJdGhpcy5faGFuZGxlVGFnQ29tcGxldGUoKTsKCQl9Cgl9OwoKCS8qKgoJICogSGFuZGxlIHRoZSB0YWcncyBvbmxvYWQgY2FsbGJhY2suCgkgKiBAbWV0aG9kIF9oYW5kbGVUYWdDb21wbGV0ZQoJICogQHByaXZhdGUKCSAqLwoJcC5faGFuZGxlVGFnQ29tcGxldGUgPSBmdW5jdGlvbiAoKSB7CgkJdGhpcy5fcmF3UmVzdWx0ID0gdGhpcy5fdGFnOwoJCXRoaXMuX3Jlc3VsdCA9IHRoaXMucmVzdWx0Rm9ybWF0dGVyICYmIHRoaXMucmVzdWx0Rm9ybWF0dGVyKHRoaXMpIHx8IHRoaXMuX3Jhd1Jlc3VsdDsKCgkJdGhpcy5fY2xlYW4oKTsKCQl0aGlzLl9zaG93VGFnKCk7CgoJCXRoaXMuZGlzcGF0Y2hFdmVudCgiY29tcGxldGUiKTsKCX07CgoJLyoqCgkgKiBSZW1vdmUgZXZlbnQgbGlzdGVuZXJzLCBidXQgZG9uJ3QgZGVzdHJveSB0aGUgcmVxdWVzdCBvYmplY3QKCSAqIEBtZXRob2QgX2NsZWFuCgkgKiBAcHJpdmF0ZQoJICovCglwLl9jbGVhbiA9IGZ1bmN0aW9uKCkgewoJCXRoaXMuX3RhZy5vbmxvYWQgPSBudWxsOwoJCXRoaXMuX3RhZy5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBudWxsOwoJCWlmICh0aGlzLl9hZGRlZFRvRE9NICYmIHRoaXMuX3RhZy5wYXJlbnROb2RlICE9IG51bGwpIHsKCQkJdGhpcy5fdGFnLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5fdGFnKTsKCQl9Cgl9OwoKCXAuX2hpZGVUYWcgPSBmdW5jdGlvbigpIHsKCQl0aGlzLl9zdGFydFRhZ1Zpc2liaWxpdHkgPSB0aGlzLl90YWcuc3R5bGUudmlzaWJpbGl0eTsKCQl0aGlzLl90YWcuc3R5bGUudmlzaWJpbGl0eSA9ICJoaWRkZW4iOwoJfTsKCglwLl9zaG93VGFnID0gZnVuY3Rpb24oKSB7CgkJdGhpcy5fdGFnLnN0eWxlLnZpc2liaWxpdHkgPSB0aGlzLl9zdGFydFRhZ1Zpc2liaWxpdHk7Cgl9OwoKCS8qKgoJICogSGFuZGxlIGEgc3RhbGxlZCBhdWRpbyBldmVudC4gVGhlIG1haW4gcGxhY2UgdGhpcyBoYXBwZW5zIGlzIHdpdGggSFRNTEF1ZGlvIGluIENocm9tZSB3aGVuIHBsYXlpbmcgYmFjayBhdWRpbwoJICogdGhhdCBpcyBhbHJlYWR5IGluIGEgbG9hZCwgYnV0IG5vdCBjb21wbGV0ZS4KCSAqIEBtZXRob2QgX2hhbmRsZVN0YWxsZWQKCSAqIEBwcml2YXRlCgkgKi8KCXAuX2hhbmRsZVN0YWxsZWQgPSBmdW5jdGlvbiAoKSB7CgkJLy9JZ25vcmUsIGxldCB0aGUgdGltZW91dCB0YWtlIGNhcmUgb2YgaXQuIFNvbWV0aW1lcyBpdHMgbm90IHJlYWxseSBzdG9wcGVkLgoJfTsKCgljcmVhdGVqcy5UYWdSZXF1ZXN0ID0gY3JlYXRlanMucHJvbW90ZShUYWdSZXF1ZXN0LCAiQWJzdHJhY3RSZXF1ZXN0Iik7Cgp9KCkpOwoKLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLy8gTWVkaWFUYWdSZXF1ZXN0LmpzCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgp0aGlzLmNyZWF0ZWpzID0gdGhpcy5jcmVhdGVqcyB8fCB7fTsKCihmdW5jdGlvbiAoKSB7CgkidXNlIHN0cmljdCI7CgoJLy8gY29uc3RydWN0b3IKCS8qKgoJICogQW4ge3sjY3Jvc3NMaW5rICJUYWdSZXF1ZXN0In19e3svY3Jvc3NMaW5rfX0gdGhhdCBsb2FkcyBIVE1MIHRhZ3MgZm9yIHZpZGVvIGFuZCBhdWRpby4KCSAqIEBjbGFzcyBNZWRpYVRhZ1JlcXVlc3QKCSAqIEBwYXJhbSB7TG9hZEl0ZW19IGxvYWRJdGVtCgkgKiBAcGFyYW0ge0hUTUxBdWRpb0VsZW1lbnR8SFRNTFZpZGVvRWxlbWVudH0gdGFnCgkgKiBAcGFyYW0ge1N0cmluZ30gc3JjQXR0cmlidXRlIFRoZSB0YWcgYXR0cmlidXRlIHRoYXQgc3BlY2lmaWVzIHRoZSBzb3VyY2UsIHN1Y2ggYXMgInNyYyIsICJocmVmIiwgZXRjLgoJICogQGNvbnN0cnVjdG9yCgkgKi8KCWZ1bmN0aW9uIE1lZGlhVGFnUmVxdWVzdChsb2FkSXRlbSwgdGFnLCBzcmNBdHRyaWJ1dGUpIHsKCQl0aGlzLkFic3RyYWN0UmVxdWVzdF9jb25zdHJ1Y3Rvcihsb2FkSXRlbSk7CgoJCS8vIHByb3RlY3RlZCBwcm9wZXJ0aWVzCgkJdGhpcy5fdGFnID0gdGFnOwoJCXRoaXMuX3RhZ1NyY0F0dHJpYnV0ZSA9IHNyY0F0dHJpYnV0ZTsKCQl0aGlzLl9sb2FkZWRIYW5kbGVyID0gY3JlYXRlanMucHJveHkodGhpcy5faGFuZGxlVGFnQ29tcGxldGUsIHRoaXMpOwoJfTsKCgl2YXIgcCA9IGNyZWF0ZWpzLmV4dGVuZChNZWRpYVRhZ1JlcXVlc3QsIGNyZWF0ZWpzLlRhZ1JlcXVlc3QpOwoJdmFyIHMgPSBNZWRpYVRhZ1JlcXVlc3Q7CgoJLy8gcHVibGljIG1ldGhvZHMKCXAubG9hZCA9IGZ1bmN0aW9uICgpIHsKCQl0aGlzLl90YWcub25zdGFsbGVkID0gY3JlYXRlanMucHJveHkodGhpcy5faGFuZGxlU3RhbGxlZCwgdGhpcyk7CgkJdGhpcy5fdGFnLm9ucHJvZ3Jlc3MgPSBjcmVhdGVqcy5wcm94eSh0aGlzLl9oYW5kbGVQcm9ncmVzcywgdGhpcyk7CgoJCS8vIFRoaXMgd2lsbCB0ZWxsIHVzIHdoZW4gYXVkaW8gaXMgYnVmZmVyZWQgZW5vdWdoIHRvIHBsYXkgdGhyb3VnaCwgYnV0IG5vdCB3aGVuIGl0cyBsb2FkZWQuCgkJLy8gVGhlIHRhZyBkb2Vzbid0IGtlZXAgbG9hZGluZyBpbiBDaHJvbWUgb25jZSBlbm91Z2ggaGFzIGJ1ZmZlcmVkLCBhbmQgd2UgaGF2ZSBkZWNpZGVkIHRoYXQgYmVoYXZpb3VyIGlzIHN1ZmZpY2llbnQuCgkJdGhpcy5fdGFnLmFkZEV2ZW50TGlzdGVuZXIgJiYgdGhpcy5fdGFnLmFkZEV2ZW50TGlzdGVuZXIoImNhbnBsYXl0aHJvdWdoIiwgdGhpcy5fbG9hZGVkSGFuZGxlciwgZmFsc2UpOyAvLyBjYW5wbGF5dGhyb3VnaCBjYWxsYmFjayBkb2Vzbid0IHdvcmsgaW4gQ2hyb21lLCBzbyB3ZSB1c2UgYW4gZXZlbnQuCgoJCXRoaXMuVGFnUmVxdWVzdF9sb2FkKCk7Cgl9OwoKCS8vIHByaXZhdGUgbWV0aG9kcwoJcC5faGFuZGxlUmVhZHlTdGF0ZUNoYW5nZSA9IGZ1bmN0aW9uICgpIHsKCQljbGVhclRpbWVvdXQodGhpcy5fbG9hZFRpbWVvdXQpOwoJCS8vIFRoaXMgaXMgc3RyaWN0bHkgZm9yIHRhZ3MgaW4gYnJvd3NlcnMgdGhhdCBkbyBub3Qgc3VwcG9ydCBvbmxvYWQuCgkJdmFyIHRhZyA9IHRoaXMuX3RhZzsKCgkJLy8gQ29tcGxldGUgaXMgZm9yIG9sZCBJRSBzdXBwb3J0LgoJCWlmICh0YWcucmVhZHlTdGF0ZSA9PSAibG9hZGVkIiB8fCB0YWcucmVhZHlTdGF0ZSA9PSAiY29tcGxldGUiKSB7CgkJCXRoaXMuX2hhbmRsZVRhZ0NvbXBsZXRlKCk7CgkJfQoJfTsKCglwLl9oYW5kbGVTdGFsbGVkID0gZnVuY3Rpb24gKCkgewoJCS8vSWdub3JlLCBsZXQgdGhlIHRpbWVvdXQgdGFrZSBjYXJlIG9mIGl0LiBTb21ldGltZXMgaXRzIG5vdCByZWFsbHkgc3RvcHBlZC4KCX07CgoJLyoqCgkgKiBBbiBYSFIgcmVxdWVzdCBoYXMgcmVwb3J0ZWQgcHJvZ3Jlc3MuCgkgKiBAbWV0aG9kIF9oYW5kbGVQcm9ncmVzcwoJICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFRoZSBYSFIgcHJvZ3Jlc3MgZXZlbnQuCgkgKiBAcHJpdmF0ZQoJICovCglwLl9oYW5kbGVQcm9ncmVzcyA9IGZ1bmN0aW9uIChldmVudCkgewoJCWlmICghZXZlbnQgfHwgZXZlbnQubG9hZGVkID4gMCAmJiBldmVudC50b3RhbCA9PSAwKSB7CgkJCXJldHVybjsgLy8gU29tZXRpbWVzIHdlIGdldCBubyAidG90YWwiLCBzbyBqdXN0IGlnbm9yZSB0aGUgcHJvZ3Jlc3MgZXZlbnQuCgkJfQoKCQl2YXIgbmV3RXZlbnQgPSBuZXcgY3JlYXRlanMuUHJvZ3Jlc3NFdmVudChldmVudC5sb2FkZWQsIGV2ZW50LnRvdGFsKTsKCQl0aGlzLmRpc3BhdGNoRXZlbnQobmV3RXZlbnQpOwoJfTsKCgkvLyBwcm90ZWN0ZWQgbWV0aG9kcwoJcC5fY2xlYW4gPSBmdW5jdGlvbiAoKSB7CgkJdGhpcy5fdGFnLnJlbW92ZUV2ZW50TGlzdGVuZXIgJiYgdGhpcy5fdGFnLnJlbW92ZUV2ZW50TGlzdGVuZXIoImNhbnBsYXl0aHJvdWdoIiwgdGhpcy5fbG9hZGVkSGFuZGxlcik7CgkJdGhpcy5fdGFnLm9uc3RhbGxlZCA9IG51bGw7CgkJdGhpcy5fdGFnLm9ucHJvZ3Jlc3MgPSBudWxsOwoKCQl0aGlzLlRhZ1JlcXVlc3RfX2NsZWFuKCk7Cgl9OwoKCWNyZWF0ZWpzLk1lZGlhVGFnUmVxdWVzdCA9IGNyZWF0ZWpzLnByb21vdGUoTWVkaWFUYWdSZXF1ZXN0LCAiVGFnUmVxdWVzdCIpOwoKfSgpKTsKCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi8vIFhIUlJlcXVlc3QuanMKLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCnRoaXMuY3JlYXRlanMgPSB0aGlzLmNyZWF0ZWpzIHx8IHt9OwoKKGZ1bmN0aW9uICgpIHsKCSJ1c2Ugc3RyaWN0IjsKCi8vIGNvbnN0cnVjdG9yCgkvKioKCSAqIEEgcHJlbG9hZGVyIHRoYXQgbG9hZHMgaXRlbXMgdXNpbmcgWEhSIHJlcXVlc3RzLCB1c3VhbGx5IFhNTEh0dHBSZXF1ZXN0LiBIb3dldmVyIFhEb21haW5SZXF1ZXN0cyB3aWxsIGJlIHVzZWQKCSAqIGZvciBjcm9zcy1kb21haW4gcmVxdWVzdHMgaWYgcG9zc2libGUsIGFuZCBvbGRlciB2ZXJzaW9ucyBvZiBJRSBmYWxsIGJhY2sgb24gdG8gQWN0aXZlWCBvYmplY3RzIHdoZW4gbmVjZXNzYXJ5LgoJICogWEhSIHJlcXVlc3RzIGxvYWQgdGhlIGNvbnRlbnQgYXMgdGV4dCBvciBiaW5hcnkgZGF0YSwgcHJvdmlkZSBwcm9ncmVzcyBhbmQgY29uc2lzdGVudCBjb21wbGV0aW9uIGV2ZW50cywgYW5kCgkgKiBjYW4gYmUgY2FuY2VsZWQgZHVyaW5nIGxvYWQuIE5vdGUgdGhhdCBYSFIgaXMgbm90IHN1cHBvcnRlZCBpbiBJRSA2IG9yIGVhcmxpZXIsIGFuZCBpcyBub3QgcmVjb21tZW5kZWQgZm9yCgkgKiBjcm9zcy1kb21haW4gbG9hZGluZy4KCSAqIEBjbGFzcyBYSFJSZXF1ZXN0CgkgKiBAY29uc3RydWN0b3IKCSAqIEBwYXJhbSB7T2JqZWN0fSBpdGVtIFRoZSBvYmplY3QgdGhhdCBkZWZpbmVzIHRoZSBmaWxlIHRvIGxvYWQuIFBsZWFzZSBzZWUgdGhlIHt7I2Nyb3NzTGluayAiTG9hZFF1ZXVlL2xvYWRGaWxlIn19e3svY3Jvc3NMaW5rfX0KCSAqIGZvciBhbiBvdmVydmlldyBvZiBzdXBwb3J0ZWQgZmlsZSBwcm9wZXJ0aWVzLgoJICogQGV4dGVuZHMgQWJzdHJhY3RMb2FkZXIKCSAqLwoJZnVuY3Rpb24gWEhSUmVxdWVzdChpdGVtKSB7CgkJdGhpcy5BYnN0cmFjdFJlcXVlc3RfY29uc3RydWN0b3IoaXRlbSk7CgoJCS8vIHByb3RlY3RlZCBwcm9wZXJ0aWVzCgkJLyoqCgkJICogQSByZWZlcmVuY2UgdG8gdGhlIFhIUiByZXF1ZXN0IHVzZWQgdG8gbG9hZCB0aGUgY29udGVudC4KCQkgKiBAcHJvcGVydHkgX3JlcXVlc3QKCQkgKiBAdHlwZSB7WE1MSHR0cFJlcXVlc3QgfCBYRG9tYWluUmVxdWVzdCB8IEFjdGl2ZVguWE1MSFRUUH0KCQkgKiBAcHJpdmF0ZQoJCSAqLwoJCXRoaXMuX3JlcXVlc3QgPSBudWxsOwoKCQkvKioKCQkgKiBBIG1hbnVhbCBsb2FkIHRpbWVvdXQgdGhhdCBpcyB1c2VkIGZvciBicm93c2VycyB0aGF0IGRvIG5vdCBzdXBwb3J0IHRoZSBvblRpbWVvdXQgZXZlbnQgb24gWEhSIChYSFIgbGV2ZWwgMSwKCQkgKiB0eXBpY2FsbHkgSUU5KS4KCQkgKiBAcHJvcGVydHkgX2xvYWRUaW1lb3V0CgkJICogQHR5cGUge051bWJlcn0KCQkgKiBAcHJpdmF0ZQoJCSAqLwoJCXRoaXMuX2xvYWRUaW1lb3V0ID0gbnVsbDsKCgkJLyoqCgkJICogVGhlIGJyb3dzZXIncyBYSFIgKFhNTEhUVFBSZXF1ZXN0KSB2ZXJzaW9uLiBTdXBwb3J0ZWQgdmVyc2lvbnMgYXJlIDEgYW5kIDIuIFRoZXJlIGlzIG5vIG9mZmljaWFsIHdheSB0byBkZXRlY3QKCQkgKiB0aGUgdmVyc2lvbiwgc28gd2UgdXNlIGNhcGFiaWxpdGllcyB0byBtYWtlIGEgYmVzdCBndWVzcy4KCQkgKiBAcHJvcGVydHkgX3hockxldmVsCgkJICogQHR5cGUge051bWJlcn0KCQkgKiBAZGVmYXVsdCAxCgkJICogQHByaXZhdGUKCQkgKi8KCQl0aGlzLl94aHJMZXZlbCA9IDE7CgoJCS8qKgoJCSAqIFRoZSByZXNwb25zZSBvZiBhIGxvYWRlZCBmaWxlLiBUaGlzIGlzIHNldCBiZWNhdXNlIGl0IGlzIGV4cGVuc2l2ZSB0byBsb29rIHVwIGNvbnN0YW50bHkuIFRoaXMgcHJvcGVydHkgd2lsbCBiZQoJCSAqIG51bGwgdW50aWwgdGhlIGZpbGUgaXMgbG9hZGVkLgoJCSAqIEBwcm9wZXJ0eSBfcmVzcG9uc2UKCQkgKiBAdHlwZSB7bWl4ZWR9CgkJICogQHByaXZhdGUKCQkgKi8KCQl0aGlzLl9yZXNwb25zZSA9IG51bGw7CgoJCS8qKgoJCSAqIFRoZSByZXNwb25zZSBvZiB0aGUgbG9hZGVkIGZpbGUgYmVmb3JlIGl0IGlzIG1vZGlmaWVkLiBJbiBtb3N0IGNhc2VzLCBjb250ZW50IGlzIGNvbnZlcnRlZCBmcm9tIHJhdyB0ZXh0IHRvCgkJICogYW4gSFRNTCB0YWcgb3IgYSBmb3JtYXR0ZWQgb2JqZWN0IHdoaWNoIGlzIHNldCB0byB0aGUgPGNvZGU+cmVzdWx0PC9jb2RlPiBwcm9wZXJ0eSwgYnV0IHRoZSBkZXZlbG9wZXIgbWF5IHN0aWxsCgkJICogd2FudCB0byBhY2Nlc3MgdGhlIHJhdyBjb250ZW50IGFzIGl0IHdhcyBsb2FkZWQuCgkJICogQHByb3BlcnR5IF9yYXdSZXNwb25zZQoJCSAqIEB0eXBlIHtTdHJpbmd8T2JqZWN0fQoJCSAqIEBwcml2YXRlCgkJICovCgkJdGhpcy5fcmF3UmVzcG9uc2UgPSBudWxsOwoKCQl0aGlzLl9jYW5jZWxlZCA9IGZhbHNlOwoKCQkvLyBTZXR1cCBvdXIgZXZlbnQgaGFuZGxlcnMgbm93LgoJCXRoaXMuX2hhbmRsZUxvYWRTdGFydFByb3h5ID0gY3JlYXRlanMucHJveHkodGhpcy5faGFuZGxlTG9hZFN0YXJ0LCB0aGlzKTsKCQl0aGlzLl9oYW5kbGVQcm9ncmVzc1Byb3h5ID0gY3JlYXRlanMucHJveHkodGhpcy5faGFuZGxlUHJvZ3Jlc3MsIHRoaXMpOwoJCXRoaXMuX2hhbmRsZUFib3J0UHJveHkgPSBjcmVhdGVqcy5wcm94eSh0aGlzLl9oYW5kbGVBYm9ydCwgdGhpcyk7CgkJdGhpcy5faGFuZGxlRXJyb3JQcm94eSA9IGNyZWF0ZWpzLnByb3h5KHRoaXMuX2hhbmRsZUVycm9yLCB0aGlzKTsKCQl0aGlzLl9oYW5kbGVUaW1lb3V0UHJveHkgPSBjcmVhdGVqcy5wcm94eSh0aGlzLl9oYW5kbGVUaW1lb3V0LCB0aGlzKTsKCQl0aGlzLl9oYW5kbGVMb2FkUHJveHkgPSBjcmVhdGVqcy5wcm94eSh0aGlzLl9oYW5kbGVMb2FkLCB0aGlzKTsKCQl0aGlzLl9oYW5kbGVSZWFkeVN0YXRlQ2hhbmdlUHJveHkgPSBjcmVhdGVqcy5wcm94eSh0aGlzLl9oYW5kbGVSZWFkeVN0YXRlQ2hhbmdlLCB0aGlzKTsKCgkJaWYgKCF0aGlzLl9jcmVhdGVYSFIoaXRlbSkpIHsKCQkJLy9UT0RPOiBUaHJvdyBlcnJvcj8KCQl9Cgl9OwoKCXZhciBwID0gY3JlYXRlanMuZXh0ZW5kKFhIUlJlcXVlc3QsIGNyZWF0ZWpzLkFic3RyYWN0UmVxdWVzdCk7CgovLyBzdGF0aWMgcHJvcGVydGllcwoJLyoqCgkgKiBBIGxpc3Qgb2YgWE1MSFRUUCBvYmplY3QgSURzIHRvIHRyeSB3aGVuIGJ1aWxkaW5nIGFuIEFjdGl2ZVggb2JqZWN0IGZvciBYSFIgcmVxdWVzdHMgaW4gZWFybGllciB2ZXJzaW9ucyBvZiBJRS4KCSAqIEBwcm9wZXJ0eSBBQ1RJVkVYX1ZFUlNJT05TCgkgKiBAdHlwZSB7QXJyYXl9CgkgKiBAc2luY2UgMC40LjIKCSAqIEBwcml2YXRlCgkgKi8KCVhIUlJlcXVlc3QuQUNUSVZFWF9WRVJTSU9OUyA9IFsKCQkiTXN4bWwyLlhNTEhUVFAuNi4wIiwKCQkiTXN4bWwyLlhNTEhUVFAuNS4wIiwKCQkiTXN4bWwyLlhNTEhUVFAuNC4wIiwKCQkiTVNYTUwyLlhNTEhUVFAuMy4wIiwKCQkiTVNYTUwyLlhNTEhUVFAiLAoJCSJNaWNyb3NvZnQuWE1MSFRUUCIKCV07CgovLyBQdWJsaWMgbWV0aG9kcwoJLyoqCgkgKiBMb29rIHVwIHRoZSBsb2FkZWQgcmVzdWx0LgoJICogQG1ldGhvZCBnZXRSZXN1bHQKCSAqIEBwYXJhbSB7Qm9vbGVhbn0gW3Jhdz1mYWxzZV0gUmV0dXJuIGEgcmF3IHJlc3VsdCBpbnN0ZWFkIG9mIGEgZm9ybWF0dGVkIHJlc3VsdC4gVGhpcyBhcHBsaWVzIHRvIGNvbnRlbnQKCSAqIGxvYWRlZCB2aWEgWEhSIHN1Y2ggYXMgc2NyaXB0cywgWE1MLCBDU1MsIGFuZCBJbWFnZXMuIElmIHRoZXJlIGlzIG5vIHJhdyByZXN1bHQsIHRoZSBmb3JtYXR0ZWQgcmVzdWx0IHdpbGwgYmUKCSAqIHJldHVybmVkIGluc3RlYWQuCgkgKiBAcmV0dXJuIHtPYmplY3R9IEEgcmVzdWx0IG9iamVjdCBjb250YWluaW5nIHRoZSBjb250ZW50IHRoYXQgd2FzIGxvYWRlZCwgc3VjaCBhczoKCSAqIDx1bD4KCSAqICAgICAgPGxpPkFuIGltYWdlIHRhZyAoJmx0O2ltYWdlIC8mZ3Q7KSBmb3IgaW1hZ2VzPC9saT4KCSAqICAgICAgPGxpPkEgc2NyaXB0IHRhZyBmb3IgSmF2YVNjcmlwdCAoJmx0O3NjcmlwdCAvJmd0OykuIE5vdGUgdGhhdCBzY3JpcHRzIGxvYWRlZCB3aXRoIHRhZ3MgbWF5IGJlIGFkZGVkIHRvIHRoZQoJICogICAgICBIVE1MIGhlYWQuPC9saT4KCSAqICAgICAgPGxpPkEgc3R5bGUgdGFnIGZvciBDU1MgKCZsdDtzdHlsZSAvJmd0Oyk8L2xpPgoJICogICAgICA8bGk+UmF3IHRleHQgZm9yIFRFWFQ8L2xpPgoJICogICAgICA8bGk+QSBmb3JtYXR0ZWQgSmF2YVNjcmlwdCBvYmplY3QgZGVmaW5lZCBieSBKU09OPC9saT4KCSAqICAgICAgPGxpPkFuIFhNTCBkb2N1bWVudDwvbGk+CgkgKiAgICAgIDxsaT5BbiBiaW5hcnkgYXJyYXlidWZmZXIgbG9hZGVkIGJ5IFhIUjwvbGk+CgkgKiA8L3VsPgoJICogTm90ZSB0aGF0IGlmIGEgcmF3IHJlc3VsdCBpcyByZXF1ZXN0ZWQsIGJ1dCBub3QgZm91bmQsIHRoZSByZXN1bHQgd2lsbCBiZSByZXR1cm5lZCBpbnN0ZWFkLgoJICovCglwLmdldFJlc3VsdCA9IGZ1bmN0aW9uIChyYXcpIHsKCQlpZiAocmF3ICYmIHRoaXMuX3Jhd1Jlc3BvbnNlKSB7CgkJCXJldHVybiB0aGlzLl9yYXdSZXNwb25zZTsKCQl9CgkJcmV0dXJuIHRoaXMuX3Jlc3BvbnNlOwoJfTsKCgkvLyBPdmVycmlkZXMgYWJzdHJhY3QgbWV0aG9kIGluIEFic3RyYWN0UmVxdWVzdAoJcC5jYW5jZWwgPSBmdW5jdGlvbiAoKSB7CgkJdGhpcy5jYW5jZWxlZCA9IHRydWU7CgkJdGhpcy5fY2xlYW4oKTsKCQl0aGlzLl9yZXF1ZXN0LmFib3J0KCk7Cgl9OwoKCS8vIE92ZXJyaWRlcyBhYnN0cmFjdCBtZXRob2QgaW4gQWJzdHJhY3RMb2FkZXIKCXAubG9hZCA9IGZ1bmN0aW9uICgpIHsKCQlpZiAodGhpcy5fcmVxdWVzdCA9PSBudWxsKSB7CgkJCXRoaXMuX2hhbmRsZUVycm9yKCk7CgkJCXJldHVybjsKCQl9CgoJCS8vRXZlbnRzCgkJdGhpcy5fcmVxdWVzdC5hZGRFdmVudExpc3RlbmVyKCJsb2Fkc3RhcnQiLCB0aGlzLl9oYW5kbGVMb2FkU3RhcnRQcm94eSwgZmFsc2UpOwoJCXRoaXMuX3JlcXVlc3QuYWRkRXZlbnRMaXN0ZW5lcigicHJvZ3Jlc3MiLCB0aGlzLl9oYW5kbGVQcm9ncmVzc1Byb3h5LCBmYWxzZSk7CgkJdGhpcy5fcmVxdWVzdC5hZGRFdmVudExpc3RlbmVyKCJhYm9ydCIsIHRoaXMuX2hhbmRsZUFib3J0UHJveHksIGZhbHNlKTsKCQl0aGlzLl9yZXF1ZXN0LmFkZEV2ZW50TGlzdGVuZXIoImVycm9yIix0aGlzLl9oYW5kbGVFcnJvclByb3h5LCBmYWxzZSk7CgkJdGhpcy5fcmVxdWVzdC5hZGRFdmVudExpc3RlbmVyKCJ0aW1lb3V0IiwgdGhpcy5faGFuZGxlVGltZW91dFByb3h5LCBmYWxzZSk7CgoJCS8vIE5vdGU6IFdlIGRvbid0IGdldCBvbmxvYWQgaW4gYWxsIGJyb3dzZXJzIChlYXJsaWVyIEZGIGFuZCBJRSkuIG9uUmVhZHlTdGF0ZUNoYW5nZSBoYW5kbGVzIHRoZXNlLgoJCXRoaXMuX3JlcXVlc3QuYWRkRXZlbnRMaXN0ZW5lcigibG9hZCIsIHRoaXMuX2hhbmRsZUxvYWRQcm94eSwgZmFsc2UpOwoJCXRoaXMuX3JlcXVlc3QuYWRkRXZlbnRMaXN0ZW5lcigicmVhZHlzdGF0ZWNoYW5nZSIsIHRoaXMuX2hhbmRsZVJlYWR5U3RhdGVDaGFuZ2VQcm94eSwgZmFsc2UpOwoKCQkvLyBTZXQgdXAgYSB0aW1lb3V0IGlmIHdlIGRvbid0IGhhdmUgWEhSMgoJCWlmICh0aGlzLl94aHJMZXZlbCA9PSAxKSB7CgkJCXRoaXMuX2xvYWRUaW1lb3V0ID0gc2V0VGltZW91dChjcmVhdGVqcy5wcm94eSh0aGlzLl9oYW5kbGVUaW1lb3V0LCB0aGlzKSwgdGhpcy5faXRlbS5sb2FkVGltZW91dCk7CgkJfQoKCQkvLyBTb21ldGltZXMgd2UgZ2V0IGJhY2sgNDA0cyBpbW1lZGlhdGVseSwgcGFydGljdWxhcmx5IHdoZW4gdGhlcmUgaXMgYSBjcm9zcyBvcmlnaW4gcmVxdWVzdC4gIC8vIG5vdGUgdGhpcyBkb2VzIG5vdCBjYXRjaCBpbiBDaHJvbWUKCQl0cnkgewoJCQlpZiAoIXRoaXMuX2l0ZW0udmFsdWVzIHx8IHRoaXMuX2l0ZW0ubWV0aG9kID09IGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLkdFVCkgewoJCQkJdGhpcy5fcmVxdWVzdC5zZW5kKCk7CgkJCX0gZWxzZSBpZiAodGhpcy5faXRlbS5tZXRob2QgPT0gY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuUE9TVCkgewoJCQkJdGhpcy5fcmVxdWVzdC5zZW5kKGNyZWF0ZWpzLlJlcXVlc3RVdGlscy5mb3JtYXRRdWVyeVN0cmluZyh0aGlzLl9pdGVtLnZhbHVlcykpOwoJCQl9CgkJfSBjYXRjaCAoZXJyb3IpIHsKCQkJdGhpcy5kaXNwYXRjaEV2ZW50KG5ldyBjcmVhdGVqcy5FcnJvckV2ZW50KCJYSFJfU0VORCIsIG51bGwsIGVycm9yKSk7CgkJfQoJfTsKCglwLnNldFJlc3BvbnNlVHlwZSA9IGZ1bmN0aW9uICh0eXBlKSB7CgkJdGhpcy5fcmVxdWVzdC5yZXNwb25zZVR5cGUgPSB0eXBlOwoJfTsKCgkvKioKCSAqIEdldCBhbGwgdGhlIHJlc3BvbnNlIGhlYWRlcnMgZnJvbSB0aGUgWG1sSHR0cFJlcXVlc3QuCgkgKgoJICogPHN0cm9uZz5Gcm9tIHRoZSBkb2NzOjwvc3Ryb25nPiBSZXR1cm4gYWxsIHRoZSBIVFRQIGhlYWRlcnMsIGV4Y2x1ZGluZyBoZWFkZXJzIHRoYXQgYXJlIGEgY2FzZS1pbnNlbnNpdGl2ZSBtYXRjaAoJICogZm9yIFNldC1Db29raWUgb3IgU2V0LUNvb2tpZTIsIGFzIGEgc2luZ2xlIHN0cmluZywgd2l0aCBlYWNoIGhlYWRlciBsaW5lIHNlcGFyYXRlZCBieSBhIFUrMDAwRCBDUiBVKzAwMEEgTEYgcGFpciwKCSAqIGV4Y2x1ZGluZyB0aGUgc3RhdHVzIGxpbmUsIGFuZCB3aXRoIGVhY2ggaGVhZGVyIG5hbWUgYW5kIGhlYWRlciB2YWx1ZSBzZXBhcmF0ZWQgYnkgYSBVKzAwM0EgQ09MT04gVSswMDIwIFNQQUNFCgkgKiBwYWlyLgoJICogQG1ldGhvZCBnZXRBbGxSZXNwb25zZUhlYWRlcnMKCSAqIEByZXR1cm4ge1N0cmluZ30KCSAqIEBzaW5jZSAwLjQuMQoJICovCglwLmdldEFsbFJlc3BvbnNlSGVhZGVycyA9IGZ1bmN0aW9uICgpIHsKCQlpZiAodGhpcy5fcmVxdWVzdC5nZXRBbGxSZXNwb25zZUhlYWRlcnMgaW5zdGFuY2VvZiBGdW5jdGlvbikgewoJCQlyZXR1cm4gdGhpcy5fcmVxdWVzdC5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKTsKCQl9IGVsc2UgewoJCQlyZXR1cm4gbnVsbDsKCQl9Cgl9OwoKCS8qKgoJICogR2V0IGEgc3BlY2lmaWMgcmVzcG9uc2UgaGVhZGVyIGZyb20gdGhlIFhtbEh0dHBSZXF1ZXN0LgoJICoKCSAqIDxzdHJvbmc+RnJvbSB0aGUgZG9jczo8L3N0cm9uZz4gUmV0dXJucyB0aGUgaGVhZGVyIGZpZWxkIHZhbHVlIGZyb20gdGhlIHJlc3BvbnNlIG9mIHdoaWNoIHRoZSBmaWVsZCBuYW1lIG1hdGNoZXMKCSAqIGhlYWRlciwgdW5sZXNzIHRoZSBmaWVsZCBuYW1lIGlzIFNldC1Db29raWUgb3IgU2V0LUNvb2tpZTIuCgkgKiBAbWV0aG9kIGdldFJlc3BvbnNlSGVhZGVyCgkgKiBAcGFyYW0ge1N0cmluZ30gaGVhZGVyIFRoZSBoZWFkZXIgbmFtZSB0byByZXRyaWV2ZS4KCSAqIEByZXR1cm4ge1N0cmluZ30KCSAqIEBzaW5jZSAwLjQuMQoJICovCglwLmdldFJlc3BvbnNlSGVhZGVyID0gZnVuY3Rpb24gKGhlYWRlcikgewoJCWlmICh0aGlzLl9yZXF1ZXN0LmdldFJlc3BvbnNlSGVhZGVyIGluc3RhbmNlb2YgRnVuY3Rpb24pIHsKCQkJcmV0dXJuIHRoaXMuX3JlcXVlc3QuZ2V0UmVzcG9uc2VIZWFkZXIoaGVhZGVyKTsKCQl9IGVsc2UgewoJCQlyZXR1cm4gbnVsbDsKCQl9Cgl9OwoKLy8gcHJvdGVjdGVkIG1ldGhvZHMKCS8qKgoJICogVGhlIFhIUiByZXF1ZXN0IGhhcyByZXBvcnRlZCBwcm9ncmVzcy4KCSAqIEBtZXRob2QgX2hhbmRsZVByb2dyZXNzCgkgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgVGhlIFhIUiBwcm9ncmVzcyBldmVudC4KCSAqIEBwcml2YXRlCgkgKi8KCXAuX2hhbmRsZVByb2dyZXNzID0gZnVuY3Rpb24gKGV2ZW50KSB7CgkJaWYgKCFldmVudCB8fCBldmVudC5sb2FkZWQgPiAwICYmIGV2ZW50LnRvdGFsID09IDApIHsKCQkJcmV0dXJuOyAvLyBTb21ldGltZXMgd2UgZ2V0IG5vICJ0b3RhbCIsIHNvIGp1c3QgaWdub3JlIHRoZSBwcm9ncmVzcyBldmVudC4KCQl9CgoJCXZhciBuZXdFdmVudCA9IG5ldyBjcmVhdGVqcy5Qcm9ncmVzc0V2ZW50KGV2ZW50LmxvYWRlZCwgZXZlbnQudG90YWwpOwoJCXRoaXMuZGlzcGF0Y2hFdmVudChuZXdFdmVudCk7Cgl9OwoKCS8qKgoJICogVGhlIFhIUiByZXF1ZXN0IGhhcyByZXBvcnRlZCBhIGxvYWQgc3RhcnQuCgkgKiBAbWV0aG9kIF9oYW5kbGVMb2FkU3RhcnQKCSAqIEBwYXJhbSB7T2JqZWN0fSBldmVudCBUaGUgWEhSIGxvYWRTdGFydCBldmVudC4KCSAqIEBwcml2YXRlCgkgKi8KCXAuX2hhbmRsZUxvYWRTdGFydCA9IGZ1bmN0aW9uIChldmVudCkgewoJCWNsZWFyVGltZW91dCh0aGlzLl9sb2FkVGltZW91dCk7CgkJdGhpcy5kaXNwYXRjaEV2ZW50KCJsb2Fkc3RhcnQiKTsKCX07CgoJLyoqCgkgKiBUaGUgWEhSIHJlcXVlc3QgaGFzIHJlcG9ydGVkIGFuIGFib3J0IGV2ZW50LgoJICogQG1ldGhvZCBoYW5kbGVBYm9ydAoJICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFRoZSBYSFIgYWJvcnQgZXZlbnQuCgkgKiBAcHJpdmF0ZQoJICovCglwLl9oYW5kbGVBYm9ydCA9IGZ1bmN0aW9uIChldmVudCkgewoJCXRoaXMuX2NsZWFuKCk7CgkJdGhpcy5kaXNwYXRjaEV2ZW50KG5ldyBjcmVhdGVqcy5FcnJvckV2ZW50KCJYSFJfQUJPUlRFRCIsIG51bGwsIGV2ZW50KSk7Cgl9OwoKCS8qKgoJICogVGhlIFhIUiByZXF1ZXN0IGhhcyByZXBvcnRlZCBhbiBlcnJvciBldmVudC4KCSAqIEBtZXRob2QgX2hhbmRsZUVycm9yCgkgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgVGhlIFhIUiBlcnJvciBldmVudC4KCSAqIEBwcml2YXRlCgkgKi8KCXAuX2hhbmRsZUVycm9yID0gZnVuY3Rpb24gKGV2ZW50KSB7CgkJdGhpcy5fY2xlYW4oKTsKCQl0aGlzLmRpc3BhdGNoRXZlbnQobmV3IGNyZWF0ZWpzLkVycm9yRXZlbnQoZXZlbnQubWVzc2FnZSkpOwoJfTsKCgkvKioKCSAqIFRoZSBYSFIgcmVxdWVzdCBoYXMgcmVwb3J0ZWQgYSByZWFkeVN0YXRlIGNoYW5nZS4gTm90ZSB0aGF0IG9sZGVyIGJyb3dzZXJzIChJRSA3ICYgOCkgZG8gbm90IHByb3ZpZGUgYW4gb25sb2FkCgkgKiBldmVudCwgc28gd2UgbXVzdCBtb25pdG9yIHRoZSByZWFkeVN0YXRlQ2hhbmdlIHRvIGRldGVybWluZSBpZiB0aGUgZmlsZSBpcyBsb2FkZWQuCgkgKiBAbWV0aG9kIF9oYW5kbGVSZWFkeVN0YXRlQ2hhbmdlCgkgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgVGhlIFhIUiByZWFkeVN0YXRlQ2hhbmdlIGV2ZW50LgoJICogQHByaXZhdGUKCSAqLwoJcC5faGFuZGxlUmVhZHlTdGF0ZUNoYW5nZSA9IGZ1bmN0aW9uIChldmVudCkgewoJCWlmICh0aGlzLl9yZXF1ZXN0LnJlYWR5U3RhdGUgPT0gNCkgewoJCQl0aGlzLl9oYW5kbGVMb2FkKCk7CgkJfQoJfTsKCgkvKioKCSAqIFRoZSBYSFIgcmVxdWVzdCBoYXMgY29tcGxldGVkLiBUaGlzIGlzIGNhbGxlZCBieSB0aGUgWEhSIHJlcXVlc3QgZGlyZWN0bHksIG9yIGJ5IGEgcmVhZHlTdGF0ZUNoYW5nZSB0aGF0IGhhcwoJICogPGNvZGU+cmVxdWVzdC5yZWFkeVN0YXRlID09IDQ8L2NvZGU+LiBPbmx5IHRoZSBmaXJzdCBjYWxsIHRvIHRoaXMgbWV0aG9kIHdpbGwgYmUgcHJvY2Vzc2VkLgoJICogQG1ldGhvZCBfaGFuZGxlTG9hZAoJICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFRoZSBYSFIgbG9hZCBldmVudC4KCSAqIEBwcml2YXRlCgkgKi8KCXAuX2hhbmRsZUxvYWQgPSBmdW5jdGlvbiAoZXZlbnQpIHsKCQlpZiAodGhpcy5sb2FkZWQpIHsKCQkJcmV0dXJuOwoJCX0KCQl0aGlzLmxvYWRlZCA9IHRydWU7CgoJCXZhciBlcnJvciA9IHRoaXMuX2NoZWNrRXJyb3IoKTsKCQlpZiAoZXJyb3IpIHsKCQkJdGhpcy5faGFuZGxlRXJyb3IoZXJyb3IpOwoJCQlyZXR1cm47CgkJfQoKCQl0aGlzLl9yZXNwb25zZSA9IHRoaXMuX2dldFJlc3BvbnNlKCk7CgkJdGhpcy5fY2xlYW4oKTsKCgkJdGhpcy5kaXNwYXRjaEV2ZW50KG5ldyBjcmVhdGVqcy5FdmVudCgiY29tcGxldGUiKSk7Cgl9OwoKCS8qKgoJICogVGhlIFhIUiByZXF1ZXN0IGhhcyB0aW1lZCBvdXQuIFRoaXMgaXMgY2FsbGVkIGJ5IHRoZSBYSFIgcmVxdWVzdCBkaXJlY3RseSwgb3IgdmlhIGEgPGNvZGU+c2V0VGltZW91dDwvY29kZT4KCSAqIGNhbGxiYWNrLgoJICogQG1ldGhvZCBfaGFuZGxlVGltZW91dAoJICogQHBhcmFtIHtPYmplY3R9IFtldmVudF0gVGhlIFhIUiB0aW1lb3V0IGV2ZW50LiBUaGlzIGlzIG9jY2FzaW9uYWxseSBudWxsIHdoZW4gY2FsbGVkIGJ5IHRoZSBiYWNrdXAgc2V0VGltZW91dC4KCSAqIEBwcml2YXRlCgkgKi8KCXAuX2hhbmRsZVRpbWVvdXQgPSBmdW5jdGlvbiAoZXZlbnQpIHsKCQl0aGlzLl9jbGVhbigpOwoKCQl0aGlzLmRpc3BhdGNoRXZlbnQobmV3IGNyZWF0ZWpzLkVycm9yRXZlbnQoIlBSRUxPQURfVElNRU9VVCIsIG51bGwsIGV2ZW50KSk7Cgl9OwoKLy8gUHJvdGVjdGVkCgkvKioKCSAqIERldGVybWluZSBpZiB0aGVyZSBpcyBhbiBlcnJvciBpbiB0aGUgY3VycmVudCBsb2FkLiBUaGlzIGNoZWNrcyB0aGUgc3RhdHVzIG9mIHRoZSByZXF1ZXN0IGZvciBwcm9ibGVtIGNvZGVzLiBOb3RlCgkgKiB0aGF0IHRoaXMgZG9lcyBub3QgY2hlY2sgZm9yIGFuIGFjdHVhbCByZXNwb25zZS4gQ3VycmVudGx5LCBpdCBvbmx5IGNoZWNrcyBmb3IgNDA0IG9yIDAgZXJyb3IgY29kZS4KCSAqIEBtZXRob2QgX2NoZWNrRXJyb3IKCSAqIEByZXR1cm4ge2ludH0gSWYgdGhlIHJlcXVlc3Qgc3RhdHVzIHJldHVybnMgYW4gZXJyb3IgY29kZS4KCSAqIEBwcml2YXRlCgkgKi8KCXAuX2NoZWNrRXJyb3IgPSBmdW5jdGlvbiAoKSB7CgkJLy9MTTogUHJvYmFibHkgbmVlZCBhZGRpdGlvbmFsIGhhbmRsZXJzIGhlcmUsIG1heWJlIDUwMQoJCXZhciBzdGF0dXMgPSBwYXJzZUludCh0aGlzLl9yZXF1ZXN0LnN0YXR1cyk7CgoJCXN3aXRjaCAoc3RhdHVzKSB7CgkJCWNhc2UgNDA0OiAgIC8vIE5vdCBGb3VuZAoJCQljYXNlIDA6ICAgICAvLyBOb3QgTG9hZGVkCgkJCQlyZXR1cm4gbmV3IEVycm9yKHN0YXR1cyk7CgkJfQoJCXJldHVybiBudWxsOwoJfTsKCgkvKioKCSAqIFZhbGlkYXRlIHRoZSByZXNwb25zZS4gRGlmZmVyZW50IGJyb3dzZXJzIGhhdmUgZGlmZmVyZW50IGFwcHJvYWNoZXMsIHNvbWUgb2Ygd2hpY2ggdGhyb3cgZXJyb3JzIHdoZW4gYWNjZXNzZWQKCSAqIGluIG90aGVyIGJyb3dzZXJzLiBJZiB0aGVyZSBpcyBubyByZXNwb25zZSwgdGhlIDxjb2RlPl9yZXNwb25zZTwvY29kZT4gcHJvcGVydHkgd2lsbCByZW1haW4gbnVsbC4KCSAqIEBtZXRob2QgX2dldFJlc3BvbnNlCgkgKiBAcHJpdmF0ZQoJICovCglwLl9nZXRSZXNwb25zZSA9IGZ1bmN0aW9uICgpIHsKCQlpZiAodGhpcy5fcmVzcG9uc2UgIT0gbnVsbCkgewoJCQlyZXR1cm4gdGhpcy5fcmVzcG9uc2U7CgkJfQoKCQlpZiAodGhpcy5fcmVxdWVzdC5yZXNwb25zZSAhPSBudWxsKSB7CgkJCXJldHVybiB0aGlzLl9yZXF1ZXN0LnJlc3BvbnNlOwoJCX0KCgkJLy8gQW5kcm9pZCAyLjIgdXNlcyAucmVzcG9uc2VUZXh0CgkJdHJ5IHsKCQkJaWYgKHRoaXMuX3JlcXVlc3QucmVzcG9uc2VUZXh0ICE9IG51bGwpIHsKCQkJCXJldHVybiB0aGlzLl9yZXF1ZXN0LnJlc3BvbnNlVGV4dDsKCQkJfQoJCX0gY2F0Y2ggKGUpIHsKCQl9CgoJCS8vIFdoZW4gbG9hZGluZyBYTUwsIElFOSBkb2VzIG5vdCByZXR1cm4gLnJlc3BvbnNlLCBpbnN0ZWFkIGl0IHJldHVybnMgcmVzcG9uc2VYTUwueG1sCgkJdHJ5IHsKCQkJaWYgKHRoaXMuX3JlcXVlc3QucmVzcG9uc2VYTUwgIT0gbnVsbCkgewoJCQkJcmV0dXJuIHRoaXMuX3JlcXVlc3QucmVzcG9uc2VYTUw7CgkJCX0KCQl9IGNhdGNoIChlKSB7CgkJfQoKCQlyZXR1cm4gbnVsbDsKCX07CgoJLyoqCgkgKiBDcmVhdGUgYW4gWEhSIHJlcXVlc3QuIERlcGVuZGluZyBvbiBhIG51bWJlciBvZiBmYWN0b3JzLCB3ZSBnZXQgdG90YWxseSBkaWZmZXJlbnQgcmVzdWx0cy4KCSAqIDxvbD48bGk+U29tZSBicm93c2VycyBnZXQgYW4gPGNvZGU+WERvbWFpblJlcXVlc3Q8L2NvZGU+IHdoZW4gbG9hZGluZyBjcm9zcy1kb21haW4uPC9saT4KCSAqICAgICAgPGxpPlhNTEh0dHBSZXF1ZXN0IGFyZSBjcmVhdGVkIHdoZW4gYXZhaWxhYmxlLjwvbGk+CgkgKiAgICAgIDxsaT5BY3RpdmVYLlhNTEhUVFAgb2JqZWN0cyBhcmUgdXNlZCBpbiBvbGRlciBJRSBicm93c2Vycy48L2xpPgoJICogICAgICA8bGk+VGV4dCByZXF1ZXN0cyBvdmVycmlkZSB0aGUgbWltZSB0eXBlIGlmIHBvc3NpYmxlPC9saT4KCSAqICAgICAgPGxpPk9yaWdpbiBoZWFkZXJzIGFyZSBzZW50IGZvciBjcm9zc2RvbWFpbiByZXF1ZXN0cyBpbiBzb21lIGJyb3dzZXJzLjwvbGk+CgkgKiAgICAgIDxsaT5CaW5hcnkgbG9hZHMgc2V0IHRoZSByZXNwb25zZSB0eXBlIHRvICJhcnJheWJ1ZmZlciI8L2xpPjwvb2w+CgkgKiBAbWV0aG9kIF9jcmVhdGVYSFIKCSAqIEBwYXJhbSB7T2JqZWN0fSBpdGVtIFRoZSByZXF1ZXN0ZWQgaXRlbSB0aGF0IGlzIGJlaW5nIGxvYWRlZC4KCSAqIEByZXR1cm4ge0Jvb2xlYW59IElmIGFuIFhIUiByZXF1ZXN0IG9yIGVxdWl2YWxlbnQgd2FzIHN1Y2Nlc3NmdWxseSBjcmVhdGVkLgoJICogQHByaXZhdGUKCSAqLwoJcC5fY3JlYXRlWEhSID0gZnVuY3Rpb24gKGl0ZW0pIHsKCQkvLyBDaGVjayBmb3IgY3Jvc3MtZG9tYWluIGxvYWRzLiBXZSBjYW4ndCBmdWxseSBzdXBwb3J0IHRoZW0sIGJ1dCB3ZSBjYW4gdHJ5LgoJCXZhciBjcm9zc2RvbWFpbiA9IGNyZWF0ZWpzLlJlcXVlc3RVdGlscy5pc0Nyb3NzRG9tYWluKGl0ZW0pOwoJCXZhciBoZWFkZXJzID0ge307CgoJCS8vIENyZWF0ZSB0aGUgcmVxdWVzdC4gRmFsbGJhY2sgdG8gd2hhdGV2ZXIgc3VwcG9ydCB3ZSBoYXZlLgoJCXZhciByZXEgPSBudWxsOwoJCWlmICh3aW5kb3cuWE1MSHR0cFJlcXVlc3QpIHsKCQkJcmVxID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7CgkJCS8vIFRoaXMgaXMgOCBvciA5LCBzbyB1c2UgWERvbWFpblJlcXVlc3QgaW5zdGVhZC4KCQkJaWYgKGNyb3NzZG9tYWluICYmIHJlcS53aXRoQ3JlZGVudGlhbHMgPT09IHVuZGVmaW5lZCAmJiB3aW5kb3cuWERvbWFpblJlcXVlc3QpIHsKCQkJCXJlcSA9IG5ldyBYRG9tYWluUmVxdWVzdCgpOwoJCQl9CgkJfSBlbHNlIHsgLy8gT2xkIElFIHZlcnNpb25zIHVzZSBhIGRpZmZlcmVudCBhcHByb2FjaAoJCQlmb3IgKHZhciBpID0gMCwgbCA9IHMuQUNUSVZFWF9WRVJTSU9OUy5sZW5ndGg7IGkgPCBsOyBpKyspIHsKCQkJCXZhciBheFZlcnNpb24gPSBzLkFDVElWRVhfVkVSU0lPTlNbaV07CgkJCQl0cnkgewoJCQkJCXJlcSA9IG5ldyBBY3RpdmVYT2JqZWN0KGF4VmVyc2lvbnMpOwoJCQkJCWJyZWFrOwoJCQkJfSBjYXRjaCAoZSkge30KCQkJfQoJCQlpZiAocmVxID09IG51bGwpIHsgcmV0dXJuIGZhbHNlOyB9CgkJfQoKCQkvLyBEZWZhdWx0IHRvIHV0Zi04IGZvciBUZXh0IHJlcXVlc3RzLgoJCWlmIChpdGVtLm1pbWVUeXBlID09IG51bGwgJiYgY3JlYXRlanMuUmVxdWVzdFV0aWxzLmlzVGV4dChpdGVtLnR5cGUpKSB7CgkJCWl0ZW0ubWltZVR5cGUgPSAidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCI7CgkJfQoKCQkvLyBJRTkgZG9lc24ndCBzdXBwb3J0IG92ZXJyaWRlTWltZVR5cGUoKSwgc28gd2UgbmVlZCB0byBjaGVjayBmb3IgaXQuCgkJaWYgKGl0ZW0ubWltZVR5cGUgJiYgcmVxLm92ZXJyaWRlTWltZVR5cGUpIHsKCQkJcmVxLm92ZXJyaWRlTWltZVR5cGUoaXRlbS5taW1lVHlwZSk7CgkJfQoKCQkvLyBEZXRlcm1pbmUgdGhlIFhIUiBsZXZlbAoJCXRoaXMuX3hockxldmVsID0gKHR5cGVvZiByZXEucmVzcG9uc2VUeXBlID09PSAic3RyaW5nIikgPyAyIDogMTsKCgkJdmFyIHNyYyA9IG51bGw7CgkJaWYgKGl0ZW0ubWV0aG9kID09IGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLkdFVCkgewoJCQlzcmMgPSBjcmVhdGVqcy5SZXF1ZXN0VXRpbHMuYnVpbGRQYXRoKGl0ZW0uc3JjLCBpdGVtLnZhbHVlcyk7CgkJfSBlbHNlIHsKCQkJc3JjID0gaXRlbS5zcmM7CgkJfQoKCQkvLyBPcGVuIHRoZSByZXF1ZXN0LiAgU2V0IGNyb3NzLWRvbWFpbiBmbGFncyBpZiBpdCBpcyBzdXBwb3J0ZWQgKFhIUiBsZXZlbCAxIG9ubHkpCgkJcmVxLm9wZW4oaXRlbS5tZXRob2QgfHwgY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuR0VULCBzcmMsIHRydWUpOwoKCQlpZiAoY3Jvc3Nkb21haW4gJiYgcmVxIGluc3RhbmNlb2YgWE1MSHR0cFJlcXVlc3QgJiYgdGhpcy5feGhyTGV2ZWwgPT0gMSkgewoJCQloZWFkZXJzWyJPcmlnaW4iXSA9IGxvY2F0aW9uLm9yaWdpbjsKCQl9CgoJCS8vIFRvIHNlbmQgZGF0YSB3ZSBuZWVkIHRvIHNldCB0aGUgQ29udGVudC10eXBlIGhlYWRlcikKCQlpZiAoaXRlbS52YWx1ZXMgJiYgaXRlbS5tZXRob2QgPT0gY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuUE9TVCkgewoJCQloZWFkZXJzWyJDb250ZW50LVR5cGUiXSA9ICJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQiOwoJCX0KCgkJaWYgKCFjcm9zc2RvbWFpbiAmJiAhaGVhZGVyc1siWC1SZXF1ZXN0ZWQtV2l0aCJdKSB7CgkJCWhlYWRlcnNbIlgtUmVxdWVzdGVkLVdpdGgiXSA9ICJYTUxIdHRwUmVxdWVzdCI7CgkJfQoKCQlpZiAoaXRlbS5oZWFkZXJzKSB7CgkJCWZvciAodmFyIG4gaW4gaXRlbS5oZWFkZXJzKSB7CgkJCQloZWFkZXJzW25dID0gaXRlbS5oZWFkZXJzW25dOwoJCQl9CgkJfQoKCQlmb3IgKG4gaW4gaGVhZGVycykgewoJCQlyZXEuc2V0UmVxdWVzdEhlYWRlcihuLCBoZWFkZXJzW25dKQoJCX0KCgkJaWYgKHJlcSBpbnN0YW5jZW9mIFhNTEh0dHBSZXF1ZXN0ICYmIGl0ZW0ud2l0aENyZWRlbnRpYWxzICE9PSB1bmRlZmluZWQpIHsKCQkJcmVxLndpdGhDcmVkZW50aWFscyA9IGl0ZW0ud2l0aENyZWRlbnRpYWxzOwoJCX0KCgkJdGhpcy5fcmVxdWVzdCA9IHJlcTsKCgkJcmV0dXJuIHRydWU7Cgl9OwoKCS8qKgoJICogQSByZXF1ZXN0IGhhcyBjb21wbGV0ZWQgKG9yIGZhaWxlZCBvciBjYW5jZWxlZCksIGFuZCBuZWVkcyB0byBiZSBkaXNwb3NlZC4KCSAqIEBtZXRob2QgX2NsZWFuCgkgKiBAcHJpdmF0ZQoJICovCglwLl9jbGVhbiA9IGZ1bmN0aW9uICgpIHsKCQljbGVhclRpbWVvdXQodGhpcy5fbG9hZFRpbWVvdXQpOwoKCQl0aGlzLl9yZXF1ZXN0LnJlbW92ZUV2ZW50TGlzdGVuZXIoImxvYWRzdGFydCIsIHRoaXMuX2hhbmRsZUxvYWRTdGFydFByb3h5KTsKCQl0aGlzLl9yZXF1ZXN0LnJlbW92ZUV2ZW50TGlzdGVuZXIoInByb2dyZXNzIiwgdGhpcy5faGFuZGxlUHJvZ3Jlc3NQcm94eSk7CgkJdGhpcy5fcmVxdWVzdC5yZW1vdmVFdmVudExpc3RlbmVyKCJhYm9ydCIsIHRoaXMuX2hhbmRsZUFib3J0UHJveHkpOwoJCXRoaXMuX3JlcXVlc3QucmVtb3ZlRXZlbnRMaXN0ZW5lcigiZXJyb3IiLHRoaXMuX2hhbmRsZUVycm9yUHJveHkpOwoJCXRoaXMuX3JlcXVlc3QucmVtb3ZlRXZlbnRMaXN0ZW5lcigidGltZW91dCIsIHRoaXMuX2hhbmRsZVRpbWVvdXRQcm94eSk7CgkJdGhpcy5fcmVxdWVzdC5yZW1vdmVFdmVudExpc3RlbmVyKCJsb2FkIiwgdGhpcy5faGFuZGxlTG9hZFByb3h5KTsKCQl0aGlzLl9yZXF1ZXN0LnJlbW92ZUV2ZW50TGlzdGVuZXIoInJlYWR5c3RhdGVjaGFuZ2UiLCB0aGlzLl9oYW5kbGVSZWFkeVN0YXRlQ2hhbmdlUHJveHkpOwoJfTsKCglwLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkgewoJCXJldHVybiAiW1ByZWxvYWRKUyBYSFJSZXF1ZXN0XSI7Cgl9OwoKCWNyZWF0ZWpzLlhIUlJlcXVlc3QgPSBjcmVhdGVqcy5wcm9tb3RlKFhIUlJlcXVlc3QsICJBYnN0cmFjdFJlcXVlc3QiKTsKCn0oKSk7CgovLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwovLyBMb2FkUXVldWUuanMKLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCnRoaXMuY3JlYXRlanMgPSB0aGlzLmNyZWF0ZWpzIHx8IHt9OwoKLyoKIFRPRE86IFdJTkRPV1MgSVNTVUVTCiAqIE5vIGVycm9yIGZvciBIVE1MIGF1ZGlvIGluIElFIDY3OAogKiBTVkcgbm8gZmFpbHVyZSBlcnJvciBpbiBJRSA2NyAobWF5YmUgOCkgVEFHUyBBTkQgWEhSCiAqIE5vIHNjcmlwdCBjb21wbGV0ZSBoYW5kbGVyIGluIElFIDY3IFRBR1MgKFhIUiBpcyBmaW5lKQogKiBObyBYTUwvSlNPTiBpbiBJRTYgVEFHUwogKiBOZWVkIHRvIGhpZGUgbG9hZGluZyBTVkcgaW4gT3BlcmEgVEFHUwogKiBObyBDU1Mgb25sb2FkL3JlYWR5c3RhdGVjaGFuZ2UgaW4gU2FmYXJpIG9yIEFuZHJvaWQgVEFHUyAocmVxdWlyZXMgcnVsZSBjaGVja2luZykKICogU1ZHIG5vIGxvYWQgb3IgZmFpbHVyZSBpbiBPcGVyYSBYSFIKICogUmVwb3J0ZWQgaXNzdWVzIHdpdGggSUU3LzgKICovCgooZnVuY3Rpb24gKCkgewoJInVzZSBzdHJpY3QiOwoKLy8gY29uc3RydWN0b3IKCS8qKgoJICogVGhlIExvYWRRdWV1ZSBjbGFzcyBpcyB0aGUgbWFpbiBBUEkgZm9yIHByZWxvYWRpbmcgY29udGVudC4gTG9hZFF1ZXVlIGlzIGEgbG9hZCBtYW5hZ2VyLCB3aGljaCBjYW4gcHJlbG9hZCBlaXRoZXIKCSAqIGEgc2luZ2xlIGZpbGUsIG9yIHF1ZXVlIG9mIGZpbGVzLgoJICoKCSAqIDxiPkNyZWF0aW5nIGEgUXVldWU8L2I+PGJyIC8+CgkgKiBUbyB1c2UgTG9hZFF1ZXVlLCBjcmVhdGUgYSBMb2FkUXVldWUgaW5zdGFuY2UuIElmIHlvdSB3YW50IHRvIGZvcmNlIHRhZyBsb2FkaW5nIHdoZXJlIHBvc3NpYmxlLCBzZXQgdGhlIHByZWZlclhIUgoJICogYXJndW1lbnQgdG8gZmFsc2UuCgkgKgoJICogICAgICB2YXIgcXVldWUgPSBuZXcgY3JlYXRlanMuTG9hZFF1ZXVlKHRydWUpOwoJICoKCSAqIDxiPkxpc3RlbmluZyBmb3IgRXZlbnRzPC9iPjxiciAvPgoJICogQWRkIGFueSBsaXN0ZW5lcnMgeW91IHdhbnQgdG8gdGhlIHF1ZXVlLiBTaW5jZSBQcmVsb2FkSlMgMC4zLjAsIHRoZSB7eyNjcm9zc0xpbmsgIkV2ZW50RGlzcGF0Y2hlciJ9fXt7L2Nyb3NzTGlua319CgkgKiBsZXRzIHlvdSBhZGQgYXMgbWFueSBsaXN0ZW5lcnMgYXMgeW91IHdhbnQgZm9yIGV2ZW50cy4gWW91IGNhbiBzdWJzY3JpYmUgdG8gdGhlIGZvbGxvd2luZyBldmVudHM6PHVsPgoJICogICAgIDxsaT57eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyL2NvbXBsZXRlOmV2ZW50In19e3svY3Jvc3NMaW5rfX06IGZpcmVkIHdoZW4gYSBxdWV1ZSBjb21wbGV0ZXMgbG9hZGluZyBhbGwKCSAqICAgICBmaWxlczwvbGk+CgkgKiAgICAgPGxpPnt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvZXJyb3I6ZXZlbnQifX17ey9jcm9zc0xpbmt9fTogZmlyZWQgd2hlbiB0aGUgcXVldWUgZW5jb3VudGVycyBhbiBlcnJvciB3aXRoCgkgKiAgICAgYW55IGZpbGUuPC9saT4KCSAqICAgICA8bGk+e3sjY3Jvc3NMaW5rICJBYnN0cmFjdExvYWRlci9wcm9ncmVzczpldmVudCJ9fXt7L2Nyb3NzTGlua319OiBQcm9ncmVzcyBmb3IgdGhlIGVudGlyZSBxdWV1ZSBoYXMKCSAqICAgICBjaGFuZ2VkLjwvbGk+CgkgKiAgICAgPGxpPnt7I2Nyb3NzTGluayAiTG9hZFF1ZXVlL2ZpbGVsb2FkOmV2ZW50In19e3svY3Jvc3NMaW5rfX06IEEgc2luZ2xlIGZpbGUgaGFzIGNvbXBsZXRlZCBsb2FkaW5nLjwvbGk+CgkgKiAgICAgPGxpPnt7I2Nyb3NzTGluayAiTG9hZFF1ZXVlL2ZpbGVwcm9ncmVzczpldmVudCJ9fXt7L2Nyb3NzTGlua319OiBQcm9ncmVzcyBmb3IgYSBzaW5nbGUgZmlsZSBoYXMgY2hhbmdlcy4gTm90ZQoJICogICAgIHRoYXQgb25seSBmaWxlcyBsb2FkZWQgd2l0aCBYSFIgKG9yIHBvc3NpYmx5IGJ5IHBsdWdpbnMpIHdpbGwgZmlyZSBwcm9ncmVzcyBldmVudHMgb3RoZXIgdGhhbiAwIG9yIDEwMCUuPC9saT4KCSAqIDwvdWw+CgkgKgoJICogICAgICBxdWV1ZS5vbigiZmlsZWxvYWQiLCBoYW5kbGVGaWxlTG9hZCwgdGhpcyk7CgkgKiAgICAgIHF1ZXVlLm9uKCJjb21wbGV0ZSIsIGhhbmRsZUNvbXBsZXRlLCB0aGlzKTsKCSAqCgkgKiA8Yj5BZGRpbmcgZmlsZXMgYW5kIG1hbmlmZXN0czwvYj48YnIgLz4KCSAqIEFkZCBmaWxlcyB5b3Ugd2FudCB0byBsb2FkIHVzaW5nIHt7I2Nyb3NzTGluayAiTG9hZFF1ZXVlL2xvYWRGaWxlIn19e3svY3Jvc3NMaW5rfX0gb3IgYWRkIG11bHRpcGxlIGZpbGVzIGF0IGEKCSAqIHRpbWUgdXNpbmcgYSBsaXN0IG9yIGEgbWFuaWZlc3QgZGVmaW5pdGlvbiB1c2luZyB7eyNjcm9zc0xpbmsgIkxvYWRRdWV1ZS9sb2FkTWFuaWZlc3QifX17ey9jcm9zc0xpbmt9fS4gRmlsZXMgYXJlCgkgKiBhcHBlbmRlZCB0byB0aGUgZW5kIG9mIHRoZSBhY3RpdmUgcXVldWUsIHNvIHlvdSBjYW4gdXNlIHRoZXNlIG1ldGhvZHMgYXMgbWFueSB0aW1lcyBhcyB5b3UgbGlrZSwgd2hlbmV2ZXIgeW91CgkgKiBsaWtlLgoJICoKCSAqICAgICAgcXVldWUubG9hZEZpbGUoImZpbGVQYXRoL2ZpbGUuanBnIik7CgkgKiAgICAgIHF1ZXVlLmxvYWRGaWxlKHtpZDoiaW1hZ2UiLCBzcmM6ImZpbGVQYXRoL2ZpbGUuanBnIn0pOwoJICogICAgICBxdWV1ZS5sb2FkTWFuaWZlc3QoWyJmaWxlUGF0aC9maWxlLmpwZyIsIHtpZDoiaW1hZ2UiLCBzcmM6ImZpbGVQYXRoL2ZpbGUuanBnIn1dKTsKCSAqCgkgKiAgICAgIC8vIFVzZSBhbiBleHRlcm5hbCBtYW5pZmVzdAoJICogICAgICBxdWV1ZS5sb2FkTWFuaWZlc3QoInBhdGgvdG8vbWFuaWZlc3QuanNvbiIpOwoJICogICAgICBxdWV1ZS5sb2FkTWFuaWZlc3Qoe3NyYzoibWFuaWZlc3QuanNvbiIsIHR5cGU6Im1hbmlmZXN0In0pOwoJICoKCSAqIElmIHlvdSBwYXNzIGBmYWxzZWAgYXMgdGhlIGBsb2FkTm93YCBwYXJhbWV0ZXIsIHRoZSBxdWV1ZSB3aWxsIG5vdCBraWNrIG9mIHRoZSBsb2FkIG9mIHRoZSBmaWxlcywgYnV0IGl0IHdpbGwgbm90CgkgKiBzdG9wIGlmIGl0IGhhcyBhbHJlYWR5IGJlZW4gc3RhcnRlZC4gQ2FsbCB0aGUge3sjY3Jvc3NMaW5rICJBYnN0cmFjdExvYWRlci9sb2FkIn19e3svY3Jvc3NMaW5rfX0gbWV0aG9kIHRvIGJlZ2luCgkgKiBhIHBhdXNlZCBxdWV1ZS4gTm90ZSB0aGF0IGEgcGF1c2VkIHF1ZXVlIHdpbGwgYXV0b21hdGljYWxseSByZXN1bWUgd2hlbiBuZXcgZmlsZXMgYXJlIGFkZGVkIHRvIGl0IHdpdGggYQoJICogYGxvYWROb3dgIGFyZ3VtZW50IG9mIGB0cnVlYC4KCSAqCgkgKiAgICAgIHF1ZXVlLmxvYWQoKTsKCSAqCgkgKiA8Yj5GaWxlIFR5cGVzPC9iPjxiciAvPgoJICogVGhlIGZpbGUgdHlwZSBvZiBhIG1hbmlmZXN0IGl0ZW0gaXMgYXV0by1kZXRlcm1pbmVkIGJ5IHRoZSBmaWxlIGV4dGVuc2lvbi4gVGhlIHBhdHRlcm4gbWF0Y2hpbmcgaW4gUHJlbG9hZEpTCgkgKiBzaG91bGQgaGFuZGxlIHRoZSBtYWpvcml0eSBvZiBzdGFuZGFyZCBmaWxlIGFuZCB1cmwgZm9ybWF0cywgYW5kIHdvcmtzIHdpdGggY29tbW9uIGZpbGUgZXh0ZW5zaW9ucy4gSWYgeW91IGhhdmUKCSAqIGVpdGhlciBhIG5vbi1zdGFuZGFyZCBmaWxlIGV4dGVuc2lvbiwgb3IgYXJlIHNlcnZpbmcgdGhlIGZpbGUgdXNpbmcgYSBwcm94eSBzY3JpcHQsIHRoZW4geW91IGNhbiBwYXNzIGluIGEKCSAqIDxjb2RlPnR5cGU8L2NvZGU+IHByb3BlcnR5IHdpdGggYW55IG1hbmlmZXN0IGl0ZW0uCgkgKgoJICogICAgICBxdWV1ZS5sb2FkRmlsZSh7c3JjOiJwYXRoL3RvL215RmlsZS5tcDN4IiwgdHlwZTpjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5TT1VORH0pOwoJICoKCSAqICAgICAgLy8gTm90ZSB0aGF0IFByZWxvYWRKUyB3aWxsIG5vdCByZWFkIGEgZmlsZSBleHRlbnNpb24gZnJvbSB0aGUgcXVlcnkgc3RyaW5nCgkgKiAgICAgIHF1ZXVlLmxvYWRGaWxlKHtzcmM6Imh0dHA6Ly9zZXJ2ZXIuY29tL3Byb3h5P2ZpbGU9aW1hZ2UuanBnIiwgdHlwZTpjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5JTUFHRX0pOwoJICoKCSAqIFN1cHBvcnRlZCB0eXBlcyBhcmUgZGVmaW5lZCBvbiB0aGUge3sjY3Jvc3NMaW5rICJBYnN0cmFjdExvYWRlciJ9fXt7L2Nyb3NzTGlua319IGNsYXNzLCBhbmQgaW5jbHVkZToKCSAqIDx1bD4KCSAqICAgICA8bGk+e3sjY3Jvc3NMaW5rICJBYnN0cmFjdExvYWRlci9CSU5BUlk6cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fTogUmF3IGJpbmFyeSBkYXRhIHZpYSBYSFI8L2xpPgoJICogICAgIDxsaT57eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyL0NTUzpwcm9wZXJ0eSJ9fXt7L2Nyb3NzTGlua319OiBDU1MgZmlsZXM8L2xpPgoJICogICAgIDxsaT57eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyL0lNQUdFOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX06IENvbW1vbiBpbWFnZSBmb3JtYXRzPC9saT4KCSAqICAgICA8bGk+e3sjY3Jvc3NMaW5rICJBYnN0cmFjdExvYWRlci9KQVZBU0NSSVBUOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX06IEphdmFTY3JpcHQgZmlsZXM8L2xpPgoJICogICAgIDxsaT57eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyL0pTT046cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fTogSlNPTiBkYXRhPC9saT4KCSAqICAgICA8bGk+e3sjY3Jvc3NMaW5rICJBYnN0cmFjdExvYWRlci9KU09OUDpwcm9wZXJ0eSJ9fXt7L2Nyb3NzTGlua319OiBKU09OIGZpbGVzIGNyb3NzLWRvbWFpbjwvbGk+CgkgKiAgICAgPGxpPnt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvTUFOSUZFU1Q6cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fTogQSBsaXN0IG9mIGZpbGVzIHRvIGxvYWQgaW4gSlNPTiBmb3JtYXQsIHNlZQoJICogICAgIHt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvbG9hZE1hbmlmZXN0In19e3svY3Jvc3NMaW5rfX08L2xpPgoJICogICAgIDxsaT57eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyL1NPVU5EOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX06IEF1ZGlvIGZpbGUgZm9ybWF0czwvbGk+CgkgKiAgICAgPGxpPnt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvU1BSSVRFU0hFRVQ6cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fTogSlNPTiBTcHJpdGVTaGVldCBkZWZpbml0ZWlvbnMuIFRoaXMKCSAqICAgICB3aWxsIGFsc28gbG9hZCBzdWItaW1hZ2VzLCBhbmQgcHJvdmlkZSBhIHt7I2Nyb3NzTGluayAiU3ByaXRlU2hlZXQifX17ey9jcm9zc0xpbmt9fSBpbnN0YW5jZS48L2xpPgoJICogICAgIDxsaT57eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyL1NWRzpwcm9wZXJ0eSJ9fXt7L2Nyb3NzTGlua319OiBTVkcgZmlsZXM8L2xpPgoJICogICAgIDxsaT57eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyL1RFWFQ6cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fTogVGV4dCBmaWxlcyAtIFhIUiBvbmx5PC9saT4KCSAqICAgICA8bGk+e3sjY3Jvc3NMaW5rICJBYnN0cmFjdExvYWRlci9YTUw6cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fTogWE1MIGRhdGE8L2xpPgoJICogPC91bD4KCSAqCgkgKiA8ZW0+Tm90ZTogTG9hZGVyIHR5cGVzIHVzZWQgdG8gYmUgZGVmaW5lZCBvbiBMb2FkUXVldWUsIGJ1dCBoYXZlIGJlZW4gbW92ZWQgdG8gQWJzdHJhY3RMb2FkZXIgZm9yIGJldHRlcgoJICogcG9ydGFiaWxpdHkgb2YgbG9hZGVyIGNsYXNzZXMsIHdoaWNoIGNhbiBiZSB1c2VkIGluZGl2aWR1YWxseSBub3cuIFRoZSBwcm9wZXJ0aWVzIG9uIExvYWRRdWV1ZSBzdGlsbCBleGlzdCwgYnV0CgkgKiBhcmUgZGVwcmVjYXRlZC48L2VtPgoJICoKCSAqIDxiPkhhbmRsaW5nIFJlc3VsdHM8L2I+PGJyIC8+CgkgKiBXaGVuIGEgZmlsZSBpcyBmaW5pc2hlZCBkb3dubG9hZGluZywgYSB7eyNjcm9zc0xpbmsgIkxvYWRRdWV1ZS9maWxlbG9hZDpldmVudCJ9fXt7L2Nyb3NzTGlua319IGV2ZW50IGlzCgkgKiBkaXNwYXRjaGVkLiBJbiBhbiBleGFtcGxlIGFib3ZlLCB0aGVyZSBpcyBhbiBldmVudCBsaXN0ZW5lciBzbmlwcGV0IGZvciBmaWxlbG9hZC4gTG9hZGVkIGZpbGVzIGFyZSB1c3VhbGx5IGEKCSAqIGZvcm1hdHRlZCBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCBpbW1lZGlhdGVseSwgaW5jbHVkaW5nOgoJICogPHVsPgoJICogICAgIDxsaT5CaW5hcnk6IFRoZSBiaW5hcnkgbG9hZGVkIHJlc3VsdDwvbGk+CgkgKiAgICAgPGxpPkNTUzogQSAmbHQ7bGluayAvJmd0OyB0YWc8L2xpPgoJICogICAgIDxsaT5JbWFnZTogQW4gJmx0O2ltZyAvJmd0OyB0YWc8L2xpPgoJICogICAgIDxsaT5KYXZhU2NyaXB0OiBBICZsdDtzY3JpcHQgLyZndDsgdGFnPC9saT4KCSAqICAgICA8bGk+SlNPTi9KU09OUDogQSBmb3JtYXR0ZWQgSmF2YVNjcmlwdCBPYmplY3Q8L2xpPgoJICogICAgIDxsaT5NYW5pZmVzdDogQSBKYXZhU2NyaXB0IG9iamVjdC4KCSAqICAgICA8bGk+U291bmQ6IEFuICZsdDthdWRpbyAvJmd0OyB0YWc8L2E+CgkgKiAgICAgPGxpPlNwcml0ZVNoZWV0OiBBIHt7I2Nyb3NzTGluayAiU3ByaXRlU2hlZXQifX17ey9jcm9zc0xpbmt9fSBpbnN0YW5jZSwgY29udGFpbmluZyBsb2FkZWQgaW1hZ2VzLgoJICogICAgIDxsaT5TVkc6IEFuICZsdDtvYmplY3QgLyZndDsgdGFnPC9saT4KCSAqICAgICA8bGk+VGV4dDogUmF3IHRleHQ8L2xpPgoJICogICAgIDxsaT5YTUw6IEFuIFhNTCBET00gbm9kZTwvbGk+CgkgKiA8L3VsPgoJICoKCSAqICAgICAgZnVuY3Rpb24gaGFuZGxlRmlsZUxvYWQoZXZlbnQpIHsKCSAqICAgICAgICAgIHZhciBpdGVtID0gZXZlbnQuaXRlbTsgLy8gQSByZWZlcmVuY2UgdG8gdGhlIGl0ZW0gdGhhdCB3YXMgcGFzc2VkIGluIHRvIHRoZSBMb2FkUXVldWUKCSAqICAgICAgICAgIHZhciB0eXBlID0gaXRlbS50eXBlOwoJICoKCSAqICAgICAgICAgIC8vIEFkZCBhbnkgaW1hZ2VzIHRvIHRoZSBwYWdlIGJvZHkuCgkgKiAgICAgICAgICBpZiAodHlwZSA9PSBjcmVhdGVqcy5Mb2FkUXVldWUuSU1BR0UpIHsKCSAqICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGV2ZW50LnJlc3VsdCk7CgkgKiAgICAgICAgICB9CgkgKiAgICAgIH0KCSAqCgkgKiBBdCBhbnkgdGltZSBhZnRlciB0aGUgZmlsZSBoYXMgYmVlbiBsb2FkZWQgKHVzdWFsbHkgYWZ0ZXIgdGhlIHF1ZXVlIGhhcyBjb21wbGV0ZWQpLCBhbnkgcmVzdWx0IGNhbiBiZSBsb29rZWQgdXAKCSAqIHZpYSBpdHMgImlkIiB1c2luZyB7eyNjcm9zc0xpbmsgIkxvYWRRdWV1ZS9nZXRSZXN1bHQifX17ey9jcm9zc0xpbmt9fS4gSWYgbm8gaWQgd2FzIHByb3ZpZGVkLCB0aGVuIHRoZQoJICogInNyYyIgb3IgZmlsZSBwYXRoIGNhbiBiZSB1c2VkIGluc3RlYWQsIGluY2x1ZGluZyB0aGUgYHBhdGhgIGRlZmluZWQgYnkgYSBtYW5pZmVzdCwgYnV0IDxzdHJvbmc+bm90IGluY2x1ZGluZzwvc3Ryb25nPgoJICogYSBiYXNlIHBhdGggZGVmaW5lZCBvbiB0aGUgTG9hZFF1ZXVlLiBJdCBpcyByZWNvbW1lbmRlZCB0byBhbHdheXMgcGFzcyBhbiBpZCBpZiB5b3Ugd2FudCB0byBsb29rIHVwIGNvbnRlbnQuCgkgKgoJICogICAgICB2YXIgaW1hZ2UgPSBxdWV1ZS5nZXRSZXN1bHQoImltYWdlIik7CgkgKiAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoaW1hZ2UpOwoJICoKCSAqIFJhdyBsb2FkZWQgY29udGVudCBjYW4gYmUgYWNjZXNzZWQgdXNpbmcgdGhlIDxjb2RlPnJhd1Jlc3VsdDwvY29kZT4gcHJvcGVydHkgb2YgdGhlIHt7I2Nyb3NzTGluayAiTG9hZFF1ZXVlL2ZpbGVsb2FkOmV2ZW50In19e3svY3Jvc3NMaW5rfX0KCSAqIGV2ZW50LCBvciBjYW4gYmUgbG9va2VkIHVwIHVzaW5nIHt7I2Nyb3NzTGluayAiTG9hZFF1ZXVlL2dldFJlc3VsdCJ9fXt7L2Nyb3NzTGlua319LCBwYXNzaW5nIGB0cnVlYCBhcyB0aGUgMm5kCgkgKiBhcmd1bWVudC4gVGhpcyBpcyBvbmx5IGFwcGxpY2FibGUgZm9yIGNvbnRlbnQgdGhhdCBoYXMgYmVlbiBwYXJzZWQgZm9yIHRoZSBicm93c2VyLCBzcGVjaWZpY2FsbHk6IEphdmFTY3JpcHQsCgkgKiBDU1MsIFhNTCwgU1ZHLCBhbmQgSlNPTiBvYmplY3RzLCBvciBhbnl0aGluZyBsb2FkZWQgd2l0aCBYSFIuCgkgKgoJICogICAgICB2YXIgaW1hZ2UgPSBxdWV1ZS5nZXRSZXN1bHQoImltYWdlIiwgdHJ1ZSk7IC8vIGxvYWQgdGhlIGJpbmFyeSBpbWFnZSBkYXRhIGxvYWRlZCB3aXRoIFhIUi4KCSAqCgkgKiA8Yj5QbHVnaW5zPC9iPjxiciAvPgoJICogTG9hZFF1ZXVlIGhhcyBhIHNpbXBsZSBwbHVnaW4gYXJjaGl0ZWN0dXJlIHRvIGhlbHAgcHJvY2VzcyBhbmQgcHJlbG9hZCBjb250ZW50LiBGb3IgZXhhbXBsZSwgdG8gcHJlbG9hZCBhdWRpbywKCSAqIG1ha2Ugc3VyZSB0byBpbnN0YWxsIHRoZSA8YSBocmVmPSJodHRwOi8vc291bmRqcy5jb20iPlNvdW5kSlM8L2E+IFNvdW5kIGNsYXNzLCB3aGljaCB3aWxsIGhlbHAgbG9hZCBIVE1MIGF1ZGlvLAoJICogRmxhc2ggYXVkaW8sIGFuZCBXZWJBdWRpbyBmaWxlcy4gVGhpcyBzaG91bGQgYmUgaW5zdGFsbGVkIDxzdHJvbmc+YmVmb3JlPC9zdHJvbmc+IGxvYWRpbmcgYW55IGF1ZGlvIGZpbGVzLgoJICoKCSAqICAgICAgcXVldWUuaW5zdGFsbFBsdWdpbihjcmVhdGVqcy5Tb3VuZCk7CgkgKgoJICogPGg0Pktub3duIEJyb3dzZXIgSXNzdWVzPC9oND4KCSAqIDx1bD4KCSAqICAgICA8bGk+QnJvd3NlcnMgd2l0aG91dCBhdWRpbyBzdXBwb3J0IGNhbiBub3QgbG9hZCBhdWRpbyBmaWxlcy48L2xpPgoJICogICAgIDxsaT5TYWZhcmkgb24gTWFjIE9TIFggY2FuIG9ubHkgcGxheSBIVE1MIGF1ZGlvIGlmIFF1aWNrVGltZSBpcyBpbnN0YWxsZWQ8L2xpPgoJICogICAgIDxsaT5IVE1MIEF1ZGlvIHRhZ3Mgd2lsbCBvbmx5IGRvd25sb2FkIHVudGlsIHRoZWlyIDxjb2RlPmNhblBsYXlUaHJvdWdoPC9jb2RlPiBldmVudCBpcyBmaXJlZC4gQnJvd3NlcnMgb3RoZXIKCSAqICAgICB0aGFuIENocm9tZSB3aWxsIGNvbnRpbnVlIHRvIGRvd25sb2FkIGluIHRoZSBiYWNrZ3JvdW5kLjwvbGk+CgkgKiAgICAgPGxpPldoZW4gbG9hZGluZyBzY3JpcHRzIHVzaW5nIHRhZ3MsIHRoZXkgYXJlIGF1dG9tYXRpY2FsbHkgYWRkZWQgdG8gdGhlIGRvY3VtZW50LjwvbGk+CgkgKiAgICAgPGxpPlNjcmlwdHMgbG9hZGVkIHZpYSBYSFIgbWF5IG5vdCBiZSBwcm9wZXJseSBpbnNwZWN0YWJsZSB3aXRoIGJyb3dzZXIgdG9vbHMuPC9saT4KCSAqICAgICA8bGk+SUU2IGFuZCBJRTcgKGFuZCBzb21lIG90aGVyIGJyb3dzZXJzKSBtYXkgbm90IGJlIGFibGUgdG8gbG9hZCBYTUwsIFRleHQsIG9yIEpTT04sIHNpbmNlIHRoZXkgcmVxdWlyZQoJICogICAgIFhIUiB0byB3b3JrLjwvbGk+CgkgKiAgICAgPGxpPkNvbnRlbnQgbG9hZGVkIHZpYSB0YWdzIHdpbGwgbm90IHNob3cgcHJvZ3Jlc3MsIGFuZCB3aWxsIGNvbnRpbnVlIHRvIGRvd25sb2FkIGluIHRoZSBiYWNrZ3JvdW5kIHdoZW4KCSAqICAgICBjYW5jZWxlZCwgYWx0aG91Z2ggbm8gZXZlbnRzIHdpbGwgYmUgZGlzcGF0Y2hlZC48L2xpPgoJICogPC91bD4KCSAqCgkgKiBAY2xhc3MgTG9hZFF1ZXVlCgkgKiBAcGFyYW0ge0Jvb2xlYW59IFtwcmVmZXJYSFI9dHJ1ZV0gRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBwcmVsb2FkIGluc3RhbmNlIHdpbGwgZmF2b3IgbG9hZGluZyB3aXRoIFhIUiAoWE1MIEhUVFAKCSAqIFJlcXVlc3RzKSwgb3IgSFRNTCB0YWdzLiBXaGVuIHRoaXMgaXMgYGZhbHNlYCwgdGhlIHF1ZXVlIHdpbGwgdXNlIHRhZyBsb2FkaW5nIHdoZW4gcG9zc2libGUsIGFuZCBmYWxsIGJhY2sgb24gWEhSCgkgKiB3aGVuIG5lY2Vzc2FyeS4KCSAqIEBwYXJhbSB7U3RyaW5nfSBbYmFzZVBhdGg9IiJdIEEgcGF0aCB0aGF0IHdpbGwgYmUgcHJlcGVuZGVkIG9uIHRvIHRoZSBzb3VyY2UgcGFyYW1ldGVyIG9mIGFsbCBpdGVtcyBpbiB0aGUgcXVldWUKCSAqIGJlZm9yZSB0aGV5IGFyZSBsb2FkZWQuICBTb3VyY2VzIGJlZ2lubmluZyB3aXRoIGEgcHJvdG9jb2wgc3VjaCBhcyBgaHR0cDovL2Agb3IgYSByZWxhdGl2ZSBwYXRoIHN1Y2ggYXMgYC4uL2AKCSAqIHdpbGwgbm90IHJlY2VpdmUgYSBiYXNlIHBhdGguCgkgKiBAcGFyYW0ge1N0cmluZ3xCb29sZWFufSBbY3Jvc3NPcmlnaW49IiJdIEFuIG9wdGlvbmFsIGZsYWcgdG8gc3VwcG9ydCBpbWFnZXMgbG9hZGVkIGZyb20gYSBDT1JTLWVuYWJsZWQgc2VydmVyLiBUbwoJICogdXNlIGl0LCBzZXQgdGhpcyB2YWx1ZSB0byBgdHJ1ZWAsIHdoaWNoIHdpbGwgZGVmYXVsdCB0aGUgY3Jvc3NPcmlnaW4gcHJvcGVydHkgb24gaW1hZ2VzIHRvICJBbm9ueW1vdXMiLiBBbnkKCSAqIHN0cmluZyB2YWx1ZSB3aWxsIGJlIHBhc3NlZCB0aHJvdWdoLCBidXQgb25seSAiIiBhbmQgIkFub255bW91cyIgYXJlIHJlY29tbWVuZGVkLiA8c3Ryb25nPk5vdGU6IFRoZSBjcm9zc09yaWdpbgoJICogcGFyYW1ldGVyIGlzIGRlcHJlY2F0ZWQuIFVzZSBMb2FkSXRlbS5jcm9zc09yaWdpbiBpbnN0ZWFkPC9zdHJvbmc+CgkgKgoJICogQGNvbnN0cnVjdG9yCgkgKiBAZXh0ZW5kcyBBYnN0cmFjdExvYWRlcgoJICovCglmdW5jdGlvbiBMb2FkUXVldWUocHJlZmVyWEhSLCBiYXNlUGF0aCwgY3Jvc3NPcmlnaW4pIHsKCQl0aGlzLkFic3RyYWN0TG9hZGVyX2NvbnN0cnVjdG9yKCk7CgkJdGhpcy5pbml0KHByZWZlclhIUiwgYmFzZVBhdGgsIGNyb3NzT3JpZ2luKTsKCX0KCgl2YXIgcCA9IGNyZWF0ZWpzLmV4dGVuZChMb2FkUXVldWUsIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyKTsKCXZhciBzID0gTG9hZFF1ZXVlOwoKCS8qKgoJICogPHN0cm9uZz5SRU1PVkVEPC9zdHJvbmc+LiBSZW1vdmVkIGluIGZhdm9yIG9mIHVzaW5nIGBNeVN1cGVyQ2xhc3NfY29uc3RydWN0b3JgLgoJICogU2VlIHt7I2Nyb3NzTGluayAiVXRpbGl0eSBNZXRob2RzL2V4dGVuZCJ9fXt7L2Nyb3NzTGlua319IGFuZCB7eyNjcm9zc0xpbmsgIlV0aWxpdHkgTWV0aG9kcy9wcm9tb3RlIn19e3svY3Jvc3NMaW5rfX0KCSAqIGZvciBkZXRhaWxzLgoJICoKCSAqIFRoZXJlIGlzIGFuIGluaGVyaXRhbmNlIHR1dG9yaWFsIGRpc3RyaWJ1dGVkIHdpdGggRWFzZWxKUyBpbiAvdHV0b3JpYWxzL0luaGVyaXRhbmNlLgoJICoKCSAqIEBtZXRob2QgaW5pdGlhbGl6ZQoJICogQHByb3RlY3RlZAoJICogQGRlcHJlY2F0ZWQKCSAqLwoJLy8gcC5pbml0aWFsaXplID0gZnVuY3Rpb24oKSB7fTsgLy8gc2VhcmNoYWJsZSBmb3IgZGV2cyB3b25kZXJpbmcgd2hlcmUgaXQgaXMuCgoKCS8qKgoJICogQW4gaW50ZXJuYWwgaW5pdGlhbGl6YXRpb24gbWV0aG9kLCB3aGljaCBpcyB1c2VkIGZvciBpbml0aWFsIHNldCB1cCwgYnV0IGFsc28gdG8gcmVzZXQgdGhlIExvYWRRdWV1ZS4KCSAqIEBtZXRob2QgaW5pdAoJICogQHBhcmFtIHByZWZlclhIUgoJICogQHBhcmFtIGJhc2VQYXRoCgkgKiBAcGFyYW0gY3Jvc3NPcmlnaW4KCSAqIEBwcml2YXRlCgkgKi8KCXAuaW5pdCA9IGZ1bmN0aW9uKHByZWZlclhIUiwgYmFzZVBhdGgsIGNyb3NzT3JpZ2luKSB7CgoJCS8vIHB1YmxpYyBwcm9wZXJ0aWVzCgkJLyoqCgkJICogQHByb3BlcnR5IHVzZVhIUgoJCSAqIEB0eXBlIHtCb29sZWFufQoJCSAqIEByZWFkT25seQoJCSAqIEBkZWZhdWx0IHRydWUKCQkgKiBAZGVwcmVjYXRlZCBVc2UgcHJlZmVyWEhSIGluc3RlYWQuCgkJICovCgkJdGhpcy51c2VYSFIgPSB0cnVlOwoKCQkvKioKCQkgKiBUcnkgYW5kIHVzZSBYTUxIdHRwUmVxdWVzdCAoWEhSKSB3aGVuIHBvc3NpYmxlLiBOb3RlIHRoYXQgTG9hZFF1ZXVlIHdpbGwgZGVmYXVsdCB0byB0YWcgbG9hZGluZyBvciBYSFIKCQkgKiBsb2FkaW5nIGRlcGVuZGluZyBvbiB0aGUgcmVxdWlyZW1lbnRzIGZvciBhIG1lZGlhIHR5cGUuIEZvciBleGFtcGxlLCBIVE1MIGF1ZGlvIGNhbiBub3QgYmUgbG9hZGVkIHdpdGggWEhSLAoJCSAqIGFuZCBwbGFpbiB0ZXh0IGNhbiBub3QgYmUgbG9hZGVkIHdpdGggdGFncywgc28gaXQgd2lsbCBkZWZhdWx0IHRoZSB0aGUgY29ycmVjdCB0eXBlIGluc3RlYWQgb2YgdXNpbmcgdGhlCgkJICogdXNlci1kZWZpbmVkIHR5cGUuCgkJICogQHR5cGUge0Jvb2xlYW59CgkJICogQGRlZmF1bHQgdHJ1ZQoJCSAqIEBzaW5jZSAwLjYuMAoJCSAqLwoJCXRoaXMucHJlZmVyWEhSID0gdHJ1ZTsgLy9UT0RPOiBHZXQvU2V0CgkJdGhpcy5fcHJlZmVyWEhSID0gdHJ1ZTsKCQl0aGlzLnNldFByZWZlclhIUihwcmVmZXJYSFIpOwoKCQkvKioKCQkgKiBEZXRlcm1pbmVzIGlmIHRoZSBMb2FkUXVldWUgd2lsbCBzdG9wIHByb2Nlc3NpbmcgdGhlIGN1cnJlbnQgcXVldWUgd2hlbiBhbiBlcnJvciBpcyBlbmNvdW50ZXJlZC4KCQkgKiBAcHJvcGVydHkgc3RvcE9uRXJyb3IKCQkgKiBAdHlwZSB7Qm9vbGVhbn0KCQkgKiBAZGVmYXVsdCBmYWxzZQoJCSAqLwoJCXRoaXMuc3RvcE9uRXJyb3IgPSBmYWxzZTsKCgkJLyoqCgkJICogRW5zdXJlIGxvYWRlZCBzY3JpcHRzICJjb21wbGV0ZSIgaW4gdGhlIG9yZGVyIHRoZXkgYXJlIHNwZWNpZmllZC4gTG9hZGVkIHNjcmlwdHMgYXJlIGFkZGVkIHRvIHRoZSBkb2N1bWVudCBoZWFkCgkJICogb25jZSB0aGV5IGFyZSBsb2FkZWQuIFNjcmlwdHMgbG9hZGVkIHZpYSB0YWdzIHdpbGwgbG9hZCBvbmUtYXQtYS10aW1lIHdoZW4gdGhpcyBwcm9wZXJ0eSBpcyBgdHJ1ZWAsIHdoZXJlYXMKCQkgKiBzY3JpcHRzIGxvYWRlZCB1c2luZyBYSFIgY2FuIGxvYWQgaW4gYW55IG9yZGVyLCBidXQgd2lsbCAiZmluaXNoIiBhbmQgYmUgYWRkZWQgdG8gdGhlIGRvY3VtZW50IGluIHRoZSBvcmRlcgoJCSAqIHNwZWNpZmllZC4KCQkgKgoJCSAqIEFueSBpdGVtcyBjYW4gYmUgc2V0IHRvIGxvYWQgaW4gb3JkZXIgYnkgc2V0dGluZyB0aGUge3sjY3Jvc3NMaW5rICJtYWludGFpbk9yZGVyOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0KCQkgKiBwcm9wZXJ0eSBvbiB0aGUgbG9hZCBpdGVtLCBvciBieSBlbnN1cmluZyB0aGF0IG9ubHkgb25lIGNvbm5lY3Rpb24gY2FuIGJlIG9wZW4gYXQgYSB0aW1lIHVzaW5nCgkJICoge3sjY3Jvc3NMaW5rICJMb2FkUXVldWUvc2V0TWF4Q29ubmVjdGlvbnMifX17ey9jcm9zc0xpbmt9fS4gTm90ZSB0aGF0IHdoZW4gdGhlIGBtYWludGFpblNjcmlwdE9yZGVyYCBwcm9wZXJ0eQoJCSAqIGlzIHNldCB0byBgdHJ1ZWAsIHNjcmlwdHMgaXRlbXMgYXJlIGF1dG9tYXRpY2FsbHkgc2V0IHRvIGBtYWludGFpbk9yZGVyPXRydWVgLCBhbmQgY2hhbmdpbmcgdGhlCgkJICogYG1haW50YWluU2NyaXB0T3JkZXJgIHRvIGBmYWxzZWAgZHVyaW5nIGEgbG9hZCB3aWxsIG5vdCBjaGFuZ2UgaXRlbXMgYWxyZWFkeSBpbiBhIHF1ZXVlLgoJCSAqCgkJICogPGg0PkV4YW1wbGU8L2g0PgoJCSAqCgkJICogICAgICB2YXIgcXVldWUgPSBuZXcgY3JlYXRlanMuTG9hZFF1ZXVlKCk7CgkJICogICAgICBxdWV1ZS5zZXRNYXhDb25uZWN0aW9ucygzKTsgLy8gU2V0IGEgaGlnaGVyIG51bWJlciB0byBsb2FkIG11bHRpcGxlIGl0ZW1zIGF0IG9uY2UKCQkgKiAgICAgIHF1ZXVlLm1haW50YWluU2NyaXB0T3JkZXIgPSB0cnVlOyAvLyBFbnN1cmUgc2NyaXB0cyBhcmUgbG9hZGVkIGluIG9yZGVyCgkJICogICAgICBxdWV1ZS5sb2FkTWFuaWZlc3QoWwoJCSAqICAgICAgICAgICJzY3JpcHQxLmpzIiwKCQkgKiAgICAgICAgICAic2NyaXB0Mi5qcyIsCgkJICogICAgICAgICAgImltYWdlLnBuZyIsIC8vIExvYWQgYW55IHRpbWUKCQkgKiAgICAgICAgICB7c3JjOiAiaW1hZ2UyLnBuZyIsIG1haW50YWluT3JkZXI6IHRydWV9IC8vIFdpbGwgd2FpdCBmb3Igc2NyaXB0Mi5qcwoJCSAqICAgICAgICAgICJpbWFnZTMucG5nIiwKCQkgKiAgICAgICAgICAic2NyaXB0My5qcyIgLy8gV2lsbCB3YWl0IGZvciBpbWFnZTIucG5nIGJlZm9yZSBsb2FkaW5nIChvciBjb21wbGV0aW5nIHdoZW4gbG9hZGluZyB3aXRoIFhIUikKCQkgKiAgICAgIF0pOwoJCSAqCgkJICogQHByb3BlcnR5IG1haW50YWluU2NyaXB0T3JkZXIKCQkgKiBAdHlwZSB7Qm9vbGVhbn0KCQkgKiBAZGVmYXVsdCB0cnVlCgkJICovCgkJdGhpcy5tYWludGFpblNjcmlwdE9yZGVyID0gdHJ1ZTsKCgkJLyoqCgkJICogVGhlIG5leHQgcHJlbG9hZCBxdWV1ZSB0byBwcm9jZXNzIHdoZW4gdGhpcyBvbmUgaXMgY29tcGxldGUuIElmIGFuIGVycm9yIGlzIHRocm93biBpbiB0aGUgY3VycmVudCBxdWV1ZSwgYW5kCgkJICoge3sjY3Jvc3NMaW5rICJMb2FkUXVldWUvc3RvcE9uRXJyb3I6cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fSBpcyBgdHJ1ZWAsIHRoZSBuZXh0IHF1ZXVlIHdpbGwgbm90IGJlIHByb2Nlc3NlZC4KCQkgKiBAcHJvcGVydHkgbmV4dAoJCSAqIEB0eXBlIHtMb2FkUXVldWV9CgkJICogQGRlZmF1bHQgbnVsbAoJCSAqLwoJCXRoaXMubmV4dCA9IG51bGw7CgoJCS8vIHByb3RlY3RlZCBwcm9wZXJ0aWVzCgkJLyoqCgkJICogV2hldGhlciB0aGUgcXVldWUgaXMgY3VycmVudGx5IHBhdXNlZCBvciBub3QuCgkJICogQHByb3BlcnR5IF9wYXVzZWQKCQkgKiBAdHlwZSB7Ym9vbGVhbn0KCQkgKiBAcHJpdmF0ZQoJCSAqLwoJCXRoaXMuX3BhdXNlZCA9IGZhbHNlOwoKCQkvKioKCQkgKiBBIHBhdGggdGhhdCB3aWxsIGJlIHByZXBlbmRlZCBvbiB0byB0aGUgaXRlbSdzIHt7I2Nyb3NzTGluayAiTG9hZEl0ZW0vc3JjOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0uIFRoZQoJCSAqIGBfYmFzZVBhdGhgIHByb3BlcnR5IHdpbGwgb25seSBiZSB1c2VkIGlmIGFuIGl0ZW0ncyBzb3VyY2UgaXMgcmVsYXRpdmUsIGFuZCBkb2VzIG5vdCBpbmNsdWRlIGEgcHJvdG9jb2wgc3VjaAoJCSAqIGFzIGBodHRwOi8vYCwgb3IgYSByZWxhdGl2ZSBwYXRoIHN1Y2ggYXMgYC4uL2AuCgkJICogQHByb3BlcnR5IF9iYXNlUGF0aAoJCSAqIEB0eXBlIHtTdHJpbmd9CgkJICogQHByaXZhdGUKCQkgKiBAc2luY2UgMC4zLjEKCQkgKi8KCQl0aGlzLl9iYXNlUGF0aCA9IGJhc2VQYXRoOwoKCQkvKioKCQkgKiBBbiBvcHRpb25hbCBmbGFnIHRvIHNldCBvbiBpbWFnZXMgdGhhdCBhcmUgbG9hZGVkIHVzaW5nIFByZWxvYWRKUywgd2hpY2ggZW5hYmxlcyBDT1JTIHN1cHBvcnQuIEltYWdlcyBsb2FkZWQKCQkgKiBjcm9zcy1kb21haW4gYnkgc2VydmVycyB0aGF0IHN1cHBvcnQgQ09SUyByZXF1aXJlIHRoZSBjcm9zc09yaWdpbiBmbGFnIHRvIGJlIGxvYWRlZCBhbmQgaW50ZXJhY3RlZCB3aXRoIGJ5CgkJICogYSBjYW52YXMuIFdoZW4gbG9hZGluZyBsb2NhbGx5LCBvciB3aXRoIGEgc2VydmVyIHdpdGggbm8gQ09SUyBzdXBwb3J0LCB0aGlzIGZsYWcgY2FuIGNhdXNlIG90aGVyIHNlY3VyaXR5IGlzc3VlcywKCQkgKiBzbyBpdCBpcyByZWNvbW1lbmRlZCB0byBvbmx5IHNldCBpdCBpZiB5b3UgYXJlIHN1cmUgdGhlIHNlcnZlciBzdXBwb3J0cyBpdC4gQ3VycmVudGx5LCBzdXBwb3J0ZWQgdmFsdWVzIGFyZSAiIgoJCSAqIGFuZCAiQW5vbnltb3VzIi4KCQkgKiBAcHJvcGVydHkgX2Nyb3NzT3JpZ2luCgkJICogQHR5cGUge1N0cmluZ30KCQkgKiBAZGVmYXVsdCAiIgoJCSAqIEBwcml2YXRlCgkJICogQHNpbmNlIDAuNC4xCgkJICovCgkJdGhpcy5fY3Jvc3NPcmlnaW4gPSBjcm9zc09yaWdpbjsKCgkJLyoqCgkJICogQW4gb2JqZWN0IGhhc2ggb2YgY2FsbGJhY2tzIHRoYXQgYXJlIGZpcmVkIGZvciBlYWNoIGZpbGUgdHlwZSBiZWZvcmUgdGhlIGZpbGUgaXMgbG9hZGVkLCBnaXZpbmcgcGx1Z2lucyB0aGUKCQkgKiBhYmlsaXR5IHRvIG92ZXJyaWRlIHByb3BlcnRpZXMgb2YgdGhlIGxvYWQuIFBsZWFzZSBzZWUgdGhlIHt7I2Nyb3NzTGluayAiTG9hZFF1ZXVlL2luc3RhbGxQbHVnaW4ifX17ey9jcm9zc0xpbmt9fQoJCSAqIG1ldGhvZCBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KCQkgKiBAcHJvcGVydHkgX3R5cGVDYWxsYmFja3MKCQkgKiBAdHlwZSB7T2JqZWN0fQoJCSAqIEBwcml2YXRlCgkJICovCgkJdGhpcy5fdHlwZUNhbGxiYWNrcyA9IHt9OwoKCQkvKioKCQkgKiBBbiBvYmplY3QgaGFzaCBvZiBjYWxsYmFja3MgdGhhdCBhcmUgZmlyZWQgZm9yIGVhY2ggZmlsZSBleHRlbnNpb24gYmVmb3JlIHRoZSBmaWxlIGlzIGxvYWRlZCwgZ2l2aW5nIHBsdWdpbnMgdGhlCgkJICogYWJpbGl0eSB0byBvdmVycmlkZSBwcm9wZXJ0aWVzIG9mIHRoZSBsb2FkLiBQbGVhc2Ugc2VlIHRoZSB7eyNjcm9zc0xpbmsgIkxvYWRRdWV1ZS9pbnN0YWxsUGx1Z2luIn19e3svY3Jvc3NMaW5rfX0KCQkgKiBtZXRob2QgZm9yIG1vcmUgaW5mb3JtYXRpb24uCgkJICogQHByb3BlcnR5IF9leHRlbnNpb25DYWxsYmFja3MKCQkgKiBAdHlwZSB7bnVsbH0KCQkgKiBAcHJpdmF0ZQoJCSAqLwoJCXRoaXMuX2V4dGVuc2lvbkNhbGxiYWNrcyA9IHt9OwoKCQkvKioKCQkgKiBEZXRlcm1pbmVzIGlmIHRoZSBsb2FkU3RhcnQgZXZlbnQgd2FzIGRpc3BhdGNoZWQgYWxyZWFkeS4gVGhpcyBldmVudCBpcyBvbmx5IGZpcmVkIG9uZSB0aW1lLCB3aGVuIHRoZSBmaXJzdAoJCSAqIGZpbGUgaXMgcmVxdWVzdGVkLgoJCSAqIEBwcm9wZXJ0eSBfbG9hZFN0YXJ0V2FzRGlzcGF0Y2hlZAoJCSAqIEB0eXBlIHtCb29sZWFufQoJCSAqIEBkZWZhdWx0IGZhbHNlCgkJICogQHByaXZhdGUKCQkgKi8KCQl0aGlzLl9sb2FkU3RhcnRXYXNEaXNwYXRjaGVkID0gZmFsc2U7CgoJCS8qKgoJCSAqIFRoZSBudW1iZXIgb2YgbWF4aW11bSBvcGVuIGNvbm5lY3Rpb25zIHRoYXQgYSBsb2FkUXVldWUgdHJpZXMgdG8gbWFpbnRhaW4uIFBsZWFzZSBzZWUKCQkgKiB7eyNjcm9zc0xpbmsgIkxvYWRRdWV1ZS9zZXRNYXhDb25uZWN0aW9ucyJ9fXt7L2Nyb3NzTGlua319IGZvciBtb3JlIGluZm9ybWF0aW9uLgoJCSAqIEBwcm9wZXJ0eSBfbWF4Q29ubmVjdGlvbnMKCQkgKiBAdHlwZSB7TnVtYmVyfQoJCSAqIEBkZWZhdWx0IDEKCQkgKiBAcHJpdmF0ZQoJCSAqLwoJCXRoaXMuX21heENvbm5lY3Rpb25zID0gMTsKCgkJLyoqCgkJICogRGV0ZXJtaW5lcyBpZiB0aGVyZSBpcyBjdXJyZW50bHkgYSBzY3JpcHQgbG9hZGluZy4gVGhpcyBoZWxwcyBlbnN1cmUgdGhhdCBvbmx5IGEgc2luZ2xlIHNjcmlwdCBsb2FkcyBhdCBvbmNlIHdoZW4KCQkgKiB1c2luZyBhIHNjcmlwdCB0YWcgdG8gZG8gcHJlbG9hZGluZy4KCQkgKiBAcHJvcGVydHkgX2N1cnJlbnRseUxvYWRpbmdTY3JpcHQKCQkgKiBAdHlwZSB7Qm9vbGVhbn0KCQkgKiBAcHJpdmF0ZQoJCSAqLwoJCXRoaXMuX2N1cnJlbnRseUxvYWRpbmdTY3JpcHQgPSBudWxsOwoKCQkvKioKCQkgKiBBbiBhcnJheSBjb250YWluaW5nIHRoZSBjdXJyZW50bHkgZG93bmxvYWRpbmcgZmlsZXMuCgkJICogQHByb3BlcnR5IF9jdXJyZW50TG9hZHMKCQkgKiBAdHlwZSB7QXJyYXl9CgkJICogQHByaXZhdGUKCQkgKi8KCQl0aGlzLl9jdXJyZW50TG9hZHMgPSBbXTsKCgkJLyoqCgkJICogQW4gYXJyYXkgY29udGFpbmluZyB0aGUgcXVldWVkIGl0ZW1zIHRoYXQgaGF2ZSBub3QgeWV0IHN0YXJ0ZWQgZG93bmxvYWRpbmcuCgkJICogQHByb3BlcnR5IF9sb2FkUXVldWUKCQkgKiBAdHlwZSB7QXJyYXl9CgkJICogQHByaXZhdGUKCQkgKi8KCQl0aGlzLl9sb2FkUXVldWUgPSBbXTsKCgkJLyoqCgkJICogQW4gYXJyYXkgY29udGFpbmluZyBkb3dubG9hZHMgdGhhdCBoYXZlIG5vdCBjb21wbGV0ZWQsIHNvIHRoYXQgdGhlIExvYWRRdWV1ZSBjYW4gYmUgcHJvcGVybHkgcmVzZXQuCgkJICogQHByb3BlcnR5IF9sb2FkUXVldWVCYWNrdXAKCQkgKiBAdHlwZSB7QXJyYXl9CgkJICogQHByaXZhdGUKCQkgKi8KCQl0aGlzLl9sb2FkUXVldWVCYWNrdXAgPSBbXTsKCgkJLyoqCgkJICogQW4gb2JqZWN0IGhhc2ggb2YgaXRlbXMgdGhhdCBoYXZlIGZpbmlzaGVkIGRvd25sb2FkaW5nLCBpbmRleGVkIGJ5IHRoZSB7eyNjcm9zc0xpbmsgIkxvYWRJdGVtIn19e3svY3Jvc3NMaW5rfX0KCQkgKiBpZC4KCQkgKiBAcHJvcGVydHkgX2xvYWRJdGVtc0J5SWQKCQkgKiBAdHlwZSB7T2JqZWN0fQoJCSAqIEBwcml2YXRlCgkJICovCgkJdGhpcy5fbG9hZEl0ZW1zQnlJZCA9IHt9OwoKCQkvKioKCQkgKiBBbiBvYmplY3QgaGFzaCBvZiBpdGVtcyB0aGF0IGhhdmUgZmluaXNoZWQgZG93bmxvYWRpbmcsIGluZGV4ZWQgYnkge3sjY3Jvc3NMaW5rICJMb2FkSXRlbSJ9fXt7L2Nyb3NzTGlua319CgkJICogc291cmNlLgoJCSAqIEBwcm9wZXJ0eSBfbG9hZEl0ZW1zQnlTcmMKCQkgKiBAdHlwZSB7T2JqZWN0fQoJCSAqIEBwcml2YXRlCgkJICovCgkJdGhpcy5fbG9hZEl0ZW1zQnlTcmMgPSB7fTsKCgkJLyoqCgkJICogQW4gb2JqZWN0IGhhc2ggb2YgbG9hZGVkIGl0ZW1zLCBpbmRleGVkIGJ5IHRoZSBJRCBvZiB0aGUge3sjY3Jvc3NMaW5rICJMb2FkSXRlbSJ9fXt7L2Nyb3NzTGlua319LgoJCSAqIEBwcm9wZXJ0eSBfbG9hZGVkUmVzdWx0cwoJCSAqIEB0eXBlIHtPYmplY3R9CgkJICogQHByaXZhdGUKCQkgKi8KCQl0aGlzLl9sb2FkZWRSZXN1bHRzID0ge307CgoJCS8qKgoJCSAqIEFuIG9iamVjdCBoYXNoIG9mIHVuLXBhcnNlZCBsb2FkZWQgaXRlbXMsIGluZGV4ZWQgYnkgdGhlIElEIG9mIHRoZSB7eyNjcm9zc0xpbmsgIkxvYWRJdGVtIn19e3svY3Jvc3NMaW5rfX0uCgkJICogQHByb3BlcnR5IF9sb2FkZWRSYXdSZXN1bHRzCgkJICogQHR5cGUge09iamVjdH0KCQkgKiBAcHJpdmF0ZQoJCSAqLwoJCXRoaXMuX2xvYWRlZFJhd1Jlc3VsdHMgPSB7fTsKCgkJLyoqCgkJICogVGhlIG51bWJlciBvZiBpdGVtcyB0aGF0IGhhdmUgYmVlbiByZXF1ZXN0ZWQuIFRoaXMgaGVscHMgbWFuYWdlIGFuIG92ZXJhbGwgcHJvZ3Jlc3Mgd2l0aG91dCBrbm93aW5nIGhvdyBsYXJnZQoJCSAqIHRoZSBmaWxlcyBhcmUgYmVmb3JlIHRoZXkgYXJlIGRvd25sb2FkZWQuIFRoaXMgZG9lcyBub3QgaW5jbHVkZSBpdGVtcyBpbnNpZGUgb2YgbG9hZGVycyBzdWNoIGFzIHRoZQoJCSAqIHt7I2Nyb3NzTGluayAiTWFuaWZlc3RMb2FkZXIifX17ey9jcm9zc0xpbmt9fS4KCQkgKiBAcHJvcGVydHkgX251bUl0ZW1zCgkJICogQHR5cGUge051bWJlcn0KCQkgKiBAZGVmYXVsdCAwCgkJICogQHByaXZhdGUKCQkgKi8KCQl0aGlzLl9udW1JdGVtcyA9IDA7CgoJCS8qKgoJCSAqIFRoZSBudW1iZXIgb2YgaXRlbXMgdGhhdCBoYXZlIGNvbXBsZXRlZCBsb2FkZWQuIFRoaXMgaGVscHMgbWFuYWdlIGFuIG92ZXJhbGwgcHJvZ3Jlc3Mgd2l0aG91dCBrbm93aW5nIGhvdyBsYXJnZQoJCSAqIHRoZSBmaWxlcyBhcmUgYmVmb3JlIHRoZXkgYXJlIGRvd25sb2FkZWQuCgkJICogQHByb3BlcnR5IF9udW1JdGVtc0xvYWRlZAoJCSAqIEB0eXBlIHtOdW1iZXJ9CgkJICogQGRlZmF1bHQgMAoJCSAqIEBwcml2YXRlCgkJICovCgkJdGhpcy5fbnVtSXRlbXNMb2FkZWQgPSAwOwoKCQkvKioKCQkgKiBBIGxpc3Qgb2Ygc2NyaXB0cyBpbiB0aGUgb3JkZXIgdGhleSB3ZXJlIHJlcXVlc3RlZC4gVGhpcyBoZWxwcyBlbnN1cmUgdGhhdCBzY3JpcHRzIGFyZSAiY29tcGxldGVkIiBpbiB0aGUgcmlnaHQKCQkgKiBvcmRlci4KCQkgKiBAcHJvcGVydHkgX3NjcmlwdE9yZGVyCgkJICogQHR5cGUge0FycmF5fQoJCSAqIEBwcml2YXRlCgkJICovCgkJdGhpcy5fc2NyaXB0T3JkZXIgPSBbXTsKCgkJLyoqCgkJICogQSBsaXN0IG9mIHNjcmlwdHMgdGhhdCBoYXZlIGJlZW4gbG9hZGVkLiBJdGVtcyBhcmUgYWRkZWQgdG8gdGhpcyBsaXN0IGFzIDxjb2RlPm51bGw8L2NvZGU+IHdoZW4gdGhleSBhcmUKCQkgKiByZXF1ZXN0ZWQsIGNvbnRhaW4gdGhlIGxvYWRlZCBpdGVtIGlmIGl0IGhhcyBjb21wbGV0ZWQsIGJ1dCBub3QgYmVlbiBkaXNwYXRjaGVkIHRvIHRoZSB1c2VyLCBhbmQgPGNvZGU+dHJ1ZTwvdHJ1ZT4KCQkgKiBvbmNlIHRoZXkgYXJlIGNvbXBsZXRlIGFuZCBoYXZlIGJlZW4gZGlzcGF0Y2hlZC4KCQkgKiBAcHJvcGVydHkgX2xvYWRlZFNjcmlwdHMKCQkgKiBAdHlwZSB7QXJyYXl9CgkJICogQHByaXZhdGUKCQkgKi8KCQl0aGlzLl9sb2FkZWRTY3JpcHRzID0gW107CgoJCS8qKgoJCSAqIFRoZSBsYXN0IHByb2dyZXNzIGFtb3VudC4gVGhpcyBpcyB1c2VkIHRvIHN1cHByZXNzIGR1cGxpY2F0ZSBwcm9ncmVzcyBldmVudHMuCgkJICogQHByb3BlcnR5IF9sYXN0UHJvZ3Jlc3MKCQkgKiBAdHlwZSB7TnVtYmVyfQoJCSAqIEBwcml2YXRlCgkJICogQHNpbmNlIDAuNi4wCgkJICovCgkJdGhpcy5fbGFzdFByb2dyZXNzID0gTmFOOwoKCQkvKioKCQkgKiBBbiBpbnRlcm5hbCBsaXN0IG9mIGFsbCB0aGUgZGVmYXVsdCBMb2FkZXJzIHRoYXQgYXJlIGluY2x1ZGVkIHdpdGggUHJlbG9hZEpTLiBCZWZvcmUgYW4gaXRlbSBpcyBsb2FkZWQsIHRoZQoJCSAqIGF2YWlsYWJsZSBsb2FkZXIgbGlzdCBpcyBpdGVyYXRlZCwgaW4gdGhlIG9yZGVyIHRoZXkgYXJlIGluY2x1ZGVkLCBhbmQgYXMgc29vbiBhcyBhIGxvYWRlciBpbmRpY2F0ZXMgaXQgY2FuCgkJICogaGFuZGxlIHRoZSBjb250ZW50LCBpdCB3aWxsIGJlIHNlbGVjdGVkLiBUaGUgZGVmYXVsdCBsb2FkZXIsICh7eyNjcm9zc0xpbmsgIlRleHRMb2FkZXIifX17ey9jcm9zc0xpbmt9fSBpcwoJCSAqIGxhc3QgaW4gdGhlIGxpc3QsIHNvIGl0IHdpbGwgYmUgdXNlZCBpZiBubyBvdGhlciBtYXRjaCBpcyBmb3VuZC4gVHlwaWNhbGx5LCBsb2FkZXJzIHdpbGwgbWF0Y2ggYmFzZWQgb24gdGhlCgkJICoge3sjY3Jvc3NMaW5rICJMb2FkSXRlbS90eXBlIn19e3svY3Jvc3NMaW5rfX0sIHdoaWNoIGlzIGF1dG9tYXRpY2FsbHkgZGV0ZXJtaW5lZCB1c2luZyB0aGUgZmlsZSBleHRlbnNpb24gb2YKCQkgKiB0aGUge3sjY3Jvc3NMaW5rICJMb2FkSXRlbS9zcmM6cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fS4KCQkgKgoJCSAqIExvYWRlcnMgY2FuIGJlIHJlbW92ZWQgZnJvbSBQcmVsb2FkSlMgYnkgc2ltcGx5IG5vdCBpbmNsdWRpbmcgdGhlbS4KCQkgKgoJCSAqIEN1c3RvbSBsb2FkZXJzIGluc3RhbGxlZCB1c2luZyB7eyNjcm9zc0xpbmsgInJlZ2lzdGVyTG9hZGVyIn19e3svY3Jvc3NMaW5rfX0gd2lsbCBiZSBwcmVwZW5kZWQgdG8gdGhpcyBsaXN0CgkJICogc28gdGhhdCB0aGV5IGFyZSBjaGVja2VkIGZpcnN0LgoJCSAqIEBwcm9wZXJ0eSBfYXZhaWxhYmxlTG9hZGVycwoJCSAqIEB0eXBlIHtBcnJheX0KCQkgKiBAcHJpdmF0ZQoJCSAqIEBzaW5jZSAwLjYuMAoJCSAqLwoJCXRoaXMuX2F2YWlsYWJsZUxvYWRlcnMgPSBbCgkJCWNyZWF0ZWpzLkltYWdlTG9hZGVyLAoJCQljcmVhdGVqcy5KYXZhU2NyaXB0TG9hZGVyLAoJCQljcmVhdGVqcy5DU1NMb2FkZXIsCgkJCWNyZWF0ZWpzLkpTT05Mb2FkZXIsCgkJCWNyZWF0ZWpzLkpTT05QTG9hZGVyLAoJCQljcmVhdGVqcy5Tb3VuZExvYWRlciwKCQkJY3JlYXRlanMuTWFuaWZlc3RMb2FkZXIsCgkJCWNyZWF0ZWpzLlNwcml0ZVNoZWV0TG9hZGVyLAoJCQljcmVhdGVqcy5YTUxMb2FkZXIsCgkJCWNyZWF0ZWpzLlNWR0xvYWRlciwKCQkJY3JlYXRlanMuQmluYXJ5TG9hZGVyLAoJCQljcmVhdGVqcy5WaWRlb0xvYWRlciwKCQkJY3JlYXRlanMuVGV4dExvYWRlciwKCQldOwoKCQkvKioKCQkgKiBUaGUgbnVtYmVyIG9mIGJ1aWx0IGluIGxvYWRlcnMsIHNvIHRoZXkgY2FuJ3QgYmUgcmVtb3ZlZCBieSB7eyNjcm9zc0xpbmsgInVucmVnaXN0ZXJMb2FkZXIifX17ey9jcm9zc0xpbmt9LgoJCSAqIEBwcm9wZXJ0eSBfZGVmYXVsdExvYWRlckxlbmd0aAoJCSAqIEB0eXBlIHtOdW1iZXJ9CgkJICogQHByaXZhdGUKCQkgKiBAc2luY2UgMC42LjAKCQkgKi8KCQl0aGlzLl9kZWZhdWx0TG9hZGVyTGVuZ3RoID0gdGhpcy5fYXZhaWxhYmxlTG9hZGVycy5sZW5ndGg7Cgl9OwoKCi8vIHN0YXRpYyBwcm9wZXJ0aWVzCgkvKioKCSAqIFRoZSB0aW1lIGluIG1pbGxpc2Vjb25kcyB0byBhc3N1bWUgYSBsb2FkIGhhcyBmYWlsZWQuIEFuIHt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvZXJyb3I6ZXZlbnQifX17ey9jcm9zc0xpbmt9fQoJICogZXZlbnQgaXMgZGlzcGF0Y2hlZCBpZiB0aGUgdGltZW91dCBpcyByZWFjaGVkIGJlZm9yZSBhbnkgZGF0YSBpcyByZWNlaXZlZC4KCSAqIEBwcm9wZXJ0eSBsb2FkVGltZW91dAoJICogQHR5cGUge051bWJlcn0KCSAqIEBkZWZhdWx0IDgwMDAKCSAqIEBzdGF0aWMKCSAqIEBzaW5jZSAwLjQuMQoJICogQGRlcHJlY2F0ZWQgSW4gZmF2b3VyIG9mIExvYWRJdGVtLmxvYWRUaW1lb3V0CgkgKi8KCXMubG9hZFRpbWVvdXQgPSA4MDAwOwoKCS8qKgoJICogVGhlIHRpbWUgaW4gbWlsbGlzZWNvbmRzIHRvIGFzc3VtZSBhIGxvYWQgaGFzIGZhaWxlZC4KCSAqIEBwcm9wZXJ0eSBMT0FEX1RJTUVPVVQKCSAqIEB0eXBlIHtOdW1iZXJ9CgkgKiBAZGVmYXVsdCAwCgkgKiBAZGVwcmVjYXRlZCBpbiBmYXZvciBvZiB0aGUge3sjY3Jvc3NMaW5rICJMb2FkUXVldWUvbG9hZFRpbWVvdXQ6cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fSBwcm9wZXJ0eS4KCSAqLwoJcy5MT0FEX1RJTUVPVVQgPSAwOwoKLy8gUHJlbG9hZCBUeXBlcwoJLyoqCgkgKiBAcHJvcGVydHkgQklOQVJZCgkgKiBAdHlwZSB7U3RyaW5nfQoJICogQGRlZmF1bHQgYmluYXJ5CgkgKiBAc3RhdGljCgkgKiBAZGVwcmVjYXRlZCBVc2UgdGhlIEFic3RyYWN0TG9hZGVyIHt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvQklOQVJZOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0gaW5zdGVhZC4KCSAqLwoJcy5CSU5BUlkgPSBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5CSU5BUlk7CgoJLyoqCgkgKiBAcHJvcGVydHkgQ1NTCgkgKiBAdHlwZSB7U3RyaW5nfQoJICogQGRlZmF1bHQgY3NzCgkgKiBAc3RhdGljCgkgKiBAZGVwcmVjYXRlZCBVc2UgdGhlIEFic3RyYWN0TG9hZGVyIHt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvQ1NTOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0gaW5zdGVhZC4KCSAqLwoJcy5DU1MgPSBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5DU1M7CgoJLyoqCgkgKiBAcHJvcGVydHkgSU1BR0UKCSAqIEB0eXBlIHtTdHJpbmd9CgkgKiBAZGVmYXVsdCBpbWFnZQoJICogQHN0YXRpYwoJICogQGRlcHJlY2F0ZWQgVXNlIHRoZSBBYnN0cmFjdExvYWRlciB7eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyL0NTUzpwcm9wZXJ0eSJ9fXt7L2Nyb3NzTGlua319IGluc3RlYWQuCgkgKi8KCXMuSU1BR0UgPSBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5JTUFHRTsKCgkvKioKCSAqIEBwcm9wZXJ0eSBKQVZBU0NSSVBUCgkgKiBAdHlwZSB7U3RyaW5nfQoJICogQGRlZmF1bHQgamF2YXNjcmlwdAoJICogQHN0YXRpYwoJICogQGRlcHJlY2F0ZWQgVXNlIHRoZSBBYnN0cmFjdExvYWRlciB7eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyL0pBVkFTQ1JJUFQ6cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fSBpbnN0ZWFkLgoJICovCglzLkpBVkFTQ1JJUFQgPSBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5KQVZBU0NSSVBUOwoKCS8qKgoJICogQHByb3BlcnR5IEpTT04KCSAqIEB0eXBlIHtTdHJpbmd9CgkgKiBAZGVmYXVsdCBqc29uCgkgKiBAc3RhdGljCgkgKiBAZGVwcmVjYXRlZCBVc2UgdGhlIEFic3RyYWN0TG9hZGVyIHt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvSlNPTjpwcm9wZXJ0eSJ9fXt7L2Nyb3NzTGlua319IGluc3RlYWQuCgkgKi8KCXMuSlNPTiA9IGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLkpTT047CgoJLyoqCgkgKiBAcHJvcGVydHkgSlNPTlAKCSAqIEB0eXBlIHtTdHJpbmd9CgkgKiBAZGVmYXVsdCBqc29ucAoJICogQHN0YXRpYwoJICogQGRlcHJlY2F0ZWQgVXNlIHRoZSBBYnN0cmFjdExvYWRlciB7eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyL0pTT05QOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0gaW5zdGVhZC4KCSAqLwoJcy5KU09OUCA9IGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLkpTT05QOwoKCS8qKgoJICogQHByb3BlcnR5IE1BTklGRVNUCgkgKiBAdHlwZSB7U3RyaW5nfQoJICogQGRlZmF1bHQgbWFuaWZlc3QKCSAqIEBzdGF0aWMKCSAqIEBzaW5jZSAwLjQuMQoJICogQGRlcHJlY2F0ZWQgVXNlIHRoZSBBYnN0cmFjdExvYWRlciB7eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyL01BTklGRVNUOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0gaW5zdGVhZC4KCSAqLwoJcy5NQU5JRkVTVCA9IGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLk1BTklGRVNUOwoKCS8qKgoJICogQHByb3BlcnR5IFNPVU5ECgkgKiBAdHlwZSB7U3RyaW5nfQoJICogQGRlZmF1bHQgc291bmQKCSAqIEBzdGF0aWMKCSAqIEBkZXByZWNhdGVkIFVzZSB0aGUgQWJzdHJhY3RMb2FkZXIge3sjY3Jvc3NMaW5rICJBYnN0cmFjdExvYWRlci9KQVZBU0NSSVBUOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0gaW5zdGVhZC4KCSAqLwoJcy5TT1VORCA9IGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLlNPVU5EOwoKCS8qKgoJICogQHByb3BlcnR5IFZJREVPCgkgKiBAdHlwZSB7U3RyaW5nfQoJICogQGRlZmF1bHQgdmlkZW8KCSAqIEBzdGF0aWMKCSAqIEBkZXByZWNhdGVkIFVzZSB0aGUgQWJzdHJhY3RMb2FkZXIge3sjY3Jvc3NMaW5rICJBYnN0cmFjdExvYWRlci9KQVZBU0NSSVBUOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0gaW5zdGVhZC4KCSAqLwoJcy5WSURFTyA9IGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLlZJREVPOwoKCS8qKgoJICogQHByb3BlcnR5IFNWRwoJICogQHR5cGUge1N0cmluZ30KCSAqIEBkZWZhdWx0IHN2ZwoJICogQHN0YXRpYwoJICogQGRlcHJlY2F0ZWQgVXNlIHRoZSBBYnN0cmFjdExvYWRlciB7eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyL1NWRzpwcm9wZXJ0eSJ9fXt7L2Nyb3NzTGlua319IGluc3RlYWQuCgkgKi8KCXMuU1ZHID0gY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuU1ZHOwoKCS8qKgoJICogQHByb3BlcnR5IFRFWFQKCSAqIEB0eXBlIHtTdHJpbmd9CgkgKiBAZGVmYXVsdCB0ZXh0CgkgKiBAc3RhdGljCgkgKiBAZGVwcmVjYXRlZCBVc2UgdGhlIEFic3RyYWN0TG9hZGVyIHt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvVEVYVDpwcm9wZXJ0eSJ9fXt7L2Nyb3NzTGlua319IGluc3RlYWQuCgkgKi8KCXMuVEVYVCA9IGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLlRFWFQ7CgoJLyoqCgkgKiBAcHJvcGVydHkgWE1MCgkgKiBAdHlwZSB7U3RyaW5nfQoJICogQGRlZmF1bHQgeG1sCgkgKiBAc3RhdGljCgkgKiBAZGVwcmVjYXRlZCBVc2UgdGhlIEFic3RyYWN0TG9hZGVyIHt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvWE1MOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0gaW5zdGVhZC4KCSAqLwoJcy5YTUwgPSBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5YTUw7CgoJLyoqCgkgKiBAcHJvcGVydHkgUE9TVAoJICogQHR5cGUge3N0cmluZ30KCSAqIEBkZXByZWNhdGVkIFVzZSB0aGUgQWJzdHJhY3RMb2FkZXIge3sjY3Jvc3NMaW5rICJBYnN0cmFjdExvYWRlci9QT1NUOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0gaW5zdGVhZC4KCSAqLwoJcy5QT1NUID0gY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuUE9TVDsKCgkvKioKCSAqIEBwcm9wZXJ0eSBHRVQKCSAqIEB0eXBlIHtzdHJpbmd9CgkgKiBAZGVwcmVjYXRlZCBVc2UgdGhlIEFic3RyYWN0TG9hZGVyIHt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvR0VUOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0gaW5zdGVhZC4KCSAqLwoJcy5HRVQgPSBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5HRVQ7CgovLyBldmVudHMKCS8qKgoJICogVGhpcyBldmVudCBpcyBmaXJlZCB3aGVuIGFuIGluZGl2aWR1YWwgZmlsZSBoYXMgbG9hZGVkLCBhbmQgYmVlbiBwcm9jZXNzZWQuCgkgKiBAZXZlbnQgZmlsZWxvYWQKCSAqIEBwYXJhbSB7T2JqZWN0fSB0YXJnZXQgVGhlIG9iamVjdCB0aGF0IGRpc3BhdGNoZWQgdGhlIGV2ZW50LgoJICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgVGhlIGV2ZW50IHR5cGUuCgkgKiBAcGFyYW0ge09iamVjdH0gaXRlbSBUaGUgZmlsZSBpdGVtIHdoaWNoIHdhcyBzcGVjaWZpZWQgaW4gdGhlIHt7I2Nyb3NzTGluayAiTG9hZFF1ZXVlL2xvYWRGaWxlIn19e3svY3Jvc3NMaW5rfX0KCSAqIG9yIHt7I2Nyb3NzTGluayAiTG9hZFF1ZXVlL2xvYWRNYW5pZmVzdCJ9fXt7L2Nyb3NzTGlua319IGNhbGwuIElmIG9ubHkgYSBzdHJpbmcgcGF0aCBvciB0YWcgd2FzIHNwZWNpZmllZCwgdGhlCgkgKiBvYmplY3Qgd2lsbCBjb250YWluIHRoYXQgdmFsdWUgYXMgYSBgc3JjYCBwcm9wZXJ0eS4KCSAqIEBwYXJhbSB7T2JqZWN0fSByZXN1bHQgVGhlIEhUTUwgdGFnIG9yIHBhcnNlZCByZXN1bHQgb2YgdGhlIGxvYWRlZCBpdGVtLgoJICogQHBhcmFtIHtPYmplY3R9IHJhd1Jlc3VsdCBUaGUgdW5wcm9jZXNzZWQgcmVzdWx0LCB1c3VhbGx5IHRoZSByYXcgdGV4dCBvciBiaW5hcnkgZGF0YSBiZWZvcmUgaXQgaXMgY29udmVydGVkCgkgKiB0byBhIHVzYWJsZSBvYmplY3QuCgkgKiBAc2luY2UgMC4zLjAKCSAqLwoKCS8qKgoJICogVGhpcyB7eyNjcm9zc0xpbmsgIlByb2dyZXNzRXZlbnQifX17ey9jcm9zc0xpbmt9fSB0aGF0IGlzIGZpcmVkIHdoZW4gYW4gYW4gaW5kaXZpZHVhbCBmaWxlJ3MgcHJvZ3Jlc3MgY2hhbmdlcy4KCSAqIEBldmVudCBmaWxlcHJvZ3Jlc3MKCSAqIEBzaW5jZSAwLjMuMAoJICovCgoJLyoqCgkgKiBUaGlzIGV2ZW50IGlzIGZpcmVkIHdoZW4gYW4gaW5kaXZpZHVhbCBmaWxlIHN0YXJ0cyB0byBsb2FkLgoJICogQGV2ZW50IGZpbGVzdGFydAoJICogQHBhcmFtIHtPYmplY3R9IFRoZSBvYmplY3QgdGhhdCBkaXNwYXRjaGVkIHRoZSBldmVudC4KCSAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlIFRoZSBldmVudCB0eXBlLgoJICogQHBhcmFtIHtPYmplY3R9IGl0ZW0gVGhlIGZpbGUgaXRlbSB3aGljaCB3YXMgc3BlY2lmaWVkIGluIHRoZSB7eyNjcm9zc0xpbmsgIkxvYWRRdWV1ZS9sb2FkRmlsZSJ9fXt7L2Nyb3NzTGlua319CgkgKiBvciB7eyNjcm9zc0xpbmsgIkxvYWRRdWV1ZS9sb2FkTWFuaWZlc3QifX17ey9jcm9zc0xpbmt9fSBjYWxsLiBJZiBvbmx5IGEgc3RyaW5nIHBhdGggb3IgdGFnIHdhcyBzcGVjaWZpZWQsIHRoZQoJICogb2JqZWN0IHdpbGwgY29udGFpbiB0aGF0IHZhbHVlIGFzIGEgcHJvcGVydHkuCgkgKi8KCi8vIHB1YmxpYyBtZXRob2RzCgkvKioKCSAqIFJlZ2lzdGVyIGEgY3VzdG9tIGxvYWRlcnMgY2xhc3MuIE5ldyBsb2FkZXJzIGFyZSBnaXZlbiBwcmVjZWRlbmNlIG92ZXIgbG9hZGVycyBhZGRlZCBlYXJsaWVyIGFuZCBkZWZhdWx0IGxvYWRlcnMuCgkgKiBJdCBpcyByZWNvbW1lbmRlZCB0aGF0IGxvYWRlcnMgZXh0ZW5kIHt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIifX17ey9jcm9zc0xpbmt9fS4gTG9hZGVycyBjYW4gb25seSBiZSBhZGRlZAoJICogb25jZSwgYW5kIHdpbGwgYmUgcHJlcGVuZGVkIHRvIHRoZSBsaXN0IG9mIGF2YWlsYWJsZSBsb2FkZXJzLgoJICogQG1ldGhvZCByZWdpc3RlckxvYWRlcgoJICogQHBhcmFtIHtDbGFzc30gVGhlIEFic3RyYWN0TG9hZGVyIGNsYXNzIHRvIGFkZC4KCSAqIEBzaW5jZSAwLjYuMAoJICovCglwLnJlZ2lzdGVyTG9hZGVyID0gZnVuY3Rpb24gKGxvYWRlcikgewoJCWlmICghbG9hZGVyIHx8ICFsb2FkZXIuY2FuTG9hZEl0ZW0pIHsKCQkJdGhyb3cgbmV3IEVycm9yKCJsb2FkZXIgaXMgb2YgYW4gaW5jb3JyZWN0IHR5cGUuIik7CgkJfSBlbHNlIGlmICh0aGlzLl9hdmFpbGFibGVMb2FkZXJzLmluZGV4T2YobG9hZGVyKSAhPSAtMSkgewoJCQl0aHJvdyBuZXcgRXJyb3IoImxvYWRlciBhbHJlYWR5IGV4aXN0cy4iKTsgLy9MTTogTWF5YmUganVzdCBzaWxlbnRseSBmYWlsIGhlcmUKCQl9CgoJCXRoaXMuX2F2YWlsYWJsZUxvYWRlcnMudW5zaGlmdChsb2FkZXIpOwoJfTsKCgkvKioKCSAqIFJlbW92ZSBhIGN1c3RvbSBsb2FkZXIgYWRkZWQgdXNpZyB7eyNjcm9zc0xpbmsgInJlZ2lzdGVyTG9hZGVyIn19e3svY3Jvc3NMaW5rfX0uIE9ubHkgY3VzdG9tIGxvYWRlcnMgY2FuIGJlCgkgKiB1bnJlZ2lzdGVyZWQsIHRoZSBkZWZhdWx0IGxvYWRlcnMgd2lsbCBhbHdheXMgYmUgYXZhaWxhYmxlLgoJICogQG1ldGhvZCB1bnJlZ2lzdGVyTG9hZGVyCgkgKiBAcGFyYW0ge0NsYXNzfSBsb2FkZXIgVGhlIEFic3RyYWN0TG9hZGVyIGNsYXNzIHRvIHJlbW92ZQoJICovCglwLnVucmVnaXN0ZXJMb2FkZXIgPSBmdW5jdGlvbiAobG9hZGVyKSB7CgkJdmFyIGlkeCA9IHRoaXMuX2F2YWlsYWJsZUxvYWRlcnMuaW5kZXhPZihsb2FkZXIpOwoJCWlmIChpZHggIT0gLTEgJiYgaWR4IDwgdGhpcy5fZGVmYXVsdExvYWRlckxlbmd0aCAtIDEpIHsKCQkJdGhpcy5fYXZhaWxhYmxlTG9hZGVycy5zcGxpY2UoaWR4LCAxKTsKCQl9Cgl9OwoKCS8qKgoJICogQG1ldGhvZCBzZXRVc2VYSFIKCSAqIEBwYXJhbSB7Qm9vbGVhbn0gdmFsdWUgVGhlIG5ldyB1c2VYSFIgdmFsdWUgdG8gc2V0LgoJICogQHJldHVybiB7Qm9vbGVhbn0gVGhlIG5ldyB1c2VYSFIgdmFsdWUuIElmIFhIUiBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBicm93c2VyLCB0aGlzIHdpbGwgcmV0dXJuIGZhbHNlLCBldmVuIGlmCgkgKiB0aGUgcHJvdmlkZWQgdmFsdWUgYXJndW1lbnQgd2FzIHRydWUuCgkgKiBAc2luY2UgMC4zLjAKCSAqIEBkZXByZWNhdGVkIHVzZSB0aGUge3sjY3Jvc3NMaW5rICJwcmVmZXJYSFI6cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fSBwcm9wZXJ0eSwgb3IgdGhlIHt7I2Nyb3NzTGluayAic2V0VXNlWEhSIn19e3svY3Jvc3NMaW5rfX0KCSAqIG1ldGhvZCBpbnN0ZWFkLgoJICovCglwLnNldFVzZVhIUiA9IGZ1bmN0aW9uICh2YWx1ZSkgewoJCXJldHVybiB0aGlzLnNldFByZWZlclhIUih2YWx1ZSk7Cgl9OwoKCS8qKgoJICogQ2hhbmdlIHRoZSB7eyNjcm9zc0xpbmsgInByZWZlclhIUjpwcm9wZXJ0eSJ9fXt7L2Nyb3NzTGlua319IHZhbHVlLiBOb3RlIHRoYXQgaWYgdGhpcyBpcyBzZXQgdG8gYHRydWVgLCBpdCBtYXkKCSAqIGZhaWwsIG9yIGJlIGlnbm9yZWQgZGVwZW5kaW5nIG9uIHRoZSBicm93c2VyJ3MgY2FwYWJpbGl0aWVzIGFuZCB0aGUgbG9hZCB0eXBlLgoJICogQG1ldGhvZCBzZXRQcmVmZXJYSFIKCSAqIEBwYXJhbSB7Qm9vbGVhbn0gdmFsdWUKCSAqIEByZXR1cm5zIHtCb29sZWFufSBUaGUgdmFsdWUgb2Yge3sjY3Jvc3NMaW5rICJwcmVmZXJYSFIifX17ey9jcm9zc0xpbmt9fSB0aGF0IHdhcyBzdWNjZXNzZnVsbHkgc2V0LgoJICogQHNpbmNlIDAuNi4wCgkgKi8KCXAuc2V0UHJlZmVyWEhSID0gZnVuY3Rpb24odmFsdWUpIHsKCQkvLyBEZXRlcm1pbmUgaWYgd2UgY2FuIHVzZSBYSFIuIFhIUiBkZWZhdWx0cyB0byBUUlVFLCBidXQgdGhlIGJyb3dzZXIgbWF5IG5vdCBzdXBwb3J0IGl0LgoJCS8vVE9ETzogU2hvdWxkIHdlIGJlIGNoZWNraW5nIGZvciB0aGUgb3RoZXIgWEhSIHR5cGVzPyBNaWdodCBoYXZlIHRvIGRvIGEgdHJ5L2NhdGNoIG9uIHRoZSBkaWZmZXJlbnQgdHlwZXMgc2ltaWxhciB0byBjcmVhdGVYSFIuCgkJdGhpcy5wcmVmZXJYSFIgPSAodmFsdWUgIT0gZmFsc2UgJiYgd2luZG93LlhNTEh0dHBSZXF1ZXN0ICE9IG51bGwpOwoJCXJldHVybiB0aGlzLnByZWZlclhIUjsKCX07CgoJLyoqCgkgKiBTdG9wcyBhbGwgcXVldWVkIGFuZCBsb2FkaW5nIGl0ZW1zLCBhbmQgY2xlYXJzIHRoZSBxdWV1ZS4gVGhpcyBhbHNvIHJlbW92ZXMgYWxsIGludGVybmFsIHJlZmVyZW5jZXMgdG8gbG9hZGVkCgkgKiBjb250ZW50LCBhbmQgYWxsb3dzIHRoZSBxdWV1ZSB0byBiZSB1c2VkIGFnYWluLgoJICogQG1ldGhvZCByZW1vdmVBbGwKCSAqIEBzaW5jZSAwLjMuMAoJICovCglwLnJlbW92ZUFsbCA9IGZ1bmN0aW9uICgpIHsKCQl0aGlzLnJlbW92ZSgpOwoJfTsKCgkvKioKCSAqIFN0b3BzIGFuIGl0ZW0gZnJvbSBiZWluZyBsb2FkZWQsIGFuZCByZW1vdmVzIGl0IGZyb20gdGhlIHF1ZXVlLiBJZiBub3RoaW5nIGlzIHBhc3NlZCwgYWxsIGl0ZW1zIGFyZSByZW1vdmVkLgoJICogVGhpcyBhbHNvIHJlbW92ZXMgaW50ZXJuYWwgcmVmZXJlbmNlcyB0byBsb2FkZWQgaXRlbShzKS4KCSAqCgkgKiA8aDQ+RXhhbXBsZTwvaDQ+CgkgKgoJICogICAgICBxdWV1ZS5sb2FkTWFuaWZlc3QoWwoJICogICAgICAgICAge3NyYzoidGVzdC5wbmciLCBpZDoicG5nIn0sCgkgKiAgICAgICAgICB7c3JjOiJ0ZXN0LmpwZyIsIGlkOiJqcGcifSwKCSAqICAgICAgICAgIHtzcmM6InRlc3QubXAzIiwgaWQ6Im1wMyJ9CgkgKiAgICAgIF0pOwoJICogICAgICBxdWV1ZS5yZW1vdmUoInBuZyIpOyAvLyBTaW5nbGUgaXRlbSBieSBJRAoJICogICAgICBxdWV1ZS5yZW1vdmUoInBuZyIsICJ0ZXN0LmpwZyIpOyAvLyBJdGVtcyBhcyBhcmd1bWVudHMuIE1peGVkIGlkIGFuZCBzcmMuCgkgKiAgICAgIHF1ZXVlLnJlbW92ZShbInRlc3QucG5nIiwgImpwZyJdKTsgLy8gSXRlbXMgaW4gYW4gQXJyYXkuIE1peGVkIGlkIGFuZCBzcmMuCgkgKgoJICogQG1ldGhvZCByZW1vdmUKCSAqIEBwYXJhbSB7U3RyaW5nIHwgQXJyYXl9IGlkc09yVXJscyogVGhlIGlkIG9yIGlkcyB0byByZW1vdmUgZnJvbSB0aGlzIHF1ZXVlLiBZb3UgY2FuIHBhc3MgYW4gaXRlbSwgYW4gYXJyYXkgb2YKCSAqIGl0ZW1zLCBvciBtdWx0aXBsZSBpdGVtcyBhcyBhcmd1bWVudHMuCgkgKiBAc2luY2UgMC4zLjAKCSAqLwoJcC5yZW1vdmUgPSBmdW5jdGlvbiAoaWRzT3JVcmxzKSB7CgkJdmFyIGFyZ3MgPSBudWxsOwoKCQlpZiAoaWRzT3JVcmxzICYmICEoaWRzT3JVcmxzIGluc3RhbmNlb2YgQXJyYXkpKSB7CgkJCWFyZ3MgPSBbaWRzT3JVcmxzXTsKCQl9IGVsc2UgaWYgKGlkc09yVXJscykgewoJCQlhcmdzID0gaWRzT3JVcmxzOwoJCX0gZWxzZSBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDApIHsKCQkJcmV0dXJuOwoJCX0KCgkJdmFyIGl0ZW1zV2VyZVJlbW92ZWQgPSBmYWxzZTsKCgkJLy8gRGVzdHJveSBldmVyeXRoaW5nCgkJaWYgKCFhcmdzKSB7CgkJCXRoaXMuY2xvc2UoKTsKCQkJZm9yICh2YXIgbiBpbiB0aGlzLl9sb2FkSXRlbXNCeUlkKSB7CgkJCQl0aGlzLl9kaXNwb3NlSXRlbSh0aGlzLl9sb2FkSXRlbXNCeUlkW25dKTsKCQkJfQoJCQl0aGlzLmluaXQodGhpcy5wcmVmZXJYSFIsIHRoaXMuX2Jhc2VQYXRoKTsKCgkJCS8vIFJlbW92ZSBzcGVjaWZpYyBpdGVtcwoJCX0gZWxzZSB7CgkJCXdoaWxlIChhcmdzLmxlbmd0aCkgewoJCQkJdmFyIGl0ZW0gPSBhcmdzLnBvcCgpOwoJCQkJdmFyIHIgPSB0aGlzLmdldFJlc3VsdChpdGVtKTsKCgkJCQkvL1JlbW92ZSBmcm9tIHRoZSBtYWluIGxvYWQgUXVldWUKCQkJCWZvciAoaSA9IHRoaXMuX2xvYWRRdWV1ZS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgewoJCQkJCWxvYWRJdGVtID0gdGhpcy5fbG9hZFF1ZXVlW2ldLmdldEl0ZW0oKTsKCQkJCQlpZiAobG9hZEl0ZW0uaWQgPT0gaXRlbSB8fCBsb2FkSXRlbS5zcmMgPT0gaXRlbSkgewoJCQkJCQl0aGlzLl9sb2FkUXVldWUuc3BsaWNlKGksIDEpWzBdLmNhbmNlbCgpOwoJCQkJCQlicmVhazsKCQkJCQl9CgkJCQl9CgoJCQkJLy9SZW1vdmUgZnJvbSB0aGUgYmFja3VwIHF1ZXVlCgkJCQlmb3IgKGkgPSB0aGlzLl9sb2FkUXVldWVCYWNrdXAubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHsKCQkJCQlsb2FkSXRlbSA9IHRoaXMuX2xvYWRRdWV1ZUJhY2t1cFtpXS5nZXRJdGVtKCk7CgkJCQkJaWYgKGxvYWRJdGVtLmlkID09IGl0ZW0gfHwgbG9hZEl0ZW0uc3JjID09IGl0ZW0pIHsKCQkJCQkJdGhpcy5fbG9hZFF1ZXVlQmFja3VwLnNwbGljZShpLCAxKVswXS5jYW5jZWwoKTsKCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJfQoKCQkJCWlmIChyKSB7CgkJCQkJdGhpcy5fZGlzcG9zZUl0ZW0odGhpcy5nZXRJdGVtKGl0ZW0pKTsKCQkJCX0gZWxzZSB7CgkJCQkJZm9yICh2YXIgaSA9IHRoaXMuX2N1cnJlbnRMb2Fkcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgewoJCQkJCQl2YXIgbG9hZEl0ZW0gPSB0aGlzLl9jdXJyZW50TG9hZHNbaV0uZ2V0SXRlbSgpOwoJCQkJCQlpZiAobG9hZEl0ZW0uaWQgPT0gaXRlbSB8fCBsb2FkSXRlbS5zcmMgPT0gaXRlbSkgewoJCQkJCQkJdGhpcy5fY3VycmVudExvYWRzLnNwbGljZShpLCAxKVswXS5jYW5jZWwoKTsKCQkJCQkJCWl0ZW1zV2VyZVJlbW92ZWQgPSB0cnVlOwoJCQkJCQkJYnJlYWs7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCgkJCS8vIElmIHRoaXMgd2FzIGNhbGxlZCBkdXJpbmcgYSBsb2FkLCB0cnkgdG8gbG9hZCB0aGUgbmV4dCBpdGVtLgoJCQlpZiAoaXRlbXNXZXJlUmVtb3ZlZCkgewoJCQkJdGhpcy5fbG9hZE5leHQoKTsKCQkJfQoJCX0KCX07CgoJLyoqCgkgKiBTdG9wcyBhbGwgb3BlbiBsb2FkcywgZGVzdHJveXMgYW55IGxvYWRlZCBpdGVtcywgYW5kIHJlc2V0cyB0aGUgcXVldWUsIHNvIGFsbCBpdGVtcyBjYW4KCSAqIGJlIHJlbG9hZGVkIGFnYWluIGJ5IGNhbGxpbmcge3sjY3Jvc3NMaW5rICJBYnN0cmFjdExvYWRlci9sb2FkIn19e3svY3Jvc3NMaW5rfX0uIEl0ZW1zIGFyZSBub3QgcmVtb3ZlZCBmcm9tIHRoZQoJICogcXVldWUuIFRvIHJlbW92ZSBpdGVtcyB1c2UgdGhlIHt7I2Nyb3NzTGluayAiTG9hZFF1ZXVlL3JlbW92ZSJ9fXt7L2Nyb3NzTGlua319IG9yCgkgKiB7eyNjcm9zc0xpbmsgIkxvYWRRdWV1ZS9yZW1vdmVBbGwifX17ey9jcm9zc0xpbmt9fSBtZXRob2QuCgkgKiBAbWV0aG9kIHJlc2V0CgkgKiBAc2luY2UgMC4zLjAKCSAqLwoJcC5yZXNldCA9IGZ1bmN0aW9uICgpIHsKCQl0aGlzLmNsb3NlKCk7CgkJZm9yICh2YXIgbiBpbiB0aGlzLl9sb2FkSXRlbXNCeUlkKSB7CgkJCXRoaXMuX2Rpc3Bvc2VJdGVtKHRoaXMuX2xvYWRJdGVtc0J5SWRbbl0pOwoJCX0KCgkJLy9SZXNldCB0aGUgcXVldWUgdG8gaXRzIHN0YXJ0IHN0YXRlCgkJdmFyIGEgPSBbXTsKCQlmb3IgKHZhciBpID0gMCwgbCA9IHRoaXMuX2xvYWRRdWV1ZUJhY2t1cC5sZW5ndGg7IGkgPCBsOyBpKyspIHsKCQkJYS5wdXNoKHRoaXMuX2xvYWRRdWV1ZUJhY2t1cFtpXS5nZXRJdGVtKCkpOwoJCX0KCgkJdGhpcy5sb2FkTWFuaWZlc3QoYSwgZmFsc2UpOwoJfTsKCgkvKioKCSAqIFJlZ2lzdGVyIGEgcGx1Z2luLiBQbHVnaW5zIGNhbiBtYXAgdG8gbG9hZCB0eXBlcyAoc291bmQsIGltYWdlLCBldGMpLCBvciBzcGVjaWZpYyBleHRlbnNpb25zIChwbmcsIG1wMywgZXRjKS4KCSAqIEN1cnJlbnRseSwgb25seSBvbmUgcGx1Z2luIGNhbiBleGlzdCBwZXIgdHlwZS9leHRlbnNpb24uCgkgKgoJICogV2hlbiBhIHBsdWdpbiBpcyBpbnN0YWxsZWQsIGEgPGNvZGU+Z2V0UHJlbG9hZEhhbmRsZXJzKCk8L2NvZGU+IG1ldGhvZCB3aWxsIGJlIGNhbGxlZCBvbiBpdC4gRm9yIG1vcmUgaW5mb3JtYXRpb24KCSAqIG9uIHRoaXMgbWV0aG9kLCBjaGVjayBvdXQgdGhlIHt7I2Nyb3NzTGluayAiU2FtcGxlUGx1Z2luL2dldFByZWxvYWRIYW5kbGVycyJ9fXt7L2Nyb3NzTGlua319IG1ldGhvZCBpbiB0aGUKCSAqIHt7I2Nyb3NzTGluayAiU2FtcGxlUGx1Z2luIn19e3svY3Jvc3NMaW5rfX0gY2xhc3MuCgkgKgoJICogQmVmb3JlIGEgZmlsZSBpcyBsb2FkZWQsIGEgbWF0Y2hpbmcgcGx1Z2luIGhhcyBhbiBvcHBvcnR1bml0eSB0byBtb2RpZnkgdGhlIGxvYWQuIElmIGEgYGNhbGxiYWNrYCBpcyByZXR1cm5lZAoJICogZnJvbSB0aGUge3sjY3Jvc3NMaW5rICJTYW1wbGVQbHVnaW4vZ2V0UHJlbG9hZEhhbmRsZXJzIn19e3svY3Jvc3NMaW5rfX0gbWV0aG9kLCBpdCB3aWxsIGJlIGludm9rZWQgZmlyc3QsIGFuZCBpdHMKCSAqIHJlc3VsdCBtYXkgY2FuY2VsIG9yIG1vZGlmeSB0aGUgaXRlbS4gVGhlIGNhbGxiYWNrIG1ldGhvZCBjYW4gYWxzbyByZXR1cm4gYSBgY29tcGxldGVIYW5kbGVyYCB0byBiZSBmaXJlZCB3aGVuCgkgKiB0aGUgZmlsZSBpcyBsb2FkZWQsIG9yIGEgYHRhZ2Agb2JqZWN0LCB3aGljaCB3aWxsIG1hbmFnZSB0aGUgYWN0dWFsIGRvd25sb2FkLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiB0aGVzZQoJICogbWV0aG9kcywgY2hlY2sgb3V0IHRoZSB7eyNjcm9zc0xpbmsgIlNhbXBsZVBsdWdpbi9wcmVsb2FkSGFuZGxlciJ9fXt7L2Nyb3NzTGlua319IGFuZCB7eyNjcm9zc0xpbmsgIlNhbXBsZVBsdWdpbi9maWxlTG9hZEhhbmRsZXIifX17ey9jcm9zc0xpbmt9fQoJICogbWV0aG9kcyBvbiB0aGUge3sjY3Jvc3NMaW5rICJTYW1wbGVQbHVnaW4ifX17ey9jcm9zc0xpbmt9fS4KCSAqCgkgKiBAbWV0aG9kIGluc3RhbGxQbHVnaW4KCSAqIEBwYXJhbSB7RnVuY3Rpb259IHBsdWdpbiBUaGUgcGx1Z2luIGNsYXNzIHRvIGluc3RhbGwuCgkgKi8KCXAuaW5zdGFsbFBsdWdpbiA9IGZ1bmN0aW9uIChwbHVnaW4pIHsKCQlpZiAocGx1Z2luID09IG51bGwpIHsgcmV0dXJuOyB9CgoJCWlmIChwbHVnaW4uZ2V0UHJlbG9hZEhhbmRsZXJzICE9IG51bGwpIHsKCQkJdmFyIG1hcCA9IHBsdWdpbi5nZXRQcmVsb2FkSGFuZGxlcnMoKTsKCQkJbWFwLnNjb3BlID0gcGx1Z2luOwoKCQkJaWYgKG1hcC50eXBlcyAhPSBudWxsKSB7CgkJCQlmb3IgKHZhciBpID0gMCwgbCA9IG1hcC50eXBlcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsKCQkJCQl0aGlzLl90eXBlQ2FsbGJhY2tzW21hcC50eXBlc1tpXV0gPSBtYXA7CgkJCQl9CgkJCX0KCgkJCWlmIChtYXAuZXh0ZW5zaW9ucyAhPSBudWxsKSB7CgkJCQlmb3IgKGkgPSAwLCBsID0gbWFwLmV4dGVuc2lvbnMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7CgkJCQkJdGhpcy5fZXh0ZW5zaW9uQ2FsbGJhY2tzW21hcC5leHRlbnNpb25zW2ldXSA9IG1hcDsKCQkJCX0KCQkJfQoJCX0KCX07CgoJLyoqCgkgKiBTZXQgdGhlIG1heGltdW0gbnVtYmVyIG9mIGNvbmN1cnJlbnQgY29ubmVjdGlvbnMuIE5vdGUgdGhhdCBicm93c2VycyBhbmQgc2VydmVycyBtYXkgaGF2ZSBhIGJ1aWx0LWluIG1heGltdW0KCSAqIG51bWJlciBvZiBvcGVuIGNvbm5lY3Rpb25zLCBzbyBhbnkgYWRkaXRpb25hbCBjb25uZWN0aW9ucyBtYXkgcmVtYWluIGluIGEgcGVuZGluZyBzdGF0ZSB1bnRpbCB0aGUgYnJvd3NlcgoJICogb3BlbnMgdGhlIGNvbm5lY3Rpb24uIFdoZW4gbG9hZGluZyBzY3JpcHRzIHVzaW5nIHRhZ3MsIGFuZCB3aGVuIHt7I2Nyb3NzTGluayAiTG9hZFF1ZXVlL21haW50YWluU2NyaXB0T3JkZXI6cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fQoJICogaXMgYHRydWVgLCBvbmx5IG9uZSBzY3JpcHQgaXMgbG9hZGVkIGF0IGEgdGltZSBkdWUgdG8gYnJvd3NlciBsaW1pdGF0aW9ucy4KCSAqCgkgKiA8aDQ+RXhhbXBsZTwvaDQ+CgkgKgoJICogICAgICB2YXIgcXVldWUgPSBuZXcgY3JlYXRlanMuTG9hZFF1ZXVlKCk7CgkgKiAgICAgIHF1ZXVlLnNldE1heENvbm5lY3Rpb25zKDEwKTsgLy8gQWxsb3cgMTAgY29uY3VycmVudCBsb2FkcwoJICoKCSAqIEBtZXRob2Qgc2V0TWF4Q29ubmVjdGlvbnMKCSAqIEBwYXJhbSB7TnVtYmVyfSB2YWx1ZSBUaGUgbnVtYmVyIG9mIGNvbmN1cnJlbnQgbG9hZHMgdG8gYWxsb3cuIEJ5IGRlZmF1bHQsIG9ubHkgYSBzaW5nbGUgY29ubmVjdGlvbiBwZXIgTG9hZFF1ZXVlCgkgKiBpcyBvcGVuIGF0IGFueSB0aW1lLgoJICovCglwLnNldE1heENvbm5lY3Rpb25zID0gZnVuY3Rpb24gKHZhbHVlKSB7CgkJdGhpcy5fbWF4Q29ubmVjdGlvbnMgPSB2YWx1ZTsKCQlpZiAoIXRoaXMuX3BhdXNlZCAmJiB0aGlzLl9sb2FkUXVldWUubGVuZ3RoID4gMCkgewoJCQl0aGlzLl9sb2FkTmV4dCgpOwoJCX0KCX07CgoJLyoqCgkgKiBMb2FkIGEgc2luZ2xlIGZpbGUuIFRvIGFkZCBtdWx0aXBsZSBmaWxlcyBhdCBvbmNlLCB1c2UgdGhlIHt7I2Nyb3NzTGluayAiTG9hZFF1ZXVlL2xvYWRNYW5pZmVzdCJ9fXt7L2Nyb3NzTGlua319CgkgKiBtZXRob2QuCgkgKgoJICogRmlsZXMgYXJlIGFsd2F5cyBhcHBlbmRlZCB0byB0aGUgY3VycmVudCBxdWV1ZSwgc28gdGhpcyBtZXRob2QgY2FuIGJlIHVzZWQgbXVsdGlwbGUgdGltZXMgdG8gYWRkIGZpbGVzLgoJICogVG8gY2xlYXIgdGhlIHF1ZXVlIGZpcnN0LCB1c2UgdGhlIHt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvY2xvc2UifX17ey9jcm9zc0xpbmt9fSBtZXRob2QuCgkgKiBAbWV0aG9kIGxvYWRGaWxlCgkgKiBAcGFyYW0ge0xvYWRJdGVtfE9iamVjdHxTdHJpbmd9IGZpbGUgVGhlIGZpbGUgb2JqZWN0IG9yIHBhdGggdG8gbG9hZC4gQSBmaWxlIGNhbiBiZSBlaXRoZXIKCSAqIDx1bD4KCSAqICAgICA8bGk+QSB7eyNjcm9zc0xpbmsgIkxvYWRJdGVtIn19e3svY3Jvc3NMaW5rfX0gaW5zdGFuY2U8L2xpPgoJICogICAgIDxsaT5BbiBvYmplY3QgY29udGFpbmluZyBwcm9wZXJ0aWVzIGRlZmluZWQgYnkge3sjY3Jvc3NMaW5rICJMb2FkSXRlbSJ9fXt7L2Nyb3NzTGlua319PC9saT4KCSAqICAgICA8bGk+T1IgQSBzdHJpbmcgcGF0aCB0byBhIHJlc291cmNlLiBOb3RlIHRoYXQgdGhpcyBraW5kIG9mIGxvYWQgaXRlbSB3aWxsIGJlIGNvbnZlcnRlZCB0byBhIHt7I2Nyb3NzTGluayAiTG9hZEl0ZW0ifX17ey9jcm9zc0xpbmt9fQoJICogICAgIGluIHRoZSBiYWNrZ3JvdW5kLjwvbGk+CgkgKiA8L3VsPgoJICogQHBhcmFtIHtCb29sZWFufSBbbG9hZE5vdz10cnVlXSBLaWNrIG9mZiBhbiBpbW1lZGlhdGUgbG9hZCAodHJ1ZSkgb3Igd2FpdCBmb3IgYSBsb2FkIGNhbGwgKGZhbHNlKS4gVGhlIGRlZmF1bHQKCSAqIHZhbHVlIGlzIHRydWUuIElmIHRoZSBxdWV1ZSBpcyBwYXVzZWQgdXNpbmcge3sjY3Jvc3NMaW5rICJMb2FkUXVldWUvc2V0UGF1c2VkIn19e3svY3Jvc3NMaW5rfX0sIGFuZCB0aGUgdmFsdWUgaXMKCSAqIGB0cnVlYCwgdGhlIHF1ZXVlIHdpbGwgcmVzdW1lIGF1dG9tYXRpY2FsbHkuCgkgKiBAcGFyYW0ge1N0cmluZ30gW2Jhc2VQYXRoXSBBIGJhc2UgcGF0aCB0aGF0IHdpbGwgYmUgcHJlcGVuZGVkIHRvIGVhY2ggZmlsZS4gVGhlIGJhc2VQYXRoIGFyZ3VtZW50IG92ZXJyaWRlcyB0aGUKCSAqIHBhdGggc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3Rvci4gTm90ZSB0aGF0IGlmIHlvdSBsb2FkIGEgbWFuaWZlc3QgdXNpbmcgYSBmaWxlIG9mIHR5cGUge3sjY3Jvc3NMaW5rICJBYnN0cmFjdExvYWRlci9NQU5JRkVTVDpwcm9wZXJ0eSJ9fXt7L2Nyb3NzTGlua319LAoJICogaXRzIGZpbGVzIHdpbGwgPHN0cm9uZz5OT1Q8L3N0cm9uZz4gdXNlIHRoZSBiYXNlUGF0aCBwYXJhbWV0ZXIuIDxzdHJvbmc+VGhlIGJhc2VQYXRoIHBhcmFtZXRlciBpcyBkZXByZWNhdGVkLjwvc3Ryb25nPgoJICogVGhpcyBwYXJhbWV0ZXIgd2lsbCBiZSByZW1vdmVkIGluIGEgZnV0dXJlIHZlcnNpb24uIFBsZWFzZSBlaXRoZXIgdXNlIHRoZSBgYmFzZVBhdGhgIHBhcmFtZXRlciBpbiB0aGUgTG9hZFF1ZXVlCgkgKiBjb25zdHJ1Y3Rvciwgb3IgYSBgcGF0aGAgcHJvcGVydHkgaW4gYSBtYW5pZmVzdCBkZWZpbml0aW9uLgoJICovCglwLmxvYWRGaWxlID0gZnVuY3Rpb24gKGZpbGUsIGxvYWROb3csIGJhc2VQYXRoKSB7CgkJaWYgKGZpbGUgPT0gbnVsbCkgewoJCQl2YXIgZXZlbnQgPSBuZXcgY3JlYXRlanMuRXJyb3JFdmVudCgiUFJFTE9BRF9OT19GSUxFIik7CgkJCXRoaXMuX3NlbmRFcnJvcihldmVudCk7CgkJCXJldHVybjsKCQl9CgkJdGhpcy5fYWRkSXRlbShmaWxlLCBudWxsLCBiYXNlUGF0aCk7CgoJCWlmIChsb2FkTm93ICE9PSBmYWxzZSkgewoJCQl0aGlzLnNldFBhdXNlZChmYWxzZSk7CgkJfSBlbHNlIHsKCQkJdGhpcy5zZXRQYXVzZWQodHJ1ZSk7CgkJfQoJfTsKCgkvKioKCSAqIExvYWQgYW4gYXJyYXkgb2YgZmlsZXMuIFRvIGxvYWQgYSBzaW5nbGUgZmlsZSwgdXNlIHRoZSB7eyNjcm9zc0xpbmsgIkxvYWRRdWV1ZS9sb2FkRmlsZSJ9fXt7L2Nyb3NzTGlua319IG1ldGhvZC4KCSAqIFRoZSBmaWxlcyBpbiB0aGUgbWFuaWZlc3QgYXJlIHJlcXVlc3RlZCBpbiB0aGUgc2FtZSBvcmRlciwgYnV0IG1heSBjb21wbGV0ZSBpbiBhIGRpZmZlcmVudCBvcmRlciBpZiB0aGUgbWF4CgkgKiBjb25uZWN0aW9ucyBhcmUgc2V0IGFib3ZlIDEgdXNpbmcge3sjY3Jvc3NMaW5rICJMb2FkUXVldWUvc2V0TWF4Q29ubmVjdGlvbnMifX17ey9jcm9zc0xpbmt9fS4gU2NyaXB0cyB3aWxsIGxvYWQKCSAqIGluIHRoZSByaWdodCBvcmRlciBhcyBsb25nIGFzIHt7I2Nyb3NzTGluayAiTG9hZFF1ZXVlL21haW50YWluU2NyaXB0T3JkZXIifX17ey9jcm9zc0xpbmt9fSBpcyB0cnVlICh3aGljaCBpcwoJICogZGVmYXVsdCkuCgkgKgoJICogRmlsZXMgYXJlIGFsd2F5cyBhcHBlbmRlZCB0byB0aGUgY3VycmVudCBxdWV1ZSwgc28gdGhpcyBtZXRob2QgY2FuIGJlIHVzZWQgbXVsdGlwbGUgdGltZXMgdG8gYWRkIGZpbGVzLgoJICogVG8gY2xlYXIgdGhlIHF1ZXVlIGZpcnN0LCB1c2UgdGhlIHt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvY2xvc2UifX17ey9jcm9zc0xpbmt9fSBtZXRob2QuCgkgKiBAbWV0aG9kIGxvYWRNYW5pZmVzdAoJICogQHBhcmFtIHtBcnJheXxTdHJpbmd8T2JqZWN0fSBtYW5pZmVzdCBBbiBsaXN0IG9mIGZpbGVzIHRvIGxvYWQuIFRoZSBsb2FkTWFuaWZlc3QgY2FsbCBzdXBwb3J0cyBmb3VyIHR5cGVzIG9mCgkgKiBtYW5pZmVzdHM6CgkgKiA8b2w+CgkgKiAgICAgPGxpPkEgc3RyaW5nIHBhdGgsIHdoaWNoIHBvaW50cyB0byBhIG1hbmlmZXN0IGZpbGUsIHdoaWNoIGlzIGEgSlNPTiBmaWxlIHRoYXQgY29udGFpbnMgYSAibWFuaWZlc3QiIHByb3BlcnR5LAoJICogICAgIHdoaWNoIGRlZmluZXMgdGhlIGxpc3Qgb2YgZmlsZXMgdG8gbG9hZCwgYW5kIGNhbiBvcHRpb25hbGx5IGNvbnRhaW4gYSAicGF0aCIgcHJvcGVydHksIHdoaWNoIHdpbGwgYmUKCSAqICAgICBwcmVwZW5kZWQgdG8gZWFjaCBmaWxlIGluIHRoZSBsaXN0LjwvbGk+CgkgKiAgICAgPGxpPkFuIG9iamVjdCB3aGljaCBkZWZpbmVzIGEgInNyYyIsIHdoaWNoIGlzIGEgSlNPTiBvciBKU09OUCBmaWxlLiBBICJjYWxsYmFjayIgY2FuIGJlIGRlZmluZWQgZm9yIEpTT05QCgkgKiAgICAgZmlsZS4gVGhlIEpTT04vSlNPTlAgZmlsZSBzaG91bGQgY29udGFpbiBhICJtYW5pZmVzdCIgcHJvcGVydHksIHdoaWNoIGRlZmluZXMgdGhlIGxpc3Qgb2YgZmlsZXMgdG8gbG9hZCwKCSAqICAgICBhbmQgY2FuIG9wdGlvbmFsbHkgY29udGFpbiBhICJwYXRoIiBwcm9wZXJ0eSwgd2hpY2ggd2lsbCBiZSBwcmVwZW5kZWQgdG8gZWFjaCBmaWxlIGluIHRoZSBsaXN0LjwvbGk+CgkgKiAgICAgPGxpPkFuIG9iamVjdCB3aGljaCBjb250YWlucyBhICJtYW5pZmVzdCIgcHJvcGVydHksIHdoaWNoIGRlZmluZXMgdGhlIGxpc3Qgb2YgZmlsZXMgdG8gbG9hZCwgYW5kIGNhbgoJICogICAgIG9wdGlvbmFsbHkgY29udGFpbiBhICJwYXRoIiBwcm9wZXJ0eSwgd2hpY2ggd2lsbCBiZSBwcmVwZW5kZWQgdG8gZWFjaCBmaWxlIGluIHRoZSBsaXN0LjwvbGk+CgkgKiAgICAgPGxpPkFuIEFycmF5IG9mIGZpbGVzIHRvIGxvYWQuPC9saT4KCSAqIDwvb2w+CgkgKgoJICogRWFjaCAiZmlsZSIgaW4gYSBtYW5pZmVzdCBjYW4gYmUgZWl0aGVyOgoJICogPHVsPgoJICogICAgIDxsaT5BIHt7I2Nyb3NzTGluayAiTG9hZEl0ZW0ifX17ey9jcm9zc0xpbmt9fSBpbnN0YW5jZTwvbGk+CgkgKiAgICAgPGxpPkFuIG9iamVjdCBjb250YWluaW5nIHByb3BlcnRpZXMgZGVmaW5lZCBieSB7eyNjcm9zc0xpbmsgIkxvYWRJdGVtIn19e3svY3Jvc3NMaW5rfX08L2xpPgoJICogICAgIDxsaT5PUiBBIHN0cmluZyBwYXRoIHRvIGEgcmVzb3VyY2UuIE5vdGUgdGhhdCB0aGlzIGtpbmQgb2YgbG9hZCBpdGVtIHdpbGwgYmUgY29udmVydGVkIHRvIGEge3sjY3Jvc3NMaW5rICJMb2FkSXRlbSJ9fXt7L2Nyb3NzTGlua319CgkgKiAgICAgaW4gdGhlIGJhY2tncm91bmQuPC9saT4KCSAqIDwvdWw+CgkgKgoJICogQHBhcmFtIHtCb29sZWFufSBbbG9hZE5vdz10cnVlXSBLaWNrIG9mZiBhbiBpbW1lZGlhdGUgbG9hZCAodHJ1ZSkgb3Igd2FpdCBmb3IgYSBsb2FkIGNhbGwgKGZhbHNlKS4gVGhlIGRlZmF1bHQKCSAqIHZhbHVlIGlzIHRydWUuIElmIHRoZSBxdWV1ZSBpcyBwYXVzZWQgdXNpbmcge3sjY3Jvc3NMaW5rICJMb2FkUXVldWUvc2V0UGF1c2VkIn19e3svY3Jvc3NMaW5rfX0gYW5kIHRoaXMgdmFsdWUgaXMKCSAqIGB0cnVlYCwgdGhlIHF1ZXVlIHdpbGwgcmVzdW1lIGF1dG9tYXRpY2FsbHkuCgkgKiBAcGFyYW0ge1N0cmluZ30gW2Jhc2VQYXRoXSBBIGJhc2UgcGF0aCB0aGF0IHdpbGwgYmUgcHJlcGVuZGVkIHRvIGVhY2ggZmlsZS4gVGhlIGJhc2VQYXRoIGFyZ3VtZW50IG92ZXJyaWRlcyB0aGUKCSAqIHBhdGggc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3Rvci4gTm90ZSB0aGF0IGlmIHlvdSBsb2FkIGEgbWFuaWZlc3QgdXNpbmcgYSBmaWxlIG9mIHR5cGUge3sjY3Jvc3NMaW5rICJMb2FkUXVldWUvTUFOSUZFU1Q6cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fSwKCSAqIGl0cyBmaWxlcyB3aWxsIDxzdHJvbmc+Tk9UPC9zdHJvbmc+IHVzZSB0aGUgYmFzZVBhdGggcGFyYW1ldGVyLiA8c3Ryb25nPlRoZSBiYXNlUGF0aCBwYXJhbWV0ZXIgaXMgZGVwcmVjYXRlZC48L3N0cm9uZz4KCSAqIFRoaXMgcGFyYW1ldGVyIHdpbGwgYmUgcmVtb3ZlZCBpbiBhIGZ1dHVyZSB2ZXJzaW9uLiBQbGVhc2UgZWl0aGVyIHVzZSB0aGUgYGJhc2VQYXRoYCBwYXJhbWV0ZXIgaW4gdGhlIExvYWRRdWV1ZQoJICogY29uc3RydWN0b3IsIG9yIGEgYHBhdGhgIHByb3BlcnR5IGluIGEgbWFuaWZlc3QgZGVmaW5pdGlvbi4KCSAqLwoJcC5sb2FkTWFuaWZlc3QgPSBmdW5jdGlvbiAobWFuaWZlc3QsIGxvYWROb3csIGJhc2VQYXRoKSB7CgkJdmFyIGZpbGVMaXN0ID0gbnVsbDsKCQl2YXIgcGF0aCA9IG51bGw7CgoJCS8vIEFycmF5LWJhc2VkIGxpc3Qgb2YgaXRlbXMKCQlpZiAobWFuaWZlc3QgaW5zdGFuY2VvZiBBcnJheSkgewoJCQlpZiAobWFuaWZlc3QubGVuZ3RoID09IDApIHsKCQkJCXZhciBldmVudCA9IG5ldyBjcmVhdGVqcy5FcnJvckV2ZW50KCJQUkVMT0FEX01BTklGRVNUX0VNUFRZIik7CgkJCQl0aGlzLl9zZW5kRXJyb3IoZXZlbnQpOwoJCQkJcmV0dXJuOwoJCQl9CgkJCWZpbGVMaXN0ID0gbWFuaWZlc3Q7CgoJCQkvLyBTdHJpbmctYmFzZWQuIE9ubHkgZmlsZSBtYW5pZmVzdHMgY2FuIGJlIHNwZWNpZmllZCB0aGlzIHdheS4gQW55IG90aGVyIHR5cGVzIHdpbGwgY2F1c2UgYW4gZXJyb3Igd2hlbiBsb2FkZWQuCgkJfSBlbHNlIGlmICh0eXBlb2YobWFuaWZlc3QpID09PSAic3RyaW5nIikgewoJCQlmaWxlTGlzdCA9IFsKCQkJCXsKCQkJCQlzcmM6IG1hbmlmZXN0LAoJCQkJCXR5cGU6IHMuTUFOSUZFU1QKCQkJCX0KCQkJXTsKCgkJfSBlbHNlIGlmICh0eXBlb2YobWFuaWZlc3QpID09ICJvYmplY3QiKSB7CgoJCQkvLyBBbiBvYmplY3QgdGhhdCBkZWZpbmVzIGEgbWFuaWZlc3QgcGF0aAoJCQlpZiAobWFuaWZlc3Quc3JjICE9PSB1bmRlZmluZWQpIHsKCQkJCWlmIChtYW5pZmVzdC50eXBlID09IG51bGwpIHsKCQkJCQltYW5pZmVzdC50eXBlID0gcy5NQU5JRkVTVDsKCQkJCX0gZWxzZSBpZiAobWFuaWZlc3QudHlwZSAhPSBzLk1BTklGRVNUKSB7CgkJCQkJdmFyIGV2ZW50ID0gbmV3IGNyZWF0ZWpzLkVycm9yRXZlbnQoIlBSRUxPQURfTUFOSUZFU1RfVFlQRSIpOwoJCQkJCXRoaXMuX3NlbmRFcnJvcihldmVudCk7CgkJCQl9CgkJCQlmaWxlTGlzdCA9IFttYW5pZmVzdF07CgoJCQkJLy8gQW4gb2JqZWN0IHRoYXQgZGVmaW5lcyBhIG1hbmlmZXN0CgkJCX0gZWxzZSBpZiAobWFuaWZlc3QubWFuaWZlc3QgIT09IHVuZGVmaW5lZCkgewoJCQkJZmlsZUxpc3QgPSBtYW5pZmVzdC5tYW5pZmVzdDsKCQkJCXBhdGggPSBtYW5pZmVzdC5wYXRoOwoJCQl9CgoJCQkvLyBVbnN1cHBvcnRlZC4gVGhpcyB3aWxsIHRocm93IGFuIGVycm9yLgoJCX0gZWxzZSB7CgkJCXZhciBldmVudCA9IG5ldyBjcmVhdGVqcy5FcnJvckV2ZW50KCJQUkVMT0FEX01BTklGRVNUX05VTEwiKTsKCQkJdGhpcy5fc2VuZEVycm9yKGV2ZW50KTsKCQkJcmV0dXJuOwoJCX0KCgkJZm9yICh2YXIgaSA9IDAsIGwgPSBmaWxlTGlzdC5sZW5ndGg7IGkgPCBsOyBpKyspIHsKCQkJdGhpcy5fYWRkSXRlbShmaWxlTGlzdFtpXSwgcGF0aCwgYmFzZVBhdGgpOwoJCX0KCgkJaWYgKGxvYWROb3cgIT09IGZhbHNlKSB7CgkJCXRoaXMuc2V0UGF1c2VkKGZhbHNlKTsKCQl9IGVsc2UgewoJCQl0aGlzLnNldFBhdXNlZCh0cnVlKTsKCQl9CgoJfTsKCgkvKioKCSAqIFN0YXJ0IGEgTG9hZFF1ZXVlIHRoYXQgd2FzIGNyZWF0ZWQsIGJ1dCBub3QgYXV0b21hdGljYWxseSBzdGFydGVkLgoJICogQG1ldGhvZCBsb2FkCgkgKi8KCXAubG9hZCA9IGZ1bmN0aW9uICgpIHsKCQl0aGlzLnNldFBhdXNlZChmYWxzZSk7Cgl9OwoKCS8qKgoJICogTG9vayB1cCBhIHt7I2Nyb3NzTGluayAiTG9hZEl0ZW0ifX17ey9jcm9zc0xpbmt9fSB1c2luZyBlaXRoZXIgdGhlICJpZCIgb3IgInNyYyIgdGhhdCB3YXMgc3BlY2lmaWVkIHdoZW4gbG9hZGluZyBpdC4gTm90ZSB0aGF0IGlmIG5vICJpZCIgd2FzCgkgKiBzdXBwbGllZCB3aXRoIHRoZSBsb2FkIGl0ZW0sIHRoZSBJRCB3aWxsIGJlIHRoZSAic3JjIiwgaW5jbHVkaW5nIGEgYHBhdGhgIHByb3BlcnR5IGRlZmluZWQgYnkgYSBtYW5pZmVzdC4gVGhlCgkgKiBgYmFzZVBhdGhgIHdpbGwgbm90IGJlIHBhcnQgb2YgdGhlIElELgoJICogQG1ldGhvZCBnZXRJdGVtCgkgKiBAcGFyYW0ge1N0cmluZ30gdmFsdWUgVGhlIDxjb2RlPmlkPC9jb2RlPiBvciA8Y29kZT5zcmM8L2NvZGU+IG9mIHRoZSBsb2FkIGl0ZW0uCgkgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBsb2FkIGl0ZW0gdGhhdCB3YXMgaW5pdGlhbGx5IHJlcXVlc3RlZCB1c2luZyB7eyNjcm9zc0xpbmsgIkxvYWRRdWV1ZS9sb2FkRmlsZSJ9fXt7L2Nyb3NzTGlua319CgkgKiBvciB7eyNjcm9zc0xpbmsgIkxvYWRRdWV1ZS9sb2FkTWFuaWZlc3QifX17ey9jcm9zc0xpbmt9fS4gVGhpcyBvYmplY3QgaXMgYWxzbyByZXR1cm5lZCB2aWEgdGhlIHt7I2Nyb3NzTGluayAiTG9hZFF1ZXVlL2ZpbGVsb2FkOmV2ZW50In19e3svY3Jvc3NMaW5rfX0KCSAqIGV2ZW50IGFzIHRoZSBgaXRlbWAgcGFyYW1ldGVyLgoJICovCglwLmdldEl0ZW0gPSBmdW5jdGlvbiAodmFsdWUpIHsKCQlyZXR1cm4gdGhpcy5fbG9hZEl0ZW1zQnlJZFt2YWx1ZV0gfHwgdGhpcy5fbG9hZEl0ZW1zQnlTcmNbdmFsdWVdOwoJfTsKCgkvKioKCSAqIExvb2sgdXAgYSBsb2FkZWQgcmVzdWx0IHVzaW5nIGVpdGhlciB0aGUgImlkIiBvciAic3JjIiB0aGF0IHdhcyBzcGVjaWZpZWQgd2hlbiBsb2FkaW5nIGl0LiBOb3RlIHRoYXQgaWYgbm8gImlkIgoJICogd2FzIHN1cHBsaWVkIHdpdGggdGhlIGxvYWQgaXRlbSwgdGhlIElEIHdpbGwgYmUgdGhlICJzcmMiLCBpbmNsdWRpbmcgYSBgcGF0aGAgcHJvcGVydHkgZGVmaW5lZCBieSBhIG1hbmlmZXN0LiBUaGUKCSAqIGBiYXNlUGF0aGAgd2lsbCBub3QgYmUgcGFydCBvZiB0aGUgSUQuCgkgKiBAbWV0aG9kIGdldFJlc3VsdAoJICogQHBhcmFtIHtTdHJpbmd9IHZhbHVlIFRoZSA8Y29kZT5pZDwvY29kZT4gb3IgPGNvZGU+c3JjPC9jb2RlPiBvZiB0aGUgbG9hZCBpdGVtLgoJICogQHBhcmFtIHtCb29sZWFufSBbcmF3UmVzdWx0PWZhbHNlXSBSZXR1cm4gYSByYXcgcmVzdWx0IGluc3RlYWQgb2YgYSBmb3JtYXR0ZWQgcmVzdWx0LiBUaGlzIGFwcGxpZXMgdG8gY29udGVudAoJICogbG9hZGVkIHZpYSBYSFIgc3VjaCBhcyBzY3JpcHRzLCBYTUwsIENTUywgYW5kIEltYWdlcy4gSWYgdGhlcmUgaXMgbm8gcmF3IHJlc3VsdCwgdGhlIGZvcm1hdHRlZCByZXN1bHQgd2lsbCBiZQoJICogcmV0dXJuZWQgaW5zdGVhZC4KCSAqIEByZXR1cm4ge09iamVjdH0gQSByZXN1bHQgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGNvbnRlbnQgdGhhdCB3YXMgbG9hZGVkLCBzdWNoIGFzOgoJICogPHVsPgoJICogICAgICA8bGk+QW4gaW1hZ2UgdGFnICgmbHQ7aW1hZ2UgLyZndDspIGZvciBpbWFnZXM8L2xpPgoJICogICAgICA8bGk+QSBzY3JpcHQgdGFnIGZvciBKYXZhU2NyaXB0ICgmbHQ7c2NyaXB0IC8mZ3Q7KS4gTm90ZSB0aGF0IHNjcmlwdHMgYXJlIGF1dG9tYXRpY2FsbHkgYWRkZWQgdG8gdGhlIEhUTUwKCSAqICAgICAgRE9NLjwvbGk+CgkgKiAgICAgIDxsaT5BIHN0eWxlIHRhZyBmb3IgQ1NTICgmbHQ7c3R5bGUgLyZndDsgb3IgJmx0O2xpbmsgJmd0Oyk8L2xpPgoJICogICAgICA8bGk+UmF3IHRleHQgZm9yIFRFWFQ8L2xpPgoJICogICAgICA8bGk+QSBmb3JtYXR0ZWQgSmF2YVNjcmlwdCBvYmplY3QgZGVmaW5lZCBieSBKU09OPC9saT4KCSAqICAgICAgPGxpPkFuIFhNTCBkb2N1bWVudDwvbGk+CgkgKiAgICAgIDxsaT5BIGJpbmFyeSBhcnJheWJ1ZmZlciBsb2FkZWQgYnkgWEhSPC9saT4KCSAqICAgICAgPGxpPkFuIGF1ZGlvIHRhZyAoJmx0O2F1ZGlvICZndDspIGZvciBIVE1MIGF1ZGlvLiBOb3RlIHRoYXQgaXQgaXMgcmVjb21tZW5kZWQgdG8gdXNlIFNvdW5kSlMgQVBJcyB0byBwbGF5CgkgKiAgICAgIGxvYWRlZCBhdWRpby4gU3BlY2lmaWNhbGx5LCBhdWRpbyBsb2FkZWQgYnkgRmxhc2ggYW5kIFdlYkF1ZGlvIHdpbGwgcmV0dXJuIGEgbG9hZGVyIG9iamVjdCB1c2luZyB0aGlzIG1ldGhvZAoJICogICAgICB3aGljaCBjYW4gbm90IGJlIHVzZWQgdG8gcGxheSBhdWRpbyBiYWNrLjwvbGk+CgkgKiA8L3VsPgoJICogVGhpcyBvYmplY3QgaXMgYWxzbyByZXR1cm5lZCB2aWEgdGhlIHt7I2Nyb3NzTGluayAiTG9hZFF1ZXVlL2ZpbGVsb2FkOmV2ZW50In19e3svY3Jvc3NMaW5rfX0gZXZlbnQgYXMgdGhlICdpdGVtYAoJICogcGFyYW1ldGVyLiBOb3RlIHRoYXQgaWYgYSByYXcgcmVzdWx0IGlzIHJlcXVlc3RlZCwgYnV0IG5vdCBmb3VuZCwgdGhlIHJlc3VsdCB3aWxsIGJlIHJldHVybmVkIGluc3RlYWQuCgkgKi8KCXAuZ2V0UmVzdWx0ID0gZnVuY3Rpb24gKHZhbHVlLCByYXdSZXN1bHQpIHsKCQl2YXIgaXRlbSA9IHRoaXMuX2xvYWRJdGVtc0J5SWRbdmFsdWVdIHx8IHRoaXMuX2xvYWRJdGVtc0J5U3JjW3ZhbHVlXTsKCQlpZiAoaXRlbSA9PSBudWxsKSB7IHJldHVybiBudWxsOyB9CgkJdmFyIGlkID0gaXRlbS5pZDsKCQlpZiAocmF3UmVzdWx0ICYmIHRoaXMuX2xvYWRlZFJhd1Jlc3VsdHNbaWRdKSB7CgkJCXJldHVybiB0aGlzLl9sb2FkZWRSYXdSZXN1bHRzW2lkXTsKCQl9CgkJcmV0dXJuIHRoaXMuX2xvYWRlZFJlc3VsdHNbaWRdOwoJfTsKCgkvKioKCSAqIEdlbmVyYXRlIGFuIGxpc3Qgb2YgaXRlbXMgbG9hZGVkIGJ5IHRoaXMgcXVldWUuCgkgKiBAbWV0aG9kIGdldEl0ZW1zCgkgKiBAcGFyYW0ge0Jvb2xlYW59IGxvYWRlZCBEZXRlcm1pbmVzIGlmIG9ubHkgaXRlbXMgdGhhdCBoYXZlIGJlZW4gbG9hZGVkIHNob3VsZCBiZSByZXR1cm5lZC4gSWYgZmFsc2UsIGluLXByb2dyZXNzCgkgKiBhbmQgZmFpbGVkIGxvYWQgaXRlbXMgd2lsbCBhbHNvIGJlIGluY2x1ZGVkLgoJICogQHJldHVybnMge0FycmF5fSBBIGxpc3Qgb2Ygb2JqZWN0cyB0aGF0IGhhdmUgYmVlbiBsb2FkZWQuIEVhY2ggaXRlbSBpbmNsdWRlcyB0aGUge3sjY3Jvc3NMaW5rICJMb2FkSXRlbSJ9fXt7L2Nyb3NzTGlua319LAoJICogcmVzdWx0LCBhbmQgcmF3UmVzdWx0LgoJICogQHNpbmNlIDAuNi4wCgkgKi8KCXAuZ2V0SXRlbXMgPSBmdW5jdGlvbihsb2FkZWQpIHsKCQl2YXIgYXJyID0gW107CgkJZm9yICh2YXIgaT0gMCwgbD10aGlzLl9sb2FkUXVldWVCYWNrdXAubGVuZ3RoOyBpPGw7IGkrKykgewoJCQl2YXIgbG9hZGVyID0gdGhpcy5fbG9hZFF1ZXVlQmFja3VwW2ldCgkJCXZhciBpdGVtID0gbG9hZGVyLmdldEl0ZW0oKTsKCQkJaWYgKGxvYWRlZCA9PT0gdHJ1ZSAmJiAhbG9hZGVyLmxvYWRlZCkgeyBjb250aW51ZTsgfQoJCQlhcnIucHVzaCh7CgkJCQlpdGVtOiBpdGVtLAoJCQkJcmVzdWx0OiB0aGlzLmdldFJlc3VsdChpdGVtLmlkKSwKCQkJCXJhd1Jlc3VsdDogdGhpcy5nZXRSZXN1bHQoaXRlbS5pZCwgdHJ1ZSkKCQkJIH0pOwoJCX0KCQlyZXR1cm4gYXJyOwoJfTsKCgkvKioKCSAqIFBhdXNlIG9yIHJlc3VtZSB0aGUgY3VycmVudCBsb2FkLiBBY3RpdmUgbG9hZHMgd2lsbCBub3QgYmUgY2FuY2VsbGVkLCBidXQgdGhlIG5leHQgaXRlbXMgaW4gdGhlIHF1ZXVlIHdpbGwgbm90CgkgKiBiZSBwcm9jZXNzZWQgd2hlbiBhY3RpdmUgbG9hZHMgY29tcGxldGUuIExvYWRRdWV1ZXMgYXJlIG5vdCBwYXVzZWQgYnkgZGVmYXVsdC4KCSAqCgkgKiBOb3RlIHRoYXQgaWYgbmV3IGl0ZW1zIGFyZSBhZGRlZCB0byB0aGUgcXVldWUgdXNpbmcge3sjY3Jvc3NMaW5rICJMb2FkUXVldWUvbG9hZEZpbGUifX17ey9jcm9zc0xpbmt9fSBvcgoJICoge3sjY3Jvc3NMaW5rICJMb2FkUXVldWUvbG9hZE1hbmlmZXN0In19e3svY3Jvc3NMaW5rfX0sIGEgcGF1c2VkIHF1ZXVlIHdpbGwgYmUgcmVzdW1lZCwgdW5sZXNzIHRoZSBgbG9hZE5vd2AKCSAqIGFyZ3VtZW50IGlzIGBmYWxzZWAuCgkgKiBAbWV0aG9kIHNldFBhdXNlZAoJICogQHBhcmFtIHtCb29sZWFufSB2YWx1ZSBXaGV0aGVyIHRoZSBxdWV1ZSBzaG91bGQgYmUgcGF1c2VkIG9yIG5vdC4KCSAqLwoJcC5zZXRQYXVzZWQgPSBmdW5jdGlvbiAodmFsdWUpIHsKCQl0aGlzLl9wYXVzZWQgPSB2YWx1ZTsKCQlpZiAoIXRoaXMuX3BhdXNlZCkgewoJCQl0aGlzLl9sb2FkTmV4dCgpOwoJCX0KCX07CgoJLyoqCgkgKiBDbG9zZSB0aGUgYWN0aXZlIHF1ZXVlLiBDbG9zaW5nIGEgcXVldWUgY29tcGxldGVseSBlbXB0aWVzIHRoZSBxdWV1ZSwgYW5kIHByZXZlbnRzIGFueSByZW1haW5pbmcgaXRlbXMgZnJvbQoJICogc3RhcnRpbmcgdG8gZG93bmxvYWQuIE5vdGUgdGhhdCBjdXJyZW50bHkgYW55IGFjdGl2ZSBsb2FkcyB3aWxsIHJlbWFpbiBvcGVuLCBhbmQgZXZlbnRzIG1heSBiZSBwcm9jZXNzZWQuCgkgKgoJICogVG8gc3RvcCBhbmQgcmVzdGFydCBhIHF1ZXVlLCB1c2UgdGhlIHt7I2Nyb3NzTGluayAiTG9hZFF1ZXVlL3NldFBhdXNlZCJ9fXt7L2Nyb3NzTGlua319IG1ldGhvZCBpbnN0ZWFkLgoJICogQG1ldGhvZCBjbG9zZQoJICovCglwLmNsb3NlID0gZnVuY3Rpb24gKCkgewoJCXdoaWxlICh0aGlzLl9jdXJyZW50TG9hZHMubGVuZ3RoKSB7CgkJCXRoaXMuX2N1cnJlbnRMb2Fkcy5wb3AoKS5jYW5jZWwoKTsKCQl9CgkJdGhpcy5fc2NyaXB0T3JkZXIubGVuZ3RoID0gMDsKCQl0aGlzLl9sb2FkZWRTY3JpcHRzLmxlbmd0aCA9IDA7CgkJdGhpcy5sb2FkU3RhcnRXYXNEaXNwYXRjaGVkID0gZmFsc2U7CgkJdGhpcy5faXRlbUNvdW50ID0gMDsKCQl0aGlzLl9sYXN0UHJvZ3Jlc3MgPSBOYU47Cgl9OwoKLy8gcHJvdGVjdGVkIG1ldGhvZHMKCS8qKgoJICogQWRkIGFuIGl0ZW0gdG8gdGhlIHF1ZXVlLiBJdGVtcyBhcmUgZm9ybWF0dGVkIGludG8gYSB1c2FibGUgb2JqZWN0IGNvbnRhaW5pbmcgYWxsIHRoZSBwcm9wZXJ0aWVzIG5lY2Vzc2FyeSB0bwoJICogbG9hZCB0aGUgY29udGVudC4gVGhlIGxvYWQgcXVldWUgaXMgcG9wdWxhdGVkIHdpdGggdGhlIGxvYWRlciBpbnN0YW5jZSB0aGF0IGhhbmRsZXMgcHJlbG9hZGluZywgYW5kIG5vdCB0aGUgbG9hZAoJICogaXRlbSB0aGF0IHdhcyBwYXNzZWQgaW4gYnkgdGhlIHVzZXIuIFRvIGxvb2sgdXAgdGhlIGxvYWQgaXRlbSBieSBpZCBvciBzcmMsIHVzZSB0aGUge3sjY3Jvc3NMaW5rICJMb2FkUXVldWUuZ2V0SXRlbSJ9fXt7L2Nyb3NzTGlua319CgkgKiBtZXRob2QuCgkgKiBAbWV0aG9kIF9hZGRJdGVtCgkgKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R9IHZhbHVlIFRoZSBpdGVtIHRvIGFkZCB0byB0aGUgcXVldWUuCgkgKiBAcGFyYW0ge1N0cmluZ30gW3BhdGhdIEFuIG9wdGlvbmFsIHBhdGggcHJlcGVuZGVkIHRvIHRoZSBgc3JjYC4gVGhlIHBhdGggd2lsbCBvbmx5IGJlIHByZXBlbmRlZCBpZiB0aGUgc3JjIGlzCgkgKiByZWxhdGl2ZSwgYW5kIGRvZXMgbm90IHN0YXJ0IHdpdGggYSBwcm90b2NvbCBzdWNoIGFzIGBodHRwOi8vYCwgb3IgYSBwYXRoIGxpa2UgYC4uL2AuIElmIHRoZSBMb2FkUXVldWUgd2FzCgkgKiBwcm92aWRlZCBhIHt7I2Nyb3NzTGluayAiX2Jhc2VQYXRoIn19e3svY3Jvc3NMaW5rfX0sIHRoZW4gaXQgd2lsbCBvcHRpb25hbGx5IGJlIHByZXBlbmRlZCBhZnRlci4KCSAqIEBwYXJhbSB7U3RyaW5nfSBbYmFzZVBhdGhdIDxzdHJvbmc+RGVwcmVjYXRlZDwvc3Ryb25nPkFuIG9wdGlvbmFsIGJhc2VQYXRoIHBhc3NlZCBpbnRvIGEge3sjY3Jvc3NMaW5rICJMb2FkUXVldWUvbG9hZE1hbmlmZXN0In19e3svY3Jvc3NMaW5rfX0KCSAqIG9yIHt7I2Nyb3NzTGluayAiTG9hZFF1ZXVlL2xvYWRGaWxlIn19e3svY3Jvc3NMaW5rfX0gY2FsbC4gVGhpcyBwYXJhbWV0ZXIgd2lsbCBiZSByZW1vdmVkIGluIGEgZnV0dXJlIHRhZ2dlZAoJICogdmVyc2lvbi4KCSAqIEBwcml2YXRlCgkgKi8KCXAuX2FkZEl0ZW0gPSBmdW5jdGlvbiAodmFsdWUsIHBhdGgsIGJhc2VQYXRoKSB7CgkJdmFyIGl0ZW0gPSB0aGlzLl9jcmVhdGVMb2FkSXRlbSh2YWx1ZSwgcGF0aCwgYmFzZVBhdGgpOyAvLyBiYXNlUGF0aCBhbmQgbWFuaWZlc3QgcGF0aCBhcmUgYWRkZWQgdG8gdGhlIHNyYy4KCQlpZiAoaXRlbSA9PSBudWxsKSB7IHJldHVybjsgfSAvLyBTb21ldGltZXMgcGx1Z2lucyBvciB0eXBlcyBzaG91bGQgYmUgc2tpcHBlZC4KCQl2YXIgbG9hZGVyID0gdGhpcy5fY3JlYXRlTG9hZGVyKGl0ZW0pOwoJCWlmIChsb2FkZXIgIT0gbnVsbCkgewoJCQlpdGVtLl9sb2FkZXIgPSBsb2FkZXI7CgkJCXRoaXMuX2xvYWRRdWV1ZS5wdXNoKGxvYWRlcik7CgkJCXRoaXMuX2xvYWRRdWV1ZUJhY2t1cC5wdXNoKGxvYWRlcik7CgoJCQl0aGlzLl9udW1JdGVtcysrOwoJCQl0aGlzLl91cGRhdGVQcm9ncmVzcygpOwoKCQkJLy8gT25seSB3b3JyeSBhYm91dCBzY3JpcHQgb3JkZXIgd2hlbiB1c2luZyBYSFIgdG8gbG9hZCBzY3JpcHRzLiBUYWdzIGFyZSBvbmx5IGxvYWRpbmcgb25lIGF0IGEgdGltZS4KCQkJaWYgKCh0aGlzLm1haW50YWluU2NyaXB0T3JkZXIKCQkJCSAmJiBpdGVtLnR5cGUgPT0gY3JlYXRlanMuTG9hZFF1ZXVlLkpBVkFTQ1JJUFQKCQkJCQkvLyYmIGxvYWRlciBpbnN0YW5jZW9mIGNyZWF0ZWpzLlhIUkxvYWRlciAvL05PVEU6IEhhdmUgdG8gdHJhY2sgYWxsIEpTIGZpbGVzIHRoaXMgd2F5CgkJCQkpCgkJCQl8fCBpdGVtLm1haW50YWluT3JkZXIgPT09IHRydWUpIHsKCQkJCXRoaXMuX3NjcmlwdE9yZGVyLnB1c2goaXRlbSk7CgkJCQl0aGlzLl9sb2FkZWRTY3JpcHRzLnB1c2gobnVsbCk7CgkJCX0KCQl9Cgl9OwoKCS8qKgoJICogQ3JlYXRlIGEgcmVmaW5lZCB7eyNjcm9zc0xpbmsgIkxvYWRJdGVtIn19e3svY3Jvc3NMaW5rfX0sIHdoaWNoIGNvbnRhaW5zIGFsbCB0aGUgcmVxdWlyZWQgcHJvcGVydGllcy4gVGhlIHR5cGUgb2YKCSAqIGl0ZW0gaXMgZGV0ZXJtaW5lZCBieSBicm93c2VyIHN1cHBvcnQsIHJlcXVpcmVtZW50cyBiYXNlZCBvbiB0aGUgZmlsZSB0eXBlLCBhbmQgZGV2ZWxvcGVyIHNldHRpbmdzLiBGb3IgZXhhbXBsZSwKCSAqIFhIUiBpcyBvbmx5IHVzZWQgZm9yIGZpbGUgdHlwZXMgdGhhdCBzdXBwb3J0IGl0IGluIG5ldyBicm93c2Vycy4KCSAqCgkgKiBCZWZvcmUgdGhlIGl0ZW0gaXMgcmV0dXJuZWQsIGFueSBwbHVnaW5zIHJlZ2lzdGVyZWQgdG8gaGFuZGxlIHRoZSB0eXBlIG9yIGV4dGVuc2lvbiB3aWxsIGJlIGZpcmVkLCB3aGljaCBtYXkKCSAqIGFsdGVyIHRoZSBsb2FkIGl0ZW0uCgkgKiBAbWV0aG9kIF9jcmVhdGVMb2FkSXRlbQoJICogQHBhcmFtIHtTdHJpbmcgfCBPYmplY3QgfCBIVE1MQXVkaW9FbGVtZW50IHwgSFRNTEltYWdlRWxlbWVudH0gdmFsdWUgVGhlIGl0ZW0gdGhhdCBuZWVkcyB0byBiZSBwcmVsb2FkZWQuCgkgKiBAcGFyYW0ge1N0cmluZ30gW3BhdGhdIEEgcGF0aCB0byBwcmVwZW5kIHRvIHRoZSBpdGVtJ3Mgc291cmNlLiBTb3VyY2VzIGJlZ2lubmluZyB3aXRoIGh0dHA6Ly8gb3Igc2ltaWxhciB3aWxsCgkgKiBub3QgcmVjZWl2ZSBhIHBhdGguIFNpbmNlIFByZWxvYWRKUyAwLjQuMSwgdGhlIHNyYyB3aWxsIGJlIG1vZGlmaWVkIHRvIGluY2x1ZGUgdGhlIGBwYXRoYCBhbmQge3sjY3Jvc3NMaW5rICJMb2FkUXVldWUvX2Jhc2VQYXRoOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0KCSAqIHdoZW4gaXQgaXMgYWRkZWQuCgkgKiBAcGFyYW0ge1N0cmluZ30gW2Jhc2VQYXRoXSA8c3Ryb25nPkRlcHJlY3RhdGVkPC9zdHJvbmc+IEEgYmFzZSBwYXRoIHRvIHByZXBlbmQgdG8gdGhlIGl0ZW1zIHNvdXJjZSBpbiBhZGRpdGlvbiB0bwoJICogdGhlIHBhdGggYXJndW1lbnQuCgkgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBsb2FkZXIgaW5zdGFuY2UgdGhhdCB3aWxsIGJlIHVzZWQuCgkgKiBAcHJpdmF0ZQoJICovCglwLl9jcmVhdGVMb2FkSXRlbSA9IGZ1bmN0aW9uICh2YWx1ZSwgcGF0aCwgYmFzZVBhdGgpIHsKCQl2YXIgaXRlbSA9IGNyZWF0ZWpzLkxvYWRJdGVtLmNyZWF0ZSh2YWx1ZSk7CgkJaWYgKGl0ZW0gPT0gbnVsbCkgeyByZXR1cm4gbnVsbDsgfQoKCQkvLyBEZXRlcm1pbmUgRXh0ZW5zaW9uLCBldGMuCgkJdmFyIG1hdGNoID0gY3JlYXRlanMuUmVxdWVzdFV0aWxzLnBhcnNlVVJJKGl0ZW0uc3JjKTsKCQlpZiAobWF0Y2guZXh0ZW5zaW9uKSB7IGl0ZW0uZXh0ID0gbWF0Y2guZXh0ZW5zaW9uOyB9CgkJaWYgKGl0ZW0udHlwZSA9PSBudWxsKSB7CgkJCWl0ZW0udHlwZSA9IGNyZWF0ZWpzLlJlcXVlc3RVdGlscy5nZXRUeXBlQnlFeHRlbnNpb24oaXRlbS5leHQpOwoJCX0KCgkJLy8gSW5qZWN0IHBhdGggJiBiYXNlUGF0aAoJCXZhciBicCA9ICIiOyAvLyBTdG9yZSB0aGUgZ2VuZXJhdGVkIGJhc2VQYXRoCgkJdmFyIHVzZUJhc2VQYXRoID0gYmFzZVBhdGggfHwgdGhpcy5fYmFzZVBhdGg7CgkJdmFyIGF1dG9JZCA9IGl0ZW0uc3JjOwoJCWlmICghbWF0Y2guYWJzb2x1dGUgJiYgIW1hdGNoLnJlbGF0aXZlKSB7CgkJCWlmIChwYXRoKSB7CgkJCQlicCA9IHBhdGg7CgkJCQl2YXIgcGF0aE1hdGNoID0gY3JlYXRlanMuUmVxdWVzdFV0aWxzLnBhcnNlVVJJKHBhdGgpOwoJCQkJYXV0b0lkID0gcGF0aCArIGF1dG9JZDsKCQkJCS8vIEFsc28gYXBwZW5kIGJhc2VQYXRoCgkJCQlpZiAodXNlQmFzZVBhdGggIT0gbnVsbCAmJiAhcGF0aE1hdGNoLmFic29sdXRlICYmICFwYXRoTWF0Y2gucmVsYXRpdmUpIHsKCQkJCQlicCA9IHVzZUJhc2VQYXRoICsgYnA7CgkJCQl9CgkJCX0gZWxzZSBpZiAodXNlQmFzZVBhdGggIT0gbnVsbCkgewoJCQkJYnAgPSB1c2VCYXNlUGF0aDsKCQkJfQoJCX0KCQlpdGVtLnNyYyA9IGJwICsgaXRlbS5zcmM7CgkJaXRlbS5wYXRoID0gYnA7CgoJCS8vIElmIHRoZXJlJ3Mgbm8gaWQsIHNldCBvbmUgbm93LgoJCWlmIChpdGVtLmlkID09PSB1bmRlZmluZWQgfHwgaXRlbS5pZCA9PT0gbnVsbCB8fCBpdGVtLmlkID09PSAiIikgewoJCQlpdGVtLmlkID0gYXV0b0lkOwoJCX0KCgkJLy8gR2l2ZSBwbHVnaW5zIGEgY2hhbmNlIHRvIG1vZGlmeSB0aGUgbG9hZEl0ZW06CgkJdmFyIGN1c3RvbUhhbmRsZXIgPSB0aGlzLl90eXBlQ2FsbGJhY2tzW2l0ZW0udHlwZV0gfHwgdGhpcy5fZXh0ZW5zaW9uQ2FsbGJhY2tzW2l0ZW0uZXh0XTsKCQlpZiAoY3VzdG9tSGFuZGxlcikgewoJCQkvLyBQbHVnaW5zIGFyZSBub3cgcGFzc2VkIGJvdGggdGhlIGZ1bGwgc291cmNlLCBhcyB3ZWxsIGFzIGEgY29tYmluZWQgcGF0aCtiYXNlUGF0aCAoYXBwcm9wcmlhdGVseSkKCQkJdmFyIHJlc3VsdCA9IGN1c3RvbUhhbmRsZXIuY2FsbGJhY2suY2FsbChjdXN0b21IYW5kbGVyLnNjb3BlLCBpdGVtLCB0aGlzKTsKCgkJCS8vIFRoZSBwbHVnaW4gd2lsbCBoYW5kbGUgdGhlIGxvYWQsIG9yIGhhcyBjYW5jZWxlZCBpdC4gSWdub3JlIGl0LgoJCQlpZiAocmVzdWx0ID09PSBmYWxzZSkgewoJCQkJcmV0dXJuIG51bGw7CgoJCQkJLy8gTG9hZCBhcyBub3JtYWw6CgkJCX0gZWxzZSBpZiAocmVzdWx0ID09PSB0cnVlKSB7CgkJCQkvLyBEbyBOb3RoaW5nCgoJCQkvLyBSZXN1bHQgaXMgYSBsb2FkZXIgY2xhc3M6CgkJCX0gZWxzZSBpZiAocmVzdWx0ICE9IG51bGwpIHsKCQkJCWl0ZW0uX2xvYWRlciA9IHJlc3VsdDsKCQkJfQoKCQkJLy8gVXBkYXRlIHRoZSBleHRlbnNpb24gaW4gY2FzZSB0aGUgdHlwZSBjaGFuZ2VkOgoJCQltYXRjaCA9IGNyZWF0ZWpzLlJlcXVlc3RVdGlscy5wYXJzZVVSSShpdGVtLnNyYyk7CgkJCWlmIChtYXRjaC5leHRlbnNpb24gIT0gbnVsbCkgewoJCQkJaXRlbS5leHQgPSBtYXRjaC5leHRlbnNpb247CgkJCX0KCQl9CgoJCS8vIFN0b3JlIHRoZSBpdGVtIGZvciBsb29rdXAuIFRoaXMgYWxzbyBoZWxwcyBjbGVhbi11cCBsYXRlci4KCQl0aGlzLl9sb2FkSXRlbXNCeUlkW2l0ZW0uaWRdID0gaXRlbTsKCQl0aGlzLl9sb2FkSXRlbXNCeVNyY1tpdGVtLnNyY10gPSBpdGVtOwoKCQlpZiAoaXRlbS5sb2FkVGltZW91dCA9PSBudWxsKSB7CgkJCWl0ZW0ubG9hZFRpbWVvdXQgPSBzLmxvYWRUaW1lb3V0OwoJCX0KCgkJaWYgKGl0ZW0uY3Jvc3NPcmlnaW4gPT0gbnVsbCkgewoJCQlpdGVtLmNyb3NzT3JpZ2luID0gdGhpcy5fY3Jvc3NPcmlnaW47CgkJfQoKCQlyZXR1cm4gaXRlbTsKCX07CgoJLyoqCgkgKiBDcmVhdGUgYSBsb2FkZXIgZm9yIGEgbG9hZCBpdGVtLgoJICogQG1ldGhvZCBfY3JlYXRlTG9hZGVyCgkgKiBAcGFyYW0ge09iamVjdH0gaXRlbSBBIGZvcm1hdHRlZCBsb2FkIGl0ZW0gdGhhdCBjYW4gYmUgdXNlZCB0byBnZW5lcmF0ZSBhIGxvYWRlci4KCSAqIEByZXR1cm4ge0Fic3RyYWN0TG9hZGVyfSBBIGxvYWRlciB0aGF0IGNhbiBiZSB1c2VkIHRvIGxvYWQgY29udGVudC4KCSAqIEBwcml2YXRlCgkgKi8KCXAuX2NyZWF0ZUxvYWRlciA9IGZ1bmN0aW9uIChpdGVtKSB7CgkJaWYgKGl0ZW0uX2xvYWRlciAhPSBudWxsKSB7IC8vIEEgcGx1Z2luIGFscmVhZHkgc3BlY2lmaWVkIGEgbG9hZGVyCgkJCXJldHVybiBpdGVtLl9sb2FkZXI7CgkJfQoKCQkvLyBJbml0aWFsbHksIHRyeSBhbmQgdXNlIHRoZSBwcm92aWRlZC9zdXBwb3J0ZWQgWEhSIG1vZGU6CgkJdmFyIHByZWZlclhIUiA9IHRoaXMucHJlZmVyWEhSOwoKCQlmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuX2F2YWlsYWJsZUxvYWRlcnMubGVuZ3RoOyBpKyspIHsKCQkJdmFyIGxvYWRlciA9IHRoaXMuX2F2YWlsYWJsZUxvYWRlcnNbaV07CgkJCWlmIChsb2FkZXIgJiYgbG9hZGVyLmNhbkxvYWRJdGVtKGl0ZW0pKSB7CgkJCQlyZXR1cm4gbmV3IGxvYWRlcihpdGVtLCBwcmVmZXJYSFIpOwoJCQl9CgkJfQoKCQkvLyBUT0RPOiBMb2cgZXJyb3IgKHJlcXVpcmVzIGNyZWF0ZWpzLmxvZykKCQlyZXR1cm4gbnVsbDsKCX07CgoJLyoqCgkgKiBMb2FkIHRoZSBuZXh0IGl0ZW0gaW4gdGhlIHF1ZXVlLiBJZiB0aGUgcXVldWUgaXMgZW1wdHkgKGFsbCBpdGVtcyBoYXZlIGJlZW4gbG9hZGVkKSwgdGhlbiB0aGUgY29tcGxldGUgZXZlbnQKCSAqIGlzIHByb2Nlc3NlZC4gVGhlIHF1ZXVlIHdpbGwgImZpbGwgdXAiIGFueSBlbXB0eSBzbG90cywgdXAgdG8gdGhlIG1heCBjb25uZWN0aW9uIHNwZWNpZmllZCB1c2luZwoJICoge3sjY3Jvc3NMaW5rICJMb2FkUXVldWUuc2V0TWF4Q29ubmVjdGlvbnMifX17ey9jcm9zc0xpbmt9fSBtZXRob2QuIFRoZSBvbmx5IGV4Y2VwdGlvbiBpcyBzY3JpcHRzIHRoYXQgYXJlIGxvYWRlZAoJICogdXNpbmcgdGFncywgd2hpY2ggaGF2ZSB0byBiZSBsb2FkZWQgb25lIGF0IGEgdGltZSB0byBtYWludGFpbiBsb2FkIG9yZGVyLgoJICogQG1ldGhvZCBfbG9hZE5leHQKCSAqIEBwcml2YXRlCgkgKi8KCXAuX2xvYWROZXh0ID0gZnVuY3Rpb24gKCkgewoJCWlmICh0aGlzLl9wYXVzZWQpIHsgcmV0dXJuOyB9CgoJCS8vIE9ubHkgZGlzcGF0Y2ggbG9hZHN0YXJ0IGV2ZW50IHdoZW4gdGhlIGZpcnN0IGZpbGUgaXMgbG9hZGVkLgoJCWlmICghdGhpcy5fbG9hZFN0YXJ0V2FzRGlzcGF0Y2hlZCkgewoJCQl0aGlzLl9zZW5kTG9hZFN0YXJ0KCk7CgkJCXRoaXMuX2xvYWRTdGFydFdhc0Rpc3BhdGNoZWQgPSB0cnVlOwoJCX0KCgkJLy8gVGhlIHF1ZXVlIGhhcyBjb21wbGV0ZWQuCgkJaWYgKHRoaXMuX251bUl0ZW1zID09IHRoaXMuX251bUl0ZW1zTG9hZGVkKSB7CgkJCXRoaXMubG9hZGVkID0gdHJ1ZTsKCQkJdGhpcy5fc2VuZENvbXBsZXRlKCk7CgoJCQkvLyBMb2FkIHRoZSBuZXh0IHF1ZXVlLCBpZiBpdCBoYXMgYmVlbiBkZWZpbmVkLgoJCQlpZiAodGhpcy5uZXh0ICYmIHRoaXMubmV4dC5sb2FkKSB7CgkJCQl0aGlzLm5leHQubG9hZCgpOwoJCQl9CgkJfSBlbHNlIHsKCQkJdGhpcy5sb2FkZWQgPSBmYWxzZTsKCQl9CgoJCS8vIE11c3QgaXRlcmF0ZSBmb3J3YXJkcyB0byBsb2FkIGluIHRoZSByaWdodCBvcmRlci4KCQlmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuX2xvYWRRdWV1ZS5sZW5ndGg7IGkrKykgewoJCQlpZiAodGhpcy5fY3VycmVudExvYWRzLmxlbmd0aCA+PSB0aGlzLl9tYXhDb25uZWN0aW9ucykgeyBicmVhazsgfQoJCQl2YXIgbG9hZGVyID0gdGhpcy5fbG9hZFF1ZXVlW2ldOwoKCQkJLy8gRGV0ZXJtaW5lIGlmIHdlIHNob3VsZCBiZSBvbmx5IGxvYWRpbmcgb25lIHRhZy1zY3JpcHQgYXQgYSB0aW1lOgoJCQkvLyBOb3RlOiBtYWludGFpbk9yZGVyIGl0ZW1zIGRvbid0IGRvIGFueXRoaW5nIGhlcmUgYmVjYXVzZSB3ZSBjYW4gaG9sZCBvbnRvIHRoZWlyIGxvYWRlZCB2YWx1ZQoJCQlpZiAoIXRoaXMuX2NhblN0YXJ0TG9hZChsb2FkZXIpKSB7IGNvbnRpbnVlOyB9CgkJCXRoaXMuX2xvYWRRdWV1ZS5zcGxpY2UoaSwgMSk7CgkJCWktLTsKCQkJdGhpcy5fbG9hZEl0ZW0obG9hZGVyKTsKCQl9Cgl9OwoKCS8qKgoJICogQmVnaW4gbG9hZGluZyBhbiBpdGVtLiBFdmVudCBsaXN0ZW5lcnMgYXJlIG5vdCBhZGRlZCB0byB0aGUgbG9hZGVycyB1bnRpbCB0aGUgbG9hZCBzdGFydHMuCgkgKiBAbWV0aG9kIF9sb2FkSXRlbQoJICogQHBhcmFtIHtBYnN0cmFjdExvYWRlcn0gbG9hZGVyIFRoZSBsb2FkZXIgaW5zdGFuY2UgdG8gc3RhcnQuIEN1cnJlbnRseSwgdGhpcyB3aWxsIGJlIGFuIFhIUkxvYWRlciBvciBUYWdMb2FkZXIuCgkgKiBAcHJpdmF0ZQoJICovCglwLl9sb2FkSXRlbSA9IGZ1bmN0aW9uIChsb2FkZXIpIHsKCQlsb2FkZXIub24oImZpbGVsb2FkIiwgdGhpcy5faGFuZGxlRmlsZUxvYWQsIHRoaXMpOwoJCWxvYWRlci5vbigicHJvZ3Jlc3MiLCB0aGlzLl9oYW5kbGVQcm9ncmVzcywgdGhpcyk7CgkJbG9hZGVyLm9uKCJjb21wbGV0ZSIsIHRoaXMuX2hhbmRsZUZpbGVDb21wbGV0ZSwgdGhpcyk7CgkJbG9hZGVyLm9uKCJlcnJvciIsIHRoaXMuX2hhbmRsZUVycm9yLCB0aGlzKTsKCQlsb2FkZXIub24oImZpbGVlcnJvciIsIHRoaXMuX2hhbmRsZUZpbGVFcnJvciwgdGhpcyk7CgkJdGhpcy5fY3VycmVudExvYWRzLnB1c2gobG9hZGVyKTsKCQl0aGlzLl9zZW5kRmlsZVN0YXJ0KGxvYWRlci5nZXRJdGVtKCkpOwoJCWxvYWRlci5sb2FkKCk7Cgl9OwoKCS8qKgoJICogVGhlIGNhbGxiYWNrIHRoYXQgaXMgZmlyZWQgd2hlbiBhIGxvYWRlciBsb2FkcyBhIGZpbGUuIFRoaXMgZW5hYmxlcyBsb2FkZXJzIGxpa2Uge3sjY3Jvc3NMaW5rICJNYW5pZmVzdExvYWRlciJ9fXt7L2Nyb3NzTGlua319CgkgKiB0byBtYWludGFpbiBpbnRlcm5hbCBxdWV1ZXMsIGJ1dCBmb3IgdGhpcyBxdWV1ZSB0byBkaXNwYXRjaCB0aGUge3sjY3Jvc3NMaW5rICJmaWxlbG9hZDpldmVudCJ9fXt7L2Nyb3NzTGlua319CgkgKiBldmVudHMuCgkgKiBAcGFyYW0ge0V2ZW50fSBUaGUge3sjY3Jvc3NMaW5rICJBYnN0cmFjdExvYWRlci9maWxlbG9hZDpldmVudCJ9fXt7L2Nyb3NzTGlua319IGV2ZW50IGZyb20gdGhlIGxvYWRlci4KCSAqIEBwcml2YXRlCgkgKiBAc2luY2UgMC42LjAKCSAqLwoJcC5faGFuZGxlRmlsZUxvYWQgPSBmdW5jdGlvbihldmVudCkgewoJCWV2ZW50LnRhcmdldCA9IG51bGw7CgkJdGhpcy5kaXNwYXRjaEV2ZW50KGV2ZW50KTsKCX07CgoJLyoqCgkgKiBUaGUgY2FsbGJhY2sgdGhhdCBpcyBmaXJlZCB3aGVuIGEgbG9hZGVyIGVuY291bnRlcnMgYW4gZXJyb3IgZnJvbSBhbiBpbnRlcm5hbCBmaWxlIGxvYWQgb3BlcmF0aW9uLiBUaGlzIGVuYWJsZXMKCSAqIGxvYWRlcnMgbGlrZSBNCgkgKiBAcGFyYW0gZXZlbnQKCSAqIEBwcml2YXRlCgkgKi8KCXAuX2hhbmRsZUZpbGVFcnJvciA9IGZ1bmN0aW9uKGV2ZW50KSB7CgkJdmFyIG5ld0V2ZW50ID0gbmV3IGNyZWF0ZWpzLkVycm9yRXZlbnQoIkZJTEVfTE9BRF9FUlJPUiIsIG51bGwsIGV2ZW50Lml0ZW0pOwoJCXRoaXMuX3NlbmRFcnJvcihuZXdFdmVudCk7Cgl9OwoKCS8qKgoJICogVGhlIGNhbGxiYWNrIHRoYXQgaXMgZmlyZWQgd2hlbiBhIGxvYWRlciBlbmNvdW50ZXJzIGFuIGVycm9yLiBUaGUgcXVldWUgd2lsbCBjb250aW51ZSBsb2FkaW5nIHVubGVzcyB7eyNjcm9zc0xpbmsgIkxvYWRRdWV1ZS9zdG9wT25FcnJvcjpwcm9wZXJ0eSJ9fXt7L2Nyb3NzTGlua319CgkgKiBpcyBzZXQgdG8gYHRydWVgLgoJICogQG1ldGhvZCBfaGFuZGxlRXJyb3IKCSAqIEBwYXJhbSB7RXJyb3JFdmVudH0gZXZlbnQgVGhlIGVycm9yIGV2ZW50LCBjb250YWluaW5nIHJlbGV2YW50IGVycm9yIGluZm9ybWF0aW9uLgoJICogQHByaXZhdGUKCSAqLwoJcC5faGFuZGxlRXJyb3IgPSBmdW5jdGlvbiAoZXZlbnQpIHsKCQl2YXIgbG9hZGVyID0gZXZlbnQudGFyZ2V0OwoJCXRoaXMuX251bUl0ZW1zTG9hZGVkKys7CgoJCXRoaXMuX2ZpbmlzaE9yZGVyZWRJdGVtKGxvYWRlciwgdHJ1ZSk7CgkJdGhpcy5fdXBkYXRlUHJvZ3Jlc3MoKTsKCgkJdmFyIG5ld0V2ZW50ID0gbmV3IGNyZWF0ZWpzLkVycm9yRXZlbnQoIkZJTEVfTE9BRF9FUlJPUiIsIG51bGwsIGxvYWRlci5nZXRJdGVtKCkpOwoJCS8vIFRPRE86IFByb3BhZ2F0ZSBhY3R1YWwgZXJyb3IgbWVzc2FnZS4KCgkJdGhpcy5fc2VuZEVycm9yKG5ld0V2ZW50KTsKCgkJaWYgKCF0aGlzLnN0b3BPbkVycm9yKSB7CgkJCXRoaXMuX3JlbW92ZUxvYWRJdGVtKGxvYWRlcik7CgkJCXRoaXMuX2xvYWROZXh0KCk7CgkJfQoJfTsKCgkvKioKCSAqIEFuIGl0ZW0gaGFzIGZpbmlzaGVkIGxvYWRpbmcuIFdlIGNhbiBhc3N1bWUgdGhhdCBpdCBpcyB0b3RhbGx5IGxvYWRlZCwgaGFzIGJlZW4gcGFyc2VkIGZvciBpbW1lZGlhdGUgdXNlLCBhbmQKCSAqIGlzIGF2YWlsYWJsZSBhcyB0aGUgInJlc3VsdCIgcHJvcGVydHkgb24gdGhlIGxvYWQgaXRlbS4gVGhlIHJhdyB0ZXh0IHJlc3VsdCBmb3IgYSBwYXJzZWQgaXRlbSAoc3VjaCBhcyBKU09OLCBYTUwsCgkgKiBDU1MsIEphdmFTY3JpcHQsIGV0YykgaXMgYXZhaWxhYmxlIGFzIHRoZSAicmF3UmVzdWx0IiBwcm9wZXJ0eSwgYW5kIGNhbiBhbHNvIGJlIGxvb2tlZCB1cCB1c2luZyB7eyNjcm9zc0xpbmsgIkxvYWRRdWV1ZS9nZXRSZXN1bHQifX17ey9jcm9zc0xpbmt9fS4KCSAqIEBtZXRob2QgX2hhbmRsZUZpbGVDb21wbGV0ZQoJICogQHBhcmFtIHtFdmVudH0gZXZlbnQgVGhlIGV2ZW50IG9iamVjdCBmcm9tIHRoZSBsb2FkZXIuCgkgKiBAcHJpdmF0ZQoJICovCglwLl9oYW5kbGVGaWxlQ29tcGxldGUgPSBmdW5jdGlvbiAoZXZlbnQpIHsKCQl2YXIgbG9hZGVyID0gZXZlbnQudGFyZ2V0OwoJCXZhciBpdGVtID0gbG9hZGVyLmdldEl0ZW0oKTsKCgkJdmFyIHJlc3VsdCA9IGxvYWRlci5nZXRSZXN1bHQoKTsKCQl0aGlzLl9sb2FkZWRSZXN1bHRzW2l0ZW0uaWRdID0gcmVzdWx0OwoJCXZhciByYXdSZXN1bHQgPSBsb2FkZXIuZ2V0UmVzdWx0KHRydWUpOwoJCWlmIChyYXdSZXN1bHQgIT0gbnVsbCAmJiByYXdSZXN1bHQgIT09IHJlc3VsdCkgewoJCQl0aGlzLl9sb2FkZWRSYXdSZXN1bHRzW2l0ZW0uaWRdID0gcmF3UmVzdWx0OwoJCX0KCgkJdGhpcy5fc2F2ZUxvYWRlZEl0ZW1zKGxvYWRlcik7CgoJCS8vIENsZWFuIHVwIHRoZSBsb2FkIGl0ZW0KCQl0aGlzLl9yZW1vdmVMb2FkSXRlbShsb2FkZXIpOwoKCQlpZiAoIXRoaXMuX2ZpbmlzaE9yZGVyZWRJdGVtKGxvYWRlcikpIHsKCQkJLy8gVGhlIGl0ZW0gd2FzIE5PVCBtYW5hZ2VkLCBzbyBwcm9jZXNzIGl0IG5vdwoJCQl0aGlzLl9wcm9jZXNzRmluaXNoZWRMb2FkKGl0ZW0sIGxvYWRlcik7CgkJfQoJfTsKCgkvKioKCSAqIFNvbWUgbG9hZGVycyBtaWdodCBsb2FkIGFkZGl0aW9uYWwgY29udGVudCwgb3RoZXIgdGhhbiB0aGUgaXRlbSB0aGV5IHdlcmUgcGFzc2VkIChzdWNoIGFzIHt7I2Nyb3NzTGluayAiTWFuaWZlc3RMb2FkZXIifX17ey9jcm9zc0xpbmt9fSkuCgkgKiBBbnkgaXRlbXMgZXhwb3NlZCBieSB0aGUgbG9hZGVyIHVzaW5nIHt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvZ2V0TG9hZEl0ZW1zIn19e3svY3Jvc3NMaW5rfX0gYXJlIGFkZGVkIHRvIHRoZQoJICogTG9hZFF1ZXVlJ3MgbG9vay11cHMsIGluY2x1ZGluZyB7eyNjcm9zc0xpbmsgImdldEl0ZW0ifX17ey9jcm9zc0xpbmt9fSBhbmQge3sjY3Jvc3NMaW5rICJnZXRSZXN1bHQifX17ey9jcm9zc0xpbmt9fQoJICogbWV0aG9kcy4KCSAqIEBtZXRob2QgX3NhdmVMb2FkZWRJdGVtcwoJICogQHBhcmFtIHtBYnN0cmFjdExvYWRlcn0gbG9hZGVyCgkgKiBAcHJvdGVjdGVkCgkgKiBAc2luY2UgMC42LjAKCSAqLwoJcC5fc2F2ZUxvYWRlZEl0ZW1zID0gZnVuY3Rpb24obG9hZGVyKSB7CgkJLy8gVE9ETzogTm90IHN1cmUgaG93IHRvIGhhbmRsZSB0aGlzLiBXb3VsZCBiZSBuaWNlIHRvIGV4cG9zZSB0aGUgaXRlbXMuCgkJLy8gTG9hZGVycyBtYXkgbG9hZCBzdWItaXRlbXMuIFRoaXMgYWRkcyB0aGVtIHRvIHRoaXMgcXVldWUKCQl2YXIgbGlzdCA9IGxvYWRlci5nZXRMb2FkZWRJdGVtcygpOwoJCWlmIChsaXN0ID09PSBudWxsKSB7IHJldHVybjsgfQoKCQlmb3IgKHZhciBpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHsKCQkJdmFyIGl0ZW0gPSBsaXN0W2ldLml0ZW07CgoJCQkvLyBTdG9yZSBpdGVtIGxvb2t1cHMKCQkJdGhpcy5fbG9hZEl0ZW1zQnlTcmNbaXRlbS5zcmNdID0gaXRlbTsKCQkJdGhpcy5fbG9hZEl0ZW1zQnlJZFtpdGVtLmlkXSA9IGl0ZW07CgoJCQkvLyBTdG9yZSBsb2FkZWQgY29udGVudAoJCQl0aGlzLl9sb2FkZWRSZXN1bHRzW2l0ZW0uaWRdID0gbGlzdFtpXS5yZXN1bHQ7CgkJCXRoaXMuX2xvYWRlZFJhd1Jlc3VsdHNbaXRlbS5pZF0gPSBsaXN0W2ldLnJhd1Jlc3VsdDsKCQl9Cgl9CgoJLyoqCgkgKiBGbGFnIGFuIGl0ZW0gYXMgZmluaXNoZWQuIElmIHRoZSBpdGVtJ3Mgb3JkZXIgaXMgYmVpbmcgbWFuYWdlZCwgdGhlbiBlbnN1cmUgdGhhdCBpdCBpcyBhbGxvd2VkIHRvIGZpbmlzaCwgYW5kIGlmCgkgKiBzbywgdHJpZ2dlciBwcmlvciBpdGVtcyB0byB0cmlnZ2VyIGFzIHdlbGwuCgkgKiBAbWV0aG9kIF9maW5pc2hPcmRlcmVkSXRlbQoJICogQHBhcmFtIHtBYnN0cmFjdExvYWRlcn0gbG9hZGVyCgkgKiBAcmV0dXJuIHtCb29sZWFufSBJZiB0aGUgaXRlbSdzIG9yZGVyIGlzIGJlaW5nIG1hbmFnZWQuIFRoaXMgYWxsb3dzIHRoZSBjYWxsZXIgdG8gdGFrZSBhbiBhbHRlcm5hdGUKCSAqIGJlaGF2aW91ciBpZiBpdCBpcy4KCSAqIEBwcml2YXRlCgkgKi8KCXAuX2ZpbmlzaE9yZGVyZWRJdGVtID0gZnVuY3Rpb24gKGxvYWRlciwgbG9hZEZhaWxlZCkgewoJCXZhciBpdGVtID0gbG9hZGVyLmdldEl0ZW0oKTsKCgkJaWYgKCh0aGlzLm1haW50YWluU2NyaXB0T3JkZXIgJiYgaXRlbS50eXBlID09IGNyZWF0ZWpzLkxvYWRRdWV1ZS5KQVZBU0NSSVBUKQoJCQl8fCBpdGVtLm1haW50YWluT3JkZXIpIHsKCgkJCS8vVE9ETzogRXZhbHVhdGUgcmVtb3ZhbCBvZiB0aGUgX2N1cnJlbnRseUxvYWRpbmdTY3JpcHQKCQkJaWYgKGxvYWRlciBpbnN0YW5jZW9mIGNyZWF0ZWpzLkphdmFTY3JpcHRMb2FkZXIpIHsKCQkJCXRoaXMuX2N1cnJlbnRseUxvYWRpbmdTY3JpcHQgPSBmYWxzZTsKCQkJfQoKCQkJdmFyIGluZGV4ID0gY3JlYXRlanMuaW5kZXhPZih0aGlzLl9zY3JpcHRPcmRlciwgaXRlbSk7CgkJCWlmIChpbmRleCA9PSAtMSkgeyByZXR1cm4gZmFsc2U7IH0gLy8gVGhpcyBsb2FkZXIgbm8gbG9uZ2VyIGV4aXN0cwoJCQl0aGlzLl9sb2FkZWRTY3JpcHRzW2luZGV4XSA9IChsb2FkRmFpbGVkID09PSB0cnVlKSA/IHRydWUgOiBpdGVtOwoKCQkJdGhpcy5fY2hlY2tTY3JpcHRMb2FkT3JkZXIoKTsKCQkJcmV0dXJuIHRydWU7CgkJfQoKCQlyZXR1cm4gZmFsc2U7Cgl9OwoKCS8qKgoJICogRW5zdXJlIHRoZSBzY3JpcHRzIGxvYWQgYW5kIGRpc3BhdGNoIGluIHRoZSBjb3JyZWN0IG9yZGVyLiBXaGVuIHVzaW5nIFhIUiwgc2NyaXB0cyBhcmUgc3RvcmVkIGluIGFuIGFycmF5IGluIHRoZQoJICogb3JkZXIgdGhleSB3ZXJlIGFkZGVkLCBidXQgd2l0aCBhICJudWxsIiB2YWx1ZS4gV2hlbiB0aGV5IGFyZSBjb21wbGV0ZWQsIHRoZSB2YWx1ZSBpcyBzZXQgdG8gdGhlIGxvYWQgaXRlbSwKCSAqIGFuZCB0aGVuIHdoZW4gdGhleSBhcmUgcHJvY2Vzc2VkIGFuZCBkaXNwYXRjaGVkLCB0aGUgdmFsdWUgaXMgc2V0IHRvIGB0cnVlYC4gVGhpcyBtZXRob2Qgc2ltcGx5CgkgKiBpdGVyYXRlcyB0aGUgYXJyYXksIGFuZCBlbnN1cmVzIHRoYXQgYW55IGxvYWRlZCBpdGVtcyB0aGF0IGFyZSBub3QgcHJlY2VkZWQgYnkgYSBgbnVsbGAgdmFsdWUgYXJlCgkgKiBkaXNwYXRjaGVkLgoJICogQG1ldGhvZCBfY2hlY2tTY3JpcHRMb2FkT3JkZXIKCSAqIEBwcml2YXRlCgkgKi8KCXAuX2NoZWNrU2NyaXB0TG9hZE9yZGVyID0gZnVuY3Rpb24gKCkgewoJCXZhciBsID0gdGhpcy5fbG9hZGVkU2NyaXB0cy5sZW5ndGg7CgoJCWZvciAodmFyIGkgPSAwOyBpIDwgbDsgaSsrKSB7CgkJCXZhciBpdGVtID0gdGhpcy5fbG9hZGVkU2NyaXB0c1tpXTsKCQkJaWYgKGl0ZW0gPT09IG51bGwpIHsgYnJlYWs7IH0gLy8gVGhpcyBpcyBzdGlsbCBsb2FkaW5nLiBEbyBub3QgcHJvY2VzcyBmdXJ0aGVyLgoJCQlpZiAoaXRlbSA9PT0gdHJ1ZSkgeyBjb250aW51ZTsgfSAvLyBUaGlzIGhhcyBjb21wbGV0ZWQsIGFuZCBiZWVuIHByb2Nlc3NlZC4gTW92ZSBvbi4KCgkJCXZhciBsb2FkSXRlbSA9IHRoaXMuX2xvYWRlZFJlc3VsdHNbaXRlbS5pZF07CgkJCWlmIChpdGVtLnR5cGUgPT0gY3JlYXRlanMuTG9hZFF1ZXVlLkpBVkFTQ1JJUFQpIHsKCQkJCS8vIEFwcGVuZCBzY3JpcHQgdGFncyB0byB0aGUgaGVhZCBhdXRvbWF0aWNhbGx5LiBUYWdzIGRvIHRoaXMgaW4gdGhlIGxvYWRlciwgYnV0IFhIUiBzY3JpcHRzIGhhdmUgdG8gbWFpbnRhaW4gb3JkZXIuCgkJCQkoZG9jdW1lbnQuYm9keSB8fCBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYm9keSIpWzBdKS5hcHBlbmRDaGlsZChsb2FkSXRlbSk7CgkJCX0KCgkJCXZhciBsb2FkZXIgPSBpdGVtLl9sb2FkZXI7CgkJCXRoaXMuX3Byb2Nlc3NGaW5pc2hlZExvYWQoaXRlbSwgbG9hZGVyKTsKCQkJdGhpcy5fbG9hZGVkU2NyaXB0c1tpXSA9IHRydWU7CgkJfQoJfTsKCgkvKioKCSAqIEEgZmlsZSBoYXMgY29tcGxldGVkIGxvYWRpbmcsIGFuZCB0aGUgTG9hZFF1ZXVlIGNhbiBtb3ZlIG9uLiBUaGlzIHRyaWdnZXJzIHRoZSBjb21wbGV0ZSBldmVudCwgYW5kIGtpY2stc3RhcnRzCgkgKiB0aGUgbmV4dCBpdGVtLgoJICogQG1ldGhvZCBfcHJvY2Vzc0ZpbmlzaGVkTG9hZAoJICogQHBhcmFtIHtMb2FkSXRlbXxPYmplY3R9IGl0ZW0KCSAqIEBwYXJhbSB7QWJzdHJhY3RMb2FkZXJ9IGxvYWRlcgoJICogQHByb3RlY3RlZAoJICovCglwLl9wcm9jZXNzRmluaXNoZWRMb2FkID0gZnVuY3Rpb24gKGl0ZW0sIGxvYWRlcikgewoJCXRoaXMuX251bUl0ZW1zTG9hZGVkKys7CgkJdGhpcy5fdXBkYXRlUHJvZ3Jlc3MoKTsKCQl0aGlzLl9zZW5kRmlsZUNvbXBsZXRlKGl0ZW0sIGxvYWRlcik7CgkJdGhpcy5fbG9hZE5leHQoKTsKCX07CgoJLyoqCgkgKiBFbnN1cmUgaXRlbXMgd2l0aCBgbWFpbnRhaW5PcmRlcj10cnVlYCB0aGF0IGFyZSBiZWZvcmUgdGhlIHNwZWNpZmllZCBpdGVtIGhhdmUgbG9hZGVkLiBUaGlzIG9ubHkgYXBwbGllcyB0bwoJICogSmF2YVNjcmlwdCBpdGVtcyB0aGF0IGFyZSBiZWluZyBsb2FkZWQgd2l0aCBhIFRhZ0xvYWRlciwgc2luY2UgdGhleSBoYXZlIHRvIGJlIGxvYWRlZCBhbmQgY29tcGxldGVkIDxzdHJvbmc+YmVmb3JlPC9zdHJvbmc+CgkgKiB0aGUgc2NyaXB0IGNhbiBldmVuIGJlIHN0YXJ0ZWQsIHNpbmNlIGl0IGV4aXN0IGluIHRoZSBET00gd2hpbGUgbG9hZGluZy4KCSAqIEBtZXRob2QgX2NhblN0YXJ0TG9hZAoJICogQHBhcmFtIHtBYnN0cmFjdExvYWRlcn0gbG9hZGVyIFRoZSBsb2FkZXIgZm9yIHRoZSBpdGVtCgkgKiBAcmV0dXJuIHtCb29sZWFufSBXaGV0aGVyIHRoZSBpdGVtIGNhbiBzdGFydCBhIGxvYWQgb3Igbm90LgoJICogQHByaXZhdGUKCSAqLwoJcC5fY2FuU3RhcnRMb2FkID0gZnVuY3Rpb24gKGxvYWRlcikgewoJCWlmICghdGhpcy5tYWludGFpblNjcmlwdE9yZGVyIHx8IGxvYWRlci5wcmVmZXJYSFIpIHsgcmV0dXJuIHRydWU7IH0KCQl2YXIgaXRlbSA9IGxvYWRlci5nZXRJdGVtKCk7CgkJaWYgKGl0ZW0udHlwZSAhPSBjcmVhdGVqcy5Mb2FkUXVldWUuSkFWQVNDUklQVCkgeyByZXR1cm4gdHJ1ZTsgfQoJCWlmICh0aGlzLl9jdXJyZW50bHlMb2FkaW5nU2NyaXB0KSB7IHJldHVybiBmYWxzZTsgfQoKCQl2YXIgaW5kZXggPSB0aGlzLl9zY3JpcHRPcmRlci5pbmRleE9mKGl0ZW0pOwoJCXZhciBpID0gMDsKCQl3aGlsZSAoaSA8IGluZGV4KSB7CgkJCXZhciBjaGVja0l0ZW0gPSB0aGlzLl9sb2FkZWRTY3JpcHRzW2ldOwoJCQlpZiAoY2hlY2tJdGVtID09IG51bGwpIHsgcmV0dXJuIGZhbHNlOyB9CgkJCWkrKzsKCQl9CgkJdGhpcy5fY3VycmVudGx5TG9hZGluZ1NjcmlwdCA9IHRydWU7CgkJcmV0dXJuIHRydWU7Cgl9OwoKCS8qKgoJICogQSBsb2FkIGl0ZW0gaXMgY29tcGxldGVkIG9yIHdhcyBjYW5jZWxlZCwgYW5kIG5lZWRzIHRvIGJlIHJlbW92ZWQgZnJvbSB0aGUgTG9hZFF1ZXVlLgoJICogQG1ldGhvZCBfcmVtb3ZlTG9hZEl0ZW0KCSAqIEBwYXJhbSB7QWJzdHJhY3RMb2FkZXJ9IGxvYWRlciBBIGxvYWRlciBpbnN0YW5jZSB0byByZW1vdmUuCgkgKiBAcHJpdmF0ZQoJICovCglwLl9yZW1vdmVMb2FkSXRlbSA9IGZ1bmN0aW9uIChsb2FkZXIpIHsKCQl2YXIgaXRlbSA9IGxvYWRlci5nZXRJdGVtKCk7CgkJZGVsZXRlIGl0ZW0uX2xvYWRlcjsKCgkJdmFyIGwgPSB0aGlzLl9jdXJyZW50TG9hZHMubGVuZ3RoOwoJCWZvciAodmFyIGkgPSAwOyBpIDwgbDsgaSsrKSB7CgkJCWlmICh0aGlzLl9jdXJyZW50TG9hZHNbaV0gPT0gbG9hZGVyKSB7CgkJCQl0aGlzLl9jdXJyZW50TG9hZHMuc3BsaWNlKGksIDEpOwoJCQkJYnJlYWs7CgkJCX0KCQl9Cgl9OwoKCS8qKgoJICogQW4gaXRlbSBoYXMgZGlzcGF0Y2hlZCBwcm9ncmVzcy4gUHJvcGFnYXRlIHRoYXQgcHJvZ3Jlc3MsIGFuZCB1cGRhdGUgdGhlIExvYWRRdWV1ZSdzIG92ZXJhbGwgcHJvZ3Jlc3MuCgkgKiBAbWV0aG9kIF9oYW5kbGVQcm9ncmVzcwoJICogQHBhcmFtIHtQcm9ncmVzc0V2ZW50fSBldmVudCBUaGUgcHJvZ3Jlc3MgZXZlbnQgZnJvbSB0aGUgaXRlbS4KCSAqIEBwcml2YXRlCgkgKi8KCXAuX2hhbmRsZVByb2dyZXNzID0gZnVuY3Rpb24gKGV2ZW50KSB7CgkJdmFyIGxvYWRlciA9IGV2ZW50LnRhcmdldDsKCQl0aGlzLl9zZW5kRmlsZVByb2dyZXNzKGxvYWRlci5nZXRJdGVtKCksIGxvYWRlci5wcm9ncmVzcyk7CgkJdGhpcy5fdXBkYXRlUHJvZ3Jlc3MoKTsKCX07CgoJLyoqCgkgKiBPdmVyYWxsIHByb2dyZXNzIGhhcyBjaGFuZ2VkLCBzbyBkZXRlcm1pbmUgdGhlIG5ldyBwcm9ncmVzcyBhbW91bnQgYW5kIGRpc3BhdGNoIGl0LiBUaGlzIGNoYW5nZXMgYW55IHRpbWUgYW4KCSAqIGl0ZW0gZGlzcGF0Y2hlcyBwcm9ncmVzcyBvciBjb21wbGV0ZXMuIE5vdGUgdGhhdCBzaW5jZSB3ZSBkb24ndCBhbHdheXMga25vdyB0aGUgYWN0dWFsIGZpbGVzaXplIG9mIGl0ZW1zIGJlZm9yZQoJICogdGhleSBhcmUgbG9hZGVkLiBJbiB0aGlzIGNhc2UsIHdlIGRlZmluZSBhICJzbG90IiBmb3IgZWFjaCBpdGVtICgxIGl0ZW0gaW4gMTAgd291bGQgZ2V0IDEwJSksIGFuZCB0aGVuIGFwcGVuZAoJICogbG9hZGVkIHByb2dyZXNzIG9uIHRvcCBvZiB0aGUgYWxyZWFkeS1sb2FkZWQgaXRlbXMuCgkgKgoJICogRm9yIGV4YW1wbGUsIGlmIDUvMTAgaXRlbXMgaGF2ZSBsb2FkZWQsIGFuZCBpdGVtIDYgaXMgMjAlIGxvYWRlZCwgdGhlIHRvdGFsIHByb2dyZXNzIHdvdWxkIGJlOgoJICogPHVsPgoJICogICAgICA8bGk+NS8xMCBvZiB0aGUgaXRlbXMgaW4gdGhlIHF1ZXVlICg1MCUpPC9saT4KCSAqICAgICAgPGxpPnBsdXMgMjAlIG9mIGl0ZW0gNidzIHNsb3QgKDIlKTwvbGk+CgkgKiAgICAgIDxsaT5lcXVhbHMgNTIlPC9saT4KCSAqIDwvdWw+CgkgKiBAbWV0aG9kIF91cGRhdGVQcm9ncmVzcwoJICogQHByaXZhdGUKCSAqLwoJcC5fdXBkYXRlUHJvZ3Jlc3MgPSBmdW5jdGlvbiAoKSB7CgkJdmFyIGxvYWRlZCA9IHRoaXMuX251bUl0ZW1zTG9hZGVkIC8gdGhpcy5fbnVtSXRlbXM7IC8vIEZ1bGx5IExvYWRlZCBQcm9ncmVzcwoJCXZhciByZW1haW5pbmcgPSB0aGlzLl9udW1JdGVtcyAtIHRoaXMuX251bUl0ZW1zTG9hZGVkOwoJCWlmIChyZW1haW5pbmcgPiAwKSB7CgkJCXZhciBjaHVuayA9IDA7CgkJCWZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5fY3VycmVudExvYWRzLmxlbmd0aDsgaSA8IGw7IGkrKykgewoJCQkJY2h1bmsgKz0gdGhpcy5fY3VycmVudExvYWRzW2ldLnByb2dyZXNzOwoJCQl9CgkJCWxvYWRlZCArPSAoY2h1bmsgLyByZW1haW5pbmcpICogKHJlbWFpbmluZyAvIHRoaXMuX251bUl0ZW1zKTsKCQl9CgoJCWlmICh0aGlzLl9sYXN0UHJvZ3Jlc3MgIT0gbG9hZGVkKSB7CgkJCXRoaXMuX3NlbmRQcm9ncmVzcyhsb2FkZWQpOwoJCQl0aGlzLl9sYXN0UHJvZ3Jlc3MgPSBsb2FkZWQ7CgkJfQoJfTsKCgkvKioKCSAqIENsZWFuIG91dCBpdGVtIHJlc3VsdHMsIHRvIGZyZWUgdGhlbSBmcm9tIG1lbW9yeS4gTWFpbmx5LCB0aGUgbG9hZGVkIGl0ZW0gYW5kIHJlc3VsdHMgYXJlIGNsZWFyZWQgZnJvbSBpbnRlcm5hbAoJICogaGFzaGVzLgoJICogQG1ldGhvZCBfZGlzcG9zZUl0ZW0KCSAqIEBwYXJhbSB7TG9hZEl0ZW18T2JqZWN0fSBpdGVtIFRoZSBpdGVtIHRoYXQgd2FzIHBhc3NlZCBpbiBmb3IgcHJlbG9hZGluZy4KCSAqIEBwcml2YXRlCgkgKi8KCXAuX2Rpc3Bvc2VJdGVtID0gZnVuY3Rpb24gKGl0ZW0pIHsKCQlkZWxldGUgdGhpcy5fbG9hZGVkUmVzdWx0c1tpdGVtLmlkXTsKCQlkZWxldGUgdGhpcy5fbG9hZGVkUmF3UmVzdWx0c1tpdGVtLmlkXTsKCQlkZWxldGUgdGhpcy5fbG9hZEl0ZW1zQnlJZFtpdGVtLmlkXTsKCQlkZWxldGUgdGhpcy5fbG9hZEl0ZW1zQnlTcmNbaXRlbS5zcmNdOwoJfTsKCgkvKioKCSAqIERpc3BhdGNoIGEgImZpbGVwcm9ncmVzcyIge3sjY3Jvc3NMaW5rICJFdmVudCJ9fXt7L2Nyb3NzTGlua319LiBQbGVhc2Ugc2VlIHRoZSBMb2FkUXVldWUge3sjY3Jvc3NMaW5rICJMb2FkUXVldWUvZmlsZXByb2dyZXNzOmV2ZW50In19e3svY3Jvc3NMaW5rfX0KCSAqIGV2ZW50IGZvciBkZXRhaWxzIG9uIHRoZSBldmVudCBwYXlsb2FkLgoJICogQG1ldGhvZCBfc2VuZEZpbGVQcm9ncmVzcwoJICogQHBhcmFtIHtMb2FkSXRlbXxPYmplY3R9IGl0ZW0gVGhlIGl0ZW0gdGhhdCBpcyBiZWluZyBsb2FkZWQuCgkgKiBAcGFyYW0ge051bWJlcn0gcHJvZ3Jlc3MgVGhlIGFtb3VudCB0aGUgaXRlbSBoYXMgYmVlbiBsb2FkZWQgKGJldHdlZW4gMCBhbmQgMSkuCgkgKiBAcHJvdGVjdGVkCgkgKi8KCXAuX3NlbmRGaWxlUHJvZ3Jlc3MgPSBmdW5jdGlvbiAoaXRlbSwgcHJvZ3Jlc3MpIHsKCQlpZiAodGhpcy5faXNDYW5jZWxlZCgpKSB7CgkJCXRoaXMuX2NsZWFuVXAoKTsKCQkJcmV0dXJuOwoJCX0KCQlpZiAoIXRoaXMuaGFzRXZlbnRMaXN0ZW5lcigiZmlsZXByb2dyZXNzIikpIHsgcmV0dXJuOyB9CgoJCS8vTE06IFJld29yayBQcm9ncmVzc0V2ZW50IHRvIHN1cHBvcnQgdGhpcz8KCQl2YXIgZXZlbnQgPSBuZXcgY3JlYXRlanMuRXZlbnQoImZpbGVwcm9ncmVzcyIpOwoJCWV2ZW50LnByb2dyZXNzID0gcHJvZ3Jlc3M7CgkJZXZlbnQubG9hZGVkID0gcHJvZ3Jlc3M7CgkJZXZlbnQudG90YWwgPSAxOwoJCWV2ZW50Lml0ZW0gPSBpdGVtOwoKCQl0aGlzLmRpc3BhdGNoRXZlbnQoZXZlbnQpOwoJfTsKCgkvKioKCSAqIERpc3BhdGNoIGEgZmlsZWxvYWQge3sjY3Jvc3NMaW5rICJFdmVudCJ9fXt7L2Nyb3NzTGlua319LiBQbGVhc2Ugc2VlIHRoZSB7eyNjcm9zc0xpbmsgIkxvYWRRdWV1ZS9maWxlbG9hZDpldmVudCJ9fXt7L2Nyb3NzTGlua319IGV2ZW50IGZvcgoJICogZGV0YWlscyBvbiB0aGUgZXZlbnQgcGF5bG9hZC4KCSAqIEBtZXRob2QgX3NlbmRGaWxlQ29tcGxldGUKCSAqIEBwYXJhbSB7TG9hZEl0ZW1PYmplY3R9IGl0ZW0gVGhlIGl0ZW0gdGhhdCBpcyBiZWluZyBsb2FkZWQuCgkgKiBAcGFyYW0ge0Fic3RyYWN0TG9hZGVyfSBsb2FkZXIKCSAqIEBwcm90ZWN0ZWQKCSAqLwoJcC5fc2VuZEZpbGVDb21wbGV0ZSA9IGZ1bmN0aW9uIChpdGVtLCBsb2FkZXIpIHsKCQlpZiAodGhpcy5faXNDYW5jZWxlZCgpKSB7IHJldHVybjsgfQoKCQl2YXIgZXZlbnQgPSBuZXcgY3JlYXRlanMuRXZlbnQoImZpbGVsb2FkIik7CgkJZXZlbnQubG9hZGVyID0gbG9hZGVyOwoJCWV2ZW50Lml0ZW0gPSBpdGVtOwoJCWV2ZW50LnJlc3VsdCA9IHRoaXMuX2xvYWRlZFJlc3VsdHNbaXRlbS5pZF07CgkJZXZlbnQucmF3UmVzdWx0ID0gdGhpcy5fbG9hZGVkUmF3UmVzdWx0c1tpdGVtLmlkXTsKCgkJLy8gVGhpcyBjYWxscyBhIGhhbmRsZXIgc3BlY2lmaWVkIG9uIHRoZSBhY3R1YWwgbG9hZCBpdGVtLiBDdXJyZW50bHksIHRoZSBTb3VuZEpTIHBsdWdpbiB1c2VzIHRoaXMuCgkJaWYgKGl0ZW0uY29tcGxldGVIYW5kbGVyKSB7CgkJCWl0ZW0uY29tcGxldGVIYW5kbGVyKGV2ZW50KTsKCQl9CgoJCXRoaXMuaGFzRXZlbnRMaXN0ZW5lcigiZmlsZWxvYWQiKSAmJiB0aGlzLmRpc3BhdGNoRXZlbnQoZXZlbnQpOwoJfTsKCgkvKioKCSAqIERpc3BhdGNoIGEgZmlsZXN0YXJ0IHt7I2Nyb3NzTGluayAiRXZlbnQifX17ey9jcm9zc0xpbmt9fSBpbW1lZGlhdGVseSBiZWZvcmUgYSBmaWxlIHN0YXJ0cyB0byBsb2FkLiBQbGVhc2Ugc2VlCgkgKiB0aGUge3sjY3Jvc3NMaW5rICJMb2FkUXVldWUvZmlsZXN0YXJ0OmV2ZW50In19e3svY3Jvc3NMaW5rfX0gZXZlbnQgZm9yIGRldGFpbHMgb24gdGhlIGV2ZW50IHBheWxvYWQuCgkgKiBAbWV0aG9kIF9zZW5kRmlsZVN0YXJ0CgkgKiBAcGFyYW0ge0xvYWRJdGVtfE9iamVjdH0gaXRlbSBUaGUgaXRlbSB0aGF0IGlzIGJlaW5nIGxvYWRlZC4KCSAqIEBwcm90ZWN0ZWQKCSAqLwoJcC5fc2VuZEZpbGVTdGFydCA9IGZ1bmN0aW9uIChpdGVtKSB7CgkJdmFyIGV2ZW50ID0gbmV3IGNyZWF0ZWpzLkV2ZW50KCJmaWxlc3RhcnQiKTsKCQlldmVudC5pdGVtID0gaXRlbTsKCQl0aGlzLmhhc0V2ZW50TGlzdGVuZXIoImZpbGVzdGFydCIpICYmIHRoaXMuZGlzcGF0Y2hFdmVudChldmVudCk7Cgl9OwoKCXAudG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7CgkJcmV0dXJuICJbUHJlbG9hZEpTIExvYWRRdWV1ZV0iOwoJfTsKCgljcmVhdGVqcy5Mb2FkUXVldWUgPSBjcmVhdGVqcy5wcm9tb3RlKExvYWRRdWV1ZSwgIkFic3RyYWN0TG9hZGVyIik7Cn0oKSk7CgovLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwovLyBUZXh0TG9hZGVyLmpzCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgp0aGlzLmNyZWF0ZWpzID0gdGhpcy5jcmVhdGVqcyB8fCB7fTsKCihmdW5jdGlvbiAoKSB7CgkidXNlIHN0cmljdCI7CgoJLy8gY29uc3RydWN0b3IKCS8qKgoJICogQSBsb2FkZXIgZm9yIFRleHQgZmlsZXMuCgkgKiBAY2xhc3MgVGV4dExvYWRlcgoJICogQHBhcmFtIHtMb2FkSXRlbXxPYmplY3R9IGxvYWRJdGVtCgkgKiBAY29uc3RydWN0b3IKCSAqLwoJZnVuY3Rpb24gVGV4dExvYWRlcihsb2FkSXRlbSkgewoJCXRoaXMuQWJzdHJhY3RMb2FkZXJfY29uc3RydWN0b3IobG9hZEl0ZW0sIHRydWUsIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLlRFWFQpOwoJfTsKCgl2YXIgcCA9IGNyZWF0ZWpzLmV4dGVuZChUZXh0TG9hZGVyLCBjcmVhdGVqcy5BYnN0cmFjdExvYWRlcik7Cgl2YXIgcyA9IFRleHRMb2FkZXI7CgoJLy8gc3RhdGljIG1ldGhvZHMKCS8qKgoJICogRGV0ZXJtaW5lcyBpZiB0aGUgbG9hZGVyIGNhbiBsb2FkIGEgc3BlY2lmaWMgaXRlbS4gVGhpcyBsb2FkZXIgbG9hZHMgaXRlbXMgdGhhdCBhcmUgb2YgdHlwZSB7eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyL1RFWFQ6cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fSwKCSAqIGJ1dCBpcyBhbHNvIHRoZSBkZWZhdWx0IGxvYWRlciBpZiBhIGZpbGUgdHlwZSBjYW4gbm90IGJlIGRldGVybWluZWQuCgkgKiBAbWV0aG9kIGNhbkxvYWRJdGVtCgkgKiBAcGFyYW0ge0xvYWRJdGVtfE9iamVjdH0gaXRlbSBUaGUgTG9hZEl0ZW0gdGhhdCBhIExvYWRRdWV1ZSBpcyB0cnlpbmcgdG8gbG9hZC4KCSAqIEByZXR1cm5zIHtCb29sZWFufSBXaGV0aGVyIHRoZSBsb2FkZXIgY2FuIGxvYWQgdGhlIGl0ZW0uCgkgKiBAc3RhdGljCgkgKi8KCXMuY2FuTG9hZEl0ZW0gPSBmdW5jdGlvbiAoaXRlbSkgewoJCXJldHVybiBpdGVtLnR5cGUgPT0gY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuVEVYVDsKCX07CgoJY3JlYXRlanMuVGV4dExvYWRlciA9IGNyZWF0ZWpzLnByb21vdGUoVGV4dExvYWRlciwgIkFic3RyYWN0TG9hZGVyIik7Cgp9KCkpOwoKLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLy8gQmluYXJ5TG9hZGVyLmpzCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgp0aGlzLmNyZWF0ZWpzID0gdGhpcy5jcmVhdGVqcyB8fCB7fTsKCihmdW5jdGlvbiAoKSB7CgkidXNlIHN0cmljdCI7CgoJLy8gY29uc3RydWN0b3IKCS8qKgoJICogQSBsb2FkZXIgZm9yIGJpbmFyeSBmaWxlcy4gVGhpcyBpcyB1c2VmdWwgZm9yIGxvYWRpbmcgd2ViIGF1ZGlvLCBvciBjb250ZW50IHRoYXQgcmVxdWlyZXMgYW4gQXJyYXlCdWZmZXIuCgkgKiBAY2xhc3MgQmluYXJ5TG9hZGVyCgkgKiBAcGFyYW0ge0xvYWRJdGVtfE9iamVjdH0gbG9hZEl0ZW0KCSAqIEBjb25zdHJ1Y3RvcgoJICovCglmdW5jdGlvbiBCaW5hcnlMb2FkZXIobG9hZEl0ZW0pIHsKCQl0aGlzLkFic3RyYWN0TG9hZGVyX2NvbnN0cnVjdG9yKGxvYWRJdGVtLCB0cnVlLCBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5CSU5BUlkpOwoJCXRoaXMub24oImluaXRpYWxpemUiLCB0aGlzLl91cGRhdGVYSFIsIHRoaXMpOwoJfTsKCgl2YXIgcCA9IGNyZWF0ZWpzLmV4dGVuZChCaW5hcnlMb2FkZXIsIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyKTsKCXZhciBzID0gQmluYXJ5TG9hZGVyOwoKCS8vIHN0YXRpYyBtZXRob2RzCgkvKioKCSAqIERldGVybWluZXMgaWYgdGhlIGxvYWRlciBjYW4gbG9hZCBhIHNwZWNpZmljIGl0ZW0uIFRoaXMgbG9hZGVyIGNhbiBvbmx5IGxvYWQgaXRlbXMgdGhhdCBhcmUgb2YgdHlwZQoJICoge3sjY3Jvc3NMaW5rICJBYnN0cmFjdExvYWRlci9CSU5BUlk6cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fQoJICogQG1ldGhvZCBjYW5Mb2FkSXRlbQoJICogQHBhcmFtIHtMb2FkSXRlbXxPYmplY3R9IGl0ZW0gVGhlIExvYWRJdGVtIHRoYXQgYSBMb2FkUXVldWUgaXMgdHJ5aW5nIHRvIGxvYWQuCgkgKiBAcmV0dXJucyB7Qm9vbGVhbn0gV2hldGhlciB0aGUgbG9hZGVyIGNhbiBsb2FkIHRoZSBpdGVtLgoJICogQHN0YXRpYwoJICovCglzLmNhbkxvYWRJdGVtID0gZnVuY3Rpb24gKGl0ZW0pIHsKCQlyZXR1cm4gaXRlbS50eXBlID09IGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLkJJTkFSWTsKCX07CgoJLy8gcHJpdmF0ZSBtZXRob2RzCgkvKioKCSAqIEJlZm9yZSB0aGUgaXRlbSBsb2Fkcywgc2V0IHRoZSByZXNwb25zZSB0eXBlIHRvICJhcnJheWJ1ZmZlciIKCSAqIEBwcm9wZXJ0eSBfdXBkYXRlWEhSCgkgKiBAcGFyYW0ge0V2ZW50fSBldmVudAoJICogQHByaXZhdGUKCSAqLwoJcC5fdXBkYXRlWEhSID0gZnVuY3Rpb24gKGV2ZW50KSB7CgkJZXZlbnQubG9hZGVyLnNldFJlc3BvbnNlVHlwZSgiYXJyYXlidWZmZXIiKTsKCX07CgoJY3JlYXRlanMuQmluYXJ5TG9hZGVyID0gY3JlYXRlanMucHJvbW90ZShCaW5hcnlMb2FkZXIsICJBYnN0cmFjdExvYWRlciIpOwoKfSgpKTsKCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi8vIENTU0xvYWRlci5qcwovLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoKdGhpcy5jcmVhdGVqcyA9IHRoaXMuY3JlYXRlanMgfHwge307CgooZnVuY3Rpb24gKCkgewoJInVzZSBzdHJpY3QiOwoKCS8vIGNvbnN0cnVjdG9yCgkvKioKCSAqIEEgbG9hZGVyIGZvciBDU1MgZmlsZXMuCgkgKiBAY2xhc3MgQ1NTTG9hZGVyCgkgKiBAcGFyYW0ge0xvYWRJdGVtfE9iamVjdH0gbG9hZEl0ZW0KCSAqIEBwYXJhbSB7Qm9vbGVhbn0gcHJlZmVyWEhSCgkgKiBAY29uc3RydWN0b3IKCSAqLwoJZnVuY3Rpb24gQ1NTTG9hZGVyKGxvYWRJdGVtLCBwcmVmZXJYSFIpIHsKCQl0aGlzLkFic3RyYWN0TG9hZGVyX2NvbnN0cnVjdG9yKGxvYWRJdGVtLCBwcmVmZXJYSFIsIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLkNTUyk7CgoJCS8vIHB1YmxpYyBwcm9wZXJ0aWVzCgkJdGhpcy5yZXN1bHRGb3JtYXR0ZXIgPSB0aGlzLl9mb3JtYXRSZXN1bHQ7CgoJCS8vIHByb3RlY3RlZCBwcm9wZXJ0aWVzCgkJdGhpcy5fdGFnU3JjQXR0cmlidXRlID0gImhyZWYiOwoKCQlpZiAocHJlZmVyWEhSKSB7CgkJCXRoaXMuX3RhZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInN0eWxlIik7CgkJfSBlbHNlIHsKCQkJdGhpcy5fdGFnID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgibGluayIpOwoJCX0KCgkJdGhpcy5fdGFnLnJlbCA9ICJzdHlsZXNoZWV0IjsKCQl0aGlzLl90YWcudHlwZSA9ICJ0ZXh0L2NzcyI7Cgl9OwoKCXZhciBwID0gY3JlYXRlanMuZXh0ZW5kKENTU0xvYWRlciwgY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIpOwoJdmFyIHMgPSBDU1NMb2FkZXI7CgoJLy8gc3RhdGljIG1ldGhvZHMKCS8qKgoJICogRGV0ZXJtaW5lcyBpZiB0aGUgbG9hZGVyIGNhbiBsb2FkIGEgc3BlY2lmaWMgaXRlbS4gVGhpcyBsb2FkZXIgY2FuIG9ubHkgbG9hZCBpdGVtcyB0aGF0IGFyZSBvZiB0eXBlCgkgKiB7eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyL0NTUzpwcm9wZXJ0eSJ9fXt7L2Nyb3NzTGlua319LgoJICogQG1ldGhvZCBjYW5Mb2FkSXRlbQoJICogQHBhcmFtIHtMb2FkSXRlbXxPYmplY3R9IGl0ZW0gVGhlIExvYWRJdGVtIHRoYXQgYSBMb2FkUXVldWUgaXMgdHJ5aW5nIHRvIGxvYWQuCgkgKiBAcmV0dXJucyB7Qm9vbGVhbn0gV2hldGhlciB0aGUgbG9hZGVyIGNhbiBsb2FkIHRoZSBpdGVtLgoJICogQHN0YXRpYwoJICovCglzLmNhbkxvYWRJdGVtID0gZnVuY3Rpb24gKGl0ZW0pIHsKCQlyZXR1cm4gaXRlbS50eXBlID09IGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLkNTUzsKCX07CgoJLy8gcHJvdGVjdGVkIG1ldGhvZHMKCS8qKgoJICogVGhlIHJlc3VsdCBmb3JtYXR0ZXIgZm9yIENTUyBmaWxlcy4KCSAqIEBtZXRob2QgX2Zvcm1hdFJlc3VsdAoJICogQHBhcmFtIHtBYnN0cmFjdExvYWRlcn0gbG9hZGVyCgkgKiBAcmV0dXJucyB7SFRNTExpbmtFbGVtZW50fEhUTUxTdHlsZUVsZW1lbnR9CgkgKiBAcHJpdmF0ZQoJICovCglwLl9mb3JtYXRSZXN1bHQgPSBmdW5jdGlvbiAobG9hZGVyKSB7CgkJaWYgKHRoaXMuX3ByZWZlclhIUikgewoJCQl2YXIgdGFnID0gbG9hZGVyLmdldFRhZygpOwoJCQl2YXIgaGVhZCA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJoZWFkIilbMF07IC8vTm90ZTogVGhpcyBpcyB1bmF2b2lkYWJsZSBpbiBJRTY3OAoJCQloZWFkLmFwcGVuZENoaWxkKHRhZyk7CgoJCQlpZiAodGFnLnN0eWxlU2hlZXQpIHsgLy8gSUUKCQkJCXRhZy5zdHlsZVNoZWV0LmNzc1RleHQgPSBsb2FkZXIuZ2V0UmVzdWx0KHRydWUpOwoJCQl9IGVsc2UgewoJCQkJdmFyIHRleHROb2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUobG9hZGVyLmdldFJlc3VsdCh0cnVlKSk7CgkJCQl0YWcuYXBwZW5kQ2hpbGQodGV4dE5vZGUpOwoJCQl9CgkJfSBlbHNlIHsKCQkJdGFnID0gdGhpcy5fdGFnOwoJCX0KCgkJcmV0dXJuIHRhZzsKCX07CgoJY3JlYXRlanMuQ1NTTG9hZGVyID0gY3JlYXRlanMucHJvbW90ZShDU1NMb2FkZXIsICJBYnN0cmFjdExvYWRlciIpOwoKfSgpKTsKCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi8vIEltYWdlTG9hZGVyLmpzCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgp0aGlzLmNyZWF0ZWpzID0gdGhpcy5jcmVhdGVqcyB8fCB7fTsKCihmdW5jdGlvbiAoKSB7CgkidXNlIHN0cmljdCI7CgoJLy8gY29uc3RydWN0b3IKCS8qKgoJICogQSBsb2FkZXIgZm9yIGltYWdlIGZpbGVzLgoJICogQGNsYXNzIEltYWdlTG9hZGVyCgkgKiBAcGFyYW0ge0xvYWRJdGVtfE9iamVjdH0gbG9hZEl0ZW0KCSAqIEBwYXJhbSB7Qm9vbGVhbn0gcHJlZmVyWEhSCgkgKiBAY29uc3RydWN0b3IKCSAqLwoJZnVuY3Rpb24gSW1hZ2VMb2FkZXIgKGxvYWRJdGVtLCBwcmVmZXJYSFIpIHsKCQl0aGlzLkFic3RyYWN0TG9hZGVyX2NvbnN0cnVjdG9yKGxvYWRJdGVtLCBwcmVmZXJYSFIsIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLklNQUdFKTsKCgkJLy8gcHVibGljIHByb3BlcnRpZXMKCQl0aGlzLnJlc3VsdEZvcm1hdHRlciA9IHRoaXMuX2Zvcm1hdFJlc3VsdDsKCgkJLy8gcHJvdGVjdGVkIHByb3BlcnRpZXMKCQl0aGlzLl90YWdTcmNBdHRyaWJ1dGUgPSAic3JjIjsKCgkJLy8gQ2hlY2sgaWYgdGhlIHByZWxvYWQgaXRlbSBpcyBhbHJlYWR5IGEgdGFnLgoJCWlmIChjcmVhdGVqcy5SZXF1ZXN0VXRpbHMuaXNJbWFnZVRhZyhsb2FkSXRlbSkpIHsKCQkJdGhpcy5fdGFnID0gbG9hZEl0ZW07CgkJfSBlbHNlIGlmIChjcmVhdGVqcy5SZXF1ZXN0VXRpbHMuaXNJbWFnZVRhZyhsb2FkSXRlbS5zcmMpKSB7CgkJCXRoaXMuX3RhZyA9IGxvYWRJdGVtLnNyYzsKCQl9IGVsc2UgaWYgKGNyZWF0ZWpzLlJlcXVlc3RVdGlscy5pc0ltYWdlVGFnKGxvYWRJdGVtLnRhZykpIHsKCQkJdGhpcy5fdGFnID0gbG9hZEl0ZW0udGFnOwoJCX0KCgkJaWYgKHRoaXMuX3RhZyAhPSBudWxsKSB7CgkJCXRoaXMuX3ByZWZlclhIUiA9IGZhbHNlOwoJCX0gZWxzZSB7CgkJCXRoaXMuX3RhZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImltZyIpOwoJCX0KCgkJdGhpcy5vbigiaW5pdGlhbGl6ZSIsIHRoaXMuX3VwZGF0ZVhIUiwgdGhpcyk7Cgl9OwoKCXZhciBwID0gY3JlYXRlanMuZXh0ZW5kKEltYWdlTG9hZGVyLCBjcmVhdGVqcy5BYnN0cmFjdExvYWRlcik7Cgl2YXIgcyA9IEltYWdlTG9hZGVyOwoKCS8vIHN0YXRpYyBtZXRob2RzCgkvKioKCSAqIERldGVybWluZXMgaWYgdGhlIGxvYWRlciBjYW4gbG9hZCBhIHNwZWNpZmljIGl0ZW0uIFRoaXMgbG9hZGVyIGNhbiBvbmx5IGxvYWQgaXRlbXMgdGhhdCBhcmUgb2YgdHlwZQoJICoge3sjY3Jvc3NMaW5rICJBYnN0cmFjdExvYWRlci9JTUFHRTpwcm9wZXJ0eSJ9fXt7L2Nyb3NzTGlua319LgoJICogQG1ldGhvZCBjYW5Mb2FkSXRlbQoJICogQHBhcmFtIHtMb2FkSXRlbXxPYmplY3R9IGl0ZW0gVGhlIExvYWRJdGVtIHRoYXQgYSBMb2FkUXVldWUgaXMgdHJ5aW5nIHRvIGxvYWQuCgkgKiBAcmV0dXJucyB7Qm9vbGVhbn0gV2hldGhlciB0aGUgbG9hZGVyIGNhbiBsb2FkIHRoZSBpdGVtLgoJICogQHN0YXRpYwoJICovCglzLmNhbkxvYWRJdGVtID0gZnVuY3Rpb24gKGl0ZW0pIHsKCQlyZXR1cm4gaXRlbS50eXBlID09IGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLklNQUdFOwoJfTsKCgkvLyBwdWJsaWMgbWV0aG9kcwoJcC5sb2FkID0gZnVuY3Rpb24gKCkgewoJCWlmICh0aGlzLl90YWcuc3JjICE9ICIiICYmIHRoaXMuX3RhZy5jb21wbGV0ZSkgewoJCQl0aGlzLl9zZW5kQ29tcGxldGUoKTsKCQkJcmV0dXJuOwoJCX0KCgkJdmFyIGNyb3NzT3JpZ2luID0gdGhpcy5faXRlbS5jcm9zc09yaWdpbjsKCQlpZiAoY3Jvc3NPcmlnaW4gPT0gdHJ1ZSkgeyBjcm9zc09yaWdpbiA9ICJBbm9ueW1vdXMiOyB9CgkJaWYgKGNyb3NzT3JpZ2luICE9IG51bGwgJiYgIWNyZWF0ZWpzLlJlcXVlc3RVdGlscy5pc0xvY2FsKHRoaXMuX2l0ZW0uc3JjKSkgewoJCQl0aGlzLl90YWcuY3Jvc3NPcmlnaW4gPSBjcm9zc09yaWdpbjsKCQl9CgoJCXRoaXMuQWJzdHJhY3RMb2FkZXJfbG9hZCgpOwoJfTsKCgkvLyBwcm90ZWN0ZWQgbWV0aG9kcwoJLyoqCgkgKiBCZWZvcmUgdGhlIGl0ZW0gbG9hZHMsIHNldCBpdHMgbWltZXR5cGUgYW5kIHJlc3BvbnNlVHlwZS4KCSAqIEBwcm9wZXJ0eSBfdXBkYXRlWEhSCgkgKiBAcGFyYW0ge0V2ZW50fSBldmVudAoJICogQHByaXZhdGUKCSAqLwoJcC5fdXBkYXRlWEhSID0gZnVuY3Rpb24gKGV2ZW50KSB7CgkJZXZlbnQubG9hZGVyLm1pbWVUeXBlID0gJ3RleHQvcGxhaW47IGNoYXJzZXQ9eC11c2VyLWRlZmluZWQtYmluYXJ5JzsKCgkJLy8gT25seSBleGlzdHMgZm9yIFhIUgoJCWlmIChldmVudC5sb2FkZXIuc2V0UmVzcG9uc2VUeXBlKSB7CgkJCWV2ZW50LmxvYWRlci5zZXRSZXNwb25zZVR5cGUoImJsb2IiKTsKCQl9Cgl9OwoKCS8qKgoJICogVGhlIHJlc3VsdCBmb3JtYXR0ZXIgZm9yIEltYWdlIGZpbGVzLgoJICogQG1ldGhvZCBfZm9ybWF0UmVzdWx0CgkgKiBAcGFyYW0ge0Fic3RyYWN0TG9hZGVyfSBsb2FkZXIKCSAqIEByZXR1cm5zIHtIVE1MSW1hZ2VFbGVtZW50fQoJICogQHByaXZhdGUKCSAqLwoJcC5fZm9ybWF0UmVzdWx0ID0gZnVuY3Rpb24gKGxvYWRlcikgewoJCXZhciBfdGhpcyA9IHRoaXM7CgkJcmV0dXJuIGZ1bmN0aW9uIChkb25lKSB7CgkJCXZhciB0YWcgPSBfdGhpcy5fdGFnOwoJCQl2YXIgVVJMID0gd2luZG93LlVSTCB8fCB3aW5kb3cud2Via2l0VVJMOwoKCQkJaWYgKCFfdGhpcy5fcHJlZmVyWEhSKSB7CgkJCQkvL2RvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodGFnKTsKCQkJfSBlbHNlIGlmIChVUkwpIHsKCQkJCXZhciBvYmpVUkwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGxvYWRlci5nZXRSZXN1bHQodHJ1ZSkpOwoJCQkJdGFnLnNyYyA9IG9ialVSTDsKCQkJCXRhZy5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7CgkJCQkJVVJMLnJldm9rZU9iamVjdFVSTChfdGhpcy5zcmMpOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJdGFnLnNyYyA9IGxvYWRlci5nZXRJdGVtKCkuc3JjOwoJCQl9CgoJCQlpZiAodGFnLmNvbXBsZXRlKSB7CgkJCQlkb25lKHRhZyk7CgkJCX0gZWxzZSB7CgkJCQl0YWcub25sb2FkID0gZnVuY3Rpb24gKCkgewoJCQkJCWRvbmUodGhpcyk7CgkJCQl9CgkJCX0KCQl9OwoJfTsKCgljcmVhdGVqcy5JbWFnZUxvYWRlciA9IGNyZWF0ZWpzLnByb21vdGUoSW1hZ2VMb2FkZXIsICJBYnN0cmFjdExvYWRlciIpOwoKfSgpKTsKCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi8vIEphdmFTY3JpcHRMb2FkZXIuanMKLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCnRoaXMuY3JlYXRlanMgPSB0aGlzLmNyZWF0ZWpzIHx8IHt9OwoKKGZ1bmN0aW9uICgpIHsKCSJ1c2Ugc3RyaWN0IjsKCgkvLyBjb25zdHJ1Y3RvcgoJLyoqCgkgKiBBIGxvYWRlciBmb3IgSmF2YVNjcmlwdCBmaWxlcy4KCSAqIEBjbGFzcyBKYXZhU2NyaXB0TG9hZGVyCgkgKiBAcGFyYW0ge0xvYWRJdGVtfE9iamVjdH0gbG9hZEl0ZW0KCSAqIEBwYXJhbSB7Qm9vbGVhbn0gcHJlZmVyWEhSCgkgKiBAY29uc3RydWN0b3IKCSAqLwoJZnVuY3Rpb24gSmF2YVNjcmlwdExvYWRlcihsb2FkSXRlbSwgcHJlZmVyWEhSKSB7CgkJdGhpcy5BYnN0cmFjdExvYWRlcl9jb25zdHJ1Y3Rvcihsb2FkSXRlbSwgcHJlZmVyWEhSLCBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5KQVZBU0NSSVBUKTsKCgkJLy8gcHVibGljIHByb3BlcnRpZXMKCQl0aGlzLnJlc3VsdEZvcm1hdHRlciA9IHRoaXMuX2Zvcm1hdFJlc3VsdDsKCgkJLy8gcHJvdGVjdGVkIHByb3BlcnRpZXMKCQl0aGlzLl90YWdTcmNBdHRyaWJ1dGUgPSAic3JjIjsKCQl0aGlzLnNldFRhZyhkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJzY3JpcHQiKSk7Cgl9OwoKCXZhciBwID0gY3JlYXRlanMuZXh0ZW5kKEphdmFTY3JpcHRMb2FkZXIsIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyKTsKCXZhciBzID0gSmF2YVNjcmlwdExvYWRlcjsKCgkvLyBzdGF0aWMgbWV0aG9kcwoJLyoqCgkgKiBEZXRlcm1pbmVzIGlmIHRoZSBsb2FkZXIgY2FuIGxvYWQgYSBzcGVjaWZpYyBpdGVtLiBUaGlzIGxvYWRlciBjYW4gb25seSBsb2FkIGl0ZW1zIHRoYXQgYXJlIG9mIHR5cGUKCSAqIHt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvSkFWQVNDUklQVDpwcm9wZXJ0eSJ9fXt7L2Nyb3NzTGlua319CgkgKiBAbWV0aG9kIGNhbkxvYWRJdGVtCgkgKiBAcGFyYW0ge0xvYWRJdGVtfE9iamVjdH0gaXRlbSBUaGUgTG9hZEl0ZW0gdGhhdCBhIExvYWRRdWV1ZSBpcyB0cnlpbmcgdG8gbG9hZC4KCSAqIEByZXR1cm5zIHtCb29sZWFufSBXaGV0aGVyIHRoZSBsb2FkZXIgY2FuIGxvYWQgdGhlIGl0ZW0uCgkgKiBAc3RhdGljCgkgKi8KCXMuY2FuTG9hZEl0ZW0gPSBmdW5jdGlvbiAoaXRlbSkgewoJCXJldHVybiBpdGVtLnR5cGUgPT0gY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuSkFWQVNDUklQVDsKCX07CgoJLy8gcHJvdGVjdGVkIG1ldGhvZHMKCS8qKgoJICogVGhlIHJlc3VsdCBmb3JtYXR0ZXIgZm9yIEphdmFTY3JpcHQgZmlsZXMuCgkgKiBAbWV0aG9kIF9mb3JtYXRSZXN1bHQKCSAqIEBwYXJhbSB7QWJzdHJhY3RMb2FkZXJ9IGxvYWRlcgoJICogQHJldHVybnMge0hUTUxMaW5rRWxlbWVudHxIVE1MU3R5bGVFbGVtZW50fQoJICogQHByaXZhdGUKCSAqLwoJcC5fZm9ybWF0UmVzdWx0ID0gZnVuY3Rpb24gKGxvYWRlcikgewoJCXZhciB0YWcgPSBsb2FkZXIuZ2V0VGFnKCk7CgkJaWYgKHRoaXMuX3ByZWZlclhIUikgewoJCQl0YWcudGV4dCA9IGxvYWRlci5nZXRSZXN1bHQodHJ1ZSk7CgkJfQoJCXJldHVybiB0YWc7Cgl9CgoJY3JlYXRlanMuSmF2YVNjcmlwdExvYWRlciA9IGNyZWF0ZWpzLnByb21vdGUoSmF2YVNjcmlwdExvYWRlciwgIkFic3RyYWN0TG9hZGVyIik7Cgp9KCkpOwoKLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLy8gSlNPTkxvYWRlci5qcwovLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoKdGhpcy5jcmVhdGVqcyA9IHRoaXMuY3JlYXRlanMgfHwge307CgooZnVuY3Rpb24gKCkgewoJInVzZSBzdHJpY3QiOwoKCS8vIGNvbnN0cnVjdG9yCgkvKioKCSAqIEEgbG9hZGVyIGZvciBKU09OIGZpbGVzLiBUbyBsb2FkIEpTT04gY3Jvc3MtZG9tYWluLCB1c2UgSlNPTlAgYW5kIHRoZSB7eyNjcm9zc0xpbmsgIkpTT05QTG9hZGVyIn19e3svY3Jvc3NMaW5rfX0KCSAqIGluc3RlYWQuIFRvIGxvYWQgSlNPTi1mb3JtYXR0ZWQgbWFuaWZlc3RzLCB1c2Uge3sjY3Jvc3NMaW5rICJNYW5pZmVzdExvYWRlciJ9fXt7L2Nyb3NzTGlua319LCBhbmQgdG8KCSAqIGxvYWQgRWFzZWxKUyBTcHJpdGVTaGVldHMsIHVzZSB7eyNjcm9zc0xpbmsgIlNwcml0ZVNoZWV0TG9hZGVyIn19e3svY3Jvc3NMaW5rfX0uCgkgKiBAY2xhc3MgSlNPTkxvYWRlcgoJICogQHBhcmFtIHtMb2FkSXRlbXxPYmplY3R9IGxvYWRJdGVtCgkgKiBAY29uc3RydWN0b3IKCSAqLwoJZnVuY3Rpb24gSlNPTkxvYWRlcihsb2FkSXRlbSkgewoJCXRoaXMuQWJzdHJhY3RMb2FkZXJfY29uc3RydWN0b3IobG9hZEl0ZW0sIHRydWUsIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLkpTT04pOwoKCQkvLyBwdWJsaWMgcHJvcGVydGllcwoJCXRoaXMucmVzdWx0Rm9ybWF0dGVyID0gdGhpcy5fZm9ybWF0UmVzdWx0OwoJfTsKCgl2YXIgcCA9IGNyZWF0ZWpzLmV4dGVuZChKU09OTG9hZGVyLCBjcmVhdGVqcy5BYnN0cmFjdExvYWRlcik7Cgl2YXIgcyA9IEpTT05Mb2FkZXI7CgoJLy8gc3RhdGljIG1ldGhvZHMKCS8qKgoJICogRGV0ZXJtaW5lcyBpZiB0aGUgbG9hZGVyIGNhbiBsb2FkIGEgc3BlY2lmaWMgaXRlbS4gVGhpcyBsb2FkZXIgY2FuIG9ubHkgbG9hZCBpdGVtcyB0aGF0IGFyZSBvZiB0eXBlCgkgKiB7eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyL0pTT046cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fS4KCSAqIEBtZXRob2QgY2FuTG9hZEl0ZW0KCSAqIEBwYXJhbSB7TG9hZEl0ZW18T2JqZWN0fSBpdGVtIFRoZSBMb2FkSXRlbSB0aGF0IGEgTG9hZFF1ZXVlIGlzIHRyeWluZyB0byBsb2FkLgoJICogQHJldHVybnMge0Jvb2xlYW59IFdoZXRoZXIgdGhlIGxvYWRlciBjYW4gbG9hZCB0aGUgaXRlbS4KCSAqIEBzdGF0aWMKCSAqLwoJcy5jYW5Mb2FkSXRlbSA9IGZ1bmN0aW9uIChpdGVtKSB7CgkJcmV0dXJuIGl0ZW0udHlwZSA9PSBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5KU09OICYmICFpdGVtLl9sb2FkQXNKU09OUDsKCX07CgoJLy8gcHJvdGVjdGVkIG1ldGhvZHMKCS8qKgoJICogVGhlIHJlc3VsdCBmb3JtYXR0ZXIgZm9yIEpTT04gZmlsZXMuCgkgKiBAbWV0aG9kIF9mb3JtYXRSZXN1bHQKCSAqIEBwYXJhbSB7QWJzdHJhY3RMb2FkZXJ9IGxvYWRlcgoJICogQHJldHVybnMge0hUTUxMaW5rRWxlbWVudHxIVE1MU3R5bGVFbGVtZW50fQoJICogQHByaXZhdGUKCSAqLwoJcC5fZm9ybWF0UmVzdWx0ID0gZnVuY3Rpb24gKGxvYWRlcikgewoJCXZhciBqc29uID0gbnVsbDsKCQl0cnkgewoJCQlqc29uID0gY3JlYXRlanMuRGF0YVV0aWxzLnBhcnNlSlNPTihsb2FkZXIuZ2V0UmVzdWx0KHRydWUpKTsKCQl9IGNhdGNoIChlKSB7CgkJCXZhciBldmVudCA9IG5ldyBjcmVhdGVqcy5FcnJvckV2ZW50KCJKU09OX0ZPUk1BVCIsIG51bGwsIGUpOwoJCQl0aGlzLl9zZW5kRXJyb3IoZXZlbnQpOwoJCQlyZXR1cm4gZTsKCQl9CgoJCXJldHVybiBqc29uOwoJfTsKCgljcmVhdGVqcy5KU09OTG9hZGVyID0gY3JlYXRlanMucHJvbW90ZShKU09OTG9hZGVyLCAiQWJzdHJhY3RMb2FkZXIiKTsKCn0oKSk7CgovLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwovLyBKU09OUExvYWRlci5qcwovLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoKdGhpcy5jcmVhdGVqcyA9IHRoaXMuY3JlYXRlanMgfHwge307CgooZnVuY3Rpb24gKCkgewoJInVzZSBzdHJpY3QiOwoKCS8vIGNvbnN0cnVjdG9yCgkvKioKCSAqIEEgbG9hZGVyIGZvciBKU09OUCBmaWxlcywgd2hpY2ggYXJlIEpTT04tZm9ybWF0dGVkIHRleHQgZmlsZXMsIHdyYXBwZWQgaW4gYSBjYWxsYmFjay4gVG8gbG9hZCByZWd1bGFyIEpTT04KCSAqIHdpdGhvdXQgYSBjYWxsYmFjayB1c2UgdGhlIHt7I2Nyb3NzTGluayAiSlNPTkxvYWRlciJ9fXt7L2Nyb3NzTGlua319IGluc3RlYWQuIFRvIGxvYWQgSlNPTi1mb3JtYXR0ZWQgbWFuaWZlc3RzLAoJICogdXNlIHt7I2Nyb3NzTGluayAiTWFuaWZlc3RMb2FkZXIifX17ey9jcm9zc0xpbmt9fSwgYW5kIHRvIGxvYWQgRWFzZWxKUyBTcHJpdGVTaGVldHMsIHVzZQoJICoge3sjY3Jvc3NMaW5rICJTcHJpdGVTaGVldExvYWRlciJ9fXt7L2Nyb3NzTGlua319LgoJICoKCSAqIE5vdGUgdGhhdCBKU09OUCBmaWxlcyBsb2FkZWQgY29uY3VycmVudGx5IHJlcXVpcmUgYSA8ZW0+dW5pcXVlPC9lbT4gY2FsbGJhY2suIFRvIGVuc3VyZSBKU09OUCBmaWxlcyBhcmUgbG9hZGVkCgkgKiBpbiBvcmRlciwgZWl0aGVyIHVzZSB0aGUge3sjY3Jvc3NMaW5rICJMb2FkUXVldWUvc2V0TWF4Q29ubmVjdGlvbnMifX17ey9jcm9zc0xpbmt9fSBtZXRob2QgKHNldCB0byAxKSwKCSAqIG9yIHNldCB7eyNjcm9zc0xpbmsgIkxvYWRJdGVtL21haW50YWluT3JkZXI6cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fSBvbiBpdGVtcyB3aXRoIHRoZSBzYW1lIGNhbGxiYWNrLgoJICogQGNsYXNzIEpTT05QTG9hZGVyCgkgKiBAcGFyYW0ge0xvYWRJdGVtfE9iamVjdH0gbG9hZEl0ZW0KCSAqIEBjb25zdHJ1Y3RvcgoJICovCglmdW5jdGlvbiBKU09OUExvYWRlcihsb2FkSXRlbSkgewoJCXRoaXMuQWJzdHJhY3RMb2FkZXJfY29uc3RydWN0b3IobG9hZEl0ZW0sIGZhbHNlLCBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5KU09OUCk7CgkJdGhpcy5zZXRUYWcoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic2NyaXB0IikpOwoJCXRoaXMuZ2V0VGFnKCkudHlwZSA9ICJ0ZXh0L2phdmFzY3JpcHQiOwoJfTsKCgl2YXIgcCA9IGNyZWF0ZWpzLmV4dGVuZChKU09OUExvYWRlciwgY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIpOwoJdmFyIHMgPSBKU09OUExvYWRlcjsKCgoJLy8gc3RhdGljIG1ldGhvZHMKCS8qKgoJICogRGV0ZXJtaW5lcyBpZiB0aGUgbG9hZGVyIGNhbiBsb2FkIGEgc3BlY2lmaWMgaXRlbS4gVGhpcyBsb2FkZXIgY2FuIG9ubHkgbG9hZCBpdGVtcyB0aGF0IGFyZSBvZiB0eXBlCgkgKiB7eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyL0pTT05QOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0uCgkgKiBAbWV0aG9kIGNhbkxvYWRJdGVtCgkgKiBAcGFyYW0ge0xvYWRJdGVtfE9iamVjdH0gaXRlbSBUaGUgTG9hZEl0ZW0gdGhhdCBhIExvYWRRdWV1ZSBpcyB0cnlpbmcgdG8gbG9hZC4KCSAqIEByZXR1cm5zIHtCb29sZWFufSBXaGV0aGVyIHRoZSBsb2FkZXIgY2FuIGxvYWQgdGhlIGl0ZW0uCgkgKiBAc3RhdGljCgkgKi8KCXMuY2FuTG9hZEl0ZW0gPSBmdW5jdGlvbiAoaXRlbSkgewoJCXJldHVybiBpdGVtLnR5cGUgPT0gY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuSlNPTlAgfHwgaXRlbS5fbG9hZEFzSlNPTlA7Cgl9OwoKCS8vIHB1YmxpYyBtZXRob2RzCglwLmNhbmNlbCA9IGZ1bmN0aW9uICgpIHsKCQl0aGlzLkFic3RyYWN0TG9hZGVyX2NhbmNlbCgpOwoJCXRoaXMuX2Rpc3Bvc2UoKTsKCX07CgoJcC5sb2FkID0gZnVuY3Rpb24gKCkgewoJCWlmICh0aGlzLl9pdGVtLmNhbGxiYWNrID09IG51bGwpIHsKCQkJdGhyb3cgbmV3IEVycm9yKCdjYWxsYmFjayBpcyByZXF1aXJlZCBmb3IgbG9hZGluZyBKU09OUCByZXF1ZXN0cy4nKTsKCQl9CgoJCS8vIFRPRE86IExvb2sgaW50byBjcmVhdGluZyBvdXIgb3duIGlGcmFtZSB0byBoYW5kbGUgdGhlIGxvYWQKCQkvLyBJbiB0aGUgZmlyc3QgYXR0ZW1wdCwgRkYgZGlkIG5vdCBnZXQgdGhlIHJlc3VsdAoJCS8vICAgcmVzdWx0IGluc3RhbmNlb2YgT2JqZWN0IGRpZCBub3Qgd29yayBlaXRoZXIKCQkvLyAgIHNvIHdlIHdvdWxkIG5lZWQgdG8gY2xvbmUgdGhlIHJlc3VsdC4KCQlpZiAod2luZG93W3RoaXMuX2l0ZW0uY2FsbGJhY2tdICE9IG51bGwpIHsKCQkJdGhyb3cgbmV3IEVycm9yKAoJCQkJIkpTT05QIGNhbGxiYWNrICciICsKCQkJCXRoaXMuX2l0ZW0uY2FsbGJhY2sgKwoJCQkJIicgYWxyZWFkeSBleGlzdHMgb24gd2luZG93LiBZb3UgbmVlZCB0byBzcGVjaWZ5IGEgZGlmZmVyZW50IGNhbGxiYWNrIG9yIHJlLW5hbWUgdGhlIGN1cnJlbnQgb25lLiIpOwoJCX0KCgkJd2luZG93W3RoaXMuX2l0ZW0uY2FsbGJhY2tdID0gY3JlYXRlanMucHJveHkodGhpcy5faGFuZGxlTG9hZCwgdGhpcyk7CgkJd2luZG93LmRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGhpcy5fdGFnKTsKCgkJLy8gTG9hZCB0aGUgdGFnCgkJdGhpcy5fdGFnLnNyYyA9IHRoaXMuX2l0ZW0uc3JjOwoJfTsKCgkvLyBwcml2YXRlIG1ldGhvZHMKCS8qKgoJICogSGFuZGxlIHRoZSBKU09OUCBjYWxsYmFjaywgd2hpY2ggaXMgYSBwdWJsaWMgbWV0aG9kIGRlZmluZWQgb24gYHdpbmRvd2AuCgkgKiBAbWV0aG9kIF9oYW5kbGVMb2FkCgkgKiBAcGFyYW0ge09iamVjdH0gVGhlIGZvcm1hdHRlZCBKU09OIGRhdGEuCgkgKiBAcHJpdmF0ZQoJICovCglwLl9oYW5kbGVMb2FkID0gZnVuY3Rpb24gKGRhdGEpIHsKCQl0aGlzLl9yZXN1bHQgPSB0aGlzLl9yYXdSZXN1bHQgPSBkYXRhOwoJCXRoaXMuX3NlbmRDb21wbGV0ZSgpOwoKCQl0aGlzLl9kaXNwb3NlKCk7Cgl9OwoJCgkvKioKCSAqIENsZWFuIHVwIHRoZSBKU09OUCBsb2FkLiBUaGlzIGNsZWFycyBvdXQgdGhlIGNhbGxiYWNrIGFuZCBzY3JpcHQgdGFnIHRoYXQgdGhpcyBsb2FkZXIgY3JlYXRlcy4KCSAqIEBtZXRob2QgX2Rpc3Bvc2UKCSAqIEBwcml2YXRlCgkgKi8KCXAuX2Rpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7CgkJd2luZG93LmRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodGhpcy5fdGFnKTsKCQlkZWxldGUgd2luZG93W3RoaXMuX2l0ZW0uY2FsbGJhY2tdOwoJfTsKCgljcmVhdGVqcy5KU09OUExvYWRlciA9IGNyZWF0ZWpzLnByb21vdGUoSlNPTlBMb2FkZXIsICJBYnN0cmFjdExvYWRlciIpOwoKfSgpKTsKCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi8vIE1hbmlmZXN0TG9hZGVyLmpzCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgp0aGlzLmNyZWF0ZWpzID0gdGhpcy5jcmVhdGVqcyB8fCB7fTsKCihmdW5jdGlvbiAoKSB7CgkidXNlIHN0cmljdCI7CgoJLy8gY29uc3RydWN0b3IKCS8qKgoJICogQSBsb2FkZXIgZm9yIEpTT04gbWFuaWZlc3RzLiBJdGVtcyBpbnNpZGUgdGhlIG1hbmlmZXN0IGFyZSBsb2FkZWQgYmVmb3JlIHRoZSBsb2FkZXIgY29tcGxldGVzLiBUbyBsb2FkIG1hbmlmZXN0cwoJICogdXNpbmcgSlNPTlAsIHNwZWNpZnkgYSB7eyNjcm9zc0xpbmsgIkxvYWRJdGVtL2NhbGxiYWNrOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0gYXMgcGFydCBvZiB0aGUKCSAqIHt7I2Nyb3NzTGluayAiTG9hZEl0ZW0ifX17ey9jcm9zc0xpbmt9fS4gTm90ZSB0aGF0IHRoZSB7eyNjcm9zc0xpbmsgIkpTT05Mb2FkZXIifX17ey9jcm9zc0xpbmt9fSBhbmQKCSAqIHt7I2Nyb3NzTGluayAiSlNPTlBMb2FkZXIifX17ey9jcm9zc0xpbmt9fSBhcmUgaGlnaGVyIHByaW9yaXR5IGxvYWRlcnMsIHNvIG1hbmlmZXN0cyA8c3Ryb25nPm11c3Q8L3N0cm9uZz4KCSAqIHNldCB0aGUge3sjY3Jvc3NMaW5rICJMb2FkSXRlbSJ9fXt7L2Nyb3NzTGlua319IHt7I2Nyb3NzTGluayAiTG9hZEl0ZW0vdHlwZTpwcm9wZXJ0eSJ9fXt7L2Nyb3NzTGlua319IHByb3BlcnR5CgkgKiB0byB7eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyL01BTklGRVNUOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0uCgkgKiBAY2xhc3MgTWFuaWZlc3RMb2FkZXIKCSAqIEBwYXJhbSB7TG9hZEl0ZW18T2JqZWN0fSBsb2FkSXRlbQoJICogQGNvbnN0cnVjdG9yCgkgKi8KCWZ1bmN0aW9uIE1hbmlmZXN0TG9hZGVyKGxvYWRJdGVtKSB7CgkJdGhpcy5BYnN0cmFjdExvYWRlcl9jb25zdHJ1Y3Rvcihsb2FkSXRlbSwgbnVsbCwgY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuTUFOSUZFU1QpOwoKCQkvLyBwcm90ZWN0ZWQgcHJvcGVydGllcwoJCS8qKgoJCSAqIEFuIGludGVybmFsIHt7I2Nyb3NzTGluayAiTG9hZFF1ZXVlIn19e3svY3Jvc3NMaW5rfX0gdGhhdCBsb2FkcyB0aGUgY29udGVudHMgb2YgdGhlIG1hbmlmZXN0LgoJCSAqIEBwcm9wZXJ0eSBfbWFuaWZlc3RRdWV1ZQoJCSAqIEB0eXBlIHtMb2FkUXVldWV9CgkJICogQHByaXZhdGUKCQkgKi8KCQl0aGlzLl9tYW5pZmVzdFF1ZXVlID0gbnVsbDsKCX07CgoJdmFyIHAgPSBjcmVhdGVqcy5leHRlbmQoTWFuaWZlc3RMb2FkZXIsIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyKTsKCXZhciBzID0gTWFuaWZlc3RMb2FkZXI7CgoJLy8gc3RhdGljIHByb3BlcnRpZXMKCS8qKgoJICogVGhlIGFtb3VudCBvZiBwcm9ncmVzcyB0aGF0IHRoZSBtYW5pZmVzdCBpdHNlbGYgdGFrZXMgdXAuCgkgKiBAcHJvcGVydHkgTUFOSUZFU1RfUFJPR1JFU1MKCSAqIEB0eXBlIHtudW1iZXJ9CgkgKiBAZGVmYXVsdCAwLjI1ICgyNSUpCgkgKiBAcHJpdmF0ZQoJICogQHN0YXRpYwoJICovCglzLk1BTklGRVNUX1BST0dSRVNTID0gMC4yNTsKCgkvLyBzdGF0aWMgbWV0aG9kcwoJLyoqCgkgKiBEZXRlcm1pbmVzIGlmIHRoZSBsb2FkZXIgY2FuIGxvYWQgYSBzcGVjaWZpYyBpdGVtLiBUaGlzIGxvYWRlciBjYW4gb25seSBsb2FkIGl0ZW1zIHRoYXQgYXJlIG9mIHR5cGUKCSAqIHt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvTUFOSUZFU1Q6cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fQoJICogQG1ldGhvZCBjYW5Mb2FkSXRlbQoJICogQHBhcmFtIHtMb2FkSXRlbXxPYmplY3R9IGl0ZW0gVGhlIExvYWRJdGVtIHRoYXQgYSBMb2FkUXVldWUgaXMgdHJ5aW5nIHRvIGxvYWQuCgkgKiBAcmV0dXJucyB7Qm9vbGVhbn0gV2hldGhlciB0aGUgbG9hZGVyIGNhbiBsb2FkIHRoZSBpdGVtLgoJICogQHN0YXRpYwoJICovCglzLmNhbkxvYWRJdGVtID0gZnVuY3Rpb24gKGl0ZW0pIHsKCQlyZXR1cm4gaXRlbS50eXBlID09IGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLk1BTklGRVNUOwoJfTsKCgkvLyBwdWJsaWMgbWV0aG9kcwoJcC5sb2FkID0gZnVuY3Rpb24gKCkgewoJCXRoaXMuQWJzdHJhY3RMb2FkZXJfbG9hZCgpOwoJfTsKCgkvLyBwcm90ZWN0ZWQgbWV0aG9kcwoJcC5fY3JlYXRlUmVxdWVzdCA9IGZ1bmN0aW9uKCkgewoJCXZhciBjYWxsYmFjayA9IHRoaXMuX2l0ZW0uY2FsbGJhY2sKCQlpZiAoY2FsbGJhY2sgIT0gbnVsbCkgewoJCQl0aGlzLl9yZXF1ZXN0ID0gbmV3IGNyZWF0ZWpzLkpTT05QTG9hZGVyKHRoaXMuX2l0ZW0pOwoJCX0gZWxzZSB7CgkJCXRoaXMuX3JlcXVlc3QgPSBuZXcgY3JlYXRlanMuSlNPTkxvYWRlcih0aGlzLl9pdGVtKTsKCQl9Cgl9OwoKCXAuaGFuZGxlRXZlbnQgPSBmdW5jdGlvbiAoZXZlbnQpIHsKCQlzd2l0Y2ggKGV2ZW50LnR5cGUpIHsKCQkJY2FzZSAiY29tcGxldGUiOgoJCQkJdGhpcy5fcmF3UmVzdWx0ID0gZXZlbnQudGFyZ2V0LmdldFJlc3VsdCh0cnVlKTsKCQkJCXRoaXMuX3Jlc3VsdCA9IGV2ZW50LnRhcmdldC5nZXRSZXN1bHQoKTsKCQkJCXRoaXMuX3NlbmRQcm9ncmVzcyhzLk1BTklGRVNUX1BST0dSRVNTKTsKCQkJCXRoaXMuX2xvYWRNYW5pZmVzdCh0aGlzLl9yZXN1bHQpOwoJCQkJcmV0dXJuOwoJCQljYXNlICJwcm9ncmVzcyI6CgkJCQlldmVudC5sb2FkZWQgKj0gcy5NQU5JRkVTVF9QUk9HUkVTUzsKCQkJCXRoaXMucHJvZ3Jlc3MgPSBldmVudC5sb2FkZWQgLyBldmVudC50b3RhbDsKCQkJCWlmIChpc05hTih0aGlzLnByb2dyZXNzKSB8fCB0aGlzLnByb2dyZXNzID09IEluZmluaXR5KSB7IHRoaXMucHJvZ3Jlc3MgPSAwOyB9CgkJCQl0aGlzLl9zZW5kUHJvZ3Jlc3MoZXZlbnQpOwoJCQkJcmV0dXJuOwoJCX0KCQl0aGlzLkFic3RyYWN0TG9hZGVyX2hhbmRsZUV2ZW50KGV2ZW50KTsKCX07CgoJcC5kZXN0cm95ID0gZnVuY3Rpb24oKSB7CgkJdGhpcy5BYnN0cmFjdExvYWRlcl9kZXN0cm95KCk7CgkJdGhpcy5fbWFuaWZlc3RRdWV1ZS5jbG9zZSgpOwoJfTsKCgkvKioKCSAqIENyZWF0ZSBhbmQgbG9hZCB0aGUgbWFuaWZlc3QgaXRlbXMgb25jZSB0aGUgYWN0dWFsIG1hbmlmZXN0IGhhcyBiZWVuIGxvYWRlZC4KCSAqIEBtZXRob2QgX2xvYWRNYW5pZmVzdAoJICogQHBhcmFtIHtPYmplY3R9IGpzb24KCSAqIEBwcml2YXRlCgkgKi8KCXAuX2xvYWRNYW5pZmVzdCA9IGZ1bmN0aW9uIChqc29uKSB7CgkJaWYgKGpzb24gJiYganNvbi5tYW5pZmVzdCkgewoJCQl2YXIgcXVldWUgPSB0aGlzLl9tYW5pZmVzdFF1ZXVlID0gbmV3IGNyZWF0ZWpzLkxvYWRRdWV1ZSgpOwoJCQlxdWV1ZS5vbigiZmlsZWxvYWQiLCB0aGlzLl9oYW5kbGVNYW5pZmVzdEZpbGVMb2FkLCB0aGlzKTsKCQkJcXVldWUub24oInByb2dyZXNzIiwgdGhpcy5faGFuZGxlTWFuaWZlc3RQcm9ncmVzcywgdGhpcyk7CgkJCXF1ZXVlLm9uKCJjb21wbGV0ZSIsIHRoaXMuX2hhbmRsZU1hbmlmZXN0Q29tcGxldGUsIHRoaXMsIHRydWUpOwoJCQlxdWV1ZS5vbigiZXJyb3IiLCB0aGlzLl9oYW5kbGVNYW5pZmVzdEVycm9yLCB0aGlzLCB0cnVlKTsKCQkJcXVldWUubG9hZE1hbmlmZXN0KGpzb24pOwoJCX0gZWxzZSB7CgkJCXRoaXMuX3NlbmRDb21wbGV0ZSgpOwoJCX0KCX07CgoJLyoqCgkgKiBBbiBpdGVtIGZyb20gdGhlIHt7I2Nyb3NzTGluayAiX21hbmlmZXN0UXVldWU6cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fSBoYXMgY29tcGxldGVkLgoJICogQG1ldGhvZCBfaGFuZGxlTWFuaWZlc3RGaWxlTG9hZAoJICogQHBhcmFtIHtFdmVudH0gZXZlbnQKCSAqIEBwcml2YXRlCgkgKi8KCXAuX2hhbmRsZU1hbmlmZXN0RmlsZUxvYWQgPSBmdW5jdGlvbiAoZXZlbnQpIHsKCQlldmVudC50YXJnZXQgPSBudWxsOwoJCXRoaXMuZGlzcGF0Y2hFdmVudChldmVudCk7Cgl9OwoKCS8qKgoJICogVGhlIG1hbmlmZXN0IGhhcyBjb21wbGV0ZWQgbG9hZGluZy4gVGhpcyB0cmlnZ2VycyB0aGUge3sjY3Jvc3NMaW5rICJBYnN0cmFjdExvYWRlci9jb21wbGV0ZTpldmVudCJ9fXt7L2Nyb3NzTGlua319CgkgKiB7eyNjcm9zc0xpbmsgIkV2ZW50In19e3svY3Jvc3NMaW5rfX0gZnJvbSB0aGUgTWFuaWZlc3RMb2FkZXIuCgkgKiBAbWV0aG9kIF9oYW5kbGVNYW5pZmVzdENvbXBsZXRlCgkgKiBAcGFyYW0ge0V2ZW50fSBldmVudAoJICogQHByaXZhdGUKCSAqLwoJcC5faGFuZGxlTWFuaWZlc3RDb21wbGV0ZSA9IGZ1bmN0aW9uIChldmVudCkgewoJCXRoaXMuX2xvYWRlZEl0ZW1zID0gdGhpcy5fbWFuaWZlc3RRdWV1ZS5nZXRJdGVtcyh0cnVlKTsKCQl0aGlzLl9zZW5kQ29tcGxldGUoKTsKCX07CgoJLyoqCgkgKiBUaGUgbWFuaWZlc3QgaGFzIHJlcG9ydGVkIHByb2dyZXNzLgoJICogQG1ldGhvZCBfaGFuZGxlTWFuaWZlc3RQcm9ncmVzcwoJICogQHBhcmFtIHtQcm9ncmVzc0V2ZW50fSBldmVudAoJICogQHByaXZhdGUKCSAqLwoJcC5faGFuZGxlTWFuaWZlc3RQcm9ncmVzcyA9IGZ1bmN0aW9uIChldmVudCkgewoJCXRoaXMucHJvZ3Jlc3MgPSBldmVudC5wcm9ncmVzcyAqICgxIC0gcy5NQU5JRkVTVF9QUk9HUkVTUykgKyBzLk1BTklGRVNUX1BST0dSRVNTOwoJCXRoaXMuX3NlbmRQcm9ncmVzcyh0aGlzLnByb2dyZXNzKTsKCX07CgoJLyoqCgkgKiBUaGUgbWFuaWZlc3QgaGFzIHJlcG9ydGVkIGFuIGVycm9yIHdpdGggb25lIG9mIHRoZSBmaWxlcy4KCSAqIEBtZXRob2QgX2hhbmRsZU1hbmlmZXN0RXJyb3IKCSAqIEBwYXJhbSB7RXJyb3JFdmVudH0gZXZlbnQKCSAqIEBwcml2YXRlCgkgKi8KCXAuX2hhbmRsZU1hbmlmZXN0RXJyb3IgPSBmdW5jdGlvbiAoZXZlbnQpIHsKCQl2YXIgbmV3RXZlbnQgPSBuZXcgY3JlYXRlanMuRXZlbnQoImZpbGVlcnJvciIpOwoJCW5ld0V2ZW50Lml0ZW0gPSBldmVudC5kYXRhOwoJCXRoaXMuZGlzcGF0Y2hFdmVudChuZXdFdmVudCk7Cgl9OwoKCWNyZWF0ZWpzLk1hbmlmZXN0TG9hZGVyID0gY3JlYXRlanMucHJvbW90ZShNYW5pZmVzdExvYWRlciwgIkFic3RyYWN0TG9hZGVyIik7Cgp9KCkpOwoKLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLy8gU291bmRMb2FkZXIuanMKLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCnRoaXMuY3JlYXRlanMgPSB0aGlzLmNyZWF0ZWpzIHx8IHt9OwoKKGZ1bmN0aW9uICgpIHsKCSJ1c2Ugc3RyaWN0IjsKCgkvLyBjb25zdHJ1Y3RvcgoJLyoqCgkgKiBBIGxvYWRlciBmb3IgSFRNTCBhdWRpbyBmaWxlcy4gUHJlbG9hZEpTIGNhbiBub3QgbG9hZCBXZWJBdWRpbyBmaWxlcywgYXMgYSBXZWJBdWRpbyBjb250ZXh0IGlzIHJlcXVpcmVkLCB3aGljaAoJICogc2hvdWxkIGJlIGNyZWF0ZWQgYnkgZWl0aGVyIGEgbGlicmFyeSBwbGF5aW5nIHRoZSBzb3VuZCAoc3VjaCBhcyA8YSBocmVmPSJodHRwOi8vc291bmRqcy5jb20iPlNvdW5kSlM8L2E+LCBvciBhbgoJICogZXh0ZXJuYWwgZnJhbWV3b3JrIHRoYXQgaGFuZGxlcyBhdWRpbyBwbGF5YmFjay4gVG8gbG9hZCBjb250ZW50IHRoYXQgY2FuIGJlIHBsYXllZCBieSBXZWJBdWRpbywgdXNlIHRoZQoJICoge3sjY3Jvc3NMaW5rICJCaW5hcnlMb2FkZXIifX17ey9jcm9zc0xpbmt9fSwgYW5kIGhhbmRsZSB0aGUgYXVkaW8gY29udGV4dCBkZWNvZGluZyBtYW51YWxseS4KCSAqIEBjbGFzcyBTb3VuZExvYWRlcgoJICogQHBhcmFtIHtMb2FkSXRlbXxPYmplY3R9IGxvYWRJdGVtCgkgKiBAcGFyYW0ge0Jvb2xlYW59IHByZWZlclhIUgoJICogQGNvbnN0cnVjdG9yCgkgKi8KCWZ1bmN0aW9uIFNvdW5kTG9hZGVyKGxvYWRJdGVtLCBwcmVmZXJYSFIpIHsKCQl0aGlzLkFic3RyYWN0TWVkaWFMb2FkZXJfY29uc3RydWN0b3IobG9hZEl0ZW0sIHByZWZlclhIUiwgY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuU09VTkQpOwoKCQkvLyBwcm90ZWN0ZWQgcHJvcGVydGllcwoJCWlmIChjcmVhdGVqcy5SZXF1ZXN0VXRpbHMuaXNBdWRpb1RhZyhsb2FkSXRlbSkpIHsKCQkJdGhpcy5fdGFnID0gbG9hZEl0ZW07CgkJfSBlbHNlIGlmIChjcmVhdGVqcy5SZXF1ZXN0VXRpbHMuaXNBdWRpb1RhZyhsb2FkSXRlbS5zcmMpKSB7CgkJCXRoaXMuX3RhZyA9IGxvYWRJdGVtOwoJCX0gZWxzZSBpZiAoY3JlYXRlanMuUmVxdWVzdFV0aWxzLmlzQXVkaW9UYWcobG9hZEl0ZW0udGFnKSkgewoJCQl0aGlzLl90YWcgPSBjcmVhdGVqcy5SZXF1ZXN0VXRpbHMuaXNBdWRpb1RhZyhsb2FkSXRlbSkgPyBsb2FkSXRlbSA6IGxvYWRJdGVtLnNyYzsKCQl9CgoJCWlmICh0aGlzLl90YWcgIT0gbnVsbCkgewoJCQl0aGlzLl9wcmVmZXJYSFIgPSBmYWxzZTsKCQl9Cgl9OwoKCXZhciBwID0gY3JlYXRlanMuZXh0ZW5kKFNvdW5kTG9hZGVyLCBjcmVhdGVqcy5BYnN0cmFjdE1lZGlhTG9hZGVyKTsKCXZhciBzID0gU291bmRMb2FkZXI7CgoJLy8gc3RhdGljIG1ldGhvZHMKCS8qKgoJICogRGV0ZXJtaW5lcyBpZiB0aGUgbG9hZGVyIGNhbiBsb2FkIGEgc3BlY2lmaWMgaXRlbS4gVGhpcyBsb2FkZXIgY2FuIG9ubHkgbG9hZCBpdGVtcyB0aGF0IGFyZSBvZiB0eXBlCgkgKiB7eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyL1NPVU5EOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0uCgkgKiBAbWV0aG9kIGNhbkxvYWRJdGVtCgkgKiBAcGFyYW0ge0xvYWRJdGVtfE9iamVjdH0gaXRlbSBUaGUgTG9hZEl0ZW0gdGhhdCBhIExvYWRRdWV1ZSBpcyB0cnlpbmcgdG8gbG9hZC4KCSAqIEByZXR1cm5zIHtCb29sZWFufSBXaGV0aGVyIHRoZSBsb2FkZXIgY2FuIGxvYWQgdGhlIGl0ZW0uCgkgKiBAc3RhdGljCgkgKi8KCXMuY2FuTG9hZEl0ZW0gPSBmdW5jdGlvbiAoaXRlbSkgewoJCXJldHVybiBpdGVtLnR5cGUgPT0gY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuU09VTkQ7Cgl9OwoKCS8vIHByb3RlY3RlZCBtZXRob2RzCglwLl9jcmVhdGVUYWcgPSBmdW5jdGlvbiAoc3JjKSB7CgkJdmFyIHRhZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImF1ZGlvIik7CgkJdGFnLmF1dG9wbGF5ID0gZmFsc2U7CgkJdGFnLnByZWxvYWQgPSAibm9uZSI7CgoJCS8vTE06IEZpcmVmb3ggZmFpbHMgd2hlbiB0aGlzIHRoZSBwcmVsb2FkPSJub25lIiBmb3Igb3RoZXIgdGFncywgYnV0IGl0IG5lZWRzIHRvIGJlICJub25lIiB0byBlbnN1cmUgUHJlbG9hZEpTIHdvcmtzLgoJCXRhZy5zcmMgPSBzcmM7CgkJcmV0dXJuIHRhZzsKCX07CgoJY3JlYXRlanMuU291bmRMb2FkZXIgPSBjcmVhdGVqcy5wcm9tb3RlKFNvdW5kTG9hZGVyLCAiQWJzdHJhY3RNZWRpYUxvYWRlciIpOwoKfSgpKTsKCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi8vIFZpZGVvTG9hZGVyLmpzCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgp0aGlzLmNyZWF0ZWpzID0gdGhpcy5jcmVhdGVqcyB8fCB7fTsKCihmdW5jdGlvbiAoKSB7CgkidXNlIHN0cmljdCI7CgoJLy8gY29uc3RydWN0b3IKCS8qKgoJICogQSBsb2FkZXIgZm9yIHZpZGVvIGZpbGVzLgoJICogQGNsYXNzIFZpZGVvTG9hZGVyCgkgKiBAcGFyYW0ge0xvYWRJdGVtfE9iamVjdH0gbG9hZEl0ZW0KCSAqIEBwYXJhbSB7Qm9vbGVhbn0gcHJlZmVyWEhSCgkgKiBAY29uc3RydWN0b3IKCSAqLwoJZnVuY3Rpb24gVmlkZW9Mb2FkZXIobG9hZEl0ZW0sIHByZWZlclhIUikgewoJCXRoaXMuQWJzdHJhY3RNZWRpYUxvYWRlcl9jb25zdHJ1Y3Rvcihsb2FkSXRlbSwgcHJlZmVyWEhSLCBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5WSURFTyk7CgoJCWlmIChjcmVhdGVqcy5SZXF1ZXN0VXRpbHMuaXNWaWRlb1RhZyhsb2FkSXRlbSkgfHwgY3JlYXRlanMuUmVxdWVzdFV0aWxzLmlzVmlkZW9UYWcobG9hZEl0ZW0uc3JjKSkgewoJCQl0aGlzLnNldFRhZyhjcmVhdGVqcy5SZXF1ZXN0VXRpbHMuaXNWaWRlb1RhZyhsb2FkSXRlbSk/bG9hZEl0ZW06bG9hZEl0ZW0uc3JjKTsKCgkJCS8vIFdlIGNhbid0IHVzZSBYSFIgZm9yIGEgdGFnIHRoYXQncyBwYXNzZWQgaW4uCgkJCXRoaXMuX3ByZWZlclhIUiA9IGZhbHNlOwoJCX0gZWxzZSB7CgkJCXRoaXMuc2V0VGFnKHRoaXMuX2NyZWF0ZVRhZygpKTsKCQl9Cgl9OwoKCXZhciBwID0gY3JlYXRlanMuZXh0ZW5kKFZpZGVvTG9hZGVyLCBjcmVhdGVqcy5BYnN0cmFjdE1lZGlhTG9hZGVyKTsKCXZhciBzID0gVmlkZW9Mb2FkZXI7CgoJLyoqCgkgKiBDcmVhdGUgYSBuZXcgdmlkZW8gdGFnCgkgKgoJICogQHJldHVybnMge0hUTUxFbGVtZW50fQoJICogQHByaXZhdGUKCSAqLwoJcC5fY3JlYXRlVGFnID0gZnVuY3Rpb24gKCkgewoJCXJldHVybiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJ2aWRlbyIpOwoJfTsKCgkvLyBzdGF0aWMgbWV0aG9kcwoJLyoqCgkgKiBEZXRlcm1pbmVzIGlmIHRoZSBsb2FkZXIgY2FuIGxvYWQgYSBzcGVjaWZpYyBpdGVtLiBUaGlzIGxvYWRlciBjYW4gb25seSBsb2FkIGl0ZW1zIHRoYXQgYXJlIG9mIHR5cGUKCSAqIHt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvVklERU86cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fS4KCSAqIEBtZXRob2QgY2FuTG9hZEl0ZW0KCSAqIEBwYXJhbSB7TG9hZEl0ZW18T2JqZWN0fSBpdGVtIFRoZSBMb2FkSXRlbSB0aGF0IGEgTG9hZFF1ZXVlIGlzIHRyeWluZyB0byBsb2FkLgoJICogQHJldHVybnMge0Jvb2xlYW59IFdoZXRoZXIgdGhlIGxvYWRlciBjYW4gbG9hZCB0aGUgaXRlbS4KCSAqIEBzdGF0aWMKCSAqLwoJcy5jYW5Mb2FkSXRlbSA9IGZ1bmN0aW9uIChpdGVtKSB7CgkJcmV0dXJuIGl0ZW0udHlwZSA9PSBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5WSURFTzsKCX07CgoJY3JlYXRlanMuVmlkZW9Mb2FkZXIgPSBjcmVhdGVqcy5wcm9tb3RlKFZpZGVvTG9hZGVyLCAiQWJzdHJhY3RNZWRpYUxvYWRlciIpOwoKfSgpKTsKCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi8vIFNwcml0ZVNoZWV0TG9hZGVyLmpzCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgp0aGlzLmNyZWF0ZWpzID0gdGhpcy5jcmVhdGVqcyB8fCB7fTsKCihmdW5jdGlvbiAoKSB7CgkidXNlIHN0cmljdCI7CgoJLy8gY29uc3RydWN0b3IKCS8qKgoJICogQSBsb2FkZXIgZm9yIEVhc2VsSlMgU3ByaXRlU2hlZXRzLiBJbWFnZXMgaW5zaWRlIHRoZSBzcHJpdGVzaGVldCBkZWZpbml0aW9uIGFyZSBsb2FkZWQgYmVmb3JlIHRoZSBsb2FkZXIKCSAqIGNvbXBsZXRlcy4gVG8gbG9hZCBTcHJpdGVTaGVldHMgdXNpbmcgSlNPTlAsIHNwZWNpZnkgYSB7eyNjcm9zc0xpbmsgIkxvYWRJdGVtL2NhbGxiYWNrOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0KCSAqIGFzIHBhcnQgb2YgdGhlIHt7I2Nyb3NzTGluayAiTG9hZEl0ZW0ifX17ey9jcm9zc0xpbmt9fS4gTm90ZSB0aGF0IHRoZSB7eyNjcm9zc0xpbmsgIkpTT05Mb2FkZXIifX17ey9jcm9zc0xpbmt9fQoJICogYW5kIHt7I2Nyb3NzTGluayAiSlNPTlBMb2FkZXIifX17ey9jcm9zc0xpbmt9fSBhcmUgaGlnaGVyIHByaW9yaXR5IGxvYWRlcnMsIHNvIFNwcml0ZVNoZWV0cyA8c3Ryb25nPm11c3Q8L3N0cm9uZz4KCSAqIHNldCB0aGUge3sjY3Jvc3NMaW5rICJMb2FkSXRlbSJ9fXt7L2Nyb3NzTGlua319IHt7I2Nyb3NzTGluayAiTG9hZEl0ZW0vdHlwZTpwcm9wZXJ0eSJ9fXt7L2Nyb3NzTGlua319IHByb3BlcnR5CgkgKiB0byB7eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyL1NQUklURVNIRUVUOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0uCgkgKiBAY2xhc3MgU3ByaXRlU2hlZXRMb2FkZXIKCSAqIEBwYXJhbSB7TG9hZEl0ZW18T2JqZWN0fSBsb2FkSXRlbQoJICogQGNvbnN0cnVjdG9yCgkgKi8KCWZ1bmN0aW9uIFNwcml0ZVNoZWV0TG9hZGVyKGxvYWRJdGVtKSB7CgkJdGhpcy5BYnN0cmFjdExvYWRlcl9jb25zdHJ1Y3Rvcihsb2FkSXRlbSwgbnVsbCwgY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuU1BSSVRFU0hFRVQpOwoKCQkvLyBwcm90ZWN0ZWQgcHJvcGVydGllcwoJCS8qKgoJCSAqIEFuIGludGVybmFsIHF1ZXVlIHdoaWNoIGxvYWRzIHRoZSBTcHJpdGVTaGVldCdzIGltYWdlcy4KCQkgKiBAbWV0aG9kIF9tYW5pZmVzdFF1ZXVlCgkJICogQHR5cGUge0xvYWRRdWV1ZX0KCQkgKiBAcHJpdmF0ZQoJCSAqLwoJCXRoaXMuX21hbmlmZXN0UXVldWUgPSBudWxsOwoJfQoKCXZhciBwID0gY3JlYXRlanMuZXh0ZW5kKFNwcml0ZVNoZWV0TG9hZGVyLCBjcmVhdGVqcy5BYnN0cmFjdExvYWRlcik7Cgl2YXIgcyA9IFNwcml0ZVNoZWV0TG9hZGVyOwoKCS8vIHN0YXRpYyBwcm9wZXJ0aWVzCgkvKioKCSAqIFRoZSBhbW91bnQgb2YgcHJvZ3Jlc3MgdGhhdCB0aGUgbWFuaWZlc3QgaXRzZWxmIHRha2VzIHVwLgoJICogQHByb3BlcnR5IFNQUklURVNIRUVUX1BST0dSRVNTCgkgKiBAdHlwZSB7bnVtYmVyfQoJICogQGRlZmF1bHQgMC4yNSAoMjUlKQoJICogQHByaXZhdGUKCSAqIEBzdGF0aWMKCSAqLwoJcy5TUFJJVEVTSEVFVF9QUk9HUkVTUyA9IDAuMjU7CgoJLy8gc3RhdGljIG1ldGhvZHMKCS8qKgoJICogRGV0ZXJtaW5lcyBpZiB0aGUgbG9hZGVyIGNhbiBsb2FkIGEgc3BlY2lmaWMgaXRlbS4gVGhpcyBsb2FkZXIgY2FuIG9ubHkgbG9hZCBpdGVtcyB0aGF0IGFyZSBvZiB0eXBlCgkgKiB7eyNjcm9zc0xpbmsgIkFic3RyYWN0TG9hZGVyL1NQUklURVNIRUVUOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0KCSAqIEBtZXRob2QgY2FuTG9hZEl0ZW0KCSAqIEBwYXJhbSB7TG9hZEl0ZW18T2JqZWN0fSBpdGVtIFRoZSBMb2FkSXRlbSB0aGF0IGEgTG9hZFF1ZXVlIGlzIHRyeWluZyB0byBsb2FkLgoJICogQHJldHVybnMge0Jvb2xlYW59IFdoZXRoZXIgdGhlIGxvYWRlciBjYW4gbG9hZCB0aGUgaXRlbS4KCSAqIEBzdGF0aWMKCSAqLwoJcy5jYW5Mb2FkSXRlbSA9IGZ1bmN0aW9uIChpdGVtKSB7CgkJcmV0dXJuIGl0ZW0udHlwZSA9PSBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5TUFJJVEVTSEVFVDsKCX07CgoJLy8gcHVibGljIG1ldGhvZHMKCXAuZGVzdHJveSA9IGZ1bmN0aW9uKCkgewoJCXRoaXMuQWJzdHJhY3RMb2FkZXJfZGVzdHJveTsKCQl0aGlzLl9tYW5pZmVzdFF1ZXVlLmNsb3NlKCk7Cgl9OwoKCS8vIHByb3RlY3RlZCBtZXRob2RzCglwLl9jcmVhdGVSZXF1ZXN0ID0gZnVuY3Rpb24oKSB7CgkJdmFyIGNhbGxiYWNrID0gdGhpcy5faXRlbS5jYWxsYmFjawoJCWlmIChjYWxsYmFjayAhPSBudWxsICYmIGNhbGxiYWNrIGluc3RhbmNlb2YgRnVuY3Rpb24pIHsKCQkJdGhpcy5fcmVxdWVzdCA9IG5ldyBjcmVhdGVqcy5KU09OUExvYWRlcih0aGlzLl9pdGVtKTsKCQl9IGVsc2UgewoJCQl0aGlzLl9yZXF1ZXN0ID0gbmV3IGNyZWF0ZWpzLkpTT05Mb2FkZXIodGhpcy5faXRlbSk7CgkJfQoJfTsKCglwLmhhbmRsZUV2ZW50ID0gZnVuY3Rpb24gKGV2ZW50KSB7CgkJc3dpdGNoIChldmVudC50eXBlKSB7CgkJCWNhc2UgImNvbXBsZXRlIjoKCQkJCXRoaXMuX3Jhd1Jlc3VsdCA9IGV2ZW50LnRhcmdldC5nZXRSZXN1bHQodHJ1ZSk7CgkJCQl0aGlzLl9yZXN1bHQgPSBldmVudC50YXJnZXQuZ2V0UmVzdWx0KCk7CgkJCQl0aGlzLl9zZW5kUHJvZ3Jlc3Mocy5TUFJJVEVTSEVFVF9QUk9HUkVTUyk7CgkJCQl0aGlzLl9sb2FkTWFuaWZlc3QodGhpcy5fcmVzdWx0KTsKCQkJCXJldHVybjsKCQkJY2FzZSAicHJvZ3Jlc3MiOgoJCQkJZXZlbnQubG9hZGVkICo9IHMuU1BSSVRFU0hFRVRfUFJPR1JFU1M7CgkJCQl0aGlzLnByb2dyZXNzID0gZXZlbnQubG9hZGVkIC8gZXZlbnQudG90YWw7CgkJCQlpZiAoaXNOYU4odGhpcy5wcm9ncmVzcykgfHwgdGhpcy5wcm9ncmVzcyA9PSBJbmZpbml0eSkgeyB0aGlzLnByb2dyZXNzID0gMDsgfQoJCQkJdGhpcy5fc2VuZFByb2dyZXNzKGV2ZW50KTsKCQkJCXJldHVybjsKCQl9CgkJdGhpcy5BYnN0cmFjdExvYWRlcl9oYW5kbGVFdmVudChldmVudCk7Cgl9OwoKCS8qKgoJICogQ3JlYXRlIGFuZCBsb2FkIHRoZSBpbWFnZXMgb25jZSB0aGUgU3ByaXRlU2hlZXQgSlNPTiBoYXMgYmVlbiBsb2FkZWQuCgkgKiBAbWV0aG9kIF9sb2FkTWFuaWZlc3QKCSAqIEBwYXJhbSB7T2JqZWN0fSBqc29uCgkgKiBAcHJpdmF0ZQoJICovCglwLl9sb2FkTWFuaWZlc3QgPSBmdW5jdGlvbiAoanNvbikgewoJCWlmIChqc29uICYmIGpzb24uaW1hZ2VzKSB7CgkJCXZhciBxdWV1ZSA9IHRoaXMuX21hbmlmZXN0UXVldWUgPSBuZXcgY3JlYXRlanMuTG9hZFF1ZXVlKCk7CgkJCXF1ZXVlLm9uKCJjb21wbGV0ZSIsIHRoaXMuX2hhbmRsZU1hbmlmZXN0Q29tcGxldGUsIHRoaXMsIHRydWUpOwoJCQlxdWV1ZS5vbigiZmlsZWxvYWQiLCB0aGlzLl9oYW5kbGVNYW5pZmVzdEZpbGVMb2FkLCB0aGlzKTsKCQkJcXVldWUub24oInByb2dyZXNzIiwgdGhpcy5faGFuZGxlTWFuaWZlc3RQcm9ncmVzcywgdGhpcyk7CgkJCXF1ZXVlLm9uKCJlcnJvciIsIHRoaXMuX2hhbmRsZU1hbmlmZXN0RXJyb3IsIHRoaXMsIHRydWUpOwoJCQlxdWV1ZS5sb2FkTWFuaWZlc3QoanNvbi5pbWFnZXMpOwoJCX0KCX07CgoJLyoqCgkgKiBBbiBpdGVtIGZyb20gdGhlIHt7I2Nyb3NzTGluayAiX21hbmlmZXN0UXVldWU6cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fSBoYXMgY29tcGxldGVkLgoJICogQG1ldGhvZCBfaGFuZGxlTWFuaWZlc3RGaWxlTG9hZAoJICogQHBhcmFtIHtFdmVudH0gZXZlbnQKCSAqIEBwcml2YXRlCgkgKi8KCXAuX2hhbmRsZU1hbmlmZXN0RmlsZUxvYWQgPSBmdW5jdGlvbiAoZXZlbnQpIHsKCQl2YXIgaW1hZ2UgPSBldmVudC5yZXN1bHQ7CgkJaWYgKGltYWdlICE9IG51bGwpIHsKCQkJdmFyIGltYWdlcyA9IHRoaXMuZ2V0UmVzdWx0KCkuaW1hZ2VzOwoJCQl2YXIgcG9zID0gaW1hZ2VzLmluZGV4T2YoZXZlbnQuaXRlbS5zcmMpOwoJCQlpbWFnZXNbcG9zXSA9IGltYWdlOwoJCX0KCX07CgoJLyoqCgkgKiBUaGUgaW1hZ2VzIGhhdmUgY29tcGxldGVkIGxvYWRpbmcuIFRoaXMgdHJpZ2dlcnMgdGhlIHt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvY29tcGxldGU6ZXZlbnQifX17ey9jcm9zc0xpbmt9fQoJICoge3sjY3Jvc3NMaW5rICJFdmVudCJ9fXt7L2Nyb3NzTGlua319IGZyb20gdGhlIFNwcml0ZVNoZWV0TG9hZGVyLgoJICogQG1ldGhvZCBfaGFuZGxlTWFuaWZlc3RDb21wbGV0ZQoJICogQHBhcmFtIHtFdmVudH0gZXZlbnQKCSAqIEBwcml2YXRlCgkgKi8KCXAuX2hhbmRsZU1hbmlmZXN0Q29tcGxldGUgPSBmdW5jdGlvbiAoZXZlbnQpIHsKCQl0aGlzLl9yZXN1bHQgPSBuZXcgY3JlYXRlanMuU3ByaXRlU2hlZXQodGhpcy5fcmVzdWx0KTsKCQl0aGlzLl9sb2FkZWRJdGVtcyA9IHRoaXMuX21hbmlmZXN0UXVldWUuZ2V0SXRlbXModHJ1ZSk7CgkJdGhpcy5fc2VuZENvbXBsZXRlKCk7Cgl9OwoKCS8qKgoJICogVGhlIGltYWdlcyB7eyNjcm9zc0xpbmsgIkxvYWRRdWV1ZSJ9fXt7L2Nyb3NzTGlua319IGhhcyByZXBvcnRlZCBwcm9ncmVzcy4KCSAqIEBtZXRob2QgX2hhbmRsZU1hbmlmZXN0UHJvZ3Jlc3MKCSAqIEBwYXJhbSB7UHJvZ3Jlc3NFdmVudH0gZXZlbnQKCSAqIEBwcml2YXRlCgkgKi8KCXAuX2hhbmRsZU1hbmlmZXN0UHJvZ3Jlc3MgPSBmdW5jdGlvbiAoZXZlbnQpIHsKCQl0aGlzLnByb2dyZXNzID0gZXZlbnQucHJvZ3Jlc3MgKiAoMSAtIHMuU1BSSVRFU0hFRVRfUFJPR1JFU1MpICsgcy5TUFJJVEVTSEVFVF9QUk9HUkVTUzsKCQl0aGlzLl9zZW5kUHJvZ3Jlc3ModGhpcy5wcm9ncmVzcyk7Cgl9OwoKCS8qKgoJICogQW4gaW1hZ2UgaGFzIHJlcG9ydGVkIGFuIGVycm9yLgoJICogQG1ldGhvZCBfaGFuZGxlTWFuaWZlc3RFcnJvcgoJICogQHBhcmFtIHtFcnJvckV2ZW50fSBldmVudAoJICogQHByaXZhdGUKCSAqLwoJcC5faGFuZGxlTWFuaWZlc3RFcnJvciA9IGZ1bmN0aW9uIChldmVudCkgewoJCXZhciBuZXdFdmVudCA9IG5ldyBjcmVhdGVqcy5FdmVudCgiZmlsZWVycm9yIik7CgkJbmV3RXZlbnQuaXRlbSA9IGV2ZW50LmRhdGE7CgkJdGhpcy5kaXNwYXRjaEV2ZW50KG5ld0V2ZW50KTsKCX07CgoJY3JlYXRlanMuU3ByaXRlU2hlZXRMb2FkZXIgPSBjcmVhdGVqcy5wcm9tb3RlKFNwcml0ZVNoZWV0TG9hZGVyLCAiQWJzdHJhY3RMb2FkZXIiKTsKCn0oKSk7CgovLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwovLyBTVkdMb2FkZXIuanMKLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCnRoaXMuY3JlYXRlanMgPSB0aGlzLmNyZWF0ZWpzIHx8IHt9OwoKKGZ1bmN0aW9uICgpIHsKCSJ1c2Ugc3RyaWN0IjsKCgkvLyBjb25zdHJ1Y3RvcgoJLyoqCgkgKiBBIGxvYWRlciBmb3IgU1ZHIGZpbGVzLgoJICogQGNsYXNzIFNWR0xvYWRlcgoJICogQHBhcmFtIHtMb2FkSXRlbXxPYmplY3R9IGxvYWRJdGVtCgkgKiBAcGFyYW0ge0Jvb2xlYW59IHByZWZlclhIUgoJICogQGNvbnN0cnVjdG9yCgkgKi8KCWZ1bmN0aW9uIFNWR0xvYWRlcihsb2FkSXRlbSwgcHJlZmVyWEhSKSB7CgkJdGhpcy5BYnN0cmFjdExvYWRlcl9jb25zdHJ1Y3Rvcihsb2FkSXRlbSwgcHJlZmVyWEhSLCBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5TVkcpOwoKCQkvLyBwdWJsaWMgcHJvcGVydGllcwoJCXRoaXMucmVzdWx0Rm9ybWF0dGVyID0gdGhpcy5fZm9ybWF0UmVzdWx0OwoKCQkvLyBwcm90ZWN0ZWQgcHJvcGVydGllcwoJCXRoaXMuX3RhZ1NyY0F0dHJpYnV0ZSA9ICJkYXRhIjsKCgkJaWYgKHByZWZlclhIUikgewoJCQl0aGlzLnNldFRhZyhkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJzdmciKSk7CgkJfSBlbHNlIHsKCQkJdGhpcy5zZXRUYWcoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgib2JqZWN0IikpOwoJCQl0aGlzLmdldFRhZygpLnR5cGUgPSAiaW1hZ2Uvc3ZnK3htbCI7CgkJfQoKCQl0aGlzLmdldFRhZygpLnN0eWxlLnZpc2liaWxpdHkgPSAiaGlkZGVuIjsKCX07CgoJdmFyIHAgPSBjcmVhdGVqcy5leHRlbmQoU1ZHTG9hZGVyLCBjcmVhdGVqcy5BYnN0cmFjdExvYWRlcik7Cgl2YXIgcyA9IFNWR0xvYWRlcjsKCgkvLyBzdGF0aWMgbWV0aG9kcwoJLyoqCgkgKiBEZXRlcm1pbmVzIGlmIHRoZSBsb2FkZXIgY2FuIGxvYWQgYSBzcGVjaWZpYyBpdGVtLiBUaGlzIGxvYWRlciBjYW4gb25seSBsb2FkIGl0ZW1zIHRoYXQgYXJlIG9mIHR5cGUKCSAqIHt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvU1ZHOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0KCSAqIEBtZXRob2QgY2FuTG9hZEl0ZW0KCSAqIEBwYXJhbSB7TG9hZEl0ZW18T2JqZWN0fSBpdGVtIFRoZSBMb2FkSXRlbSB0aGF0IGEgTG9hZFF1ZXVlIGlzIHRyeWluZyB0byBsb2FkLgoJICogQHJldHVybnMge0Jvb2xlYW59IFdoZXRoZXIgdGhlIGxvYWRlciBjYW4gbG9hZCB0aGUgaXRlbS4KCSAqIEBzdGF0aWMKCSAqLwoJcy5jYW5Mb2FkSXRlbSA9IGZ1bmN0aW9uIChpdGVtKSB7CgkJcmV0dXJuIGl0ZW0udHlwZSA9PSBjcmVhdGVqcy5BYnN0cmFjdExvYWRlci5TVkc7Cgl9OwoKCS8vIHByb3RlY3RlZCBtZXRob2RzCgkvKioKCSAqIFRoZSByZXN1bHQgZm9ybWF0dGVyIGZvciBTVkcgZmlsZXMuCgkgKiBAbWV0aG9kIF9mb3JtYXRSZXN1bHQKCSAqIEBwYXJhbSB7QWJzdHJhY3RMb2FkZXJ9IGxvYWRlcgoJICogQHJldHVybnMge09iamVjdH0KCSAqIEBwcml2YXRlCgkgKi8KCXAuX2Zvcm1hdFJlc3VsdCA9IGZ1bmN0aW9uIChsb2FkZXIpIHsKCQkvLyBtaW1lIHNob3VsZCBiZSBpbWFnZS9zdmcreG1sLCBidXQgT3BlcmEgcmVxdWlyZXMgdGV4dC94bWwKCQl2YXIgeG1sID0gY3JlYXRlanMuRGF0YVV0aWxzLnBhcnNlWE1MKGxvYWRlci5nZXRSZXN1bHQodHJ1ZSksICJ0ZXh0L3htbCIpOwoJCXZhciB0YWcgPSBsb2FkZXIuZ2V0VGFnKCk7CgoJCWlmICghdGhpcy5fcHJlZmVyWEhSICYmIGRvY3VtZW50LmJvZHkuY29udGFpbnModGFnKSkgewoJCQlkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKHRhZyk7CgkJfQoKCQlpZiAoeG1sLmRvY3VtZW50RWxlbWVudCAhPSBudWxsKSB7CgkJCXRhZy5hcHBlbmRDaGlsZCh4bWwuZG9jdW1lbnRFbGVtZW50KTsKCQkJdGFnLnN0eWxlLnZpc2liaWxpdHkgPSAidmlzaWJsZSI7CgkJCXJldHVybiB0YWc7CgkJfSBlbHNlIHsgLy8gRm9yIGJyb3dzZXJzIHRoYXQgZG9uJ3Qgc3VwcG9ydCBTVkcsIGp1c3QgZ2l2ZSB0aGVtIHRoZSBYTUwuIChJRSA5LTgpCgkJCXJldHVybiB4bWw7CgkJfQoJfQoKCWNyZWF0ZWpzLlNWR0xvYWRlciA9IGNyZWF0ZWpzLnByb21vdGUoU1ZHTG9hZGVyLCAiQWJzdHJhY3RMb2FkZXIiKTsKCn0oKSk7CgovLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwovLyBYTUxMb2FkZXIuanMKLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCnRoaXMuY3JlYXRlanMgPSB0aGlzLmNyZWF0ZWpzIHx8IHt9OwoKKGZ1bmN0aW9uICgpIHsKCSJ1c2Ugc3RyaWN0IjsKCgkvLyBjb25zdHJ1Y3RvcgoJLyoqCgkgKiBBIGxvYWRlciBmb3IgQ1NTIGZpbGVzLgoJICogQGNsYXNzIFhNTExvYWRlcgoJICogQHBhcmFtIHtMb2FkSXRlbXxPYmplY3R9IGxvYWRJdGVtCgkgKiBAY29uc3RydWN0b3IKCSAqLwoJZnVuY3Rpb24gWE1MTG9hZGVyKGxvYWRJdGVtKSB7CgkJdGhpcy5BYnN0cmFjdExvYWRlcl9jb25zdHJ1Y3Rvcihsb2FkSXRlbSwgdHJ1ZSwgY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuWE1MKTsKCgkJLy8gcHVibGljIHByb3BlcnRpZXMKCQl0aGlzLnJlc3VsdEZvcm1hdHRlciA9IHRoaXMuX2Zvcm1hdFJlc3VsdDsKCX07CgoJdmFyIHAgPSBjcmVhdGVqcy5leHRlbmQoWE1MTG9hZGVyLCBjcmVhdGVqcy5BYnN0cmFjdExvYWRlcik7Cgl2YXIgcyA9IFhNTExvYWRlcjsKCgkvLyBzdGF0aWMgbWV0aG9kcwoJLyoqCgkgKiBEZXRlcm1pbmVzIGlmIHRoZSBsb2FkZXIgY2FuIGxvYWQgYSBzcGVjaWZpYyBpdGVtLiBUaGlzIGxvYWRlciBjYW4gb25seSBsb2FkIGl0ZW1zIHRoYXQgYXJlIG9mIHR5cGUKCSAqIHt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvWE1MOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0uCgkgKiBAbWV0aG9kIGNhbkxvYWRJdGVtCgkgKiBAcGFyYW0ge0xvYWRJdGVtfE9iamVjdH0gaXRlbSBUaGUgTG9hZEl0ZW0gdGhhdCBhIExvYWRRdWV1ZSBpcyB0cnlpbmcgdG8gbG9hZC4KCSAqIEByZXR1cm5zIHtCb29sZWFufSBXaGV0aGVyIHRoZSBsb2FkZXIgY2FuIGxvYWQgdGhlIGl0ZW0uCgkgKiBAc3RhdGljCgkgKi8KCXMuY2FuTG9hZEl0ZW0gPSBmdW5jdGlvbiAoaXRlbSkgewoJCXJldHVybiBpdGVtLnR5cGUgPT0gY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuWE1MOwoJfTsKCgkvLyBwcm90ZWN0ZWQgbWV0aG9kcwoJLyoqCgkgKiBUaGUgcmVzdWx0IGZvcm1hdHRlciBmb3IgWE1MIGZpbGVzLgoJICogQG1ldGhvZCBfZm9ybWF0UmVzdWx0CgkgKiBAcGFyYW0ge0Fic3RyYWN0TG9hZGVyfSBsb2FkZXIKCSAqIEByZXR1cm5zIHtYTUxEb2N1bWVudH0KCSAqIEBwcml2YXRlCgkgKi8KCXAuX2Zvcm1hdFJlc3VsdCA9IGZ1bmN0aW9uIChsb2FkZXIpIHsKCQlyZXR1cm4gY3JlYXRlanMuRGF0YVV0aWxzLnBhcnNlWE1MKGxvYWRlci5nZXRSZXN1bHQodHJ1ZSksICJ0ZXh0L3htbCIpOwoJfTsKCgljcmVhdGVqcy5YTUxMb2FkZXIgPSBjcmVhdGVqcy5wcm9tb3RlKFhNTExvYWRlciwgIkFic3RyYWN0TG9hZGVyIik7Cgp9KCkpOw==" ></script>




<!--
	<script type="text/javascript" src="/jkwii/js/jsdoit/preload/src/preloadjs/loaders/ManifestLoader.js"></script>
	-->
	<script id="script_preloadjs_next_combined_js" src="data:/text/plain;base64,LyoKICogTWFuaWZlc3RMb2FkZXIKICogVmlzaXQgaHR0cDovL2NyZWF0ZWpzLmNvbS8gZm9yIGRvY3VtZW50YXRpb24sIHVwZGF0ZXMgYW5kIGV4YW1wbGVzLgogKgogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTIgZ3NraW5uZXIuY29tLCBpbmMuCiAqCiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uCiAqIG9idGFpbmluZyBhIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uCiAqIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQKICogcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsCiAqIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCiAqIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZQogKiBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZwogKiBjb25kaXRpb25zOgogKgogKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZQogKiBpbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsCiAqIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUwogKiBPRiBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORAogKiBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVAogKiBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwKICogV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HCiAqIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IKICogT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLgogKi8KCi8qKgogKiBAbW9kdWxlIFByZWxvYWRKUwogKi8KCi8vIG5hbWVzcGFjZToKdGhpcy5jcmVhdGVqcyA9IHRoaXMuY3JlYXRlanMgfHwge307CgooZnVuY3Rpb24gKCkgewoJInVzZSBzdHJpY3QiOwoKCS8vIGNvbnN0cnVjdG9yCgkvKioKCSAqIEEgbG9hZGVyIGZvciBKU09OIG1hbmlmZXN0cy4gSXRlbXMgaW5zaWRlIHRoZSBtYW5pZmVzdCBhcmUgbG9hZGVkIGJlZm9yZSB0aGUgbG9hZGVyIGNvbXBsZXRlcy4gVG8gbG9hZCBtYW5pZmVzdHMKCSAqIHVzaW5nIEpTT05QLCBzcGVjaWZ5IGEge3sjY3Jvc3NMaW5rICJMb2FkSXRlbS9jYWxsYmFjazpwcm9wZXJ0eSJ9fXt7L2Nyb3NzTGlua319IGFzIHBhcnQgb2YgdGhlCgkgKiB7eyNjcm9zc0xpbmsgIkxvYWRJdGVtIn19e3svY3Jvc3NMaW5rfX0uCgkgKgoJICogVGhlIGxpc3Qgb2YgZmlsZXMgaW4gdGhlIG1hbmlmZXN0IG11c3QgYmUgZGVmaW5lZCBvbiB0aGUgdG9wLWxldmVsIEpTT04gb2JqZWN0IGluIGEgYG1hbmlmZXN0YCBwcm9wZXJ0eS4gVGhpcwoJICogZXhhbXBsZSBzaG93cyBhIHNhbXBsZSBtYW5pZmVzdCBkZWZpbml0aW9uLCBhcyB3ZWxsIGFzIGhvdyB0byB0byBpbmNsdWRlIGEgc3ViLW1hbmlmZXN0LgoJICoKCSAqIAkJewoJICogCQkJInBhdGgiOiAiYXNzZXRzLyIsCgkgKgkgCSAgICAibWFuaWZlc3QiOiBbCgkgKgkJCQkiaW1hZ2UucG5nIiwKCSAqCQkJCXsic3JjIjogImltYWdlMi5wbmciLCAiaWQiOiJpbWFnZTIifSwKCSAqCQkJCXsic3JjIjogInN1Yi1tYW5pZmVzdC5qc29uIiwgInR5cGUiOiJtYW5pZmVzdCIsICJjYWxsYmFjayI6Impzb25DYWxsYmFjayJ9CgkgKgkgCSAgICBdCgkgKgkgCX0KCSAqCgkgKiBXaGVuIGEgTWFuaWZlc3RMb2FkZXIgaGFzIGNvbXBsZXRlZCBsb2FkaW5nLCB0aGUgcGFyZW50IGxvYWRlciAodXN1YWxseSBhIHt7I2Nyb3NzTGluayAiTG9hZFF1ZXVlIn19e3svY3Jvc3NMaW5rfX0sCgkgKiBidXQgY291bGQgYWxzbyBiZSBhbm90aGVyIE1hbmlmZXN0TG9hZGVyKSB3aWxsIGluaGVyaXQgYWxsIHRoZSBsb2FkZWQgaXRlbXMsIHNvIHlvdSBjYW4gYWNjZXNzIHRoZW0gZGlyZWN0bHkuCgkgKgoJICogTm90ZSB0aGF0IHRoZSB7eyNjcm9zc0xpbmsgIkpTT05Mb2FkZXIifX17ey9jcm9zc0xpbmt9fSBhbmQge3sjY3Jvc3NMaW5rICJKU09OUExvYWRlciJ9fXt7L2Nyb3NzTGlua319IGFyZQoJICogaGlnaGVyIHByaW9yaXR5IGxvYWRlcnMsIHNvIG1hbmlmZXN0cyA8c3Ryb25nPm11c3Q8L3N0cm9uZz4gc2V0IHRoZSB7eyNjcm9zc0xpbmsgIkxvYWRJdGVtIn19e3svY3Jvc3NMaW5rfX0KCSAqIHt7I2Nyb3NzTGluayAiTG9hZEl0ZW0vdHlwZTpwcm9wZXJ0eSJ9fXt7L2Nyb3NzTGlua319IHByb3BlcnR5IHRvIHt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvTUFOSUZFU1Q6cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fS4KCSAqIEBjbGFzcyBNYW5pZmVzdExvYWRlcgoJICogQHBhcmFtIHtMb2FkSXRlbXxPYmplY3R9IGxvYWRJdGVtCgkgKiBAZXh0ZW5kcyBBYnN0cmFjdExvYWRlcgoJICogQGNvbnN0cnVjdG9yCgkgKi8KCWZ1bmN0aW9uIE1hbmlmZXN0TG9hZGVyKGxvYWRJdGVtKSB7CgkJdGhpcy5BYnN0cmFjdExvYWRlcl9jb25zdHJ1Y3Rvcihsb2FkSXRlbSwgbnVsbCwgY3JlYXRlanMuQWJzdHJhY3RMb2FkZXIuTUFOSUZFU1QpOwoKCQkvLyBwcm90ZWN0ZWQgcHJvcGVydGllcwoJCS8qKgoJCSAqIEFuIGludGVybmFsIHt7I2Nyb3NzTGluayAiTG9hZFF1ZXVlIn19e3svY3Jvc3NMaW5rfX0gdGhhdCBsb2FkcyB0aGUgY29udGVudHMgb2YgdGhlIG1hbmlmZXN0LgoJCSAqIEBwcm9wZXJ0eSBfbWFuaWZlc3RRdWV1ZQoJCSAqIEB0eXBlIHtMb2FkUXVldWV9CgkJICogQHByaXZhdGUKCQkgKi8KCQl0aGlzLl9tYW5pZmVzdFF1ZXVlID0gbnVsbDsKCX07CgoJdmFyIHAgPSBjcmVhdGVqcy5leHRlbmQoTWFuaWZlc3RMb2FkZXIsIGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyKTsKCXZhciBzID0gTWFuaWZlc3RMb2FkZXI7CgoJLy8gc3RhdGljIHByb3BlcnRpZXMKCS8qKgoJICogVGhlIGFtb3VudCBvZiBwcm9ncmVzcyB0aGF0IHRoZSBtYW5pZmVzdCBpdHNlbGYgdGFrZXMgdXAuCgkgKiBAcHJvcGVydHkgTUFOSUZFU1RfUFJPR1JFU1MKCSAqIEB0eXBlIHtudW1iZXJ9CgkgKiBAZGVmYXVsdCAwLjI1ICgyNSUpCgkgKiBAcHJpdmF0ZQoJICogQHN0YXRpYwoJICovCglzLk1BTklGRVNUX1BST0dSRVNTID0gMC4yNTsKCgkvLyBzdGF0aWMgbWV0aG9kcwoJLyoqCgkgKiBEZXRlcm1pbmVzIGlmIHRoZSBsb2FkZXIgY2FuIGxvYWQgYSBzcGVjaWZpYyBpdGVtLiBUaGlzIGxvYWRlciBjYW4gb25seSBsb2FkIGl0ZW1zIHRoYXQgYXJlIG9mIHR5cGUKCSAqIHt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvTUFOSUZFU1Q6cHJvcGVydHkifX17ey9jcm9zc0xpbmt9fQoJICogQG1ldGhvZCBjYW5Mb2FkSXRlbQoJICogQHBhcmFtIHtMb2FkSXRlbXxPYmplY3R9IGl0ZW0gVGhlIExvYWRJdGVtIHRoYXQgYSBMb2FkUXVldWUgaXMgdHJ5aW5nIHRvIGxvYWQuCgkgKiBAcmV0dXJucyB7Qm9vbGVhbn0gV2hldGhlciB0aGUgbG9hZGVyIGNhbiBsb2FkIHRoZSBpdGVtLgoJICogQHN0YXRpYwoJICovCglzLmNhbkxvYWRJdGVtID0gZnVuY3Rpb24gKGl0ZW0pIHsKCQlyZXR1cm4gaXRlbS50eXBlID09IGNyZWF0ZWpzLkFic3RyYWN0TG9hZGVyLk1BTklGRVNUOwoJfTsKCgkvLyBwdWJsaWMgbWV0aG9kcwoJcC5sb2FkID0gZnVuY3Rpb24gKCkgewoJCXRoaXMuQWJzdHJhY3RMb2FkZXJfbG9hZCgpOwoJfTsKCgkvLyBwcm90ZWN0ZWQgbWV0aG9kcwoJcC5fY3JlYXRlUmVxdWVzdCA9IGZ1bmN0aW9uKCkgewoJCXZhciBjYWxsYmFjayA9IHRoaXMuX2l0ZW0uY2FsbGJhY2s7CgkJaWYgKGNhbGxiYWNrICE9IG51bGwpIHsKCQkJdGhpcy5fcmVxdWVzdCA9IG5ldyBjcmVhdGVqcy5KU09OUExvYWRlcih0aGlzLl9pdGVtKTsKCQl9IGVsc2UgewoJCQl0aGlzLl9yZXF1ZXN0ID0gbmV3IGNyZWF0ZWpzLkpTT05Mb2FkZXIodGhpcy5faXRlbSk7CgkJfQoJfTsKCglwLmhhbmRsZUV2ZW50ID0gZnVuY3Rpb24gKGV2ZW50KSB7CgkJc3dpdGNoIChldmVudC50eXBlKSB7CgkJCWNhc2UgImNvbXBsZXRlIjoKCQkJCXRoaXMuX3Jhd1Jlc3VsdCA9IGV2ZW50LnRhcmdldC5nZXRSZXN1bHQodHJ1ZSk7CgkJCQl0aGlzLl9yZXN1bHQgPSBldmVudC50YXJnZXQuZ2V0UmVzdWx0KCk7CgkJCQl0aGlzLl9zZW5kUHJvZ3Jlc3Mocy5NQU5JRkVTVF9QUk9HUkVTUyk7CgkJCQl0aGlzLl9sb2FkTWFuaWZlc3QodGhpcy5fcmVzdWx0KTsKCQkJCXJldHVybjsKCQkJY2FzZSAicHJvZ3Jlc3MiOgoJCQkJZXZlbnQubG9hZGVkICo9IHMuTUFOSUZFU1RfUFJPR1JFU1M7CgkJCQl0aGlzLnByb2dyZXNzID0gZXZlbnQubG9hZGVkIC8gZXZlbnQudG90YWw7CgkJCQlpZiAoaXNOYU4odGhpcy5wcm9ncmVzcykgfHwgdGhpcy5wcm9ncmVzcyA9PSBJbmZpbml0eSkgeyB0aGlzLnByb2dyZXNzID0gMDsgfQoJCQkJdGhpcy5fc2VuZFByb2dyZXNzKGV2ZW50KTsKCQkJCXJldHVybjsKCQl9CgkJdGhpcy5BYnN0cmFjdExvYWRlcl9oYW5kbGVFdmVudChldmVudCk7Cgl9OwoKCXAuZGVzdHJveSA9IGZ1bmN0aW9uKCkgewoJCXRoaXMuQWJzdHJhY3RMb2FkZXJfZGVzdHJveSgpOwoJCXRoaXMuX21hbmlmZXN0UXVldWUuY2xvc2UoKTsKCX07CgoJLyoqCgkgKiBDcmVhdGUgYW5kIGxvYWQgdGhlIG1hbmlmZXN0IGl0ZW1zIG9uY2UgdGhlIGFjdHVhbCBtYW5pZmVzdCBoYXMgYmVlbiBsb2FkZWQuCgkgKiBAbWV0aG9kIF9sb2FkTWFuaWZlc3QKCSAqIEBwYXJhbSB7T2JqZWN0fSBqc29uCgkgKiBAcHJpdmF0ZQoJICovCglwLl9sb2FkTWFuaWZlc3QgPSBmdW5jdGlvbiAoanNvbikgewoJCWlmIChqc29uICYmIGpzb24ubWFuaWZlc3QpIHsKCQkJdmFyIHF1ZXVlID0gdGhpcy5fbWFuaWZlc3RRdWV1ZSA9IG5ldyBjcmVhdGVqcy5Mb2FkUXVldWUoKTsKCQkJcXVldWUub24oImZpbGVsb2FkIiwgdGhpcy5faGFuZGxlTWFuaWZlc3RGaWxlTG9hZCwgdGhpcyk7CgkJCXF1ZXVlLm9uKCJwcm9ncmVzcyIsIHRoaXMuX2hhbmRsZU1hbmlmZXN0UHJvZ3Jlc3MsIHRoaXMpOwoJCQlxdWV1ZS5vbigiY29tcGxldGUiLCB0aGlzLl9oYW5kbGVNYW5pZmVzdENvbXBsZXRlLCB0aGlzLCB0cnVlKTsKCQkJcXVldWUub24oImVycm9yIiwgdGhpcy5faGFuZGxlTWFuaWZlc3RFcnJvciwgdGhpcywgdHJ1ZSk7CgkJCXF1ZXVlLmxvYWRNYW5pZmVzdChqc29uKTsKCQl9IGVsc2UgewoJCQl0aGlzLl9zZW5kQ29tcGxldGUoKTsKCQl9Cgl9OwoKCS8qKgoJICogQW4gaXRlbSBmcm9tIHRoZSB7eyNjcm9zc0xpbmsgIl9tYW5pZmVzdFF1ZXVlOnByb3BlcnR5In19e3svY3Jvc3NMaW5rfX0gaGFzIGNvbXBsZXRlZC4KCSAqIEBtZXRob2QgX2hhbmRsZU1hbmlmZXN0RmlsZUxvYWQKCSAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50CgkgKiBAcHJpdmF0ZQoJICovCglwLl9oYW5kbGVNYW5pZmVzdEZpbGVMb2FkID0gZnVuY3Rpb24gKGV2ZW50KSB7CgkJZXZlbnQudGFyZ2V0ID0gbnVsbDsKCQl0aGlzLmRpc3BhdGNoRXZlbnQoZXZlbnQpOwoJfTsKCgkvKioKCSAqIFRoZSBtYW5pZmVzdCBoYXMgY29tcGxldGVkIGxvYWRpbmcuIFRoaXMgdHJpZ2dlcnMgdGhlIHt7I2Nyb3NzTGluayAiQWJzdHJhY3RMb2FkZXIvY29tcGxldGU6ZXZlbnQifX17ey9jcm9zc0xpbmt9fQoJICoge3sjY3Jvc3NMaW5rICJFdmVudCJ9fXt7L2Nyb3NzTGlua319IGZyb20gdGhlIE1hbmlmZXN0TG9hZGVyLgoJICogQG1ldGhvZCBfaGFuZGxlTWFuaWZlc3RDb21wbGV0ZQoJICogQHBhcmFtIHtFdmVudH0gZXZlbnQKCSAqIEBwcml2YXRlCgkgKi8KCXAuX2hhbmRsZU1hbmlmZXN0Q29tcGxldGUgPSBmdW5jdGlvbiAoZXZlbnQpIHsKCQl0aGlzLl9sb2FkZWRJdGVtcyA9IHRoaXMuX21hbmlmZXN0UXVldWUuZ2V0SXRlbXModHJ1ZSk7CgkJdGhpcy5fc2VuZENvbXBsZXRlKCk7Cgl9OwoKCS8qKgoJICogVGhlIG1hbmlmZXN0IGhhcyByZXBvcnRlZCBwcm9ncmVzcy4KCSAqIEBtZXRob2QgX2hhbmRsZU1hbmlmZXN0UHJvZ3Jlc3MKCSAqIEBwYXJhbSB7UHJvZ3Jlc3NFdmVudH0gZXZlbnQKCSAqIEBwcml2YXRlCgkgKi8KCXAuX2hhbmRsZU1hbmlmZXN0UHJvZ3Jlc3MgPSBmdW5jdGlvbiAoZXZlbnQpIHsKCQl0aGlzLnByb2dyZXNzID0gZXZlbnQucHJvZ3Jlc3MgKiAoMSAtIHMuTUFOSUZFU1RfUFJPR1JFU1MpICsgcy5NQU5JRkVTVF9QUk9HUkVTUzsKCQl0aGlzLl9zZW5kUHJvZ3Jlc3ModGhpcy5wcm9ncmVzcyk7Cgl9OwoKCS8qKgoJICogVGhlIG1hbmlmZXN0IGhhcyByZXBvcnRlZCBhbiBlcnJvciB3aXRoIG9uZSBvZiB0aGUgZmlsZXMuCgkgKiBAbWV0aG9kIF9oYW5kbGVNYW5pZmVzdEVycm9yCgkgKiBAcGFyYW0ge0Vycm9yRXZlbnR9IGV2ZW50CgkgKiBAcHJpdmF0ZQoJICovCglwLl9oYW5kbGVNYW5pZmVzdEVycm9yID0gZnVuY3Rpb24gKGV2ZW50KSB7CgkJdmFyIG5ld0V2ZW50ID0gbmV3IGNyZWF0ZWpzLkV2ZW50KCJmaWxlZXJyb3IiKTsKCQluZXdFdmVudC5pdGVtID0gZXZlbnQuZGF0YTsKCQl0aGlzLmRpc3BhdGNoRXZlbnQobmV3RXZlbnQpOwoJfTsKCgljcmVhdGVqcy5NYW5pZmVzdExvYWRlciA9IGNyZWF0ZWpzLnByb21vdGUoTWFuaWZlc3RMb2FkZXIsICJBYnN0cmFjdExvYWRlciIpOwoKfSgpKTsK" ></script>



<!-- We also provide hosted minified versions of all CreateJS libraries.
	http://code.createjs.com -->

<script id="editable">
	var preload;

	function init_jaxgrid() {
		// Create a new queue.
		//preload = new createjs.LoadQueue(true, "assets/");

		// Use this instead to favor tag loading
		preload = new createjs.LoadQueue(true);

		createjs.Sound.registerPlugins([createjs.HTMLAudioPlugin]);  // need this so it doesn't default to Web Audio
		preload.installPlugin(createjs.Sound);

		preload.on("fileload", handleFileLoaded);
		preload.on("error", handleError);
	}

	function loadManifest() {
		preload.loadManifest({src: "/jkwii/js/jsdoit/preload/_assets/static/MediaGridManifest.json", callback: "loadMediaGrid", type: "manifest"}, true, "/jkwii/js/jsdoit/preload/_assets/");
	}

	function stop() {
		if (preload != null) {
			preload.close();
		}
	}

	// Load a single asset.
	function loadAsset(target) {
		var div = document.getElementById(target.id);
		div.innerHTML = "<label>Loading...</label>";

		var type = target.attributes.getNamedItem("type");

		var item = {
			src: target.id,
			id: target.id
		};
		
		if (!type) {
			preload.loadManifest({path: "/jkwii/js/jsdoit/preload/_assets/", manifest: [item]});
		} else {
			item.type = type.value;
			item.callback = "maps";
			preload.loadFile(item, true);
		}
	}

	// Once each file is loaded, show it. Each ID corresponds to the related DIV.
	function handleFileLoaded(event) {
		var item = event.item;
		var id = item.id;
		var result = event.result;

		var div = document.getElementById(id);
		if (div == null) {
			console.log("Could not find DIV:", id, event);
			return;
		}
		switch (item.type) {
			case createjs.AbstractLoader.CSS:
				(document.head || document.getElementsByTagName("head")[0]).appendChild(result);
				div.innerHTML = "<label>CSS is complete :)</label>";
				break;

			case createjs.AbstractLoader.IMAGE:
				div.innerText = "";
				result.width = div.clientWidth;
				result.height = div.clientHeight;
				div.appendChild(result);
				break;

			case createjs.AbstractLoader.JAVASCRIPT:
				document.body.appendChild(result);
				div.innerHTML = "<label>Javascript is complete :)</label>";
				break;

			case createjs.AbstractLoader.JSON:
			case createjs.AbstractLoader.XML:
				div.innerHTML = "<label>" +
						item.type +
						" loaded: <br /><xmp>" +
						(event.rawResult ? event.rawResult : '') +
						"</xmp></label>";
				break;
			case createjs.AbstractLoader.JSONP:
				div.innerHTML = "<label>JSONP is complete :)</label>";
				break;
			case createjs.AbstractLoader.SOUND:
				document.body.appendChild(result);
				result.play();
				div.innerHTML = "<label>Sound is complete :)</label>";
				break;

			case createjs.AbstractLoader.SVG:
				div.innerHTML = "";
				div.appendChild(result);
				break
		}
		div.style.backgroundColor = "#222222";
	}

	// A file failed to load.
	function handleError(event) {
		var item = event.data;
		var div = document.getElementById(item.id);
		if (div != null) {
			div.innerHTML = "<label>Error " + (item.id == "NoFileHere.png"?":)":":(")+"</label>";
			div.className = "gridBox error";
		}
	}
</script>

</body>
</html>
//


koh5_pano



Your browser does not support the HTML5 canvas element.


Drag mouse to navigate.

Navigation





17.Aug.2010, Martin Wengenmayer