{
	"address": "8624b52f9ddcd04a",
	"balance": "1896976029620",
	"keys": [
		{
			"index": "0",
			"public_key": "0x6e4f43f79d3c1d8cacb3d5f3e7aeedb29feaeb4559fdb71a97e2fd0438565310e87670035d83bc10fe67fe314dba5363c81654595d64884b1ecad1512a64e65e",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "57",
			"weight": "1000",
			"revoked": true
		},
		{
			"index": "1",
			"public_key": "0xb8cf3deaf03db95abc406f0eb7b35c83e6c131919ca4faf11d0aeb66b832e4ea4ae9bee1ce0f93613e6f8bcf40a18a7a90f2de622f2b9de91171d2cdeb90ae86",
			"signing_algorithm": "ECDSA_secp256k1",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "2",
			"weight": "250",
			"revoked": true
		},
		{
			"index": "2",
			"public_key": "0xf4c49ec76efeb369cedefe511ed7def63d7090d80577d238e216d8ef88682fae151b4af30be7b99ef999547ccb3c1dc6f3b94865ee2e9e4a1572960d31a73694",
			"signing_algorithm": "ECDSA_secp256k1",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "0",
			"weight": "250",
			"revoked": true
		},
		{
			"index": "3",
			"public_key": "0x5c421222950a6f41b41420f032cbb1fb9c1902ad205b76d6fbd943c92eb6459e780cffa92d137bd4a754976135774d6dac860062922aea93bc9ff834c4c95790",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "2",
			"weight": "250",
			"revoked": true
		},
		{
			"index": "4",
			"public_key": "0xbcd1fa5093e884c028e36a47a5ba4cd4e55d08f931685c8a28e5eee9fe8573967f480df8049b1b6f03e40ab072d227592ba62927db64c9c2655fef26c65b836b",
			"signing_algorithm": "ECDSA_secp256k1",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "0",
			"weight": "250",
			"revoked": true
		},
		{
			"index": "5",
			"public_key": "0x181a71ed25fc85443aebcf6ec708241498f93a3b395e628d98685b4d78e3242c1e1b11edeb0c143d752df5b155fce47df223e7a535b18b8409b2452d4d1df5c9",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "88",
			"weight": "250",
			"revoked": false
		},
		{
			"index": "6",
			"public_key": "0x5c999370c484e2963d4dce5b75e4c48a1e901518d34f5abfe6e13de064e71c31f1412068e9f20b4692764287fd71f7cac2924f04fec270aa8f7476eba96aa965",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "26",
			"weight": "250",
			"revoked": false
		},
		{
			"index": "7",
			"public_key": "0xb049757d6412fdecd6b1a67f94cbf07dca5c0102831a9b3db2d17ee3a3a9fcc9081311c92b5479c9ea1cdcf49d3f4cfa81990c35849a3eb1a31dbe0c6b257f0d",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "0",
			"weight": "250",
			"revoked": false
		},
		{
			"index": "8",
			"public_key": "0x708c3b36830e9d8dcfac9536fcec3df02fc24b82fbb793d5e3206c64ded49f8e11bcf2aa535b2c2f8e6ace17b6f3c8c6edd0d041222023e8e4b0729b07726b74",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "0",
			"weight": "250",
			"revoked": false
		},
		{
			"index": "9",
			"public_key": "0xee4aec89e6d83fe563ee93de01374961fcf117b7e746c78b3097f54b630a053fd4ee70a4bde974ce12d71deb444c5c23c224ad92f05a6f72b54742fd9700a3b7",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "0",
			"weight": "250",
			"revoked": true
		},
		{
			"index": "10",
			"public_key": "0x475aac6dc9e0a045323f8e24f0aa8ebbec9dfedc34a5cc47bbb206f8d639f03812231731a9608edab6582056ab0a3281350666330daca384c7dff777cc6823be",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "0",
			"weight": "250",
			"revoked": false
		},
		{
			"index": "11",
			"public_key": "0x9a9b21fd1a3bba399fc88289da202d14fd3dc03498f06d77af15f2c30a30f4138118410d7ade3a21a103752b385b15abbeca50d271583de0eb5bb0465310baa3",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "0",
			"weight": "250",
			"revoked": false
		}
	],
	"contracts": {
		"FlowClusterQC": "Ci8qIAoqCiogIE1hbmFnZXMgdGhlIHByb2Nlc3Mgb2YgY29sbGVjdGluZyB2b3RlcyBmb3IgdGhlIHJvb3QgcXVvcnVtIGNlcnRpZmljYXRlIG9mIHRoZSB1cGNvbWluZwoqICBlcG9jaCBmb3IgYWxsIGNvbGxlY3Rpb24gbm9kZSBjbHVzdGVycyBhc3NpZ25lZCBmb3IgdGhlIHVwY29taW5nIGVwb2NoLgoqCiogIFdoZW4gY29sbGVjdG9yIG5vZGVzIGFyZSBmaXJzdCByZWdpc3RlcmVkLCB0aGV5IGNhbiByZXF1ZXN0IGEgVm90ZXIgb2JqZWN0IGZyb20gdGhpcyBjb250cmFjdC4KKiAgVGhleSdsbCB1c2UgdGhpcyBvYmplY3QgZm9yIGV2ZXJ5IHN1YnNlcXVlbnQgZXBvY2ggd2hlcmUgdGhleSBhcmUgYSBzdGFrZWQgY29sbGVjdG9yIG5vZGUuCioKKiAgQXQgdGhlIGJlZ2lubmluZyBvZiBlYWNoIEVwb2NoU2V0dXAgcGhhc2UsIHRoZSBhZG1pbiBpbml0aWFsaXplcyB0aGlzIGNvbnRyYWN0IHdpdGgKKiAgdGhlIGNvbGxlY3RvciBjbHVzdGVycyBmb3IgdGhlIHVwY29taW5nIGVwb2NoLiBFYWNoIGNvbGxlY3RvciBub2RlIGhhcyBhIHNpbmdsZSB2b3RlCiogIHRoYXQgaXMgYWxsb2NhdGVkIGZvciB0aGVtIGFuZCB0aGV5IGNhbiBvbmx5IGNhbGwgdGhlaXIgYHZvdGVgIGZ1bmN0aW9uIG9uY2UuCiogIAoqICBPbmNlIGFsbCB0aGUgY2x1c3RlcnMgaGF2ZSByZWNlaXZlZCBlbm91Z2ggaWRlbnRpY2FsIHZvdGVzIHRvIHN1cnBhc3MgdGhlaXIgd2VpZ2h0IHRocmVzaG9sZCwKKiAgVGhlIFFDIGdlbmVyYXRpb24gcGhhc2UgaXMgZmluaXNoZWQgYW5kIHRoZSBhZG1pbiB3aWxsIGVuZCB0aGUgdm90aW5nLgoqICBBdCBhbnkgcG9pbnQsIGFueW9uZSBjYW4gcXVlcnkgdGhlIHZvdGluZyBpbmZvcm1hdGlvbiBmb3IgdGhlIGNsdXN0ZXJzIAoqICBieSB1c2luZyB0aGUgYGdldENsdXN0ZXJzYCBmdW5jdGlvbi4KKiAKKiAgVGhpcyBjb250cmFjdCBpcyBhIG1lbWJlciBvZiBhIHNlcmllcyBvZiBlcG9jaCBzbWFydCBjb250cmFjdHMgd2hpY2ggY29vcmRpbmF0ZXMgdGhlIAoqICBwcm9jZXNzIG9mIHRyYW5zaXRpb25pbmcgYmV0d2VlbiBlcG9jaHMgaW4gRmxvdy4KKi8KCmltcG9ydCBDcnlwdG8KCmFjY2VzcyhhbGwpIGNvbnRyYWN0IEZsb3dDbHVzdGVyUUMgewoKICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICAvLyBDT05UUkFDVCBWQVJJQUJMRVMKICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgogICAgLy8vIEluZGljYXRlcyB3aGV0aGVyIHZvdGVzIGFyZSBjdXJyZW50bHkgYmVpbmcgY29sbGVjdGVkLgogICAgLy8vIElmIGZhbHNlLCBubyBub2RlIG9wZXJhdG9yIHdpbGwgYmUgYWJsZSB0byBzdWJtaXQgdm90ZXMKICAgIGFjY2VzcyhhbGwpIHZhciBpblByb2dyZXNzOiBCb29sCgogICAgLy8vIFRoZSBjb2xsZWN0aW9uIG5vZGUgY2x1c3RlcnMgZm9yIHRoZSBjdXJyZW50IGVwb2NoCiAgICBhY2Nlc3MoYWNjb3VudCkgdmFyIGNsdXN0ZXJzOiBbQ2x1c3Rlcl0KCiAgICAvLy8gSW5kaWNhdGVzIGlmIGEgdm90ZXIgcmVzb3VyY2UgaGFzIGFscmVhZHkgYmVlbiBjbGFpbWVkIGJ5IGEgbm9kZSBJRAogICAgLy8vIGZyb20gdGhlIGlkZW50aXR5IHRhYmxlIGNvbnRyYWN0CiAgICAvLy8gTm9kZSBJRHMgaGF2ZSB0byBjbGFpbSBhIHZvdGVyIG9uY2UKICAgIC8vLyBvbmUgbm9kZSB3aWxsIHVzZSB0aGUgc2FtZSBzcGVjaWZpYyBJRCBhbmQgVm90ZXIgcmVzb3VyY2UgZm9yIGFsbCB0aW1lCiAgICAvLy8gYG5pbGAgbWVhbnMgdGhhdCB0aGVyZSBpcyBubyB2b3RpbmcgY2FwYWJpbGl0eSBmb3IgdGhlIG5vZGUgSUQKICAgIC8vLyBmYWxzZSBtZWFucyB0aGF0IGEgdm90ZXIgY2FwYWJpbGl0eSBmb3IgdGhlIElELCBidXQgaXQgaGFzbid0IGJlZW4gY2xhaW1lZAogICAgLy8vIHRydWUgbWVhbnMgdGhhdCB0aGUgdm90ZXIgY2FwYWJpbGl0eSBoYXMgYmVlbiBjbGFpbWVkIGJ5IHRoZSBub2RlCiAgICBhY2Nlc3MoYWNjb3VudCkgdmFyIHZvdGVyQ2xhaW1lZDoge1N0cmluZzogQm9vbH0KCiAgICAvLy8gSW5kaWNhdGVzIHdoYXQgY2x1c3RlciBhIG5vZGUgaXMgaW4gZm9yIHRoZSBjdXJyZW50IGVwb2NoCiAgICAvLy8gVmFsdWUgaXMgYSBjbHVzdGVyIGluZGV4CiAgICBhY2Nlc3MoY29udHJhY3QpIHZhciBub2RlQ2x1c3Rlcjoge1N0cmluZzogVUludDE2fQoKICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICAvLyBDT05UUkFDVCBDT05TVEFOVFMKICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgogICAgLy8vIENhbm9uaWNhbCBwYXRocyBmb3IgYWRtaW4gYW5kIHZvdGVyIHJlc291cmNlcwogICAgYWNjZXNzKGFsbCkgbGV0IEFkbWluU3RvcmFnZVBhdGg6IFN0b3JhZ2VQYXRoCiAgICBhY2Nlc3MoYWxsKSBsZXQgVm90ZXJTdG9yYWdlUGF0aDogU3RvcmFnZVBhdGgKCiAgICAvLy8gUmVwcmVzZW50cyBhIGNvbGxlY3Rpb24gbm9kZSBjbHVzdGVyIGZvciBhIGdpdmVuIGVwb2NoLiAKICAgIGFjY2VzcyhhbGwpIHN0cnVjdCBDbHVzdGVyIHsKCiAgICAgICAgLy8vIFRoZSBpbmRleCBvZiB0aGUgY2x1c3RlciB3aXRoaW4gdGhlIGNsdXN0ZXIgYXJyYXkuIFRoaXMgdW5pcXVlbHkgaWRlbnRpZmllcwogICAgICAgIC8vLyBhIGNsdXN0ZXIgZm9yIGEgZ2l2ZW4gZXBvY2gKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgaW5kZXg6IFVJbnQxNgoKICAgICAgICAvLy8gV2VpZ2h0cyBmb3IgZWFjaCBub2RlSUQgaW4gdGhlIGNsdXN0ZXIKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgbm9kZVdlaWdodHM6IHtTdHJpbmc6IFVJbnQ2NH0KCiAgICAgICAgLy8vIFRoZSB0b3RhbCBub2RlIHdlaWdodCBvZiBhbGwgdGhlIG5vZGVzIGluIHRoZSBjbHVzdGVyCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IHRvdGFsV2VpZ2h0OiBVSW50NjQKCiAgICAgICAgLy8vIFZvdGVzIHRoYXQgbm9kZXMgY2xhaW0gYXQgdGhlIGJlZ2lubmluZyBvZiBlYWNoIEVwb2NoU2V0dXAgcGhhc2UKICAgICAgICAvLy8gS2V5IGlzIG5vZGUgSUQgZnJvbSB0aGUgaWRlbnRpdHkgdGFibGUgY29udHJhY3QKICAgICAgICAvLy8gVm90ZSByZXNvdXJjZXMgd2l0aG91dCBzaWduYXR1cmVzIG9yIG1lc3NhZ2VzIGZvciBlYWNoIG5vZGUgYXJlIHN0b3JlZCBoZXJlCiAgICAgICAgLy8vIGF0IHRoZSBiZWdpbm5pbmcgb2YgZWFjaCBlcG9jaCBzZXR1cCBwaGFzZS4gCiAgICAgICAgLy8vIFdoZW4gYSBub2RlIHN1Ym1pdHMgYSB2b3RlLCB0aGUgdm90ZSBmdW5jdGlvbiB0YWtlcyBpdCBvdXQgb2YgdGhpcyBtYXAsCiAgICAgICAgLy8vIGFkZHMgdGhlaXIgc2lnbmF0dXJlIGFuZCBtZXNzYWdlLCB0aGVuIGFkZHMgaXQgYmFjayB0byB0aGlzIHZvdGUgbGlzdC4KICAgICAgICAvLy8gSWYgYSBub2RlIGhhcyB2b3RlZCwgdGhlaXIgYHNpZ25hdHVyZWAgYW5kIGBtZXNzYWdlYCBmaWVsZCB3aWxsIGJlIG5vbi1gbmlsYAogICAgICAgIC8vLyBJZiBhIG5vZGUgaGFzbid0IHZvdGVkLCB0aGVpciBgc2lnbmF0dXJlYCBhbmQgYG1lc3NhZ2VgIGZpZWxkIHdpbGwgYmUgYG5pbGAKICAgICAgICBhY2Nlc3MoYWxsKSB2YXIgZ2VuZXJhdGVkVm90ZXM6IHtTdHJpbmc6IFZvdGV9CgogICAgICAgIC8vLyBUcmFja3MgZWFjaCB1bmlxdWUgdm90ZSBhbmQgaG93IG11Y2ggY29tYmluZWQgd2VpZ2h0IGhhcyBiZWVuIHNlbnQgZm9yIHRoZSB2b3RlCiAgICAgICAgYWNjZXNzKGFsbCkgdmFyIHVuaXF1ZVZvdGVNZXNzYWdlVG90YWxXZWlnaHRzOiB7U3RyaW5nOiBVSW50NjR9CgogICAgICAgIGluaXQoaW5kZXg6IFVJbnQxNiwgbm9kZVdlaWdodHM6IHtTdHJpbmc6IFVJbnQ2NH0pIHsKICAgICAgICAgICAgc2VsZi5pbmRleCA9IGluZGV4CiAgICAgICAgICAgIHNlbGYubm9kZVdlaWdodHMgPSBub2RlV2VpZ2h0cwoKICAgICAgICAgICAgdmFyIHRvdGFsV2VpZ2h0OiBVSW50NjQgPSAwCiAgICAgICAgICAgIGZvciB3ZWlnaHQgaW4gbm9kZVdlaWdodHMudmFsdWVzIHsKICAgICAgICAgICAgICAgIHRvdGFsV2VpZ2h0ID0gdG90YWxXZWlnaHQgKyB3ZWlnaHQKICAgICAgICAgICAgfQogICAgICAgICAgICBzZWxmLnRvdGFsV2VpZ2h0ID0gdG90YWxXZWlnaHQKICAgICAgICAgICAgc2VsZi5nZW5lcmF0ZWRWb3RlcyA9IHt9CiAgICAgICAgICAgIHNlbGYudW5pcXVlVm90ZU1lc3NhZ2VUb3RhbFdlaWdodHMgPSB7fQogICAgICAgIH0KCiAgICAgICAgLy8vIFJldHVybnMgdGhlIG51bWJlciBvZiBub2RlcyBpbiB0aGUgY2x1c3RlcgogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBzaXplKCk6IFVJbnQxNiB7CiAgICAgICAgICAgIHJldHVybiBVSW50MTYoc2VsZi5ub2RlV2VpZ2h0cy5sZW5ndGgpIAogICAgICAgIH0KCiAgICAgICAgLy8vIFJldHVybnMgdGhlIG1pbmltdW0gc3VtIG9mIHZvdGUgd2VpZ2h0IHJlcXVpcmVkIGluIG9yZGVyIHRvIGJlIGFibGUgdG8gZ2VuZXJhdGUgYQogICAgICAgIC8vLyB2YWxpZCBxdW9ydW0gY2VydGlmaWNhdGUgZm9yIHRoaXMgY2x1c3Rlci4KICAgICAgICAvLy8gVGhpcyBpcyBhbiBJTkNMVVNJVkUgbG93ZXIgYm91bmQ6IGEgdm90ZSB3ZWlnaHQgPj0gdGhpcyB2YWx1ZSBtZWV0cyBxdW9ydW0uCiAgICAgICAgLy8vIFRoZSB0aHJlc2hvbGQgaXMgc2V0IGFib3ZlIDIvMyBvZiB0b3RhbCB3ZWlnaHQsIGVuc3VyaW5nIEJ5emFudGluZSBmYXVsdCB0b2xlcmFuY2UuCiAgICAgICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gdm90ZVRocmVzaG9sZCgpOiBVSW50NjQgewogICAgICAgICAgICBpZiBzZWxmLnRvdGFsV2VpZ2h0ID09IDAgewogICAgICAgICAgICAgICAgcmV0dXJuIDAKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGV0IGZsb29yT25lVGhpcmQgPSBzZWxmLnRvdGFsV2VpZ2h0IC8gVUludDY0KDMpIC8vIGludGVnZXIgZGl2aXNpb24sIGluY2x1ZGVzIGZsb29yCgogICAgICAgICAgICB2YXIgcmVzID0gVUludDY0KDIpICogZmxvb3JPbmVUaGlyZAoKICAgICAgICAgICAgbGV0IGRpdlJlbWFpbmRlciA9IHNlbGYudG90YWxXZWlnaHQgJSBVSW50NjQoMykKCiAgICAgICAgICAgIGlmIGRpdlJlbWFpbmRlciA8PSBVSW50NjQoMSkgewogICAgICAgICAgICAgICAgcmVzID0gcmVzICsgVUludDY0KDEpCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXMgPSByZXMgKyBkaXZSZW1haW5kZXIKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHJlcwogICAgICAgIH0KCiAgICAgICAgLy8vIFJldHVybnMgdGhlIHN0YXR1cyBvZiB0aGlzIGNsdXN0ZXIncyBRQyBwcm9jZXNzCiAgICAgICAgLy8vIElmIGEgdm90ZSBtZXNzYWdlIGFjY3VtdWxhdGVzIHdlaWdodCA+PSB2b3RlVGhyZXNob2xkKCksIHRoZSBRQyBpcyBjb21wbGV0ZS4KICAgICAgICAvLy8gVGhlbiB0aGlzIGNsdXN0ZXIncyBRQyBnZW5lcmF0aW9uIGlzIGNvbnNpZGVyZWQgY29tcGxldGUgYW5kIHRoaXMgbWV0aG9kIHJldHVybnMKICAgICAgICAvLy8gdGhlIHZvdGUgbWVzc2FnZSB0aGF0IHJlYWNoZWQgcXVvcnVtLgogICAgICAgIC8vLyBJZiBubyB2b3RlIGlzIGZvdW5kIHRvIHJlYWNoIHF1b3J1bSwgdGhlbiBgbmlsYCBpcyByZXR1cm5lZC4KICAgICAgICAvLy8KICAgICAgICAvLy8gTk9URTogVGhlIGA+PWAgY29tcGFyaXNvbiBpcyBjb3JyZWN0IGFuZCBpbnRlbnRpb25hbC4gdm90ZVRocmVzaG9sZCgpIHJldHVybnMgYW4KICAgICAgICAvLy8gaW5jbHVzaXZlIGxvd2VyIGJvdW5kIOKAlCBhIHRvdGFsIHdlaWdodCBlcXVhbCB0byB0aGUgdGhyZXNob2xkIHNhdGlzZmllcyBxdW9ydW0uCiAgICAgICAgLy8vIFRoaXMgaXMgTk9UIGEgd2Vha2VuZWQgcXVvcnVtIGNoZWNrOyB0aGUgdGhyZXNob2xkIHZhbHVlIGl0c2VsZiBpcyBjYWxjdWxhdGVkIHRvCiAgICAgICAgLy8vIHJlcXVpcmUgc3RyaWN0bHkgbW9yZSB0aGFuIDIvMyBvZiB0b3RhbCB3ZWlnaHQuCiAgICAgICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gaXNDb21wbGV0ZSgpOiBTdHJpbmc/IHsKICAgICAgICAgICAgZm9yIG1lc3NhZ2UgaW4gc2VsZi51bmlxdWVWb3RlTWVzc2FnZVRvdGFsV2VpZ2h0cy5rZXlzIHsKICAgICAgICAgICAgICAgIGlmIHNlbGYudW5pcXVlVm90ZU1lc3NhZ2VUb3RhbFdlaWdodHNbbWVzc2FnZV0hID49IHNlbGYudm90ZVRocmVzaG9sZCgpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWVzc2FnZQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBuaWwKICAgICAgICB9CgogICAgICAgIC8vLyBHZW5lcmF0ZXMgdGhlIFF1b3J1bSBDZXJ0aWZpY2F0ZSBmb3IgdGhpcyBjbHVzdGVyCiAgICAgICAgLy8vIElmIHRoZSBjbHVzdGVyIGlzIG5vdCBjb21wbGV0ZSwgdGhpcyByZXR1cm5zIGBuaWxgCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIGdlbmVyYXRlUXVvcnVtQ2VydGlmaWNhdGUoKTogQ2x1c3RlclFDPyB7CgogICAgICAgICAgICAvLyBPbmx5IGdlbmVyYXRlIHRoZSBRQyBpZiB0aGUgdm90aW5nIGlzIGNvbXBsZXRlIGZvciB0aGlzIGNsdXN0ZXIKICAgICAgICAgICAgaWYgbGV0IHF1b3J1bU1lc3NhZ2UgPSBzZWxmLmlzQ29tcGxldGUoKSB7CgogICAgICAgICAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IGVtcHR5IFFDCiAgICAgICAgICAgICAgICB2YXIgY2VydGlmaWNhdGU6IENsdXN0ZXJRQyA9IENsdXN0ZXJRQyhpbmRleDogc2VsZi5pbmRleCwgc2lnbmF0dXJlczogW10sIG1lc3NhZ2U6IHF1b3J1bU1lc3NhZ2UsIHZvdGVySURzOiBbXSkKCiAgICAgICAgICAgICAgICAvLyBBZGQgdGhlIHNpZ25hdHVyZXMsIG1lc3NhZ2VzLCBhbmQgbm9kZSBJRHMgb25seSBmb3Igdm90ZXMKICAgICAgICAgICAgICAgIC8vIHRoYXQgbWF0Y2ggdGhlIHZvdGVzIHRoYXQgcmVhY2hlZCBxdW9ydW0KICAgICAgICAgICAgICAgIGZvciB2b3RlIGluIHNlbGYuZ2VuZXJhdGVkVm90ZXMudmFsdWVzIHsKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGNvdW50IHZvdGVzIHRoYXQgd2VyZSBzdWJtaXR0ZWQKICAgICAgICAgICAgICAgICAgICBpZiBsZXQgc3VibWl0dGVkTWVzc2FnZSA9IHZvdGUubWVzc2FnZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIHN1Ym1pdHRlZE1lc3NhZ2UgPT0gcXVvcnVtTWVzc2FnZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZXJ0aWZpY2F0ZS5hZGRTaWduYXR1cmUodm90ZS5zaWduYXR1cmUhKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2VydGlmaWNhdGUuYWRkVm90ZXJJRCh2b3RlLm5vZGVJRCkKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gY2VydGlmaWNhdGUKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBuaWwKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8vIEdldHMgYSB2b3RlIHRoYXQgd2FzIGdlbmVyYXRlZCBmb3IgYSBub2RlIElECiAgICAgICAgYWNjZXNzKGNvbnRyYWN0KSB2aWV3IGZ1biBnZXRHZW5lcmF0ZWRWb3RlKG5vZGVJZDogU3RyaW5nKTogVm90ZT8gewogICAgICAgICAgICByZXR1cm4gc2VsZi5nZW5lcmF0ZWRWb3Rlc1tub2RlSWRdCiAgICAgICAgfQoKICAgICAgICAvLy8gU2V0cyB0aGUgdm90ZSBmb3IgdGhlIHNwZWNpZmllZCBub2RlIElECiAgICAgICAgYWNjZXNzKGNvbnRyYWN0KSBmdW4gc2V0R2VuZXJhdGVkVm90ZShub2RlSWQ6IFN0cmluZywgdm90ZTogVm90ZSkgewogICAgICAgICAgICBzZWxmLmdlbmVyYXRlZFZvdGVzW25vZGVJZF0gPSB2b3RlCiAgICAgICAgfQoKICAgICAgICAvLy8gR2V0cyB0aGUgdG90YWwgd2VpZ2h0IGNvbW1pdGVkIGZvciBhIHVuaXF1ZSB2b3RlCiAgICAgICAgYWNjZXNzKGNvbnRyYWN0KSB2aWV3IGZ1biBnZXRVbmlxdWVWb3RlTWVzc2FnZVRvdGFsV2VpZ2h0KHZvdGU6IFN0cmluZyk6IFVJbnQ2ND8gewogICAgICAgICAgICByZXR1cm4gc2VsZi51bmlxdWVWb3RlTWVzc2FnZVRvdGFsV2VpZ2h0c1t2b3RlXQogICAgICAgIH0KCiAgICAgICAgLy8vIFNldHMgdGhlIHRvdGFsIHdlaWdodCBmb3IgYSB1bmlxdWUgdm90ZQogICAgICAgIGFjY2Vzcyhjb250cmFjdCkgZnVuIHNldFVuaXF1ZVZvdGVNZXNzYWdlVG90YWxXZWlnaHQodm90ZTogU3RyaW5nLCB3ZWlnaHQ6IFVJbnQ2NCkgewogICAgICAgICAgICBzZWxmLnVuaXF1ZVZvdGVNZXNzYWdlVG90YWxXZWlnaHRzW3ZvdGVdID0gd2VpZ2h0CiAgICAgICAgfQogICAgfQoKICAgIC8vLyBgVm90ZWAgcmVwcmVzZW50cyBhIHZvdGUgZnJvbSBvbmUgY29sbGVjdGlvbiBub2RlLiAKICAgIC8vLyBJdCBzaW1wbHkgY29udGFpbnMgc3RyaW5ncyB3aXRoIHRoZSBzaWduZWQgbWVzc2FnZQogICAgLy8vIHRoZSBoZXggZW5jb2RlZCBtZXNzYWdlIGl0c2VsZi4gVm90ZXMgYXJlIGFnZ3JlZ2F0ZWQgdG8gYnVpbGQgcXVvcnVtIGNlcnRpZmljYXRlcwogICAgYWNjZXNzKGFsbCkgc3RydWN0IFZvdGUgewoKICAgICAgICAvLy8gVGhlIG5vZGUgSUQgZnJvbSB0aGUgc3Rha2luZyBjb250cmFjdAogICAgICAgIGFjY2VzcyhhbGwpIHZhciBub2RlSUQ6IFN0cmluZwoKICAgICAgICAvLy8gVGhlIHNpZ25lZCBtZXNzYWdlIGZyb20gdGhlIG5vZGUgKHVzaW5nIHRoZSBub2RlcyBgc3Rha2luZ0tleWApCiAgICAgICAgYWNjZXNzKGFsbCkgdmFyIHNpZ25hdHVyZTogU3RyaW5nPwoKICAgICAgICAvLy8gVGhlIGhleC1lbmNvZGVkIG1lc3NhZ2UgZm9yIHRoZSB2b3RlCiAgICAgICAgYWNjZXNzKGFsbCkgdmFyIG1lc3NhZ2U6IFN0cmluZz8KCiAgICAgICAgLy8vIFRoZSBpbmRleCBvZiB0aGUgY2x1c3RlciB0aGF0IHRoaXMgdm90ZSAoYW5kIG5vZGUpIGlzIGluCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IGNsdXN0ZXJJbmRleDogVUludDE2CgogICAgICAgIC8vLyBUaGUgd2VpZ2h0IG9mIHRoZSB2b3RlIChhbmQgbm9kZSkKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgd2VpZ2h0OiBVSW50NjQKCiAgICAgICAgdmlldyBpbml0KG5vZGVJRDogU3RyaW5nLCBjbHVzdGVySW5kZXg6IFVJbnQxNiwgdm90ZVdlaWdodDogVUludDY0KSB7CiAgICAgICAgICAgIHByZSB7CiAgICAgICAgICAgICAgICBub2RlSUQubGVuZ3RoID09IDY0OiAiRmxvd0NsdXN0ZXJRQy5Wb3RlLmluaXQ6IFZvdGVyIElEIG11c3QgYmUgYSB2YWxpZCBsZW5ndGggb2YgNjQgaGV4IGNoYXJhY3RlcnMgYnV0IGdvdCBcKG5vZGVJRC5sZW5ndGgpIgogICAgICAgICAgICB9CiAgICAgICAgICAgIHNlbGYuc2lnbmF0dXJlID0gbmlsCiAgICAgICAgICAgIHNlbGYubWVzc2FnZSA9IG5pbAogICAgICAgICAgICBzZWxmLm5vZGVJRCA9IG5vZGVJRAogICAgICAgICAgICBzZWxmLmNsdXN0ZXJJbmRleCA9IGNsdXN0ZXJJbmRleAogICAgICAgICAgICBzZWxmLndlaWdodCA9IHZvdGVXZWlnaHQKICAgICAgICB9CgogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBzZXRTaWduYXR1cmUoXyBzaWduYXR1cmU6IFN0cmluZykgewogICAgICAgICAgICBzZWxmLnNpZ25hdHVyZSA9IHNpZ25hdHVyZQogICAgICAgIH0KCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIHNldE1lc3NhZ2UoXyBtZXNzYWdlOiBTdHJpbmcpIHsKICAgICAgICAgICAgc2VsZi5tZXNzYWdlID0gbWVzc2FnZQogICAgICAgIH0KICAgIH0KCiAgICAvLy8gUmVwcmVzZW50cyB0aGUgcXVvcnVtIGNlcnRpZmljYXRlIGZvciBhIHNwZWNpZmljIGNsdXN0ZXIKICAgIC8vLyBhbmQgYWxsIHRoZSBub2Rlcy92b3RlcyBpbiB0aGUgY2x1c3RlcgogICAgYWNjZXNzKGFsbCkgc3RydWN0IENsdXN0ZXJRQyB7CgogICAgICAgIC8vLyBUaGUgaW5kZXggb2YgdGhlIHFjIGluIHRoZSBjbHVzdGVyIHJlY29yZAogICAgICAgIGFjY2VzcyhhbGwpIGxldCBpbmRleDogVUludDE2CgogICAgICAgIC8vLyBUaGUgdm90ZSBzaWduYXR1cmVzIGZyb20gYWxsIHRoZSBub2RlcyBpbiB0aGUgY2x1c3RlcgogICAgICAgIGFjY2VzcyhhbGwpIHZhciB2b3RlU2lnbmF0dXJlczogW1N0cmluZ10KCiAgICAgICAgLy8vIFRoZSB2b3RlIG1lc3NhZ2UgZnJvbSBhbGwgdGhlIHZhbGlkIHZvdGVycyBpbiB0aGUgY2x1c3RlcgogICAgICAgIGFjY2VzcyhhbGwpIHZhciB2b3RlTWVzc2FnZTogU3RyaW5nCgogICAgICAgIC8vLyBUaGUgbm9kZSBJRHMgdGhhdCBjb3JyZXNwb25kIHRvIGVhY2ggdm90ZQogICAgICAgIGFjY2VzcyhhbGwpIHZhciB2b3RlcklEczogW1N0cmluZ10KCiAgICAgICAgdmlldyBpbml0KGluZGV4OiBVSW50MTYsIHNpZ25hdHVyZXM6IFtTdHJpbmddLCBtZXNzYWdlOiBTdHJpbmcsIHZvdGVySURzOiBbU3RyaW5nXSkgewogICAgICAgICAgICBzZWxmLmluZGV4ID0gaW5kZXgKICAgICAgICAgICAgc2VsZi52b3RlU2lnbmF0dXJlcyA9IHNpZ25hdHVyZXMKICAgICAgICAgICAgc2VsZi52b3RlTWVzc2FnZSA9IG1lc3NhZ2UKICAgICAgICAgICAgc2VsZi52b3RlcklEcyA9IHZvdGVySURzCiAgICAgICAgfQoKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gYWRkU2lnbmF0dXJlKF8gc2lnbmF0dXJlOiBTdHJpbmcpIHsKICAgICAgICAgICAgc2VsZi52b3RlU2lnbmF0dXJlcy5hcHBlbmQoc2lnbmF0dXJlKQogICAgICAgIH0KCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIGFkZFZvdGVySUQoXyB2b3RlcklEOiBTdHJpbmcpIHsKICAgICAgICAgICAgc2VsZi52b3RlcklEcy5hcHBlbmQodm90ZXJJRCkKICAgICAgICB9CiAgICB9CgogICAgLy8vIFJlcHJlc2VudHMgdGhlIGFnZ3JlZ2F0ZWQgc2lnbmF0dXJlIGZvciBhIGNsdXN0ZXIgcXVvcnVtIGNlcnRpZmljYXRlLgogICAgYWNjZXNzKGFsbCkgc3RydWN0IENsdXN0ZXJRQ1ZvdGVEYXRhIHsKICAgICAgICAvLy8gVGhlIGFnZ3JlZ2F0ZWQgc2lnbmF0dXJlLCBoZXgtZW5jb2RlZC4gSW5jbHVkZXMgb25lIHZvdGUgZm9yIGVhY2ggbm9kZSBpbiBgdm90ZXJJRHNgLgogICAgICAgIGFjY2VzcyhhbGwpIGxldCBhZ2dyZWdhdGVkU2lnbmF0dXJlOiBTdHJpbmcKCiAgICAgICAgLy8vIFRoZSBub2RlIElEcyB0aGF0IGNvbnRyaWJ1dGVkIHRoZWlyIHZvdGUgdG8gdGhlIGFnZ3JlZ2F0ZWQgc2lnbmF0dXJlLgogICAgICAgIGFjY2VzcyhhbGwpIGxldCB2b3RlcklEczogW1N0cmluZ10KCiAgICAgICAgaW5pdChhZ2dyZWdhdGVkU2lnbmF0dXJlOiBTdHJpbmcsIHZvdGVySURzOiBbU3RyaW5nXSkgewogICAgICAgICAgICBzZWxmLmFnZ3JlZ2F0ZWRTaWduYXR1cmUgPSBhZ2dyZWdhdGVkU2lnbmF0dXJlCiAgICAgICAgICAgIHNlbGYudm90ZXJJRHMgPSB2b3RlcklEcwogICAgICAgIH0KICAgIH0KCiAgICAvLy8gVGhlIFZvdGVyIHJlc291cmNlIGlzIGdlbmVyYXRlZCBmb3IgZWFjaCBjb2xsZWN0aW9uIG5vZGUgYWZ0ZXIgdGhleSByZWdpc3Rlci4KICAgIC8vLyBFYWNoIHJlc291cmNlIGluc3RhbmNlIGlzIGdvb2QgZm9yIGFsbCBmdXR1cmUgcG90ZW50aWFsIGVwb2NocywgYnV0IHdpbGwKICAgIC8vLyBvbmx5IGJlIHZhbGlkIGlmIHRoZSBub2RlIG9wZXJhdG9yIGhhcyBiZWVuIGNvbmZpcm1lZCBhcyBhIGNvbGxlY3RvciBub2RlIGZvciB0aGUgbmV4dCBlcG9jaC4KICAgIGFjY2VzcyhhbGwpIHJlc291cmNlIFZvdGVyIHsKCiAgICAgICAgLy8vIFRoZSBub2RlSUQgb2YgdGhlIHZvdGVyIChmcm9tIHRoZSBzdGFraW5nIGNvbnRyYWN0KQogICAgICAgIGFjY2VzcyhhbGwpIGxldCBub2RlSUQ6IFN0cmluZwoKICAgICAgICAvLy8gVGhlIHN0YWtpbmcga2V5IG9mIHRoZSBub2RlIChmcm9tIHRoZSBzdGFraW5nIGNvbnRyYWN0KQogICAgICAgIGFjY2VzcyhhbGwpIHZhciBzdGFraW5nS2V5OiBTdHJpbmcKCiAgICAgICAgaW5pdChub2RlSUQ6IFN0cmluZywgc3Rha2luZ0tleTogU3RyaW5nKSB7CiAgICAgICAgICAgIHByZSB7CiAgICAgICAgICAgICAgICAhRmxvd0NsdXN0ZXJRQy52b3RlcklzQ2xhaW1lZChub2RlSUQpOiAiRmxvd0NsdXN0ZXJRQy5Wb3Rlci5pbml0OiBDYW5ub3QgY3JlYXRlIGEgVm90ZXIgcmVzb3VyY2UgZm9yIGEgbm9kZSBJRCAoXChub2RlSUQpKSB0aGF0IGhhcyBhbHJlYWR5IGJlZW4gY2xhaW1lZCIKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc2VsZi5ub2RlSUQgPSBub2RlSUQKICAgICAgICAgICAgc2VsZi5zdGFraW5nS2V5ID0gc3Rha2luZ0tleQogICAgICAgICAgICBGbG93Q2x1c3RlclFDLnZvdGVyQ2xhaW1lZFtub2RlSURdID0gdHJ1ZQogICAgICAgIH0KCiAgICAgICAgLy8vIFN1Ym1pdHMgdGhlIGdpdmVuIHZvdGUuIENhbiBiZSBjYWxsZWQgb25seSBvbmNlIHBlciBlcG9jaAogICAgICAgIC8vLyAKICAgICAgICAvLy8gUGFyYW1zOiB2b3RlU2lnbmF0dXJlOiBTaWduZWQgYHZvdGVNZXNzYWdlYCB3aXRoIHRoZSBub2RlcyBgc3Rha2luZ0tleWAKICAgICAgICAvLy8gICAgICAgICB2b3RlTWVzc2FnZTogSGV4LWVuY29kZWQgbWVzc2FnZQogICAgICAgIC8vLwogICAgICAgIGFjY2VzcyhhbGwpIGZ1biB2b3RlKHZvdGVTaWduYXR1cmU6IFN0cmluZywgdm90ZU1lc3NhZ2U6IFN0cmluZykgewogICAgICAgICAgICBwcmUgewogICAgICAgICAgICAgICAgRmxvd0NsdXN0ZXJRQy5pblByb2dyZXNzOiAiRmxvd0NsdXN0ZXJRQy5Wb3Rlci52b3RlOiBWb3RpbmcgcGhhc2UgaXMgbm90IGluIHByb2dyZXNzIgogICAgICAgICAgICAgICAgdm90ZVNpZ25hdHVyZS5sZW5ndGggPiAwOiAiRmxvd0NsdXN0ZXJRQy5Wb3Rlci52b3RlOiBWb3RlIHNpZ25hdHVyZSBtdXN0IG5vdCBiZSBlbXB0eSIKICAgICAgICAgICAgICAgIHZvdGVNZXNzYWdlLmxlbmd0aCA+IDA6ICJGbG93Q2x1c3RlclFDLlZvdGVyLnZvdGU6IFZvdGUgbWVzc2FnZSBtdXN0IG5vdCBiZSBlbXB0eSIKICAgICAgICAgICAgICAgICFGbG93Q2x1c3RlclFDLm5vZGVIYXNWb3RlZChzZWxmLm5vZGVJRCk6ICJGbG93Q2x1c3RlclFDLlZvdGVyLnZvdGU6IFZvdGUgbXVzdCBub3QgaGF2ZSBiZWVuIGNhc3QgYWxyZWFkeSBmb3Igbm9kZSBJRCBcKHNlbGYubm9kZUlEKSIKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gR2V0IHRoZSBwdWJsaWMga2V5IG9iamVjdCBmcm9tIHRoZSBzdG9yZWQga2V5CiAgICAgICAgICAgIGxldCBwdWJsaWNLZXkgPSBQdWJsaWNLZXkoCiAgICAgICAgICAgICAgICBwdWJsaWNLZXk6IHNlbGYuc3Rha2luZ0tleS5kZWNvZGVIZXgoKSwKICAgICAgICAgICAgICAgIHNpZ25hdHVyZUFsZ29yaXRobTogU2lnbmF0dXJlQWxnb3JpdGhtLkJMU19CTFMxMl8zODEKICAgICAgICAgICAgKQoKICAgICAgICAgICAgLy8gQ2hlY2sgdG8gc2VlIHRoYXQgdGhlIHNpZ25hdHVyZSBvbiB0aGUgbWVzc2FnZSBpcyB2YWxpZCAKICAgICAgICAgICAgbGV0IGlzVmFsaWQgPSBwdWJsaWNLZXkudmVyaWZ5KAogICAgICAgICAgICAgICAgc2lnbmF0dXJlOiB2b3RlU2lnbmF0dXJlLmRlY29kZUhleCgpLAogICAgICAgICAgICAgICAgc2lnbmVkRGF0YTogdm90ZU1lc3NhZ2UuZGVjb2RlSGV4KCksCiAgICAgICAgICAgICAgICBkb21haW5TZXBhcmF0aW9uVGFnOiAiRkxPVy1Db2xsZWN0b3JfVm90ZS1WMDAtQ1MwMC13aXRoLSIsCiAgICAgICAgICAgICAgICBoYXNoQWxnb3JpdGhtOiBIYXNoQWxnb3JpdGhtLktNQUMxMjhfQkxTX0JMUzEyXzM4MQogICAgICAgICAgICApCgogICAgICAgICAgICAvLyBBc3NlcnQgdGhlIHZhbGlkaXR5CiAgICAgICAgICAgIGFzc2VydCAoCiAgICAgICAgICAgICAgICBpc1ZhbGlkLAogICAgICAgICAgICAgICAgbWVzc2FnZTogIkZsb3dDbHVzdGVyUUMuVm90ZXIudm90ZTogVm90ZSBTaWduYXR1cmUgY2Fubm90IGJlIHZlcmlmaWVkIGZvciBub2RlIElEIFwoc2VsZi5ub2RlSUQpIgogICAgICAgICAgICApCgogICAgICAgICAgICAvLyBHZXQgdGhlIGNsdXN0ZXIgdGhhdCB0aGlzIG5vZGUgYmVsb25ncyB0bwogICAgICAgICAgICBsZXQgY2x1c3RlckluZGV4ID0gRmxvd0NsdXN0ZXJRQy5ub2RlQ2x1c3RlcltzZWxmLm5vZGVJRF0KICAgICAgICAgICAgICAgID8/IHBhbmljKCJGbG93Q2x1c3RlclFDLlZvdGVyLnZvdGU6IE5vZGUgXChzZWxmLm5vZGVJRCkgY2Fubm90IHZvdGUgZHVyaW5nIHRoZSBjdXJyZW50IGVwb2NoIGJlY2F1c2UgaXQgaXMgbm90IHJlZ2lzdGVyZWQiKQogICAgICAgICAgICBsZXQgY2x1c3RlciA9IEZsb3dDbHVzdGVyUUMuY2x1c3RlcnNbY2x1c3RlckluZGV4XSEKCiAgICAgICAgICAgIC8vIEdldCB0aGlzIG5vZGUncyBhbGxvY2F0ZWQgdm90ZQogICAgICAgICAgICBsZXQgdm90ZSA9IGNsdXN0ZXIuZ2V0R2VuZXJhdGVkVm90ZShub2RlSWQ6IHNlbGYubm9kZUlEKSEKCiAgICAgICAgICAgIC8vIFNldCB0aGUgc2lnbmF0dXJlIGFuZCBtZXNzYWdlIGZpZWxkcwogICAgICAgICAgICB2b3RlLnNldFNpZ25hdHVyZSh2b3RlU2lnbmF0dXJlKQogICAgICAgICAgICB2b3RlLnNldE1lc3NhZ2Uodm90ZU1lc3NhZ2UpCgogICAgICAgICAgICAvLyBTZXQgdGhlIG5ldyB0b3RhbCB3ZWlnaHQgZm9yIHRoZSB2b3RlCiAgICAgICAgICAgIGxldCB0b3RhbFdlaWdodCA9IGNsdXN0ZXIuZ2V0VW5pcXVlVm90ZU1lc3NhZ2VUb3RhbFdlaWdodCh2b3RlOiB2b3RlTWVzc2FnZSkgPz8gMAogICAgICAgICAgICB2YXIgbmV3V2VpZ2h0ID0gdG90YWxXZWlnaHQgKyB2b3RlLndlaWdodAogICAgICAgICAgICBjbHVzdGVyLnNldFVuaXF1ZVZvdGVNZXNzYWdlVG90YWxXZWlnaHQodm90ZTogdm90ZU1lc3NhZ2UsIHdlaWdodDogbmV3V2VpZ2h0KQoKICAgICAgICAgICAgLy8gU2F2ZSB0aGUgbW9kaWZpZWQgdm90ZSBhbmQgY2x1c3RlciBiYWNrCiAgICAgICAgICAgIGNsdXN0ZXIuc2V0R2VuZXJhdGVkVm90ZShub2RlSWQ6IHNlbGYubm9kZUlELCB2b3RlOiB2b3RlKQogICAgICAgICAgICBGbG93Q2x1c3RlclFDLmNsdXN0ZXJzW2NsdXN0ZXJJbmRleF0gPSBjbHVzdGVyCiAgICAgICAgfQoKICAgIH0KCiAgICAvLy8gSW50ZXJmYWNlIHRoYXQgb25seSBjb250YWlucyBvcGVyYXRpb25zIHRoYXQgYXJlIHBhcnQKICAgIC8vLyBvZiB0aGUgcmVndWxhciBhdXRvbWF0ZWQgZnVuY3Rpb25pbmcgb2YgdGhlIGVwb2NoIHByb2Nlc3MKICAgIC8vLyBUaGVzZSBhcmUgYWNjZXNzZWQgYnkgdGhlIGBGbG93RXBvY2hgIGNvbnRyYWN0IHRocm91Z2ggYSBjYXBhYmlsaXR5CiAgICBhY2Nlc3MoYWxsKSByZXNvdXJjZSBpbnRlcmZhY2UgRXBvY2hPcGVyYXRpb25zIHsKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gY3JlYXRlVm90ZXIobm9kZUlEOiBTdHJpbmcsIHN0YWtpbmdLZXk6IFN0cmluZyk6IEBWb3RlcgogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBzdGFydFZvdGluZyhjbHVzdGVyczogW0NsdXN0ZXJdKSAKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gc3RvcFZvdGluZygpCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIGZvcmNlU3RvcFZvdGluZygpCiAgICB9CgogICAgLy8vIFRoZSBBZG1pbiByZXNvdXJjZSBwcm92aWRlcyB0aGUgYWJpbGl0eSB0byBjcmVhdGUgdG8gVm90ZXIgcmVzb3VyY2Ugb2JqZWN0cywKICAgIC8vLyBiZWdpbiB2b3RpbmcsIGFuZCBlbmQgdm90aW5nIGZvciBhbiBlcG9jaAogICAgYWNjZXNzKGFsbCkgcmVzb3VyY2UgQWRtaW46IEVwb2NoT3BlcmF0aW9ucyB7CgogICAgICAgIC8vLyBDcmVhdGVzIGEgbmV3IFZvdGVyIHJlc291cmNlIGZvciBhIGNvbGxlY3Rpb24gbm9kZQogICAgICAgIC8vLyBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgcHVibGljbHkgYWNjZXNzaWJsZSBpbiB0aGUgRmxvd0Vwb2NoCiAgICAgICAgLy8vIGNvbnRyYWN0LCB3aGljaCB3aWxsIHJlc3RyaWN0IHRoZSBjcmVhdGlvbiB0byBvbmx5IGNvbGxlY3RvciBub2RlcwogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBjcmVhdGVWb3Rlcihub2RlSUQ6IFN0cmluZywgc3Rha2luZ0tleTogU3RyaW5nKTogQFZvdGVyIHsKICAgICAgICAgICAgcmV0dXJuIDwtY3JlYXRlIFZvdGVyKG5vZGVJRDogbm9kZUlELCBzdGFraW5nS2V5OiBzdGFraW5nS2V5KQogICAgICAgIH0KCiAgICAgICAgLy8vIENvbmZpZ3VyZXMgdGhlIGNvbnRyYWN0IGZvciB0aGUgbmV4dCBlcG9jaCdzIGNsdXN0ZXJzCiAgICAgICAgLy8vCiAgICAgICAgLy8vIE5PVEU6IFRoaXMgd2lsbCBiZSBjYWxsZWQgYnkgdGhlIHRvcC1sZXZlbCBGbG93RXBvY2hzIGNvbnRyYWN0IHVwb24KICAgICAgICAvLy8gdHJhbnNpdGlvbmluZyB0byB0aGUgRXBvY2ggU2V0dXAgUGhhc2UuCiAgICAgICAgLy8vCiAgICAgICAgLy8vIENBVVRJT046IGNhbGxpbmcgdGhpcyBlcmFzZXMgdGhlIHZvdGVzIGZvciB0aGUgY3VycmVudC9wcmV2aW91cyBlcG9jaC4KICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gc3RhcnRWb3RpbmcoY2x1c3RlcnM6IFtDbHVzdGVyXSkgewogICAgICAgICAgICBGbG93Q2x1c3RlclFDLmluUHJvZ3Jlc3MgPSB0cnVlCiAgICAgICAgICAgIEZsb3dDbHVzdGVyUUMuY2x1c3RlcnMgPSBjbHVzdGVycwoKICAgICAgICAgICAgdmFyIGNsdXN0ZXJJbmRleDogVUludDE2ID0gMAogICAgICAgICAgICBmb3IgY2x1c3RlciBpbiBjbHVzdGVycyB7CgogICAgICAgICAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IFZvdGUgc3RydWN0IGZvciBlYWNoIHBhcnRpY2lwYXRpbmcgbm9kZQogICAgICAgICAgICAgICAgZm9yIG5vZGVJRCBpbiBjbHVzdGVyLm5vZGVXZWlnaHRzLmtleXMgewogICAgICAgICAgICAgICAgICAgIGNsdXN0ZXIuc2V0R2VuZXJhdGVkVm90ZShub2RlSWQ6IG5vZGVJRCx2b3RlOiBWb3RlKG5vZGVJRDogbm9kZUlELCBjbHVzdGVySW5kZXg6IGNsdXN0ZXJJbmRleCwgdm90ZVdlaWdodDogY2x1c3Rlci5ub2RlV2VpZ2h0c1tub2RlSURdISkpCiAgICAgICAgICAgICAgICAgICAgRmxvd0NsdXN0ZXJRQy5ub2RlQ2x1c3Rlcltub2RlSURdID0gY2x1c3RlckluZGV4ICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBGbG93Q2x1c3RlclFDLmNsdXN0ZXJzW2NsdXN0ZXJJbmRleF0gPSBjbHVzdGVyCiAgICAgICAgICAgICAgICBjbHVzdGVySW5kZXggPSBjbHVzdGVySW5kZXggKyBVSW50MTYoMSkKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8vIFN0b3BzIHZvdGluZyBmb3IgdGhlIGN1cnJlbnQgZXBvY2guIENhbiBvbmx5IGJlIGNhbGxlZCBvbmNlIGEgMi8zIAogICAgICAgIC8vLyBtYWpvcml0eSBvZiBlYWNoIGNsdXN0ZXIgaGFzIHN1Ym1pdHRlZCBhIHZvdGUuIAogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBzdG9wVm90aW5nKCkgewogICAgICAgICAgICBwcmUgewogICAgICAgICAgICAgICAgRmxvd0NsdXN0ZXJRQy52b3RpbmdDb21wbGV0ZWQoKTogIkZsb3dDbHVzdGVyUUMuQWRtaW4uc3RvcFZvdGluZzogVm90aW5nIG11c3QgYmUgY29tcGxldGUgYmVmb3JlIGl0IGNhbiBiZSBzdG9wcGVkIgogICAgICAgICAgICB9CiAgICAgICAgICAgIEZsb3dDbHVzdGVyUUMuaW5Qcm9ncmVzcyA9IGZhbHNlCiAgICAgICAgfQoKICAgICAgICAvLy8gRm9yY2UgYSBzdG9wIG9mIHRoZSB2b3RpbmcgcGVyaW9kCiAgICAgICAgLy8vIFNob3VsZCBvbmx5IGJlIHVzZWQgaWYgdGhlIHByb3RvY29sIGhhbHRzIGFuZCBuZWVkcyB0byBiZSByZXNldAogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBmb3JjZVN0b3BWb3RpbmcoKSB7CiAgICAgICAgICAgIEZsb3dDbHVzdGVyUUMuaW5Qcm9ncmVzcyA9IGZhbHNlCiAgICAgICAgfQogICAgfQoKICAgIC8vLyBSZXR1cm5zIGEgYm9vbGVhbiB0ZWxsaW5nIGlmIHRoZSB2b3RlciBpcyByZWdpc3RlcmVkIGZvciB0aGUgY3VycmVudCB2b3RpbmcgcGhhc2UKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIHZvdGVySXNSZWdpc3RlcmVkKF8gbm9kZUlEOiBTdHJpbmcpOiBCb29sIHsKICAgICAgICByZXR1cm4gRmxvd0NsdXN0ZXJRQy5ub2RlQ2x1c3Rlcltub2RlSURdICE9IG5pbAogICAgfQoKICAgIC8vLyBSZXR1cm5zIGEgYm9vbGVhbiB0ZWxsaW5nIGlmIHRoZSBub2RlIGhhcyBjbGFpbWVkIHRoZWlyIGBWb3RlcmAgcmVzb3VyY2Ugb2JqZWN0CiAgICAvLy8gVGhlIG9iamVjdCBjYW4gb25seSBiZSBjbGFpbWVkIG9uY2UsIGJ1dCBpZiB0aGUgbm9kZSBkZXN0cm95cyB0aGVpciBgVm90ZXJgIG9iamVjdCwKICAgIC8vLyBJdCBjb3VsZCBiZSBjbGFpbWVkIGFnYWluCiAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biB2b3RlcklzQ2xhaW1lZChfIG5vZGVJRDogU3RyaW5nKTogQm9vbCB7CiAgICAgICAgcmV0dXJuIEZsb3dDbHVzdGVyUUMudm90ZXJDbGFpbWVkW25vZGVJRF0gIT0gbmlsCiAgICB9CgogICAgLy8vIFJldHVybnMgd2hldGhlciB0aGlzIHZvdGVyIGhhcyBzdWNjZXNzZnVsbHkgc3VibWl0dGVkIGEgdm90ZSBmb3IgdGhpcyBlcG9jaC4KICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIG5vZGVIYXNWb3RlZChfIG5vZGVJRDogU3RyaW5nKTogQm9vbCB7CgogICAgICAgIC8vIEdldCB0aGUgY2x1c3RlciB0aGF0IHRoaXMgbm9kZSBiZWxvbmdzIHRvCiAgICAgICAgaWYgbGV0IGNsdXN0ZXJJbmRleCA9IEZsb3dDbHVzdGVyUUMubm9kZUNsdXN0ZXJbbm9kZUlEXSB7CiAgICAgICAgICAgIGxldCBjbHVzdGVyID0gRmxvd0NsdXN0ZXJRQy5jbHVzdGVyc1tjbHVzdGVySW5kZXhdCgogICAgICAgICAgICAvLyBJZiB0aGUgbm9kZSBpcyByZWdpc3RlcmVkIGZvciB0aGlzIGVwb2NoLAogICAgICAgICAgICAvLyBjaGVjayB0byBzZWUgaWYgdGhleSBoYXZlIHZvdGVkCiAgICAgICAgICAgIGlmIGNsdXN0ZXIubm9kZVdlaWdodHNbbm9kZUlEXSAhPSBuaWwgewogICAgICAgICAgICAgICAgcmV0dXJuIGNsdXN0ZXIuZ2VuZXJhdGVkVm90ZXNbbm9kZUlEXSEuc2lnbmF0dXJlICE9IG5pbAogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2UKICAgIH0KCiAgICAvLy8gR2V0cyBhbGwgb2YgdGhlIGNvbGxlY3RvciBjbHVzdGVycyBmb3IgdGhlIGN1cnJlbnQgZXBvY2gKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGdldENsdXN0ZXJzKCk6IFtDbHVzdGVyXSB7CiAgICAgICAgcmV0dXJuIHNlbGYuY2x1c3RlcnMKICAgIH0KCiAgICAvLy8gUmV0dXJucyB0cnVlIGlmIHdlIGhhdmUgY29sbGVjdGVkIGVub3VnaCB2b3RlcyBmb3IgYWxsIGNsdXN0ZXJzLgogICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gdm90aW5nQ29tcGxldGVkKCk6IEJvb2wgewogICAgICAgIGZvciBjbHVzdGVyIGluIEZsb3dDbHVzdGVyUUMuY2x1c3RlcnMgewogICAgICAgICAgICBpZiBjbHVzdGVyLmlzQ29tcGxldGUoKSA9PSBuaWwgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWUKICAgIH0KCiAgICBpbml0KCkgewogICAgICAgIHNlbGYuQWRtaW5TdG9yYWdlUGF0aCA9IC9zdG9yYWdlL2Zsb3dFcG9jaHNRQ0FkbWluCiAgICAgICAgc2VsZi5Wb3RlclN0b3JhZ2VQYXRoID0gL3N0b3JhZ2UvZmxvd0Vwb2Noc1FDVm90ZXIKCiAgICAgICAgc2VsZi5pblByb2dyZXNzID0gZmFsc2UgCiAgICAgICAgCiAgICAgICAgc2VsZi5jbHVzdGVycyA9IFtdCiAgICAgICAgc2VsZi52b3RlckNsYWltZWQgPSB7fQogICAgICAgIHNlbGYubm9kZUNsdXN0ZXIgPSB7fQoKICAgICAgICBzZWxmLmFjY291bnQuc3RvcmFnZS5zYXZlKDwtY3JlYXRlIEFkbWluKCksIHRvOiBzZWxmLkFkbWluU3RvcmFnZVBhdGgpCiAgICB9Cn0=",
		"FlowDKG": "LyogCioKKiAgTWFuYWdlcyB0aGUgcHJvY2VzcyBvZiBnZW5lcmF0aW5nIGEgZ3JvdXAga2V5IHdpdGggdGhlIHBhcnRpY2lwYXRpb24gb2YgYWxsIHRoZSBjb25zZW5zdXMgbm9kZXMKKiAgZm9yIHRoZSB1cGNvbWluZyBlcG9jaC4KKgoqICBXaGVuIGNvbnNlbnN1cyBub2RlcyBhcmUgZmlyc3QgY29uZmlybWVkLCB0aGV5IGNhbiByZXF1ZXN0IGEgUGFydGljaXBhbnQgb2JqZWN0IGZyb20gdGhpcyBjb250cmFjdAoqICBUaGV5J2xsIHVzZSB0aGlzIG9iamVjdCBmb3IgZXZlcnkgc3Vic2VxdWVudCBlcG9jaCB0aGF0IHRoZXkgYXJlIGEgc3Rha2VkIGNvbnNlbnN1cyBub2RlLgoqCiogIEF0IHRoZSBiZWdpbm5pbmcgb2YgZWFjaCBFcG9jaFNldHVwIHBoYXNlLCB0aGUgYWRtaW4gaW5pdGlhbGl6ZXMgdGhpcyBjb250cmFjdCB3aXRoCiogIHRoZSBsaXN0IG9mIGNvbnNlbnN1cyBub2RlcyBmb3IgdGhlIHVwY29taW5nIGVwb2NoLiBFYWNoIGNvbnNlbnN1cyBub2RlCiogIGNhbiBwb3N0IGFzIG1hbnkgbWVzc2FnZXMgYXMgdGhleSB3YW50IHRvIHRoZSBES0cgIndoaXRlYm9hcmQiIHdpdGggdGhlIGBQYXJ0aWNpcGFudC5wb3N0TWVzc2FnZSgpYCBtZXRob2QsCiogIGJ1dCBlYWNoIG5vZGUgY2FuIG9ubHkgc3VibWl0IGEgZmluYWwgc3VibWlzc2lvbiBvbmNlIHBlciBlcG9jaCB2aWEgdGhlIGBQYXJ0aWNpcGFudC5zZW5kRmluYWxTdWJtaXNzaW9uKCkgbWV0aG9kLgoqICAKKiAgT25jZSBhID41MCUgdGhyZXNob2xkIG9mIGNvbnNlbnN1cyBub2RlcyBoYXZlIHN1Ym1pdHRlZCB0aGUgZXhhY3Qgc2FtZSBzZXQgb2Yga2V5cywKKiAgdGhlIERLRyBwaGFzZSBpcyB0ZWNobmljYWxseSBmaW5pc2hlZC4KKiAgQW55b25lIGNhbiBxdWVyeSB0aGUgc3RhdGUgb2YgdGhlIHN1Ym1pc3Npb25zIHdpdGggdGhlIEZsb3dES0cuZ2V0RmluYWxTdWJtaXNzaW9ucygpCiogIG9yIEZsb3dES0cuZGtnQ29tcGxldGVkKCkgbWV0aG9kcy4KKiAgQ29uc2Vuc3VzIG5vZGVzIGNhbiBjb250aW51ZSB0byBzdWJtaXQgZmluYWwgbWVzc2FnZXMgZXZlbiBhZnRlciB0aGUgcmVxdWlyZWQgYW1vdW50IGhhdmUgYmVlbiBzdWJtaXR0ZWQgdGhvdWdoLgoqIAoqICBUaGlzIGNvbnRyYWN0IGlzIGEgbWVtYmVyIG9mIGEgc2VyaWVzIG9mIGVwb2NoIHNtYXJ0IGNvbnRyYWN0cyB3aGljaCBjb29yZGluYXRlcyB0aGUgCiogIHByb2Nlc3Mgb2YgdHJhbnNpdGlvbmluZyBiZXR3ZWVuIGVwb2NocyBpbiBGbG93LgoqLwoKYWNjZXNzKGFsbCkgY29udHJhY3QgRmxvd0RLRyB7CgogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgIC8vIERLRyBFVkVOVFMKICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgogICAgLy8vIEVtaXR0ZWQgd2hlbiB0aGUgYWRtaW4gZW5hYmxlcyB0aGUgREtHCiAgICBhY2Nlc3MoYWxsKSBldmVudCBTdGFydERLRygpCgogICAgLy8vIEVtaXR0ZWQgd2hlbiB0aGUgYWRtaW4gZW5kcyB0aGUgREtHIChvbmUgREtHIGluc3RhbmNlKS4KICAgIC8vLyBUaGUgZXZlbnQgaW5jbHVkZXMgdGhlIGNhbm9uaWNhbCByZXN1bHQgc3VibWlzc2lvbiBpZiB0aGUgREtHIHN1Y2NlZWRlZCwKICAgIC8vLyBvciBuaWwgaWYgdGhlIERLRyBmYWlsZWQgb3Igd2FzIHN0b3BwZWQgYmVmb3JlIGNvbXBsZXRpb24uCiAgICBhY2Nlc3MoYWxsKSBldmVudCBFbmRES0coZmluYWxTdWJtaXNzaW9uOiBSZXN1bHRTdWJtaXNzaW9uPykKCiAgICAvLy8gRW1pdHRlZCB3aGVuIGEgY29uc2Vuc3VzIG5vZGUgaGFzIHBvc3RlZCBhIG1lc3NhZ2UgdG8gdGhlIERLRyB3aGl0ZWJvYXJkCiAgICBhY2Nlc3MoYWxsKSBldmVudCBCcm9hZGNhc3RNZXNzYWdlKG5vZGVJRDogU3RyaW5nLCBjb250ZW50OiBTdHJpbmcpCgogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgIC8vIENPTlRSQUNUIFZBUklBQkxFUwogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgICAvLy8gVGhlIGxlbmd0aCBvZiBrZXlzIHRoYXQgaGF2ZSB0byBiZSBzdWJtaXR0ZWQgYXMgYSBmaW5hbCBzdWJtaXNzaW9uCiAgICBhY2Nlc3MoYWxsKSBsZXQgc3VibWlzc2lvbktleUxlbmd0aDogSW50CgogICAgLy8vIEluZGljYXRlcyBpZiB0aGUgREtHIGlzIGVuYWJsZWQgb3Igbm90CiAgICBhY2Nlc3MoYWxsKSB2YXIgZGtnRW5hYmxlZDogQm9vbAoKICAgIC8vLyBJbmRpY2F0ZXMgaWYgYSBQYXJ0aWNpcGFudCByZXNvdXJjZSBoYXMgYWxyZWFkeSBiZWVuIGNsYWltZWQgYnkgYSBub2RlIElECiAgICAvLy8gZnJvbSB0aGUgaWRlbnRpdHkgdGFibGUgY29udHJhY3QKICAgIC8vLyBOb2RlIElEcyBoYXZlIHRvIGNsYWltIGEgcGFydGljaXBhbnQgb25jZQogICAgLy8vIG9uZSBub2RlIHdpbGwgdXNlIHRoZSBzYW1lIHNwZWNpZmljIElEIGFuZCBQYXJ0aWNpcGFudCByZXNvdXJjZSBmb3IgYWxsIHRpbWUKICAgIC8vLyBgbmlsYCBvciBmYWxzZSBtZWFucyB0aGF0IHRoZXJlIGlzIG5vIHZvdGluZyBjYXBhYmlsaXR5IGZvciB0aGUgbm9kZSBJRAogICAgLy8vIHRydWUgbWVhbnMgdGhhdCB0aGUgcGFydGljaXBhbnQgY2FwYWJpbGl0eSBoYXMgYmVlbiBjbGFpbWVkIGJ5IHRoZSBub2RlCiAgICBhY2Nlc3MoYWNjb3VudCkgdmFyIG5vZGVDbGFpbWVkOiB7U3RyaW5nOiBCb29sfQoKICAgIC8vLyBSZWNvcmQgb2Ygd2hpdGVib2FyZCBtZXNzYWdlcyBmb3IgdGhlIGN1cnJlbnQgZXBvY2gKICAgIC8vLyBUaGlzIGlzIHJlc2V0IGF0IHRoZSBiZWdpbm5pbmcgb2YgZXZlcnkgREtHIGluc3RhbmNlIChvbmNlIHBlciBlcG9jaCkKICAgIGFjY2VzcyhhY2NvdW50KSB2YXIgd2hpdGVib2FyZE1lc3NhZ2VzOiBbTWVzc2FnZV0KCiAgICAvLyBERVBSRUNBVEVEIEZJRUxEUyAocmVwbGFjZWQgYnkgU3VibWlzc2lvblRyYWNrZXIpCiAgICBhY2Nlc3MoYWNjb3VudCkgdmFyIGZpbmFsU3VibWlzc2lvbkJ5Tm9kZUlEOiB7U3RyaW5nOiBbU3RyaW5nP119IC8vIGRlcHJlY2F0ZWQgYW5kIHVudXNlZAogICAgYWNjZXNzKGFjY291bnQpIHZhciB1bmlxdWVGaW5hbFN1Ym1pc3Npb25zOiBbW1N0cmluZz9dXSAgICAgICAgICAvLyBkZXByZWNhdGVkIGFuZCB1bnVzZWQKICAgIGFjY2VzcyhhY2NvdW50KSB2YXIgdW5pcXVlRmluYWxTdWJtaXNzaW9uQ291bnQ6IHtJbnQ6IFVJbnQ2NH0gICAgLy8gZGVwcmVjYXRlZCBhbmQgdW51c2VkCgogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgIC8vIENPTlRSQUNUIENPTlNUQU5UUwogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgICAvLyBDYW5vbmljYWwgcGF0aHMgZm9yIGFkbWluIGFuZCBwYXJ0aWNpcGFudCByZXNvdXJjZXMKICAgIGFjY2VzcyhhbGwpIGxldCBBZG1pblN0b3JhZ2VQYXRoOiBTdG9yYWdlUGF0aAogICAgYWNjZXNzKGFsbCkgbGV0IFBhcnRpY2lwYW50U3RvcmFnZVBhdGg6IFN0b3JhZ2VQYXRoCiAgICBhY2Nlc3MoYWxsKSBsZXQgUGFydGljaXBhbnRQdWJsaWNQYXRoOiBQdWJsaWNQYXRoCgogICAgLy8vIFN0cnVjdCB0byByZXByZXNlbnQgYSBzaW5nbGUgd2hpdGVib2FyZCBtZXNzYWdlCiAgICBhY2Nlc3MoYWxsKSBzdHJ1Y3QgTWVzc2FnZSB7CgogICAgICAgIC8vLyBUaGUgSUQgb2YgdGhlIG5vZGUgd2hvIHN1Ym1pdHRlZCB0aGUgbWVzc2FnZQogICAgICAgIGFjY2VzcyhhbGwpIGxldCBub2RlSUQ6IFN0cmluZwoKICAgICAgICAvLy8gVGhlIGNvbnRlbnQgb2YgdGhlIG1lc3NhZ2UKICAgICAgICAvLy8gV2UgbWFrZSBubyBhc3N1bXB0aW9ucyBvciBhc3NlcnRpb25zIGFib3V0IHRoZSBjb250ZW50IG9mIHRoZSBtZXNzYWdlCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IGNvbnRlbnQ6IFN0cmluZwoKICAgICAgICBpbml0KG5vZGVJRDogU3RyaW5nLCBjb250ZW50OiBTdHJpbmcpIHsKICAgICAgICAgICAgc2VsZi5ub2RlSUQgPSBub2RlSUQKICAgICAgICAgICAgc2VsZi5jb250ZW50ID0gY29udGVudAogICAgICAgIH0KICAgIH0KCiAgICAvLyBDaGVja3Mgd2hldGhlciB0aGUgUmVzdWx0U3VibWlzc2lvbiBjb25zdHJ1Y3RvciBhcmd1bWVudHMgc2F0aXNmeSBJbnZhcmlhbnQgKDEpOgogICAgLy8gICAoMSkgZWl0aGVyIGFsbCBmaWVsZHMgYXJlIG5pbCAoZW1wdHkgc3VibWlzc2lvbikgb3Igbm8gZmllbGRzIGFyZSBuaWwKICAgIC8vIEEgdmFsaWQgZW1wdHkgc3VibWlzc2lvbiBoYXMgYWxsIGZpZWxkcyBuaWwsIGFuZCBpcyB1c2VkIHdoZW4gdGhlIHN1Ym1pdHRvciBsb2NhbGx5IGZhaWxlZCB0aGUgREtHLgogICAgLy8gQWxsIG5vbi1lbXB0eSBzdWJtaXNzaW9ucyBtdXN0IGhhdmUgYWxsIG5vbi1uaWwgZmllbGRzLgogICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gY2hlY2tFbXB0eVN1Ym1pc3Npb25JbnZhcmlhbnQoZ3JvdXBQdWJLZXk6IFN0cmluZz8sIHB1YktleXM6IFtTdHJpbmddPywgaWRNYXBwaW5nOiB7U3RyaW5nOkludH0/KTogQm9vbCB7CiAgICAgICAgLy8gSWYgYW55IGZpZWxkcyBhcmUgbmlsLCB0aGVuIHRoaXMgcmVwcmVzZW50cyBhIGVtcHR5IHN1Ym1pc3Npb24gYW5kIGFsbCBmaWVsZHMgbXVzdCBiZSBuaWwKICAgICAgICBpZiBncm91cFB1YktleSA9PSBuaWwgJiYgcHViS2V5cyA9PSBuaWwgJiYgaWRNYXBwaW5nID09IG5pbCB7CiAgICAgICAgICAgIHJldHVybiB0cnVlCiAgICAgICAgfQogICAgICAgIC8vIE90aGVyd2lzZSwgYWxsIGZpZWxkcyBtdXN0IGJlIG5vbi1uaWwKICAgICAgICByZXR1cm4gZ3JvdXBQdWJLZXkgIT0gbmlsICYmIHB1YktleXMgIT0gbmlsICYmIGlkTWFwcGluZyAhPSBuaWwgCiAgICB9CgogICAgLy8gQ2hlY2tzIHRoZSBncm91cCBwdWJsaWMga2V5IChwYXJ0IG9mIGEgUmVzdWx0U3VibWlzc2lvbikgZm9yIHZhbGlkaXR5LgogICAgLy8gQSB2YWxpZCBwdWJsaWMga2V5IGluIHRoaXMgY29udGV4dCBpcyBlaXRoZXI6ICgxKSBhIGhleC1lbmNvZGVkIDk2IGJ5dGVzLCBvciAoMikgbmlsLgogICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gaXNWYWxpZEdyb3VwS2V5KF8gZ3JvdXBLZXk6IFN0cmluZz8pOiBCb29sIHsKICAgICAgICAgaWYgZ3JvdXBLZXkgPT0gbmlsIHsKICAgICAgICAgICAgLy8gQnkgSW52YXJpYW50ICgxKSwgVGhpcyBpcyBhIG5pbC9lbXB0eSBzdWJtaXNzaW9uIChzZWUgY2hlY2tFbXB0eVN1Ym1pc3Npb25JbnZhcmlhbnQpCiAgICAgICAgICAgIHJldHVybiB0cnVlCiAgICAgICAgfQogICAgICAgIHJldHVybiBncm91cEtleSEubGVuZ3RoID09IEZsb3dES0cuc3VibWlzc2lvbktleUxlbmd0aAogICAgfQoKICAgIC8vIENoZWNrcyBhIGxpc3Qgb2YgcGFydGljaXBhbnQgcHVibGljIGtleXMgKHBhcnQgb2YgYSBSZXN1bHRTdWJtaXNzaW9uKSBmb3IgdmFsaWRpdHkuCiAgICAvLyBBIHZhbGlkIHB1YmxpYyBrZXkgaW4gdGhpcyBjb250ZXh0IGlzIGVpdGhlcjogKDEpIGEgaGV4LWVuY29kZWQgOTYgYnl0ZXMsIG9yICgyKSBuaWwuCiAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBpc1ZhbGlkUHViS2V5cyhfIHB1YktleXM6IFtTdHJpbmddPyk6IEJvb2wgewogICAgICAgIGlmIHB1YktleXMgPT0gbmlsIHsKICAgICAgICAgICAgLy8gQnkgSW52YXJpYW50ICgxKSwgVGhpcyBpcyBhIG5pbC9lbXB0eSBzdWJtaXNzaW9uIChzZWUgY2hlY2tFbXB0eVN1Ym1pc3Npb25JbnZhcmlhbnQpCiAgICAgICAgICAgIHJldHVybiB0cnVlCiAgICAgICAgfQogICAgICAgIGZvciBrZXkgaW4gcHViS2V5cyEgewogICAgICAgICAgICAvLyBrZXlzIG11c3QgYmUgZXhhY3RseSA5NiBieXRlcwogICAgICAgICAgICAgaWYga2V5Lmxlbmd0aCAhPSBGbG93REtHLnN1Ym1pc3Npb25LZXlMZW5ndGggewogICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZQogICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZQogICAgfQoKICAgIC8vIENoZWNrcyB0aGF0IGFuIGlkIG1hcHBpbmcgKHBhcnQgb2YgUmVzdWx0U3VibWlzc2lvbikgY29udGFpbnMgb25lIGVudHJ5IHBlciBwdWJsaWMga2V5LgogICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gaXNWYWxpZElETWFwcGluZyhwdWJLZXlzOiBbU3RyaW5nXT8sIGlkTWFwcGluZzoge1N0cmluZzogSW50fT8pOiBCb29sIHsKICAgICAgICBpZiBwdWJLZXlzID09IG5pbCB7CiAgICAgICAgICAgIC8vIEJ5IEludmFyaWFudCAoMSksIFRoaXMgaXMgYSBuaWwvZW1wdHkgc3VibWlzc2lvbiAoc2VlIGNoZWNrRW1wdHlTdWJtaXNzaW9uSW52YXJpYW50KQogICAgICAgICAgICByZXR1cm4gdHJ1ZQogICAgICAgIH0KICAgICAgICByZXR1cm4gcHViS2V5cyEubGVuZ3RoID09IGlkTWFwcGluZyEua2V5cy5sZW5ndGgKICAgIH0KCiAgICAvLyBSZXN1bHRTdWJtaXNzaW9uIHJlcHJlc2VudHMgYSByZXN1bHQgc3VibWlzc2lvbiBmcm9tIG9uZSBES0cgcGFydGljaXBhbnQuCiAgICAvLyBFYWNoIHN1Ym1pc3Npb24gaW5jbHVkZXMgYSBncm91cCBwdWJsaWMga2V5IGFuZCBhbiBvcmRlcmVkIGxpc3Qgb2YgcGFydGljaXBhbnQgcHVibGljIGtleXMuCiAgICAvLyBBIHN1Ym1pc3Npb24gbWF5IGJlIGVtcHR5LCBpbiB3aGljaCBjYXNlIGFsbCBmaWVsZHMgYXJlIG5pbCAtIHRoaXMgaXMgdXNlZCB0byByZXByZXNlbnQgYSBsb2NhbCBES0cgZmFpbHVyZS4KICAgIC8vIEFsbCBub24tZW1wdHkgc3VibWlzc2lvbiB3aWxsIGhhdmUgYWxsIG5vbi1uaWwsIHZhbGlkIGZpZWxkcy4KICAgIC8vIEJ5IGNvbnZlbnRpb24sIGFsbCBrZXlzIGFyZSBlbmNvZGVkIGFzIGxvd2VyY2FzZSBoZXggc3RyaW5ncywgdGhvdWdoIGl0IGlzIG5vdCBlbmZvcmNlZCBoZXJlLgogICAgLy8KICAgIC8vIElOVkFSSUFOVFM6CiAgICAvLyAgKDEpIGVpdGhlciBhbGwgZmllbGRzIGFyZSBuaWwgKGVtcHR5IHN1Ym1pc3Npb24pIG9yIG5vIGZpZWxkcyBhcmUgbmlsCiAgICAvLyAgKDIpIGFsbCBrZXkgc3RyaW5ncyBhcmUgdGhlIGV4cGVjdGVkIGxlbmd0aCBmb3IgQkxTIHB1YmxpYyBrZXlzCiAgICAvLyAgKDMpIGFsbCBub24tZW1wdHkgc3VibWlzc2lvbnMgaGF2ZSBvbmUgcGFydGljaXBhbnQga2V5IHBlciBub2RlIElEIGluIGlkTWFwcGluZwogICAgYWNjZXNzKGFsbCkgc3RydWN0IFJlc3VsdFN1Ym1pc3Npb24gewogICAgICAgIC8vIFRoZSBncm91cCBwdWJsaWMga2V5IGZvciB0aGUgYmVhY29uIGNvbW1pdHRlZSByZXN1bHRpbmcgZnJvbSB0aGUgREtHLgogICAgICAgIGFjY2VzcyhhbGwpIGxldCBncm91cFB1YktleTogU3RyaW5nPwogICAgICAgIC8vIEFuIG9yZGVyZWQgbGlzdCBvZiBpbmRpdmlkdWFsIHB1YmxpYyBrZXlzIGZvciB0aGUgYmVhY29uIGNvbW1pdHRlZSByZXN1bHRpbmcgZnJvbSB0aGUgREtHLgogICAgICAgIGFjY2VzcyhhbGwpIGxldCBwdWJLZXlzOiBbU3RyaW5nXT8KICAgICAgICAvLyBBIG1hcHBpbmcgZnJvbSBub2RlIElEIHRvIERLRyBpbmRleC4KICAgICAgICAvLyBUaGVyZSBtdXN0IGJlIGV4YWN0bHkgb25lIGtleSBwZXIgYXV0aG9yaXplZCBES0cgcGFydGljaXBhbnQuCiAgICAgICAgLy8gVGhlIHNldCBvZiB2YWx1ZXMgc2hvdWxkIGZvcm0gdGhlIHNldCB7MCwgMSwgMiwgLi4uIG4tMX0sIHdoZXJlIG4gaXMgdGhlIG51bWJlciBvZgogICAgICAgIC8vIGF1dGhvcml6ZWQgREtHIHBhcnRpY2lwYW50LCBob3dldmVyIHRoaXMgaXMgbm90IGVuZm9yY2VkIGhlcmUuCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IGlkTWFwcGluZzoge1N0cmluZzpJbnR9PwoKICAgICAgICBpbml0KGdyb3VwUHViS2V5OiBTdHJpbmc/LCBwdWJLZXlzOiBbU3RyaW5nXT8sIGlkTWFwcGluZzoge1N0cmluZzpJbnR9PykgewogICAgICAgICAgICBwcmUgewogICAgICAgICAgICAgICAgRmxvd0RLRy5jaGVja0VtcHR5U3VibWlzc2lvbkludmFyaWFudChncm91cFB1YktleTogZ3JvdXBQdWJLZXksIHB1YktleXM6IHB1YktleXMsIGlkTWFwcGluZzogaWRNYXBwaW5nKTogCiAgICAgICAgICAgICAgICAgICAgIkZsb3dES0cuUmVzdWx0U3VibWlzc2lvbi5pbml0OiB2aW9sYXRlcyBlbXB0eSBzdWJtaXNzaW9uIGludmFyaWFudCAtIFJlc3VsdFN1Ym1pc3Npb24gZmllbGRzIG11c3QgYmUgYWxsIG5pbCBvciBhbGwgbm9uLW5pbCIKICAgICAgICAgICAgICAgIEZsb3dES0cuaXNWYWxpZEdyb3VwS2V5KGdyb3VwUHViS2V5KToKICAgICAgICAgICAgICAgICAgICAiRmxvd0RLRy5SZXN1bHRTdWJtaXNzaW9uLmluaXQ6IGludmFsaWQgZ3JvdXAga2V5IC0gbXVzdCBiZSBuaWwgb3IgaGV4LWVuY29kZWQgOTYtYnl0ZSBzdHJpbmciCiAgICAgICAgICAgICAgICBGbG93REtHLmlzVmFsaWRQdWJLZXlzKHB1YktleXMpOgogICAgICAgICAgICAgICAgICAgICJGbG93REtHLlJlc3VsdFN1Ym1pc3Npb24uaW5pdDogaW52YWxpZCBwYXJ0aWNpcGFudCBrZXkgLSBtdXN0IGJlIG5pbCBvciBoZXgtZW5jb2RlZCA5Ni1ieXRlIHN0cmluZyIKICAgICAgICAgICAgICAgIEZsb3dES0cuaXNWYWxpZElETWFwcGluZyhwdWJLZXlzOiBwdWJLZXlzLCBpZE1hcHBpbmc6IGlkTWFwcGluZyk6CiAgICAgICAgICAgICAgICAgICAgIkZsb3dES0cuUmVzdWx0U3VibWlzc2lvbi5pbml0OiBpbnZhbGlkIElEIG1hcHBpbmcgLSBtdXN0IGJlIHNhbWUgc2l6ZSBhcyBwdWJLZXlzIgogICAgICAgICAgICB9CiAgICAgICAgICAgIHNlbGYuZ3JvdXBQdWJLZXkgPSBncm91cFB1YktleQogICAgICAgICAgICBzZWxmLnB1YktleXMgPSBwdWJLZXlzCiAgICAgICAgICAgIHNlbGYuaWRNYXBwaW5nID0gaWRNYXBwaW5nCiAgICAgICAgfQoKICAgICAgICAvLyBSZXR1cm5zIHRydWUgaWYgdGhpcyBSZXN1bHRTdWJtaXNzaW9uIGluc3RhbmNlIHJlcHJlc2VudHMgYW4gZW1wdHkgc3VibWlzc2lvbi4KICAgICAgICAvLyBTaW5jZSB0aGUgY29uc3RydWN0b3IgZW5mb3JjZXMgaW52YXJpYW50ICgxKSwgd2Ugb25seSBuZWVkIHRvIGNoZWNrIG9uZSBmaWVsZC4KICAgICAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBpc0VtcHR5KCk6IEJvb2wgewogICAgICAgICAgICByZXR1cm4gc2VsZi5ncm91cFB1YktleSA9PSBuaWwKICAgICAgICB9CgogICAgICAgIC8vIENoZWNrcyB3aGV0aGVyIHRoZSBpbnB1dCBpcyBlcXVpdmFsZW50IHRvIHRoaXMgUmVzdWx0U3VibWlzc2lvbi4KICAgICAgICAvLyBTdWJtaXNzaW9ucyBtdXN0IGhhdmUgaWRlbnRpY2FsIGtleXMsIGluIHRoZSBzYW1lIG9yZGVyLCBhbmQgaWRlbnRpY2FsIGluZGV4IG1hcHBpbmdzLgogICAgICAgIC8vIEVtcHR5IHN1Ym1pc3Npb25zIGFyZSBjb25zaWRlcmVkIGVxdWFsLgogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBlcXVhbHMoXyBvdGhlcjogRmxvd0RLRy5SZXN1bHRTdWJtaXNzaW9uKTogQm9vbCB7CiAgICAgICAgICAgIGlmIHNlbGYuZ3JvdXBQdWJLZXkgIT0gb3RoZXIuZ3JvdXBQdWJLZXkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlCiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgc2VsZi5wdWJLZXlzICE9IG90aGVyLnB1YktleXMgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlCiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgc2VsZi5pZE1hcHBpbmcgIT0gb3RoZXIuaWRNYXBwaW5nIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0cnVlCiAgICAgICAgfQoKICAgICAgICAvLyBDaGVja3Mgd2hldGhlciB0aGlzIFJlc3VsdFN1Ym1pc3Npb24gQ09VTEQgQkUgYSB2YWxpZCBzdWJtaXNzaW9uIGZvciB0aGUgZ2l2ZW4gREtHIGNvbW1pdHRlZS4KICAgICAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBpc1ZhbGlkRm9yQ29tbWl0dGVlKGF1dGhvcml6ZWQ6IFtTdHJpbmddKTogQm9vbCB7CiAgICAgICAgICAgIGlmIHNlbGYuaXNFbXB0eSgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIE11c3QgaGF2ZSBvbmUgcHVibGljIGtleSBwZXIgREtHIHBhcnRpY2lwYW50CiAgICAgICAgICAgIGlmIGF1dGhvcml6ZWQubGVuZ3RoICE9IHNlbGYucHViS2V5cyEubGVuZ3RoIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIE11c3QgaGF2ZSBhIERLRyBpbmRleCBtYXBwZWQgZm9yIGVhY2ggREtHIHBhcnRpY2lwYW50CiAgICAgICAgICAgIGZvciBub2RlSUQgaW4gYXV0aG9yaXplZCB7CiAgICAgICAgICAgICAgICBpZiBzZWxmLmlkTWFwcGluZyFbbm9kZUlEXSA9PSBuaWwgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0cnVlCiAgICAgICAgfQogICAgfQoKICAgIC8vIFN1Ym1pc3Npb25UcmFja2VyIHRyYWNrcyBhbGwgc3RhdGUgcmVsYXRlZCB0byByZXN1bHQgc3VibWlzc2lvbnMuCiAgICAvLyBJdCBpcyBpbnRlbmRlZCBmb3IgaW50ZXJuYWwgdXNlIGJ5IHRoZSBGbG93REtHIGNvbnRyYWN0IGFzIGEgcHJpdmF0ZSBzaW5nbGV0b24uCiAgICAvLyBGdXR1cmUgbW9kaWZpY2F0aW9ucyBNVVNUIE5PVCBtYWtlIHRoaXMgc2luZ2xldG9uIGluc3RhbmNlIG9mIFN1Ym1pc3Npb25UcmFja2VyIHB1YmxpY2x5IGFjY2Vzc2libGUuCiAgICBhY2Nlc3MoYWxsKSBzdHJ1Y3QgU3VibWlzc2lvblRyYWNrZXIgewogICAgICAgIC8vIFNldCBvZiBhdXRob3JpemVkIHBhcnRpY2lwYW50cyBmb3IgdGhpcyBES0cgaW5zdGFuY2UgKHRoZSAiREtHIGNvbW1pdHRlZSIpCiAgICAgICAgLy8gS2V5cyBhcmUgbm9kZSBJRHMsIGFzIHJlZ2lzdGVyZWQgaW4gdGhlIEZsb3dJRFRhYmxlU3Rha2luZyBjb250cmFjdC4KICAgICAgICAvLyBOT1RFOiBhbGwgdmFsdWVzIGFyZSB0cnVlIC0gdGhpcyBpcyBzdHJ1Y3R1cmVkIGFzIGEgbWFwIGZvciBPKDEpIGxvb2t1cDsgY29uY2VwdHVhbGx5IGl0IGlzIGEgc2V0LgogICAgICAgIGFjY2VzcyhhbGwpIHZhciBhdXRob3JpemVkOiB7U3RyaW5nOiBCb29sfQogICAgICAgIC8vIExpc3Qgb2YgdW5pcXVlIHN1Ym1pc3Npb25zLCBpbiBzdWJtaXNzaW9uIG9yZGVyCiAgICAgICAgYWNjZXNzKGFsbCkgdmFyIHVuaXF1ZXM6IFtGbG93REtHLlJlc3VsdFN1Ym1pc3Npb25dCiAgICAgICAgLy8gTWFwcyBub2RlIElEIG9mIGF1dGhvcml6ZWQgcGFydGljaXBhbnRzIHRvIGFuIGluZGV4IHdpdGhpbiAidW5pcXVlcyIKICAgICAgICBhY2Nlc3MoYWxsKSB2YXIgYnlOb2RlSUQ6IHtTdHJpbmc6IEludH0KICAgICAgICAvLyBNYXBzIGluZGV4IHdpdGhpbiAidW5pcXVlcyIgdG8gY291bnQgb2Ygc3VibWlzc2lvbnMKICAgICAgICBhY2Nlc3MoYWxsKSB2YXIgY291bnRzOiB7SW50OiBVSW50NjR9CgogICAgICAgIGluaXQoKSB7CiAgICAgICAgICAgIHNlbGYuYXV0aG9yaXplZCA9IHt9CiAgICAgICAgICAgIHNlbGYudW5pcXVlcyA9IFtdCiAgICAgICAgICAgIHNlbGYuYnlOb2RlSUQgPSB7fQogICAgICAgICAgICBzZWxmLmNvdW50cyA9IHt9CiAgICAgICAgfQoKICAgICAgICAvLyBDYWxsZWQgZWFjaCB0aW1lIGEgbmV3IERLRyBpbnN0YW5jZSBzdGFydHMsIHRvIHJlc2V0IFN1Ym1pc3Npb25UcmFja2VyIHN0YXRlLgogICAgICAgIC8vIE5PVEU6IHdlIGNvdWxkIGFsc28gcmUtaW5zdGFudGlhdGUgYSBuZXcgU3VibWlzc2lvblRyYWNrZXIgZWFjaCB0aW1lLCBidXQgdGhpcyBwYXR0ZXJuIG1ha2VzCiAgICAgICAgLy8gc3RvcmFnZSBtYW5hZ2VtZW50IHNpbXBsZXIgYmVjYXVzZSB5b3UgbmV2ZXIgbG9hZC9zYXZlIHRoZSB0cmFja2VyIGFmdGVyIGNvbnN0cnVjdGlvbiBvciB1cGdyYWRlLgogICAgICAgIGFjY2VzcyhhbGwpIGZ1biByZXNldChub2RlSURzOiBbU3RyaW5nXSkgewogICAgICAgICAgICBzZWxmLmF1dGhvcml6ZWQgPSB7fQogICAgICAgICAgICBzZWxmLnVuaXF1ZXMgPSBbXQogICAgICAgICAgICBzZWxmLmJ5Tm9kZUlEID0ge30KICAgICAgICAgICAgc2VsZi5jb3VudHMgPSB7fQogICAgICAgICAgICBmb3Igbm9kZUlEIGluIG5vZGVJRHMgewogICAgICAgICAgICAgICAgc2VsZi5hdXRob3JpemVkW25vZGVJRF0gPSB0cnVlCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIEFkZHMgdGhlIHJlc3VsdCBzdWJtaXNzaW9uIGZvciB0aGUgREtHIHBhcnRpY2lwYW50IGlkZW50aWZpZWQgYnkgbm9kZUlELgogICAgICAgIC8vIFRoZSBES0cgcGFydGljaXBhbnQgbXVzdCBiZSBhdXRob3JpemVkIGZvciB0aGUgY3VycmVudCBlcG9jaCwgYW5kIGVhY2ggcGFydGljaXBhbnQgbWF5IHN1Ym1pdCBvbmx5IG9uY2UuCiAgICAgICAgLy8gQ0FVVElPTjogVGhpcyBtZXRob2Qgc2hvdWxkIG9ubHkgYmUgY2FsbGVkIGJ5IFBhcnRpY2lwYW50LCB3aGljaCBlbmZvcmNlcyB0aGF0IFBhcnRpY2lwYW50Lm5vZGVJRCBpcyBwYXNzZWQgaW4uCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIGFkZFN1Ym1pc3Npb24obm9kZUlEOiBTdHJpbmcsIHN1Ym1pc3Npb246IFJlc3VsdFN1Ym1pc3Npb24pIHsKICAgICAgICAgICAgcHJlIHsKICAgICAgICAgICAgICAgIHNlbGYuYXV0aG9yaXplZFtub2RlSURdICE9IG5pbDoKICAgICAgICAgICAgICAgICAgICAiRmxvd0RLRy5hZGRTdWJtaXNzaW9uOiBTdWJtaXR0b3IgKG5vZGUgSUQ6IFwobm9kZUlEKSkgaXMgbm90IGF1dGhvcml6ZWQgZm9yIHRoaXMgREtHIGluc3RhbmNlLiIKICAgICAgICAgICAgICAgIHNlbGYuYnlOb2RlSURbbm9kZUlEXSA9PSBuaWw6CiAgICAgICAgICAgICAgICAgICAgIkZsb3dES0cuU3VibWlzc2lvblRyYWNrZXIuYWRkU3VibWlzc2lvbjogU3VibWl0dG9yIChub2RlIElEOiBcKG5vZGVJRCkpIG1heSBvbmx5IHN1Ym1pdCBvbmNlIGFuZCBoYXMgYWxyZWFkeSBzdWJtaXR0ZWQiCiAgICAgICAgICAgICAgICBzdWJtaXNzaW9uLmlzVmFsaWRGb3JDb21taXR0ZWUoYXV0aG9yaXplZDogc2VsZi5hdXRob3JpemVkLmtleXMpOgogICAgICAgICAgICAgICAgICAgICJGbG93REtHLlN1Ym1pc3Npb25UcmFja2VyLmFkZFN1Ym1pc3Npb246IFN1Ym1pc3Npb24gbXVzdCBjb250YWluIGV4YWN0bHkgb25lIHB1YmxpYyBrZXkgcGVyIGF1dGhvcml6ZWQgcGFydGljaXBhbnQiCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIDEpIENoZWNrIHdoZXRoZXIgdGhpcyBzdWJtaXNzaW9uIGlzIGVxdWl2YWxlbnQgdG8gYW4gZXhpc3Rpbmcgc3VibWlzc2lvbiAodHlwaWNhbCBjYXNlKQogICAgICAgICAgICB2YXIgc3VibWlzc2lvbkluZGV4ID0gMAogICAgICAgICAgICB3aGlsZSBzdWJtaXNzaW9uSW5kZXggPCBzZWxmLnVuaXF1ZXMubGVuZ3RoIHsKICAgICAgICAgICAgICAgIGlmIHN1Ym1pc3Npb24uZXF1YWxzKHNlbGYudW5pcXVlc1tzdWJtaXNzaW9uSW5kZXhdKSB7CiAgICAgICAgICAgICAgICAgICAgc2VsZi5ieU5vZGVJRFtub2RlSURdID0gc3VibWlzc2lvbkluZGV4CiAgICAgICAgICAgICAgICAgICAgc2VsZi5jb3VudHNbc3VibWlzc2lvbkluZGV4XSA9IHNlbGYuY291bnRzW3N1Ym1pc3Npb25JbmRleF0hICsgMSAKICAgICAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHN1Ym1pc3Npb25JbmRleCA9IHN1Ym1pc3Npb25JbmRleCArIDEKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gMikgVGhpcyBzdWJtaXNzaW9uIGRpZmZlcnMgZnJvbSBhbGwgZXhpc3Rpbmcgc3VibWlzc2lvbnMgKG9yIGlzIHRoZSBmaXJzdCksIHNvIGFkZCBhIG5ldyB1bmlxdWUgc3VibWlzc2lvbi4KICAgICAgICAgICAgLy8gTk9URTogYXQgdGhpcyBwb2ludCBzdWJtaXNzaW9uSW5kZXggPT0gc2VsZi51bmlxdWVzLmxlbmd0aCAodGhlIGluZGV4IG9mIHRoZSBzdWJtaXNzaW9uIHdlIGFyZSBhZGRpbmcpCiAgICAgICAgICAgIHNlbGYudW5pcXVlcy5hcHBlbmQoc3VibWlzc2lvbikKICAgICAgICAgICAgc2VsZi5ieU5vZGVJRFtub2RlSURdID0gc3VibWlzc2lvbkluZGV4CiAgICAgICAgICAgIHNlbGYuY291bnRzW3N1Ym1pc3Npb25JbmRleF0gPSAxCiAgICAgICAgfQoKICAgICAgICAvLyBSZXR1cm5zIHRoZSBub24tZW1wdHkgcmVzdWx0IHdoaWNoIHdhcyBzdWJtaXR0ZWQgYnkgYXQgbGVhc3QgdGhyZXNob2xkKzEgREtHIHBhcnRpY2lwYW50cy4KICAgICAgICAvLyBJZiBubyByZXN1bHQgcmVjZWl2ZWQgZW5vdWdoIHN1Ym1pc3Npb25zLCByZXR1cm5zIG5pbC4KICAgICAgICAvLyBDYWxsZXJzIHNob3VsZCB1c2UgYSB0aHJlc2hvbGQgdGhhdCBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gaGFsZiB0aGUgREtHIGNvbW1pdHRlZSBzaXplLgogICAgICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIHN1Ym1pc3Npb25FeGNlZWRzVGhyZXNob2xkKF8gdGhyZXNob2xkOiBVSW50NjQpOiBSZXN1bHRTdWJtaXNzaW9uPyB7CiAgICAgICAgICAgIHBvc3QgewogICAgICAgICAgICAgICAgcmVzdWx0ID09IG5pbCB8fCAhcmVzdWx0IS5pc0VtcHR5KCk6CiAgICAgICAgICAgICAgICAgICAgIkZsb3dES0cuU3VibWlzc2lvblRyYWNrZXIuc3VibWlzc2lvbkV4Y2VlZHNUaHJlc2hvbGQ6IElmIGEgc3VibWlzc2lvbiBpcyByZXR1cm5lZCwgaXQgbXVzdCBiZSBub24tZW1wdHkiCiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIHN1Ym1pc3Npb25JbmRleCA9IDAKICAgICAgICAgICAgd2hpbGUgc3VibWlzc2lvbkluZGV4IDwgc2VsZi51bmlxdWVzLmxlbmd0aCB7CiAgICAgICAgICAgICAgICBpZiBzZWxmLmNvdW50c1tzdWJtaXNzaW9uSW5kZXhdISA+IHRocmVzaG9sZCB7CiAgICAgICAgICAgICAgICAgICAgbGV0IHN1Ym1pc3Npb24gPSBzZWxmLnVuaXF1ZXNbc3VibWlzc2lvbkluZGV4XQogICAgICAgICAgICAgICAgICAgIC8vIGV4Y2x1ZGUgZW1wdHkgc3VibWlzc2lvbnMsIGFzIHRoZXNlIGFyZSBpbmVsaWdpYmxlIGZvciBjb25zaWRlcmluZyB0aGUgREtHIGNvbXBsZXRlZAogICAgICAgICAgICAgICAgICAgIGlmIHN1Ym1pc3Npb24uaXNFbXB0eSgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3VibWlzc2lvbkluZGV4ID0gc3VibWlzc2lvbkluZGV4ICsgMQogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvLyByZXR1cm4gdGhlIG5vbi1lbXB0eSBzdWJtaXNzaW9uIHN1Ym1pdHRlZCBieSA+dGhyZXNob2xkIERLRyBwYXJ0aWNpcGFudHMKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3VibWlzc2lvbgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgc3VibWlzc2lvbkluZGV4ID0gc3VibWlzc2lvbkluZGV4ICsgMQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBuaWwKICAgICAgICB9CgogICAgICAgIC8vIFJldHVybnMgdGhlIHJlc3VsdCBzdWJtaXR0ZWQgYnkgdGhlIG5vZGUgd2l0aCB0aGUgZ2l2ZW4gSUQuCiAgICAgICAgLy8gUmV0dXJucyBuaWwgaWYgdGhlIG5vZGUgaXMgbm90IGF1dGhvcml6ZWQgb3IgaGFzIG5vdCBzdWJtaXR0ZWQgZm9yIHRoZSBjdXJyZW50IERLRy4KICAgICAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBnZXRTdWJtaXNzaW9uQnlOb2RlSUQoXyBub2RlSUQ6IFN0cmluZyk6IFJlc3VsdFN1Ym1pc3Npb24/IHsKICAgICAgICAgICAgaWYgbGV0IHN1Ym1pc3Npb25JbmRleCA9IHNlbGYuYnlOb2RlSURbbm9kZUlEXSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZi51bmlxdWVzW3N1Ym1pc3Npb25JbmRleF0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbmlsCiAgICAgICAgfQoKICAgICAgICAvLyBSZXR1cm5zIGFsbCB1bmlxdWUgc3VibWlzc2lvbnMgZm9yIHRoZSBjdXJyZW50IERLRyBpbnN0YW5jZS4KICAgICAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBnZXRVbmlxdWVTdWJtaXNzaW9ucygpOiBbUmVzdWx0U3VibWlzc2lvbl0gewogICAgICAgICAgICByZXR1cm4gc2VsZi51bmlxdWVzCiAgICAgICAgfQogICAgfQoKICAgIC8vLyBUaGUgUGFydGljaXBhbnQgcmVzb3VyY2UgaXMgZ2VuZXJhdGVkIGZvciBlYWNoIGNvbnNlbnN1cyBub2RlIHdoZW4gdGhleSByZWdpc3Rlci4KICAgIC8vLyBFYWNoIHJlc291cmNlIGluc3RhbmNlIGlzIGdvb2QgZm9yIGFsbCBmdXR1cmUgcG90ZW50aWFsIGVwb2NocywgYnV0IHdpbGwKICAgIC8vLyBvbmx5IGJlIHZhbGlkIGlmIHRoZSBub2RlIG9wZXJhdG9yIGhhcyBiZWVuIGNvbmZpcm1lZCBhcyBhIGNvbnNlbnN1cyBub2RlIGZvciB0aGUgbmV4dCBlcG9jaC4KICAgIGFjY2VzcyhhbGwpIHJlc291cmNlIFBhcnRpY2lwYW50IHsKCiAgICAgICAgLy8vIFRoZSBub2RlIElEIG9mIHRoZSBwYXJ0aWNpcGFudAogICAgICAgIGFjY2VzcyhhbGwpIGxldCBub2RlSUQ6IFN0cmluZwoKICAgICAgICBpbml0KG5vZGVJRDogU3RyaW5nKSB7CiAgICAgICAgICAgIHByZSB7CiAgICAgICAgICAgICAgICBGbG93REtHLnBhcnRpY2lwYW50SXNDbGFpbWVkKG5vZGVJRCkgPT0gbmlsOgogICAgICAgICAgICAgICAgICAgICJGbG93REtHLlBhcnRpY2lwYW50LmluaXQ6IENhbm5vdCBjcmVhdGUgUGFydGljaXBhbnQgcmVzb3VyY2UgZm9yIGEgbm9kZSBJRCAoXChub2RlSUQpKSB0aGF0IGhhcyBhbHJlYWR5IGJlZW4gY2xhaW1lZCIKICAgICAgICAgICAgfQogICAgICAgICAgICBzZWxmLm5vZGVJRCA9IG5vZGVJRAogICAgICAgICAgICBGbG93REtHLm5vZGVDbGFpbWVkW25vZGVJRF0gPSB0cnVlCiAgICAgICAgfQoKICAgICAgICAvLy8gUG9zdHMgYSB3aGl0ZWJvYXJkIG1lc3NhZ2UgdG8gdGhlIGNvbnRyYWN0CiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIHBvc3RNZXNzYWdlKF8gY29udGVudDogU3RyaW5nKSB7CiAgICAgICAgICAgIHByZSB7CiAgICAgICAgICAgICAgICBGbG93REtHLnBhcnRpY2lwYW50SXNSZWdpc3RlcmVkKHNlbGYubm9kZUlEKToKICAgICAgICAgICAgICAgICAgICAiRmxvd0RLRy5QYXJ0aWNpcGFudC5wb3N0TWVzc2FnZTogQ2Fubm90IHBvc3Qgd2hpdGVib2FyZCBtZXNzYWdlLiBTZW5kZXIgKG5vZGUgSUQ6IFwoc2VsZi5ub2RlSUQpKSBpcyBub3QgcmVnaXN0ZXJlZCBmb3IgdGhlIGN1cnJlbnQgREtHIGluc3RhbmNlIgogICAgICAgICAgICAgICAgY29udGVudC5sZW5ndGggPiAwOgogICAgICAgICAgICAgICAgICAgICJGbG93REtHLlBhcnRpY2lwYW50LnBvc3RNZXNzYWdlOiBDYW5ub3QgcG9zdCBlbXB0eSBtZXNzYWdlIHRvIHRoZSB3aGl0ZWJvYXJkIgogICAgICAgICAgICAgICAgRmxvd0RLRy5ka2dFbmFibGVkOgogICAgICAgICAgICAgICAgICAgICJGbG93REtHLlBhcnRpY2lwYW50LnBvc3RNZXNzYWdlOiBDYW5ub3QgcG9zdCB3aGl0ZWJvYXJkIG1lc3NhZ2Ugd2hlbiBES0cgaXMgZGlzYWJsZWQiCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGNyZWF0ZSB0aGUgbWVzc2FnZSBzdHJ1Y3QKICAgICAgICAgICAgbGV0IG1lc3NhZ2UgPSBNZXNzYWdlKG5vZGVJRDogc2VsZi5ub2RlSUQsIGNvbnRlbnQ6IGNvbnRlbnQpCgogICAgICAgICAgICAvLyBhZGQgdGhlIG1lc3NhZ2UgdG8gdGhlIG1lc3NhZ2UgcmVjb3JkCiAgICAgICAgICAgIEZsb3dES0cud2hpdGVib2FyZE1lc3NhZ2VzLmFwcGVuZChtZXNzYWdlKQoKICAgICAgICAgICAgZW1pdCBCcm9hZGNhc3RNZXNzYWdlKG5vZGVJRDogc2VsZi5ub2RlSUQsIGNvbnRlbnQ6IGNvbnRlbnQpCgogICAgICAgIH0KCiAgICAgICAgLy8vIFNlbmRzIHRoZSBmaW5hbCBrZXkgdmVjdG9yIHN1Ym1pc3Npb24uIAogICAgICAgIC8vLyBDYW4gb25seSBiZSBjYWxsZWQgYnkgY29uc2Vuc3VzIG5vZGVzIHRoYXQgYXJlIHJlZ2lzdGVyZWQKICAgICAgICAvLy8gYW5kIGNhbiBvbmx5IGJlIGNhbGxlZCBvbmNlIHBlciBjb25zZW5zdXMgbm9kZSBwZXIgZXBvY2gKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gc2VuZEZpbmFsU3VibWlzc2lvbihfIHN1Ym1pc3Npb246IFJlc3VsdFN1Ym1pc3Npb24pIHsKICAgICAgICAgICAgcHJlIHsKICAgICAgICAgICAgICAgIEZsb3dES0cuZGtnRW5hYmxlZDoKICAgICAgICAgICAgICAgICAgICAiRmxvd0RLRy5QYXJ0aWNpcGFudC5wb3N0TWVzc2FnZTogQ2Fubm90IHNlbmQgZmluYWwgc3VibWlzc2lvbiB3aGVuIERLRyBpcyBkaXNhYmxlZCIKICAgICAgICAgICAgfQogICAgICAgICAgICBGbG93REtHLmJvcnJvd1N1Ym1pc3Npb25UcmFja2VyKCkuYWRkU3VibWlzc2lvbihub2RlSUQ6IHNlbGYubm9kZUlELCBzdWJtaXNzaW9uOiBzdWJtaXNzaW9uKQogICAgICAgIH0KICAgIH0KCiAgICAvLy8gSW50ZXJmYWNlIHRoYXQgb25seSBjb250YWlucyBvcGVyYXRpb25zIHRoYXQgYXJlIHBhcnQKICAgIC8vLyBvZiB0aGUgcmVndWxhciBhdXRvbWF0ZWQgZnVuY3Rpb25pbmcgb2YgdGhlIGVwb2NoIHByb2Nlc3MKICAgIC8vLyBUaGVzZSBhcmUgYWNjZXNzZWQgYnkgdGhlIGBGbG93RXBvY2hgIGNvbnRyYWN0IHRocm91Z2ggYSBjYXBhYmlsaXR5CiAgICBhY2Nlc3MoYWxsKSByZXNvdXJjZSBpbnRlcmZhY2UgRXBvY2hPcGVyYXRpb25zIHsKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gY3JlYXRlUGFydGljaXBhbnQobm9kZUlEOiBTdHJpbmcpOiBAUGFydGljaXBhbnQKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gc3RhcnRES0cobm9kZUlEczogW1N0cmluZ10pCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIGVuZERLRygpCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIGZvcmNlRW5kREtHKCkKICAgIH0KCiAgICAvLy8gVGhlIEFkbWluIHJlc291cmNlIHByb3ZpZGVzIHRoZSBhYmlsaXR5IHRvIGJlZ2luIGFuZCBlbmQgdm90aW5nIGZvciBhbiBlcG9jaAogICAgYWNjZXNzKGFsbCkgcmVzb3VyY2UgQWRtaW46IEVwb2NoT3BlcmF0aW9ucyB7CgogICAgICAgIC8vLyBTZXRzIHRoZSBvcHRpb25hbCBzYWZlIERLRyBzdWNjZXNzIHRocmVzaG9sZAogICAgICAgIC8vLyBTZXQgdGhlIHRocmVzaG9sZCB0byBuaWwgaWYgaXQgaXNuJ3QgbmVlZGVkCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIHNldFNhZmVTdWNjZXNzVGhyZXNob2xkKG5ld1RocmVzaG9sZFBlcmNlbnRhZ2U6IFVGaXg2ND8pIHsKICAgICAgICAgICAgcHJlIHsKICAgICAgICAgICAgICAgICFGbG93REtHLmRrZ0VuYWJsZWQ6CiAgICAgICAgICAgICAgICAgICAgIkZsb3dES0cuQWRtaW4uc2V0U2FmZVN1Y2Nlc3NUaHJlc2hvbGQ6IENhbm5vdCBzZXQgdGhlIERLRyBzdWNjZXNzIHRocmVzaG9sZCB3aGlsZSB0aGUgREtHIGlzIGVuYWJsZWQiCiAgICAgICAgICAgICAgICBuZXdUaHJlc2hvbGRQZXJjZW50YWdlID09IG5pbCB8fCBuZXdUaHJlc2hvbGRQZXJjZW50YWdlISA8IDEuMDoKICAgICAgICAgICAgICAgICAgICAiRmxvd0RLRy5BZG1pbi5zZXRTYWZlU3VjY2Vzc1RocmVzaG9sZDogSW52YWxpZCBpbnB1dC4gU2FmZSB0aHJlc2hvbGQgcGVyY2VudGFnZSBtdXN0IGJlIGluIFswLDEpIGJ1dCBnb3QgXChuZXdUaHJlc2hvbGRQZXJjZW50YWdlISkiCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEZsb3dES0cuYWNjb3VudC5zdG9yYWdlLmxvYWQ8VUZpeDY0Pihmcm9tOiAvc3RvcmFnZS9mbG93REtHU2FmZVRocmVzaG9sZCkKCiAgICAgICAgICAgIC8vIElmIG5ld1RocmVzaG9sZFBlcmNlbnRhZ2UgaXMgbmlsLCB3ZSBleGl0IGhlcmUuIFNpbmNlIHdlIGxvYWRlZCBmcm9tCiAgICAgICAgICAgIC8vIHN0b3JhZ2UgcHJldmlvdXNseSwgdGhpcyByZXN1bHRzIGluIC9zdG9yYWdlL2Zsb3dES0dTYWZlVGhyZXNob2xkIGJlaW5nIGVtcHR5CiAgICAgICAgICAgIGlmIGxldCBwZXJjZW50YWdlID0gbmV3VGhyZXNob2xkUGVyY2VudGFnZSB7CiAgICAgICAgICAgICAgICBGbG93REtHLmFjY291bnQuc3RvcmFnZS5zYXZlPFVGaXg2ND4ocGVyY2VudGFnZSwgdG86IC9zdG9yYWdlL2Zsb3dES0dTYWZlVGhyZXNob2xkKQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLy8gQ3JlYXRlcyBhIG5ldyBQYXJ0aWNpcGFudCByZXNvdXJjZSBmb3IgYSBjb25zZW5zdXMgbm9kZQogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBjcmVhdGVQYXJ0aWNpcGFudChub2RlSUQ6IFN0cmluZyk6IEBQYXJ0aWNpcGFudCB7CiAgICAgICAgICAgIGxldCBwYXJ0aWNpcGFudCA8LWNyZWF0ZSBQYXJ0aWNpcGFudChub2RlSUQ6IG5vZGVJRCkKICAgICAgICAgICAgRmxvd0RLRy5ub2RlQ2xhaW1lZFtub2RlSURdID0gdHJ1ZQogICAgICAgICAgICByZXR1cm4gPC1wYXJ0aWNpcGFudAogICAgICAgIH0KCiAgICAgICAgLy8vIFJlc2V0cyBhbGwgdGhlIGZpZWxkcyBmb3IgdHJhY2tpbmcgdGhlIGN1cnJlbnQgREtHIHByb2Nlc3MKICAgICAgICAvLy8gYW5kIHNldHMgdGhlIGdpdmVuIG5vZGUgSURzIGFzIHJlZ2lzdGVyZWQKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gc3RhcnRES0cobm9kZUlEczogW1N0cmluZ10pIHsKICAgICAgICAgICAgcHJlIHsKICAgICAgICAgICAgICAgIEZsb3dES0cuZGtnRW5hYmxlZCA9PSBmYWxzZToKICAgICAgICAgICAgICAgICAgICAiRmxvd0RLRy5BZG1pbi5zdGFydERLRzogQ2Fubm90IHN0YXJ0IHRoZSBES0cgd2hlbiBpdCBpcyBhbHJlYWR5IHJ1bm5pbmciCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENsZWFyIGFsbCBwZXItaW5zdGFuY2UgREtHIHN0YXRlCiAgICAgICAgICAgIEZsb3dES0cud2hpdGVib2FyZE1lc3NhZ2VzID0gW10KICAgICAgICAgICAgRmxvd0RLRy5ib3Jyb3dTdWJtaXNzaW9uVHJhY2tlcigpLnJlc2V0KG5vZGVJRHM6IG5vZGVJRHMpCiAgICAgICAgICAgIEZsb3dES0cudW5pcXVlRmluYWxTdWJtaXNzaW9ucyA9IFtdICAgICAvLyBkZXByZWNhdGVkIGFuZCB1bnVzZWQKICAgICAgICAgICAgRmxvd0RLRy51bmlxdWVGaW5hbFN1Ym1pc3Npb25Db3VudCA9IHt9IC8vIGRlcHJlY2F0ZWQgYW5kIHVudXNlZAoKICAgICAgICAgICAgRmxvd0RLRy5ka2dFbmFibGVkID0gdHJ1ZQoKICAgICAgICAgICAgZW1pdCBTdGFydERLRygpCiAgICAgICAgfQoKICAgICAgICAvLy8gRGlzYWJsZXMgdGhlIERLRyBhbmQgY2xvc2VzIHRoZSBvcHBvcnR1bml0eSBmb3IgbWVzc2FnZXMgYW5kIHN1Ym1pc3Npb25zCiAgICAgICAgLy8vIHVudGlsIHRoZSBuZXh0IHRpbWUgdGhlIERLRyBpcyBlbmFibGVkCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIGVuZERLRygpIHsKICAgICAgICAgICAgcHJlIHsgCiAgICAgICAgICAgICAgICBGbG93REtHLmRrZ0VuYWJsZWQgPT0gdHJ1ZToKICAgICAgICAgICAgICAgICAgICAiRmxvd0RLRy5BZG1pbi5lbmRES0c6IENhbm5vdCBlbmQgdGhlIERLRyB3aGVuIGl0IGlzIGFscmVhZHkgZGlzYWJsZWQiCiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGV0IGRrZ1Jlc3VsdCA9IEZsb3dES0cuZGtnQ29tcGxldGVkKCkKICAgICAgICAgICAgYXNzZXJ0KAogICAgICAgICAgICAgICAgZGtnUmVzdWx0ICE9IG5pbCwKICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICJGbG93REtHLkFkbWluLmVuZERLRzogQ2Fubm90IGVuZCB0aGUgREtHIHdpdGhvdXQgYSBjYW5vbmljYWwgZmluYWwgUmVzdWx0U3VibWlzc2lvbiIKICAgICAgICAgICAgKQoKICAgICAgICAgICAgRmxvd0RLRy5ka2dFbmFibGVkID0gZmFsc2UKCiAgICAgICAgICAgIGVtaXQgRW5kREtHKGZpbmFsU3VibWlzc2lvbjogZGtnUmVzdWx0KQogICAgICAgIH0KCiAgICAgICAgLy8vIEVuZHMgdGhlIERLRyB3aXRob3V0IGNoZWNraW5nIGlmIGl0IGlzIGNvbXBsZXRlZAogICAgICAgIC8vLyBTaG91bGQgb25seSBiZSB1c2VkIGlmIHNvbWV0aGluZyBnb2VzIHdyb25nIHdpdGggdGhlIERLRywKICAgICAgICAvLy8gdGhlIHByb3RvY29sIGhhbHRzLCBvciBuZWVkcyB0byBiZSByZXNldCBmb3Igc29tZSByZWFzb24KICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gZm9yY2VFbmRES0coKSB7CiAgICAgICAgICAgIEZsb3dES0cuZGtnRW5hYmxlZCA9IGZhbHNlCgogICAgICAgICAgICBlbWl0IEVuZERLRyhmaW5hbFN1Ym1pc3Npb246IEZsb3dES0cuZGtnQ29tcGxldGVkKCkpCiAgICAgICAgfQogICAgfQoKICAgIC8vLyBSZXR1cm5zIHRydWUgaWYgYSBub2RlIGlzIHJlZ2lzdGVyZWQgYXMgYSBjb25zZW5zdXMgbm9kZSBmb3IgdGhlIHByb3Bvc2VkIGVwb2NoCiAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBwYXJ0aWNpcGFudElzUmVnaXN0ZXJlZChfIG5vZGVJRDogU3RyaW5nKTogQm9vbCB7CiAgICAgICAgcmV0dXJuIEZsb3dES0cubXVzdEJvcnJvd1N1Ym1pc3Npb25UcmFja2VyKCkuYXV0aG9yaXplZFtub2RlSURdICE9IG5pbAogICAgfQoKICAgIC8vLyBSZXR1cm5zIHRydWUgaWYgYSBjb25zZW5zdXMgbm9kZSBoYXMgY2xhaW1lZCB0aGVpciBQYXJ0aWNpcGFudCByZXNvdXJjZQogICAgLy8vIHdoaWNoIGlzIHZhbGlkIGZvciBhbGwgZnV0dXJlIGVwb2NocyB3aGVyZSB0aGUgbm9kZSBpcyByZWdpc3RlcmVkCiAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBwYXJ0aWNpcGFudElzQ2xhaW1lZChfIG5vZGVJRDogU3RyaW5nKTogQm9vbD8gewogICAgICAgIHJldHVybiBGbG93REtHLm5vZGVDbGFpbWVkW25vZGVJRF0KICAgIH0KCiAgICAvLy8gR2V0cyBhbiBhcnJheSBvZiBhbGwgdGhlIHdoaXRlYm9hcmQgbWVzc2FnZXMKICAgIC8vLyB0aGF0IGhhdmUgYmVlbiBzdWJtaXR0ZWQgYnkgYWxsIG5vZGVzIGluIHRoZSBES0cKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGdldFdoaXRlQm9hcmRNZXNzYWdlcygpOiBbTWVzc2FnZV0gewogICAgICAgIHJldHVybiBzZWxmLndoaXRlYm9hcmRNZXNzYWdlcwogICAgfQoKICAgIC8vLyBSZXR1cm5zIHdoZXRoZXIgdGhpcyBub2RlIGhhcyBzdWNjZXNzZnVsbHkgc3VibWl0dGVkIGEgZmluYWwgc3VibWlzc2lvbiBmb3IgdGhpcyBlcG9jaC4KICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIG5vZGVIYXNTdWJtaXR0ZWQoXyBub2RlSUQ6IFN0cmluZyk6IEJvb2wgewogICAgICAgIHJldHVybiBzZWxmLm11c3RCb3Jyb3dTdWJtaXNzaW9uVHJhY2tlcigpLmJ5Tm9kZUlEW25vZGVJRF0gIT0gbmlsCiAgICB9CgogICAgLy8vIEdldHMgdGhlIHNwZWNpZmljIGZpbmFsIHN1Ym1pc3Npb24gZm9yIGEgbm9kZSBJRAogICAgLy8vIElmIHRoZSBub2RlIGhhc24ndCBzdWJtaXR0ZWQgb3IgcmVnaXN0ZXJlZCwgdGhpcyByZXR1cm5zIGBuaWxgCiAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBnZXROb2RlRmluYWxTdWJtaXNzaW9uKF8gbm9kZUlEOiBTdHJpbmcpOiBSZXN1bHRTdWJtaXNzaW9uPyB7CiAgICAgICAgcmV0dXJuIHNlbGYubXVzdEJvcnJvd1N1Ym1pc3Npb25UcmFja2VyKCkuZ2V0U3VibWlzc2lvbkJ5Tm9kZUlEKG5vZGVJRCkKICAgIH0KCiAgICAvLy8gR2V0IHRoZSBsaXN0IG9mIGFsbCB0aGUgY29uc2Vuc3VzIG5vZGUgSURzIHBhcnRpY2lwYXRpbmcKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGdldENvbnNlbnN1c05vZGVJRHMoKTogW1N0cmluZ10gewogICAgICAgIHJldHVybiAqc2VsZi5tdXN0Qm9ycm93U3VibWlzc2lvblRyYWNrZXIoKS5hdXRob3JpemVkLmtleXMKICAgIH0KCiAgICAvLy8gR2V0IHRoZSBhcnJheSBvZiBhbGwgdGhlIHVuaXF1ZSBmaW5hbCBzdWJtaXNzaW9ucwogICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gZ2V0RmluYWxTdWJtaXNzaW9ucygpOiBbUmVzdWx0U3VibWlzc2lvbl0gewogICAgICAgIHJldHVybiBzZWxmLm11c3RCb3Jyb3dTdWJtaXNzaW9uVHJhY2tlcigpLmdldFVuaXF1ZVN1Ym1pc3Npb25zKCkKICAgIH0KCiAgICAvLy8gR2V0IHRoZSBjb3VudCBvZiB0aGUgZmluYWwgc3VibWlzc2lvbnMgYXJyYXkKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGdldEZpbmFsU3VibWlzc2lvbkNvdW50KCk6IHtJbnQ6IFVJbnQ2NH0gewogICAgICAgIHJldHVybiAqc2VsZi5tdXN0Qm9ycm93U3VibWlzc2lvblRyYWNrZXIoKS5jb3VudHMKICAgIH0KCiAgICAvLy8gR2V0cyB0aGUgbmF0aXZlIHRocmVzaG9sZCB0aGF0IHRoZSBzdWJtaXNzaW9uIGNvdW50IG5lZWRzIHRvIGV4Y2VlZCB0byBiZSBjb25zaWRlcmVkIGNvbXBsZXRlIFt0PWZsb29yKChuLTEpLzIpXQogICAgLy8vIFRoaXMgZnVuY3Rpb24gcmV0dXJucyB0aGUgTk9OLUlOQ0xVU0lWRSBsb3dlciBib3VuZCBvZiBob25lc3QgcGFydGljaXBhbnRzLgogICAgLy8vIEZvciB0aGUgREtHIHRvIHN1Y2NlZWQsIHRoZSBudW1iZXIgb2YgaG9uZXN0IHBhcnRpY2lwYW50cyBtdXN0IEVYQ0VFRCB0aGlzIHRocmVzaG9sZCB2YWx1ZS4KICAgIC8vLyAKICAgIC8vLyBFeGFtcGxlOgogICAgLy8vIFdlIGhhdmUgMTAgREtHIG5vZGVzIChuPTEwKQogICAgLy8vIFRoZSB0aHJlc2hvbGQgdmFsdWUgaXMgdD1mbG9vcigxMC0xKS8yKSAodD00KQogICAgLy8vIFRoZXJlIG11c3QgYmUgQVQgTEVBU1QgNSBob25lc3Qgbm9kZXMgZm9yIHRoZSBES0cgdG8gc3VjY2VlZAogICAgLy8vIFRoZSBmdW5jdGlvbiBtdXN0IG1hdGNoIHRoZSB0aHJlc2hvbGQgY29tcHV0YXRpb24gb24gdGhlIHByb3RvY29sIHNpZGU6IGh0dHBzOi8vZ2l0aHViLmNvbS9vbmZsb3cvZmxvdy1nby9ibG9iL21hc3Rlci9tb2R1bGUvc2lnbmF0dXJlL3RocmVzaG9sZC5nbyNMNwogICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gZ2V0TmF0aXZlU3VjY2Vzc1RocmVzaG9sZCgpOiBVSW50NjQgewogICAgICAgIGxldCBuID0gc2VsZi5nZXRDb25zZW5zdXNOb2RlSURzKCkubGVuZ3RoCiAgICAgICAgLy8gYXZvaWQgaW5pdGlhbGl6aW5nIHRoZSB0aHJlc2hvbGQgdG8gMCB3aGVuIG49MgogICAgICAgIGlmIG4gPT0gMiB7CiAgICAgICAgICAgIHJldHVybiAxCiAgICAgICAgfQogICAgICAgIHJldHVybiBVSW50NjQoKG4tMSkvMikKICAgIH0KCiAgICAvLy8gR2V0cyB0aGUgc2FmZSB0aHJlc2hvbGQgdGhhdCB0aGUgc3VibWlzc2lvbiBjb3VudCBuZWVkcyB0byBleGNlZWQgdG8gYmUgY29uc2lkZXJlZCBjb21wbGV0ZS4KICAgIC8vLyAoYWx3YXlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgbmF0aXZlIHN1Y2Nlc3MgdGhyZXNob2xkKQogICAgLy8vIAogICAgLy8vIFRoaXMgZnVuY3Rpb24gcmV0dXJucyB0aGUgTk9OLUlOQ0xVU0lWRSBsb3dlciBib3VuZCBvZiBob25lc3QgcGFydGljaXBhbnRzLiBJZiB0aGlzIGZ1bmN0aW9uIAogICAgLy8vIHJldHVybnMgdGhyZXNob2xkIHQsIHRoZXJlIG11c3QgYmUgQVQgTEVBU1QgdCsxIGhvbmVzdCBub2RlcyBmb3IgdGhlIERLRyB0byBzdWNjZWVkLgogICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gZ2V0U2FmZVN1Y2Nlc3NUaHJlc2hvbGQoKTogVUludDY0IHsKICAgICAgICB2YXIgdGhyZXNob2xkID0gc2VsZi5nZXROYXRpdmVTdWNjZXNzVGhyZXNob2xkKCkKCiAgICAgICAgLy8gR2V0IHRoZSBzYWZldHkgcmF0ZSBwZXJjZW50YWdlCiAgICAgICAgaWYgbGV0IHNhZmV0eVJhdGUgPSBzZWxmLmdldFNhZmVUaHJlc2hvbGRQZXJjZW50YWdlKCkgewoKICAgICAgICAgICAgbGV0IHNhZmVUaHJlc2hvbGQgPSBVSW50NjQoc2FmZXR5UmF0ZSAqIFVGaXg2NChzZWxmLmdldENvbnNlbnN1c05vZGVJRHMoKS5sZW5ndGgpKQoKICAgICAgICAgICAgaWYgc2FmZVRocmVzaG9sZCA+IHRocmVzaG9sZCB7CiAgICAgICAgICAgICAgICB0aHJlc2hvbGQgPSBzYWZlVGhyZXNob2xkCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0aHJlc2hvbGQKICAgIH0KCiAgICAvLy8gR2V0cyB0aGUgc2FmZSB0aHJlc2hvbGQgcGVyY2VudGFnZS4gVGhpcyB2YWx1ZSBtdXN0IGJlIGVpdGhlciBuaWwgKHNlbWFudGljYWxseTogMCkgb3IgaW4gWzAsIDEuMCkKICAgIC8vLyBUaGlzIHNhZmUgdGhyZXNob2xkIGlzIHVzZWQgdG8gYXJ0aWZpY2lhbGx5IGluY3JlYXNlIHRoZSBES0cgcGFydGljaXBhdGlvbiByZXF1aXJlbWVudHMgdG8gCiAgICAvLy8gZW5zdXJlIGEgbG93ZXItYm91bmQgbnVtYmVyIG9mIFJhbmRvbSBCZWFjb24gQ29tbWl0dGVlIG1lbWJlcnMgKGJleW9uZCB0aGUgYmFyZSBtaW5pbXVtIHJlcXVpcmVkCiAgICAvLy8gYnkgdGhlIERLRyBwcm90b2NvbCkuCiAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBnZXRTYWZlVGhyZXNob2xkUGVyY2VudGFnZSgpOiBVRml4NjQ/IHsKICAgICAgICBsZXQgc2FmZXR5UmF0ZSA9IHNlbGYuYWNjb3VudC5zdG9yYWdlLmNvcHk8VUZpeDY0Pihmcm9tOiAvc3RvcmFnZS9mbG93REtHU2FmZVRocmVzaG9sZCkKICAgICAgICByZXR1cm4gc2FmZXR5UmF0ZQogICAgfQoKICAgIC8vIEJvcnJvd3MgdGhlIHNpbmdsZXRvbiBTdWJtaXNzaW9uVHJhY2tlciBmcm9tIHN0b3JhZ2UsIGNyZWF0aW5nIGl0IGlmIG5vbmUgZXhpc3RzLgogICAgYWNjZXNzKGNvbnRyYWN0KSBmdW4gYm9ycm93U3VibWlzc2lvblRyYWNrZXIoKTogJkZsb3dES0cuU3VibWlzc2lvblRyYWNrZXIgewogICAgICAgIC8vIFRoZSBzaW5nbGV0b24gU3VibWlzc2lvblRyYWNrZXIgYWxyZWFkeSBleGlzdHMgaW4gc3RvcmFnZSAtIHJldHVybiBhIHJlZmVyZW5jZSB0byBpdC4KICAgICAgICBpZiBsZXQgdHJhY2tlciA9IHNlbGYuYWNjb3VudC5zdG9yYWdlLmJvcnJvdzwmU3VibWlzc2lvblRyYWNrZXI+KGZyb206IC9zdG9yYWdlL2Zsb3dES0dGaW5hbFN1Ym1pc3Npb25UcmFja2VyKSB7CiAgICAgICAgICAgIHJldHVybiB0cmFja2VyCiAgICAgICAgfQogICAgICAgIC8vIFRoZSBzaW5nbGV0b24gU3VibWlzc2lvblRyYWNrZXIgaGFzIG5vdCBiZWVuIGNyZWF0ZWQgeWV0IC0gY3JlYXRlIGl0IGFuZCByZXR1cm4gYSByZWZlcmVuY2UuCiAgICAgICAgLy8gVGhpcyBjb2RlcGF0aCBzaG91bGQgYmUgZXhlY3V0ZWQgYXQgbW9zdCBvbmNlIHBlciBGbG93REtHIGluc3RhbmNlIGFuZCBvbmx5IGlmIGl0IHdhcyB1cGdyYWRlZCBmcm9tIGFuIG9sZGVyIHZlcnNpb24uCiAgICAgICAgc2VsZi5hY2NvdW50LnN0b3JhZ2Uuc2F2ZShTdWJtaXNzaW9uVHJhY2tlcigpLCB0bzogL3N0b3JhZ2UvZmxvd0RLR0ZpbmFsU3VibWlzc2lvblRyYWNrZXIpCiAgICAgICAgcmV0dXJuIHNlbGYubXVzdEJvcnJvd1N1Ym1pc3Npb25UcmFja2VyKCkKICAgIH0KCiAgICAvLyBCb3Jyb3dzIHRoZSBzaW5nbGV0b24gU3VibWlzc2lvblRyYWNrZXIgZnJvbSBzdG9yYWdlOyBwYW5pY3MgaWYgbm9uZSBleGlzdHMuCiAgICBhY2Nlc3MoY29udHJhY3QpIHZpZXcgZnVuIG11c3RCb3Jyb3dTdWJtaXNzaW9uVHJhY2tlcigpOiAmRmxvd0RLRy5TdWJtaXNzaW9uVHJhY2tlciB7CiAgICAgICAgcmV0dXJuIHNlbGYuYWNjb3VudC5zdG9yYWdlLmJvcnJvdzwmU3VibWlzc2lvblRyYWNrZXI+KGZyb206IC9zdG9yYWdlL2Zsb3dES0dGaW5hbFN1Ym1pc3Npb25UcmFja2VyKSA/PwogICAgICAgICAgICBwYW5pYygiRmxvd0RLRy5tdXN0Qm9ycm93U3VibWlzc2lvblRyYWNrZXI6IENyaXRpY2FsIGludmFyaWFudCB2aW9sYXRlZCEgTm8gU3VibWlzc2lvblRyYWNrZXIgaW5zdGFuY2Ugc3RvcmVkIGF0IC9zdG9yYWdlL2Zsb3dES0dGaW5hbFN1Ym1pc3Npb25UcmFja2VyIikKICAgIH0KCiAgICAvLy8gUmV0dXJucyB0aGUgZmluYWwgc2V0IG9mIGtleXMgaWYgYW55IG9uZSBzZXQgb2Yga2V5cyBoYXMgc3RyaWN0bHkgbW9yZSB0aGFuIChub2Rlcy0xKS8yIHN1Ym1pc3Npb25zCiAgICAvLy8gUmV0dXJucyBuaWwgaWYgbm90IGZvdW5kIChpbmNvbXBsZXRlKQogICAgYWNjZXNzKGFsbCkgZnVuIGRrZ0NvbXBsZXRlZCgpOiBSZXN1bHRTdWJtaXNzaW9uPyB7CiAgICAgICAgaWYgIXNlbGYuZGtnRW5hYmxlZCB7IHJldHVybiBuaWwgfQoKICAgICAgICBsZXQgdGhyZXNob2xkID0gc2VsZi5nZXRTYWZlU3VjY2Vzc1RocmVzaG9sZCgpCiAgICAgICAgcmV0dXJuIHNlbGYuYm9ycm93U3VibWlzc2lvblRyYWNrZXIoKS5zdWJtaXNzaW9uRXhjZWVkc1RocmVzaG9sZCh0aHJlc2hvbGQpCiAgICB9CgogICAgaW5pdCgpIHsKICAgICAgICBzZWxmLnN1Ym1pc3Npb25LZXlMZW5ndGggPSAxOTIgLy8gOTYgYnl0ZXMsIGhleC1lbmNvZGVkCgogICAgICAgIHNlbGYuQWRtaW5TdG9yYWdlUGF0aCA9IC9zdG9yYWdlL2Zsb3dFcG9jaHNES0dBZG1pbgogICAgICAgIHNlbGYuUGFydGljaXBhbnRTdG9yYWdlUGF0aCA9IC9zdG9yYWdlL2Zsb3dFcG9jaHNES0dQYXJ0aWNpcGFudAogICAgICAgIHNlbGYuUGFydGljaXBhbnRQdWJsaWNQYXRoID0gL3B1YmxpYy9mbG93RXBvY2hzREtHUGFydGljaXBhbnQKCiAgICAgICAgc2VsZi5ka2dFbmFibGVkID0gZmFsc2UKCiAgICAgICAgc2VsZi5maW5hbFN1Ym1pc3Npb25CeU5vZGVJRCA9IHt9ICAgIC8vIGRlcHJlY2F0ZWQKICAgICAgICBzZWxmLnVuaXF1ZUZpbmFsU3VibWlzc2lvbkNvdW50ID0ge30gLy8gZGVwcmVjYXRlZAogICAgICAgIHNlbGYudW5pcXVlRmluYWxTdWJtaXNzaW9ucyA9IFtdICAgICAvLyBkZXByZWNhdGVkCiAgICAgICAgCiAgICAgICAgc2VsZi5ub2RlQ2xhaW1lZCA9IHt9CiAgICAgICAgc2VsZi53aGl0ZWJvYXJkTWVzc2FnZXMgPSBbXQoKICAgICAgICBzZWxmLmFjY291bnQuc3RvcmFnZS5zYXZlKDwtY3JlYXRlIEFkbWluKCksIHRvOiBzZWxmLkFkbWluU3RvcmFnZVBhdGgpCiAgICAgICAgc2VsZi5hY2NvdW50LnN0b3JhZ2Uuc2F2ZShTdWJtaXNzaW9uVHJhY2tlcigpLCB0bzogL3N0b3JhZ2UvZmxvd0RLR0ZpbmFsU3VibWlzc2lvblRyYWNrZXIpCiAgICB9Cn0KIAo=",
		"FlowEpoch": "aW1wb3J0IEZ1bmdpYmxlVG9rZW4gZnJvbSAweGYyMzNkY2VlODhmZTBhYmUKaW1wb3J0IEZsb3dUb2tlbiBmcm9tIDB4MTY1NDY1MzM5OTA0MGE2MQppbXBvcnQgRmxvd0lEVGFibGVTdGFraW5nIGZyb20gMHg4NjI0YjUyZjlkZGNkMDRhCmltcG9ydCBGbG93Q2x1c3RlclFDIGZyb20gMHg4NjI0YjUyZjlkZGNkMDRhCmltcG9ydCBGbG93REtHIGZyb20gMHg4NjI0YjUyZjlkZGNkMDRhCmltcG9ydCBGbG93RmVlcyBmcm9tIDB4ZjkxOWVlNzc0NDdiNzQ5NwoKLy8gVGhlIHRvcC1sZXZlbCBzbWFydCBjb250cmFjdCBtYW5hZ2luZyB0aGUgbGlmZWN5Y2xlIG9mIGVwb2Nocy4gSW4gRmxvdywKLy8gZXBvY2hzIGFyZSB0aGUgc21hbGxlc3QgdW5pdCBvZiB0aW1lIHdoZXJlIHRoZSBpZGVudGl0eSB0YWJsZSAodGhlIHNldCBvZgovLyBuZXR3b3JrIG9wZXJhdG9ycykgaXMgc3RhdGljLiBPcGVyYXRvcnMgbWF5IG9ubHkgbGVhdmUgb3Igam9pbiB0aGUgbmV0d29yawovLyBhdCBlcG9jaCBib3VuZGFyaWVzLiBPcGVyYXRvcnMgbWF5IGJlIGVqZWN0ZWQgZHVyaW5nIGFuIGVwb2NoIGZvciB2YXJpb3VzCi8vIG1pc2RlbWVhbm91cnMsIGJ1dCB0aGV5IHJlbWFpbiBpbiB0aGUgaWRlbnRpdHkgdGFibGUgdW50aWwgdGhlIGVwb2NoIGVuZHMuCi8vCi8vIEVwb2NocyBhcmUgc3BsaXQgaW50byAzIHBoYXNlczoKLy8gfD09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gfCBFUE9DSCBOICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBFUE9DSCBOKzEgLi4uCi8vIHwtLS0tLSBTdGFraW5nIC0tLS0tfC0gU2V0dXAgLXwtIENvbW1pdHRlZCAtfHwgLi4uCi8vIHw9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vCi8vIDEpICBTVEFLSU5HIFBIQVNFCi8vIE5vZGUgb3BlcmF0b3JzIGFyZSBhYmxlIHRvIHN1Ym1pdCBzdGFraW5nIHJlcXVlc3RzIGZvciB0aGUgTkVYVCBlcG9jaCBkdXJpbmcKLy8gdGhpcyBwaGFzZS4gQXQgdGhlIGVuZCBvZiB0aGlzIHBoYXNlLCB0aGUgRXBvY2ggc21hcnQgY29udHJhY3QgcmVzb2x2ZXMgdGhlCi8vIG91dHN0YW5kaW5nIHN0YWtpbmcgcmVxdWVzdHMgYW5kIGRldGVybWluZXMgdGhlIGlkZW50aXR5IHRhYmxlIGZvciB0aGUgbmV4dAovLyBlcG9jaC4gVGhlIEVwb2NoIHNtYXJ0IGNvbnRyYWN0IGVtaXRzIHRoZSBFcG9jaFNldHVwIHNlcnZpY2UgZXZlbnQgY29udGFpbmluZwovLyB0aGUgaWRlbnRpdHkgdGFibGUgZm9yIHRoZSBuZXh0IGVwb2NoLCB3aGljaCBpbml0aWF0ZXMgdGhlIHRyYW5zaXRpb24gdG8gdGhlCi8vIEVwb2NoIFNldHVwIFBoYXNlLgovLwovLyAyKSBTRVRVUCBQSEFTRQovLyBXaGVuIHRoaXMgcGhhc2UgYmVnaW5zIHRoZSBwYXJ0aWNpcGFudHMgaW4gdGhlIG5leHQgZXBvY2ggYXJlIHNldC4gRHVyaW5nIHRoaXMKLy8gcGhhc2UsIHRoZXNlIHBhcnRpY2lwYW50cyBwcmVwYXJlIGZvciB0aGUgbmV4dCBlcG9jaC4gSW4gcGFydGljdWxhciwgY29sbGVjdGlvbgovLyBub2RlcyBzdWJtaXQgdm90ZXMgZm9yIHRoZWlyIGNsdXN0ZXIncyByb290IHF1b3J1bSBjZXJ0aWZpY2F0ZSBhbmQgY29uc2Vuc3VzCi8vIG5vZGVzIHJ1biB0aGUgZGlzdHJpYnV0ZWQga2V5IGdlbmVyYXRpb24gcHJvdG9jb2wgKERLRykgdG8gc2V0IHVwIHRoZSByYW5kb20KLy8gYmVhY29uLiBXaGVuIHRoZXNlIHByZXBhcmF0aW9ucyBhcmUgY29tcGxldGUsIHRoZSBFcG9jaCBzbWFydCBjb250cmFjdCBlbWl0cyB0aGUKLy8gRXBvY2hDb21taXQgc2VydmljZSBldmVudCBjb250YWluaW5nIHRoZSBhcnRpZmFjdHMgb2YgdGhlIHNldCBwcm9jZXNzLCB3aGljaAovLyBpbml0aWF0ZXMgdGhlIHRyYW5zaXRpb24gdG8gdGhlIEVwb2NoIENvbW1pdCBQaGFzZS4KLy8KLy8gMykgQ09NTUlUVEVEIFBIQVNFCi8vIFdoZW4gdGhpcyBwaGFzZSBiZWdpbnMsIHRoZSBuZXR3b3JrIGlzIGZ1bGx5IHByZXBhcmVkIHRvIHRyYW5zaXRpb24gdG8gdGhlIG5leHQKLy8gZXBvY2guIEEgZmFpbHVyZSB0byBlbnRlciB0aGlzIHBoYXNlIGJlZm9yZSB0cmFuc2l0aW9uaW5nIHRvIHRoZSBuZXh0IGVwb2NoCi8vIGluZGljYXRlcyB0aGF0IHRoZSBwYXJ0aWNpcGFudHMgaW4gdGhlIG5leHQgZXBvY2ggZmFpbGVkIHRvIGNvbXBsZXRlIHRoZSBzZXQgdXAKLy8gcHJvY2VkdXJlLCB3aGljaCBpcyBhIGNyaXRpY2FsIGZhaWx1cmUgYW5kIHdpbGwgY2F1c2UgdGhlIGNoYWluIHRvIGhhbHQuCgphY2Nlc3MoYWxsKSBjb250cmFjdCBGbG93RXBvY2ggewoKICAgIGFjY2VzcyhhbGwpIGVudW0gRXBvY2hQaGFzZTogVUludDggewogICAgICAgIGFjY2VzcyhhbGwpIGNhc2UgU1RBS0lOR0FVQ1RJT04KICAgICAgICBhY2Nlc3MoYWxsKSBjYXNlIEVQT0NIU0VUVVAKICAgICAgICBhY2Nlc3MoYWxsKSBjYXNlIEVQT0NIQ09NTUlUCiAgICB9CgogICAgYWNjZXNzKGFsbCkgZW51bSBOb2RlUm9sZTogVUludDggewogICAgICAgIGFjY2VzcyhhbGwpIGNhc2UgTk9ORQogICAgICAgIGFjY2VzcyhhbGwpIGNhc2UgQ29sbGVjdG9yCiAgICAgICAgYWNjZXNzKGFsbCkgY2FzZSBDb25zZW5zdXMKICAgICAgICBhY2Nlc3MoYWxsKSBjYXNlIEV4ZWN1dGlvbgogICAgICAgIGFjY2VzcyhhbGwpIGNhc2UgVmVyaWZpY2F0aW9uCiAgICAgICAgYWNjZXNzKGFsbCkgY2FzZSBBY2Nlc3MKICAgIH0KCiAgICAvLy8gVGhlIEVwb2NoIFN0YXJ0IHNlcnZpY2UgZXZlbnQgaXMgZW1pdHRlZCB3aGVuIHRoZSBjb250cmFjdCB0cmFuc2l0aW9ucwogICAgLy8vIHRvIGEgbmV3IGVwb2NoIGluIHRoZSBzdGFraW5nIGF1Y3Rpb24gcGhhc2UuCiAgICBhY2Nlc3MoYWxsKSBldmVudCBFcG9jaFN0YXJ0ICgKCiAgICAgICAgLy8vIFRoZSBjb3VudGVyIGZvciB0aGUgY3VycmVudCBlcG9jaCB0aGF0IGlzIGJlZ2lubmluZwogICAgICAgIGNvdW50ZXI6IFVJbnQ2NCwKCiAgICAgICAgLy8vIFRoZSBmaXJzdCB2aWV3IChpbmNsdXNpdmUpIG9mIHRoZSBjdXJyZW50IGVwb2NoLgogICAgICAgIGZpcnN0VmlldzogVUludDY0LAoKICAgICAgICAvLy8gVGhlIGxhc3QgdmlldyAoaW5jbHVzaXZlKSBvZiB0aGUgY3VycmVudCBlcG9jaCdzIHN0YWtpbmcgYXVjdGlvbi4KICAgICAgICBzdGFraW5nQXVjdGlvbkVuZFZpZXc6IFVJbnQ2NCwKCiAgICAgICAgLy8vIFRoZSBsYXN0IHZpZXcgKGluY2x1c2l2ZSkgb2YgdGhlIGN1cnJlbnQgZXBvY2guCiAgICAgICAgZmluYWxWaWV3OiBVSW50NjQsCgogICAgICAgIC8vLyBUb3RhbCBGTE9XIHN0YWtlZCBieSBhbGwgbm9kZXMgYW5kIGRlbGVnYXRvcnMgZm9yIHRoZSBjdXJyZW50IGVwb2NoLgogICAgICAgIHRvdGFsU3Rha2VkOiBVRml4NjQsCgogICAgICAgIC8vLyBUb3RhbCBzdXBwbHkgb2YgYWxsIEZMT1cgZm9yIHRoZSBjdXJyZW50IGVwb2NoCiAgICAgICAgLy8vIEluY2x1ZGVzIHRoZSByZXdhcmRzIHRoYXQgd2lsbCBiZSBwYWlkIGZvciB0aGUgcHJldmlvdXMgZXBvY2gKICAgICAgICB0b3RhbEZsb3dTdXBwbHk6IFVGaXg2NCwKCiAgICAgICAgLy8vIFRoZSB0b3RhbCByZXdhcmRzIHRoYXQgd2lsbCBiZSBwYWlkIG91dCBhdCB0aGUgZW5kIG9mIHRoZSBjdXJyZW50IGVwb2NoLgogICAgICAgIHRvdGFsUmV3YXJkczogVUZpeDY0LAogICAgKQoKICAgIC8vLyBUaGUgRXBvY2ggU2V0dXAgc2VydmljZSBldmVudCBpcyBlbWl0dGVkIHdoZW4gd2UgdHJhbnNpdGlvbiB0byB0aGUgRXBvY2ggU2V0dXAKICAgIC8vLyBwaGFzZS4gSXQgY29udGFpbnMgdGhlIGZpbmFsaXplZCBpZGVudGl0eSB0YWJsZSBmb3IgdGhlIHVwY29taW5nIGVwb2NoLgogICAgYWNjZXNzKGFsbCkgZXZlbnQgRXBvY2hTZXR1cCgKCiAgICAgICAgLy8vIFRoZSBjb3VudGVyIGZvciB0aGUgdXBjb21pbmcgZXBvY2guIE11c3QgYmUgb25lIGdyZWF0ZXIgdGhhbiB0aGUKICAgICAgICAvLy8gY291bnRlciBmb3IgdGhlIGN1cnJlbnQgZXBvY2guCiAgICAgICAgY291bnRlcjogVUludDY0LAoKICAgICAgICAvLy8gSWRlbnRpdHkgdGFibGUgZm9yIHRoZSB1cGNvbWluZyBlcG9jaCB3aXRoIGFsbCBub2RlIGluZm9ybWF0aW9uLgogICAgICAgIC8vLyBJbmNsdWRlczoKICAgICAgICAvLy8gbm9kZUlELCBzdGFraW5nIGtleSwgbmV0d29ya2luZyBrZXksIG5ldHdvcmtpbmcgYWRkcmVzcywgcm9sZSwKICAgICAgICAvLy8gc3Rha2luZyBpbmZvcm1hdGlvbiwgd2VpZ2h0LCBhbmQgbW9yZS4KICAgICAgICBub2RlSW5mbzogW0Zsb3dJRFRhYmxlU3Rha2luZy5Ob2RlSW5mb10sCgogICAgICAgIC8vLyBUaGUgZmlyc3QgdmlldyAoaW5jbHVzaXZlKSBvZiB0aGUgdXBjb21pbmcgZXBvY2guCiAgICAgICAgZmlyc3RWaWV3OiBVSW50NjQsCgogICAgICAgIC8vLyBUaGUgbGFzdCB2aWV3IChpbmNsdXNpdmUpIG9mIHRoZSB1cGNvbWluZyBlcG9jaC4KICAgICAgICBmaW5hbFZpZXc6IFVJbnQ2NCwKCiAgICAgICAgLy8vIFRoZSBjbHVzdGVyIGFzc2lnbm1lbnQgZm9yIHRoZSB1cGNvbWluZyBlcG9jaC4gRWFjaCBlbGVtZW50IGluIHRoZSBsaXN0CiAgICAgICAgLy8vIHJlcHJlc2VudHMgb25lIGNsdXN0ZXIgYW5kIGNvbnRhaW5zIGFsbCB0aGUgbm9kZSBJRHMgYXNzaWduZWQgdG8gdGhhdAogICAgICAgIC8vLyBjbHVzdGVyLCB3aXRoIHRoZWlyIHdlaWdodHMgYW5kIHZvdGVzCiAgICAgICAgY29sbGVjdG9yQ2x1c3RlcnM6IFtGbG93Q2x1c3RlclFDLkNsdXN0ZXJdLAoKICAgICAgICAvLy8gVGhlIHNvdXJjZSBvZiByYW5kb21uZXNzIHRvIHNlZWQgdGhlIGxlYWRlciBzZWxlY3Rpb24gYWxnb3JpdGhtIHdpdGgKICAgICAgICAvLy8gZm9yIHRoZSB1cGNvbWluZyBlcG9jaC4KICAgICAgICByYW5kb21Tb3VyY2U6IFN0cmluZywKCiAgICAgICAgLy8vIFRoZSBkZWFkbGluZXMgb2YgZWFjaCBwaGFzZSBpbiB0aGUgREtHIHByb3RvY29sIHRvIGJlIGNvbXBsZXRlZCBpbiB0aGUgdXBjb21pbmcKICAgICAgICAvLy8gRXBvY2hTZXR1cCBwaGFzZS4gRGVhZGxpbmVzIGFyZSBzcGVjaWZpZWQgaW4gdGVybXMgb2YgYSBjb25zZW5zdXMgdmlldyBudW1iZXIuCiAgICAgICAgLy8vIFdoZW4gYSBES0cgcGFydGljaXBhbnQgb2JzZXJ2ZXMgYSBmaW5hbGl6ZWQgYW5kIHNlYWxlZCBibG9jayB3aXRoIHZpZXcgZ3JlYXRlcgogICAgICAgIC8vLyB0aGFuIHRoZSBnaXZlbiBkZWFkbGluZSwgaXQgY2FuIHNhZmVseSB0cmFuc2l0aW9uIHRvIHRoZSBuZXh0IHBoYXNlLgogICAgICAgIERLR1BoYXNlMUZpbmFsVmlldzogVUludDY0LAogICAgICAgIERLR1BoYXNlMkZpbmFsVmlldzogVUludDY0LAogICAgICAgIERLR1BoYXNlM0ZpbmFsVmlldzogVUludDY0LAoKICAgICAgICAvLy8gVGhlIHRhcmdldCBkdXJhdGlvbiBmb3IgdGhlIHVwY29taW5nIGVwb2NoLCBpbiBzZWNvbmRzCiAgICAgICAgdGFyZ2V0RHVyYXRpb246IFVJbnQ2NCwKICAgICAgICAvLy8gVGhlIHRhcmdldCBlbmQgdGltZSBmb3IgdGhlIHVwY29taW5nIGVwb2NoLCBzcGVjaWZpZWQgaW4gc2Vjb25kLXByZWNpc2lvbiBVbml4IHRpbWUKICAgICAgICB0YXJnZXRFbmRUaW1lOiBVSW50NjQKICAgICkKCiAgICAvLy8gVGhlIEVwb2NoQ29tbWl0IHNlcnZpY2UgZXZlbnQgaXMgZW1pdHRlZCB3aGVuIHdlIHRyYW5zaXRpb24gZnJvbSB0aGUgRXBvY2gKICAgIC8vLyBDb21taXR0ZWQgcGhhc2UuIEl0IGlzIGVtaXR0ZWQgb25seSB3aGVuIGFsbCBwcmVwYXJhdGlvbiBmb3IgdGhlIHVwY29taW5nIGVwb2NoCiAgICAvLy8gaGFzIGJlZW4gY29tcGxldGVkCiAgICBhY2Nlc3MoYWxsKSBldmVudCBFcG9jaENvbW1pdCAoCgogICAgICAgIC8vLyBUaGUgY291bnRlciBmb3IgdGhlIHVwY29taW5nIGVwb2NoLiBNdXN0IGJlIGVxdWFsIHRvIHRoZSBjb3VudGVyIGluIHRoZQogICAgICAgIC8vLyBwcmV2aW91cyBFcG9jaFNldHVwIGV2ZW50LgogICAgICAgIGNvdW50ZXI6IFVJbnQ2NCwKCiAgICAgICAgLy8vIFRoZSByZXN1bHQgb2YgdGhlIFFDIGFnZ3JlZ2F0aW9uIHByb2Nlc3MuIEVhY2ggZWxlbWVudCBjb250YWlucwogICAgICAgIC8vLyBhbGwgdGhlIG5vZGVzIGFuZCB2b3RlcyByZWNlaXZlZCBmb3IgYSBwYXJ0aWN1bGFyIGNsdXN0ZXIKICAgICAgICAvLy8gUUMgc3RhbmRzIGZvciBxdW9ydW0gY2VydGlmaWNhdGUgdGhhdCBlYWNoIGNsdXN0ZXIgZ2VuZXJhdGVzLgogICAgICAgIGNsdXN0ZXJRQ3M6IFtGbG93Q2x1c3RlclFDLkNsdXN0ZXJRQ10sCgogICAgICAgIC8vLyBUaGUgcmVzdWx0aW5nIHB1YmxpYyBrZXlzIGZyb20gdGhlIERLRyBwcm9jZXNzLCBlbmNvZGVkIGFzIGJ5IHRoZSBmbG93LWdvCiAgICAgICAgLy8vIGNyeXB0byBsaWJyYXJ5LCB0aGVuIGhleC1lbmNvZGVkLgogICAgICAgIC8vLyBHcm91cCBwdWJsaWMga2V5IGlzIHRoZSBmaXJzdCBlbGVtZW50LCBmb2xsb3dlZCBieSB0aGUgaW5kaXZpZHVhbCBrZXlzCiAgICAgICAgZGtnUHViS2V5czogW1N0cmluZ10sCgogICAgICAgIGRrZ0dyb3VwS2V5OiBTdHJpbmcsCgogICAgICAgIGRrZ0lkTWFwcGluZzoge1N0cmluZzogSW50fSwKICAgICkKCiAgICAvLy8gVGhlIEVwb2NoUmVjb3ZlciBzZXJ2aWNlIGV2ZW50IGlzIGVtaXR0ZWQgdmlhIHRoZSByZWNvdmVyRXBvY2ggZ292ZXJuYW5jZSB0cmFuc2FjdGlvbiB0byBleGVjdXRlIGFuIGVwb2NoIHJlY292ZXJ5LgogICAgLy8vIFRoZSBlcG9jaCByZWNvdmVyeSBwcm9jZXNzIGlzIHVzZWQgaWYgdGhlIEVwb2NoIFByZXBhcmF0aW9uIFByb3RvY29sIGZhaWxzIGZvciBhbnkgcmVhc29uLgogICAgLy8vIFdoZW4gdGhpcyBoYXBwZW5zLCB0aGUgbmV0d29yayBlbnRlcnMgRXBvY2ggRmFsbGJhY2sgTW9kZSBbRUZNXSwgd2hlcmVpbiB0aGUgUHJvdG9jb2wgU3RhdGUKICAgIC8vLyBleHRlbmRzIHRoZSBjdXJyZW50IGVwb2NoIHVudGlsIGFuIGVwb2NoIHJlY292ZXJ5IGNhbiB0YWtlIHBsYWNlLiBJbiBnZW5lcmFsLCB3aGlsZSBpbiBFRk0sIHRoZQogICAgLy8vIFByb3RvY29sIFN0YXRlIGFuZCB0aGUgRmxvd0Vwb2NoIHNtYXJ0IGNvbnRyYWN0IG1heSBoYXZlIGNvbmZsaWN0aW5nIHZpZXdzIGFib3V0IHRoZSBjdXJyZW50CiAgICAvLy8gdmFsaWQgZXBvY2ggc3RhdGUgKGVwb2NoIGNvdW50ZXIgYW5kIHBoYXNlKS4gVGhlIGVwb2NoIHJlY292ZXJ5IHByb2Nlc3MgcmVzb2x2ZXMgdGhpcyBpbmNvbnNpc3RlbmN5CiAgICAvLy8gYnkgaW5qZWN0aW5nIGEgbmV3IGNvbW1vbiBzaGFyZWQgc3RhdGUgdG8gcHJvY2VlZCBmb3J3YXJkIGZyb20uIAogICAgLy8vIENvbmNyZXRlbHksIHRoZSBlcG9jaCByZWNvdmVyeSBwcm9jZXNzIGZ1bGx5IHNwZWNpZmllcyB0aGUgcGFyYW1ldGVycyBmb3IgYSBuZXcgZXBvY2ggdG8gdHJhbnNpdGlvbiBpbnRvCiAgICAvLy8gKGVzc2VudGlhbGx5IGFsbCBmaWVsZHMgb2YgdGhlIEVwb2NoU2V0dXAgYW5kIEVwb2NoQ29tbWl0IGV2ZW50cyksIGNhbGxlZCB0aGUgcmVjb3ZlcnkgZXBvY2guCiAgICAvLy8gVGhlIEZsb3dFcG9jaCBzbWFydCBjb250cmFjdHMgaW5zZXJ0cyB0aGUgcmVjb3ZlcnkgZXBvY2gsIHN0YXJ0cyBpdCwgYW5kIGVtaXRzIHRoZSBFcG9jaFJlY292ZXIgZXZlbnQsCiAgICAvLy8gd2hpY2ggY29udGFpbnMgdGhlIHNhbWUgZGF0YS4gV2hlbiB0aGUgRXBvY2hSZWNvdmVyIGV2ZW50IGlzIHByb2Nlc3NlZCBieSB0aGUgcHJvdG9jb2wgc3RhdGUsIAogICAgLy8vIHRoZSBQcm90b2NvbCBTdGF0ZSBpcyB1cGRhdGVkIHRvIGluY2x1ZGUgdGhlIHJlY292ZXJ5IGVwb2NoIGFzIHdlbGwuCiAgICBhY2Nlc3MoYWxsKSBldmVudCBFcG9jaFJlY292ZXIgKAogICAgICAgIC8vLyBUaGUgY291bnRlciBmb3IgdGhlIFJlY292ZXJ5RXBvY2guCiAgICAgICAgLy8vIFRoaXMgbXVzdCBiZSAxIGdyZWF0ZXIgdGhhbiB0aGUgY3VycmVudCBlcG9jaCBjb3VudGVyLCBhcyByZXBvcnRlZCBieSB0aGUgUHJvdG9jb2wgU3RhdGUsCiAgICAgICAgLy8vIG90aGVyd2lzZSB0aGUgRXBvY2hSZWNvdmVyIGV2ZW50IHdpbGwgYmUgcmVqZWN0ZWQgKHJlY292ZXJ5IHByb2Nlc3Mgd2lsbCBmYWlsKS4KICAgICAgICBjb3VudGVyOiBVSW50NjQsCgogICAgICAgIC8vLyBJZGVudGl0eSB0YWJsZSBmb3IgdGhlIHVwY29taW5nIGVwb2NoIHdpdGggYWxsIG5vZGUgaW5mb3JtYXRpb24uCiAgICAgICAgLy8vIGluY2x1ZGluZyBub2RlSUQsIHN0YWtpbmcga2V5LCBuZXR3b3JraW5nIGtleSwgbmV0d29ya2luZyBhZGRyZXNzLCByb2xlLAogICAgICAgIC8vLyBzdGFraW5nIGluZm9ybWF0aW9uLCB3ZWlnaHQsIGFuZCBtb3JlLgogICAgICAgIG5vZGVJbmZvOiBbRmxvd0lEVGFibGVTdGFraW5nLk5vZGVJbmZvXSwKCiAgICAgICAgLy8vIFRoZSBmaXJzdCB2aWV3IChpbmNsdXNpdmUpIG9mIHRoZSBSZWNvdmVyeUVwb2NoLiBUaGlzIG11c3QgYmUgMSBncmVhdGVyCiAgICAgICAgLy8vIHRoYW4gdGhlIGN1cnJlbnQgZXBvY2gncyBmaW5hbCB2aWV3LCBhcyByZXBvcnRlZCBieSB0aGUgUHJvdG9jb2wgU3RhdGUsCiAgICAgICAgLy8vIG90aGVyd2lzZSB0aGUgRXBvY2hSZWNvdmVyIGV2ZW50IHdpbGwgYmUgcmVqZWN0ZWQgKHJlY292ZXJ5IHByb2Nlc3Mgd2lsbCBmYWlsKS4KICAgICAgICBmaXJzdFZpZXc6IFVJbnQ2NCwKCiAgICAgICAgLy8vIFRoZSBsYXN0IHZpZXcgKGluY2x1c2l2ZSkgb2YgdGhlIFJlY292ZXJ5RXBvY2guCiAgICAgICAgZmluYWxWaWV3OiBVSW50NjQsCgogICAgICAgIC8vLyBUaGUgY29sbGVjdG9yIG5vZGUgY2x1c3RlciBhc3NpZ25tZW50IGZvciB0aGUgUmVjb3ZlcnlFcG9jaC4gRWFjaCBlbGVtZW50IGluIHRoZSBsaXN0CiAgICAgICAgLy8vIHJlcHJlc2VudHMgb25lIGNsdXN0ZXIgYW5kIGNvbnRhaW5zIGFsbCB0aGUgbm9kZSBJRHMgYXNzaWduZWQgdG8gdGhhdCBjbHVzdGVyLgogICAgICAgIGNsdXN0ZXJBc3NpZ25tZW50czogW1tTdHJpbmddXSwKCiAgICAgICAgLy8vIFRoZSBzb3VyY2Ugb2YgcmFuZG9tbmVzcyB0byBzZWVkIHRoZSBsZWFkZXIgc2VsZWN0aW9uIGFsZ29yaXRobSB3aXRoCiAgICAgICAgLy8vIGZvciB0aGUgdXBjb21pbmcgZXBvY2guCiAgICAgICAgcmFuZG9tU291cmNlOiBTdHJpbmcsCgogICAgICAgIC8vLyBUaGUgZGVhZGxpbmVzIG9mIGVhY2ggcGhhc2UgaW4gdGhlIERLRyBwcm90b2NvbCB0byBiZSBjb21wbGV0ZWQgaW4gdGhlIHVwY29taW5nCiAgICAgICAgLy8vIEVwb2NoU2V0dXAgcGhhc2UuIERlYWRsaW5lcyBhcmUgc3BlY2lmaWVkIGluIHRlcm1zIG9mIGEgY29uc2Vuc3VzIHZpZXcgbnVtYmVyLgogICAgICAgIC8vLyBXaGVuIGEgREtHIHBhcnRpY2lwYW50IG9ic2VydmVzIGEgZmluYWxpemVkIGFuZCBzZWFsZWQgYmxvY2sgd2l0aCB2aWV3IGdyZWF0ZXIKICAgICAgICAvLy8gdGhhbiB0aGUgZ2l2ZW4gZGVhZGxpbmUsIGl0IGNhbiBzYWZlbHkgdHJhbnNpdGlvbiB0byB0aGUgbmV4dCBwaGFzZS4KICAgICAgICBES0dQaGFzZTFGaW5hbFZpZXc6IFVJbnQ2NCwKICAgICAgICBES0dQaGFzZTJGaW5hbFZpZXc6IFVJbnQ2NCwKICAgICAgICBES0dQaGFzZTNGaW5hbFZpZXc6IFVJbnQ2NCwKCiAgICAgICAgLy8vIFRoZSB0YXJnZXQgZHVyYXRpb24gZm9yIHRoZSB1cGNvbWluZyBlcG9jaCwgaW4gc2Vjb25kcwogICAgICAgIHRhcmdldER1cmF0aW9uOiBVSW50NjQsCiAgICAgICAgLy8vIFRoZSB0YXJnZXQgZW5kIHRpbWUgZm9yIHRoZSB1cGNvbWluZyBlcG9jaCwgc3BlY2lmaWVkIGluIHNlY29uZC1wcmVjaXNpb24gVW5peCB0aW1lCiAgICAgICAgdGFyZ2V0RW5kVGltZTogVUludDY0LAoKICAgICAgICAvLy8gVGhlIGNsdXN0ZXIgUUNzIHBhc3NlZCBpbiB0aGUgcmVjb3ZlckVwb2NoIHRyYW5zYWN0aW9uLiBUaGVzZSBhcmUgZ2VuZXJhdGVkIG91dC1vZi1iYW5kCiAgICAgICAgLy8vIHVzaW5nIHRoZSBzYW1lIHByb2NlZHVyZSBhcyBkdXJpbmcgYSBzcG9yay4KICAgICAgICAvLy8gQ0FVVElPTjogVmFsaWRpdHkgb2YgdGhlIFFDcyBpcyBub3QgZXhwbGljaXRseSB2ZXJpZmllZCBkdXJpbmcgdGhlIHJlY292ZXJ5IHByb2Nlc3MuIEFuCiAgICAgICAgLy8vIGludmFsaWQgY2x1c3RlciBRQyB3aWxsIHByZXZlbnQgdGhlIHJlc3BlY3RpdmUgY2x1c3RlciBmcm9tIHN0YXJ0aW5nIGl0cyBsb2NhbCBjb25zZW5zdXMKICAgICAgICAvLy8gYW5kIGhlbmNlIHByZXZlbnQgaXQgZnJvbSBmdW5jdGlvbmluZyBmb3IgdGhlIGVudGlyZSBlcG9jaC4gSWYgYWxsIGNsdXN0ZXIgUUNzIGFyZSBpbnZhbGlkLAogICAgICAgIC8vLyB0aGUgYmxvY2tjaGFpbiBjYW5ub3QgaW5nZXN0IHRyYW5zYWN0aW9ucywgd2hpY2ggY2FuIG9ubHkgYmUgcmVzb2x2ZWQgdGhyb3VnaCBhIHNwb3JrIQogICAgICAgIGNsdXN0ZXJRQ1ZvdGVEYXRhOiBbRmxvd0NsdXN0ZXJRQy5DbHVzdGVyUUNWb3RlRGF0YV0sCgogICAgICAgIC8vLyBUaGUgREtHIHB1YmxpYyBrZXlzIGFuZCBJRCBtYXBwaW5nIGZvciB0aGUgcmVjb3ZlcnkgZXBvY2guIAogICAgICAgIC8vLyBDdXJyZW50bHksIHRoZXNlIGFyZSByZS11c2VkIGZyb20gdGhlIGxhc3Qgc3VjY2Vzc2Z1bCBES0cuCiAgICAgICAgLy8vIENBVVRJT046IFZhbGlkaXR5IG9mIHRoZSBrZXkgdmVjdG9yIGlzIG5vdCBleHBsaWNpdGx5IHZlcmlmaWVkIGR1cmluZyB0aGUgcmVjb3ZlcnkgcHJvY2Vzcy4KICAgICAgICAvLy8gSW52YWxpZCBES0cgaW5mb3JtYXRpb24gaGFzIHRoZSBwb3RlbnRpYWwgdG8gcHJldmVudCBGbG93J3MgbWFpbiBjb25zZW5zdXMgZnJvbSBjb250aW51aW5nLAogICAgICAgIC8vLyB3aGljaCB3b3VsZCBoYWx0IHRoZSBjaGFpbiBmb3IgZ29vZCBhbmQgY2FuIG9ubHkgYmUgcmVzb2x2ZWQgdGhyb3VnaCBhIHNwb3JrLgoKICAgICAgICBka2dQdWJLZXlzOiBbU3RyaW5nXSwKICAgICAgICBka2dHcm91cEtleTogU3RyaW5nLAogICAgICAgIGRrZ0lkTWFwcGluZzoge1N0cmluZzogSW50fSwKICAgICkKCiAgICAvLy8gQ29udGFpbnMgc3BlY2lmaWMgbWV0YWRhdGEgYWJvdXQgYSBwYXJ0aWN1bGFyIGVwb2NoCiAgICAvLy8gQWxsIGhpc3RvcmljYWwgZXBvY2ggbWV0YWRhdGEgaXMgc3RvcmVkIHBlcm1hbmVudGx5CiAgICBhY2Nlc3MoYWxsKSBzdHJ1Y3QgRXBvY2hNZXRhZGF0YSB7CgogICAgICAgIC8vLyBUaGUgaWRlbnRpZmllciBmb3IgdGhlIGVwb2NoCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IGNvdW50ZXI6IFVJbnQ2NAoKICAgICAgICAvLy8gVGhlIHNlZWQgdXNlZCBmb3IgZ2VuZXJhdGluZyB0aGUgZXBvY2ggc2V0dXAKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgc2VlZDogU3RyaW5nCgogICAgICAgIC8vLyBUaGUgZmlyc3QgdmlldyBvZiB0aGlzIGVwb2NoCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IHN0YXJ0VmlldzogVUludDY0CgogICAgICAgIC8vLyBUaGUgbGFzdCB2aWV3IG9mIHRoaXMgZXBvY2gKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgZW5kVmlldzogVUludDY0CgogICAgICAgIC8vLyBUaGUgbGFzdCB2aWV3IG9mIHRoZSBzdGFraW5nIGF1Y3Rpb24KICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgc3Rha2luZ0VuZFZpZXc6IFVJbnQ2NAoKICAgICAgICAvLy8gVGhlIHRvdGFsIHJld2FyZHMgdGhhdCBhcmUgcGFpZCBvdXQgZm9yIHRoZSBlcG9jaAogICAgICAgIGFjY2VzcyhhbGwpIHZhciB0b3RhbFJld2FyZHM6IFVGaXg2NAoKICAgICAgICAvLy8gVGhlIHJld2FyZCBhbW91bnRzIHRoYXQgYXJlIHBhaWQgdG8gZWFjaCBpbmRpdmlkdWFsIG5vZGUgYW5kIGl0cyBkZWxlZ2F0b3JzCiAgICAgICAgYWNjZXNzKGFsbCkgdmFyIHJld2FyZEFtb3VudHM6IFtGbG93SURUYWJsZVN0YWtpbmcuUmV3YXJkc0JyZWFrZG93bl0KCiAgICAgICAgLy8vIFRyYWNrcyBpZiByZXdhcmRzIGhhdmUgYmVlbiBwYWlkIGZvciB0aGlzIGVwb2NoCiAgICAgICAgYWNjZXNzKGFsbCkgdmFyIHJld2FyZHNQYWlkOiBCb29sCgogICAgICAgIC8vLyBUaGUgb3JnYW5pemF0aW9uIG9mIGNvbGxlY3RvciBub2RlIElEcyBpbnRvIGNsdXN0ZXJzCiAgICAgICAgLy8vIGRldGVybWluZWQgYnkgYSByb3VuZCByb2JpbiBzb3J0aW5nIGFsZ29yaXRobQogICAgICAgIGFjY2VzcyhhbGwpIGxldCBjb2xsZWN0b3JDbHVzdGVyczogW0Zsb3dDbHVzdGVyUUMuQ2x1c3Rlcl0KCiAgICAgICAgLy8vIFRoZSBRdW9ydW0gQ2VydGlmaWNhdGVzIGZyb20gdGhlIENsdXN0ZXJRQyBjb250cmFjdAogICAgICAgIGFjY2VzcyhhbGwpIHZhciBjbHVzdGVyUUNzOiBbRmxvd0NsdXN0ZXJRQy5DbHVzdGVyUUNdCgogICAgICAgIC8vLyBUaGUgcHVibGljIGtleXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBEaXN0cmlidXRlZCBLZXkgR2VuZXJhdGlvbgogICAgICAgIC8vLyBwcm9jZXNzIHRoYXQgY29uc2Vuc3VzIG5vZGVzIHBhcnRpY2lwYXRlIGluCiAgICAgICAgLy8vIFRoZSBmaXJzdCBlbGVtZW50IGlzIHRoZSBncm91cCBwdWJsaWMga2V5LCBmb2xsb3dlZCBieSBuIHBhcnRpY2lwYW50IHB1YmxpYyBrZXlzLgogICAgICAgIC8vLyBOT1RFOiBUaGlzIGRhdGEgc3RydWN0dXJlIHdhcyB1cGRhdGVkIHRvIGluY2x1ZGUgYSBtYXBwaW5nIGZyb20gbm9kZSBJRCB0byBES0cgaW5kZXguCiAgICAgICAgLy8vIEJlY2F1c2Ugc3RydWN0dXJlcyBjYW5ub3QgYmUgdXBkYXRlZCBpbiBDYWRlbmNlLCB3ZSBpbmNsdWRlIHRoZSBncm91cFB1YktleSBhbmQgcHViS2V5cwogICAgICAgIC8vLyBmaWVsZHMgaGVyZSAoaWRNYXBwaW5nIGZpZWxkIGlzIG9taXR0ZWQpLgogICAgICAgIGFjY2VzcyhhbGwpIHZhciBka2dLZXlzOiBbU3RyaW5nXQoKICAgICAgICBpbml0KGNvdW50ZXI6IFVJbnQ2NCwKICAgICAgICAgICAgIHNlZWQ6IFN0cmluZywKICAgICAgICAgICAgIHN0YXJ0VmlldzogVUludDY0LAogICAgICAgICAgICAgZW5kVmlldzogVUludDY0LAogICAgICAgICAgICAgc3Rha2luZ0VuZFZpZXc6IFVJbnQ2NCwKICAgICAgICAgICAgIHRvdGFsUmV3YXJkczogVUZpeDY0LAogICAgICAgICAgICAgY29sbGVjdG9yQ2x1c3RlcnM6IFtGbG93Q2x1c3RlclFDLkNsdXN0ZXJdLAogICAgICAgICAgICAgY2x1c3RlclFDczogW0Zsb3dDbHVzdGVyUUMuQ2x1c3RlclFDXSwKICAgICAgICAgICAgIGRrZ0tleXM6IFtTdHJpbmddKSB7CgogICAgICAgICAgICBzZWxmLmNvdW50ZXIgPSBjb3VudGVyCiAgICAgICAgICAgIHNlbGYuc2VlZCA9IHNlZWQKICAgICAgICAgICAgc2VsZi5zdGFydFZpZXcgPSBzdGFydFZpZXcKICAgICAgICAgICAgc2VsZi5lbmRWaWV3ID0gZW5kVmlldwogICAgICAgICAgICBzZWxmLnN0YWtpbmdFbmRWaWV3ID0gc3Rha2luZ0VuZFZpZXcKICAgICAgICAgICAgc2VsZi50b3RhbFJld2FyZHMgPSB0b3RhbFJld2FyZHMKICAgICAgICAgICAgc2VsZi5yZXdhcmRBbW91bnRzID0gW10KICAgICAgICAgICAgc2VsZi5yZXdhcmRzUGFpZCA9IGZhbHNlCiAgICAgICAgICAgIHNlbGYuY29sbGVjdG9yQ2x1c3RlcnMgPSBjb2xsZWN0b3JDbHVzdGVycwogICAgICAgICAgICBzZWxmLmNsdXN0ZXJRQ3MgPSBjbHVzdGVyUUNzCiAgICAgICAgICAgIHNlbGYuZGtnS2V5cyA9IGRrZ0tleXMKICAgICAgICB9CgogICAgICAgIGFjY2VzcyhhY2NvdW50KSBmdW4gY29weSgpOiBFcG9jaE1ldGFkYXRhIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGYKICAgICAgICB9CgogICAgICAgIGFjY2VzcyhhY2NvdW50KSBmdW4gc2V0VG90YWxSZXdhcmRzKF8gbmV3UmV3YXJkczogVUZpeDY0KSB7CiAgICAgICAgICAgIHNlbGYudG90YWxSZXdhcmRzID0gbmV3UmV3YXJkcwogICAgICAgIH0KCiAgICAgICAgYWNjZXNzKGFjY291bnQpIGZ1biBzZXRSZXdhcmRBbW91bnRzKF8gcmV3YXJkQnJlYWtkb3duOiBbRmxvd0lEVGFibGVTdGFraW5nLlJld2FyZHNCcmVha2Rvd25dKSB7CiAgICAgICAgICAgIHNlbGYucmV3YXJkQW1vdW50cyA9IHJld2FyZEJyZWFrZG93bgogICAgICAgIH0KCiAgICAgICAgYWNjZXNzKGFjY291bnQpIGZ1biBzZXRSZXdhcmRzUGFpZChfIHJld2FyZHNQYWlkOiBCb29sKSB7CiAgICAgICAgICAgIHNlbGYucmV3YXJkc1BhaWQgPSByZXdhcmRzUGFpZAogICAgICAgIH0KCiAgICAgICAgYWNjZXNzKGFjY291bnQpIGZ1biBzZXRDbHVzdGVyUUNzKHFjczogW0Zsb3dDbHVzdGVyUUMuQ2x1c3RlclFDXSkgewogICAgICAgICAgICBzZWxmLmNsdXN0ZXJRQ3MgPSBxY3MKICAgICAgICB9CgogICAgICAgIC8vLyBTZXRzIHRoZSBES0cgZ3JvdXAga2V5IChrZXlzWzBdKSBhbmQgcGFydGljaXBhbnQga2V5cyAoa2V5c1sxOl0pIGZyb20gdGhlIERLRyByZXN1bHQuCiAgICAgICAgLy8vIE5PVEU6IFRoaXMgZGF0YSBzdHJ1Y3R1cmUgd2FzIHVwZGF0ZWQgdG8gaW5jbHVkZSBhIG1hcHBpbmcgZnJvbSBub2RlIElEIHRvIERLRyBpbmRleC4KICAgICAgICAvLy8gQmVjYXVzZSBzdHJ1Y3R1cmVzIGNhbm5vdCBiZSB1cGRhdGVkIGluIENhZGVuY2UsIHdlIGluY2x1ZGUgdGhlIGdyb3VwUHViS2V5IGFuZCBwdWJLZXlzCiAgICAgICAgLy8vIGZpZWxkcyBoZXJlIChpZE1hcHBpbmcgZmllbGQgaXMgb21pdHRlZCkuCiAgICAgICAgYWNjZXNzKGFjY291bnQpIGZ1biBzZXRES0dLZXlzKGtleXM6IFtTdHJpbmddKSB7CiAgICAgICAgICAgIHNlbGYuZGtnS2V5cyA9IGtleXMKICAgICAgICB9CiAgICB9CgogICAgLy8vIE1ldGFkYXRhIHRoYXQgaXMgbWFuYWdlZCBhbmQgY2FuIGJlIGNoYW5nZWQgYnkgdGhlIEFkbWluCiAgICBhY2Nlc3MoYWxsKSBzdHJ1Y3QgQ29uZmlnIHsKICAgICAgICAvLy8gVGhlIG51bWJlciBvZiB2aWV3cyBpbiBhbiBlbnRpcmUgZXBvY2gKICAgICAgICBhY2Nlc3MoYWxsKSB2YXIgbnVtVmlld3NJbkVwb2NoOiBVSW50NjQKCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIHNldE51bVZpZXdzSW5FcG9jaChfIHZpZXdzOiBVSW50NjQpIHsKICAgICAgICAgICAgc2VsZi5udW1WaWV3c0luRXBvY2ggPSB2aWV3cwogICAgICAgIH0KCiAgICAgICAgLy8vIFRoZSBudW1iZXIgb2Ygdmlld3MgaW4gdGhlIHN0YWtpbmcgYXVjdGlvbgogICAgICAgIGFjY2VzcyhhbGwpIHZhciBudW1WaWV3c0luU3Rha2luZ0F1Y3Rpb246IFVJbnQ2NAoKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gc2V0TnVtVmlld3NJblN0YWtpbmdBdWN0aW9uKF8gdmlld3M6IFVJbnQ2NCkgewogICAgICAgICAgICBzZWxmLm51bVZpZXdzSW5TdGFraW5nQXVjdGlvbiA9IHZpZXdzCiAgICAgICAgfQoKICAgICAgICAvLy8gVGhlIG51bWJlciBvZiB2aWV3cyBpbiBlYWNoIGRrZyBwaGFzZQogICAgICAgIGFjY2VzcyhhbGwpIHZhciBudW1WaWV3c0luREtHUGhhc2U6IFVJbnQ2NAoKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gc2V0TnVtVmlld3NJbkRLR1BoYXNlKF8gdmlld3M6IFVJbnQ2NCkgewogICAgICAgICAgICBzZWxmLm51bVZpZXdzSW5ES0dQaGFzZSA9IHZpZXdzCiAgICAgICAgfQoKICAgICAgICAvLy8gVGhlIG51bWJlciBvZiBjb2xsZWN0b3IgY2x1c3RlcnMgaW4gZWFjaCBlcG9jaAogICAgICAgIGFjY2VzcyhhbGwpIHZhciBudW1Db2xsZWN0b3JDbHVzdGVyczogVUludDE2CgogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBzZXROdW1Db2xsZWN0b3JDbHVzdGVycyhfIG51bUNsdXN0ZXJzOiBVSW50MTYpIHsKICAgICAgICAgICAgc2VsZi5udW1Db2xsZWN0b3JDbHVzdGVycyA9IG51bUNsdXN0ZXJzCiAgICAgICAgfQoKICAgICAgICAvLy8gVHJhY2tzIHRoZSByYXRlIGF0IHdoaWNoIHRoZSByZXdhcmRzIHBheW91dCBpbmNyZWFzZXMgZXZlcnkgZXBvY2gKICAgICAgICAvLy8gVGhpcyB2YWx1ZSBpcyBtdWx0aXBsaWVkIGJ5IHRoZSBGTE9XIHRvdGFsIHN1cHBseSB0byBnZXQgdGhlIG5leHQgcGF5b3V0CiAgICAgICAgYWNjZXNzKGFsbCkgdmFyIEZMT1dzdXBwbHlJbmNyZWFzZVBlcmNlbnRhZ2U6IFVGaXg2NAoKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gc2V0RkxPV3N1cHBseUluY3JlYXNlUGVyY2VudGFnZShfIHBlcmNlbnRhZ2U6IFVGaXg2NCkgewogICAgICAgICAgICBzZWxmLkZMT1dzdXBwbHlJbmNyZWFzZVBlcmNlbnRhZ2UgPSBwZXJjZW50YWdlCiAgICAgICAgfQoKICAgICAgICBpbml0KG51bVZpZXdzSW5FcG9jaDogVUludDY0LCBudW1WaWV3c0luU3Rha2luZ0F1Y3Rpb246IFVJbnQ2NCwgbnVtVmlld3NJbkRLR1BoYXNlOiBVSW50NjQsIG51bUNvbGxlY3RvckNsdXN0ZXJzOiBVSW50MTYsIEZMT1dzdXBwbHlJbmNyZWFzZVBlcmNlbnRhZ2U6IFVGaXg2NCkgewogICAgICAgICAgICBzZWxmLm51bVZpZXdzSW5FcG9jaCA9IG51bVZpZXdzSW5FcG9jaAogICAgICAgICAgICBzZWxmLm51bVZpZXdzSW5TdGFraW5nQXVjdGlvbiA9IG51bVZpZXdzSW5TdGFraW5nQXVjdGlvbgogICAgICAgICAgICBzZWxmLm51bVZpZXdzSW5ES0dQaGFzZSA9IG51bVZpZXdzSW5ES0dQaGFzZQogICAgICAgICAgICBzZWxmLm51bUNvbGxlY3RvckNsdXN0ZXJzID0gbnVtQ29sbGVjdG9yQ2x1c3RlcnMKICAgICAgICAgICAgc2VsZi5GTE9Xc3VwcGx5SW5jcmVhc2VQZXJjZW50YWdlID0gRkxPV3N1cHBseUluY3JlYXNlUGVyY2VudGFnZQogICAgICAgIH0KICAgIH0KCiAgICAvLy8gQ29uZmlndXJhdGlvbiBmb3IgZXBvY2ggdGltaW5nLgogICAgLy8vIEVhY2ggZXBvY2ggaXMgYXNzaWduZWQgYSB0YXJnZXQgZW5kIHRpbWUgd2hlbiBpdCBpcyBzZXR1cCAod2l0aGluIHRoZSBFcG9jaFNldHVwIGV2ZW50KS4KICAgIC8vLyBUaGUgY29uZmlndXJhdGlvbiBkZWZpbmVzIGEgcmVmZXJlbmNlIGVwb2NoIGNvdW50ZXIgYW5kIHRpbWVzdGFtcCwgd2hpY2ggZGVmaW5lcwogICAgLy8vIGFsbCBmdXR1cmUgdGFyZ2V0IGVuZCB0aW1lcy4gSWYgYHRhcmdldEVwb2NoQ291bnRlcmAgaXMgYW4gdXBjb21pbmcgZXBvY2gsIHRoZW4KICAgIC8vLyBpdHMgdGFyZ2V0IGVuZCB0aW1lIGlzIGdpdmVuIGJ5OgogICAgLy8vCiAgICAvLy8gICB0YXJnZXRFbmRUaW1lID0gcmVmVGltZXN0YW1wICsgZHVyYXRpb24gKiAodGFyZ2V0RXBvY2hDb3VudGVyLXJlZkNvdW50ZXIpCiAgICAvLy8KICAgIGFjY2VzcyhhbGwpIHN0cnVjdCBFcG9jaFRpbWluZ0NvbmZpZyB7CiAgICAgICAgLy8vIFRoZSBkdXJhdGlvbiBvZiBlYWNoIGVwb2NoLCBpbiBzZWNvbmRzCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IGR1cmF0aW9uOiBVSW50NjQKICAgICAgICAvLy8gVGhlIGNvdW50ZXIgb2YgdGhlIHJlZmVyZW5jZSBlcG9jaAogICAgICAgIGFjY2VzcyhhbGwpIGxldCByZWZDb3VudGVyOiBVSW50NjQKICAgICAgICAvLy8gVGhlIGVuZCB0aW1lIG9mIHRoZSByZWZlcmVuY2UgZXBvY2gsIHNwZWNpZmllZCBpbiBzZWNvbmQtcHJlY2lzaW9uIFVuaXggdGltZQogICAgICAgIGFjY2VzcyhhbGwpIGxldCByZWZUaW1lc3RhbXA6IFVJbnQ2NAoKICAgICAgICAvLy8gQ29tcHV0ZSB0YXJnZXQgc3dpdGNob3ZlciB0aW1lIGJhc2VkIG9uIG9mZnNldCBmcm9tIHJlZmVyZW5jZSBjb3VudGVyL3N3aXRjaG92ZXIuCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIGdldFRhcmdldEVuZFRpbWVGb3JFcG9jaChfIHRhcmdldEVwb2NoQ291bnRlcjogVUludDY0KTogVUludDY0IHsKICAgICAgICAgICAgcmV0dXJuIHNlbGYucmVmVGltZXN0YW1wICsgc2VsZi5kdXJhdGlvbiAqICh0YXJnZXRFcG9jaENvdW50ZXItc2VsZi5yZWZDb3VudGVyKQogICAgICAgIH0KCiAgICAgICAgaW5pdChkdXJhdGlvbjogVUludDY0LCByZWZDb3VudGVyOiBVSW50NjQsIHJlZlRpbWVzdGFtcDogVUludDY0KSB7CiAgICAgICAgICAgICBzZWxmLmR1cmF0aW9uID0gZHVyYXRpb24KICAgICAgICAgICAgIHNlbGYucmVmQ291bnRlciA9IHJlZkNvdW50ZXIKICAgICAgICAgICAgIHNlbGYucmVmVGltZXN0YW1wID0gcmVmVGltZXN0YW1wCiAgICAgICAgfQogICAgfQoKICAgIC8vLyBIb2xkcyB0aGUgYEZsb3dFcG9jaC5Db25maWdgIHN0cnVjdCB3aXRoIHRoZSBjb25maWd1cmFibGUgbWV0YWRhdGEKICAgIGFjY2Vzcyhjb250cmFjdCkgbGV0IGNvbmZpZ3VyYWJsZU1ldGFkYXRhOiBDb25maWcKCiAgICAvLy8gTWV0YWRhdGEgdGhhdCBpcyBtYW5hZ2VkIGJ5IHRoZSBzbWFydCBjb250cmFjdAogICAgLy8vIGFuZCBjYW5ub3QgYmUgY2hhbmdlZCBieSB0aGUgQWRtaW4KCiAgICAvLy8gQ29udGFpbnMgYSBoaXN0b3JpY2FsIHJlY29yZCBvZiB0aGUgbWV0YWRhdGEgZnJvbSBhbGwgcHJldmlvdXMgZXBvY2hzCiAgICAvLy8gaW5kZXhlZCBieSBlcG9jaCBudW1iZXIKCiAgICAvLy8gUmV0dXJucyB0aGUgbWV0YWRhdGEgZnJvbSB0aGUgc3BlY2lmaWVkIGVwb2NoCiAgICAvLy8gb3IgbmlsIGlmIGl0IGlzbid0IGZvdW5kCiAgICAvLy8gRXBvY2ggTWV0YWRhdGEgaXMgc3RvcmVkIGluIGFjY291bnQgc3RvcmFnZSBzbyB0aGUgZ3Jvd2luZyBkaWN0aW9uYXJ5CiAgICAvLy8gZG9lcyBub3QgaGF2ZSB0byBiZSBsb2FkZWQgZXZlcnkgdGltZSB0aGUgY29udHJhY3QgaXMgbG9hZGVkCiAgICBhY2Nlc3MoYWxsKSBmdW4gZ2V0RXBvY2hNZXRhZGF0YShfIGVwb2NoQ291bnRlcjogVUludDY0KTogRXBvY2hNZXRhZGF0YT8gewogICAgICAgIGlmIGxldCBtZXRhZGF0YURpY3Rpb25hcnkgPSBzZWxmLmFjY291bnQuc3RvcmFnZS5ib3Jyb3c8JntVSW50NjQ6IEVwb2NoTWV0YWRhdGF9Pihmcm9tOiBzZWxmLm1ldGFkYXRhU3RvcmFnZVBhdGgpIHsKICAgICAgICAgICAgaWYgbGV0IG1ldGFkYXRhUmVmID0gbWV0YWRhdGFEaWN0aW9uYXJ5W2Vwb2NoQ291bnRlcl0gewogICAgICAgICAgICAgICAgcmV0dXJuIG1ldGFkYXRhUmVmLmNvcHkoKQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBuaWwKICAgIH0KCiAgICAvLy8gU2F2ZXMgYSBtb2RpZmllZCBFcG9jaE1ldGFkYXRhIHN0cnVjdCB0byB0aGUgbWV0YWRhdGEgaW4gYWNjb3VudCBzdG9yYWdlCiAgICBhY2Nlc3MoY29udHJhY3QpIGZ1biBzYXZlRXBvY2hNZXRhZGF0YShfIG5ld01ldGFkYXRhOiBFcG9jaE1ldGFkYXRhKSB7CiAgICAgICAgcHJlIHsKICAgICAgICAgICAgLy8gVGhlIGBjdXJyZW50RXBvY2hDb3VudGVyID09IDBgIGd1YXJkIGVuc3VyZXMgdGhlIHN1YnRyYWN0aW9uIGlzIG9ubHkKICAgICAgICAgICAgLy8gZXZhbHVhdGVkIHdoZW4gdGhlIGNvdW50ZXIgaXMgPj0gMSwgbWFraW5nIGBjdXJyZW50RXBvY2hDb3VudGVyIC0gMWAgc2FmZS4KICAgICAgICAgICAgc2VsZi5jdXJyZW50RXBvY2hDb3VudGVyID09IDAgfHwKICAgICAgICAgICAgKG5ld01ldGFkYXRhLmNvdW50ZXIgPj0gc2VsZi5jdXJyZW50RXBvY2hDb3VudGVyIC0gMSAmJgogICAgICAgICAgICBuZXdNZXRhZGF0YS5jb3VudGVyIDw9IHNlbGYucHJvcG9zZWRFcG9jaENvdW50ZXIoKSk6CiAgICAgICAgICAgICAgICAiRmxvd0Vwb2NoLnNhdmVFcG9jaE1ldGFkYXRhOiBDYW5ub3QgbW9kaWZ5IGVwb2NoIG1ldGFkYXRhIGZyb20gZXBvY2hzIGFmdGVyIHRoZSBwcm9wb3NlZCBlcG9jaCBcKHNlbGYucHJvcG9zZWRFcG9jaENvdW50ZXIoKSkgb3IgYmVmb3JlIHRoZSBwcmV2aW91cyBlcG9jaCBcKHNlbGYuY3VycmVudEVwb2NoQ291bnRlciAtIDEpIgogICAgICAgIH0KICAgICAgICBpZiBsZXQgbWV0YWRhdGFEaWN0aW9uYXJ5ID0gc2VsZi5hY2NvdW50LnN0b3JhZ2UuYm9ycm93PGF1dGgoTXV0YXRlKSAme1VJbnQ2NDogRXBvY2hNZXRhZGF0YX0+KGZyb206IHNlbGYubWV0YWRhdGFTdG9yYWdlUGF0aCkgewogICAgICAgICAgICBpZiBsZXQgbWV0YWRhdGEgPSBtZXRhZGF0YURpY3Rpb25hcnlbbmV3TWV0YWRhdGEuY291bnRlcl0gewogICAgICAgICAgICAgICAgYXNzZXJ0ICgKICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YS5jb3VudGVyID09IG5ld01ldGFkYXRhLmNvdW50ZXIsCiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogIkZsb3dFcG9jaC5zYXZlRXBvY2hNZXRhZGF0YTogQ2Fubm90IHNhdmUgbWV0YWRhdGEgd2l0aCBtaXNtYXRjaGluZyBlcG9jaCBjb3VudGVycyIKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgfQogICAgICAgICAgICBtZXRhZGF0YURpY3Rpb25hcnlbbmV3TWV0YWRhdGEuY291bnRlcl0gPSBuZXdNZXRhZGF0YQogICAgICAgIH0KICAgIH0KCiAgICAvLy8gR2VuZXJhdGVzIDEyOCBiaXRzIG9mIHJhbmRvbW5lc3MgdXNpbmcgc3lzdGVtIHJhbmRvbSAoZGVyaXZlZCBmcm9tIFJhbmRvbSBCZWFjb24pLgogICAgYWNjZXNzKGNvbnRyYWN0KSBmdW4gZ2VuZXJhdGVSYW5kb21Tb3VyY2UoKTogU3RyaW5nIHsKICAgICAgICBwb3N0IHsKICAgICAgICAgICAgcmVzdWx0Lmxlbmd0aCA9PSAzMjoKICAgICAgICAgICAgICAgICJGbG93RXBvY2guZ2VuZXJhdGVSYW5kb21Tb3VyY2U6IENyaXRpY2FsIGludmFyaWFudCB2aW9sYXRlZCEgRXhwZWN0ZWQgaGV4IHJhbmRvbSBzb3VyY2Ugd2l0aCBsZW5ndGggMzIgKDEyOCBiaXRzKSBidXQgZ290IGxlbmd0aCBcKHJlc3VsdC5sZW5ndGgpIGluc3RlYWQuIgogICAgICAgIH0KICAgICAgICB2YXIgcmFuZG9tU291cmNlID0gU3RyaW5nLmVuY29kZUhleChyZXZlcnRpYmxlUmFuZG9tPFVJbnQxMjg+KCkudG9CaWdFbmRpYW5CeXRlcygpKQogICAgICAgIHJldHVybiByYW5kb21Tb3VyY2UKICAgIH0KCiAgICAvLy8gVGhlIGNvdW50ZXIsIG9yIElELCBvZiB0aGUgY3VycmVudCBlcG9jaAogICAgYWNjZXNzKGFsbCkgdmFyIGN1cnJlbnRFcG9jaENvdW50ZXI6IFVJbnQ2NAoKICAgIC8vLyBUaGUgY3VycmVudCBwaGFzZSB0aGF0IHRoZSBlcG9jaCBpcyBpbgogICAgYWNjZXNzKGFsbCkgdmFyIGN1cnJlbnRFcG9jaFBoYXNlOiBFcG9jaFBoYXNlCgogICAgLy8vIFBhdGggd2hlcmUgdGhlIGBGbG93RXBvY2guQWRtaW5gIHJlc291cmNlIGlzIHN0b3JlZAogICAgYWNjZXNzKGFsbCkgbGV0IGFkbWluU3RvcmFnZVBhdGg6IFN0b3JhZ2VQYXRoCgogICAgLy8vIFBhdGggd2hlcmUgdGhlIGBGbG93RXBvY2guSGVhcnRiZWF0YCByZXNvdXJjZSBpcyBzdG9yZWQKICAgIGFjY2VzcyhhbGwpIGxldCBoZWFydGJlYXRTdG9yYWdlUGF0aDogU3RvcmFnZVBhdGgKCiAgICAvLy8gUGF0aCB3aGVyZSB0aGUgYHtVSW50NjQ6IEVwb2NoTWV0YWRhdGF9YCBkaWN0aW9uYXJ5IGlzIHN0b3JlZAogICAgYWNjZXNzKGFsbCkgbGV0IG1ldGFkYXRhU3RvcmFnZVBhdGg6IFN0b3JhZ2VQYXRoCgogICAgLy8vIFJlc291cmNlIHRoYXQgY2FuIHVwZGF0ZSBzb21lIG9mIHRoZSBjb250cmFjdCBmaWVsZHMKICAgIGFjY2VzcyhhbGwpIHJlc291cmNlIEFkbWluIHsKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gdXBkYXRlRXBvY2hWaWV3cyhfIG5ld0Vwb2NoVmlld3M6IFVJbnQ2NCkgewogICAgICAgICAgICBwcmUgewogICAgICAgICAgICAgICAgRmxvd0Vwb2NoLmN1cnJlbnRFcG9jaFBoYXNlID09IEVwb2NoUGhhc2UuU1RBS0lOR0FVQ1RJT046ICJGbG93RXBvY2guQWRtaW4udXBkYXRlRXBvY2hWaWV3czogQ2FuIG9ubHkgdXBkYXRlIGZpZWxkcyBkdXJpbmcgdGhlIHN0YWtpbmcgYXVjdGlvbiIKICAgICAgICAgICAgICAgIEZsb3dFcG9jaC5pc1ZhbGlkUGhhc2VDb25maWd1cmF0aW9uKEZsb3dFcG9jaC5jb25maWd1cmFibGVNZXRhZGF0YS5udW1WaWV3c0luU3Rha2luZ0F1Y3Rpb24sCiAgICAgICAgICAgICAgICAgICAgRmxvd0Vwb2NoLmNvbmZpZ3VyYWJsZU1ldGFkYXRhLm51bVZpZXdzSW5ES0dQaGFzZSwKICAgICAgICAgICAgICAgICAgICBuZXdFcG9jaFZpZXdzKTogIkZsb3dFcG9jaC5BZG1pbi51cGRhdGVFcG9jaFZpZXdzOiBOZXcgRXBvY2ggVmlld3MgbXVzdCBiZSBncmVhdGVyIHRoYW4gdGhlIHN1bSBvZiBzdGFraW5nIGFuZCBES0cgUGhhc2Ugdmlld3MiCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEZsb3dFcG9jaC5jb25maWd1cmFibGVNZXRhZGF0YS5zZXROdW1WaWV3c0luRXBvY2gobmV3RXBvY2hWaWV3cykKICAgICAgICB9CgogICAgICAgIGFjY2VzcyhhbGwpIGZ1biB1cGRhdGVBdWN0aW9uVmlld3MoXyBuZXdBdWN0aW9uVmlld3M6IFVJbnQ2NCkgewogICAgICAgICAgICBwcmUgewogICAgICAgICAgICAgICAgRmxvd0Vwb2NoLmN1cnJlbnRFcG9jaFBoYXNlID09IEVwb2NoUGhhc2UuU1RBS0lOR0FVQ1RJT046ICJGbG93RXBvY2guQWRtaW4udXBkYXRlQXVjdGlvblZpZXdzOiBDYW4gb25seSB1cGRhdGUgZmllbGRzIGR1cmluZyB0aGUgc3Rha2luZyBhdWN0aW9uIgogICAgICAgICAgICAgICAgRmxvd0Vwb2NoLmlzVmFsaWRQaGFzZUNvbmZpZ3VyYXRpb24obmV3QXVjdGlvblZpZXdzLAogICAgICAgICAgICAgICAgICAgIEZsb3dFcG9jaC5jb25maWd1cmFibGVNZXRhZGF0YS5udW1WaWV3c0luREtHUGhhc2UsCiAgICAgICAgICAgICAgICAgICAgRmxvd0Vwb2NoLmNvbmZpZ3VyYWJsZU1ldGFkYXRhLm51bVZpZXdzSW5FcG9jaCk6ICJGbG93RXBvY2guQWRtaW4udXBkYXRlQXVjdGlvblZpZXdzOiBFcG9jaCBWaWV3cyBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB0aGUgc3VtIG9mIG5ldyBzdGFraW5nIGFuZCBES0cgUGhhc2Ugdmlld3MiCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEZsb3dFcG9jaC5jb25maWd1cmFibGVNZXRhZGF0YS5zZXROdW1WaWV3c0luU3Rha2luZ0F1Y3Rpb24obmV3QXVjdGlvblZpZXdzKQogICAgICAgIH0KCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIHVwZGF0ZURLR1BoYXNlVmlld3MoXyBuZXdQaGFzZVZpZXdzOiBVSW50NjQpIHsKICAgICAgICAgICAgcHJlIHsKICAgICAgICAgICAgICAgIEZsb3dFcG9jaC5jdXJyZW50RXBvY2hQaGFzZSA9PSBFcG9jaFBoYXNlLlNUQUtJTkdBVUNUSU9OOiAiRmxvd0Vwb2NoLkFkbWluLnVwZGF0ZURLR1BoYXNlVmlld3M6IENhbiBvbmx5IHVwZGF0ZSBmaWVsZHMgZHVyaW5nIHRoZSBzdGFraW5nIGF1Y3Rpb24iCiAgICAgICAgICAgICAgICBGbG93RXBvY2guaXNWYWxpZFBoYXNlQ29uZmlndXJhdGlvbihGbG93RXBvY2guY29uZmlndXJhYmxlTWV0YWRhdGEubnVtVmlld3NJblN0YWtpbmdBdWN0aW9uLAogICAgICAgICAgICAgICAgICAgIG5ld1BoYXNlVmlld3MsCiAgICAgICAgICAgICAgICAgICAgRmxvd0Vwb2NoLmNvbmZpZ3VyYWJsZU1ldGFkYXRhLm51bVZpZXdzSW5FcG9jaCk6ICJGbG93RXBvY2guQWRtaW4udXBkYXRlREtHUGhhc2VWaWV3czogRXBvY2ggVmlld3MgbXVzdCBiZSBncmVhdGVyIHRoYW4gdGhlIHN1bSBvZiBzdGFraW5nIGFuZCBuZXcgREtHIFBoYXNlIHZpZXdzIgogICAgICAgICAgICB9CgogICAgICAgICAgICBGbG93RXBvY2guY29uZmlndXJhYmxlTWV0YWRhdGEuc2V0TnVtVmlld3NJbkRLR1BoYXNlKG5ld1BoYXNlVmlld3MpCiAgICAgICAgfQoKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gdXBkYXRlRXBvY2hUaW1pbmdDb25maWcoXyBuZXdDb25maWc6IEVwb2NoVGltaW5nQ29uZmlnKSB7CiAgICAgICAgICAgIHByZSB7CiAgICAgICAgICAgICAgICBGbG93RXBvY2guY3VycmVudEVwb2NoQ291bnRlciA+PSBuZXdDb25maWcucmVmQ291bnRlcjogIkZsb3dFcG9jaC5BZG1pbi51cGRhdGVFcG9jaFRpbWluZ0NvbmZpZzogUmVmZXJlbmNlIGVwb2NoIG11c3QgYmUgYmVmb3JlIG5leHQgZXBvY2giCiAgICAgICAgICAgIH0KICAgICAgICAgICAgRmxvd0Vwb2NoLmFjY291bnQuc3RvcmFnZS5sb2FkPEVwb2NoVGltaW5nQ29uZmlnPihmcm9tOiAvc3RvcmFnZS9mbG93RXBvY2hUaW1pbmdDb25maWcpCiAgICAgICAgICAgIEZsb3dFcG9jaC5hY2NvdW50LnN0b3JhZ2Uuc2F2ZShuZXdDb25maWcsIHRvOiAvc3RvcmFnZS9mbG93RXBvY2hUaW1pbmdDb25maWcpCiAgICAgICAgfQoKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gdXBkYXRlTnVtQ29sbGVjdG9yQ2x1c3RlcnMoXyBuZXdOdW1DbHVzdGVyczogVUludDE2KSB7CiAgICAgICAgICAgIHByZSB7CiAgICAgICAgICAgICAgICBGbG93RXBvY2guY3VycmVudEVwb2NoUGhhc2UgPT0gRXBvY2hQaGFzZS5TVEFLSU5HQVVDVElPTjogIkZsb3dFcG9jaC5BZG1pbi51cGRhdGVOdW1Db2xsZWN0b3JDbHVzdGVyczogQ2FuIG9ubHkgdXBkYXRlIGZpZWxkcyBkdXJpbmcgdGhlIHN0YWtpbmcgYXVjdGlvbiIKICAgICAgICAgICAgfQoKICAgICAgICAgICAgRmxvd0Vwb2NoLmNvbmZpZ3VyYWJsZU1ldGFkYXRhLnNldE51bUNvbGxlY3RvckNsdXN0ZXJzKG5ld051bUNsdXN0ZXJzKQogICAgICAgIH0KCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIHVwZGF0ZUZMT1dTdXBwbHlJbmNyZWFzZVBlcmNlbnRhZ2UoXyBuZXdQZXJjZW50YWdlOiBVRml4NjQpIHsKICAgICAgICAgICAgcHJlIHsKICAgICAgICAgICAgICAgIEZsb3dFcG9jaC5jdXJyZW50RXBvY2hQaGFzZSA9PSBFcG9jaFBoYXNlLlNUQUtJTkdBVUNUSU9OOiAiRmxvd0Vwb2NoLkFkbWluLnVwZGF0ZUZMT1dTdXBwbHlJbmNyZWFzZVBlcmNlbnRhZ2U6IENhbiBvbmx5IHVwZGF0ZSBmaWVsZHMgZHVyaW5nIHRoZSBzdGFraW5nIGF1Y3Rpb24iCiAgICAgICAgICAgICAgICBuZXdQZXJjZW50YWdlIDw9IDEuMDogIkZsb3dFcG9jaC5BZG1pbi51cGRhdGVGTE9XU3VwcGx5SW5jcmVhc2VQZXJjZW50YWdlOiBOZXcgRkxPVyBzdXBwbHkgaW5jcmVhc2UgcGVyY2VudGFnZSBtdXN0IGJlIGJldHdlZW4gemVybyBhbmQgb25lIGJ1dCBnb3QgXChuZXdQZXJjZW50YWdlKSIKICAgICAgICAgICAgfQoKICAgICAgICAgICAgRmxvd0Vwb2NoLmNvbmZpZ3VyYWJsZU1ldGFkYXRhLnNldEZMT1dzdXBwbHlJbmNyZWFzZVBlcmNlbnRhZ2UobmV3UGVyY2VudGFnZSkKICAgICAgICB9CgogICAgICAgIC8vIEVuYWJsZSBvciBkaXNhYmxlIGF1dG9tYXRpYyByZXdhcmRzIGNhbGN1bGF0aW9ucyBhbmQgcGF5bWVudHMKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gdXBkYXRlQXV0b21hdGljUmV3YXJkc0VuYWJsZWQoXyBlbmFibGVkOiBCb29sKSB7CiAgICAgICAgICAgIEZsb3dFcG9jaC5hY2NvdW50LnN0b3JhZ2UubG9hZDxCb29sPihmcm9tOiAvc3RvcmFnZS9mbG93QXV0b21hdGljUmV3YXJkc0VuYWJsZWQpCiAgICAgICAgICAgIEZsb3dFcG9jaC5hY2NvdW50LnN0b3JhZ2Uuc2F2ZShlbmFibGVkLCB0bzogL3N0b3JhZ2UvZmxvd0F1dG9tYXRpY1Jld2FyZHNFbmFibGVkKQogICAgICAgIH0KICAgICAgICAvLy8gRW1pdHMgdGhlIEVwb2NoUmVjb3ZlciBzZXJ2aWNlIGV2ZW50LiBJbnB1dHMgZm9yIHRoZSByZWNvdmVyeSBlcG9jaCB3aWxsIGJlIHZhbGlkYXRlZCBiZWZvcmUgdGhlIHJlY292ZXIgZXZlbnQgaXMgZW1pdHRlZC4KICAgICAgICAvLy8gVGhpcyBmdW5jIHNob3VsZCBvbmx5IGJlIHVzZWQgZHVyaW5nIHRoZSBlcG9jaCByZWNvdmVyeSBnb3Zlcm5hbmNlIGludGVydmVudGlvbi4KICAgICAgICBhY2Nlc3Moc2VsZikgZnVuIGVtaXRFcG9jaFJlY292ZXJFdmVudChlcG9jaENvdW50ZXI6IFVJbnQ2NCwKICAgICAgICAgICAgc3RhcnRWaWV3OiBVSW50NjQsCiAgICAgICAgICAgIHN0YWtpbmdFbmRWaWV3OiBVSW50NjQsCiAgICAgICAgICAgIGVuZFZpZXc6IFVJbnQ2NCwKICAgICAgICAgICAgbm9kZUlEczogW1N0cmluZ10sCiAgICAgICAgICAgIGNsdXN0ZXJBc3NpZ25tZW50czogW1tTdHJpbmddXSwKICAgICAgICAgICAgcmFuZG9tU291cmNlOiBTdHJpbmcsCiAgICAgICAgICAgIHRhcmdldER1cmF0aW9uOiBVSW50NjQsCiAgICAgICAgICAgIHRhcmdldEVuZFRpbWU6IFVJbnQ2NCwKICAgICAgICAgICAgY2x1c3RlclFDVm90ZURhdGE6IFtGbG93Q2x1c3RlclFDLkNsdXN0ZXJRQ1ZvdGVEYXRhXSwKICAgICAgICAgICAgZGtnUHViS2V5czogW1N0cmluZ10sCiAgICAgICAgICAgIGRrZ0dyb3VwS2V5OiBTdHJpbmcsCiAgICAgICAgICAgIGRrZ0lkTWFwcGluZzoge1N0cmluZzogSW50fSwKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgIHNlbGYucmVjb3ZlckVwb2NoUHJlQ2hlY2tzKAogICAgICAgICAgICAgICAgc3RhcnRWaWV3OiBzdGFydFZpZXcsIAogICAgICAgICAgICAgICAgc3Rha2luZ0VuZFZpZXc6IHN0YWtpbmdFbmRWaWV3LCAKICAgICAgICAgICAgICAgIGVuZFZpZXc6IGVuZFZpZXcsIAogICAgICAgICAgICAgICAgbm9kZUlEczogbm9kZUlEcywKICAgICAgICAgICAgICAgIG51bU9mQ2x1c3RlckFzc2lnbm1lbnRzOiBjbHVzdGVyQXNzaWdubWVudHMubGVuZ3RoLAogICAgICAgICAgICAgICAgbnVtT2ZDbHVzdGVyUUNWb3RlRGF0YTogY2x1c3RlclFDVm90ZURhdGEubGVuZ3RoLAogICAgICAgICAgICApCiAgICAgICAgICAgIC8vLyBDb25zdHJ1Y3QgdGhlIGlkZW50aXR5IHRhYmxlIGZvciB0aGUgcmVjb3ZlcnkgZXBvY2gKICAgICAgICAgICAgbGV0IG5vZGVzOiBbRmxvd0lEVGFibGVTdGFraW5nLk5vZGVJbmZvXSA9IFtdCiAgICAgICAgICAgIGZvciBub2RlSUQgaW4gbm9kZUlEcyB7CiAgICAgICAgICAgICAgICBub2Rlcy5hcHBlbmQoRmxvd0lEVGFibGVTdGFraW5nLk5vZGVJbmZvKG5vZGVJRDogbm9kZUlEKSkKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgbGV0IG51bVZpZXdzSW5ES0dQaGFzZSA9IEZsb3dFcG9jaC5jb25maWd1cmFibGVNZXRhZGF0YS5udW1WaWV3c0luREtHUGhhc2UKICAgICAgICAgICAgbGV0IGRrZ1BoYXNlMUZpbmFsVmlldyA9IHN0YWtpbmdFbmRWaWV3ICsgbnVtVmlld3NJbkRLR1BoYXNlCiAgICAgICAgICAgIGxldCBka2dQaGFzZTJGaW5hbFZpZXcgPSBka2dQaGFzZTFGaW5hbFZpZXcgKyBudW1WaWV3c0luREtHUGhhc2UKICAgICAgICAgICAgbGV0IGRrZ1BoYXNlM0ZpbmFsVmlldyA9IGRrZ1BoYXNlMkZpbmFsVmlldyArIG51bVZpZXdzSW5ES0dQaGFzZQoKICAgICAgICAgICAgLy8vIGVtaXQgRXBvY2hSZWNvdmVyIGV2ZW50CiAgICAgICAgICAgIGVtaXQgRmxvd0Vwb2NoLkVwb2NoUmVjb3ZlcigKICAgICAgICAgICAgICAgIGNvdW50ZXI6IGVwb2NoQ291bnRlciwKICAgICAgICAgICAgICAgIG5vZGVJbmZvOiBub2RlcywKICAgICAgICAgICAgICAgIGZpcnN0Vmlldzogc3RhcnRWaWV3LAogICAgICAgICAgICAgICAgZmluYWxWaWV3OiBlbmRWaWV3LAogICAgICAgICAgICAgICAgY2x1c3RlckFzc2lnbm1lbnRzOiBjbHVzdGVyQXNzaWdubWVudHMsCiAgICAgICAgICAgICAgICByYW5kb21Tb3VyY2U6IHJhbmRvbVNvdXJjZSwKICAgICAgICAgICAgICAgIERLR1BoYXNlMUZpbmFsVmlldzogZGtnUGhhc2UxRmluYWxWaWV3LAogICAgICAgICAgICAgICAgREtHUGhhc2UyRmluYWxWaWV3OiBka2dQaGFzZTJGaW5hbFZpZXcsCiAgICAgICAgICAgICAgICBES0dQaGFzZTNGaW5hbFZpZXc6IGRrZ1BoYXNlM0ZpbmFsVmlldywKICAgICAgICAgICAgICAgIHRhcmdldER1cmF0aW9uOiB0YXJnZXREdXJhdGlvbiwKICAgICAgICAgICAgICAgIHRhcmdldEVuZFRpbWU6IHRhcmdldEVuZFRpbWUsCiAgICAgICAgICAgICAgICBjbHVzdGVyUUNWb3RlRGF0YTogY2x1c3RlclFDVm90ZURhdGEsCiAgICAgICAgICAgICAgICBka2dQdWJLZXlzOiBka2dQdWJLZXlzLAogICAgICAgICAgICAgICAgZGtnR3JvdXBLZXk6IGRrZ0dyb3VwS2V5LAogICAgICAgICAgICAgICAgZGtnSWRNYXBwaW5nOiBka2dJZE1hcHBpbmcsCiAgICAgICAgICAgICkKICAgICAgICB9CgogICAgICAgIC8vLyBQZXJmb3JtcyBzYW5pdHkgY2hlY2tzIGZvciB0aGUgcHJvdmlkZWQgZXBvY2ggY29uZmlndXJhdGlvbi4gSXQgd2lsbCBlbnN1cmUgdGhlIGZvbGxvd2luZzsKICAgICAgICAvLy8gLSBUaGVyZSBpcyBhIHZhbGlkIHBoYXNlIGNvbmZpZ3VyYXRpb24uCiAgICAgICAgLy8vIC0gQWxsIG5vZGVzIGluIHRoZSBub2RlIGlkcyBsaXN0IGhhdmUgYSB3ZWlnaHQgPiAwLgogICAgICAgIGFjY2VzcyhzZWxmKSBmdW4gcmVjb3ZlckVwb2NoUHJlQ2hlY2tzKHN0YXJ0VmlldzogVUludDY0LAogICAgICAgICAgICBzdGFraW5nRW5kVmlldzogVUludDY0LAogICAgICAgICAgICBlbmRWaWV3OiBVSW50NjQsCiAgICAgICAgICAgIG5vZGVJRHM6IFtTdHJpbmddLAogICAgICAgICAgICBudW1PZkNsdXN0ZXJBc3NpZ25tZW50czogSW50LAogICAgICAgICAgICBudW1PZkNsdXN0ZXJRQ1ZvdGVEYXRhOiBJbnQpIAogICAgICAgIHsKICAgICAgICAgICAgcHJlIHsKICAgICAgICAgICAgICAgIEZsb3dFcG9jaC5pc1ZhbGlkUGhhc2VDb25maWd1cmF0aW9uKHN0YWtpbmdFbmRWaWV3LXN0YXJ0VmlldysxLCBGbG93RXBvY2guY29uZmlndXJhYmxlTWV0YWRhdGEubnVtVmlld3NJbkRLR1BoYXNlLCBlbmRWaWV3LXN0YXJ0VmlldysxKToKICAgICAgICAgICAgICAgICAgICAiRmxvd0Vwb2NoLkFkbWluLnJlY292ZXJFcG9jaFByZUNoZWNrczogSW52YWxpZCBzdGFydFZpZXcsIHN0YWtpbmdFbmRWaWV3LCBhbmQgZW5kVmlldyBjb25maWd1cmF0aW9uIgogICAgICAgICAgICB9CgogICAgICAgICAgICAvLy8gc2FuaXR5IGNoZWNrIGFsbCBub2RlcyBzaG91bGQgaGF2ZSBhIHdlaWdodCA+IDAKICAgICAgICAgICAgZm9yIG5vZGVJRCBpbiBub2RlSURzIHsKICAgICAgICAgICAgICAgIGFzc2VydCgKICAgICAgICAgICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcuTm9kZUluZm8obm9kZUlEOiBub2RlSUQpLmluaXRpYWxXZWlnaHQgPiAwLCAKICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiAiRmxvd0Vwb2NoLkFkbWluLnJlY292ZXJFcG9jaFByZUNoZWNrczogQWxsIG5vZGVzIGluIG5vZGUgaWRzIGxpc3QgZm9yIHJlY292ZXJ5IGVwb2NoIG11c3QgaGF2ZSBhIHdlaWdodCA+IDAuIFRoZSBub2RlIFwobm9kZUlEKSBoYXMgYSB3ZWlnaHQgb2YgMC4iCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHNhbml0eSBjaGVjayB3ZSBtdXN0IHJlY2VpdmUgcWMgdm90ZSBkYXRhIGZvciBlYWNoIGNsdXN0ZXIKICAgICAgICAgICAgYXNzZXJ0KAogICAgICAgICAgICAgICAgbnVtT2ZDbHVzdGVyQXNzaWdubWVudHMgPT0gbnVtT2ZDbHVzdGVyUUNWb3RlRGF0YSwgCiAgICAgICAgICAgICAgICBtZXNzYWdlOiAiRmxvd0Vwb2NoLkFkbWluLnJlY292ZXJFcG9jaFByZUNoZWNrczogVGhlIG51bWJlciBvZiBjbHVzdGVyIGFzc2lnbm1lbnRzIFwobnVtT2ZDbHVzdGVyQXNzaWdubWVudHMpIGRvZXMgbm90IG1hdGNoIHRoZSBudW1iZXIgb2YgY2x1c3RlciBxYyB2b3RlIGRhdGEgXChudW1PZkNsdXN0ZXJRQ1ZvdGVEYXRhKSIKICAgICAgICAgICAgKQogICAgICAgIH0KICAgICAgICAKICAgICAgICAvLy8gU3RvcHMgZXBvY2ggY29tcG9uZW50cy4gV2hlbiB3ZSBhcmUgaW4gdGhlIFN0YWtpbmdBdWN0aW9uIHBoYXNlIHRoZSBzdGFraW5nIGF1Y3Rpb24gaXMgc3RvcHBlZCAKICAgICAgICAvLy8gb3RoZXJ3aXNlIGNsdXN0ZXIgcWMgdm90aW5nIGFuZCB0aGUgZGtnIGlzIHN0b3BwZWQuCiAgICAgICAgYWNjZXNzKHNlbGYpIGZ1biBzdG9wRXBvY2hDb21wb25lbnRzKCkgewogICAgICAgICAgICBpZiBGbG93RXBvY2guY3VycmVudEVwb2NoUGhhc2UgPT0gRXBvY2hQaGFzZS5TVEFLSU5HQVVDVElPTiB7CiAgICAgICAgICAgICAgICAvLy8gU2luY2Ugd2UgYXJlIHJlc2V0dGluZyB0aGUgZXBvY2gsIHdlIGRvIG5vdCBuZWVkIHRvCiAgICAgICAgICAgICAgICAvLy8gc3RhcnQgZXBvY2ggc2V0dXAgYWxzby4gV2Ugb25seSBuZWVkIHRvIGVuZCB0aGUgc3Rha2luZyBhdWN0aW9uCiAgICAgICAgICAgICAgICBGbG93RXBvY2guYm9ycm93U3Rha2luZ0FkbWluKCkuZW5kU3Rha2luZ0F1Y3Rpb24oKQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8vIGZvcmNlIHJlc2V0IHRoZSBRQyBhbmQgREtHCiAgICAgICAgICAgICAgICBGbG93RXBvY2guYm9ycm93Q2x1c3RlclFDQWRtaW4oKS5mb3JjZVN0b3BWb3RpbmcoKQogICAgICAgICAgICAgICAgRmxvd0Vwb2NoLmJvcnJvd0RLR0FkbWluKCkuZm9yY2VFbmRES0coKQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLy8gRW5kcyB0aGUgY3VycmVudGx5IGFjdGl2ZSBlcG9jaCBhbmQgc3RhcnRzIGEgbmV3ICJyZWNvdmVyeSBlcG9jaCIgd2l0aCB0aGUgcHJvdmlkZWQgY29uZmlndXJhdGlvbi4KICAgICAgICAvLy8gVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIHJlY292ZXIgZnJvbSBFcG9jaCBGYWxsYmFjayBNb2RlIChFRk0pLgogICAgICAgIC8vLyBUaGUgInJlY292ZXJ5IGVwb2NoIiBjb25maWcgd2lsbCBiZSBlbWl0dGVkIGluIHRoZSBFcG9jaFJlY292ZXIgc2VydmljZSBldmVudC4KICAgICAgICAvLy8gVGhlICJyZWNvdmVyeSBlcG9jaCIgbXVzdCBoYXZlIGEgY291bnRlciBleGFjdGx5IG9uZSBncmVhdGVyIHRoYW4gdGhlIGN1cnJlbnQgZXBvY2ggY291bnRlci4KICAgICAgICAvLy8gCiAgICAgICAgLy8vIFRoaXMgZnVuY3Rpb24gZGlmZmVycyBmcm9tIHJlY292ZXJDdXJyZW50RXBvY2ggYmVjYXVzZSBpdCBpbmNyZW1lbnRzIHRoZSBlcG9jaCBjb3VudGVyIGFuZCB3aWxsIGNhbGN1bGF0ZSByZXdhcmRzLiAKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gcmVjb3Zlck5ld0Vwb2NoKAogICAgICAgICAgICByZWNvdmVyeUVwb2NoQ291bnRlcjogVUludDY0LAogICAgICAgICAgICBzdGFydFZpZXc6IFVJbnQ2NCwKICAgICAgICAgICAgc3Rha2luZ0VuZFZpZXc6IFVJbnQ2NCwKICAgICAgICAgICAgZW5kVmlldzogVUludDY0LAogICAgICAgICAgICB0YXJnZXREdXJhdGlvbjogVUludDY0LAogICAgICAgICAgICB0YXJnZXRFbmRUaW1lOiBVSW50NjQsCiAgICAgICAgICAgIGNsdXN0ZXJBc3NpZ25tZW50czogW1tTdHJpbmddXSwKICAgICAgICAgICAgY2x1c3RlclFDVm90ZURhdGE6IFtGbG93Q2x1c3RlclFDLkNsdXN0ZXJRQ1ZvdGVEYXRhXSwKICAgICAgICAgICAgZGtnUHViS2V5czogW1N0cmluZ10sCiAgICAgICAgICAgIGRrZ0dyb3VwS2V5OiBTdHJpbmcsCiAgICAgICAgICAgIGRrZ0lkTWFwcGluZzoge1N0cmluZzogSW50fSwKICAgICAgICAgICAgbm9kZUlEczogW1N0cmluZ10pIAogICAgICAgIHsKICAgICAgICAgICAgcHJlIHsKICAgICAgICAgICAgICAgIHJlY292ZXJ5RXBvY2hDb3VudGVyID09IEZsb3dFcG9jaC5wcm9wb3NlZEVwb2NoQ291bnRlcigpOgogICAgICAgICAgICAgICAgICAgICJGbG93RXBvY2guQWRtaW4ucmVjb3Zlck5ld0Vwb2NoOiBSZWNvdmVyeSBlcG9jaCBjb3VudGVyIG11c3QgZXF1YWwgY3VycmVudCBlcG9jaCBjb3VudGVyICsgMS4gR290IHJlY292ZXJ5IGVwb2NoIGNvdW50ZXIgKFwocmVjb3ZlcnlFcG9jaENvdW50ZXIpKSB3aXRoIGN1cnJlbnQgZXBvY2ggY291bnRlciAoXChGbG93RXBvY2guY3VycmVudEVwb2NoQ291bnRlcikpLiIKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc2VsZi5zdG9wRXBvY2hDb21wb25lbnRzKCkKICAgICAgICAgICAgbGV0IHJhbmRvbVNvdXJjZSA9IEZsb3dFcG9jaC5nZW5lcmF0ZVJhbmRvbVNvdXJjZSgpCgogICAgICAgICAgICAvLy8gQ3JlYXRlIG5ldyBFcG9jaE1ldGFkYXRhIGZvciB0aGUgcmVjb3ZlcnkgZXBvY2ggd2l0aCB0aGUgbmV3IHZhbHVlcwogICAgICAgICAgICBsZXQgbmV3RXBvY2hNZXRhZGF0YSA9IEVwb2NoTWV0YWRhdGEoCiAgICAgICAgICAgICAgICAvLy8gSW5jcmVtZW50IHRoZSBlcG9jaCBjb3VudGVyIHdoZW4gcmVjb3ZlcmluZyB3aXRoIGEgbmV3IGVwb2NoCiAgICAgICAgICAgICAgICBjb3VudGVyOiByZWNvdmVyeUVwb2NoQ291bnRlciwKICAgICAgICAgICAgICAgIHNlZWQ6IHJhbmRvbVNvdXJjZSwKICAgICAgICAgICAgICAgIHN0YXJ0Vmlldzogc3RhcnRWaWV3LAogICAgICAgICAgICAgICAgZW5kVmlldzogZW5kVmlldywKICAgICAgICAgICAgICAgIHN0YWtpbmdFbmRWaWV3OiBzdGFraW5nRW5kVmlldywKICAgICAgICAgICAgICAgIHRvdGFsUmV3YXJkczogMC4wLCAgICAgLy8gd2lsbCBiZSBvdmVyd3JpdHRlbiBpbiBgY2FsY3VsYXRlQW5kU2V0UmV3YXJkc2AgYmVsb3cKICAgICAgICAgICAgICAgIGNvbGxlY3RvckNsdXN0ZXJzOiBbXSwKICAgICAgICAgICAgICAgIGNsdXN0ZXJRQ3M6IFtdLAogICAgICAgICAgICAgICAgZGtnS2V5czogW2RrZ0dyb3VwS2V5XS5jb25jYXQoZGtnUHViS2V5cykKICAgICAgICAgICAgKQoKICAgICAgICAgICAgLy8vIFNhdmUgdGhlIG5ldyBlcG9jaCBtZXRhIGRhdGEsIGl0IHdpbGwgYmUgcmVmZXJlbmNlZCBhcyB0aGUgZXBvY2ggcHJvZ3Jlc3NlcwogICAgICAgICAgICBGbG93RXBvY2guc2F2ZUVwb2NoTWV0YWRhdGEobmV3RXBvY2hNZXRhZGF0YSkKCiAgICAgICAgICAgIC8vLyBDYWxjdWxhdGUgcmV3YXJkcyBmb3IgdGhlIGN1cnJlbnQgZXBvY2ggYW5kIHNldCB0aGUgcGF5b3V0IGZvciB0aGUgbmV4dCBlcG9jaAogICAgICAgICAgICBGbG93RXBvY2guY2FsY3VsYXRlQW5kU2V0UmV3YXJkcygpCgogICAgICAgICAgICAvLy8gRW1pdCB0aGUgRXBvY2hSZWNvdmVyIHNlcnZpY2UgZXZlbnQuCiAgICAgICAgICAgIC8vLyBUaGlzIHdpbGwgYmUgcHJvY2Vzc2VkIGJ5IHRoZSBQcm90b2NvbCBTdGF0ZSwgd2hpY2ggd2lsbCB0aGVuIGV4aXQgRUZNCiAgICAgICAgICAgIC8vLyBhbmQgZW50ZXIgdGhlIHJlY292ZXJ5IGVwb2NoIGF0IHRoZSBzcGVjaWZpZWQgc3RhcnQgdmlldy4KICAgICAgICAgICAgc2VsZi5lbWl0RXBvY2hSZWNvdmVyRXZlbnQoZXBvY2hDb3VudGVyOiByZWNvdmVyeUVwb2NoQ291bnRlciwKICAgICAgICAgICAgICAgIHN0YXJ0Vmlldzogc3RhcnRWaWV3LAogICAgICAgICAgICAgICAgc3Rha2luZ0VuZFZpZXc6IHN0YWtpbmdFbmRWaWV3LAogICAgICAgICAgICAgICAgZW5kVmlldzogZW5kVmlldywKICAgICAgICAgICAgICAgIG5vZGVJRHM6IG5vZGVJRHMsCiAgICAgICAgICAgICAgICBjbHVzdGVyQXNzaWdubWVudHM6IGNsdXN0ZXJBc3NpZ25tZW50cywKICAgICAgICAgICAgICAgIHJhbmRvbVNvdXJjZTogcmFuZG9tU291cmNlLAogICAgICAgICAgICAgICAgdGFyZ2V0RHVyYXRpb246IHRhcmdldER1cmF0aW9uLAogICAgICAgICAgICAgICAgdGFyZ2V0RW5kVGltZTogdGFyZ2V0RW5kVGltZSwKICAgICAgICAgICAgICAgIGNsdXN0ZXJRQ1ZvdGVEYXRhOiBjbHVzdGVyUUNWb3RlRGF0YSwKICAgICAgICAgICAgICAgIGRrZ1B1YktleXM6IGRrZ1B1YktleXMsCiAgICAgICAgICAgICAgICBka2dHcm91cEtleTogZGtnR3JvdXBLZXksCiAgICAgICAgICAgICAgICBka2dJZE1hcHBpbmc6IGRrZ0lkTWFwcGluZywKICAgICAgICAgICAgKQoKICAgICAgICAgICAgLy8vIFN0YXJ0IGEgbmV3IEVwb2NoLCB3aGljaCBpbmNyZW1lbnRzIHRoZSBjdXJyZW50IGVwb2NoIGNvdW50ZXIKICAgICAgICAgICAgRmxvd0Vwb2NoLnN0YXJ0TmV3RXBvY2goKQogICAgICAgIH0KCiAgICAgICAgLy8vIFJlcGxhY2VzIHRoZSBjdXJyZW50bHkgYWN0aXZlIGVwb2NoIHdpdGggYSBuZXcgInJlY292ZXJ5IGVwb2NoIiB3aXRoIHRoZSBwcm92aWRlZCBjb25maWd1cmF0aW9uLgogICAgICAgIC8vLyBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gcmVjb3ZlciBmcm9tIEVwb2NoIEZhbGxiYWNrIE1vZGUgKEVGTSkuCiAgICAgICAgLy8vIFRoZSAicmVjb3ZlcnkgZXBvY2giIGNvbmZpZyB3aWxsIGJlIGVtaXR0ZWQgaW4gdGhlIEVwb2NoUmVjb3ZlciBzZXJ2aWNlIGV2ZW50LgogICAgICAgIC8vLyBUaGUgInJlY292ZXJ5IGVwb2NoIG11c3QgaGF2ZSBhIGNvdW50ZXIgZXhhY3RseSBlcXVhbCB0byB0aGUgY3VycmVudCBlcG9jaCBjb3VudGVyLgogICAgICAgIC8vLyAKICAgICAgICAvLy8gVGhpcyBmdW5jdGlvbiBkaWZmZXJzIGZyb20gcmVjb3Zlck5ld0Vwb2NoIGJlY2F1c2UgaXQgcmVwbGFjZXMgdGhlIGN1cnJlbnRseSBhY3RpdmUgZXBvY2ggaW5zdGVhZCBvZiBzdGFydGluZyBhIG5ldyBlcG9jaC4KICAgICAgICAvLy8gVGhpcyBmdW5jdGlvbiBkb2VzIG5vdCBjYWxjdWxhdGUgb3IgZGlzdHJpYnV0ZSByZXdhcmRzCiAgICAgICAgLy8vIENhbGxpbmcgcmVjb3ZlckN1cnJlbnRFcG9jaCBtdWx0aXBsZSB0aW1lcyBkb2VzIG5vdCBjYXVzZSBtdWx0aXBsZSByZXdhcmQgcGF5b3V0cy4KICAgICAgICAvLy8gUmV3YXJkcyBmb3IgdGhlIHJlY292ZXJ5IGVwb2NoIHdpbGwgYmUgY2FsY3VsYXRlZCBhbmQgcGFpZCBvdXQgZHVyaW5nIHRoZSBjb3Vyc2Ugb2YgdGhlIGVwb2NoLiAKICAgICAgICAvLy8gQ0FVVElPTjogVGhpcyBjYXVzZXMgZGF0YSBsb3NzIGJ5IHJlcGxhY2luZyB0aGUgZXhpc3RpbmcgY3VycmVudCBlcG9jaCBtZXRhZGF0YSB3aXRoIHRoZSBpbnB1dHMgdG8gdGhpcyBmdW5jdGlvbi4KICAgICAgICAvLy8gVGhpcyBmdW5jdGlvbiBleGlzdHMgdG8gcmVjb3ZlciBmcm9tIHBvdGVudGlhbCByYWNlIGNvbmRpdGlvbnMgdGhhdCBjYXVzZWQgYSBwcmlvciByZWNvdmVyQ3VycmVudEVwb2NoIHRyYW5zYWN0aW9uIHRvIGZhaWw7CiAgICAgICAgLy8vIHRoaXMgYWxsb3dzIG9wZXJhdG9ycyB0byByZXRyeSB0aGUgcmVjb3ZlcnkgcHJvY2VkdXJlLCBvdmVyd3JpdGluZyB0aGUgcHJpb3IgZmFpbGVkIGF0dGVtcHQuCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIHJlY292ZXJDdXJyZW50RXBvY2goCiAgICAgICAgICAgIHJlY292ZXJ5RXBvY2hDb3VudGVyOiBVSW50NjQsCiAgICAgICAgICAgIHN0YXJ0VmlldzogVUludDY0LAogICAgICAgICAgICBzdGFraW5nRW5kVmlldzogVUludDY0LAogICAgICAgICAgICBlbmRWaWV3OiBVSW50NjQsCiAgICAgICAgICAgIHRhcmdldER1cmF0aW9uOiBVSW50NjQsCiAgICAgICAgICAgIHRhcmdldEVuZFRpbWU6IFVJbnQ2NCwKICAgICAgICAgICAgY2x1c3RlckFzc2lnbm1lbnRzOiBbW1N0cmluZ11dLAogICAgICAgICAgICBjbHVzdGVyUUNWb3RlRGF0YTogW0Zsb3dDbHVzdGVyUUMuQ2x1c3RlclFDVm90ZURhdGFdLAogICAgICAgICAgICBka2dQdWJLZXlzOiBbU3RyaW5nXSwKICAgICAgICAgICAgZGtnR3JvdXBLZXk6IFN0cmluZywKICAgICAgICAgICAgZGtnSWRNYXBwaW5nOiB7U3RyaW5nOiBJbnR9LAogICAgICAgICAgICBub2RlSURzOiBbU3RyaW5nXSkgCiAgICAgICAgeyAKICAgICAgICAgICAgcHJlIHsKICAgICAgICAgICAgICAgIHJlY292ZXJ5RXBvY2hDb3VudGVyID09IEZsb3dFcG9jaC5jdXJyZW50RXBvY2hDb3VudGVyOgogICAgICAgICAgICAgICAgICAgICJGbG93RXBvY2guQWRtaW4ucmVjb3ZlckN1cnJlbnRFcG9jaDogUmVjb3ZlcnkgZXBvY2ggY291bnRlciBtdXN0IGVxdWFsIGN1cnJlbnQgZXBvY2ggY291bnRlci4gR290IHJlY292ZXJ5IGVwb2NoIGNvdW50ZXIgKFwocmVjb3ZlcnlFcG9jaENvdW50ZXIpKSB3aXRoIGN1cnJlbnQgZXBvY2ggY291bnRlciAoXChGbG93RXBvY2guY3VycmVudEVwb2NoQ291bnRlcikpLiIKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc2VsZi5zdG9wRXBvY2hDb21wb25lbnRzKCkKICAgICAgICAgICAgRmxvd0Vwb2NoLmN1cnJlbnRFcG9jaFBoYXNlID0gRXBvY2hQaGFzZS5TVEFLSU5HQVVDVElPTgogICAgICAgICAgICAKICAgICAgICAgICAgbGV0IGN1cnJlbnRFcG9jaE1ldGFkYXRhID0gRmxvd0Vwb2NoLmdldEVwb2NoTWV0YWRhdGEocmVjb3ZlcnlFcG9jaENvdW50ZXIpCiAgICAgICAgICAgIC8vLyBDcmVhdGUgbmV3IEVwb2NoTWV0YWRhdGEgZm9yIHRoZSByZWNvdmVyeSBlcG9jaCB3aXRoIHRoZSBuZXcgdmFsdWVzLgogICAgICAgICAgICAvLy8gVGhpcyBlcG9jaCBtZXRhZGF0YSB3aWxsIG92ZXJ3cml0ZSB0aGUgZXBvY2ggbWV0YWRhdGEgb2YgdGhlIGN1cnJlbnQgZXBvY2guCiAgICAgICAgICAgIGxldCByZWNvdmVyeUVwb2NoTWV0YWRhdGE6IEZsb3dFcG9jaC5FcG9jaE1ldGFkYXRhID0gRXBvY2hNZXRhZGF0YSgKICAgICAgICAgICAgICAgIGNvdW50ZXI6IHJlY292ZXJ5RXBvY2hDb3VudGVyLAogICAgICAgICAgICAgICAgc2VlZDogY3VycmVudEVwb2NoTWV0YWRhdGEhLnNlZWQsCiAgICAgICAgICAgICAgICBzdGFydFZpZXc6IHN0YXJ0VmlldywKICAgICAgICAgICAgICAgIGVuZFZpZXc6IGVuZFZpZXcsCiAgICAgICAgICAgICAgICBzdGFraW5nRW5kVmlldzogc3Rha2luZ0VuZFZpZXcsCiAgICAgICAgICAgICAgICB0b3RhbFJld2FyZHM6IGN1cnJlbnRFcG9jaE1ldGFkYXRhIS50b3RhbFJld2FyZHMsCiAgICAgICAgICAgICAgICBjb2xsZWN0b3JDbHVzdGVyczogW10sCiAgICAgICAgICAgICAgICBjbHVzdGVyUUNzOiBbXSwKICAgICAgICAgICAgICAgIGRrZ0tleXM6IFtka2dHcm91cEtleV0uY29uY2F0KGRrZ1B1YktleXMpCiAgICAgICAgICAgICkKCiAgICAgICAgICAgIC8vLyBTYXZlIEVwb2NoTWV0YWRhdGEgZm9yIHRoZSByZWNvdmVyeSBlcG9jaCwgaXQgd2lsbCBiZSByZWZlcmVuY2VkIGFzIHRoZSBlcG9jaCBwcm9ncmVzc2VzLgogICAgICAgICAgICAvLy8gQ0FVVElPTjogVGhpcyBvdmVyd3JpdGVzIHRoZSBFcG9jaE1ldGFkYXRhIGFscmVhZHkgc3RvcmVkIGZvciB0aGUgY3VycmVudCBlcG9jaC4KICAgICAgICAgICAgRmxvd0Vwb2NoLnNhdmVFcG9jaE1ldGFkYXRhKHJlY292ZXJ5RXBvY2hNZXRhZGF0YSkKCiAgICAgICAgICAgIC8vLyBFbWl0IHRoZSBFcG9jaFJlY292ZXIgc2VydmljZSBldmVudC4KICAgICAgICAgICAgLy8vIFRoaXMgd2lsbCBiZSBwcm9jZXNzZWQgYnkgdGhlIFByb3RvY29sIFN0YXRlLCB3aGljaCB3aWxsIHRoZW4gZXhpdCBFRk0KICAgICAgICAgICAgLy8vIGFuZCBlbnRlciB0aGUgcmVjb3ZlcnkgZXBvY2ggYXQgdGhlIHNwZWNpZmllZCBzdGFydCB2aWV3LgogICAgICAgICAgICBzZWxmLmVtaXRFcG9jaFJlY292ZXJFdmVudCggCiAgICAgICAgICAgICAgICBlcG9jaENvdW50ZXI6IHJlY292ZXJ5RXBvY2hDb3VudGVyLAogICAgICAgICAgICAgICAgc3RhcnRWaWV3OiBzdGFydFZpZXcsCiAgICAgICAgICAgICAgICBzdGFraW5nRW5kVmlldzogc3Rha2luZ0VuZFZpZXcsCiAgICAgICAgICAgICAgICBlbmRWaWV3OiBlbmRWaWV3LAogICAgICAgICAgICAgICAgbm9kZUlEczogbm9kZUlEcywKICAgICAgICAgICAgICAgIGNsdXN0ZXJBc3NpZ25tZW50czogY2x1c3RlckFzc2lnbm1lbnRzLAogICAgICAgICAgICAgICAgcmFuZG9tU291cmNlOiByZWNvdmVyeUVwb2NoTWV0YWRhdGEuc2VlZCwKICAgICAgICAgICAgICAgIHRhcmdldER1cmF0aW9uOiB0YXJnZXREdXJhdGlvbiwKICAgICAgICAgICAgICAgIHRhcmdldEVuZFRpbWU6IHRhcmdldEVuZFRpbWUsCiAgICAgICAgICAgICAgICBjbHVzdGVyUUNWb3RlRGF0YTogY2x1c3RlclFDVm90ZURhdGEsCiAgICAgICAgICAgICAgICBka2dQdWJLZXlzOiBka2dQdWJLZXlzLAogICAgICAgICAgICAgICAgZGtnR3JvdXBLZXk6IGRrZ0dyb3VwS2V5LAogICAgICAgICAgICAgICAgZGtnSWRNYXBwaW5nOiBka2dJZE1hcHBpbmcsCiAgICAgICAgICAgICkKICAgICAgICB9CgogICAgICAgIC8vLyBFbmRzIHRoZSBjdXJyZW50bHkgYWN0aXZlIGVwb2NoIGFuZCBzdGFydHMgYSBuZXcgb25lIHdpdGggdGhlIHByb3ZpZGVkIGNvbmZpZ3VyYXRpb24uCiAgICAgICAgLy8vIFRoZSBuZXcgZXBvY2gsIGFmdGVyIHJlc2V0RXBvY2ggY29tcGxldGVzLCBoYXMgYGNvdW50ZXIgPSBjdXJyZW50RXBvY2hDb3VudGVyICsgMWAuCiAgICAgICAgLy8vIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCBkdXJpbmcgc3BvcmtzIC0gc2luY2UgdGhlIGNvbnNlbnN1cyB2aWV3IGlzIHJlc2V0LCBhbmQgdGhlIHByb3RvY29sIGlzCiAgICAgICAgLy8vIGJvb3RzdHJhcHBlZCB3aXRoIGEgbmV3IGluaXRpYWwgc3RhdGUgc25hcHNob3QsIHRoaXMgaW5pdGlhbGl6ZXMgRmxvd0Vwb2NoIHdpdGggdGhlIGZpcnN0IGVwb2NoCiAgICAgICAgLy8vIG9mIHRoZSBuZXcgc3BvcmssIGFzIGRlZmluZWQgaW4gdGhhdCBzbmFwc2hvdC4KICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gcmVzZXRFcG9jaCgKICAgICAgICAgICAgY3VycmVudEVwb2NoQ291bnRlcjogVUludDY0LAogICAgICAgICAgICByYW5kb21Tb3VyY2U6IFN0cmluZywKICAgICAgICAgICAgc3RhcnRWaWV3OiBVSW50NjQsCiAgICAgICAgICAgIHN0YWtpbmdFbmRWaWV3OiBVSW50NjQsCiAgICAgICAgICAgIGVuZFZpZXc6IFVJbnQ2NCwKICAgICAgICAgICAgY29sbGVjdG9yQ2x1c3RlcnM6IFtGbG93Q2x1c3RlclFDLkNsdXN0ZXJdLAogICAgICAgICAgICBjbHVzdGVyUUNzOiBbRmxvd0NsdXN0ZXJRQy5DbHVzdGVyUUNdLAogICAgICAgICAgICBka2dQdWJLZXlzOiBbU3RyaW5nXSkKICAgICAgICB7CiAgICAgICAgICAgIHByZSB7CiAgICAgICAgICAgICAgICBjdXJyZW50RXBvY2hDb3VudGVyID09IEZsb3dFcG9jaC5jdXJyZW50RXBvY2hDb3VudGVyOgogICAgICAgICAgICAgICAgICAgICJDYW5ub3Qgc3VibWl0IGEgY3VycmVudCBFcG9jaCBjb3VudGVyIHRoYXQgZG9lcyBub3QgbWF0Y2ggdGhlIGN1cnJlbnQgY291bnRlciBzdG9yZWQgaW4gdGhlIHNtYXJ0IGNvbnRyYWN0IgogICAgICAgICAgICAgICAgRmxvd0Vwb2NoLmlzVmFsaWRQaGFzZUNvbmZpZ3VyYXRpb24oc3Rha2luZ0VuZFZpZXctc3RhcnRWaWV3KzEsIEZsb3dFcG9jaC5jb25maWd1cmFibGVNZXRhZGF0YS5udW1WaWV3c0luREtHUGhhc2UsIGVuZFZpZXctc3RhcnRWaWV3KzEpOgogICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIHN0YXJ0Vmlldywgc3Rha2luZ0VuZFZpZXcsIGFuZCBlbmRWaWV3IGNvbmZpZ3VyYXRpb24iCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHNlbGYuc3RvcEVwb2NoQ29tcG9uZW50cygpCgogICAgICAgICAgICAvLyBDcmVhdGUgbmV3IEVwb2NoIG1ldGFkYXRhIGZvciB0aGUgbmV4dCBlcG9jaAogICAgICAgICAgICAvLyB3aXRoIHRoZSBuZXcgdmFsdWVzCiAgICAgICAgICAgIGxldCBuZXdFcG9jaE1ldGFkYXRhID0gRXBvY2hNZXRhZGF0YSgKICAgICAgICAgICAgICAgICAgICBjb3VudGVyOiBjdXJyZW50RXBvY2hDb3VudGVyICsgMSwKICAgICAgICAgICAgICAgICAgICBzZWVkOiByYW5kb21Tb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgc3RhcnRWaWV3OiBzdGFydFZpZXcsCiAgICAgICAgICAgICAgICAgICAgZW5kVmlldzogZW5kVmlldywKICAgICAgICAgICAgICAgICAgICBzdGFraW5nRW5kVmlldzogc3Rha2luZ0VuZFZpZXcsCiAgICAgICAgICAgICAgICAgICAgdG90YWxSZXdhcmRzOiAwLjAsIC8vIHdpbGwgYmUgb3ZlcndyaXR0ZW4gaW4gY2FsY3VsYXRlQW5kU2V0UmV3YXJkcyBiZWxvdwogICAgICAgICAgICAgICAgICAgIGNvbGxlY3RvckNsdXN0ZXJzOiBjb2xsZWN0b3JDbHVzdGVycywKICAgICAgICAgICAgICAgICAgICBjbHVzdGVyUUNzOiBjbHVzdGVyUUNzLAogICAgICAgICAgICAgICAgICAgIGRrZ0tleXM6IGRrZ1B1YktleXMpCgogICAgICAgICAgICBGbG93RXBvY2guc2F2ZUVwb2NoTWV0YWRhdGEobmV3RXBvY2hNZXRhZGF0YSkKCiAgICAgICAgICAgIC8vIENhbGN1bGF0ZSByZXdhcmRzIGZvciB0aGUgY3VycmVudCBlcG9jaAogICAgICAgICAgICAvLyBhbmQgc2V0IHRoZSBwYXlvdXQgZm9yIHRoZSBuZXh0IGVwb2NoCiAgICAgICAgICAgIEZsb3dFcG9jaC5jYWxjdWxhdGVBbmRTZXRSZXdhcmRzKCkKCiAgICAgICAgICAgIC8vIFN0YXJ0IGEgbmV3IEVwb2NoLCB3aGljaCBpbmNyZW1lbnRzIHRoZSBjdXJyZW50IGVwb2NoIGNvdW50ZXIKICAgICAgICAgICAgRmxvd0Vwb2NoLnN0YXJ0TmV3RXBvY2goKQogICAgICAgIH0KICAgIH0KCiAgICAvLy8gUmVzb3VyY2UgdGhhdCBpcyBjb250cm9sbGVkIGJ5IHRoZSBwcm90b2NvbCBhbmQgaXMgdXNlZAogICAgLy8vIHRvIGNoYW5nZSB0aGUgY3VycmVudCBwaGFzZSBvZiB0aGUgZXBvY2ggb3IgcmVzZXQgdGhlIGVwb2NoIGlmIG5lZWRlZAogICAgYWNjZXNzKGFsbCkgcmVzb3VyY2UgSGVhcnRiZWF0IHsKICAgICAgICAvLy8gRnVuY3Rpb24gdGhhdCBpcyBjYWxsZWQgZXZlcnkgYmxvY2sgdG8gYWR2YW5jZSB0aGUgZXBvY2gKICAgICAgICAvLy8gYW5kIGNoYW5nZSBwaGFzZSBpZiB0aGUgcmVxdWlyZWQgY29uZGl0aW9ucyBoYXZlIGJlZW4gbWV0CiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIGFkdmFuY2VCbG9jaygpIHsKICAgICAgICAgICAgc3dpdGNoIEZsb3dFcG9jaC5jdXJyZW50RXBvY2hQaGFzZSB7CiAgICAgICAgICAgICAgICBjYXNlIEVwb2NoUGhhc2UuU1RBS0lOR0FVQ1RJT046CiAgICAgICAgICAgICAgICAgICAgbGV0IGN1cnJlbnRCbG9jayA9IGdldEN1cnJlbnRCbG9jaygpCiAgICAgICAgICAgICAgICAgICAgbGV0IGN1cnJlbnRFcG9jaE1ldGFkYXRhID0gRmxvd0Vwb2NoLmdldEVwb2NoTWV0YWRhdGEoRmxvd0Vwb2NoLmN1cnJlbnRFcG9jaENvdW50ZXIpIQogICAgICAgICAgICAgICAgICAgIC8vIFBheSByZXdhcmRzIG9ubHkgaWYgYXV0b21hdGljIHJld2FyZHMgYXJlIGVuYWJsZWQKICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIHdpbGwgb25seSBhY3R1YWxseSBoYXBwZW4gb25jZSBpbW1lZGlhdGVseSBhZnRlciB0aGUgZXBvY2ggYmVnaW5zCiAgICAgICAgICAgICAgICAgICAgLy8gYmVjYXVzZSBgcGF5UmV3YXJkc0ZvclByZXZpb3VzRXBvY2goKWAgd2lsbCBvbmx5IHBheSByZXdhcmRzIG9uY2UKICAgICAgICAgICAgICAgICAgICBpZiBGbG93RXBvY2guYXV0b21hdGljUmV3YXJkc0VuYWJsZWQoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYucGF5UmV3YXJkc0ZvclByZXZpb3VzRXBvY2goKQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiBjdXJyZW50QmxvY2sudmlldyA+PSBjdXJyZW50RXBvY2hNZXRhZGF0YS5zdGFraW5nRW5kVmlldyB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuZW5kU3Rha2luZ0F1Y3Rpb24oKQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNhc2UgRXBvY2hQaGFzZS5FUE9DSFNFVFVQOgogICAgICAgICAgICAgICAgICAgIGlmIEZsb3dDbHVzdGVyUUMudm90aW5nQ29tcGxldGVkKCkgJiYgKEZsb3dES0cuZGtnQ29tcGxldGVkKCkgIT0gbmlsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuY2FsY3VsYXRlQW5kU2V0UmV3YXJkcygpCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuc3RhcnRFcG9jaENvbW1pdCgpCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY2FzZSBFcG9jaFBoYXNlLkVQT0NIQ09NTUlUOgogICAgICAgICAgICAgICAgICAgIGxldCBjdXJyZW50QmxvY2sgPSBnZXRDdXJyZW50QmxvY2soKQogICAgICAgICAgICAgICAgICAgIGxldCBjdXJyZW50RXBvY2hNZXRhZGF0YSA9IEZsb3dFcG9jaC5nZXRFcG9jaE1ldGFkYXRhKEZsb3dFcG9jaC5jdXJyZW50RXBvY2hDb3VudGVyKSEKICAgICAgICAgICAgICAgICAgICBpZiBjdXJyZW50QmxvY2sudmlldyA+PSBjdXJyZW50RXBvY2hNZXRhZGF0YS5lbmRWaWV3IHsKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5lbmRFcG9jaCgpCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8vIENhbGxzIGBGbG93RXBvY2hgIGZ1bmN0aW9ucyB0byBlbmQgdGhlIHN0YWtpbmcgYXVjdGlvbiBwaGFzZQogICAgICAgIC8vLyBhbmQgc3RhcnQgdGhlIEVwb2NoIFNldHVwIHBoYXNlCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIGVuZFN0YWtpbmdBdWN0aW9uKCkgewogICAgICAgICAgICBwcmUgewogICAgICAgICAgICAgICAgRmxvd0Vwb2NoLmN1cnJlbnRFcG9jaFBoYXNlID09IEVwb2NoUGhhc2UuU1RBS0lOR0FVQ1RJT046ICJDYW4gb25seSBlbmQgc3Rha2luZyBhdWN0aW9uIGR1cmluZyB0aGUgc3Rha2luZyBhdWN0aW9uIgogICAgICAgICAgICB9CgogICAgICAgICAgICBsZXQgcHJvcG9zZWROb2RlSURzID0gRmxvd0Vwb2NoLmVuZFN0YWtpbmdBdWN0aW9uKCkKCiAgICAgICAgICAgIC8vLyByYW5kb20gc291cmNlIG11c3QgYmUgYSBoZXggc3RyaW5nIG9mIDMyIGNoYXJhY3RlcnMgKGkuZSAxNiBieXRlcyBvciAxMjggYml0cykKICAgICAgICAgICAgbGV0IHJhbmRvbVNvdXJjZSA9IEZsb3dFcG9jaC5nZW5lcmF0ZVJhbmRvbVNvdXJjZSgpCgogICAgICAgICAgICBGbG93RXBvY2guc3RhcnRFcG9jaFNldHVwKHByb3Bvc2VkTm9kZUlEczogcHJvcG9zZWROb2RlSURzLCByYW5kb21Tb3VyY2U6IHJhbmRvbVNvdXJjZSkKICAgICAgICB9CgogICAgICAgIC8vLyBDYWxscyBgRmxvd0Vwb2NoYCBmdW5jdGlvbnMgdG8gZW5kIHRoZSBFcG9jaCBTZXR1cCBwaGFzZQogICAgICAgIC8vLyBhbmQgc3RhcnQgdGhlIEVwb2NoIFNldHVwIFBoYXNlCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIHN0YXJ0RXBvY2hDb21taXQoKSB7CiAgICAgICAgICAgIHByZSB7CiAgICAgICAgICAgICAgICBGbG93RXBvY2guY3VycmVudEVwb2NoUGhhc2UgPT0gRXBvY2hQaGFzZS5FUE9DSFNFVFVQOiAiQ2FuIG9ubHkgZW5kIEVwb2NoIFNldHVwIGR1cmluZyBFcG9jaCBTZXR1cCIKICAgICAgICAgICAgfQoKICAgICAgICAgICAgRmxvd0Vwb2NoLnN0YXJ0RXBvY2hDb21taXQoKQogICAgICAgIH0KCiAgICAgICAgLy8vIENhbGxzIGBGbG93RXBvY2hgIGZ1bmN0aW9ucyB0byBlbmQgdGhlIEVwb2NoIENvbW1pdCBwaGFzZQogICAgICAgIC8vLyBhbmQgc3RhcnQgdGhlIFN0YWtpbmcgQXVjdGlvbiBwaGFzZSBvZiBhIG5ldyBlcG9jaAogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBlbmRFcG9jaCgpIHsKICAgICAgICAgICAgcHJlIHsKICAgICAgICAgICAgICAgIEZsb3dFcG9jaC5jdXJyZW50RXBvY2hQaGFzZSA9PSBFcG9jaFBoYXNlLkVQT0NIQ09NTUlUOiAiQ2FuIG9ubHkgZW5kIGVwb2NoIGR1cmluZyBFcG9jaCBDb21taXQiCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEZsb3dFcG9jaC5zdGFydE5ld0Vwb2NoKCkKICAgICAgICB9CgogICAgICAgIC8vLyBOZWVkcyB0byBiZSBjYWxsZWQgYmVmb3JlIHRoZSBlcG9jaCBpcyBvdmVyCiAgICAgICAgLy8vIENhbGN1bGF0ZXMgcmV3YXJkcyBmb3IgdGhlIGN1cnJlbnQgZXBvY2ggYW5kIHN0b3JlcyB0aGVtIGluIGVwb2NoIG1ldGFkYXRhCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIGNhbGN1bGF0ZUFuZFNldFJld2FyZHMoKSB7CiAgICAgICAgICAgIEZsb3dFcG9jaC5jYWxjdWxhdGVBbmRTZXRSZXdhcmRzKCkKICAgICAgICB9CgogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBwYXlSZXdhcmRzRm9yUHJldmlvdXNFcG9jaCgpIHsKICAgICAgICAgICAgRmxvd0Vwb2NoLnBheVJld2FyZHNGb3JQcmV2aW91c0Vwb2NoKCkKICAgICAgICB9CiAgICB9CgogICAgLy8vIENhbGN1bGF0ZXMgYSBuZXcgdG9rZW4gcGF5b3V0IGZvciB0aGUgY3VycmVudCBlcG9jaAogICAgLy8vIGFuZCBzZXRzIHRoZSBuZXcgcGF5b3V0IGZvciB0aGUgbmV4dCBlcG9jaAogICAgYWNjZXNzKGFjY291bnQpIGZ1biBjYWxjdWxhdGVBbmRTZXRSZXdhcmRzKCkgewoKICAgICAgICBsZXQgc3Rha2luZ0FkbWluID0gc2VsZi5ib3Jyb3dTdGFraW5nQWRtaW4oKQoKICAgICAgICAvLyBDYWxjdWxhdGUgcmV3YXJkcyBmb3IgdGhlIGN1cnJlbnQgZXBvY2ggdGhhdCBpcyBhYm91dCB0byBlbmQKICAgICAgICAvLyBhbmQgc2F2ZSB0aGF0IHJld2FyZCBicmVha2Rvd24gaW4gdGhlIGVwb2NoIG1ldGFkYXRhIGZvciB0aGUgY3VycmVudCBlcG9jaAogICAgICAgIGxldCByZXdhcmRzU3VtbWFyeSA9IHN0YWtpbmdBZG1pbi5jYWxjdWxhdGVSZXdhcmRzKCkKICAgICAgICBsZXQgY3VycmVudE1ldGFkYXRhID0gc2VsZi5nZXRFcG9jaE1ldGFkYXRhKHNlbGYuY3VycmVudEVwb2NoQ291bnRlcikhCiAgICAgICAgY3VycmVudE1ldGFkYXRhLnNldFJld2FyZEFtb3VudHMocmV3YXJkc1N1bW1hcnkuYnJlYWtkb3duKQogICAgICAgIGN1cnJlbnRNZXRhZGF0YS5zZXRUb3RhbFJld2FyZHMocmV3YXJkc1N1bW1hcnkudG90YWxSZXdhcmRzKQogICAgICAgIHNlbGYuc2F2ZUVwb2NoTWV0YWRhdGEoY3VycmVudE1ldGFkYXRhKQoKICAgICAgICBpZiBGbG93RXBvY2guYXV0b21hdGljUmV3YXJkc0VuYWJsZWQoKSB7CiAgICAgICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgdG90YWwgc3VwcGx5IG9mIEZMT1cgYWZ0ZXIgdGhlIGN1cnJlbnQgZXBvY2gncyBwYXlvdXQKICAgICAgICAgICAgLy8gdGhlIGNhbGN1bGF0aW9uIGluY2x1ZGVzIHRoZSB0b2tlbnMgdGhhdCBoYXZlbid0IGJlZW4gbWludGVkIGZvciB0aGUgY3VycmVudCBlcG9jaCB5ZXQKICAgICAgICAgICAgbGV0IGN1cnJlbnRQYXlvdXQgPSBGbG93SURUYWJsZVN0YWtpbmcuZ2V0RXBvY2hUb2tlblBheW91dCgpCiAgICAgICAgICAgIGxldCBmZWVBbW91bnQgPSBGbG93RmVlcy5nZXRGZWVCYWxhbmNlKCkKICAgICAgICAgICAgdmFyIGZsb3dUb3RhbFN1cHBseUFmdGVyUGF5b3V0ID0gMC4wCiAgICAgICAgICAgIGlmIGZlZUFtb3VudCA+PSBjdXJyZW50UGF5b3V0IHsKICAgICAgICAgICAgICAgIGZsb3dUb3RhbFN1cHBseUFmdGVyUGF5b3V0ID0gRmxvd1Rva2VuLnRvdGFsU3VwcGx5CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBmbG93VG90YWxTdXBwbHlBZnRlclBheW91dCA9IEZsb3dUb2tlbi50b3RhbFN1cHBseSArIChjdXJyZW50UGF5b3V0IC0gZmVlQW1vdW50KQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBMb2FkIHRoZSBhbW91bnQgb2YgYm9udXMgdG9rZW5zIGZyb20gc3RvcmFnZQogICAgICAgICAgICBsZXQgYm9udXNUb2tlbnMgPSBGbG93RXBvY2guZ2V0Qm9udXNUb2tlbnMoKQoKICAgICAgICAgICAgLy8gU3VidHJhY3QgYm9udXMgdG9rZW5zIGZyb20gdGhlIHRvdGFsIHN1cHBseSB0byBnZXQgdGhlIHJlYWwgc3VwcGx5CiAgICAgICAgICAgIGlmIGJvbnVzVG9rZW5zIDwgZmxvd1RvdGFsU3VwcGx5QWZ0ZXJQYXlvdXQgewogICAgICAgICAgICAgICAgZmxvd1RvdGFsU3VwcGx5QWZ0ZXJQYXlvdXQgPSBmbG93VG90YWxTdXBwbHlBZnRlclBheW91dCAtIGJvbnVzVG9rZW5zCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgcGF5b3V0IGZvciB0aGUgbmV4dCBlcG9jaAogICAgICAgICAgICBsZXQgcHJvcG9zZWRQYXlvdXQgPSBmbG93VG90YWxTdXBwbHlBZnRlclBheW91dCAqIEZsb3dFcG9jaC5jb25maWd1cmFibGVNZXRhZGF0YS5GTE9Xc3VwcGx5SW5jcmVhc2VQZXJjZW50YWdlCgogICAgICAgICAgICAvLyBTZXQgdGhlIG5ldyBwYXlvdXQgaW4gdGhlIHN0YWtpbmcgY29udHJhY3QgYW5kIHByb3Bvc2VkIEVwb2NoIE1ldGFkYXRhCiAgICAgICAgICAgIHNlbGYuYm9ycm93U3Rha2luZ0FkbWluKCkuc2V0RXBvY2hUb2tlblBheW91dChwcm9wb3NlZFBheW91dCkKICAgICAgICAgICAgbGV0IHByb3Bvc2VkTWV0YWRhdGEgPSBzZWxmLmdldEVwb2NoTWV0YWRhdGEoc2VsZi5wcm9wb3NlZEVwb2NoQ291bnRlcigpKQogICAgICAgICAgICAgICAgPz8gcGFuaWMoIkNhbm5vdCBzZXQgcmV3YXJkcyBmb3IgdGhlIG5leHQgZXBvY2ggYmVjdWFzZSBpdCBoYXNuJ3QgYmVlbiBwcm9wb3NlZCB5ZXQiKQogICAgICAgICAgICBwcm9wb3NlZE1ldGFkYXRhLnNldFRvdGFsUmV3YXJkcyhwcm9wb3NlZFBheW91dCkKICAgICAgICAgICAgc2VsZi5zYXZlRXBvY2hNZXRhZGF0YShwcm9wb3NlZE1ldGFkYXRhKQogICAgICAgIH0KICAgIH0KCiAgICAvLy8gUGF5cyByZXdhcmRzIHRvIHRoZSBub2RlcyBhbmQgZGVsZWdhdG9ycyBvZiB0aGUgcHJldmlvdXMgZXBvY2gKICAgIGFjY2VzcyhhY2NvdW50KSBmdW4gcGF5UmV3YXJkc0ZvclByZXZpb3VzRXBvY2goKSB7CiAgICAgICAgLy8gYGN1cnJlbnRFcG9jaENvdW50ZXJgIGlzIGFsd2F5cyA+PSAxIGhlcmUgYmVjYXVzZSB0aGlzIGZ1bmN0aW9uIGlzIG9ubHkgY2FsbGVkCiAgICAgICAgLy8gZHVyaW5nIGVwb2NoIHRyYW5zaXRpb25zIGFmdGVyIHRoZSBmaXJzdCBlcG9jaCBoYXMgY29tcGxldGVkLCBtYWtpbmcgYC0gMWAgc2FmZS4KICAgICAgICBpZiBsZXQgcHJldmlvdXNFcG9jaE1ldGFkYXRhID0gc2VsZi5nZXRFcG9jaE1ldGFkYXRhKHNlbGYuY3VycmVudEVwb2NoQ291bnRlciAtIDEpIHsKICAgICAgICAgICAgaWYgIXByZXZpb3VzRXBvY2hNZXRhZGF0YS5yZXdhcmRzUGFpZCB7CiAgICAgICAgICAgICAgICBsZXQgc3VtbWFyeSA9IEZsb3dJRFRhYmxlU3Rha2luZy5FcG9jaFJld2FyZHNTdW1tYXJ5KHRvdGFsUmV3YXJkczogcHJldmlvdXNFcG9jaE1ldGFkYXRhLnRvdGFsUmV3YXJkcywgYnJlYWtkb3duOiBwcmV2aW91c0Vwb2NoTWV0YWRhdGEucmV3YXJkQW1vdW50cykKICAgICAgICAgICAgICAgIHNlbGYuYm9ycm93U3Rha2luZ0FkbWluKCkucGF5UmV3YXJkcyhmb3JFcG9jaENvdW50ZXI6IHByZXZpb3VzRXBvY2hNZXRhZGF0YS5jb3VudGVyLCByZXdhcmRzU3VtbWFyeTogc3VtbWFyeSkKICAgICAgICAgICAgICAgIHByZXZpb3VzRXBvY2hNZXRhZGF0YS5zZXRSZXdhcmRzUGFpZCh0cnVlKQogICAgICAgICAgICAgICAgc2VsZi5zYXZlRXBvY2hNZXRhZGF0YShwcmV2aW91c0Vwb2NoTWV0YWRhdGEpCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLy8vIE1vdmVzIHN0YWtpbmcgdG9rZW5zIGJldHdlZW4gYnVja2V0cywKICAgIC8vLyBhbmQgc3RhcnRzIHRoZSBuZXcgZXBvY2ggc3Rha2luZyBhdWN0aW9uCiAgICBhY2Nlc3MoYWNjb3VudCkgZnVuIHN0YXJ0TmV3RXBvY2goKSB7CgogICAgICAgIC8vIEVuZCBRQyBhbmQgREtHIGlmIHRoZXkgYXJlIHN0aWxsIGVuYWJsZWQKICAgICAgICBpZiBGbG93Q2x1c3RlclFDLmluUHJvZ3Jlc3MgewogICAgICAgICAgICBzZWxmLmJvcnJvd0NsdXN0ZXJRQ0FkbWluKCkuc3RvcFZvdGluZygpCiAgICAgICAgfQogICAgICAgIGlmIEZsb3dES0cuZGtnRW5hYmxlZCB7CiAgICAgICAgICAgIHNlbGYuYm9ycm93REtHQWRtaW4oKS5lbmRES0coKQogICAgICAgIH0KCiAgICAgICAgc2VsZi5ib3Jyb3dTdGFraW5nQWRtaW4oKS5tb3ZlVG9rZW5zKG5ld0Vwb2NoQ291bnRlcjogc2VsZi5wcm9wb3NlZEVwb2NoQ291bnRlcigpKQoKICAgICAgICBzZWxmLmN1cnJlbnRFcG9jaFBoYXNlID0gRXBvY2hQaGFzZS5TVEFLSU5HQVVDVElPTgoKICAgICAgICAvLyBVcGRhdGUgdGhlIGVwb2NoIGNvdW50ZXJzCiAgICAgICAgc2VsZi5jdXJyZW50RXBvY2hDb3VudGVyID0gc2VsZi5wcm9wb3NlZEVwb2NoQ291bnRlcigpCgogICAgICAgIC8vIGBwcm9wb3NlZEVwb2NoQ291bnRlcigpYCByZXR1cm5zIGBjdXJyZW50RXBvY2hDb3VudGVyICsgMWAsIHNvIGFmdGVyIHRoZQogICAgICAgIC8vIGFzc2lnbm1lbnQgYWJvdmUgYGN1cnJlbnRFcG9jaENvdW50ZXJgIGlzID49IDEsIG1ha2luZyBgLSAxYCBzYWZlLgogICAgICAgIGxldCBwcmV2aW91c0Vwb2NoTWV0YWRhdGEgPSBzZWxmLmdldEVwb2NoTWV0YWRhdGEoc2VsZi5jdXJyZW50RXBvY2hDb3VudGVyIC0gMSkhCiAgICAgICAgbGV0IG5ld0Vwb2NoTWV0YWRhdGEgPSBzZWxmLmdldEVwb2NoTWV0YWRhdGEoc2VsZi5jdXJyZW50RXBvY2hDb3VudGVyKSEKCiAgICAgICAgZW1pdCBFcG9jaFN0YXJ0ICgKICAgICAgICAgICAgY291bnRlcjogc2VsZi5jdXJyZW50RXBvY2hDb3VudGVyLAogICAgICAgICAgICBmaXJzdFZpZXc6IG5ld0Vwb2NoTWV0YWRhdGEuc3RhcnRWaWV3LAogICAgICAgICAgICBzdGFraW5nQXVjdGlvbkVuZFZpZXc6IG5ld0Vwb2NoTWV0YWRhdGEuc3Rha2luZ0VuZFZpZXcsCiAgICAgICAgICAgIGZpbmFsVmlldzogbmV3RXBvY2hNZXRhZGF0YS5lbmRWaWV3LAogICAgICAgICAgICB0b3RhbFN0YWtlZDogRmxvd0lEVGFibGVTdGFraW5nLmdldFRvdGFsU3Rha2VkKCksCiAgICAgICAgICAgIHRvdGFsRmxvd1N1cHBseTogRmxvd1Rva2VuLnRvdGFsU3VwcGx5ICsgcHJldmlvdXNFcG9jaE1ldGFkYXRhLnRvdGFsUmV3YXJkcywKICAgICAgICAgICAgdG90YWxSZXdhcmRzOiBGbG93SURUYWJsZVN0YWtpbmcuZ2V0RXBvY2hUb2tlblBheW91dCgpLAogICAgICAgICkKICAgIH0KCiAgICAvLy8gRW5kcyB0aGUgc3Rha2luZyBBdWN0aW9uIHdpdGggYWxsIHRoZSBwcm9wb3NlZCBub2RlcyBhcHByb3ZlZAogICAgYWNjZXNzKGFjY291bnQpIGZ1biBlbmRTdGFraW5nQXVjdGlvbigpOiBbU3RyaW5nXSB7CiAgICAgICAgcmV0dXJuIHNlbGYuYm9ycm93U3Rha2luZ0FkbWluKCkuZW5kU3Rha2luZ0F1Y3Rpb24oKQogICAgfQoKICAgIC8vLyBTdGFydHMgdGhlIEVwb2NoU2V0dXAgcGhhc2UgYW5kIGVtaXRzIHRoZSBlcG9jaCBzZXR1cCBldmVudAogICAgLy8vIFRoaXMgaGFzIHRvIGJlIGNhbGxlZCBkaXJlY3RseSBhZnRlciBgZW5kU3Rha2luZ0F1Y3Rpb25gCiAgICBhY2Nlc3MoYWNjb3VudCkgZnVuIHN0YXJ0RXBvY2hTZXR1cChwcm9wb3NlZE5vZGVJRHM6IFtTdHJpbmddLCByYW5kb21Tb3VyY2U6IFN0cmluZykgewoKICAgICAgICAvLyBIb2xkcyB0aGUgbm9kZSBJbmZvcm1hdGlvbiBvZiBhbGwgdGhlIGFwcHJvdmVkIG5vZGVzCiAgICAgICAgdmFyIG5vZGVJbmZvQXJyYXk6IFtGbG93SURUYWJsZVN0YWtpbmcuTm9kZUluZm9dID0gW10KCiAgICAgICAgLy8gSG9sZHMgbm9kZSBJRHMgb2Ygb25seSBjb2xsZWN0b3Igbm9kZXMgZm9yIFFDCiAgICAgICAgdmFyIGNvbGxlY3Rvck5vZGVJRHM6IFtTdHJpbmddID0gW10KCiAgICAgICAgLy8gSG9sZHMgbm9kZSBJRHMgb2Ygb25seSBjb25zZW5zdXMgbm9kZXMgZm9yIERLRwogICAgICAgIHZhciBjb25zZW5zdXNOb2RlSURzOiBbU3RyaW5nXSA9IFtdCgogICAgICAgIC8vIEdldCBOb2RlSW5mbyBmb3IgYWxsIHRoZSBub2RlcwogICAgICAgIC8vIEdldCBhbGwgdGhlIGNvbGxlY3RvciBhbmQgY29uc2Vuc3VzIG5vZGVzCiAgICAgICAgLy8gdG8gaW5pdGlhbGl6ZSB0aGUgUUMgYW5kIERLRwogICAgICAgIGZvciBpZCBpbiBwcm9wb3NlZE5vZGVJRHMgewogICAgICAgICAgICBsZXQgbm9kZUluZm8gPSBGbG93SURUYWJsZVN0YWtpbmcuTm9kZUluZm8obm9kZUlEOiBpZCkKCiAgICAgICAgICAgIG5vZGVJbmZvQXJyYXkuYXBwZW5kKG5vZGVJbmZvKQoKICAgICAgICAgICAgaWYgbm9kZUluZm8ucm9sZSA9PSBOb2RlUm9sZS5Db2xsZWN0b3IucmF3VmFsdWUgewogICAgICAgICAgICAgICAgY29sbGVjdG9yTm9kZUlEcy5hcHBlbmQobm9kZUluZm8uaWQpCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIG5vZGVJbmZvLnJvbGUgPT0gTm9kZVJvbGUuQ29uc2Vuc3VzLnJhd1ZhbHVlIHsKICAgICAgICAgICAgICAgIGNvbnNlbnN1c05vZGVJRHMuYXBwZW5kKG5vZGVJbmZvLmlkKQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBPcmdhbml6ZSB0aGUgY29sbGVjdG9yIG5vZGVzIGludG8gY2x1c3RlcnMKICAgICAgICBsZXQgY29sbGVjdG9yQ2x1c3RlcnMgPSBzZWxmLmNyZWF0ZUNvbGxlY3RvckNsdXN0ZXJzKG5vZGVJRHM6IGNvbGxlY3Rvck5vZGVJRHMpCgogICAgICAgIC8vIFN0YXJ0IFFDIFZvdGluZyB3aXRoIHRoZSBzdXBwbGllZCBjbHVzdGVycwogICAgICAgIHNlbGYuYm9ycm93Q2x1c3RlclFDQWRtaW4oKS5zdGFydFZvdGluZyhjbHVzdGVyczogY29sbGVjdG9yQ2x1c3RlcnMpCgogICAgICAgIC8vIFN0YXJ0IERLRyB3aXRoIHRoZSBjb25zZW5zdXMgbm9kZXMKICAgICAgICBzZWxmLmJvcnJvd0RLR0FkbWluKCkuc3RhcnRES0cobm9kZUlEczogY29uc2Vuc3VzTm9kZUlEcykKCiAgICAgICAgbGV0IGN1cnJlbnRFcG9jaE1ldGFkYXRhID0gc2VsZi5nZXRFcG9jaE1ldGFkYXRhKHNlbGYuY3VycmVudEVwb2NoQ291bnRlcikhCgogICAgICAgIC8vIEluaXRpYWxpemUgdGhlIG1ldGFkYXRhIGZvciB0aGUgbmV4dCBlcG9jaAogICAgICAgIC8vIFFDIGFuZCBES0cgbWV0YWRhdGEgd2lsbCBiZSBmaWxsZWQgaW4gbGF0ZXIKICAgICAgICBsZXQgcHJvcG9zZWRFcG9jaE1ldGFkYXRhID0gRXBvY2hNZXRhZGF0YShjb3VudGVyOiBzZWxmLnByb3Bvc2VkRXBvY2hDb3VudGVyKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZWQ6IHJhbmRvbVNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRWaWV3OiBjdXJyZW50RXBvY2hNZXRhZGF0YS5lbmRWaWV3ICsgVUludDY0KDEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRWaWV3OiBjdXJyZW50RXBvY2hNZXRhZGF0YS5lbmRWaWV3ICsgc2VsZi5jb25maWd1cmFibGVNZXRhZGF0YS5udW1WaWV3c0luRXBvY2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YWtpbmdFbmRWaWV3OiBjdXJyZW50RXBvY2hNZXRhZGF0YS5lbmRWaWV3ICsgc2VsZi5jb25maWd1cmFibGVNZXRhZGF0YS5udW1WaWV3c0luU3Rha2luZ0F1Y3Rpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsUmV3YXJkczogMC4wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xsZWN0b3JDbHVzdGVyczogY29sbGVjdG9yQ2x1c3RlcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsdXN0ZXJRQ3M6IFtdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBka2dLZXlzOiBbXSkKCiAgICAgICAgLy8gQ29tcHV0ZSB0aGUgdGFyZ2V0IGVuZCB0aW1lIGZvciB0aGUgbmV4dCBlcG9jaAogICAgICAgIGxldCB0aW1pbmdDb25maWcgPSBzZWxmLmdldEVwb2NoVGltaW5nQ29uZmlnKCkKICAgICAgICBsZXQgcHJvcG9zZWRUYXJnZXREdXJhdGlvbiA9IHRpbWluZ0NvbmZpZy5kdXJhdGlvbgogICAgICAgIGxldCBwcm9wb3NlZFRhcmdldEVuZFRpbWUgPSB0aW1pbmdDb25maWcuZ2V0VGFyZ2V0RW5kVGltZUZvckVwb2NoKHNlbGYucHJvcG9zZWRFcG9jaENvdW50ZXIoKSkKCiAgICAgICAgc2VsZi5zYXZlRXBvY2hNZXRhZGF0YShwcm9wb3NlZEVwb2NoTWV0YWRhdGEpCgogICAgICAgIHNlbGYuY3VycmVudEVwb2NoUGhhc2UgPSBFcG9jaFBoYXNlLkVQT0NIU0VUVVAKCiAgICAgICAgbGV0IGRrZ1BoYXNlMUZpbmFsVmlldyA9IHByb3Bvc2VkRXBvY2hNZXRhZGF0YS5zdGFraW5nRW5kVmlldyArIHNlbGYuY29uZmlndXJhYmxlTWV0YWRhdGEubnVtVmlld3NJbkRLR1BoYXNlCiAgICAgICAgbGV0IGRrZ1BoYXNlMkZpbmFsVmlldyA9IGRrZ1BoYXNlMUZpbmFsVmlldyArIHNlbGYuY29uZmlndXJhYmxlTWV0YWRhdGEubnVtVmlld3NJbkRLR1BoYXNlCiAgICAgICAgbGV0IGRrZ1BoYXNlM0ZpbmFsVmlldyA9IGRrZ1BoYXNlMkZpbmFsVmlldyArIHNlbGYuY29uZmlndXJhYmxlTWV0YWRhdGEubnVtVmlld3NJbkRLR1BoYXNlCiAgICAgICAgZW1pdCBFcG9jaFNldHVwKGNvdW50ZXI6IHByb3Bvc2VkRXBvY2hNZXRhZGF0YS5jb3VudGVyLAogICAgICAgICAgICAgICAgICAgICAgICBub2RlSW5mbzogbm9kZUluZm9BcnJheSwKICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3RWaWV3OiBwcm9wb3NlZEVwb2NoTWV0YWRhdGEuc3RhcnRWaWV3LAogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFZpZXc6IHByb3Bvc2VkRXBvY2hNZXRhZGF0YS5lbmRWaWV3LAogICAgICAgICAgICAgICAgICAgICAgICBjb2xsZWN0b3JDbHVzdGVyczogY29sbGVjdG9yQ2x1c3RlcnMsCiAgICAgICAgICAgICAgICAgICAgICAgIHJhbmRvbVNvdXJjZTogcmFuZG9tU291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICBES0dQaGFzZTFGaW5hbFZpZXc6IGRrZ1BoYXNlMUZpbmFsVmlldywKICAgICAgICAgICAgICAgICAgICAgICAgREtHUGhhc2UyRmluYWxWaWV3OiAgZGtnUGhhc2UyRmluYWxWaWV3LAogICAgICAgICAgICAgICAgICAgICAgICBES0dQaGFzZTNGaW5hbFZpZXc6ICBka2dQaGFzZTNGaW5hbFZpZXcsCiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldER1cmF0aW9uOiBwcm9wb3NlZFRhcmdldER1cmF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRFbmRUaW1lOiBwcm9wb3NlZFRhcmdldEVuZFRpbWUpCiAgICB9CgogICAgLy8vIEVuZHMgdGhlIEVwb2NoU2V0dXAgcGhhc2Ugd2hlbiB0aGUgUUMgYW5kIERLRyBhcmUgY29tcGxldGVkCiAgICAvLy8gYW5kIGVtaXRzIHRoZSBFcG9jaENvbW1pdCBldmVudCB3aXRoIHRoZSByZXN1bHRzCiAgICBhY2Nlc3MoYWNjb3VudCkgZnVuIHN0YXJ0RXBvY2hDb21taXQoKSB7CiAgICAgICAgaWYgIUZsb3dDbHVzdGVyUUMudm90aW5nQ29tcGxldGVkKCkgfHwgRmxvd0RLRy5ka2dDb21wbGV0ZWQoKSA9PSBuaWwgewogICAgICAgICAgICByZXR1cm4KICAgICAgICB9CgogICAgICAgIGxldCBjbHVzdGVycyA9IEZsb3dDbHVzdGVyUUMuZ2V0Q2x1c3RlcnMoKQoKICAgICAgICAvLyBIb2xkcyB0aGUgcXVvcnVtIGNlcnRpZmljYXRlcyBmb3IgZWFjaCBjbHVzdGVyCiAgICAgICAgdmFyIGNsdXN0ZXJRQ3M6IFtGbG93Q2x1c3RlclFDLkNsdXN0ZXJRQ10gPSBbXQoKICAgICAgICAvLyBpdGVyYXRlIHRocm91Z2ggYWxsIHRoZSBjbHVzdGVycyBhbmQgY3JlYXRlIHRoZWlyIGNlcnRpZmljYXRlIGFycmF5cwogICAgICAgIGZvciBjbHVzdGVyIGluIGNsdXN0ZXJzIHsKICAgICAgICAgICAgdmFyIGNlcnRpZmljYXRlID0gY2x1c3Rlci5nZW5lcmF0ZVF1b3J1bUNlcnRpZmljYXRlKCkKICAgICAgICAgICAgICAgID8/IHBhbmljKCJDb3VsZCBub3QgZ2VuZXJhdGUgdGhlIHF1b3J1bSBjZXJ0aWZpY2F0ZSBmb3IgdGhpcyBjbHVzdGVyIikKCiAgICAgICAgICAgIGNsdXN0ZXJRQ3MuYXBwZW5kKGNlcnRpZmljYXRlKQogICAgICAgIH0KCiAgICAgICAgLy8gU2V0IGNsdXN0ZXIgUUNzIGluIHRoZSBwcm9wb3NlZCBlcG9jaCBtZXRhZGF0YSBhbmQgc3RvcCBRQyB2b3RpbmcKICAgICAgICBsZXQgcHJvcG9zZWRFcG9jaE1ldGFkYXRhID0gc2VsZi5nZXRFcG9jaE1ldGFkYXRhKHNlbGYucHJvcG9zZWRFcG9jaENvdW50ZXIoKSkhCiAgICAgICAgcHJvcG9zZWRFcG9jaE1ldGFkYXRhLnNldENsdXN0ZXJRQ3MocWNzOiBjbHVzdGVyUUNzKQoKICAgICAgICAvLyBTZXQgREtHIHJlc3VsdCBpbiB0aGUgcHJvcG9zZWQgZXBvY2ggbWV0YWRhdGEgYW5kIHN0b3AgREtHCiAgICAgICAgbGV0IGRrZ1Jlc3VsdCA9IEZsb3dES0cuZGtnQ29tcGxldGVkKCkhCiAgICAgICAgLy8gQ29uc3RydWN0IGEgcGFydGlhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgREtHIHJlc3VsdCBmb3Igc3RvcmFnZSBpbiB0aGUgZXBvY2ggbWV0YWRhdGEuCiAgICAgICAgLy8gU2VlIHNldERLR0tleXMgZG9jdW1lbnRhdGlvbiBmb3IgY29udGV4dCBvbiB3aHkgdGhlIG5vZGUgSUQgbWFwcGluZyBpcyBvbWl0dGVkIGhlcmUuCiAgICAgICAgbGV0IGRrZ1B1YktleXMgPSBbZGtnUmVzdWx0Lmdyb3VwUHViS2V5IV0uY29uY2F0KGRrZ1Jlc3VsdC5wdWJLZXlzISkKICAgICAgICBwcm9wb3NlZEVwb2NoTWV0YWRhdGEuc2V0REtHS2V5cyhrZXlzOiBka2dQdWJLZXlzKQogICAgICAgIHNlbGYuc2F2ZUVwb2NoTWV0YWRhdGEocHJvcG9zZWRFcG9jaE1ldGFkYXRhKQoKICAgICAgICBzZWxmLmN1cnJlbnRFcG9jaFBoYXNlID0gRXBvY2hQaGFzZS5FUE9DSENPTU1JVAoKICAgICAgICBlbWl0IEVwb2NoQ29tbWl0KGNvdW50ZXI6IHNlbGYucHJvcG9zZWRFcG9jaENvdW50ZXIoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsdXN0ZXJRQ3M6IGNsdXN0ZXJRQ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBka2dQdWJLZXlzOiBka2dSZXN1bHQucHViS2V5cyEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBka2dHcm91cEtleTogZGtnUmVzdWx0Lmdyb3VwUHViS2V5ISwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRrZ0lkTWFwcGluZzogZGtnUmVzdWx0LmlkTWFwcGluZyEpCiAgICB9CgogICAgLy8vIEJvcnJvdyBhIHJlZmVyZW5jZSB0byB0aGUgRmxvd0lEVGFibGVTdGFraW5nIEFkbWluIHJlc291cmNlCiAgICBhY2Nlc3MoY29udHJhY3QpIHZpZXcgZnVuIGJvcnJvd1N0YWtpbmdBZG1pbigpOiAmRmxvd0lEVGFibGVTdGFraW5nLkFkbWluIHsKICAgICAgICBsZXQgYWRtaW5DYXBhYmlsaXR5ID0gc2VsZi5hY2NvdW50LnN0b3JhZ2UuY29weTxDYXBhYmlsaXR5Pihmcm9tOiAvc3RvcmFnZS9mbG93U3Rha2luZ0FkbWluRXBvY2hPcGVyYXRpb25zKQogICAgICAgICAgICA/PyBwYW5pYygiQ291bGQgbm90IGdldCBjYXBhYmlsaXR5IGZyb20gYWNjb3VudCBzdG9yYWdlIikKCiAgICAgICAgLy8gYm9ycm93IGEgcmVmZXJlbmNlIHRvIHRoZSBzdGFraW5nIGFkbWluIG9iamVjdAogICAgICAgIGxldCBhZG1pblJlZiA9IGFkbWluQ2FwYWJpbGl0eS5ib3Jyb3c8JkZsb3dJRFRhYmxlU3Rha2luZy5BZG1pbj4oKQogICAgICAgICAgICA/PyBwYW5pYygiQ291bGQgbm90IGJvcnJvdyByZWZlcmVuY2UgdG8gc3Rha2luZyBhZG1pbiIpCgogICAgICAgIHJldHVybiBhZG1pblJlZgogICAgfQoKICAgIC8vLyBCb3Jyb3cgYSByZWZlcmVuY2UgdG8gdGhlIENsdXN0ZXJRQ3MgQWRtaW4gcmVzb3VyY2UKICAgIGFjY2Vzcyhjb250cmFjdCkgZnVuIGJvcnJvd0NsdXN0ZXJRQ0FkbWluKCk6ICZGbG93Q2x1c3RlclFDLkFkbWluIHsKICAgICAgICBsZXQgYWRtaW5DYXBhYmlsaXR5ID0gc2VsZi5hY2NvdW50LnN0b3JhZ2UuY29weTxDYXBhYmlsaXR5Pihmcm9tOiAvc3RvcmFnZS9mbG93UUNBZG1pbkVwb2NoT3BlcmF0aW9ucykKICAgICAgICAgICAgPz8gcGFuaWMoIkNvdWxkIG5vdCBnZXQgY2FwYWJpbGl0eSBmcm9tIGFjY291bnQgc3RvcmFnZSIpCgogICAgICAgIC8vIGJvcnJvdyBhIHJlZmVyZW5jZSB0byB0aGUgUUMgYWRtaW4gb2JqZWN0CiAgICAgICAgbGV0IGFkbWluUmVmID0gYWRtaW5DYXBhYmlsaXR5LmJvcnJvdzwmRmxvd0NsdXN0ZXJRQy5BZG1pbj4oKQogICAgICAgICAgICA/PyBwYW5pYygiQ291bGQgbm90IGJvcnJvdyByZWZlcmVuY2UgdG8gUUMgYWRtaW4iKQoKICAgICAgICByZXR1cm4gYWRtaW5SZWYKICAgIH0KCiAgICAvLy8gQm9ycm93IGEgcmVmZXJlbmNlIHRvIHRoZSBES0cgQWRtaW4gcmVzb3VyY2UKICAgIGFjY2Vzcyhjb250cmFjdCkgZnVuIGJvcnJvd0RLR0FkbWluKCk6ICZGbG93REtHLkFkbWluIHsKICAgICAgICBsZXQgYWRtaW5DYXBhYmlsaXR5ID0gc2VsZi5hY2NvdW50LnN0b3JhZ2UuY29weTxDYXBhYmlsaXR5Pihmcm9tOiAvc3RvcmFnZS9mbG93REtHQWRtaW5FcG9jaE9wZXJhdGlvbnMpCiAgICAgICAgICAgID8/IHBhbmljKCJDb3VsZCBub3QgZ2V0IGNhcGFiaWxpdHkgZnJvbSBhY2NvdW50IHN0b3JhZ2UiKQoKICAgICAgICAvLyBib3Jyb3cgYSByZWZlcmVuY2UgdG8gdGhlIGRrZyBhZG1pbiBvYmplY3QKICAgICAgICBsZXQgYWRtaW5SZWYgPSBhZG1pbkNhcGFiaWxpdHkuYm9ycm93PCZGbG93REtHLkFkbWluPigpCiAgICAgICAgICAgID8/IHBhbmljKCJDb3VsZCBub3QgYm9ycm93IHJlZmVyZW5jZSB0byBka2cgYWRtaW4iKQoKICAgICAgICByZXR1cm4gYWRtaW5SZWYKICAgIH0KCiAgICAvLy8gTWFrZXMgc3VyZSB0aGUgc2V0IG9mIHBoYXNlIGxlbmd0aHMgKGluIHZpZXdzKSBhcmUgdmFsaWQuCiAgICAvLy8gU3ViLXBoYXNlcyBjYW5ub3QgYmUgZ3JlYXRlciB0aGFuIHRoZSBmdWxsIGVwb2NoIGxlbmd0aC4KICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGlzVmFsaWRQaGFzZUNvbmZpZ3VyYXRpb24oXyBhdWN0aW9uTGVuOiBVSW50NjQsIF8gZGtnUGhhc2VMZW46IFVJbnQ2NCwgXyBlcG9jaExlbjogVUludDY0KTogQm9vbCB7CiAgICAgICAgcmV0dXJuIChhdWN0aW9uTGVuICsgKDMqZGtnUGhhc2VMZW4pKSA8IGVwb2NoTGVuCiAgICB9CgogICAgLy8vIFJhbmRvbWl6ZXMgdGhlIGxpc3Qgb2YgY29sbGVjdG9yIG5vZGUgSUQgYW5kIHVzZXMgYSByb3VuZCByb2JpbiBhbGdvcml0aG0KICAgIC8vLyB0byBhc3NpZ24gYWxsIGNvbGxlY3RvciBub2RlcyB0byBlcXVhbCBzaXplZCBjbHVzdGVycwogICAgYWNjZXNzKGFsbCkgZnVuIGNyZWF0ZUNvbGxlY3RvckNsdXN0ZXJzKG5vZGVJRHM6IFtTdHJpbmddKTogW0Zsb3dDbHVzdGVyUUMuQ2x1c3Rlcl0gewogICAgICAgIHByZSB7CiAgICAgICAgICAgIFVJbnQxNihub2RlSURzLmxlbmd0aCkgPj0gc2VsZi5jb25maWd1cmFibGVNZXRhZGF0YS5udW1Db2xsZWN0b3JDbHVzdGVyczogIkNhbm5vdCBoYXZlIGxlc3MgY29sbGVjdG9yIG5vZGVzIHRoYW4gY2x1c3RlcnMiCiAgICAgICAgfQogICAgICAgIHZhciBzaHVmZmxlZElEcyA9IHNlbGYucmFuZG9taXplKG5vZGVJRHMpCgogICAgICAgIC8vIEhvbGRzIGNsdXN0ZXIgYXNzaWdubWVudHMgZm9yIGNvbGxlY3RvciBub2RlcwogICAgICAgIGxldCBjbHVzdGVyczogW0Zsb3dDbHVzdGVyUUMuQ2x1c3Rlcl0gPSBbXQogICAgICAgIHZhciBjbHVzdGVySW5kZXg6IFVJbnQxNiA9IDAKICAgICAgICBsZXQgbm9kZVdlaWdodHNEaWN0aW9uYXJ5OiBbe1N0cmluZzogVUludDY0fV0gPSBbXQogICAgICAgIHdoaWxlIGNsdXN0ZXJJbmRleCA8IHNlbGYuY29uZmlndXJhYmxlTWV0YWRhdGEubnVtQ29sbGVjdG9yQ2x1c3RlcnMgewogICAgICAgICAgICBub2RlV2VpZ2h0c0RpY3Rpb25hcnkuYXBwZW5kKHt9KQogICAgICAgICAgICBjbHVzdGVySW5kZXggPSBjbHVzdGVySW5kZXggKyAxCiAgICAgICAgfQogICAgICAgIGNsdXN0ZXJJbmRleCA9IDAKCiAgICAgICAgZm9yIGlkIGluIHNodWZmbGVkSURzIHsKCiAgICAgICAgICAgIGxldCBub2RlSW5mbyA9IEZsb3dJRFRhYmxlU3Rha2luZy5Ob2RlSW5mbyhub2RlSUQ6IGlkKQoKICAgICAgICAgICAgbm9kZVdlaWdodHNEaWN0aW9uYXJ5W2NsdXN0ZXJJbmRleF1baWRdID0gbm9kZUluZm8uaW5pdGlhbFdlaWdodAoKICAgICAgICAgICAgLy8gQWR2YW5jZSB0byB0aGUgbmV4dCBjbHVzdGVyLCBvciBiYWNrIHRvIHRoZSBmaXJzdCBpZiB3ZSBoYXZlIGdvdHRlbiB0byB0aGUgbGFzdCBvbmUKICAgICAgICAgICAgY2x1c3RlckluZGV4ID0gY2x1c3RlckluZGV4ICsgMQogICAgICAgICAgICBpZiBjbHVzdGVySW5kZXggPT0gc2VsZi5jb25maWd1cmFibGVNZXRhZGF0YS5udW1Db2xsZWN0b3JDbHVzdGVycyB7CiAgICAgICAgICAgICAgICBjbHVzdGVySW5kZXggPSAwCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIENyZWF0ZSB0aGUgY2x1c3RlcnMgQXJyYXkgdGhhdCBpcyBzZW50IHRvIHRoZSBRQyBjb250cmFjdAogICAgICAgIC8vIGFuZCBlbWl0dGVkIGluIHRoZSBFcG9jaFNldHVwIGV2ZW50CiAgICAgICAgY2x1c3RlckluZGV4ID0gMAogICAgICAgIHdoaWxlIGNsdXN0ZXJJbmRleCA8IHNlbGYuY29uZmlndXJhYmxlTWV0YWRhdGEubnVtQ29sbGVjdG9yQ2x1c3RlcnMgewogICAgICAgICAgICBjbHVzdGVycy5hcHBlbmQoRmxvd0NsdXN0ZXJRQy5DbHVzdGVyKGluZGV4OiBjbHVzdGVySW5kZXgsIG5vZGVXZWlnaHRzOiBub2RlV2VpZ2h0c0RpY3Rpb25hcnlbY2x1c3RlckluZGV4XSEpKQogICAgICAgICAgICBjbHVzdGVySW5kZXggPSBjbHVzdGVySW5kZXggKyAxCiAgICAgICAgfQoKICAgICAgICByZXR1cm4gY2x1c3RlcnMKICAgIH0KCiAgICAvLy8gQSBmdW5jdGlvbiB0byBnZW5lcmF0ZSBhIHJhbmRvbSBwZXJtdXRhdGlvbiBvZiBhcnJbXQogICAgLy8vIHVzaW5nIHRoZSBmaXNoZXIgeWF0ZXMgc2h1ZmZsaW5nIGFsZ29yaXRobQogICAgYWNjZXNzKGFsbCkgZnVuIHJhbmRvbWl6ZShfIGFycmF5OiBbU3RyaW5nXSk6IFtTdHJpbmddIHsKCiAgICAgICAgdmFyIGkgPSBhcnJheS5sZW5ndGggLSAxCgogICAgICAgIC8vIFN0YXJ0IGZyb20gdGhlIGxhc3QgZWxlbWVudCBhbmQgc3dhcCBvbmUgYnkgb25lLiBXZSBkb24ndAogICAgICAgIC8vIG5lZWQgdG8gcnVuIGZvciB0aGUgZmlyc3QgZWxlbWVudCB0aGF0J3Mgd2h5IGkgPiAwCiAgICAgICAgd2hpbGUgaSA+IDAKICAgICAgICB7CiAgICAgICAgICAgIC8vIFBpY2sgYSByYW5kb20gaW5kZXggZnJvbSAwIHRvIGkKICAgICAgICAgICAgLy8vIFRPRE86IHRoaXMgbmFpdmUgaW1wbGVtZW50YXRpb24gaXMgdW5uZWNlc3NhcmlseSBjb3N0bHkgYXQgcnVudGltZSAtLSB1cGRhdGUgd2l0aCByZXZlcnRpYmxlUmFuZG9tPFVJbnQ2ND4oaSsxKSB3aGVuIGF2YWlsYWJsZQogICAgICAgICAgICB2YXIgcmFuZG9tTnVtID0gcmV2ZXJ0aWJsZVJhbmRvbTxVSW50NjQ+KCkKICAgICAgICAgICAgdmFyIHJhbmRvbUluZGV4ID0gcmFuZG9tTnVtICUgVUludDY0KGkgKyAxKQoKICAgICAgICAgICAgLy8gU3dhcCBhcnJbaV0gd2l0aCB0aGUgZWxlbWVudCBhdCByYW5kb20gaW5kZXgKICAgICAgICAgICAgdmFyIHRlbXAgPSBhcnJheVtpXQogICAgICAgICAgICBhcnJheVtpXSA9IGFycmF5W3JhbmRvbUluZGV4XQogICAgICAgICAgICBhcnJheVtyYW5kb21JbmRleF0gPSB0ZW1wCgogICAgICAgICAgICBpID0gaSAtIDEKICAgICAgICB9CgogICAgICAgIHJldHVybiBhcnJheQogICAgfQoKICAgIC8vLyBDb2xsZWN0b3Igbm9kZXMgY2FsbCB0aGlzIGZ1bmN0aW9uIHRvIGdldCB0aGVpciBRQyBWb3RlciByZXNvdXJjZQogICAgLy8vIGluIG9yZGVyIHRvIHBhcnRpY2lwYXRlIHRoZSB0aGUgUUMgZ2VuZXJhdGlvbiBmb3IgdGhlaXIgY2x1c3RlcgogICAgYWNjZXNzKGFsbCkgZnVuIGdldENsdXN0ZXJRQ1ZvdGVyKG5vZGVTdGFrZXI6ICZGbG93SURUYWJsZVN0YWtpbmcuTm9kZVN0YWtlcik6IEBGbG93Q2x1c3RlclFDLlZvdGVyIHsKICAgICAgICBsZXQgbm9kZUluZm8gPSBGbG93SURUYWJsZVN0YWtpbmcuTm9kZUluZm8obm9kZUlEOiBub2RlU3Rha2VyLmlkKQoKICAgICAgICBhc3NlcnQgKAogICAgICAgICAgICBub2RlSW5mby5yb2xlID09IE5vZGVSb2xlLkNvbGxlY3Rvci5yYXdWYWx1ZSwKICAgICAgICAgICAgbWVzc2FnZTogIk5vZGUgb3BlcmF0b3IgbXVzdCBiZSBhIGNvbGxlY3RvciBub2RlIHRvIGdldCBhIFFDIFZvdGVyIG9iamVjdCIKICAgICAgICApCgogICAgICAgIGxldCBjbHVzdGVyUUNBZG1pbiA9IHNlbGYuYm9ycm93Q2x1c3RlclFDQWRtaW4oKQogICAgICAgIHJldHVybiA8LWNsdXN0ZXJRQ0FkbWluLmNyZWF0ZVZvdGVyKG5vZGVJRDogbm9kZVN0YWtlci5pZCwgc3Rha2luZ0tleTogbm9kZUluZm8uc3Rha2luZ0tleSkKICAgIH0KCiAgICAvLy8gQ29uc2Vuc3VzIG5vZGVzIGNhbGwgdGhpcyBmdW5jdGlvbiB0byBnZXQgdGhlaXIgREtHIFBhcnRpY2lwYW50IHJlc291cmNlCiAgICAvLy8gaW4gb3JkZXIgdG8gcGFydGljaXBhdGUgaW4gdGhlIERLRyBmb3IgdGhlIG5leHQgZXBvY2gKICAgIGFjY2VzcyhhbGwpIGZ1biBnZXRES0dQYXJ0aWNpcGFudChub2RlU3Rha2VyOiAmRmxvd0lEVGFibGVTdGFraW5nLk5vZGVTdGFrZXIpOiBARmxvd0RLRy5QYXJ0aWNpcGFudCB7CiAgICAgICAgbGV0IG5vZGVJbmZvID0gRmxvd0lEVGFibGVTdGFraW5nLk5vZGVJbmZvKG5vZGVJRDogbm9kZVN0YWtlci5pZCkKCiAgICAgICAgYXNzZXJ0ICgKICAgICAgICAgICAgbm9kZUluZm8ucm9sZSA9PSBOb2RlUm9sZS5Db25zZW5zdXMucmF3VmFsdWUsCiAgICAgICAgICAgIG1lc3NhZ2U6ICJOb2RlIG9wZXJhdG9yIG11c3QgYmUgYSBjb25zZW5zdXMgbm9kZSB0byBnZXQgYSBES0cgUGFydGljaXBhbnQgb2JqZWN0IgogICAgICAgICkKCiAgICAgICAgbGV0IGRrZ0FkbWluID0gc2VsZi5ib3Jyb3dES0dBZG1pbigpCiAgICAgICAgcmV0dXJuIDwtZGtnQWRtaW4uY3JlYXRlUGFydGljaXBhbnQobm9kZUlEOiBub2RlU3Rha2VyLmlkKQogICAgfQoKICAgIC8vLyBSZXR1cm5zIHRoZSBtZXRhZGF0YSB0aGF0IGlzIGFibGUgdG8gYmUgY29uZmlndXJlZCBieSB0aGUgYWRtaW4KICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGdldENvbmZpZ01ldGFkYXRhKCk6IENvbmZpZyB7CiAgICAgICAgcmV0dXJuIHNlbGYuY29uZmlndXJhYmxlTWV0YWRhdGEKICAgIH0KCiAgICAvLy8gUmV0dXJucyB0aGUgY29uZmlnIGZvciBlcG9jaCB0aW1pbmcsIHdoaWNoIGNhbiBiZSBjb25maWd1cmVkIGJ5IHRoZSBhZG1pbi4KICAgIC8vLyBDb25jZXB0dWFsbHksIHRoaXMgc2hvdWxkIGJlIHBhcnQgb2YgYENvbmZpZ2AsIGhvd2V2ZXIgaXQgd2FzIGFkZGVkIGxhdGVyIGluIGFuCiAgICAvLy8gdXBncmFkZSB3aGljaCByZXF1aXJlcyBuZXcgZmllbGRzIGJlIHNwZWNpZmllZCBzZXBhcmF0ZWx5IGZyb20gZXhpc3Rpbmcgc3RydWN0cy4KICAgIGFjY2VzcyhhbGwpIGZ1biBnZXRFcG9jaFRpbWluZ0NvbmZpZygpOiBFcG9jaFRpbWluZ0NvbmZpZyB7CiAgICAgICAgcmV0dXJuIHNlbGYuYWNjb3VudC5zdG9yYWdlLmNvcHk8RXBvY2hUaW1pbmdDb25maWc+KGZyb206IC9zdG9yYWdlL2Zsb3dFcG9jaFRpbWluZ0NvbmZpZykhCiAgICB9CgogICAgLy8vIFRoZSBwcm9wb3NlZCBFcG9jaCBjb3VudGVyIGlzIGFsd2F5cyB0aGUgY3VycmVudCBjb3VudGVyIHBsdXMgMQogICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gcHJvcG9zZWRFcG9jaENvdW50ZXIoKTogVUludDY0IHsKICAgICAgICByZXR1cm4gc2VsZi5jdXJyZW50RXBvY2hDb3VudGVyICsgMSBhcyBVSW50NjQKICAgIH0KCiAgICBhY2Nlc3MoYWxsKSBmdW4gYXV0b21hdGljUmV3YXJkc0VuYWJsZWQoKTogQm9vbCB7CiAgICAgICAgcmV0dXJuIHNlbGYuYWNjb3VudC5zdG9yYWdlLmNvcHk8Qm9vbD4oZnJvbTogL3N0b3JhZ2UvZmxvd0F1dG9tYXRpY1Jld2FyZHNFbmFibGVkKSA/PyBmYWxzZQogICAgfQoKICAgIC8vLyBHZXRzIHRoZSBjdXJyZW50IGFtb3VudCBvZiBib251cyB0b2tlbnMgbGVmdCB0byBiZSBkZXN0cm95ZWQKICAgIC8vLyBCb251cyB0b2tlbnMgYXJlIHRva2VucyB0aGF0IHdlcmUgYWxsb2NhdGVkIGFzIGEgZGVjZW50cmFsaXphdGlvbiBpbmNlbnRpdmUKICAgIC8vLyB0aGF0IGFyZSBjdXJyZW50bHkgaW4gdGhlIHByb2Nlc3Mgb2YgYmVpbmcgZGVzdHJveWVkLiBUaGUgcHJlc2VuY2Ugb2YgYm9udXMKICAgIC8vLyB0b2tlbnMgdGhyb3dzIG9mZiB0aGUgaW50ZW5kZWQgY2FsY3VsYXRpb24gZm9yIHRoZSBGTE9XIGluZmxhdGlvbiByYXRlCiAgICAvLy8gc28gdGhleSBhcmUgbm90IGluY2x1ZGVkIGluIHRoYXQgY2FsY3VsYXRpb24KICAgIC8vLyBFdmVudHVhbGx5LCBhbGwgdGhlIGJvbnVzIHRva2VucyB3aWxsIGJlIGRlc3Ryb3llZCBhbmQKICAgIC8vLyB0aGlzIHdpbGwgbm90IGJlIG5lZWRlZCBhbnltb3JlCiAgICBhY2Nlc3MoYWxsKSBmdW4gZ2V0Qm9udXNUb2tlbnMoKTogVUZpeDY0IHsKICAgICAgICByZXR1cm4gc2VsZi5hY2NvdW50LnN0b3JhZ2UuY29weTxVRml4NjQ+KGZyb206IC9zdG9yYWdlL0Zsb3dCb251c1Rva2VuQW1vdW50KQogICAgICAgICAgICAgICAgPz8gMC4wCiAgICB9CgogICAgaW5pdCAoY3VycmVudEVwb2NoQ291bnRlcjogVUludDY0LAogICAgICAgICAgbnVtVmlld3NJbkVwb2NoOiBVSW50NjQsCiAgICAgICAgICBudW1WaWV3c0luU3Rha2luZ0F1Y3Rpb246IFVJbnQ2NCwKICAgICAgICAgIG51bVZpZXdzSW5ES0dQaGFzZTogVUludDY0LAogICAgICAgICAgbnVtQ29sbGVjdG9yQ2x1c3RlcnM6IFVJbnQxNiwKICAgICAgICAgIEZMT1dzdXBwbHlJbmNyZWFzZVBlcmNlbnRhZ2U6IFVGaXg2NCwKICAgICAgICAgIHJhbmRvbVNvdXJjZTogU3RyaW5nLAogICAgICAgICAgY29sbGVjdG9yQ2x1c3RlcnM6IFtGbG93Q2x1c3RlclFDLkNsdXN0ZXJdLAogICAgICAgICAgY2x1c3RlclFDczogW0Zsb3dDbHVzdGVyUUMuQ2x1c3RlclFDXSwKICAgICAgICAgIGRrZ1B1YktleXM6IFtTdHJpbmddKSB7CiAgICAgICAgcHJlIHsKICAgICAgICAgICAgRmxvd0Vwb2NoLmlzVmFsaWRQaGFzZUNvbmZpZ3VyYXRpb24obnVtVmlld3NJblN0YWtpbmdBdWN0aW9uLCBudW1WaWV3c0luREtHUGhhc2UsIG51bVZpZXdzSW5FcG9jaCk6CiAgICAgICAgICAgICAgICAiSW52YWxpZCBzdGFydFZpZXcgYW5kIGVuZFZpZXcgY29uZmlndXJhdGlvbiIKICAgICAgICB9CgogICAgICAgIHNlbGYuY29uZmlndXJhYmxlTWV0YWRhdGEgPSBDb25maWcobnVtVmlld3NJbkVwb2NoOiBudW1WaWV3c0luRXBvY2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1WaWV3c0luU3Rha2luZ0F1Y3Rpb246IG51bVZpZXdzSW5TdGFraW5nQXVjdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bVZpZXdzSW5ES0dQaGFzZTogbnVtVmlld3NJbkRLR1BoYXNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtQ29sbGVjdG9yQ2x1c3RlcnM6IG51bUNvbGxlY3RvckNsdXN0ZXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRkxPV3N1cHBseUluY3JlYXNlUGVyY2VudGFnZTogRkxPV3N1cHBseUluY3JlYXNlUGVyY2VudGFnZSkKCiAgICAgICAgLy8gU2V0IGEgcmVhc29uYWJsZSBkZWZhdWx0IGZvciB0aGUgZXBvY2ggdGltaW5nIGNvbmZpZyB0YXJnZXRpbmcgMSBibG9jayBwZXIgc2Vjb25kCiAgICAgICAgbGV0IGRlZmF1bHRFcG9jaFRpbWluZ0NvbmZpZyA9IEVwb2NoVGltaW5nQ29uZmlnKAogICAgICAgICAgICBkdXJhdGlvbjogbnVtVmlld3NJbkVwb2NoLAogICAgICAgICAgICByZWZDb3VudGVyOiBjdXJyZW50RXBvY2hDb3VudGVyLAogICAgICAgICAgICByZWZUaW1lc3RhbXA6IFVJbnQ2NChnZXRDdXJyZW50QmxvY2soKS50aW1lc3RhbXApK251bVZpZXdzSW5FcG9jaCkKICAgICAgICBGbG93RXBvY2guYWNjb3VudC5zdG9yYWdlLnNhdmUoZGVmYXVsdEVwb2NoVGltaW5nQ29uZmlnLCB0bzogL3N0b3JhZ2UvZmxvd0Vwb2NoVGltaW5nQ29uZmlnKQoKICAgICAgICBzZWxmLmN1cnJlbnRFcG9jaENvdW50ZXIgPSBjdXJyZW50RXBvY2hDb3VudGVyCiAgICAgICAgc2VsZi5jdXJyZW50RXBvY2hQaGFzZSA9IEVwb2NoUGhhc2UuU1RBS0lOR0FVQ1RJT04KICAgICAgICBzZWxmLmFkbWluU3RvcmFnZVBhdGggPSAvc3RvcmFnZS9mbG93RXBvY2hBZG1pbgogICAgICAgIHNlbGYuaGVhcnRiZWF0U3RvcmFnZVBhdGggPSAvc3RvcmFnZS9mbG93RXBvY2hIZWFydGJlYXQKICAgICAgICBzZWxmLm1ldGFkYXRhU3RvcmFnZVBhdGggPSAvc3RvcmFnZS9mbG93RXBvY2hNZXRhZGF0YQoKICAgICAgICBsZXQgZXBvY2hNZXRhZGF0YToge1VJbnQ2NDogRXBvY2hNZXRhZGF0YX0gPSB7fQoKICAgICAgICBzZWxmLmFjY291bnQuc3RvcmFnZS5zYXZlKGVwb2NoTWV0YWRhdGEsIHRvOiBzZWxmLm1ldGFkYXRhU3RvcmFnZVBhdGgpCgogICAgICAgIHNlbGYuYWNjb3VudC5zdG9yYWdlLnNhdmUoPC1jcmVhdGUgQWRtaW4oKSwgdG86IHNlbGYuYWRtaW5TdG9yYWdlUGF0aCkKICAgICAgICBzZWxmLmFjY291bnQuc3RvcmFnZS5zYXZlKDwtY3JlYXRlIEhlYXJ0YmVhdCgpLCB0bzogc2VsZi5oZWFydGJlYXRTdG9yYWdlUGF0aCkKCiAgICAgICAgLy8gQ3JlYXRlIGEgcHJpdmF0ZSBjYXBhYmlsaXR5IHRvIHRoZSBzdGFraW5nIGFkbWluIGFuZCBzdG9yZSBpdCBpbiBhIGRpZmZlcmVudCBwYXRoCiAgICAgICAgLy8gT24gTWFpbm5ldCBhbmQgVGVzdG5ldCwgdGhlIEFkbWluIHJlc291cmNlcyBhcmUgc3RvcmVkIGluIHRoZSBzZXJ2aWNlIGFjY291bnQsIHJhdGhlciB0aGFuIGhlcmUuCiAgICAgICAgLy8gQXMgYSBkZWZhdWx0LCB3ZSBzdG9yZSBib3RoIHRoZSBhZG1pbiByZXNvdXJjZXMsIGFuZCB0aGUgY2FwYWJpbGl0aWVzIGxpbmtpbmcgdG8gdGhvc2UgcmVzb3VyY2VzLCBpbiB0aGUgc2FtZSBhY2NvdW50LgogICAgICAgIC8vIFRoaXMgZW5zdXJlcyB0aGF0IHRoaXMgY29uc3RydWN0b3IgcHJvZHVjZXMgYSBzdGF0ZSB3aGljaCBpcyBjb21wYXRpYmxlIHdpdGggdGhlIHN5c3RlbSBjaHVuawogICAgICAgIC8vIHNvIHRoYXQgbmV3bHkgY3JlYXRlZCBuZXR3b3JrcyBhcmUgZnVuY3Rpb25hbCB3aXRob3V0IGFkZGl0aW9uYWwgcmVzb3VyY2UgbWFuaXB1bGF0aW9uLgogICAgICAgIGxldCBzdGFraW5nQWRtaW5DYXBhYmlsaXR5ID0gc2VsZi5hY2NvdW50LmNhcGFiaWxpdGllcy5zdG9yYWdlLmlzc3VlPCZGbG93SURUYWJsZVN0YWtpbmcuQWRtaW4+KEZsb3dJRFRhYmxlU3Rha2luZy5TdGFraW5nQWRtaW5TdG9yYWdlUGF0aCkKICAgICAgICBzZWxmLmFjY291bnQuc3RvcmFnZS5zYXZlPENhcGFiaWxpdHk8JkZsb3dJRFRhYmxlU3Rha2luZy5BZG1pbj4+KHN0YWtpbmdBZG1pbkNhcGFiaWxpdHksIHRvOiAvc3RvcmFnZS9mbG93U3Rha2luZ0FkbWluRXBvY2hPcGVyYXRpb25zKQoKICAgICAgICAvLyBDcmVhdGUgYSBwcml2YXRlIGNhcGFiaWxpdHkgdG8gdGhlIHFjIGFkbWluCiAgICAgICAgLy8gYW5kIHN0b3JlIGl0IGluIGEgZGlmZmVyZW50IHBhdGgKICAgICAgICBsZXQgcWNBZG1pbkNhcGFiaWxpdHkgPSBzZWxmLmFjY291bnQuY2FwYWJpbGl0aWVzLnN0b3JhZ2UuaXNzdWU8JkZsb3dDbHVzdGVyUUMuQWRtaW4+KEZsb3dDbHVzdGVyUUMuQWRtaW5TdG9yYWdlUGF0aCkKICAgICAgICBzZWxmLmFjY291bnQuc3RvcmFnZS5zYXZlPENhcGFiaWxpdHk8JkZsb3dDbHVzdGVyUUMuQWRtaW4+PihxY0FkbWluQ2FwYWJpbGl0eSwgdG86IC9zdG9yYWdlL2Zsb3dRQ0FkbWluRXBvY2hPcGVyYXRpb25zKQoKICAgICAgICAvLyBDcmVhdGUgYSBwcml2YXRlIGNhcGFiaWxpdHkgdG8gdGhlIGRrZyBhZG1pbgogICAgICAgIC8vIGFuZCBzdG9yZSBpdCBpbiBhIGRpZmZlcmVudCBwYXRoCiAgICAgICAgbGV0IGRrZ0FkbWluQ2FwYWJpbGl0eSA9IHNlbGYuYWNjb3VudC5jYXBhYmlsaXRpZXMuc3RvcmFnZS5pc3N1ZTwmRmxvd0RLRy5BZG1pbj4oRmxvd0RLRy5BZG1pblN0b3JhZ2VQYXRoKQogICAgICAgIHNlbGYuYWNjb3VudC5zdG9yYWdlLnNhdmU8Q2FwYWJpbGl0eTwmRmxvd0RLRy5BZG1pbj4+KGRrZ0FkbWluQ2FwYWJpbGl0eSwgdG86IC9zdG9yYWdlL2Zsb3dES0dBZG1pbkVwb2NoT3BlcmF0aW9ucykKCiAgICAgICAgc2VsZi5ib3Jyb3dTdGFraW5nQWRtaW4oKS5zdGFydFN0YWtpbmdBdWN0aW9uKCkKCiAgICAgICAgbGV0IGN1cnJlbnRCbG9jayA9IGdldEN1cnJlbnRCbG9jaygpCgogICAgICAgIGxldCBmaXJzdEVwb2NoTWV0YWRhdGEgPSBFcG9jaE1ldGFkYXRhKGNvdW50ZXI6IHNlbGYuY3VycmVudEVwb2NoQ291bnRlciwKICAgICAgICAgICAgICAgICAgICBzZWVkOiByYW5kb21Tb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgc3RhcnRWaWV3OiBjdXJyZW50QmxvY2sudmlldywKICAgICAgICAgICAgICAgICAgICBlbmRWaWV3OiBjdXJyZW50QmxvY2sudmlldyArIHNlbGYuY29uZmlndXJhYmxlTWV0YWRhdGEubnVtVmlld3NJbkVwb2NoIC0gMSwKICAgICAgICAgICAgICAgICAgICBzdGFraW5nRW5kVmlldzogY3VycmVudEJsb2NrLnZpZXcgKyBzZWxmLmNvbmZpZ3VyYWJsZU1ldGFkYXRhLm51bVZpZXdzSW5TdGFraW5nQXVjdGlvbiAtIDEsCiAgICAgICAgICAgICAgICAgICAgdG90YWxSZXdhcmRzOiBGbG93SURUYWJsZVN0YWtpbmcuZ2V0RXBvY2hUb2tlblBheW91dCgpLAogICAgICAgICAgICAgICAgICAgIGNvbGxlY3RvckNsdXN0ZXJzOiBjb2xsZWN0b3JDbHVzdGVycywKICAgICAgICAgICAgICAgICAgICBjbHVzdGVyUUNzOiBjbHVzdGVyUUNzLAogICAgICAgICAgICAgICAgICAgIGRrZ0tleXM6IGRrZ1B1YktleXMpCgogICAgICAgIHNlbGYuc2F2ZUVwb2NoTWV0YWRhdGEoZmlyc3RFcG9jaE1ldGFkYXRhKQogICAgfQp9Cg==",
		"FlowIDTableStaking": "LyoKCiAgICBGbG93SURUYWJsZVN0YWtpbmcKCiAgICBUaGUgRmxvdyBJRCBUYWJsZSBhbmQgU3Rha2luZyBjb250cmFjdCBtYW5hZ2VzCiAgICBub2RlIG9wZXJhdG9ycycgYW5kIGRlbGVnYXRvcnMnIGluZm9ybWF0aW9uCiAgICBhbmQgRmxvdyB0b2tlbnMgdGhhdCBhcmUgc3Rha2VkIGFzIHBhcnQgb2YgdGhlIEZsb3cgUHJvdG9jb2wuCgogICAgTm9kZXMgc3VibWl0IHRoZWlyIHN0YWtlIHRvIHRoZSBwdWJsaWMgYWRkTm9kZUluZm8gZnVuY3Rpb24KICAgIGR1cmluZyB0aGUgc3Rha2luZyBhdWN0aW9uIHBoYXNlLgoKICAgIFRoaXMgcmVjb3JkcyB0aGVpciBpbmZvIGFuZCBjb21taXR0ZWQgdG9rZW5zLiBUaGV5IGFsc28gd2lsbCBnZXQgYSBOb2RlCiAgICBPYmplY3QgdGhhdCB0aGV5IGNhbiB1c2UgdG8gc3Rha2UsIHVuc3Rha2UsIGFuZCB3aXRoZHJhdyByZXdhcmRzLgoKICAgIEVhY2ggbm9kZSBoYXMgbXVsdGlwbGUgdG9rZW4gYnVja2V0cyB0aGF0IGhvbGQgdGhlaXIgdG9rZW5zCiAgICBiYXNlZCBvbiB0aGVpciBzdGF0dXM6IGNvbW1pdHRlZCwgc3Rha2VkLCB1bnN0YWtpbmcsIHVuc3Rha2VkLCBhbmQgcmV3YXJkZWQuCgogICAgRGVsZWdhdG9ycyBjYW4gYWxzbyByZWdpc3RlciB0byBkZWxlZ2F0ZSBGTE9XIHRvIGEgbm9kZSBvcGVyYXRvcgogICAgZHVyaW5nIHRoZSBzdGFraW5nIGF1Y3Rpb24gcGhhc2UgYnkgdXNpbmcgdGhlIHJlZ2lzdGVyTmV3RGVsZWdhdG9yKCkgZnVuY3Rpb24uCiAgICBUaGV5IGhhdmUgdGhlIHNhbWUgdG9rZW4gYnVja2V0cyB0aGF0IG5vZGUgb3BlcmF0b3JzIGRvLgoKICAgIFRoZSBBZG1pbiBoYXMgdGhlIGF1dGhvcml0eSB0byByZW1vdmUgbm9kZSByZWNvcmRzLAogICAgcmVmdW5kIGluc3VmZmljaWVudGx5IHN0YWtlZCBub2RlcywgcGF5IHJld2FyZHMsCiAgICBhbmQgbW92ZSB0b2tlbnMgYmV0d2VlbiBidWNrZXRzLiBUaGVzZSB3aWxsIGhhcHBlbiBvbmNlIGV2ZXJ5IGVwb2NoLgoKICAgIFNlZSBhZGRpdGlvbmFsIHN0YWtpbmcgZG9jdW1lbnRhdGlvbiBoZXJlOiBodHRwczovL2RvY3Mub25mbG93Lm9yZy9zdGFraW5nLwoKICovCgppbXBvcnQgRnVuZ2libGVUb2tlbiBmcm9tIDB4ZjIzM2RjZWU4OGZlMGFiZQppbXBvcnQgRmxvd1Rva2VuIGZyb20gMHgxNjU0NjUzMzk5MDQwYTYxCmltcG9ydCBGbG93RmVlcyBmcm9tIDB4ZjkxOWVlNzc0NDdiNzQ5NwppbXBvcnQgQnVybmVyIGZyb20gMHhmMjMzZGNlZTg4ZmUwYWJlCmltcG9ydCBDcnlwdG8KCmFjY2VzcyhhbGwpIGNvbnRyYWN0IEZsb3dJRFRhYmxlU3Rha2luZyB7CgogICAgLy8vIEVwb2NoCiAgICBhY2Nlc3MoYWxsKSBldmVudCBOZXdFcG9jaCh0b3RhbFN0YWtlZDogVUZpeDY0LCB0b3RhbFJld2FyZFBheW91dDogVUZpeDY0LCBuZXdFcG9jaENvdW50ZXI6IFVJbnQ2NCkKICAgIGFjY2VzcyhhbGwpIGV2ZW50IEVwb2NoVG90YWxSZXdhcmRzUGFpZCh0b3RhbDogVUZpeDY0LCBmcm9tRmVlczogVUZpeDY0LCBtaW50ZWQ6IFVGaXg2NCwgZmVlc0J1cm5lZDogVUZpeDY0LCBlcG9jaENvdW50ZXJGb3JSZXdhcmRzOiBVSW50NjQpCgogICAgLy8vIE5vZGUKICAgIGFjY2VzcyhhbGwpIGV2ZW50IE5ld05vZGVDcmVhdGVkKG5vZGVJRDogU3RyaW5nLCByb2xlOiBVSW50OCwgYW1vdW50Q29tbWl0dGVkOiBVRml4NjQpCiAgICBhY2Nlc3MoYWxsKSBldmVudCBUb2tlbnNDb21taXR0ZWQobm9kZUlEOiBTdHJpbmcsIGFtb3VudDogVUZpeDY0KQogICAgYWNjZXNzKGFsbCkgZXZlbnQgVG9rZW5zU3Rha2VkKG5vZGVJRDogU3RyaW5nLCBhbW91bnQ6IFVGaXg2NCkKICAgIGFjY2VzcyhhbGwpIGV2ZW50IE5vZGVUb2tlbnNSZXF1ZXN0ZWRUb1Vuc3Rha2Uobm9kZUlEOiBTdHJpbmcsIGFtb3VudDogVUZpeDY0KQogICAgYWNjZXNzKGFsbCkgZXZlbnQgVG9rZW5zVW5zdGFraW5nKG5vZGVJRDogU3RyaW5nLCBhbW91bnQ6IFVGaXg2NCkKICAgIGFjY2VzcyhhbGwpIGV2ZW50IFRva2Vuc1Vuc3Rha2VkKG5vZGVJRDogU3RyaW5nLCBhbW91bnQ6IFVGaXg2NCkKICAgIGFjY2VzcyhhbGwpIGV2ZW50IE5vZGVSZW1vdmVkQW5kUmVmdW5kZWQobm9kZUlEOiBTdHJpbmcsIGFtb3VudDogVUZpeDY0KQogICAgYWNjZXNzKGFsbCkgZXZlbnQgUmV3YXJkc1BhaWQobm9kZUlEOiBTdHJpbmcsIGFtb3VudDogVUZpeDY0LCBlcG9jaENvdW50ZXI6ICBVSW50NjQpCiAgICBhY2Nlc3MoYWxsKSBldmVudCBVbnN0YWtlZFRva2Vuc1dpdGhkcmF3bihub2RlSUQ6IFN0cmluZywgYW1vdW50OiBVRml4NjQpCiAgICBhY2Nlc3MoYWxsKSBldmVudCBSZXdhcmRUb2tlbnNXaXRoZHJhd24obm9kZUlEOiBTdHJpbmcsIGFtb3VudDogVUZpeDY0KQogICAgYWNjZXNzKGFsbCkgZXZlbnQgTmV0d29ya2luZ0FkZHJlc3NVcGRhdGVkKG5vZGVJRDogU3RyaW5nLCBuZXdBZGRyZXNzOiBTdHJpbmcpCiAgICBhY2Nlc3MoYWxsKSBldmVudCBOb2RlV2VpZ2h0Q2hhbmdlZChub2RlSUQ6IFN0cmluZywgbmV3V2VpZ2h0OiBVSW50NjQpCgogICAgLy8vIERlbGVnYXRvcgogICAgYWNjZXNzKGFsbCkgZXZlbnQgTmV3RGVsZWdhdG9yQ3JlYXRlZChub2RlSUQ6IFN0cmluZywgZGVsZWdhdG9ySUQ6IFVJbnQzMikKICAgIGFjY2VzcyhhbGwpIGV2ZW50IERlbGVnYXRvclRva2Vuc0NvbW1pdHRlZChub2RlSUQ6IFN0cmluZywgZGVsZWdhdG9ySUQ6IFVJbnQzMiwgYW1vdW50OiBVRml4NjQpCiAgICBhY2Nlc3MoYWxsKSBldmVudCBEZWxlZ2F0b3JUb2tlbnNTdGFrZWQobm9kZUlEOiBTdHJpbmcsIGRlbGVnYXRvcklEOiBVSW50MzIsIGFtb3VudDogVUZpeDY0KQogICAgYWNjZXNzKGFsbCkgZXZlbnQgRGVsZWdhdG9yVG9rZW5zUmVxdWVzdGVkVG9VbnN0YWtlKG5vZGVJRDogU3RyaW5nLCBkZWxlZ2F0b3JJRDogVUludDMyLCBhbW91bnQ6IFVGaXg2NCkKICAgIGFjY2VzcyhhbGwpIGV2ZW50IERlbGVnYXRvclRva2Vuc1Vuc3Rha2luZyhub2RlSUQ6IFN0cmluZywgZGVsZWdhdG9ySUQ6IFVJbnQzMiwgYW1vdW50OiBVRml4NjQpCiAgICBhY2Nlc3MoYWxsKSBldmVudCBEZWxlZ2F0b3JUb2tlbnNVbnN0YWtlZChub2RlSUQ6IFN0cmluZywgZGVsZWdhdG9ySUQ6IFVJbnQzMiwgYW1vdW50OiBVRml4NjQpCiAgICBhY2Nlc3MoYWxsKSBldmVudCBEZWxlZ2F0b3JSZXdhcmRzUGFpZChub2RlSUQ6IFN0cmluZywgZGVsZWdhdG9ySUQ6IFVJbnQzMiwgYW1vdW50OiBVRml4NjQsIGVwb2NoQ291bnRlcjogIFVJbnQ2NCkKICAgIGFjY2VzcyhhbGwpIGV2ZW50IERlbGVnYXRvclVuc3Rha2VkVG9rZW5zV2l0aGRyYXduKG5vZGVJRDogU3RyaW5nLCBkZWxlZ2F0b3JJRDogVUludDMyLCBhbW91bnQ6IFVGaXg2NCkKICAgIGFjY2VzcyhhbGwpIGV2ZW50IERlbGVnYXRvclJld2FyZFRva2Vuc1dpdGhkcmF3bihub2RlSUQ6IFN0cmluZywgZGVsZWdhdG9ySUQ6IFVJbnQzMiwgYW1vdW50OiBVRml4NjQpCgogICAgLy8vIENvbnRyYWN0IEZpZWxkcwogICAgYWNjZXNzKGFsbCkgZXZlbnQgTmV3RGVsZWdhdG9yQ3V0UGVyY2VudGFnZShuZXdDdXRQZXJjZW50YWdlOiBVRml4NjQpCiAgICBhY2Nlc3MoYWxsKSBldmVudCBOZXdXZWVrbHlQYXlvdXQobmV3UGF5b3V0OiBVRml4NjQpCiAgICBhY2Nlc3MoYWxsKSBldmVudCBOZXdTdGFraW5nTWluaW11bXMobmV3TWluaW11bXM6IHtVSW50ODogVUZpeDY0fSkKICAgIGFjY2VzcyhhbGwpIGV2ZW50IE5ld0RlbGVnYXRvclN0YWtpbmdNaW5pbXVtKG5ld01pbmltdW06IFVGaXg2NCkKCiAgICAvLy8gSG9sZHMgdGhlIGlkZW50aXR5IHRhYmxlIGZvciBhbGwgdGhlIG5vZGVzIGluIHRoZSBuZXR3b3JrLgogICAgLy8vIEluY2x1ZGVzIG5vZGVzIHRoYXQgYXJlbid0IGFjdGl2ZWx5IHBhcnRpY2lwYXRpbmcKICAgIC8vLyBrZXkgPSBub2RlIElECiAgICBhY2Nlc3MoY29udHJhY3QpIHZhciBub2RlczogQHtTdHJpbmc6IE5vZGVSZWNvcmR9CgogICAgLy8vIFRoZSBtaW5pbXVtIGFtb3VudCBvZiB0b2tlbnMgdGhhdCBlYWNoIHN0YWtlciB0eXBlIGhhcyB0byBzdGFrZQogICAgLy8vIGluIG9yZGVyIHRvIGJlIGNvbnNpZGVyZWQgdmFsaWQKICAgIC8vLyBLZXlzOgogICAgLy8vIDEgLSBDb2xsZWN0b3IgTm9kZXMKICAgIC8vLyAyIC0gQ29uc2Vuc3VzIE5vZGVzCiAgICAvLy8gMyAtIEV4ZWN1dGlvbiBOb2RlcwogICAgLy8vIDQgLSBWZXJpZmljYXRpb24gTm9kZXMKICAgIC8vLyA1IC0gQWNjZXNzIE5vZGVzCiAgICBhY2Nlc3MoYWNjb3VudCkgdmFyIG1pbmltdW1TdGFrZVJlcXVpcmVkOiB7VUludDg6IFVGaXg2NH0KCiAgICAvLy8gVGhlIHRvdGFsIGFtb3VudCBvZiB0b2tlbnMgdGhhdCBhcmUgc3Rha2VkIGZvciBhbGwgdGhlIG5vZGVzCiAgICAvLy8gb2YgZWFjaCBub2RlIHR5cGUgZHVyaW5nIHRoZSBjdXJyZW50IGVwb2NoCiAgICBhY2Nlc3MoYWNjb3VudCkgdmFyIHRvdGFsVG9rZW5zU3Rha2VkQnlOb2RlVHlwZToge1VJbnQ4OiBVRml4NjR9CgogICAgLy8vIFRoZSB0b3RhbCBhbW91bnQgb2YgdG9rZW5zIHRoYXQgd2lsbCBiZSBwYWlkIGFzIHJld2FyZHMgZHVyaW5ndCB0aGUgY3VycmVudCBlcG9jaAogICAgYWNjZXNzKGFjY291bnQpIHZhciBlcG9jaFRva2VuUGF5b3V0OiBVRml4NjQKCiAgICAvLy8gVGhlIHJhdGlvIG9mIHRoZSB3ZWVrbHkgYXdhcmRzIHRoYXQgZWFjaCBub2RlIHR5cGUgZ2V0cwogICAgLy8vIE5PVEU6IEN1cnJlbnRseSBpcyBub3QgdXNlZAogICAgYWNjZXNzKGNvbnRyYWN0KSB2YXIgcmV3YXJkUmF0aW9zOiB7VUludDg6IFVGaXg2NH0KCiAgICAvLy8gVGhlIHBlcmNlbnRhZ2Ugb2YgcmV3YXJkcyB0aGF0IGV2ZXJ5IG5vZGUgb3BlcmF0b3IgdGFrZXMgZnJvbQogICAgLy8vIHRoZSB1c2VycyB0aGF0IGFyZSBkZWxlZ2F0aW5nIHRvIGl0CiAgICBhY2Nlc3MoYWNjb3VudCkgdmFyIG5vZGVEZWxlZ2F0aW5nUmV3YXJkQ3V0OiBVRml4NjQKCiAgICAvLy8gUGF0aHMgZm9yIHN0b3Jpbmcgc3Rha2luZyByZXNvdXJjZXMKICAgIGFjY2VzcyhhbGwpIGxldCBOb2RlU3Rha2VyU3RvcmFnZVBhdGg6IFN0b3JhZ2VQYXRoCiAgICBhY2Nlc3MoYWxsKSBsZXQgTm9kZVN0YWtlclB1YmxpY1BhdGg6IFB1YmxpY1BhdGgKICAgIGFjY2VzcyhhbGwpIGxldCBTdGFraW5nQWRtaW5TdG9yYWdlUGF0aDogU3RvcmFnZVBhdGgKICAgIGFjY2VzcyhhbGwpIGxldCBEZWxlZ2F0b3JTdG9yYWdlUGF0aDogU3RvcmFnZVBhdGgKCiAgICAvKioqKioqKioqKiogSUQgVGFibGUgYW5kIFN0YWtpbmcgQ29tcG9zaXRlIFR5cGUgRGVmaW5pdGlvbnMgKioqKioqKioqKioqKi8KCiAgICAvLy8gQ29udGFpbnMgaW5mb3JtYXRpb24gdGhhdCBpcyBzcGVjaWZpYyB0byBhIG5vZGUgaW4gRmxvdwogICAgYWNjZXNzKGFsbCkgcmVzb3VyY2UgTm9kZVJlY29yZCB7CgogICAgICAgIC8vLyBUaGUgdW5pcXVlIElEIG9mIHRoZSBub2RlCiAgICAgICAgLy8vIFNldCB3aGVuIHRoZSBub2RlIGlzIGNyZWF0ZWQKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgaWQ6IFN0cmluZwoKICAgICAgICAvLy8gVGhlIHR5cGUgb2Ygbm9kZQogICAgICAgIGFjY2VzcyhhbGwpIHZhciByb2xlOiBVSW50OAoKICAgICAgICBhY2Nlc3MoYWxsKSB2YXIgbmV0d29ya2luZ0FkZHJlc3M6IFN0cmluZwogICAgICAgIGFjY2VzcyhhbGwpIHZhciBuZXR3b3JraW5nS2V5OiBTdHJpbmcKICAgICAgICBhY2Nlc3MoYWxsKSB2YXIgc3Rha2luZ0tleTogU3RyaW5nCgogICAgICAgIC8vLyBUaGUgdG90YWwgdG9rZW5zIHRoYXQgb25seSB0aGlzIG5vZGUgY3VycmVudGx5IGhhcyBzdGFrZWQsIG5vdCBpbmNsdWRpbmcgZGVsZWdhdG9ycwogICAgICAgIC8vLyBUaGlzIHZhbHVlIG11c3QgYWx3YXlzIGJlIGFib3ZlIHRoZSBtaW5pbXVtIHJlcXVpcmVtZW50IHRvIHN0YXkgc3Rha2VkIG9yIGFjY2VwdCBkZWxlZ2F0b3JzCiAgICAgICAgYWNjZXNzKG1hcHBpbmcgSWRlbnRpdHkpIHZhciB0b2tlbnNTdGFrZWQ6IEBGbG93VG9rZW4uVmF1bHQKCiAgICAgICAgLy8vIFRoZSB0b2tlbnMgdGhhdCB0aGlzIG5vZGUgaGFzIGNvbW1pdHRlZCB0byBzdGFrZSBmb3IgdGhlIG5leHQgZXBvY2guCiAgICAgICAgLy8vIE1vdmVzIHRvIHRoZSB0b2tlbnNTdGFrZWQgYnVja2V0IGF0IHRoZSBlbmQgb2YgYW4gZXBvY2gKICAgICAgICBhY2Nlc3MobWFwcGluZyBJZGVudGl0eSkgdmFyIHRva2Vuc0NvbW1pdHRlZDogQEZsb3dUb2tlbi5WYXVsdAoKICAgICAgICAvLy8gVGhlIHRva2VucyB0aGF0IHRoaXMgbm9kZSBoYXMgdW5zdGFrZWQgZnJvbSB0aGUgcHJldmlvdXMgZXBvY2gKICAgICAgICAvLy8gTW92ZXMgdG8gdGhlIHRva2Vuc1Vuc3Rha2VkIGJ1Y2tldCBhdCB0aGUgZW5kIG9mIGFuIGVwb2NoLgogICAgICAgIGFjY2VzcyhtYXBwaW5nIElkZW50aXR5KSB2YXIgdG9rZW5zVW5zdGFraW5nOiBARmxvd1Rva2VuLlZhdWx0CgogICAgICAgIC8vLyBUb2tlbnMgdGhhdCB0aGlzIG5vZGUgaGFzIHVuc3Rha2VkIGFuZCBhcmUgYWJsZSB0byB3aXRoZHJhdyB3aGVuZXZlciB0aGV5IHdhbnQKICAgICAgICBhY2Nlc3MobWFwcGluZyBJZGVudGl0eSkgdmFyIHRva2Vuc1Vuc3Rha2VkOiBARmxvd1Rva2VuLlZhdWx0CgogICAgICAgIC8vLyBTdGFraW5nIHJld2FyZHMgYXJlIHBhaWQgdG8gdGhpcyBidWNrZXQKICAgICAgICBhY2Nlc3MobWFwcGluZyBJZGVudGl0eSkgdmFyIHRva2Vuc1Jld2FyZGVkOiBARmxvd1Rva2VuLlZhdWx0CgogICAgICAgIC8vLyBMaXN0IG9mIGRlbGVnYXRvcnMgZm9yIHRoaXMgbm9kZSBvcGVyYXRvcgogICAgICAgIGFjY2VzcyhhbGwpIGxldCBkZWxlZ2F0b3JzOiBAe1VJbnQzMjogRGVsZWdhdG9yUmVjb3JkfQoKICAgICAgICAvLy8gVGhlIGluY3JlbWVudGluZyBJRCB1c2VkIHRvIHJlZ2lzdGVyIG5ldyBkZWxlZ2F0b3JzLgogICAgICAgIC8vLyBOT1RFOiBkZWxlZ2F0b3JJRHMgYXJlIHNjb3BlZCBwZXIgbm9kZSDigJQgdGhlIHVuaXF1ZSBpZGVudGlmaWVyIGZvciBhIGRlbGVnYXRvciBpcwogICAgICAgIC8vLyB0aGUgcGFpciAobm9kZUlELCBkZWxlZ2F0b3JJRCksIG5vdCBkZWxlZ2F0b3JJRCBhbG9uZS4gVHdvIGRlbGVnYXRvcnMgYXQgZGlmZmVyZW50CiAgICAgICAgLy8vIG5vZGVzIG1heSBzaGFyZSB0aGUgc2FtZSBkZWxlZ2F0b3JJRCB3aXRob3V0IGFueSBjb2xsaXNpb24gb3IgY29uZmxpY3QuCiAgICAgICAgYWNjZXNzKGFsbCkgdmFyIGRlbGVnYXRvcklEQ291bnRlcjogVUludDMyCgogICAgICAgIC8vLyBUaGUgYW1vdW50IG9mIHRva2VucyB0aGF0IHRoaXMgbm9kZSBoYXMgcmVxdWVzdGVkIHRvIHVuc3Rha2UgZm9yIHRoZSBuZXh0IGVwb2NoCiAgICAgICAgYWNjZXNzKGFsbCkgdmFyIHRva2Vuc1JlcXVlc3RlZFRvVW5zdGFrZTogVUZpeDY0CgogICAgICAgIC8vLyBXZWlnaHQgYXMgZGV0ZXJtaW5lZCBieSB0aGUgYW1vdW50IHN0YWtlZCBhZnRlciB0aGUgc3Rha2luZyBhdWN0aW9uIChjdXJyZW50bHkgYWx3YXlzIDEwMCkKICAgICAgICBhY2Nlc3MoYWxsKSB2YXIgaW5pdGlhbFdlaWdodDogVUludDY0CgogICAgICAgIGluaXQoCiAgICAgICAgICAgIGlkOiBTdHJpbmcsCiAgICAgICAgICAgIHJvbGU6IFVJbnQ4LAogICAgICAgICAgICBuZXR3b3JraW5nQWRkcmVzczogU3RyaW5nLAogICAgICAgICAgICBuZXR3b3JraW5nS2V5OiBTdHJpbmcsCiAgICAgICAgICAgIHN0YWtpbmdLZXk6IFN0cmluZywKICAgICAgICAgICAgc3Rha2luZ0tleVBvUDogU3RyaW5nLAogICAgICAgICAgICB0b2tlbnNDb21taXR0ZWQ6IEB7RnVuZ2libGVUb2tlbi5WYXVsdH0KICAgICAgICApIHsKICAgICAgICAgICAgcHJlIHsKICAgICAgICAgICAgICAgIGlkLmxlbmd0aCA9PSA2NDogIkZsb3dJRFRhYmxlU3Rha2luZy5Ob2RlUmVjb3JkLmluaXQ6IE5vZGUgSUQgbGVuZ3RoIG11c3QgYmUgMzIgYnl0ZXMgKDY0IGhleCBjaGFyYWN0ZXJzKSBidXQgZ290IFwoaWQubGVuZ3RoKSIKICAgICAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy5pc1ZhbGlkTm9kZUlEKGlkKTogIkZsb3dJRFRhYmxlU3Rha2luZy5Ob2RlUmVjb3JkLmluaXQ6IFRoZSBub2RlIElEIG11c3QgaGF2ZSBvbmx5IG51bWJlcnMgYW5kIGxvd2VyY2FzZSBoZXggY2hhcmFjdGVycyBidXQgZ290IFwoaWQpIgogICAgICAgICAgICAgICAgRmxvd0lEVGFibGVTdGFraW5nLm5vZGVzW2lkXSA9PSBuaWw6ICJGbG93SURUYWJsZVN0YWtpbmcuTm9kZVJlY29yZC5pbml0OiBUaGUgbm9kZSBJRCBcKGlkKSBhbHJlYWR5IGV4aXN0cyBpbiB0aGUgaWRlbnRpdHkgdGFibGUgYW5kIGNhbm5vdCBiZSB1c2VkIGFnYWluIgogICAgICAgICAgICAgICAgcm9sZSA+PSBVSW50OCgxKSAmJiByb2xlIDw9IFVJbnQ4KDUpOiAiRmxvd0lEVGFibGVTdGFraW5nLk5vZGVSZWNvcmQuaW5pdDogVGhlIHJvbGUgbXVzdCBiZSAxLCAyLCAzLCA0LCBvciA1IGJ1dCBnb3QgXChyb2xlKSIKICAgICAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy5pc1ZhbGlkTmV0d29ya2luZ0FkZHJlc3MoYWRkcmVzczogbmV0d29ya2luZ0FkZHJlc3MpOiAiRmxvd0lEVGFibGVTdGFraW5nLk5vZGVSZWNvcmQuaW5pdDogVGhlIG5ldHdvcmtpbmdBZGRyZXNzIG11c3QgYmUgYSB2YWxpZCBkb21haW4gbmFtZSB3aXRoIGEgcG9ydCAoZS5nLiwgbm9kZS5mbG93LmNvbTozNTY5KSwgbXVzdCBub3QgZXhjZWVkIDUxMCBjaGFyYWN0ZXJzLCBhbmQgY2Fubm90IGJlIGFuIElQIGFkZHJlc3MsIGJ1dCBnb3QgXChuZXR3b3JraW5nQWRkcmVzcykiCiAgICAgICAgICAgICAgICBuZXR3b3JraW5nS2V5Lmxlbmd0aCA9PSAxMjg6ICJGbG93SURUYWJsZVN0YWtpbmcuTm9kZVJlY29yZC5pbml0OiBUaGUgbmV0d29ya2luZ0tleSBsZW5ndGggbXVzdCBiZSBleGFjdGx5IDY0IGJ5dGVzICgxMjggaGV4IGNoYXJhY3RlcnMpIGJ1dCBnb3QgXChuZXR3b3JraW5nS2V5Lmxlbmd0aCkiCiAgICAgICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcuaXNMb3dlcmNhc2VIZXgobmV0d29ya2luZ0tleSk6ICJGbG93SURUYWJsZVN0YWtpbmcuTm9kZVJlY29yZC5pbml0OiBUaGUgbmV0d29ya2luZ0tleSBtdXN0IGNvbnRhaW4gb25seSBsb3dlcmNhc2UgaGV4IGNoYXJhY3RlcnMgKDAtOSwgYS1mKSIKICAgICAgICAgICAgICAgIHN0YWtpbmdLZXkubGVuZ3RoID09IDE5MjogIkZsb3dJRFRhYmxlU3Rha2luZy5Ob2RlUmVjb3JkLmluaXQ6IFRoZSBzdGFraW5nS2V5IGxlbmd0aCBtdXN0IGJlIGV4YWN0bHkgOTYgYnl0ZXMgKDE5MiBoZXggY2hhcmFjdGVycykgYnV0IGdvdCBcKHN0YWtpbmdLZXkubGVuZ3RoKSIKICAgICAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy5pc0xvd2VyY2FzZUhleChzdGFraW5nS2V5KTogIkZsb3dJRFRhYmxlU3Rha2luZy5Ob2RlUmVjb3JkLmluaXQ6IFRoZSBzdGFraW5nS2V5IG11c3QgY29udGFpbiBvbmx5IGxvd2VyY2FzZSBoZXggY2hhcmFjdGVycyAoMC05LCBhLWYpIgogICAgICAgICAgICAgICAgIUZsb3dJRFRhYmxlU3Rha2luZy5nZXROZXR3b3JraW5nQWRkcmVzc0NsYWltZWQoYWRkcmVzczogbmV0d29ya2luZ0FkZHJlc3MpOiAiRmxvd0lEVGFibGVTdGFraW5nLk5vZGVSZWNvcmQuaW5pdDogVGhlIG5ldHdvcmtpbmdBZGRyZXNzIFwobmV0d29ya2luZ0FkZHJlc3MpIGhhcyBhbHJlYWR5IGJlZW4gY2xhaW1lZCBieSBhbm90aGVyIG5vZGUgYW5kIGNhbm5vdCBiZSB1c2VkIGFnYWluIgogICAgICAgICAgICAgICAgIUZsb3dJRFRhYmxlU3Rha2luZy5nZXROZXR3b3JraW5nS2V5Q2xhaW1lZChrZXk6IG5ldHdvcmtpbmdLZXkpOiAiRmxvd0lEVGFibGVTdGFraW5nLk5vZGVSZWNvcmQuaW5pdDogVGhlIG5ldHdvcmtpbmdLZXkgXChuZXR3b3JraW5nS2V5KSBoYXMgYWxyZWFkeSBiZWVuIGNsYWltZWQgYnkgYW5vdGhlciBub2RlIGFuZCBjYW5ub3QgYmUgdXNlZCBhZ2FpbiIKICAgICAgICAgICAgICAgICFGbG93SURUYWJsZVN0YWtpbmcuZ2V0U3Rha2luZ0tleUNsYWltZWQoa2V5OiBzdGFraW5nS2V5KTogIkZsb3dJRFRhYmxlU3Rha2luZy5Ob2RlUmVjb3JkLmluaXQ6IFRoZSBzdGFraW5nS2V5IFwoc3Rha2luZ0tleSkgaGFzIGFscmVhZHkgYmVlbiBjbGFpbWVkIGJ5IGFub3RoZXIgbm9kZSBhbmQgY2Fubm90IGJlIHVzZWQgYWdhaW4iCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxldCBzdGFrZUtleSA9IFB1YmxpY0tleSgKICAgICAgICAgICAgICAgIHB1YmxpY0tleTogc3Rha2luZ0tleS5kZWNvZGVIZXgoKSwKICAgICAgICAgICAgICAgIHNpZ25hdHVyZUFsZ29yaXRobTogU2lnbmF0dXJlQWxnb3JpdGhtLkJMU19CTFMxMl8zODEKICAgICAgICAgICAgKQoKICAgICAgICAgICAgLy8gVmVyaWZ5IHRoZSBwcm9vZiBvZiBwb3NzZXNpb24gb2YgdGhlIHByaXZhdGUgc3Rha2luZyBrZXkKICAgICAgICAgICAgYXNzZXJ0KAogICAgICAgICAgICAgICAgc3Rha2VLZXkudmVyaWZ5UG9QKHN0YWtpbmdLZXlQb1AuZGVjb2RlSGV4KCkpLAogICAgICAgICAgICAgICAgbWVzc2FnZTogCiAgICAgICAgICAgICAgICAgICAgIkZsb3dJRFRhYmxlU3Rha2luZy5Ob2RlUmVjb3JkLmluaXQ6IENhbm5vdCBjcmVhdGUgbm9kZSB3aXRoIElEIFwoaWQpLiBUaGUgUHJvb2Ygb2YgUG9zc2Vzc2lvbiAoXChzdGFraW5nS2V5UG9QKSkgZm9yIHRoZSBub2RlJ3Mgc3Rha2luZyBrZXkgKFwoc3Rha2luZ0tleSkpIGlzIGludmFsaWQiCiAgICAgICAgICAgICkKCiAgICAgICAgICAgIGxldCBuZXRLZXkgPSBQdWJsaWNLZXkoCiAgICAgICAgICAgICAgICBwdWJsaWNLZXk6IG5ldHdvcmtpbmdLZXkuZGVjb2RlSGV4KCksCiAgICAgICAgICAgICAgICBzaWduYXR1cmVBbGdvcml0aG06IFNpZ25hdHVyZUFsZ29yaXRobS5FQ0RTQV9QMjU2CiAgICAgICAgICAgICkKCiAgICAgICAgICAgIHNlbGYuaWQgPSBpZAogICAgICAgICAgICBzZWxmLnJvbGUgPSByb2xlCiAgICAgICAgICAgIHNlbGYubmV0d29ya2luZ0FkZHJlc3MgPSBuZXR3b3JraW5nQWRkcmVzcwogICAgICAgICAgICBzZWxmLm5ldHdvcmtpbmdLZXkgPSBuZXR3b3JraW5nS2V5CiAgICAgICAgICAgIHNlbGYuc3Rha2luZ0tleSA9IHN0YWtpbmdLZXkKICAgICAgICAgICAgc2VsZi5pbml0aWFsV2VpZ2h0ID0gMAogICAgICAgICAgICBzZWxmLmRlbGVnYXRvcnMgPC0ge30KICAgICAgICAgICAgc2VsZi5kZWxlZ2F0b3JJRENvdW50ZXIgPSAwCgogICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcudXBkYXRlQ2xhaW1lZChwYXRoOiAvc3RvcmFnZS9uZXR3b3JraW5nQWRkcmVzc2VzQ2xhaW1lZCwgbmV0d29ya2luZ0FkZHJlc3MsIGNsYWltZWQ6IHRydWUpCiAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy51cGRhdGVDbGFpbWVkKHBhdGg6IC9zdG9yYWdlL25ldHdvcmtpbmdLZXlzQ2xhaW1lZCwgbmV0d29ya2luZ0tleSwgY2xhaW1lZDogdHJ1ZSkKICAgICAgICAgICAgRmxvd0lEVGFibGVTdGFraW5nLnVwZGF0ZUNsYWltZWQocGF0aDogL3N0b3JhZ2Uvc3Rha2luZ0tleXNDbGFpbWVkLCBzdGFraW5nS2V5LCBjbGFpbWVkOiB0cnVlKQoKICAgICAgICAgICAgc2VsZi50b2tlbnNDb21taXR0ZWQgPC0gdG9rZW5zQ29tbWl0dGVkIGFzISBARmxvd1Rva2VuLlZhdWx0CiAgICAgICAgICAgIHNlbGYudG9rZW5zU3Rha2VkIDwtIEZsb3dUb2tlbi5jcmVhdGVFbXB0eVZhdWx0KHZhdWx0VHlwZTogVHlwZTxARmxvd1Rva2VuLlZhdWx0PigpKSBhcyEgQEZsb3dUb2tlbi5WYXVsdAogICAgICAgICAgICBzZWxmLnRva2Vuc1Vuc3Rha2luZyA8LSBGbG93VG9rZW4uY3JlYXRlRW1wdHlWYXVsdCh2YXVsdFR5cGU6IFR5cGU8QEZsb3dUb2tlbi5WYXVsdD4oKSkgYXMhIEBGbG93VG9rZW4uVmF1bHQKICAgICAgICAgICAgc2VsZi50b2tlbnNVbnN0YWtlZCA8LSBGbG93VG9rZW4uY3JlYXRlRW1wdHlWYXVsdCh2YXVsdFR5cGU6IFR5cGU8QEZsb3dUb2tlbi5WYXVsdD4oKSkgYXMhIEBGbG93VG9rZW4uVmF1bHQKICAgICAgICAgICAgc2VsZi50b2tlbnNSZXdhcmRlZCA8LSBGbG93VG9rZW4uY3JlYXRlRW1wdHlWYXVsdCh2YXVsdFR5cGU6IFR5cGU8QEZsb3dUb2tlbi5WYXVsdD4oKSkgYXMhIEBGbG93VG9rZW4uVmF1bHQKICAgICAgICAgICAgc2VsZi50b2tlbnNSZXF1ZXN0ZWRUb1Vuc3Rha2UgPSAwLjAKCiAgICAgICAgICAgIGVtaXQgTmV3Tm9kZUNyZWF0ZWQobm9kZUlEOiBzZWxmLmlkLCByb2xlOiBzZWxmLnJvbGUsIGFtb3VudENvbW1pdHRlZDogc2VsZi50b2tlbnNDb21taXR0ZWQuYmFsYW5jZSkKICAgICAgICB9CgogICAgICAgIC8vLyBVdGlsaXR5IEZ1bmN0aW9uIHRoYXQgY2hlY2tzIGEgbm9kZSdzIG92ZXJhbGwgY29tbWl0dGVkIGJhbGFuY2UgZnJvbSBpdHMgYm9ycm93ZWQgcmVjb3JkCiAgICAgICAgYWNjZXNzKGFjY291bnQpIHZpZXcgZnVuIG5vZGVGdWxsQ29tbWl0dGVkQmFsYW5jZSgpOiBVRml4NjQgewogICAgICAgICAgICBpZiAoc2VsZi50b2tlbnNDb21taXR0ZWQuYmFsYW5jZSArIHNlbGYudG9rZW5zU3Rha2VkLmJhbGFuY2UpIDwgc2VsZi50b2tlbnNSZXF1ZXN0ZWRUb1Vuc3Rha2UgewogICAgICAgICAgICAgICAgcmV0dXJuIDAuMAogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYudG9rZW5zQ29tbWl0dGVkLmJhbGFuY2UgKyBzZWxmLnRva2Vuc1N0YWtlZC5iYWxhbmNlIC0gc2VsZi50b2tlbnNSZXF1ZXN0ZWRUb1Vuc3Rha2UKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8vIGJvcnJvdyBhIHJlZmVyZW5jZSB0byB0byBvbmUgb2YgdGhlIGRlbGVnYXRvcnMgZm9yIGEgbm9kZSBpbiB0aGUgcmVjb3JkCiAgICAgICAgYWNjZXNzKGFjY291bnQpIHZpZXcgZnVuIGJvcnJvd0RlbGVnYXRvclJlY29yZChfIGRlbGVnYXRvcklEOiBVSW50MzIpOiBhdXRoKEZ1bmdpYmxlVG9rZW4uV2l0aGRyYXcpICZEZWxlZ2F0b3JSZWNvcmQgewogICAgICAgICAgICBwcmUgewogICAgICAgICAgICAgICAgc2VsZi5kZWxlZ2F0b3JzW2RlbGVnYXRvcklEXSAhPSBuaWw6CiAgICAgICAgICAgICAgICAgICAgIkZsb3dJRFRhYmxlU3Rha2luZy5Ob2RlUmVjb3JkLmJvcnJvd0RlbGVnYXRvclJlY29yZDogU3BlY2lmaWVkIGRlbGVnYXRvciBJRCBcKGRlbGVnYXRvcklEKSBkb2VzIG5vdCBleGlzdCBpbiB0aGUgcmVjb3JkIgogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAoJnNlbGYuZGVsZWdhdG9yc1tkZWxlZ2F0b3JJRF0gYXMgYXV0aChGdW5naWJsZVRva2VuLldpdGhkcmF3KSAmRGVsZWdhdG9yUmVjb3JkPykhCiAgICAgICAgfQoKICAgICAgICAvLy8gQWRkIGEgZGVsZWdhdG9yIHRvIHRoZSBub2RlIHJlY29yZAogICAgICAgIGFjY2VzcyhhY2NvdW50KSBmdW4gc2V0RGVsZWdhdG9yKGRlbGVnYXRvcklEOiBVSW50MzIsIGRlbGVnYXRvcjogQERlbGVnYXRvclJlY29yZCkgewogICAgICAgICAgICBzZWxmLmRlbGVnYXRvcnNbZGVsZWdhdG9ySURdIDwtISBkZWxlZ2F0b3IKICAgICAgICB9CgogICAgICAgIGFjY2VzcyhhY2NvdW50KSBmdW4gc2V0RGVsZWdhdG9ySURDb3VudGVyKF8gbmV3Q291bnRlcjogVUludDMyKSB7CiAgICAgICAgICAgIHNlbGYuZGVsZWdhdG9ySURDb3VudGVyID0gbmV3Q291bnRlcgogICAgICAgIH0KCiAgICAgICAgYWNjZXNzKGFjY291bnQpIGZ1biBzZXROZXR3b3JraW5nQWRkcmVzcyhfIG5ld0FkZHJlc3M6IFN0cmluZykgewogICAgICAgICAgICBzZWxmLm5ldHdvcmtpbmdBZGRyZXNzID0gbmV3QWRkcmVzcwogICAgICAgIH0KCiAgICAgICAgYWNjZXNzKGNvbnRyYWN0KSBmdW4gc2V0VG9rZW5zUmVxdWVzdGVkVG9VbnN0YWtlKF8gbmV3VW5zdGFrZVJlcXVlc3Q6IFVGaXg2NCkgewogICAgICAgICAgICBzZWxmLnRva2Vuc1JlcXVlc3RlZFRvVW5zdGFrZSA9IG5ld1Vuc3Rha2VSZXF1ZXN0CiAgICAgICAgfQoKICAgICAgICBhY2Nlc3MoY29udHJhY3QpIGZ1biBzZXRXZWlnaHQoXyBuZXdXZWlnaHQ6IFVJbnQ2NCkgewogICAgICAgICAgICBzZWxmLmluaXRpYWxXZWlnaHQgPSBuZXdXZWlnaHQKICAgICAgICB9CiAgICB9CgogICAgLy8vIFN0cnVjdCB0byBjcmVhdGUgdG8gZ2V0IHJlYWQtb25seSBpbmZvIGFib3V0IGEgbm9kZQogICAgYWNjZXNzKGFsbCkgc3RydWN0IE5vZGVJbmZvIHsKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgaWQ6IFN0cmluZwogICAgICAgIGFjY2VzcyhhbGwpIGxldCByb2xlOiBVSW50OAogICAgICAgIGFjY2VzcyhhbGwpIGxldCBuZXR3b3JraW5nQWRkcmVzczogU3RyaW5nCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IG5ldHdvcmtpbmdLZXk6IFN0cmluZwogICAgICAgIGFjY2VzcyhhbGwpIGxldCBzdGFraW5nS2V5OiBTdHJpbmcKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgdG9rZW5zU3Rha2VkOiBVRml4NjQKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgdG9rZW5zQ29tbWl0dGVkOiBVRml4NjQKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgdG9rZW5zVW5zdGFraW5nOiBVRml4NjQKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgdG9rZW5zVW5zdGFrZWQ6IFVGaXg2NAogICAgICAgIGFjY2VzcyhhbGwpIGxldCB0b2tlbnNSZXdhcmRlZDogVUZpeDY0CgogICAgICAgIC8vLyBsaXN0IG9mIGRlbGVnYXRvciBJRHMgZm9yIHRoaXMgbm9kZSBvcGVyYXRvcgogICAgICAgIGFjY2VzcyhhbGwpIGxldCBkZWxlZ2F0b3JzOiAmW1VJbnQzMl0KICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgZGVsZWdhdG9ySURDb3VudGVyOiBVSW50MzIKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgdG9rZW5zUmVxdWVzdGVkVG9VbnN0YWtlOiBVRml4NjQKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgaW5pdGlhbFdlaWdodDogVUludDY0CgogICAgICAgIHZpZXcgaW5pdChub2RlSUQ6IFN0cmluZykgewogICAgICAgICAgICBsZXQgbm9kZVJlY29yZCA9IEZsb3dJRFRhYmxlU3Rha2luZy5ib3Jyb3dOb2RlUmVjb3JkKG5vZGVJRCkKCiAgICAgICAgICAgIHNlbGYuaWQgPSBub2RlUmVjb3JkLmlkCiAgICAgICAgICAgIHNlbGYucm9sZSA9IG5vZGVSZWNvcmQucm9sZQogICAgICAgICAgICBzZWxmLm5ldHdvcmtpbmdBZGRyZXNzID0gbm9kZVJlY29yZC5uZXR3b3JraW5nQWRkcmVzcwogICAgICAgICAgICBzZWxmLm5ldHdvcmtpbmdLZXkgPSBub2RlUmVjb3JkLm5ldHdvcmtpbmdLZXkKICAgICAgICAgICAgc2VsZi5zdGFraW5nS2V5ID0gbm9kZVJlY29yZC5zdGFraW5nS2V5CiAgICAgICAgICAgIHNlbGYudG9rZW5zU3Rha2VkID0gbm9kZVJlY29yZC50b2tlbnNTdGFrZWQuYmFsYW5jZQogICAgICAgICAgICBzZWxmLnRva2Vuc0NvbW1pdHRlZCA9IG5vZGVSZWNvcmQudG9rZW5zQ29tbWl0dGVkLmJhbGFuY2UKICAgICAgICAgICAgc2VsZi50b2tlbnNVbnN0YWtpbmcgPSBub2RlUmVjb3JkLnRva2Vuc1Vuc3Rha2luZy5iYWxhbmNlCiAgICAgICAgICAgIHNlbGYudG9rZW5zVW5zdGFrZWQgPSBub2RlUmVjb3JkLnRva2Vuc1Vuc3Rha2VkLmJhbGFuY2UKICAgICAgICAgICAgc2VsZi50b2tlbnNSZXdhcmRlZCA9IG5vZGVSZWNvcmQudG9rZW5zUmV3YXJkZWQuYmFsYW5jZQogICAgICAgICAgICBzZWxmLmRlbGVnYXRvcnMgPSBub2RlUmVjb3JkLmRlbGVnYXRvcnMua2V5cwogICAgICAgICAgICBzZWxmLmRlbGVnYXRvcklEQ291bnRlciA9IG5vZGVSZWNvcmQuZGVsZWdhdG9ySURDb3VudGVyCiAgICAgICAgICAgIHNlbGYudG9rZW5zUmVxdWVzdGVkVG9VbnN0YWtlID0gbm9kZVJlY29yZC50b2tlbnNSZXF1ZXN0ZWRUb1Vuc3Rha2UKICAgICAgICAgICAgc2VsZi5pbml0aWFsV2VpZ2h0ID0gbm9kZVJlY29yZC5pbml0aWFsV2VpZ2h0CiAgICAgICAgfQoKICAgICAgICAvLy8gRGVyaXZlZCBGaWVsZHMKICAgICAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biB0b3RhbENvbW1pdHRlZFdpdGhEZWxlZ2F0b3JzKCk6IFVGaXg2NCB7CiAgICAgICAgICAgIGxldCBub2RlUmVjb3JkID0gRmxvd0lEVGFibGVTdGFraW5nLmJvcnJvd05vZGVSZWNvcmQoc2VsZi5pZCkKICAgICAgICAgICAgdmFyIGNvbW1pdHRlZFN1bSA9IHNlbGYudG90YWxDb21taXR0ZWRXaXRob3V0RGVsZWdhdG9ycygpCgogICAgICAgICAgICB2YXIgaW5kZXggPSAwCiAgICAgICAgICAgIHdoaWxlIGluZGV4IDwgc2VsZi5kZWxlZ2F0b3JzLmxlbmd0aCB7CiAgICAgICAgICAgICAgICBsZXQgZGVsZWdhdG9yID0gc2VsZi5kZWxlZ2F0b3JzW2luZGV4XQogICAgICAgICAgICAgICAgaW5kZXggPSBpbmRleCArIDEKICAgICAgICAgICAgICAgIGxldCBkZWxSZWNvcmQgPSBub2RlUmVjb3JkLmJvcnJvd0RlbGVnYXRvclJlY29yZChkZWxlZ2F0b3IpCiAgICAgICAgICAgICAgICBjb21taXR0ZWRTdW0gPSBjb21taXR0ZWRTdW0gKyBkZWxSZWNvcmQuZGVsZWdhdG9yRnVsbENvbW1pdHRlZEJhbGFuY2UoKQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBjb21taXR0ZWRTdW0KICAgICAgICB9CgogICAgICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIHRvdGFsQ29tbWl0dGVkV2l0aG91dERlbGVnYXRvcnMoKTogVUZpeDY0IHsKICAgICAgICAgICAgbGV0IG5vZGVSZWNvcmQgPSBGbG93SURUYWJsZVN0YWtpbmcuYm9ycm93Tm9kZVJlY29yZChzZWxmLmlkKQogICAgICAgICAgICByZXR1cm4gbm9kZVJlY29yZC5ub2RlRnVsbENvbW1pdHRlZEJhbGFuY2UoKQogICAgICAgIH0KCiAgICAgICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gdG90YWxTdGFrZWRXaXRoRGVsZWdhdG9ycygpOiBVRml4NjQgewogICAgICAgICAgICBsZXQgbm9kZVJlY29yZCA9IEZsb3dJRFRhYmxlU3Rha2luZy5ib3Jyb3dOb2RlUmVjb3JkKHNlbGYuaWQpCiAgICAgICAgICAgIHZhciBzdGFrZWRTdW0gPSBzZWxmLnRva2Vuc1N0YWtlZAoKICAgICAgICAgICAgdmFyIGluZGV4ID0gMAogICAgICAgICAgICB3aGlsZSBpbmRleCA8IHNlbGYuZGVsZWdhdG9ycy5sZW5ndGggewogICAgICAgICAgICAgICAgbGV0IGRlbGVnYXRvciA9IHNlbGYuZGVsZWdhdG9yc1tpbmRleF0KICAgICAgICAgICAgICAgIGluZGV4ID0gaW5kZXggKyAxCiAgICAgICAgICAgICAgICBsZXQgZGVsUmVjb3JkID0gbm9kZVJlY29yZC5ib3Jyb3dEZWxlZ2F0b3JSZWNvcmQoZGVsZWdhdG9yKQogICAgICAgICAgICAgICAgc3Rha2VkU3VtID0gc3Rha2VkU3VtICsgZGVsUmVjb3JkLnRva2Vuc1N0YWtlZC5iYWxhbmNlCiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHN0YWtlZFN1bQogICAgICAgIH0KCiAgICAgICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gdG90YWxUb2tlbnNJblJlY29yZCgpOiBVRml4NjQgewogICAgICAgICAgICByZXR1cm4gc2VsZi50b2tlbnNTdGFrZWQgKyBzZWxmLnRva2Vuc0NvbW1pdHRlZCArIHNlbGYudG9rZW5zVW5zdGFraW5nICsgc2VsZi50b2tlbnNVbnN0YWtlZCArIHNlbGYudG9rZW5zUmV3YXJkZWQKICAgICAgICB9CiAgICB9CgogICAgLy8vIFJlY29yZHMgdGhlIHN0YWtpbmcgaW5mbyBhc3NvY2lhdGVkIHdpdGggYSBkZWxlZ2F0b3IKICAgIC8vLyBUaGlzIHJlc291cmNlIGlzIHN0b3JlZCBpbiB0aGUgTm9kZVJlY29yZCBvYmplY3QgdGhhdCBpcyBiZWluZyBkZWxlZ2F0ZWQgdG8KICAgIGFjY2VzcyhhbGwpIHJlc291cmNlIERlbGVnYXRvclJlY29yZCB7CiAgICAgICAgLy8vIFRva2VucyB0aGlzIGRlbGVnYXRvciBoYXMgY29tbWl0dGVkIGZvciB0aGUgbmV4dCBlcG9jaAogICAgICAgIGFjY2VzcyhtYXBwaW5nIElkZW50aXR5KSB2YXIgdG9rZW5zQ29tbWl0dGVkOiBARmxvd1Rva2VuLlZhdWx0CgogICAgICAgIC8vLyBUb2tlbnMgdGhpcyBkZWxlZ2F0b3IgaGFzIHN0YWtlZCBmb3IgdGhlIGN1cnJlbnQgZXBvY2gKICAgICAgICBhY2Nlc3MobWFwcGluZyBJZGVudGl0eSkgdmFyIHRva2Vuc1N0YWtlZDogQEZsb3dUb2tlbi5WYXVsdAoKICAgICAgICAvLy8gVG9rZW5zIHRoaXMgZGVsZWdhdG9yIGhhcyByZXF1ZXN0ZWQgdG8gdW5zdGFrZSBhbmQgaXMgbG9ja2VkIGZvciB0aGUgY3VycmVudCBlcG9jaAogICAgICAgIGFjY2VzcyhtYXBwaW5nIElkZW50aXR5KSB2YXIgdG9rZW5zVW5zdGFraW5nOiBARmxvd1Rva2VuLlZhdWx0CgogICAgICAgIC8vLyBUb2tlbnMgdGhpcyBkZWxlZ2F0b3IgaGFzIGJlZW4gcmV3YXJkZWQgYW5kIGNhbiB3aXRoZHJhdwogICAgICAgIGFjY2VzcyhtYXBwaW5nIElkZW50aXR5KSBsZXQgdG9rZW5zUmV3YXJkZWQ6IEBGbG93VG9rZW4uVmF1bHQKCiAgICAgICAgLy8vIFRva2VucyB0aGF0IHRoaXMgZGVsZWdhdG9yIHVuc3Rha2VkIGFuZCBjYW4gd2l0aGRyYXcKICAgICAgICBhY2Nlc3MobWFwcGluZyBJZGVudGl0eSkgbGV0IHRva2Vuc1Vuc3Rha2VkOiBARmxvd1Rva2VuLlZhdWx0CgogICAgICAgIC8vLyBBbW91bnQgb2YgdG9rZW5zIHRoYXQgdGhlIGRlbGVnYXRvciBoYXMgcmVxdWVzdGVkIHRvIHVuc3Rha2UKICAgICAgICBhY2Nlc3MoYWxsKSB2YXIgdG9rZW5zUmVxdWVzdGVkVG9VbnN0YWtlOiBVRml4NjQKCiAgICAgICAgaW5pdCgpIHsKICAgICAgICAgICAgc2VsZi50b2tlbnNDb21taXR0ZWQgPC0gRmxvd1Rva2VuLmNyZWF0ZUVtcHR5VmF1bHQodmF1bHRUeXBlOiBUeXBlPEBGbG93VG9rZW4uVmF1bHQ+KCkpIGFzISBARmxvd1Rva2VuLlZhdWx0CiAgICAgICAgICAgIHNlbGYudG9rZW5zU3Rha2VkIDwtIEZsb3dUb2tlbi5jcmVhdGVFbXB0eVZhdWx0KHZhdWx0VHlwZTogVHlwZTxARmxvd1Rva2VuLlZhdWx0PigpKSBhcyEgQEZsb3dUb2tlbi5WYXVsdAogICAgICAgICAgICBzZWxmLnRva2Vuc1Vuc3Rha2luZyA8LSBGbG93VG9rZW4uY3JlYXRlRW1wdHlWYXVsdCh2YXVsdFR5cGU6IFR5cGU8QEZsb3dUb2tlbi5WYXVsdD4oKSkgYXMhIEBGbG93VG9rZW4uVmF1bHQKICAgICAgICAgICAgc2VsZi50b2tlbnNSZXdhcmRlZCA8LSBGbG93VG9rZW4uY3JlYXRlRW1wdHlWYXVsdCh2YXVsdFR5cGU6IFR5cGU8QEZsb3dUb2tlbi5WYXVsdD4oKSkgYXMhIEBGbG93VG9rZW4uVmF1bHQKICAgICAgICAgICAgc2VsZi50b2tlbnNVbnN0YWtlZCA8LSBGbG93VG9rZW4uY3JlYXRlRW1wdHlWYXVsdCh2YXVsdFR5cGU6IFR5cGU8QEZsb3dUb2tlbi5WYXVsdD4oKSkgYXMhIEBGbG93VG9rZW4uVmF1bHQKICAgICAgICAgICAgc2VsZi50b2tlbnNSZXF1ZXN0ZWRUb1Vuc3Rha2UgPSAwLjAKICAgICAgICB9CgogICAgICAgIC8vLyBVdGlsaXR5IEZ1bmN0aW9uIHRoYXQgY2hlY2tzIGEgZGVsZWdhdG9yJ3Mgb3ZlcmFsbCBjb21taXR0ZWQgYmFsYW5jZSBmcm9tIGl0cyBib3Jyb3dlZCByZWNvcmQKICAgICAgICBhY2Nlc3MoY29udHJhY3QpIHZpZXcgZnVuIGRlbGVnYXRvckZ1bGxDb21taXR0ZWRCYWxhbmNlKCk6IFVGaXg2NCB7CiAgICAgICAgICAgIGlmIChzZWxmLnRva2Vuc0NvbW1pdHRlZC5iYWxhbmNlICsgc2VsZi50b2tlbnNTdGFrZWQuYmFsYW5jZSkgPCBzZWxmLnRva2Vuc1JlcXVlc3RlZFRvVW5zdGFrZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gMC4wCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZi50b2tlbnNDb21taXR0ZWQuYmFsYW5jZSArIHNlbGYudG9rZW5zU3Rha2VkLmJhbGFuY2UgLSBzZWxmLnRva2Vuc1JlcXVlc3RlZFRvVW5zdGFrZQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBhY2Nlc3MoY29udHJhY3QpIGZ1biBzZXRUb2tlbnNSZXF1ZXN0ZWRUb1Vuc3Rha2UoXyBuZXdVbnN0YWtlUmVxdWVzdDogVUZpeDY0KSB7CiAgICAgICAgICAgIHNlbGYudG9rZW5zUmVxdWVzdGVkVG9VbnN0YWtlID0gbmV3VW5zdGFrZVJlcXVlc3QKICAgICAgICB9CiAgICB9CgogICAgLy8vIFN0cnVjdCB0aGF0IGNhbiBiZSByZXR1cm5lZCB0byBzaG93IGFsbCB0aGUgaW5mbyBhYm91dCBhIGRlbGVnYXRvcgogICAgYWNjZXNzKGFsbCkgc3RydWN0IERlbGVnYXRvckluZm8gewogICAgICAgIGFjY2VzcyhhbGwpIGxldCBpZDogVUludDMyCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IG5vZGVJRDogU3RyaW5nCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IHRva2Vuc0NvbW1pdHRlZDogVUZpeDY0CiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IHRva2Vuc1N0YWtlZDogVUZpeDY0CiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IHRva2Vuc1Vuc3Rha2luZzogVUZpeDY0CiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IHRva2Vuc1Jld2FyZGVkOiBVRml4NjQKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgdG9rZW5zVW5zdGFrZWQ6IFVGaXg2NAogICAgICAgIGFjY2VzcyhhbGwpIGxldCB0b2tlbnNSZXF1ZXN0ZWRUb1Vuc3Rha2U6IFVGaXg2NAoKICAgICAgICB2aWV3IGluaXQobm9kZUlEOiBTdHJpbmcsIGRlbGVnYXRvcklEOiBVSW50MzIpIHsKICAgICAgICAgICAgbGV0IG5vZGVSZWNvcmQgPSBGbG93SURUYWJsZVN0YWtpbmcuYm9ycm93Tm9kZVJlY29yZChub2RlSUQpCiAgICAgICAgICAgIGxldCBkZWxlZ2F0b3JSZWNvcmQgPSBub2RlUmVjb3JkLmJvcnJvd0RlbGVnYXRvclJlY29yZChkZWxlZ2F0b3JJRCkKICAgICAgICAgICAgc2VsZi5pZCA9IGRlbGVnYXRvcklECiAgICAgICAgICAgIHNlbGYubm9kZUlEID0gbm9kZUlECiAgICAgICAgICAgIHNlbGYudG9rZW5zQ29tbWl0dGVkID0gZGVsZWdhdG9yUmVjb3JkLnRva2Vuc0NvbW1pdHRlZC5iYWxhbmNlCiAgICAgICAgICAgIHNlbGYudG9rZW5zU3Rha2VkID0gZGVsZWdhdG9yUmVjb3JkLnRva2Vuc1N0YWtlZC5iYWxhbmNlCiAgICAgICAgICAgIHNlbGYudG9rZW5zVW5zdGFraW5nID0gZGVsZWdhdG9yUmVjb3JkLnRva2Vuc1Vuc3Rha2luZy5iYWxhbmNlCiAgICAgICAgICAgIHNlbGYudG9rZW5zVW5zdGFrZWQgPSBkZWxlZ2F0b3JSZWNvcmQudG9rZW5zVW5zdGFrZWQuYmFsYW5jZQogICAgICAgICAgICBzZWxmLnRva2Vuc1Jld2FyZGVkID0gZGVsZWdhdG9yUmVjb3JkLnRva2Vuc1Jld2FyZGVkLmJhbGFuY2UKICAgICAgICAgICAgc2VsZi50b2tlbnNSZXF1ZXN0ZWRUb1Vuc3Rha2UgPSBkZWxlZ2F0b3JSZWNvcmQudG9rZW5zUmVxdWVzdGVkVG9VbnN0YWtlCiAgICAgICAgfQoKICAgICAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biB0b3RhbFRva2Vuc0luUmVjb3JkKCk6IFVGaXg2NCB7CiAgICAgICAgICAgIHJldHVybiBzZWxmLnRva2Vuc1N0YWtlZCArIHNlbGYudG9rZW5zQ29tbWl0dGVkICsgc2VsZi50b2tlbnNVbnN0YWtpbmcgKyBzZWxmLnRva2Vuc1Vuc3Rha2VkICsgc2VsZi50b2tlbnNSZXdhcmRlZAogICAgICAgIH0KICAgIH0KCiAgICBhY2Nlc3MoYWxsKSByZXNvdXJjZSBpbnRlcmZhY2UgTm9kZVN0YWtlclB1YmxpYyB7CiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IGlkOiBTdHJpbmcKICAgIH0KCiAgICBhY2Nlc3MoYWxsKSBlbnRpdGxlbWVudCBOb2RlT3BlcmF0b3IKCiAgICAvLy8gUmVzb3VyY2UgdGhhdCB0aGUgbm9kZSBvcGVyYXRvciBjb250cm9scyBmb3Igc3Rha2luZwogICAgYWNjZXNzKGFsbCkgcmVzb3VyY2UgTm9kZVN0YWtlcjogTm9kZVN0YWtlclB1YmxpYyB7CgogICAgICAgIC8vLyBVbmlxdWUgSUQgZm9yIHRoZSBub2RlIG9wZXJhdG9yCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IGlkOiBTdHJpbmcKCiAgICAgICAgaW5pdChpZDogU3RyaW5nKSB7CiAgICAgICAgICAgIHNlbGYuaWQgPSBpZAogICAgICAgIH0KCiAgICAgICAgLy8vIFRlbGxzIHdoZXRoZXIgdGhlIG5vZGUgaXMgYSBuZXcgbm9kZSB3aG8gY3VycmVudGx5IGlzIG5vdCBwYXJ0aWNpcGF0aW5nIHdpdGggdG9rZW5zIHN0YWtlZAogICAgICAgIC8vLyBhbmQgaGFzIGVub3VnaCBjb21taXR0ZWQgZm9yIHRoZSBuZXh0IGVwb2NoIGZvciBpdHMgcm9sZQogICAgICAgIGFjY2VzcyhzZWxmKSB2aWV3IGZ1biBpc0VsaWdpYmxlRm9yQ2FuZGlkYXRlTm9kZVN0YXR1cyhfIG5vZGVSZWNvcmQ6ICZGbG93SURUYWJsZVN0YWtpbmcuTm9kZVJlY29yZCk6IEJvb2wgewogICAgICAgICAgICBsZXQgcGFydGljaXBhbnRMaXN0ID0gRmxvd0lEVGFibGVTdGFraW5nLmFjY291bnQuc3RvcmFnZS5ib3Jyb3c8JntTdHJpbmc6IEJvb2x9Pihmcm9tOiAvc3RvcmFnZS9pZFRhYmxlQ3VycmVudExpc3QpIQogICAgICAgICAgICBpZiBwYXJ0aWNpcGFudExpc3Rbbm9kZVJlY29yZC5pZF0gPT0gdHJ1ZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2UKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbm9kZVJlY29yZC50b2tlbnNTdGFrZWQuYmFsYW5jZSA9PSAwLjAgJiYKICAgICAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy5pc0dyZWF0ZXJUaGFuTWluaW11bUZvclJvbGUobnVtVG9rZW5zOiBub2RlUmVjb3JkLnRva2Vuc0NvbW1pdHRlZC5iYWxhbmNlLCByb2xlOiBub2RlUmVjb3JkLnJvbGUpCiAgICAgICAgfQoKICAgICAgICAvLy8gQ2hhbmdlIHRoZSBub2RlJ3MgbmV0d29ya2luZyBhZGRyZXNzIHRvIGEgbmV3IG9uZQogICAgICAgIGFjY2VzcyhOb2RlT3BlcmF0b3IpIGZ1biB1cGRhdGVOZXR3b3JraW5nQWRkcmVzcyhfIG5ld0FkZHJlc3M6IFN0cmluZykgewogICAgICAgICAgICBwcmUgewogICAgICAgICAgICAgICAgRmxvd0lEVGFibGVTdGFraW5nLnN0YWtpbmdFbmFibGVkKCk6ICJGbG93SURUYWJsZVN0YWtpbmcuTm9kZVN0YWtlci51cGRhdGVOZXR3b3JraW5nQWRkcmVzczogQ2Fubm90IHVwZGF0ZSBuZXR3b3JraW5nIGFkZHJlc3MgaWYgdGhlIHN0YWtpbmcgYXVjdGlvbiBpc24ndCBpbiBwcm9ncmVzcyIKICAgICAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy5pc1ZhbGlkTmV0d29ya2luZ0FkZHJlc3MoYWRkcmVzczogbmV3QWRkcmVzcyk6ICJGbG93SURUYWJsZVN0YWtpbmcuTm9kZVN0YWtlci51cGRhdGVOZXR3b3JraW5nQWRkcmVzczogVGhlIG5ldHdvcmtpbmdBZGRyZXNzIG11c3QgYmUgYSB2YWxpZCBkb21haW4gbmFtZSB3aXRoIGEgcG9ydCAoZS5nLiwgbm9kZS5mbG93LmNvbTozNTY5KSwgbXVzdCBub3QgZXhjZWVkIDUxMCBjaGFyYWN0ZXJzLCBhbmQgY2Fubm90IGJlIGFuIElQIGFkZHJlc3MiCiAgICAgICAgICAgICAgICAhRmxvd0lEVGFibGVTdGFraW5nLmdldE5ldHdvcmtpbmdBZGRyZXNzQ2xhaW1lZChhZGRyZXNzOiBuZXdBZGRyZXNzKTogIkZsb3dJRFRhYmxlU3Rha2luZy5Ob2RlU3Rha2VyLnVwZGF0ZU5ldHdvcmtpbmdBZGRyZXNzOiBUaGUgbmV0d29ya2luZ0FkZHJlc3MgY2Fubm90IGhhdmUgYWxyZWFkeSBiZWVuIGNsYWltZWQiCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEJvcnJvdyB0aGUgbm9kZSdzIHJlY29yZCBmcm9tIHRoZSBzdGFraW5nIGNvbnRyYWN0CiAgICAgICAgICAgIGxldCBub2RlUmVjb3JkID0gRmxvd0lEVGFibGVTdGFraW5nLmJvcnJvd05vZGVSZWNvcmQoc2VsZi5pZCkKCiAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy51cGRhdGVDbGFpbWVkKHBhdGg6IC9zdG9yYWdlL25ldHdvcmtpbmdBZGRyZXNzZXNDbGFpbWVkLCBub2RlUmVjb3JkLm5ldHdvcmtpbmdBZGRyZXNzLCBjbGFpbWVkOiBmYWxzZSkKCiAgICAgICAgICAgIG5vZGVSZWNvcmQuc2V0TmV0d29ya2luZ0FkZHJlc3MobmV3QWRkcmVzcykKCiAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy51cGRhdGVDbGFpbWVkKHBhdGg6IC9zdG9yYWdlL25ldHdvcmtpbmdBZGRyZXNzZXNDbGFpbWVkLCBuZXdBZGRyZXNzLCBjbGFpbWVkOiB0cnVlKQoKICAgICAgICAgICAgZW1pdCBOZXR3b3JraW5nQWRkcmVzc1VwZGF0ZWQobm9kZUlEOiBzZWxmLmlkLCBuZXdBZGRyZXNzOiBuZXdBZGRyZXNzKQogICAgICAgIH0KCiAgICAgICAgLy8vIEFkZCBuZXcgdG9rZW5zIHRvIHRoZSBzeXN0ZW0gdG8gc3Rha2UgZHVyaW5nIHRoZSBuZXh0IGVwb2NoCiAgICAgICAgYWNjZXNzKE5vZGVPcGVyYXRvcikgZnVuIHN0YWtlTmV3VG9rZW5zKF8gdG9rZW5zOiBAe0Z1bmdpYmxlVG9rZW4uVmF1bHR9KSB7CiAgICAgICAgICAgIHByZSB7CiAgICAgICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcuc3Rha2luZ0VuYWJsZWQoKTogIkZsb3dJRFRhYmxlU3Rha2luZy5Ob2RlU3Rha2VyLnN0YWtlTmV3VG9rZW5zOiBDYW5ub3Qgc3Rha2UgaWYgdGhlIHN0YWtpbmcgYXVjdGlvbiBpc24ndCBpbiBwcm9ncmVzcyIKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQm9ycm93IHRoZSBub2RlJ3MgcmVjb3JkIGZyb20gdGhlIHN0YWtpbmcgY29udHJhY3QKICAgICAgICAgICAgbGV0IG5vZGVSZWNvcmQgPSBGbG93SURUYWJsZVN0YWtpbmcuYm9ycm93Tm9kZVJlY29yZChzZWxmLmlkKQoKICAgICAgICAgICAgZW1pdCBUb2tlbnNDb21taXR0ZWQobm9kZUlEOiBub2RlUmVjb3JkLmlkLCBhbW91bnQ6IHRva2Vucy5iYWxhbmNlKQoKICAgICAgICAgICAgLy8gQWRkIHRoZSBuZXcgdG9rZW5zIHRvIHRva2VucyBjb21taXR0ZWQKICAgICAgICAgICAgbm9kZVJlY29yZC50b2tlbnNDb21taXR0ZWQuZGVwb3NpdChmcm9tOiA8LXRva2VucykKCiAgICAgICAgICAgIC8vIE9ubHkgYWRkIHRoZW0gYXMgYSBjYW5kaWRhdGUgbm9kZSBpZiB0aGV5IGRvbid0IGFscmVhZHkKICAgICAgICAgICAgLy8gaGF2ZSB0b2tlbnMgc3Rha2VkIGFuZCBhcmUgYWJvdmUgdGhlIG1pbmltdW0KICAgICAgICAgICAgaWYgc2VsZi5pc0VsaWdpYmxlRm9yQ2FuZGlkYXRlTm9kZVN0YXR1cyhub2RlUmVjb3JkKSB7CiAgICAgICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcuYWRkVG9DYW5kaWRhdGVOb2RlTGlzdChub2RlSUQ6IG5vZGVSZWNvcmQuaWQsIHJvbGVUb0FkZDogbm9kZVJlY29yZC5yb2xlKQogICAgICAgICAgICB9CgogICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcubW9kaWZ5TmV3TW92ZXNQZW5kaW5nKG5vZGVJRDogc2VsZi5pZCwgZGVsZWdhdG9ySUQ6IG5pbCwgZXhpc3RpbmdMaXN0OiBuaWwpCiAgICAgICAgfQoKICAgICAgICAvLy8gU3Rha2UgdG9rZW5zIHRoYXQgYXJlIGluIHRoZSB0b2tlbnNVbnN0YWtlZCBidWNrZXQKICAgICAgICBhY2Nlc3MoTm9kZU9wZXJhdG9yKSBmdW4gc3Rha2VVbnN0YWtlZFRva2VucyhhbW91bnQ6IFVGaXg2NCkgewogICAgICAgICAgICBwcmUgewogICAgICAgICAgICAgICAgRmxvd0lEVGFibGVTdGFraW5nLnN0YWtpbmdFbmFibGVkKCk6ICJGbG93SURUYWJsZVN0YWtpbmcuTm9kZVN0YWtlci5zdGFrZVVuc3Rha2VkVG9rZW5zOiBDYW5ub3Qgc3Rha2UgaWYgdGhlIHN0YWtpbmcgYXVjdGlvbiBpc24ndCBpbiBwcm9ncmVzcyIKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGV0IG5vZGVSZWNvcmQgPSBGbG93SURUYWJsZVN0YWtpbmcuYm9ycm93Tm9kZVJlY29yZChzZWxmLmlkKQoKICAgICAgICAgICAgdmFyIHJlbWFpbmluZ0Ftb3VudCA9IGFtb3VudAoKICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFueSB0b2tlbnMgdGhhdCBoYXZlIGJlZW4gcmVxdWVzdGVkIHRvIHVuc3Rha2UgZm9yIHRoZSBjdXJyZW50IGVwb2NoLAogICAgICAgICAgICAvLyBjYW5jZWwgdGhvc2UgZmlyc3QgYmVmb3JlIHN0YWtpbmcgbmV3IHVuc3Rha2VkIHRva2VucwogICAgICAgICAgICBpZiByZW1haW5pbmdBbW91bnQgPD0gbm9kZVJlY29yZC50b2tlbnNSZXF1ZXN0ZWRUb1Vuc3Rha2UgewogICAgICAgICAgICAgICAgbm9kZVJlY29yZC5zZXRUb2tlbnNSZXF1ZXN0ZWRUb1Vuc3Rha2Uobm9kZVJlY29yZC50b2tlbnNSZXF1ZXN0ZWRUb1Vuc3Rha2UgLSByZW1haW5pbmdBbW91bnQpCiAgICAgICAgICAgICAgICByZW1haW5pbmdBbW91bnQgPSAwLjAKICAgICAgICAgICAgfSBlbHNlIGlmIHJlbWFpbmluZ0Ftb3VudCA+IG5vZGVSZWNvcmQudG9rZW5zUmVxdWVzdGVkVG9VbnN0YWtlIHsKICAgICAgICAgICAgICAgIHJlbWFpbmluZ0Ftb3VudCA9IHJlbWFpbmluZ0Ftb3VudCAtIG5vZGVSZWNvcmQudG9rZW5zUmVxdWVzdGVkVG9VbnN0YWtlCiAgICAgICAgICAgICAgICBub2RlUmVjb3JkLnNldFRva2Vuc1JlcXVlc3RlZFRvVW5zdGFrZSgwLjApCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENvbW1pdCB0aGUgcmVtYWluaW5nIGFtb3VudCBmcm9tIHRoZSB0b2tlbnMgdW5zdGFrZWQgYnVja2V0CiAgICAgICAgICAgIG5vZGVSZWNvcmQudG9rZW5zQ29tbWl0dGVkLmRlcG9zaXQoZnJvbTogPC1ub2RlUmVjb3JkLnRva2Vuc1Vuc3Rha2VkLndpdGhkcmF3KGFtb3VudDogcmVtYWluaW5nQW1vdW50KSkKCiAgICAgICAgICAgIGVtaXQgVG9rZW5zQ29tbWl0dGVkKG5vZGVJRDogbm9kZVJlY29yZC5pZCwgYW1vdW50OiByZW1haW5pbmdBbW91bnQpCgogICAgICAgICAgICAvLyBPbmx5IGFkZCB0aGVtIGFzIGEgY2FuZGlkYXRlIG5vZGUgaWYgdGhleSBkb24ndCBhbHJlYWR5CiAgICAgICAgICAgIC8vIGhhdmUgdG9rZW5zIHN0YWtlZCBhbmQgYXJlIGFib3ZlIHRoZSBtaW5pbXVtCiAgICAgICAgICAgIGlmIHNlbGYuaXNFbGlnaWJsZUZvckNhbmRpZGF0ZU5vZGVTdGF0dXMobm9kZVJlY29yZCkgewogICAgICAgICAgICAgICAgRmxvd0lEVGFibGVTdGFraW5nLmFkZFRvQ2FuZGlkYXRlTm9kZUxpc3Qobm9kZUlEOiBub2RlUmVjb3JkLmlkLCByb2xlVG9BZGQ6IG5vZGVSZWNvcmQucm9sZSkKICAgICAgICAgICAgfQoKICAgICAgICAgICAgRmxvd0lEVGFibGVTdGFraW5nLm1vZGlmeU5ld01vdmVzUGVuZGluZyhub2RlSUQ6IHNlbGYuaWQsIGRlbGVnYXRvcklEOiBuaWwsIGV4aXN0aW5nTGlzdDogbmlsKQogICAgICAgIH0KCiAgICAgICAgLy8vIFN0YWtlIHRva2VucyB0aGF0IGFyZSBpbiB0aGUgdG9rZW5zUmV3YXJkZWQgYnVja2V0CiAgICAgICAgYWNjZXNzKE5vZGVPcGVyYXRvcikgZnVuIHN0YWtlUmV3YXJkZWRUb2tlbnMoYW1vdW50OiBVRml4NjQpIHsKICAgICAgICAgICAgcHJlIHsKICAgICAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy5zdGFraW5nRW5hYmxlZCgpOiAiRmxvd0lEVGFibGVTdGFraW5nLk5vZGVTdGFrZXIuc3Rha2VSZXdhcmRlZFRva2VuczogQ2Fubm90IHN0YWtlIGlmIHRoZSBzdGFraW5nIGF1Y3Rpb24gaXNuJ3QgaW4gcHJvZ3Jlc3MiCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxldCBub2RlUmVjb3JkID0gRmxvd0lEVGFibGVTdGFraW5nLmJvcnJvd05vZGVSZWNvcmQoc2VsZi5pZCkKCiAgICAgICAgICAgIG5vZGVSZWNvcmQudG9rZW5zQ29tbWl0dGVkLmRlcG9zaXQoZnJvbTogPC1ub2RlUmVjb3JkLnRva2Vuc1Jld2FyZGVkLndpdGhkcmF3KGFtb3VudDogYW1vdW50KSkKCiAgICAgICAgICAgIGVtaXQgVG9rZW5zQ29tbWl0dGVkKG5vZGVJRDogbm9kZVJlY29yZC5pZCwgYW1vdW50OiBhbW91bnQpCgogICAgICAgICAgICAvLyBPbmx5IGFkZCB0aGVtIGFzIGEgY2FuZGlkYXRlIG5vZGUgaWYgdGhleSBkb24ndCBhbHJlYWR5CiAgICAgICAgICAgIC8vIGhhdmUgdG9rZW5zIHN0YWtlZCBhbmQgYXJlIGFib3ZlIHRoZSBtaW5pbXVtCiAgICAgICAgICAgIGlmIHNlbGYuaXNFbGlnaWJsZUZvckNhbmRpZGF0ZU5vZGVTdGF0dXMobm9kZVJlY29yZCkgewogICAgICAgICAgICAgICAgRmxvd0lEVGFibGVTdGFraW5nLmFkZFRvQ2FuZGlkYXRlTm9kZUxpc3Qobm9kZUlEOiBub2RlUmVjb3JkLmlkLCByb2xlVG9BZGQ6IG5vZGVSZWNvcmQucm9sZSkKICAgICAgICAgICAgfQoKICAgICAgICAgICAgRmxvd0lEVGFibGVTdGFraW5nLm1vZGlmeU5ld01vdmVzUGVuZGluZyhub2RlSUQ6IHNlbGYuaWQsIGRlbGVnYXRvcklEOiBuaWwsIGV4aXN0aW5nTGlzdDogbmlsKQogICAgICAgIH0KCiAgICAgICAgLy8vIFJlcXVlc3QgYW1vdW50IHRva2VucyB0byBiZSByZW1vdmVkIGZyb20gc3Rha2luZyBhdCB0aGUgZW5kIG9mIHRoZSBuZXh0IGVwb2NoCiAgICAgICAgYWNjZXNzKE5vZGVPcGVyYXRvcikgZnVuIHJlcXVlc3RVbnN0YWtpbmcoYW1vdW50OiBVRml4NjQpIHsKICAgICAgICAgICAgcHJlIHsKICAgICAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy5zdGFraW5nRW5hYmxlZCgpOiAiRmxvd0lEVGFibGVTdGFraW5nLk5vZGVTdGFrZXIucmVxdWVzdFVuc3Rha2luZzogQ2Fubm90IHVuc3Rha2UgaWYgdGhlIHN0YWtpbmcgYXVjdGlvbiBpc24ndCBpbiBwcm9ncmVzcyIKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGV0IG5vZGVSZWNvcmQgPSBGbG93SURUYWJsZVN0YWtpbmcuYm9ycm93Tm9kZVJlY29yZChzZWxmLmlkKQoKICAgICAgICAgICAgLy8gSWYgdGhlIHJlcXVlc3QgaXMgZ3JlYXRlciB0aGFuIHRoZSB0b3RhbCBudW1iZXIgb2YgdG9rZW5zCiAgICAgICAgICAgIC8vIHRoYXQgY2FuIGJlIHVuc3Rha2VkLCByZXZlcnQKICAgICAgICAgICAgYXNzZXJ0ICgKICAgICAgICAgICAgICAgIG5vZGVSZWNvcmQudG9rZW5zU3Rha2VkLmJhbGFuY2UgKwogICAgICAgICAgICAgICAgbm9kZVJlY29yZC50b2tlbnNDb21taXR0ZWQuYmFsYW5jZQogICAgICAgICAgICAgICAgPj0gYW1vdW50ICsgbm9kZVJlY29yZC50b2tlbnNSZXF1ZXN0ZWRUb1Vuc3Rha2UsCiAgICAgICAgICAgICAgICBtZXNzYWdlOiAiRmxvd0lEVGFibGVTdGFraW5nLk5vZGVTdGFrZXIucmVxdWVzdFVuc3Rha2luZzogTm90IGVub3VnaCB0b2tlbnMgdG8gdW5zdGFrZSEgT25seSBoYXZlIFwobm9kZVJlY29yZC50b2tlbnNTdGFrZWQuYmFsYW5jZSArIG5vZGVSZWNvcmQudG9rZW5zQ29tbWl0dGVkLmJhbGFuY2UpIHRva2VucyBidXQgcmVxdWVzdGVkIHRvIHVuc3Rha2UgXChhbW91bnQgKyBub2RlUmVjb3JkLnRva2Vuc1JlcXVlc3RlZFRvVW5zdGFrZSkgdG9rZW5zIgogICAgICAgICAgICApCgogICAgICAgICAgICAvLyBOb2RlIG9wZXJhdG9ycyB3aG8gaGF2ZSBkZWxlZ2F0b3JzIGhhdmUgdG8gaGF2ZSBlbm91Z2ggb2YgdGhlaXIgb3duIHRva2VucyBzdGFrZWQKICAgICAgICAgICAgLy8gdG8gbWVldCB0aGUgbWluaW11bSwgd2l0aG91dCBhbnkgY29udHJpYnV0aW9ucyBmcm9tIGRlbGVnYXRvcnMKICAgICAgICAgICAgYXNzZXJ0ICgKICAgICAgICAgICAgICAgIG5vZGVSZWNvcmQuZGVsZWdhdG9ycy5sZW5ndGggPT0gMCB8fAogICAgICAgICAgICAgICAgRmxvd0lEVGFibGVTdGFraW5nLmlzR3JlYXRlclRoYW5NaW5pbXVtRm9yUm9sZShudW1Ub2tlbnM6IEZsb3dJRFRhYmxlU3Rha2luZy5Ob2RlSW5mbyhub2RlSUQ6IG5vZGVSZWNvcmQuaWQpLnRvdGFsQ29tbWl0dGVkV2l0aG91dERlbGVnYXRvcnMoKSAtIGFtb3VudCwgcm9sZTogbm9kZVJlY29yZC5yb2xlKSwKICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICJGbG93SURUYWJsZVN0YWtpbmcuTm9kZVN0YWtlci5yZXF1ZXN0VW5zdGFraW5nOiBDYW5ub3QgdW5zdGFrZSBiZWxvdyB0aGUgbWluaW11bSBzdGFrZSByZXF1aXJlbWVudCBpZiB0aGVyZSBhcmUgZGVsZWdhdG9ycy4iCiAgICAgICAgICAgICkKCiAgICAgICAgICAgIGxldCBhbW91bnRDb21taXR0ZWQgPSBub2RlUmVjb3JkLnRva2Vuc0NvbW1pdHRlZC5iYWxhbmNlCgogICAgICAgICAgICAvLyBJZiB0aGUgcmVxdWVzdCBjYW4gY29tZSBmcm9tIGNvbW1pdHRlZCwgd2l0aGRyYXcgZnJvbSBjb21taXR0ZWQgdG8gdW5zdGFrZWQKICAgICAgICAgICAgaWYgYW1vdW50Q29tbWl0dGVkID49IGFtb3VudCB7CgogICAgICAgICAgICAgICAgLy8gd2l0aGRyYXcgdGhlIHJlcXVlc3RlZCB0b2tlbnMgZnJvbSBjb21taXR0ZWQgc2luY2UgdGhleSBoYXZlIG5vdCBiZWVuIHN0YWtlZCB5ZXQKICAgICAgICAgICAgICAgIG5vZGVSZWNvcmQudG9rZW5zVW5zdGFrZWQuZGVwb3NpdChmcm9tOiA8LW5vZGVSZWNvcmQudG9rZW5zQ29tbWl0dGVkLndpdGhkcmF3KGFtb3VudDogYW1vdW50KSkKCiAgICAgICAgICAgICAgICBlbWl0IFRva2Vuc1Vuc3Rha2VkKG5vZGVJRDogc2VsZi5pZCwgYW1vdW50OiBhbW91bnQpCgogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbGV0IGFtb3VudENvbW1pdHRlZCA9IG5vZGVSZWNvcmQudG9rZW5zQ29tbWl0dGVkLmJhbGFuY2UKCiAgICAgICAgICAgICAgICAvLyB3aXRoZHJhdyB0aGUgcmVxdWVzdGVkIHRva2VucyBmcm9tIGNvbW1pdHRlZCBzaW5jZSB0aGV5IGhhdmUgbm90IGJlZW4gc3Rha2VkIHlldAogICAgICAgICAgICAgICAgbm9kZVJlY29yZC50b2tlbnNVbnN0YWtlZC5kZXBvc2l0KGZyb206IDwtbm9kZVJlY29yZC50b2tlbnNDb21taXR0ZWQud2l0aGRyYXcoYW1vdW50OiBhbW91bnRDb21taXR0ZWQpKQoKICAgICAgICAgICAgICAgIC8vIHVwZGF0ZSByZXF1ZXN0IHRvIHNob3cgdGhhdCBsZWZ0b3ZlciBhbW91bnQgaXMgcmVxdWVzdGVkIHRvIGJlIHVuc3Rha2VkCiAgICAgICAgICAgICAgICBub2RlUmVjb3JkLnNldFRva2Vuc1JlcXVlc3RlZFRvVW5zdGFrZShub2RlUmVjb3JkLnRva2Vuc1JlcXVlc3RlZFRvVW5zdGFrZSArIChhbW91bnQgLSBhbW91bnRDb21taXR0ZWQpKQoKICAgICAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy5tb2RpZnlOZXdNb3Zlc1BlbmRpbmcobm9kZUlEOiBzZWxmLmlkLCBkZWxlZ2F0b3JJRDogbmlsLCBleGlzdGluZ0xpc3Q6IG5pbCkKCiAgICAgICAgICAgICAgICBlbWl0IFRva2Vuc1Vuc3Rha2VkKG5vZGVJRDogc2VsZi5pZCwgYW1vdW50OiBhbW91bnRDb21taXR0ZWQpCiAgICAgICAgICAgICAgICBlbWl0IE5vZGVUb2tlbnNSZXF1ZXN0ZWRUb1Vuc3Rha2Uobm9kZUlEOiBzZWxmLmlkLCBhbW91bnQ6IG5vZGVSZWNvcmQudG9rZW5zUmVxdWVzdGVkVG9VbnN0YWtlKQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBSZW1vdmUgdGhlIG5vZGUgYXMgYSBjYW5kaWRhdGUgbm9kZSBpZiB0aGV5IHdlcmUgb25lIGJlZm9yZSBidXQgYXJlbid0IG5vdwogICAgICAgICAgICBpZiAhc2VsZi5pc0VsaWdpYmxlRm9yQ2FuZGlkYXRlTm9kZVN0YXR1cyhub2RlUmVjb3JkKSB7CiAgICAgICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcucmVtb3ZlRnJvbUNhbmRpZGF0ZU5vZGVMaXN0KG5vZGVJRDogc2VsZi5pZCwgcm9sZTogbm9kZVJlY29yZC5yb2xlKQogICAgICAgICAgICB9ICAgCiAgICAgICAgfQoKICAgICAgICAvLy8gUmVxdWVzdHMgdG8gdW5zdGFrZSBhbGwgb2YgdGhlIG5vZGUgb3BlcmF0b3JzIHN0YWtlZCBhbmQgY29tbWl0dGVkIHRva2VucwogICAgICAgIC8vLyBhcyB3ZWxsIGFzIGFsbCB0aGUgc3Rha2VkIGFuZCBjb21taXR0ZWQgdG9rZW5zIG9mIGFsbCBvZiB0aGVpciBkZWxlZ2F0b3JzCiAgICAgICAgYWNjZXNzKE5vZGVPcGVyYXRvcikgZnVuIHVuc3Rha2VBbGwoKSB7CiAgICAgICAgICAgIHByZSB7CiAgICAgICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcuc3Rha2luZ0VuYWJsZWQoKTogIkZsb3dJRFRhYmxlU3Rha2luZy5Ob2RlU3Rha2VyLnVuc3Rha2VBbGw6IENhbm5vdCB1bnN0YWtlIGlmIHRoZSBzdGFraW5nIGF1Y3Rpb24gaXNuJ3QgaW4gcHJvZ3Jlc3MiCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxldCBub2RlUmVjb3JkID0gRmxvd0lEVGFibGVTdGFraW5nLmJvcnJvd05vZGVSZWNvcmQoc2VsZi5pZCkKCiAgICAgICAgICAgIGlmIG5vZGVSZWNvcmQudG9rZW5zQ29tbWl0dGVkLmJhbGFuY2UgPiAwLjAgewoKICAgICAgICAgICAgICAgIGVtaXQgVG9rZW5zVW5zdGFrZWQobm9kZUlEOiBzZWxmLmlkLCBhbW91bnQ6IG5vZGVSZWNvcmQudG9rZW5zQ29tbWl0dGVkLmJhbGFuY2UpCgogICAgICAgICAgICAgICAgLy8vIGlmIHRoZSByZXF1ZXN0IGNhbiBjb21lIGZyb20gY29tbWl0dGVkLCB3aXRoZHJhdyBmcm9tIGNvbW1pdHRlZCB0byB1bnN0YWtlZAogICAgICAgICAgICAgICAgLy8vIHdpdGhkcmF3IHRoZSByZXF1ZXN0ZWQgdG9rZW5zIGZyb20gY29tbWl0dGVkIHNpbmNlIHRoZXkgaGF2ZSBub3QgYmVlbiBzdGFrZWQgeWV0CiAgICAgICAgICAgICAgICBub2RlUmVjb3JkLnRva2Vuc1Vuc3Rha2VkLmRlcG9zaXQoZnJvbTogPC1ub2RlUmVjb3JkLnRva2Vuc0NvbW1pdHRlZC53aXRoZHJhdyhhbW91bnQ6IG5vZGVSZWNvcmQudG9rZW5zQ29tbWl0dGVkLmJhbGFuY2UpKQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiBub2RlUmVjb3JkLnRva2Vuc1N0YWtlZC5iYWxhbmNlID4gMC4wIHsKCiAgICAgICAgICAgICAgICAvLy8gdXBkYXRlIHJlcXVlc3QgdG8gc2hvdyB0aGF0IGxlZnRvdmVyIGFtb3VudCBpcyByZXF1ZXN0ZWQgdG8gYmUgdW5zdGFrZWQKICAgICAgICAgICAgICAgIG5vZGVSZWNvcmQuc2V0VG9rZW5zUmVxdWVzdGVkVG9VbnN0YWtlKG5vZGVSZWNvcmQudG9rZW5zU3Rha2VkLmJhbGFuY2UpCgogICAgICAgICAgICAgICAgRmxvd0lEVGFibGVTdGFraW5nLm1vZGlmeU5ld01vdmVzUGVuZGluZyhub2RlSUQ6IHNlbGYuaWQsIGRlbGVnYXRvcklEOiBuaWwsIGV4aXN0aW5nTGlzdDogbmlsKQoKICAgICAgICAgICAgICAgIGVtaXQgTm9kZVRva2Vuc1JlcXVlc3RlZFRvVW5zdGFrZShub2RlSUQ6IHNlbGYuaWQsIGFtb3VudDogbm9kZVJlY29yZC50b2tlbnNSZXF1ZXN0ZWRUb1Vuc3Rha2UpCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy5yZW1vdmVGcm9tQ2FuZGlkYXRlTm9kZUxpc3Qobm9kZUlEOiBzZWxmLmlkLCByb2xlOiBub2RlUmVjb3JkLnJvbGUpCiAgICAgICAgfQoKICAgICAgICAvLy8gV2l0aGRyYXcgdG9rZW5zIGZyb20gdGhlIHVuc3Rha2VkIGJ1Y2tldAogICAgICAgIGFjY2VzcyhOb2RlT3BlcmF0b3IpIGZ1biB3aXRoZHJhd1Vuc3Rha2VkVG9rZW5zKGFtb3VudDogVUZpeDY0KTogQHtGdW5naWJsZVRva2VuLlZhdWx0fSB7CiAgICAgICAgICAgIGxldCBub2RlUmVjb3JkID0gRmxvd0lEVGFibGVTdGFraW5nLmJvcnJvd05vZGVSZWNvcmQoc2VsZi5pZCkKCiAgICAgICAgICAgIGVtaXQgVW5zdGFrZWRUb2tlbnNXaXRoZHJhd24obm9kZUlEOiBub2RlUmVjb3JkLmlkLCBhbW91bnQ6IGFtb3VudCkKCiAgICAgICAgICAgIHJldHVybiA8LSBub2RlUmVjb3JkLnRva2Vuc1Vuc3Rha2VkLndpdGhkcmF3KGFtb3VudDogYW1vdW50KQogICAgICAgIH0KCiAgICAgICAgLy8vIFdpdGhkcmF3IHRva2VucyBmcm9tIHRoZSByZXdhcmRlZCBidWNrZXQKICAgICAgICBhY2Nlc3MoTm9kZU9wZXJhdG9yKSBmdW4gd2l0aGRyYXdSZXdhcmRlZFRva2VucyhhbW91bnQ6IFVGaXg2NCk6IEB7RnVuZ2libGVUb2tlbi5WYXVsdH0gewogICAgICAgICAgICBsZXQgbm9kZVJlY29yZCA9IEZsb3dJRFRhYmxlU3Rha2luZy5ib3Jyb3dOb2RlUmVjb3JkKHNlbGYuaWQpCgogICAgICAgICAgICBlbWl0IFJld2FyZFRva2Vuc1dpdGhkcmF3bihub2RlSUQ6IG5vZGVSZWNvcmQuaWQsIGFtb3VudDogYW1vdW50KQoKICAgICAgICAgICAgcmV0dXJuIDwtIG5vZGVSZWNvcmQudG9rZW5zUmV3YXJkZWQud2l0aGRyYXcoYW1vdW50OiBhbW91bnQpCiAgICAgICAgfQogICAgfQoKICAgIC8vLyBQdWJsaWMgaW50ZXJmYWNlIHRvIHF1ZXJ5IGluZm9ybWF0aW9uIGFib3V0IGEgZGVsZWdhdG9yCiAgICAvLy8gZnJvbSB0aGUgYWNjb3VudCBpdCBpcyBzdG9yZWQgaW4gCiAgICBhY2Nlc3MoYWxsKSByZXNvdXJjZSBpbnRlcmZhY2UgTm9kZURlbGVnYXRvclB1YmxpYyB7CiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IGlkOiBVSW50MzIKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgbm9kZUlEOiBTdHJpbmcKICAgIH0KCiAgICBhY2Nlc3MoYWxsKSBlbnRpdGxlbWVudCBEZWxlZ2F0b3JPd25lcgoKICAgIC8vLyBSZXNvdXJjZSBvYmplY3QgdGhhdCB0aGUgZGVsZWdhdG9yIHN0b3JlcyBpbiB0aGVpciBhY2NvdW50IHRvIHBlcmZvcm0gc3Rha2luZyBhY3Rpb25zCiAgICBhY2Nlc3MoYWxsKSByZXNvdXJjZSBOb2RlRGVsZWdhdG9yOiBOb2RlRGVsZWdhdG9yUHVibGljIHsKCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IGlkOiBVSW50MzIKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgbm9kZUlEOiBTdHJpbmcKCiAgICAgICAgaW5pdChpZDogVUludDMyLCBub2RlSUQ6IFN0cmluZykgewogICAgICAgICAgICBzZWxmLmlkID0gaWQKICAgICAgICAgICAgc2VsZi5ub2RlSUQgPSBub2RlSUQKICAgICAgICB9CgogICAgICAgIC8vLyBEZWxlZ2F0ZSBuZXcgdG9rZW5zIHRvIHRoZSBub2RlIG9wZXJhdG9yCiAgICAgICAgYWNjZXNzKERlbGVnYXRvck93bmVyKSBmdW4gZGVsZWdhdGVOZXdUb2tlbnMoZnJvbTogQHtGdW5naWJsZVRva2VuLlZhdWx0fSkgewogICAgICAgICAgICBwcmUgewogICAgICAgICAgICAgICAgRmxvd0lEVGFibGVTdGFraW5nLnN0YWtpbmdFbmFibGVkKCk6ICJGbG93SURUYWJsZVN0YWtpbmcuTm9kZURlbGVnYXRvci5kZWxlZ2F0ZU5ld1Rva2VuczogQ2Fubm90IGRlbGVnYXRlIGlmIHRoZSBzdGFraW5nIGF1Y3Rpb24gaXNuJ3QgaW4gcHJvZ3Jlc3MiCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGJvcnJvdyB0aGUgbm9kZSByZWNvcmQgb2YgdGhlIG5vZGUgaW4gb3JkZXIgdG8gZ2V0IHRoZSBkZWxlZ2F0b3IgcmVjb3JkCiAgICAgICAgICAgIGxldCBub2RlUmVjb3JkID0gRmxvd0lEVGFibGVTdGFraW5nLmJvcnJvd05vZGVSZWNvcmQoc2VsZi5ub2RlSUQpCiAgICAgICAgICAgIGxldCBkZWxSZWNvcmQgPSBub2RlUmVjb3JkLmJvcnJvd0RlbGVnYXRvclJlY29yZChzZWxmLmlkKQoKICAgICAgICAgICAgZW1pdCBEZWxlZ2F0b3JUb2tlbnNDb21taXR0ZWQobm9kZUlEOiBzZWxmLm5vZGVJRCwgZGVsZWdhdG9ySUQ6IHNlbGYuaWQsIGFtb3VudDogZnJvbS5iYWxhbmNlKQoKICAgICAgICAgICAgLy8gQ29tbWl0IHRoZSBuZXcgdG9rZW5zIHRvIHRoZSBkZWxlZ2F0b3IgcmVjb3JkCiAgICAgICAgICAgIGRlbFJlY29yZC50b2tlbnNDb21taXR0ZWQuZGVwb3NpdChmcm9tOiA8LWZyb20pCgogICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcubW9kaWZ5TmV3TW92ZXNQZW5kaW5nKG5vZGVJRDogc2VsZi5ub2RlSUQsIGRlbGVnYXRvcklEOiBzZWxmLmlkLCBleGlzdGluZ0xpc3Q6IG5pbCkKICAgICAgICB9CgogICAgICAgIC8vLyBEZWxlZ2F0ZSB0b2tlbnMgZnJvbSB0aGUgdW5zdGFrZWQgYnVja2V0IHRvIHRoZSBub2RlIG9wZXJhdG9yCiAgICAgICAgYWNjZXNzKERlbGVnYXRvck93bmVyKSBmdW4gZGVsZWdhdGVVbnN0YWtlZFRva2VucyhhbW91bnQ6IFVGaXg2NCkgewogICAgICAgICAgICBwcmUgewogICAgICAgICAgICAgICAgRmxvd0lEVGFibGVTdGFraW5nLnN0YWtpbmdFbmFibGVkKCk6ICJGbG93SURUYWJsZVN0YWtpbmcuTm9kZURlbGVnYXRvci5kZWxlZ2F0ZVVuc3Rha2VkVG9rZW5zOiBDYW5ub3QgZGVsZWdhdGUgaWYgdGhlIHN0YWtpbmcgYXVjdGlvbiBpc24ndCBpbiBwcm9ncmVzcyIKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGV0IG5vZGVSZWNvcmQgPSBGbG93SURUYWJsZVN0YWtpbmcuYm9ycm93Tm9kZVJlY29yZChzZWxmLm5vZGVJRCkKICAgICAgICAgICAgbGV0IGRlbFJlY29yZCA9IG5vZGVSZWNvcmQuYm9ycm93RGVsZWdhdG9yUmVjb3JkKHNlbGYuaWQpCgogICAgICAgICAgICB2YXIgcmVtYWluaW5nQW1vdW50ID0gYW1vdW50CgogICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgYW55IHRva2VucyB0aGF0IGhhdmUgYmVlbiByZXF1ZXN0ZWQgdG8gdW5zdGFrZSBmb3IgdGhlIGN1cnJlbnQgZXBvY2gsCiAgICAgICAgICAgIC8vIGNhbmNlbCB0aG9zZSBmaXJzdCBiZWZvcmUgc3Rha2luZyBuZXcgdW5zdGFrZWQgdG9rZW5zCiAgICAgICAgICAgIGlmIHJlbWFpbmluZ0Ftb3VudCA8PSBkZWxSZWNvcmQudG9rZW5zUmVxdWVzdGVkVG9VbnN0YWtlIHsKICAgICAgICAgICAgICAgIGRlbFJlY29yZC5zZXRUb2tlbnNSZXF1ZXN0ZWRUb1Vuc3Rha2UoZGVsUmVjb3JkLnRva2Vuc1JlcXVlc3RlZFRvVW5zdGFrZSAtIHJlbWFpbmluZ0Ftb3VudCkKICAgICAgICAgICAgICAgIHJlbWFpbmluZ0Ftb3VudCA9IDAuMAogICAgICAgICAgICB9IGVsc2UgaWYgcmVtYWluaW5nQW1vdW50ID4gZGVsUmVjb3JkLnRva2Vuc1JlcXVlc3RlZFRvVW5zdGFrZSB7CiAgICAgICAgICAgICAgICByZW1haW5pbmdBbW91bnQgPSByZW1haW5pbmdBbW91bnQgLSBkZWxSZWNvcmQudG9rZW5zUmVxdWVzdGVkVG9VbnN0YWtlCiAgICAgICAgICAgICAgICBkZWxSZWNvcmQuc2V0VG9rZW5zUmVxdWVzdGVkVG9VbnN0YWtlKDAuMCkKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQ29tbWl0IHRoZSByZW1haW5pbmcgdW5zdGFrZWQgdG9rZW5zCiAgICAgICAgICAgIGRlbFJlY29yZC50b2tlbnNDb21taXR0ZWQuZGVwb3NpdChmcm9tOiA8LWRlbFJlY29yZC50b2tlbnNVbnN0YWtlZC53aXRoZHJhdyhhbW91bnQ6IHJlbWFpbmluZ0Ftb3VudCkpCgogICAgICAgICAgICBlbWl0IERlbGVnYXRvclRva2Vuc0NvbW1pdHRlZChub2RlSUQ6IHNlbGYubm9kZUlELCBkZWxlZ2F0b3JJRDogc2VsZi5pZCwgYW1vdW50OiBhbW91bnQpCgogICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcubW9kaWZ5TmV3TW92ZXNQZW5kaW5nKG5vZGVJRDogc2VsZi5ub2RlSUQsIGRlbGVnYXRvcklEOiBzZWxmLmlkLCBleGlzdGluZ0xpc3Q6IG5pbCkKICAgICAgICB9CgogICAgICAgIC8vLyBEZWxlZ2F0ZSB0b2tlbnMgZnJvbSB0aGUgcmV3YXJkcyBidWNrZXQgdG8gdGhlIG5vZGUgb3BlcmF0b3IKICAgICAgICBhY2Nlc3MoRGVsZWdhdG9yT3duZXIpIGZ1biBkZWxlZ2F0ZVJld2FyZGVkVG9rZW5zKGFtb3VudDogVUZpeDY0KSB7CiAgICAgICAgICAgIHByZSB7CiAgICAgICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcuc3Rha2luZ0VuYWJsZWQoKTogIkZsb3dJRFRhYmxlU3Rha2luZy5Ob2RlRGVsZWdhdG9yLmRlbGVnYXRlUmV3YXJkZWRUb2tlbnM6IENhbm5vdCBkZWxlZ2F0ZSBpZiB0aGUgc3Rha2luZyBhdWN0aW9uIGlzbid0IGluIHByb2dyZXNzIgogICAgICAgICAgICB9CgogICAgICAgICAgICBsZXQgbm9kZVJlY29yZCA9IEZsb3dJRFRhYmxlU3Rha2luZy5ib3Jyb3dOb2RlUmVjb3JkKHNlbGYubm9kZUlEKQogICAgICAgICAgICBsZXQgZGVsUmVjb3JkID0gbm9kZVJlY29yZC5ib3Jyb3dEZWxlZ2F0b3JSZWNvcmQoc2VsZi5pZCkKCiAgICAgICAgICAgIGRlbFJlY29yZC50b2tlbnNDb21taXR0ZWQuZGVwb3NpdChmcm9tOiA8LWRlbFJlY29yZC50b2tlbnNSZXdhcmRlZC53aXRoZHJhdyhhbW91bnQ6IGFtb3VudCkpCgogICAgICAgICAgICBlbWl0IERlbGVnYXRvclRva2Vuc0NvbW1pdHRlZChub2RlSUQ6IHNlbGYubm9kZUlELCBkZWxlZ2F0b3JJRDogc2VsZi5pZCwgYW1vdW50OiBhbW91bnQpCgogICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcubW9kaWZ5TmV3TW92ZXNQZW5kaW5nKG5vZGVJRDogc2VsZi5ub2RlSUQsIGRlbGVnYXRvcklEOiBzZWxmLmlkLCBleGlzdGluZ0xpc3Q6IG5pbCkKICAgICAgICB9CgogICAgICAgIC8vLyBSZXF1ZXN0IHRvIHVuc3Rha2UgZGVsZWdhdGVkIHRva2VucyBkdXJpbmcgdGhlIG5leHQgZXBvY2gKICAgICAgICBhY2Nlc3MoRGVsZWdhdG9yT3duZXIpIGZ1biByZXF1ZXN0VW5zdGFraW5nKGFtb3VudDogVUZpeDY0KSB7CiAgICAgICAgICAgIHByZSB7CiAgICAgICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcuc3Rha2luZ0VuYWJsZWQoKTogIkZsb3dJRFRhYmxlU3Rha2luZy5Ob2RlRGVsZWdhdG9yLnJlcXVlc3RVbnN0YWtpbmc6IENhbm5vdCByZXF1ZXN0IHVuc3Rha2luZyBpZiB0aGUgc3Rha2luZyBhdWN0aW9uIGlzbid0IGluIHByb2dyZXNzIgogICAgICAgICAgICB9CgogICAgICAgICAgICBsZXQgbm9kZVJlY29yZCA9IEZsb3dJRFRhYmxlU3Rha2luZy5ib3Jyb3dOb2RlUmVjb3JkKHNlbGYubm9kZUlEKQogICAgICAgICAgICBsZXQgZGVsUmVjb3JkID0gbm9kZVJlY29yZC5ib3Jyb3dEZWxlZ2F0b3JSZWNvcmQoc2VsZi5pZCkKCiAgICAgICAgICAgIC8vIFRoZSBkZWxlZ2F0b3IgbXVzdCBoYXZlIGVub3VnaCB0b2tlbnMgdG8gdW5zdGFrZQogICAgICAgICAgICBhc3NlcnQgKAogICAgICAgICAgICAgICAgZGVsUmVjb3JkLnRva2Vuc1N0YWtlZC5iYWxhbmNlICsKICAgICAgICAgICAgICAgIGRlbFJlY29yZC50b2tlbnNDb21taXR0ZWQuYmFsYW5jZQogICAgICAgICAgICAgICAgPj0gYW1vdW50ICsgZGVsUmVjb3JkLnRva2Vuc1JlcXVlc3RlZFRvVW5zdGFrZSwKICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICJGbG93SURUYWJsZVN0YWtpbmcuTm9kZURlbGVnYXRvci5yZXF1ZXN0VW5zdGFraW5nOiBOb3QgZW5vdWdoIHRva2VucyB0byB1bnN0YWtlISBPbmx5IGhhdmUgXChkZWxSZWNvcmQudG9rZW5zU3Rha2VkLmJhbGFuY2UgKyBkZWxSZWNvcmQudG9rZW5zQ29tbWl0dGVkLmJhbGFuY2UpIHRva2VucyBidXQgcmVxdWVzdGVkIHRvIHVuc3Rha2UgXChhbW91bnQgKyBkZWxSZWNvcmQudG9rZW5zUmVxdWVzdGVkVG9VbnN0YWtlKSB0b2tlbnMiCiAgICAgICAgICAgICkKCiAgICAgICAgICAgIC8vIGlmIHRoZSByZXF1ZXN0IGNhbiBjb21lIGZyb20gY29tbWl0dGVkLCB3aXRoZHJhdyBmcm9tIGNvbW1pdHRlZCB0byB1bnN0YWtlZAogICAgICAgICAgICBpZiBkZWxSZWNvcmQudG9rZW5zQ29tbWl0dGVkLmJhbGFuY2UgPj0gYW1vdW50IHsKCiAgICAgICAgICAgICAgICAvLyB3aXRoZHJhdyB0aGUgcmVxdWVzdGVkIHRva2VucyBmcm9tIGNvbW1pdHRlZCBzaW5jZSB0aGV5IGhhdmUgbm90IGJlZW4gc3Rha2VkIHlldAogICAgICAgICAgICAgICAgZGVsUmVjb3JkLnRva2Vuc1Vuc3Rha2VkLmRlcG9zaXQoZnJvbTogPC1kZWxSZWNvcmQudG9rZW5zQ29tbWl0dGVkLndpdGhkcmF3KGFtb3VudDogYW1vdW50KSkKICAgICAgICAgICAgICAgIGVtaXQgRGVsZWdhdG9yVG9rZW5zVW5zdGFrZWQobm9kZUlEOiBzZWxmLm5vZGVJRCwgZGVsZWdhdG9ySUQ6IHNlbGYuaWQsIGFtb3VudDogYW1vdW50KQoKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vLyBHZXQgdGhlIGJhbGFuY2Ugb2YgdGhlIHRva2VucyB0aGF0IGFyZSBjdXJyZW50bHkgY29tbWl0dGVkCiAgICAgICAgICAgICAgICBsZXQgYW1vdW50Q29tbWl0dGVkID0gZGVsUmVjb3JkLnRva2Vuc0NvbW1pdHRlZC5iYWxhbmNlCgogICAgICAgICAgICAgICAgaWYgYW1vdW50Q29tbWl0dGVkID4gMC4wIHsKICAgICAgICAgICAgICAgICAgICBkZWxSZWNvcmQudG9rZW5zVW5zdGFrZWQuZGVwb3NpdChmcm9tOiA8LWRlbFJlY29yZC50b2tlbnNDb21taXR0ZWQud2l0aGRyYXcoYW1vdW50OiBhbW91bnRDb21taXR0ZWQpKQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vLyB1cGRhdGUgcmVxdWVzdCB0byBzaG93IHRoYXQgbGVmdG92ZXIgYW1vdW50IGlzIHJlcXVlc3RlZCB0byBiZSB1bnN0YWtlZAogICAgICAgICAgICAgICAgZGVsUmVjb3JkLnNldFRva2Vuc1JlcXVlc3RlZFRvVW5zdGFrZShkZWxSZWNvcmQudG9rZW5zUmVxdWVzdGVkVG9VbnN0YWtlICsgKGFtb3VudCAtIGFtb3VudENvbW1pdHRlZCkpCgogICAgICAgICAgICAgICAgRmxvd0lEVGFibGVTdGFraW5nLm1vZGlmeU5ld01vdmVzUGVuZGluZyhub2RlSUQ6IHNlbGYubm9kZUlELCBkZWxlZ2F0b3JJRDogc2VsZi5pZCwgZXhpc3RpbmdMaXN0OiBuaWwpCgogICAgICAgICAgICAgICAgZW1pdCBEZWxlZ2F0b3JUb2tlbnNVbnN0YWtlZChub2RlSUQ6IHNlbGYubm9kZUlELCBkZWxlZ2F0b3JJRDogc2VsZi5pZCwgYW1vdW50OiBhbW91bnRDb21taXR0ZWQpCiAgICAgICAgICAgICAgICBlbWl0IERlbGVnYXRvclRva2Vuc1JlcXVlc3RlZFRvVW5zdGFrZShub2RlSUQ6IHNlbGYubm9kZUlELCBkZWxlZ2F0b3JJRDogc2VsZi5pZCwgYW1vdW50OiBkZWxSZWNvcmQudG9rZW5zUmVxdWVzdGVkVG9VbnN0YWtlKQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLy8gV2l0aGRyYXcgdG9rZW5zIGZyb20gdGhlIHVuc3Rha2VkIGJ1Y2tldAogICAgICAgIGFjY2VzcyhEZWxlZ2F0b3JPd25lcikgZnVuIHdpdGhkcmF3VW5zdGFrZWRUb2tlbnMoYW1vdW50OiBVRml4NjQpOiBAe0Z1bmdpYmxlVG9rZW4uVmF1bHR9IHsKICAgICAgICAgICAgbGV0IG5vZGVSZWNvcmQgPSBGbG93SURUYWJsZVN0YWtpbmcuYm9ycm93Tm9kZVJlY29yZChzZWxmLm5vZGVJRCkKICAgICAgICAgICAgbGV0IGRlbFJlY29yZCA9IG5vZGVSZWNvcmQuYm9ycm93RGVsZWdhdG9yUmVjb3JkKHNlbGYuaWQpCgogICAgICAgICAgICBlbWl0IERlbGVnYXRvclVuc3Rha2VkVG9rZW5zV2l0aGRyYXduKG5vZGVJRDogbm9kZVJlY29yZC5pZCwgZGVsZWdhdG9ySUQ6IHNlbGYuaWQsIGFtb3VudDogYW1vdW50KQoKICAgICAgICAgICAgcmV0dXJuIDwtIGRlbFJlY29yZC50b2tlbnNVbnN0YWtlZC53aXRoZHJhdyhhbW91bnQ6IGFtb3VudCkKICAgICAgICB9CgogICAgICAgIC8vLyBXaXRoZHJhdyB0b2tlbnMgZnJvbSB0aGUgcmV3YXJkZWQgYnVja2V0CiAgICAgICAgYWNjZXNzKERlbGVnYXRvck93bmVyKSBmdW4gd2l0aGRyYXdSZXdhcmRlZFRva2VucyhhbW91bnQ6IFVGaXg2NCk6IEB7RnVuZ2libGVUb2tlbi5WYXVsdH0gewogICAgICAgICAgICBsZXQgbm9kZVJlY29yZCA9IEZsb3dJRFRhYmxlU3Rha2luZy5ib3Jyb3dOb2RlUmVjb3JkKHNlbGYubm9kZUlEKQogICAgICAgICAgICBsZXQgZGVsUmVjb3JkID0gbm9kZVJlY29yZC5ib3Jyb3dEZWxlZ2F0b3JSZWNvcmQoc2VsZi5pZCkKCiAgICAgICAgICAgIGVtaXQgRGVsZWdhdG9yUmV3YXJkVG9rZW5zV2l0aGRyYXduKG5vZGVJRDogbm9kZVJlY29yZC5pZCwgZGVsZWdhdG9ySUQ6IHNlbGYuaWQsIGFtb3VudDogYW1vdW50KQoKICAgICAgICAgICAgcmV0dXJuIDwtIGRlbFJlY29yZC50b2tlbnNSZXdhcmRlZC53aXRoZHJhdyhhbW91bnQ6IGFtb3VudCkKICAgICAgICB9CiAgICB9CgogICAgLy8vIEluY2x1ZGVzIGFsbCB0aGUgcmV3YXJkcyBicmVha2Rvd25zIGZvciBhbGwgdGhlIG5vZGVzIGFuZCBkZWxlZ2F0b3JzIGZvciBhIHNwZWNpZmljIGVwb2NoCiAgICAvLy8gYXMgd2VsbCBhcyB0aGUgdG90YWwgYW1vdW50IG9mIHRva2VucyB0byBiZSBtaW50ZWQgZm9yIHJld2FyZHMKICAgIGFjY2VzcyhhbGwpIHN0cnVjdCBFcG9jaFJld2FyZHNTdW1tYXJ5IHsKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgdG90YWxSZXdhcmRzOiBVRml4NjQKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgYnJlYWtkb3duOiBbUmV3YXJkc0JyZWFrZG93bl0KCiAgICAgICAgdmlldyBpbml0KHRvdGFsUmV3YXJkczogVUZpeDY0LCBicmVha2Rvd246IFtSZXdhcmRzQnJlYWtkb3duXSkgewogICAgICAgICAgICBzZWxmLnRvdGFsUmV3YXJkcyA9IHRvdGFsUmV3YXJkcwogICAgICAgICAgICBzZWxmLmJyZWFrZG93biA9IGJyZWFrZG93bgogICAgICAgIH0KICAgIH0KCiAgICAvLy8gRGV0YWlscyB0aGUgcmV3YXJkcyBicmVha2Rvd24gZm9yIGFuIGluZGl2aWR1YWwgbm9kZSBhbmQgaXRzIGRlbGVnYXRvcnMKICAgIGFjY2VzcyhhbGwpIHN0cnVjdCBSZXdhcmRzQnJlYWtkb3duIHsKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgbm9kZUlEOiBTdHJpbmcKICAgICAgICBhY2Nlc3MoYWxsKSB2YXIgbm9kZVJld2FyZHM6IFVGaXg2NAogICAgICAgIGFjY2VzcyhhbGwpIGxldCBkZWxlZ2F0b3JSZXdhcmRzOiB7VUludDMyOiBVRml4NjR9CgogICAgICAgIHZpZXcgaW5pdChub2RlSUQ6IFN0cmluZykgewogICAgICAgICAgICBzZWxmLm5vZGVJRCA9IG5vZGVJRAogICAgICAgICAgICBzZWxmLm5vZGVSZXdhcmRzID0gMC4wCiAgICAgICAgICAgIHNlbGYuZGVsZWdhdG9yUmV3YXJkcyA9IHt9CiAgICAgICAgfQoKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gc2V0Tm9kZVJld2FyZHMoXyByZXdhcmRzOiBVRml4NjQpIHsKICAgICAgICAgICAgc2VsZi5ub2RlUmV3YXJkcyA9IHJld2FyZHMKICAgICAgICB9CgogICAgICAgIC8vLyBTY2FsZSB0aGUgcmV3YXJkcyBvZiBhIHNpbmdsZSBkZWxlZ2F0b3IgYnkgYSBzY2FsaW5nIGZhY3RvcgogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBzY2FsZURlbGVnYXRvclJld2FyZHMoZGVsZWdhdG9ySUQ6IFVJbnQzMiwgc2NhbGluZ0ZhY3RvcjogVUZpeDY0KSB7CiAgICAgICAgICAgIGlmIGxldCByZXdhcmQgPSBzZWxmLmRlbGVnYXRvclJld2FyZHNbZGVsZWdhdG9ySURdIHsKICAgICAgICAgICAgICAgICAgICBzZWxmLmRlbGVnYXRvclJld2FyZHNbZGVsZWdhdG9ySURdID0gcmV3YXJkICogc2NhbGluZ0ZhY3RvcgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBzY2FsZU9wZXJhdG9yUmV3YXJkcyhzY2FsaW5nRmFjdG9yOiBVRml4NjQpIHsKICAgICAgICAgICAgc2VsZi5ub2RlUmV3YXJkcyA9IHNlbGYubm9kZVJld2FyZHMgKiBzY2FsaW5nRmFjdG9yCiAgICAgICAgfQoKICAgICAgICAvLy8gU2NhbGUgdGhlIHJld2FyZHMgb2YgYWxsIHRoZSBzdGFrZXJzIGluIHRoZSByZWNvcmQKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gc2NhbGVBbGxSZXdhcmRzKHNjYWxpbmdGYWN0b3I6IFVGaXg2NCkgewogICAgICAgICAgICBzZWxmLnNjYWxlT3BlcmF0b3JSZXdhcmRzKHNjYWxpbmdGYWN0b3I6IHNjYWxpbmdGYWN0b3IpCiAgICAgICAgICAgIGZvciBpZCBpbiBzZWxmLmRlbGVnYXRvclJld2FyZHMua2V5cyB7CiAgICAgICAgICAgICAgICBzZWxmLnNjYWxlRGVsZWdhdG9yUmV3YXJkcyhkZWxlZ2F0b3JJRDogaWQsIHNjYWxpbmdGYWN0b3I6IHNjYWxpbmdGYWN0b3IpCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vLyBTZXRzIHRoZSByZXdhcmQgYW1vdW50IGZvciBhIHNwZWNpZmljIGRlbGVnYXRvciBvZiB0aGlzIG5vZGUKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gc2V0RGVsZWdhdG9yUmV3YXJkKGRlbGVnYXRvcklEOiBVSW50MzIsIHJld2FyZHM6IFVGaXg2NCkgewogICAgICAgICAgICBzZWxmLmRlbGVnYXRvclJld2FyZHNbZGVsZWdhdG9ySURdID0gcmV3YXJkcwogICAgICAgIH0KICAgIH0KCiAgICAvLy8gSW50ZXJmYWNlIHRoYXQgb25seSBjb250YWlucyBvcGVyYXRpb25zIHRoYXQgYXJlIHBhcnQKICAgIC8vLyBvZiB0aGUgcmVndWxhciBhdXRvbWF0ZWQgZnVuY3Rpb25pbmcgb2YgdGhlIGVwb2NoIHByb2Nlc3MKICAgIC8vLyBUaGVzZSBhcmUgYWNjZXNzZWQgYnkgdGhlIGBGbG93RXBvY2hgIGNvbnRyYWN0IHRocm91Z2ggYSBjYXBhYmlsaXR5CiAgICBhY2Nlc3MoYWxsKSByZXNvdXJjZSBpbnRlcmZhY2UgRXBvY2hPcGVyYXRpb25zIHsKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gc2V0RXBvY2hUb2tlblBheW91dChfIG5ld1BheW91dDogVUZpeDY0KQogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBzZXRTbG90TGltaXRzKHNsb3RMaW1pdHM6IHtVSW50ODogVUludDE2fSkKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gc2V0Tm9kZVdlaWdodChub2RlSUQ6IFN0cmluZywgd2VpZ2h0OiBVSW50NjQpCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIHN0YXJ0U3Rha2luZ0F1Y3Rpb24oKQogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBlbmRTdGFraW5nQXVjdGlvbigpOiBbU3RyaW5nXQogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBwYXlSZXdhcmRzKGZvckVwb2NoQ291bnRlcjogVUludDY0LCByZXdhcmRzU3VtbWFyeTogRXBvY2hSZXdhcmRzU3VtbWFyeSkKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gY2FsY3VsYXRlUmV3YXJkcygpOiBFcG9jaFJld2FyZHNTdW1tYXJ5CiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIG1vdmVUb2tlbnMobmV3RXBvY2hDb3VudGVyOiBVSW50NjQpCiAgICB9CgogICAgYWNjZXNzKGFsbCkgcmVzb3VyY2UgQWRtaW46IEVwb2NoT3BlcmF0aW9ucyB7CgogICAgICAgIC8vLyBTZXRzIGEgbmV3IHNldCBvZiBtaW5pbXVtIHN0YWtpbmcgcmVxdWlyZW1lbnRzIGZvciBhbGwgdGhlIG5vZGVzCiAgICAgICAgLy8vIE5vZGVzJyBpbmRleGVzIGFyZSB0aGVpciByb2xlIG51bWJlcnMKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gc2V0TWluaW11bVN0YWtlUmVxdWlyZW1lbnRzKF8gbmV3UmVxdWlyZW1lbnRzOiB7VUludDg6IFVGaXg2NH0pIHsKICAgICAgICAgICAgcHJlIHsKICAgICAgICAgICAgICAgIG5ld1JlcXVpcmVtZW50cy5rZXlzLmxlbmd0aCA9PSA1OgogICAgICAgICAgICAgICAgICAgICJGbG93SURUYWJsZVN0YWtpbmcuQWRtaW4uc2V0TWluaW11bVN0YWtlUmVxdWlyZW1lbnRzOiBUaGVyZSBtdXN0IGJlIGZpdmUgZW50cmllcyBmb3Igbm9kZSBtaW5pbXVtIHN0YWtlIHJlcXVpcmVtZW50cyBidXQgZ290IFwobmV3UmVxdWlyZW1lbnRzLmtleXMubGVuZ3RoKSIKICAgICAgICAgICAgfQogICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcubWluaW11bVN0YWtlUmVxdWlyZWQgPSBuZXdSZXF1aXJlbWVudHMKICAgICAgICAgICAgZW1pdCBOZXdTdGFraW5nTWluaW11bXMobmV3TWluaW11bXM6IG5ld1JlcXVpcmVtZW50cykKICAgICAgICB9CgogICAgICAgIC8vLyBTZXRzIGEgbmV3IHNldCBvZiBtaW5pbXVtIHN0YWtpbmcgcmVxdWlyZW1lbnRzIGZvciBhbGwgdGhlIGRlbGVnYXRvcnMKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gc2V0RGVsZWdhdG9yTWluaW11bVN0YWtlUmVxdWlyZW1lbnQoXyBuZXdSZXF1aXJlbWVudDogVUZpeDY0KSB7CiAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy5hY2NvdW50LnN0b3JhZ2UubG9hZDxVRml4NjQ+KGZyb206IC9zdG9yYWdlL2RlbGVnYXRvclN0YWtpbmdNaW5pbXVtKQogICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcuYWNjb3VudC5zdG9yYWdlLnNhdmUobmV3UmVxdWlyZW1lbnQsIHRvOiAvc3RvcmFnZS9kZWxlZ2F0b3JTdGFraW5nTWluaW11bSkKCiAgICAgICAgICAgIGVtaXQgTmV3RGVsZWdhdG9yU3Rha2luZ01pbmltdW0obmV3TWluaW11bTogbmV3UmVxdWlyZW1lbnQpCiAgICAgICAgfQoKICAgICAgICAvLy8gQ2hhbmdlcyB0aGUgdG90YWwgd2Vla2x5IHBheW91dCB0byBhIG5ldyB2YWx1ZQogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBzZXRFcG9jaFRva2VuUGF5b3V0KF8gbmV3UGF5b3V0OiBVRml4NjQpIHsKICAgICAgICAgICAgaWYgbmV3UGF5b3V0ICE9IEZsb3dJRFRhYmxlU3Rha2luZy5lcG9jaFRva2VuUGF5b3V0IHsKICAgICAgICAgICAgICAgIGVtaXQgTmV3V2Vla2x5UGF5b3V0KG5ld1BheW91dDogbmV3UGF5b3V0KQogICAgICAgICAgICB9CiAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy5lcG9jaFRva2VuUGF5b3V0ID0gbmV3UGF5b3V0CiAgICAgICAgfQoKICAgICAgICAvLy8gU2V0cyBhIG5ldyBkZWxlZ2F0b3IgY3V0IHBlcmNlbnRhZ2UgdGhhdCBub2RlcyB0YWtlIGZyb20gZGVsZWdhdG9yIHJld2FyZHMKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gc2V0Q3V0UGVyY2VudGFnZShfIG5ld0N1dFBlcmNlbnRhZ2U6IFVGaXg2NCkgewogICAgICAgICAgICBwcmUgewogICAgICAgICAgICAgICAgbmV3Q3V0UGVyY2VudGFnZSA+IDAuMCAmJiBuZXdDdXRQZXJjZW50YWdlIDwgMS4wOgogICAgICAgICAgICAgICAgICAgICJGbG93SURUYWJsZVN0YWtpbmcuQWRtaW4uc2V0Q3V0UGVyY2VudGFnZTogQ3V0IHBlcmNlbnRhZ2UgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDEgYnV0IGdvdCBcKG5ld0N1dFBlcmNlbnRhZ2UpIgogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIG5ld0N1dFBlcmNlbnRhZ2UgIT0gRmxvd0lEVGFibGVTdGFraW5nLm5vZGVEZWxlZ2F0aW5nUmV3YXJkQ3V0IHsKICAgICAgICAgICAgICAgIGVtaXQgTmV3RGVsZWdhdG9yQ3V0UGVyY2VudGFnZShuZXdDdXRQZXJjZW50YWdlOiBuZXdDdXRQZXJjZW50YWdlKQogICAgICAgICAgICB9CiAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy5ub2RlRGVsZWdhdGluZ1Jld2FyZEN1dCA9IG5ld0N1dFBlcmNlbnRhZ2UKICAgICAgICB9CgogICAgICAgIC8vLyBTZXRzIG5ldyBsaW1pdHMgdG8gdGhlIG51bWJlciBvZiBjYW5kaWRhdGUgbm9kZXMgZm9yIGFuIGVwb2NoIGZvciBhIHNwZWNpZmljIHJvbGUKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gc2V0Q2FuZGlkYXRlTm9kZUxpbWl0KHJvbGU6IFVJbnQ4LCBuZXdMaW1pdDogVUludDY0KSB7CiAgICAgICAgICAgIHByZSB7CiAgICAgICAgICAgICAgICByb2xlID49IFVJbnQ4KDEpICYmIHJvbGUgPD0gVUludDgoNSk6ICJGbG93SURUYWJsZVN0YWtpbmcuQWRtaW4uc2V0Q2FuZGlkYXRlTm9kZUxpbWl0OiBUaGUgcm9sZSBtdXN0IGJlIDEsIDIsIDMsIDQsIG9yIDUgYnV0IGdvdCBcKHJvbGUpIgogICAgICAgICAgICB9CgogICAgICAgICAgICBsZXQgY2FuZGlkYXRlTm9kZUxpbWl0cyA9IEZsb3dJRFRhYmxlU3Rha2luZy5hY2NvdW50LnN0b3JhZ2UubG9hZDx7VUludDg6IFVJbnQ2NH0+KGZyb206IC9zdG9yYWdlL2lkVGFibGVDYW5kaWRhdGVOb2RlTGltaXRzKSEKICAgICAgICAgICAgY2FuZGlkYXRlTm9kZUxpbWl0c1tyb2xlXSA9IG5ld0xpbWl0CiAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy5hY2NvdW50LnN0b3JhZ2Uuc2F2ZTx7VUludDg6IFVJbnQ2NH0+KGNhbmRpZGF0ZU5vZGVMaW1pdHMsIHRvOiAvc3RvcmFnZS9pZFRhYmxlQ2FuZGlkYXRlTm9kZUxpbWl0cykKICAgICAgICB9CgogICAgICAgIC8vLyBTZXQgc2xvdCAoY291bnQpIGxpbWl0cyBmb3IgZWFjaCBub2RlIHJvbGUKICAgICAgICAvLy8gVGhlIHNsb3QgbGltaXQgbGltaXRzIHRoZSBudW1iZXIgb2YgcGFydGljaXBhbnQgbm9kZXMgd2l0aCB0aGUgZ2l2ZW4gcm9sZSB3aGljaCBtYXkgYmUgYWRkZWQgdG8gdGhlIG5ldHdvcmsuCiAgICAgICAgLy8vIEl0IG9ubHkgcHJldmVudHMgY2FuZGlkYXRlIG5vZGVzIGZyb20gam9pbmluZy4gSXQgZG9lcyBub3QgY2F1c2UgZXhpc3RpbmcgcGFydGljaXBhbnQgbm9kZXMgdG8gdW5zdGFrZSwKICAgICAgICAvLy8gZXZlbiBpZiB0aGUgbnVtYmVyIG9mIHBhcnRpY2lwYW50IG5vZGVzIGV4Y2VlZHMgdGhlIHNsb3QgbGltaXQuCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIHNldFNsb3RMaW1pdHMoc2xvdExpbWl0czoge1VJbnQ4OiBVSW50MTZ9KSB7CiAgICAgICAgICAgIHByZSB7CiAgICAgICAgICAgICAgICBzbG90TGltaXRzLmtleXMubGVuZ3RoID09IDU6ICJGbG93SURUYWJsZVN0YWtpbmcuQWRtaW4uc2V0U2xvdExpbWl0czogU2xvdCBMaW1pdHMgRGljdGlvbmFyeSBjYW4gb25seSBoYXZlIDUgZW50cmllcyBidXQgZ290IFwoc2xvdExpbWl0cy5rZXlzLmxlbmd0aCkiCiAgICAgICAgICAgICAgICBzbG90TGltaXRzWzFdICE9IG5pbDogIkZsb3dJRFRhYmxlU3Rha2luZy5BZG1pbi5zZXRTbG90TGltaXRzOiBOZWVkIHRvIGhhdmUgYSBsaW1pdCBzZXQgZm9yIGNvbGxlY3RvciBub2RlcyIKICAgICAgICAgICAgICAgIHNsb3RMaW1pdHNbMl0gIT0gbmlsOiAiRmxvd0lEVGFibGVTdGFraW5nLkFkbWluLnNldFNsb3RMaW1pdHM6IE5lZWQgdG8gaGF2ZSBhIGxpbWl0IHNldCBmb3IgY29uc2Vuc3VzIG5vZGVzIgogICAgICAgICAgICAgICAgc2xvdExpbWl0c1szXSAhPSBuaWw6ICJGbG93SURUYWJsZVN0YWtpbmcuQWRtaW4uc2V0U2xvdExpbWl0czogTmVlZCB0byBoYXZlIGEgbGltaXQgc2V0IGZvciBleGVjdXRpb24gbm9kZXMiCiAgICAgICAgICAgICAgICBzbG90TGltaXRzWzRdICE9IG5pbDogIkZsb3dJRFRhYmxlU3Rha2luZy5BZG1pbi5zZXRTbG90TGltaXRzOiBOZWVkIHRvIGhhdmUgYSBsaW1pdCBzZXQgZm9yIHZlcmlmaWNhdGlvbiBub2RlcyIKICAgICAgICAgICAgICAgIHNsb3RMaW1pdHNbNV0gIT0gbmlsOiAiRmxvd0lEVGFibGVTdGFraW5nLkFkbWluLnNldFNsb3RMaW1pdHM6IE5lZWQgdG8gaGF2ZSBhIGxpbWl0IHNldCBmb3IgYWNjZXNzIG5vZGVzIgogICAgICAgICAgICB9CgogICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcuYWNjb3VudC5zdG9yYWdlLmxvYWQ8e1VJbnQ4OiBVSW50MTZ9Pihmcm9tOiAvc3RvcmFnZS9mbG93U3Rha2luZ1Nsb3RMaW1pdHMpCiAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy5hY2NvdW50LnN0b3JhZ2Uuc2F2ZShzbG90TGltaXRzLCB0bzogL3N0b3JhZ2UvZmxvd1N0YWtpbmdTbG90TGltaXRzKQogICAgICAgIH0KCiAgICAgICAgLy8vIFNldHMgdGhlIG51bWJlciBvZiBvcGVuIG5vZGUgc2xvdHMgdG8gYWxsb3cgcGVyIGVwb2NoCiAgICAgICAgLy8vIE9ubHkgYWNjZXNzIG5vZGVzIGFyZSB1c2VkIGZvciB0aGlzIGN1cnJlbnRseSwKICAgICAgICAvLy8gYnV0IG90aGVyIG5vZGUgdHlwZXMgd2lsbCBiZSBhZGRlZCBpbiB0aGUgZnV0dXJlCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIHNldE9wZW5Ob2RlU2xvdHMob3BlblNsb3RzOiB7VUludDg6IFVJbnQxNn0pIHsKICAgICAgICAgICAgcHJlIHsKICAgICAgICAgICAgICAgIG9wZW5TbG90c1s1XSAhPSBuaWw6ICJGbG93SURUYWJsZVN0YWtpbmcuQWRtaW4uc2V0T3Blbk5vZGVTbG90czogTmVlZCB0byBoYXZlIGEgdmFsdWUgc2V0IGZvciBhY2Nlc3Mgbm9kZXMiCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy5hY2NvdW50LnN0b3JhZ2UubG9hZDx7VUludDg6IFVJbnQxNn0+KGZyb206IC9zdG9yYWdlL2Zsb3dTdGFraW5nT3Blbk5vZGVTbG90cykKICAgICAgICAgICAgRmxvd0lEVGFibGVTdGFraW5nLmFjY291bnQuc3RvcmFnZS5zYXZlKG9wZW5TbG90cywgdG86IC9zdG9yYWdlL2Zsb3dTdGFraW5nT3Blbk5vZGVTbG90cykKICAgICAgICB9CgogICAgICAgIC8vLyBTZXRzIGEgbGlzdCBvZiBub2RlIElEcyB3aG8gd2lsbCBub3QgcmVjZWl2ZSByZXdhcmRzIGZvciB0aGUgY3VycmVudCBlcG9jaAogICAgICAgIC8vLyBUaGlzIGlzIHVzZWQgZHVyaW5nIGVwb2NocyB0byBwdW5pc2ggbm9kZXMgd2hvIGhhdmUgcG9vciB1cHRpbWUgCiAgICAgICAgLy8vIG9yIHdobyBkbyBub3QgdXBkYXRlIHRvIGxhdGVzdCBub2RlIHNvZnR3YXJlIHF1aWNrbHkgZW5vdWdoCiAgICAgICAgLy8vIFRoZSBwYXJhbWV0ZXIgaXMgYSBkaWN0aW9uYXJ5IG1hcHBpbmcgbm9kZSBJRHMKICAgICAgICAvLy8gdG8gYSBwZXJjZW50YWdlLCB3aGljaCBpcyB0aGUgcGVyY2VudGFnZSBvZiB0aGVpciBleHBlY3RlZCByZXdhcmRzIHRoYXQKICAgICAgICAvLy8gdGhleSB3aWxsIHJlY2VpdmUgaW5zdGVhZCBvZiB0aGUgZnVsbCBhbW91bnQKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gc2V0Tm9uT3BlcmF0aW9uYWxOb2Rlc0xpc3QoXyBub2RlSURzOiB7U3RyaW5nOiBVRml4NjR9KSB7CiAgICAgICAgICAgIGZvciBwZXJjZW50YWdlIGluIG5vZGVJRHMudmFsdWVzIHsKICAgICAgICAgICAgICAgIGFzc2VydCgKICAgICAgICAgICAgICAgICAgICBwZXJjZW50YWdlID49IDAuMCAmJiBwZXJjZW50YWdlIDwgMS4wLAogICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICJGbG93SURUYWJsZVN0YWtpbmcuQWRtaW4uc2V0Tm9uT3BlcmF0aW9uYWxOb2Rlc0xpc3Q6IFBlcmNlbnRhZ2UgdmFsdWUgdG8gZGVjcmVhc2UgcmV3YXJkcyBwYXlvdXQgc2hvdWxkIGJlIGJldHdlZW4gMCBhbmQgMSBidXQgZ290IFwocGVyY2VudGFnZSkiCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgIH0KICAgICAgICAgICAgRmxvd0lEVGFibGVTdGFraW5nLmFjY291bnQuc3RvcmFnZS5sb2FkPHtTdHJpbmc6IFVGaXg2NH0+KGZyb206IC9zdG9yYWdlL2lkVGFibGVOb25PcGVyYXRpb25hbE5vZGVzTGlzdCkKICAgICAgICAgICAgRmxvd0lEVGFibGVTdGFraW5nLmFjY291bnQuc3RvcmFnZS5zYXZlPHtTdHJpbmc6IFVGaXg2NH0+KG5vZGVJRHMsIHRvOiAvc3RvcmFnZS9pZFRhYmxlTm9uT3BlcmF0aW9uYWxOb2Rlc0xpc3QpCiAgICAgICAgfQoKICAgICAgICAvLy8gQWxsb3dzIHRoZSBwcm90b2NvbCB0byBzZXQgYSBzcGVjaWZpYyB3ZWlnaHQgZm9yIGEgbm9kZQogICAgICAgIC8vLyBpZiB0aGVpciBzdGFrZWQgYW1vdW50IGNoYW5nZXMgb3IgaWYgdGhleSBhcmUgcmVtb3ZlZAogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBzZXROb2RlV2VpZ2h0KG5vZGVJRDogU3RyaW5nLCB3ZWlnaHQ6IFVJbnQ2NCkgewogICAgICAgICAgICBpZiB3ZWlnaHQgPiAxMDAgewogICAgICAgICAgICAgICAgcGFuaWMoIkZsb3dJRFRhYmxlU3Rha2luZy5BZG1pbi5zZXROb2RlV2VpZ2h0OiBTcGVjaWZpZWQgbm9kZSB3ZWlnaHQgb3V0IG9mIHJhbmdlLiBNdXN0IGJlIGJldHdlZW4gMCBhbmQgMTAwIGJ1dCBnb3QgXCh3ZWlnaHQpIikKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGV0IG5vZGVSZWNvcmQgPSBGbG93SURUYWJsZVN0YWtpbmcuYm9ycm93Tm9kZVJlY29yZChub2RlSUQpCiAgICAgICAgICAgIG5vZGVSZWNvcmQuc2V0V2VpZ2h0KHdlaWdodCkKICAgICAgICAgICAgZW1pdCBOb2RlV2VpZ2h0Q2hhbmdlZChub2RlSUQ6IG5vZGVJRCwgbmV3V2VpZ2h0OiB3ZWlnaHQpCiAgICAgICAgfQoKICAgICAgICAvLy8gU2V0cyBhIGxpc3Qgb2YgYXBwcm92ZWQgbm9kZSBJRHMgZm9yIHRoZSBuZXh0IGVwb2NoCiAgICAgICAgLy8vIE5vZGVzIG5vdCBvbiB0aGlzIGxpc3Qgd2lsbCBiZSB1bnN0YWtlZCBhdCB0aGUgZW5kIG9mIHRoZSBzdGFraW5nIGF1Y3Rpb24KICAgICAgICAvLy8gYW5kIG5vdCBjb25zaWRlcmVkIHRvIGJlIGEgcHJvcG9zZWQvc3Rha2VkIG5vZGUKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gc2V0QXBwcm92ZWRMaXN0KF8gbmV3QXBwcm92ZUxpc3Q6IHtTdHJpbmc6IEJvb2x9KSB7CiAgICAgICAgICAgIGxldCBjdXJyZW50QXBwcm92ZUxpc3QgPSBGbG93SURUYWJsZVN0YWtpbmcuZ2V0QXBwcm92ZWRMaXN0KCkKICAgICAgICAgICAgICAgID8/IHBhbmljKCJGbG93SURUYWJsZVN0YWtpbmcuQWRtaW4uc2V0QXBwcm92ZWRMaXN0OiBDb3VsZCBub3QgbG9hZCBhcHByb3ZlIGxpc3QgZnJvbSBzdG9yYWdlIikKCiAgICAgICAgICAgIGZvciBpZCBpbiBuZXdBcHByb3ZlTGlzdCB7CiAgICAgICAgICAgICAgICBpZiBGbG93SURUYWJsZVN0YWtpbmcubm9kZXNbaWRdID09IG5pbCB7CiAgICAgICAgICAgICAgICAgICAgcGFuaWMoIkZsb3dJRFRhYmxlU3Rha2luZy5BZG1pbi5zZXRBcHByb3ZlZExpc3Q6IEFwcHJvdmVkIG5vZGUgXChpZCkgZG9lcyBub3QgYWxyZWFkeSBleGlzdCBpbiB0aGUgaWRlbnRpdHkgdGFibGUiKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBJZiBvbmUgb2YgdGhlIG5vZGVzIGhhcyBiZWVuIHJlbW92ZWQgZnJvbSB0aGUgYXBwcm92ZSBsaXN0CiAgICAgICAgICAgIC8vIGl0IG5lZWQgdG8gYmUgc2V0IGFzIG1vdmVzUGVuZGluZyBzbyBpdCB3aWxsIGJlIGNhdWdodCBpbiB0aGUgYHJlbW92ZUludmFsaWROb2Rlc2AgbWV0aG9kCiAgICAgICAgICAgIC8vIElmIHRoaXMgaGFwcGVucyBub3QgZHVyaW5nIHRoZSBzdGFraW5nIGF1Y3Rpb24sIHRoZSBub2RlIHNob3VsZCBiZSByZW1vdmVkIGFuZCBtYXJrZWQgdG8gdW5zdGFrZSBpbW1lZGlhdGVseQogICAgICAgICAgICBmb3IgaWQgaW4gY3VycmVudEFwcHJvdmVMaXN0IHsKICAgICAgICAgICAgICAgIGlmIG5ld0FwcHJvdmVMaXN0W2lkXSA9PSBuaWwgewogICAgICAgICAgICAgICAgICAgIGlmIEZsb3dJRFRhYmxlU3Rha2luZy5zdGFraW5nRW5hYmxlZCgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgRmxvd0lEVGFibGVTdGFraW5nLm1vZGlmeU5ld01vdmVzUGVuZGluZyhub2RlSUQ6IGlkLCBkZWxlZ2F0b3JJRDogbmlsLCBleGlzdGluZ0xpc3Q6IG5pbCkKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnVuc2FmZVJlbW92ZUFuZFJlZnVuZE5vZGVSZWNvcmQoaWQpCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHNlbGYudW5zYWZlU2V0QXBwcm92ZWRMaXN0KG5ld0FwcHJvdmVMaXN0KQogICAgICAgIH0KCiAgICAgICAgLy8vIFNldHMgdGhlIGFwcHJvdmVkIGxpc3Qgd2l0aG91dCB2YWxpZGF0aW5nIGl0IChyZXF1aXJlcyBjYWxsZXIgdG8gdmFsaWRhdGUpCiAgICAgICAgYWNjZXNzKHNlbGYpIGZ1biB1bnNhZmVTZXRBcHByb3ZlZExpc3QoXyBuZXdBcHByb3ZlTGlzdDoge1N0cmluZzogQm9vbH0pIHsKICAgICAgICAgICAgbGV0IGN1cnJlbnRBcHByb3ZlTGlzdCA9IEZsb3dJRFRhYmxlU3Rha2luZy5hY2NvdW50LnN0b3JhZ2UubG9hZDx7U3RyaW5nOiBCb29sfT4oZnJvbTogL3N0b3JhZ2UvaWRUYWJsZUFwcHJvdmVMaXN0KQogICAgICAgICAgICAgICAgPz8gcGFuaWMoIkZsb3dJRFRhYmxlU3Rha2luZy5BZG1pbi51bnNhZmVTZXRBcHByb3ZlZExpc3Q6IENvdWxkIG5vdCBsb2FkIHRoZSBjdXJyZW50IGFwcHJvdmUgbGlzdCBmcm9tIHN0b3JhZ2UiKQogICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcuYWNjb3VudC5zdG9yYWdlLnNhdmU8e1N0cmluZzogQm9vbH0+KG5ld0FwcHJvdmVMaXN0LCB0bzogL3N0b3JhZ2UvaWRUYWJsZUFwcHJvdmVMaXN0KQogICAgICAgIH0KCiAgICAgICAgLy8vIFJlbW92ZXMgYW5kIHJlZnVuZHMgdGhlIG5vZGUgcmVjb3JkIHdpdGhvdXQgYWxzbyByZW1vdmluZyB0aGVtIGZyb20gdGhlIGFwcHJvdmVkLWxpc3QKICAgICAgICBhY2Nlc3Moc2VsZikgZnVuIHVuc2FmZVJlbW92ZUFuZFJlZnVuZE5vZGVSZWNvcmQoXyBub2RlSUQ6IFN0cmluZykgewogICAgICAgICAgICBsZXQgbm9kZVJlY29yZCA9IEZsb3dJRFRhYmxlU3Rha2luZy5ib3Jyb3dOb2RlUmVjb3JkKG5vZGVJRCkKCiAgICAgICAgICAgIGVtaXQgTm9kZVJlbW92ZWRBbmRSZWZ1bmRlZChub2RlSUQ6IG5vZGVSZWNvcmQuaWQsIGFtb3VudDogbm9kZVJlY29yZC50b2tlbnNDb21taXR0ZWQuYmFsYW5jZSArIG5vZGVSZWNvcmQudG9rZW5zU3Rha2VkLmJhbGFuY2UpCgogICAgICAgICAgICAvLyBtb3ZlIHRoZWlyIGNvbW1pdHRlZCB0b2tlbnMgYmFjayB0byB0aGVpciB1bnN0YWtlZCB0b2tlbnMKICAgICAgICAgICAgbm9kZVJlY29yZC50b2tlbnNVbnN0YWtlZC5kZXBvc2l0KGZyb206IDwtbm9kZVJlY29yZC50b2tlbnNDb21taXR0ZWQud2l0aGRyYXcoYW1vdW50OiBub2RlUmVjb3JkLnRva2Vuc0NvbW1pdHRlZC5iYWxhbmNlKSkKCiAgICAgICAgICAgIC8vIElmIHRoZSBub2RlIGlzIGN1cnJlbnRseSBzdGFrZWQsIHVuc3Rha2UgaXQgYW5kIHN1YnRyYWN0IG9uZSBmcm9tIHRoZSBjb3VudAogICAgICAgICAgICAvLyBpZiBzdGFraW5nIGlzIGN1cnJlbnRseSBkaXNhYmxlZCwgdGhlbiB0aGF0IG1lYW5zIHRoYXQgdGhlIG5vZGUKICAgICAgICAgICAgLy8gaGFzIGFscmVhZHkgYmVlbiBhZGRlZCB0byB0aGUgbm9kZSBjb3VudHMgYW5kIG5lZWRzIHRvIGJlIHN1YnRyYWN0ZWQgYWxzbwogICAgICAgICAgICBpZiBub2RlUmVjb3JkLnRva2Vuc1N0YWtlZC5iYWxhbmNlID4gMC4wIHx8ICFGbG93SURUYWJsZVN0YWtpbmcuc3Rha2luZ0VuYWJsZWQoKSB7CiAgICAgICAgICAgICAgICAvLyBTZXQgdGhlaXIgcmVxdWVzdCB0byB1bnN0YWtlIGVxdWFsIHRvIGFsbCB0aGVpciBzdGFrZWQgdG9rZW5zCiAgICAgICAgICAgICAgICAvLyBzaW5jZSB0aGV5IGFyZSBmb3JjZWQgdG8gdW5zdGFrZQogICAgICAgICAgICAgICAgbm9kZVJlY29yZC5zZXRUb2tlbnNSZXF1ZXN0ZWRUb1Vuc3Rha2Uobm9kZVJlY29yZC50b2tlbnNTdGFrZWQuYmFsYW5jZSkKCiAgICAgICAgICAgICAgICAvLyBTdWJyYWN0IDEgZnJvbSB0aGUgY291bnRzIGZvciB0aGlzIG5vZGUncyByb2xlCiAgICAgICAgICAgICAgICAvLyBTaW5jZSB0aGV5IHdpbGwgbm90IGZpbGwgYW4gb3BlbiBzbG90IGFueSBtb3JlCiAgICAgICAgICAgICAgICB2YXIgY3VycmVudFJvbGVOb2RlQ291bnRzOiB7VUludDg6IFVJbnQxNn0gPSBGbG93SURUYWJsZVN0YWtpbmcuZ2V0Q3VycmVudFJvbGVOb2RlQ291bnRzKCkKICAgICAgICAgICAgICAgIHZhciBjdXJyZW50Um9sZUNvdW50ID0gY3VycmVudFJvbGVOb2RlQ291bnRzW25vZGVSZWNvcmQucm9sZV0hCiAgICAgICAgICAgICAgICBpZiBjdXJyZW50Um9sZUNvdW50ID4gMCB7CiAgICAgICAgICAgICAgICAgICAgY3VycmVudFJvbGVOb2RlQ291bnRzW25vZGVSZWNvcmQucm9sZV0gPSBjdXJyZW50Um9sZUNvdW50IC0gMQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgRmxvd0lEVGFibGVTdGFraW5nLmFjY291bnQuc3RvcmFnZS5sb2FkPHtVSW50ODogVUludDE2fT4oZnJvbTogL3N0b3JhZ2UvZmxvd1N0YWtpbmdSb2xlTm9kZUNvdW50cykKICAgICAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy5hY2NvdW50LnN0b3JhZ2Uuc2F2ZShjdXJyZW50Um9sZU5vZGVDb3VudHMsIHRvOiAvc3RvcmFnZS9mbG93U3Rha2luZ1JvbGVOb2RlQ291bnRzKQogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbW92ZXNQZW5kaW5nTGlzdCA9IEZsb3dJRFRhYmxlU3Rha2luZy5hY2NvdW50LnN0b3JhZ2UuYm9ycm93PGF1dGgoTXV0YXRlKSAme1N0cmluZzoge1VJbnQzMjogQm9vbH19Pihmcm9tOiAvc3RvcmFnZS9pZFRhYmxlTW92ZXNQZW5kaW5nTGlzdCkKICAgICAgICAgICAgICAgID8/IHBhbmljKCJGbG93SURUYWJsZVN0YWtpbmcuQWRtaW4udW5zYWZlUmVtb3ZlQW5kUmVmdW5kTm9kZVJlY29yZDogTm8gbW92ZXMgcGVuZGluZyBsaXN0IGluIGFjY291bnQgc3RvcmFnZSIpCgogICAgICAgICAgICAvLyBJdGVyYXRlIHRocm91Z2ggYWxsIGRlbGVnYXRvcnMgYW5kIHVuc3Rha2UgdGhlaXIgdG9rZW5zCiAgICAgICAgICAgIC8vIHNpbmNlIHRoZWlyIG5vZGUgaGFzIHVuc3Rha2VkCiAgICAgICAgICAgIGxldCBrZXlzID0gbm9kZVJlY29yZC5kZWxlZ2F0b3JzLmtleXMKICAgICAgICAgICAgdmFyIGluZGV4ID0gMAogICAgICAgICAgICB3aGlsZSBpbmRleCA8IGtleXMubGVuZ3RoIHsKICAgICAgICAgICAgICAgIGxldCBkZWxlZ2F0b3IgPSBrZXlzW2luZGV4XQogICAgICAgICAgICAgICAgaW5kZXggPSBpbmRleCArIDEKCiAgICAgICAgICAgICAgICBsZXQgZGVsUmVjb3JkID0gbm9kZVJlY29yZC5ib3Jyb3dEZWxlZ2F0b3JSZWNvcmQoZGVsZWdhdG9yKQoKICAgICAgICAgICAgICAgIGlmIGRlbFJlY29yZC50b2tlbnNDb21taXR0ZWQuYmFsYW5jZSA+IDAuMCB7CiAgICAgICAgICAgICAgICAgICAgZW1pdCBEZWxlZ2F0b3JUb2tlbnNVbnN0YWtlZChub2RlSUQ6IG5vZGVSZWNvcmQuaWQsIGRlbGVnYXRvcklEOiBkZWxlZ2F0b3IsIGFtb3VudDogZGVsUmVjb3JkLnRva2Vuc0NvbW1pdHRlZC5iYWxhbmNlKQoKICAgICAgICAgICAgICAgICAgICAvLyBtb3ZlIHRoZWlyIGNvbW1pdHRlZCB0b2tlbnMgYmFjayB0byB0aGVpciB1bnN0YWtlZCB0b2tlbnMKICAgICAgICAgICAgICAgICAgICBkZWxSZWNvcmQudG9rZW5zVW5zdGFrZWQuZGVwb3NpdChmcm9tOiA8LWRlbFJlY29yZC50b2tlbnNDb21taXR0ZWQud2l0aGRyYXcoYW1vdW50OiBkZWxSZWNvcmQudG9rZW5zQ29tbWl0dGVkLmJhbGFuY2UpKQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIFJlcXVlc3QgdG8gdW5zdGFrZSBhbGwgdG9rZW5zCiAgICAgICAgICAgICAgICBpZiBkZWxSZWNvcmQudG9rZW5zU3Rha2VkLmJhbGFuY2UgPiAwLjAgewogICAgICAgICAgICAgICAgICAgIGRlbFJlY29yZC5zZXRUb2tlbnNSZXF1ZXN0ZWRUb1Vuc3Rha2UoZGVsUmVjb3JkLnRva2Vuc1N0YWtlZC5iYWxhbmNlKQogICAgICAgICAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy5tb2RpZnlOZXdNb3Zlc1BlbmRpbmcobm9kZUlEOiBub2RlUmVjb3JkLmlkLCBkZWxlZ2F0b3JJRDogZGVsZWdhdG9yLCBleGlzdGluZ0xpc3Q6IG1vdmVzUGVuZGluZ0xpc3QpCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy5tb2RpZnlOZXdNb3Zlc1BlbmRpbmcobm9kZUlEOiBub2RlUmVjb3JkLmlkLCBkZWxlZ2F0b3JJRDogbmlsLCBleGlzdGluZ0xpc3Q6IG1vdmVzUGVuZGluZ0xpc3QpCgogICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcucmVtb3ZlRnJvbUNhbmRpZGF0ZU5vZGVMaXN0KG5vZGVJRDogbm9kZVJlY29yZC5pZCwgcm9sZTogbm9kZVJlY29yZC5yb2xlKQoKICAgICAgICAgICAgLy8gQ2xlYXIgaW5pdGlhbCB3ZWlnaHQgYmVjYXVzZSB0aGUgbm9kZSBpcyBub3Qgc3Rha2VkIGFueSBtb3JlCiAgICAgICAgICAgIG5vZGVSZWNvcmQuc2V0V2VpZ2h0KDApCiAgICAgICAgfQoKICAgICAgICAvLy8gUmVtb3ZlcyBub2RlcyBieSBzZXR0aW5nIHRoZWlyIHdlaWdodCB0byB6ZXJvIGFuZCByZWZ1bmRpbmcKICAgICAgICAvLy8gc3Rha2VkIGFuZCBkZWxlZ2F0ZWQgdG9rZW5zLgogICAgICAgIGFjY2VzcyhhbGwpIGZ1biByZW1vdmVBbmRSZWZ1bmROb2RlUmVjb3JkKF8gbm9kZUlEOiBTdHJpbmcpIHsKICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSByZWZ1bmRlZCBub2RlIGZyb20gdGhlIGFwcHJvdmUgbGlzdAogICAgICAgICAgICBsZXQgYXBwcm92ZUxpc3QgPSBGbG93SURUYWJsZVN0YWtpbmcuZ2V0QXBwcm92ZWRMaXN0KCkKICAgICAgICAgICAgICAgID8/IHBhbmljKCJGbG93SURUYWJsZVN0YWtpbmcuQWRtaW4ucmVtb3ZlQW5kUmVmdW5kTm9kZVJlY29yZDogQ291bGQgbm90IGxvYWQgYXBwcm92ZSBsaXN0IGZyb20gc3RvcmFnZSIpCiAgICAgICAgICAgIGFwcHJvdmVMaXN0LnJlbW92ZShrZXk6IG5vZGVJRCkKICAgICAgICAgICAgc2VsZi51bnNhZmVTZXRBcHByb3ZlZExpc3QoYXBwcm92ZUxpc3QpCiAgICAgICAgICAgIHNlbGYudW5zYWZlUmVtb3ZlQW5kUmVmdW5kTm9kZVJlY29yZChub2RlSUQpCiAgICAgICAgfQoKICAgICAgICAvLy8gU3RhcnRzIHRoZSBzdGFraW5nIGF1Y3Rpb24sIHRoZSBwZXJpb2Qgd2hlbiBub2RlcyBhbmQgZGVsZWdhdG9ycwogICAgICAgIC8vLyBhcmUgYWxsb3dlZCB0byBwZXJmb3JtIHN0YWtpbmcgcmVsYXRlZCBvcGVyYXRpb25zCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIHN0YXJ0U3Rha2luZ0F1Y3Rpb24oKSB7CiAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy5hY2NvdW50LnN0b3JhZ2UubG9hZDxCb29sPihmcm9tOiAvc3RvcmFnZS9zdGFraW5nRW5hYmxlZCkKICAgICAgICAgICAgRmxvd0lEVGFibGVTdGFraW5nLmFjY291bnQuc3RvcmFnZS5zYXZlKHRydWUsIHRvOiAvc3RvcmFnZS9zdGFraW5nRW5hYmxlZCkKICAgICAgICB9CgogICAgICAgIC8vLyBFbmRzIHRoZSBzdGFraW5nIEF1Y3Rpb24gYnkgcmVtb3ZpbmcgYW55IHVuYXBwcm92ZWQgbm9kZXMgYW5kIHNldHRpbmcgc3Rha2luZ0VuYWJsZWQgdG8gZmFsc2UKICAgICAgICAvLy8gcmV0dXJucyBhIGxpc3Qgb2YgYWxsIHRoZSBwcm9wb3NlZCBub2RlIElEcyBmb3IgdGhlIG5leHQgZXBvY2gKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gZW5kU3Rha2luZ0F1Y3Rpb24oKTogW1N0cmluZ10gewogICAgICAgICAgICB2YXIgcHJvcG9zZWROb2RlTGlzdCA9IHNlbGYucmVtb3ZlSW52YWxpZE5vZGVzKCkKICAgICAgICAgICAgdmFyIG5ld05vZGVzID0gc2VsZi5maWxsTm9kZVJvbGVTbG90cygpCiAgICAgICAgICAgIGZvciBpZCBpbiBuZXdOb2RlcyB7CiAgICAgICAgICAgICAgICBwcm9wb3NlZE5vZGVMaXN0W2lkXSA9IHRydWUKICAgICAgICAgICAgfQoKICAgICAgICAgICAgRmxvd0lEVGFibGVTdGFraW5nLmFjY291bnQuc3RvcmFnZS5sb2FkPEJvb2w+KGZyb206IC9zdG9yYWdlL3N0YWtpbmdFbmFibGVkKQogICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcuYWNjb3VudC5zdG9yYWdlLnNhdmUoZmFsc2UsIHRvOiAvc3RvcmFnZS9zdGFraW5nRW5hYmxlZCkKCiAgICAgICAgICAgIHJldHVybiBwcm9wb3NlZE5vZGVMaXN0LmtleXMKICAgICAgICB9CgogICAgICAgIC8vLyBJdGVyYXRlcyB0aHJvdWdoIGFsbCB0aGUgcmVnaXN0ZXJlZCBub2RlcyBhbmQgaWYgaXQgZmluZHMKICAgICAgICAvLy8gYSBub2RlIHRoYXQgaGFzIGluc3VmZmljaWVudCB0b2tlbnMgY29tbWl0dGVkIGZvciB0aGUgbmV4dCBlcG9jaCBvciBpc24ndCBpbiB0aGUgYXBwcm92ZWQgbGlzdAogICAgICAgIC8vLyBpdCBtb3ZlcyB0aGVpciBjb21taXR0ZWQgdG9rZW5zIHRvIHRoZWlyIHVuc3Rha2VkIGJ1Y2tldAogICAgICAgIGFjY2VzcyhhbGwpIGZ1biByZW1vdmVJbnZhbGlkTm9kZXMoKToge1N0cmluZzogQm9vbH0gewogICAgICAgICAgICBsZXQgYXBwcm92ZWROb2RlSURzID0gRmxvd0lEVGFibGVTdGFraW5nLmdldEFwcHJvdmVkTGlzdCgpCiAgICAgICAgICAgICAgICA/PyBwYW5pYygiRmxvd0lEVGFibGVTdGFraW5nLkFkbWluLnJlbW92ZUludmFsaWROb2RlczogQ291bGQgbm90IHJlYWQgdGhlIGFwcHJvdmUgbGlzdCBmcm9tIHN0b3JhZ2UiKQoKICAgICAgICAgICAgbGV0IG1vdmVzUGVuZGluZ0xpc3QgPSBGbG93SURUYWJsZVN0YWtpbmcuZ2V0TW92ZXNQZW5kaW5nTGlzdCgpCiAgICAgICAgICAgICAgICA/PyBwYW5pYygiRmxvd0lEVGFibGVTdGFraW5nLkFkbWluLnJlbW92ZUludmFsaWROb2RlczogQ291bGQgbm90IGNvcHkgbW92ZXMgcGVuZGluZyBsaXN0IGZyb20gc3RvcmFnZSIpCgogICAgICAgICAgICBsZXQgcGFydGljaXBhbnRMaXN0ID0gRmxvd0lEVGFibGVTdGFraW5nLmdldFBhcnRpY2lwYW50Tm9kZUxpc3QoKQogICAgICAgICAgICAgICAgPz8gcGFuaWMoIkZsb3dJRFRhYmxlU3Rha2luZy5BZG1pbi5yZW1vdmVJbnZhbGlkTm9kZXM6IENvdWxkIG5vdCBjb3B5IHBhcnRpY2lwYW50IGxpc3QgZnJvbSBzdG9yYWdlIikgICAgCgogICAgICAgICAgICAvLyBXZSBvbmx5IGl0ZXJhdGUgdGhyb3VnaCBtb3Zlc1BlbmRpbmdMaXN0IGhlcmUgYmVjYXVzZSBhbnkgbm9kZQogICAgICAgICAgICAvLyB0aGF0IGhhcyBpbnN1ZmZpY2llbnQgc3Rha2UgY29tbWl0dGVkIHdpbGwgYmUgYmVjYXVzZSBpdCBoYXMgc3VibWl0dGVkCiAgICAgICAgICAgIC8vIGEgc3Rha2luZyBvcGVyYXRpb24gdGhhdCB3b3VsZCBoYXZlIGdvdHRlbiBpdCBpbnRvIHRoYXQgc3RhdGUgdG8gYmUgcmVtb3ZlZAogICAgICAgICAgICAvLyBhbmQgY2FuZGlkYXRlIG5vZGVzIHdpbGwgYWxzbyBiZSBvbiB0aGUgbW92ZXNQZW5kaW5nTGlzdAogICAgICAgICAgICAvLyB0byBnZXQgdGhlaXIgaW5pdGlhbFdlaWdodCBzZXQgdG8gMTAwCiAgICAgICAgICAgIC8vIE5vZGVzIHJlbW92ZWQgZnJvbSB0aGUgYXBwcm92ZSBsaXN0IGFyZSBhbHJlYWR5IHJlZnVuZGVkIGF0IHRoZSB0aW1lCiAgICAgICAgICAgIC8vIG9mIHJlbW92YWwgaW4gdGhlIHNldEFwcHJvdmVkTGlzdCBtZXRob2QKICAgICAgICAgICAgZm9yIG5vZGVJRCBpbiBtb3Zlc1BlbmRpbmdMaXN0IHsKICAgICAgICAgICAgICAgIGxldCBub2RlUmVjb3JkID0gRmxvd0lEVGFibGVTdGFraW5nLmJvcnJvd05vZGVSZWNvcmQobm9kZUlEKQoKICAgICAgICAgICAgICAgIGxldCB0b3RhbFRva2Vuc0NvbW1pdHRlZCA9IG5vZGVSZWNvcmQubm9kZUZ1bGxDb21taXR0ZWRCYWxhbmNlKCkKCiAgICAgICAgICAgICAgICBsZXQgZ3JlYXRlclRoYW5NaW4gPSBGbG93SURUYWJsZVN0YWtpbmcuaXNHcmVhdGVyVGhhbk1pbmltdW1Gb3JSb2xlKG51bVRva2VuczogdG90YWxUb2tlbnNDb21taXR0ZWQsIHJvbGU6IG5vZGVSZWNvcmQucm9sZSkKICAgICAgICAgICAgICAgIGxldCBub2RlSXNBcHByb3ZlZDogQm9vbCA9ICBhcHByb3ZlZE5vZGVJRHNbbm9kZUlEXSA/PyBmYWxzZQoKICAgICAgICAgICAgICAgIC8vIGFkbWluLWFwcHJvdmVkIG5vZGUgcm9sZXMgKGV4ZWN1dGlvbi9jb2xsZWN0aW9uL2NvbnNlbnN1cy92ZXJpZmljYXRpb24pCiAgICAgICAgICAgICAgICAvLyBtdXN0IGJlIGFwcHJvdmVkIEFORCBoYXZlIHN1ZmZpY2llbnQgc3Rha2UKICAgICAgICAgICAgICAgIGlmIG5vZGVSZWNvcmQucm9sZSAhPSBVSW50OCg1KSAmJiAoIWdyZWF0ZXJUaGFuTWluIHx8ICFub2RlSXNBcHByb3ZlZCkgewogICAgICAgICAgICAgICAgICAgIHNlbGYucmVtb3ZlQW5kUmVmdW5kTm9kZVJlY29yZChub2RlSUQpCiAgICAgICAgICAgICAgICAgICAgRmxvd0lEVGFibGVTdGFraW5nLnJlbW92ZUZyb21DYW5kaWRhdGVOb2RlTGlzdChub2RlSUQ6IG5vZGVSZWNvcmQuaWQsIHJvbGU6IG5vZGVSZWNvcmQucm9sZSkKICAgICAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudExpc3QucmVtb3ZlKGtleTogbm9kZVJlY29yZC5pZCkKICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIHBlcm1pc3Npb25sZXNzIG5vZGUgcm9sZXMgKGFjY2VzcykKICAgICAgICAgICAgICAgIC8vIE5PVEU6IEFjY2VzcyBub2RlcyB3aGljaCByZWdpc3RlcmVkIHByaW9yIHRvIHRoZSAxMDAtRkxPVyBzdGFrZSByZXF1aXJlbWVudAogICAgICAgICAgICAgICAgLy8gKHdoaWNoIG11c3QgYmUgYXBwcm92ZWQpIGFyZSBub3QgcmVtb3ZlZCBkdXJpbmcgYSB0ZW1wb3JhcnkgZ3JhY2UgcGVyaW9kIGR1cmluZyAKICAgICAgICAgICAgICAgIC8vIHdoaWNoIHRoZXNlIGdyYW5kZmF0aGVyZWQgbm9kZSBvcGVyYXRvcnMgbWF5IHN1Ym1pdCB0aGUgbmVjZXNzYXJ5IHN0YWtlIHJlcXVpcmVtZW50LgogICAgICAgICAgICAgICAgLy8gVGhlcmVmb3JlIEFjY2VzcyBub2RlcyBtdXN0IGVpdGhlciBiZSBhcHByb3ZlZCBPUiBoYXZlIHN1ZmZpY2llbnQgc3Rha2U6CiAgICAgICAgICAgICAgICAvLyAgLSBPbGQgQU5zIG11c3QgYmUgYXBwcm92ZWQsIGJ1dCBhcmUgYWxsb3dlZCB0byBoYXZlIHplcm8gc3Rha2UKICAgICAgICAgICAgICAgIC8vICAtIE5ldyBBTnMgbWF5IGJlIHVuYXBwcm92ZWQsIGJ1dCBtdXN0IGhhdmUgc3VibWl0dGVkIHN1ZmZpY2llbnQgc3Rha2UKICAgICAgICAgICAgICAgIGlmIG5vZGVSZWNvcmQucm9sZSA9PSBVSW50OCg1KSAmJiAhZ3JlYXRlclRoYW5NaW4gJiYgIW5vZGVJc0FwcHJvdmVkIHsKICAgICAgICAgICAgICAgICAgICBzZWxmLnJlbW92ZUFuZFJlZnVuZE5vZGVSZWNvcmQobm9kZUlEKQogICAgICAgICAgICAgICAgICAgIHBhcnRpY2lwYW50TGlzdC5yZW1vdmUoa2V5OiBub2RlUmVjb3JkLmlkKQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgbm9kZVJlY29yZC5zZXRXZWlnaHQoMTAwKQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gcGFydGljaXBhbnRMaXN0CiAgICAgICAgfQoKICAgICAgICAvLy8gRWFjaCBub2RlIHJvbGUgb25seSBoYXMgYSBjZXJ0YWluIG51bWJlciBvZiBzbG90cyBhdmFpbGFibGUgcGVyIGVwb2NoCiAgICAgICAgLy8vIHNvIGlmIHRoZXJlIGFyZSBtb3JlIGNhbmRpZGF0ZSBub2RlcyBmb3IgdGhhdCByb2xlIHRoYW4gdGhlcmUgYXJlIHNsb3RzCiAgICAgICAgLy8vIG5vZGVzIGFyZSByYW5kb21seSBzZWxlY3RlZCBmcm9tIHRoZSBsaXN0IHRvIGJlIGluY2x1ZGVkLgogICAgICAgIC8vLyBOb2RlcyB3aGljaCBhcmUgbm90IHNlbGVjdGVkIGZvciBpbmNsdXNpb24gYXJlIHJlbW92ZWQgYW5kIHJlZnVuZGVkIGluIHRoaXMgZnVuY3Rpb24uCiAgICAgICAgLy8vIEFsbCBjYW5kaWRhdGUgbm9kZXMgbGVmdCBzdGFrZWQgYWZ0ZXIgdGhpcyBmdW5jdGlvbiBleGl0cyBhcmUgaW1wbGljaXRseSBzZWxlY3RlZCB0byBmaWxsIHRoZSAKICAgICAgICAvLy8gYXZhaWxhYmxlIHNsb3RzLCBhbmQgd2lsbCBiZWNvbWUgcGFydGljaXBhbnRzIGF0IHRoZSBuZXh0IGVwb2NoIHRyYW5zaXRpb24uCiAgICAgICAgLy8vIAogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBmaWxsTm9kZVJvbGVTbG90cygpOiBbU3RyaW5nXSB7CgogICAgICAgICAgICB2YXIgY3VycmVudE5vZGVDb3VudDoge1VJbnQ4OiBVSW50MTZ9ID0gRmxvd0lEVGFibGVTdGFraW5nLmdldEN1cnJlbnRSb2xlTm9kZUNvdW50cygpCgogICAgICAgICAgICBsZXQgc2xvdExpbWl0czoge1VJbnQ4OiBVSW50MTZ9ID0gRmxvd0lEVGFibGVTdGFraW5nLmdldFJvbGVTbG90TGltaXRzKCkKCiAgICAgICAgICAgIGxldCBvcGVuU2xvdHMgPSBGbG93SURUYWJsZVN0YWtpbmcuZ2V0T3Blbk5vZGVTbG90cygpCiAgICAgICAgICAgIAogICAgICAgICAgICBsZXQgbm9kZXNUb0FkZDogW1N0cmluZ10gPSBbXQoKICAgICAgICAgICAgLy8gTG9hZCBhbmQgcmVzZXQgdGhlIGNhbmRpZGF0ZSBub2RlIGxpc3QKICAgICAgICAgICAgbGV0IGNhbmRpZGF0ZU5vZGVzID0gRmxvd0lEVGFibGVTdGFraW5nLmFjY291bnQuc3RvcmFnZS5sb2FkPHtVSW50ODoge1N0cmluZzogQm9vbH19Pihmcm9tOiAvc3RvcmFnZS9pZFRhYmxlQ2FuZGlkYXRlTm9kZXMpID8/IHt9CiAgICAgICAgICAgIGxldCBlbXB0eUNhbmRpZGF0ZU5vZGVzOiB7VUludDg6IHtTdHJpbmc6IEJvb2x9fSA9IHsxOiB7fSwgMjoge30sIDM6IHt9LCA0OiB7fSwgNToge319CiAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy5hY2NvdW50LnN0b3JhZ2Uuc2F2ZShlbXB0eUNhbmRpZGF0ZU5vZGVzLCB0bzogL3N0b3JhZ2UvaWRUYWJsZUNhbmRpZGF0ZU5vZGVzKQoKICAgICAgICAgICAgZm9yIHJvbGUgaW4gY3VycmVudE5vZGVDb3VudC5rZXlzIHsKCiAgICAgICAgICAgICAgICBsZXQgY2FuZGlkYXRlTm9kZXNGb3JSb2xlID0gY2FuZGlkYXRlTm9kZXNbcm9sZV0hCiAgICAgICAgICAgICAgICBsZXQgbm9kZXNUb1JlbW92ZUZyb21DYW5kaWRhdGVOb2RlczogW1N0cmluZ10gPSBbXQoKICAgICAgICAgICAgICAgIGlmIGN1cnJlbnROb2RlQ291bnRbcm9sZV0hID49IHNsb3RMaW1pdHNbcm9sZV0hIHsKICAgICAgICAgICAgICAgICAgICAvLyBpZiBhbGwgc2xvdHMgYXJlIGZ1bGwsIHJlbW92ZSBhbmQgcmVmdW5kIGFsbCBwZW5kaW5nIG5vZGVzCiAgICAgICAgICAgICAgICAgICAgZm9yIG5vZGVJRCBpbiBjYW5kaWRhdGVOb2Rlc0ZvclJvbGUgewogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnJlbW92ZUFuZFJlZnVuZE5vZGVSZWNvcmQobm9kZUlEKQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSBpZiBjdXJyZW50Tm9kZUNvdW50W3JvbGVdISArIFVJbnQxNihjYW5kaWRhdGVOb2Rlc0ZvclJvbGUua2V5cy5sZW5ndGgpID4gc2xvdExpbWl0c1tyb2xlXSEgewogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIC8vIE5vdCBhbGwgc2xvdHMgYXJlIGZ1bGwsIGJ1dCBhZGRpdGlvbiBvZiBhbGwgdGhlIGNhbmRpZGF0ZSBub2RlcyBleGNlZWRzIHRoZSBzbG90IGxpbWl0CiAgICAgICAgICAgICAgICAgICAgLy8gQ2FsY3VsYXRlIGhvdyBtYW55IG5vZGVzIHRvIHJlbW92ZSBmcm9tIHRoZSBjYW5kaWRhdGUgbGlzdCBmb3IgdGhpcyByb2xlCiAgICAgICAgICAgICAgICAgICAgdmFyIG51bU5vZGVzVG9SZW1vdmU6IFVJbnQxNiA9IGN1cnJlbnROb2RlQ291bnRbcm9sZV0hICsgVUludDE2KGNhbmRpZGF0ZU5vZGVzRm9yUm9sZS5rZXlzLmxlbmd0aCkgLSBzbG90TGltaXRzW3JvbGVdIQogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIGxldCBudW1Ob2Rlc1RvQWRkID0gVUludDE2KGNhbmRpZGF0ZU5vZGVzRm9yUm9sZS5rZXlzLmxlbmd0aCkgLSBudW1Ob2Rlc1RvUmVtb3ZlCgogICAgICAgICAgICAgICAgICAgIC8vIEluZGljYXRlcyB3aGljaCBpbmRpY2llcyBpbiB0aGUgY2FuZGlkYXRlIG5vZGVzIGFycmF5IHdpbGwgYmUgcmVtb3ZlZAogICAgICAgICAgICAgICAgICAgIHZhciBkZWxldGlvbkxpc3Q6IHtVSW50MTY6IEJvb2x9ID0ge30KICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAvLyBSYW5kb21seSBzZWxlY3Qgd2hpY2ggaW5kaWNpZXMgd2lsbCBiZSByZW1vdmVkCiAgICAgICAgICAgICAgICAgICAgd2hpbGUgbnVtTm9kZXNUb1JlbW92ZSA+IDAgewogICAgICAgICAgICAgICAgICAgICAgICBsZXQgc2VsZWN0aW9uID0gcmV2ZXJ0aWJsZVJhbmRvbTxVSW50MTY+KG1vZHVsbzogVUludDE2KGNhbmRpZGF0ZU5vZGVzRm9yUm9sZS5rZXlzLmxlbmd0aCkpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSBpbmRleCBoYXMgYWxyZWFkeSwgYmVlbiBzZWxlY3RlZCwgdHJ5IGFnYWluCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIGl0IGhhcyBub3QsIG1hcmsgaXQgdG8gYmUgcmVtb3ZlZAogICAgICAgICAgICAgICAgICAgICAgICBpZiBkZWxldGlvbkxpc3Rbc2VsZWN0aW9uXSA9PSBuaWwgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRpb25MaXN0W3NlbGVjdGlvbl0gPSB0cnVlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1Ob2Rlc1RvUmVtb3ZlID0gbnVtTm9kZXNUb1JlbW92ZSAtIDEKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gUmVtb3ZlIGFuZCBSZWZ1bmQgdGhlIHNlbGVjdGVkIG5vZGVzCiAgICAgICAgICAgICAgICAgICAgZm9yIG5vZGVJbmRleCBpbiBkZWxldGlvbkxpc3QgewogICAgICAgICAgICAgICAgICAgICAgICBsZXQgbm9kZUlEID0gY2FuZGlkYXRlTm9kZXNGb3JSb2xlLmtleXNbbm9kZUluZGV4XQogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnJlbW92ZUFuZFJlZnVuZE5vZGVSZWNvcmQobm9kZUlEKQogICAgICAgICAgICAgICAgICAgICAgICBub2Rlc1RvUmVtb3ZlRnJvbUNhbmRpZGF0ZU5vZGVzLmFwcGVuZChub2RlSUQpCiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBTZXQgdGhlIGN1cnJlbnQgbm9kZSBjb3VudCBmb3IgdGhlIHJvbGUgdG8gdGhlIGxpbWl0IGZvciB0aGUgcm9sZSwgc2luY2UgdGhleSB3ZXJlIGFsbCBmaWxsZWQKICAgICAgICAgICAgICAgICAgICBjdXJyZW50Tm9kZUNvdW50W3JvbGVdID0gY3VycmVudE5vZGVDb3VudFtyb2xlXSEgKyBudW1Ob2Rlc1RvQWRkCgogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvLyBOb3QgYWxsIHRoZSBzbG90cyBhcmUgZnVsbCwgYW5kIHRoZSBhZGRpdGlvbiBvZiBhbGwgdGhlIGNhbmRpZGF0ZSBub2RlcwogICAgICAgICAgICAgICAgICAgIC8vIGRvZXMgbm90IGV4Y2VlZCB0aGUgc2xvdCBsaW1pdAogICAgICAgICAgICAgICAgICAgIC8vIE5vIGFjdGlvbiBpcyBuZWVkZWQgdG8gbWFyayB0aGUgbm9kZXMgYXMgYWRkZWQgYmVjYXVzZSB0aGV5IGFyZSBhbHJlYWR5IGluY2x1ZGVkCiAgICAgICAgICAgICAgICAgICAgY3VycmVudE5vZGVDb3VudFtyb2xlXSA9IGN1cnJlbnROb2RlQ291bnRbcm9sZV0hICsgVUludDE2KGNhbmRpZGF0ZU5vZGVzRm9yUm9sZS5rZXlzLmxlbmd0aCkKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBSZW1vdmUgdGhlIHJlZnVuZGVkIG5vZGVzIGZyb20gdGhlIGNhbmRpZGF0ZSBub2RlcyBsaXN0CiAgICAgICAgICAgICAgICBmb3Igbm9kZSBpbiBub2Rlc1RvUmVtb3ZlRnJvbUNhbmRpZGF0ZU5vZGVzIHsKICAgICAgICAgICAgICAgICAgICBjYW5kaWRhdGVOb2Rlc0ZvclJvbGUucmVtb3ZlKGtleTogbm9kZSkKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBub2Rlc1RvQWRkLmFwcGVuZEFsbChjYW5kaWRhdGVOb2Rlc0ZvclJvbGUua2V5cykKCiAgICAgICAgICAgICAgICAvLyBBZGQgdGhlIGRlc2lyZWQgb3BlbiBzbG90cyBmb3IgZWFjaCByb2xlIHRvIHRoZSBjdXJyZW50IG5vZGUgY291bnQKICAgICAgICAgICAgICAgIC8vIHRvIG1ha2UgdGhlIHNsb3QgbGltaXRzLiBUaGlzIGNvdWxkIGxvd2VyIHRoZSBzbG90IGxpbWl0cyBpZiB0aGUKICAgICAgICAgICAgICAgIC8vIG5ldyBvcGVuIHNsb3RzIGFyZSBsb3dlciB0aGFuIHRoZSBleGlzdGluZyBzbG90IGxpbWl0cwogICAgICAgICAgICAgICAgaWYgbGV0IG9wZW5TbG90c0ZvclJvbGUgPSBvcGVuU2xvdHNbcm9sZV0gewogICAgICAgICAgICAgICAgICAgIHNsb3RMaW1pdHNbcm9sZV0gPSBjdXJyZW50Tm9kZUNvdW50W3JvbGVdISArIG9wZW5TbG90c0ZvclJvbGUKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgRmxvd0lEVGFibGVTdGFraW5nLmFjY291bnQuc3RvcmFnZS5sb2FkPHtVSW50ODogVUludDE2fT4oZnJvbTogL3N0b3JhZ2UvZmxvd1N0YWtpbmdSb2xlTm9kZUNvdW50cykKICAgICAgICAgICAgRmxvd0lEVGFibGVTdGFraW5nLmFjY291bnQuc3RvcmFnZS5zYXZlKGN1cnJlbnROb2RlQ291bnQsIHRvOiAvc3RvcmFnZS9mbG93U3Rha2luZ1JvbGVOb2RlQ291bnRzKQoKICAgICAgICAgICAgc2VsZi5zZXRTbG90TGltaXRzKHNsb3RMaW1pdHM6IHNsb3RMaW1pdHMpCgogICAgICAgICAgICByZXR1cm4gbm9kZXNUb0FkZAogICAgICAgIH0KCiAgICAgICAgLy8vIENhbGxlZCBhdCB0aGUgZW5kIG9mIHRoZSBlcG9jaCB0byBwYXkgcmV3YXJkcyB0byBub2RlIG9wZXJhdG9ycwogICAgICAgIC8vLyBiYXNlZCBvbiB0aGUgdG9rZW5zIHRoYXQgdGhleSBoYXZlIHN0YWtlZAogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBwYXlSZXdhcmRzKGZvckVwb2NoQ291bnRlcjogVUludDY0LCByZXdhcmRzU3VtbWFyeTogRXBvY2hSZXdhcmRzU3VtbWFyeSkgewoKICAgICAgICAgICAgbGV0IHJld2FyZHNCcmVha2Rvd25BcnJheSA9IHJld2FyZHNTdW1tYXJ5LmJyZWFrZG93bgogICAgICAgICAgICBsZXQgdG90YWxSZXdhcmRzID0gcmV3YXJkc1N1bW1hcnkudG90YWxSZXdhcmRzCiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgbm8gbm9kZSBvcGVyYXRvcnMgdG8gcGF5IHJld2FyZHMgdG8sIGRvIG5vdCBtaW50IG5ldyB0b2tlbnMKICAgICAgICAgICAgaWYgcmV3YXJkc0JyZWFrZG93bkFycmF5Lmxlbmd0aCA9PSAwIHsKICAgICAgICAgICAgICAgIGVtaXQgRXBvY2hUb3RhbFJld2FyZHNQYWlkKHRvdGFsOiB0b3RhbFJld2FyZHMsIGZyb21GZWVzOiAwLjAsIG1pbnRlZDogMC4wLCBmZWVzQnVybmVkOiAwLjAsIGVwb2NoQ291bnRlckZvclJld2FyZHM6IGZvckVwb2NoQ291bnRlcikKCiAgICAgICAgICAgICAgICAvLyBDbGVhciB0aGUgbm9uLW9wZXJhdGlvbmFsIG5vZGUgbGlzdCBzbyBpdCBkb2Vzbid0IHBlcnNpc3QgdG8gdGhlIG5leHQgcmV3YXJkcyBwYXltZW50CiAgICAgICAgICAgICAgICBsZXQgZW1wdHlOb2RlTGlzdDoge1N0cmluZzogVUZpeDY0fSA9IHt9CiAgICAgICAgICAgICAgICBzZWxmLnNldE5vbk9wZXJhdGlvbmFsTm9kZXNMaXN0KGVtcHR5Tm9kZUxpc3QpCgogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIH0gCgogICAgICAgICAgICBsZXQgZmVlQmFsYW5jZSA9IEZsb3dGZWVzLmdldEZlZUJhbGFuY2UoKQogICAgICAgICAgICB2YXIgbWludGVkUmV3YXJkczogVUZpeDY0ID0gMC4wCiAgICAgICAgICAgIGlmIGZlZUJhbGFuY2UgPCB0b3RhbFJld2FyZHMgewogICAgICAgICAgICAgICAgbWludGVkUmV3YXJkcyA9IHRvdGFsUmV3YXJkcyAtIGZlZUJhbGFuY2UKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQm9ycm93IHRoZSBmZWUgYWRtaW4gYW5kIHdpdGhkcmF3IGFsbCB0aGUgZmVlcyB0aGF0IGhhdmUgYmVlbiBjb2xsZWN0ZWQgc2luY2UgdGhlIGxhc3QgcmV3YXJkcyBwYXltZW50CiAgICAgICAgICAgIGxldCBmZWVBZG1pbiA9IEZsb3dJRFRhYmxlU3Rha2luZy5ib3Jyb3dGZWVzQWRtaW4oKQogICAgICAgICAgICBsZXQgcmV3YXJkc1ZhdWx0IDwtIGZlZUFkbWluLndpdGhkcmF3VG9rZW5zRnJvbUZlZVZhdWx0KGFtb3VudDogZmVlQmFsYW5jZSkKCiAgICAgICAgICAgIC8vIE1pbnQgdGhlIHJlbWFpbmluZyBGTE9XIGZvciByZXdhcmRzCiAgICAgICAgICAgIGlmIG1pbnRlZFJld2FyZHMgPiAwLjAgewogICAgICAgICAgICAgICAgbGV0IGZsb3dUb2tlbk1pbnRlciA9IEZsb3dJRFRhYmxlU3Rha2luZy5hY2NvdW50LnN0b3JhZ2UuYm9ycm93PCZGbG93VG9rZW4uTWludGVyPihmcm9tOiAvc3RvcmFnZS9mbG93VG9rZW5NaW50ZXIpCiAgICAgICAgICAgICAgICAgICAgPz8gcGFuaWMoIkZsb3dJRFRhYmxlU3Rha2luZy5Ob2RlU3Rha2VyLnBheVJld2FyZHM6IENvdWxkIG5vdCBib3Jyb3cgbWludGVyIHJlZmVyZW5jZSIpCiAgICAgICAgICAgICAgICByZXdhcmRzVmF1bHQuZGVwb3NpdChmcm9tOiA8LWZsb3dUb2tlbk1pbnRlci5taW50VG9rZW5zKGFtb3VudDogbWludGVkUmV3YXJkcykpCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciByZXdhcmRCcmVha2Rvd24gaW4gcmV3YXJkc0JyZWFrZG93bkFycmF5IHsKICAgICAgICAgICAgICAgIGxldCBub2RlUmVjb3JkID0gRmxvd0lEVGFibGVTdGFraW5nLmJvcnJvd05vZGVSZWNvcmQocmV3YXJkQnJlYWtkb3duLm5vZGVJRCkKICAgICAgICAgICAgICAgIGxldCBub2RlUmV3YXJkID0gcmV3YXJkQnJlYWtkb3duLm5vZGVSZXdhcmRzCiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIG5vZGVSZWNvcmQudG9rZW5zUmV3YXJkZWQuZGVwb3NpdChmcm9tOiA8LXJld2FyZHNWYXVsdC53aXRoZHJhdyhhbW91bnQ6IG5vZGVSZXdhcmQpKQoKICAgICAgICAgICAgICAgIGZvciBkZWxlZ2F0b3IgaW4gcmV3YXJkQnJlYWtkb3duLmRlbGVnYXRvclJld2FyZHMua2V5cyB7CiAgICAgICAgICAgICAgICAgICAgbGV0IGRlbFJlY29yZCA9IG5vZGVSZWNvcmQuYm9ycm93RGVsZWdhdG9yUmVjb3JkKGRlbGVnYXRvcikKICAgICAgICAgICAgICAgICAgICBsZXQgZGVsZWdhdG9yUmV3YXJkID0gcmV3YXJkQnJlYWtkb3duLmRlbGVnYXRvclJld2FyZHNbZGVsZWdhdG9yXSEKICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgZGVsUmVjb3JkLnRva2Vuc1Jld2FyZGVkLmRlcG9zaXQoZnJvbTogPC1yZXdhcmRzVmF1bHQud2l0aGRyYXcoYW1vdW50OiBkZWxlZ2F0b3JSZXdhcmQpKQogICAgICAgICAgICAgICAgICAgIGVtaXQgRGVsZWdhdG9yUmV3YXJkc1BhaWQobm9kZUlEOiByZXdhcmRCcmVha2Rvd24ubm9kZUlELCBkZWxlZ2F0b3JJRDogZGVsZWdhdG9yLCBhbW91bnQ6IGRlbGVnYXRvclJld2FyZCwgZXBvY2hDb3VudGVyOiBmb3JFcG9jaENvdW50ZXIpCiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZW1pdCBSZXdhcmRzUGFpZChub2RlSUQ6IHJld2FyZEJyZWFrZG93bi5ub2RlSUQsIGFtb3VudDogbm9kZVJld2FyZCwgZXBvY2hDb3VudGVyOiBmb3JFcG9jaENvdW50ZXIpCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBmcm9tRmVlcyA9IGZlZUJhbGFuY2UKICAgICAgICAgICAgaWYgZmVlQmFsYW5jZSA+PSB0b3RhbFJld2FyZHMgewogICAgICAgICAgICAgICAgZnJvbUZlZXMgPSB0b3RhbFJld2FyZHMKICAgICAgICAgICAgfQogICAgICAgICAgICBlbWl0IEVwb2NoVG90YWxSZXdhcmRzUGFpZCh0b3RhbDogdG90YWxSZXdhcmRzLCBmcm9tRmVlczogZnJvbUZlZXMsIG1pbnRlZDogbWludGVkUmV3YXJkcywgZmVlc0J1cm5lZDogcmV3YXJkc1ZhdWx0LmJhbGFuY2UsIGVwb2NoQ291bnRlckZvclJld2FyZHM6IGZvckVwb2NoQ291bnRlcikKCiAgICAgICAgICAgIC8vIENsZWFyIHRoZSBub24tb3BlcmF0aW9uYWwgbm9kZSBsaXN0IHNvIGl0IGRvZXNuJ3QgcGVyc2lzdCB0byB0aGUgbmV4dCByZXdhcmRzIHBheW1lbnQKICAgICAgICAgICAgbGV0IGVtcHR5Tm9kZUxpc3Q6IHtTdHJpbmc6IFVGaXg2NH0gPSB7fQogICAgICAgICAgICBzZWxmLnNldE5vbk9wZXJhdGlvbmFsTm9kZXNMaXN0KGVtcHR5Tm9kZUxpc3QpCgogICAgICAgICAgICAvLyBEZXN0cm95IHRoZSByZW1haW5pbmcgZmVlcywgZXZlbiBpZiB0aGVyZSBhcmUgc29tZSBsZWZ0CiAgICAgICAgICAgIEJ1cm5lci5idXJuKDwtcmV3YXJkc1ZhdWx0KQogICAgICAgIH0KCiAgICAgICAgLy8vIENhbGN1bGF0ZXMgcmV3YXJkcyBmb3IgYWxsIHRoZSBzdGFrZWQgbm9kZSBvcGVyYXRvcnMgYW5kIGRlbGVnYXRvcnMKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gY2FsY3VsYXRlUmV3YXJkcygpOiBFcG9jaFJld2FyZHNTdW1tYXJ5IHsKICAgICAgICAgICAgbGV0IHN0YWtlZE5vZGVJRHM6IHtTdHJpbmc6IEJvb2x9ID0gRmxvd0lEVGFibGVTdGFraW5nLmdldFBhcnRpY2lwYW50Tm9kZUxpc3QoKSEKCiAgICAgICAgICAgIC8vIEdldCB0aGUgc3VtIG9mIGFsbCB0b2tlbnMgc3Rha2VkCiAgICAgICAgICAgIHZhciB0b3RhbFN0YWtlZCA9IEZsb3dJRFRhYmxlU3Rha2luZy5nZXRUb3RhbFN0YWtlZCgpCiAgICAgICAgICAgIGlmIHRvdGFsU3Rha2VkID09IDAuMCB7CiAgICAgICAgICAgICAgICByZXR1cm4gRXBvY2hSZXdhcmRzU3VtbWFyeSh0b3RhbFJld2FyZHM6IDAuMCwgYnJlYWtkb3duOiBbXSkKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBDYWxjdWxhdGUgdGhlIHNjYWxlIHRvIGJlIG11bHRpcGxpZWQgYnkgbnVtYmVyIG9mIHRva2VucyBzdGFrZWQgcGVyIG5vZGUKICAgICAgICAgICAgdmFyIHRvdGFsUmV3YXJkU2NhbGUgPSBGbG93SURUYWJsZVN0YWtpbmcuZXBvY2hUb2tlblBheW91dCAvIHRvdGFsU3Rha2VkCgogICAgICAgICAgICB2YXIgcmV3YXJkc0JyZWFrZG93bkFycmF5OiBbRmxvd0lEVGFibGVTdGFraW5nLlJld2FyZHNCcmVha2Rvd25dID0gW10KCiAgICAgICAgICAgIC8vIFRoZSB0b3RhbCByZXdhcmRzIHRoYXQgYXJlIHdpdGhoZWxkIGZyb20gdGhlIG5vbi1vcGVyYXRpb25hbCBub2RlcwogICAgICAgICAgICB2YXIgc3VtUmV3YXJkc1dpdGhoZWxkID0gMC4wCgogICAgICAgICAgICAvLyBUaGUgdG90YWwgYW1vdW50IG9mIHN0YWtlIGZyb20gbm9uLW9wZXJhdGlvbmFsIG5vZGVzIGFuZCBkZWxlZ2F0b3JzCiAgICAgICAgICAgIHZhciBzdW1TdGFrZUZyb21Ob25PcGVyYXRpb25hbFN0YWtlcnMgPSAwLjAKCiAgICAgICAgICAgIC8vIEl0ZXJhdGUgdGhyb3VnaCBhbGwgdGhlIG5vbi1vcGVyYXRpb25hbCBub2RlcyBhbmQgY2FsY3VsYXRlCiAgICAgICAgICAgIC8vIHRoZWlyIHJld2FyZHMgdGhhdCB3aWxsIGJlIHdpdGhoZWxkCiAgICAgICAgICAgIGxldCBub25PcGVyYXRpb25hbE5vZGVzID0gRmxvd0lEVGFibGVTdGFraW5nLmdldE5vbk9wZXJhdGlvbmFsTm9kZXNMaXN0KCkKICAgICAgICAgICAgZm9yIG5vZGVJRCBpbiBub25PcGVyYXRpb25hbE5vZGVzIHsKICAgICAgICAgICAgICAgIGxldCBub2RlUmVjb3JkID0gRmxvd0lEVGFibGVTdGFraW5nLmJvcnJvd05vZGVSZWNvcmQobm9kZUlEKQoKICAgICAgICAgICAgICAgIC8vIEVhY2ggbm9kZSdzIHJld2FyZHMgY2FuIGJlIGRlY3JlYXNlZCB0byBhIGRpZmZlcmVudCBwZXJjZW50YWdlCiAgICAgICAgICAgICAgICAvLyBJdHMgZGVsZWdhdG9yJ3MgcmV3YXJkcyBhcmUgYWxzbyBkZWNyZWFzZWQgdG8gdGhlIHNhbWUgcGVyY2VudGFnZQogICAgICAgICAgICAgICAgbGV0IHJld2FyZERlY3JlYXNlVG9QZXJjZW50YWdlID0gbm9uT3BlcmF0aW9uYWxOb2Rlc1tub2RlSURdIQoKICAgICAgICAgICAgICAgIHN1bVN0YWtlRnJvbU5vbk9wZXJhdGlvbmFsU3Rha2VycyA9IHN1bVN0YWtlRnJvbU5vbk9wZXJhdGlvbmFsU3Rha2VycyArIG5vZGVSZWNvcmQudG9rZW5zU3Rha2VkLmJhbGFuY2UKCiAgICAgICAgICAgICAgICAvLyBDYWxjdWxhdGUgdGhlIG5vcm1hbCByZXdhcmQgYW1vdW50LCB0aGVuIHRoZSByZXdhcmRzIGxlZnQgYWZ0ZXIgdGhlIGRlY3JlYXNlCiAgICAgICAgICAgICAgICB2YXIgbm9kZVJld2FyZEFtb3VudCA9IG5vZGVSZWNvcmQudG9rZW5zU3Rha2VkLmJhbGFuY2UgKiB0b3RhbFJld2FyZFNjYWxlCiAgICAgICAgICAgICAgICB2YXIgbm9kZVJld2FyZHNBZnRlcldpdGhob2xkaW5nID0gbm9kZVJld2FyZEFtb3VudCAqIHJld2FyZERlY3JlYXNlVG9QZXJjZW50YWdlCgogICAgICAgICAgICAgICAgLy8gQWRkIHRoZSByZW1haW5pbmcgdG8gdGhlIHRvdGFsIG51bWJlciBvZiByZXdhcmRzIHdpdGhoZWxkCiAgICAgICAgICAgICAgICBzdW1SZXdhcmRzV2l0aGhlbGQgPSBzdW1SZXdhcmRzV2l0aGhlbGQgKyAobm9kZVJld2FyZEFtb3VudCAtIG5vZGVSZXdhcmRzQWZ0ZXJXaXRoaG9sZGluZykKCiAgICAgICAgICAgICAgICBsZXQgcmV3YXJkc0JyZWFrZG93biA9IEZsb3dJRFRhYmxlU3Rha2luZy5SZXdhcmRzQnJlYWtkb3duKG5vZGVJRDogbm9kZUlEKQoKICAgICAgICAgICAgICAgIC8vIEl0ZXJhdGUgdGhyb3VnaCBhbGwgdGhlIHdpdGhoZWxkIG5vZGUncyBkZWxlZ2F0b3JzCiAgICAgICAgICAgICAgICAvLyBhbmQgY2FsY3VsYXRlIHRoZWlyIGRlY3JlYXNlZCByZXdhcmRzIGFzIHdlbGwKICAgICAgICAgICAgICAgIGxldCBrZXlzID0gbm9kZVJlY29yZC5kZWxlZ2F0b3JzLmtleXMKICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IDAKICAgICAgICAgICAgICAgIHdoaWxlIGluZGV4IDwga2V5cy5sZW5ndGggewogICAgICAgICAgICAgICAgICAgIGxldCBkZWxlZ2F0b3IgPSBrZXlzW2luZGV4XQogICAgICAgICAgICAgICAgICAgIGluZGV4ID0gaW5kZXggKyAxCgogICAgICAgICAgICAgICAgICAgIGxldCBkZWxSZWNvcmQgPSBub2RlUmVjb3JkLmJvcnJvd0RlbGVnYXRvclJlY29yZChkZWxlZ2F0b3IpCgogICAgICAgICAgICAgICAgICAgIHN1bVN0YWtlRnJvbU5vbk9wZXJhdGlvbmFsU3Rha2VycyA9IHN1bVN0YWtlRnJvbU5vbk9wZXJhdGlvbmFsU3Rha2VycyArIGRlbFJlY29yZC50b2tlbnNTdGFrZWQuYmFsYW5jZQoKICAgICAgICAgICAgICAgICAgICAvLyBDYWxjdWxhdGUgdGhlIGFtb3VudCBvZiB0b2tlbnMgdGhhdCB0aGlzIGRlbGVnYXRvciByZWNlaXZlcwogICAgICAgICAgICAgICAgICAgIC8vIGRlY3JlYXNlZCB0byB0aGUgcGVyY2VudGFnZSBmcm9tIHRoZSBub24tb3BlcmF0aW9uYWwgbm9kZQogICAgICAgICAgICAgICAgICAgIHZhciBkZWxlZ2F0b3JSZXdhcmRBbW91bnQgPSBkZWxSZWNvcmQudG9rZW5zU3Rha2VkLmJhbGFuY2UgKiB0b3RhbFJld2FyZFNjYWxlCiAgICAgICAgICAgICAgICAgICAgdmFyIGRlbGVnYXRvclJld2FyZHNBZnRlcldpdGhob2xkaW5nID0gZGVsZWdhdG9yUmV3YXJkQW1vdW50ICogcmV3YXJkRGVjcmVhc2VUb1BlcmNlbnRhZ2UKCiAgICAgICAgICAgICAgICAgICAgLy8gQWRkIHRoZSB3aXRoaGVsZCByZXdhcmRzIHRvIHRoZSB0b3RhbCBzdW0KICAgICAgICAgICAgICAgICAgICBzdW1SZXdhcmRzV2l0aGhlbGQgPSBzdW1SZXdhcmRzV2l0aGhlbGQgKyAoZGVsZWdhdG9yUmV3YXJkQW1vdW50IC0gZGVsZWdhdG9yUmV3YXJkc0FmdGVyV2l0aGhvbGRpbmcpCgogICAgICAgICAgICAgICAgICAgIGlmIGRlbGVnYXRvclJld2FyZHNBZnRlcldpdGhob2xkaW5nID09IDAuMCB7IGNvbnRpbnVlIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gdGFrZSB0aGUgbm9kZSBvcGVyYXRvcidzIGN1dAogICAgICAgICAgICAgICAgICAgIGlmIChkZWxlZ2F0b3JSZXdhcmRzQWZ0ZXJXaXRoaG9sZGluZyAqIEZsb3dJRFRhYmxlU3Rha2luZy5ub2RlRGVsZWdhdGluZ1Jld2FyZEN1dCkgPiAwLjAgewoKICAgICAgICAgICAgICAgICAgICAgICAgbGV0IG5vZGVDdXRBbW91bnQgPSBkZWxlZ2F0b3JSZXdhcmRzQWZ0ZXJXaXRoaG9sZGluZyAqIEZsb3dJRFRhYmxlU3Rha2luZy5ub2RlRGVsZWdhdGluZ1Jld2FyZEN1dAoKICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVJld2FyZHNBZnRlcldpdGhob2xkaW5nID0gbm9kZVJld2FyZHNBZnRlcldpdGhob2xkaW5nICsgbm9kZUN1dEFtb3VudAoKICAgICAgICAgICAgICAgICAgICAgICAgZGVsZWdhdG9yUmV3YXJkc0FmdGVyV2l0aGhvbGRpbmcgPSBkZWxlZ2F0b3JSZXdhcmRzQWZ0ZXJXaXRoaG9sZGluZyAtIG5vZGVDdXRBbW91bnQKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV3YXJkc0JyZWFrZG93bi5zZXREZWxlZ2F0b3JSZXdhcmQoZGVsZWdhdG9ySUQ6IGRlbGVnYXRvciwgcmV3YXJkczogZGVsZWdhdG9yUmV3YXJkc0FmdGVyV2l0aGhvbGRpbmcpCiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV3YXJkc0JyZWFrZG93bi5zZXROb2RlUmV3YXJkcyhub2RlUmV3YXJkc0FmdGVyV2l0aGhvbGRpbmcpCiAgICAgICAgICAgICAgICByZXdhcmRzQnJlYWtkb3duQXJyYXkuYXBwZW5kKHJld2FyZHNCcmVha2Rvd24pCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIElmIGFsbCBzdGFrZWQgbm9kZXMgYXJlIG5vbi1vcGVyYXRpb25hbCwgdGhlIGRlbm9taW5hdG9yIGlzIHplcm8gYW5kIHRoZXJlIGFyZQogICAgICAgICAgICAvLyBubyBvcGVyYXRpb25hbCBub2RlcyB0byByZWRpc3RyaWJ1dGUgd2l0aGhlbGQgcmV3YXJkcyB0bywgc28gdGhlIHNjYWxlIGlzIHplcm8uCiAgICAgICAgICAgIHZhciB3aXRoaGVsZFJld2FyZHNTY2FsZSA9IDAuMAogICAgICAgICAgICBsZXQgb3BlcmF0aW9uYWxTdGFrZSA9IHRvdGFsU3Rha2VkIC0gc3VtU3Rha2VGcm9tTm9uT3BlcmF0aW9uYWxTdGFrZXJzCiAgICAgICAgICAgIGlmIG9wZXJhdGlvbmFsU3Rha2UgPiAwLjAgewogICAgICAgICAgICAgICAgd2l0aGhlbGRSZXdhcmRzU2NhbGUgPSBzdW1SZXdhcmRzV2l0aGhlbGQgLyBvcGVyYXRpb25hbFN0YWtlCiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGV0IHRvdGFsUmV3YXJkc1BsdXNXaXRoaGVsZCA9IHRvdGFsUmV3YXJkU2NhbGUgKyB3aXRoaGVsZFJld2FyZHNTY2FsZQoKICAgICAgICAgICAgLy8vIGl0ZXJhdGUgdGhyb3VnaCBhbGwgdGhlIG5vZGVzIHRvIHBheQogICAgICAgICAgICBmb3Igbm9kZUlEIGluIHN0YWtlZE5vZGVJRHMgewogICAgICAgICAgICAgICAgaWYgbm9uT3BlcmF0aW9uYWxOb2Rlc1tub2RlSURdICE9IG5pbCB7IGNvbnRpbnVlIH0KCiAgICAgICAgICAgICAgICBsZXQgbm9kZVJlY29yZCA9IEZsb3dJRFRhYmxlU3Rha2luZy5ib3Jyb3dOb2RlUmVjb3JkKG5vZGVJRCkKCiAgICAgICAgICAgICAgICB2YXIgbm9kZVJld2FyZEFtb3VudCA9IG5vZGVSZWNvcmQudG9rZW5zU3Rha2VkLmJhbGFuY2UgKiB0b3RhbFJld2FyZHNQbHVzV2l0aGhlbGQKCiAgICAgICAgICAgICAgICBpZiBub2RlUmV3YXJkQW1vdW50ID09IDAuMCB8fCBub2RlUmVjb3JkLnJvbGUgPT0gVUludDgoNSkgIHsgY29udGludWUgfQoKICAgICAgICAgICAgICAgIGxldCByZXdhcmRzQnJlYWtkb3duID0gRmxvd0lEVGFibGVTdGFraW5nLlJld2FyZHNCcmVha2Rvd24obm9kZUlEOiBub2RlSUQpCgogICAgICAgICAgICAgICAgLy8gSXRlcmF0ZSB0aHJvdWdoIGFsbCBkZWxlZ2F0b3JzIGFuZCByZXdhcmQgdGhlbSB0aGVpciBzaGFyZQogICAgICAgICAgICAgICAgLy8gb2YgdGhlIHJld2FyZHMgZm9yIHRoZSB0b2tlbnMgdGhleSBoYXZlIHN0YWtlZCBmb3IgdGhpcyBub2RlCiAgICAgICAgICAgICAgICBsZXQga2V5cyA9IG5vZGVSZWNvcmQuZGVsZWdhdG9ycy5rZXlzCiAgICAgICAgICAgICAgICB2YXIgaW5kZXggPSAwCiAgICAgICAgICAgICAgICB3aGlsZSBpbmRleCA8IGtleXMubGVuZ3RoIHsKICAgICAgICAgICAgICAgICAgICBsZXQgZGVsZWdhdG9yID0ga2V5c1tpbmRleF0KICAgICAgICAgICAgICAgICAgICBpbmRleCA9IGluZGV4ICsgMQoKICAgICAgICAgICAgICAgICAgICBsZXQgZGVsUmVjb3JkID0gbm9kZVJlY29yZC5ib3Jyb3dEZWxlZ2F0b3JSZWNvcmQoZGVsZWdhdG9yKQoKICAgICAgICAgICAgICAgICAgICAvLy8gQ2FsY3VsYXRlIHRoZSBhbW91bnQgb2YgdG9rZW5zIHRoYXQgdGhpcyBkZWxlZ2F0b3IgcmVjZWl2ZXMKICAgICAgICAgICAgICAgICAgICB2YXIgZGVsZWdhdG9yUmV3YXJkQW1vdW50ID0gZGVsUmVjb3JkLnRva2Vuc1N0YWtlZC5iYWxhbmNlICogdG90YWxSZXdhcmRzUGx1c1dpdGhoZWxkCgogICAgICAgICAgICAgICAgICAgIGlmIGRlbGVnYXRvclJld2FyZEFtb3VudCA9PSAwLjAgeyBjb250aW51ZSB9CgogICAgICAgICAgICAgICAgICAgIC8vIHRha2UgdGhlIG5vZGUgb3BlcmF0b3IncyBjdXQKICAgICAgICAgICAgICAgICAgICBpZiAoZGVsZWdhdG9yUmV3YXJkQW1vdW50ICogRmxvd0lEVGFibGVTdGFraW5nLm5vZGVEZWxlZ2F0aW5nUmV3YXJkQ3V0KSA+IDAuMCB7CgogICAgICAgICAgICAgICAgICAgICAgICBsZXQgbm9kZUN1dEFtb3VudCA9IGRlbGVnYXRvclJld2FyZEFtb3VudCAqIEZsb3dJRFRhYmxlU3Rha2luZy5ub2RlRGVsZWdhdGluZ1Jld2FyZEN1dAoKICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVJld2FyZEFtb3VudCA9IG5vZGVSZXdhcmRBbW91bnQgKyBub2RlQ3V0QW1vdW50CgogICAgICAgICAgICAgICAgICAgICAgICBkZWxlZ2F0b3JSZXdhcmRBbW91bnQgPSBkZWxlZ2F0b3JSZXdhcmRBbW91bnQgLSBub2RlQ3V0QW1vdW50CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJld2FyZHNCcmVha2Rvd24uc2V0RGVsZWdhdG9yUmV3YXJkKGRlbGVnYXRvcklEOiBkZWxlZ2F0b3IsIHJld2FyZHM6IGRlbGVnYXRvclJld2FyZEFtb3VudCkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgcmV3YXJkc0JyZWFrZG93bi5zZXROb2RlUmV3YXJkcyhub2RlUmV3YXJkQW1vdW50KQogICAgICAgICAgICAgICAgcmV3YXJkc0JyZWFrZG93bkFycmF5LmFwcGVuZChyZXdhcmRzQnJlYWtkb3duKQogICAgICAgICAgICB9CgogICAgICAgICAgICBsZXQgc3VtbWFyeSA9IEVwb2NoUmV3YXJkc1N1bW1hcnkodG90YWxSZXdhcmRzOiBGbG93SURUYWJsZVN0YWtpbmcuZXBvY2hUb2tlblBheW91dCwgYnJlYWtkb3duOiByZXdhcmRzQnJlYWtkb3duQXJyYXkpCgogICAgICAgICAgICByZXR1cm4gc3VtbWFyeQogICAgICAgIH0KCiAgICAgICAgLy8vIENhbGxlZCBhdCB0aGUgZW5kIG9mIHRoZSBlcG9jaCB0byBtb3ZlIHRva2VucyBiZXR3ZWVuIGJ1Y2tldHMKICAgICAgICAvLy8gZm9yIHN0YWtlcnMKICAgICAgICAvLy8gVG9rZW5zIHRoYXQgaGF2ZSBiZWVuIGNvbW1pdHRlZCBhcmUgbW92ZWQgdG8gdGhlIHN0YWtlZCBidWNrZXQKICAgICAgICAvLy8gVG9rZW5zIHRoYXQgd2VyZSB1bnN0YWtpbmcgZHVyaW5nIHRoZSBsYXN0IGVwb2NoIGFyZSBmdWxseSB1bnN0YWtlZAogICAgICAgIC8vLyBVbnN0YWtpbmcgcmVxdWVzdHMgYXJlIGZpbGxlZCBieSBtb3ZpbmcgdGhvc2UgdG9rZW5zIGZyb20gc3Rha2VkIHRvIHVuc3Rha2luZwogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBtb3ZlVG9rZW5zKG5ld0Vwb2NoQ291bnRlcjogVUludDY0KSB7CiAgICAgICAgICAgIHByZSB7CiAgICAgICAgICAgICAgICAhRmxvd0lEVGFibGVTdGFraW5nLnN0YWtpbmdFbmFibGVkKCk6ICJGbG93SURUYWJsZVN0YWtpbmcuTm9kZVN0YWtlci5tb3ZlVG9rZW5zOiBDYW5ub3QgbW92ZSB0b2tlbnMgaWYgdGhlIHN0YWtpbmcgYXVjdGlvbiBpcyBzdGlsbCBpbiBwcm9ncmVzcyIKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGV0IGFwcHJvdmVkTm9kZUlEcyA9IEZsb3dJRFRhYmxlU3Rha2luZy5nZXRBcHByb3ZlZExpc3QoKQogICAgICAgICAgICAgICAgPz8gcGFuaWMoIkZsb3dJRFRhYmxlU3Rha2luZy5Ob2RlU3Rha2VyLm1vdmVUb2tlbnM6IENvdWxkIG5vdCByZWFkIHRoZSBhcHByb3ZlIGxpc3QgZnJvbSBzdG9yYWdlIikKCiAgICAgICAgICAgIGxldCBtb3Zlc1BlbmRpbmdOb2RlSURzID0gRmxvd0lEVGFibGVTdGFraW5nLmFjY291bnQuc3RvcmFnZS5sb2FkPHtTdHJpbmc6IHtVSW50MzI6IEJvb2x9fT4oZnJvbTogL3N0b3JhZ2UvaWRUYWJsZU1vdmVzUGVuZGluZ0xpc3QpCiAgICAgICAgICAgICAgICA/PyBwYW5pYygiRmxvd0lEVGFibGVTdGFraW5nLk5vZGVTdGFrZXIubW92ZVRva2VuczogTm8gbW92ZXMgcGVuZGluZyBsaXN0IGluIGFjY291bnQgc3RvcmFnZSIpCgogICAgICAgICAgICAvLyBSZXNldCB0aGUgbW92ZXNQZW5kaW5nTGlzdAogICAgICAgICAgICB2YXIgZW1wdHlNb3Zlc1BlbmRpbmdMaXN0OiB7U3RyaW5nOiB7VUludDMyOiBCb29sfX0gPSB7fQogICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcuYWNjb3VudC5zdG9yYWdlLnNhdmUoZW1wdHlNb3Zlc1BlbmRpbmdMaXN0LCB0bzogL3N0b3JhZ2UvaWRUYWJsZU1vdmVzUGVuZGluZ0xpc3QpCiAgICAgICAgICAgIGxldCBuZXdNb3Zlc1BlbmRpbmdMaXN0ID0gRmxvd0lEVGFibGVTdGFraW5nLmFjY291bnQuc3RvcmFnZS5ib3Jyb3c8YXV0aChNdXRhdGUpICZ7U3RyaW5nOiB7VUludDMyOiBCb29sfX0+KGZyb206IC9zdG9yYWdlL2lkVGFibGVNb3Zlc1BlbmRpbmdMaXN0KQogICAgICAgICAgICAgICAgPz8gcGFuaWMoIkZsb3dJRFRhYmxlU3Rha2luZy5Ob2RlU3Rha2VyLm1vdmVUb2tlbnM6IE5vIG1vdmVzIHBlbmRpbmcgbGlzdCBpbiBhY2NvdW50IHN0b3JhZ2UiKQoKICAgICAgICAgICAgbGV0IHN0YWtlZE5vZGVJRHM6IHtTdHJpbmc6IEJvb2x9ID0gRmxvd0lEVGFibGVTdGFraW5nLmdldFBhcnRpY2lwYW50Tm9kZUxpc3QoKSEKCiAgICAgICAgICAgIGZvciBub2RlSUQgaW4gbW92ZXNQZW5kaW5nTm9kZUlEcyB7CiAgICAgICAgICAgICAgICBsZXQgbm9kZVJlY29yZCA9IEZsb3dJRFRhYmxlU3Rha2luZy5ib3Jyb3dOb2RlUmVjb3JkKG5vZGVJRCkKCiAgICAgICAgICAgICAgICBsZXQgYXBwcm92ZWQgPSBhcHByb3ZlZE5vZGVJRHNbbm9kZUlEXSA/PyBmYWxzZQoKICAgICAgICAgICAgICAgIC8vIG1hcmsgdGhlIGNvbW1pdHRlZCB0b2tlbnMgYXMgc3Rha2VkCiAgICAgICAgICAgICAgICBpZiBub2RlUmVjb3JkLnRva2Vuc0NvbW1pdHRlZC5iYWxhbmNlID4gMC4wIHx8IGFwcHJvdmVkIHsKICAgICAgICAgICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcudG90YWxUb2tlbnNTdGFrZWRCeU5vZGVUeXBlW25vZGVSZWNvcmQucm9sZV0gPSBGbG93SURUYWJsZVN0YWtpbmcudG90YWxUb2tlbnNTdGFrZWRCeU5vZGVUeXBlW25vZGVSZWNvcmQucm9sZV0hICsgbm9kZVJlY29yZC50b2tlbnNDb21taXR0ZWQuYmFsYW5jZQogICAgICAgICAgICAgICAgICAgIGVtaXQgVG9rZW5zU3Rha2VkKG5vZGVJRDogbm9kZVJlY29yZC5pZCwgYW1vdW50OiBub2RlUmVjb3JkLnRva2Vuc0NvbW1pdHRlZC5iYWxhbmNlKQogICAgICAgICAgICAgICAgICAgIG5vZGVSZWNvcmQudG9rZW5zU3Rha2VkLmRlcG9zaXQoZnJvbTogPC1ub2RlUmVjb3JkLnRva2Vuc0NvbW1pdHRlZC53aXRoZHJhdyhhbW91bnQ6IG5vZGVSZWNvcmQudG9rZW5zQ29tbWl0dGVkLmJhbGFuY2UpKQogICAgICAgICAgICAgICAgICAgIHN0YWtlZE5vZGVJRHNbbm9kZVJlY29yZC5pZF0gPSB0cnVlCiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gbWFya2VkIHRoZSB1bnN0YWtpbmcgdG9rZW5zIGFzIHVuc3Rha2VkCiAgICAgICAgICAgICAgICBpZiBub2RlUmVjb3JkLnRva2Vuc1Vuc3Rha2luZy5iYWxhbmNlID4gMC4wIHsKICAgICAgICAgICAgICAgICAgICBlbWl0IFRva2Vuc1Vuc3Rha2VkKG5vZGVJRDogbm9kZVJlY29yZC5pZCwgYW1vdW50OiBub2RlUmVjb3JkLnRva2Vuc1Vuc3Rha2luZy5iYWxhbmNlKQogICAgICAgICAgICAgICAgICAgIG5vZGVSZWNvcmQudG9rZW5zVW5zdGFrZWQuZGVwb3NpdChmcm9tOiA8LW5vZGVSZWNvcmQudG9rZW5zVW5zdGFraW5nLndpdGhkcmF3KGFtb3VudDogbm9kZVJlY29yZC50b2tlbnNVbnN0YWtpbmcuYmFsYW5jZSkpCiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gdW5zdGFrZSB0aGUgcmVxdWVzdGVkIHRva2VucyBhbmQgbW92ZSB0aGVtIHRvIHRva2Vuc1Vuc3Rha2luZwogICAgICAgICAgICAgICAgaWYgbm9kZVJlY29yZC50b2tlbnNSZXF1ZXN0ZWRUb1Vuc3Rha2UgPiAwLjAgewogICAgICAgICAgICAgICAgICAgIGVtaXQgVG9rZW5zVW5zdGFraW5nKG5vZGVJRDogbm9kZVJlY29yZC5pZCwgYW1vdW50OiBub2RlUmVjb3JkLnRva2Vuc1JlcXVlc3RlZFRvVW5zdGFrZSkKICAgICAgICAgICAgICAgICAgICBub2RlUmVjb3JkLnRva2Vuc1Vuc3Rha2luZy5kZXBvc2l0KGZyb206IDwtbm9kZVJlY29yZC50b2tlbnNTdGFrZWQud2l0aGRyYXcoYW1vdW50OiBub2RlUmVjb3JkLnRva2Vuc1JlcXVlc3RlZFRvVW5zdGFrZSkpCiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIG5vZGUgbm8gbG9uZ2VyIGhhcyBhYm92ZSB0aGUgbWluaW11bSwgcmVtb3ZlIHRoZW0gZnJvbSB0aGUgbGlzdCBvZiBhY3RpdmUgbm9kZXMKICAgICAgICAgICAgICAgICAgICBpZiAhRmxvd0lEVGFibGVTdGFraW5nLmlzR3JlYXRlclRoYW5NaW5pbXVtRm9yUm9sZShudW1Ub2tlbnM6IG5vZGVSZWNvcmQudG9rZW5zU3Rha2VkLmJhbGFuY2UsIHJvbGU6IG5vZGVSZWNvcmQucm9sZSkgewogICAgICAgICAgICAgICAgICAgICAgICBzdGFrZWROb2RlSURzLnJlbW92ZShrZXk6IG5vZGVSZWNvcmQuaWQpCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vIHVuc3Rha2VkIHRva2VucyBhdXRvbWF0aWNhbGx5IG1hcmsgdGhlIG5vZGUgYXMgcGVuZGluZwogICAgICAgICAgICAgICAgICAgIC8vIGJlY2F1c2UgdGhleSB3aWxsIG1vdmUgaW4gdGhlIG5leHQgZXBvY2gKICAgICAgICAgICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcubW9kaWZ5TmV3TW92ZXNQZW5kaW5nKG5vZGVJRDogbm9kZUlELCBkZWxlZ2F0b3JJRDogbmlsLCBleGlzdGluZ0xpc3Q6IG5ld01vdmVzUGVuZGluZ0xpc3QpCiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgbGV0IHBlbmRpbmdEZWxlZ2F0b3JzTGlzdCA9IG1vdmVzUGVuZGluZ05vZGVJRHNbbm9kZUlEXSEKCiAgICAgICAgICAgICAgICAvLyBtb3ZlIGFsbCB0aGUgZGVsZWdhdG9ycycgdG9rZW5zIGJldHdlZW4gYnVja2V0cwogICAgICAgICAgICAgICAgZm9yIGRlbGVnYXRvciBpbiBwZW5kaW5nRGVsZWdhdG9yc0xpc3QgewogICAgICAgICAgICAgICAgICAgIGxldCBkZWxSZWNvcmQgPSBub2RlUmVjb3JkLmJvcnJvd0RlbGVnYXRvclJlY29yZChkZWxlZ2F0b3IpCgogICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSBkZWxlZ2F0b3IncyBjb21taXR0ZWQgdG9rZW5zIGZvciB0aGUgbmV4dCBlcG9jaAogICAgICAgICAgICAgICAgICAgIC8vIGlzIGxlc3MgdGhhbiB0aGUgZGVsZWdhdG9yIG1pbmltdW0sIHVuc3Rha2UgYWxsIHRoZWlyIHRva2VucwogICAgICAgICAgICAgICAgICAgIGxldCBhY3R1YWxDb21taXR0ZWRGb3JOZXh0RXBvY2ggPSBkZWxSZWNvcmQudG9rZW5zQ29tbWl0dGVkLmJhbGFuY2UgKyBkZWxSZWNvcmQudG9rZW5zU3Rha2VkLmJhbGFuY2UgLSBkZWxSZWNvcmQudG9rZW5zUmVxdWVzdGVkVG9VbnN0YWtlCiAgICAgICAgICAgICAgICAgICAgaWYgYWN0dWFsQ29tbWl0dGVkRm9yTmV4dEVwb2NoIDwgRmxvd0lEVGFibGVTdGFraW5nLmdldERlbGVnYXRvck1pbmltdW1TdGFrZVJlcXVpcmVtZW50KCkgewogICAgICAgICAgICAgICAgICAgICAgICBkZWxSZWNvcmQudG9rZW5zVW5zdGFrZWQuZGVwb3NpdChmcm9tOiA8LWRlbFJlY29yZC50b2tlbnNDb21taXR0ZWQud2l0aGRyYXcoYW1vdW50OiBkZWxSZWNvcmQudG9rZW5zQ29tbWl0dGVkLmJhbGFuY2UpKQogICAgICAgICAgICAgICAgICAgICAgICBkZWxSZWNvcmQuc2V0VG9rZW5zUmVxdWVzdGVkVG9VbnN0YWtlKGRlbFJlY29yZC50b2tlbnNTdGFrZWQuYmFsYW5jZSkKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy50b3RhbFRva2Vuc1N0YWtlZEJ5Tm9kZVR5cGVbbm9kZVJlY29yZC5yb2xlXSA9IEZsb3dJRFRhYmxlU3Rha2luZy50b3RhbFRva2Vuc1N0YWtlZEJ5Tm9kZVR5cGVbbm9kZVJlY29yZC5yb2xlXSEgKyBkZWxSZWNvcmQudG9rZW5zQ29tbWl0dGVkLmJhbGFuY2UKCiAgICAgICAgICAgICAgICAgICAgLy8gbWFyayB0aGVpciBjb21taXR0ZWQgdG9rZW5zIGFzIHN0YWtlZAogICAgICAgICAgICAgICAgICAgIGlmIGRlbFJlY29yZC50b2tlbnNDb21taXR0ZWQuYmFsYW5jZSA+IDAuMCB7CiAgICAgICAgICAgICAgICAgICAgICAgIGVtaXQgRGVsZWdhdG9yVG9rZW5zU3Rha2VkKG5vZGVJRDogbm9kZVJlY29yZC5pZCwgZGVsZWdhdG9ySUQ6IGRlbGVnYXRvciwgYW1vdW50OiBkZWxSZWNvcmQudG9rZW5zQ29tbWl0dGVkLmJhbGFuY2UpCiAgICAgICAgICAgICAgICAgICAgICAgIGRlbFJlY29yZC50b2tlbnNTdGFrZWQuZGVwb3NpdChmcm9tOiA8LWRlbFJlY29yZC50b2tlbnNDb21taXR0ZWQud2l0aGRyYXcoYW1vdW50OiBkZWxSZWNvcmQudG9rZW5zQ29tbWl0dGVkLmJhbGFuY2UpKQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gbWFya2VkIHRoZSB1bnN0YWtpbmcgdG9rZW5zIGFzIHVuc3Rha2VkCiAgICAgICAgICAgICAgICAgICAgaWYgZGVsUmVjb3JkLnRva2Vuc1Vuc3Rha2luZy5iYWxhbmNlID4gMC4wIHsKICAgICAgICAgICAgICAgICAgICAgICAgZW1pdCBEZWxlZ2F0b3JUb2tlbnNVbnN0YWtlZChub2RlSUQ6IG5vZGVSZWNvcmQuaWQsIGRlbGVnYXRvcklEOiBkZWxlZ2F0b3IsIGFtb3VudDogZGVsUmVjb3JkLnRva2Vuc1Vuc3Rha2luZy5iYWxhbmNlKQogICAgICAgICAgICAgICAgICAgICAgICBkZWxSZWNvcmQudG9rZW5zVW5zdGFrZWQuZGVwb3NpdChmcm9tOiA8LWRlbFJlY29yZC50b2tlbnNVbnN0YWtpbmcud2l0aGRyYXcoYW1vdW50OiBkZWxSZWNvcmQudG9rZW5zVW5zdGFraW5nLmJhbGFuY2UpKQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gdW5zdGFrZSB0aGUgcmVxdWVzdGVkIHRva2VucyBhbmQgbW92ZSB0aGVtIHRvIHRva2Vuc1Vuc3Rha2luZwogICAgICAgICAgICAgICAgICAgIGlmIGRlbFJlY29yZC50b2tlbnNSZXF1ZXN0ZWRUb1Vuc3Rha2UgPiAwLjAgewogICAgICAgICAgICAgICAgICAgICAgICBlbWl0IERlbGVnYXRvclRva2Vuc1Vuc3Rha2luZyhub2RlSUQ6IG5vZGVSZWNvcmQuaWQsIGRlbGVnYXRvcklEOiBkZWxlZ2F0b3IsIGFtb3VudDogZGVsUmVjb3JkLnRva2Vuc1JlcXVlc3RlZFRvVW5zdGFrZSkKICAgICAgICAgICAgICAgICAgICAgICAgZGVsUmVjb3JkLnRva2Vuc1Vuc3Rha2luZy5kZXBvc2l0KGZyb206IDwtZGVsUmVjb3JkLnRva2Vuc1N0YWtlZC53aXRoZHJhdyhhbW91bnQ6IGRlbFJlY29yZC50b2tlbnNSZXF1ZXN0ZWRUb1Vuc3Rha2UpKQogICAgICAgICAgICAgICAgICAgICAgICAvLyB1bnN0YWtlZCB0b2tlbnMgYXV0b21hdGljYWxseSBtYXJrIHRoZSBkZWxlZ2F0b3IgYXMgcGVuZGluZwogICAgICAgICAgICAgICAgICAgICAgICAvLyBiZWNhdXNlIHRoZXkgd2lsbCBtb3ZlIGluIHRoZSBuZXh0IGVwb2NoCiAgICAgICAgICAgICAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy5tb2RpZnlOZXdNb3Zlc1BlbmRpbmcobm9kZUlEOiBub2RlSUQsIGRlbGVnYXRvcklEOiBkZWxlZ2F0b3IsIGV4aXN0aW5nTGlzdDogbmV3TW92ZXNQZW5kaW5nTGlzdCkKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIHN1YnRyYWN0IHRoZWlyIHJlcXVlc3RlZCB0b2tlbnMgZnJvbSB0aGUgdG90YWwgc3Rha2VkIGZvciB0aGVpciBub2RlIHR5cGUKICAgICAgICAgICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcudG90YWxUb2tlbnNTdGFrZWRCeU5vZGVUeXBlW25vZGVSZWNvcmQucm9sZV0gPSBGbG93SURUYWJsZVN0YWtpbmcudG90YWxUb2tlbnNTdGFrZWRCeU5vZGVUeXBlW25vZGVSZWNvcmQucm9sZV0hIC0gZGVsUmVjb3JkLnRva2Vuc1JlcXVlc3RlZFRvVW5zdGFrZQoKICAgICAgICAgICAgICAgICAgICBkZWxSZWNvcmQuc2V0VG9rZW5zUmVxdWVzdGVkVG9VbnN0YWtlKDAuMCkKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBzdWJ0cmFjdCB0aGVpciByZXF1ZXN0ZWQgdG9rZW5zIGZyb20gdGhlIHRvdGFsIHN0YWtlZCBmb3IgdGhlaXIgbm9kZSB0eXBlCiAgICAgICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcudG90YWxUb2tlbnNTdGFrZWRCeU5vZGVUeXBlW25vZGVSZWNvcmQucm9sZV0gPSBGbG93SURUYWJsZVN0YWtpbmcudG90YWxUb2tlbnNTdGFrZWRCeU5vZGVUeXBlW25vZGVSZWNvcmQucm9sZV0hIC0gbm9kZVJlY29yZC50b2tlbnNSZXF1ZXN0ZWRUb1Vuc3Rha2UKCiAgICAgICAgICAgICAgICAvLyBSZXNldCB0aGUgdG9rZW5zIHJlcXVlc3RlZCBmaWVsZCBzbyBpdCBjYW4gYmUgdXNlZCBmb3IgdGhlIG5leHQgZXBvY2gKICAgICAgICAgICAgICAgIG5vZGVSZWNvcmQuc2V0VG9rZW5zUmVxdWVzdGVkVG9VbnN0YWtlKDAuMCkKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gU3RhcnQgdGhlIG5ldyBlcG9jaCdzIHN0YWtpbmcgYXVjdGlvbgogICAgICAgICAgICBzZWxmLnN0YXJ0U3Rha2luZ0F1Y3Rpb24oKQoKICAgICAgICAgICAgLy8gU2V0IHRoZSBjdXJyZW50IEVwb2NoIHBhcnRpY2lwYW50IG5vZGUgbGlzdAogICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcuc2V0UGFydGljaXBhbnROb2RlTGlzdChzdGFrZWROb2RlSURzKQoKICAgICAgICAgICAgLy8gSW5kaWNhdGVzIHRoYXQgdGhlIHRva2VucyBoYXZlIG1vdmVkIGFuZCB0aGUgZXBvY2ggaGFzIGVuZGVkCiAgICAgICAgICAgIC8vIFRlbGxzIHdoYXQgdGhlIG5ldyByZXdhcmQgcGF5b3V0IHdpbGwgYmUuIFRoZSBuZXcgcGF5b3V0IGlzIGNhbGN1bGF0ZWQgYW5kIGNoYW5nZWQKICAgICAgICAgICAgLy8gYmVmb3JlIHRoaXMgbWV0aG9kIGlzIGV4ZWN1dGVkIGFuZCB3aWxsIG5vdCBiZSBjaGFuZ2VkIGZvciB0aGUgcmVzdCBvZiB0aGUgZXBvY2gKICAgICAgICAgICAgZW1pdCBOZXdFcG9jaCh0b3RhbFN0YWtlZDogRmxvd0lEVGFibGVTdGFraW5nLmdldFRvdGFsU3Rha2VkKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxSZXdhcmRQYXlvdXQ6IEZsb3dJRFRhYmxlU3Rha2luZy5lcG9jaFRva2VuUGF5b3V0LAogICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0Vwb2NoQ291bnRlcjogbmV3RXBvY2hDb3VudGVyKQogICAgICAgIH0KICAgIH0KCiAgICAvLy8gQW55IHVzZXIgY2FuIGNhbGwgdGhpcyBmdW5jdGlvbiB0byByZWdpc3RlciBhIG5ldyBOb2RlCiAgICAvLy8gSXQgcmV0dXJucyB0aGUgcmVzb3VyY2UgZm9yIG5vZGVzIHRoYXQgdGhleSBjYW4gc3RvcmUgaW4gdGhlaXIgYWNjb3VudCBzdG9yYWdlCiAgICBhY2Nlc3MoYWxsKSBmdW4gYWRkTm9kZVJlY29yZChpZDogU3RyaW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgIHJvbGU6IFVJbnQ4LAogICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHdvcmtpbmdBZGRyZXNzOiBTdHJpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0d29ya2luZ0tleTogU3RyaW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgIHN0YWtpbmdLZXk6IFN0cmluZywKICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFraW5nS2V5UG9QOiBTdHJpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgdG9rZW5zQ29tbWl0dGVkOiBAe0Z1bmdpYmxlVG9rZW4uVmF1bHR9KTogQE5vZGVTdGFrZXIKICAgIHsKICAgICAgICBhc3NlcnQgKAogICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcuc3Rha2luZ0VuYWJsZWQoKSwKICAgICAgICAgICAgbWVzc2FnZTogIkZsb3dJRFRhYmxlU3Rha2luZy5Ob2RlU3Rha2VyLmFkZE5vZGVSZWNvcmQ6IENhbm5vdCByZWdpc3RlciBhIG5vZGUgb3BlcmF0b3IgaWYgdGhlIHN0YWtpbmcgYXVjdGlvbiBpc24ndCBpbiBwcm9ncmVzcyIKICAgICAgICApCgogICAgICAgIC8vIE5PVEU6IEFuIGVtcHR5IHZhdWx0IGlzIGludGVudGlvbmFsbHkgcGFzc2VkIHRvIE5vZGVSZWNvcmQgaGVyZS4gVGhlIGNhbGxlci1wcm92aWRlZAogICAgICAgIC8vIHRva2Vuc0NvbW1pdHRlZCB2YXVsdCBpcyB2YWxpZGF0ZWQgYWdhaW5zdCB0aGUgbWluaW11bSBzdGFrZSByZXF1aXJlbWVudCBhdCBsaW5lIGJlbG93LAogICAgICAgIC8vIHRoZW4gZGVwb3NpdGVkIHZpYSBzdGFrZU5ld1Rva2VucygpIGltbWVkaWF0ZWx5IGFmdGVyIHRoZSBub2RlIGlzIHN0b3JlZC4gVGhlIE5vZGVSZWNvcmQKICAgICAgICAvLyBpcyBjcmVhdGVkIGZpcnN0IHNvIGl0IGV4aXN0cyBpbiBzdG9yYWdlIGJlZm9yZSB0b2tlbnMgYXJlIGNvbW1pdHRlZCB0byBpdC4KICAgICAgICBsZXQgbmV3Tm9kZSA8LSBjcmVhdGUgTm9kZVJlY29yZChpZDogaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm9sZTogcm9sZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXR3b3JraW5nQWRkcmVzczogbmV0d29ya2luZ0FkZHJlc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0d29ya2luZ0tleTogbmV0d29ya2luZ0tleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFraW5nS2V5OiBzdGFraW5nS2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YWtpbmdLZXlQb1A6IHN0YWtpbmdLZXlQb1AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9rZW5zQ29tbWl0dGVkOiA8LUZsb3dUb2tlbi5jcmVhdGVFbXB0eVZhdWx0KHZhdWx0VHlwZTogVHlwZTxARmxvd1Rva2VuLlZhdWx0PigpKSkKCiAgICAgICAgbGV0IG1pbmltdW0gPSBzZWxmLm1pbmltdW1TdGFrZVJlcXVpcmVkW3JvbGVdIQoKICAgICAgICBhc3NlcnQoCiAgICAgICAgICAgIHNlbGYuaXNHcmVhdGVyVGhhbk1pbmltdW1Gb3JSb2xlKG51bVRva2VuczogdG9rZW5zQ29tbWl0dGVkLmJhbGFuY2UsIHJvbGU6IHJvbGUpLAogICAgICAgICAgICBtZXNzYWdlOiAiRmxvd0lEVGFibGVTdGFraW5nLk5vZGVTdGFrZXIuYWRkTm9kZVJlY29yZDogVGhlIGFtb3VudCBvZiB0b2tlbnMgY29tbWl0dGVkIGZvciByZWdpc3RyYXRpb24gb2YgXCh0b2tlbnNDb21taXR0ZWQuYmFsYW5jZSkgaXMgbm90IGFib3ZlIHRoZSBtaW5pbXVtIChcKG1pbmltdW0pKSBmb3IgdGhlIGNob3NlbiBub2RlIHJvbGUgKFwocm9sZSkpIgogICAgICAgICkKCiAgICAgICAgRmxvd0lEVGFibGVTdGFraW5nLm5vZGVzW2lkXSA8LSEgbmV3Tm9kZQoKICAgICAgICAvLyByZXR1cm4gYSBuZXcgTm9kZVN0YWtlciBvYmplY3QgdGhhdCB0aGUgbm9kZSBvcGVyYXRvciBzdG9yZXMgaW4gdGhlaXIgYWNjb3VudAogICAgICAgIGxldCBub2RlU3Rha2VyIDwtY3JlYXRlIE5vZGVTdGFrZXIoaWQ6IGlkKQoKICAgICAgICBub2RlU3Rha2VyLnN0YWtlTmV3VG9rZW5zKDwtdG9rZW5zQ29tbWl0dGVkKQoKICAgICAgICByZXR1cm4gPC1ub2RlU3Rha2VyCiAgICB9CgogICAgLy8vIFJlZ2lzdGVycyBhIG5ldyBkZWxlZ2F0b3Igd2l0aCBhIHVuaXF1ZSBJRCBmb3IgdGhlIHNwZWNpZmllZCBub2RlIG9wZXJhdG9yCiAgICAvLy8gYW5kIHJldHVybnMgYSBkZWxlZ2F0b3Igb2JqZWN0IHRvIHRoZSBjYWxsZXIKICAgIGFjY2VzcyhhbGwpIGZ1biByZWdpc3Rlck5ld0RlbGVnYXRvcihub2RlSUQ6IFN0cmluZywgdG9rZW5zQ29tbWl0dGVkOiBAe0Z1bmdpYmxlVG9rZW4uVmF1bHR9KTogQE5vZGVEZWxlZ2F0b3IgewogICAgICAgIGFzc2VydCAoCiAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy5zdGFraW5nRW5hYmxlZCgpLAogICAgICAgICAgICBtZXNzYWdlOiAiRmxvd0lEVGFibGVTdGFraW5nLk5vZGVTdGFrZXIucmVnaXN0ZXJOZXdEZWxlZ2F0b3I6IENhbm5vdCByZWdpc3RlciBhIGRlbGVnYXRvciBpZiB0aGUgc3Rha2luZyBhdWN0aW9uIGlzbid0IGluIHByb2dyZXNzIgogICAgICAgICkKCiAgICAgICAgbGV0IG5vZGVSZWNvcmQgPSBGbG93SURUYWJsZVN0YWtpbmcuYm9ycm93Tm9kZVJlY29yZChub2RlSUQpCgogICAgICAgIGFzc2VydCAoCiAgICAgICAgICAgIG5vZGVSZWNvcmQucm9sZSAhPSBVSW50OCg1KSwKICAgICAgICAgICAgbWVzc2FnZTogIkZsb3dJRFRhYmxlU3Rha2luZy5Ob2RlU3Rha2VyLnJlZ2lzdGVyTmV3RGVsZWdhdG9yOiBDYW5ub3QgcmVnaXN0ZXIgYSBkZWxlZ2F0b3IgZm9yIGFuIGFjY2VzcyBub2RlIgogICAgICAgICkKCiAgICAgICAgbGV0IG1pbmltdW0gPSBzZWxmLmdldERlbGVnYXRvck1pbmltdW1TdGFrZVJlcXVpcmVtZW50KCkKICAgICAgICBhc3NlcnQoCiAgICAgICAgICAgIHRva2Vuc0NvbW1pdHRlZC5iYWxhbmNlID49IG1pbmltdW0sCiAgICAgICAgICAgIG1lc3NhZ2U6ICJGbG93SURUYWJsZVN0YWtpbmcuTm9kZVN0YWtlci5yZWdpc3Rlck5ld0RlbGVnYXRvcjogVGhlIGFtb3VudCBvZiB0b2tlbnMgY29tbWl0dGVkIGZvciByZWdpc3RyYXRpb24gb2YgXCh0b2tlbnNDb21taXR0ZWQuYmFsYW5jZSkgaXMgbm90IGFib3ZlIHRoZSBtaW5pbXVtIChcKG1pbmltdW0pKSBmb3IgZGVsZWdhdG9ycyIKICAgICAgICApCgogICAgICAgIGFzc2VydCAoCiAgICAgICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy5pc0dyZWF0ZXJUaGFuTWluaW11bUZvclJvbGUobnVtVG9rZW5zOiBub2RlUmVjb3JkLm5vZGVGdWxsQ29tbWl0dGVkQmFsYW5jZSgpLCByb2xlOiBub2RlUmVjb3JkLnJvbGUpLAogICAgICAgICAgICBtZXNzYWdlOiAiRmxvd0lEVGFibGVTdGFraW5nLk5vZGVTdGFrZXIucmVnaXN0ZXJOZXdEZWxlZ2F0b3I6IENhbm5vdCByZWdpc3RlciBhIGRlbGVnYXRvciBiZWNhdXNlIHRoZSBub2RlIG9wZXJhdG9yIGZvciBJRCBcKG5vZGVJRCkgaXMgYmVsb3cgdGhlIG1pbmltdW0gc3Rha2UgcmVxdWlyZW1lbnQgZm9yIHRoZWlyIG5vZGUgcm9sZSAoXChub2RlUmVjb3JkLnJvbGUpKSIKICAgICAgICApCgogICAgICAgIC8vIGluY3JlbWVudCB0aGUgZGVsZWdhdG9yIElEIGNvdW50ZXIgZm9yIHRoaXMgbm9kZQogICAgICAgIG5vZGVSZWNvcmQuc2V0RGVsZWdhdG9ySURDb3VudGVyKG5vZGVSZWNvcmQuZGVsZWdhdG9ySURDb3VudGVyICsgVUludDMyKDEpKQoKICAgICAgICAvLyBDcmVhdGUgYSBuZXcgZGVsZWdhdG9yIHJlY29yZCBhbmQgc3RvcmUgaXQgaW4gdGhlIGNvbnRyYWN0CiAgICAgICAgbm9kZVJlY29yZC5zZXREZWxlZ2F0b3IoZGVsZWdhdG9ySUQ6IG5vZGVSZWNvcmQuZGVsZWdhdG9ySURDb3VudGVyLCBkZWxlZ2F0b3I6IDwtIGNyZWF0ZSBEZWxlZ2F0b3JSZWNvcmQoKSkKCiAgICAgICAgZW1pdCBOZXdEZWxlZ2F0b3JDcmVhdGVkKG5vZGVJRDogbm9kZVJlY29yZC5pZCwgZGVsZWdhdG9ySUQ6IG5vZGVSZWNvcmQuZGVsZWdhdG9ySURDb3VudGVyKQoKICAgICAgICAvLyBDcmVhdGUgYSBuZXcgTm9kZURlbGVnYXRvciBvYmplY3QgdGhhdCB0aGUgb3duZXIgc3RvcmVzIGluIHRoZWlyIGFjY291bnQKICAgICAgICBsZXQgbmV3RGVsZWdhdG9yIDwtY3JlYXRlIE5vZGVEZWxlZ2F0b3IoaWQ6IG5vZGVSZWNvcmQuZGVsZWdhdG9ySURDb3VudGVyLCBub2RlSUQ6IG5vZGVSZWNvcmQuaWQpCgogICAgICAgIG5ld0RlbGVnYXRvci5kZWxlZ2F0ZU5ld1Rva2Vucyhmcm9tOiA8LXRva2Vuc0NvbW1pdHRlZCkKCiAgICAgICAgcmV0dXJuIDwtbmV3RGVsZWdhdG9yCiAgICB9CgogICAgLy8vIGJvcnJvdyBhIHJlZmVyZW5jZSB0byB0byBvbmUgb2YgdGhlIG5vZGVzIGluIHRoZSByZWNvcmQKICAgIGFjY2VzcyhhY2NvdW50KSB2aWV3IGZ1biBib3Jyb3dOb2RlUmVjb3JkKF8gbm9kZUlEOiBTdHJpbmcpOiBhdXRoKEZ1bmdpYmxlVG9rZW4uV2l0aGRyYXcpICZOb2RlUmVjb3JkIHsKICAgICAgICBwcmUgewogICAgICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcubm9kZXNbbm9kZUlEXSAhPSBuaWw6CiAgICAgICAgICAgICAgICAiRmxvd0lEVGFibGVTdGFraW5nLk5vZGVTdGFrZXIuYm9ycm93Tm9kZVJlY29yZDogU3BlY2lmaWVkIG5vZGUgSUQgXChub2RlSUQpIGRvZXMgbm90IGV4aXN0IGluIHRoZSBpZGVudGl0eSB0YWJsZSIKICAgICAgICB9CiAgICAgICAgcmV0dXJuICgmRmxvd0lEVGFibGVTdGFraW5nLm5vZGVzW25vZGVJRF0gYXMgYXV0aChGdW5naWJsZVRva2VuLldpdGhkcmF3KSAmTm9kZVJlY29yZD8pIQogICAgfQoKICAgIC8vLyBib3Jyb3cgYSByZWZlcmVuY2UgdG8gdGhlIGBGbG93RmVlc2AgYWRtaW4gcmVzb3VyY2UgZm9yIHBheWluZyByZXdhcmRzCiAgICBhY2Nlc3MoYWNjb3VudCkgdmlldyBmdW4gYm9ycm93RmVlc0FkbWluKCk6ICZGbG93RmVlcy5BZG1pbmlzdHJhdG9yIHsKICAgICAgICBsZXQgZmVlc0FkbWluID0gc2VsZi5hY2NvdW50LnN0b3JhZ2UuYm9ycm93PCZGbG93RmVlcy5BZG1pbmlzdHJhdG9yPihmcm9tOiAvc3RvcmFnZS9mbG93RmVlc0FkbWluKQogICAgICAgICAgICA/PyBwYW5pYygiRmxvd0lEVGFibGVTdGFraW5nLk5vZGVTdGFrZXIuYm9ycm93RmVlc0FkbWluOiBDb3VsZCBub3QgYm9ycm93IGEgcmVmZXJlbmNlIHRvIHRoZSBGbG93RmVlcyBBZG1pbiBvYmplY3QiKQoKICAgICAgICByZXR1cm4gZmVlc0FkbWluCiAgICB9CgogICAgLy8vIFVwZGF0ZXMgYSBjbGFpbWVkIGJvb2xlYW4gZm9yIGEgc3BlY2lmaWMgcGF0aCB0byBpbmRpY2F0ZSB0aGF0CiAgICAvLy8gYSBwaWVjZSBvZiBub2RlIG1ldGFkYXRhIGhhcyBiZWVuIGNsYWltZWQgYnkgYSBub2RlCiAgICBhY2Nlc3MoYWNjb3VudCkgZnVuIHVwZGF0ZUNsYWltZWQocGF0aDogU3RvcmFnZVBhdGgsIF8ga2V5OiBTdHJpbmcsIGNsYWltZWQ6IEJvb2wpIHsKICAgICAgICBsZXQgY2xhaW1lZERpY3Rpb25hcnkgPSBzZWxmLmFjY291bnQuc3RvcmFnZS5ib3Jyb3c8YXV0aChNdXRhdGUpICZ7U3RyaW5nOiBCb29sfT4oZnJvbTogcGF0aCkKICAgICAgICAgICAgPz8gcGFuaWMoIkZsb3dJRFRhYmxlU3Rha2luZy5Ob2RlU3Rha2VyLnVwZGF0ZUNsYWltZWQ6IEludmFsaWQgcGF0aCBmb3IgZGljdGlvbmFyeSIpCgogICAgICAgIGlmIGNsYWltZWQgewogICAgICAgICAgICBjbGFpbWVkRGljdGlvbmFyeVtrZXldID0gdHJ1ZQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGNsYWltZWREaWN0aW9uYXJ5LnJlbW92ZShrZXk6IGtleSkKICAgICAgICB9CiAgICB9CgogICAgLy8vIFNldHMgYSBsaXN0IG9mIGFwcHJvdmVkIG5vZGUgSURzIGZvciB0aGUgY3VycmVudCBlcG9jaAogICAgYWNjZXNzKGNvbnRyYWN0KSBmdW4gc2V0UGFydGljaXBhbnROb2RlTGlzdChfIG5vZGVJRHM6IHtTdHJpbmc6IEJvb2x9KSB7CiAgICAgICAgbGV0IGxpc3QgPSBzZWxmLmFjY291bnQuc3RvcmFnZS5sb2FkPHtTdHJpbmc6IEJvb2x9Pihmcm9tOiAvc3RvcmFnZS9pZFRhYmxlQ3VycmVudExpc3QpCgogICAgICAgIHNlbGYuYWNjb3VudC5zdG9yYWdlLnNhdmU8e1N0cmluZzogQm9vbH0+KG5vZGVJRHMsIHRvOiAvc3RvcmFnZS9pZFRhYmxlQ3VycmVudExpc3QpCiAgICB9CgogICAgLy8vIEdldHMgdGhlIGN1cnJlbnQgbGlzdCBvZiBwYXJ0aWNpcGFudCAoc3Rha2VkIGluIHRoZSBjdXJyZW50IGVwb2NoKSBub2RlcyBhcyBhIGRpY3Rpb25hcnkuCiAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBnZXRQYXJ0aWNpcGFudE5vZGVMaXN0KCk6IHtTdHJpbmc6IEJvb2x9PyB7CiAgICAgICAgcmV0dXJuIHNlbGYuYWNjb3VudC5zdG9yYWdlLmNvcHk8e1N0cmluZzogQm9vbH0+KGZyb206IC9zdG9yYWdlL2lkVGFibGVDdXJyZW50TGlzdCkKICAgIH0KCiAgICAvLy8gR2V0cyB0aGUgY3VycmVudCBsaXN0IG9mIHBhcnRpY2lwYW50IG5vZGVzIChsaWtlIGdldEN1cnJlbnROb2RlTGlzdCkgYnV0IGFzIGEgbGlzdAogICAgLy8vIEtlcHQgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5CiAgICBhY2Nlc3MoYWxsKSBmdW4gZ2V0U3Rha2VkTm9kZUlEcygpOiBbU3RyaW5nXSB7CiAgICAgICAgbGV0IG5vZGVJRHMgPSBzZWxmLmdldFBhcnRpY2lwYW50Tm9kZUxpc3QoKSEKICAgICAgICByZXR1cm4gbm9kZUlEcy5rZXlzCiAgICB9CgogICAgLy8vIEFkZHMgYSBub2RlIGFuZC9vciBkZWxlZ2F0b3IgdG8gdGhlIG1vdmVzIHBlbmRpbmcgbGlzdAogICAgLy8vIGFuZCByZXR1cm5zIHRoZSBsaXN0CiAgICAvLy8gSWYgYGV4aXN0aW5nTGlzdGAgaXMgYG5pbGAsIHRoaXMgbG9hZHMgdGhlIGN1cnJlbnQgbGlzdCBmcm9tIHN0b3JhZ2UgYW5kIG1vZGlmaWVzIGl0CiAgICAvLy8gSWYgYGV4aXN0aW5nTGlzdGAgaXMgbm9uLWBuaWxgLCB0aGlzIG1vZGlmaWVzIHRoZSBnaXZlbiBsaXN0IGluc3RlYWQgb2YgbG9hZGluZyBmcm9tIHN0b3JhZ2UKICAgIGFjY2Vzcyhjb250cmFjdCkgZnVuIG1vZGlmeU5ld01vdmVzUGVuZGluZyhub2RlSUQ6IFN0cmluZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxlZ2F0b3JJRDogVUludDMyPywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZ0xpc3Q6IGF1dGgoTXV0YXRlKSAme1N0cmluZzoge1VJbnQzMjogQm9vbH19PykKICAgIHsKICAgICAgICBsZXQgbW92ZXNQZW5kaW5nTGlzdCA9IGV4aXN0aW5nTGlzdCA/PyAoc2VsZi5hY2NvdW50LnN0b3JhZ2UuYm9ycm93PGF1dGgoTXV0YXRlKSAme1N0cmluZzoge1VJbnQzMjogQm9vbH19Pihmcm9tOiAvc3RvcmFnZS9pZFRhYmxlTW92ZXNQZW5kaW5nTGlzdCkKICAgICAgICAgICAgPz8gcGFuaWMoIkZsb3dJRFRhYmxlU3Rha2luZy5Ob2RlU3Rha2VyLm1vZGlmeU5ld01vdmVzUGVuZGluZzogTm8gbW92ZXMgcGVuZGluZyBsaXN0IGluIGFjY291bnQgc3RvcmFnZSIpKQoKICAgICAgICAvLyBJZiB0aGVyZSBpcyBhbHJlYWR5IGEgbGlzdCBmb3IgdGhlIGdpdmVuIG5vZGUgSUQsIG92ZXJ3cml0ZSB0aGUgY3JlYXRlZCBvbmUKICAgICAgICBpZiBsZXQgZXhpc3RpbmdEZWxlZ2F0b3JMaXN0ID0gbW92ZXNQZW5kaW5nTGlzdC5yZW1vdmUoa2V5OiBub2RlSUQpIHsKCiAgICAgICAgICAgIC8vIElmIHRoaXMgZnVuY3Rpb24gY2FsbCBpcyB0byByZWNvcmQgYSBkZWxlZ2F0b3IncyBtb3ZlbWVudCwKICAgICAgICAgICAgLy8gcmVjb3JkIHRoZSBJRAogICAgICAgICAgICBpZiBsZXQgdW53cmFwcGVkRGVsZWdhdG9ySUQgPSBkZWxlZ2F0b3JJRCB7CiAgICAgICAgICAgICAgICBleGlzdGluZ0RlbGVnYXRvckxpc3RbdW53cmFwcGVkRGVsZWdhdG9ySURdID0gdHJ1ZQogICAgICAgICAgICB9CiAgICAgICAgICAgIG1vdmVzUGVuZGluZ0xpc3Rbbm9kZUlEXSA9IGV4aXN0aW5nRGVsZWdhdG9yTGlzdAogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIENyZWF0ZSBhbiBlbXB0eSBsaXN0IG9mIGRlbGVnYXRvcnMgd2l0aCBwZW5kaW5nIG1vdmVzIGZvciB0aGUgbm9kZSBJRAogICAgICAgICAgICB2YXIgZGVsZWdhdG9yTGlzdDoge1VJbnQzMjogQm9vbH0gPSB7fQogICAgICAgICAgICAvLyBJZiB0aGlzIGZ1bmN0aW9uIGNhbGwgaXMgdG8gcmVjb3JkIGEgZGVsZWdhdG9yJ3MgbW92ZW1lbnQsCiAgICAgICAgICAgIC8vIHJlY29yZCB0aGUgSUQKICAgICAgICAgICAgaWYgbGV0IHVud3JhcHBlZERlbGVnYXRvcklEID0gZGVsZWdhdG9ySUQgewogICAgICAgICAgICAgICAgZGVsZWdhdG9yTGlzdFt1bndyYXBwZWREZWxlZ2F0b3JJRF0gPSB0cnVlCiAgICAgICAgICAgIH0KICAgICAgICAgICAgbW92ZXNQZW5kaW5nTGlzdFtub2RlSURdID0gZGVsZWdhdG9yTGlzdAogICAgICAgIH0KICAgIH0KCiAgICAvLy8gR2V0cyBhIGxpc3Qgb2Ygbm9kZSBJRHMgd2hvIGhhdmUgcGVuZGluZyB0b2tlbiBtb3ZlbWVudHMKICAgIC8vLyBvciB3aG8ncyBkZWxlZ2F0b3JzIGhhdmUgcGVuZGluZyBtb3ZlbWVudHMKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGdldE1vdmVzUGVuZGluZ0xpc3QoKToge1N0cmluZzoge1VJbnQzMjogQm9vbH19PyB7CiAgICAgICAgcmV0dXJuIHNlbGYuYWNjb3VudC5zdG9yYWdlLmNvcHk8e1N0cmluZzoge1VJbnQzMjogQm9vbH19Pihmcm9tOiAvc3RvcmFnZS9pZFRhYmxlTW92ZXNQZW5kaW5nTGlzdCkKICAgIH0KCiAgICAvLy8gQ2FuZGlkYXRlIE5vZGVzIE1ldGhvZHMKICAgIC8vLwogICAgLy8vIENhbmRpZGF0ZSBOb2RlcyBhcmUgbmV3bHkgY29tbWl0dGVkIG5vZGVzIHdobyBhcmVuJ3QgYWxyZWFkeSBzdGFrZWQKICAgIC8vLyBUaGVyZSBpcyBhIGxpbWl0IHRvIHRoZSBudW1iZXIgb2YgY2FuZGlkYXRlIG5vZGVzIHBlciBub2RlIHJvbGUgcGVyIGVwb2NoCiAgICAvLy8gVGhlIGNhbmRpZGF0ZSBub2RlIGxpc3QgaXMgYSBkaWN0aW9uYXJ5IHRoYXQgbWFwcyBub2RlIHJvbGVzCiAgICAvLy8gdG8gYSBsaXN0IG9mIG5vZGUgSURzIG9mIHRoYXQgcm9sZQogICAgLy8vIEdldHMgdGhlIGNhbmRpZGF0ZSBub2RlIGxpc3Qgc2l6ZSBsaW1pdHMgZm9yIGVhY2ggcm9sZQogICAgYWNjZXNzKGFsbCkgZnVuIGdldENhbmRpZGF0ZU5vZGVMaW1pdHMoKToge1VJbnQ4OiBVSW50NjR9PyB7CiAgICAgICAgcmV0dXJuIHNlbGYuYWNjb3VudC5zdG9yYWdlLmNvcHk8e1VJbnQ4OiBVSW50NjR9Pihmcm9tOiAvc3RvcmFnZS9pZFRhYmxlQ2FuZGlkYXRlTm9kZUxpbWl0cykKICAgIH0KCiAgICAvLy8gQWRkcyB0aGUgcHJvdmlkZWQgbm9kZSBJRCB0byB0aGUgY2FuZGlkYXRlIG5vZGUgbGlzdAogICAgYWNjZXNzKGNvbnRyYWN0KSBmdW4gYWRkVG9DYW5kaWRhdGVOb2RlTGlzdChub2RlSUQ6IFN0cmluZywgcm9sZVRvQWRkOiBVSW50OCkgewogICAgICAgIHByZSB7CiAgICAgICAgICAgIHJvbGVUb0FkZCA+PSBVSW50OCgxKSAmJiByb2xlVG9BZGQgPD0gVUludDgoNSk6ICJGbG93SURUYWJsZVN0YWtpbmcuTm9kZVN0YWtlci5hZGRUb0NhbmRpZGF0ZU5vZGVMaXN0OiBUaGUgcm9sZSBtdXN0IGJlIDEsIDIsIDMsIDQsIG9yIDUgYnV0IGdvdCBcKHJvbGVUb0FkZCkiCiAgICAgICAgfQoKICAgICAgICB2YXIgY2FuZGlkYXRlTm9kZXMgPSBGbG93SURUYWJsZVN0YWtpbmcuYWNjb3VudC5zdG9yYWdlLmJvcnJvdzxhdXRoKE11dGF0ZSkgJntVSW50ODoge1N0cmluZzogQm9vbH19Pihmcm9tOiAvc3RvcmFnZS9pZFRhYmxlQ2FuZGlkYXRlTm9kZXMpIQogICAgICAgIHZhciBjYW5kaWRhdGVOb2Rlc0ZvclJvbGUgPSBjYW5kaWRhdGVOb2Rlcy5yZW1vdmUoa2V5OiByb2xlVG9BZGQpCiAgICAgICAgICAgID8/IHBhbmljKCJGbG93SURUYWJsZVN0YWtpbmcuTm9kZVN0YWtlci5hZGRUb0NhbmRpZGF0ZU5vZGVMaXN0OiBDb3VsZCBub3QgZ2V0IGNhbmRpZGF0ZSBub2RlcyBmb3Igcm9sZTogXChyb2xlVG9BZGQpIikKCiAgICAgICAgaWYgVUludDY0KGNhbmRpZGF0ZU5vZGVzRm9yUm9sZS5rZXlzLmxlbmd0aCkgPj0gc2VsZi5nZXRDYW5kaWRhdGVOb2RlTGltaXRzKCkhW3JvbGVUb0FkZF0hIHsKICAgICAgICAgICAgcGFuaWMoIkZsb3dJRFRhYmxlU3Rha2luZy5Ob2RlU3Rha2VyLmFkZFRvQ2FuZGlkYXRlTm9kZUxpc3Q6IENhbmRpZGF0ZSBub2RlIGxpbWl0IG9mIFwoc2VsZi5nZXRDYW5kaWRhdGVOb2RlTGltaXRzKCkhW3JvbGVUb0FkZF0hKSBleGNlZWRlZCBmb3Igbm9kZSByb2xlIFwocm9sZVRvQWRkKSIpCiAgICAgICAgfQoKICAgICAgICBjYW5kaWRhdGVOb2Rlc0ZvclJvbGVbbm9kZUlEXSA9IHRydWUKICAgICAgICBjYW5kaWRhdGVOb2Rlc1tyb2xlVG9BZGRdID0gY2FuZGlkYXRlTm9kZXNGb3JSb2xlCiAgICB9CgogICAgLy8vIFJlbW92ZXMgdGhlIHByb3ZpZGVkIG5vZGUgSUQgZnJvbSB0aGUgY2FuZGlkYXRlIG5vZGUgbGlzdAogICAgYWNjZXNzKGNvbnRyYWN0KSBmdW4gcmVtb3ZlRnJvbUNhbmRpZGF0ZU5vZGVMaXN0KG5vZGVJRDogU3RyaW5nLCByb2xlOiBVSW50OCkgewogICAgICAgIHByZSB7CiAgICAgICAgICAgIHJvbGUgPj0gVUludDgoMSkgJiYgcm9sZSA8PSBVSW50OCg1KTogIkZsb3dJRFRhYmxlU3Rha2luZy5Ob2RlU3Rha2VyLnJlbW92ZUZyb21DYW5kaWRhdGVOb2RlTGlzdDogVGhlIHJvbGUgbXVzdCBiZSAxLCAyLCAzLCA0LCBvciA1IGJ1dCBnb3QgXChyb2xlKSIKICAgICAgICB9CgogICAgICAgIHZhciBjYW5kaWRhdGVOb2RlcyA9IEZsb3dJRFRhYmxlU3Rha2luZy5hY2NvdW50LnN0b3JhZ2UuYm9ycm93PGF1dGgoTXV0YXRlKSAme1VJbnQ4OiB7U3RyaW5nOiBCb29sfX0+KGZyb206IC9zdG9yYWdlL2lkVGFibGVDYW5kaWRhdGVOb2RlcykKICAgICAgICAgICAgPz8gcGFuaWMoIkZsb3dJRFRhYmxlU3Rha2luZy5Ob2RlU3Rha2VyLnJlbW92ZUZyb21DYW5kaWRhdGVOb2RlTGlzdDogQ291bGQgbm90IGxvYWQgY2FuZGlkYXRlIG5vZGUgbGlzdCBmcm9tIHN0b3JhZ2UiKQogICAgICAgIHZhciBjYW5kaWRhdGVOb2Rlc0ZvclJvbGUgPSBjYW5kaWRhdGVOb2Rlcy5yZW1vdmUoa2V5OiByb2xlKQogICAgICAgICAgICA/PyBwYW5pYygiRmxvd0lEVGFibGVTdGFraW5nLk5vZGVTdGFrZXIucmVtb3ZlRnJvbUNhbmRpZGF0ZU5vZGVMaXN0OiBDb3VsZCBub3QgZ2V0IGNhbmRpZGF0ZSBub2RlcyBmb3Igcm9sZTogXChyb2xlKSIpCiAgICAgICAgCiAgICAgICAgY2FuZGlkYXRlTm9kZXNGb3JSb2xlLnJlbW92ZShrZXk6IG5vZGVJRCkKICAgICAgICBjYW5kaWRhdGVOb2Rlc1tyb2xlXSA9IGNhbmRpZGF0ZU5vZGVzRm9yUm9sZQogICAgfQoKICAgIC8vLyBSZXR1cm5zIHRoZSBjdXJyZW50IGNhbmRpZGF0ZSBub2RlIGxpc3QKICAgIGFjY2VzcyhhbGwpIGZ1biBnZXRDYW5kaWRhdGVOb2RlTGlzdCgpOiB7VUludDg6IHtTdHJpbmc6IEJvb2x9fSB7CiAgICAgICAgcmV0dXJuIEZsb3dJRFRhYmxlU3Rha2luZy5hY2NvdW50LnN0b3JhZ2UuY29weTx7VUludDg6IHtTdHJpbmc6IEJvb2x9fT4oZnJvbTogL3N0b3JhZ2UvaWRUYWJsZUNhbmRpZGF0ZU5vZGVzKQogICAgICAgICAgICA/PyB7MToge30sIDI6IHt9LCAzOiB7fSwgNDoge30sIDU6IHt9fQogICAgfQoKICAgIC8vLyBHZXQgc2xvdCAoY291bnQpIGxpbWl0cyBmb3IgZWFjaCBub2RlIHJvbGUKICAgIGFjY2VzcyhhbGwpIGZ1biBnZXRSb2xlU2xvdExpbWl0cygpOiB7VUludDg6IFVJbnQxNn0gewogICAgICAgIHJldHVybiBGbG93SURUYWJsZVN0YWtpbmcuYWNjb3VudC5zdG9yYWdlLmNvcHk8e1VJbnQ4OiBVSW50MTZ9Pihmcm9tOiAvc3RvcmFnZS9mbG93U3Rha2luZ1Nsb3RMaW1pdHMpCiAgICAgICAgICAgID8/IHsxOiAwLCAyOiAwLCAzOiAwLCA0OiAwLCA1OiAwfQogICAgfQoKICAgIC8vLyBHZXRzIHRoZSBudW1iZXIgb2YgYXV0by1vcGVuZWQgc2xvdHMgZm9yIGVhY2ggbm9kZSByb2xlLiAKICAgIGFjY2VzcyhhbGwpIGZ1biBnZXRPcGVuTm9kZVNsb3RzKCk6IHtVSW50ODogVUludDE2fSB7CiAgICAgICAgcmV0dXJuIEZsb3dJRFRhYmxlU3Rha2luZy5hY2NvdW50LnN0b3JhZ2UuY29weTx7VUludDg6IFVJbnQxNn0+KGZyb206IC9zdG9yYWdlL2Zsb3dTdGFraW5nT3Blbk5vZGVTbG90cykKICAgICAgICAgICAgPz8gKHt9IGFzIHtVSW50ODogVUludDE2fSkKICAgIH0KCiAgICAvLy8gUmV0dXJucyBhIGRpY3Rpb25hcnkgdGhhdCBpbmRpY2F0ZXMgaG93IG1hbnkgcGFydGljaXBhbnQgbm9kZXMgdGhlcmUgYXJlIGZvciBlYWNoIHJvbGUKICAgIGFjY2VzcyhhbGwpIGZ1biBnZXRDdXJyZW50Um9sZU5vZGVDb3VudHMoKToge1VJbnQ4OiBVSW50MTZ9IHsKICAgICAgICBpZiBsZXQgY3VycmVudENvdW50cyA9IEZsb3dJRFRhYmxlU3Rha2luZy5hY2NvdW50LnN0b3JhZ2UuY29weTx7VUludDg6IFVJbnQxNn0+KGZyb206IC9zdG9yYWdlL2Zsb3dTdGFraW5nUm9sZU5vZGVDb3VudHMpIHsKICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRDb3VudHMKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBJZiB0aGUgY29udHJhY3QgY2FuJ3QgcmVhZCB0aGUgdmFsdWUgZnJvbSBzdG9yYWdlLCBjb25zdHJ1Y3QgaXQKICAgICAgICAgICAgbGV0IHBhcnRpY2lwYW50Tm9kZUlEcyA9IEZsb3dJRFRhYmxlU3Rha2luZy5nZXRQYXJ0aWNpcGFudE5vZGVMaXN0KCkhCgogICAgICAgICAgICBsZXQgcm9sZUNvdW50czoge1VJbnQ4OiBVSW50MTZ9ID0gezE6IDAsIDI6IDAsIDM6IDAsIDQ6IDAsIDU6IDB9CgogICAgICAgICAgICBmb3Igbm9kZUlEIGluIHBhcnRpY2lwYW50Tm9kZUlEcyB7CiAgICAgICAgICAgICAgICBsZXQgbm9kZUluZm8gPSBGbG93SURUYWJsZVN0YWtpbmcuTm9kZUluZm8obm9kZUlEOiBub2RlSUQpCiAgICAgICAgICAgICAgICByb2xlQ291bnRzW25vZGVJbmZvLnJvbGVdID0gcm9sZUNvdW50c1tub2RlSW5mby5yb2xlXSEgKyAxCiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJvbGVDb3VudHMKICAgICAgICB9CiAgICB9CgogICAgLy8vIENoZWNrcyBpZiB0aGUgZ2l2ZW4gc3RyaW5nIGNvbnRhaW5zIG9ubHkgbG93ZXJjYXNlIGhleCBjaGFyYWN0ZXJzICgwLTksIGEtZikKICAgIC8vLyBVc2VkIHRvIHByZXZlbnQgY2FzZS1hbGlhc2luZyBhdHRhY2tzIHdoZXJlIGRpZmZlcmVudCBoZXggc3RyaW5ncwogICAgLy8vIChlLmcuLCAiYWFiYiIgdnMgIkFBQkIiKSBkZWNvZGUgdG8gdGhlIHNhbWUgYnl0ZXMKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGlzTG93ZXJjYXNlSGV4KF8gaW5wdXQ6IFN0cmluZyk6IEJvb2wgewogICAgICAgIGxldCBieXRlVmVyc2lvbiA9IGlucHV0LnV0ZjgKCiAgICAgICAgZm9yIGNoYXJhY3RlciBpbiBieXRlVmVyc2lvbiB7CiAgICAgICAgICAgIC8vIE9ubHkgYWxsb3cgMC05IChBU0NJSSA0OC01NykgYW5kIGEtZiAoQVNDSUkgOTctMTAyKQogICAgICAgICAgICBpZiAoKGNoYXJhY3RlciA8IDQ4KSB8fCAoY2hhcmFjdGVyID4gNTcgJiYgY2hhcmFjdGVyIDwgOTcpIHx8IChjaGFyYWN0ZXIgPiAxMDIpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2UKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWUKICAgIH0KCiAgICAvLy8gQ2hlY2tzIGlmIHRoZSBnaXZlbiBub2RlIElEIGhhcyBhbGwgbnVtYmVycyBvciBsb3dlcmNhc2UgaGV4IGNoYXJhY3RlcnMKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGlzVmFsaWROb2RlSUQoXyBpbnB1dDogU3RyaW5nKTogQm9vbCB7CiAgICAgICAgcmV0dXJuIHNlbGYuaXNMb3dlcmNhc2VIZXgoaW5wdXQpCiAgICB9CgogICAgLy8vIFZhbGlkYXRlcyB0aGF0IGEgbmV0d29ya2luZyBhZGRyZXNzIGlzIHByb3Blcmx5IGZvcm1hdHRlZAogICAgLy8vIFJlcXVpcmVtZW50czoKICAgIC8vLyAxLiBNdXN0IG5vdCBiZSBhbiBJUCBhZGRyZXNzCiAgICAvLy8gMi4gTXVzdCBjb250YWluIGEgcG9ydCBudW1iZXIgYWZ0ZXIgYSBjb2xvbgogICAgLy8vIDMuIE11c3QgYmUgYSB2YWxpZCBkb21haW4gbmFtZSBmb3JtYXQKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGlzVmFsaWROZXR3b3JraW5nQWRkcmVzcyhhZGRyZXNzOiBTdHJpbmcpOiBCb29sIHsKICAgICAgICAvLyBDaGVjayBsZW5ndGgKICAgICAgICBpZiAgYWRkcmVzcy5sZW5ndGggPT0gMCB8fCBhZGRyZXNzLmxlbmd0aCA+IDUxMCB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZQogICAgICAgIH0KCiAgICAgICAgLy8gU3BsaXQgdGhlIGFkZHJlc3MgaW50byBkb21haW4gYW5kIHBvcnQKICAgICAgICBsZXQgcGFydHMgPSBhZGRyZXNzLnNwbGl0KHNlcGFyYXRvcjogIjoiKQogICAgICAgIC8vIENoZWNrIGlmIGFkZHJlc3MgaXMgbm90IGFuIElQdjYgYWRkcmVzcwogICAgICAgIGlmIHBhcnRzLmxlbmd0aCAhPSAyIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlCiAgICAgICAgfQoKICAgICAgICBsZXQgZG9tYWluID0gcGFydHNbMF0KICAgICAgICBsZXQgcG9ydCA9IHBhcnRzWzFdCgogICAgICAgIC8vIENoZWNrIGlmIHBvcnQgaXMgYSB2YWxpZCBudW1iZXIgYmV0d2VlbiAxIGFuZCA2NTUzNQogICAgICAgIGxldCBwb3J0TnVtID0gVUludDE2LmZyb21TdHJpbmcocG9ydCkKICAgICAgICBpZiBwb3J0TnVtID09IG5pbCB8fCBwb3J0TnVtISA8IDEgfHwgcG9ydE51bSEgPiA2NTUzNSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZQogICAgICAgIH0KCiAgICAgICAgLy8gQ2hlY2sgaWYgZG9tYWluIGNvbnRhaW5zIG9ubHkgbGV0dGVycywgZGlnaXRzLCBkb3QsIGRhc2gsIGh5cGhlbiBvciB1bmRlcnNjb3JlCiAgICAgICAgbGV0IHZhbGlkQ2hhcnMgPSAiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkuLV8iLnV0ZjgKICAgICAgICBmb3IgY2hhciBpbiBkb21haW4udXRmOCB7CiAgICAgICAgICAgIGlmICF2YWxpZENoYXJzLmNvbnRhaW5zKGNoYXIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBsZXQgbGFiZWxzID0gZG9tYWluLnNwbGl0KHNlcGFyYXRvcjogIi4iKQogICAgICAgIGxldCB0bGQgPSBsYWJlbHNbbGFiZWxzLmxlbmd0aCAtIDFdCiAgICAgICAgdmFyIGhhc0xldHRlciA9IGZhbHNlCiAgICAgICAgZm9yIGMgaW4gdGxkLnV0ZjggewogICAgICAgICAgICAvLyBUTEQgbXVzdCBub3QgYmUgYWxsIGRpZ2l0cyBpLmUuIGFuIElQIGFkZHJlc3MKICAgICAgICAgICAgbGV0IGlzVXBwZXIgPSBjID49IDY1ICYmIGMgPD0gOTAgICAvLyAnQSctJ1onCiAgICAgICAgICAgIGxldCBpc0xvd2VyID0gYyA+PSA5NyAmJiBjIDw9IDEyMiAgLy8gJ2EnLSd6JwogICAgICAgICAgICBpZiBpc1VwcGVyIHx8IGlzTG93ZXIgewogICAgICAgICAgICAgICAgaGFzTGV0dGVyID0gdHJ1ZQogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgIWhhc0xldHRlciB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWUKICAgIH0KCiAgICAvLy8gSW5kaWNhdGVzIGlmIHRoZSBzdGFraW5nIGF1Y3Rpb24gaXMgY3VycmVudGx5IGVuYWJsZWQKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIHN0YWtpbmdFbmFibGVkKCk6IEJvb2wgewogICAgICAgIHJldHVybiBzZWxmLmFjY291bnQuc3RvcmFnZS5jb3B5PEJvb2w+KGZyb206IC9zdG9yYWdlL3N0YWtpbmdFbmFibGVkKSA/PyBmYWxzZQogICAgfQoKICAgIC8vLyBHZXRzIGFuIGFycmF5IG9mIHRoZSBub2RlIElEcyB0aGF0IGFyZSBwcm9wb3NlZCBmb3IgdGhlIG5leHQgZXBvY2gKICAgIC8vLyBEdXJpbmcgdGhlIHN0YWtpbmcgYXVjdGlvbiwgdGhpcyB3aWxsIG5vdCBpbmNsdWRlIGFjY2VzcyBub2RlcyB3aG8KICAgIC8vLyBoYXZlbid0IGJlZW4gc2VsZWN0ZWQgYnkgdGhlIHNsb3Qgc2VsZWN0aW9uIGFsZ29yaXRobSB5ZXQKICAgIC8vLyBBZnRlciB0aGUgc3Rha2luZyBhdWN0aW9uIGVuZHMsIHNwZWNpZmljYWxseSBhZnRlciB1bmFwcHJvdmVkIG5vZGVzIGhhdmUgYmVlbgogICAgLy8vIHJlbW92ZWQgYW5kIHNsb3RzIGhhdmUgYmVlbiBmaWxsZWQgYW5kIGZvciB0aGUgcmVzdCBvZiB0aGUgZXBvY2gsCiAgICAvLy8gVGhpcyBsaXN0IHdpbGwgYWNjdXJhdGVseSByZXByZXNlbnQgdGhlIG5vZGVzIHRoYXQgd2lsbCBiZSBpbiB0aGUgbmV4dCBlcG9jaAogICAgYWNjZXNzKGFsbCkgZnVuIGdldFByb3Bvc2VkTm9kZUlEcygpOiBbU3RyaW5nXSB7CgogICAgICAgIGxldCBub2RlSURzID0gRmxvd0lEVGFibGVTdGFraW5nLmdldE5vZGVJRHMoKQogICAgICAgIGxldCBhcHByb3ZlZE5vZGVJRHM6IHtTdHJpbmc6IEJvb2x9ID0gRmxvd0lEVGFibGVTdGFraW5nLmdldEFwcHJvdmVkTGlzdCgpCiAgICAgICAgICAgID8/IHBhbmljKCJGbG93SURUYWJsZVN0YWtpbmcuTm9kZVN0YWtlci5nZXRQcm9wb3NlZE5vZGVJRHM6IENvdWxkIG5vdCByZWFkIHRoZSBhcHByb3ZlIGxpc3QgZnJvbSBzdG9yYWdlIikKICAgICAgICBsZXQgcHJvcG9zZWROb2RlSURzOiB7U3RyaW5nOiBCb29sfSA9IHt9CgogICAgICAgIGZvciBub2RlSUQgaW4gbm9kZUlEcyB7CgogICAgICAgICAgICBsZXQgbm9kZVJlY29yZCA9IEZsb3dJRFRhYmxlU3Rha2luZy5ib3Jyb3dOb2RlUmVjb3JkKG5vZGVJRCkKCiAgICAgICAgICAgIGxldCB0b3RhbFRva2Vuc0NvbW1pdHRlZCA9IG5vZGVSZWNvcmQubm9kZUZ1bGxDb21taXR0ZWRCYWxhbmNlKCkKCiAgICAgICAgICAgIGxldCBncmVhdGVyVGhhbk1pbiA9IEZsb3dJRFRhYmxlU3Rha2luZy5pc0dyZWF0ZXJUaGFuTWluaW11bUZvclJvbGUobnVtVG9rZW5zOiB0b3RhbFRva2Vuc0NvbW1pdHRlZCwgcm9sZTogbm9kZVJlY29yZC5yb2xlKQogICAgICAgICAgICBsZXQgbm9kZUlzQXBwcm92ZWQ6IEJvb2wgPSAgYXBwcm92ZWROb2RlSURzW25vZGVJRF0gPz8gZmFsc2UKICAgICAgICAgICAgbGV0IG5vZGVXZWlnaHQgPSBub2RlUmVjb3JkLmluaXRpYWxXZWlnaHQKCiAgICAgICAgICAgIC8vIGFkbWluLWFwcHJvdmVkIG5vZGUgcm9sZXMgKGV4ZWN1dGlvbi9jb2xsZWN0aW9uL2NvbnNlbnN1cy92ZXJpZmljYXRpb24pCiAgICAgICAgICAgIC8vIG11c3QgYmUgYXBwcm92ZWQgQU5EIGhhdmUgc3VmZmljaWVudCBzdGFrZQogICAgICAgICAgICBpZiBub2RlUmVjb3JkLnJvbGUgIT0gVUludDgoNSkgJiYgZ3JlYXRlclRoYW5NaW4gJiYgbm9kZUlzQXBwcm92ZWQgewogICAgICAgICAgICAgICAgcHJvcG9zZWROb2RlSURzW25vZGVJRF0gPSB0cnVlCiAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBwZXJtaXNzaW9ubGVzcyBub2RlIHJvbGVzIChhY2Nlc3MpCiAgICAgICAgICAgIC8vIE5PVEU6IEFjY2VzcyBub2RlcyB3aGljaCByZWdpc3RlcmVkIHByaW9yIHRvIHRoZSAxMDAtRkxPVyBzdGFrZSByZXF1aXJlbWVudAogICAgICAgICAgICAvLyAod2hpY2ggbXVzdCBiZSBhcHByb3ZlZCkgYXJlIG5vdCByZW1vdmVkIGR1cmluZyBhIHRlbXBvcmFyeSBncmFjZSBwZXJpb2QgZHVyaW5nIAogICAgICAgICAgICAvLyB3aGljaCB0aGVzZSBncmFuZGZhdGhlcmVkIG5vZGUgb3BlcmF0b3JzIG1heSBzdWJtaXQgdGhlIG5lY2Vzc2FyeSBzdGFrZSByZXF1aXJlbWVudC4KICAgICAgICAgICAgLy8gVGhlcmVmb3JlIEFjY2VzcyBub2RlcyBtdXN0IGVpdGhlciBiZSBhcHByb3ZlZCBPUiBoYXZlIHN1ZmZpY2llbnQgc3Rha2U6CiAgICAgICAgICAgIC8vICAtIE9sZCBBTnMgbXVzdCBiZSBhcHByb3ZlZCwgYnV0IGFyZSBhbGxvd2VkIHRvIGhhdmUgemVybyBzdGFrZQogICAgICAgICAgICAvLyAgLSBOZXcgQU5zIG1heSBiZSB1bmFwcHJvdmVkLCBidXQgbXVzdCBoYXZlIHN1Ym1pdHRlZCBzdWZmaWNpZW50IHN0YWtlCiAgICAgICAgICAgIGlmIG5vZGVSZWNvcmQucm9sZSA9PSBVSW50OCg1KSAmJgogICAgICAgICAgICAgICAoZ3JlYXRlclRoYW5NaW4gfHwgbm9kZUlzQXBwcm92ZWQpICYmCiAgICAgICAgICAgICAgIG5vZGVXZWlnaHQgPiAwCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHByb3Bvc2VkTm9kZUlEc1tub2RlSURdID0gdHJ1ZQogICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gcHJvcG9zZWROb2RlSURzLmtleXMKICAgIH0KCiAgICAvLy8gR2V0cyBhbiBhcnJheSBvZiBhbGwgdGhlIG5vZGUgSURzIHRoYXQgaGF2ZSBldmVyIHJlZ2lzdGVyZWQKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGdldE5vZGVJRHMoKTogW1N0cmluZ10gewogICAgICAgIHJldHVybiBGbG93SURUYWJsZVN0YWtpbmcubm9kZXMua2V5cwogICAgfQoKICAgIC8vLyBDaGVja3MgaWYgdGhlIGFtb3VudCBvZiB0b2tlbnMgaXMgZ3JlYXRlciB0aGFuIHRoZSBtaW5pbXVtIHN0YWtpbmcgcmVxdWlyZW1lbnQKICAgIC8vLyBmb3IgdGhlIHNwZWNpZmllZCBub2RlIHJvbGUKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGlzR3JlYXRlclRoYW5NaW5pbXVtRm9yUm9sZShudW1Ub2tlbnM6IFVGaXg2NCwgcm9sZTogVUludDgpOiBCb29sIHsKICAgICAgICBsZXQgbWluaW11bVN0YWtlID0gc2VsZi5taW5pbXVtU3Rha2VSZXF1aXJlZFtyb2xlXQogICAgICAgICAgICA/PyBwYW5pYygiRmxvd0lEVGFibGVTdGFraW5nLk5vZGVTdGFrZXIuaXNHcmVhdGVyVGhhbk1pbmltdW1Gb3JSb2xlOiBJbmNvcnJlY3Qgcm9sZSBwcm92aWRlZCBmb3IgbWluaW11bSBzdGFrZS4gTXVzdCBiZSAxLCAyLCAzLCA0LCBvciA1IGJ1dCBnb3QgXChyb2xlKSIpCgogICAgICAgIHJldHVybiBudW1Ub2tlbnMgPj0gbWluaW11bVN0YWtlCiAgICB9CgogICAgLy8vIEluZGljYXRlcyBpZiB0aGUgc3BlY2lmaWVkIG5ldHdvcmtpbmcgYWRkcmVzcyBpcyBjbGFpbWVkIGJ5IGEgbm9kZQogICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gZ2V0TmV0d29ya2luZ0FkZHJlc3NDbGFpbWVkKGFkZHJlc3M6IFN0cmluZyk6IEJvb2wgewogICAgICAgIHJldHVybiBzZWxmLmdldENsYWltZWQocGF0aDogL3N0b3JhZ2UvbmV0d29ya2luZ0FkZHJlc3Nlc0NsYWltZWQsIGtleTogYWRkcmVzcykKICAgIH0KCiAgICAvLy8gSW5kaWNhdGVzIGlmIHRoZSBzcGVjaWZpZWQgbmV0d29ya2luZyBrZXkgaXMgY2xhaW1lZCBieSBhIG5vZGUKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGdldE5ldHdvcmtpbmdLZXlDbGFpbWVkKGtleTogU3RyaW5nKTogQm9vbCB7CiAgICAgICAgcmV0dXJuIHNlbGYuZ2V0Q2xhaW1lZChwYXRoOiAvc3RvcmFnZS9uZXR3b3JraW5nS2V5c0NsYWltZWQsIGtleToga2V5KQogICAgfQoKICAgIC8vLyBJbmRpY2F0ZXMgaWYgdGhlIHNwZWNpZmllZCBzdGFraW5nIGtleSBpcyBjbGFpbWVkIGJ5IGEgbm9kZQogICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gZ2V0U3Rha2luZ0tleUNsYWltZWQoa2V5OiBTdHJpbmcpOiBCb29sIHsKICAgICAgICByZXR1cm4gc2VsZi5nZXRDbGFpbWVkKHBhdGg6IC9zdG9yYWdlL3N0YWtpbmdLZXlzQ2xhaW1lZCwga2V5OiBrZXkpCiAgICB9CgogICAgLy8vIEdldHMgdGhlIGNsYWltZWQgc3RhdHVzIG9mIGEgcGFydGljdWxhciBwaWVjZSBvZiBub2RlIG1ldGFkYXRhCiAgICBhY2Nlc3MoYWNjb3VudCkgdmlldyBmdW4gZ2V0Q2xhaW1lZChwYXRoOiBTdG9yYWdlUGF0aCwga2V5OiBTdHJpbmcpOiBCb29sIHsKCQlsZXQgY2xhaW1lZERpY3Rpb25hcnkgPSBzZWxmLmFjY291bnQuc3RvcmFnZS5ib3Jyb3c8JntTdHJpbmc6IEJvb2x9Pihmcm9tOiBwYXRoKQogICAgICAgICAgICA/PyBwYW5pYygiRmxvd0lEVGFibGVTdGFraW5nLk5vZGVTdGFrZXIuZ2V0Q2xhaW1lZDogSW52YWxpZCBwYXRoIGZvciBkaWN0aW9uYXJ5IikKICAgICAgICByZXR1cm4gY2xhaW1lZERpY3Rpb25hcnlba2V5XSA/PyBmYWxzZQogICAgfQoKICAgIC8vLyBSZXR1cm5zIHRoZSBsaXN0IG9mIGFwcHJvdmVkIG5vZGUgSURzIHRoYXQgdGhlIGFkbWluIGhhcyBzZXQKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGdldEFwcHJvdmVkTGlzdCgpOiB7U3RyaW5nOiBCb29sfT8gewogICAgICAgIHJldHVybiBzZWxmLmFjY291bnQuc3RvcmFnZS5jb3B5PHtTdHJpbmc6IEJvb2x9Pihmcm9tOiAvc3RvcmFnZS9pZFRhYmxlQXBwcm92ZUxpc3QpCiAgICB9CgogICAgLy8vIFJldHVybnMgdGhlIGxpc3Qgb2Ygbm9kZSBJRHMgd2hvc2UgcmV3YXJkcyB3aWxsIGJlIHJlZHVjZWQgaW4gdGhlIG5leHQgcGF5bWVudAogICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gZ2V0Tm9uT3BlcmF0aW9uYWxOb2Rlc0xpc3QoKToge1N0cmluZzogVUZpeDY0fSB7CiAgICAgICAgcmV0dXJuIHNlbGYuYWNjb3VudC5zdG9yYWdlLmNvcHk8e1N0cmluZzogVUZpeDY0fT4oZnJvbTogL3N0b3JhZ2UvaWRUYWJsZU5vbk9wZXJhdGlvbmFsTm9kZXNMaXN0KQogICAgICAgICAgICA/PyBwYW5pYygiRmxvd0lEVGFibGVTdGFraW5nLk5vZGVTdGFrZXIuZ2V0Tm9uT3BlcmF0aW9uYWxOb2Rlc0xpc3Q6IENvdWxkIG5vdCBnZXQgbm9uLW9wZXJhdGlvbmFsIG5vZGUgbGlzdCIpCiAgICB9CgogICAgLy8vIEdldHMgdGhlIG1pbmltdW0gc3Rha2UgcmVxdWlyZW1lbnRzIGZvciBhbGwgdGhlIG5vZGUgdHlwZXMKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGdldE1pbmltdW1TdGFrZVJlcXVpcmVtZW50cygpOiB7VUludDg6IFVGaXg2NH0gewogICAgICAgIHJldHVybiBzZWxmLm1pbmltdW1TdGFrZVJlcXVpcmVkCiAgICB9CgogICAgLy8vIEdldHMgdGhlIG1pbmltdW0gc3Rha2UgcmVxdWlyZW1lbnQgZm9yIGRlbGVnYXRvcnMKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGdldERlbGVnYXRvck1pbmltdW1TdGFrZVJlcXVpcmVtZW50KCk6IFVGaXg2NCB7CiAgICAgICAgcmV0dXJuIHNlbGYuYWNjb3VudC5zdG9yYWdlLmNvcHk8VUZpeDY0Pihmcm9tOiAvc3RvcmFnZS9kZWxlZ2F0b3JTdGFraW5nTWluaW11bSkKICAgICAgICAgICAgPz8gMC4wCiAgICB9CgogICAgLy8vIEdldHMgYSBkaWN0aW9uYXJ5IHRoYXQgaW5kaWNhdGVzIHRoZSBjdXJyZW50IG51bWJlciBvZiB0b2tlbnMgc3Rha2VkCiAgICAvLy8gYnkgYWxsIHRoZSBub2RlcyBvZiBlYWNoIHR5cGUKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGdldFRvdGFsVG9rZW5zU3Rha2VkQnlOb2RlVHlwZSgpOiB7VUludDg6IFVGaXg2NH0gewogICAgICAgIHJldHVybiBzZWxmLnRvdGFsVG9rZW5zU3Rha2VkQnlOb2RlVHlwZQogICAgfQoKICAgIC8vLyBHZXRzIHRoZSB0b3RhbCBudW1iZXIgb2YgRkxPVyB0aGF0IGlzIGN1cnJlbnRseSBzdGFrZWQKICAgIC8vLyBieSBhbGwgb2YgdGhlIHN0YWtlZCBub2RlcyBpbiB0aGUgY3VycmVudCBlcG9jaAogICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gZ2V0VG90YWxTdGFrZWQoKTogVUZpeDY0IHsKICAgICAgICB2YXIgdG90YWxTdGFrZWQ6IFVGaXg2NCA9IDAuMAogICAgICAgIGZvciBub2RlVHlwZSBpbiBGbG93SURUYWJsZVN0YWtpbmcudG90YWxUb2tlbnNTdGFrZWRCeU5vZGVUeXBlLmtleXMgewogICAgICAgICAgICAvLyBEbyBub3QgY291bnQgYWNjZXNzIG5vZGVzCiAgICAgICAgICAgIGlmIG5vZGVUeXBlICE9IFVJbnQ4KDUpIHsKICAgICAgICAgICAgICAgIHRvdGFsU3Rha2VkID0gdG90YWxTdGFrZWQgKyBGbG93SURUYWJsZVN0YWtpbmcudG90YWxUb2tlbnNTdGFrZWRCeU5vZGVUeXBlW25vZGVUeXBlXSEKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gdG90YWxTdGFrZWQKICAgIH0KCiAgICAvLy8gR2V0cyB0aGUgdG9rZW4gcGF5b3V0IHZhbHVlIGZvciB0aGUgY3VycmVudCBlcG9jaAogICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gZ2V0RXBvY2hUb2tlblBheW91dCgpOiBVRml4NjQgewogICAgICAgIHJldHVybiBzZWxmLmVwb2NoVG9rZW5QYXlvdXQKICAgIH0KCiAgICAvLy8gR2V0cyB0aGUgY3V0IHBlcmNlbnRhZ2UgZm9yIGRlbGVnYXRvciByZXdhcmRzIHBhaWQgdG8gbm9kZSBvcGVyYXRvcnMKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGdldFJld2FyZEN1dFBlcmNlbnRhZ2UoKTogVUZpeDY0IHsKICAgICAgICByZXR1cm4gc2VsZi5ub2RlRGVsZWdhdGluZ1Jld2FyZEN1dAogICAgfQoKICAgIC8vLyBHZXRzIHRoZSByYXRpb3Mgb2YgcmV3YXJkcyB0aGF0IGRpZmZlcmVudCBub2RlIHJvbGVzIHJlY2lldmUKICAgIC8vLyBOT1RFOiBDdXJyZW50bHkgaXMgbm90IHVzZWQKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGdldFJld2FyZFJhdGlvcygpOiB7VUludDg6IFVGaXg2NH0gewogICAgICAgIHJldHVybiBzZWxmLnJld2FyZFJhdGlvcwogICAgfQoKICAgIGluaXQoXyBlcG9jaFRva2VuUGF5b3V0OiBVRml4NjQsIF8gcmV3YXJkQ3V0OiBVRml4NjQsIF8gY2FuZGlkYXRlTm9kZUxpbWl0czoge1VJbnQ4OiBVSW50NjR9KSB7CiAgICAgICAgc2VsZi5hY2NvdW50LnN0b3JhZ2Uuc2F2ZSh0cnVlLCB0bzogL3N0b3JhZ2Uvc3Rha2luZ0VuYWJsZWQpCgogICAgICAgIHNlbGYubm9kZXMgPC0ge30KCiAgICAgICAgbGV0IGNsYWltZWREaWN0aW9uYXJ5OiB7U3RyaW5nOiBCb29sfSA9IHt9CiAgICAgICAgc2VsZi5hY2NvdW50LnN0b3JhZ2Uuc2F2ZShjbGFpbWVkRGljdGlvbmFyeSwgdG86IC9zdG9yYWdlL3N0YWtpbmdLZXlzQ2xhaW1lZCkKICAgICAgICBzZWxmLmFjY291bnQuc3RvcmFnZS5zYXZlKGNsYWltZWREaWN0aW9uYXJ5LCB0bzogL3N0b3JhZ2UvbmV0d29ya2luZ0tleXNDbGFpbWVkKQogICAgICAgIHNlbGYuYWNjb3VudC5zdG9yYWdlLnNhdmUoY2xhaW1lZERpY3Rpb25hcnksIHRvOiAvc3RvcmFnZS9uZXR3b3JraW5nQWRkcmVzc2VzQ2xhaW1lZCkKCiAgICAgICAgc2VsZi5Ob2RlU3Rha2VyU3RvcmFnZVBhdGggPSAvc3RvcmFnZS9mbG93U3Rha2VyCiAgICAgICAgc2VsZi5Ob2RlU3Rha2VyUHVibGljUGF0aCA9IC9wdWJsaWMvZmxvd1N0YWtlcgogICAgICAgIHNlbGYuU3Rha2luZ0FkbWluU3RvcmFnZVBhdGggPSAvc3RvcmFnZS9mbG93U3Rha2luZ0FkbWluCiAgICAgICAgc2VsZi5EZWxlZ2F0b3JTdG9yYWdlUGF0aCA9IC9zdG9yYWdlL2Zsb3dTdGFraW5nRGVsZWdhdG9yCgogICAgICAgIHNlbGYubWluaW11bVN0YWtlUmVxdWlyZWQgPSB7VUludDgoMSk6IDI1MDAwMC4wLCBVSW50OCgyKTogNTAwMDAwLjAsIFVJbnQ4KDMpOiAxMjUwMDAwLjAsIFVJbnQ4KDQpOiAxMzUwMDAuMCwgVUludDgoNSk6IDEwMC4wfQogICAgICAgIHNlbGYuYWNjb3VudC5zdG9yYWdlLnNhdmUoNTAuMCBhcyBVRml4NjQsIHRvOiAvc3RvcmFnZS9kZWxlZ2F0b3JTdGFraW5nTWluaW11bSkKICAgICAgICBzZWxmLnRvdGFsVG9rZW5zU3Rha2VkQnlOb2RlVHlwZSA9IHtVSW50OCgxKTogMC4wLCBVSW50OCgyKTogMC4wLCBVSW50OCgzKTogMC4wLCBVSW50OCg0KTogMC4wLCBVSW50OCg1KTogMC4wfQogICAgICAgIHNlbGYuZXBvY2hUb2tlblBheW91dCA9IGVwb2NoVG9rZW5QYXlvdXQKICAgICAgICBzZWxmLm5vZGVEZWxlZ2F0aW5nUmV3YXJkQ3V0ID0gcmV3YXJkQ3V0CiAgICAgICAgc2VsZi5yZXdhcmRSYXRpb3MgPSB7VUludDgoMSk6IDAuMTY4LCBVSW50OCgyKTogMC41MTgsIFVJbnQ4KDMpOiAwLjA3OCwgVUludDgoNCk6IDAuMjM2LCBVSW50OCg1KTogMC4wfQoKICAgICAgICBsZXQgYXBwcm92ZUxpc3Q6IHtTdHJpbmc6IEJvb2x9ID0ge30KICAgICAgICBzZWxmLnNldFBhcnRpY2lwYW50Tm9kZUxpc3QoYXBwcm92ZUxpc3QpCiAgICAgICAgc2VsZi5hY2NvdW50LnN0b3JhZ2Uuc2F2ZTx7U3RyaW5nOiBCb29sfT4oYXBwcm92ZUxpc3QsIHRvOiAvc3RvcmFnZS9pZFRhYmxlQXBwcm92ZUxpc3QpCgogICAgICAgIGxldCBub25PcGVyYXRpb25hbExpc3Q6IHtTdHJpbmc6IFVGaXg2NH0gPSB7fQogICAgICAgIHNlbGYuYWNjb3VudC5zdG9yYWdlLnNhdmU8e1N0cmluZzogVUZpeDY0fT4obm9uT3BlcmF0aW9uYWxMaXN0LCB0bzogL3N0b3JhZ2UvaWRUYWJsZU5vbk9wZXJhdGlvbmFsTm9kZXNMaXN0KQoKICAgICAgICBsZXQgbW92ZXNQZW5kaW5nTGlzdDoge1N0cmluZzoge1VJbnQzMjogQm9vbH19ID0ge30KICAgICAgICBzZWxmLmFjY291bnQuc3RvcmFnZS5zYXZlPHtTdHJpbmc6IHtVSW50MzI6IEJvb2x9fT4obW92ZXNQZW5kaW5nTGlzdCwgdG86IC9zdG9yYWdlL2lkVGFibGVNb3Zlc1BlbmRpbmdMaXN0KQoKICAgICAgICBsZXQgZW1wdHlDYW5kaWRhdGVOb2Rlczoge1VJbnQ4OiB7U3RyaW5nOiBCb29sfX0gPSB7MToge30sIDI6IHt9LCAzOiB7fSwgNDoge30sIDU6IHt9fQogICAgICAgIEZsb3dJRFRhYmxlU3Rha2luZy5hY2NvdW50LnN0b3JhZ2Uuc2F2ZShlbXB0eUNhbmRpZGF0ZU5vZGVzLCB0bzogL3N0b3JhZ2UvaWRUYWJsZUNhbmRpZGF0ZU5vZGVzKQoKICAgICAgICAvLyBTYXZlIHRoZSBjYW5kaWRhdGUgbm9kZXMgbGltaXQKICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcuYWNjb3VudC5zdG9yYWdlLnNhdmU8e1VJbnQ4OiBVSW50NjR9PihjYW5kaWRhdGVOb2RlTGltaXRzLCB0bzogL3N0b3JhZ2UvaWRUYWJsZUNhbmRpZGF0ZU5vZGVMaW1pdHMpCgogICAgICAgIGxldCBzbG90TGltaXRzOiB7VUludDg6IFVJbnQxNn0gPSB7MTogMTAwMDAsIDI6IDEwMDAwLCAzOiAxMDAwMCwgNDogMTAwMDAsIDU6IDEwMDAwfQogICAgICAgIC8vIFNhdmUgc2xvdCBsaW1pdHMKICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcuYWNjb3VudC5zdG9yYWdlLnNhdmUoc2xvdExpbWl0cywgdG86IC9zdG9yYWdlL2Zsb3dTdGFraW5nU2xvdExpbWl0cykKCiAgICAgICAgbGV0IHNsb3RDb3VudHM6IHtVSW50ODogVUludDE2fSA9IHsxOiAwLCAyOiAwLCAzOiAwLCA0OiAwLCA1OiAwfQogICAgICAgIC8vIFNhdmUgc2xvdCBjb3VudHMKICAgICAgICBGbG93SURUYWJsZVN0YWtpbmcuYWNjb3VudC5zdG9yYWdlLnNhdmUoc2xvdENvdW50cywgdG86IC9zdG9yYWdlL2Zsb3dTdGFraW5nUm9sZU5vZGVDb3VudHMpCgogICAgICAgIHNlbGYuYWNjb3VudC5zdG9yYWdlLnNhdmUoPC1jcmVhdGUgQWRtaW4oKSwgdG86IHNlbGYuU3Rha2luZ0FkbWluU3RvcmFnZVBhdGgpCiAgICB9Cn0="
	},
	"_expandable": {},
	"_links": {
		"_self": "/v1/accounts/8624b52f9ddcd04a"
	}
}