IyBDb3B5cmlnaHQgKGMpIDIwMDcgSW50ZWwgQ29ycG9yYXRpb24uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiMKIyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYQojIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUKIyAiU29mdHdhcmUiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nCiMgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLAojIGRpc3RyaWJ1dGUsIHN1YiBsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8KIyBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8KIyB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CiMKIyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSAoaW5jbHVkaW5nIHRoZQojIG5leHQgcGFyYWdyYXBoKSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zCiMgb2YgdGhlIFNvZnR3YXJlLgojCiMgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MKIyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GCiMgTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVC4KIyBJTiBOTyBFVkVOVCBTSEFMTCBQUkVDSVNJT04gSU5TSUdIVCBBTkQvT1IgSVRTIFNVUFBMSUVSUyBCRSBMSUFCTEUgRk9SCiMgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsCiMgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUKIyBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KCiMgbGlidmEgcGFja2FnZSB2ZXJzaW9uIG51bWJlciwgKGFzIGRpc3RpbmN0IGZyb20gc2hhcmVkIGxpYnJhcnkgdmVyc2lvbikKbTRfZGVmaW5lKFtsaWJ2YV9tYWpvcl92ZXJzaW9uXSwgWzBdKQptNF9kZWZpbmUoW2xpYnZhX21pbm9yX3ZlcnNpb25dLCBbMzFdKQptNF9kZWZpbmUoW2xpYnZhX21pY3JvX3ZlcnNpb25dLCBbMV0pCgptNF9kZWZpbmUoW2xpYnZhX3ZlcnNpb25dLAogICAgICAgICAgW2xpYnZhX21ham9yX3ZlcnNpb24ubGlidmFfbWlub3JfdmVyc2lvbi5saWJ2YV9taWNyb192ZXJzaW9uXSkKCiMgaWYgdGhlIGxpYnJhcnkgc291cmNlIGNvZGUgaGFzIGNoYW5nZWQsIGluY3JlbWVudCByZXZpc2lvbgptNF9kZWZpbmUoW2xpYnZhX2x0X3JldmlzaW9uXSwgWzddKQojIGlmIGFueSBpbnRlcmZhY2Ugd2FzIGFkZGVkL3JlbW92ZWQvY2hhbmdlZCwgdGhlbiBpbmMgY3VycmVudCwgcmVzZXQgcmV2aXNpb24KbTRfZGVmaW5lKFtsaWJ2YV9sdF9jdXJyZW50XSwgWzFdKQojIGlmIGFueSBpbnRlcmZhY2Ugd2FzIGFkZGVkIHNpbmNlIGxhc3QgcHVibGljIHJlbGVhc2UsIHRoZW4gaW5jcmVtZW50IGFnZQojIGlmIGFueSBpbnRlcmZhY2Ugd2FzIHJlbW92ZWQgc2luY2UgbGFzdCBwdWJsaWMgcmVsZWFzZSwgdGhlbiBzZXQgYWdlIHRvIDAKbTRfZGVmaW5lKFtsaWJ2YV9sdF9hZ2VdLCBbMF0pCgpBQ19QUkVSRVEoMi41NykKQUNfSU5JVChbbGlidmFdLCBbbGlidmFfdmVyc2lvbl0sIFt3YWxkby5iYXN0aWFuQGludGVsLmNvbV0sIGxpYnZhKQpBQ19DT05GSUdfU1JDRElSKFtNYWtlZmlsZS5hbV0pCkFNX0lOSVRfQVVUT01BS0UoW2Rpc3QtYnppcDJdKQoKQU1fQ09ORklHX0hFQURFUihbY29uZmlnLmhdKQptNF9pZmRlZihbQU1fU0lMRU5UX1JVTEVTXSwgW0FNX1NJTEVOVF9SVUxFUyhbeWVzXSldKQoKTElCVkFfTUFKT1JfVkVSU0lPTj1saWJ2YV9tYWpvcl92ZXJzaW9uCkxJQlZBX01JTk9SX1ZFUlNJT049bGlidmFfbWlub3JfdmVyc2lvbgpMSUJWQV9NSUNST19WRVJTSU9OPWxpYnZhX21pY3JvX3ZlcnNpb24KTElCVkFfVkVSU0lPTj1saWJ2YV92ZXJzaW9uCkFDX1NVQlNUKExJQlZBX01BSk9SX1ZFUlNJT04pCkFDX1NVQlNUKExJQlZBX01JTk9SX1ZFUlNJT04pCkFDX1NVQlNUKExJQlZBX01JQ1JPX1ZFUlNJT04pCkFDX1NVQlNUKExJQlZBX1ZFUlNJT04pCgpMSUJWQV9MVF9DVVJSRU5UPWxpYnZhX2x0X2N1cnJlbnQKTElCVkFfTFRfUkVWPWxpYnZhX2x0X3JldmlzaW9uCkxJQlZBX0xUX0FHRT1saWJ2YV9sdF9hZ2UKTElCVkFfTFRfVkVSU0lPTj0iJExJQlZBX0xUX0NVUlJFTlQ6JExJQlZBX0xUX1JFVjokTElCVkFfTFRfQUdFIgpMSUJWQV9MVF9MREZMQUdTPSItdmVyc2lvbi1pbmZvICRMSUJWQV9MVF9WRVJTSU9OIgpBQ19TVUJTVChMSUJWQV9MVF9WRVJTSU9OKQpBQ19TVUJTVChMSUJWQV9MVF9MREZMQUdTKQoKQUNfQVJHX0VOQUJMRShnbHgsCiAgICAgICAgICAgICAgW0FDX0hFTFBfU1RSSU5HKFstLWVuYWJsZS1nbHhdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYnVpbGQgd2l0aCBPcGVuR0wgZm9yIFgxMSBzdXBwb3J0XSldLAogICAgICAgICAgICAgIFtdLCBbZW5hYmxlX2dseD15ZXNdKQoKQUNfQVJHX0VOQUJMRShkdW1teS1kcml2ZXIsCiAgICAgICAgICAgICAgW0FDX0hFTFBfU1RSSU5HKFstLWVuYWJsZS1kdW1teS1kcml2ZXJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYnVpbGQgZHVtbXkgdmlkZW8gZHJpdmVyXSldLAogICAgICAgICAgICAgIFtdLCBbZW5hYmxlX2R1bW15X2RyaXZlcj15ZXNdKQpBTV9DT05ESVRJT05BTChCVUlMRF9EVU1NWV9EUklWRVIsIHRlc3QgeCRlbmFibGVfZHVtbXlfZHJpdmVyID0geHllcykKCkFDX0FSR19FTkFCTEUoZHVtbXktYmFja2VuZCwKICAgICAgICAgICAgICBbQUNfSEVMUF9TVFJJTkcoWy0tZW5hYmxlLWR1bW15LWJhY2tlbmRdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYnVpbGQgZHVtbXkgbGlidmEgYmFja2VuZF0pXSwKICAgICAgICAgICAgICBbXSwgW2VuYWJsZV9kdW1teV9iYWNrZW5kPW5vXSkKCkFDX0FSR19FTkFCTEUoaTk2NS1kcml2ZXIsCiAgICAgICAgICAgICAgW0FDX0hFTFBfU1RSSU5HKFstLWVuYWJsZS1pOTY1LWRyaXZlcl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtidWlsZCBpOTY1IHZpZGVvIGRyaXZlcl0pXSwKICAgICAgICAgICAgICBbXSwgW2VuYWJsZV9pOTY1X2RyaXZlcj1ub10pCgpBQ19BUkdfV0lUSChkcml2ZXJzLXBhdGgsCgkgICAgW0FDX0hFTFBfU1RSSU5HKFstLXdpdGgtZHJpdmVycy1wYXRoPVtbcGF0aF1dXSwgW2RyaXZlcnMgcGF0aF0pXSwsCgkgICAgW3dpdGhfZHJpdmVyc19wYXRoPSIkbGliZGlyL2RyaSJdKQoKTElCVkFfRFJJVkVSU19QQVRIPSIkd2l0aF9kcml2ZXJzX3BhdGgiCkFDX1NVQlNUKExJQlZBX0RSSVZFUlNfUEFUSCkKCkFDX0RJU0FCTEVfU1RBVElDCkFDX1BST0dfTElCVE9PTApBQ19QUk9HX0NDCgpBQ19IRUFERVJfU1REQwpBQ19TWVNfTEFSR0VGSUxFCgpQS0dfQ0hFQ0tfTU9EVUxFUyhbWDExXSwgW3gxMV0pClBLR19DSEVDS19NT0RVTEVTKFtYRVhUXSxbeGV4dF0pClBLR19DSEVDS19NT0RVTEVTKFtYRklYRVNdLCBbeGZpeGVzXSkKUEtHX0NIRUNLX01PRFVMRVMoW0RSTV0sIFtsaWJkcm1dKQoKUEtHX0NIRUNLX01PRFVMRVMoR0VONEFTTSwgW2ludGVsLWdlbjRhc20gPj0gMS4xXSwgW2dlbjRhc209eWVzXSwgW2dlbjRhc209bm9dKQpBTV9DT05ESVRJT05BTChIQVZFX0dFTjRBU00sIHRlc3QgeCRnZW40YXNtID0geHllcykKCiMgQ2hlY2sgZm9yIGxpYmRybSA+PSAyLjQuMjMgKG5lZWRlZCBmb3IgaTk2NV9kcnZfdmlkZW8uc28pCmlmIHRlc3QgeCRlbmFibGVfaTk2NV9kcml2ZXIgPSB4eWVzICYmICEgJFBLR19DT05GSUcgLS1hdGxlYXN0LXZlcnNpb249Mi40LjIzIGxpYmRybTsgdGhlbgogICAgQUNfTVNHX1dBUk4oW2xpYmRybSA8IDIuNC4yMyBmb3VuZCwgZGlzYWJsaW5nIGJ1aWxkIG9mIGk5NjUgdmlkZW8gZHJpdmVyXSkKICAgIGVuYWJsZV9pOTY1X2RyaXZlcj1ubwpmaQpBTV9DT05ESVRJT05BTChCVUlMRF9JOTY1X0RSSVZFUiwgdGVzdCB4JGVuYWJsZV9pOTY1X2RyaXZlciA9IHh5ZXMpCgppZiB0ZXN0IHgkZW5hYmxlX2R1bW15X2JhY2tlbmQgPSB4eWVzOyB0aGVuCiAgICBQS0dfQ0hFQ0tfTU9EVUxFUyhbVURFVl0sIFtsaWJ1ZGV2XSwgW2xpYnVkZXY9eWVzXSwgW2xpYnVkZXY9bm9dKQpmaQppZiB0ZXN0IHgkbGlidWRldiA9IHhubzsgdGhlbgogICBlbmFibGVfZHVtbXlfYmFja2VuZD1ubwpmaQpBTV9DT05ESVRJT05BTChCVUlMRF9EVU1NWV9CQUNLRU5ELCB0ZXN0IHgkZW5hYmxlX2R1bW15X2JhY2tlbmQgPSB4eWVzKQoKIyBDaGVjayBmb3IgT3BlbkdMIChYMTEpClVTRV9HTFg9Im5vIgpHTF9ERVBTX0NGTEFHUz0iIgpHTF9ERVBTX0xJQlM9IiIKaWYgdGVzdCB4JGVuYWJsZV9nbHggPSB4eWVzOyB0aGVuCiAgICBBQ19DSEVDS19IRUFERVJTKFtHTC9nbC5oXSkKICAgIEFDX0NIRUNLX0hFQURFUlMoW0dML2dseC5oXSkKICAgIEFDX0NIRUNLX0xJQihHTCwgZ2xYQ3JlYXRlQ29udGV4dCwgWwogICAgICAgIFVTRV9HTFg9InllcyIKICAgICAgICBHTF9ERVBTX0xJQlM9Ii1sWDExIC1sR0wiCiAgICBdKQpmaQpBQ19TVUJTVChHTF9ERVBTX0NGTEFHUykKQUNfU1VCU1QoR0xfREVQU19MSUJTKQpBTV9DT05ESVRJT05BTChVU0VfR0xYLCB0ZXN0ICIkVVNFX0dMWCIgPSAieWVzIikKCiMgV2Ugb25seSBuZWVkIHRoZSBoZWFkZXJzLCB3ZSBkb24ndCBsaW5rIGFnYWluc3QgdGhlIERSTSBsaWJyYXJpZXMKTElCVkFfQ0ZMQUdTPSIkRFJNX0NGTEFHUyIKQUNfU1VCU1QoTElCVkFfQ0ZMQUdTKQpBQ19TVUJTVChMSUJWQV9MSUJTKQoKcGtnY29uZmlnZGlyPSR7bGliZGlyfS9wa2djb25maWcKQUNfU1VCU1QocGtnY29uZmlnZGlyKQoKTElCVkFfRElTUExBWT14MTEKbGlidmFjb3JlbGliPWxpYnZhLmxhCmxpYnZhYmFja2VuZGxpYj1saWJ2YS0kTElCVkFfRElTUExBWS5sYQpBQ19TVUJTVChbbGlidmFjb3JlbGliXSkKQUNfU1VCU1QoW2xpYnZhYmFja2VuZGxpYl0pCgpBQ19PVVRQVVQoWwoJTWFrZWZpbGUKCXZhL01ha2VmaWxlCgl2YS92YV92ZXJzaW9uLmgKCXZhL3gxMS9NYWtlZmlsZQoJdmEvZ2x4L01ha2VmaWxlCgl2YS9kdW1teS9NYWtlZmlsZQoJZHVtbXlfZHJ2X3ZpZGVvL01ha2VmaWxlCglpOTY1X2Rydl92aWRlby9NYWtlZmlsZQoJaTk2NV9kcnZfdmlkZW8vc2hhZGVycy9NYWtlZmlsZQoJaTk2NV9kcnZfdmlkZW8vc2hhZGVycy9oMjY0L01ha2VmaWxlCglpOTY1X2Rydl92aWRlby9zaGFkZXJzL2gyNjQvbWMvTWFrZWZpbGUKCWk5NjVfZHJ2X3ZpZGVvL3NoYWRlcnMvbXBlZzIvTWFrZWZpbGUKCWk5NjVfZHJ2X3ZpZGVvL3NoYWRlcnMvbXBlZzIvdmxkL01ha2VmaWxlCglpOTY1X2Rydl92aWRlby9zaGFkZXJzL3JlbmRlci9NYWtlZmlsZQoJaTk2NV9kcnZfdmlkZW8vc2hhZGVycy9wb3N0X3Byb2Nlc3NpbmcvTWFrZWZpbGUKCXRlc3QvTWFrZWZpbGUKCXRlc3QvYmFzaWMvTWFrZWZpbGUKCXRlc3QvZGVjb2RlL01ha2VmaWxlCgl0ZXN0L3B1dHN1cmZhY2UvTWFrZWZpbGUKCXRlc3QvZW5jb2RlL01ha2VmaWxlCgl0ZXN0L3ZhaW5mby9NYWtlZmlsZQoJbGlidmEucGMKCWxpYnZhLXgxMS5wYwoJbGlidmEtZ2x4LnBjCglsaWJ2YS10cGkucGMKXSkKCiMgUHJpbnQgYSBzbWFsbCBzdW1tYXJ5CgplY2hvICIiCmVjaG8gImxpYnZhIC0gJHtMSUJWQV9WRVJTSU9OfSIKZWNobyAiIgoKZWNobyAiIJUgR2xvYmFsIDoiCmVjaG8gIiAgICAgUHJlZml4OiAke3ByZWZpeH0iCmVjaG8gIiIKCkFTX0lGKFt0ZXN0IHgkZW5hYmxlX2k5NjVfZHJpdmVyID0geHllc10sIFtEUklWRVJTPSJpOTY1ICREUklWRVJTIl0pIApBU19JRihbdGVzdCB4JGVuYWJsZV9kdW1teV9kcml2ZXIgPSB4eWVzXSwgW0RSSVZFUlM9ImR1bW15ICREUklWRVJTIl0pCgplY2hvICIglSBEcml2ZXJzOiAke0RSSVZFUlN9IgoKQVNfSUYoW3Rlc3QgeCRVU0VfR0xYID0geHllc10sIFtCQUNLRU5EUz0iZ2x4ICRCQUNLRU5EUyJdKQpCQUNLRU5EUz0ieDExICRCQUNLRU5EUyIKQVNfSUYoW3Rlc3QgeCRlbmFibGVfZHVtbXlfYmFja2VuZCA9IHh5ZXNdLCBbQkFDS0VORFM9ImR1bW15IAokQkFDS0VORFMiXSkKCmVjaG8gIiCVIFdpbnN5cyA6ICR7QkFDS0VORFN9IgoK