ZGlmZiAtLWdpdCBhL0RvYy9saWIvbGlibWFpbGJveC50ZXggYi9Eb2MvbGliL2xpYm1haWxib3gudGV4CmluZGV4IGRkMTg1NjIuLjUwZGQzZGQgMTAwNjQ0Ci0tLSBhL0RvYy9saWIvbGlibWFpbGJveC50ZXgKKysrIGIvRG9jL2xpYi9saWJtYWlsYm94LnRleApAQCAtMSwxMiArMSwxMjUzIEBACiBcc2VjdGlvbntcbW9kdWxle21haWxib3h9IC0tLQotICAgICAgICAgUmVhZCB2YXJpb3VzIG1haWxib3ggZm9ybWF0c30KKyAgICAgICAgICBNYW5pcHVsYXRlIG1haWxib3hlcyBpbiB2YXJpb3VzIGZvcm1hdHN9CiAKLVxkZWNsYXJlbW9kdWxle3N0YW5kYXJkfXttYWlsYm94fQotXG1vZHVsZXN5bm9wc2lze1JlYWQgdmFyaW91cyBtYWlsYm94IGZvcm1hdHMufQorXGRlY2xhcmVtb2R1bGV7fXttYWlsYm94fQorXG1vZHVsZWF1dGhvcntHcmVnb3J5IEsufkpvaG5zb259e2drakBncmVnb3J5a2pvaG5zb24uY29tfQorXHNlY3Rpb25hdXRob3J7R3JlZ29yeSBLLn5Kb2huc29ufXtna2pAZ3JlZ29yeWtqb2huc29uLmNvbX0KK1xtb2R1bGVzeW5vcHNpc3tNYW5pcHVsYXRlIG1haWxib3hlcyBpbiB2YXJpb3VzIGZvcm1hdHN9CiAKIAotVGhpcyBtb2R1bGUgZGVmaW5lcyBhIG51bWJlciBvZiBjbGFzc2VzIHRoYXQgYWxsb3cgZWFzeSBhbmQgdW5pZm9ybQotYWNjZXNzIHRvIG1haWwgbWVzc2FnZXMgaW4gYSAoXFVOSVgpIG1haWxib3guCitUaGlzIG1vZHVsZSBkZWZpbmVzIHR3byBjbGFzc2VzLCBcY2xhc3N7TWFpbGJveH0gYW5kIFxjbGFzc3tNZXNzYWdlfSwgZm9yCithY2Nlc3NpbmcgYW5kIG1hbmlwdWxhdGluZyBvbi1kaXNrIG1haWxib3hlcyBhbmQgdGhlIG1lc3NhZ2VzIHRoZXkgY29udGFpbi4KK1xjbGFzc3tNYWlsYm94fSBvZmZlcnMgYSBkaWN0aW9uYXJ5LWxpa2UgbWFwcGluZyBmcm9tIGtleXMgdG8gbWVzc2FnZXMuCitcY2xhc3N7TWVzc2FnZX0gZXh0ZW5kcyB0aGUgXG1vZHVsZXtlbWFpbC5NZXNzYWdlfSBtb2R1bGUncyBcY2xhc3N7TWVzc2FnZX0KK2NsYXNzIHdpdGggZm9ybWF0LXNwZWNpZmljIHN0YXRlIGFuZCBiZWhhdmlvci4gU3VwcG9ydGVkIG1haWxib3ggZm9ybWF0cyBhcmUKK01haWxkaXIsIG1ib3gsIE1ILCBCYWJ5bCwgYW5kIE1NREYuCisKK1xiZWdpbntzZWVhbHNvfQorICAgIFxzZWVtb2R1bGV7ZW1haWx9e1JlcHJlc2VudCBhbmQgbWFuaXB1bGF0ZSBtZXNzYWdlcy59CitcZW5ke3NlZWFsc299CisKK1xzdWJzZWN0aW9ue1xjbGFzc3tNYWlsYm94fSBvYmplY3RzfQorXGxhYmVse21haWxib3gtb2JqZWN0c30KKworXGJlZ2lue2NsYXNzZGVzYyp9e01haWxib3h9CitBIG1haWxib3gsIHdoaWNoIG1heSBiZSBpbnNwZWN0ZWQgYW5kIG1vZGlmaWVkLgorXGVuZHtjbGFzc2Rlc2MqfQorCitUaGUgXGNsYXNze01haWxib3h9IGludGVyZmFjZSBpcyBkaWN0aW9uYXJ5LWxpa2UsIHdpdGggc21hbGwga2V5cworY29ycmVzcG9uZGluZyB0byBtZXNzYWdlcy4gS2V5cyBhcmUgaXNzdWVkIGJ5IHRoZSBcY2xhc3N7TWFpbGJveH0gaW5zdGFuY2UKK3dpdGggd2hpY2ggdGhleSB3aWxsIGJlIHVzZWQgYW5kIGFyZSBvbmx5IG1lYW5pbmdmdWwgdG8gdGhhdCBcY2xhc3N7TWFpbGJveH0KK2luc3RhbmNlLiBBIGtleSBjb250aW51ZXMgdG8gaWRlbnRpZnkgYSBtZXNzYWdlIGV2ZW4gaWYgdGhlIGNvcnJlc3BvbmRpbmcKK21lc3NhZ2UgaXMgbW9kaWZpZWQsIHN1Y2ggYXMgYnkgcmVwbGFjaW5nIGl0IHdpdGggYW5vdGhlciBtZXNzYWdlLiBNZXNzYWdlcyBtYXkKK2JlIGFkZGVkIHRvIGEgXGNsYXNze01haWxib3h9IGluc3RhbmNlIHVzaW5nIHRoZSBzZXQtbGlrZSBtZXRob2QKK1xtZXRob2R7YWRkKCl9IGFuZCByZW1vdmVkIHVzaW5nIGEgXGNvZGV7ZGVsfSBzdGF0ZW1lbnQgb3IgdGhlIHNldC1saWtlIG1ldGhvZHMKK1xtZXRob2R7cmVtb3ZlKCl9IGFuZCBcbWV0aG9ke2Rpc2NhcmQoKX0uCisKK1xjbGFzc3tNYWlsYm94fSBpbnRlcmZhY2Ugc2VtYW50aWNzIGRpZmZlciBmcm9tIGRpY3Rpb25hcnkgc2VtYW50aWNzIGluIHNvbWUKK25vdGV3b3J0aHkgd2F5cy4gRWFjaCB0aW1lIGEgbWVzc2FnZSBpcyByZXF1ZXN0ZWQsIGEgbmV3IHJlcHJlc2VudGF0aW9uCisodHlwaWNhbGx5IGEgXGNsYXNze01lc3NhZ2V9IGluc3RhbmNlKSBpcyBnZW5lcmF0ZWQsIGJhc2VkIHVwb24gdGhlIGN1cnJlbnQKK3N0YXRlIG9mIHRoZSBtYWlsYm94LiBTaW1pbGFybHksIHdoZW4gYSBtZXNzYWdlIGlzIGFkZGVkIHRvIGEgXGNsYXNze01haWxib3h9CitpbnN0YW5jZSwgdGhlIHByb3ZpZGVkIG1lc3NhZ2UgcmVwcmVzZW50YXRpb24ncyBjb250ZW50cyBhcmUgY29waWVkLiBJbiBuZWl0aGVyCitjYXNlIGlzIGEgcmVmZXJlbmNlIHRvIHRoZSBtZXNzYWdlIHJlcHJlc2VudGF0aW9uIGtlcHQgYnkgdGhlIFxjbGFzc3tNYWlsYm94fQoraW5zdGFuY2UuCisKK1RoZSBkZWZhdWx0IFxjbGFzc3tNYWlsYm94fSBpdGVyYXRvciBpdGVyYXRlcyBvdmVyIG1lc3NhZ2UgcmVwcmVzZW50YXRpb25zLCBub3QKK2tleXMgYXMgdGhlIGRlZmF1bHQgZGljdGlvbmFyeSBpdGVyYXRvciBkb2VzLiBNb3Jlb3ZlciwgbW9kaWZpY2F0aW9uIG9mIGEKK21haWxib3ggZHVyaW5nIGl0ZXJhdGlvbiBpcyBzYWZlIGFuZCB3ZWxsLWRlZmluZWQuIE1lc3NhZ2VzIGFkZGVkIHRvIHRoZQorbWFpbGJveCBhZnRlciBhbiBpdGVyYXRvciBpcyBjcmVhdGVkIHdpbGwgbm90IGJlIHNlZW4gYnkgdGhlIGl0ZXJhdG9yLiBNZXNzYWdlcworcmVtb3ZlZCBmcm9tIHRoZSBtYWlsYm94IGJlZm9yZSB0aGUgaXRlcmF0b3IgeWllbGRzIHRoZW0gd2lsbCBiZSBzaWxlbnRseQorc2tpcHBlZCwgdGhvdWdoIHVzaW5nIGEga2V5IGZyb20gYW4gaXRlcmF0b3IgbWF5IHJlc3VsdCBpbiBhCitcZXhjZXB0aW9ue0tleUVycm9yfSBleGNlcHRpb24gaWYgdGhlIGNvcnJlc3BvbmRpbmcgbWVzc2FnZSBpcyBzdWJzZXF1ZW50bHkKK3JlbW92ZWQuCisKK1xjbGFzc3tNYWlsYm94fSBpdHNlbGYgaXMgaW50ZW5kZWQgdG8gZGVmaW5lIGFuIGludGVyZmFjZSBhbmQgdG8gYmUgaW5oZXJpdGVkCitmcm9tIGJ5IGZvcm1hdC1zcGVjaWZpYyBzdWJjbGFzc2VzIGJ1dCBpcyBub3QgaW50ZW5kZWQgdG8gYmUgaW5zdGFudGlhdGVkLgorSW5zdGVhZCwgeW91IHNob3VsZCBpbnN0YW50aWF0ZSBhIHN1YmNsYXNzLgorCitcY2xhc3N7TWFpbGJveH0gaW5zdGFuY2VzIGhhdmUgdGhlIGZvbGxvd2luZyBtZXRob2RzOgorCitcYmVnaW57bWV0aG9kZGVzY317YWRkfXttZXNzYWdlfQorQWRkIFx2YXJ7bWVzc2FnZX0gdG8gdGhlIG1haWxib3ggYW5kIHJldHVybiB0aGUga2V5IHRoYXQgaGFzIGJlZW4gYXNzaWduZWQgdG8KK2l0LgorCitQYXJhbWV0ZXIgXHZhcnttZXNzYWdlfSBtYXkgYmUgYSBcY2xhc3N7TWVzc2FnZX0gaW5zdGFuY2UsIGFuCitcY2xhc3N7ZW1haWwuTWVzc2FnZS5NZXNzYWdlfSBpbnN0YW5jZSwgYSBzdHJpbmcsIG9yIGEgZmlsZS1saWtlIG9iamVjdCAod2hpY2gKK3Nob3VsZCBiZSBvcGVuIGluIHRleHQgbW9kZSkuIElmIFx2YXJ7bWVzc2FnZX0gaXMgYW4gaW5zdGFuY2Ugb2YgdGhlCithcHByb3ByaWF0ZSBmb3JtYXQtc3BlY2lmaWMgXGNsYXNze01lc3NhZ2V9IHN1YmNsYXNzIChlLmcuLCBpZiBpdCdzIGFuCitcY2xhc3N7bWJveE1lc3NhZ2V9IGluc3RhbmNlIGFuZCB0aGlzIGlzIGFuIFxjbGFzc3ttYm94fSBpbnN0YW5jZSksIGl0cworZm9ybWF0LXNwZWNpZmljIGluZm9ybWF0aW9uIGlzIHVzZWQuIE90aGVyd2lzZSwgcmVhc29uYWJsZSBkZWZhdWx0cyBmb3IKK2Zvcm1hdC1zcGVjaWZpYyBpbmZvcm1hdGlvbiBhcmUgdXNlZC4KK1xlbmR7bWV0aG9kZGVzY30KKworXGJlZ2lue21ldGhvZGRlc2N9e3JlbW92ZX17a2V5fQorXG1ldGhvZGxpbmV7X19kZWxpdGVtX199e2tleX0KK1xtZXRob2RsaW5le2Rpc2NhcmR9e2tleX0KK0RlbGV0ZSB0aGUgbWVzc2FnZSBjb3JyZXNwb25kaW5nIHRvIFx2YXJ7a2V5fSBmcm9tIHRoZSBtYWlsYm94LgorCitJZiBubyBzdWNoIG1lc3NhZ2UgZXhpc3RzLCBhIFxleGNlcHRpb257S2V5RXJyb3J9IGV4Y2VwdGlvbiBpcyByYWlzZWQgaWYgdGhlCittZXRob2Qgd2FzIGNhbGxlZCBhcyBcbWV0aG9ke3JlbW92ZSgpfSBvciBcbWV0aG9ke19fZGVsaXRlbV9fKCl9IGJ1dCBubworZXhjZXB0aW9uIGlzIHJhaXNlZCBpZiB0aGUgbWV0aG9kIHdhcyBjYWxsZWQgYXMgXG1ldGhvZHtkaXNjYXJkKCl9LiBUaGUKK2JlaGF2aW9yIG9mIFxtZXRob2R7ZGlzY2FyZCgpfSBtYXkgYmUgcHJlZmVycmVkIGlmIHRoZSB1bmRlcmx5aW5nIG1haWxib3gKK2Zvcm1hdCBzdXBwb3J0cyBjb25jdXJyZW50IG1vZGlmaWNhdGlvbiBieSBvdGhlciBwcm9jZXNzZXMuCitcZW5ke21ldGhvZGRlc2N9CisKK1xiZWdpbnttZXRob2RkZXNjfXtfX3NldGl0ZW1fX317a2V5LCBtZXNzYWdlfQorUmVwbGFjZSB0aGUgbWVzc2FnZSBjb3JyZXNwb25kaW5nIHRvIFx2YXJ7a2V5fSB3aXRoIFx2YXJ7bWVzc2FnZX0uIFJhaXNlIGEKK1xleGNlcHRpb257S2V5RXJyb3J9IGV4Y2VwdGlvbiBpZiBubyBtZXNzYWdlIGFscmVhZHkgY29ycmVzcG9uZHMgdG8gXHZhcntrZXl9LgorCitBcyB3aXRoIFxtZXRob2R7YWRkKCl9LCBwYXJhbWV0ZXIgXHZhcnttZXNzYWdlfSBtYXkgYmUgYSBcY2xhc3N7TWVzc2FnZX0KK2luc3RhbmNlLCBhbiBcY2xhc3N7ZW1haWwuTWVzc2FnZS5NZXNzYWdlfSBpbnN0YW5jZSwgYSBzdHJpbmcsIG9yIGEgZmlsZS1saWtlCitvYmplY3QgKHdoaWNoIHNob3VsZCBiZSBvcGVuIGluIHRleHQgbW9kZSkuIElmIFx2YXJ7bWVzc2FnZX0gaXMgYW4gaW5zdGFuY2Ugb2YKK3RoZSBhcHByb3ByaWF0ZSBmb3JtYXQtc3BlY2lmaWMgXGNsYXNze01lc3NhZ2V9IHN1YmNsYXNzIChlLmcuLCBpZiBpdCdzIGFuCitcY2xhc3N7bWJveE1lc3NhZ2V9IGluc3RhbmNlIGFuZCB0aGlzIGlzIGFuIFxjbGFzc3ttYm94fSBpbnN0YW5jZSksIGl0cworZm9ybWF0LXNwZWNpZmljIGluZm9ybWF0aW9uIGlzIHVzZWQuIE90aGVyd2lzZSwgdGhlIGZvcm1hdC1zcGVjaWZpYyBpbmZvcm1hdGlvbgorb2YgdGhlIG1lc3NhZ2UgdGhhdCBjdXJyZW50bHkgY29ycmVzcG9uZHMgdG8gXHZhcntrZXl9IGlzIGxlZnQgdW5jaGFuZ2VkLiAKK1xlbmR7bWV0aG9kZGVzY30KKworXGJlZ2lue21ldGhvZGRlc2N9e2l0ZXJrZXlzfXt9CitcbWV0aG9kbGluZXtrZXlzfXt9CitSZXR1cm4gYW4gaXRlcmF0b3Igb3ZlciBhbGwga2V5cyBpZiBjYWxsZWQgYXMgXG1ldGhvZHtpdGVya2V5cygpfSBvciByZXR1cm4gYQorbGlzdCBvZiBrZXlzIGlmIGNhbGxlZCBhcyBcbWV0aG9ke2tleXMoKX0uCitcZW5ke21ldGhvZGRlc2N9CisKK1xiZWdpbnttZXRob2RkZXNjfXtpdGVydmFsdWVzfXt9CitcbWV0aG9kbGluZXtfX2l0ZXJfX317fQorXG1ldGhvZGxpbmV7dmFsdWVzfXt9CitSZXR1cm4gYW4gaXRlcmF0b3Igb3ZlciByZXByZXNlbnRhdGlvbnMgb2YgYWxsIG1lc3NhZ2VzIGlmIGNhbGxlZCBhcworXG1ldGhvZHtpdGVydmFsdWVzKCl9IG9yIFxtZXRob2R7X19pdGVyX18oKX0gb3IgcmV0dXJuIGEgbGlzdCBvZiBzdWNoCityZXByZXNlbnRhdGlvbnMgaWYgY2FsbGVkIGFzIFxtZXRob2R7dmFsdWVzKCl9LiBUaGUgbWVzc2FnZXMgYXJlIHJlcHJlc2VudGVkIGFzCitpbnN0YW5jZXMgb2YgdGhlIGFwcHJvcHJpYXRlIGZvcm1hdC1zcGVjaWZpYyBcY2xhc3N7TWVzc2FnZX0gc3ViY2xhc3MgdW5sZXNzIGEKK2N1c3RvbSBtZXNzYWdlIGZhY3Rvcnkgd2FzIHNwZWNpZmllZCB3aGVuIHRoZSBcY2xhc3N7TWFpbGJveH0gaW5zdGFuY2Ugd2FzCitpbml0aWFsaXplZC4gXG5vdGV7VGhlIGJlaGF2aW9yIG9mIFxtZXRob2R7X19pdGVyX18oKX0gaXMgdW5saWtlIHRoYXQgb2YKK2RpY3Rpb25hcmllcywgd2hpY2ggaXRlcmF0ZSBvdmVyIGtleXMufQorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317aXRlcml0ZW1zfXt9CitcbWV0aG9kbGluZXtpdGVtc317fQorUmV0dXJuIGFuIGl0ZXJhdG9yIG92ZXIgKFx2YXJ7a2V5fSwgXHZhcnttZXNzYWdlfSkgcGFpcnMsIHdoZXJlIFx2YXJ7a2V5fSBpcyBhCitrZXkgYW5kIFx2YXJ7bWVzc2FnZX0gaXMgYSBtZXNzYWdlIHJlcHJlc2VudGF0aW9uLCBpZiBjYWxsZWQgYXMKK1xtZXRob2R7aXRlcml0ZW1zKCl9IG9yIHJldHVybiBhIGxpc3Qgb2Ygc3VjaCBwYWlycyBpZiBjYWxsZWQgYXMKK1xtZXRob2R7aXRlbXMoKX0uIFRoZSBtZXNzYWdlcyBhcmUgcmVwcmVzZW50ZWQgYXMgaW5zdGFuY2VzIG9mIHRoZSBhcHByb3ByaWF0ZQorZm9ybWF0LXNwZWNpZmljIFxjbGFzc3tNZXNzYWdlfSBzdWJjbGFzcyB1bmxlc3MgYSBjdXN0b20gbWVzc2FnZSBmYWN0b3J5IHdhcworc3BlY2lmaWVkIHdoZW4gdGhlIFxjbGFzc3tNYWlsYm94fSBpbnN0YW5jZSB3YXMgaW5pdGlhbGl6ZWQuCitcZW5ke21ldGhvZGRlc2N9CisKK1xiZWdpbnttZXRob2RkZXNjfXtnZXR9e2tleVxvcHRpb25hbHssIGRlZmF1bHQ9Tm9uZX19CitcbWV0aG9kbGluZXtfX2dldGl0ZW1fX317a2V5fQorUmV0dXJuIGEgcmVwcmVzZW50YXRpb24gb2YgdGhlIG1lc3NhZ2UgY29ycmVzcG9uZGluZyB0byBcdmFye2tleX0uIElmIG5vIHN1Y2gKK21lc3NhZ2UgZXhpc3RzLCBcdmFye2RlZmF1bHR9IGlzIHJldHVybmVkIGlmIHRoZSBtZXRob2Qgd2FzIGNhbGxlZCBhcworXG1ldGhvZHtnZXQoKX0gYW5kIGEgXGV4Y2VwdGlvbntLZXlFcnJvcn0gZXhjZXB0aW9uIGlzIHJhaXNlZCBpZiB0aGUgbWV0aG9kIHdhcworY2FsbGVkIGFzIFxtZXRob2R7X19nZXRpdGVtX18oKX0uIFRoZSBtZXNzYWdlIGlzIHJlcHJlc2VudGVkIGFzIGFuIGluc3RhbmNlIG9mCit0aGUgYXBwcm9wcmlhdGUgZm9ybWF0LXNwZWNpZmljIFxjbGFzc3tNZXNzYWdlfSBzdWJjbGFzcyB1bmxlc3MgYSBjdXN0b20KK21lc3NhZ2UgZmFjdG9yeSB3YXMgc3BlY2lmaWVkIHdoZW4gdGhlIFxjbGFzc3tNYWlsYm94fSBpbnN0YW5jZSB3YXMKK2luaXRpYWxpemVkLgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317Z2V0X21lc3NhZ2V9e2tleX0KK1JldHVybiBhIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtZXNzYWdlIGNvcnJlc3BvbmRpbmcgdG8gXHZhcntrZXl9IGFzIGFuCitpbnN0YW5jZSBvZiB0aGUgYXBwcm9wcmlhdGUgZm9ybWF0LXNwZWNpZmljIFxjbGFzc3tNZXNzYWdlfSBzdWJjbGFzcywgb3IgcmFpc2UKK2EgXGV4Y2VwdGlvbntLZXlFcnJvcn0gZXhjZXB0aW9uIGlmIG5vIHN1Y2ggbWVzc2FnZSBleGlzdHMuCitcZW5ke21ldGhvZGRlc2N9CisKK1xiZWdpbnttZXRob2RkZXNjfXtnZXRfc3RyaW5nfXtrZXl9CitSZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIG1lc3NhZ2UgY29ycmVzcG9uZGluZyB0byBcdmFye2tleX0sIG9yCityYWlzZSBhIFxleGNlcHRpb257S2V5RXJyb3J9IGV4Y2VwdGlvbiBpZiBubyBzdWNoIG1lc3NhZ2UgZXhpc3RzLgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317Z2V0X2ZpbGV9e2tleX0KK1JldHVybiBhIGZpbGUtbGlrZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgbWVzc2FnZSBjb3JyZXNwb25kaW5nIHRvIFx2YXJ7a2V5fSwKK29yIHJhaXNlIGEgXGV4Y2VwdGlvbntLZXlFcnJvcn0gZXhjZXB0aW9uIGlmIG5vIHN1Y2ggbWVzc2FnZSBleGlzdHMuIFRoZQorZmlsZS1saWtlIG9iamVjdCBiZWhhdmVzIGFzIGlmIG9wZW4gaW4gYmluYXJ5IG1vZGUuIFRoaXMgZmlsZSBzaG91bGQgYmUgY2xvc2VkCitvbmNlIGl0IGlzIG5vIGxvbmdlciBuZWVkZWQuCisKK1xub3Rle1VubGlrZSBvdGhlciByZXByZXNlbnRhdGlvbnMgb2YgbWVzc2FnZXMsIGZpbGUtbGlrZSByZXByZXNlbnRhdGlvbnMgYXJlCitub3QgbmVjZXNzYXJpbHkgaW5kZXBlbmRlbnQgb2YgdGhlIFxjbGFzc3tNYWlsYm94fSBpbnN0YW5jZSB0aGF0IGNyZWF0ZWQgdGhlbQorb3Igb2YgdGhlIHVuZGVybHlpbmcgbWFpbGJveC4gTW9yZSBzcGVjaWZpYyBkb2N1bWVudGF0aW9uIGlzIHByb3ZpZGVkIGJ5IGVhY2gKK3N1YmNsYXNzLn0KK1xlbmR7bWV0aG9kZGVzY30KKworXGJlZ2lue21ldGhvZGRlc2N9e2hhc19rZXl9e2tleX0KK1xtZXRob2RsaW5le19fY29udGFpbnNfX317a2V5fQorUmV0dXJuIFxjb2Rle1RydWV9IGlmIFx2YXJ7a2V5fSBjb3JyZXNwb25kcyB0byBhIG1lc3NhZ2UsIFxjb2Rle0ZhbHNlfQorb3RoZXJ3aXNlLgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317X19sZW5fX317fQorUmV0dXJuIGEgY291bnQgb2YgbWVzc2FnZXMgaW4gdGhlIG1haWxib3guCitcZW5ke21ldGhvZGRlc2N9CisKK1xiZWdpbnttZXRob2RkZXNjfXtjbGVhcn17fQorRGVsZXRlIGFsbCBtZXNzYWdlcyBmcm9tIHRoZSBtYWlsYm94LgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317cG9wfXtrZXlcb3B0aW9uYWx7LCBkZWZhdWx0fX0KK1JldHVybiBhIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtZXNzYWdlIGNvcnJlc3BvbmRpbmcgdG8gXHZhcntrZXl9IGFuZCBkZWxldGUKK3RoZSBtZXNzYWdlLiBJZiBubyBzdWNoIG1lc3NhZ2UgZXhpc3RzLCByZXR1cm4gXHZhcntkZWZhdWx0fSBpZiBpdCB3YXMgc3VwcGxpZWQKK29yIGVsc2UgcmFpc2UgYSBcZXhjZXB0aW9ue0tleUVycm9yfSBleGNlcHRpb24uIFRoZSBtZXNzYWdlIGlzIHJlcHJlc2VudGVkIGFzCithbiBpbnN0YW5jZSBvZiB0aGUgYXBwcm9wcmlhdGUgZm9ybWF0LXNwZWNpZmljIFxjbGFzc3tNZXNzYWdlfSBzdWJjbGFzcyB1bmxlc3MKK2EgY3VzdG9tIG1lc3NhZ2UgZmFjdG9yeSB3YXMgc3BlY2lmaWVkIHdoZW4gdGhlIFxjbGFzc3tNYWlsYm94fSBpbnN0YW5jZSB3YXMKK2luaXRpYWxpemVkLgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317cG9waXRlbX17fQorUmV0dXJuIGFuIGFyYml0cmFyeSAoXHZhcntrZXl9LCBcdmFye21lc3NhZ2V9KSBwYWlyLCB3aGVyZSBcdmFye2tleX0gaXMgYSBrZXkKK2FuZCBcdmFye21lc3NhZ2V9IGlzIGEgbWVzc2FnZSByZXByZXNlbnRhdGlvbiwgYW5kIGRlbGV0ZSB0aGUgY29ycmVzcG9uZGluZworbWVzc2FnZS4gSWYgdGhlIG1haWxib3ggaXMgZW1wdHksIHJhaXNlIGEgXGV4Y2VwdGlvbntLZXlFcnJvcn0gZXhjZXB0aW9uLiBUaGUKK21lc3NhZ2UgaXMgcmVwcmVzZW50ZWQgYXMgYW4gaW5zdGFuY2Ugb2YgdGhlIGFwcHJvcHJpYXRlIGZvcm1hdC1zcGVjaWZpYworXGNsYXNze01lc3NhZ2V9IHN1YmNsYXNzIHVubGVzcyBhIGN1c3RvbSBtZXNzYWdlIGZhY3Rvcnkgd2FzIHNwZWNpZmllZCB3aGVuIHRoZQorXGNsYXNze01haWxib3h9IGluc3RhbmNlIHdhcyBpbml0aWFsaXplZC4KK1xlbmR7bWV0aG9kZGVzY30KKworXGJlZ2lue21ldGhvZGRlc2N9e3VwZGF0ZX17YXJnfQorUGFyYW1ldGVyIFx2YXJ7YXJnfSBzaG91bGQgYmUgYSBcdmFye2tleX0tdG8tXHZhcnttZXNzYWdlfSBtYXBwaW5nIG9yIGFuCitpdGVyYWJsZSBvZiAoXHZhcntrZXl9LCBcdmFye21lc3NhZ2V9KSBwYWlycy4gVXBkYXRlcyB0aGUgbWFpbGJveCBzbyB0aGF0LCBmb3IKK2VhY2ggZ2l2ZW4gXHZhcntrZXl9IGFuZCBcdmFye21lc3NhZ2V9LCB0aGUgbWVzc2FnZSBjb3JyZXNwb25kaW5nIHRvIFx2YXJ7a2V5fQoraXMgc2V0IHRvIFx2YXJ7bWVzc2FnZX0gYXMgaWYgYnkgdXNpbmcgXG1ldGhvZHtfX3NldGl0ZW1fXygpfS4gQXMgd2l0aAorXG1ldGhvZHtfX3NldGl0ZW1fXygpfSwgZWFjaCBcdmFye2tleX0gbXVzdCBhbHJlYWR5IGNvcnJlc3BvbmQgdG8gYSBtZXNzYWdlIGluCit0aGUgbWFpbGJveCBvciBlbHNlIGEgXGV4Y2VwdGlvbntLZXlFcnJvcn0gZXhjZXB0aW9uIHdpbGwgYmUgcmFpc2VkLCBzbyBpbgorZ2VuZXJhbCBpdCBpcyBpbmNvcnJlY3QgZm9yIFx2YXJ7YXJnfSB0byBiZSBhIFxjbGFzc3tNYWlsYm94fSBpbnN0YW5jZS4KK1xub3Rle1VubGlrZSB3aXRoIGRpY3Rpb25hcmllcywga2V5d29yZCBhcmd1bWVudHMgYXJlIG5vdCBzdXBwb3J0ZWQufQorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317Zmx1c2h9e30KK1dyaXRlIGFueSBwZW5kaW5nIGNoYW5nZXMgdG8gdGhlIGZpbGVzeXN0ZW0uIEZvciBzb21lIFxjbGFzc3tNYWlsYm94fQorc3ViY2xhc3NlcywgY2hhbmdlcyBhcmUgYWx3YXlzIHdyaXR0ZW4gaW1tZWRpYXRlbHkgYW5kIHRoaXMgbWV0aG9kIGRvZXMKK25vdGhpbmcuCitcZW5ke21ldGhvZGRlc2N9CisKK1xiZWdpbnttZXRob2RkZXNjfXtsb2NrfXt9CitBY3F1aXJlIGFuIGV4Y2x1c2l2ZSBhZHZpc29yeSBsb2NrIG9uIHRoZSBtYWlsYm94IHNvIHRoYXQgb3RoZXIgcHJvY2Vzc2VzIGtub3cKK25vdCB0byBtb2RpZnkgaXQuIEFuIFxleGNlcHRpb257RXh0ZXJuYWxDbGFzaEVycm9yfSBpcyByYWlzZWQgaWYgdGhlIGxvY2sgaXMKK25vdCBhdmFpbGFibGUuIFRoZSBwYXJ0aWN1bGFyIGxvY2tpbmcgbWVjaGFuaXNtcyB1c2VkIGRlcGVuZCB1cG9uIHRoZSBtYWlsYm94Citmb3JtYXQuCitcZW5ke21ldGhvZGRlc2N9CisKK1xiZWdpbnttZXRob2RkZXNjfXt1bmxvY2t9e30KK1JlbGVhc2UgdGhlIGxvY2sgb24gdGhlIG1haWxib3gsIGlmIGFueS4KK1xlbmR7bWV0aG9kZGVzY30KKworXGJlZ2lue21ldGhvZGRlc2N9e2Nsb3NlfXt9CitGbHVzaCB0aGUgbWFpbGJveCwgdW5sb2NrIGl0IGlmIG5lY2Vzc2FyeSwgYW5kIGNsb3NlIGFueSBvcGVuIGZpbGVzLiBGb3Igc29tZQorXGNsYXNze01haWxib3h9IHN1YmNsYXNzZXMsIHRoaXMgbWV0aG9kIGRvZXMgbm90aGluZy4KK1xlbmR7bWV0aG9kZGVzY30KKworCitcc3Vic3Vic2VjdGlvbntcY2xhc3N7TWFpbGRpcn19CitcbGFiZWx7bWFpbGJveC1tYWlsZGlyfQorCitcYmVnaW57Y2xhc3NkZXNjfXtNYWlsZGlyfXtkaXJuYW1lXG9wdGlvbmFseywgZmFjdG9yeT1yZmM4MjIuTWVzc2FnZVxvcHRpb25hbHssCitjcmVhdGU9VHJ1ZX19fQorQSBzdWJjbGFzcyBvZiBcY2xhc3N7TWFpbGJveH0gZm9yIG1haWxib3hlcyBpbiBNYWlsZGlyIGZvcm1hdC4gUGFyYW1ldGVyCitcdmFye2ZhY3Rvcnl9IGlzIGEgY2FsbGFibGUgb2JqZWN0IHRoYXQgYWNjZXB0cyBhIGZpbGUtbGlrZSBtZXNzYWdlCityZXByZXNlbnRhdGlvbiAod2hpY2ggYmVoYXZlcyBhcyBpZiBvcGVuIGluIGJpbmFyeSBtb2RlKSBhbmQgcmV0dXJucyBhIGN1c3RvbQorcmVwcmVzZW50YXRpb24uIElmIFx2YXJ7ZmFjdG9yeX0gaXMgXGNvZGV7Tm9uZX0sIFxjbGFzc3tNYWlsZGlyTWVzc2FnZX0gaXMgdXNlZAorYXMgdGhlIGRlZmF1bHQgbWVzc2FnZSByZXByZXNlbnRhdGlvbi4gSWYgXHZhcntjcmVhdGV9IGlzIFxjb2Rle1RydWV9LCB0aGUKK21haWxib3ggaXMgY3JlYXRlZCBpZiBpdCBkb2VzIG5vdCBleGlzdC4KKworSXQgaXMgZm9yIGhpc3RvcmljYWwgcmVhc29ucyB0aGF0IFx2YXJ7ZmFjdG9yeX0gZGVmYXVsdHMgdG8KK1xjbGFzc3tyZmM4MjIuTWVzc2FnZX0gYW5kIHRoYXQgXHZhcntkaXJuYW1lfSBpcyBuYW1lZCBhcyBzdWNoIHJhdGhlciB0aGFuCitcdmFye3BhdGh9LiBGb3IgYSBcY2xhc3N7TWFpbGRpcn0gaW5zdGFuY2UgdGhhdCBiZWhhdmVzIGxpa2UgaW5zdGFuY2VzIG9mIG90aGVyCitcY2xhc3N7TWFpbGJveH0gc3ViY2xhc3Nlcywgc2V0IFx2YXJ7ZmFjdG9yeX0gdG8gXGNvZGV7Tm9uZX0uCitcZW5ke2NsYXNzZGVzY30KKworTWFpbGRpciBpcyBhIGRpcmVjdG9yeS1iYXNlZCBtYWlsYm94IGZvcm1hdCBpbnZlbnRlZCBmb3IgdGhlIHFtYWlsIG1haWwKK3RyYW5zZmVyIGFnZW50IGFuZCBub3cgd2lkZWx5IHN1cHBvcnRlZCBieSBvdGhlciBwcm9ncmFtcy4gTWVzc2FnZXMgaW4gYQorTWFpbGRpciBtYWlsYm94IGFyZSBzdG9yZWQgaW4gc2VwYXJhdGUgZmlsZXMgd2l0aGluIGEgY29tbW9uIGRpcmVjdG9yeQorc3RydWN0dXJlLiBUaGlzIGRlc2lnbiBhbGxvd3MgTWFpbGRpciBtYWlsYm94ZXMgdG8gYmUgYWNjZXNzZWQgYW5kIG1vZGlmaWVkIGJ5CittdWx0aXBsZSB1bnJlbGF0ZWQgcHJvZ3JhbXMgd2l0aG91dCBkYXRhIGNvcnJ1cHRpb24sIHNvIGZpbGUgbG9ja2luZyBpcwordW5uZWNlc3NhcnkuCisKK01haWxkaXIgbWFpbGJveGVzIGNvbnRhaW4gdGhyZWUgc3ViZGlyZWN0b3JpZXMsIG5hbWVseTogXGZpbGV7dG1wfSwgXGZpbGV7bmV3fSwKK2FuZCBcZmlsZXtjdXJ9LiBNZXNzYWdlcyBhcmUgY3JlYXRlZCBtb21lbnRhcmlseSBpbiB0aGUgXGZpbGV7dG1wfSBzdWJkaXJlY3RvcnkKK2FuZCB0aGVuIG1vdmVkIHRvIHRoZSBcZmlsZXtuZXd9IHN1YmRpcmVjdG9yeSB0byBmaW5hbGl6ZSBkZWxpdmVyeS4gQSBtYWlsIHVzZXIKK2FnZW50IG1heSBzdWJzZXF1ZW50bHkgbW92ZSB0aGUgbWVzc2FnZSB0byB0aGUgXGZpbGV7Y3VyfSBzdWJkaXJlY3RvcnkgYW5kCitzdG9yZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgc3RhdGUgb2YgdGhlIG1lc3NhZ2UgaW4gYSBzcGVjaWFsICJpbmZvIiBzZWN0aW9uCithcHBlbmRlZCB0byBpdHMgZmlsZSBuYW1lLgorCitGb2xkZXJzIG9mIHRoZSBzdHlsZSBpbnRyb2R1Y2VkIGJ5IHRoZSBDb3VyaWVyIG1haWwgdHJhbnNmZXIgYWdlbnQgYXJlIGFsc28KK3N1cHBvcnRlZC4gQW55IHN1YmRpcmVjdG9yeSBvZiB0aGUgbWFpbiBtYWlsYm94IGlzIGNvbnNpZGVyZWQgYSBmb2xkZXIgaWYKK1xjaGFyYWN0ZXJ7Ln0gaXMgdGhlIGZpcnN0IGNoYXJhY3RlciBpbiBpdHMgbmFtZS4gRm9sZGVyIG5hbWVzIGFyZSByZXByZXNlbnRlZAorYnkgXGNsYXNze01haWxkaXJ9IHdpdGhvdXQgdGhlIGxlYWRpbmcgXGNoYXJhY3RlcnsufS4gRWFjaCBmb2xkZXIgaXMgaXRzZWxmIGEKK01haWxkaXIgbWFpbGJveCBidXQgc2hvdWxkIG5vdCBjb250YWluIG90aGVyIGZvbGRlcnMuIEluc3RlYWQsIGEgbG9naWNhbAorbmVzdGluZyBpcyBpbmRpY2F0ZWQgdXNpbmcgXGNoYXJhY3RlcnsufSB0byBkZWxpbWl0IGxldmVscywgZS5nLiwKKyJBcmNoaXZlZC4yMDA1LjA3Ii4KKworXGJlZ2lue25vdGljZX0KK1RoZSBNYWlsZGlyIHNwZWNpZmljYXRpb24gcmVxdWlyZXMgdGhlIHVzZSBvZiBhIGNvbG9uIChcY2hhcmFjdGVyezp9KSBpbgorY2VydGFpbiBtZXNzYWdlIGZpbGUgbmFtZXMuIEhvd2V2ZXIsIHNvbWUgb3BlcmF0aW5nIHN5c3RlbXMgZG8gbm90IHBlcm1pdCB0aGlzCitjaGFyYWN0ZXIgaW4gZmlsZSBuYW1lcywgSWYgeW91IHdpc2ggdG8gdXNlIGEgTWFpbGRpci1saWtlIGZvcm1hdCBvbiBzdWNoIGFuCitvcGVyYXRpbmcgc3lzdGVtLCB5b3Ugc2hvdWxkIHNwZWNpZnkgYW5vdGhlciBjaGFyYWN0ZXIgdG8gdXNlIGluc3RlYWQuIFRoZQorZXhjbGFtYXRpb24gcG9pbnQgKFxjaGFyYWN0ZXJ7IX0pIGlzIGEgcG9wdWxhciBjaG9pY2UuIEZvciBleGFtcGxlOgorXGJlZ2lue3ZlcmJhdGltfQoraW1wb3J0IG1haWxib3gKK21haWxib3guTWFpbGRpci5jb2xvbiA9ICchJworXGVuZHt2ZXJiYXRpbX0KK1RoZSBcbWVtYmVye2NvbG9ufSBhdHRyaWJ1dGUgbWF5IGFsc28gYmUgc2V0IG9uIGEgcGVyLWluc3RhbmNlIGJhc2lzLgorXGVuZHtub3RpY2V9CisKK1xjbGFzc3tNYWlsZGlyfSBpbnN0YW5jZXMgaGF2ZSBhbGwgb2YgdGhlIG1ldGhvZHMgb2YgXGNsYXNze01haWxib3h9IGluCithZGRpdGlvbiB0byB0aGUgZm9sbG93aW5nOgorCitcYmVnaW57bWV0aG9kZGVzY317bGlzdF9mb2xkZXJzfXt9CitSZXR1cm4gYSBsaXN0IG9mIHRoZSBuYW1lcyBvZiBhbGwgZm9sZGVycy4KK1xlbmR7bWV0aG9kZGVzY30KKworXGJlZ2lue21ldGhvZGRlc2N9e2dldF9mb2xkZXJ9e2ZvbGRlcn0KK1JldHVybiBhIFxjbGFzc3tNYWlsZGlyfSBpbnN0YW5jZSByZXByZXNlbnRpbmcgdGhlIGZvbGRlciB3aG9zZSBuYW1lIGlzCitcdmFye2ZvbGRlcn0uIEEgXGV4Y2VwdGlvbntOb1N1Y2hNYWlsYm94RXJyb3J9IGV4Y2VwdGlvbiBpcyByYWlzZWQgaWYgdGhlCitmb2xkZXIgZG9lcyBub3QgZXhpc3QuCitcZW5ke21ldGhvZGRlc2N9CisKK1xiZWdpbnttZXRob2RkZXNjfXthZGRfZm9sZGVyfXtmb2xkZXJ9CitDcmVhdGUgYSBmb2xkZXIgd2hvc2UgbmFtZSBpcyBcdmFye2ZvbGRlcn0gYW5kIHJldHVybiBhIFxjbGFzc3tNYWlsZGlyfQoraW5zdGFuY2UgcmVwcmVzZW50aW5nIGl0LgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317cmVtb3ZlX2ZvbGRlcn17Zm9sZGVyfQorRGVsZXRlIHRoZSBmb2xkZXIgd2hvc2UgbmFtZSBpcyBcdmFye2ZvbGRlcn0uIElmIHRoZSBmb2xkZXIgY29udGFpbnMgYW55CittZXNzYWdlcywgYSBcZXhjZXB0aW9ue05vdEVtcHR5RXJyb3J9IGV4Y2VwdGlvbiB3aWxsIGJlIHJhaXNlZCBhbmQgdGhlIGZvbGRlcgord2lsbCBub3QgYmUgZGVsZXRlZC4KK1xlbmR7bWV0aG9kZGVzY30KKworXGJlZ2lue21ldGhvZGRlc2N9e2NsZWFufXt9CitEZWxldGUgdGVtcG9yYXJ5IGZpbGVzIGZyb20gdGhlIG1haWxib3ggdGhhdCBoYXZlIG5vdCBiZWVuIGFjY2Vzc2VkIGluIHRoZQorbGFzdCAzNiBob3Vycy4gVGhlIE1haWxkaXIgc3BlY2lmaWNhdGlvbiBzYXlzIHRoYXQgbWFpbC1yZWFkaW5nIHByb2dyYW1zCitzaG91bGQgZG8gdGhpcyBvY2Nhc2lvbmFsbHkuCitcZW5ke21ldGhvZGRlc2N9CisKK1NvbWUgXGNsYXNze01haWxib3h9IG1ldGhvZHMgaW1wbGVtZW50ZWQgYnkgXGNsYXNze01haWxkaXJ9IGRlc2VydmUgc3BlY2lhbAorcmVtYXJrczoKKworXGJlZ2lue21ldGhvZGRlc2N9e2FkZH17bWVzc2FnZX0KK1xtZXRob2RsaW5lW01haWxkaXJde19fc2V0aXRlbV9ffXtrZXksIG1lc3NhZ2V9CitcbWV0aG9kbGluZVtNYWlsZGlyXXt1cGRhdGV9e2FyZ30KK1x3YXJuaW5ne1RoZXNlIG1ldGhvZHMgZ2VuZXJhdGUgdW5pcXVlIGZpbGUgbmFtZXMgYmFzZWQgdXBvbiB0aGUgY3VycmVudAorcHJvY2VzcyBJRC4gV2hlbiB1c2luZyBtdWx0aXBsZSB0aHJlYWRzLCB1bmRldGVjdGVkIG5hbWUgY2xhc2hlcyBtYXkgb2NjdXIgYW5kCitjYXVzZSBjb3JydXB0aW9uIG9mIHRoZSBtYWlsYm94IHVubGVzcyB0aHJlYWRzIGFyZSBjb29yZGluYXRlZCB0byBhdm9pZCB1c2luZwordGhlc2UgbWV0aG9kcyB0byBtYW5pcHVsYXRlIHRoZSBzYW1lIG1haWxib3ggc2ltdWx0YW5lb3VzbHkufQorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317Zmx1c2h9e30KK0FsbCBjaGFuZ2VzIHRvIE1haWxkaXIgbWFpbGJveGVzIGFyZSBpbW1lZGlhdGVseSBhcHBsaWVkLCBzbyB0aGlzIG1ldGhvZCBkb2VzCitub3RoaW5nLgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317bG9ja317fQorXG1ldGhvZGxpbmV7dW5sb2NrfXt9CitNYWlsZGlyIG1haWxib3hlcyBkbyBub3Qgc3VwcG9ydCAob3IgcmVxdWlyZSkgbG9ja2luZywgc28gdGhlc2UgbWV0aG9kcyBkbworbm90aGluZy4gCitcZW5ke21ldGhvZGRlc2N9CisKK1xiZWdpbnttZXRob2RkZXNjfXtjbG9zZX17fQorXGNsYXNze01haWxkaXJ9IGluc3RhbmNlcyBkbyBub3Qga2VlcCBhbnkgb3BlbiBmaWxlcyBhbmQgdGhlIHVuZGVybHlpbmcKK21haWxib3hlcyBkbyBub3Qgc3VwcG9ydCBsb2NraW5nLCBzbyB0aGlzIG1ldGhvZCBkb2VzIG5vdGhpbmcuCitcZW5ke21ldGhvZGRlc2N9CisKK1xiZWdpbnttZXRob2RkZXNjfXtnZXRfZmlsZX17a2V5fQorRGVwZW5kaW5nIHVwb24gdGhlIGhvc3QgcGxhdGZvcm0sIGl0IG1heSBub3QgYmUgcG9zc2libGUgdG8gbW9kaWZ5IG9yIHJlbW92ZQordGhlIHVuZGVybHlpbmcgbWVzc2FnZSB3aGlsZSB0aGUgcmV0dXJuZWQgZmlsZSByZW1haW5zIG9wZW4uCitcZW5ke21ldGhvZGRlc2N9CisKK1xiZWdpbntzZWVhbHNvfQorICAgIFxzZWVsaW5re2h0dHA6Ly93d3cucW1haWwub3JnL21hbi9tYW41L21haWxkaXIuaHRtbH17bWFpbGRpciBtYW4gcGFnZSBmcm9tCisgICAgcW1haWx9e1RoZSBvcmlnaW5hbCBzcGVjaWZpY2F0aW9uIG9mIHRoZSBmb3JtYXQufQorICAgIFxzZWVsaW5re2h0dHA6Ly9jci55cC50by9wcm90by9tYWlsZGlyLmh0bWx9e1VzaW5nIG1haWxkaXIgZm9ybWF0fXtOb3RlcworICAgIG9uIE1haWxkaXIgYnkgaXRzIGludmVudG9yLiBJbmNsdWRlcyBhbiB1cGRhdGVkIG5hbWUtY3JlYXRpb24gc2NoZW1lIGFuZAorICAgIGRldGFpbHMgb24gImluZm8iIHNlbWFudGljcy59CisgICAgXHNlZWxpbmt7aHR0cDovL3d3dy5jb3VyaWVyLW10YS5vcmcvP21haWxkaXIuaHRtbH17bWFpbGRpciBtYW4gcGFnZSBmcm9tCisgICAgQ291cmllcn17QW5vdGhlciBzcGVjaWZpY2F0aW9uIG9mIHRoZSBmb3JtYXQuIERlc2NyaWJlcyBhIGNvbW1vbiBleHRlbnNpb24KKyAgICBmb3Igc3VwcG9ydGluZyBmb2xkZXJzLn0KK1xlbmR7c2VlYWxzb30KKworXHN1YnN1YnNlY3Rpb257XGNsYXNze21ib3h9fQorXGxhYmVse21haWxib3gtbWJveH0KKworXGJlZ2lue2NsYXNzZGVzY317bWJveH17cGF0aFxvcHRpb25hbHssIGZhY3Rvcnk9Tm9uZVxvcHRpb25hbHssIGNyZWF0ZT1UcnVlfX19CitBIHN1YmNsYXNzIG9mIFxjbGFzc3tNYWlsYm94fSBmb3IgbWFpbGJveGVzIGluIG1ib3ggZm9ybWF0LiBQYXJhbWV0ZXIKK1x2YXJ7ZmFjdG9yeX0gaXMgYSBjYWxsYWJsZSBvYmplY3QgdGhhdCBhY2NlcHRzIGEgZmlsZS1saWtlIG1lc3NhZ2UKK3JlcHJlc2VudGF0aW9uICh3aGljaCBiZWhhdmVzIGFzIGlmIG9wZW4gaW4gYmluYXJ5IG1vZGUpIGFuZCByZXR1cm5zIGEgY3VzdG9tCityZXByZXNlbnRhdGlvbi4gSWYgXHZhcntmYWN0b3J5fSBpcyBcY29kZXtOb25lfSwgXGNsYXNze21ib3hNZXNzYWdlfSBpcyB1c2VkIGFzCit0aGUgZGVmYXVsdCBtZXNzYWdlIHJlcHJlc2VudGF0aW9uLiBJZiBcdmFye2NyZWF0ZX0gaXMgXGNvZGV7VHJ1ZX0sIHRoZSBtYWlsYm94CitpcyBjcmVhdGVkIGlmIGl0IGRvZXMgbm90IGV4aXN0LgorXGVuZHtjbGFzc2Rlc2N9CisKK1RoZSBtYm94IGZvcm1hdCBpcyB0aGUgY2xhc3NpYyBmb3JtYXQgZm9yIHN0b3JpbmcgbWFpbCBvbiBcVU5JWHt9IHN5c3RlbXMuIEFsbAorbWVzc2FnZXMgaW4gYW4gbWJveCBtYWlsYm94IGFyZSBzdG9yZWQgaW4gYSBzaW5nbGUgZmlsZSB3aXRoIHRoZSBiZWdpbm5pbmcgb2YKK2VhY2ggbWVzc2FnZSBpbmRpY2F0ZWQgYnkgYSBsaW5lIHdob3NlIGZpcnN0IGZpdmUgY2hhcmFjdGVycyBhcmUgIkZyb21+Ii4KKworU2V2ZXJhbCB2YXJpYXRpb25zIG9mIHRoZSBtYm94IGZvcm1hdCBleGlzdCB0byBhZGRyZXNzIHBlcmNlaXZlZCBzaG9ydGNvbWluZ3MKK2luIHRoZSBvcmlnaW5hbC4gSW4gdGhlIGludGVyZXN0IG9mIGNvbXBhdGliaWxpdHksIFxjbGFzc3ttYm94fSBpbXBsZW1lbnRzIHRoZQorb3JpZ2luYWwgZm9ybWF0LCB3aGljaCBpcyBzb21ldGltZXMgcmVmZXJyZWQgdG8gYXMgXGRmbnttYm94b30uIFRoaXMgbWVhbnMgdGhhdAordGhlIFxtYWlsaGVhZGVye0NvbnRlbnQtTGVuZ3RofSBoZWFkZXIsIGlmIHByZXNlbnQsIGlzIGlnbm9yZWQgYW5kIHRoYXQgYW55CitvY2N1cnJlbmNlcyBvZiAiRnJvbX4iIGF0IHRoZSBiZWdpbm5pbmcgb2YgYSBsaW5lIGluIGEgbWVzc2FnZSBib2R5IGFyZQordHJhbnNmb3JtZWQgdG8gIj5Gcm9tfiIgd2hlbiBzdG9yaW5nIHRoZSBtZXNzYWdlLCBhbHRob3VnaCBvY2N1cmVuY2VzIG9mCisiPkZyb21+IiBhcmUgbm90IHRyYW5zZm9ybWVkIHRvICJGcm9tfiIgd2hlbiByZWFkaW5nIHRoZSBtZXNzYWdlLgorCitTb21lIFxjbGFzc3tNYWlsYm94fSBtZXRob2RzIGltcGxlbWVudGVkIGJ5IFxjbGFzc3ttYm94fSBkZXNlcnZlIHNwZWNpYWwKK3JlbWFya3M6CisKK1xiZWdpbnttZXRob2RkZXNjfXtnZXRfZmlsZX17a2V5fQorVXNpbmcgdGhlIGZpbGUgYWZ0ZXIgY2FsbGluZyBcbWV0aG9ke2ZsdXNoKCl9IG9yIFxtZXRob2R7Y2xvc2UoKX0gb24gdGhlCitcY2xhc3N7bWJveH0gaW5zdGFuY2UgbWF5IHlpZWxkIHVucHJlZGljdGFibGUgcmVzdWx0cyBvciByYWlzZSBhbiBleGNlcHRpb24uCitcZW5ke21ldGhvZGRlc2N9CisKK1xiZWdpbnttZXRob2RkZXNjfXtsb2NrfXt9CitcbWV0aG9kbGluZXt1bmxvY2t9e30KK1RocmVlIGxvY2tpbmcgbWVjaGFuaXNtcyBhcmUgdXNlZC0tLWRvdCBsb2NraW5nIGFuZCwgaWYgYXZhaWxhYmxlLCB0aGUKK1xjZnVuY3Rpb257ZmxvY2soKX0gYW5kIFxjZnVuY3Rpb257bG9ja2YoKX0gc3lzdGVtIGNhbGxzLgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57c2VlYWxzb30KKyAgICBcc2VlbGlua3todHRwOi8vd3d3LnFtYWlsLm9yZy9tYW4vbWFuNS9tYm94Lmh0bWx9e21ib3ggbWFuIHBhZ2UgZnJvbQorICAgIHFtYWlsfXtBIHNwZWNpZmljYXRpb24gb2YgdGhlIGZvcm1hdCBhbmQgaXRzIHZhcmlhdGlvbnMufQorICAgIFxzZWVsaW5re2h0dHA6Ly93d3cudGluLm9yZy9iaW4vbWFuLmNnaT9zZWN0aW9uPTVcJnRvcGljPW1ib3h9e21ib3ggbWFuCisgICAgcGFnZSBmcm9tIHRpbn17QW5vdGhlciBzcGVjaWZpY2F0aW9uIG9mIHRoZSBmb3JtYXQsIHdpdGggZGV0YWlscyBvbgorICAgIGxvY2tpbmcufQorICAgIFxzZWVsaW5re2h0dHA6Ly9ob21lLm5ldHNjYXBlLmNvbS9lbmcvbW96aWxsYS8yLjAvcmVsbm90ZXMvZGVtby9jb250ZW50LWxlbmd0aC5odG1sfQorICAgIHtDb25maWd1cmluZyBOZXRzY2FwZSBNYWlsIG9uIFxVTklYe306IFdoeSBUaGUgQ29udGVudC1MZW5ndGggRm9ybWF0IGlzCisgICAgQmFkfXtBbiBhcmd1bWVudCBmb3IgdXNpbmcgdGhlIG9yaWdpbmFsIG1ib3ggZm9ybWF0IHJhdGhlciB0aGFuIGEKKyAgICB2YXJpYXRpb24ufQorICAgIFxzZWVsaW5re2h0dHA6Ly9ob21lcGFnZXMudGVzY28ubmV0Li9cdGlsZGV7fUouZGVCb3luZVBvbGxhcmQvRkdBL21haWwtbWJveC1mb3JtYXRzLmh0bWx9CisgICAgeyJtYm94IiBpcyBhIGZhbWlseSBvZiBzZXZlcmFsIG11dHVhbGx5IGluY29tcGF0aWJsZSBtYWlsYm94IGZvcm1hdHN9e0EKKyAgICBoaXN0b3J5IG9mIG1ib3ggdmFyaWF0aW9ucy59CitcZW5ke3NlZWFsc299CisKK1xzdWJzdWJzZWN0aW9ue1xjbGFzc3tNSH19CitcbGFiZWx7bWFpbGJveC1taH0KKworXGJlZ2lue2NsYXNzZGVzY317TUh9e3BhdGhcb3B0aW9uYWx7LCBmYWN0b3J5PU5vbmVcb3B0aW9uYWx7LCBjcmVhdGU9VHJ1ZX19fQorQSBzdWJjbGFzcyBvZiBcY2xhc3N7TWFpbGJveH0gZm9yIG1haWxib3hlcyBpbiBNSCBmb3JtYXQuIFBhcmFtZXRlcgorXHZhcntmYWN0b3J5fSBpcyBhIGNhbGxhYmxlIG9iamVjdCB0aGF0IGFjY2VwdHMgYSBmaWxlLWxpa2UgbWVzc2FnZQorcmVwcmVzZW50YXRpb24gKHdoaWNoIGJlaGF2ZXMgYXMgaWYgb3BlbiBpbiBiaW5hcnkgbW9kZSkgYW5kIHJldHVybnMgYSBjdXN0b20KK3JlcHJlc2VudGF0aW9uLiBJZiBcdmFye2ZhY3Rvcnl9IGlzIFxjb2Rle05vbmV9LCBcY2xhc3N7TUhNZXNzYWdlfSBpcyB1c2VkIGFzCit0aGUgZGVmYXVsdCBtZXNzYWdlIHJlcHJlc2VudGF0aW9uLiBJZiBcdmFye2NyZWF0ZX0gaXMgXGNvZGV7VHJ1ZX0sIHRoZSBtYWlsYm94CitpcyBjcmVhdGVkIGlmIGl0IGRvZXMgbm90IGV4aXN0LgorXGVuZHtjbGFzc2Rlc2N9CisKK01IIGlzIGEgZGlyZWN0b3J5LWJhc2VkIG1haWxib3ggZm9ybWF0IGludmVudGVkIGZvciB0aGUgTUggTWVzc2FnZSBIYW5kbGluZworU3lzdGVtLCBhIG1haWwgdXNlciBhZ2VudC4gRWFjaCBtZXNzYWdlIGluIGFuIE1IIG1haWxib3ggcmVzaWRlcyBpbiBpdHMgb3duCitmaWxlLiBBbiBNSCBtYWlsYm94IG1heSBjb250YWluIG90aGVyIE1IIG1haWxib3hlcyAoY2FsbGVkIFxkZm57Zm9sZGVyc30pIGluCithZGRpdGlvbiB0byBtZXNzYWdlcy4gRm9sZGVycyBtYXkgYmUgbmVzdGVkIGluZGVmaW5pdGVseS4gTUggbWFpbGJveGVzIGFsc28KK3N1cHBvcnQgXGRmbntzZXF1ZW5jZXN9LCB3aGljaCBhcmUgbmFtZWQgbGlzdHMgdXNlZCB0byBsb2dpY2FsbHkgZ3JvdXAgbWVzc2FnZXMKK3dpdGhvdXQgbW92aW5nIHRoZW0gdG8gc3ViLWZvbGRlcnMuIFNlcXVlbmNlcyBhcmUgZGVmaW5lZCBpbiBhIGZpbGUgY2FsbGVkCitcZmlsZXsubWhfc2VxdWVuY2VzfSBpbiBlYWNoIGZvbGRlci4KKworVGhlIFxjbGFzc3tNSH0gY2xhc3MgbWFuaXB1bGF0ZXMgTUggbWFpbGJveGVzLCBidXQgaXQgZG9lcyBub3QgYXR0ZW1wdCB0bworZW11bGF0ZSBhbGwgb2YgXHByb2dyYW17bWh9J3MgYmVoYXZpb3JzLiBJbiBwYXJ0aWN1bGFyLCBpdCBkb2VzIG5vdCBtb2RpZnkgYW5kCitpcyBub3QgYWZmZWN0ZWQgYnkgdGhlIFxmaWxle2NvbnRleHR9IG9yIFxmaWxley5taF9wcm9maWxlfSBmaWxlcyB0aGF0IGFyZSB1c2VkCitieSBccHJvZ3JhbXttaH0gdG8gc3RvcmUgaXRzIHN0YXRlIGFuZCBjb25maWd1cmF0aW9uLgorCitcY2xhc3N7TUh9IGluc3RhbmNlcyBoYXZlIGFsbCBvZiB0aGUgbWV0aG9kcyBvZiBcY2xhc3N7TWFpbGJveH0gaW4gYWRkaXRpb24gdG8KK3RoZSBmb2xsb3dpbmc6CisKK1xiZWdpbnttZXRob2RkZXNjfXtsaXN0X2ZvbGRlcnN9e30KK1JldHVybiBhIGxpc3Qgb2YgdGhlIG5hbWVzIG9mIGFsbCBmb2xkZXJzLgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317Z2V0X2ZvbGRlcn17Zm9sZGVyfQorUmV0dXJuIGFuIFxjbGFzc3tNSH0gaW5zdGFuY2UgcmVwcmVzZW50aW5nIHRoZSBmb2xkZXIgd2hvc2UgbmFtZSBpcworXHZhcntmb2xkZXJ9LiBBIFxleGNlcHRpb257Tm9TdWNoTWFpbGJveEVycm9yfSBleGNlcHRpb24gaXMgcmFpc2VkIGlmIHRoZQorZm9sZGVyIGRvZXMgbm90IGV4aXN0LgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317YWRkX2ZvbGRlcn17Zm9sZGVyfQorQ3JlYXRlIGEgZm9sZGVyIHdob3NlIG5hbWUgaXMgXHZhcntmb2xkZXJ9IGFuZCByZXR1cm4gYW4gXGNsYXNze01IfSBpbnN0YW5jZQorcmVwcmVzZW50aW5nIGl0LgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317cmVtb3ZlX2ZvbGRlcn17Zm9sZGVyfQorRGVsZXRlIHRoZSBmb2xkZXIgd2hvc2UgbmFtZSBpcyBcdmFye2ZvbGRlcn0uIElmIHRoZSBmb2xkZXIgY29udGFpbnMgYW55CittZXNzYWdlcywgYSBcZXhjZXB0aW9ue05vdEVtcHR5RXJyb3J9IGV4Y2VwdGlvbiB3aWxsIGJlIHJhaXNlZCBhbmQgdGhlIGZvbGRlcgord2lsbCBub3QgYmUgZGVsZXRlZC4KK1xlbmR7bWV0aG9kZGVzY30KKworXGJlZ2lue21ldGhvZGRlc2N9e2dldF9zZXF1ZW5jZXN9e30KK1JldHVybiBhIGRpY3Rpb25hcnkgb2Ygc2VxdWVuY2UgbmFtZXMgbWFwcGVkIHRvIGtleSBsaXN0cy4gSWYgdGhlcmUgYXJlIG5vCitzZXF1ZW5jZXMsIHRoZSBlbXB0eSBkaWN0aW9uYXJ5IGlzIHJldHVybmVkLgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317c2V0X3NlcXVlbmNlc317c2VxdWVuY2VzfQorUmUtZGVmaW5lIHRoZSBzZXF1ZW5jZXMgdGhhdCBleGlzdCBpbiB0aGUgbWFpbGJveCBiYXNlZCB1cG9uIFx2YXJ7c2VxdWVuY2VzfSwgYQorZGljdGlvbmFyeSBvZiBuYW1lcyBtYXBwZWQgdG8ga2V5IGxpc3RzLCBsaWtlIHJldHVybmVkIGJ5CitcbWV0aG9ke2dldF9zZXF1ZW5jZXMoKX0uCitcZW5ke21ldGhvZGRlc2N9CisKK1xiZWdpbnttZXRob2RkZXNjfXtwYWNrfXt9CitSZW5hbWUgbWVzc2FnZXMgaW4gdGhlIG1haWxib3ggYXMgbmVjZXNzYXJ5IHRvIGVsaW1pbmF0ZSBnYXBzIGluIG51bWJlcmluZy4KK0VudHJpZXMgaW4gdGhlIHNlcXVlbmNlcyBsaXN0IGFyZSB1cGRhdGVkIGNvcnJlc3BvbmRpbmdseS4gXG5vdGV7QWxyZWFkeS1pc3N1ZWQKK2tleXMgYXJlIGludmFsaWRhdGVkIGJ5IHRoaXMgb3BlcmF0aW9uIGFuZCBzaG91bGQgbm90IGJlIHN1YnNlcXVlbnRseSB1c2VkLn0KK1xlbmR7bWV0aG9kZGVzY30KKworU29tZSBcY2xhc3N7TWFpbGJveH0gbWV0aG9kcyBpbXBsZW1lbnRlZCBieSBcY2xhc3N7TUh9IGRlc2VydmUgc3BlY2lhbCByZW1hcmtzOgorCitcYmVnaW57bWV0aG9kZGVzY317cmVtb3ZlfXtrZXl9CitcbWV0aG9kbGluZXtfX2RlbGl0ZW1fX317a2V5fQorXG1ldGhvZGxpbmV7ZGlzY2FyZH17a2V5fQorVGhlc2UgbWV0aG9kcyBpbW1lZGlhdGVseSBkZWxldGUgdGhlIG1lc3NhZ2UuIFRoZSBNSCBjb252ZW50aW9uIG9mIG1hcmtpbmcgYQorbWVzc2FnZSBmb3IgZGVsZXRpb24gYnkgcHJlcGVuZGluZyBhIGNvbW1hIHRvIGl0cyBuYW1lIGlzIG5vdCB1c2VkLgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317bG9ja317fQorXG1ldGhvZGxpbmV7dW5sb2NrfXt9CitUaHJlZSBsb2NraW5nIG1lY2hhbmlzbXMgYXJlIHVzZWQtLS1kb3QgbG9ja2luZyBhbmQsIGlmIGF2YWlsYWJsZSwgdGhlCitcY2Z1bmN0aW9ue2Zsb2NrKCl9IGFuZCBcY2Z1bmN0aW9ue2xvY2tmKCl9IHN5c3RlbSBjYWxscy4gRm9yIE1IIG1haWxib3hlcywKK2xvY2tpbmcgdGhlIG1haWxib3ggbWVhbnMgbG9ja2luZyB0aGUgXGZpbGV7Lm1oX3NlcXVlbmNlc30gZmlsZSBhbmQsIG9ubHkgZm9yCit0aGUgZHVyYXRpb24gb2YgYW55IG9wZXJhdGlvbnMgdGhhdCBhZmZlY3QgdGhlbSwgbG9ja2luZyBpbmRpdmlkdWFsIG1lc3NhZ2UKK2ZpbGVzLgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317Z2V0X2ZpbGV9e2tleX0KK0RlcGVuZGluZyB1cG9uIHRoZSBob3N0IHBsYXRmb3JtLCBpdCBtYXkgbm90IGJlIHBvc3NpYmxlIHRvIHJlbW92ZSB0aGUKK3VuZGVybHlpbmcgbWVzc2FnZSB3aGlsZSB0aGUgcmV0dXJuZWQgZmlsZSByZW1haW5zIG9wZW4uCitcZW5ke21ldGhvZGRlc2N9CisKK1xiZWdpbnttZXRob2RkZXNjfXtmbHVzaH17fQorQWxsIGNoYW5nZXMgdG8gTUggbWFpbGJveGVzIGFyZSBpbW1lZGlhdGVseSBhcHBsaWVkLCBzbyB0aGlzIG1ldGhvZCBkb2VzCitub3RoaW5nLgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317Y2xvc2V9e30KK1xjbGFzc3tNSH0gaW5zdGFuY2VzIGRvIG5vdCBrZWVwIGFueSBvcGVuIGZpbGVzLCBzbyB0aGlzIG1ldGhvZCBpcyBlcXVpdmVsYW50Cit0byBcbWV0aG9ke3VubG9jaygpfS4KK1xlbmR7bWV0aG9kZGVzY30KKworXGJlZ2lue3NlZWFsc299Citcc2VlbGlua3todHRwOi8vd3d3Lm5vbmdudS5vcmcvbm1oL317bm1oIC0gTWVzc2FnZSBIYW5kbGluZyBTeXN0ZW19e0hvbWUgcGFnZQorb2YgXHByb2dyYW17bm1ofSwgYW4gdXBkYXRlZCB2ZXJzaW9uIG9mIHRoZSBvcmlnaW5hbCBccHJvZ3JhbXttaH0ufQorXHNlZWxpbmt7aHR0cDovL3d3dy5pY3MudWNpLmVkdS9cdGlsZGV7fW1oL2Jvb2svfXtNSCBcJiBubWg6IEVtYWlsIGZvciBVc2VycyBcJgorUHJvZ3JhbW1lcnN9e0EgR1BMLWxpY2Vuc2VkIGJvb2sgb24gXHByb2dyYW17bWh9IGFuZCBccHJvZ3JhbXtubWh9LCB3aXRoIHNvbWUKK2luZm9ybWF0aW9uIG9uIHRoZSBtYWlsYm94IGZvcm1hdC59CitcZW5ke3NlZWFsc299CisKK1xzdWJzdWJzZWN0aW9ue1xjbGFzc3tCYWJ5bH19CitcbGFiZWx7bWFpbGJveC1iYWJ5bH0KKworXGJlZ2lue2NsYXNzZGVzY317QmFieWx9e3BhdGhcb3B0aW9uYWx7LCBmYWN0b3J5PU5vbmVcb3B0aW9uYWx7LCBjcmVhdGU9VHJ1ZX19fQorQSBzdWJjbGFzcyBvZiBcY2xhc3N7TWFpbGJveH0gZm9yIG1haWxib3hlcyBpbiBCYWJ5bCBmb3JtYXQuIFBhcmFtZXRlcgorXHZhcntmYWN0b3J5fSBpcyBhIGNhbGxhYmxlIG9iamVjdCB0aGF0IGFjY2VwdHMgYSBmaWxlLWxpa2UgbWVzc2FnZQorcmVwcmVzZW50YXRpb24gKHdoaWNoIGJlaGF2ZXMgYXMgaWYgb3BlbiBpbiBiaW5hcnkgbW9kZSkgYW5kIHJldHVybnMgYSBjdXN0b20KK3JlcHJlc2VudGF0aW9uLiBJZiBcdmFye2ZhY3Rvcnl9IGlzIFxjb2Rle05vbmV9LCBcY2xhc3N7QmFieWxNZXNzYWdlfSBpcyB1c2VkCithcyB0aGUgZGVmYXVsdCBtZXNzYWdlIHJlcHJlc2VudGF0aW9uLiBJZiBcdmFye2NyZWF0ZX0gaXMgXGNvZGV7VHJ1ZX0sIHRoZQorbWFpbGJveCBpcyBjcmVhdGVkIGlmIGl0IGRvZXMgbm90IGV4aXN0LgorXGVuZHtjbGFzc2Rlc2N9CisKK0JhYnlsIGlzIGEgc2luZ2xlLWZpbGUgbWFpbGJveCBmb3JtYXQgdXNlZCBieSB0aGUgUm1haWwgbWFpbCB1c2VyIGFnZW50CitpbmNsdWRlZCB3aXRoIEVtYWNzLiBUaGUgYmVnaW5uaW5nIG9mIGEgbWVzc2FnZSBpcyBpbmRpY2F0ZWQgYnkgYSBsaW5lCitjb250YWluaW5nIHRoZSB0d28gY2hhcmFjdGVycyBDb250cm9sLVVuZGVyc2NvcmUKKyhcY2hhcmFjdGVye1x0ZXh0YmFja3NsYXNoMDM3fSkgYW5kIENvbnRyb2wtTCAoXGNoYXJhY3RlcntcdGV4dGJhY2tzbGFzaDAxNH0pLgorVGhlIGVuZCBvZiBhIG1lc3NhZ2UgaXMgaW5kaWNhdGVkIGJ5IHRoZSBzdGFydCBvZiB0aGUgbmV4dCBtZXNzYWdlIG9yLCBpbiB0aGUKK2Nhc2Ugb2YgdGhlIGxhc3QgbWVzc2FnZSwgYSBsaW5lIGNvbnRhaW5pbmcgYSBDb250cm9sLVVuZGVyc2NvcmUKKyhcY2hhcmFjdGVye1x0ZXh0YmFja3NsYXNoMDM3fSkgY2hhcmFjdGVyLgorCitNZXNzYWdlcyBpbiBhIEJhYnlsIG1haWxib3ggaGF2ZSB0d28gc2V0cyBvZiBoZWFkZXJzLCBvcmlnaW5hbCBoZWFkZXJzIGFuZAorc28tY2FsbGVkIHZpc2libGUgaGVhZGVycy4gVmlzaWJsZSBoZWFkZXJzIGFyZSB0eXBpY2FsbHkgYSBzdWJzZXQgb2YgdGhlCitvcmlnaW5hbCBoZWFkZXJzIHRoYXQgaGF2ZSBiZWVuIHJlZm9ybWF0dGVkIG9yIGFicmlkZ2VkIHRvIGJlIG1vcmUgYXR0cmFjdGl2ZS4KK0VhY2ggbWVzc2FnZSBpbiBhIEJhYnlsIG1haWxib3ggYWxzbyBoYXMgYW4gYWNjb21wYW55aW5nIGxpc3Qgb2YgXGRmbntsYWJlbHN9LAorb3Igc2hvcnQgc3RyaW5ncyB0aGF0IHJlY29yZCBleHRyYSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbWVzc2FnZSwgYW5kIGEgbGlzdCBvZgorYWxsIHVzZXItZGVmaW5lZCBsYWJlbHMgZm91bmQgaW4gdGhlIG1haWxib3ggaXMga2VwdCBpbiB0aGUgQmFieWwgb3B0aW9ucworc2VjdGlvbi4KKworXGNsYXNze0JhYnlsfSBpbnN0YW5jZXMgaGF2ZSBhbGwgb2YgdGhlIG1ldGhvZHMgb2YgXGNsYXNze01haWxib3h9IGluIGFkZGl0aW9uCit0byB0aGUgZm9sbG93aW5nOgorCitcYmVnaW57bWV0aG9kZGVzY317Z2V0X2xhYmVsc317fQorUmV0dXJuIGEgbGlzdCBvZiB0aGUgbmFtZXMgb2YgYWxsIHVzZXItZGVmaW5lZCBsYWJlbHMgdXNlZCBpbiB0aGUgbWFpbGJveC4KK1xub3Rle1RoZSBhY3R1YWwgbWVzc2FnZXMgYXJlIGluc3BlY3RlZCB0byBkZXRlcm1pbmUgd2hpY2ggbGFiZWxzIGV4aXN0IGluIHRoZQorbWFpbGJveCByYXRoZXIgdGhhbiBjb25zdWx0aW5nIHRoZSBsaXN0IG9mIGxhYmVscyBpbiB0aGUgQmFieWwgb3B0aW9ucyBzZWN0aW9uLAorYnV0IHRoZSBCYWJ5bCBzZWN0aW9uIGlzIHVwZGF0ZWQgd2hlbmV2ZXIgdGhlIG1haWxib3ggaXMgbW9kaWZpZWQufQorXGVuZHttZXRob2RkZXNjfQorCitTb21lIFxjbGFzc3tNYWlsYm94fSBtZXRob2RzIGltcGxlbWVudGVkIGJ5IFxjbGFzc3tCYWJ5bH0gZGVzZXJ2ZSBzcGVjaWFsCityZW1hcmtzOgorCitcYmVnaW57bWV0aG9kZGVzY317Z2V0X2ZpbGV9e2tleX0KK0luIEJhYnlsIG1haWxib3hlcywgdGhlIGhlYWRlcnMgb2YgYSBtZXNzYWdlIGFyZSBub3Qgc3RvcmVkIGNvbnRpZ3VvdXNseSB3aXRoCit0aGUgYm9keSBvZiB0aGUgbWVzc2FnZS4gVG8gZ2VuZXJhdGUgYSBmaWxlLWxpa2UgcmVwcmVzZW50YXRpb24sIHRoZSBoZWFkZXJzCithbmQgYm9keSBhcmUgY29waWVkIHRvZ2V0aGVyIGludG8gYSBcY2xhc3N7U3RyaW5nSU99IGluc3RhbmNlIChmcm9tIHRoZQorXG1vZHVsZXtTdHJpbmdJT30gbW9kdWxlKSwgd2hpY2ggaGFzIGFuIEFQSSBpZGVudGljYWwgdG8gdGhhdCBvZiBhIGZpbGUuIEFzIGEKK3Jlc3VsdCwgdGhlIGZpbGUtbGlrZSBvYmplY3QgaXMgdHJ1bHkgaW5kZXBlbmRlbnQgb2YgdGhlIHVuZGVybHlpbmcgbWFpbGJveCBidXQKK2RvZXMgbm90IHNhdmUgbWVtb3J5IGNvbXBhcmVkIHRvIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uLgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317bG9ja317fQorXG1ldGhvZGxpbmV7dW5sb2NrfXt9CitUaHJlZSBsb2NraW5nIG1lY2hhbmlzbXMgYXJlIHVzZWQtLS1kb3QgbG9ja2luZyBhbmQsIGlmIGF2YWlsYWJsZSwgdGhlCitcY2Z1bmN0aW9ue2Zsb2NrKCl9IGFuZCBcY2Z1bmN0aW9ue2xvY2tmKCl9IHN5c3RlbSBjYWxscy4KK1xlbmR7bWV0aG9kZGVzY30KKworXGJlZ2lue3NlZWFsc299Citcc2VlbGlua3todHRwOi8vcXVpbWJ5LmdudXMub3JnL25vdGVzL0JBQllMfXtGb3JtYXQgb2YgVmVyc2lvbiA1IEJhYnlsIEZpbGVzfXtBCitzcGVjaWZpY2F0aW9uIG9mIHRoZSBCYWJ5bCBmb3JtYXQufQorXHNlZWxpbmt7aHR0cDovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2VtYWNzL21hbnVhbC9odG1sX25vZGUvUm1haWwuaHRtbH17UmVhZGluZworTWFpbCB3aXRoIFJtYWlsfXtUaGUgUm1haWwgbWFudWFsLCB3aXRoIHNvbWUgaW5mb3JtYXRpb24gb24gQmFieWwgc2VtYW50aWNzLn0KK1xlbmR7c2VlYWxzb30KKworXHN1YnN1YnNlY3Rpb257XGNsYXNze01NREZ9fQorXGxhYmVse21haWxib3gtbW1kZn0KKworXGJlZ2lue2NsYXNzZGVzY317TU1ERn17cGF0aFxvcHRpb25hbHssIGZhY3Rvcnk9Tm9uZVxvcHRpb25hbHssIGNyZWF0ZT1UcnVlfX19CitBIHN1YmNsYXNzIG9mIFxjbGFzc3tNYWlsYm94fSBmb3IgbWFpbGJveGVzIGluIE1NREYgZm9ybWF0LiBQYXJhbWV0ZXIKK1x2YXJ7ZmFjdG9yeX0gaXMgYSBjYWxsYWJsZSBvYmplY3QgdGhhdCBhY2NlcHRzIGEgZmlsZS1saWtlIG1lc3NhZ2UKK3JlcHJlc2VudGF0aW9uICh3aGljaCBiZWhhdmVzIGFzIGlmIG9wZW4gaW4gYmluYXJ5IG1vZGUpIGFuZCByZXR1cm5zIGEgY3VzdG9tCityZXByZXNlbnRhdGlvbi4gSWYgXHZhcntmYWN0b3J5fSBpcyBcY29kZXtOb25lfSwgXGNsYXNze01NREZNZXNzYWdlfSBpcyB1c2VkIGFzCit0aGUgZGVmYXVsdCBtZXNzYWdlIHJlcHJlc2VudGF0aW9uLiBJZiBcdmFye2NyZWF0ZX0gaXMgXGNvZGV7VHJ1ZX0sIHRoZSBtYWlsYm94CitpcyBjcmVhdGVkIGlmIGl0IGRvZXMgbm90IGV4aXN0LgorXGVuZHtjbGFzc2Rlc2N9CisKK01NREYgaXMgYSBzaW5nbGUtZmlsZSBtYWlsYm94IGZvcm1hdCBpbnZlbnRlZCBmb3IgdGhlIE11bHRpY2hhbm5lbCBNZW1vcmFuZHVtCitEaXN0cmlidXRpb24gRmFjaWxpdHksIGEgbWFpbCB0cmFuc2ZlciBhZ2VudC4gRWFjaCBtZXNzYWdlIGlzIGluIHRoZSBzYW1lIGZvcm0KK2FzIGFuIG1ib3ggbWVzc2FnZSBidXQgaXMgYnJhY2tldGVkIGJlZm9yZSBhbmQgYWZ0ZXIgYnkgbGluZXMgY29udGFpbmluZyBmb3VyCitDb250cm9sLUEgKFxjaGFyYWN0ZXJ7XHRleHRiYWNrc2xhc2gwMDF9KSBjaGFyYWN0ZXJzLiBBcyB3aXRoIHRoZSBtYm94IGZvcm1hdCwKK3RoZSBiZWdpbm5pbmcgb2YgZWFjaCBtZXNzYWdlIGlzIGluZGljYXRlZCBieSBhIGxpbmUgd2hvc2UgZmlyc3QgZml2ZQorY2hhcmFjdGVycyBhcmUgIkZyb21+IiwgYnV0IGFkZGl0aW9uYWwgb2NjdXJyZW5jZXMgb2YgIkZyb21+IiBhcmUgbm90Cit0cmFuc2Zvcm1lZCB0byAiPkZyb21+IiB3aGVuIHN0b3JpbmcgbWVzc2FnZXMgYmVjYXVzZSB0aGUgZXh0cmEgbWVzc2FnZQorc2VwYXJhdG9yIGxpbmVzIHByZXZlbnQgbWlzdGFraW5nIHN1Y2ggb2NjdXJyZW5jZXMgZm9yIHRoZSBzdGFydHMgb2Ygc3Vic2VxdWVudAorbWVzc2FnZXMuCisKK1NvbWUgXGNsYXNze01haWxib3h9IG1ldGhvZHMgaW1wbGVtZW50ZWQgYnkgXGNsYXNze01NREZ9IGRlc2VydmUgc3BlY2lhbAorcmVtYXJrczoKKworXGJlZ2lue21ldGhvZGRlc2N9e2dldF9maWxlfXtrZXl9CitVc2luZyB0aGUgZmlsZSBhZnRlciBjYWxsaW5nIFxtZXRob2R7Zmx1c2goKX0gb3IgXG1ldGhvZHtjbG9zZSgpfSBvbiB0aGUKK1xjbGFzc3tNTURGfSBpbnN0YW5jZSBtYXkgeWllbGQgdW5wcmVkaWN0YWJsZSByZXN1bHRzIG9yIHJhaXNlIGFuIGV4Y2VwdGlvbi4KK1xlbmR7bWV0aG9kZGVzY30KKworXGJlZ2lue21ldGhvZGRlc2N9e2xvY2t9e30KK1xtZXRob2RsaW5le3VubG9ja317fQorVGhyZWUgbG9ja2luZyBtZWNoYW5pc21zIGFyZSB1c2VkLS0tZG90IGxvY2tpbmcgYW5kLCBpZiBhdmFpbGFibGUsIHRoZQorXGNmdW5jdGlvbntmbG9jaygpfSBhbmQgXGNmdW5jdGlvbntsb2NrZigpfSBzeXN0ZW0gY2FsbHMuCitcZW5ke21ldGhvZGRlc2N9CisKK1xiZWdpbntzZWVhbHNvfQorXHNlZWxpbmt7aHR0cDovL3d3dy50aW4ub3JnL2Jpbi9tYW4uY2dpP3NlY3Rpb249NVwmdG9waWM9bW1kZn17bW1kZiBtYW4gcGFnZQorZnJvbSB0aW59e0Egc3BlY2lmaWNhdGlvbiBvZiBNTURGIGZvcm1hdCBmcm9tIHRoZSBkb2N1bWVudGF0aW9uIG9mIHRpbiwgYQorbmV3c3JlYWRlci59Citcc2VlbGlua3todHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL01NREZ9e01NREZ9e0EgV2lraXBlZGlhIGFydGljbGUKK2Rlc2NyaWJpbmcgdGhlIE11bHRpY2hhbm5lbCBNZW1vcmFuZHVtIERpc3RyaWJ1dGlvbiBGYWNpbGl0eS59CitcZW5ke3NlZWFsc299CisKK1xzdWJzZWN0aW9ue1xjbGFzc3tNZXNzYWdlfSBvYmplY3RzfQorXGxhYmVse21haWxib3gtbWVzc2FnZS1vYmplY3RzfQorCitcYmVnaW57Y2xhc3NkZXNjfXtNZXNzYWdlfXtcb3B0aW9uYWx7bWVzc2FnZX19CitBIHN1YmNsYXNzIG9mIHRoZSBcbW9kdWxle2VtYWlsLk1lc3NhZ2V9IG1vZHVsZSdzIFxjbGFzc3tNZXNzYWdlfS4gU3ViY2xhc3Nlcworb2YgXGNsYXNze21haWxib3guTWVzc2FnZX0gYWRkIG1haWxib3gtZm9ybWF0LXNwZWNpZmljIHN0YXRlIGFuZCBiZWhhdmlvci4KKworSWYgXHZhcnttZXNzYWdlfSBpcyBvbWl0dGVkLCB0aGUgbmV3IGluc3RhbmNlIGlzIGNyZWF0ZWQgaW4gYSBkZWZhdWx0LCBlbXB0eQorc3RhdGUuIElmIFx2YXJ7bWVzc2FnZX0gaXMgYW4gXGNsYXNze2VtYWlsLk1lc3NhZ2UuTWVzc2FnZX0gaW5zdGFuY2UsIGl0cworY29udGVudHMgYXJlIGNvcGllZDsgZnVydGhlcm1vcmUsIGFueSBmb3JtYXQtc3BlY2lmaWMgaW5mb3JtYXRpb24gaXMgY29udmVydGVkCitpbnNvZmFyIGFzIHBvc3NpYmxlIGlmIFx2YXJ7bWVzc2FnZX0gaXMgYSBcY2xhc3N7TWVzc2FnZX0gaW5zdGFuY2UuIElmCitcdmFye21lc3NhZ2V9IGlzIGEgc3RyaW5nIG9yIGEgZmlsZSwgaXQgc2hvdWxkIGNvbnRhaW4gYW4gXHJmY3syODIyfS1jb21wbGlhbnQKK21lc3NhZ2UsIHdoaWNoIGlzIHJlYWQgYW5kIHBhcnNlZC4KK1xlbmR7Y2xhc3NkZXNjfQorCitUaGUgZm9ybWF0LXNwZWNpZmljIHN0YXRlIGFuZCBiZWhhdmlvcnMgb2ZmZXJlZCBieSBzdWJjbGFzc2VzIHZhcnksIGJ1dCBpbgorZ2VuZXJhbCBpdCBpcyBvbmx5IHRoZSBwcm9wZXJ0aWVzIHRoYXQgYXJlIG5vdCBzcGVjaWZpYyB0byBhIHBhcnRpY3VsYXIgbWFpbGJveAordGhhdCBhcmUgc3VwcG9ydGVkIChhbHRob3VnaCBwcmVzdW1hYmx5IHRoZSBwcm9wZXJ0aWVzIGFyZSBzcGVjaWZpYyB0byBhCitwYXJ0aWN1bGFyIG1haWxib3ggZm9ybWF0KS4gRm9yIGV4YW1wbGUsIGZpbGUgb2Zmc2V0cyBmb3Igc2luZ2xlLWZpbGUgbWFpbGJveAorZm9ybWF0cyBhbmQgZmlsZSBuYW1lcyBmb3IgZGlyZWN0b3J5LWJhc2VkIG1haWxib3ggZm9ybWF0cyBhcmUgbm90IHJldGFpbmVkLAorYmVjYXVzZSB0aGV5IGFyZSBvbmx5IGFwcGxpY2FibGUgdG8gdGhlIG9yaWdpbmFsIG1haWxib3guIEJ1dCBzdGF0ZSBzdWNoIGFzCit3aGV0aGVyIGEgbWVzc2FnZSBoYXMgYmVlbiByZWFkIGJ5IHRoZSB1c2VyIG9yIG1hcmtlZCBhcyBpbXBvcnRhbnQgaXMgcmV0YWluZWQsCitiZWNhdXNlIGl0IGFwcGxpZXMgdG8gdGhlIG1lc3NhZ2UgaXRzZWxmLgorCitUaGVyZSBpcyBubyByZXF1aXJlbWVudCB0aGF0IFxjbGFzc3tNZXNzYWdlfSBpbnN0YW5jZXMgYmUgdXNlZCB0byByZXByZXNlbnQKK21lc3NhZ2VzIHJldHJpZXZlZCB1c2luZyBcY2xhc3N7TWFpbGJveH0gaW5zdGFuY2VzLiBJbiBzb21lIHNpdHVhdGlvbnMsIHRoZQordGltZSBhbmQgbWVtb3J5IHJlcXVpcmVkIHRvIGdlbmVyYXRlIFxjbGFzc3tNZXNzYWdlfSByZXByZXNlbnRhdGlvbnMgbWlnaHQgbm90Citub3QgYWNjZXB0YWJsZS4gRm9yIHN1Y2ggc2l0dWF0aW9ucywgXGNsYXNze01haWxib3h9IGluc3RhbmNlcyBhbHNvIG9mZmVyCitzdHJpbmcgYW5kIGZpbGUtbGlrZSByZXByZXNlbnRhdGlvbnMsIGFuZCBhIGN1c3RvbSBtZXNzYWdlIGZhY3RvcnkgbWF5IGJlCitzcGVjaWZpZWQgd2hlbiBhIFxjbGFzc3tNYWlsYm94fSBpbnN0YW5jZSBpcyBpbml0aWFsaXplZC4gCisKK1xzdWJzdWJzZWN0aW9ue1xjbGFzc3tNYWlsZGlyTWVzc2FnZX19CitcbGFiZWx7bWFpbGJveC1tYWlsZGlybWVzc2FnZX0KKworXGJlZ2lue2NsYXNzZGVzY317TWFpbGRpck1lc3NhZ2V9e1xvcHRpb25hbHttZXNzYWdlfX0KK0EgbWVzc2FnZSB3aXRoIE1haWxkaXItc3BlY2lmaWMgYmVoYXZpb3JzLiBQYXJhbWV0ZXIgXHZhcnttZXNzYWdlfQoraGFzIHRoZSBzYW1lIG1lYW5pbmcgYXMgd2l0aCB0aGUgXGNsYXNze01lc3NhZ2V9IGNvbnN0cnVjdG9yLgorXGVuZHtjbGFzc2Rlc2N9CisKK1R5cGljYWxseSwgYSBtYWlsIHVzZXIgYWdlbnQgYXBwbGljYXRpb24gbW92ZXMgYWxsIG9mIHRoZSBtZXNzYWdlcyBpbiB0aGUKK1xmaWxle25ld30gc3ViZGlyZWN0b3J5IHRvIHRoZSBcZmlsZXtjdXJ9IHN1YmRpcmVjdG9yeSBhZnRlciB0aGUgZmlyc3QgdGltZSB0aGUKK3VzZXIgb3BlbnMgYW5kIGNsb3NlcyB0aGUgbWFpbGJveCwgcmVjb3JkaW5nIHRoYXQgdGhlIG1lc3NhZ2VzIGFyZSBvbGQgd2hldGhlcgorb3Igbm90IHRoZXkndmUgYWN0dWFsbHkgYmVlbiByZWFkLiBFYWNoIG1lc3NhZ2UgaW4gXGZpbGV7Y3VyfSBoYXMgYW4gImluZm8iCitzZWN0aW9uIGFkZGVkIHRvIGl0cyBmaWxlIG5hbWUgdG8gc3RvcmUgaW5mb3JtYXRpb24gYWJvdXQgaXRzIHN0YXRlLiAoU29tZSBtYWlsCityZWFkZXJzIG1heSBhbHNvIGFkZCBhbiAiaW5mbyIgc2VjdGlvbiB0byBtZXNzYWdlcyBpbiBcZmlsZXtuZXd9LikgVGhlICJpbmZvIgorc2VjdGlvbiBtYXkgdGFrZSBvbmUgb2YgdHdvIGZvcm1zOiBpdCBtYXkgY29udGFpbiAiMiwiIGZvbGxvd2VkIGJ5IGEgbGlzdCBvZgorc3RhbmRhcmRpemVkIGZsYWdzIChlLmcuLCAiMixGUiIpIG9yIGl0IG1heSBjb250YWluICIxLCIgZm9sbG93ZWQgYnkgc28tY2FsbGVkCitleHBlcmltZW50YWwgaW5mb3JtYXRpb24uIFN0YW5kYXJkIGZsYWdzIGZvciBNYWlsZGlyIG1lc3NhZ2VzIGFyZSBhcyBmb2xsb3dzOgorCitcYmVnaW57dGFibGVpaWl9e2x8bHxsfXt0ZXh0cm19e0ZsYWd9e01lYW5pbmd9e0V4cGxhbmF0aW9ufQorXGxpbmVpaWl7RH17RHJhZnR9e1VuZGVyIGNvbXBvc2l0aW9ufQorXGxpbmVpaWl7Rn17RmxhZ2dlZH17TWFya2VkIGFzIGltcG9ydGFudH0KK1xsaW5laWlpe1B9e1Bhc3NlZH17Rm9yd2FyZGVkLCByZXNlbnQsIG9yIGJvdW5jZWR9CitcbGluZWlpaXtSfXtSZXBsaWVkfXtSZXBsaWVkIHRvfQorXGxpbmVpaWl7U317U2Vlbn17UmVhZH0KK1xsaW5laWlpe1R9e1RyYXNoZWR9e01hcmtlZCBmb3Igc3Vic2VxdWVudCBkZWxldGlvbn0KK1xlbmR7dGFibGVpaWl9CisKK1xjbGFzc3tNYWlsZGlyTWVzc2FnZX0gaW5zdGFuY2VzIG9mZmVyIHRoZSBmb2xsb3dpbmcgbWV0aG9kczoKKworXGJlZ2lue21ldGhvZGRlc2N9e2dldF9zdWJkaXJ9e30KK1JldHVybiBlaXRoZXIgIm5ldyIgKGlmIHRoZSBtZXNzYWdlIHNob3VsZCBiZSBzdG9yZWQgaW4gdGhlIFxmaWxle25ld30KK3N1YmRpcmVjdG9yeSkgb3IgImN1ciIgKGlmIHRoZSBtZXNzYWdlIHNob3VsZCBiZSBzdG9yZWQgaW4gdGhlIFxmaWxle2N1cn0KK3N1YmRpcmVjdG9yeSkuIFxub3Rle0EgbWVzc2FnZSBpcyB0eXBpY2FsbHkgbW92ZWQgZnJvbSBcZmlsZXtuZXd9IHRvIFxmaWxle2N1cn0KK2FmdGVyIGl0cyBtYWlsYm94IGhhcyBiZWVuIGFjY2Vzc2VkLCB3aGV0aGVyIG9yIG5vdCB0aGUgbWVzc2FnZSBpcyBoYXMgYmVlbgorcmVhZC4gQSBtZXNzYWdlIFxjb2Rle21zZ30gaGFzIGJlZW4gcmVhZCBpZiBcY29kZXsiUyIgbm90IGluIG1zZy5nZXRfZmxhZ3MoKX0KK2lzIFxjb2Rle1RydWV9Ln0KK1xlbmR7bWV0aG9kZGVzY30KKworXGJlZ2lue21ldGhvZGRlc2N9e3NldF9zdWJkaXJ9e3N1YmRpcn0KK1NldCB0aGUgc3ViZGlyZWN0b3J5IHRoZSBtZXNzYWdlIHNob3VsZCBiZSBzdG9yZWQgaW4uIFBhcmFtZXRlciBcdmFye3N1YmRpcn0KK211c3QgYmUgZWl0aGVyICJuZXciIG9yICJjdXIiLgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317Z2V0X2ZsYWdzfXt9CitSZXR1cm4gYSBzdHJpbmcgc3BlY2lmeWluZyB0aGUgZmxhZ3MgdGhhdCBhcmUgY3VycmVudGx5IHNldC4gSWYgdGhlIG1lc3NhZ2UKK2NvbXBsaWVzIHdpdGggdGhlIHN0YW5kYXJkIE1haWxkaXIgZm9ybWF0LCB0aGUgcmVzdWx0IGlzIHRoZSBjb25jYXRlbmF0aW9uIGluCithbHBoYWJldGljYWwgb3JkZXIgb2YgemVybyBvciBvbmUgb2NjdXJyZW5jZSBvZiBlYWNoIG9mIFxjaGFyYWN0ZXJ7RH0sCitcY2hhcmFjdGVye0Z9LCBcY2hhcmFjdGVye1B9LCBcY2hhcmFjdGVye1J9LCBcY2hhcmFjdGVye1N9LCBhbmQgXGNoYXJhY3RlcntUfS4KK1RoZSBlbXB0eSBzdHJpbmcgaXMgcmV0dXJuZWQgaWYgbm8gZmxhZ3MgYXJlIHNldCBvciBpZiAiaW5mbyIgY29udGFpbnMKK2V4cGVyaW1lbnRhbCBzZW1hbnRpY3MuCitcZW5ke21ldGhvZGRlc2N9CisKK1xiZWdpbnttZXRob2RkZXNjfXtzZXRfZmxhZ3N9e2ZsYWdzfQorU2V0IHRoZSBmbGFncyBzcGVjaWZpZWQgYnkgXHZhcntmbGFnc30gYW5kIHVuc2V0IGFsbCBvdGhlcnMuCitcZW5ke21ldGhvZGRlc2N9CisKK1xiZWdpbnttZXRob2RkZXNjfXthZGRfZmxhZ317ZmxhZ30KK1NldCB0aGUgZmxhZyhzKSBzcGVjaWZpZWQgYnkgXHZhcntmbGFnfSB3aXRob3V0IGNoYW5naW5nIG90aGVyIGZsYWdzLiBUbyBhZGQKK21vcmUgdGhhbiBvbmUgZmxhZyBhdCBhIHRpbWUsIFx2YXJ7ZmxhZ30gbWF5IGJlIGEgc3RyaW5nIG9mIG1vcmUgdGhhbiBvbmUKK2NoYXJhY3Rlci4gVGhlIGN1cnJlbnQgImluZm8iIGlzIG92ZXJ3cml0dGVuIHdoZXRoZXIgb3Igbm90IGl0IGNvbnRhaW5zCitleHBlcmltZW50YWwgaW5mb3JtYXRpb24gcmF0aGVyIHRoYW4KK2ZsYWdzLgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317cmVtb3ZlX2ZsYWd9e2ZsYWd9CitVbnNldCB0aGUgZmxhZyhzKSBzcGVjaWZpZWQgYnkgXHZhcntmbGFnfSB3aXRob3V0IGNoYW5naW5nIG90aGVyIGZsYWdzLiBUbworcmVtb3ZlIG1vcmUgdGhhbiBvbmUgZmxhZyBhdCBhIHRpbWUsIFx2YXJ7ZmxhZ30gbWF5YmUgYSBzdHJpbmcgb2YgbW9yZSB0aGFuIG9uZQorY2hhcmFjdGVyLiBJZiAiaW5mbyIgY29udGFpbnMgZXhwZXJpbWVudGFsIGluZm9ybWF0aW9uIHJhdGhlciB0aGFuIGZsYWdzLCB0aGUKK2N1cnJlbnQgImluZm8iIGlzIG5vdCBtb2RpZmllZC4KK1xlbmR7bWV0aG9kZGVzY30KKworXGJlZ2lue21ldGhvZGRlc2N9e2dldF9kYXRlfXt9CitSZXR1cm4gdGhlIGRlbGl2ZXJ5IGRhdGUgb2YgdGhlIG1lc3NhZ2UgYXMgYSBmbG9hdGluZy1wb2ludCBudW1iZXIgcmVwcmVzZW50aW5nCitzZWNvbmRzIHNpbmNlIHRoZSBlcG9jaC4KK1xlbmR7bWV0aG9kZGVzY30KKworXGJlZ2lue21ldGhvZGRlc2N9e3NldF9kYXRlfXtkYXRlfQorU2V0IHRoZSBkZWxpdmVyeSBkYXRlIG9mIHRoZSBtZXNzYWdlIHRvIFx2YXJ7ZGF0ZX0sIGEgZmxvYXRpbmctcG9pbnQgbnVtYmVyCityZXByZXNlbnRpbmcgc2Vjb25kcyBzaW5jZSB0aGUgZXBvY2guCitcZW5ke21ldGhvZGRlc2N9CisKK1xiZWdpbnttZXRob2RkZXNjfXtnZXRfaW5mb317fQorUmV0dXJuIGEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlICJpbmZvIiBmb3IgYSBtZXNzYWdlLiBUaGlzIGlzIHVzZWZ1bCBmb3IKK2FjY2Vzc2luZyBhbmQgbW9kaWZ5aW5nICJpbmZvIiB0aGF0IGlzIGV4cGVyaW1lbnRhbCAoaS5lLiwgbm90IGEgbGlzdCBvZgorZmxhZ3MpLgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317c2V0X2luZm99e2luZm99CitTZXQgImluZm8iIHRvIFx2YXJ7aW5mb30sIHdoaWNoIHNob3VsZCBiZSBhIHN0cmluZy4KK1xlbmR7bWV0aG9kZGVzY30KKworV2hlbiBhIFxjbGFzc3tNYWlsZGlyTWVzc2FnZX0gaW5zdGFuY2UgaXMgY3JlYXRlZCBiYXNlZCB1cG9uIGFuCitcY2xhc3N7bWJveE1lc3NhZ2V9IG9yIFxjbGFzc3tNTURGTWVzc2FnZX0gaW5zdGFuY2UsIHRoZSBcbWFpbGhlYWRlcntTdGF0dXN9CithbmQgXG1haWxoZWFkZXJ7WC1TdGF0dXN9IGhlYWRlcnMgYXJlIG9taXR0ZWQgYW5kIHRoZSBmb2xsb3dpbmcgY29udmVyc2lvbnMKK3Rha2UgcGxhY2U6CisKK1xiZWdpbnt0YWJsZWlpfXtsfGx9e3RleHRybX0KKyAgICB7UmVzdWx0aW5nIHN0YXRlfXtcY2xhc3N7bWJveE1lc3NhZ2V9IG9yIFxjbGFzc3tNTURGTWVzc2FnZX0gc3RhdGV9CitcbGluZWlpeyJjdXIiIHN1YmRpcmVjdG9yeX17TyBmbGFnfQorXGxpbmVpaXtGIGZsYWd9e0YgZmxhZ30KK1xsaW5laWl7UiBmbGFnfXtBIGZsYWd9CitcbGluZWlpe1MgZmxhZ317UiBmbGFnfQorXGxpbmVpaXtUIGZsYWd9e0QgZmxhZ30KK1xlbmR7dGFibGVpaX0KKworV2hlbiBhIFxjbGFzc3tNYWlsZGlyTWVzc2FnZX0gaW5zdGFuY2UgaXMgY3JlYXRlZCBiYXNlZCB1cG9uIGFuCitcY2xhc3N7TUhNZXNzYWdlfSBpbnN0YW5jZSwgdGhlIGZvbGxvd2luZyBjb252ZXJzaW9ucyB0YWtlIHBsYWNlOgorCitcYmVnaW57dGFibGVpaX17bHxsfXt0ZXh0cm19CisgICAge1Jlc3VsdGluZyBzdGF0ZX17XGNsYXNze01ITWVzc2FnZX0gc3RhdGV9CitcbGluZWlpeyJjdXIiIHN1YmRpcmVjdG9yeX17InVuc2VlbiIgc2VxdWVuY2V9CitcbGluZWlpeyJjdXIiIHN1YmRpcmVjdG9yeSBhbmQgUyBmbGFnfXtubyAidW5zZWVuIiBzZXF1ZW5jZX0KK1xsaW5laWl7RiBmbGFnfXsiZmxhZ2dlZCIgc2VxdWVuY2V9CitcbGluZWlpe1IgZmxhZ317InJlcGxpZWQiIHNlcXVlbmNlfQorXGVuZHt0YWJsZWlpfQorCitXaGVuIGEgXGNsYXNze01haWxkaXJNZXNzYWdlfSBpbnN0YW5jZSBpcyBjcmVhdGVkIGJhc2VkIHVwb24gYQorXGNsYXNze0JhYnlsTWVzc2FnZX0gaW5zdGFuY2UsIHRoZSBmb2xsb3dpbmcgY29udmVyc2lvbnMgdGFrZSBwbGFjZToKKworXGJlZ2lue3RhYmxlaWl9e2x8bH17dGV4dHJtfQorICAgIHtSZXN1bHRpbmcgc3RhdGV9e1xjbGFzc3tCYWJ5bE1lc3NhZ2V9IHN0YXRlfQorXGxpbmVpaXsiY3VyIiBzdWJkaXJlY3Rvcnl9eyJ1bnNlZW4iIGxhYmVsfQorXGxpbmVpaXsiY3VyIiBzdWJkaXJlY3RvcnkgYW5kIFMgZmxhZ317bm8gInVuc2VlbiIgbGFiZWx9CitcbGluZWlpe1AgZmxhZ317ImZvcndhcmRlZCIgb3IgInJlc2VudCIgbGFiZWx9CitcbGluZWlpe1IgZmxhZ317ImFuc3dlcmVkIiBsYWJlbH0KK1xsaW5laWl7VCBmbGFnfXsiZGVsZXRlZCIgbGFiZWx9CitcZW5ke3RhYmxlaWl9CisKK1xzdWJzdWJzZWN0aW9ue1xjbGFzc3ttYm94TWVzc2FnZX19CitcbGFiZWx7bWFpbGJveC1tYm94bWVzc2FnZX0KKworXGJlZ2lue2NsYXNzZGVzY317bWJveE1lc3NhZ2V9e1xvcHRpb25hbHttZXNzYWdlfX0KK0EgbWVzc2FnZSB3aXRoIG1ib3gtc3BlY2lmaWMgYmVoYXZpb3JzLiBQYXJhbWV0ZXIgXHZhcnttZXNzYWdlfSBoYXMgdGhlIHNhbWUKK21lYW5pbmcgYXMgd2l0aCB0aGUgXGNsYXNze01lc3NhZ2V9IGNvbnN0cnVjdG9yLgorXGVuZHtjbGFzc2Rlc2N9CisKK01lc3NhZ2VzIGluIGFuIG1ib3ggbWFpbGJveCBhcmUgc3RvcmVkIHRvZ2V0aGVyIGluIGEgc2luZ2xlIGZpbGUuIFRoZSBzZW5kZXIncworZW52ZWxvcGUgYWRkcmVzcyBhbmQgdGhlIHRpbWUgb2YgZGVsaXZlcnkgYXJlIHR5cGljYWxseSBzdG9yZWQgaW4gYSBsaW5lCitiZWdpbm5pbmcgd2l0aCAiRnJvbX4iIHRoYXQgaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgc3RhcnQgb2YgYSBtZXNzYWdlLCB0aG91Z2gKK3RoZXJlIGlzIGNvbnNpZGVyYWJsZSB2YXJpYXRpb24gaW4gdGhlIGV4YWN0IGZvcm1hdCBvZiB0aGlzIGRhdGEgYW1vbmcgbWJveAoraW1wbGVtZW50YXRpb25zLiBGbGFncyB0aGF0IGluZGljYXRlIHRoZSBzdGF0ZSBvZiB0aGUgbWVzc2FnZSwgc3VjaCBhcyB3aGV0aGVyCitpdCBoYXMgYmVlbiByZWFkIG9yIG1hcmtlZCBhcyBpbXBvcnRhbnQsIGFyZSB0eXBpY2FsbHkgc3RvcmVkIGluCitcbWFpbGhlYWRlcntTdGF0dXN9IGFuZCBcbWFpbGhlYWRlcntYLVN0YXR1c30gaGVhZGVycy4KKworQ29udmVudGlvbmFsIGZsYWdzIGZvciBtYm94IG1lc3NhZ2VzIGFyZSBhcyBmb2xsb3dzOgorCitcYmVnaW57dGFibGVpaWl9e2x8bHxsfXt0ZXh0cm19e0ZsYWd9e01lYW5pbmd9e0V4cGxhbmF0aW9ufQorXGxpbmVpaWl7Un17UmVhZH17UmVhZH0KK1xsaW5laWlpe099e09sZH17UHJldmlvdXNseSBkZXRlY3RlZCBieSBNVUF9CitcbGluZWlpaXtEfXtEZWxldGVkfXtNYXJrZWQgZm9yIHN1YnNlcXVlbnQgZGVsZXRpb259CitcbGluZWlpaXtGfXtGbGFnZ2VkfXtNYXJrZWQgYXMgaW1wb3J0YW50fQorXGxpbmVpaWl7QX17QW5zd2VyZWR9e1JlcGxpZWQgdG99CitcZW5ke3RhYmxlaWlpfQorCitUaGUgIlIiIGFuZCAiTyIgZmxhZ3MgYXJlIHN0b3JlZCBpbiB0aGUgXG1haWxoZWFkZXJ7U3RhdHVzfSBoZWFkZXIsIGFuZCB0aGUKKyJEIiwgIkYiLCBhbmQgIkEiIGZsYWdzIGFyZSBzdG9yZWQgaW4gdGhlIFxtYWlsaGVhZGVye1gtU3RhdHVzfSBoZWFkZXIuIFRoZQorZmxhZ3MgYW5kIGhlYWRlcnMgdHlwaWNhbGx5IGFwcGVhciBpbiB0aGUgb3JkZXIgbWVudGlvbmVkLgorCitcY2xhc3N7bWJveE1lc3NhZ2V9IGluc3RhbmNlcyBvZmZlciB0aGUgZm9sbG93aW5nIG1ldGhvZHM6CisKK1xiZWdpbnttZXRob2RkZXNjfXtnZXRfZnJvbX17fQorUmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgIkZyb21+IiBsaW5lIHRoYXQgbWFya3MgdGhlIHN0YXJ0IG9mIHRoZQorbWVzc2FnZSBpbiBhbiBtYm94IG1haWxib3guIFRoZSBsZWFkaW5nICJGcm9tfiIgYW5kIHRoZSB0cmFpbGluZyBuZXdsaW5lIGFyZQorZXhjbHVkZWQuCitcZW5ke21ldGhvZGRlc2N9CisKK1xiZWdpbnttZXRob2RkZXNjfXtzZXRfZnJvbX17ZnJvbV9cb3B0aW9uYWx7LCB0aW1lXz1Ob25lfX0KK1NldCB0aGUgIkZyb21+IiBsaW5lIHRvIFx2YXJ7ZnJvbV99LCB3aGljaCBzaG91bGQgYmUgc3BlY2lmaWVkIHdpdGhvdXQgYQorbGVhZGluZyAiRnJvbX4iIG9yIHRyYWlsaW5nIG5ld2xpbmUuIEZvciBjb252ZW5pZW5jZSwgXHZhcnt0aW1lX30gbWF5IGJlCitzcGVjaWZpZWQgYW5kIHdpbGwgYmUgZm9ybWF0dGVkIGFwcHJvcHJpYXRlbHkgYW5kIGFwcGVuZGVkIHRvIFx2YXJ7ZnJvbV99LiBJZgorXHZhcnt0aW1lX30gaXMgc3BlY2lmaWVkLCBpdCBzaG91bGQgYmUgYSBcY2xhc3N7c3RydWN0X3RpbWV9IGluc3RhbmNlLCBhIHR1cGxlCitzdWl0YWJsZSBmb3IgcGFzc2luZyB0byBcbWV0aG9ke3RpbWUuc3RyZnRpbWUoKX0sIG9yIFxjb2Rle1RydWV9ICh0byB1c2UKK1xtZXRob2R7dGltZS5nbXRpbWUoKX0pLgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317Z2V0X2ZsYWdzfXt9CitSZXR1cm4gYSBzdHJpbmcgc3BlY2lmeWluZyB0aGUgZmxhZ3MgdGhhdCBhcmUgY3VycmVudGx5IHNldC4gSWYgdGhlIG1lc3NhZ2UKK2NvbXBsaWVzIHdpdGggdGhlIGNvbnZlbnRpb25hbCBmb3JtYXQsIHRoZSByZXN1bHQgaXMgdGhlIGNvbmNhdGVuYXRpb24gaW4gdGhlCitmb2xsb3dpbmcgb3JkZXIgb2YgemVybyBvciBvbmUgb2NjdXJyZW5jZSBvZiBlYWNoIG9mIFxjaGFyYWN0ZXJ7Un0sCitcY2hhcmFjdGVye099LCBcY2hhcmFjdGVye0R9LCBcY2hhcmFjdGVye0Z9LCBhbmQgXGNoYXJhY3RlcntBfS4KK1xlbmR7bWV0aG9kZGVzY30KKworXGJlZ2lue21ldGhvZGRlc2N9e3NldF9mbGFnc317ZmxhZ3N9CitTZXQgdGhlIGZsYWdzIHNwZWNpZmllZCBieSBcdmFye2ZsYWdzfSBhbmQgdW5zZXQgYWxsIG90aGVycy4gUGFyYW1ldGVyCitcdmFye2ZsYWdzfSBzaG91bGQgYmUgdGhlIGNvbmNhdGVuYXRpb24gaW4gYW55IG9yZGVyIG9mIHplcm8gb3IgbW9yZQorb2NjdXJyZW5jZXMgb2YgZWFjaCBvZiBcY2hhcmFjdGVye1J9LCBcY2hhcmFjdGVye099LCBcY2hhcmFjdGVye0R9LAorXGNoYXJhY3RlcntGfSwgYW5kIFxjaGFyYWN0ZXJ7QX0uCitcZW5ke21ldGhvZGRlc2N9CisKK1xiZWdpbnttZXRob2RkZXNjfXthZGRfZmxhZ317ZmxhZ30KK1NldCB0aGUgZmxhZyhzKSBzcGVjaWZpZWQgYnkgXHZhcntmbGFnfSB3aXRob3V0IGNoYW5naW5nIG90aGVyIGZsYWdzLiBUbyBhZGQKK21vcmUgdGhhbiBvbmUgZmxhZyBhdCBhIHRpbWUsIFx2YXJ7ZmxhZ30gbWF5IGJlIGEgc3RyaW5nIG9mIG1vcmUgdGhhbiBvbmUKK2NoYXJhY3Rlci4KK1xlbmR7bWV0aG9kZGVzY30KKworXGJlZ2lue21ldGhvZGRlc2N9e3JlbW92ZV9mbGFnfXtmbGFnfQorVW5zZXQgdGhlIGZsYWcocykgc3BlY2lmaWVkIGJ5IFx2YXJ7ZmxhZ30gd2l0aG91dCBjaGFuZ2luZyBvdGhlciBmbGFncy4gVG8KK3JlbW92ZSBtb3JlIHRoYW4gb25lIGZsYWcgYXQgYSB0aW1lLCBcdmFye2ZsYWd9IG1heWJlIGEgc3RyaW5nIG9mIG1vcmUgdGhhbiBvbmUKK2NoYXJhY3Rlci4KK1xlbmR7bWV0aG9kZGVzY30KKworV2hlbiBhbiBcY2xhc3N7bWJveE1lc3NhZ2V9IGluc3RhbmNlIGlzIGNyZWF0ZWQgYmFzZWQgdXBvbiBhCitcY2xhc3N7TWFpbGRpck1lc3NhZ2V9IGluc3RhbmNlLCBhICJGcm9tfiIgbGluZSBpcyBnZW5lcmF0ZWQgYmFzZWQgdXBvbiB0aGUKK1xjbGFzc3tNYWlsZGlyTWVzc2FnZX0gaW5zdGFuY2UncyBkZWxpdmVyeSBkYXRlLCBhbmQgdGhlIGZvbGxvd2luZyBjb252ZXJzaW9ucwordGFrZSBwbGFjZToKKworXGJlZ2lue3RhYmxlaWl9e2x8bH17dGV4dHJtfQorICAgIHtSZXN1bHRpbmcgc3RhdGV9e1xjbGFzc3tNYWlsZGlyTWVzc2FnZX0gc3RhdGV9CitcbGluZWlpe1IgZmxhZ317UyBmbGFnfQorXGxpbmVpaXtPIGZsYWd9eyJjdXIiIHN1YmRpcmVjdG9yeX0KK1xsaW5laWl7RCBmbGFnfXtUIGZsYWd9CitcbGluZWlpe0YgZmxhZ317RiBmbGFnfQorXGxpbmVpaXtBIGZsYWd9e1IgZmxhZ30KK1xlbmR7dGFibGVpaX0KKworV2hlbiBhbiBcY2xhc3N7bWJveE1lc3NhZ2V9IGluc3RhbmNlIGlzIGNyZWF0ZWQgYmFzZWQgdXBvbiBhbiBcY2xhc3N7TUhNZXNzYWdlfQoraW5zdGFuY2UsIHRoZSBmb2xsb3dpbmcgY29udmVyc2lvbnMgdGFrZSBwbGFjZToKKworXGJlZ2lue3RhYmxlaWl9e2x8bH17dGV4dHJtfQorICAgIHtSZXN1bHRpbmcgc3RhdGV9e1xjbGFzc3tNSE1lc3NhZ2V9IHN0YXRlfQorXGxpbmVpaXtSIGZsYWcgYW5kIE8gZmxhZ317bm8gInVuc2VlbiIgc2VxdWVuY2V9CitcbGluZWlpe08gZmxhZ317InVuc2VlbiIgc2VxdWVuY2V9CitcbGluZWlpe0YgZmxhZ317ImZsYWdnZWQiIHNlcXVlbmNlfQorXGxpbmVpaXtBIGZsYWd9eyJyZXBsaWVkIiBzZXF1ZW5jZX0KK1xlbmR7dGFibGVpaX0KKworV2hlbiBhbiBcY2xhc3N7bWJveE1lc3NhZ2V9IGluc3RhbmNlIGlzIGNyZWF0ZWQgYmFzZWQgdXBvbiBhCitcY2xhc3N7QmFieWxNZXNzYWdlfSBpbnN0YW5jZSwgdGhlIGZvbGxvd2luZyBjb252ZXJzaW9ucyB0YWtlIHBsYWNlOgorCitcYmVnaW57dGFibGVpaX17bHxsfXt0ZXh0cm19CisgICAge1Jlc3VsdGluZyBzdGF0ZX17XGNsYXNze0JhYnlsTWVzc2FnZX0gc3RhdGV9CitcbGluZWlpe1IgZmxhZyBhbmQgTyBmbGFnfXtubyAidW5zZWVuIiBsYWJlbH0KK1xsaW5laWl7TyBmbGFnfXsidW5zZWVuIiBsYWJlbH0KK1xsaW5laWl7RCBmbGFnfXsiZGVsZXRlZCIgbGFiZWx9CitcbGluZWlpe0EgZmxhZ317ImFuc3dlcmVkIiBsYWJlbH0KK1xlbmR7dGFibGVpaX0KKworV2hlbiBhIFxjbGFzc3tNZXNzYWdlfSBpbnN0YW5jZSBpcyBjcmVhdGVkIGJhc2VkIHVwb24gYW4gXGNsYXNze01NREZNZXNzYWdlfQoraW5zdGFuY2UsIHRoZSAiRnJvbX4iIGxpbmUgaXMgY29waWVkIGFuZCBhbGwgZmxhZ3MgZGlyZWN0bHkgY29ycmVzcG9uZDoKKworXGJlZ2lue3RhYmxlaWl9e2x8bH17dGV4dHJtfQorICAgIHtSZXN1bHRpbmcgc3RhdGV9e1xjbGFzc3tNTURGTWVzc2FnZX0gc3RhdGV9CitcbGluZWlpe1IgZmxhZ317UiBmbGFnfQorXGxpbmVpaXtPIGZsYWd9e08gZmxhZ30KK1xsaW5laWl7RCBmbGFnfXtEIGZsYWd9CitcbGluZWlpe0YgZmxhZ317RiBmbGFnfQorXGxpbmVpaXtBIGZsYWd9e0EgZmxhZ30KK1xlbmR7dGFibGVpaX0KKworXHN1YnN1YnNlY3Rpb257XGNsYXNze01ITWVzc2FnZX19CitcbGFiZWx7bWFpbGJveC1taG1lc3NhZ2V9CisKK1xiZWdpbntjbGFzc2Rlc2N9e01ITWVzc2FnZX17XG9wdGlvbmFse21lc3NhZ2V9fQorQSBtZXNzYWdlIHdpdGggTUgtc3BlY2lmaWMgYmVoYXZpb3JzLiBQYXJhbWV0ZXIgXHZhcnttZXNzYWdlfSBoYXMgdGhlIHNhbWUKK21lYW5pbmcgYXMgd2l0aCB0aGUgXGNsYXNze01lc3NhZ2V9IGNvbnN0cnVjdG9yLgorXGVuZHtjbGFzc2Rlc2N9CisKK01IIG1lc3NhZ2VzIGRvIG5vdCBzdXBwb3J0IG1hcmtzIG9yIGZsYWdzIGluIHRoZSB0cmFkaXRpb25hbCBzZW5zZSwgYnV0IHRoZXkgZG8KK3N1cHBvcnQgc2VxdWVuY2VzLCB3aGljaCBhcmUgbG9naWNhbCBncm91cGluZ3Mgb2YgYXJiaXRyYXJ5IG1lc3NhZ2VzLiBTb21lIG1haWwKK3JlYWRpbmcgcHJvZ3JhbXMgKGFsdGhvdWdoIG5vdCB0aGUgc3RhbmRhcmQgXHByb2dyYW17bWh9IGFuZCBccHJvZ3JhbXtubWh9KSB1c2UKK3NlcXVlbmNlcyBpbiBtdWNoIHRoZSBzYW1lIHdheSBmbGFncyBhcmUgdXNlZCB3aXRoIG90aGVyIGZvcm1hdHMsIGFzIGZvbGxvd3M6CisKK1xiZWdpbnt0YWJsZWlpfXtsfGx9e3RleHRybX17U2VxdWVuY2V9e0V4cGxhbmF0aW9ufQorXGxpbmVpaXt1bnNlZW59e05vdCByZWFkLCBidXQgcHJldmlvdXNseSBkZXRlY3RlZCBieSBNVUF9CitcbGluZWlpe3JlcGxpZWR9e1JlcGxpZWQgdG99CitcbGluZWlpe2ZsYWdnZWR9e01hcmtlZCBhcyBpbXBvcnRhbnR9CitcZW5ke3RhYmxlaWl9CisKK1xjbGFzc3tNSE1lc3NhZ2V9IGluc3RhbmNlcyBvZmZlciB0aGUgZm9sbG93aW5nIG1ldGhvZHM6CisKK1xiZWdpbnttZXRob2RkZXNjfXtnZXRfc2VxdWVuY2VzfXt9CitSZXR1cm4gYSBsaXN0IG9mIHRoZSBuYW1lcyBvZiBzZXF1ZW5jZXMgdGhhdCBpbmNsdWRlIHRoaXMgbWVzc2FnZS4KK1xlbmR7bWV0aG9kZGVzY30KKworXGJlZ2lue21ldGhvZGRlc2N9e3NldF9zZXF1ZW5jZXN9e3NlcXVlbmNlc30KK1NldCB0aGUgbGlzdCBvZiBzZXF1ZW5jZXMgdGhhdCBpbmNsdWRlIHRoaXMgbWVzc2FnZS4KK1xlbmR7bWV0aG9kZGVzY30KKworXGJlZ2lue21ldGhvZGRlc2N9e2FkZF9zZXF1ZW5jZX17c2VxdWVuY2V9CitBZGQgXHZhcntzZXF1ZW5jZX0gdG8gdGhlIGxpc3Qgb2Ygc2VxdWVuY2VzIHRoYXQgaW5jbHVkZSB0aGlzIG1lc3NhZ2UuCitcZW5ke21ldGhvZGRlc2N9CisKK1xiZWdpbnttZXRob2RkZXNjfXtyZW1vdmVfc2VxdWVuY2V9e3NlcXVlbmNlfQorUmVtb3ZlIFx2YXJ7c2VxdWVuY2V9IGZyb20gdGhlIGxpc3Qgb2Ygc2VxdWVuY2VzIHRoYXQgaW5jbHVkZSB0aGlzIG1lc3NhZ2UuCitcZW5ke21ldGhvZGRlc2N9CisKK1doZW4gYW4gXGNsYXNze01ITWVzc2FnZX0gaW5zdGFuY2UgaXMgY3JlYXRlZCBiYXNlZCB1cG9uIGEKK1xjbGFzc3tNYWlsZGlyTWVzc2FnZX0gaW5zdGFuY2UsIHRoZSBmb2xsb3dpbmcgY29udmVyc2lvbnMgdGFrZSBwbGFjZToKKworXGJlZ2lue3RhYmxlaWl9e2x8bH17dGV4dHJtfQorICAgIHtSZXN1bHRpbmcgc3RhdGV9e1xjbGFzc3tNYWlsZGlyTWVzc2FnZX0gc3RhdGV9CitcbGluZWlpeyJ1bnNlZW4iIHNlcXVlbmNlfXtubyBTIGZsYWd9CitcbGluZWlpeyJyZXBsaWVkIiBzZXF1ZW5jZX17UiBmbGFnfQorXGxpbmVpaXsiZmxhZ2dlZCIgc2VxdWVuY2V9e0YgZmxhZ30KK1xlbmR7dGFibGVpaX0KKworV2hlbiBhbiBcY2xhc3N7TUhNZXNzYWdlfSBpbnN0YW5jZSBpcyBjcmVhdGVkIGJhc2VkIHVwb24gYW4gXGNsYXNze21ib3hNZXNzYWdlfQorb3IgXGNsYXNze01NREZNZXNzYWdlfSBpbnN0YW5jZSwgdGhlIFxtYWlsaGVhZGVye1N0YXR1c30gYW5kCitcbWFpbGhlYWRlcntYLVN0YXR1c30gaGVhZGVycyBhcmUgb21pdHRlZCBhbmQgdGhlIGZvbGxvd2luZyBjb252ZXJzaW9ucyB0YWtlCitwbGFjZToKKworXGJlZ2lue3RhYmxlaWl9e2x8bH17dGV4dHJtfQorICAgIHtSZXN1bHRpbmcgc3RhdGV9e1xjbGFzc3ttYm94TWVzc2FnZX0gb3IgXGNsYXNze01NREZNZXNzYWdlfSBzdGF0ZX0KK1xsaW5laWl7InVuc2VlbiIgc2VxdWVuY2V9e25vIFIgZmxhZ30KK1xsaW5laWl7InJlcGxpZWQiIHNlcXVlbmNlfXtBIGZsYWd9CitcbGluZWlpeyJmbGFnZ2VkIiBzZXF1ZW5jZX17RiBmbGFnfQorXGVuZHt0YWJsZWlpfQorCitXaGVuIGFuIFxjbGFzc3tNSE1lc3NhZ2V9IGluc3RhbmNlIGlzIGNyZWF0ZWQgYmFzZWQgdXBvbiBhIFxjbGFzc3tCYWJ5bE1lc3NhZ2V9CitpbnN0YW5jZSwgdGhlIGZvbGxvd2luZyBjb252ZXJzaW9ucyB0YWtlIHBsYWNlOgorCitcYmVnaW57dGFibGVpaX17bHxsfXt0ZXh0cm19CisgICAge1Jlc3VsdGluZyBzdGF0ZX17XGNsYXNze0JhYnlsTWVzc2FnZX0gc3RhdGV9CitcbGluZWlpeyJ1bnNlZW4iIHNlcXVlbmNlfXsidW5zZWVuIiBsYWJlbH0KK1xsaW5laWl7InJlcGxpZWQiIHNlcXVlbmNlfXsiYW5zd2VyZWQiIGxhYmVsfQorXGVuZHt0YWJsZWlpfQorCitcc3Vic3Vic2VjdGlvbntcY2xhc3N7QmFieWxNZXNzYWdlfX0KK1xsYWJlbHttYWlsYm94LWJhYnlsbWVzc2FnZX0KKworXGJlZ2lue2NsYXNzZGVzY317QmFieWxNZXNzYWdlfXtcb3B0aW9uYWx7bWVzc2FnZX19CitBIG1lc3NhZ2Ugd2l0aCBCYWJ5bC1zcGVjaWZpYyBiZWhhdmlvcnMuIFBhcmFtZXRlciBcdmFye21lc3NhZ2V9IGhhcyB0aGUgc2FtZQorbWVhbmluZyBhcyB3aXRoIHRoZSBcY2xhc3N7TWVzc2FnZX0gY29uc3RydWN0b3IuCitcZW5ke2NsYXNzZGVzY30KKworQ2VydGFpbiBtZXNzYWdlIGxhYmVscywgY2FsbGVkIFxkZm57YXR0cmlidXRlc30sIGFyZSBkZWZpbmVkIGJ5IGNvbnZlbnRpb24gdG8KK2hhdmUgc3BlY2lhbCBtZWFuaW5ncy4gVGhlIGF0dHJpYnV0ZXMgYXJlIGFzIGZvbGxvd3M6CisKK1xiZWdpbnt0YWJsZWlpfXtsfGx9e3RleHRybX17TGFiZWx9e0V4cGxhbmF0aW9ufQorXGxpbmVpaXt1bnNlZW59e05vdCByZWFkLCBidXQgcHJldmlvdXNseSBkZXRlY3RlZCBieSBNVUF9CitcbGluZWlpe2RlbGV0ZWR9e01hcmtlZCBmb3Igc3Vic2VxdWVudCBkZWxldGlvbn0KK1xsaW5laWl7ZmlsZWR9e0NvcGllZCB0byBhbm90aGVyIGZpbGUgb3IgbWFpbGJveH0KK1xsaW5laWl7YW5zd2VyZWR9e1JlcGxpZWQgdG99CitcbGluZWlpe2ZvcndhcmRlZH17Rm9yd2FyZGVkfQorXGxpbmVpaXtlZGl0ZWR9e01vZGlmaWVkIGJ5IHRoZSB1c2VyfQorXGxpbmVpaXtyZXNlbnR9e1Jlc2VudH0KK1xlbmR7dGFibGVpaX0KKworQnkgZGVmYXVsdCwgUm1haWwgZGlzcGxheXMgb25seQordmlzaWJsZSBoZWFkZXJzLiBUaGUgXGNsYXNze0JhYnlsTWVzc2FnZX0gY2xhc3MsIHRob3VnaCwgdXNlcyB0aGUgb3JpZ2luYWwKK2hlYWRlcnMgYmVjYXVzZSB0aGV5IGFyZSBtb3JlIGNvbXBsZXRlLiBWaXNpYmxlIGhlYWRlcnMgbWF5IGJlIGFjY2Vzc2VkCitleHBsaWNpdGx5IGlmIGRlc2lyZWQuCisKK1xjbGFzc3tCYWJ5bE1lc3NhZ2V9IGluc3RhbmNlcyBvZmZlciB0aGUgZm9sbG93aW5nIG1ldGhvZHM6CisKK1xiZWdpbnttZXRob2RkZXNjfXtnZXRfbGFiZWxzfXt9CitSZXR1cm4gYSBsaXN0IG9mIGxhYmVscyBvbiB0aGUgbWVzc2FnZS4KK1xlbmR7bWV0aG9kZGVzY30KKworXGJlZ2lue21ldGhvZGRlc2N9e3NldF9sYWJlbHN9e2xhYmVsc30KK1NldCB0aGUgbGlzdCBvZiBsYWJlbHMgb24gdGhlIG1lc3NhZ2UgdG8gXHZhcntsYWJlbHN9LgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317YWRkX2xhYmVsfXtsYWJlbH0KK0FkZCBcdmFye2xhYmVsfSB0byB0aGUgbGlzdCBvZiBsYWJlbHMgb24gdGhlIG1lc3NhZ2UuCitcZW5ke21ldGhvZGRlc2N9CisKK1xiZWdpbnttZXRob2RkZXNjfXtyZW1vdmVfbGFiZWx9e2xhYmVsfQorUmVtb3ZlIFx2YXJ7bGFiZWx9IGZyb20gdGhlIGxpc3Qgb2YgbGFiZWxzIG9uIHRoZSBtZXNzYWdlLgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317Z2V0X3Zpc2libGV9e30KK1JldHVybiBhbiBcY2xhc3N7TWVzc2FnZX0gaW5zdGFuY2Ugd2hvc2UgaGVhZGVycyBhcmUgdGhlIG1lc3NhZ2UncyB2aXNpYmxlCitoZWFkZXJzIGFuZCB3aG9zZSBib2R5IGlzIGVtcHR5LgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317c2V0X3Zpc2libGV9e3Zpc2libGV9CitTZXQgdGhlIG1lc3NhZ2UncyB2aXNpYmxlIGhlYWRlcnMgdG8gYmUgdGhlIHNhbWUgYXMgdGhlIGhlYWRlcnMgaW4KK1x2YXJ7bWVzc2FnZX0uIFBhcmFtZXRlciBcdmFye3Zpc2libGV9IHNob3VsZCBiZSBhIFxjbGFzc3tNZXNzYWdlfSBpbnN0YW5jZSwgYW4KK1xjbGFzc3tlbWFpbC5NZXNzYWdlLk1lc3NhZ2V9IGluc3RhbmNlLCBhIHN0cmluZywgb3IgYSBmaWxlLWxpa2Ugb2JqZWN0ICh3aGljaAorc2hvdWxkIGJlIG9wZW4gaW4gdGV4dCBtb2RlKS4KK1xlbmR7bWV0aG9kZGVzY30KKworXGJlZ2lue21ldGhvZGRlc2N9e3VwZGF0ZV92aXNpYmxlfXt9CitXaGVuIGEgXGNsYXNze0JhYnlsTWVzc2FnZX0gaW5zdGFuY2UncyBvcmlnaW5hbCBoZWFkZXJzIGFyZSBtb2RpZmllZCwgdGhlCit2aXNpYmxlIGhlYWRlcnMgYXJlIG5vdCBhdXRvbWF0aWNhbGx5IG1vZGlmaWVkIHRvIGNvcnJlc3BvbmQuIFRoaXMgbWV0aG9kCit1cGRhdGVzIHRoZSB2aXNpYmxlIGhlYWRlcnMgYXMgZm9sbG93czogZWFjaCB2aXNpYmxlIGhlYWRlciB3aXRoIGEKK2NvcnJlc3BvbmRpbmcgb3JpZ2luYWwgaGVhZGVyIGlzIHNldCB0byB0aGUgdmFsdWUgb2YgdGhlIG9yaWdpbmFsIGhlYWRlciwgZWFjaAordmlzaWJsZSBoZWFkZXIgd2l0aG91dCBhIGNvcnJlc3BvbmRpbmcgb3JpZ2luYWwgaGVhZGVyIGlzIHJlbW92ZWQsIGFuZCBhbnkgb2YKK1xtYWlsaGVhZGVye0RhdGV9LCBcbWFpbGhlYWRlcntGcm9tfSwgXG1haWxoZWFkZXJ7UmVwbHktVG99LCBcbWFpbGhlYWRlcntUb30sCitcbWFpbGhlYWRlcntDQ30sIGFuZCBcbWFpbGhlYWRlcntTdWJqZWN0fSB0aGF0IGFyZSBwcmVzZW50IGluIHRoZSBvcmlnaW5hbAoraGVhZGVycyBidXQgbm90IHRoZSB2aXNpYmxlIGhlYWRlcnMgYXJlIGFkZGVkIHRvIHRoZSB2aXNpYmxlIGhlYWRlcnMuCitcZW5ke21ldGhvZGRlc2N9CisKK1doZW4gYSBcY2xhc3N7QmFieWxNZXNzYWdlfSBpbnN0YW5jZSBpcyBjcmVhdGVkIGJhc2VkIHVwb24gYQorXGNsYXNze01haWxkaXJNZXNzYWdlfSBpbnN0YW5jZSwgdGhlIGZvbGxvd2luZyBjb252ZXJzaW9ucyB0YWtlIHBsYWNlOgorCitcYmVnaW57dGFibGVpaX17bHxsfXt0ZXh0cm19CisgICAge1Jlc3VsdGluZyBzdGF0ZX17XGNsYXNze01haWxkaXJNZXNzYWdlfSBzdGF0ZX0KK1xsaW5laWl7InVuc2VlbiIgbGFiZWx9e25vIFMgZmxhZ30KK1xsaW5laWl7ImRlbGV0ZWQiIGxhYmVsfXtUIGZsYWd9CitcbGluZWlpeyJhbnN3ZXJlZCIgbGFiZWx9e1IgZmxhZ30KK1xsaW5laWl7ImZvcndhcmRlZCIgbGFiZWx9e1AgZmxhZ30KK1xlbmR7dGFibGVpaX0KKworV2hlbiBhIFxjbGFzc3tCYWJ5bE1lc3NhZ2V9IGluc3RhbmNlIGlzIGNyZWF0ZWQgYmFzZWQgdXBvbiBhbgorXGNsYXNze21ib3hNZXNzYWdlfSBvciBcY2xhc3N7TU1ERk1lc3NhZ2V9IGluc3RhbmNlLCB0aGUgXG1haWxoZWFkZXJ7U3RhdHVzfQorYW5kIFxtYWlsaGVhZGVye1gtU3RhdHVzfSBoZWFkZXJzIGFyZSBvbWl0dGVkIGFuZCB0aGUgZm9sbG93aW5nIGNvbnZlcnNpb25zCit0YWtlIHBsYWNlOgorCitcYmVnaW57dGFibGVpaX17bHxsfXt0ZXh0cm19CisgICAge1Jlc3VsdGluZyBzdGF0ZX17XGNsYXNze21ib3hNZXNzYWdlfSBvciBcY2xhc3N7TU1ERk1lc3NhZ2V9IHN0YXRlfQorXGxpbmVpaXsidW5zZWVuIiBsYWJlbH17bm8gUiBmbGFnfQorXGxpbmVpaXsiZGVsZXRlZCIgbGFiZWx9e0QgZmxhZ30KK1xsaW5laWl7ImFuc3dlcmVkIiBsYWJlbH17QSBmbGFnfQorXGVuZHt0YWJsZWlpfQorCitXaGVuIGEgXGNsYXNze0JhYnlsTWVzc2FnZX0gaW5zdGFuY2UgaXMgY3JlYXRlZCBiYXNlZCB1cG9uIGFuIFxjbGFzc3tNSE1lc3NhZ2V9CitpbnN0YW5jZSwgdGhlIGZvbGxvd2luZyBjb252ZXJzaW9ucyB0YWtlIHBsYWNlOgorCitcYmVnaW57dGFibGVpaX17bHxsfXt0ZXh0cm19CisgICAge1Jlc3VsdGluZyBzdGF0ZX17XGNsYXNze01ITWVzc2FnZX0gc3RhdGV9CitcbGluZWlpeyJ1bnNlZW4iIGxhYmVsfXsidW5zZWVuIiBzZXF1ZW5jZX0KK1xsaW5laWl7ImFuc3dlcmVkIiBsYWJlbH17InJlcGxpZWQiIHNlcXVlbmNlfQorXGVuZHt0YWJsZWlpfQorCitcc3Vic3Vic2VjdGlvbntcY2xhc3N7TU1ERk1lc3NhZ2V9fQorXGxhYmVse21haWxib3gtbW1kZm1lc3NhZ2V9CisKK1xiZWdpbntjbGFzc2Rlc2N9e01NREZNZXNzYWdlfXtcb3B0aW9uYWx7bWVzc2FnZX19CitBIG1lc3NhZ2Ugd2l0aCBNTURGLXNwZWNpZmljIGJlaGF2aW9ycy4gUGFyYW1ldGVyIFx2YXJ7bWVzc2FnZX0gaGFzIHRoZSBzYW1lCittZWFuaW5nIGFzIHdpdGggdGhlIFxjbGFzc3tNZXNzYWdlfSBjb25zdHJ1Y3Rvci4KK1xlbmR7Y2xhc3NkZXNjfQorCitBcyB3aXRoIG1lc3NhZ2UgaW4gYW4gbWJveCBtYWlsYm94LCBNTURGIG1lc3NhZ2VzIGFyZSBzdG9yZWQgd2l0aCB0aGUgc2VuZGVyJ3MKK2FkZHJlc3MgYW5kIHRoZSBkZWxpdmVyeSBkYXRlIGluIGFuIGluaXRpYWwgbGluZSBiZWdpbm5pbmcgd2l0aCAiRnJvbSAiLgorTGlrZXdpc2UsIGZsYWdzIHRoYXQgaW5kaWNhdGUgdGhlIHN0YXRlIG9mIHRoZSBtZXNzYWdlIGFyZSB0eXBpY2FsbHkgc3RvcmVkIGluCitcbWFpbGhlYWRlcntTdGF0dXN9IGFuZCBcbWFpbGhlYWRlcntYLVN0YXR1c30gaGVhZGVycy4KKworQ29udmVudGlvbmFsIGZsYWdzIGZvciBNTURGIG1lc3NhZ2VzIGFyZSBpZGVudGljYWwgdG8gdGhvc2Ugb2YgbWJveCBtZXNzYWdlIGFuZAorYXJlIGFzIGZvbGxvd3M6CisKK1xiZWdpbnt0YWJsZWlpaX17bHxsfGx9e3RleHRybX17RmxhZ317TWVhbmluZ317RXhwbGFuYXRpb259CitcbGluZWlpaXtSfXtSZWFkfXtSZWFkfQorXGxpbmVpaWl7T317T2xkfXtQcmV2aW91c2x5IGRldGVjdGVkIGJ5IE1VQX0KK1xsaW5laWlpe0R9e0RlbGV0ZWR9e01hcmtlZCBmb3Igc3Vic2VxdWVudCBkZWxldGlvbn0KK1xsaW5laWlpe0Z9e0ZsYWdnZWR9e01hcmtlZCBhcyBpbXBvcnRhbnR9CitcbGluZWlpaXtBfXtBbnN3ZXJlZH17UmVwbGllZCB0b30KK1xlbmR7dGFibGVpaWl9CisKK1RoZSAiUiIgYW5kICJPIiBmbGFncyBhcmUgc3RvcmVkIGluIHRoZSBcbWFpbGhlYWRlcntTdGF0dXN9IGhlYWRlciwgYW5kIHRoZQorIkQiLCAiRiIsIGFuZCAiQSIgZmxhZ3MgYXJlIHN0b3JlZCBpbiB0aGUgXG1haWxoZWFkZXJ7WC1TdGF0dXN9IGhlYWRlci4gVGhlCitmbGFncyBhbmQgaGVhZGVycyB0eXBpY2FsbHkgYXBwZWFyIGluIHRoZSBvcmRlciBtZW50aW9uZWQuCisKK1xjbGFzc3tNTURGTWVzc2FnZX0gaW5zdGFuY2VzIG9mZmVyIHRoZSBmb2xsb3dpbmcgbWV0aG9kcywgd2hpY2ggYXJlIGlkZW50aWNhbAordG8gdGhvc2Ugb2ZmZXJlZCBieSBcY2xhc3N7bWJveE1lc3NhZ2V9OgorCitcYmVnaW57bWV0aG9kZGVzY317Z2V0X2Zyb219e30KK1JldHVybiBhIHN0cmluZyByZXByZXNlbnRpbmcgdGhlICJGcm9tfiIgbGluZSB0aGF0IG1hcmtzIHRoZSBzdGFydCBvZiB0aGUKK21lc3NhZ2UgaW4gYW4gbWJveCBtYWlsYm94LiBUaGUgbGVhZGluZyAiRnJvbX4iIGFuZCB0aGUgdHJhaWxpbmcgbmV3bGluZSBhcmUKK2V4Y2x1ZGVkLgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317c2V0X2Zyb219e2Zyb21fXG9wdGlvbmFseywgdGltZV89Tm9uZX19CitTZXQgdGhlICJGcm9tfiIgbGluZSB0byBcdmFye2Zyb21ffSwgd2hpY2ggc2hvdWxkIGJlIHNwZWNpZmllZCB3aXRob3V0IGEKK2xlYWRpbmcgIkZyb21+IiBvciB0cmFpbGluZyBuZXdsaW5lLiBGb3IgY29udmVuaWVuY2UsIFx2YXJ7dGltZV99IG1heSBiZQorc3BlY2lmaWVkIGFuZCB3aWxsIGJlIGZvcm1hdHRlZCBhcHByb3ByaWF0ZWx5IGFuZCBhcHBlbmRlZCB0byBcdmFye2Zyb21ffS4gSWYKK1x2YXJ7dGltZV99IGlzIHNwZWNpZmllZCwgaXQgc2hvdWxkIGJlIGEgXGNsYXNze3N0cnVjdF90aW1lfSBpbnN0YW5jZSwgYSB0dXBsZQorc3VpdGFibGUgZm9yIHBhc3NpbmcgdG8gXG1ldGhvZHt0aW1lLnN0cmZ0aW1lKCl9LCBvciBcY29kZXtUcnVlfSAodG8gdXNlCitcbWV0aG9ke3RpbWUuZ210aW1lKCl9KS4KK1xlbmR7bWV0aG9kZGVzY30KKworXGJlZ2lue21ldGhvZGRlc2N9e2dldF9mbGFnc317fQorUmV0dXJuIGEgc3RyaW5nIHNwZWNpZnlpbmcgdGhlIGZsYWdzIHRoYXQgYXJlIGN1cnJlbnRseSBzZXQuIElmIHRoZSBtZXNzYWdlCitjb21wbGllcyB3aXRoIHRoZSBjb252ZW50aW9uYWwgZm9ybWF0LCB0aGUgcmVzdWx0IGlzIHRoZSBjb25jYXRlbmF0aW9uIGluIHRoZQorZm9sbG93aW5nIG9yZGVyIG9mIHplcm8gb3Igb25lIG9jY3VycmVuY2Ugb2YgZWFjaCBvZiBcY2hhcmFjdGVye1J9LAorXGNoYXJhY3RlcntPfSwgXGNoYXJhY3RlcntEfSwgXGNoYXJhY3RlcntGfSwgYW5kIFxjaGFyYWN0ZXJ7QX0uCitcZW5ke21ldGhvZGRlc2N9CisKK1xiZWdpbnttZXRob2RkZXNjfXtzZXRfZmxhZ3N9e2ZsYWdzfQorU2V0IHRoZSBmbGFncyBzcGVjaWZpZWQgYnkgXHZhcntmbGFnc30gYW5kIHVuc2V0IGFsbCBvdGhlcnMuIFBhcmFtZXRlcgorXHZhcntmbGFnc30gc2hvdWxkIGJlIHRoZSBjb25jYXRlbmF0aW9uIGluIGFueSBvcmRlciBvZiB6ZXJvIG9yIG1vcmUKK29jY3VycmVuY2VzIG9mIGVhY2ggb2YgXGNoYXJhY3RlcntSfSwgXGNoYXJhY3RlcntPfSwgXGNoYXJhY3RlcntEfSwKK1xjaGFyYWN0ZXJ7Rn0sIGFuZCBcY2hhcmFjdGVye0F9LgorXGVuZHttZXRob2RkZXNjfQorCitcYmVnaW57bWV0aG9kZGVzY317YWRkX2ZsYWd9e2ZsYWd9CitTZXQgdGhlIGZsYWcocykgc3BlY2lmaWVkIGJ5IFx2YXJ7ZmxhZ30gd2l0aG91dCBjaGFuZ2luZyBvdGhlciBmbGFncy4gVG8gYWRkCittb3JlIHRoYW4gb25lIGZsYWcgYXQgYSB0aW1lLCBcdmFye2ZsYWd9IG1heSBiZSBhIHN0cmluZyBvZiBtb3JlIHRoYW4gb25lCitjaGFyYWN0ZXIuCitcZW5ke21ldGhvZGRlc2N9CisKK1xiZWdpbnttZXRob2RkZXNjfXtyZW1vdmVfZmxhZ317ZmxhZ30KK1Vuc2V0IHRoZSBmbGFnKHMpIHNwZWNpZmllZCBieSBcdmFye2ZsYWd9IHdpdGhvdXQgY2hhbmdpbmcgb3RoZXIgZmxhZ3MuIFRvCityZW1vdmUgbW9yZSB0aGFuIG9uZSBmbGFnIGF0IGEgdGltZSwgXHZhcntmbGFnfSBtYXliZSBhIHN0cmluZyBvZiBtb3JlIHRoYW4gb25lCitjaGFyYWN0ZXIuCitcZW5ke21ldGhvZGRlc2N9CisKK1doZW4gYW4gXGNsYXNze01NREZNZXNzYWdlfSBpbnN0YW5jZSBpcyBjcmVhdGVkIGJhc2VkIHVwb24gYQorXGNsYXNze01haWxkaXJNZXNzYWdlfSBpbnN0YW5jZSwgYSAiRnJvbX4iIGxpbmUgaXMgZ2VuZXJhdGVkIGJhc2VkIHVwb24gdGhlCitcY2xhc3N7TWFpbGRpck1lc3NhZ2V9IGluc3RhbmNlJ3MgZGVsaXZlcnkgZGF0ZSwgYW5kIHRoZSBmb2xsb3dpbmcgY29udmVyc2lvbnMKK3Rha2UgcGxhY2U6CisKK1xiZWdpbnt0YWJsZWlpfXtsfGx9e3RleHRybX0KKyAgICB7UmVzdWx0aW5nIHN0YXRlfXtcY2xhc3N7TWFpbGRpck1lc3NhZ2V9IHN0YXRlfQorXGxpbmVpaXtSIGZsYWd9e1MgZmxhZ30KK1xsaW5laWl7TyBmbGFnfXsiY3VyIiBzdWJkaXJlY3Rvcnl9CitcbGluZWlpe0QgZmxhZ317VCBmbGFnfQorXGxpbmVpaXtGIGZsYWd9e0YgZmxhZ30KK1xsaW5laWl7QSBmbGFnfXtSIGZsYWd9CitcZW5ke3RhYmxlaWl9CisKK1doZW4gYW4gXGNsYXNze01NREZNZXNzYWdlfSBpbnN0YW5jZSBpcyBjcmVhdGVkIGJhc2VkIHVwb24gYW4gXGNsYXNze01ITWVzc2FnZX0KK2luc3RhbmNlLCB0aGUgZm9sbG93aW5nIGNvbnZlcnNpb25zIHRha2UgcGxhY2U6CisKK1xiZWdpbnt0YWJsZWlpfXtsfGx9e3RleHRybX0KKyAgICB7UmVzdWx0aW5nIHN0YXRlfXtcY2xhc3N7TUhNZXNzYWdlfSBzdGF0ZX0KK1xsaW5laWl7UiBmbGFnIGFuZCBPIGZsYWd9e25vICJ1bnNlZW4iIHNlcXVlbmNlfQorXGxpbmVpaXtPIGZsYWd9eyJ1bnNlZW4iIHNlcXVlbmNlfQorXGxpbmVpaXtGIGZsYWd9eyJmbGFnZ2VkIiBzZXF1ZW5jZX0KK1xsaW5laWl7QSBmbGFnfXsicmVwbGllZCIgc2VxdWVuY2V9CitcZW5ke3RhYmxlaWl9CisKK1doZW4gYW4gXGNsYXNze01NREZNZXNzYWdlfSBpbnN0YW5jZSBpcyBjcmVhdGVkIGJhc2VkIHVwb24gYQorXGNsYXNze0JhYnlsTWVzc2FnZX0gaW5zdGFuY2UsIHRoZSBmb2xsb3dpbmcgY29udmVyc2lvbnMgdGFrZSBwbGFjZToKKworXGJlZ2lue3RhYmxlaWl9e2x8bH17dGV4dHJtfQorICAgIHtSZXN1bHRpbmcgc3RhdGV9e1xjbGFzc3tCYWJ5bE1lc3NhZ2V9IHN0YXRlfQorXGxpbmVpaXtSIGZsYWcgYW5kIE8gZmxhZ317bm8gInVuc2VlbiIgbGFiZWx9CitcbGluZWlpe08gZmxhZ317InVuc2VlbiIgbGFiZWx9CitcbGluZWlpe0QgZmxhZ317ImRlbGV0ZWQiIGxhYmVsfQorXGxpbmVpaXtBIGZsYWd9eyJhbnN3ZXJlZCIgbGFiZWx9CitcZW5ke3RhYmxlaWl9CisKK1doZW4gYW4gXGNsYXNze01NREZNZXNzYWdlfSBpbnN0YW5jZSBpcyBjcmVhdGVkIGJhc2VkIHVwb24gYW4KK1xjbGFzc3ttYm94TWVzc2FnZX0gaW5zdGFuY2UsIHRoZSAiRnJvbX4iIGxpbmUgaXMgY29waWVkIGFuZCBhbGwgZmxhZ3MgZGlyZWN0bHkKK2NvcnJlc3BvbmQ6CisKK1xiZWdpbnt0YWJsZWlpfXtsfGx9e3RleHRybX0KKyAgICB7UmVzdWx0aW5nIHN0YXRlfXtcY2xhc3N7bWJveE1lc3NhZ2V9IHN0YXRlfQorXGxpbmVpaXtSIGZsYWd9e1IgZmxhZ30KK1xsaW5laWl7TyBmbGFnfXtPIGZsYWd9CitcbGluZWlpe0QgZmxhZ317RCBmbGFnfQorXGxpbmVpaXtGIGZsYWd9e0YgZmxhZ30KK1xsaW5laWl7QSBmbGFnfXtBIGZsYWd9CitcZW5ke3RhYmxlaWl9CisKK1xzdWJzZWN0aW9ue0V4Y2VwdGlvbnN9CitcbGFiZWx7bWFpbGJveC1kZXByZWNhdGVkfQorCitUaGUgZm9sbG93aW5nIGV4Y2VwdGlvbiBjbGFzc2VzIGFyZSBkZWZpbmVkIGluIHRoZSBcbW9kdWxle21haWxib3h9IG1vZHVsZToKKworXGJlZ2lue2NsYXNzZGVzY317RXJyb3J9e30KK1RoZSBiYXNlZCBjbGFzcyBmb3IgYWxsIG90aGVyIG1vZHVsZS1zcGVjaWZpYyBleGNlcHRpb25zLgorXGVuZHtjbGFzc2Rlc2N9CisKK1xiZWdpbntjbGFzc2Rlc2N9e05vU3VjaE1haWxib3hFcnJvcn17fQorUmFpc2VkIHdoZW4gYSBtYWlsYm94IGlzIGV4cGVjdGVkIGJ1dCBpcyBub3QgZm91bmQsIHN1Y2ggYXMgd2hlbiBpbnN0YW50aWF0aW5nCithIFxjbGFzc3tNYWlsYm94fSBzdWJjbGFzcyB3aXRoIGEgcGF0aCB0aGF0IGRvZXMgbm90IGV4aXN0IChhbmQgd2l0aCB0aGUKK1x2YXJ7Y3JlYXRlfSBwYXJhbWV0ZXIgc2V0IHRvIFxjb2Rle0ZhbHNlfSksIG9yIHdoZW4gb3BlbmluZyBhIGZvbGRlciB0aGF0IGRvZXMKK25vdCBleGlzdC4KK1xlbmR7Y2xhc3NkZXNjfQorCitcYmVnaW57Y2xhc3NkZXNjfXtOb3RFbXB0eUVycm9yRXJyb3J9e30KK1JhaXNlZCB3aGVuIGEgbWFpbGJveCBpcyBub3QgZW1wdHkgYnV0IGlzIGV4cGVjdGVkIHRvIGJlLCBzdWNoIGFzIHdoZW4gZGVsZXRpbmcKK2EgZm9sZGVyIHRoYXQgY29udGFpbnMgbWVzc2FnZXMuCitcZW5ke2NsYXNzZGVzY30KKworXGJlZ2lue2NsYXNzZGVzY317RXh0ZXJuYWxDbGFzaEVycm9yfXt9CitSYWlzZWQgd2hlbiBzb21lIG1haWxib3gtcmVsYXRlZCBjb25kaXRpb24gYmV5b25kIHRoZSBjb250cm9sIG9mIHRoZSBwcm9ncmFtCitjYXVzZXMgaXQgdG8gYmUgdW5hYmxlIHRvIHByb2NlZWQsIHN1Y2ggYXMgd2hlbiBmYWlsaW5nIHRvIGFjcXVpcmUgYSBsb2NrIHRoYXQKK2Fub3RoZXIgcHJvZ3JhbSBhbHJlYWR5IGhvbGRzIGEgbG9jaywgb3Igd2hlbiBhIHVuaXF1ZWx5LWdlbmVyYXRlZCBmaWxlIG5hbWUKK2FscmVhZHkgZXhpc3RzLgorXGVuZHtjbGFzc2Rlc2N9CisKK1xiZWdpbntjbGFzc2Rlc2N9e0Zvcm1hdEVycm9yfXt9CitSYWlzZWQgd2hlbiB0aGUgZGF0YSBpbiBhIGZpbGUgY2Fubm90IGJlIHBhcnNlZCwgc3VjaCBhcyB3aGVuIGFuIFxjbGFzc3tNSH0KK2luc3RhbmNlIGF0dGVtcHRzIHRvIHJlYWQgYSBjb3JydXB0ZWQgXGZpbGV7Lm1oX3NlcXVlbmNlc30gZmlsZS4KK1xlbmR7Y2xhc3NkZXNjfQorCitcc3Vic2VjdGlvbntEZXByZWNhdGVkIGNsYXNzZXMgYW5kIG1ldGhvZHN9CitcbGFiZWx7bWFpbGJveC1kZXByZWNhdGVkfQorCitPbGRlciB2ZXJzaW9ucyBvZiB0aGUgXG1vZHVsZXttYWlsYm94fSBtb2R1bGUgZG8gbm90IHN1cHBvcnQgbW9kaWZpY2F0aW9uIG9mCittYWlsYm94ZXMsIHN1Y2ggYXMgYWRkaW5nIG9yIHJlbW92aW5nIG1lc3NhZ2UsIGFuZCBkbyBub3QgcHJvdmlkZSBjbGFzc2VzIHRvCityZXByZXNlbnQgZm9ybWF0LXNwZWNpZmljIG1lc3NhZ2UgcHJvcGVydGllcy4gRm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHRoZQorb2xkZXIgbWFpbGJveCBjbGFzc2VzIGFyZSBzdGlsbCBhdmFpbGFibGUsIGJ1dCB0aGUgbmV3ZXIgY2xhc3NlcyBzaG91bGQgYmUgdXNlZAoraW4gcHJlZmVyZW5jZSB0byB0aGVtLgorCitPbGRlciBtYWlsYm94IG9iamVjdHMgc3VwcG9ydCBvbmx5IGl0ZXJhdGlvbiBhbmQgcHJvdmlkZSBhIHNpbmdsZSBwdWJsaWMKK21ldGhvZDoKKworXGJlZ2lue21ldGhvZGRlc2N9e25leHR9e30KK1JldHVybiB0aGUgbmV4dCBtZXNzYWdlIGluIHRoZSBtYWlsYm94LCBjcmVhdGVkIHdpdGggdGhlIG9wdGlvbmFsIFx2YXJ7ZmFjdG9yeX0KK2FyZ3VtZW50IHBhc3NlZCBpbnRvIHRoZSBtYWlsYm94IG9iamVjdCdzIGNvbnN0cnVjdG9yLiBCeSBkZWZhdWx0IHRoaXMgaXMgYW4KK1xjbGFzc3tyZmM4MjIuTWVzc2FnZX0gb2JqZWN0IChzZWUgdGhlIFxyZWZtb2R1bGV7cmZjODIyfSBtb2R1bGUpLiAgRGVwZW5kaW5nCitvbiB0aGUgbWFpbGJveCBpbXBsZW1lbnRhdGlvbiB0aGUgXHZhcntmcH0gYXR0cmlidXRlIG9mIHRoaXMgb2JqZWN0IG1heSBiZSBhCit0cnVlIGZpbGUgb2JqZWN0IG9yIGEgY2xhc3MgaW5zdGFuY2Ugc2ltdWxhdGluZyBhIGZpbGUgb2JqZWN0LCB0YWtpbmcgY2FyZSBvZgordGhpbmdzIGxpa2UgbWVzc2FnZSBib3VuZGFyaWVzIGlmIG11bHRpcGxlIG1haWwgbWVzc2FnZXMgYXJlIGNvbnRhaW5lZCBpbiBhCitzaW5nbGUgZmlsZSwgZXRjLiAgSWYgbm8gbW9yZSBtZXNzYWdlcyBhcmUgYXZhaWxhYmxlLCB0aGlzIG1ldGhvZCByZXR1cm5zCitcY29kZXtOb25lfS4KK1xlbmR7bWV0aG9kZGVzY30KKworTW9zdCBvZiB0aGUgb2xkZXIgbWFpbGJveCBjbGFzc2VzIGhhdmUgbmFtZXMgdGhhdCBkaWZmZXIgZnJvbSB0aGUgY3VycmVudAorbWFpbGJveCBjbGFzcyBuYW1lcywgZXhjZXB0IGZvciBcY2xhc3N7TWFpbGRpcn0uIEZvciB0aGlzIHJlYXNvbiwgdGhlIG5ldworXGNsYXNze01haWxkaXJ9IGNsYXNzIGRlZmluZXMgYSBcbWV0aG9ke25leHQoKX0gbWV0aG9kIGFuZCBpdHMgY29uc3RydWN0b3IKK2RpZmZlcnMgc2xpZ2h0bHkgZnJvbSB0aG9zZSBvZiB0aGUgb3RoZXIgbmV3IG1haWxib3ggY2xhc3Nlcy4KKworVGhlIG9sZGVyIG1haWxib3ggY2xhc3NlcyB3aG9zZSBuYW1lcyBhcmUgbm90IHRoZSBzYW1lIGFzIHRoZWlyIG5ld2VyCitjb3VudGVycGFydHMgYXJlIGFzIGZvbGxvd3M6CiAKIFxiZWdpbntjbGFzc2Rlc2N9e1VuaXhNYWlsYm94fXtmcFxvcHRpb25hbHssIGZhY3Rvcnl9fQogQWNjZXNzIHRvIGEgY2xhc3NpYyBcVU5JWC1zdHlsZSBtYWlsYm94LCB3aGVyZSBhbGwgbWVzc2FnZXMgYXJlCkBAIC02OCwxMiArMTMwOSw2IEBACiBcdmFye2ZhY3Rvcnl9IGlzIGFzIHdpdGggdGhlIFxjbGFzc3tVbml4TWFpbGJveH0gY2xhc3MuCiBcZW5ke2NsYXNzZGVzY30KIAotXGJlZ2lue2NsYXNzZGVzY317TWFpbGRpcn17ZGlybmFtZVxvcHRpb25hbHssIGZhY3Rvcnl9fQotQWNjZXNzIGEgUW1haWwgbWFpbCBkaXJlY3RvcnkuICBBbGwgbmV3IGFuZCBjdXJyZW50IG1haWwgZm9yIHRoZQotbWFpbGJveCBzcGVjaWZpZWQgYnkgXHZhcntkaXJuYW1lfSBpcyBtYWRlIGF2YWlsYWJsZS4KLVx2YXJ7ZmFjdG9yeX0gaXMgYXMgd2l0aCB0aGUgXGNsYXNze1VuaXhNYWlsYm94fSBjbGFzcy4KLVxlbmR7Y2xhc3NkZXNjfQotCiBcYmVnaW57Y2xhc3NkZXNjfXtCYWJ5bE1haWxib3h9e2ZwXG9wdGlvbmFseywgZmFjdG9yeX19CiBBY2Nlc3MgYSBCYWJ5bCBtYWlsYm94LCB3aGljaCBpcyBzaW1pbGFyIHRvIGFuIE1NREYgbWFpbGJveC4gIEluCiBCYWJ5bCBmb3JtYXQsIGVhY2ggbWVzc2FnZSBoYXMgdHdvIHNldHMgb2YgaGVhZGVycywgdGhlCkBAIC04OSwxMSArMTMyNCw4IEBACiBcY2xhc3N7VW5peE1haWxib3h9IGNsYXNzLgogXGVuZHtjbGFzc2Rlc2N9CiAKLU5vdGUgdGhhdCBiZWNhdXNlIHRoZSBccmVmbW9kdWxle3JmYzgyMn0gbW9kdWxlIGlzIGRlcHJlY2F0ZWQsIGl0IGlzCi1yZWNvbW1lbmRlZCB0aGF0IHlvdSB1c2UgdGhlIFxyZWZtb2R1bGV7ZW1haWx9IHBhY2thZ2UgdG8gY3JlYXRlCi1tZXNzYWdlIG9iamVjdHMgZnJvbSBhIG1haWxib3guICAoVGhlIGRlZmF1bHQgY2FuJ3QgYmUgY2hhbmdlZCBmb3IKLWJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IHJlYXNvbnMuKSAgVGhlIHNhZmVzdCB3YXkgdG8gZG8gdGhpcyBpcyB3aXRoCi1iaXQgb2YgY29kZToKK0lmIHlvdSB3aXNoIHRvIHVzZSB0aGUgb2xkZXIgbWFpbGJveCBjbGFzc2VzIHdpdGggdGhlIFxtb2R1bGV7ZW1haWx9IG1vZHVsZQorcmF0aGVyIHRoYW4gdGhlIGRlcHJlY2F0ZWQgXG1vZHVsZXtyZmM4MjJ9IG1vZHVsZSwgeW91IGNhbiBkbyBzbyBhcyBmb2xsb3dzOgogCiBcYmVnaW57dmVyYmF0aW19CiBpbXBvcnQgZW1haWwKQEAgLTEwNSwxNyArMTMzNywxNCBAQAogICAgICAgICByZXR1cm4gZW1haWwubWVzc2FnZV9mcm9tX2ZpbGUoZnApCiAgICAgZXhjZXB0IGVtYWlsLkVycm9ycy5NZXNzYWdlUGFyc2VFcnJvcjoKICAgICAgICAgIyBEb24ndCByZXR1cm4gTm9uZSBzaW5jZSB0aGF0IHdpbGwKLQkjIHN0b3AgdGhlIG1haWxib3ggaXRlcmF0b3IKLQlyZXR1cm4gJycKKyAgICAgICAgIyBzdG9wIHRoZSBtYWlsYm94IGl0ZXJhdG9yCisgICAgICAgIHJldHVybiAnJwogCiBtYm94ID0gbWFpbGJveC5Vbml4TWFpbGJveChmcCwgbXNnZmFjdG9yeSkKIFxlbmR7dmVyYmF0aW19CiAKLVRoZSBhYm92ZSB3cmFwcGVyIGlzIGRlZmVuc2l2ZSBhZ2FpbnN0IGlsbC1mb3JtZWQgTUlNRSBtZXNzYWdlcyBpbiB0aGUKLW1haWxib3gsIGJ1dCB5b3UgaGF2ZSB0byBiZSBwcmVwYXJlZCB0byByZWNlaXZlIHRoZSBlbXB0eSBzdHJpbmcgZnJvbQotdGhlIG1haWxib3gncyBcZnVuY3Rpb257bmV4dCgpfSBtZXRob2QuICBPbiB0aGUgb3RoZXIgaGFuZCwgaWYgeW91Ci1rbm93IHlvdXIgbWFpbGJveCBjb250YWlucyBvbmx5IHdlbGwtZm9ybWVkIE1JTUUgbWVzc2FnZXMsIHlvdSBjYW4KLXNpbXBsaWZ5IHRoaXMgdG86CitBbHRlcm5hdGl2ZWx5LCBpZiB5b3Uga25vdyB5b3VyIG1haWxib3ggY29udGFpbnMgb25seSB3ZWxsLWZvcm1lZCBNSU1FCittZXNzYWdlcywgeW91IGNhbiBzaW1wbGlmeSB0aGlzIHRvOgogCiBcYmVnaW57dmVyYmF0aW19CiBpbXBvcnQgZW1haWwKQEAgLTEyNCwzNSArMTM1Myw1NyBAQAogbWJveCA9IG1haWxib3guVW5peE1haWxib3goZnAsIGVtYWlsLm1lc3NhZ2VfZnJvbV9maWxlKQogXGVuZHt2ZXJiYXRpbX0KIAotXGJlZ2lue3NlZWFsc299Ci0gIFxzZWV0aXRsZVtodHRwOi8vd3d3LnFtYWlsLm9yZy9tYW4vbWFuNS9tYm94Lmh0bWxde21ib3ggLQotICAgICAgICAgICAgZmlsZSBjb250YWluaW5nIG1haWwgbWVzc2FnZXN9e0Rlc2NyaXB0aW9uIG9mIHRoZQotICAgICAgICAgICAgdHJhZGl0aW9uYWwgYGBtYm94JycgbWFpbGJveCBmb3JtYXQufQotICBcc2VldGl0bGVbaHR0cDovL3d3dy5xbWFpbC5vcmcvbWFuL21hbjUvbWFpbGRpci5odG1sXXttYWlsZGlyIC0KLSAgICAgICAgICAgIGRpcmVjdG9yeSBmb3IgaW5jb21pbmcgbWFpbCBtZXNzYWdlc317RGVzY3JpcHRpb24gb2YgdGhlCi0gICAgICAgICAgICBgYG1haWxkaXInJyBtYWlsYm94IGZvcm1hdC59Ci0gIFxzZWV0aXRsZVtodHRwOi8vaG9tZS5uZXRzY2FwZS5jb20vZW5nL21vemlsbGEvMi4wL3JlbG5vdGVzL2RlbW8vY29udGVudC1sZW5ndGguaHRtbF17Q29uZmlndXJpbmcKLSAgICAgICAgICAgIE5ldHNjYXBlIE1haWwgb24gXFVOSVg6IFdoeSB0aGUgQ29udGVudC1MZW5ndGggRm9ybWF0IGlzCi0gICAgICAgICAgICBCYWR9e0EgZGVzY3JpcHRpb24gb2YgcHJvYmxlbXMgd2l0aCByZWx5aW5nIG9uIHRoZQotICAgICAgICAgICAgXG1haWxoZWFkZXJ7Q29udGVudC1MZW5ndGh9IGhlYWRlciBmb3IgbWVzc2FnZXMgc3RvcmVkIGluCi0gICAgICAgICAgICBtYWlsYm94IGZpbGVzLn0KLVxlbmR7c2VlYWxzb30KK1xzdWJzZWN0aW9ue0V4YW1wbGVzfQorXGxhYmVse21haWxib3gtZXhhbXBsZXN9CiAKK0Egc2ltcGxlIGV4YW1wbGUgb2YgcHJpbnRpbmcgdGhlIHN1YmplY3RzIG9mIGFsbCBtZXNzYWdlcyBpbiBhIG1haWxib3ggdGhhdAorc2VlbSBpbnRlcmVzdGluZzoKIAotXHN1YnNlY3Rpb257TWFpbGJveCBPYmplY3RzIFxsYWJlbHttYWlsYm94LW9iamVjdHN9fQorXGJlZ2lue3ZlcmJhdGltfQoraW1wb3J0IG1haWxib3gKK2ZvciBtZXNzYWdlIGluIG1haWxib3gubWJveCgnfi9tYm94Jyk6CisgICAgc3ViamVjdCA9IG1lc3NhZ2VbJ3N1YmplY3QnXSAgICAgICAjIENvdWxkIHBvc3NpYmx5IGJlIE5vbmUuCisgICAgaWYgc3ViamVjdCBhbmQgJ3B5dGhvbicgaW4gc3ViamVjdC5sb3dlcigpOgorICAgICAgICBwcmludCBzdWJqZWN0CitcZW5ke3ZlcmJhdGltfQogCi1BbGwgaW1wbGVtZW50YXRpb25zIG9mIG1haWxib3ggb2JqZWN0cyBhcmUgaXRlcmFibGUgb2JqZWN0cywgYW5kCi1oYXZlIG9uZSBleHRlcm5hbGx5IHZpc2libGUgbWV0aG9kLiAgVGhpcyBtZXRob2QgaXMgdXNlZCBieSBpdGVyYXRvcnMKLWNyZWF0ZWQgZnJvbSBtYWlsYm94IG9iamVjdHMgYW5kIG1heSBhbHNvIGJlIHVzZWQgZGlyZWN0bHkuCitBIChzdXJwcmlzaW5nbHkpIHNpbXBsZSBleGFtcGxlIG9mIGNvcHlpbmcgYWxsIG1haWwgZnJvbSBhIEJhYnlsIG1haWxib3ggdG8gYW4KK01IIG1haWxib3gsIGNvbnZlcnRpbmcgYWxsIG9mIHRoZSBmb3JtYXQtc3BlY2lmaWMgaW5mb3JtYXRpb24gdGhhdCBjYW4gYmUKK2NvbnZlcnRlZDoKIAotXGJlZ2lue21ldGhvZGRlc2N9W21haWxib3hde25leHR9e30KLVJldHVybiB0aGUgbmV4dCBtZXNzYWdlIGluIHRoZSBtYWlsYm94LCBjcmVhdGVkIHdpdGggdGhlIG9wdGlvbmFsCi1cdmFye2ZhY3Rvcnl9IGFyZ3VtZW50IHBhc3NlZCBpbnRvIHRoZSBtYWlsYm94IG9iamVjdCdzIGNvbnN0cnVjdG9yLgotQnkgZGVmYXVsdCB0aGlzIGlzIGFuIFxjbGFzc3tyZmM4MjIuTWVzc2FnZX0KLW9iamVjdCAoc2VlIHRoZSBccmVmbW9kdWxle3JmYzgyMn0gbW9kdWxlKS4gIERlcGVuZGluZyBvbiB0aGUgbWFpbGJveAotaW1wbGVtZW50YXRpb24gdGhlIFx2YXJ7ZnB9IGF0dHJpYnV0ZSBvZiB0aGlzIG9iamVjdCBtYXkgYmUgYSB0cnVlCi1maWxlIG9iamVjdCBvciBhIGNsYXNzIGluc3RhbmNlIHNpbXVsYXRpbmcgYSBmaWxlIG9iamVjdCwgdGFraW5nIGNhcmUKLW9mIHRoaW5ncyBsaWtlIG1lc3NhZ2UgYm91bmRhcmllcyBpZiBtdWx0aXBsZSBtYWlsIG1lc3NhZ2VzIGFyZQotY29udGFpbmVkIGluIGEgc2luZ2xlIGZpbGUsIGV0Yy4gIElmIG5vIG1vcmUgbWVzc2FnZXMgYXJlIGF2YWlsYWJsZSwKLXRoaXMgbWV0aG9kIHJldHVybnMgXGNvZGV7Tm9uZX0uCi1cZW5ke21ldGhvZGRlc2N9CitcYmVnaW57dmVyYmF0aW19CitpbXBvcnQgbWFpbGJveAorZGVzdGluYXRpb24gPSBtYWlsYm94Lk1IKCd+L01haWwnKQorZm9yIG1lc3NhZ2UgaW4gbWFpbGJveC5CYWJ5bCgnfi9STUFJTCcpOgorICAgIGRlc3RpbmF0aW9uLmFkZChNSE1lc3NhZ2UobWVzc2FnZSkpCitcZW5ke3ZlcmJhdGltfQorCitBbiBleGFtcGxlIG9mIHNvcnRpbmcgbWFpbCBmcm9tIG51bWVyb3VzIG1haWxpbmcgbGlzdHMsIGJlaW5nIGNhcmVmdWwgdG8gYXZvaWQKK21haWwgY29ycnVwdGlvbiBkdWUgdG8gY29uY3VycmVudCBtb2RpZmljYXRpb24gYnkgb3RoZXIgcHJvZ3JhbXMsIG1haWwgbG9zcyBkdWUKK3RvIGludGVycnVwdGlvbiBvZiB0aGUgcHJvZ3JhbSwgb3IgcHJlbWF0dXJlIHRlcm1pbmF0aW9uIGR1ZSB0byBtYWxmb3JtZWQKK21lc3NhZ2VzIGluIHRoZSBtYWlsYm94OgorCitcYmVnaW57dmVyYmF0aW19CitpbXBvcnQgbWFpbGJveAoraW1wb3J0IGVtYWlsLkVycm9ycworbGlzdF9uYW1lcyA9ICgncHl0aG9uLWxpc3QnLCAncHl0aG9uLWRldicsICdweXRob24tYnVncycpCitib3hlcyA9IGRpY3QoKG5hbWUsIG1haWxib3gubWJveCgnfi9lbWFpbC8lcycgJSBuYW1lKSkgZm9yIG5hbWUgaW4gbGlzdF9uYW1lcykKK2luYm94ID0gbWFpbGJveC5NYWlsZGlyKCd+L01haWxkaXInLCBOb25lKQorZm9yIGtleSBpbiBpbmJveC5pdGVya2V5cygpOgorICAgIHRyeToKKyAgICAgICAgbWVzc2FnZSA9IGluYm94W2tleV0KKyAgICBleGNlcHQgZW1haWwuRXJyb3JzLk1lc3NhZ2VQYXJzZUVycm9yOgorICAgICAgICBjb250aW51ZSAgICAgICAgICAgICAgICAjIFRoZSBtZXNzYWdlIGlzIG1hbGZvcm1lZC4gSnVzdCBsZWF2ZSBpdC4KKyAgICBmb3IgbmFtZSBpbiBsaXN0X25hbWVzOgorICAgICAgICBsaXN0X2lkID0gbWVzc2FnZVsnbGlzdC1pZCddCisgICAgICAgIGlmIGxpc3RfaWQgYW5kIG5hbWUgaW4gbGlzdF9pZDoKKyAgICAgICAgICAgIGJveCA9IGJveGVzW25hbWVdCisgICAgICAgICAgICBib3gubG9jaygpCisgICAgICAgICAgICBib3guYWRkKG1lc3NhZ2UpCisgICAgICAgICAgICBib3guZmx1c2goKSAgICAgICAgICMgV3JpdGUgY29weSB0byBkaXNrIGJlZm9yZSByZW1vdmluZyBvcmlnaW5hbC4KKyAgICAgICAgICAgIGJveC51bmxvY2soKQorICAgICAgICAgICAgaW5ib3guZGlzY2FyZChrZXkpCisgICAgICAgICAgICBicmVhayAgICAgICAgICAgICAgICMgRm91bmQgZGVzdGluYXRpb24sIHNvIHN0b3AgbG9va2luZy4KK2ZvciBib3ggaW4gYm94ZXMuaXRlcnZhbHVlcygpOgorICAgIGJveC5jbG9zZSgpCitcZW5ke3ZlcmJhdGltfQpkaWZmIC0tZ2l0IGEvTGliL21haWxib3gucHkgYi9MaWIvbWFpbGJveC5weQppbmRleCBjODljMWE0Li5hYzg3YTUxIDEwMDc1NQotLS0gYS9MaWIvbWFpbGJveC5weQorKysgYi9MaWIvbWFpbGJveC5weQpAQCAtMSwxMyArMSwxODg0IEBACiAjISAvdXNyL2Jpbi9lbnYgcHl0aG9uCiAKLSIiIkNsYXNzZXMgdG8gaGFuZGxlIFVuaXggc3R5bGUsIE1NREYgc3R5bGUsIGFuZCBNSCBzdHlsZSBtYWlsYm94ZXMuIiIiCisiIiJSZWFkL3dyaXRlIHN1cHBvcnQgZm9yIE1haWxkaXIsIG1ib3gsIE1ILCBCYWJ5bCwgYW5kIE1NREYgbWFpbGJveGVzLiIiIgogCi0KLWltcG9ydCByZmM4MjIKIGltcG9ydCBvcworaW1wb3J0IHRpbWUKK2ltcG9ydCBjYWxlbmRhcgoraW1wb3J0IHNvY2tldAoraW1wb3J0IGVycm5vCitpbXBvcnQgY29weQoraW1wb3J0IGVtYWlsCitpbXBvcnQgZW1haWwuTWVzc2FnZQoraW1wb3J0IGVtYWlsLkdlbmVyYXRvcgoraW1wb3J0IHJmYzgyMgoraW1wb3J0IFN0cmluZ0lPCit0cnk6CisgICAgaW1wb3J0IGZuY3RsCitleGNlcHQgSW1wb3J0RXJyb3I6CisgICAgZmNudGwgPSBOb25lCiAKLV9fYWxsX18gPSBbIlVuaXhNYWlsYm94IiwiTW1kZk1haWxib3giLCJNSE1haWxib3giLCJNYWlsZGlyIiwiQmFieWxNYWlsYm94IiwKLSAgICAgICAgICAgIlBvcnRhYmxlVW5peE1haWxib3giXQorX19hbGxfXyA9IFsgJ01haWxib3gnLCAnTWFpbGRpcicsICdtYm94JywgJ01IJywgJ0JhYnlsJywgJ01NREYnLAorICAgICAgICAgICAgJ01lc3NhZ2UnLCAnTWFpbGRpck1lc3NhZ2UnLCAnbWJveE1lc3NhZ2UnLCAnTUhNZXNzYWdlJywKKyAgICAgICAgICAgICdCYWJ5bE1lc3NhZ2UnLCAnTU1ERk1lc3NhZ2UnLCAnVW5peE1haWxib3gnLAorICAgICAgICAgICAgJ1BvcnRhYmxlVW5peE1haWxib3gnLCAnTW1kZk1haWxib3gnLCAnTUhNYWlsYm94JywgJ0JhYnlsTWFpbGJveCcgXQorCisKK2NsYXNzIE1haWxib3g6CisgICAgIiIiQSBncm91cCBvZiBtZXNzYWdlcyBpbiBhIHBhcnRpY3VsYXIgcGxhY2UuIiIiCisKKyAgICBkZWYgX19pbml0X18oc2VsZiwgcGF0aCwgZmFjdG9yeT1Ob25lLCBjcmVhdGU9VHJ1ZSk6CisgICAgICAgICIiIkluaXRpYWxpemUgYSBNYWlsYm94IGluc3RhbmNlLiIiIgorICAgICAgICBzZWxmLl9wYXRoID0gb3MucGF0aC5hYnNwYXRoKG9zLnBhdGguZXhwYW5kdXNlcihwYXRoKSkKKyAgICAgICAgc2VsZi5fZmFjdG9yeSA9IGZhY3RvcnkKKworICAgIGRlZiBhZGQoc2VsZiwgbWVzc2FnZSk6CisgICAgICAgICIiIkFkZCBtZXNzYWdlIGFuZCByZXR1cm4gYXNzaWduZWQga2V5LiIiIgorICAgICAgICByYWlzZSBOb3RJbXBsZW1lbnRlZEVycm9yKCdNZXRob2QgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBzdWJjbGFzcycpCisKKyAgICBkZWYgcmVtb3ZlKHNlbGYsIGtleSk6CisgICAgICAgICIiIlJlbW92ZSB0aGUga2V5ZWQgbWVzc2FnZTsgcmFpc2UgS2V5RXJyb3IgaWYgaXQgZG9lc24ndCBleGlzdC4iIiIKKyAgICAgICAgcmFpc2UgTm90SW1wbGVtZW50ZWRFcnJvcignTWV0aG9kIG11c3QgYmUgaW1wbGVtZW50ZWQgYnkgc3ViY2xhc3MnKQorCisgICAgZGVmIF9fZGVsaXRlbV9fKHNlbGYsIGtleSk6CisgICAgICAgIHNlbGYucmVtb3ZlKGtleSkKKworICAgIGRlZiBkaXNjYXJkKHNlbGYsIGtleSk6CisgICAgICAgICIiIklmIHRoZSBrZXllZCBtZXNzYWdlIGV4aXN0cywgcmVtb3ZlIGl0LiIiIgorICAgICAgICB0cnk6CisgICAgICAgICAgICBzZWxmLnJlbW92ZShrZXkpCisgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKKyAgICAgICAgICAgIHBhc3MKKworICAgIGRlZiBfX3NldGl0ZW1fXyhzZWxmLCBrZXksIG1lc3NhZ2UpOgorICAgICAgICAiIiJSZXBsYWNlIHRoZSBrZXllZCBtZXNzYWdlOyByYWlzZSBLZXlFcnJvciBpZiBpdCBkb2Vzbid0IGV4aXN0LiIiIgorICAgICAgICByYWlzZSBOb3RJbXBsZW1lbnRlZEVycm9yKCdNZXRob2QgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBzdWJjbGFzcycpCisKKyAgICBkZWYgZ2V0KHNlbGYsIGtleSwgZGVmYXVsdD1Ob25lKToKKyAgICAgICAgIiIiUmV0dXJuIHRoZSBrZXllZCBtZXNzYWdlLCBvciBkZWZhdWx0IGlmIGl0IGRvZXNuJ3QgZXhpc3QuIiIiCisgICAgICAgIHRyeToKKyAgICAgICAgICAgIHJldHVybiBzZWxmLl9fZ2V0aXRlbV9fKGtleSkKKyAgICAgICAgZXhjZXB0IEtleUVycm9yOgorICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHQKKworICAgIGRlZiBfX2dldGl0ZW1fXyhzZWxmLCBrZXkpOgorICAgICAgICAiIiJSZXR1cm4gdGhlIGtleWVkIG1lc3NhZ2U7IHJhaXNlIEtleUVycm9yIGlmIGl0IGRvZXNuJ3QgZXhpc3QuIiIiCisgICAgICAgIGlmIG5vdCBzZWxmLl9mYWN0b3J5OgorICAgICAgICAgICAgcmV0dXJuIHNlbGYuZ2V0X21lc3NhZ2Uoa2V5KQorICAgICAgICBlbHNlOgorICAgICAgICAgICAgcmV0dXJuIHNlbGYuX2ZhY3Rvcnkoc2VsZi5nZXRfZmlsZShrZXkpKQorCisgICAgZGVmIGdldF9tZXNzYWdlKHNlbGYsIGtleSk6CisgICAgICAgICIiIlJldHVybiBhIE1lc3NhZ2UgcmVwcmVzZW50YXRpb24gb3IgcmFpc2UgYSBLZXlFcnJvci4iIiIKKyAgICAgICAgcmFpc2UgTm90SW1wbGVtZW50ZWRFcnJvcignTWV0aG9kIG11c3QgYmUgaW1wbGVtZW50ZWQgYnkgc3ViY2xhc3MnKQorCisgICAgZGVmIGdldF9zdHJpbmcoc2VsZiwga2V5KToKKyAgICAgICAgIiIiUmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9yIHJhaXNlIGEgS2V5RXJyb3IuIiIiCisgICAgICAgIHJhaXNlIE5vdEltcGxlbWVudGVkRXJyb3IoJ01ldGhvZCBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IHN1YmNsYXNzJykKKworICAgIGRlZiBnZXRfZmlsZShzZWxmLCBrZXkpOgorICAgICAgICAiIiJSZXR1cm4gYSBmaWxlLWxpa2UgcmVwcmVzZW50YXRpb24gb3IgcmFpc2UgYSBLZXlFcnJvci4iIiIKKyAgICAgICAgcmFpc2UgTm90SW1wbGVtZW50ZWRFcnJvcignTWV0aG9kIG11c3QgYmUgaW1wbGVtZW50ZWQgYnkgc3ViY2xhc3MnKQorCisgICAgZGVmIGl0ZXJrZXlzKHNlbGYpOgorICAgICAgICAiIiJSZXR1cm4gYW4gaXRlcmF0b3Igb3ZlciBrZXlzLiIiIgorICAgICAgICByYWlzZSBOb3RJbXBsZW1lbnRlZEVycm9yKCdNZXRob2QgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBzdWJjbGFzcycpCisKKyAgICBkZWYga2V5cyhzZWxmKToKKyAgICAgICAgIiIiUmV0dXJuIGEgbGlzdCBvZiBrZXlzLiIiIgorICAgICAgICByZXR1cm4gbGlzdChzZWxmLml0ZXJrZXlzKCkpCisKKyAgICBkZWYgaXRlcnZhbHVlcyhzZWxmKToKKyAgICAgICAgIiIiUmV0dXJuIGFuIGl0ZXJhdG9yIG92ZXIgYWxsIG1lc3NhZ2VzLiIiIgorICAgICAgICBmb3Iga2V5IGluIHNlbGYuaXRlcmtleXMoKToKKyAgICAgICAgICAgIHRyeToKKyAgICAgICAgICAgICAgICB2YWx1ZSA9IHNlbGZba2V5XQorICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgorICAgICAgICAgICAgICAgIGNvbnRpbnVlCisgICAgICAgICAgICB5aWVsZCB2YWx1ZQorCisgICAgZGVmIF9faXRlcl9fKHNlbGYpOgorICAgICAgICByZXR1cm4gc2VsZi5pdGVydmFsdWVzKCkKKworICAgIGRlZiB2YWx1ZXMoc2VsZik6CisgICAgICAgICIiIlJldHVybiBhIGxpc3Qgb2YgbWVzc2FnZXMuIE1lbW9yeSBpbnRlbnNpdmUuIiIiCisgICAgICAgIHJldHVybiBsaXN0KHNlbGYuaXRlcnZhbHVlcygpKQorCisgICAgZGVmIGl0ZXJpdGVtcyhzZWxmKToKKyAgICAgICAgIiIiUmV0dXJuIGFuIGl0ZXJhdG9yIG92ZXIgKGtleSwgbWVzc2FnZSkgdHVwbGVzLiIiIgorICAgICAgICBmb3Iga2V5IGluIHNlbGYuaXRlcmtleXMoKToKKyAgICAgICAgICAgIHRyeToKKyAgICAgICAgICAgICAgICB2YWx1ZSA9IHNlbGZba2V5XQorICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgorICAgICAgICAgICAgICAgIGNvbnRpbnVlCisgICAgICAgICAgICB5aWVsZCAoa2V5LCB2YWx1ZSkKKworICAgIGRlZiBpdGVtcyhzZWxmKToKKyAgICAgICAgIiIiUmV0dXJuIGEgbGlzdCBvZiAoa2V5LCBtZXNzYWdlKSB0dXBsZXMuIE1lbW9yeSBpbnRlbnNpdmUuIiIiCisgICAgICAgIHJldHVybiBsaXN0KHNlbGYuaXRlcml0ZW1zKCkpCisKKyAgICBkZWYgaGFzX2tleShzZWxmLCBrZXkpOgorICAgICAgICAiIiJSZXR1cm4gVHJ1ZSBpZiB0aGUga2V5ZWQgbWVzc2FnZSBleGlzdHMsIEZhbHNlIG90aGVyd2lzZS4iIiIKKyAgICAgICAgcmFpc2UgTm90SW1wbGVtZW50ZWRFcnJvcignTWV0aG9kIG11c3QgYmUgaW1wbGVtZW50ZWQgYnkgc3ViY2xhc3MnKQorCisgICAgZGVmIF9fY29udGFpbnNfXyhzZWxmLCBrZXkpOgorICAgICAgICByZXR1cm4gc2VsZi5oYXNfa2V5KGtleSkKKworICAgIGRlZiBfX2xlbl9fKHNlbGYpOgorICAgICAgICAiIiJSZXR1cm4gYSBjb3VudCBvZiBtZXNzYWdlcyBpbiB0aGUgbWFpbGJveC4iIiIKKyAgICAgICAgcmFpc2UgTm90SW1wbGVtZW50ZWRFcnJvcignTWV0aG9kIG11c3QgYmUgaW1wbGVtZW50ZWQgYnkgc3ViY2xhc3MnKQorCisgICAgZGVmIGNsZWFyKHNlbGYpOgorICAgICAgICAiIiJEZWxldGUgYWxsIG1lc3NhZ2VzLiIiIgorICAgICAgICBmb3Iga2V5IGluIHNlbGYuaXRlcmtleXMoKToKKyAgICAgICAgICAgIHNlbGYuZGlzY2FyZChrZXkpCisKKyAgICBkZWYgcG9wKHNlbGYsIGtleSwgZGVmYXVsdD1Ob25lKToKKyAgICAgICAgIiIiRGVsZXRlIHRoZSBrZXllZCBtZXNzYWdlIGFuZCByZXR1cm4gaXQsIG9yIGRlZmF1bHQuIiIiCisgICAgICAgIHRyeToKKyAgICAgICAgICAgIHJlc3VsdCA9IHNlbGZba2V5XQorICAgICAgICBleGNlcHQgS2V5RXJyb3I6CisgICAgICAgICAgICByZXR1cm4gZGVmYXVsdAorICAgICAgICBzZWxmLmRpc2NhcmQoa2V5KQorICAgICAgICByZXR1cm4gcmVzdWx0CisKKyAgICBkZWYgcG9waXRlbShzZWxmKToKKyAgICAgICAgIiIiRGVsZXRlIGFuIGFyYml0cmFyeSAoa2V5LCBtZXNzYWdlKSBwYWlyIGFuZCByZXR1cm4gaXQuIiIiCisgICAgICAgIGZvciBrZXkgaW4gc2VsZi5pdGVya2V5cygpOgorICAgICAgICAgICAgcmV0dXJuIChrZXksIHNlbGYucG9wKGtleSkpICAgICAjIFRoaXMgaXMgb25seSBydW4gb25jZS4KKyAgICAgICAgZWxzZToKKyAgICAgICAgICAgIHJhaXNlIEtleUVycm9yKCdObyBtZXNzYWdlcyBpbiBtYWlsYm94JykKKworICAgIGRlZiB1cGRhdGUoc2VsZiwgYXJnPU5vbmUpOgorICAgICAgICAiIiJDaGFuZ2UgdGhlIG1lc3NhZ2VzIHRoYXQgY29ycmVzcG9uZCB0byBjZXJ0YWluIGtleXMuIiIiCisgICAgICAgIGlmIGhhc2F0dHIoYXJnLCAnaXRlcml0ZW1zJyk6CisgICAgICAgICAgICBzb3VyY2UgPSBhcmcuaXRlcml0ZW1zKCkKKyAgICAgICAgZWxpZiBoYXNhdHRyKGFyZywgJ2l0ZW1zJyk6CisgICAgICAgICAgICBzb3VyY2UgPSBhcmcuaXRlbXMoKQorICAgICAgICBlbHNlOgorICAgICAgICAgICAgc291cmNlID0gYXJnCisgICAgICAgIGJhZF9rZXkgPSBGYWxzZQorICAgICAgICBmb3Iga2V5LCBtZXNzYWdlIGluIHNvdXJjZToKKyAgICAgICAgICAgIHRyeToKKyAgICAgICAgICAgICAgICBzZWxmW2tleV0gPSBtZXNzYWdlCisgICAgICAgICAgICBleGNlcHQgS2V5RXJyb3I6CisgICAgICAgICAgICAgICAgYmFkX2tleSA9IFRydWUKKyAgICAgICAgaWYgYmFkX2tleToKKyAgICAgICAgICAgIHJhaXNlIEtleUVycm9yKCdObyBtZXNzYWdlIHdpdGgga2V5KHMpJykKKworICAgIGRlZiBmbHVzaChzZWxmKToKKyAgICAgICAgIiIiV3JpdGUgYW55IHBlbmRpbmcgY2hhbmdlcyB0byB0aGUgZGlzay4iIiIKKyAgICAgICAgcmFpc2UgTm90SW1wbGVtZW50ZWRFcnJvcignTWV0aG9kIG11c3QgYmUgaW1wbGVtZW50ZWQgYnkgc3ViY2xhc3MnKQorCisgICAgZGVmIGxvY2soc2VsZik6CisgICAgICAgICIiIkxvY2sgdGhlIG1haWxib3guIiIiCisgICAgICAgIHJhaXNlIE5vdEltcGxlbWVudGVkRXJyb3IoJ01ldGhvZCBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IHN1YmNsYXNzJykKKworICAgIGRlZiB1bmxvY2soc2VsZik6CisgICAgICAgICIiIlVubG9jayB0aGUgbWFpbGJveCBpZiBpdCBpcyBsb2NrZWQuIiIiCisgICAgICAgIHJhaXNlIE5vdEltcGxlbWVudGVkRXJyb3IoJ01ldGhvZCBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IHN1YmNsYXNzJykKKworICAgIGRlZiBjbG9zZShzZWxmKToKKyAgICAgICAgIiIiRmx1c2ggYW5kIGNsb3NlIHRoZSBtYWlsYm94LiIiIgorICAgICAgICByYWlzZSBOb3RJbXBsZW1lbnRlZEVycm9yKCdNZXRob2QgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBzdWJjbGFzcycpCisKKyAgICBkZWYgX2R1bXBfbWVzc2FnZShzZWxmLCBtZXNzYWdlLCB0YXJnZXQsIG1hbmdsZV9mcm9tXz1GYWxzZSk6CisgICAgICAgICMgTW9zdCBmaWxlcyBhcmUgb3BlbmVkIGluIGJpbmFyeSBtb2RlIHRvIGFsbG93IHByZWRpY3RhYmxlIHNlZWtpbmcuCisgICAgICAgICMgVG8gZ2V0IG5hdGl2ZSBsaW5lIGVuZGluZ3Mgb24gZGlzaywgdGhlIHVzZXItZnJpZW5kbHkgXG4gbGluZSBlbmRpbmdzCisgICAgICAgICMgdXNlZCBpbiBzdHJpbmdzIGFuZCBieSBlbWFpbC5NZXNzYWdlIGFyZSB0cmFuc2xhdGVkIGhlcmUuCisgICAgICAgICIiIkR1bXAgbWVzc2FnZSBjb250ZW50cyB0byB0YXJnZXQgZmlsZS4iIiIKKyAgICAgICAgaWYgaXNpbnN0YW5jZShtZXNzYWdlLCBlbWFpbC5NZXNzYWdlLk1lc3NhZ2UpOgorICAgICAgICAgICAgYnVmZmVyID0gU3RyaW5nSU8uU3RyaW5nSU8oKQorICAgICAgICAgICAgZ2VuID0gZW1haWwuR2VuZXJhdG9yLkdlbmVyYXRvcihidWZmZXIsIG1hbmdsZV9mcm9tXywgMCkKKyAgICAgICAgICAgIGdlbi5mbGF0dGVuKG1lc3NhZ2UpCisgICAgICAgICAgICBidWZmZXIuc2VlaygwKQorICAgICAgICAgICAgdGFyZ2V0LndyaXRlKGJ1ZmZlci5yZWFkKCkucmVwbGFjZSgnXG4nLCBvcy5saW5lc2VwKSkKKyAgICAgICAgZWxpZiBpc2luc3RhbmNlKG1lc3NhZ2UsIHN0cik6CisgICAgICAgICAgICBpZiBtYW5nbGVfZnJvbV86CisgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG1lc3NhZ2UucmVwbGFjZSgnXG5Gcm9tICcsICdcbj5Gcm9tICcpCisgICAgICAgICAgICBtZXNzYWdlID0gbWVzc2FnZS5yZXBsYWNlKCdcbicsIG9zLmxpbmVzZXApCisgICAgICAgICAgICB0YXJnZXQud3JpdGUobWVzc2FnZSkKKyAgICAgICAgZWxpZiBoYXNhdHRyKG1lc3NhZ2UsICdyZWFkJyk6CisgICAgICAgICAgICB3aGlsZSBUcnVlOgorICAgICAgICAgICAgICAgIGxpbmUgPSBtZXNzYWdlLnJlYWRsaW5lKCkKKyAgICAgICAgICAgICAgICBpZiBsaW5lID09ICcnOgorICAgICAgICAgICAgICAgICAgICBicmVhaworICAgICAgICAgICAgICAgIGlmIG1hbmdsZV9mcm9tXyBhbmQgbGluZS5zdGFydHN3aXRoKCdGcm9tICcpOgorICAgICAgICAgICAgICAgICAgICBsaW5lID0gJz5Gcm9tICcgKyBsaW5lWzU6XQorICAgICAgICAgICAgICAgIGxpbmUgPSBsaW5lLnJlcGxhY2UoJ1xuJywgb3MubGluZXNlcCkKKyAgICAgICAgICAgICAgICB0YXJnZXQud3JpdGUobGluZSkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICAgIHJhaXNlIFR5cGVFcnJvcignSW52YWxpZCBtZXNzYWdlIHR5cGU6ICVzJyAlIHR5cGUobWVzc2FnZSkpCisKKworY2xhc3MgTWFpbGRpcihNYWlsYm94KToKKyAgICAiIiJBIHFtYWlsLXN0eWxlIE1haWxkaXIgbWFpbGJveC4iIiIKKworICAgIGNvbG9uID0gJzonCisKKyAgICBkZWYgX19pbml0X18oc2VsZiwgZGlybmFtZSwgZmFjdG9yeT1yZmM4MjIuTWVzc2FnZSwgY3JlYXRlPVRydWUpOgorICAgICAgICAiIiJJbml0aWFsaXplIGEgTWFpbGRpciBpbnN0YW5jZS4iIiIKKyAgICAgICAgTWFpbGJveC5fX2luaXRfXyhzZWxmLCBkaXJuYW1lLCBmYWN0b3J5LCBjcmVhdGUpCisgICAgICAgIGlmIG5vdCBvcy5wYXRoLmV4aXN0cyhzZWxmLl9wYXRoKToKKyAgICAgICAgICAgIGlmIGNyZWF0ZToKKyAgICAgICAgICAgICAgICBvcy5ta2RpcihzZWxmLl9wYXRoLCAwNzAwKQorICAgICAgICAgICAgICAgIG9zLm1rZGlyKG9zLnBhdGguam9pbihzZWxmLl9wYXRoLCAndG1wJyksIDA3MDApCisgICAgICAgICAgICAgICAgb3MubWtkaXIob3MucGF0aC5qb2luKHNlbGYuX3BhdGgsICduZXcnKSwgMDcwMCkKKyAgICAgICAgICAgICAgICBvcy5ta2Rpcihvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgJ2N1cicpLCAwNzAwKQorICAgICAgICAgICAgZWxzZToKKyAgICAgICAgICAgICAgICByYWlzZSBOb1N1Y2hNYWlsYm94RXJyb3Ioc2VsZi5fcGF0aCkKKyAgICAgICAgc2VsZi5fdG9jID0ge30KKworICAgIGRlZiBhZGQoc2VsZiwgbWVzc2FnZSk6CisgICAgICAgICIiIkFkZCBtZXNzYWdlIGFuZCByZXR1cm4gYXNzaWduZWQga2V5LiIiIgorICAgICAgICB0bXBfZmlsZSA9IHNlbGYuX2NyZWF0ZV90bXAoKQorICAgICAgICB0cnk6CisgICAgICAgICAgICBzZWxmLl9kdW1wX21lc3NhZ2UobWVzc2FnZSwgdG1wX2ZpbGUpCisgICAgICAgIGZpbmFsbHk6CisgICAgICAgICAgICB0bXBfZmlsZS5jbG9zZSgpCisgICAgICAgIGlmIGlzaW5zdGFuY2UobWVzc2FnZSwgTWFpbGRpck1lc3NhZ2UpOgorICAgICAgICAgICAgc3ViZGlyID0gbWVzc2FnZS5nZXRfc3ViZGlyKCkKKyAgICAgICAgICAgIHN1ZmZpeCA9IHNlbGYuY29sb24gKyBtZXNzYWdlLmdldF9pbmZvKCkKKyAgICAgICAgICAgIGlmIHN1ZmZpeCA9PSBzZWxmLmNvbG9uOgorICAgICAgICAgICAgICAgIHN1ZmZpeCA9ICcnCisgICAgICAgIGVsc2U6CisgICAgICAgICAgICBzdWJkaXIgPSAnbmV3JworICAgICAgICAgICAgc3VmZml4ID0gJycKKyAgICAgICAgdW5pcSA9IG9zLnBhdGguYmFzZW5hbWUodG1wX2ZpbGUubmFtZSkuc3BsaXQoc2VsZi5jb2xvbilbMF0KKyAgICAgICAgZGVzdCA9IG9zLnBhdGguam9pbihzZWxmLl9wYXRoLCBzdWJkaXIsIHVuaXEgKyBzdWZmaXgpCisgICAgICAgIG9zLnJlbmFtZSh0bXBfZmlsZS5uYW1lLCBkZXN0KQorICAgICAgICBpZiBpc2luc3RhbmNlKG1lc3NhZ2UsIE1haWxkaXJNZXNzYWdlKToKKyAgICAgICAgICAgIG9zLnV0aW1lKGRlc3QsIChvcy5wYXRoLmdldGF0aW1lKGRlc3QpLCBtZXNzYWdlLmdldF9kYXRlKCkpKQorICAgICAgICByZXR1cm4gdW5pcQorCisgICAgZGVmIHJlbW92ZShzZWxmLCBrZXkpOgorICAgICAgICAiIiJSZW1vdmUgdGhlIGtleWVkIG1lc3NhZ2U7IHJhaXNlIEtleUVycm9yIGlmIGl0IGRvZXNuJ3QgZXhpc3QuIiIiCisgICAgICAgIG9zLnJlbW92ZShvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgc2VsZi5fbG9va3VwKGtleSkpKQorCisgICAgZGVmIGRpc2NhcmQoc2VsZiwga2V5KToKKyAgICAgICAgIiIiSWYgdGhlIGtleWVkIG1lc3NhZ2UgZXhpc3RzLCByZW1vdmUgaXQuIiIiCisgICAgICAgICMgVGhpcyBvdmVycmlkZXMgYW4gaW5hcHBsaWNhYmxlIGltcGxlbWVudGF0aW9uIGluIHRoZSBzdXBlcmNsYXNzLgorICAgICAgICB0cnk6CisgICAgICAgICAgICBzZWxmLnJlbW92ZShrZXkpCisgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKKyAgICAgICAgICAgIHBhc3MKKyAgICAgICAgZXhjZXB0IE9TRXJyb3IsIGU6CisgICAgICAgICAgICBpZiBlLmVycm5vID09IGVycm5vLkVOT0VOVDoKKyAgICAgICAgICAgICAgICBwYXNzCisgICAgICAgICAgICBlbHNlOgorICAgICAgICAgICAgICAgIHJhaXNlIAorCisgICAgZGVmIF9fc2V0aXRlbV9fKHNlbGYsIGtleSwgbWVzc2FnZSk6CisgICAgICAgICIiIlJlcGxhY2UgdGhlIGtleWVkIG1lc3NhZ2U7IHJhaXNlIEtleUVycm9yIGlmIGl0IGRvZXNuJ3QgZXhpc3QuIiIiCisgICAgICAgIG9sZF9zdWJwYXRoID0gc2VsZi5fbG9va3VwKGtleSkKKyAgICAgICAgdGVtcF9rZXkgPSBzZWxmLmFkZChtZXNzYWdlKQorICAgICAgICB0ZW1wX3N1YnBhdGggPSBzZWxmLl9sb29rdXAodGVtcF9rZXkpCisgICAgICAgIGlmIGlzaW5zdGFuY2UobWVzc2FnZSwgTWFpbGRpck1lc3NhZ2UpOgorICAgICAgICAgICAgIyB0ZW1wJ3Mgc3ViZGlyIGFuZCBzdWZmaXggd2VyZSBzcGVjaWZpZWQgYnkgbWVzc2FnZS4KKyAgICAgICAgICAgIGRvbWluYW50X3N1YnBhdGggPSB0ZW1wX3N1YnBhdGgKKyAgICAgICAgZWxzZToKKyAgICAgICAgICAgICMgdGVtcCdzIHN1YmRpciBhbmQgc3VmZml4IHdlcmUgZGVmYXVsdHMgZnJvbSBhZGQoKS4KKyAgICAgICAgICAgIGRvbWluYW50X3N1YnBhdGggPSBvbGRfc3VicGF0aAorICAgICAgICBzdWJkaXIgPSBvcy5wYXRoLmRpcm5hbWUoZG9taW5hbnRfc3VicGF0aCkKKyAgICAgICAgaWYgc2VsZi5jb2xvbiBpbiBkb21pbmFudF9zdWJwYXRoOgorICAgICAgICAgICAgc3VmZml4ID0gc2VsZi5jb2xvbiArIGRvbWluYW50X3N1YnBhdGguc3BsaXQoc2VsZi5jb2xvbilbLTFdCisgICAgICAgIGVsc2U6CisgICAgICAgICAgICBzdWZmaXggPSAnJworICAgICAgICBzZWxmLmRpc2NhcmQoa2V5KQorICAgICAgICBuZXdfcGF0aCA9IG9zLnBhdGguam9pbihzZWxmLl9wYXRoLCBzdWJkaXIsIGtleSArIHN1ZmZpeCkKKyAgICAgICAgb3MucmVuYW1lKG9zLnBhdGguam9pbihzZWxmLl9wYXRoLCB0ZW1wX3N1YnBhdGgpLCBuZXdfcGF0aCkKKyAgICAgICAgaWYgaXNpbnN0YW5jZShtZXNzYWdlLCBNYWlsZGlyTWVzc2FnZSk6CisgICAgICAgICAgICBvcy51dGltZShuZXdfcGF0aCwgKG9zLnBhdGguZ2V0YXRpbWUobmV3X3BhdGgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmdldF9kYXRlKCkpKQorCisgICAgZGVmIGdldF9tZXNzYWdlKHNlbGYsIGtleSk6CisgICAgICAgICIiIlJldHVybiBhIE1lc3NhZ2UgcmVwcmVzZW50YXRpb24gb3IgcmFpc2UgYSBLZXlFcnJvci4iIiIKKyAgICAgICAgc3VicGF0aCA9IHNlbGYuX2xvb2t1cChrZXkpCisgICAgICAgIGYgPSBmaWxlKG9zLnBhdGguam9pbihzZWxmLl9wYXRoLCBzdWJwYXRoKSwgJ3InKQorICAgICAgICB0cnk6CisgICAgICAgICAgICBtc2cgPSBNYWlsZGlyTWVzc2FnZShmKQorICAgICAgICBmaW5hbGx5OgorICAgICAgICAgICAgZi5jbG9zZSgpCisgICAgICAgIHN1YmRpciwgbmFtZSA9IG9zLnBhdGguc3BsaXQoc3VicGF0aCkKKyAgICAgICAgbXNnLnNldF9zdWJkaXIoc3ViZGlyKQorICAgICAgICBpZiBzZWxmLmNvbG9uIGluIG5hbWU6CisgICAgICAgICAgICBtc2cuc2V0X2luZm8obmFtZS5zcGxpdChzZWxmLmNvbG9uKVstMV0pCisgICAgICAgIG1zZy5zZXRfZGF0ZShvcy5wYXRoLmdldG10aW1lKG9zLnBhdGguam9pbihzZWxmLl9wYXRoLCBzdWJwYXRoKSkpCisgICAgICAgIHJldHVybiBtc2cKKworICAgIGRlZiBnZXRfc3RyaW5nKHNlbGYsIGtleSk6CisgICAgICAgICIiIlJldHVybiBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvciByYWlzZSBhIEtleUVycm9yLiIiIgorICAgICAgICBmID0gZmlsZShvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgc2VsZi5fbG9va3VwKGtleSkpLCAncicpCisgICAgICAgIHRyeToKKyAgICAgICAgICAgIHJldHVybiBmLnJlYWQoKQorICAgICAgICBmaW5hbGx5OgorICAgICAgICAgICAgZi5jbG9zZSgpCisKKyAgICBkZWYgZ2V0X2ZpbGUoc2VsZiwga2V5KToKKyAgICAgICAgIiIiUmV0dXJuIGEgZmlsZS1saWtlIHJlcHJlc2VudGF0aW9uIG9yIHJhaXNlIGEgS2V5RXJyb3IuIiIiCisgICAgICAgIGYgPSBmaWxlKG9zLnBhdGguam9pbihzZWxmLl9wYXRoLCBzZWxmLl9sb29rdXAoa2V5KSksICdyYicpCisgICAgICAgIHJldHVybiBfUHJveHlGaWxlKGYpCisKKyAgICBkZWYgaXRlcmtleXMoc2VsZik6CisgICAgICAgICIiIlJldHVybiBhbiBpdGVyYXRvciBvdmVyIGtleXMuIiIiCisgICAgICAgIHNlbGYuX3JlZnJlc2goKQorICAgICAgICBmb3Iga2V5IGluIHNlbGYuX3RvYzoKKyAgICAgICAgICAgIHRyeToKKyAgICAgICAgICAgICAgICBzZWxmLl9sb29rdXAoa2V5KQorICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgorICAgICAgICAgICAgICAgIGNvbnRpbnVlCisgICAgICAgICAgICB5aWVsZCBrZXkKKworICAgIGRlZiBoYXNfa2V5KHNlbGYsIGtleSk6CisgICAgICAgICIiIlJldHVybiBUcnVlIGlmIHRoZSBrZXllZCBtZXNzYWdlIGV4aXN0cywgRmFsc2Ugb3RoZXJ3aXNlLiIiIgorICAgICAgICBzZWxmLl9yZWZyZXNoKCkKKyAgICAgICAgcmV0dXJuIGtleSBpbiBzZWxmLl90b2MKKworICAgIGRlZiBfX2xlbl9fKHNlbGYpOgorICAgICAgICAiIiJSZXR1cm4gYSBjb3VudCBvZiBtZXNzYWdlcyBpbiB0aGUgbWFpbGJveC4iIiIKKyAgICAgICAgc2VsZi5fcmVmcmVzaCgpCisgICAgICAgIHJldHVybiBsZW4oc2VsZi5fdG9jKQorCisgICAgZGVmIGZsdXNoKHNlbGYpOgorICAgICAgICAiIiJXcml0ZSBhbnkgcGVuZGluZyBjaGFuZ2VzIHRvIGRpc2suIiIiCisgICAgICAgIHJldHVybiAgIyBNYWlsZGlyIGNoYW5nZXMgYXJlIGFsd2F5cyB3cml0dGVuIGltbWVkaWF0ZWx5LgorCisgICAgZGVmIGxvY2soc2VsZik6CisgICAgICAgICIiIkxvY2sgdGhlIG1haWxib3guIiIiCisgICAgICAgIHJldHVybgorCisgICAgZGVmIHVubG9jayhzZWxmKToKKyAgICAgICAgIiIiVW5sb2NrIHRoZSBtYWlsYm94IGlmIGl0IGlzIGxvY2tlZC4iIiIKKyAgICAgICAgcmV0dXJuCisKKyAgICBkZWYgY2xvc2Uoc2VsZik6CisgICAgICAgICIiIkZsdXNoIGFuZCBjbG9zZSB0aGUgbWFpbGJveC4iIiIKKyAgICAgICAgcmV0dXJuCisKKyAgICBkZWYgbGlzdF9mb2xkZXJzKHNlbGYpOgorICAgICAgICAiIiJSZXR1cm4gYSBsaXN0IG9mIGZvbGRlciBuYW1lcy4iIiIKKyAgICAgICAgcmVzdWx0ID0gW10KKyAgICAgICAgZm9yIGVudHJ5IGluIG9zLmxpc3RkaXIoc2VsZi5fcGF0aCk6CisgICAgICAgICAgICBpZiBsZW4oZW50cnkpID4gMSBhbmQgZW50cnlbMF0gPT0gJy4nIGFuZCBcCisgICAgICAgICAgICAgICBvcy5wYXRoLmlzZGlyKG9zLnBhdGguam9pbihzZWxmLl9wYXRoLCBlbnRyeSkpOgorICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoZW50cnlbMTpdKQorICAgICAgICByZXR1cm4gcmVzdWx0CisKKyAgICBkZWYgZ2V0X2ZvbGRlcihzZWxmLCBmb2xkZXIpOgorICAgICAgICAiIiJSZXR1cm4gYSBNYWlsZGlyIGluc3RhbmNlIGZvciB0aGUgbmFtZWQgZm9sZGVyLiIiIgorICAgICAgICByZXR1cm4gTWFpbGRpcihvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgJy4nICsgZm9sZGVyKSwgY3JlYXRlPUZhbHNlKQorCisgICAgZGVmIGFkZF9mb2xkZXIoc2VsZiwgZm9sZGVyKToKKyAgICAgICAgIiIiQ3JlYXRlIGEgZm9sZGVyIGFuZCByZXR1cm4gYSBNYWlsZGlyIGluc3RhbmNlIHJlcHJlc2VudGluZyBpdC4iIiIKKyAgICAgICAgcGF0aCA9IG9zLnBhdGguam9pbihzZWxmLl9wYXRoLCAnLicgKyBmb2xkZXIpCisgICAgICAgIHJlc3VsdCA9IE1haWxkaXIocGF0aCkKKyAgICAgICAgbWFpbGRpcmZvbGRlcl9wYXRoID0gb3MucGF0aC5qb2luKHBhdGgsICdtYWlsZGlyZm9sZGVyJykKKyAgICAgICAgaWYgbm90IG9zLnBhdGguZXhpc3RzKG1haWxkaXJmb2xkZXJfcGF0aCk6CisgICAgICAgICAgICBvcy5jbG9zZShvcy5vcGVuKG1haWxkaXJmb2xkZXJfcGF0aCwgb3MuT19DUkVBVCB8IG9zLk9fV1JPTkxZKSkKKyAgICAgICAgcmV0dXJuIHJlc3VsdAorCisgICAgZGVmIHJlbW92ZV9mb2xkZXIoc2VsZiwgZm9sZGVyKToKKyAgICAgICAgIiIiRGVsZXRlIHRoZSBuYW1lZCBmb2xkZXIsIHdoaWNoIG11c3QgYmUgZW1wdHkuIiIiCisgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgJy4nICsgZm9sZGVyKQorICAgICAgICBmb3IgZW50cnkgaW4gb3MubGlzdGRpcihvcy5wYXRoLmpvaW4ocGF0aCwgJ25ldycpKSArIFwKKyAgICAgICAgICAgICAgICAgICAgIG9zLmxpc3RkaXIob3MucGF0aC5qb2luKHBhdGgsICdjdXInKSk6CisgICAgICAgICAgICBpZiBsZW4oZW50cnkpIDwgMSBvciBlbnRyeVswXSAhPSAnLic6CisgICAgICAgICAgICAgICAgcmFpc2UgTm90RW1wdHlFcnJvcignRm9sZGVyIGNvbnRhaW5zIG1lc3NhZ2Uocyk6ICVzJyAlIGZvbGRlcikKKyAgICAgICAgZm9yIGVudHJ5IGluIG9zLmxpc3RkaXIocGF0aCk6CisgICAgICAgICAgICBpZiBlbnRyeSAhPSAnbmV3JyBhbmQgZW50cnkgIT0gJ2N1cicgYW5kIGVudHJ5ICE9ICd0bXAnIGFuZCBcCisgICAgICAgICAgICAgICBvcy5wYXRoLmlzZGlyKG9zLnBhdGguam9pbihwYXRoLCBlbnRyeSkpOgorICAgICAgICAgICAgICAgIHJhaXNlIE5vdEVtcHR5RXJyb3IoIkZvbGRlciBjb250YWlucyBzdWJkaXJlY3RvcnkgJyVzJzogJXMiICUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmb2xkZXIsIGVudHJ5KSkKKyAgICAgICAgZm9yIHJvb3QsIGRpcnMsIGZpbGVzIGluIG9zLndhbGsocGF0aCwgdG9wZG93bj1GYWxzZSk6CisgICAgICAgICAgICBmb3IgZW50cnkgaW4gZmlsZXM6CisgICAgICAgICAgICAgICAgb3MucmVtb3ZlKG9zLnBhdGguam9pbihyb290LCBlbnRyeSkpCisgICAgICAgICAgICBmb3IgZW50cnkgaW4gZGlyczoKKyAgICAgICAgICAgICAgICBvcy5ybWRpcihvcy5wYXRoLmpvaW4ocm9vdCwgZW50cnkpKQorICAgICAgICBvcy5ybWRpcihwYXRoKQorCisgICAgZGVmIGNsZWFuKHNlbGYpOgorICAgICAgICAiIiJEZWxldGUgb2xkIGZpbGVzIGluICJ0bXAiLiIiIgorICAgICAgICBub3cgPSB0aW1lLnRpbWUoKQorICAgICAgICBmb3IgZW50cnkgaW4gb3MubGlzdGRpcihvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgJ3RtcCcpKToKKyAgICAgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgJ3RtcCcsIGVudHJ5KQorICAgICAgICAgICAgaWYgbm93IC0gb3MucGF0aC5nZXRhdGltZShwYXRoKSA+IDEyOTYwMDogICAjIDYwICogNjAgKiAzNgorICAgICAgICAgICAgICAgIG9zLnJlbW92ZShwYXRoKQorCisgICAgX2NvdW50ID0gMSAgIyBUaGlzIGlzIHVzZWQgdG8gZ2VuZXJhdGUgdW5pcXVlIGZpbGUgbmFtZXMuCisKKyAgICBkZWYgX2NyZWF0ZV90bXAoc2VsZik6CisgICAgICAgICIiIkNyZWF0ZSBhIGZpbGUgaW4gdGhlIHRtcCBzdWJkaXJlY3RvcnkgYW5kIG9wZW4gYW5kIHJldHVybiBpdC4iIiIKKyAgICAgICAgbm93ID0gdGltZS50aW1lKCkKKyAgICAgICAgaG9zdG5hbWUgPSBzb2NrZXQuZ2V0aG9zdG5hbWUoKQorICAgICAgICBpZiAnLycgaW4gaG9zdG5hbWU6CisgICAgICAgICAgICBob3N0bmFtZSA9IGhvc3RuYW1lLnJlcGxhY2UoJy8nLCByJ1wwNTcnKQorICAgICAgICBpZiAnOicgaW4gaG9zdG5hbWU6CisgICAgICAgICAgICBob3N0bmFtZSA9IGhvc3RuYW1lLnJlcGxhY2UoJzonLCByJ1wwNzInKQorICAgICAgICB1bmlxID0gIiVzLk0lc1Alc1Elcy4lcyIgJSAoaW50KG5vdyksIGludChub3cgJSAxICogMWU2KSwgb3MuZ2V0cGlkKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWlsZGlyLl9jb3VudCwgaG9zdG5hbWUpCisgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgJ3RtcCcsIHVuaXEpCisgICAgICAgIHRyeToKKyAgICAgICAgICAgIG9zLnN0YXQocGF0aCkKKyAgICAgICAgZXhjZXB0IE9TRXJyb3IsIGU6CisgICAgICAgICAgICBpZiBlLmVycm5vID09IGVycm5vLkVOT0VOVDoKKyAgICAgICAgICAgICAgICBNYWlsZGlyLl9jb3VudCArPSAxCisgICAgICAgICAgICAgICAgcmV0dXJuIGZpbGUocGF0aCwgJ3diKycpCisgICAgICAgICAgICBlbHNlOgorICAgICAgICAgICAgICAgIHJhaXNlCisgICAgICAgIGVsc2U6CisgICAgICAgICAgICByYWlzZSBFeHRlcm5hbENsYXNoRXJyb3IoJ05hbWUgY2xhc2ggcHJldmVudGVkIGZpbGUgY3JlYXRpb246ICVzJyAlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aCkKKworICAgIGRlZiBfcmVmcmVzaChzZWxmKToKKyAgICAgICAgIiIiVXBkYXRlIHRhYmxlIG9mIGNvbnRlbnRzIG1hcHBpbmcuIiIiCisgICAgICAgIHNlbGYuX3RvYyA9IHt9CisgICAgICAgIGZvciBzdWJkaXIgaW4gKCduZXcnLCAnY3VyJyk6CisgICAgICAgICAgICBmb3IgZW50cnkgaW4gb3MubGlzdGRpcihvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgc3ViZGlyKSk6CisgICAgICAgICAgICAgICAgdW5pcSA9IGVudHJ5LnNwbGl0KHNlbGYuY29sb24pWzBdCisgICAgICAgICAgICAgICAgc2VsZi5fdG9jW3VuaXFdID0gb3MucGF0aC5qb2luKHN1YmRpciwgZW50cnkpCisKKyAgICBkZWYgX2xvb2t1cChzZWxmLCBrZXkpOgorICAgICAgICAiIiJVc2UgVE9DIHRvIHJldHVybiBzdWJwYXRoIGZvciBnaXZlbiBrZXksIG9yIHJhaXNlIGEgS2V5RXJyb3IuIiIiCisgICAgICAgIHRyeToKKyAgICAgICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKG9zLnBhdGguam9pbihzZWxmLl9wYXRoLCBzZWxmLl90b2Nba2V5XSkpOgorICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLl90b2Nba2V5XQorICAgICAgICBleGNlcHQgS2V5RXJyb3I6CisgICAgICAgICAgICBwYXNzCisgICAgICAgIHNlbGYuX3JlZnJlc2goKQorICAgICAgICB0cnk6CisgICAgICAgICAgICByZXR1cm4gc2VsZi5fdG9jW2tleV0KKyAgICAgICAgZXhjZXB0IEtleUVycm9yOgorICAgICAgICAgICAgcmFpc2UgS2V5RXJyb3IoJ05vIG1lc3NhZ2Ugd2l0aCBrZXk6ICVzJyAlIGtleSkKKworICAgICMgVGhpcyBtZXRob2QgaXMgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgb25seS4KKyAgICBkZWYgbmV4dChzZWxmKToKKyAgICAgICAgIiIiUmV0dXJuIHRoZSBuZXh0IG1lc3NhZ2UgaW4gYSBvbmUtdGltZSBpdGVyYXRpb24uIiIiCisgICAgICAgIGlmIG5vdCBoYXNhdHRyKHNlbGYsICdfb25ldGltZV9rZXlzJyk6CisgICAgICAgICAgICBzZWxmLl9vbmV0aW1lX2tleXMgPSBzZWxmLml0ZXJrZXlzKCkKKyAgICAgICAgd2hpbGUgVHJ1ZToKKyAgICAgICAgICAgIHRyeToKKyAgICAgICAgICAgICAgICByZXR1cm4gc2VsZltzZWxmLl9vbmV0aW1lX2tleXMubmV4dCgpXQorICAgICAgICAgICAgZXhjZXB0IFN0b3BJdGVyYXRpb246CisgICAgICAgICAgICAgICAgcmV0dXJuIE5vbmUKKyAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKKyAgICAgICAgICAgICAgICBjb250aW51ZQorCisKK2NsYXNzIF9zaW5nbGVmaWxlTWFpbGJveChNYWlsYm94KToKKyAgICAiIiJBIHNpbmdsZS1maWxlIG1haWxib3guIiIiCisKKyAgICBkZWYgX19pbml0X18oc2VsZiwgcGF0aCwgZmFjdG9yeT1Ob25lLCBjcmVhdGU9VHJ1ZSk6CisgICAgICAgICIiIkluaXRpYWxpemUgYSBzaW5nbGUtZmlsZSBtYWlsYm94LiIiIgorICAgICAgICBNYWlsYm94Ll9faW5pdF9fKHNlbGYsIHBhdGgsIGZhY3RvcnksIGNyZWF0ZSkKKyAgICAgICAgdHJ5OgorICAgICAgICAgICAgZiA9IGZpbGUoc2VsZi5fcGF0aCwgJ3JiKycpCisgICAgICAgIGV4Y2VwdCBJT0Vycm9yLCBlOgorICAgICAgICAgICAgaWYgZS5lcnJubyA9PSBlcnJuby5FTk9FTlQ6CisgICAgICAgICAgICAgICAgaWYgY3JlYXRlOgorICAgICAgICAgICAgICAgICAgICBmID0gZmlsZShzZWxmLl9wYXRoLCAnd2IrJykKKyAgICAgICAgICAgICAgICBlbHNlOgorICAgICAgICAgICAgICAgICAgICByYWlzZSBOb1N1Y2hNYWlsYm94RXJyb3Ioc2VsZi5fcGF0aCkKKyAgICAgICAgICAgIGVsaWYgZS5lcnJubyA9PSBlcnJuby5FQUNDRVM6CisgICAgICAgICAgICAgICAgZiA9IGZpbGUoc2VsZi5fcGF0aCwgJ3JiJykKKyAgICAgICAgICAgIGVsc2U6CisgICAgICAgICAgICAgICAgcmFpc2UKKyAgICAgICAgc2VsZi5fZmlsZSA9IGYKKyAgICAgICAgc2VsZi5fdG9jID0gTm9uZQorICAgICAgICBzZWxmLl9uZXh0X2tleSA9IDAKKyAgICAgICAgc2VsZi5fcGVuZGluZyA9IEZhbHNlICAgIyBObyBjaGFuZ2VzIHJlcXVpcmUgcmV3cml0aW5nIHRoZSBmaWxlLgorICAgICAgICBzZWxmLl9sb2NrZWQgPSBGYWxzZQorCisgICAgZGVmIGFkZChzZWxmLCBtZXNzYWdlKToKKyAgICAgICAgIiIiQWRkIG1lc3NhZ2UgYW5kIHJldHVybiBhc3NpZ25lZCBrZXkuIiIiCisgICAgICAgIHNlbGYuX2xvb2t1cCgpCisgICAgICAgIHNlbGYuX3RvY1tzZWxmLl9uZXh0X2tleV0gPSBzZWxmLl9hcHBlbmRfbWVzc2FnZShtZXNzYWdlKQorICAgICAgICBzZWxmLl9uZXh0X2tleSArPSAxCisgICAgICAgIHNlbGYuX3BlbmRpbmcgPSBUcnVlCisgICAgICAgIHJldHVybiBzZWxmLl9uZXh0X2tleSAtIDEKKworICAgIGRlZiByZW1vdmUoc2VsZiwga2V5KToKKyAgICAgICAgIiIiUmVtb3ZlIHRoZSBrZXllZCBtZXNzYWdlOyByYWlzZSBLZXlFcnJvciBpZiBpdCBkb2Vzbid0IGV4aXN0LiIiIgorICAgICAgICBzZWxmLl9sb29rdXAoa2V5KQorICAgICAgICBkZWwgc2VsZi5fdG9jW2tleV0KKyAgICAgICAgc2VsZi5fcGVuZGluZyA9IFRydWUKKworICAgIGRlZiBfX3NldGl0ZW1fXyhzZWxmLCBrZXksIG1lc3NhZ2UpOgorICAgICAgICAiIiJSZXBsYWNlIHRoZSBrZXllZCBtZXNzYWdlOyByYWlzZSBLZXlFcnJvciBpZiBpdCBkb2Vzbid0IGV4aXN0LiIiIgorICAgICAgICBzZWxmLl9sb29rdXAoa2V5KQorICAgICAgICBzZWxmLl90b2Nba2V5XSA9IHNlbGYuX2FwcGVuZF9tZXNzYWdlKG1lc3NhZ2UpCisgICAgICAgIHNlbGYuX3BlbmRpbmcgPSBUcnVlCisKKyAgICBkZWYgaXRlcmtleXMoc2VsZik6CisgICAgICAgICIiIlJldHVybiBhbiBpdGVyYXRvciBvdmVyIGtleXMuIiIiCisgICAgICAgIHNlbGYuX2xvb2t1cCgpCisgICAgICAgIGZvciBrZXkgaW4gc2VsZi5fdG9jLmtleXMoKToKKyAgICAgICAgICAgIHlpZWxkIGtleQorCisgICAgZGVmIGhhc19rZXkoc2VsZiwga2V5KToKKyAgICAgICAgIiIiUmV0dXJuIFRydWUgaWYgdGhlIGtleWVkIG1lc3NhZ2UgZXhpc3RzLCBGYWxzZSBvdGhlcndpc2UuIiIiCisgICAgICAgIHNlbGYuX2xvb2t1cCgpCisgICAgICAgIHJldHVybiBrZXkgaW4gc2VsZi5fdG9jCisKKyAgICBkZWYgX19sZW5fXyhzZWxmKToKKyAgICAgICAgIiIiUmV0dXJuIGEgY291bnQgb2YgbWVzc2FnZXMgaW4gdGhlIG1haWxib3guIiIiCisgICAgICAgIHNlbGYuX2xvb2t1cCgpCisgICAgICAgIHJldHVybiBsZW4oc2VsZi5fdG9jKQorCisgICAgZGVmIGxvY2soc2VsZik6CisgICAgICAgICIiIkxvY2sgdGhlIG1haWxib3guIiIiCisgICAgICAgIGlmIG5vdCBzZWxmLl9sb2NrZWQ6CisgICAgICAgICAgICBfbG9ja19maWxlKHNlbGYuX2ZpbGUpCisgICAgICAgICAgICBzZWxmLl9sb2NrZWQgPSBUcnVlCisKKyAgICBkZWYgdW5sb2NrKHNlbGYpOgorICAgICAgICAiIiJVbmxvY2sgdGhlIG1haWxib3ggaWYgaXQgaXMgbG9ja2VkLiIiIgorICAgICAgICBpZiBzZWxmLl9sb2NrZWQ6CisgICAgICAgICAgICBfdW5sb2NrX2ZpbGUoc2VsZi5fZmlsZSkKKyAgICAgICAgICAgIHNlbGYuX2xvY2tlZCA9IEZhbHNlCisKKyAgICBkZWYgZmx1c2goc2VsZik6CisgICAgICAgICIiIldyaXRlIGFueSBwZW5kaW5nIGNoYW5nZXMgdG8gZGlzay4iIiIKKyAgICAgICAgaWYgbm90IHNlbGYuX3BlbmRpbmc6CisgICAgICAgICAgICByZXR1cm4KKyAgICAgICAgc2VsZi5fbG9va3VwKCkKKyAgICAgICAgbmV3X2ZpbGUgPSBfY3JlYXRlX3RlbXBvcmFyeShzZWxmLl9wYXRoKQorICAgICAgICB0cnk6CisgICAgICAgICAgICBuZXdfdG9jID0ge30KKyAgICAgICAgICAgIHNlbGYuX3ByZV9tYWlsYm94X2hvb2sobmV3X2ZpbGUpCisgICAgICAgICAgICBmb3Iga2V5IGluIHNvcnRlZChzZWxmLl90b2Mua2V5cygpKToKKyAgICAgICAgICAgICAgICBzdGFydCwgc3RvcCA9IHNlbGYuX3RvY1trZXldCisgICAgICAgICAgICAgICAgc2VsZi5fZmlsZS5zZWVrKHN0YXJ0KQorICAgICAgICAgICAgICAgIHNlbGYuX3ByZV9tZXNzYWdlX2hvb2sobmV3X2ZpbGUpCisgICAgICAgICAgICAgICAgbmV3X3N0YXJ0ID0gbmV3X2ZpbGUudGVsbCgpCisgICAgICAgICAgICAgICAgd2hpbGUgVHJ1ZToKKyAgICAgICAgICAgICAgICAgICAgYnVmZmVyID0gc2VsZi5fZmlsZS5yZWFkKG1pbig0MDk2LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0b3AgLSBzZWxmLl9maWxlLnRlbGwoKSkpCisgICAgICAgICAgICAgICAgICAgIGlmIGJ1ZmZlciA9PSAnJzoKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrCisgICAgICAgICAgICAgICAgICAgIG5ld19maWxlLndyaXRlKGJ1ZmZlcikKKyAgICAgICAgICAgICAgICBuZXdfdG9jW2tleV0gPSAobmV3X3N0YXJ0LCBuZXdfZmlsZS50ZWxsKCkpCisgICAgICAgICAgICAgICAgc2VsZi5fcG9zdF9tZXNzYWdlX2hvb2sobmV3X2ZpbGUpCisgICAgICAgIGV4Y2VwdDoKKyAgICAgICAgICAgIG5ld19maWxlLmNsb3NlKCkKKyAgICAgICAgICAgIG9zLnJlbW92ZShuZXdfZmlsZS5uYW1lKQorICAgICAgICAgICAgcmFpc2UKKyAgICAgICAgbmV3X2ZpbGUuY2xvc2UoKQorICAgICAgICBzZWxmLl9maWxlLmNsb3NlKCkKKyAgICAgICAgdHJ5OgorICAgICAgICAgICAgb3MucmVuYW1lKG5ld19maWxlLm5hbWUsIHNlbGYuX3BhdGgpCisgICAgICAgIGV4Y2VwdCBPU0Vycm9yLCBlOgorICAgICAgICAgICAgaWYgZS5lcnJubyA9PSBlcnJuby5FRVhJU1Q6CisgICAgICAgICAgICAgICAgb3MucmVtb3ZlKHNlbGYuX3BhdGgpCisgICAgICAgICAgICAgICAgb3MucmVuYW1lKG5ld19maWxlLm5hbWUsIHNlbGYuX3BhdGgpCisgICAgICAgICAgICBlbHNlOgorICAgICAgICAgICAgICAgIHJhaXNlCisgICAgICAgIHNlbGYuX2ZpbGUgPSBmaWxlKHNlbGYuX3BhdGgsICdyYisnKQorICAgICAgICBzZWxmLl90b2MgPSBuZXdfdG9jCisgICAgICAgIHNlbGYuX3BlbmRpbmcgPSBGYWxzZQorICAgICAgICBpZiBzZWxmLl9sb2NrZWQ6CisgICAgICAgICAgICBfbG9ja19maWxlKG5ld19maWxlLCBkb3Rsb2NrPUZhbHNlKQorCisgICAgZGVmIF9wcmVfbWFpbGJveF9ob29rKHNlbGYsIGYpOgorICAgICAgICAiIiJDYWxsZWQgYmVmb3JlIHdyaXRpbmcgdGhlIG1haWxib3ggdG8gZmlsZSBmLiIiIgorICAgICAgICByZXR1cm4KKworICAgIGRlZiBfcHJlX21lc3NhZ2VfaG9vayhzZWxmLCBmKToKKyAgICAgICAgIiIiQ2FsbGVkIGJlZm9yZSB3cml0aW5nIGVhY2ggbWVzc2FnZSB0byBmaWxlIGYuIiIiCisgICAgICAgIHJldHVybgorCisgICAgZGVmIF9wb3N0X21lc3NhZ2VfaG9vayhzZWxmLCBmKToKKyAgICAgICAgIiIiQ2FsbGVkIGFmdGVyIHdyaXRpbmcgZWFjaCBtZXNzYWdlIHRvIGZpbGUgZi4iIiIKKyAgICAgICAgcmV0dXJuCisKKyAgICBkZWYgY2xvc2Uoc2VsZik6CisgICAgICAgICIiIkZsdXNoIGFuZCBjbG9zZSB0aGUgbWFpbGJveC4iIiIKKyAgICAgICAgc2VsZi5mbHVzaCgpCisgICAgICAgIGlmIHNlbGYuX2xvY2tlZDoKKyAgICAgICAgICAgIHNlbGYudW5sb2NrKCkKKyAgICAgICAgc2VsZi5fZmlsZS5jbG9zZSgpCisKKyAgICBkZWYgX2xvb2t1cChzZWxmLCBrZXk9Tm9uZSk6CisgICAgICAgICIiIlJldHVybiAoc3RhcnQsIHN0b3ApIG9yIHJhaXNlIEtleUVycm9yLiIiIgorICAgICAgICBpZiBzZWxmLl90b2MgaXMgTm9uZToKKyAgICAgICAgICAgIHNlbGYuX2dlbmVyYXRlX3RvYygpCisgICAgICAgIGlmIGtleSBpcyBub3QgTm9uZToKKyAgICAgICAgICAgIHRyeToKKyAgICAgICAgICAgICAgICByZXR1cm4gc2VsZi5fdG9jW2tleV0KKyAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKKyAgICAgICAgICAgICAgICByYWlzZSBLZXlFcnJvcignTm8gbWVzc2FnZSB3aXRoIGtleTogJXMnICUga2V5KQorCisgICAgZGVmIF9hcHBlbmRfbWVzc2FnZShzZWxmLCBtZXNzYWdlKToKKyAgICAgICAgIiIiQXBwZW5kIG1lc3NhZ2UgdG8gbWFpbGJveCBhbmQgcmV0dXJuIChzdGFydCwgc3RvcCkgb2Zmc2V0cy4iIiIKKyAgICAgICAgc2VsZi5fZmlsZS5zZWVrKDAsIDIpCisgICAgICAgIHNlbGYuX3ByZV9tZXNzYWdlX2hvb2soc2VsZi5fZmlsZSkKKyAgICAgICAgb2Zmc2V0cyA9IHNlbGYuX2luc3RhbGxfbWVzc2FnZShtZXNzYWdlKQorICAgICAgICBzZWxmLl9wb3N0X21lc3NhZ2VfaG9vayhzZWxmLl9maWxlKQorICAgICAgICBzZWxmLl9maWxlLmZsdXNoKCkKKyAgICAgICAgcmV0dXJuIG9mZnNldHMKKworCisKK2NsYXNzIF9tYm94TU1ERihfc2luZ2xlZmlsZU1haWxib3gpOgorICAgICIiIkFuIG1ib3ggb3IgTU1ERiBtYWlsYm94LiIiIgorCisgICAgX21hbmdsZV9mcm9tXyA9IFRydWUKKworICAgIGRlZiBnZXRfbWVzc2FnZShzZWxmLCBrZXkpOgorICAgICAgICAiIiJSZXR1cm4gYSBNZXNzYWdlIHJlcHJlc2VudGF0aW9uIG9yIHJhaXNlIGEgS2V5RXJyb3IuIiIiCisgICAgICAgIHN0YXJ0LCBzdG9wID0gc2VsZi5fbG9va3VwKGtleSkKKyAgICAgICAgc2VsZi5fZmlsZS5zZWVrKHN0YXJ0KQorICAgICAgICBmcm9tX2xpbmUgPSBzZWxmLl9maWxlLnJlYWRsaW5lKCkucmVwbGFjZShvcy5saW5lc2VwLCAnJykKKyAgICAgICAgc3RyaW5nID0gc2VsZi5fZmlsZS5yZWFkKHN0b3AgLSBzZWxmLl9maWxlLnRlbGwoKSkKKyAgICAgICAgbXNnID0gc2VsZi5fbWVzc2FnZV9mYWN0b3J5KHN0cmluZy5yZXBsYWNlKG9zLmxpbmVzZXAsICdcbicpKQorICAgICAgICBtc2cuc2V0X2Zyb20oZnJvbV9saW5lWzU6XSkKKyAgICAgICAgcmV0dXJuIG1zZworCisgICAgZGVmIGdldF9zdHJpbmcoc2VsZiwga2V5LCBmcm9tXz1GYWxzZSk6CisgICAgICAgICIiIlJldHVybiBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvciByYWlzZSBhIEtleUVycm9yLiIiIgorICAgICAgICBzdGFydCwgc3RvcCA9IHNlbGYuX2xvb2t1cChrZXkpCisgICAgICAgIHNlbGYuX2ZpbGUuc2VlayhzdGFydCkKKyAgICAgICAgaWYgbm90IGZyb21fOgorICAgICAgICAgICAgc2VsZi5fZmlsZS5yZWFkbGluZSgpCisgICAgICAgIHN0cmluZyA9IHNlbGYuX2ZpbGUucmVhZChzdG9wIC0gc2VsZi5fZmlsZS50ZWxsKCkpCisgICAgICAgIHJldHVybiBzdHJpbmcucmVwbGFjZShvcy5saW5lc2VwLCAnXG4nKQorCisgICAgZGVmIGdldF9maWxlKHNlbGYsIGtleSwgZnJvbV89RmFsc2UpOgorICAgICAgICAiIiJSZXR1cm4gYSBmaWxlLWxpa2UgcmVwcmVzZW50YXRpb24gb3IgcmFpc2UgYSBLZXlFcnJvci4iIiIKKyAgICAgICAgc3RhcnQsIHN0b3AgPSBzZWxmLl9sb29rdXAoa2V5KQorICAgICAgICBzZWxmLl9maWxlLnNlZWsoc3RhcnQpCisgICAgICAgIGlmIG5vdCBmcm9tXzoKKyAgICAgICAgICAgIHNlbGYuX2ZpbGUucmVhZGxpbmUoKQorICAgICAgICByZXR1cm4gX1BhcnRpYWxGaWxlKHNlbGYuX2ZpbGUsIHNlbGYuX2ZpbGUudGVsbCgpLCBzdG9wKQorCisgICAgZGVmIF9pbnN0YWxsX21lc3NhZ2Uoc2VsZiwgbWVzc2FnZSk6CisgICAgICAgICIiIkZvcm1hdCBhIG1lc3NhZ2UgYW5kIGJsaW5kbHkgd3JpdGUgdG8gc2VsZi5fZmlsZS4iIiIKKyAgICAgICAgZnJvbV9saW5lID0gTm9uZQorICAgICAgICBpZiBpc2luc3RhbmNlKG1lc3NhZ2UsIHN0cikgYW5kIG1lc3NhZ2Uuc3RhcnRzd2l0aCgnRnJvbSAnKToKKyAgICAgICAgICAgIG5ld2xpbmUgPSBtZXNzYWdlLmZpbmQoJ1xuJykKKyAgICAgICAgICAgIGlmIG5ld2xpbmUgIT0gLTE6CisgICAgICAgICAgICAgICAgZnJvbV9saW5lID0gbWVzc2FnZVs6bmV3bGluZV0KKyAgICAgICAgICAgICAgICBtZXNzYWdlID0gbWVzc2FnZVtuZXdsaW5lICsgMTpdCisgICAgICAgICAgICBlbHNlOgorICAgICAgICAgICAgICAgIGZyb21fbGluZSA9IG1lc3NhZ2UKKyAgICAgICAgICAgICAgICBtZXNzYWdlID0gJycKKyAgICAgICAgZWxpZiBpc2luc3RhbmNlKG1lc3NhZ2UsIF9tYm94TU1ERk1lc3NhZ2UpOgorICAgICAgICAgICAgZnJvbV9saW5lID0gJ0Zyb20gJyArIG1lc3NhZ2UuZ2V0X2Zyb20oKQorICAgICAgICBlbGlmIGlzaW5zdGFuY2UobWVzc2FnZSwgZW1haWwuTWVzc2FnZS5NZXNzYWdlKToKKyAgICAgICAgICAgIGZyb21fbGluZSA9IG1lc3NhZ2UuZ2V0X3VuaXhmcm9tKCkgICMgTWF5IGJlIE5vbmUuCisgICAgICAgIGlmIGZyb21fbGluZSBpcyBOb25lOgorICAgICAgICAgICAgZnJvbV9saW5lID0gJ0Zyb20gTUFJTEVSLURBRU1PTiAlcycgJSB0aW1lLmFzY3RpbWUodGltZS5nbXRpbWUoKSkKKyAgICAgICAgc3RhcnQgPSBzZWxmLl9maWxlLnRlbGwoKQorICAgICAgICBzZWxmLl9maWxlLndyaXRlKGZyb21fbGluZSArIG9zLmxpbmVzZXApCisgICAgICAgIHNlbGYuX2R1bXBfbWVzc2FnZShtZXNzYWdlLCBzZWxmLl9maWxlLCBzZWxmLl9tYW5nbGVfZnJvbV8pCisgICAgICAgIHN0b3AgPSBzZWxmLl9maWxlLnRlbGwoKQorICAgICAgICByZXR1cm4gKHN0YXJ0LCBzdG9wKQorCisKK2NsYXNzIG1ib3goX21ib3hNTURGKToKKyAgICAiIiJBIGNsYXNzaWMgbWJveCBtYWlsYm94LiIiIgorCisgICAgX21hbmdsZV9mcm9tXyA9IFRydWUKKworICAgIGRlZiBfX2luaXRfXyhzZWxmLCBwYXRoLCBmYWN0b3J5PU5vbmUsIGNyZWF0ZT1UcnVlKToKKyAgICAgICAgIiIiSW5pdGlhbGl6ZSBhbiBtYm94IG1haWxib3guIiIiCisgICAgICAgIHNlbGYuX21lc3NhZ2VfZmFjdG9yeSA9IG1ib3hNZXNzYWdlCisgICAgICAgIF9tYm94TU1ERi5fX2luaXRfXyhzZWxmLCBwYXRoLCBmYWN0b3J5LCBjcmVhdGUpCisKKyAgICBkZWYgX3ByZV9tZXNzYWdlX2hvb2soc2VsZiwgZik6CisgICAgICAgICIiIkNhbGxlZCBiZWZvcmUgd3JpdGluZyBlYWNoIG1lc3NhZ2UgdG8gZmlsZSBmLiIiIgorICAgICAgICBpZiBmLnRlbGwoKSAhPSAwOgorICAgICAgICAgICAgZi53cml0ZShvcy5saW5lc2VwKQorCisgICAgZGVmIF9nZW5lcmF0ZV90b2Moc2VsZik6CisgICAgICAgICIiIkdlbmVyYXRlIGtleS10by0oc3RhcnQsIHN0b3ApIHRhYmxlIG9mIGNvbnRlbnRzLiIiIgorICAgICAgICBzdGFydHMsIHN0b3BzID0gW10sIFtdCisgICAgICAgIHNlbGYuX2ZpbGUuc2VlaygwKQorICAgICAgICB3aGlsZSBUcnVlOgorICAgICAgICAgICAgbGluZV9wb3MgPSBzZWxmLl9maWxlLnRlbGwoKQorICAgICAgICAgICAgbGluZSA9IHNlbGYuX2ZpbGUucmVhZGxpbmUoKQorICAgICAgICAgICAgaWYgbGluZS5zdGFydHN3aXRoKCdGcm9tICcpOgorICAgICAgICAgICAgICAgIGlmIGxlbihzdG9wcykgPCBsZW4oc3RhcnRzKToKKyAgICAgICAgICAgICAgICAgICAgc3RvcHMuYXBwZW5kKGxpbmVfcG9zIC0gbGVuKG9zLmxpbmVzZXApKQorICAgICAgICAgICAgICAgIHN0YXJ0cy5hcHBlbmQobGluZV9wb3MpCisgICAgICAgICAgICBlbGlmIGxpbmUgPT0gJyc6CisgICAgICAgICAgICAgICAgc3RvcHMuYXBwZW5kKGxpbmVfcG9zKQorICAgICAgICAgICAgICAgIGJyZWFrCisgICAgICAgIHNlbGYuX3RvYyA9IGRpY3QoZW51bWVyYXRlKHppcChzdGFydHMsIHN0b3BzKSkpCisgICAgICAgIHNlbGYuX25leHRfa2V5ID0gbGVuKHNlbGYuX3RvYykKKworCitjbGFzcyBNTURGKF9tYm94TU1ERik6CisgICAgIiIiQW4gTU1ERiBtYWlsYm94LiIiIgorCisgICAgZGVmIF9faW5pdF9fKHNlbGYsIHBhdGgsIGZhY3Rvcnk9Tm9uZSwgY3JlYXRlPVRydWUpOgorICAgICAgICAiIiJJbml0aWFsaXplIGFuIE1NREYgbWFpbGJveC4iIiIKKyAgICAgICAgc2VsZi5fbWVzc2FnZV9mYWN0b3J5ID0gTU1ERk1lc3NhZ2UKKyAgICAgICAgX21ib3hNTURGLl9faW5pdF9fKHNlbGYsIHBhdGgsIGZhY3RvcnksIGNyZWF0ZSkKKworICAgIGRlZiBfcHJlX21lc3NhZ2VfaG9vayhzZWxmLCBmKToKKyAgICAgICAgIiIiQ2FsbGVkIGJlZm9yZSB3cml0aW5nIGVhY2ggbWVzc2FnZSB0byBmaWxlIGYuIiIiCisgICAgICAgIGYud3JpdGUoJ1wwMDFcMDAxXDAwMVwwMDEnICsgb3MubGluZXNlcCkKKworICAgIGRlZiBfcG9zdF9tZXNzYWdlX2hvb2soc2VsZiwgZik6CisgICAgICAgICIiIkNhbGxlZCBhZnRlciB3cml0aW5nIGVhY2ggbWVzc2FnZSB0byBmaWxlIGYuIiIiCisgICAgICAgIGYud3JpdGUob3MubGluZXNlcCArICdcMDAxXDAwMVwwMDFcMDAxJyArIG9zLmxpbmVzZXApCisKKyAgICBkZWYgX2dlbmVyYXRlX3RvYyhzZWxmKToKKyAgICAgICAgIiIiR2VuZXJhdGUga2V5LXRvLShzdGFydCwgc3RvcCkgdGFibGUgb2YgY29udGVudHMuIiIiCisgICAgICAgIHN0YXJ0cywgc3RvcHMgPSBbXSwgW10KKyAgICAgICAgc2VsZi5fZmlsZS5zZWVrKDApCisgICAgICAgIG5leHRfcG9zID0gMAorICAgICAgICB3aGlsZSBUcnVlOgorICAgICAgICAgICAgbGluZV9wb3MgPSBuZXh0X3BvcworICAgICAgICAgICAgbGluZSA9IHNlbGYuX2ZpbGUucmVhZGxpbmUoKQorICAgICAgICAgICAgbmV4dF9wb3MgPSBzZWxmLl9maWxlLnRlbGwoKQorICAgICAgICAgICAgaWYgbGluZS5zdGFydHN3aXRoKCdcMDAxXDAwMVwwMDFcMDAxJyArIG9zLmxpbmVzZXApOgorICAgICAgICAgICAgICAgIHN0YXJ0cy5hcHBlbmQobmV4dF9wb3MpCisgICAgICAgICAgICAgICAgd2hpbGUgVHJ1ZToKKyAgICAgICAgICAgICAgICAgICAgbGluZV9wb3MgPSBuZXh0X3BvcworICAgICAgICAgICAgICAgICAgICBsaW5lID0gc2VsZi5fZmlsZS5yZWFkbGluZSgpCisgICAgICAgICAgICAgICAgICAgIG5leHRfcG9zID0gc2VsZi5fZmlsZS50ZWxsKCkKKyAgICAgICAgICAgICAgICAgICAgaWYgbGluZSA9PSAnXDAwMVwwMDFcMDAxXDAwMScgKyBvcy5saW5lc2VwOgorICAgICAgICAgICAgICAgICAgICAgICAgc3RvcHMuYXBwZW5kKGxpbmVfcG9zIC0gbGVuKG9zLmxpbmVzZXApKQorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsKKyAgICAgICAgICAgICAgICAgICAgZWxpZiBsaW5lID09ICcnOgorICAgICAgICAgICAgICAgICAgICAgICAgc3RvcHMuYXBwZW5kKGxpbmVfcG9zKQorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsKKyAgICAgICAgICAgIGVsaWYgbGluZSA9PSAnJzoKKyAgICAgICAgICAgICAgICBicmVhaworICAgICAgICBzZWxmLl90b2MgPSBkaWN0KGVudW1lcmF0ZSh6aXAoc3RhcnRzLCBzdG9wcykpKQorICAgICAgICBzZWxmLl9uZXh0X2tleSA9IGxlbihzZWxmLl90b2MpCisKKworY2xhc3MgTUgoTWFpbGJveCk6CisgICAgIiIiQW4gTUggbWFpbGJveC4iIiIKKworICAgIGRlZiBfX2luaXRfXyhzZWxmLCBwYXRoLCBmYWN0b3J5PU5vbmUsIGNyZWF0ZT1UcnVlKToKKyAgICAgICAgIiIiSW5pdGlhbGl6ZSBhbiBNSCBpbnN0YW5jZS4iIiIKKyAgICAgICAgTWFpbGJveC5fX2luaXRfXyhzZWxmLCBwYXRoLCBmYWN0b3J5LCBjcmVhdGUpCisgICAgICAgIGlmIG5vdCBvcy5wYXRoLmV4aXN0cyhzZWxmLl9wYXRoKToKKyAgICAgICAgICAgIGlmIGNyZWF0ZToKKyAgICAgICAgICAgICAgICBvcy5ta2RpcihzZWxmLl9wYXRoLCAwNzAwKQorICAgICAgICAgICAgICAgIG9zLmNsb3NlKG9zLm9wZW4ob3MucGF0aC5qb2luKHNlbGYuX3BhdGgsICcubWhfc2VxdWVuY2VzJyksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcy5PX0NSRUFUIHwgb3MuT19FWENMIHwgb3MuT19XUk9OTFksIDA2MDApKQorICAgICAgICAgICAgZWxzZToKKyAgICAgICAgICAgICAgICByYWlzZSBOb1N1Y2hNYWlsYm94RXJyb3Ioc2VsZi5fcGF0aCkKKyAgICAgICAgc2VsZi5fbG9ja2VkID0gRmFsc2UKKworICAgIGRlZiBhZGQoc2VsZiwgbWVzc2FnZSk6CisgICAgICAgICIiIkFkZCBtZXNzYWdlIGFuZCByZXR1cm4gYXNzaWduZWQga2V5LiIiIgorICAgICAgICBrZXlzID0gc2VsZi5rZXlzKCkKKyAgICAgICAgaWYgbGVuKGtleXMpID09IDA6CisgICAgICAgICAgICBuZXdfa2V5ID0gMQorICAgICAgICBlbHNlOgorICAgICAgICAgICAgbmV3X2tleSA9IG1heChrZXlzKSArIDEKKyAgICAgICAgbmV3X3BhdGggPSBvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgc3RyKG5ld19rZXkpKQorICAgICAgICBmID0gX2NyZWF0ZV9jYXJlZnVsbHkobmV3X3BhdGgpCisgICAgICAgIHRyeToKKyAgICAgICAgICAgIGlmIHNlbGYuX2xvY2tlZDoKKyAgICAgICAgICAgICAgICBfbG9ja19maWxlKGYpCisgICAgICAgICAgICB0cnk6CisgICAgICAgICAgICAgICAgc2VsZi5fZHVtcF9tZXNzYWdlKG1lc3NhZ2UsIGYpCisgICAgICAgICAgICAgICAgaWYgaXNpbnN0YW5jZShtZXNzYWdlLCBNSE1lc3NhZ2UpOgorICAgICAgICAgICAgICAgICAgICBzZWxmLl9kdW1wX3NlcXVlbmNlcyhtZXNzYWdlLCBuZXdfa2V5KQorICAgICAgICAgICAgZmluYWxseToKKyAgICAgICAgICAgICAgICBpZiBzZWxmLl9sb2NrZWQ6CisgICAgICAgICAgICAgICAgICAgIF91bmxvY2tfZmlsZShmKQorICAgICAgICBmaW5hbGx5OgorICAgICAgICAgICAgZi5jbG9zZSgpCisgICAgICAgIHJldHVybiBuZXdfa2V5CisKKyAgICBkZWYgcmVtb3ZlKHNlbGYsIGtleSk6CisgICAgICAgICIiIlJlbW92ZSB0aGUga2V5ZWQgbWVzc2FnZTsgcmFpc2UgS2V5RXJyb3IgaWYgaXQgZG9lc24ndCBleGlzdC4iIiIKKyAgICAgICAgcGF0aCA9IG9zLnBhdGguam9pbihzZWxmLl9wYXRoLCBzdHIoa2V5KSkKKyAgICAgICAgdHJ5OgorICAgICAgICAgICAgZiA9IGZpbGUocGF0aCwgJ3JiKycpCisgICAgICAgIGV4Y2VwdCBJT0Vycm9yLCBlOgorICAgICAgICAgICAgaWYgZS5lcnJubyA9PSBlcnJuby5FTk9FTlQ6CisgICAgICAgICAgICAgICAgcmFpc2UgS2V5RXJyb3IoJ05vIG1lc3NhZ2Ugd2l0aCBrZXk6ICVzJyAlIGtleSkKKyAgICAgICAgICAgIGVsc2U6CisgICAgICAgICAgICAgICAgcmFpc2UKKyAgICAgICAgdHJ5OgorICAgICAgICAgICAgaWYgc2VsZi5fbG9ja2VkOgorICAgICAgICAgICAgICAgIF9sb2NrX2ZpbGUoZikKKyAgICAgICAgICAgIHRyeToKKyAgICAgICAgICAgICAgICBmLmNsb3NlKCkKKyAgICAgICAgICAgICAgICBvcy5yZW1vdmUob3MucGF0aC5qb2luKHNlbGYuX3BhdGgsIHN0cihrZXkpKSkKKyAgICAgICAgICAgIGZpbmFsbHk6CisgICAgICAgICAgICAgICAgaWYgc2VsZi5fbG9ja2VkOgorICAgICAgICAgICAgICAgICAgICBfdW5sb2NrX2ZpbGUoZikKKyAgICAgICAgZmluYWxseToKKyAgICAgICAgICAgIGYuY2xvc2UoKQorCisgICAgZGVmIF9fc2V0aXRlbV9fKHNlbGYsIGtleSwgbWVzc2FnZSk6CisgICAgICAgICIiIlJlcGxhY2UgdGhlIGtleWVkIG1lc3NhZ2U7IHJhaXNlIEtleUVycm9yIGlmIGl0IGRvZXNuJ3QgZXhpc3QuIiIiCisgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgc3RyKGtleSkpCisgICAgICAgIHRyeToKKyAgICAgICAgICAgIGYgPSBmaWxlKHBhdGgsICdyYisnKQorICAgICAgICBleGNlcHQgSU9FcnJvciwgZToKKyAgICAgICAgICAgIGlmIGUuZXJybm8gPT0gZXJybm8uRU5PRU5UOgorICAgICAgICAgICAgICAgIHJhaXNlIEtleUVycm9yKCdObyBtZXNzYWdlIHdpdGgga2V5OiAlcycgJSBrZXkpCisgICAgICAgICAgICBlbHNlOgorICAgICAgICAgICAgICAgIHJhaXNlCisgICAgICAgIHRyeToKKyAgICAgICAgICAgIGlmIHNlbGYuX2xvY2tlZDoKKyAgICAgICAgICAgICAgICBfbG9ja19maWxlKGYpCisgICAgICAgICAgICB0cnk6CisgICAgICAgICAgICAgICAgb3MuY2xvc2Uob3Mub3BlbihwYXRoLCBvcy5PX1dST05MWSB8IG9zLk9fVFJVTkMpKQorICAgICAgICAgICAgICAgIHNlbGYuX2R1bXBfbWVzc2FnZShtZXNzYWdlLCBmKQorICAgICAgICAgICAgICAgIGlmIGlzaW5zdGFuY2UobWVzc2FnZSwgTUhNZXNzYWdlKToKKyAgICAgICAgICAgICAgICAgICAgc2VsZi5fZHVtcF9zZXF1ZW5jZXMobWVzc2FnZSwga2V5KQorICAgICAgICAgICAgZmluYWxseToKKyAgICAgICAgICAgICAgICBpZiBzZWxmLl9sb2NrZWQ6CisgICAgICAgICAgICAgICAgICAgIF91bmxvY2tfZmlsZShmKQorICAgICAgICBmaW5hbGx5OgorICAgICAgICAgICAgZi5jbG9zZSgpCisKKyAgICBkZWYgZ2V0X21lc3NhZ2Uoc2VsZiwga2V5KToKKyAgICAgICAgIiIiUmV0dXJuIGEgTWVzc2FnZSByZXByZXNlbnRhdGlvbiBvciByYWlzZSBhIEtleUVycm9yLiIiIgorICAgICAgICB0cnk6CisgICAgICAgICAgICBpZiBzZWxmLl9sb2NrZWQ6CisgICAgICAgICAgICAgICAgZiA9IGZpbGUob3MucGF0aC5qb2luKHNlbGYuX3BhdGgsIHN0cihrZXkpKSwgJ3IrJykKKyAgICAgICAgICAgIGVsc2U6CisgICAgICAgICAgICAgICAgZiA9IGZpbGUob3MucGF0aC5qb2luKHNlbGYuX3BhdGgsIHN0cihrZXkpKSwgJ3InKQorICAgICAgICBleGNlcHQgSU9FcnJvciwgZToKKyAgICAgICAgICAgIGlmIGUuZXJybm8gPT0gZXJybm8uRU5PRU5UOgorICAgICAgICAgICAgICAgIHJhaXNlIEtleUVycm9yKCdObyBtZXNzYWdlIHdpdGgga2V5OiAlcycgJSBrZXkpCisgICAgICAgICAgICBlbHNlOgorICAgICAgICAgICAgICAgIHJhaXNlCisgICAgICAgIHRyeToKKyAgICAgICAgICAgIGlmIHNlbGYuX2xvY2tlZDoKKyAgICAgICAgICAgICAgICBfbG9ja19maWxlKGYpCisgICAgICAgICAgICB0cnk6CisgICAgICAgICAgICAgICAgbXNnID0gTUhNZXNzYWdlKGYpCisgICAgICAgICAgICBmaW5hbGx5OgorICAgICAgICAgICAgICAgIGlmIHNlbGYuX2xvY2tlZDoKKyAgICAgICAgICAgICAgICAgICAgX3VubG9ja19maWxlKGYpCisgICAgICAgIGZpbmFsbHk6CisgICAgICAgICAgICBmLmNsb3NlKCkKKyAgICAgICAgZm9yIG5hbWUsIGtleV9saXN0IGluIHNlbGYuZ2V0X3NlcXVlbmNlcygpOgorICAgICAgICAgICAgaWYga2V5IGluIGtleV9saXN0OgorICAgICAgICAgICAgICAgIG1zZy5hZGRfc2VxdWVuY2UobmFtZSkKKyAgICAgICAgcmV0dXJuIG1zZworCisgICAgZGVmIGdldF9zdHJpbmcoc2VsZiwga2V5KToKKyAgICAgICAgIiIiUmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9yIHJhaXNlIGEgS2V5RXJyb3IuIiIiCisgICAgICAgIHRyeToKKyAgICAgICAgICAgIGlmIHNlbGYuX2xvY2tlZDoKKyAgICAgICAgICAgICAgICBmID0gZmlsZShvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgc3RyKGtleSkpLCAncisnKQorICAgICAgICAgICAgZWxzZToKKyAgICAgICAgICAgICAgICBmID0gZmlsZShvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgc3RyKGtleSkpLCAncicpCisgICAgICAgIGV4Y2VwdCBJT0Vycm9yLCBlOgorICAgICAgICAgICAgaWYgZS5lcnJubyA9PSBlcnJuby5FTk9FTlQ6CisgICAgICAgICAgICAgICAgcmFpc2UgS2V5RXJyb3IoJ05vIG1lc3NhZ2Ugd2l0aCBrZXk6ICVzJyAlIGtleSkKKyAgICAgICAgICAgIGVsc2U6CisgICAgICAgICAgICAgICAgcmFpc2UKKyAgICAgICAgdHJ5OgorICAgICAgICAgICAgaWYgc2VsZi5fbG9ja2VkOgorICAgICAgICAgICAgICAgIF9sb2NrX2ZpbGUoZikKKyAgICAgICAgICAgIHRyeToKKyAgICAgICAgICAgICAgICByZXR1cm4gZi5yZWFkKCkKKyAgICAgICAgICAgIGZpbmFsbHk6CisgICAgICAgICAgICAgICAgaWYgc2VsZi5fbG9ja2VkOgorICAgICAgICAgICAgICAgICAgICBfdW5sb2NrX2ZpbGUoZikKKyAgICAgICAgZmluYWxseToKKyAgICAgICAgICAgIGYuY2xvc2UoKQorCisgICAgZGVmIGdldF9maWxlKHNlbGYsIGtleSk6CisgICAgICAgICIiIlJldHVybiBhIGZpbGUtbGlrZSByZXByZXNlbnRhdGlvbiBvciByYWlzZSBhIEtleUVycm9yLiIiIgorICAgICAgICB0cnk6CisgICAgICAgICAgICBmID0gZmlsZShvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgc3RyKGtleSkpLCAncmInKQorICAgICAgICBleGNlcHQgSU9FcnJvciwgZToKKyAgICAgICAgICAgIGlmIGUuZXJybm8gPT0gZXJybm8uRU5PRU5UOgorICAgICAgICAgICAgICAgIHJhaXNlIEtleUVycm9yKCdObyBtZXNzYWdlIHdpdGgga2V5OiAlcycgJSBrZXkpCisgICAgICAgICAgICBlbHNlOgorICAgICAgICAgICAgICAgIHJhaXNlCisgICAgICAgIHJldHVybiBfUHJveHlGaWxlKGYpCisKKyAgICBkZWYgaXRlcmtleXMoc2VsZik6CisgICAgICAgICIiIlJldHVybiBhbiBpdGVyYXRvciBvdmVyIGtleXMuIiIiCisgICAgICAgIHJldHVybiBpdGVyKHNvcnRlZChpbnQoZW50cnkpIGZvciBlbnRyeSBpbiBvcy5saXN0ZGlyKHNlbGYuX3BhdGgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGVudHJ5LmlzZGlnaXQoKSkpCisKKyAgICBkZWYgaGFzX2tleShzZWxmLCBrZXkpOgorICAgICAgICAiIiJSZXR1cm4gVHJ1ZSBpZiB0aGUga2V5ZWQgbWVzc2FnZSBleGlzdHMsIEZhbHNlIG90aGVyd2lzZS4iIiIKKyAgICAgICAgcmV0dXJuIG9zLnBhdGguZXhpc3RzKG9zLnBhdGguam9pbihzZWxmLl9wYXRoLCBzdHIoa2V5KSkpCisKKyAgICBkZWYgX19sZW5fXyhzZWxmKToKKyAgICAgICAgIiIiUmV0dXJuIGEgY291bnQgb2YgbWVzc2FnZXMgaW4gdGhlIG1haWxib3guIiIiCisgICAgICAgIHJldHVybiBsZW4obGlzdChzZWxmLml0ZXJrZXlzKCkpKQorCisgICAgZGVmIGxvY2soc2VsZik6CisgICAgICAgICIiIkxvY2sgdGhlIG1haWxib3guIiIiCisgICAgICAgIGlmIG5vdCBzZWxmLl9sb2NrZWQ6CisgICAgICAgICAgICBzZWxmLl9maWxlID0gZmlsZShvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgJy5taF9zZXF1ZW5jZXMnKSwgJ3JiKycpCisgICAgICAgICAgICBfbG9ja19maWxlKHNlbGYuX2ZpbGUpCisgICAgICAgICAgICBzZWxmLl9sb2NrZWQgPSBUcnVlCisKKyAgICBkZWYgdW5sb2NrKHNlbGYpOgorICAgICAgICAiIiJVbmxvY2sgdGhlIG1haWxib3ggaWYgaXQgaXMgbG9ja2VkLiIiIgorICAgICAgICBpZiBzZWxmLl9sb2NrZWQ6CisgICAgICAgICAgICBfdW5sb2NrX2ZpbGUoc2VsZi5fZmlsZSkKKyAgICAgICAgICAgIHNlbGYuX2ZpbGUuY2xvc2UoKQorICAgICAgICAgICAgZGVsIHNlbGYuX2ZpbGUKKyAgICAgICAgICAgIHNlbGYuX2xvY2tlZCA9IEZhbHNlCisKKyAgICBkZWYgZmx1c2goc2VsZik6CisgICAgICAgICIiIldyaXRlIGFueSBwZW5kaW5nIGNoYW5nZXMgdG8gdGhlIGRpc2suIiIiCisgICAgICAgIHJldHVybgorCisgICAgZGVmIGNsb3NlKHNlbGYpOgorICAgICAgICAiIiJGbHVzaCBhbmQgY2xvc2UgdGhlIG1haWxib3guIiIiCisgICAgICAgIGlmIHNlbGYuX2xvY2tlZDoKKyAgICAgICAgICAgIHNlbGYudW5sb2NrKCkKKworICAgIGRlZiBsaXN0X2ZvbGRlcnMoc2VsZik6CisgICAgICAgICIiIlJldHVybiBhIGxpc3Qgb2YgZm9sZGVyIG5hbWVzLiIiIgorICAgICAgICByZXN1bHQgPSBbXQorICAgICAgICBmb3IgZW50cnkgaW4gb3MubGlzdGRpcihzZWxmLl9wYXRoKToKKyAgICAgICAgICAgIGlmIG9zLnBhdGguaXNkaXIob3MucGF0aC5qb2luKHNlbGYuX3BhdGgsIGVudHJ5KSk6CisgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChlbnRyeSkKKyAgICAgICAgcmV0dXJuIHJlc3VsdAorCisgICAgZGVmIGdldF9mb2xkZXIoc2VsZiwgZm9sZGVyKToKKyAgICAgICAgIiIiUmV0dXJuIGFuIE1IIGluc3RhbmNlIGZvciB0aGUgbmFtZWQgZm9sZGVyLiIiIgorICAgICAgICByZXR1cm4gTUgob3MucGF0aC5qb2luKHNlbGYuX3BhdGgsIGZvbGRlciksIGNyZWF0ZT1GYWxzZSkKKworICAgIGRlZiBhZGRfZm9sZGVyKHNlbGYsIGZvbGRlcik6CisgICAgICAgICIiIkNyZWF0ZSBhIGZvbGRlciBhbmQgcmV0dXJuIGFuIE1IIGluc3RhbmNlIHJlcHJlc2VudGluZyBpdC4iIiIKKyAgICAgICAgcmV0dXJuIE1IKG9zLnBhdGguam9pbihzZWxmLl9wYXRoLCBmb2xkZXIpKQorCisgICAgZGVmIHJlbW92ZV9mb2xkZXIoc2VsZiwgZm9sZGVyKToKKyAgICAgICAgIiIiRGVsZXRlIHRoZSBuYW1lZCBmb2xkZXIsIHdoaWNoIG11c3QgYmUgZW1wdHkuIiIiCisgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgZm9sZGVyKQorICAgICAgICBlbnRyaWVzID0gb3MubGlzdGRpcihwYXRoKQorICAgICAgICBpZiBlbnRyaWVzID09IFsnLm1oX3NlcXVlbmNlcyddOgorICAgICAgICAgICAgb3MucmVtb3ZlKG9zLnBhdGguam9pbihwYXRoLCAnLm1oX3NlcXVlbmNlcycpKQorICAgICAgICBlbGlmIGVudHJpZXMgPT0gW106CisgICAgICAgICAgICBwYXNzCisgICAgICAgIGVsc2U6CisgICAgICAgICAgICByYWlzZSBOb3RFbXB0eUVycm9yKCdGb2xkZXIgbm90IGVtcHR5OiAlcycgJSBzZWxmLl9wYXRoKQorICAgICAgICBvcy5ybWRpcihwYXRoKQorCisgICAgZGVmIGdldF9zZXF1ZW5jZXMoc2VsZik6CisgICAgICAgICIiIlJldHVybiBhIG5hbWUtdG8ta2V5LWxpc3QgZGljdGlvbmFyeSB0byBkZWZpbmUgZWFjaCBzZXF1ZW5jZS4iIiIKKyAgICAgICAgcmVzdWx0cyA9IHt9CisgICAgICAgIGYgPSBmaWxlKG9zLnBhdGguam9pbihzZWxmLl9wYXRoLCAnLm1oX3NlcXVlbmNlcycpLCAncicpCisgICAgICAgIHRyeToKKyAgICAgICAgICAgIGFsbF9rZXlzID0gc2V0KHNlbGYua2V5cygpKQorICAgICAgICAgICAgZm9yIGxpbmUgaW4gZjoKKyAgICAgICAgICAgICAgICB0cnk6CisgICAgICAgICAgICAgICAgICAgIG5hbWUsIGNvbnRlbnRzID0gbGluZS5zcGxpdCgnOicpCisgICAgICAgICAgICAgICAgICAgIGtleXMgPSBzZXQoKQorICAgICAgICAgICAgICAgICAgICBmb3Igc3BlYyBpbiBjb250ZW50cy5zcGxpdCgpOgorICAgICAgICAgICAgICAgICAgICAgICAgaWYgc3BlYy5pc2RpZ2l0KCk6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5cy5hZGQoaW50KHNwZWMpKQorICAgICAgICAgICAgICAgICAgICAgICAgZWxzZToKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydCwgc3RvcCA9IChpbnQoeCkgZm9yIHggaW4gc3BlYy5zcGxpdCgnLScpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleXMudXBkYXRlKHJhbmdlKHN0YXJ0LCBzdG9wICsgMSkpCisgICAgICAgICAgICAgICAgICAgIHJlc3VsdHNbbmFtZV0gPSBba2V5IGZvciBrZXkgaW4gc29ydGVkKGtleXMpIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYga2V5IGluIGFsbF9rZXlzXQorICAgICAgICAgICAgICAgICAgICBpZiBsZW4ocmVzdWx0c1tuYW1lXSkgPT0gMDoKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlbCByZXN1bHRzW25hbWVdCisgICAgICAgICAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6CisgICAgICAgICAgICAgICAgICAgIHJhaXNlIEZvcm1hdEVycm9yKCdJbnZhbGlkIHNlcXVlbmNlIHNwZWNpZmljYXRpb246ICVzJyAlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUucnN0cmlwKCkpCisgICAgICAgIGZpbmFsbHk6CisgICAgICAgICAgICBmLmNsb3NlKCkKKyAgICAgICAgcmV0dXJuIHJlc3VsdHMKKworICAgIGRlZiBzZXRfc2VxdWVuY2VzKHNlbGYsIHNlcXVlbmNlcyk6CisgICAgICAgICIiIlNldCBzZXF1ZW5jZXMgdXNpbmcgdGhlIGdpdmVuIG5hbWUtdG8ta2V5LWxpc3QgZGljdGlvbmFyeS4iIiIKKyAgICAgICAgZiA9IGZpbGUob3MucGF0aC5qb2luKHNlbGYuX3BhdGgsICcubWhfc2VxdWVuY2VzJyksICdyKycpCisgICAgICAgIHRyeToKKyAgICAgICAgICAgIG9zLmNsb3NlKG9zLm9wZW4oZi5uYW1lLCBvcy5PX1dST05MWSB8IG9zLk9fVFJVTkMpKQorICAgICAgICAgICAgZm9yIG5hbWUsIGtleXMgaW4gc2VxdWVuY2VzLml0ZXJpdGVtcygpOgorICAgICAgICAgICAgICAgIGlmIGxlbihrZXlzKSA9PSAwOgorICAgICAgICAgICAgICAgICAgICBjb250aW51ZQorICAgICAgICAgICAgICAgIGYud3JpdGUoJyVzOicgJSBuYW1lKQorICAgICAgICAgICAgICAgIHByZXYgPSBOb25lCisgICAgICAgICAgICAgICAgY29tcGxldGluZyA9IEZhbHNlCisgICAgICAgICAgICAgICAgZm9yIGtleSBpbiBzb3J0ZWQoc2V0KGtleXMpKToKKyAgICAgICAgICAgICAgICAgICAgaWYga2V5IC0gMSA9PSBwcmV2OgorICAgICAgICAgICAgICAgICAgICAgICAgaWYgbm90IGNvbXBsZXRpbmc6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcGxldGluZyA9IFRydWUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmLndyaXRlKCctJykKKyAgICAgICAgICAgICAgICAgICAgZWxpZiBjb21wbGV0aW5nOgorICAgICAgICAgICAgICAgICAgICAgICAgY29tcGxldGluZyA9IEZhbHNlCisgICAgICAgICAgICAgICAgICAgICAgICBmLndyaXRlKCclcyAlcycgJSAocHJldiwga2V5KSkKKyAgICAgICAgICAgICAgICAgICAgZWxzZToKKyAgICAgICAgICAgICAgICAgICAgICAgIGYud3JpdGUoJyAlcycgJSBrZXkpCisgICAgICAgICAgICAgICAgICAgIHByZXYgPSBrZXkKKyAgICAgICAgICAgICAgICBpZiBjb21wbGV0aW5nOgorICAgICAgICAgICAgICAgICAgICBmLndyaXRlKHN0cihwcmV2KSArICdcbicpCisgICAgICAgICAgICAgICAgZWxzZToKKyAgICAgICAgICAgICAgICAgICAgZi53cml0ZSgnXG4nKQorICAgICAgICBmaW5hbGx5OgorICAgICAgICAgICAgZi5jbG9zZSgpCisKKyAgICBkZWYgcGFjayhzZWxmKToKKyAgICAgICAgIiIiUmUtbmFtZSBtZXNzYWdlcyB0byBlbGltaW5hdGUgbnVtYmVyaW5nIGdhcHMuIEludmFsaWRhdGVzIGtleXMuIiIiCisgICAgICAgIHNlcXVlbmNlcyA9IHNlbGYuZ2V0X3NlcXVlbmNlcygpCisgICAgICAgIHByZXYgPSAwCisgICAgICAgIGNoYW5nZXMgPSBbXQorICAgICAgICBmb3Iga2V5IGluIHNlbGYuaXRlcmtleXMoKToKKyAgICAgICAgICAgIGlmIGtleSAtIDEgIT0gcHJldjoKKyAgICAgICAgICAgICAgICBjaGFuZ2VzLmFwcGVuZCgoa2V5LCBwcmV2ICsgMSkpCisgICAgICAgICAgICAgICAgZiA9IGZpbGUob3MucGF0aC5qb2luKHNlbGYuX3BhdGgsIHN0cihrZXkpKSwgJ3IrJykKKyAgICAgICAgICAgICAgICB0cnk6CisgICAgICAgICAgICAgICAgICAgIGlmIHNlbGYuX2xvY2tlZDoKKyAgICAgICAgICAgICAgICAgICAgICAgIF9sb2NrX2ZpbGUoZikKKyAgICAgICAgICAgICAgICAgICAgdHJ5OgorICAgICAgICAgICAgICAgICAgICAgICAgaWYgaGFzYXR0cihvcywgJ2xpbmsnKToKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcy5saW5rKG9zLnBhdGguam9pbihzZWxmLl9wYXRoLCBzdHIoa2V5KSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgc3RyKHByZXYgKyAxKSkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3MudW5saW5rKG9zLnBhdGguam9pbihzZWxmLl9wYXRoLCBzdHIoa2V5KSkpCisgICAgICAgICAgICAgICAgICAgICAgICBlbHNlOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYuY2xvc2UoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9zLnJlbmFtZShvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgc3RyKGtleSkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgc3RyKHByZXYgKyAxKSkpCisgICAgICAgICAgICAgICAgICAgIGZpbmFsbHk6CisgICAgICAgICAgICAgICAgICAgICAgICBpZiBzZWxmLl9sb2NrZWQ6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3VubG9ja19maWxlKGYpCisgICAgICAgICAgICAgICAgZmluYWxseToKKyAgICAgICAgICAgICAgICAgICAgZi5jbG9zZSgpCisgICAgICAgICAgICBwcmV2ICs9IDEKKyAgICAgICAgc2VsZi5fbmV4dF9rZXkgPSBwcmV2ICsgMQorICAgICAgICBpZiBsZW4oY2hhbmdlcykgPT0gMDoKKyAgICAgICAgICAgIHJldHVybgorICAgICAgICBmb3IgbmFtZSwga2V5X2xpc3QgaW4gc2VxdWVuY2VzLml0ZW1zKCk6CisgICAgICAgICAgICBmb3Igb2xkLCBuZXcgaW4gY2hhbmdlczoKKyAgICAgICAgICAgICAgICBpZiBvbGQgaW4ga2V5X2xpc3Q6CisgICAgICAgICAgICAgICAgICAgIGtleV9saXN0W2tleV9saXN0LmluZGV4KG9sZCldID0gbmV3CisgICAgICAgIHNlbGYuc2V0X3NlcXVlbmNlcyhzZXF1ZW5jZXMpCisKKyAgICBkZWYgX2R1bXBfc2VxdWVuY2VzKHNlbGYsIG1lc3NhZ2UsIGtleSk6CisgICAgICAgICIiIkluc3BlY3QgYSBuZXcgTUhNZXNzYWdlIGFuZCB1cGRhdGUgc2VxdWVuY2VzIGFwcHJvcHJpYXRlbHkuIiIiCisgICAgICAgIHBlbmRpbmdfc2VxdWVuY2VzID0gbWVzc2FnZS5nZXRfc2VxdWVuY2VzKCkKKyAgICAgICAgYWxsX3NlcXVlbmNlcyA9IHNlbGYuZ2V0X3NlcXVlbmNlcygpCisgICAgICAgIGZvciBuYW1lLCBrZXlfbGlzdCBpbiBhbGxfc2VxdWVuY2VzLml0ZXJpdGVtcygpOgorICAgICAgICAgICAgaWYgbmFtZSBpbiBwZW5kaW5nX3NlcXVlbmNlczoKKyAgICAgICAgICAgICAgICBrZXlfbGlzdC5hcHBlbmQoa2V5KQorICAgICAgICAgICAgZWxpZiBrZXkgaW4ga2V5X2xpc3Q6CisgICAgICAgICAgICAgICAgZGVsIGtleV9saXN0W2tleV9saXN0LmluZGV4KGtleSldCisgICAgICAgIGZvciBzZXF1ZW5jZSBpbiBwZW5kaW5nX3NlcXVlbmNlczoKKyAgICAgICAgICAgIGlmIHNlcXVlbmNlIG5vdCBpbiBhbGxfc2VxdWVuY2VzOgorICAgICAgICAgICAgICAgIGFsbF9zZXF1ZW5jZXNbc2VxdWVuY2VdID0gW2tleV0KKyAgICAgICAgc2VsZi5zZXRfc2VxdWVuY2VzKGFsbF9zZXF1ZW5jZXMpCisKKworY2xhc3MgQmFieWwoX3NpbmdsZWZpbGVNYWlsYm94KToKKyAgICAiIiJBbiBSbWFpbC1zdHlsZSBCYWJ5bCBtYWlsYm94LiIiIgorCisgICAgX3NwZWNpYWxfbGFiZWxzID0gZnJvemVuc2V0KCgndW5zZWVuJywgJ2RlbGV0ZWQnLCAnZmlsZWQnLCAnYW5zd2VyZWQnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2ZvcndhcmRlZCcsICdlZGl0ZWQnLCAncmVzZW50JykpCisKKyAgICBkZWYgX19pbml0X18oc2VsZiwgcGF0aCwgZmFjdG9yeT1Ob25lLCBjcmVhdGU9VHJ1ZSk6CisgICAgICAgICIiIkluaXRpYWxpemUgYSBCYWJ5bCBtYWlsYm94LiIiIgorICAgICAgICBfc2luZ2xlZmlsZU1haWxib3guX19pbml0X18oc2VsZiwgcGF0aCwgZmFjdG9yeSwgY3JlYXRlKQorICAgICAgICBzZWxmLl9sYWJlbHMgPSB7fQorCisgICAgZGVmIGFkZChzZWxmLCBtZXNzYWdlKToKKyAgICAgICAgIiIiQWRkIG1lc3NhZ2UgYW5kIHJldHVybiBhc3NpZ25lZCBrZXkuIiIiCisgICAgICAgIGtleSA9IF9zaW5nbGVmaWxlTWFpbGJveC5hZGQoc2VsZiwgbWVzc2FnZSkKKyAgICAgICAgaWYgaXNpbnN0YW5jZShtZXNzYWdlLCBCYWJ5bE1lc3NhZ2UpOgorICAgICAgICAgICAgc2VsZi5fbGFiZWxzW2tleV0gPSBtZXNzYWdlLmdldF9sYWJlbHMoKQorICAgICAgICByZXR1cm4ga2V5CisKKyAgICBkZWYgcmVtb3ZlKHNlbGYsIGtleSk6CisgICAgICAgICIiIlJlbW92ZSB0aGUga2V5ZWQgbWVzc2FnZTsgcmFpc2UgS2V5RXJyb3IgaWYgaXQgZG9lc24ndCBleGlzdC4iIiIKKyAgICAgICAgX3NpbmdsZWZpbGVNYWlsYm94LnJlbW92ZShzZWxmLCBrZXkpCisgICAgICAgIGlmIGtleSBpbiBzZWxmLl9sYWJlbHM6CisgICAgICAgICAgICBkZWwgc2VsZi5fbGFiZWxzW2tleV0KKworICAgIGRlZiBfX3NldGl0ZW1fXyhzZWxmLCBrZXksIG1lc3NhZ2UpOgorICAgICAgICAiIiJSZXBsYWNlIHRoZSBrZXllZCBtZXNzYWdlOyByYWlzZSBLZXlFcnJvciBpZiBpdCBkb2Vzbid0IGV4aXN0LiIiIgorICAgICAgICBfc2luZ2xlZmlsZU1haWxib3guX19zZXRpdGVtX18oc2VsZiwga2V5LCBtZXNzYWdlKQorICAgICAgICBpZiBpc2luc3RhbmNlKG1lc3NhZ2UsIEJhYnlsTWVzc2FnZSk6CisgICAgICAgICAgICBzZWxmLl9sYWJlbHNba2V5XSA9IG1lc3NhZ2UuZ2V0X2xhYmVscygpCisKKyAgICBkZWYgZ2V0X21lc3NhZ2Uoc2VsZiwga2V5KToKKyAgICAgICAgIiIiUmV0dXJuIGEgTWVzc2FnZSByZXByZXNlbnRhdGlvbiBvciByYWlzZSBhIEtleUVycm9yLiIiIgorICAgICAgICBzdGFydCwgc3RvcCA9IHNlbGYuX2xvb2t1cChrZXkpCisgICAgICAgIHNlbGYuX2ZpbGUuc2VlayhzdGFydCkKKyAgICAgICAgc2VsZi5fZmlsZS5yZWFkbGluZSgpICAgIyBTa2lwICcxLCcgbGluZSBzcGVjaWZ5aW5nIGxhYmVscy4KKyAgICAgICAgb3JpZ2luYWxfaGVhZGVycyA9IFN0cmluZ0lPLlN0cmluZ0lPKCkKKyAgICAgICAgd2hpbGUgVHJ1ZToKKyAgICAgICAgICAgIGxpbmUgPSBzZWxmLl9maWxlLnJlYWRsaW5lKCkKKyAgICAgICAgICAgIGlmIGxpbmUgPT0gJyoqKiBFT09IICoqKicgKyBvcy5saW5lc2VwIG9yIGxpbmUgPT0gJyc6CisgICAgICAgICAgICAgICAgYnJlYWsKKyAgICAgICAgICAgIG9yaWdpbmFsX2hlYWRlcnMud3JpdGUobGluZS5yZXBsYWNlKG9zLmxpbmVzZXAsICdcbicpKQorICAgICAgICB2aXNpYmxlX2hlYWRlcnMgPSBTdHJpbmdJTy5TdHJpbmdJTygpCisgICAgICAgIHdoaWxlIFRydWU6CisgICAgICAgICAgICBsaW5lID0gc2VsZi5fZmlsZS5yZWFkbGluZSgpCisgICAgICAgICAgICBpZiBsaW5lID09IG9zLmxpbmVzZXAgb3IgbGluZSA9PSAnJzoKKyAgICAgICAgICAgICAgICBicmVhaworICAgICAgICAgICAgdmlzaWJsZV9oZWFkZXJzLndyaXRlKGxpbmUucmVwbGFjZShvcy5saW5lc2VwLCAnXG4nKSkKKyAgICAgICAgYm9keSA9IHNlbGYuX2ZpbGUucmVhZChzdG9wIC0gc2VsZi5fZmlsZS50ZWxsKCkpLnJlcGxhY2Uob3MubGluZXNlcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1xuJykKKyAgICAgICAgbXNnID0gQmFieWxNZXNzYWdlKG9yaWdpbmFsX2hlYWRlcnMuZ2V0dmFsdWUoKSArIGJvZHkpCisgICAgICAgIG1zZy5zZXRfdmlzaWJsZSh2aXNpYmxlX2hlYWRlcnMuZ2V0dmFsdWUoKSkKKyAgICAgICAgaWYga2V5IGluIHNlbGYuX2xhYmVsczoKKyAgICAgICAgICAgIG1zZy5zZXRfbGFiZWxzKHNlbGYuX2xhYmVsc1trZXldKQorICAgICAgICByZXR1cm4gbXNnCisKKyAgICBkZWYgZ2V0X3N0cmluZyhzZWxmLCBrZXkpOgorICAgICAgICAiIiJSZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb3IgcmFpc2UgYSBLZXlFcnJvci4iIiIKKyAgICAgICAgc3RhcnQsIHN0b3AgPSBzZWxmLl9sb29rdXAoa2V5KQorICAgICAgICBzZWxmLl9maWxlLnNlZWsoc3RhcnQpCisgICAgICAgIHNlbGYuX2ZpbGUucmVhZGxpbmUoKSAgICMgU2tpcCAnMSwnIGxpbmUgc3BlY2lmeWluZyBsYWJlbHMuCisgICAgICAgIG9yaWdpbmFsX2hlYWRlcnMgPSBTdHJpbmdJTy5TdHJpbmdJTygpCisgICAgICAgIHdoaWxlIFRydWU6CisgICAgICAgICAgICBsaW5lID0gc2VsZi5fZmlsZS5yZWFkbGluZSgpCisgICAgICAgICAgICBpZiBsaW5lID09ICcqKiogRU9PSCAqKionICsgb3MubGluZXNlcCBvciBsaW5lID09ICcnOgorICAgICAgICAgICAgICAgIGJyZWFrCisgICAgICAgICAgICBvcmlnaW5hbF9oZWFkZXJzLndyaXRlKGxpbmUucmVwbGFjZShvcy5saW5lc2VwLCAnXG4nKSkKKyAgICAgICAgd2hpbGUgVHJ1ZToKKyAgICAgICAgICAgIGxpbmUgPSBzZWxmLl9maWxlLnJlYWRsaW5lKCkKKyAgICAgICAgICAgIGlmIGxpbmUgPT0gb3MubGluZXNlcCBvciBsaW5lID09ICcnOgorICAgICAgICAgICAgICAgIGJyZWFrCisgICAgICAgIHJldHVybiBvcmlnaW5hbF9oZWFkZXJzLmdldHZhbHVlKCkgKyBcCisgICAgICAgICAgICAgICBzZWxmLl9maWxlLnJlYWQoc3RvcCAtIHNlbGYuX2ZpbGUudGVsbCgpKS5yZXBsYWNlKG9zLmxpbmVzZXAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdcbicpCisKKyAgICBkZWYgZ2V0X2ZpbGUoc2VsZiwga2V5KToKKyAgICAgICAgIiIiUmV0dXJuIGEgZmlsZS1saWtlIHJlcHJlc2VudGF0aW9uIG9yIHJhaXNlIGEgS2V5RXJyb3IuIiIiCisgICAgICAgIHJldHVybiBTdHJpbmdJTy5TdHJpbmdJTyhzZWxmLmdldF9zdHJpbmcoa2V5KS5yZXBsYWNlKCdcbicsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9zLmxpbmVzZXApKQorCisgICAgZGVmIGdldF9sYWJlbHMoc2VsZik6CisgICAgICAgICIiIlJldHVybiBhIGxpc3Qgb2YgdXNlci1kZWZpbmVkIGxhYmVscyBpbiB0aGUgbWFpbGJveC4iIiIKKyAgICAgICAgc2VsZi5fbG9va3VwKCkKKyAgICAgICAgbGFiZWxzID0gc2V0KCkKKyAgICAgICAgZm9yIGxhYmVsX2xpc3QgaW4gc2VsZi5fbGFiZWxzLnZhbHVlcygpOgorICAgICAgICAgICAgbGFiZWxzLnVwZGF0ZShsYWJlbF9saXN0KQorICAgICAgICBsYWJlbHMuZGlmZmVyZW5jZV91cGRhdGUoc2VsZi5fc3BlY2lhbF9sYWJlbHMpCisgICAgICAgIHJldHVybiBsaXN0KGxhYmVscykKKworICAgIGRlZiBfZ2VuZXJhdGVfdG9jKHNlbGYpOgorICAgICAgICAiIiJHZW5lcmF0ZSBrZXktdG8tKHN0YXJ0LCBzdG9wKSB0YWJsZSBvZiBjb250ZW50cy4iIiIKKyAgICAgICAgc3RhcnRzLCBzdG9wcyA9IFtdLCBbXQorICAgICAgICBzZWxmLl9maWxlLnNlZWsoMCkKKyAgICAgICAgbmV4dF9wb3MgPSAwCisgICAgICAgIGxhYmVsX2xpc3RzID0gW10KKyAgICAgICAgd2hpbGUgVHJ1ZToKKyAgICAgICAgICAgIGxpbmVfcG9zID0gbmV4dF9wb3MKKyAgICAgICAgICAgIGxpbmUgPSBzZWxmLl9maWxlLnJlYWRsaW5lKCkKKyAgICAgICAgICAgIG5leHRfcG9zID0gc2VsZi5fZmlsZS50ZWxsKCkKKyAgICAgICAgICAgIGlmIGxpbmUgPT0gJ1wwMzdcMDE0JyArIG9zLmxpbmVzZXA6CisgICAgICAgICAgICAgICAgaWYgbGVuKHN0b3BzKSA8IGxlbihzdGFydHMpOgorICAgICAgICAgICAgICAgICAgICBzdG9wcy5hcHBlbmQobGluZV9wb3MgLSBsZW4ob3MubGluZXNlcCkpCisgICAgICAgICAgICAgICAgc3RhcnRzLmFwcGVuZChuZXh0X3BvcykKKyAgICAgICAgICAgICAgICBsYWJlbHMgPSBbbGFiZWwuc3RyaXAoKSBmb3IgbGFiZWwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbiBzZWxmLl9maWxlLnJlYWRsaW5lKClbMTpdLnNwbGl0KCcsJykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBsYWJlbC5zdHJpcCgpICE9ICcnXQorICAgICAgICAgICAgICAgIGxhYmVsX2xpc3RzLmFwcGVuZChsYWJlbHMpCisgICAgICAgICAgICBlbGlmIGxpbmUgPT0gJ1wwMzcnIG9yIGxpbmUgPT0gJ1wwMzcnICsgb3MubGluZXNlcDoKKyAgICAgICAgICAgICAgICBpZiBsZW4oc3RvcHMpIDwgbGVuKHN0YXJ0cyk6CisgICAgICAgICAgICAgICAgICAgIHN0b3BzLmFwcGVuZChsaW5lX3BvcyAtIGxlbihvcy5saW5lc2VwKSkKKyAgICAgICAgICAgIGVsaWYgbGluZSA9PSAnJzoKKyAgICAgICAgICAgICAgICBzdG9wcy5hcHBlbmQobGluZV9wb3MgLSBsZW4ob3MubGluZXNlcCkpCisgICAgICAgICAgICAgICAgYnJlYWsKKyAgICAgICAgc2VsZi5fdG9jID0gZGljdChlbnVtZXJhdGUoemlwKHN0YXJ0cywgc3RvcHMpKSkKKyAgICAgICAgc2VsZi5fbGFiZWxzID0gZGljdChlbnVtZXJhdGUobGFiZWxfbGlzdHMpKQorICAgICAgICBzZWxmLl9uZXh0X2tleSA9IGxlbihzZWxmLl90b2MpCisKKyAgICBkZWYgX3ByZV9tYWlsYm94X2hvb2soc2VsZiwgZik6CisgICAgICAgICIiIkNhbGxlZCBiZWZvcmUgd3JpdGluZyB0aGUgbWFpbGJveCB0byBmaWxlIGYuIiIiCisgICAgICAgIGYud3JpdGUoJ0JBQllMIE9QVElPTlM6JXNWZXJzaW9uOiA1JXNMYWJlbHM6JXMlc1wwMzcnICUKKyAgICAgICAgICAgICAgICAob3MubGluZXNlcCwgb3MubGluZXNlcCwgJywnLmpvaW4oc2VsZi5nZXRfbGFiZWxzKCkpLAorICAgICAgICAgICAgICAgICBvcy5saW5lc2VwKSkKKworICAgIGRlZiBfcHJlX21lc3NhZ2VfaG9vayhzZWxmLCBmKToKKyAgICAgICAgIiIiQ2FsbGVkIGJlZm9yZSB3cml0aW5nIGVhY2ggbWVzc2FnZSB0byBmaWxlIGYuIiIiCisgICAgICAgIGYud3JpdGUoJ1wwMTQnICsgb3MubGluZXNlcCkKKworICAgIGRlZiBfcG9zdF9tZXNzYWdlX2hvb2soc2VsZiwgZik6CisgICAgICAgICIiIkNhbGxlZCBhZnRlciB3cml0aW5nIGVhY2ggbWVzc2FnZSB0byBmaWxlIGYuIiIiCisgICAgICAgIGYud3JpdGUob3MubGluZXNlcCArICdcMDM3JykKKworICAgIGRlZiBfaW5zdGFsbF9tZXNzYWdlKHNlbGYsIG1lc3NhZ2UpOgorICAgICAgICAiIiJXcml0ZSBtZXNzYWdlIGNvbnRlbnRzIGFuZCByZXR1cm4gKHN0YXJ0LCBzdG9wKS4iIiIKKyAgICAgICAgc3RhcnQgPSBzZWxmLl9maWxlLnRlbGwoKQorICAgICAgICBpZiBpc2luc3RhbmNlKG1lc3NhZ2UsIEJhYnlsTWVzc2FnZSk6CisgICAgICAgICAgICBzcGVjaWFsX2xhYmVscyA9IFtdCisgICAgICAgICAgICBsYWJlbHMgPSBbXQorICAgICAgICAgICAgZm9yIGxhYmVsIGluIG1lc3NhZ2UuZ2V0X2xhYmVscygpOgorICAgICAgICAgICAgICAgIGlmIGxhYmVsIGluIHNlbGYuX3NwZWNpYWxfbGFiZWxzOgorICAgICAgICAgICAgICAgICAgICBzcGVjaWFsX2xhYmVscy5hcHBlbmQobGFiZWwpCisgICAgICAgICAgICAgICAgZWxzZToKKyAgICAgICAgICAgICAgICAgICAgbGFiZWxzLmFwcGVuZChsYWJlbCkKKyAgICAgICAgICAgIHNlbGYuX2ZpbGUud3JpdGUoJzEnKQorICAgICAgICAgICAgZm9yIGxhYmVsIGluIHNwZWNpYWxfbGFiZWxzOgorICAgICAgICAgICAgICAgIHNlbGYuX2ZpbGUud3JpdGUoJywgJyArIGxhYmVsKQorICAgICAgICAgICAgc2VsZi5fZmlsZS53cml0ZSgnLCwnKQorICAgICAgICAgICAgZm9yIGxhYmVsIGluIGxhYmVsczoKKyAgICAgICAgICAgICAgICBzZWxmLl9maWxlLndyaXRlKCcgJyArIGxhYmVsICsgJywnKQorICAgICAgICAgICAgc2VsZi5fZmlsZS53cml0ZShvcy5saW5lc2VwKQorICAgICAgICBlbHNlOgorICAgICAgICAgICAgc2VsZi5fZmlsZS53cml0ZSgnMSwsJyArIG9zLmxpbmVzZXApCisgICAgICAgIGlmIGlzaW5zdGFuY2UobWVzc2FnZSwgZW1haWwuTWVzc2FnZS5NZXNzYWdlKToKKyAgICAgICAgICAgIG9yaWdfYnVmZmVyID0gU3RyaW5nSU8uU3RyaW5nSU8oKQorICAgICAgICAgICAgb3JpZ19nZW5lcmF0b3IgPSBlbWFpbC5HZW5lcmF0b3IuR2VuZXJhdG9yKG9yaWdfYnVmZmVyLCBGYWxzZSwgMCkKKyAgICAgICAgICAgIG9yaWdfZ2VuZXJhdG9yLmZsYXR0ZW4obWVzc2FnZSkKKyAgICAgICAgICAgIG9yaWdfYnVmZmVyLnNlZWsoMCkKKyAgICAgICAgICAgIHdoaWxlIFRydWU6CisgICAgICAgICAgICAgICAgbGluZSA9IG9yaWdfYnVmZmVyLnJlYWRsaW5lKCkKKyAgICAgICAgICAgICAgICBzZWxmLl9maWxlLndyaXRlKGxpbmUucmVwbGFjZSgnXG4nLCBvcy5saW5lc2VwKSkKKyAgICAgICAgICAgICAgICBpZiBsaW5lID09ICdcbicgb3IgbGluZSA9PSAnJzoKKyAgICAgICAgICAgICAgICAgICAgYnJlYWsKKyAgICAgICAgICAgIHNlbGYuX2ZpbGUud3JpdGUoJyoqKiBFT09IICoqKicgKyBvcy5saW5lc2VwKQorICAgICAgICAgICAgaWYgaXNpbnN0YW5jZShtZXNzYWdlLCBCYWJ5bE1lc3NhZ2UpOgorICAgICAgICAgICAgICAgIHZpc19idWZmZXIgPSBTdHJpbmdJTy5TdHJpbmdJTygpCisgICAgICAgICAgICAgICAgdmlzX2dlbmVyYXRvciA9IGVtYWlsLkdlbmVyYXRvci5HZW5lcmF0b3IodmlzX2J1ZmZlciwgRmFsc2UsIDApCisgICAgICAgICAgICAgICAgdmlzX2dlbmVyYXRvci5mbGF0dGVuKG1lc3NhZ2UuZ2V0X3Zpc2libGUoKSkKKyAgICAgICAgICAgICAgICB3aGlsZSBUcnVlOgorICAgICAgICAgICAgICAgICAgICBsaW5lID0gdmlzX2J1ZmZlci5yZWFkbGluZSgpCisgICAgICAgICAgICAgICAgICAgIHNlbGYuX2ZpbGUud3JpdGUobGluZS5yZXBsYWNlKCdcbicsIG9zLmxpbmVzZXApKQorICAgICAgICAgICAgICAgICAgICBpZiBsaW5lID09ICdcbicgb3IgbGluZSA9PSAnJzoKKyAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrCisgICAgICAgICAgICBlbHNlOgorICAgICAgICAgICAgICAgIG9yaWdfYnVmZmVyLnNlZWsoMCkKKyAgICAgICAgICAgICAgICB3aGlsZSBUcnVlOgorICAgICAgICAgICAgICAgICAgICBsaW5lID0gb3JpZ19idWZmZXIucmVhZGxpbmUoKQorICAgICAgICAgICAgICAgICAgICBzZWxmLl9maWxlLndyaXRlKGxpbmUucmVwbGFjZSgnXG4nLCBvcy5saW5lc2VwKSkKKyAgICAgICAgICAgICAgICAgICAgaWYgbGluZSA9PSAnXG4nIG9yIGxpbmUgPT0gJyc6CisgICAgICAgICAgICAgICAgICAgICAgICBicmVhaworICAgICAgICAgICAgd2hpbGUgVHJ1ZToKKyAgICAgICAgICAgICAgICBidWZmZXIgPSBvcmlnX2J1ZmZlci5yZWFkKDQwOTYpICMgQnVmZmVyIHNpemUgaXMgYXJiaXRyYXJ5LgorICAgICAgICAgICAgICAgIGlmIGJ1ZmZlciA9PSAnJzoKKyAgICAgICAgICAgICAgICAgICAgYnJlYWsKKyAgICAgICAgICAgICAgICBzZWxmLl9maWxlLndyaXRlKGJ1ZmZlci5yZXBsYWNlKCdcbicsIG9zLmxpbmVzZXApKQorICAgICAgICBlbGlmIGlzaW5zdGFuY2UobWVzc2FnZSwgc3RyKToKKyAgICAgICAgICAgIGJvZHlfc3RhcnQgPSBtZXNzYWdlLmZpbmQoJ1xuXG4nKSArIDIKKyAgICAgICAgICAgIGlmIGJvZHlfc3RhcnQgLSAyICE9IC0xOgorICAgICAgICAgICAgICAgIHNlbGYuX2ZpbGUud3JpdGUobWVzc2FnZVs6Ym9keV9zdGFydF0ucmVwbGFjZSgnXG4nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcy5saW5lc2VwKSkKKyAgICAgICAgICAgICAgICBzZWxmLl9maWxlLndyaXRlKCcqKiogRU9PSCAqKionICsgb3MubGluZXNlcCkKKyAgICAgICAgICAgICAgICBzZWxmLl9maWxlLndyaXRlKG1lc3NhZ2VbOmJvZHlfc3RhcnRdLnJlcGxhY2UoJ1xuJywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3MubGluZXNlcCkpCisgICAgICAgICAgICAgICAgc2VsZi5fZmlsZS53cml0ZShtZXNzYWdlW2JvZHlfc3RhcnQ6XS5yZXBsYWNlKCdcbicsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9zLmxpbmVzZXApKQorICAgICAgICAgICAgZWxzZToKKyAgICAgICAgICAgICAgICBzZWxmLl9maWxlLndyaXRlKCcqKiogRU9PSCAqKionICsgb3MubGluZXNlcCArIG9zLmxpbmVzZXApCisgICAgICAgICAgICAgICAgc2VsZi5fZmlsZS53cml0ZShtZXNzYWdlLnJlcGxhY2UoJ1xuJywgb3MubGluZXNlcCkpCisgICAgICAgIGVsaWYgaGFzYXR0cihtZXNzYWdlLCAncmVhZGxpbmUnKToKKyAgICAgICAgICAgIG9yaWdpbmFsX3BvcyA9IG1lc3NhZ2UudGVsbCgpCisgICAgICAgICAgICBmaXJzdF9wYXNzID0gVHJ1ZQorICAgICAgICAgICAgd2hpbGUgVHJ1ZToKKyAgICAgICAgICAgICAgICBsaW5lID0gbWVzc2FnZS5yZWFkbGluZSgpCisgICAgICAgICAgICAgICAgc2VsZi5fZmlsZS53cml0ZShsaW5lLnJlcGxhY2UoJ1xuJywgb3MubGluZXNlcCkpCisgICAgICAgICAgICAgICAgaWYgbGluZSA9PSAnXG4nIG9yIGxpbmUgPT0gJyc6CisgICAgICAgICAgICAgICAgICAgIHNlbGYuX2ZpbGUud3JpdGUoJyoqKiBFT09IICoqKicgKyBvcy5saW5lc2VwKQorICAgICAgICAgICAgICAgICAgICBpZiBmaXJzdF9wYXNzOgorICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3RfcGFzcyA9IEZhbHNlCisgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnNlZWsob3JpZ2luYWxfcG9zKQorICAgICAgICAgICAgICAgICAgICBlbHNlOgorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsKKyAgICAgICAgICAgIHdoaWxlIFRydWU6CisgICAgICAgICAgICAgICAgYnVmZmVyID0gbWVzc2FnZS5yZWFkKDQwOTYpICAgICAjIEJ1ZmZlciBzaXplIGlzIGFyYml0cmFyeS4KKyAgICAgICAgICAgICAgICBpZiBidWZmZXIgPT0gJyc6CisgICAgICAgICAgICAgICAgICAgIGJyZWFrCisgICAgICAgICAgICAgICAgc2VsZi5fZmlsZS53cml0ZShidWZmZXIucmVwbGFjZSgnXG4nLCBvcy5saW5lc2VwKSkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICAgIHJhaXNlIFR5cGVFcnJvcignSW52YWxpZCBtZXNzYWdlIHR5cGU6ICVzJyAlIHR5cGUobWVzc2FnZSkpCisgICAgICAgIHN0b3AgPSBzZWxmLl9maWxlLnRlbGwoKQorICAgICAgICByZXR1cm4gKHN0YXJ0LCBzdG9wKQorCisKK2NsYXNzIE1lc3NhZ2UoZW1haWwuTWVzc2FnZS5NZXNzYWdlKToKKyAgICAiIiJNZXNzYWdlIHdpdGggbWFpbGJveC1mb3JtYXQtc3BlY2lmaWMgcHJvcGVydGllcy4iIiIKKworICAgIGRlZiBfX2luaXRfXyhzZWxmLCBtZXNzYWdlPU5vbmUpOgorICAgICAgICAiIiJJbml0aWFsaXplIGEgTWVzc2FnZSBpbnN0YW5jZS4iIiIKKyAgICAgICAgaWYgaXNpbnN0YW5jZShtZXNzYWdlLCBlbWFpbC5NZXNzYWdlLk1lc3NhZ2UpOgorICAgICAgICAgICAgc2VsZi5fYmVjb21lX21lc3NhZ2UoY29weS5kZWVwY29weShtZXNzYWdlKSkKKyAgICAgICAgICAgIGlmIGlzaW5zdGFuY2UobWVzc2FnZSwgTWVzc2FnZSk6CisgICAgICAgICAgICAgICAgbWVzc2FnZS5fZXhwbGFpbl90byhzZWxmKQorICAgICAgICBlbGlmIGlzaW5zdGFuY2UobWVzc2FnZSwgc3RyKToKKyAgICAgICAgICAgIHNlbGYuX2JlY29tZV9tZXNzYWdlKGVtYWlsLm1lc3NhZ2VfZnJvbV9zdHJpbmcobWVzc2FnZSkpCisgICAgICAgIGVsaWYgaGFzYXR0cihtZXNzYWdlLCAicmVhZCIpOgorICAgICAgICAgICAgc2VsZi5fYmVjb21lX21lc3NhZ2UoZW1haWwubWVzc2FnZV9mcm9tX2ZpbGUobWVzc2FnZSkpCisgICAgICAgIGVsaWYgbWVzc2FnZSBpcyBOb25lOgorICAgICAgICAgICAgZW1haWwuTWVzc2FnZS5NZXNzYWdlLl9faW5pdF9fKHNlbGYpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgICByYWlzZSBUeXBlRXJyb3IoJ0ludmFsaWQgbWVzc2FnZSB0eXBlOiAlcycgJSB0eXBlKG1lc3NhZ2UpKQorCisgICAgZGVmIF9iZWNvbWVfbWVzc2FnZShzZWxmLCBtZXNzYWdlKToKKyAgICAgICAgIiIiQXNzdW1lIHRoZSBub24tZm9ybWF0LXNwZWNpZmljIHN0YXRlIG9mIG1lc3NhZ2UuIiIiCisgICAgICAgIGZvciBuYW1lIGluICgnX2hlYWRlcnMnLCAnX3VuaXhmcm9tJywgJ19wYXlsb2FkJywgJ19jaGFyc2V0JywKKyAgICAgICAgICAgICAgICAgICAgICdwcmVhbWJsZScsICdlcGlsb2d1ZScsICdkZWZlY3RzJywgJ19kZWZhdWx0X3R5cGUnKToKKyAgICAgICAgICAgIHNlbGYuX19kaWN0X19bbmFtZV0gPSBtZXNzYWdlLl9fZGljdF9fW25hbWVdCisKKyAgICBkZWYgX2V4cGxhaW5fdG8oc2VsZiwgbWVzc2FnZSk6CisgICAgICAgICIiIkNvcHkgZm9ybWF0LXNwZWNpZmljIHN0YXRlIHRvIG1lc3NhZ2UgaW5zb2ZhciBhcyBwb3NzaWJsZS4iIiIKKyAgICAgICAgaWYgaXNpbnN0YW5jZShtZXNzYWdlLCBNZXNzYWdlKToKKyAgICAgICAgICAgIHJldHVybiAgIyBUaGVyZSdzIG5vdGhpbmcgZm9ybWF0LXNwZWNpZmljIHRvIGV4cGxhaW4uCisgICAgICAgIGVsc2U6CisgICAgICAgICAgICByYWlzZSBUeXBlRXJyb3IoJ0Nhbm5vdCBjb252ZXJ0IHRvIHNwZWNpZmllZCB0eXBlJykKKworCitjbGFzcyBNYWlsZGlyTWVzc2FnZShNZXNzYWdlKToKKyAgICAiIiJNZXNzYWdlIHdpdGggTWFpbGRpci1zcGVjaWZpYyBwcm9wZXJ0aWVzLiIiIgorCisgICAgZGVmIF9faW5pdF9fKHNlbGYsIG1lc3NhZ2U9Tm9uZSk6CisgICAgICAgICIiIkluaXRpYWxpemUgYSBNYWlsZGlyTWVzc2FnZSBpbnN0YW5jZS4iIiIKKyAgICAgICAgc2VsZi5fc3ViZGlyID0gJ25ldycKKyAgICAgICAgc2VsZi5faW5mbyA9ICcnCisgICAgICAgIHNlbGYuX2RhdGUgPSB0aW1lLnRpbWUoKQorICAgICAgICBNZXNzYWdlLl9faW5pdF9fKHNlbGYsIG1lc3NhZ2UpCisKKyAgICBkZWYgZ2V0X3N1YmRpcihzZWxmKToKKyAgICAgICAgIiIiUmV0dXJuICduZXcnIG9yICdjdXInLiIiIgorICAgICAgICByZXR1cm4gc2VsZi5fc3ViZGlyCisKKyAgICBkZWYgc2V0X3N1YmRpcihzZWxmLCBzdWJkaXIpOgorICAgICAgICAiIiJTZXQgc3ViZGlyIHRvICduZXcnIG9yICdjdXInLiIiIgorICAgICAgICBpZiBzdWJkaXIgPT0gJ25ldycgb3Igc3ViZGlyID09ICdjdXInOgorICAgICAgICAgICAgc2VsZi5fc3ViZGlyID0gc3ViZGlyCisgICAgICAgIGVsc2U6CisgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJzdWJkaXIgbXVzdCBiZSAnbmV3JyBvciAnY3VyJzogJXMiICUgc3ViZGlyKQorCisgICAgZGVmIGdldF9mbGFncyhzZWxmKToKKyAgICAgICAgIiIiUmV0dXJuIGFzIGEgc3RyaW5nIHRoZSBmbGFncyB0aGF0IGFyZSBzZXQuIiIiCisgICAgICAgIGlmIHNlbGYuX2luZm8uc3RhcnRzd2l0aCgnMiwnKToKKyAgICAgICAgICAgIHJldHVybiBzZWxmLl9pbmZvWzI6XQorICAgICAgICBlbHNlOgorICAgICAgICAgICAgcmV0dXJuICcnCisKKyAgICBkZWYgc2V0X2ZsYWdzKHNlbGYsIGZsYWdzKToKKyAgICAgICAgIiIiU2V0IHRoZSBnaXZlbiBmbGFncyBhbmQgdW5zZXQgYWxsIG90aGVycy4iIiIKKyAgICAgICAgc2VsZi5faW5mbyA9ICcyLCcgKyAnJy5qb2luKHNvcnRlZChmbGFncykpCisKKyAgICBkZWYgYWRkX2ZsYWcoc2VsZiwgZmxhZyk6CisgICAgICAgICIiIlNldCB0aGUgZ2l2ZW4gZmxhZyhzKSB3aXRob3V0IGNoYW5naW5nIG90aGVycy4iIiIKKyAgICAgICAgc2VsZi5zZXRfZmxhZ3MoJycuam9pbihzZXQoc2VsZi5nZXRfZmxhZ3MoKSkgfCBzZXQoZmxhZykpKQorCisgICAgZGVmIHJlbW92ZV9mbGFnKHNlbGYsIGZsYWcpOgorICAgICAgICAiIiJVbnNldCB0aGUgZ2l2ZW4gc3RyaW5nIGZsYWcocykgd2l0aG91dCBjaGFuZ2luZyBvdGhlcnMuIiIiCisgICAgICAgIGlmIHNlbGYuZ2V0X2ZsYWdzKCkgIT0gJyc6CisgICAgICAgICAgICBzZWxmLnNldF9mbGFncygnJy5qb2luKHNldChzZWxmLmdldF9mbGFncygpKSAtIHNldChmbGFnKSkpCisKKyAgICBkZWYgZ2V0X2RhdGUoc2VsZik6CisgICAgICAgICIiIlJldHVybiBkZWxpdmVyeSBkYXRlIG9mIG1lc3NhZ2UsIGluIHNlY29uZHMgc2luY2UgdGhlIGVwb2NoLiIiIgorICAgICAgICByZXR1cm4gc2VsZi5fZGF0ZQorCisgICAgZGVmIHNldF9kYXRlKHNlbGYsIGRhdGUpOgorICAgICAgICAiIiJTZXQgZGVsaXZlcnkgZGF0ZSBvZiBtZXNzYWdlLCBpbiBzZWNvbmRzIHNpbmNlIHRoZSBlcG9jaC4iIiIKKyAgICAgICAgdHJ5OgorICAgICAgICAgICAgc2VsZi5fZGF0ZSA9IGZsb2F0KGRhdGUpCisgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgorICAgICAgICAgICAgcmFpc2UgVHlwZUVycm9yKCJjYW4ndCBjb252ZXJ0IHRvIGZsb2F0OiAlcyIgJSBkYXRlKQorCisgICAgZGVmIGdldF9pbmZvKHNlbGYpOgorICAgICAgICAiIiJHZXQgdGhlIG1lc3NhZ2UncyAiaW5mbyIgYXMgYSBzdHJpbmcuIiIiCisgICAgICAgIHJldHVybiBzZWxmLl9pbmZvCisKKyAgICBkZWYgc2V0X2luZm8oc2VsZiwgaW5mbyk6CisgICAgICAgICIiIlNldCB0aGUgbWVzc2FnZSdzICJpbmZvIiBzdHJpbmcuIiIiCisgICAgICAgIGlmIGlzaW5zdGFuY2UoaW5mbywgc3RyKToKKyAgICAgICAgICAgIHNlbGYuX2luZm8gPSBpbmZvCisgICAgICAgIGVsc2U6CisgICAgICAgICAgICByYWlzZSBUeXBlRXJyb3IoJ2luZm8gbXVzdCBiZSBhIHN0cmluZzogJXMnICUgdHlwZShpbmZvKSkKKworICAgIGRlZiBfZXhwbGFpbl90byhzZWxmLCBtZXNzYWdlKToKKyAgICAgICAgIiIiQ29weSBNYWlsZGlyLXNwZWNpZmljIHN0YXRlIHRvIG1lc3NhZ2UgaW5zb2ZhciBhcyBwb3NzaWJsZS4iIiIKKyAgICAgICAgaWYgaXNpbnN0YW5jZShtZXNzYWdlLCBNYWlsZGlyTWVzc2FnZSk6CisgICAgICAgICAgICBtZXNzYWdlLnNldF9mbGFncyhzZWxmLmdldF9mbGFncygpKQorICAgICAgICAgICAgbWVzc2FnZS5zZXRfc3ViZGlyKHNlbGYuZ2V0X3N1YmRpcigpKQorICAgICAgICAgICAgbWVzc2FnZS5zZXRfZGF0ZShzZWxmLmdldF9kYXRlKCkpCisgICAgICAgIGVsaWYgaXNpbnN0YW5jZShtZXNzYWdlLCBfbWJveE1NREZNZXNzYWdlKToKKyAgICAgICAgICAgIGZsYWdzID0gc2V0KHNlbGYuZ2V0X2ZsYWdzKCkpCisgICAgICAgICAgICBpZiAnUycgaW4gZmxhZ3M6CisgICAgICAgICAgICAgICAgbWVzc2FnZS5hZGRfZmxhZygnUicpCisgICAgICAgICAgICBpZiBzZWxmLmdldF9zdWJkaXIoKSA9PSAnY3VyJzoKKyAgICAgICAgICAgICAgICBtZXNzYWdlLmFkZF9mbGFnKCdPJykKKyAgICAgICAgICAgIGlmICdUJyBpbiBmbGFnczoKKyAgICAgICAgICAgICAgICBtZXNzYWdlLmFkZF9mbGFnKCdEJykKKyAgICAgICAgICAgIGlmICdGJyBpbiBmbGFnczoKKyAgICAgICAgICAgICAgICBtZXNzYWdlLmFkZF9mbGFnKCdGJykKKyAgICAgICAgICAgIGlmICdSJyBpbiBmbGFnczoKKyAgICAgICAgICAgICAgICBtZXNzYWdlLmFkZF9mbGFnKCdBJykKKyAgICAgICAgICAgIG1lc3NhZ2Uuc2V0X2Zyb20oJ01BSUxFUi1EQUVNT04nLCB0aW1lLmdtdGltZShzZWxmLmdldF9kYXRlKCkpKQorICAgICAgICBlbGlmIGlzaW5zdGFuY2UobWVzc2FnZSwgTUhNZXNzYWdlKToKKyAgICAgICAgICAgIGZsYWdzID0gc2V0KHNlbGYuZ2V0X2ZsYWdzKCkpCisgICAgICAgICAgICBpZiAnUycgbm90IGluIGZsYWdzOgorICAgICAgICAgICAgICAgIG1lc3NhZ2UuYWRkX3NlcXVlbmNlKCd1bnNlZW4nKQorICAgICAgICAgICAgaWYgJ1InIGluIGZsYWdzOgorICAgICAgICAgICAgICAgIG1lc3NhZ2UuYWRkX3NlcXVlbmNlKCdyZXBsaWVkJykKKyAgICAgICAgICAgIGlmICdGJyBpbiBmbGFnczoKKyAgICAgICAgICAgICAgICBtZXNzYWdlLmFkZF9zZXF1ZW5jZSgnZmxhZ2dlZCcpCisgICAgICAgIGVsaWYgaXNpbnN0YW5jZShtZXNzYWdlLCBCYWJ5bE1lc3NhZ2UpOgorICAgICAgICAgICAgZmxhZ3MgPSBzZXQoc2VsZi5nZXRfZmxhZ3MoKSkKKyAgICAgICAgICAgIGlmICdTJyBub3QgaW4gZmxhZ3M6CisgICAgICAgICAgICAgICAgbWVzc2FnZS5hZGRfbGFiZWwoJ3Vuc2VlbicpCisgICAgICAgICAgICBpZiAnVCcgaW4gZmxhZ3M6CisgICAgICAgICAgICAgICAgbWVzc2FnZS5hZGRfbGFiZWwoJ2RlbGV0ZWQnKQorICAgICAgICAgICAgaWYgJ1InIGluIGZsYWdzOgorICAgICAgICAgICAgICAgIG1lc3NhZ2UuYWRkX2xhYmVsKCdhbnN3ZXJlZCcpCisgICAgICAgICAgICBpZiAnUCcgaW4gZmxhZ3M6CisgICAgICAgICAgICAgICAgbWVzc2FnZS5hZGRfbGFiZWwoJ2ZvcndhcmRlZCcpCisgICAgICAgIGVsaWYgaXNpbnN0YW5jZShtZXNzYWdlLCBNZXNzYWdlKToKKyAgICAgICAgICAgIHBhc3MKKyAgICAgICAgZWxzZToKKyAgICAgICAgICAgIHJhaXNlIFR5cGVFcnJvcignQ2Fubm90IGNvbnZlcnQgdG8gc3BlY2lmaWVkIHR5cGU6ICVzJyAlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZShtZXNzYWdlKSkKKworCitjbGFzcyBfbWJveE1NREZNZXNzYWdlKE1lc3NhZ2UpOgorICAgICIiIk1lc3NhZ2Ugd2l0aCBtYm94LSBvciBNTURGLXNwZWNpZmljIHByb3BlcnRpZXMuIiIiCisKKyAgICBkZWYgX19pbml0X18oc2VsZiwgbWVzc2FnZT1Ob25lKToKKyAgICAgICAgIiIiSW5pdGlhbGl6ZSBhbiBtYm94TU1ERk1lc3NhZ2UgaW5zdGFuY2UuIiIiCisgICAgICAgIHNlbGYuc2V0X2Zyb20oJ01BSUxFUi1EQUVNT04nLCBUcnVlKQorICAgICAgICBpZiBpc2luc3RhbmNlKG1lc3NhZ2UsIGVtYWlsLk1lc3NhZ2UuTWVzc2FnZSk6CisgICAgICAgICAgICB1bml4ZnJvbSA9IG1lc3NhZ2UuZ2V0X3VuaXhmcm9tKCkKKyAgICAgICAgICAgIGlmIHVuaXhmcm9tIGlzIG5vdCBOb25lIGFuZCB1bml4ZnJvbS5zdGFydHN3aXRoKCdGcm9tICcpOgorICAgICAgICAgICAgICAgIHNlbGYuc2V0X2Zyb20odW5peGZyb21bNTpdKQorICAgICAgICBNZXNzYWdlLl9faW5pdF9fKHNlbGYsIG1lc3NhZ2UpCisKKyAgICBkZWYgZ2V0X2Zyb20oc2VsZik6CisgICAgICAgICIiIlJldHVybiBjb250ZW50cyBvZiAiRnJvbSAiIGxpbmUuIiIiCisgICAgICAgIHJldHVybiBzZWxmLl9mcm9tCisKKyAgICBkZWYgc2V0X2Zyb20oc2VsZiwgZnJvbV8sIHRpbWVfPU5vbmUpOgorICAgICAgICAiIiJTZXQgIkZyb20gIiBsaW5lLCBmb3JtYXR0aW5nIGFuZCBhcHBlbmRpbmcgdGltZV8gaWYgc3BlY2lmaWVkLiIiIgorICAgICAgICBpZiB0aW1lXyBpcyBub3QgTm9uZToKKyAgICAgICAgICAgIGlmIHRpbWVfIGlzIFRydWU6CisgICAgICAgICAgICAgICAgdGltZV8gPSB0aW1lLmdtdGltZSgpCisgICAgICAgICAgICBmcm9tXyArPSAnICcgKyB0aW1lLmFzY3RpbWUodGltZV8pCisgICAgICAgIHNlbGYuX2Zyb20gPSBmcm9tXworCisgICAgZGVmIGdldF9mbGFncyhzZWxmKToKKyAgICAgICAgIiIiUmV0dXJuIGFzIGEgc3RyaW5nIHRoZSBmbGFncyB0aGF0IGFyZSBzZXQuIiIiCisgICAgICAgIHJldHVybiBzZWxmLmdldCgnU3RhdHVzJywgJycpICsgc2VsZi5nZXQoJ1gtU3RhdHVzJywgJycpCisKKyAgICBkZWYgc2V0X2ZsYWdzKHNlbGYsIGZsYWdzKToKKyAgICAgICAgIiIiU2V0IHRoZSBnaXZlbiBmbGFncyBhbmQgdW5zZXQgYWxsIG90aGVycy4iIiIKKyAgICAgICAgZmxhZ3MgPSBzZXQoZmxhZ3MpCisgICAgICAgIHN0YXR1c19mbGFncywgeHN0YXR1c19mbGFncyA9ICcnLCAnJworICAgICAgICBmb3IgZmxhZyBpbiAoJ1InLCAnTycpOgorICAgICAgICAgICAgaWYgZmxhZyBpbiBmbGFnczoKKyAgICAgICAgICAgICAgICBzdGF0dXNfZmxhZ3MgKz0gZmxhZworICAgICAgICAgICAgICAgIGZsYWdzLnJlbW92ZShmbGFnKQorICAgICAgICBmb3IgZmxhZyBpbiAoJ0QnLCAnRicsICdBJyk6CisgICAgICAgICAgICBpZiBmbGFnIGluIGZsYWdzOgorICAgICAgICAgICAgICAgIHhzdGF0dXNfZmxhZ3MgKz0gZmxhZworICAgICAgICAgICAgICAgIGZsYWdzLnJlbW92ZShmbGFnKQorICAgICAgICB4c3RhdHVzX2ZsYWdzICs9ICcnLmpvaW4oc29ydGVkKGZsYWdzKSkKKyAgICAgICAgdHJ5OgorICAgICAgICAgICAgc2VsZi5yZXBsYWNlX2hlYWRlcignU3RhdHVzJywgc3RhdHVzX2ZsYWdzKQorICAgICAgICBleGNlcHQgS2V5RXJyb3I6CisgICAgICAgICAgICBzZWxmLmFkZF9oZWFkZXIoJ1N0YXR1cycsIHN0YXR1c19mbGFncykKKyAgICAgICAgdHJ5OgorICAgICAgICAgICAgc2VsZi5yZXBsYWNlX2hlYWRlcignWC1TdGF0dXMnLCB4c3RhdHVzX2ZsYWdzKQorICAgICAgICBleGNlcHQgS2V5RXJyb3I6CisgICAgICAgICAgICBzZWxmLmFkZF9oZWFkZXIoJ1gtU3RhdHVzJywgeHN0YXR1c19mbGFncykKKworICAgIGRlZiBhZGRfZmxhZyhzZWxmLCBmbGFnKToKKyAgICAgICAgIiIiU2V0IHRoZSBnaXZlbiBmbGFnKHMpIHdpdGhvdXQgY2hhbmdpbmcgb3RoZXJzLiIiIgorICAgICAgICBzZWxmLnNldF9mbGFncygnJy5qb2luKHNldChzZWxmLmdldF9mbGFncygpKSB8IHNldChmbGFnKSkpCisKKyAgICBkZWYgcmVtb3ZlX2ZsYWcoc2VsZiwgZmxhZyk6CisgICAgICAgICIiIlVuc2V0IHRoZSBnaXZlbiBzdHJpbmcgZmxhZyhzKSB3aXRob3V0IGNoYW5naW5nIG90aGVycy4iIiIKKyAgICAgICAgaWYgJ1N0YXR1cycgaW4gc2VsZiBvciAnWC1TdGF0dXMnIGluIHNlbGY6CisgICAgICAgICAgICBzZWxmLnNldF9mbGFncygnJy5qb2luKHNldChzZWxmLmdldF9mbGFncygpKSAtIHNldChmbGFnKSkpCisKKyAgICBkZWYgX2V4cGxhaW5fdG8oc2VsZiwgbWVzc2FnZSk6CisgICAgICAgICIiIkNvcHkgbWJveC0gb3IgTU1ERi1zcGVjaWZpYyBzdGF0ZSB0byBtZXNzYWdlIGluc29mYXIgYXMgcG9zc2libGUuIiIiCisgICAgICAgIGlmIGlzaW5zdGFuY2UobWVzc2FnZSwgTWFpbGRpck1lc3NhZ2UpOgorICAgICAgICAgICAgZmxhZ3MgPSBzZXQoc2VsZi5nZXRfZmxhZ3MoKSkKKyAgICAgICAgICAgIGlmICdPJyBpbiBmbGFnczoKKyAgICAgICAgICAgICAgICBtZXNzYWdlLnNldF9zdWJkaXIoJ2N1cicpCisgICAgICAgICAgICBpZiAnRicgaW4gZmxhZ3M6CisgICAgICAgICAgICAgICAgbWVzc2FnZS5hZGRfZmxhZygnRicpCisgICAgICAgICAgICBpZiAnQScgaW4gZmxhZ3M6CisgICAgICAgICAgICAgICAgbWVzc2FnZS5hZGRfZmxhZygnUicpCisgICAgICAgICAgICBpZiAnUicgaW4gZmxhZ3M6CisgICAgICAgICAgICAgICAgbWVzc2FnZS5hZGRfZmxhZygnUycpCisgICAgICAgICAgICBpZiAnRCcgaW4gZmxhZ3M6CisgICAgICAgICAgICAgICAgbWVzc2FnZS5hZGRfZmxhZygnVCcpCisgICAgICAgICAgICBkZWwgbWVzc2FnZVsnc3RhdHVzJ10KKyAgICAgICAgICAgIGRlbCBtZXNzYWdlWyd4LXN0YXR1cyddCisgICAgICAgICAgICBtYXliZV9kYXRlID0gJyAnLmpvaW4oc2VsZi5nZXRfZnJvbSgpLnNwbGl0KClbLTU6XSkKKyAgICAgICAgICAgIHRyeToKKyAgICAgICAgICAgICAgICBtZXNzYWdlLnNldF9kYXRlKGNhbGVuZGFyLnRpbWVnbSh0aW1lLnN0cnB0aW1lKG1heWJlX2RhdGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnJWEgJWIgJWQgJUg6JU06JVMgJVknKSkpCisgICAgICAgICAgICBleGNlcHQgKFZhbHVlRXJyb3IsIE92ZXJmbG93RXJyb3IpOgorICAgICAgICAgICAgICAgIHBhc3MKKyAgICAgICAgZWxpZiBpc2luc3RhbmNlKG1lc3NhZ2UsIF9tYm94TU1ERk1lc3NhZ2UpOgorICAgICAgICAgICAgbWVzc2FnZS5zZXRfZmxhZ3Moc2VsZi5nZXRfZmxhZ3MoKSkKKyAgICAgICAgICAgIG1lc3NhZ2Uuc2V0X2Zyb20oc2VsZi5nZXRfZnJvbSgpKQorICAgICAgICBlbGlmIGlzaW5zdGFuY2UobWVzc2FnZSwgTUhNZXNzYWdlKToKKyAgICAgICAgICAgIGZsYWdzID0gc2V0KHNlbGYuZ2V0X2ZsYWdzKCkpCisgICAgICAgICAgICBpZiAnUicgbm90IGluIGZsYWdzOgorICAgICAgICAgICAgICAgIG1lc3NhZ2UuYWRkX3NlcXVlbmNlKCd1bnNlZW4nKQorICAgICAgICAgICAgaWYgJ0EnIGluIGZsYWdzOgorICAgICAgICAgICAgICAgIG1lc3NhZ2UuYWRkX3NlcXVlbmNlKCdyZXBsaWVkJykKKyAgICAgICAgICAgIGlmICdGJyBpbiBmbGFnczoKKyAgICAgICAgICAgICAgICBtZXNzYWdlLmFkZF9zZXF1ZW5jZSgnZmxhZ2dlZCcpCisgICAgICAgICAgICBkZWwgbWVzc2FnZVsnc3RhdHVzJ10KKyAgICAgICAgICAgIGRlbCBtZXNzYWdlWyd4LXN0YXR1cyddCisgICAgICAgIGVsaWYgaXNpbnN0YW5jZShtZXNzYWdlLCBCYWJ5bE1lc3NhZ2UpOgorICAgICAgICAgICAgZmxhZ3MgPSBzZXQoc2VsZi5nZXRfZmxhZ3MoKSkKKyAgICAgICAgICAgIGlmICdSJyBub3QgaW4gZmxhZ3M6CisgICAgICAgICAgICAgICAgbWVzc2FnZS5hZGRfbGFiZWwoJ3Vuc2VlbicpCisgICAgICAgICAgICBpZiAnRCcgaW4gZmxhZ3M6CisgICAgICAgICAgICAgICAgbWVzc2FnZS5hZGRfbGFiZWwoJ2RlbGV0ZWQnKQorICAgICAgICAgICAgaWYgJ0EnIGluIGZsYWdzOgorICAgICAgICAgICAgICAgIG1lc3NhZ2UuYWRkX2xhYmVsKCdhbnN3ZXJlZCcpCisgICAgICAgICAgICBkZWwgbWVzc2FnZVsnc3RhdHVzJ10KKyAgICAgICAgICAgIGRlbCBtZXNzYWdlWyd4LXN0YXR1cyddCisgICAgICAgIGVsaWYgaXNpbnN0YW5jZShtZXNzYWdlLCBNZXNzYWdlKToKKyAgICAgICAgICAgIHBhc3MKKyAgICAgICAgZWxzZToKKyAgICAgICAgICAgIHJhaXNlIFR5cGVFcnJvcignQ2Fubm90IGNvbnZlcnQgdG8gc3BlY2lmaWVkIHR5cGU6ICVzJyAlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZShtZXNzYWdlKSkKKworCitjbGFzcyBtYm94TWVzc2FnZShfbWJveE1NREZNZXNzYWdlKToKKyAgICAiIiJNZXNzYWdlIHdpdGggbWJveC1zcGVjaWZpYyBwcm9wZXJ0aWVzLiIiIgorCisKK2NsYXNzIE1ITWVzc2FnZShNZXNzYWdlKToKKyAgICAiIiJNZXNzYWdlIHdpdGggTUgtc3BlY2lmaWMgcHJvcGVydGllcy4iIiIKKworICAgIGRlZiBfX2luaXRfXyhzZWxmLCBtZXNzYWdlPU5vbmUpOgorICAgICAgICAiIiJJbml0aWFsaXplIGFuIE1ITWVzc2FnZSBpbnN0YW5jZS4iIiIKKyAgICAgICAgc2VsZi5fc2VxdWVuY2VzID0gW10KKyAgICAgICAgTWVzc2FnZS5fX2luaXRfXyhzZWxmLCBtZXNzYWdlKQorCisgICAgZGVmIGdldF9zZXF1ZW5jZXMoc2VsZik6CisgICAgICAgICIiIlJldHVybiBhIGxpc3Qgb2Ygc2VxdWVuY2VzIHRoYXQgaW5jbHVkZSB0aGUgbWVzc2FnZS4iIiIKKyAgICAgICAgcmV0dXJuIHNlbGYuX3NlcXVlbmNlc1s6XQorCisgICAgZGVmIHNldF9zZXF1ZW5jZXMoc2VsZiwgc2VxdWVuY2VzKToKKyAgICAgICAgIiIiU2V0IHRoZSBsaXN0IG9mIHNlcXVlbmNlcyB0aGF0IGluY2x1ZGUgdGhlIG1lc3NhZ2UuIiIiCisgICAgICAgIHNlbGYuX3NlcXVlbmNlcyA9IGxpc3Qoc2VxdWVuY2VzKQorCisgICAgZGVmIGFkZF9zZXF1ZW5jZShzZWxmLCBzZXF1ZW5jZSk6CisgICAgICAgICIiIkFkZCBzZXF1ZW5jZSB0byBsaXN0IG9mIHNlcXVlbmNlcyBpbmNsdWRpbmcgdGhlIG1lc3NhZ2UuIiIiCisgICAgICAgIGlmIGlzaW5zdGFuY2Uoc2VxdWVuY2UsIHN0cik6CisgICAgICAgICAgICBpZiBub3Qgc2VxdWVuY2UgaW4gc2VsZi5fc2VxdWVuY2VzOgorICAgICAgICAgICAgICAgIHNlbGYuX3NlcXVlbmNlcy5hcHBlbmQoc2VxdWVuY2UpCisgICAgICAgIGVsc2U6CisgICAgICAgICAgICByYWlzZSBUeXBlRXJyb3IoJ3NlcXVlbmNlIG11c3QgYmUgYSBzdHJpbmc6ICVzJyAlIHR5cGUoc2VxdWVuY2UpKQorCisgICAgZGVmIHJlbW92ZV9zZXF1ZW5jZShzZWxmLCBzZXF1ZW5jZSk6CisgICAgICAgICIiIlJlbW92ZSBzZXF1ZW5jZSBmcm9tIHRoZSBsaXN0IG9mIHNlcXVlbmNlcyBpbmNsdWRpbmcgdGhlIG1lc3NhZ2UuIiIiCisgICAgICAgIHRyeToKKyAgICAgICAgICAgIHNlbGYuX3NlcXVlbmNlcy5yZW1vdmUoc2VxdWVuY2UpCisgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgorICAgICAgICAgICAgcGFzcworCisgICAgZGVmIF9leHBsYWluX3RvKHNlbGYsIG1lc3NhZ2UpOgorICAgICAgICAiIiJDb3B5IE1ILXNwZWNpZmljIHN0YXRlIHRvIG1lc3NhZ2UgaW5zb2ZhciBhcyBwb3NzaWJsZS4iIiIKKyAgICAgICAgaWYgaXNpbnN0YW5jZShtZXNzYWdlLCBNYWlsZGlyTWVzc2FnZSk6CisgICAgICAgICAgICBzZXF1ZW5jZXMgPSBzZXQoc2VsZi5nZXRfc2VxdWVuY2VzKCkpCisgICAgICAgICAgICBpZiAndW5zZWVuJyBpbiBzZXF1ZW5jZXM6CisgICAgICAgICAgICAgICAgbWVzc2FnZS5zZXRfc3ViZGlyKCdjdXInKQorICAgICAgICAgICAgZWxzZToKKyAgICAgICAgICAgICAgICBtZXNzYWdlLnNldF9zdWJkaXIoJ2N1cicpCisgICAgICAgICAgICAgICAgbWVzc2FnZS5hZGRfZmxhZygnUycpCisgICAgICAgICAgICBpZiAnZmxhZ2dlZCcgaW4gc2VxdWVuY2VzOgorICAgICAgICAgICAgICAgIG1lc3NhZ2UuYWRkX2ZsYWcoJ0YnKQorICAgICAgICAgICAgaWYgJ3JlcGxpZWQnIGluIHNlcXVlbmNlczoKKyAgICAgICAgICAgICAgICBtZXNzYWdlLmFkZF9mbGFnKCdSJykKKyAgICAgICAgZWxpZiBpc2luc3RhbmNlKG1lc3NhZ2UsIF9tYm94TU1ERk1lc3NhZ2UpOgorICAgICAgICAgICAgc2VxdWVuY2VzID0gc2V0KHNlbGYuZ2V0X3NlcXVlbmNlcygpKQorICAgICAgICAgICAgaWYgJ3Vuc2Vlbicgbm90IGluIHNlcXVlbmNlczoKKyAgICAgICAgICAgICAgICBtZXNzYWdlLmFkZF9mbGFnKCdSTycpCisgICAgICAgICAgICBlbHNlOgorICAgICAgICAgICAgICAgIG1lc3NhZ2UuYWRkX2ZsYWcoJ08nKQorICAgICAgICAgICAgaWYgJ2ZsYWdnZWQnIGluIHNlcXVlbmNlczoKKyAgICAgICAgICAgICAgICBtZXNzYWdlLmFkZF9mbGFnKCdGJykKKyAgICAgICAgICAgIGlmICdyZXBsaWVkJyBpbiBzZXF1ZW5jZXM6CisgICAgICAgICAgICAgICAgbWVzc2FnZS5hZGRfZmxhZygnQScpCisgICAgICAgIGVsaWYgaXNpbnN0YW5jZShtZXNzYWdlLCBNSE1lc3NhZ2UpOgorICAgICAgICAgICAgZm9yIHNlcXVlbmNlIGluIHNlbGYuZ2V0X3NlcXVlbmNlcygpOgorICAgICAgICAgICAgICAgIG1lc3NhZ2UuYWRkX3NlcXVlbmNlKHNlcXVlbmNlKQorICAgICAgICBlbGlmIGlzaW5zdGFuY2UobWVzc2FnZSwgQmFieWxNZXNzYWdlKToKKyAgICAgICAgICAgIHNlcXVlbmNlcyA9IHNldChzZWxmLmdldF9zZXF1ZW5jZXMoKSkKKyAgICAgICAgICAgIGlmICd1bnNlZW4nIGluIHNlcXVlbmNlczoKKyAgICAgICAgICAgICAgICBtZXNzYWdlLmFkZF9sYWJlbCgndW5zZWVuJykKKyAgICAgICAgICAgIGlmICdyZXBsaWVkJyBpbiBzZXF1ZW5jZXM6CisgICAgICAgICAgICAgICAgbWVzc2FnZS5hZGRfbGFiZWwoJ2Fuc3dlcmVkJykKKyAgICAgICAgZWxpZiBpc2luc3RhbmNlKG1lc3NhZ2UsIE1lc3NhZ2UpOgorICAgICAgICAgICAgcGFzcworICAgICAgICBlbHNlOgorICAgICAgICAgICAgcmFpc2UgVHlwZUVycm9yKCdDYW5ub3QgY29udmVydCB0byBzcGVjaWZpZWQgdHlwZTogJXMnICUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlKG1lc3NhZ2UpKQorCisKK2NsYXNzIEJhYnlsTWVzc2FnZShNZXNzYWdlKToKKyAgICAiIiJNZXNzYWdlIHdpdGggQmFieWwtc3BlY2lmaWMgcHJvcGVydGllcy4iIiIKKworICAgIGRlZiBfX2luaXRfXyhzZWxmLCBtZXNzYWdlPU5vbmUpOgorICAgICAgICAiIiJJbml0aWFsaXplIGFuIEJhYnlsTWVzc2FnZSBpbnN0YW5jZS4iIiIKKyAgICAgICAgc2VsZi5fbGFiZWxzID0gW10KKyAgICAgICAgc2VsZi5fdmlzaWJsZSA9IE1lc3NhZ2UoKQorICAgICAgICBNZXNzYWdlLl9faW5pdF9fKHNlbGYsIG1lc3NhZ2UpCisKKyAgICBkZWYgZ2V0X2xhYmVscyhzZWxmKToKKyAgICAgICAgIiIiUmV0dXJuIGEgbGlzdCBvZiBsYWJlbHMgb24gdGhlIG1lc3NhZ2UuIiIiCisgICAgICAgIHJldHVybiBzZWxmLl9sYWJlbHNbOl0KKworICAgIGRlZiBzZXRfbGFiZWxzKHNlbGYsIGxhYmVscyk6CisgICAgICAgICIiIlNldCB0aGUgbGlzdCBvZiBsYWJlbHMgb24gdGhlIG1lc3NhZ2UuIiIiCisgICAgICAgIHNlbGYuX2xhYmVscyA9IGxpc3QobGFiZWxzKQorCisgICAgZGVmIGFkZF9sYWJlbChzZWxmLCBsYWJlbCk6CisgICAgICAgICIiIkFkZCBsYWJlbCB0byBsaXN0IG9mIGxhYmVscyBvbiB0aGUgbWVzc2FnZS4iIiIKKyAgICAgICAgaWYgaXNpbnN0YW5jZShsYWJlbCwgc3RyKToKKyAgICAgICAgICAgIGlmIGxhYmVsIG5vdCBpbiBzZWxmLl9sYWJlbHM6CisgICAgICAgICAgICAgICAgc2VsZi5fbGFiZWxzLmFwcGVuZChsYWJlbCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICAgIHJhaXNlIFR5cGVFcnJvcignbGFiZWwgbXVzdCBiZSBhIHN0cmluZzogJXMnICUgdHlwZShsYWJlbCkpCisKKyAgICBkZWYgcmVtb3ZlX2xhYmVsKHNlbGYsIGxhYmVsKToKKyAgICAgICAgIiIiUmVtb3ZlIGxhYmVsIGZyb20gdGhlIGxpc3Qgb2YgbGFiZWxzIG9uIHRoZSBtZXNzYWdlLiIiIgorICAgICAgICB0cnk6CisgICAgICAgICAgICBzZWxmLl9sYWJlbHMucmVtb3ZlKGxhYmVsKQorICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKKyAgICAgICAgICAgIHBhc3MKKyAgICAKKyAgICBkZWYgZ2V0X3Zpc2libGUoc2VsZik6CisgICAgICAgICIiIlJldHVybiBhIE1lc3NhZ2UgcmVwcmVzZW50YXRpb24gb2YgdmlzaWJsZSBoZWFkZXJzLiIiIgorICAgICAgICByZXR1cm4gTWVzc2FnZShzZWxmLl92aXNpYmxlKQorCisgICAgZGVmIHNldF92aXNpYmxlKHNlbGYsIHZpc2libGUpOgorICAgICAgICAiIiJTZXQgdGhlIE1lc3NhZ2UgcmVwcmVzZW50YXRpb24gb2YgdmlzaWJsZSBoZWFkZXJzLiIiIgorICAgICAgICBzZWxmLl92aXNpYmxlID0gTWVzc2FnZSh2aXNpYmxlKQorCisgICAgZGVmIHVwZGF0ZV92aXNpYmxlKHNlbGYpOgorICAgICAgICAiIiJVcGRhdGUgYW5kL29yIHNlbnNpYmx5IGdlbmVyYXRlIGEgc2V0IG9mIHZpc2libGUgaGVhZGVycy4iIiIKKyAgICAgICAgZm9yIGhlYWRlciBpbiBzZWxmLl92aXNpYmxlLmtleXMoKToKKyAgICAgICAgICAgIGlmIGhlYWRlciBpbiBzZWxmOgorICAgICAgICAgICAgICAgIHNlbGYuX3Zpc2libGUucmVwbGFjZV9oZWFkZXIoaGVhZGVyLCBzZWxmW2hlYWRlcl0pCisgICAgICAgICAgICBlbHNlOgorICAgICAgICAgICAgICAgIGRlbCBzZWxmLl92aXNpYmxlW2hlYWRlcl0KKyAgICAgICAgZm9yIGhlYWRlciBpbiAoJ0RhdGUnLCAnRnJvbScsICdSZXBseS1UbycsICdUbycsICdDQycsICdTdWJqZWN0Jyk6CisgICAgICAgICAgICBpZiBoZWFkZXIgaW4gc2VsZiBhbmQgaGVhZGVyIG5vdCBpbiBzZWxmLl92aXNpYmxlOgorICAgICAgICAgICAgICAgIHNlbGYuX3Zpc2libGVbaGVhZGVyXSA9IHNlbGZbaGVhZGVyXQorCisgICAgZGVmIF9leHBsYWluX3RvKHNlbGYsIG1lc3NhZ2UpOgorICAgICAgICAiIiJDb3B5IEJhYnlsLXNwZWNpZmljIHN0YXRlIHRvIG1lc3NhZ2UgaW5zb2ZhciBhcyBwb3NzaWJsZS4iIiIKKyAgICAgICAgaWYgaXNpbnN0YW5jZShtZXNzYWdlLCBNYWlsZGlyTWVzc2FnZSk6CisgICAgICAgICAgICBsYWJlbHMgPSBzZXQoc2VsZi5nZXRfbGFiZWxzKCkpCisgICAgICAgICAgICBpZiAndW5zZWVuJyBpbiBsYWJlbHM6CisgICAgICAgICAgICAgICAgbWVzc2FnZS5zZXRfc3ViZGlyKCdjdXInKQorICAgICAgICAgICAgZWxzZToKKyAgICAgICAgICAgICAgICBtZXNzYWdlLnNldF9zdWJkaXIoJ2N1cicpCisgICAgICAgICAgICAgICAgbWVzc2FnZS5hZGRfZmxhZygnUycpCisgICAgICAgICAgICBpZiAnZm9yd2FyZGVkJyBpbiBsYWJlbHMgb3IgJ3Jlc2VudCcgaW4gbGFiZWxzOgorICAgICAgICAgICAgICAgIG1lc3NhZ2UuYWRkX2ZsYWcoJ1AnKQorICAgICAgICAgICAgaWYgJ2Fuc3dlcmVkJyBpbiBsYWJlbHM6CisgICAgICAgICAgICAgICAgbWVzc2FnZS5hZGRfZmxhZygnUicpCisgICAgICAgICAgICBpZiAnZGVsZXRlZCcgaW4gbGFiZWxzOgorICAgICAgICAgICAgICAgIG1lc3NhZ2UuYWRkX2ZsYWcoJ1QnKQorICAgICAgICBlbGlmIGlzaW5zdGFuY2UobWVzc2FnZSwgX21ib3hNTURGTWVzc2FnZSk6CisgICAgICAgICAgICBsYWJlbHMgPSBzZXQoc2VsZi5nZXRfbGFiZWxzKCkpCisgICAgICAgICAgICBpZiAndW5zZWVuJyBub3QgaW4gbGFiZWxzOgorICAgICAgICAgICAgICAgIG1lc3NhZ2UuYWRkX2ZsYWcoJ1JPJykKKyAgICAgICAgICAgIGVsc2U6CisgICAgICAgICAgICAgICAgbWVzc2FnZS5hZGRfZmxhZygnTycpCisgICAgICAgICAgICBpZiAnZGVsZXRlZCcgaW4gbGFiZWxzOgorICAgICAgICAgICAgICAgIG1lc3NhZ2UuYWRkX2ZsYWcoJ0QnKQorICAgICAgICAgICAgaWYgJ2Fuc3dlcmVkJyBpbiBsYWJlbHM6CisgICAgICAgICAgICAgICAgbWVzc2FnZS5hZGRfZmxhZygnQScpCisgICAgICAgIGVsaWYgaXNpbnN0YW5jZShtZXNzYWdlLCBNSE1lc3NhZ2UpOgorICAgICAgICAgICAgbGFiZWxzID0gc2V0KHNlbGYuZ2V0X2xhYmVscygpKQorICAgICAgICAgICAgaWYgJ3Vuc2VlbicgaW4gbGFiZWxzOgorICAgICAgICAgICAgICAgIG1lc3NhZ2UuYWRkX3NlcXVlbmNlKCd1bnNlZW4nKQorICAgICAgICAgICAgaWYgJ2Fuc3dlcmVkJyBpbiBsYWJlbHM6CisgICAgICAgICAgICAgICAgbWVzc2FnZS5hZGRfc2VxdWVuY2UoJ3JlcGxpZWQnKQorICAgICAgICBlbGlmIGlzaW5zdGFuY2UobWVzc2FnZSwgQmFieWxNZXNzYWdlKToKKyAgICAgICAgICAgIG1lc3NhZ2Uuc2V0X3Zpc2libGUoc2VsZi5nZXRfdmlzaWJsZSgpKQorICAgICAgICAgICAgZm9yIGxhYmVsIGluIHNlbGYuZ2V0X2xhYmVscygpOgorICAgICAgICAgICAgICAgIG1lc3NhZ2UuYWRkX2xhYmVsKGxhYmVsKQorICAgICAgICBlbGlmIGlzaW5zdGFuY2UobWVzc2FnZSwgTWVzc2FnZSk6CisgICAgICAgICAgICBwYXNzCisgICAgICAgIGVsc2U6CisgICAgICAgICAgICByYWlzZSBUeXBlRXJyb3IoJ0Nhbm5vdCBjb252ZXJ0IHRvIHNwZWNpZmllZCB0eXBlOiAlcycgJQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUobWVzc2FnZSkpCisKKworY2xhc3MgTU1ERk1lc3NhZ2UoX21ib3hNTURGTWVzc2FnZSk6CisgICAgIiIiTWVzc2FnZSB3aXRoIE1NREYtc3BlY2lmaWMgcHJvcGVydGllcy4iIiIKKworCitjbGFzcyBfUHJveHlGaWxlOgorICAgICIiIkEgcmVhZC1vbmx5IHdyYXBwZXIgb2YgYSBmaWxlLiIiIgorCisgICAgZGVmIF9faW5pdF9fKHNlbGYsIGYsIHBvcz1Ob25lKToKKyAgICAgICAgIiIiSW5pdGlhbGl6ZSBhIF9Qcm94eUZpbGUuIiIiCisgICAgICAgIHNlbGYuX2ZpbGUgPSBmCisgICAgICAgIGlmIHBvcyBpcyBOb25lOgorICAgICAgICAgICAgc2VsZi5fcG9zID0gZi50ZWxsKCkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICAgIHNlbGYuX3BvcyA9IHBvcworCisgICAgZGVmIHJlYWQoc2VsZiwgc2l6ZT1Ob25lKToKKyAgICAgICAgIiIiUmVhZCBieXRlcy4iIiIKKyAgICAgICAgcmV0dXJuIHNlbGYuX3JlYWQoc2l6ZSwgc2VsZi5fZmlsZS5yZWFkKQorCisgICAgZGVmIHJlYWRsaW5lKHNlbGYsIHNpemU9Tm9uZSk6CisgICAgICAgICIiIlJlYWQgYSBsaW5lLiIiIgorICAgICAgICByZXR1cm4gc2VsZi5fcmVhZChzaXplLCBzZWxmLl9maWxlLnJlYWRsaW5lKQorCisgICAgZGVmIHJlYWRsaW5lcyhzZWxmLCBzaXplaGludD1Ob25lKToKKyAgICAgICAgIiIiUmVhZCBtdWx0aXBsZSBsaW5lcy4iIiIKKyAgICAgICAgcmVzdWx0ID0gW10KKyAgICAgICAgZm9yIGxpbmUgaW4gc2VsZjoKKyAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQobGluZSkKKyAgICAgICAgICAgIGlmIHNpemVoaW50IGlzIG5vdCBOb25lOgorICAgICAgICAgICAgICAgIHNpemVoaW50IC09IGxlbihsaW5lKQorICAgICAgICAgICAgICAgIGlmIHNpemVoaW50IDw9IDA6CisgICAgICAgICAgICAgICAgICAgIGJyZWFrCisgICAgICAgIHJldHVybiByZXN1bHQKKworICAgIGRlZiBfX2l0ZXJfXyhzZWxmKToKKyAgICAgICAgIiIiSXRlcmF0ZSBvdmVyIGxpbmVzLiIiIgorICAgICAgICByZXR1cm4gaXRlcihzZWxmLnJlYWRsaW5lLCAiIikKKworICAgIGRlZiB0ZWxsKHNlbGYpOgorICAgICAgICAiIiJSZXR1cm4gdGhlIHBvc2l0aW9uLiIiIgorICAgICAgICByZXR1cm4gc2VsZi5fcG9zCisKKyAgICBkZWYgc2VlayhzZWxmLCBvZmZzZXQsIHdoZW5jZT0wKToKKyAgICAgICAgIiIiQ2hhbmdlIHBvc2l0aW9uLiIiIgorICAgICAgICBpZiB3aGVuY2UgPT0gMToKKyAgICAgICAgICAgIHNlbGYuX2ZpbGUuc2VlayhzZWxmLl9wb3MpCisgICAgICAgIHNlbGYuX2ZpbGUuc2VlayhvZmZzZXQsIHdoZW5jZSkKKyAgICAgICAgc2VsZi5fcG9zID0gc2VsZi5fZmlsZS50ZWxsKCkKKworICAgIGRlZiBjbG9zZShzZWxmKToKKyAgICAgICAgIiIiQ2xvc2UgdGhlIGZpbGUuIiIiCisgICAgICAgIGRlbCBzZWxmLl9maWxlCisKKyAgICBkZWYgX3JlYWQoc2VsZiwgc2l6ZSwgcmVhZF9tZXRob2QpOgorICAgICAgICAiIiJSZWFkIHNpemUgYnl0ZXMgdXNpbmcgcmVhZF9tZXRob2QuIiIiCisgICAgICAgIGlmIHNpemUgaXMgTm9uZToKKyAgICAgICAgICAgIHNpemUgPSAtMQorICAgICAgICBzZWxmLl9maWxlLnNlZWsoc2VsZi5fcG9zKQorICAgICAgICByZXN1bHQgPSByZWFkX21ldGhvZChzaXplKQorICAgICAgICBzZWxmLl9wb3MgPSBzZWxmLl9maWxlLnRlbGwoKQorICAgICAgICByZXR1cm4gcmVzdWx0CisKKworY2xhc3MgX1BhcnRpYWxGaWxlKF9Qcm94eUZpbGUpOgorICAgICIiIkEgcmVhZC1vbmx5IHdyYXBwZXIgb2YgcGFydCBvZiBhIGZpbGUuIiIiCisKKyAgICBkZWYgX19pbml0X18oc2VsZiwgZiwgc3RhcnQ9Tm9uZSwgc3RvcD1Ob25lKToKKyAgICAgICAgIiIiSW5pdGlhbGl6ZSBhIF9QYXJ0aWFsRmlsZS4iIiIKKyAgICAgICAgX1Byb3h5RmlsZS5fX2luaXRfXyhzZWxmLCBmLCBzdGFydCkKKyAgICAgICAgc2VsZi5fc3RhcnQgPSBzdGFydAorICAgICAgICBzZWxmLl9zdG9wID0gc3RvcAorCisgICAgZGVmIHRlbGwoc2VsZik6CisgICAgICAgICIiIlJldHVybiB0aGUgcG9zaXRpb24gd2l0aCByZXNwZWN0IHRvIHN0YXJ0LiIiIgorICAgICAgICByZXR1cm4gX1Byb3h5RmlsZS50ZWxsKHNlbGYpIC0gc2VsZi5fc3RhcnQKKworICAgIGRlZiBzZWVrKHNlbGYsIG9mZnNldCwgd2hlbmNlPTApOgorICAgICAgICAiIiJDaGFuZ2UgcG9zaXRpb24sIHBvc3NpYmx5IHdpdGggcmVzcGVjdCB0byBzdGFydCBvciBzdG9wLiIiIgorICAgICAgICBpZiB3aGVuY2UgPT0gMDoKKyAgICAgICAgICAgIHNlbGYuX3BvcyA9IHNlbGYuX3N0YXJ0CisgICAgICAgICAgICB3aGVuY2UgPSAxCisgICAgICAgIGVsaWYgd2hlbmNlID09IDI6CisgICAgICAgICAgICBzZWxmLl9wb3MgPSBzZWxmLl9zdG9wCisgICAgICAgICAgICB3aGVuY2UgPSAxCisgICAgICAgIF9Qcm94eUZpbGUuc2VlayhzZWxmLCBvZmZzZXQsIHdoZW5jZSkKKworICAgIGRlZiBfcmVhZChzZWxmLCBzaXplLCByZWFkX21ldGhvZCk6CisgICAgICAgICIiIlJlYWQgc2l6ZSBieXRlcyB1c2luZyByZWFkX21ldGhvZCwgaG9ub3Jpbmcgc3RhcnQgYW5kIHN0b3AuIiIiCisgICAgICAgIHJlbWFpbmluZyA9IHNlbGYuX3N0b3AgLSBzZWxmLl9wb3MKKyAgICAgICAgaWYgcmVtYWluaW5nIDw9IDA6CisgICAgICAgICAgICByZXR1cm4gJycKKyAgICAgICAgaWYgc2l6ZSBpcyBOb25lIG9yIHNpemUgPCAwIG9yIHNpemUgPiByZW1haW5pbmc6CisgICAgICAgICAgICBzaXplID0gcmVtYWluaW5nCisgICAgICAgIHJldHVybiBfUHJveHlGaWxlLl9yZWFkKHNlbGYsIHNpemUsIHJlYWRfbWV0aG9kKQorCisKK2RlZiBfbG9ja19maWxlKGYsIGRvdGxvY2s9VHJ1ZSk6CisgICAgIiIiTG9jayBmaWxlIGYgdXNpbmcgbG9ja2YsIGZsb2NrLCBhbmQgZG90IGxvY2tpbmcuIiIiCisgICAgZG90bG9ja19kb25lID0gRmFsc2UKKyAgICB0cnk6CisgICAgICAgIGlmIGZjbnRsOgorICAgICAgICAgICAgdHJ5OgorICAgICAgICAgICAgICAgIGZjbnRsLmxvY2tmKGYsIGZjbnRsLkxPQ0tfRVggfCBmY250bC5MT0NLX05CKQorICAgICAgICAgICAgZXhjZXB0IElPRXJyb3IsIGU6CisgICAgICAgICAgICAgICAgaWYgZS5lcnJubyA9PSBlcnJuby5FQUdBSU46CisgICAgICAgICAgICAgICAgICAgIHJhaXNlIEV4dGVybmFsQ2xhc2hFcnJvcignbG9ja2Y6IGxvY2sgdW5hdmFpbGFibGU6ICVzJyAlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmLm5hbWUpCisgICAgICAgICAgICAgICAgZWxzZToKKyAgICAgICAgICAgICAgICAgICAgcmFpc2UKKyAgICAgICAgICAgIHRyeToKKyAgICAgICAgICAgICAgICBmY250bC5mbG9jayhmLCBmY250bC5MT0NLX0VYIHwgZmNudGwuTE9DS19OQikKKyAgICAgICAgICAgIGV4Y2VwdCBJT0Vycm9yLCBlOgorICAgICAgICAgICAgICAgIGlmIGUuZXJybm8gPT0gZXJybm8uRVdPVUxEQkxPQ0s6CisgICAgICAgICAgICAgICAgICAgIHJhaXNlIEV4dGVybmFsQ2xhc2hFcnJvcignZmxvY2s6IGxvY2sgdW5hdmFpbGFibGU6ICVzJyAlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmLm5hbWUpCisgICAgICAgICAgICAgICAgZWxzZToKKyAgICAgICAgICAgICAgICAgICAgcmFpc2UKKyAgICAgICAgaWYgZG90bG9jazoKKyAgICAgICAgICAgIHRyeToKKyAgICAgICAgICAgICAgICBwcmVfbG9jayA9IF9jcmVhdGVfdGVtcG9yYXJ5KGYubmFtZSArICcubG9jaycpCisgICAgICAgICAgICAgICAgcHJlX2xvY2suY2xvc2UoKQorICAgICAgICAgICAgZXhjZXB0IElPRXJyb3IsIGU6CisgICAgICAgICAgICAgICAgaWYgZS5lcnJubyA9PSBlcnJuby5FQUNDRVM6CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAgIyBXaXRob3V0IHdyaXRlIGFjY2VzcywganVzdCBza2lwIGRvdGxvY2tpbmcuCisgICAgICAgICAgICAgICAgZWxzZToKKyAgICAgICAgICAgICAgICAgICAgcmFpc2UKKyAgICAgICAgICAgIHRyeToKKyAgICAgICAgICAgICAgICBpZiBoYXNhdHRyKG9zLCAnbGluaycpOgorICAgICAgICAgICAgICAgICAgICBvcy5saW5rKHByZV9sb2NrLm5hbWUsIGYubmFtZSArICcubG9jaycpCisgICAgICAgICAgICAgICAgICAgIGRvdGxvY2tfZG9uZSA9IFRydWUKKyAgICAgICAgICAgICAgICAgICAgb3MudW5saW5rKHByZV9sb2NrLm5hbWUpCisgICAgICAgICAgICAgICAgZWxzZToKKyAgICAgICAgICAgICAgICAgICAgb3MucmVuYW1lKHByZV9sb2NrLm5hbWUsIGYubmFtZSArICcubG9jaycpCisgICAgICAgICAgICAgICAgICAgIGRvdGxvY2tfZG9uZSA9IFRydWUKKyAgICAgICAgICAgIGV4Y2VwdCBPU0Vycm9yLCBlOgorICAgICAgICAgICAgICAgIGlmIGUuZXJybm8gPT0gZXJybm8uRUVYSVNUOgorICAgICAgICAgICAgICAgICAgICBvcy5yZW1vdmUocHJlX2xvY2submFtZSkKKyAgICAgICAgICAgICAgICAgICAgcmFpc2UgRXh0ZXJuYWxDbGFzaEVycm9yKCdkb3QgbG9jayB1bmF2YWlsYWJsZTogJXMnICUgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmLm5hbWUpCisgICAgICAgICAgICAgICAgZWxzZToKKyAgICAgICAgICAgICAgICAgICAgcmFpc2UKKyAgICBleGNlcHQ6CisgICAgICAgIGlmIGZjbnRsOgorICAgICAgICAgICAgZmNudGwubG9ja2YoZiwgZmNudGwuTE9DS19VTikKKyAgICAgICAgICAgIGZjbnRsLmZsb2NrKGYsIGZjbnRsLkxPQ0tfVU4pCisgICAgICAgIGlmIGRvdGxvY2tfZG9uZToKKyAgICAgICAgICAgIG9zLnJlbW92ZShmLm5hbWUgKyAnLmxvY2snKQorICAgICAgICByYWlzZQorCitkZWYgX3VubG9ja19maWxlKGYpOgorICAgICIiIlVubG9jayBmaWxlIGYgdXNpbmcgbG9ja2YsIGZsb2NrLCBhbmQgZG90IGxvY2tpbmcuIiIiCisgICAgaWYgZmNudGw6CisgICAgICAgIGZjbnRsLmxvY2tmKGYsIGZjbnRsLkxPQ0tfVU4pCisgICAgICAgIGZjbnRsLmZsb2NrKGYsIGZjbnRsLkxPQ0tfVU4pCisgICAgaWYgb3MucGF0aC5leGlzdHMoZi5uYW1lICsgJy5sb2NrJyk6CisgICAgICAgIG9zLnJlbW92ZShmLm5hbWUgKyAnLmxvY2snKQorCitkZWYgX2NyZWF0ZV9jYXJlZnVsbHkocGF0aCk6CisgICAgIiIiQ3JlYXRlIGEgZmlsZSBpZiBpdCBkb2Vzbid0IGV4aXN0IGFuZCBvcGVuIGZvciByZWFkaW5nIGFuZCB3cml0aW5nLiIiIgorICAgIGZkID0gb3Mub3BlbihwYXRoLCBvcy5PX0NSRUFUIHwgb3MuT19FWENMIHwgb3MuT19SRFdSKQorICAgIHRyeToKKyAgICAgICAgcmV0dXJuIGZpbGUocGF0aCwgJ3JiKycpCisgICAgZmluYWxseToKKyAgICAgICAgb3MuY2xvc2UoZmQpCisKK2RlZiBfY3JlYXRlX3RlbXBvcmFyeShwYXRoKToKKyAgICAiIiJDcmVhdGUgYSB0ZW1wIGZpbGUgYmFzZWQgb24gcGF0aCBhbmQgb3BlbiBmb3IgcmVhZGluZyBhbmQgd3JpdGluZy4iIiIKKyAgICByZXR1cm4gX2NyZWF0ZV9jYXJlZnVsbHkoJyVzLiVzLiVzLiVzJyAlIChwYXRoLCBpbnQodGltZS50aW1lKCkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvY2tldC5nZXRob3N0bmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9zLmdldHBpZCgpKSkKKworCisjIyBTdGFydDogY2xhc3NlcyBmcm9tIHRoZSBvcmlnaW5hbCBtb2R1bGUgKGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5KS4KKworIyBOb3RlIHRoYXQgdGhlIE1haWxkaXIgY2xhc3MsIHdob3NlIG5hbWUgaXMgdW5jaGFuZ2VkLCBpdHNlbGYgb2ZmZXJzIGEgbmV4dCgpCisjIG1ldGhvZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eS4KIAogY2xhc3MgX01haWxib3g6CiAKQEAgLTMyLDYyICsxOTAzLDcgQEAKICAgICAgICAgICAgIHNlbGYuc2Vla3AgPSBzdG9wID0gc2VsZi5mcC50ZWxsKCkKICAgICAgICAgICAgIGlmIHN0YXJ0ICE9IHN0b3A6CiAgICAgICAgICAgICAgICAgYnJlYWsKLSAgICAgICAgcmV0dXJuIHNlbGYuZmFjdG9yeShfU3ViZmlsZShzZWxmLmZwLCBzdGFydCwgc3RvcCkpCi0KLQotY2xhc3MgX1N1YmZpbGU6Ci0KLSAgICBkZWYgX19pbml0X18oc2VsZiwgZnAsIHN0YXJ0LCBzdG9wKToKLSAgICAgICAgc2VsZi5mcCA9IGZwCi0gICAgICAgIHNlbGYuc3RhcnQgPSBzdGFydAotICAgICAgICBzZWxmLnN0b3AgPSBzdG9wCi0gICAgICAgIHNlbGYucG9zID0gc2VsZi5zdGFydAotCi0KLSAgICBkZWYgX3JlYWQoc2VsZiwgbGVuZ3RoLCByZWFkX2Z1bmN0aW9uKToKLSAgICAgICAgaWYgc2VsZi5wb3MgPj0gc2VsZi5zdG9wOgotICAgICAgICAgICAgcmV0dXJuICcnCi0gICAgICAgIHJlbWFpbmluZyA9IHNlbGYuc3RvcCAtIHNlbGYucG9zCi0gICAgICAgIGlmIGxlbmd0aCBpcyBOb25lIG9yIGxlbmd0aCA8IDAgb3IgbGVuZ3RoID4gcmVtYWluaW5nOgotICAgICAgICAgICAgbGVuZ3RoID0gcmVtYWluaW5nCi0gICAgICAgIHNlbGYuZnAuc2VlayhzZWxmLnBvcykKLSAgICAgICAgZGF0YSA9IHJlYWRfZnVuY3Rpb24obGVuZ3RoKQotICAgICAgICBzZWxmLnBvcyA9IHNlbGYuZnAudGVsbCgpCi0gICAgICAgIHJldHVybiBkYXRhCi0KLSAgICBkZWYgcmVhZChzZWxmLCBsZW5ndGggPSBOb25lKToKLSAgICAgICAgcmV0dXJuIHNlbGYuX3JlYWQobGVuZ3RoLCBzZWxmLmZwLnJlYWQpCi0KLSAgICBkZWYgcmVhZGxpbmUoc2VsZiwgbGVuZ3RoID0gTm9uZSk6Ci0gICAgICAgIHJldHVybiBzZWxmLl9yZWFkKGxlbmd0aCwgc2VsZi5mcC5yZWFkbGluZSkKLQotICAgIGRlZiByZWFkbGluZXMoc2VsZiwgc2l6ZWhpbnQgPSAtMSk6Ci0gICAgICAgIGxpbmVzID0gW10KLSAgICAgICAgd2hpbGUgMToKLSAgICAgICAgICAgIGxpbmUgPSBzZWxmLnJlYWRsaW5lKCkKLSAgICAgICAgICAgIGlmIG5vdCBsaW5lOgotICAgICAgICAgICAgICAgIGJyZWFrCi0gICAgICAgICAgICBsaW5lcy5hcHBlbmQobGluZSkKLSAgICAgICAgICAgIGlmIHNpemVoaW50ID49IDA6Ci0gICAgICAgICAgICAgICAgc2l6ZWhpbnQgPSBzaXplaGludCAtIGxlbihsaW5lKQotICAgICAgICAgICAgICAgIGlmIHNpemVoaW50IDw9IDA6Ci0gICAgICAgICAgICAgICAgICAgIGJyZWFrCi0gICAgICAgIHJldHVybiBsaW5lcwotCi0gICAgZGVmIHRlbGwoc2VsZik6Ci0gICAgICAgIHJldHVybiBzZWxmLnBvcyAtIHNlbGYuc3RhcnQKLQotICAgIGRlZiBzZWVrKHNlbGYsIHBvcywgd2hlbmNlPTApOgotICAgICAgICBpZiB3aGVuY2UgPT0gMDoKLSAgICAgICAgICAgIHNlbGYucG9zID0gc2VsZi5zdGFydCArIHBvcwotICAgICAgICBlbGlmIHdoZW5jZSA9PSAxOgotICAgICAgICAgICAgc2VsZi5wb3MgPSBzZWxmLnBvcyArIHBvcwotICAgICAgICBlbGlmIHdoZW5jZSA9PSAyOgotICAgICAgICAgICAgc2VsZi5wb3MgPSBzZWxmLnN0b3AgKyBwb3MKLQotICAgIGRlZiBjbG9zZShzZWxmKToKLSAgICAgICAgZGVsIHNlbGYuZnAKLQorICAgICAgICByZXR1cm4gc2VsZi5mYWN0b3J5KF9QYXJ0aWFsRmlsZShzZWxmLmZwLCBzdGFydCwgc3RvcCkpCiAKICMgUmVjb21tZW5kZWQgdG8gdXNlIFBvcnRhYmxlVW5peE1haWxib3ggaW5zdGVhZCEKIGNsYXNzIFVuaXhNYWlsYm94KF9NYWlsYm94KToKQEAgLTIxMywzNiArMjAyOSw2IEBACiAgICAgICAgIHJldHVybiBtc2cKIAogCi1jbGFzcyBNYWlsZGlyOgotICAgICMgUW1haWwgZGlyZWN0b3J5IG1haWxib3gKLQotICAgIGRlZiBfX2luaXRfXyhzZWxmLCBkaXJuYW1lLCBmYWN0b3J5PXJmYzgyMi5NZXNzYWdlKToKLSAgICAgICAgc2VsZi5kaXJuYW1lID0gZGlybmFtZQotICAgICAgICBzZWxmLmZhY3RvcnkgPSBmYWN0b3J5Ci0KLSAgICAgICAgIyBjaGVjayBmb3IgbmV3IG1haWwKLSAgICAgICAgbmV3ZGlyID0gb3MucGF0aC5qb2luKHNlbGYuZGlybmFtZSwgJ25ldycpCi0gICAgICAgIGJveGVzID0gW29zLnBhdGguam9pbihuZXdkaXIsIGYpCi0gICAgICAgICAgICAgICAgIGZvciBmIGluIG9zLmxpc3RkaXIobmV3ZGlyKSBpZiBmWzBdICE9ICcuJ10KLQotICAgICAgICAjIE5vdyBjaGVjayBmb3IgY3VycmVudCBtYWlsIGluIHRoaXMgbWFpbGRpcgotICAgICAgICBjdXJkaXIgPSBvcy5wYXRoLmpvaW4oc2VsZi5kaXJuYW1lLCAnY3VyJykKLSAgICAgICAgYm94ZXMgKz0gW29zLnBhdGguam9pbihjdXJkaXIsIGYpCi0gICAgICAgICAgICAgICAgICBmb3IgZiBpbiBvcy5saXN0ZGlyKGN1cmRpcikgaWYgZlswXSAhPSAnLiddCi0gICAgICAgIGJveGVzLnJldmVyc2UoKQotICAgICAgICBzZWxmLmJveGVzID0gYm94ZXMKLQotICAgIGRlZiBfX2l0ZXJfXyhzZWxmKToKLSAgICAgICAgcmV0dXJuIGl0ZXIoc2VsZi5uZXh0LCBOb25lKQotCi0gICAgZGVmIG5leHQoc2VsZik6Ci0gICAgICAgIGlmIG5vdCBzZWxmLmJveGVzOgotICAgICAgICAgICAgcmV0dXJuIE5vbmUKLSAgICAgICAgZm4gPSBzZWxmLmJveGVzLnBvcCgpCi0gICAgICAgIGZwID0gb3BlbihmbikKLSAgICAgICAgcmV0dXJuIHNlbGYuZmFjdG9yeShmcCkKLQotCiBjbGFzcyBCYWJ5bE1haWxib3goX01haWxib3gpOgogCiAgICAgZGVmIF9zZWFyY2hfc3RhcnQoc2VsZik6CkBAIC0yNjMsNTkgKzIwNDksMjAgQEAKICAgICAgICAgICAgICAgICBzZWxmLmZwLnNlZWsocG9zKQogICAgICAgICAgICAgICAgIHJldHVybgogCi0KLWRlZiBfdGVzdCgpOgotICAgIGltcG9ydCBzeXMKLQotICAgIGFyZ3MgPSBzeXMuYXJndlsxOl0KLSAgICBpZiBub3QgYXJnczoKLSAgICAgICAgZm9yIGtleSBpbiAnTUFJTERJUicsICdNQUlMJywgJ0xPR05BTUUnLCAnVVNFUic6Ci0gICAgICAgICAgICBpZiBrZXkgaW4gb3MuZW52aXJvbjoKLSAgICAgICAgICAgICAgICBtYm94ID0gb3MuZW52aXJvbltrZXldCi0gICAgICAgICAgICAgICAgYnJlYWsKLSAgICAgICAgZWxzZToKLSAgICAgICAgICAgIHByaW50ICIkTUFJTCwgJExPR05BTUUgbm9yICRVU0VSIHNldCAtLSB3aG8gYXJlIHlvdT8iCi0gICAgICAgICAgICByZXR1cm4KLSAgICBlbHNlOgotICAgICAgICBtYm94ID0gYXJnc1swXQotICAgIGlmIG1ib3hbOjFdID09ICcrJzoKLSAgICAgICAgbWJveCA9IG9zLmVudmlyb25bJ0hPTUUnXSArICcvTWFpbC8nICsgbWJveFsxOl0KLSAgICBlbGlmIG5vdCAnLycgaW4gbWJveDoKLSAgICAgICAgaWYgb3MucGF0aC5pc2ZpbGUoJy92YXIvbWFpbC8nICsgbWJveCk6Ci0gICAgICAgICAgICBtYm94ID0gJy92YXIvbWFpbC8nICsgbWJveAotICAgICAgICBlbHNlOgotICAgICAgICAgICAgbWJveCA9ICcvdXNyL21haWwvJyArIG1ib3gKLSAgICBpZiBvcy5wYXRoLmlzZGlyKG1ib3gpOgotICAgICAgICBpZiBvcy5wYXRoLmlzZGlyKG9zLnBhdGguam9pbihtYm94LCAnY3VyJykpOgotICAgICAgICAgICAgbWIgPSBNYWlsZGlyKG1ib3gpCi0gICAgICAgIGVsc2U6Ci0gICAgICAgICAgICBtYiA9IE1ITWFpbGJveChtYm94KQotICAgIGVsc2U6Ci0gICAgICAgIGZwID0gb3BlbihtYm94LCAncicpCi0gICAgICAgIG1iID0gUG9ydGFibGVVbml4TWFpbGJveChmcCkKLQotICAgIG1zZ3MgPSBbXQotICAgIHdoaWxlIDE6Ci0gICAgICAgIG1zZyA9IG1iLm5leHQoKQotICAgICAgICBpZiBtc2cgaXMgTm9uZToKLSAgICAgICAgICAgIGJyZWFrCi0gICAgICAgIG1zZ3MuYXBwZW5kKG1zZykKLSAgICAgICAgaWYgbGVuKGFyZ3MpIDw9IDE6Ci0gICAgICAgICAgICBtc2cuZnAgPSBOb25lCi0gICAgaWYgbGVuKGFyZ3MpID4gMToKLSAgICAgICAgbnVtID0gaW50KGFyZ3NbMV0pCi0gICAgICAgIHByaW50ICdNZXNzYWdlICVkIGJvZHk6JyVudW0KLSAgICAgICAgbXNnID0gbXNnc1tudW0tMV0KLSAgICAgICAgbXNnLnJld2luZGJvZHkoKQotICAgICAgICBzeXMuc3Rkb3V0LndyaXRlKG1zZy5mcC5yZWFkKCkpCi0gICAgZWxzZToKLSAgICAgICAgcHJpbnQgJ01haWxib3gnLG1ib3gsJ2hhcycsbGVuKG1zZ3MpLCdtZXNzYWdlczonCi0gICAgICAgIGZvciBtc2cgaW4gbXNnczoKLSAgICAgICAgICAgIGYgPSBtc2cuZ2V0aGVhZGVyKCdmcm9tJykgb3IgIiIKLSAgICAgICAgICAgIHMgPSBtc2cuZ2V0aGVhZGVyKCdzdWJqZWN0Jykgb3IgIiIKLSAgICAgICAgICAgIGQgPSBtc2cuZ2V0aGVhZGVyKCdkYXRlJykgb3IgIiIKLSAgICAgICAgICAgIHByaW50ICctJTIwLjIwcyAgICUyMC4yMHMgICAlLTMwLjMwcyclKGYsIGRbNTpdLCBzKQorIyMgRW5kOiBjbGFzc2VzIGZyb20gdGhlIG9yaWdpbmFsIG1vZHVsZSAoZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkpLgogCiAKLWlmIF9fbmFtZV9fID09ICdfX21haW5fXyc6Ci0gICAgX3Rlc3QoKQorY2xhc3MgRXJyb3IoRXhjZXB0aW9uKToKKyAgICAiIiJSYWlzZWQgZm9yIG1vZHVsZS1zcGVjaWZpYyBlcnJvcnMuIiIiCisKK2NsYXNzIE5vU3VjaE1haWxib3hFcnJvcihFcnJvcik6CisgICAgIiIiVGhlIHNwZWNpZmllZCBtYWlsYm94IGRvZXMgbm90IGV4aXN0IGFuZCB3b24ndCBiZSBjcmVhdGVkLiIiIgorCitjbGFzcyBOb3RFbXB0eUVycm9yKEVycm9yKToKKyAgICAiIiJUaGUgc3BlY2lmaWVkIG1haWxib3ggaXMgbm90IGVtcHR5IGFuZCBkZWxldGlvbiB3YXMgcmVxdWVzdGVkLiIiIgorCitjbGFzcyBFeHRlcm5hbENsYXNoRXJyb3IoRXJyb3IpOgorICAgICIiIkFub3RoZXIgcHJvY2VzcyBjYXVzZWQgYW4gYWN0aW9uIHRvIGZhaWwuIiIiCisKK2NsYXNzIEZvcm1hdEVycm9yKEVycm9yKToKKyAgICAiIiJBIGZpbGUgYXBwZWFycyB0byBoYXZlIGFuIGludmFsaWQgZm9ybWF0LiIiIgpkaWZmIC0tZ2l0IGEvTGliL3Rlc3QvdGVzdF9tYWlsYm94LnB5IGIvTGliL3Rlc3QvdGVzdF9tYWlsYm94LnB5CmluZGV4IDc3ZDM5YTYuLjgzYzI0NDMgMTAwNjQ0Ci0tLSBhL0xpYi90ZXN0L3Rlc3RfbWFpbGJveC5weQorKysgYi9MaWIvdGVzdC90ZXN0X21haWxib3gucHkKQEAgLTEsMTUgKzEsMTU3MiBAQAotaW1wb3J0IG1haWxib3gKIGltcG9ydCBvcwogaW1wb3J0IHRpbWUKLWltcG9ydCB1bml0dGVzdAoraW1wb3J0IHN0YXQKK2ltcG9ydCBzb2NrZXQKK2ltcG9ydCBlbWFpbAoraW1wb3J0IGVtYWlsLk1lc3NhZ2UKK2ltcG9ydCByZmM4MjIKK2ltcG9ydCByZQoraW1wb3J0IFN0cmluZ0lPCiBmcm9tIHRlc3QgaW1wb3J0IHRlc3Rfc3VwcG9ydAotCi0jIGNsZWFudXAgZWFybGllciB0ZXN0cworaW1wb3J0IHVuaXR0ZXN0CitpbXBvcnQgbWFpbGJveAoraW1wb3J0IGdsb2IKIHRyeToKLSAgICBvcy51bmxpbmsodGVzdF9zdXBwb3J0LlRFU1RGTikKLWV4Y2VwdCBvcy5lcnJvcjoKKyAgICBpbXBvcnQgZmNudGwKK2V4Y2VwdCBJbXBvcnRFcnJvcjoKICAgICBwYXNzCiAKKworY2xhc3MgVGVzdEJhc2UodW5pdHRlc3QuVGVzdENhc2UpOgorCisgICAgZGVmIF9jaGVja19zYW1wbGUoc2VsZiwgbXNnKToKKyAgICAgICAgIyBJbnNwZWN0IGEgbWFpbGJveC5NZXNzYWdlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzYW1wbGUgbWVzc2FnZQorICAgICAgICBzZWxmLmFzc2VydF8oaXNpbnN0YW5jZShtc2csIGVtYWlsLk1lc3NhZ2UuTWVzc2FnZSkpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhpc2luc3RhbmNlKG1zZywgbWFpbGJveC5NZXNzYWdlKSkKKyAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gX3NhbXBsZV9oZWFkZXJzLml0ZXJpdGVtcygpOgorICAgICAgICAgICAgc2VsZi5hc3NlcnRfKHZhbHVlIGluIG1zZy5nZXRfYWxsKGtleSkpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuaXNfbXVsdGlwYXJ0KCkpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhsZW4obXNnLmdldF9wYXlsb2FkKCkpID09IGxlbihfc2FtcGxlX3BheWxvYWRzKSkKKyAgICAgICAgZm9yIGksIHBheWxvYWQgaW4gZW51bWVyYXRlKF9zYW1wbGVfcGF5bG9hZHMpOgorICAgICAgICAgICAgcGFydCA9IG1zZy5nZXRfcGF5bG9hZChpKQorICAgICAgICAgICAgc2VsZi5hc3NlcnRfKGlzaW5zdGFuY2UocGFydCwgZW1haWwuTWVzc2FnZS5NZXNzYWdlKSkKKyAgICAgICAgICAgIHNlbGYuYXNzZXJ0Xyhub3QgaXNpbnN0YW5jZShwYXJ0LCBtYWlsYm94Lk1lc3NhZ2UpKQorICAgICAgICAgICAgc2VsZi5hc3NlcnRfKHBhcnQuZ2V0X3BheWxvYWQoKSA9PSBwYXlsb2FkKQorCisgICAgZGVmIF9kZWxldGVfcmVjdXJzaXZlbHkoc2VsZiwgdGFyZ2V0KToKKyAgICAgICAgIyBEZWxldGUgYSBmaWxlIG9yIGRlbGV0ZSBhIGRpcmVjdG9yeSByZWN1cnNpdmVseQorICAgICAgICBpZiBvcy5wYXRoLmlzZGlyKHRhcmdldCk6CisgICAgICAgICAgICBmb3IgcGF0aCwgZGlycywgZmlsZXMgaW4gb3Mud2Fsayh0YXJnZXQsIHRvcGRvd249RmFsc2UpOgorICAgICAgICAgICAgICAgIGZvciBuYW1lIGluIGZpbGVzOgorICAgICAgICAgICAgICAgICAgICBvcy5yZW1vdmUob3MucGF0aC5qb2luKHBhdGgsIG5hbWUpKQorICAgICAgICAgICAgICAgIGZvciBuYW1lIGluIGRpcnM6CisgICAgICAgICAgICAgICAgICAgIG9zLnJtZGlyKG9zLnBhdGguam9pbihwYXRoLCBuYW1lKSkKKyAgICAgICAgICAgIG9zLnJtZGlyKHRhcmdldCkKKyAgICAgICAgZWxpZiBvcy5wYXRoLmV4aXN0cyh0YXJnZXQpOgorICAgICAgICAgICAgb3MucmVtb3ZlKHRhcmdldCkKKworCitjbGFzcyBUZXN0TWFpbGJveChUZXN0QmFzZSk6CisKKyAgICBfZmFjdG9yeSA9IE5vbmUgICAgICMgT3ZlcnJpZGRlbiBieSBzdWJjbGFzc2VzIHRvIHJldXNlIHRlc3RzCisgICAgX3RlbXBsYXRlID0gJ0Zyb206IGZvb1xuXG4lcycKKworICAgIGRlZiBzZXRVcChzZWxmKToKKyAgICAgICAgc2VsZi5fcGF0aCA9IHRlc3Rfc3VwcG9ydC5URVNURk4KKyAgICAgICAgc2VsZi5fYm94ID0gc2VsZi5fZmFjdG9yeShzZWxmLl9wYXRoKQorCisgICAgZGVmIHRlYXJEb3duKHNlbGYpOgorICAgICAgICBzZWxmLl9ib3guY2xvc2UoKQorICAgICAgICBzZWxmLl9kZWxldGVfcmVjdXJzaXZlbHkoc2VsZi5fcGF0aCkKKworICAgIGRlZiB0ZXN0X2FkZChzZWxmKToKKyAgICAgICAgIyBBZGQgY29waWVzIG9mIGEgc2FtcGxlIG1lc3NhZ2UKKyAgICAgICAga2V5cyA9IFtdCisgICAgICAgIGtleXMuYXBwZW5kKHNlbGYuX2JveC5hZGQoc2VsZi5fdGVtcGxhdGUgJSAwKSkKKyAgICAgICAgc2VsZi5hc3NlcnRfKGxlbihzZWxmLl9ib3gpID09IDEpCisgICAgICAgIGtleXMuYXBwZW5kKHNlbGYuX2JveC5hZGQobWFpbGJveC5NZXNzYWdlKF9zYW1wbGVfbWVzc2FnZSkpKQorICAgICAgICBzZWxmLmFzc2VydF8obGVuKHNlbGYuX2JveCkgPT0gMikKKyAgICAgICAga2V5cy5hcHBlbmQoc2VsZi5fYm94LmFkZChlbWFpbC5tZXNzYWdlX2Zyb21fc3RyaW5nKF9zYW1wbGVfbWVzc2FnZSkpKQorICAgICAgICBzZWxmLmFzc2VydF8obGVuKHNlbGYuX2JveCkgPT0gMykKKyAgICAgICAga2V5cy5hcHBlbmQoc2VsZi5fYm94LmFkZChTdHJpbmdJTy5TdHJpbmdJTyhfc2FtcGxlX21lc3NhZ2UpKSkKKyAgICAgICAgc2VsZi5hc3NlcnRfKGxlbihzZWxmLl9ib3gpID09IDQpCisgICAgICAgIGtleXMuYXBwZW5kKHNlbGYuX2JveC5hZGQoX3NhbXBsZV9tZXNzYWdlKSkKKyAgICAgICAgc2VsZi5hc3NlcnRfKGxlbihzZWxmLl9ib3gpID09IDUpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZWxmLl9ib3guZ2V0X3N0cmluZyhrZXlzWzBdKSA9PSBzZWxmLl90ZW1wbGF0ZSAlIDApCisgICAgICAgIGZvciBpIGluICgxLCAyLCAzLCA0KToKKyAgICAgICAgICAgIHNlbGYuX2NoZWNrX3NhbXBsZShzZWxmLl9ib3hba2V5c1tpXV0pCisKKyAgICBkZWYgdGVzdF9yZW1vdmUoc2VsZik6CisgICAgICAgICMgUmVtb3ZlIG1lc3NhZ2VzIHVzaW5nIHJlbW92ZSgpCisgICAgICAgIHNlbGYuX3Rlc3RfcmVtb3ZlX29yX2RlbGl0ZW0oc2VsZi5fYm94LnJlbW92ZSkKKworICAgIGRlZiB0ZXN0X2RlbGl0ZW0oc2VsZik6CisgICAgICAgICMgUmVtb3ZlIG1lc3NhZ2VzIHVzaW5nIF9fZGVsaXRlbV9fKCkKKyAgICAgICAgc2VsZi5fdGVzdF9yZW1vdmVfb3JfZGVsaXRlbShzZWxmLl9ib3guX19kZWxpdGVtX18pCisKKyAgICBkZWYgX3Rlc3RfcmVtb3ZlX29yX2RlbGl0ZW0oc2VsZiwgbWV0aG9kKToKKyAgICAgICAgIyAoVXNlZCBieSB0ZXN0X3JlbW92ZSgpIGFuZCB0ZXN0X2RlbGl0ZW0oKS4pCisgICAgICAgIGtleTAgPSBzZWxmLl9ib3guYWRkKHNlbGYuX3RlbXBsYXRlICUgMCkKKyAgICAgICAga2V5MSA9IHNlbGYuX2JveC5hZGQoc2VsZi5fdGVtcGxhdGUgJSAxKQorICAgICAgICBzZWxmLmFzc2VydF8obGVuKHNlbGYuX2JveCkgPT0gMikKKyAgICAgICAgbWV0aG9kKGtleTApCisgICAgICAgIGwgPSBsZW4oc2VsZi5fYm94KQorICAgICAgICBzZWxmLmFzc2VydF8obCA9PSAxLCAiYWN0dWFsIGw6ICVzIiAlIGwpCisgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKEtleUVycm9yLCBsYW1iZGE6IHNlbGYuX2JveFtrZXkwXSkKKyAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoS2V5RXJyb3IsIGxhbWJkYTogbWV0aG9kKGtleTApKQorICAgICAgICBzZWxmLmFzc2VydF8oc2VsZi5fYm94LmdldF9zdHJpbmcoa2V5MSkgPT0gc2VsZi5fdGVtcGxhdGUgJSAxKQorICAgICAgICBrZXkyID0gc2VsZi5fYm94LmFkZChzZWxmLl90ZW1wbGF0ZSAlIDIpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhsZW4oc2VsZi5fYm94KSA9PSAyKQorICAgICAgICBtZXRob2Qoa2V5MikKKyAgICAgICAgbCA9IGxlbihzZWxmLl9ib3gpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhsID09IDEsICJhY3R1YWwgbDogJXMiICUgbCkKKyAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoS2V5RXJyb3IsIGxhbWJkYTogc2VsZi5fYm94W2tleTJdKQorICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhLZXlFcnJvciwgbGFtYmRhOiBtZXRob2Qoa2V5MikpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZWxmLl9ib3guZ2V0X3N0cmluZyhrZXkxKSA9PSBzZWxmLl90ZW1wbGF0ZSAlIDEpCisgICAgICAgIG1ldGhvZChrZXkxKQorICAgICAgICBzZWxmLmFzc2VydF8obGVuKHNlbGYuX2JveCkgPT0gMCkKKyAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoS2V5RXJyb3IsIGxhbWJkYTogc2VsZi5fYm94W2tleTFdKQorICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhLZXlFcnJvciwgbGFtYmRhOiBtZXRob2Qoa2V5MSkpCisKKyAgICBkZWYgdGVzdF9kaXNjYXJkKHNlbGYsIHJlcGV0aXRpb25zPTEwKToKKyAgICAgICAgIyBEaXNjYXJkIG1lc3NhZ2VzCisgICAgICAgIGtleTAgPSBzZWxmLl9ib3guYWRkKHNlbGYuX3RlbXBsYXRlICUgMCkKKyAgICAgICAga2V5MSA9IHNlbGYuX2JveC5hZGQoc2VsZi5fdGVtcGxhdGUgJSAxKQorICAgICAgICBzZWxmLmFzc2VydF8obGVuKHNlbGYuX2JveCkgPT0gMikKKyAgICAgICAgc2VsZi5fYm94LmRpc2NhcmQoa2V5MCkKKyAgICAgICAgc2VsZi5hc3NlcnRfKGxlbihzZWxmLl9ib3gpID09IDEpCisgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKEtleUVycm9yLCBsYW1iZGE6IHNlbGYuX2JveFtrZXkwXSkKKyAgICAgICAgc2VsZi5fYm94LmRpc2NhcmQoa2V5MCkKKyAgICAgICAgc2VsZi5hc3NlcnRfKGxlbihzZWxmLl9ib3gpID09IDEpCisgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKEtleUVycm9yLCBsYW1iZGE6IHNlbGYuX2JveFtrZXkwXSkKKworICAgIGRlZiB0ZXN0X2dldChzZWxmKToKKyAgICAgICAgIyBSZXRyaWV2ZSBtZXNzYWdlcyB1c2luZyBnZXQoKQorICAgICAgICBrZXkwID0gc2VsZi5fYm94LmFkZChzZWxmLl90ZW1wbGF0ZSAlIDApCisgICAgICAgIG1zZyA9IHNlbGYuX2JveC5nZXQoa2V5MCkKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1zZ1snZnJvbSddID09ICdmb28nKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnLmdldF9wYXlsb2FkKCkgPT0gJzAnKQorICAgICAgICBzZWxmLmFzc2VydF8oc2VsZi5fYm94LmdldCgnZm9vJykgaXMgTm9uZSkKKyAgICAgICAgc2VsZi5hc3NlcnRfKHNlbGYuX2JveC5nZXQoJ2ZvbycsIEZhbHNlKSBpcyBGYWxzZSkKKyAgICAgICAgc2VsZi5fYm94LmNsb3NlKCkKKyAgICAgICAgc2VsZi5fYm94ID0gc2VsZi5fZmFjdG9yeShzZWxmLl9wYXRoLCBmYWN0b3J5PXJmYzgyMi5NZXNzYWdlKQorICAgICAgICBrZXkxID0gc2VsZi5fYm94LmFkZChzZWxmLl90ZW1wbGF0ZSAlIDEpCisgICAgICAgIG1zZyA9IHNlbGYuX2JveC5nZXQoa2V5MSkKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1zZ1snZnJvbSddID09ICdmb28nKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnLmZwLnJlYWQoKSA9PSAnMScpCisKKyAgICBkZWYgdGVzdF9nZXRpdGVtKHNlbGYpOgorICAgICAgICAjIFJldHJpZXZlIG1lc3NhZ2UgdXNpbmcgX19nZXRpdGVtX18oKQorICAgICAgICBrZXkwID0gc2VsZi5fYm94LmFkZChzZWxmLl90ZW1wbGF0ZSAlIDApCisgICAgICAgIG1zZyA9IHNlbGYuX2JveFtrZXkwXQorICAgICAgICBzZWxmLmFzc2VydF8obXNnWydmcm9tJ10gPT0gJ2ZvbycpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X3BheWxvYWQoKSA9PSAnMCcpCisgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKEtleUVycm9yLCBsYW1iZGE6IHNlbGYuX2JveFsnZm9vJ10pCisgICAgICAgIHNlbGYuX2JveC5kaXNjYXJkKGtleTApCisgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKEtleUVycm9yLCBsYW1iZGE6IHNlbGYuX2JveFtrZXkwXSkKKworICAgIGRlZiB0ZXN0X2dldF9tZXNzYWdlKHNlbGYpOgorICAgICAgICAjIEdldCBNZXNzYWdlIHJlcHJlc2VudGF0aW9ucyBvZiBtZXNzYWdlcworICAgICAgICBrZXkwID0gc2VsZi5fYm94LmFkZChzZWxmLl90ZW1wbGF0ZSAlIDApCisgICAgICAgIGtleTEgPSBzZWxmLl9ib3guYWRkKF9zYW1wbGVfbWVzc2FnZSkKKyAgICAgICAgbXNnMCA9IHNlbGYuX2JveC5nZXRfbWVzc2FnZShrZXkwKQorICAgICAgICBzZWxmLmFzc2VydF8oaXNpbnN0YW5jZShtc2cwLCBtYWlsYm94Lk1lc3NhZ2UpKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnMFsnZnJvbSddID09ICdmb28nKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnMC5nZXRfcGF5bG9hZCgpID09ICcwJykKKyAgICAgICAgc2VsZi5fY2hlY2tfc2FtcGxlKHNlbGYuX2JveC5nZXRfbWVzc2FnZShrZXkxKSkKKworICAgIGRlZiB0ZXN0X2dldF9zdHJpbmcoc2VsZik6CisgICAgICAgICMgR2V0IHN0cmluZyByZXByZXNlbnRhdGlvbnMgb2YgbWVzc2FnZXMKKyAgICAgICAga2V5MCA9IHNlbGYuX2JveC5hZGQoc2VsZi5fdGVtcGxhdGUgJSAwKQorICAgICAgICBrZXkxID0gc2VsZi5fYm94LmFkZChfc2FtcGxlX21lc3NhZ2UpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZWxmLl9ib3guZ2V0X3N0cmluZyhrZXkwKSA9PSBzZWxmLl90ZW1wbGF0ZSAlIDApCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZWxmLl9ib3guZ2V0X3N0cmluZyhrZXkxKSA9PSBfc2FtcGxlX21lc3NhZ2UpCisKKyAgICBkZWYgdGVzdF9nZXRfZmlsZShzZWxmKToKKyAgICAgICAgIyBHZXQgZmlsZSByZXByZXNlbnRhdGlvbnMgb2YgbWVzc2FnZXMKKyAgICAgICAga2V5MCA9IHNlbGYuX2JveC5hZGQoc2VsZi5fdGVtcGxhdGUgJSAwKQorICAgICAgICBrZXkxID0gc2VsZi5fYm94LmFkZChfc2FtcGxlX21lc3NhZ2UpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZWxmLl9ib3guZ2V0X2ZpbGUoa2V5MCkucmVhZCgpLnJlcGxhY2Uob3MubGluZXNlcCwgJ1xuJykKKyAgICAgICAgICAgICAgICAgICAgID09IHNlbGYuX3RlbXBsYXRlICUgMCkKKyAgICAgICAgc2VsZi5hc3NlcnRfKHNlbGYuX2JveC5nZXRfZmlsZShrZXkxKS5yZWFkKCkucmVwbGFjZShvcy5saW5lc2VwLCAnXG4nKQorICAgICAgICAgICAgICAgICAgICAgPT0gX3NhbXBsZV9tZXNzYWdlKQorCisgICAgZGVmIHRlc3RfaXRlcmtleXMoc2VsZik6CisgICAgICAgICMgR2V0IGtleXMgdXNpbmcgaXRlcmtleXMoKQorICAgICAgICBzZWxmLl9jaGVja19pdGVyYXRpb24oc2VsZi5fYm94Lml0ZXJrZXlzLCBkb19rZXlzPVRydWUsIGRvX3ZhbHVlcz1GYWxzZSkKKworICAgIGRlZiB0ZXN0X2tleXMoc2VsZik6CisgICAgICAgICMgR2V0IGtleXMgdXNpbmcga2V5cygpCisgICAgICAgIHNlbGYuX2NoZWNrX2l0ZXJhdGlvbihzZWxmLl9ib3gua2V5cywgZG9fa2V5cz1UcnVlLCBkb192YWx1ZXM9RmFsc2UpCisKKyAgICBkZWYgdGVzdF9pdGVydmFsdWVzKHNlbGYpOgorICAgICAgICAjIEdldCB2YWx1ZXMgdXNpbmcgaXRlcnZhbHVlcygpCisgICAgICAgIHNlbGYuX2NoZWNrX2l0ZXJhdGlvbihzZWxmLl9ib3guaXRlcnZhbHVlcywgZG9fa2V5cz1GYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvX3ZhbHVlcz1UcnVlKQorCisgICAgZGVmIHRlc3RfaXRlcihzZWxmKToKKyAgICAgICAgIyBHZXQgdmFsdWVzIHVzaW5nIF9faXRlcl9fKCkKKyAgICAgICAgc2VsZi5fY2hlY2tfaXRlcmF0aW9uKHNlbGYuX2JveC5fX2l0ZXJfXywgZG9fa2V5cz1GYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvX3ZhbHVlcz1UcnVlKQorCisgICAgZGVmIHRlc3RfdmFsdWVzKHNlbGYpOgorICAgICAgICAjIEdldCB2YWx1ZXMgdXNpbmcgdmFsdWVzKCkKKyAgICAgICAgc2VsZi5fY2hlY2tfaXRlcmF0aW9uKHNlbGYuX2JveC52YWx1ZXMsIGRvX2tleXM9RmFsc2UsIGRvX3ZhbHVlcz1UcnVlKQorCisgICAgZGVmIHRlc3RfaXRlcml0ZW1zKHNlbGYpOgorICAgICAgICAjIEdldCBrZXlzIGFuZCB2YWx1ZXMgdXNpbmcgaXRlcml0ZW1zKCkKKyAgICAgICAgc2VsZi5fY2hlY2tfaXRlcmF0aW9uKHNlbGYuX2JveC5pdGVyaXRlbXMsIGRvX2tleXM9VHJ1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvX3ZhbHVlcz1UcnVlKQorCisgICAgZGVmIHRlc3RfaXRlbXMoc2VsZik6CisgICAgICAgICMgR2V0IGtleXMgYW5kIHZhbHVlcyB1c2luZyBpdGVtcygpCisgICAgICAgIHNlbGYuX2NoZWNrX2l0ZXJhdGlvbihzZWxmLl9ib3guaXRlbXMsIGRvX2tleXM9VHJ1ZSwgZG9fdmFsdWVzPVRydWUpCisKKyAgICBkZWYgX2NoZWNrX2l0ZXJhdGlvbihzZWxmLCBtZXRob2QsIGRvX2tleXMsIGRvX3ZhbHVlcywgcmVwZXRpdGlvbnM9MTApOgorICAgICAgICBmb3IgdmFsdWUgaW4gbWV0aG9kKCk6CisgICAgICAgICAgICBzZWxmLmZhaWwoIk5vdCBlbXB0eSIpCisgICAgICAgIGtleXMsIHZhbHVlcyA9IFtdLCBbXQorICAgICAgICBmb3IgaSBpbiB4cmFuZ2UocmVwZXRpdGlvbnMpOgorICAgICAgICAgICAga2V5cy5hcHBlbmQoc2VsZi5fYm94LmFkZChzZWxmLl90ZW1wbGF0ZSAlIGkpKQorICAgICAgICAgICAgdmFsdWVzLmFwcGVuZChzZWxmLl90ZW1wbGF0ZSAlIGkpCisgICAgICAgIGlmIGRvX2tleXMgYW5kIG5vdCBkb192YWx1ZXM6CisgICAgICAgICAgICByZXR1cm5lZF9rZXlzID0gbGlzdChtZXRob2QoKSkKKyAgICAgICAgZWxpZiBkb192YWx1ZXMgYW5kIG5vdCBkb19rZXlzOgorICAgICAgICAgICAgcmV0dXJuZWRfdmFsdWVzID0gbGlzdChtZXRob2QoKSkKKyAgICAgICAgZWxzZToKKyAgICAgICAgICAgIHJldHVybmVkX2tleXMsIHJldHVybmVkX3ZhbHVlcyA9IFtdLCBbXQorICAgICAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gbWV0aG9kKCk6CisgICAgICAgICAgICAgICAgcmV0dXJuZWRfa2V5cy5hcHBlbmQoa2V5KQorICAgICAgICAgICAgICAgIHJldHVybmVkX3ZhbHVlcy5hcHBlbmQodmFsdWUpCisgICAgICAgIGlmIGRvX2tleXM6CisgICAgICAgICAgICBzZWxmLmFzc2VydF8obGVuKGtleXMpID09IGxlbihyZXR1cm5lZF9rZXlzKSkKKyAgICAgICAgICAgIHNlbGYuYXNzZXJ0XyhzZXQoa2V5cykgPT0gc2V0KHJldHVybmVkX2tleXMpKQorICAgICAgICBpZiBkb192YWx1ZXM6CisgICAgICAgICAgICBjb3VudCA9IDAKKyAgICAgICAgICAgIGZvciB2YWx1ZSBpbiByZXR1cm5lZF92YWx1ZXM6CisgICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRfKHZhbHVlWydmcm9tJ10gPT0gJ2ZvbycpCisgICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRfKGludCh2YWx1ZS5nZXRfcGF5bG9hZCgpKSA8IHJlcGV0aXRpb25zKQorICAgICAgICAgICAgICAgIGNvdW50ICs9IDEKKyAgICAgICAgICAgIHNlbGYuYXNzZXJ0XyhsZW4odmFsdWVzKSA9PSBjb3VudCkKKworICAgIGRlZiB0ZXN0X2hhc19rZXkoc2VsZik6CisgICAgICAgICMgQ2hlY2sgZXhpc3RlbmNlIG9mIGtleXMgdXNpbmcgaGFzX2tleSgpCisgICAgICAgIHNlbGYuX3Rlc3RfaGFzX2tleV9vcl9jb250YWlucyhzZWxmLl9ib3guaGFzX2tleSkKKworICAgIGRlZiB0ZXN0X2NvbnRhaW5zKHNlbGYpOgorICAgICAgICAjIENoZWNrIGV4aXN0ZW5jZSBvZiBrZXlzIHVzaW5nIF9fY29udGFpbnNfXygpCisgICAgICAgIHNlbGYuX3Rlc3RfaGFzX2tleV9vcl9jb250YWlucyhzZWxmLl9ib3guX19jb250YWluc19fKQorCisgICAgZGVmIF90ZXN0X2hhc19rZXlfb3JfY29udGFpbnMoc2VsZiwgbWV0aG9kKToKKyAgICAgICAgIyAoVXNlZCBieSB0ZXN0X2hhc19rZXkoKSBhbmQgdGVzdF9jb250YWlucygpLikKKyAgICAgICAgc2VsZi5hc3NlcnRfKG5vdCBtZXRob2QoJ2ZvbycpKQorICAgICAgICBrZXkwID0gc2VsZi5fYm94LmFkZChzZWxmLl90ZW1wbGF0ZSAlIDApCisgICAgICAgIHNlbGYuYXNzZXJ0XyhtZXRob2Qoa2V5MCkpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhub3QgbWV0aG9kKCdmb28nKSkKKyAgICAgICAga2V5MSA9IHNlbGYuX2JveC5hZGQoc2VsZi5fdGVtcGxhdGUgJSAxKQorICAgICAgICBzZWxmLmFzc2VydF8obWV0aG9kKGtleTEpKQorICAgICAgICBzZWxmLmFzc2VydF8obWV0aG9kKGtleTApKQorICAgICAgICBzZWxmLmFzc2VydF8obm90IG1ldGhvZCgnZm9vJykpCisgICAgICAgIHNlbGYuX2JveC5yZW1vdmUoa2V5MCkKKyAgICAgICAgc2VsZi5hc3NlcnRfKG5vdCBtZXRob2Qoa2V5MCkpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhtZXRob2Qoa2V5MSkpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhub3QgbWV0aG9kKCdmb28nKSkKKyAgICAgICAgc2VsZi5fYm94LnJlbW92ZShrZXkxKQorICAgICAgICBzZWxmLmFzc2VydF8obm90IG1ldGhvZChrZXkxKSkKKyAgICAgICAgc2VsZi5hc3NlcnRfKG5vdCBtZXRob2Qoa2V5MCkpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhub3QgbWV0aG9kKCdmb28nKSkKKworICAgIGRlZiB0ZXN0X2xlbihzZWxmLCByZXBldGl0aW9ucz0xMCk6CisgICAgICAgICMgR2V0IG1lc3NhZ2UgY291bnQKKyAgICAgICAga2V5cyA9IFtdCisgICAgICAgIGZvciBpIGluIHhyYW5nZShyZXBldGl0aW9ucyk6CisgICAgICAgICAgICBzZWxmLmFzc2VydF8obGVuKHNlbGYuX2JveCkgPT0gaSkKKyAgICAgICAgICAgIGtleXMuYXBwZW5kKHNlbGYuX2JveC5hZGQoc2VsZi5fdGVtcGxhdGUgJSBpKSkKKyAgICAgICAgICAgIHNlbGYuYXNzZXJ0XyhsZW4oc2VsZi5fYm94KSA9PSBpICsgMSkKKyAgICAgICAgZm9yIGkgaW4geHJhbmdlKHJlcGV0aXRpb25zKToKKyAgICAgICAgICAgIHNlbGYuYXNzZXJ0XyhsZW4oc2VsZi5fYm94KSA9PSByZXBldGl0aW9ucyAtIGkpCisgICAgICAgICAgICBzZWxmLl9ib3gucmVtb3ZlKGtleXNbaV0pCisgICAgICAgICAgICBzZWxmLmFzc2VydF8obGVuKHNlbGYuX2JveCkgPT0gcmVwZXRpdGlvbnMgLSBpIC0gMSkKKworICAgIGRlZiB0ZXN0X3NldF9pdGVtKHNlbGYpOgorICAgICAgICAjIE1vZGlmeSBtZXNzYWdlcyB1c2luZyBfX3NldGl0ZW1fXygpCisgICAgICAgIGtleTAgPSBzZWxmLl9ib3guYWRkKHNlbGYuX3RlbXBsYXRlICUgJ29yaWdpbmFsIDAnKQorICAgICAgICBzZWxmLmFzc2VydF8oc2VsZi5fYm94LmdldF9zdHJpbmcoa2V5MCkgPT0gXAorICAgICAgICAgICAgICAgICAgICAgc2VsZi5fdGVtcGxhdGUgJSAnb3JpZ2luYWwgMCcpCisgICAgICAgIGtleTEgPSBzZWxmLl9ib3guYWRkKHNlbGYuX3RlbXBsYXRlICUgJ29yaWdpbmFsIDEnKQorICAgICAgICBzZWxmLmFzc2VydF8oc2VsZi5fYm94LmdldF9zdHJpbmcoa2V5MSkgPT0gXAorICAgICAgICAgICAgICAgICAgICAgc2VsZi5fdGVtcGxhdGUgJSAnb3JpZ2luYWwgMScpCisgICAgICAgIHNlbGYuX2JveFtrZXkwXSA9IHNlbGYuX3RlbXBsYXRlICUgJ2NoYW5nZWQgMCcKKyAgICAgICAgc2VsZi5hc3NlcnRfKHNlbGYuX2JveC5nZXRfc3RyaW5nKGtleTApID09IFwKKyAgICAgICAgICAgICAgICAgICAgIHNlbGYuX3RlbXBsYXRlICUgJ2NoYW5nZWQgMCcpCisgICAgICAgIHNlbGYuX2JveFtrZXkxXSA9IHNlbGYuX3RlbXBsYXRlICUgJ2NoYW5nZWQgMScKKyAgICAgICAgc2VsZi5hc3NlcnRfKHNlbGYuX2JveC5nZXRfc3RyaW5nKGtleTEpID09IFwKKyAgICAgICAgICAgICAgICAgICAgIHNlbGYuX3RlbXBsYXRlICUgJ2NoYW5nZWQgMScpCisgICAgICAgIHNlbGYuX2JveFtrZXkwXSA9IF9zYW1wbGVfbWVzc2FnZQorICAgICAgICBzZWxmLl9jaGVja19zYW1wbGUoc2VsZi5fYm94W2tleTBdKQorICAgICAgICBzZWxmLl9ib3hba2V5MV0gPSBzZWxmLl9ib3hba2V5MF0KKyAgICAgICAgc2VsZi5fY2hlY2tfc2FtcGxlKHNlbGYuX2JveFtrZXkxXSkKKyAgICAgICAgc2VsZi5fYm94W2tleTBdID0gc2VsZi5fdGVtcGxhdGUgJSAnb3JpZ2luYWwgMCcKKyAgICAgICAgc2VsZi5hc3NlcnRfKHNlbGYuX2JveC5nZXRfc3RyaW5nKGtleTApID09CisgICAgICAgICAgICAgICAgICAgICBzZWxmLl90ZW1wbGF0ZSAlICdvcmlnaW5hbCAwJykKKyAgICAgICAgc2VsZi5fY2hlY2tfc2FtcGxlKHNlbGYuX2JveFtrZXkxXSkKKyAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoS2V5RXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGxhbWJkYTogc2VsZi5fYm94Ll9fc2V0aXRlbV9fKCdmb28nLCAnYmFyJykpCisgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKEtleUVycm9yLCBsYW1iZGE6IHNlbGYuX2JveFsnZm9vJ10pCisgICAgICAgIHNlbGYuYXNzZXJ0XyhsZW4oc2VsZi5fYm94KSA9PSAyKQorCisgICAgZGVmIHRlc3RfY2xlYXIoc2VsZiwgaXRlcmF0aW9ucz0xMCk6CisgICAgICAgICMgUmVtb3ZlIGFsbCBtZXNzYWdlcyB1c2luZyBjbGVhcigpCisgICAgICAgIGtleXMgPSBbXQorICAgICAgICBmb3IgaSBpbiB4cmFuZ2UoaXRlcmF0aW9ucyk6CisgICAgICAgICAgICBzZWxmLl9ib3guYWRkKHNlbGYuX3RlbXBsYXRlICUgaSkKKyAgICAgICAgZm9yIGksIGtleSBpbiBlbnVtZXJhdGUoa2V5cyk6CisgICAgICAgICAgICBzZWxmLmFzc2VydF8oc2VsZi5fYm94LmdldF9zdHJpbmcoa2V5KSA9PSBzZWxmLl90ZW1wbGF0ZSAlIGkpCisgICAgICAgIHNlbGYuX2JveC5jbGVhcigpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhsZW4oc2VsZi5fYm94KSA9PSAwKQorICAgICAgICBmb3IgaSwga2V5IGluIGVudW1lcmF0ZShrZXlzKToKKyAgICAgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKEtleUVycm9yLCBsYW1iZGE6IHNlbGYuX2JveC5nZXRfc3RyaW5nKGtleSkpCisKKyAgICBkZWYgdGVzdF9wb3Aoc2VsZik6CisgICAgICAgICMgR2V0IGFuZCByZW1vdmUgYSBtZXNzYWdlIHVzaW5nIHBvcCgpCisgICAgICAgIGtleTAgPSBzZWxmLl9ib3guYWRkKHNlbGYuX3RlbXBsYXRlICUgMCkKKyAgICAgICAgc2VsZi5hc3NlcnRfKGtleTAgaW4gc2VsZi5fYm94KQorICAgICAgICBrZXkxID0gc2VsZi5fYm94LmFkZChzZWxmLl90ZW1wbGF0ZSAlIDEpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhrZXkxIGluIHNlbGYuX2JveCkKKyAgICAgICAgc2VsZi5hc3NlcnRfKHNlbGYuX2JveC5wb3Aoa2V5MCkuZ2V0X3BheWxvYWQoKSA9PSAnMCcpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhrZXkwIG5vdCBpbiBzZWxmLl9ib3gpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhrZXkxIGluIHNlbGYuX2JveCkKKyAgICAgICAga2V5MiA9IHNlbGYuX2JveC5hZGQoc2VsZi5fdGVtcGxhdGUgJSAyKQorICAgICAgICBzZWxmLmFzc2VydF8oa2V5MiBpbiBzZWxmLl9ib3gpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZWxmLl9ib3gucG9wKGtleTIpLmdldF9wYXlsb2FkKCkgPT0gJzInKQorICAgICAgICBzZWxmLmFzc2VydF8oa2V5MiBub3QgaW4gc2VsZi5fYm94KQorICAgICAgICBzZWxmLmFzc2VydF8oa2V5MSBpbiBzZWxmLl9ib3gpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZWxmLl9ib3gucG9wKGtleTEpLmdldF9wYXlsb2FkKCkgPT0gJzEnKQorICAgICAgICBzZWxmLmFzc2VydF8oa2V5MSBub3QgaW4gc2VsZi5fYm94KQorICAgICAgICBzZWxmLmFzc2VydF8obGVuKHNlbGYuX2JveCkgPT0gMCkKKworICAgIGRlZiB0ZXN0X3BvcGl0ZW0oc2VsZiwgaXRlcmF0aW9ucz0xMCk6CisgICAgICAgICMgR2V0IGFuZCByZW1vdmUgYW4gYXJiaXRyYXJ5IChrZXksIG1lc3NhZ2UpIHVzaW5nIHBvcGl0ZW0oKQorICAgICAgICBrZXlzID0gW10KKyAgICAgICAgZm9yIGkgaW4geHJhbmdlKDEwKToKKyAgICAgICAgICAgIGtleXMuYXBwZW5kKHNlbGYuX2JveC5hZGQoc2VsZi5fdGVtcGxhdGUgJSBpKSkKKyAgICAgICAgc2VlbiA9IFtdCisgICAgICAgIGZvciBpIGluIHhyYW5nZSgxMCk6CisgICAgICAgICAgICBrZXksIG1zZyA9IHNlbGYuX2JveC5wb3BpdGVtKCkKKyAgICAgICAgICAgIHNlbGYuYXNzZXJ0XyhrZXkgaW4ga2V5cykKKyAgICAgICAgICAgIHNlbGYuYXNzZXJ0XyhrZXkgbm90IGluIHNlZW4pCisgICAgICAgICAgICBzZWVuLmFwcGVuZChrZXkpCisgICAgICAgICAgICBzZWxmLmFzc2VydF8oaW50KG1zZy5nZXRfcGF5bG9hZCgpKSA9PSBrZXlzLmluZGV4KGtleSkpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhsZW4oc2VsZi5fYm94KSA9PSAwKQorICAgICAgICBmb3Iga2V5IGluIGtleXM6CisgICAgICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhLZXlFcnJvciwgbGFtYmRhOiBzZWxmLl9ib3hba2V5XSkKKworICAgIGRlZiB0ZXN0X3VwZGF0ZShzZWxmKToKKyAgICAgICAgIyBNb2RpZnkgbXVsdGlwbGUgbWVzc2FnZXMgdXNpbmcgdXBkYXRlKCkKKyAgICAgICAga2V5MCA9IHNlbGYuX2JveC5hZGQoc2VsZi5fdGVtcGxhdGUgJSAnb3JpZ2luYWwgMCcpCisgICAgICAgIGtleTEgPSBzZWxmLl9ib3guYWRkKHNlbGYuX3RlbXBsYXRlICUgJ29yaWdpbmFsIDEnKQorICAgICAgICBrZXkyID0gc2VsZi5fYm94LmFkZChzZWxmLl90ZW1wbGF0ZSAlICdvcmlnaW5hbCAyJykKKyAgICAgICAgc2VsZi5fYm94LnVwZGF0ZSh7a2V5MDogc2VsZi5fdGVtcGxhdGUgJSAnY2hhbmdlZCAwJywKKyAgICAgICAgICAgICAgICAgICAgICAgICAga2V5MjogX3NhbXBsZV9tZXNzYWdlfSkKKyAgICAgICAgc2VsZi5hc3NlcnRfKGxlbihzZWxmLl9ib3gpID09IDMpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZWxmLl9ib3guZ2V0X3N0cmluZyhrZXkwKSA9PQorICAgICAgICAgICAgICAgICAgICAgc2VsZi5fdGVtcGxhdGUgJSAnY2hhbmdlZCAwJykKKyAgICAgICAgc2VsZi5hc3NlcnRfKHNlbGYuX2JveC5nZXRfc3RyaW5nKGtleTEpID09CisgICAgICAgICAgICAgICAgICAgICBzZWxmLl90ZW1wbGF0ZSAlICdvcmlnaW5hbCAxJykKKyAgICAgICAgc2VsZi5fY2hlY2tfc2FtcGxlKHNlbGYuX2JveFtrZXkyXSkKKyAgICAgICAgc2VsZi5fYm94LnVwZGF0ZShbKGtleTIsIHNlbGYuX3RlbXBsYXRlICUgJ2NoYW5nZWQgMicpLAorICAgICAgICAgICAgICAgICAgICAoa2V5MSwgc2VsZi5fdGVtcGxhdGUgJSAnY2hhbmdlZCAxJyksCisgICAgICAgICAgICAgICAgICAgIChrZXkwLCBzZWxmLl90ZW1wbGF0ZSAlICdvcmlnaW5hbCAwJyldKQorICAgICAgICBzZWxmLmFzc2VydF8obGVuKHNlbGYuX2JveCkgPT0gMykKKyAgICAgICAgc2VsZi5hc3NlcnRfKHNlbGYuX2JveC5nZXRfc3RyaW5nKGtleTApID09CisgICAgICAgICAgICAgICAgICAgICBzZWxmLl90ZW1wbGF0ZSAlICdvcmlnaW5hbCAwJykKKyAgICAgICAgc2VsZi5hc3NlcnRfKHNlbGYuX2JveC5nZXRfc3RyaW5nKGtleTEpID09CisgICAgICAgICAgICAgICAgICAgICBzZWxmLl90ZW1wbGF0ZSAlICdjaGFuZ2VkIDEnKQorICAgICAgICBzZWxmLmFzc2VydF8oc2VsZi5fYm94LmdldF9zdHJpbmcoa2V5MikgPT0KKyAgICAgICAgICAgICAgICAgICAgIHNlbGYuX3RlbXBsYXRlICUgJ2NoYW5nZWQgMicpCisgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKEtleUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICBsYW1iZGE6IHNlbGYuX2JveC51cGRhdGUoeydmb28nOiAnYmFyJywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleTA6IHNlbGYuX3RlbXBsYXRlICUgImNoYW5nZWQgMCJ9KSkKKyAgICAgICAgc2VsZi5hc3NlcnRfKGxlbihzZWxmLl9ib3gpID09IDMpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZWxmLl9ib3guZ2V0X3N0cmluZyhrZXkwKSA9PQorICAgICAgICAgICAgICAgICAgICAgc2VsZi5fdGVtcGxhdGUgJSAiY2hhbmdlZCAwIikKKyAgICAgICAgc2VsZi5hc3NlcnRfKHNlbGYuX2JveC5nZXRfc3RyaW5nKGtleTEpID09CisgICAgICAgICAgICAgICAgICAgICBzZWxmLl90ZW1wbGF0ZSAlICJjaGFuZ2VkIDEiKQorICAgICAgICBzZWxmLmFzc2VydF8oc2VsZi5fYm94LmdldF9zdHJpbmcoa2V5MikgPT0KKyAgICAgICAgICAgICAgICAgICAgIHNlbGYuX3RlbXBsYXRlICUgImNoYW5nZWQgMiIpCisKKyAgICBkZWYgdGVzdF9mbHVzaChzZWxmKToKKyAgICAgICAgIyBXcml0ZSBjaGFuZ2VzIHRvIGRpc2sKKyAgICAgICAgc2VsZi5fdGVzdF9mbHVzaF9vcl9jbG9zZShzZWxmLl9ib3guZmx1c2gpCisKKyAgICBkZWYgdGVzdF9sb2NrX3VubG9jayhzZWxmKToKKyAgICAgICAgIyBMb2NrIGFuZCB1bmxvY2sgdGhlIG1haWxib3gKKyAgICAgICAgc2VsZi5hc3NlcnRfKG5vdCBvcy5wYXRoLmV4aXN0cyhzZWxmLl9nZXRfbG9ja19wYXRoKCkpKQorICAgICAgICBzZWxmLl9ib3gubG9jaygpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhvcy5wYXRoLmV4aXN0cyhzZWxmLl9nZXRfbG9ja19wYXRoKCkpKQorICAgICAgICBzZWxmLl9ib3gudW5sb2NrKCkKKyAgICAgICAgc2VsZi5hc3NlcnRfKG5vdCBvcy5wYXRoLmV4aXN0cyhzZWxmLl9nZXRfbG9ja19wYXRoKCkpKQorCisgICAgZGVmIHRlc3RfY2xvc2Uoc2VsZik6CisgICAgICAgICMgQ2xvc2UgbWFpbGJveCBhbmQgZmx1c2ggY2hhbmdlcyB0byBkaXNrCisgICAgICAgIHNlbGYuX3Rlc3RfZmx1c2hfb3JfY2xvc2Uoc2VsZi5fYm94LmNsb3NlKQorCisgICAgZGVmIF90ZXN0X2ZsdXNoX29yX2Nsb3NlKHNlbGYsIG1ldGhvZCk6CisgICAgICAgIGNvbnRlbnRzID0gW3NlbGYuX3RlbXBsYXRlICUgaSBmb3IgaSBpbiB4cmFuZ2UoMyldCisgICAgICAgIHNlbGYuX2JveC5hZGQoY29udGVudHNbMF0pCisgICAgICAgIHNlbGYuX2JveC5hZGQoY29udGVudHNbMV0pCisgICAgICAgIHNlbGYuX2JveC5hZGQoY29udGVudHNbMl0pCisgICAgICAgIG1ldGhvZCgpCisgICAgICAgIHNlbGYuX2JveCA9IHNlbGYuX2ZhY3Rvcnkoc2VsZi5fcGF0aCkKKyAgICAgICAga2V5cyA9IHNlbGYuX2JveC5rZXlzKCkKKyAgICAgICAgc2VsZi5hc3NlcnRfKGxlbihrZXlzKSA9PSAzKQorICAgICAgICBmb3Iga2V5IGluIGtleXM6CisgICAgICAgICAgICBzZWxmLmFzc2VydF8oc2VsZi5fYm94LmdldF9zdHJpbmcoa2V5KSBpbiBjb250ZW50cykKKworICAgIGRlZiB0ZXN0X2R1bXBfbWVzc2FnZShzZWxmKToKKyAgICAgICAgIyBXcml0ZSBtZXNzYWdlIHJlcHJlc2VudGF0aW9ucyB0byBkaXNrCisgICAgICAgIGZvciBpbnB1dCBpbiAoZW1haWwubWVzc2FnZV9mcm9tX3N0cmluZyhfc2FtcGxlX21lc3NhZ2UpLAorICAgICAgICAgICAgICAgICAgICAgIF9zYW1wbGVfbWVzc2FnZSwgU3RyaW5nSU8uU3RyaW5nSU8oX3NhbXBsZV9tZXNzYWdlKSk6CisgICAgICAgICAgICBvdXRwdXQgPSBTdHJpbmdJTy5TdHJpbmdJTygpCisgICAgICAgICAgICBzZWxmLl9ib3guX2R1bXBfbWVzc2FnZShpbnB1dCwgb3V0cHV0KQorICAgICAgICAgICAgc2VsZi5hc3NlcnRfKG91dHB1dC5nZXR2YWx1ZSgpID09CisgICAgICAgICAgICAgICAgICAgICAgICAgX3NhbXBsZV9tZXNzYWdlLnJlcGxhY2UoJ1xuJywgb3MubGluZXNlcCkpCisgICAgICAgIG91dHB1dCA9IFN0cmluZ0lPLlN0cmluZ0lPKCkKKyAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICBsYW1iZGE6IHNlbGYuX2JveC5fZHVtcF9tZXNzYWdlKE5vbmUsIG91dHB1dCkpCisKKyAgICBkZWYgX2dldF9sb2NrX3BhdGgoc2VsZik6CisgICAgICAgICMgUmV0dXJuIHRoZSBwYXRoIG9mIHRoZSBkb3QgbG9jayBmaWxlLiBNYXkgYmUgb3ZlcnJpZGRlbi4KKyAgICAgICAgcmV0dXJuIHNlbGYuX3BhdGggKyAnLmxvY2snCisKKworY2xhc3MgVGVzdE1haWxib3hTdXBlcmNsYXNzKFRlc3RCYXNlKToKKworICAgIGRlZiB0ZXN0X25vdGltcGxlbWVudGVkKHNlbGYpOgorICAgICAgICAjIFRlc3QgdGhhdCBhbGwgTWFpbGJveCBtZXRob2RzIHJhaXNlIE5vdEltcGxlbWVudGVkRXhjZXB0aW9uLgorICAgICAgICBib3ggPSBtYWlsYm94Lk1haWxib3goJ3BhdGgnKQorICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhOb3RJbXBsZW1lbnRlZEVycm9yLCBsYW1iZGE6IGJveC5hZGQoJycpKQorICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhOb3RJbXBsZW1lbnRlZEVycm9yLCBsYW1iZGE6IGJveC5yZW1vdmUoJycpKQorICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhOb3RJbXBsZW1lbnRlZEVycm9yLCBsYW1iZGE6IGJveC5fX2RlbGl0ZW1fXygnJykpCisgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKE5vdEltcGxlbWVudGVkRXJyb3IsIGxhbWJkYTogYm94LmRpc2NhcmQoJycpKQorICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhOb3RJbXBsZW1lbnRlZEVycm9yLCBsYW1iZGE6IGJveC5fX3NldGl0ZW1fXygnJywgJycpKQorICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhOb3RJbXBsZW1lbnRlZEVycm9yLCBsYW1iZGE6IGJveC5pdGVya2V5cygpKQorICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhOb3RJbXBsZW1lbnRlZEVycm9yLCBsYW1iZGE6IGJveC5rZXlzKCkpCisgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKE5vdEltcGxlbWVudGVkRXJyb3IsIGxhbWJkYTogYm94Lml0ZXJ2YWx1ZXMoKS5uZXh0KCkpCisgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKE5vdEltcGxlbWVudGVkRXJyb3IsIGxhbWJkYTogYm94Ll9faXRlcl9fKCkubmV4dCgpKQorICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhOb3RJbXBsZW1lbnRlZEVycm9yLCBsYW1iZGE6IGJveC52YWx1ZXMoKSkKKyAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoTm90SW1wbGVtZW50ZWRFcnJvciwgbGFtYmRhOiBib3guaXRlcml0ZW1zKCkubmV4dCgpKQorICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhOb3RJbXBsZW1lbnRlZEVycm9yLCBsYW1iZGE6IGJveC5pdGVtcygpKQorICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhOb3RJbXBsZW1lbnRlZEVycm9yLCBsYW1iZGE6IGJveC5nZXQoJycpKQorICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhOb3RJbXBsZW1lbnRlZEVycm9yLCBsYW1iZGE6IGJveC5fX2dldGl0ZW1fXygnJykpCisgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKE5vdEltcGxlbWVudGVkRXJyb3IsIGxhbWJkYTogYm94LmdldF9tZXNzYWdlKCcnKSkKKyAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoTm90SW1wbGVtZW50ZWRFcnJvciwgbGFtYmRhOiBib3guZ2V0X3N0cmluZygnJykpCisgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKE5vdEltcGxlbWVudGVkRXJyb3IsIGxhbWJkYTogYm94LmdldF9maWxlKCcnKSkKKyAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoTm90SW1wbGVtZW50ZWRFcnJvciwgbGFtYmRhOiBib3guaGFzX2tleSgnJykpCisgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKE5vdEltcGxlbWVudGVkRXJyb3IsIGxhbWJkYTogYm94Ll9fY29udGFpbnNfXygnJykpCisgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKE5vdEltcGxlbWVudGVkRXJyb3IsIGxhbWJkYTogYm94Ll9fbGVuX18oKSkKKyAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoTm90SW1wbGVtZW50ZWRFcnJvciwgbGFtYmRhOiBib3guY2xlYXIoKSkKKyAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoTm90SW1wbGVtZW50ZWRFcnJvciwgbGFtYmRhOiBib3gucG9wKCcnKSkKKyAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoTm90SW1wbGVtZW50ZWRFcnJvciwgbGFtYmRhOiBib3gucG9waXRlbSgpKQorICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhOb3RJbXBsZW1lbnRlZEVycm9yLCBsYW1iZGE6IGJveC51cGRhdGUoKCgnJywgJycpLCkpKQorICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhOb3RJbXBsZW1lbnRlZEVycm9yLCBsYW1iZGE6IGJveC5mbHVzaCgpKQorICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhOb3RJbXBsZW1lbnRlZEVycm9yLCBsYW1iZGE6IGJveC5sb2NrKCkpCisgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKE5vdEltcGxlbWVudGVkRXJyb3IsIGxhbWJkYTogYm94LnVubG9jaygpKQorICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhOb3RJbXBsZW1lbnRlZEVycm9yLCBsYW1iZGE6IGJveC5jbG9zZSgpKQorCisKK2NsYXNzIFRlc3RNYWlsZGlyKFRlc3RNYWlsYm94KToKKworICAgIF9mYWN0b3J5ID0gbGFtYmRhIHNlbGYsIHBhdGgsIGZhY3Rvcnk9Tm9uZTogbWFpbGJveC5NYWlsZGlyKHBhdGgsIGZhY3RvcnkpCisKKyAgICBkZWYgc2V0VXAoc2VsZik6CisgICAgICAgIFRlc3RNYWlsYm94LnNldFVwKHNlbGYpCisgICAgICAgIGlmIG9zLm5hbWUgPT0gJ250JzoKKyAgICAgICAgICAgIHNlbGYuX2JveC5jb2xvbiA9ICchJworCisgICAgZGVmIHRlc3RfYWRkX01NKHNlbGYpOgorICAgICAgICAjIEFkZCBhIE1haWxkaXJNZXNzYWdlIGluc3RhbmNlCisgICAgICAgIG1zZyA9IG1haWxib3guTWFpbGRpck1lc3NhZ2Uoc2VsZi5fdGVtcGxhdGUgJSAwKQorICAgICAgICBtc2cuc2V0X3N1YmRpcignY3VyJykKKyAgICAgICAgbXNnLnNldF9pbmZvKCdmb28nKQorICAgICAgICBrZXkgPSBzZWxmLl9ib3guYWRkKG1zZykKKyAgICAgICAgc2VsZi5hc3NlcnRfKG9zLnBhdGguZXhpc3RzKG9zLnBhdGguam9pbihzZWxmLl9wYXRoLCAnY3VyJywgJyVzJXNmb28nICUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoa2V5LCBzZWxmLl9ib3guY29sb24pKSkpCisKKyAgICBkZWYgdGVzdF9nZXRfTU0oc2VsZik6CisgICAgICAgICMgR2V0IGEgTWFpbGRpck1lc3NhZ2UgaW5zdGFuY2UKKyAgICAgICAgbXNnID0gbWFpbGJveC5NYWlsZGlyTWVzc2FnZShzZWxmLl90ZW1wbGF0ZSAlIDApCisgICAgICAgIG1zZy5zZXRfc3ViZGlyKCdjdXInKQorICAgICAgICBtc2cuc2V0X2ZsYWdzKCdSRicpCisgICAgICAgIGtleSA9IHNlbGYuX2JveC5hZGQobXNnKQorICAgICAgICBtc2dfcmV0dXJuZWQgPSBzZWxmLl9ib3guZ2V0X21lc3NhZ2Uoa2V5KQorICAgICAgICBzZWxmLmFzc2VydF8oaXNpbnN0YW5jZShtc2dfcmV0dXJuZWQsIG1haWxib3guTWFpbGRpck1lc3NhZ2UpKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnX3JldHVybmVkLmdldF9zdWJkaXIoKSA9PSAnY3VyJykKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1zZ19yZXR1cm5lZC5nZXRfZmxhZ3MoKSA9PSAnRlInKQorCisgICAgZGVmIHRlc3Rfc2V0X01NKHNlbGYpOgorICAgICAgICAjIFNldCB3aXRoIGEgTWFpbGRpck1lc3NhZ2UgaW5zdGFuY2UKKyAgICAgICAgbXNnMCA9IG1haWxib3guTWFpbGRpck1lc3NhZ2Uoc2VsZi5fdGVtcGxhdGUgJSAwKQorICAgICAgICBtc2cwLnNldF9mbGFncygnVFAnKQorICAgICAgICBrZXkgPSBzZWxmLl9ib3guYWRkKG1zZzApCisgICAgICAgIG1zZ19yZXR1cm5lZCA9IHNlbGYuX2JveC5nZXRfbWVzc2FnZShrZXkpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2dfcmV0dXJuZWQuZ2V0X3N1YmRpcigpID09ICduZXcnKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnX3JldHVybmVkLmdldF9mbGFncygpID09ICdQVCcpCisgICAgICAgIG1zZzEgPSBtYWlsYm94Lk1haWxkaXJNZXNzYWdlKHNlbGYuX3RlbXBsYXRlICUgMSkKKyAgICAgICAgc2VsZi5fYm94W2tleV0gPSBtc2cxCisgICAgICAgIG1zZ19yZXR1cm5lZCA9IHNlbGYuX2JveC5nZXRfbWVzc2FnZShrZXkpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2dfcmV0dXJuZWQuZ2V0X3N1YmRpcigpID09ICduZXcnKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnX3JldHVybmVkLmdldF9mbGFncygpID09ICcnKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnX3JldHVybmVkLmdldF9wYXlsb2FkKCkgPT0gJzEnKQorICAgICAgICBtc2cyID0gbWFpbGJveC5NYWlsZGlyTWVzc2FnZShzZWxmLl90ZW1wbGF0ZSAlIDIpCisgICAgICAgIG1zZzIuc2V0X2luZm8oJzIsUycpCisgICAgICAgIHNlbGYuX2JveFtrZXldID0gbXNnMgorICAgICAgICBzZWxmLl9ib3hba2V5XSA9IHNlbGYuX3RlbXBsYXRlICUgMworICAgICAgICBtc2dfcmV0dXJuZWQgPSBzZWxmLl9ib3guZ2V0X21lc3NhZ2Uoa2V5KQorICAgICAgICBzZWxmLmFzc2VydF8obXNnX3JldHVybmVkLmdldF9zdWJkaXIoKSA9PSAnbmV3JykKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1zZ19yZXR1cm5lZC5nZXRfZmxhZ3MoKSA9PSAnUycpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2dfcmV0dXJuZWQuZ2V0X3BheWxvYWQoKSA9PSAnMycpCisKKyAgICBkZWYgdGVzdF9pbml0aWFsaXplX25ldyhzZWxmKToKKyAgICAgICAgIyBJbml0aWFsaXplIGEgbm9uLWV4aXN0ZW50IG1haWxib3gKKyAgICAgICAgc2VsZi50ZWFyRG93bigpCisgICAgICAgIHNlbGYuX2JveCA9IG1haWxib3guTWFpbGRpcihzZWxmLl9wYXRoKQorICAgICAgICBzZWxmLl9jaGVja19iYXNpY3MoZmFjdG9yeT1yZmM4MjIuTWVzc2FnZSkKKyAgICAgICAgc2VsZi5fZGVsZXRlX3JlY3Vyc2l2ZWx5KHNlbGYuX3BhdGgpCisgICAgICAgIHNlbGYuX2JveCA9IHNlbGYuX2ZhY3Rvcnkoc2VsZi5fcGF0aCwgZmFjdG9yeT1Ob25lKQorICAgICAgICBzZWxmLl9jaGVja19iYXNpY3MoKQorCisgICAgZGVmIHRlc3RfaW5pdGlhbGl6ZV9leGlzdGluZyhzZWxmKToKKyAgICAgICAgIyBJbml0aWFsaXplIGFuIGV4aXN0aW5nIG1haWxib3gKKyAgICAgICAgc2VsZi50ZWFyRG93bigpCisgICAgICAgIGZvciBzdWJkaXIgaW4gJycsICd0bXAnLCAnbmV3JywgJ2N1cic6CisgICAgICAgICAgICBvcy5ta2Rpcihvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgc3ViZGlyKSkKKyAgICAgICAgc2VsZi5fYm94ID0gbWFpbGJveC5NYWlsZGlyKHNlbGYuX3BhdGgpCisgICAgICAgIHNlbGYuX2NoZWNrX2Jhc2ljcyhmYWN0b3J5PXJmYzgyMi5NZXNzYWdlKQorICAgICAgICBzZWxmLl9ib3ggPSBtYWlsYm94Lk1haWxkaXIoc2VsZi5fcGF0aCwgZmFjdG9yeT1Ob25lKQorICAgICAgICBzZWxmLl9jaGVja19iYXNpY3MoKQorCisgICAgZGVmIF9jaGVja19iYXNpY3Moc2VsZiwgZmFjdG9yeT1Ob25lKToKKyAgICAgICAgIyAoVXNlZCBieSB0ZXN0X29wZW5fbmV3KCkgYW5kIHRlc3Rfb3Blbl9leGlzdGluZygpLikKKyAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChzZWxmLl9ib3guX3BhdGgsIG9zLnBhdGguYWJzcGF0aChzZWxmLl9wYXRoKSkKKyAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChzZWxmLl9ib3guX2ZhY3RvcnksIGZhY3RvcnkpCisgICAgICAgIGZvciBzdWJkaXIgaW4gJycsICd0bXAnLCAnbmV3JywgJ2N1cic6CisgICAgICAgICAgICBwYXRoID0gb3MucGF0aC5qb2luKHNlbGYuX3BhdGgsIHN1YmRpcikKKyAgICAgICAgICAgIG1vZGUgPSBvcy5zdGF0KHBhdGgpW3N0YXQuU1RfTU9ERV0KKyAgICAgICAgICAgIHNlbGYuYXNzZXJ0XyhzdGF0LlNfSVNESVIobW9kZSksICJOb3QgYSBkaXJlY3Rvcnk6ICclcyciICUgcGF0aCkKKworICAgIGRlZiB0ZXN0X2xpc3RfZm9sZGVycyhzZWxmKToKKyAgICAgICAgIyBMaXN0IGZvbGRlcnMKKyAgICAgICAgc2VsZi5fYm94LmFkZF9mb2xkZXIoJ29uZScpCisgICAgICAgIHNlbGYuX2JveC5hZGRfZm9sZGVyKCd0d28nKQorICAgICAgICBzZWxmLl9ib3guYWRkX2ZvbGRlcigndGhyZWUnKQorICAgICAgICBzZWxmLmFzc2VydF8obGVuKHNlbGYuX2JveC5saXN0X2ZvbGRlcnMoKSkgPT0gMykKKyAgICAgICAgc2VsZi5hc3NlcnRfKHNldChzZWxmLl9ib3gubGlzdF9mb2xkZXJzKCkpID09CisgICAgICAgICAgICAgICAgICAgICBzZXQoKCdvbmUnLCAndHdvJywgJ3RocmVlJykpKQorCisgICAgZGVmIHRlc3RfZ2V0X2ZvbGRlcihzZWxmKToKKyAgICAgICAgIyBPcGVuIGZvbGRlcnMKKyAgICAgICAgc2VsZi5fYm94LmFkZF9mb2xkZXIoJ2Zvby5iYXInKQorICAgICAgICBmb2xkZXIwID0gc2VsZi5fYm94LmdldF9mb2xkZXIoJ2Zvby5iYXInKQorICAgICAgICBmb2xkZXIwLmFkZChzZWxmLl90ZW1wbGF0ZSAlICdiYXInKQorICAgICAgICBzZWxmLmFzc2VydF8ob3MucGF0aC5pc2Rpcihvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgJy5mb28uYmFyJykpKQorICAgICAgICBmb2xkZXIxID0gc2VsZi5fYm94LmdldF9mb2xkZXIoJ2Zvby5iYXInKQorICAgICAgICBzZWxmLmFzc2VydF8oZm9sZGVyMS5nZXRfc3RyaW5nKGZvbGRlcjEua2V5cygpWzBdKSA9PSBcCisgICAgICAgICAgICAgICAgICAgICBzZWxmLl90ZW1wbGF0ZSAlICdiYXInKQorCisgICAgZGVmIHRlc3RfYWRkX2FuZF9yZW1vdmVfZm9sZGVycyhzZWxmKToKKyAgICAgICAgIyBEZWxldGUgZm9sZGVycworICAgICAgICBzZWxmLl9ib3guYWRkX2ZvbGRlcignb25lJykKKyAgICAgICAgc2VsZi5fYm94LmFkZF9mb2xkZXIoJ3R3bycpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhsZW4oc2VsZi5fYm94Lmxpc3RfZm9sZGVycygpKSA9PSAyKQorICAgICAgICBzZWxmLmFzc2VydF8oc2V0KHNlbGYuX2JveC5saXN0X2ZvbGRlcnMoKSkgPT0gc2V0KCgnb25lJywgJ3R3bycpKSkKKyAgICAgICAgc2VsZi5fYm94LnJlbW92ZV9mb2xkZXIoJ29uZScpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhsZW4oc2VsZi5fYm94Lmxpc3RfZm9sZGVycygpKSA9PSAxKQorICAgICAgICBzZWxmLmFzc2VydF8oc2V0KHNlbGYuX2JveC5saXN0X2ZvbGRlcnMoKSkgPT0gc2V0KCgndHdvJywpKSkKKyAgICAgICAgc2VsZi5fYm94LmFkZF9mb2xkZXIoJ3RocmVlJykKKyAgICAgICAgc2VsZi5hc3NlcnRfKGxlbihzZWxmLl9ib3gubGlzdF9mb2xkZXJzKCkpID09IDIpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZXQoc2VsZi5fYm94Lmxpc3RfZm9sZGVycygpKSA9PSBzZXQoKCd0d28nLCAndGhyZWUnKSkpCisgICAgICAgIHNlbGYuX2JveC5yZW1vdmVfZm9sZGVyKCd0aHJlZScpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhsZW4oc2VsZi5fYm94Lmxpc3RfZm9sZGVycygpKSA9PSAxKQorICAgICAgICBzZWxmLmFzc2VydF8oc2V0KHNlbGYuX2JveC5saXN0X2ZvbGRlcnMoKSkgPT0gc2V0KCgndHdvJywpKSkKKyAgICAgICAgc2VsZi5fYm94LnJlbW92ZV9mb2xkZXIoJ3R3bycpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhsZW4oc2VsZi5fYm94Lmxpc3RfZm9sZGVycygpKSA9PSAwKQorICAgICAgICBzZWxmLmFzc2VydF8oc2VsZi5fYm94Lmxpc3RfZm9sZGVycygpID09IFtdKQorCisgICAgZGVmIHRlc3RfY2xlYW4oc2VsZik6CisgICAgICAgICMgUmVtb3ZlIG9sZCBmaWxlcyBmcm9tICd0bXAnCisgICAgICAgIGZvb19wYXRoID0gb3MucGF0aC5qb2luKHNlbGYuX3BhdGgsICd0bXAnLCAnZm9vJykKKyAgICAgICAgYmFyX3BhdGggPSBvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgJ3RtcCcsICdiYXInKQorICAgICAgICBmaWxlKGZvb19wYXRoLCAndycpLmNsb3NlKCkKKyAgICAgICAgZmlsZShiYXJfcGF0aCwgJ3cnKS5jbG9zZSgpCisgICAgICAgIHNlbGYuX2JveC5jbGVhbigpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhvcy5wYXRoLmV4aXN0cyhmb29fcGF0aCkpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhvcy5wYXRoLmV4aXN0cyhiYXJfcGF0aCkpCisgICAgICAgIGZvb19zdGF0ID0gb3Muc3RhdChmb29fcGF0aCkKKyAgICAgICAgb3MudXRpbWUob3MucGF0aC5qb2luKGZvb19wYXRoKSwgKHRpbWUudGltZSgpIC0gMTI5NjAwIC0gMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvb19zdGF0LnN0X210aW1lKSkKKyAgICAgICAgc2VsZi5fYm94LmNsZWFuKCkKKyAgICAgICAgc2VsZi5hc3NlcnRfKG5vdCBvcy5wYXRoLmV4aXN0cyhmb29fcGF0aCkpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhvcy5wYXRoLmV4aXN0cyhiYXJfcGF0aCkpCisKKyAgICBkZWYgdGVzdF9jcmVhdGVfdG1wKHNlbGYsIHJlcGV0aXRpb25zPTEwKToKKyAgICAgICAgIyBDcmVhdGUgZmlsZXMgaW4gdG1wIGRpcmVjdG9yeQorICAgICAgICBob3N0bmFtZSA9IHNvY2tldC5nZXRob3N0bmFtZSgpCisgICAgICAgIGlmICcvJyBpbiBob3N0bmFtZToKKyAgICAgICAgICAgIGhvc3RuYW1lID0gaG9zdG5hbWUucmVwbGFjZSgnLycsIHInXDA1NycpCisgICAgICAgIGlmICc6JyBpbiBob3N0bmFtZToKKyAgICAgICAgICAgIGhvc3RuYW1lID0gaG9zdG5hbWUucmVwbGFjZSgnOicsIHInXDA3MicpCisgICAgICAgIHBpZCA9IG9zLmdldHBpZCgpCisgICAgICAgIHBhdHRlcm4gPSByZS5jb21waWxlKHIiKD9QPHRpbWU+XGQrKVwuTSg/UDxNPlxkezEsNn0pUCg/UDxQPlxkKykiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHIiUSg/UDxRPlxkKylcLig/UDxob3N0PlteOi9dKykiKQorICAgICAgICBwcmV2aW91c19ncm91cHMgPSBOb25lCisgICAgICAgIGZvciB4IGluIHhyYW5nZShyZXBldGl0aW9ucyk6CisgICAgICAgICAgICB0bXBfZmlsZSA9IHNlbGYuX2JveC5fY3JlYXRlX3RtcCgpCisgICAgICAgICAgICBoZWFkLCB0YWlsID0gb3MucGF0aC5zcGxpdCh0bXBfZmlsZS5uYW1lKQorICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChoZWFkLCBvcy5wYXRoLmFic3BhdGgob3MucGF0aC5qb2luKHNlbGYuX3BhdGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRtcCIpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZpbGUgaW4gd3JvbmcgbG9jYXRpb246ICclcyciICUgaGVhZCkKKyAgICAgICAgICAgIG1hdGNoID0gcGF0dGVybi5tYXRjaCh0YWlsKQorICAgICAgICAgICAgc2VsZi5hc3NlcnRfKG1hdGNoICE9IE5vbmUsICJJbnZhbGlkIGZpbGUgbmFtZTogJyVzJyIgJSB0YWlsKQorICAgICAgICAgICAgZ3JvdXBzID0gbWF0Y2guZ3JvdXBzKCkKKyAgICAgICAgICAgIGlmIHByZXZpb3VzX2dyb3VwcyAhPSBOb25lOgorICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0XyhpbnQoZ3JvdXBzWzBdID49IHByZXZpb3VzX2dyb3Vwc1swXSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOb24tbW9ub3RvbmljIHNlY29uZHM6ICclcycgYmVmb3JlICclcyciICUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHByZXZpb3VzX2dyb3Vwc1swXSwgZ3JvdXBzWzBdKSkKKyAgICAgICAgICAgICAgICBzZWxmLmFzc2VydF8oaW50KGdyb3Vwc1sxXSA+PSBwcmV2aW91c19ncm91cHNbMV0pIG9yCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3Vwc1swXSAhPSBncm91cHNbMV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOb24tbW9ub3RvbmljIG1pbGxpc2Vjb25kczogJyVzJyBiZWZvcmUgJyVzJyIgJQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocHJldmlvdXNfZ3JvdXBzWzFdLCBncm91cHNbMV0pKQorICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0XyhpbnQoZ3JvdXBzWzJdKSA9PSBwaWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQcm9jZXNzIElEIG1pc21hdGNoOiAnJXMnIHNob3VsZCBiZSAnJXMnIiAlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChncm91cHNbMl0sIHBpZCkpCisgICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRfKGludChncm91cHNbM10pID09IGludChwcmV2aW91c19ncm91cHNbM10pICsgMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vbi1zZXF1ZW50aWFsIGNvdW50ZXI6ICclcycgYmVmb3JlICclcyciICUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHByZXZpb3VzX2dyb3Vwc1szXSwgZ3JvdXBzWzNdKSkKKyAgICAgICAgICAgICAgICBzZWxmLmFzc2VydF8oZ3JvdXBzWzRdID09IGhvc3RuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSG9zdCBuYW1lIG1pc21hdGNoOiAnJXMnIHNob3VsZCBiZSAnJXMnIiAlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChncm91cHNbNF0sIGhvc3RuYW1lKSkKKyAgICAgICAgICAgIHByZXZpb3VzX2dyb3VwcyA9IGdyb3VwcworICAgICAgICAgICAgdG1wX2ZpbGUud3JpdGUoX3NhbXBsZV9tZXNzYWdlKQorICAgICAgICAgICAgdG1wX2ZpbGUuc2VlaygwKQorICAgICAgICAgICAgc2VsZi5hc3NlcnRfKHRtcF9maWxlLnJlYWQoKSA9PSBfc2FtcGxlX21lc3NhZ2UpCisgICAgICAgICAgICB0bXBfZmlsZS5jbG9zZSgpCisgICAgICAgIGZpbGVfY291bnQgPSBsZW4ob3MubGlzdGRpcihvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgInRtcCIpKSkKKyAgICAgICAgc2VsZi5hc3NlcnRfKGZpbGVfY291bnQgPT0gcmVwZXRpdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAiV3JvbmcgZmlsZSBjb3VudDogJyVzJyBzaG91bGQgYmUgJyVzJyIgJQorICAgICAgICAgICAgICAgICAgICAgKGZpbGVfY291bnQsIHJlcGV0aXRpb25zKSkKKworICAgIGRlZiB0ZXN0X3JlZnJlc2goc2VsZik6CisgICAgICAgICMgVXBkYXRlIHRoZSB0YWJsZSBvZiBjb250ZW50cworICAgICAgICBzZWxmLmFzc2VydF8oc2VsZi5fYm94Ll90b2MgPT0ge30pCisgICAgICAgIGtleTAgPSBzZWxmLl9ib3guYWRkKHNlbGYuX3RlbXBsYXRlICUgMCkKKyAgICAgICAga2V5MSA9IHNlbGYuX2JveC5hZGQoc2VsZi5fdGVtcGxhdGUgJSAxKQorICAgICAgICBzZWxmLmFzc2VydF8oc2VsZi5fYm94Ll90b2MgPT0ge30pCisgICAgICAgIHNlbGYuX2JveC5fcmVmcmVzaCgpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZWxmLl9ib3guX3RvYyA9PSB7a2V5MDogb3MucGF0aC5qb2luKCduZXcnLCBrZXkwKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXkxOiBvcy5wYXRoLmpvaW4oJ25ldycsIGtleTEpfSkKKyAgICAgICAga2V5MiA9IHNlbGYuX2JveC5hZGQoc2VsZi5fdGVtcGxhdGUgJSAyKQorICAgICAgICBzZWxmLmFzc2VydF8oc2VsZi5fYm94Ll90b2MgPT0ge2tleTA6IG9zLnBhdGguam9pbignbmV3Jywga2V5MCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5MTogb3MucGF0aC5qb2luKCduZXcnLCBrZXkxKX0pCisgICAgICAgIHNlbGYuX2JveC5fcmVmcmVzaCgpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZWxmLl9ib3guX3RvYyA9PSB7a2V5MDogb3MucGF0aC5qb2luKCduZXcnLCBrZXkwKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXkxOiBvcy5wYXRoLmpvaW4oJ25ldycsIGtleTEpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleTI6IG9zLnBhdGguam9pbignbmV3Jywga2V5Mil9KQorCisgICAgZGVmIHRlc3RfbG9va3VwKHNlbGYpOgorICAgICAgICAjIExvb2sgdXAgbWVzc2FnZSBzdWJwYXRocyBpbiB0aGUgVE9DCisgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKEtleUVycm9yLCBsYW1iZGE6IHNlbGYuX2JveC5fbG9va3VwKCdmb28nKSkKKyAgICAgICAga2V5MCA9IHNlbGYuX2JveC5hZGQoc2VsZi5fdGVtcGxhdGUgJSAwKQorICAgICAgICBzZWxmLmFzc2VydF8oc2VsZi5fYm94Ll9sb29rdXAoa2V5MCkgPT0gb3MucGF0aC5qb2luKCduZXcnLCBrZXkwKSkKKyAgICAgICAgb3MucmVtb3ZlKG9zLnBhdGguam9pbihzZWxmLl9wYXRoLCAnbmV3Jywga2V5MCkpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZWxmLl9ib3guX3RvYyA9PSB7a2V5MDogb3MucGF0aC5qb2luKCduZXcnLCBrZXkwKX0pCisgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKEtleUVycm9yLCBsYW1iZGE6IHNlbGYuX2JveC5fbG9va3VwKGtleTApKQorICAgICAgICBzZWxmLmFzc2VydF8oc2VsZi5fYm94Ll90b2MgPT0ge30pCisKKyAgICBkZWYgdGVzdF9sb2NrX3VubG9jayhzZWxmKToKKyAgICAgICAgIyBMb2NrIGFuZCB1bmxvY2sgdGhlIG1haWxib3guIEZvciBNYWlsZGlyLCB0aGlzIGRvZXMgbm90aGluZy4KKyAgICAgICAgc2VsZi5fYm94LmxvY2soKQorICAgICAgICBzZWxmLl9ib3gudW5sb2NrKCkKKworCitjbGFzcyBfVGVzdE1ib3hNTURGKFRlc3RNYWlsYm94KToKKworICAgIGRlZiB0ZWFyRG93bihzZWxmKToKKyAgICAgICAgc2VsZi5fYm94LmNsb3NlKCkKKyAgICAgICAgc2VsZi5fZGVsZXRlX3JlY3Vyc2l2ZWx5KHNlbGYuX3BhdGgpCisgICAgICAgIGZvciBsb2NrX3JlbW5hbnQgaW4gZ2xvYi5nbG9iKHNlbGYuX3BhdGggKyAnLionKToKKyAgICAgICAgICAgIG9zLnJlbW92ZShsb2NrX3JlbW5hbnQpCisKKyAgICBkZWYgdGVzdF9hZGRfZnJvbV9zdHJpbmcoc2VsZik6CisgICAgICAgICMgQWRkIGEgc3RyaW5nIHN0YXJ0aW5nIHdpdGggJ0Zyb20gJyB0byB0aGUgbWFpbGJveAorICAgICAgICBrZXkgPSBzZWxmLl9ib3guYWRkKCdGcm9tIGZvb0BiYXIgYmxhaFxuRnJvbTogZm9vXG5cbjAnKQorICAgICAgICBzZWxmLmFzc2VydF8oc2VsZi5fYm94W2tleV0uZ2V0X2Zyb20oKSA9PSAnZm9vQGJhciBibGFoJykKKyAgICAgICAgc2VsZi5hc3NlcnRfKHNlbGYuX2JveFtrZXldLmdldF9wYXlsb2FkKCkgPT0gJzAnKQorCisgICAgZGVmIHRlc3RfYWRkX21ib3hfb3JfbW1kZl9tZXNzYWdlKHNlbGYpOgorICAgICAgICAjIEFkZCBhbiBtYm94TWVzc2FnZSBvciBNTURGTWVzc2FnZQorICAgICAgICBmb3IgY2xhc3NfIGluIChtYWlsYm94Lm1ib3hNZXNzYWdlLCBtYWlsYm94Lk1NREZNZXNzYWdlKToKKyAgICAgICAgICAgIG1zZyA9IGNsYXNzXygnRnJvbSBmb29AYmFyIGJsYWhcbkZyb206IGZvb1xuXG4wJykKKyAgICAgICAgICAgIGtleSA9IHNlbGYuX2JveC5hZGQobXNnKQorCisgICAgZGVmIHRlc3Rfb3Blbl9jbG9zZV9vcGVuKHNlbGYpOgorICAgICAgICAjIE9wZW4gYW5kIGluc3BlY3QgcHJldmlvdXNseS1jcmVhdGVkIG1haWxib3gKKyAgICAgICAgdmFsdWVzID0gW3NlbGYuX3RlbXBsYXRlICUgaSBmb3IgaSBpbiB4cmFuZ2UoMyldCisgICAgICAgIGZvciB2YWx1ZSBpbiB2YWx1ZXM6CisgICAgICAgICAgICBzZWxmLl9ib3guYWRkKHZhbHVlKQorICAgICAgICBzZWxmLl9ib3guY2xvc2UoKQorICAgICAgICBtdGltZSA9IG9zLnBhdGguZ2V0bXRpbWUoc2VsZi5fcGF0aCkKKyAgICAgICAgc2VsZi5fYm94ID0gc2VsZi5fZmFjdG9yeShzZWxmLl9wYXRoKQorICAgICAgICBzZWxmLmFzc2VydF8obGVuKHNlbGYuX2JveCkgPT0gMykKKyAgICAgICAgZm9yIGtleSBpbiBzZWxmLl9ib3guaXRlcmtleXMoKToKKyAgICAgICAgICAgIHNlbGYuYXNzZXJ0XyhzZWxmLl9ib3guZ2V0X3N0cmluZyhrZXkpIGluIHZhbHVlcykKKyAgICAgICAgc2VsZi5fYm94LmNsb3NlKCkKKyAgICAgICAgc2VsZi5hc3NlcnRfKG10aW1lID09IG9zLnBhdGguZ2V0bXRpbWUoc2VsZi5fcGF0aCkpCisKKyAgICBkZWYgdGVzdF9hZGRfYW5kX2Nsb3NlKHNlbGYpOgorICAgICAgICAjIFZlcmlmeWluZyB0aGF0IGNsb3NpbmcgYSBtYWlsYm94IGRvZXNuJ3QgY2hhbmdlIGFkZGVkIGl0ZW1zCisgICAgICAgIHNlbGYuX2JveC5hZGQoX3NhbXBsZV9tZXNzYWdlKQorICAgICAgICBmb3IgaSBpbiB4cmFuZ2UoMyk6CisgICAgICAgICAgICBzZWxmLl9ib3guYWRkKHNlbGYuX3RlbXBsYXRlICUgaSkKKyAgICAgICAgc2VsZi5fYm94LmFkZChfc2FtcGxlX21lc3NhZ2UpCisgICAgICAgIHNlbGYuX2JveC5fZmlsZS5mbHVzaCgpCisgICAgICAgIHNlbGYuX2JveC5fZmlsZS5zZWVrKDApCisgICAgICAgIGNvbnRlbnRzID0gc2VsZi5fYm94Ll9maWxlLnJlYWQoKQorICAgICAgICBzZWxmLl9ib3guY2xvc2UoKQorICAgICAgICBzZWxmLmFzc2VydF8oY29udGVudHMgPT0gZmlsZShzZWxmLl9wYXRoLCAncmInKS5yZWFkKCkpCisgICAgICAgIHNlbGYuX2JveCA9IHNlbGYuX2ZhY3Rvcnkoc2VsZi5fcGF0aCkKKworCitjbGFzcyBUZXN0TWJveChfVGVzdE1ib3hNTURGKToKKworICAgIF9mYWN0b3J5ID0gbGFtYmRhIHNlbGYsIHBhdGgsIGZhY3Rvcnk9Tm9uZTogbWFpbGJveC5tYm94KHBhdGgsIGZhY3RvcnkpCisKKworY2xhc3MgVGVzdE1NREYoX1Rlc3RNYm94TU1ERik6CisKKyAgICBfZmFjdG9yeSA9IGxhbWJkYSBzZWxmLCBwYXRoLCBmYWN0b3J5PU5vbmU6IG1haWxib3guTU1ERihwYXRoLCBmYWN0b3J5KQorCisKK2NsYXNzIFRlc3RNSChUZXN0TWFpbGJveCk6CisKKyAgICBfZmFjdG9yeSA9IGxhbWJkYSBzZWxmLCBwYXRoLCBmYWN0b3J5PU5vbmU6IG1haWxib3guTUgocGF0aCwgZmFjdG9yeSkKKworICAgIGRlZiB0ZXN0X2xpc3RfZm9sZGVycyhzZWxmKToKKyAgICAgICAgIyBMaXN0IGZvbGRlcnMKKyAgICAgICAgc2VsZi5fYm94LmFkZF9mb2xkZXIoJ29uZScpCisgICAgICAgIHNlbGYuX2JveC5hZGRfZm9sZGVyKCd0d28nKQorICAgICAgICBzZWxmLl9ib3guYWRkX2ZvbGRlcigndGhyZWUnKQorICAgICAgICBzZWxmLmFzc2VydF8obGVuKHNlbGYuX2JveC5saXN0X2ZvbGRlcnMoKSkgPT0gMykKKyAgICAgICAgc2VsZi5hc3NlcnRfKHNldChzZWxmLl9ib3gubGlzdF9mb2xkZXJzKCkpID09CisgICAgICAgICAgICAgICAgICAgICBzZXQoKCdvbmUnLCAndHdvJywgJ3RocmVlJykpKQorCisgICAgZGVmIHRlc3RfZ2V0X2ZvbGRlcihzZWxmKToKKyAgICAgICAgIyBPcGVuIGZvbGRlcnMKKyAgICAgICAgc2VsZi5fYm94LmFkZF9mb2xkZXIoJ2Zvby5iYXInKQorICAgICAgICBmb2xkZXIwID0gc2VsZi5fYm94LmdldF9mb2xkZXIoJ2Zvby5iYXInKQorICAgICAgICBmb2xkZXIwLmFkZChzZWxmLl90ZW1wbGF0ZSAlICdiYXInKQorICAgICAgICBzZWxmLmFzc2VydF8ob3MucGF0aC5pc2Rpcihvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgJ2Zvby5iYXInKSkpCisgICAgICAgIGZvbGRlcjEgPSBzZWxmLl9ib3guZ2V0X2ZvbGRlcignZm9vLmJhcicpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhmb2xkZXIxLmdldF9zdHJpbmcoZm9sZGVyMS5rZXlzKClbMF0pID09IFwKKyAgICAgICAgICAgICAgICAgICAgIHNlbGYuX3RlbXBsYXRlICUgJ2JhcicpCisKKyAgICBkZWYgdGVzdF9hZGRfYW5kX3JlbW92ZV9mb2xkZXJzKHNlbGYpOgorICAgICAgICAjIERlbGV0ZSBmb2xkZXJzCisgICAgICAgIHNlbGYuX2JveC5hZGRfZm9sZGVyKCdvbmUnKQorICAgICAgICBzZWxmLl9ib3guYWRkX2ZvbGRlcigndHdvJykKKyAgICAgICAgc2VsZi5hc3NlcnRfKGxlbihzZWxmLl9ib3gubGlzdF9mb2xkZXJzKCkpID09IDIpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZXQoc2VsZi5fYm94Lmxpc3RfZm9sZGVycygpKSA9PSBzZXQoKCdvbmUnLCAndHdvJykpKQorICAgICAgICBzZWxmLl9ib3gucmVtb3ZlX2ZvbGRlcignb25lJykKKyAgICAgICAgc2VsZi5hc3NlcnRfKGxlbihzZWxmLl9ib3gubGlzdF9mb2xkZXJzKCkpID09IDEpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZXQoc2VsZi5fYm94Lmxpc3RfZm9sZGVycygpKSA9PSBzZXQoKCd0d28nLCkpKQorICAgICAgICBzZWxmLl9ib3guYWRkX2ZvbGRlcigndGhyZWUnKQorICAgICAgICBzZWxmLmFzc2VydF8obGVuKHNlbGYuX2JveC5saXN0X2ZvbGRlcnMoKSkgPT0gMikKKyAgICAgICAgc2VsZi5hc3NlcnRfKHNldChzZWxmLl9ib3gubGlzdF9mb2xkZXJzKCkpID09IHNldCgoJ3R3bycsICd0aHJlZScpKSkKKyAgICAgICAgc2VsZi5fYm94LnJlbW92ZV9mb2xkZXIoJ3RocmVlJykKKyAgICAgICAgc2VsZi5hc3NlcnRfKGxlbihzZWxmLl9ib3gubGlzdF9mb2xkZXJzKCkpID09IDEpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZXQoc2VsZi5fYm94Lmxpc3RfZm9sZGVycygpKSA9PSBzZXQoKCd0d28nLCkpKQorICAgICAgICBzZWxmLl9ib3gucmVtb3ZlX2ZvbGRlcigndHdvJykKKyAgICAgICAgc2VsZi5hc3NlcnRfKGxlbihzZWxmLl9ib3gubGlzdF9mb2xkZXJzKCkpID09IDApCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZWxmLl9ib3gubGlzdF9mb2xkZXJzKCkgPT0gW10pCisKKyAgICBkZWYgdGVzdF9zZXF1ZW5jZXMoc2VsZik6CisgICAgICAgICMgR2V0IGFuZCBzZXQgc2VxdWVuY2VzCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZWxmLl9ib3guZ2V0X3NlcXVlbmNlcygpID09IHt9KQorICAgICAgICBtc2cwID0gbWFpbGJveC5NSE1lc3NhZ2Uoc2VsZi5fdGVtcGxhdGUgJSAwKQorICAgICAgICBtc2cwLmFkZF9zZXF1ZW5jZSgnZm9vJykKKyAgICAgICAga2V5MCA9IHNlbGYuX2JveC5hZGQobXNnMCkKKyAgICAgICAgc2VsZi5hc3NlcnRfKHNlbGYuX2JveC5nZXRfc2VxdWVuY2VzKCkgPT0geydmb28nOltrZXkwXX0pCisgICAgICAgIG1zZzEgPSBtYWlsYm94Lk1ITWVzc2FnZShzZWxmLl90ZW1wbGF0ZSAlIDEpCisgICAgICAgIG1zZzEuc2V0X3NlcXVlbmNlcyhbJ2JhcicsICdyZXBsaWVkJywgJ2ZvbyddKQorICAgICAgICBrZXkxID0gc2VsZi5fYm94LmFkZChtc2cxKQorICAgICAgICBzZWxmLmFzc2VydF8oc2VsZi5fYm94LmdldF9zZXF1ZW5jZXMoKSA9PQorICAgICAgICAgICAgICAgICAgICAgeydmb28nOltrZXkwLCBrZXkxXSwgJ2Jhcic6W2tleTFdLCAncmVwbGllZCc6W2tleTFdfSkKKyAgICAgICAgbXNnMC5zZXRfc2VxdWVuY2VzKFsnZmxhZ2dlZCddKQorICAgICAgICBzZWxmLl9ib3hba2V5MF0gPSBtc2cwCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZWxmLl9ib3guZ2V0X3NlcXVlbmNlcygpID09CisgICAgICAgICAgICAgICAgICAgICB7J2Zvbyc6W2tleTFdLCAnYmFyJzpba2V5MV0sICdyZXBsaWVkJzpba2V5MV0sCisgICAgICAgICAgICAgICAgICAgICAgJ2ZsYWdnZWQnOltrZXkwXX0pCisgICAgICAgIHNlbGYuX2JveC5yZW1vdmUoa2V5MSkKKyAgICAgICAgc2VsZi5hc3NlcnRfKHNlbGYuX2JveC5nZXRfc2VxdWVuY2VzKCkgPT0geydmbGFnZ2VkJzpba2V5MF19KQorCisgICAgZGVmIHRlc3RfcGFjayhzZWxmKToKKyAgICAgICAgIyBQYWNrIHRoZSBjb250ZW50cyBvZiB0aGUgbWFpbGJveAorICAgICAgICBtc2cwID0gbWFpbGJveC5NSE1lc3NhZ2Uoc2VsZi5fdGVtcGxhdGUgJSAwKQorICAgICAgICBtc2cxID0gbWFpbGJveC5NSE1lc3NhZ2Uoc2VsZi5fdGVtcGxhdGUgJSAxKQorICAgICAgICBtc2cyID0gbWFpbGJveC5NSE1lc3NhZ2Uoc2VsZi5fdGVtcGxhdGUgJSAyKQorICAgICAgICBtc2czID0gbWFpbGJveC5NSE1lc3NhZ2Uoc2VsZi5fdGVtcGxhdGUgJSAzKQorICAgICAgICBtc2cwLnNldF9zZXF1ZW5jZXMoWydmb28nLCAndW5zZWVuJ10pCisgICAgICAgIG1zZzEuc2V0X3NlcXVlbmNlcyhbJ2ZvbyddKQorICAgICAgICBtc2cyLnNldF9zZXF1ZW5jZXMoWydmb28nLCAnZmxhZ2dlZCddKQorICAgICAgICBtc2czLnNldF9zZXF1ZW5jZXMoWydmb28nLCAnYmFyJywgJ3JlcGxpZWQnXSkKKyAgICAgICAga2V5MCA9IHNlbGYuX2JveC5hZGQobXNnMCkKKyAgICAgICAga2V5MSA9IHNlbGYuX2JveC5hZGQobXNnMSkKKyAgICAgICAga2V5MiA9IHNlbGYuX2JveC5hZGQobXNnMikKKyAgICAgICAga2V5MyA9IHNlbGYuX2JveC5hZGQobXNnMykKKyAgICAgICAgc2VsZi5hc3NlcnRfKHNlbGYuX2JveC5nZXRfc2VxdWVuY2VzKCkgPT0KKyAgICAgICAgICAgICAgICAgICAgIHsnZm9vJzpba2V5MCxrZXkxLGtleTIsa2V5M10sICd1bnNlZW4nOltrZXkwXSwKKyAgICAgICAgICAgICAgICAgICAgICAnZmxhZ2dlZCc6W2tleTJdLCAnYmFyJzpba2V5M10sICdyZXBsaWVkJzpba2V5M119KQorICAgICAgICBzZWxmLl9ib3gucmVtb3ZlKGtleTIpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZWxmLl9ib3guZ2V0X3NlcXVlbmNlcygpID09CisgICAgICAgICAgICAgICAgICAgICB7J2Zvbyc6W2tleTAsa2V5MSxrZXkzXSwgJ3Vuc2Vlbic6W2tleTBdLCAnYmFyJzpba2V5M10sCisgICAgICAgICAgICAgICAgICAgICAgJ3JlcGxpZWQnOltrZXkzXX0pCisgICAgICAgIHNlbGYuX2JveC5wYWNrKCkKKyAgICAgICAgc2VsZi5hc3NlcnRfKHNlbGYuX2JveC5rZXlzKCkgPT0gWzEsIDIsIDNdKQorICAgICAgICBrZXkwID0ga2V5MAorICAgICAgICBrZXkxID0ga2V5MCArIDEKKyAgICAgICAga2V5MiA9IGtleTEgKyAxCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZWxmLl9ib3guZ2V0X3NlcXVlbmNlcygpID09CisgICAgICAgICAgICAgICAgICAgICB7J2Zvbyc6WzEsIDIsIDNdLCAndW5zZWVuJzpbMV0sICdiYXInOlszXSwgJ3JlcGxpZWQnOlszXX0pCisKKyAgICBkZWYgX2dldF9sb2NrX3BhdGgoc2VsZik6CisgICAgICAgIHJldHVybiBvcy5wYXRoLmpvaW4oc2VsZi5fcGF0aCwgJy5taF9zZXF1ZW5jZXMubG9jaycpCisKKworY2xhc3MgVGVzdEJhYnlsKFRlc3RNYWlsYm94KToKKworICAgIF9mYWN0b3J5ID0gbGFtYmRhIHNlbGYsIHBhdGgsIGZhY3Rvcnk9Tm9uZTogbWFpbGJveC5CYWJ5bChwYXRoLCBmYWN0b3J5KQorCisgICAgZGVmIHRlYXJEb3duKHNlbGYpOgorICAgICAgICBzZWxmLl9ib3guY2xvc2UoKQorICAgICAgICBzZWxmLl9kZWxldGVfcmVjdXJzaXZlbHkoc2VsZi5fcGF0aCkKKyAgICAgICAgZm9yIGxvY2tfcmVtbmFudCBpbiBnbG9iLmdsb2Ioc2VsZi5fcGF0aCArICcuKicpOgorICAgICAgICAgICAgb3MucmVtb3ZlKGxvY2tfcmVtbmFudCkKKworICAgIGRlZiB0ZXN0X2xhYmVscyhzZWxmKToKKyAgICAgICAgIyBHZXQgbGFiZWxzIGZyb20gdGhlIG1haWxib3gKKyAgICAgICAgc2VsZi5hc3NlcnRfKHNlbGYuX2JveC5nZXRfbGFiZWxzKCkgPT0gW10pCisgICAgICAgIG1zZzAgPSBtYWlsYm94LkJhYnlsTWVzc2FnZShzZWxmLl90ZW1wbGF0ZSAlIDApCisgICAgICAgIG1zZzAuYWRkX2xhYmVsKCdmb28nKQorICAgICAgICBrZXkwID0gc2VsZi5fYm94LmFkZChtc2cwKQorICAgICAgICBzZWxmLmFzc2VydF8oc2VsZi5fYm94LmdldF9sYWJlbHMoKSA9PSBbJ2ZvbyddKQorICAgICAgICBtc2cxID0gbWFpbGJveC5CYWJ5bE1lc3NhZ2Uoc2VsZi5fdGVtcGxhdGUgJSAxKQorICAgICAgICBtc2cxLnNldF9sYWJlbHMoWydiYXInLCAnYW5zd2VyZWQnLCAnZm9vJ10pCisgICAgICAgIGtleTEgPSBzZWxmLl9ib3guYWRkKG1zZzEpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZXQoc2VsZi5fYm94LmdldF9sYWJlbHMoKSkgPT0gc2V0KFsnZm9vJywgJ2JhciddKSkKKyAgICAgICAgbXNnMC5zZXRfbGFiZWxzKFsnYmxhaCcsICdmaWxlZCddKQorICAgICAgICBzZWxmLl9ib3hba2V5MF0gPSBtc2cwCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZXQoc2VsZi5fYm94LmdldF9sYWJlbHMoKSkgPT0KKyAgICAgICAgICAgICAgICAgICAgIHNldChbJ2ZvbycsICdiYXInLCAnYmxhaCddKSkKKyAgICAgICAgc2VsZi5fYm94LnJlbW92ZShrZXkxKQorICAgICAgICBzZWxmLmFzc2VydF8oc2V0KHNlbGYuX2JveC5nZXRfbGFiZWxzKCkpID09IHNldChbJ2JsYWgnXSkpCisKKworY2xhc3MgVGVzdE1lc3NhZ2UoVGVzdEJhc2UpOgorCisgICAgX2ZhY3RvcnkgPSBtYWlsYm94Lk1lc3NhZ2UgICAgICAjIE92ZXJyaWRkZW4gYnkgc3ViY2xhc3NlcyB0byByZXVzZSB0ZXN0cworCisgICAgZGVmIHNldFVwKHNlbGYpOgorICAgICAgICBzZWxmLl9wYXRoID0gdGVzdF9zdXBwb3J0LlRFU1RGTgorCisgICAgZGVmIHRlYXJEb3duKHNlbGYpOgorICAgICAgICBzZWxmLl9kZWxldGVfcmVjdXJzaXZlbHkoc2VsZi5fcGF0aCkKKworICAgIGRlZiB0ZXN0X2luaXRpYWxpemVfd2l0aF9lTU0oc2VsZik6CisgICAgICAgICMgSW5pdGlhbGl6ZSBiYXNlZCBvbiBlbWFpbC5NZXNzYWdlLk1lc3NhZ2UgaW5zdGFuY2UKKyAgICAgICAgZU1NID0gZW1haWwubWVzc2FnZV9mcm9tX3N0cmluZyhfc2FtcGxlX21lc3NhZ2UpCisgICAgICAgIG1zZyA9IHNlbGYuX2ZhY3RvcnkoZU1NKQorICAgICAgICBzZWxmLl9wb3N0X2luaXRpYWxpemVfaG9vayhtc2cpCisgICAgICAgIHNlbGYuX2NoZWNrX3NhbXBsZShtc2cpCisKKyAgICBkZWYgdGVzdF9pbml0aWFsaXplX3dpdGhfc3RyaW5nKHNlbGYpOgorICAgICAgICAjIEluaXRpYWxpemUgYmFzZWQgb24gc3RyaW5nCisgICAgICAgIG1zZyA9IHNlbGYuX2ZhY3RvcnkoX3NhbXBsZV9tZXNzYWdlKQorICAgICAgICBzZWxmLl9wb3N0X2luaXRpYWxpemVfaG9vayhtc2cpCisgICAgICAgIHNlbGYuX2NoZWNrX3NhbXBsZShtc2cpCisKKyAgICBkZWYgdGVzdF9pbml0aWFsaXplX3dpdGhfZmlsZShzZWxmKToKKyAgICAgICAgIyBJbml0aWFsaXplIGJhc2VkIG9uIGNvbnRlbnRzIG9mIGZpbGUKKyAgICAgICAgZiA9IG9wZW4oc2VsZi5fcGF0aCwgJ3crJykKKyAgICAgICAgZi53cml0ZShfc2FtcGxlX21lc3NhZ2UpCisgICAgICAgIGYuc2VlaygwKQorICAgICAgICBtc2cgPSBzZWxmLl9mYWN0b3J5KGYpCisgICAgICAgIHNlbGYuX3Bvc3RfaW5pdGlhbGl6ZV9ob29rKG1zZykKKyAgICAgICAgc2VsZi5fY2hlY2tfc2FtcGxlKG1zZykKKyAgICAgICAgZi5jbG9zZSgpCisKKyAgICBkZWYgdGVzdF9pbml0aWFsaXplX3dpdGhfbm90aGluZyhzZWxmKToKKyAgICAgICAgIyBJbml0aWFsaXplIHdpdGhvdXQgYXJndW1lbnRzCisgICAgICAgIG1zZyA9IHNlbGYuX2ZhY3RvcnkoKQorICAgICAgICBzZWxmLl9wb3N0X2luaXRpYWxpemVfaG9vayhtc2cpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhpc2luc3RhbmNlKG1zZywgZW1haWwuTWVzc2FnZS5NZXNzYWdlKSkKKyAgICAgICAgc2VsZi5hc3NlcnRfKGlzaW5zdGFuY2UobXNnLCBtYWlsYm94Lk1lc3NhZ2UpKQorICAgICAgICBzZWxmLmFzc2VydF8oaXNpbnN0YW5jZShtc2csIHNlbGYuX2ZhY3RvcnkpKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnLmtleXMoKSA9PSBbXSkKKyAgICAgICAgc2VsZi5hc3NlcnRfKG5vdCBtc2cuaXNfbXVsdGlwYXJ0KCkpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X3BheWxvYWQoKSA9PSBOb25lKQorCisgICAgZGVmIHRlc3RfaW5pdGlhbGl6ZV9pbmNvcnJlY3RseShzZWxmKToKKyAgICAgICAgIyBJbml0aWFsaXplIHdpdGggaW52YWxpZCBhcmd1bWVudAorICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsIGxhbWJkYTogc2VsZi5fZmFjdG9yeShvYmplY3QoKSkpCisKKyAgICBkZWYgdGVzdF9iZWNvbWVfbWVzc2FnZShzZWxmKToKKyAgICAgICAgIyBUYWtlIG9uIHRoZSBzdGF0ZSBvZiBhbm90aGVyIG1lc3NhZ2UKKyAgICAgICAgZU1NID0gZW1haWwubWVzc2FnZV9mcm9tX3N0cmluZyhfc2FtcGxlX21lc3NhZ2UpCisgICAgICAgIG1zZyA9IHNlbGYuX2ZhY3RvcnkoKQorICAgICAgICBtc2cuX2JlY29tZV9tZXNzYWdlKGVNTSkKKyAgICAgICAgc2VsZi5fY2hlY2tfc2FtcGxlKG1zZykKKworICAgIGRlZiB0ZXN0X2V4cGxhaW5fdG8oc2VsZik6CisgICAgICAgICMgQ29weSBzZWxmJ3MgZm9ybWF0LXNwZWNpZmljIGRhdGEgdG8gb3RoZXIgbWVzc2FnZSBmb3JtYXRzLgorICAgICAgICAjIFRoaXMgdGVzdCBpcyBzdXBlcmZpY2lhbDsgYmV0dGVyIG9uZXMgYXJlIGluIFRlc3RNZXNzYWdlQ29udmVyc2lvbi4KKyAgICAgICAgbXNnID0gc2VsZi5fZmFjdG9yeSgpCisgICAgICAgIGZvciBjbGFzc18gaW4gKG1haWxib3guTWVzc2FnZSwgbWFpbGJveC5NYWlsZGlyTWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgbWFpbGJveC5tYm94TWVzc2FnZSwgbWFpbGJveC5NSE1lc3NhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgIG1haWxib3guQmFieWxNZXNzYWdlLCBtYWlsYm94Lk1NREZNZXNzYWdlKToKKyAgICAgICAgICAgIG90aGVyX21zZyA9IGNsYXNzXygpCisgICAgICAgICAgICBtc2cuX2V4cGxhaW5fdG8ob3RoZXJfbXNnKQorICAgICAgICBvdGhlcl9tc2cgPSBlbWFpbC5NZXNzYWdlLk1lc3NhZ2UoKQorICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsIGxhbWJkYTogbXNnLl9leHBsYWluX3RvKG90aGVyX21zZykpCisKKyAgICBkZWYgX3Bvc3RfaW5pdGlhbGl6ZV9ob29rKHNlbGYsIG1zZyk6CisgICAgICAgICMgT3ZlcnJpZGRlbiBieSBzdWJjbGFzc2VzIHRvIGNoZWNrIGV4dHJhIHRoaW5ncyBhZnRlciBpbml0aWFsaXphdGlvbgorICAgICAgICBwYXNzCisKKworY2xhc3MgVGVzdE1haWxkaXJNZXNzYWdlKFRlc3RNZXNzYWdlKToKKworICAgIF9mYWN0b3J5ID0gbWFpbGJveC5NYWlsZGlyTWVzc2FnZQorCisgICAgZGVmIF9wb3N0X2luaXRpYWxpemVfaG9vayhzZWxmLCBtc2cpOgorICAgICAgICBzZWxmLmFzc2VydF8obXNnLl9zdWJkaXIgPT0gJ25ldycpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuX2luZm8gPT0gJycpCisKKyAgICBkZWYgdGVzdF9zdWJkaXIoc2VsZik6CisgICAgICAgICMgVXNlIGdldF9zdWJkaXIoKSBhbmQgc2V0X3N1YmRpcigpCisgICAgICAgIG1zZyA9IG1haWxib3guTWFpbGRpck1lc3NhZ2UoX3NhbXBsZV9tZXNzYWdlKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnLmdldF9zdWJkaXIoKSA9PSAnbmV3JykKKyAgICAgICAgbXNnLnNldF9zdWJkaXIoJ2N1cicpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X3N1YmRpcigpID09ICdjdXInKQorICAgICAgICBtc2cuc2V0X3N1YmRpcignbmV3JykKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1zZy5nZXRfc3ViZGlyKCkgPT0gJ25ldycpCisgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IsIGxhbWJkYTogbXNnLnNldF9zdWJkaXIoJ3RtcCcpKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnLmdldF9zdWJkaXIoKSA9PSAnbmV3JykKKyAgICAgICAgbXNnLnNldF9zdWJkaXIoJ25ldycpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X3N1YmRpcigpID09ICduZXcnKQorICAgICAgICBzZWxmLl9jaGVja19zYW1wbGUobXNnKQorCisgICAgZGVmIHRlc3RfZmxhZ3Moc2VsZik6CisgICAgICAgICMgVXNlIGdldF9mbGFncygpLCBzZXRfZmxhZ3MoKSwgYWRkX2ZsYWcoKSwgcmVtb3ZlX2ZsYWcoKQorICAgICAgICBtc2cgPSBtYWlsYm94Lk1haWxkaXJNZXNzYWdlKF9zYW1wbGVfbWVzc2FnZSkKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1zZy5nZXRfZmxhZ3MoKSA9PSAnJykKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1zZy5nZXRfc3ViZGlyKCkgPT0gJ25ldycpCisgICAgICAgIG1zZy5zZXRfZmxhZ3MoJ0YnKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnLmdldF9zdWJkaXIoKSA9PSAnbmV3JykKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1zZy5nZXRfZmxhZ3MoKSA9PSAnRicpCisgICAgICAgIG1zZy5zZXRfZmxhZ3MoJ1NEVFAnKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnLmdldF9mbGFncygpID09ICdEUFNUJykKKyAgICAgICAgbXNnLmFkZF9mbGFnKCdGVCcpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X2ZsYWdzKCkgPT0gJ0RGUFNUJykKKyAgICAgICAgbXNnLnJlbW92ZV9mbGFnKCdURFJQJykKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1zZy5nZXRfZmxhZ3MoKSA9PSAnRlMnKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnLmdldF9zdWJkaXIoKSA9PSAnbmV3JykKKyAgICAgICAgc2VsZi5fY2hlY2tfc2FtcGxlKG1zZykKKworICAgIGRlZiB0ZXN0X2RhdGUoc2VsZik6CisgICAgICAgICMgVXNlIGdldF9kYXRlKCkgYW5kIHNldF9kYXRlKCkKKyAgICAgICAgbXNnID0gbWFpbGJveC5NYWlsZGlyTWVzc2FnZShfc2FtcGxlX21lc3NhZ2UpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhhYnMobXNnLmdldF9kYXRlKCkgLSB0aW1lLnRpbWUoKSkgPCA2MCkKKyAgICAgICAgbXNnLnNldF9kYXRlKDAuMCkKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1zZy5nZXRfZGF0ZSgpID09IDAuMCkKKworICAgIGRlZiB0ZXN0X2luZm8oc2VsZik6CisgICAgICAgICMgVXNlIGdldF9pbmZvKCkgYW5kIHNldF9pbmZvKCkKKyAgICAgICAgbXNnID0gbWFpbGJveC5NYWlsZGlyTWVzc2FnZShfc2FtcGxlX21lc3NhZ2UpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X2luZm8oKSA9PSAnJykKKyAgICAgICAgbXNnLnNldF9pbmZvKCcxLGZvbz1iYXInKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnLmdldF9pbmZvKCkgPT0gJzEsZm9vPWJhcicpCisgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFR5cGVFcnJvciwgbGFtYmRhOiBtc2cuc2V0X2luZm8oTm9uZSkpCisgICAgICAgIHNlbGYuX2NoZWNrX3NhbXBsZShtc2cpCisKKyAgICBkZWYgdGVzdF9pbmZvX2FuZF9mbGFncyhzZWxmKToKKyAgICAgICAgIyBUZXN0IGludGVyYWN0aW9uIG9mIGluZm8gYW5kIGZsYWcgbWV0aG9kcworICAgICAgICBtc2cgPSBtYWlsYm94Lk1haWxkaXJNZXNzYWdlKF9zYW1wbGVfbWVzc2FnZSkKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1zZy5nZXRfaW5mbygpID09ICcnKQorICAgICAgICBtc2cuc2V0X2ZsYWdzKCdTRicpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X2ZsYWdzKCkgPT0gJ0ZTJykKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1zZy5nZXRfaW5mbygpID09ICcyLEZTJykKKyAgICAgICAgbXNnLnNldF9pbmZvKCcxLCcpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X2ZsYWdzKCkgPT0gJycpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X2luZm8oKSA9PSAnMSwnKQorICAgICAgICBtc2cucmVtb3ZlX2ZsYWcoJ1JQVCcpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X2ZsYWdzKCkgPT0gJycpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X2luZm8oKSA9PSAnMSwnKQorICAgICAgICBtc2cuYWRkX2ZsYWcoJ0QnKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnLmdldF9mbGFncygpID09ICdEJykKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1zZy5nZXRfaW5mbygpID09ICcyLEQnKQorICAgICAgICBzZWxmLl9jaGVja19zYW1wbGUobXNnKQorCisKK2NsYXNzIF9UZXN0TWJveE1NREZNZXNzYWdlKFRlc3RNZXNzYWdlKToKKworICAgIF9mYWN0b3J5ID0gbWFpbGJveC5fbWJveE1NREZNZXNzYWdlCisKKyAgICBkZWYgX3Bvc3RfaW5pdGlhbGl6ZV9ob29rKHNlbGYsIG1zZyk6CisgICAgICAgIHNlbGYuX2NoZWNrX2Zyb20obXNnKQorCisgICAgZGVmIHRlc3RfaW5pdGlhbGl6ZV93aXRoX3VuaXhmcm9tKHNlbGYpOgorICAgICAgICAjIEluaXRpYWxpemUgd2l0aCBhIG1lc3NhZ2UgdGhhdCBhbHJlYWR5IGhhcyBhIF91bml4ZnJvbSBhdHRyaWJ1dGUKKyAgICAgICAgbXNnID0gbWFpbGJveC5NZXNzYWdlKF9zYW1wbGVfbWVzc2FnZSkKKyAgICAgICAgbXNnLnNldF91bml4ZnJvbSgnRnJvbSBmb29AYmFyIGJsYWgnKQorICAgICAgICBtc2cgPSBtYWlsYm94Lm1ib3hNZXNzYWdlKG1zZykKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1zZy5nZXRfZnJvbSgpID09ICdmb29AYmFyIGJsYWgnLCBtc2cuZ2V0X2Zyb20oKSkKKworICAgIGRlZiB0ZXN0X2Zyb20oc2VsZik6CisgICAgICAgICMgR2V0IGFuZCBzZXQgIkZyb20gIiBsaW5lCisgICAgICAgIG1zZyA9IG1haWxib3gubWJveE1lc3NhZ2UoX3NhbXBsZV9tZXNzYWdlKQorICAgICAgICBzZWxmLl9jaGVja19mcm9tKG1zZykKKyAgICAgICAgbXNnLnNldF9mcm9tKCdmb28gYmFyJykKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1zZy5nZXRfZnJvbSgpID09ICdmb28gYmFyJykKKyAgICAgICAgbXNnLnNldF9mcm9tKCdmb29AYmFyJywgVHJ1ZSkKKyAgICAgICAgc2VsZi5fY2hlY2tfZnJvbShtc2csICdmb29AYmFyJykKKyAgICAgICAgbXNnLnNldF9mcm9tKCdibGFoQHRlbXAnLCB0aW1lLmxvY2FsdGltZSgpKQorICAgICAgICBzZWxmLl9jaGVja19mcm9tKG1zZywgJ2JsYWhAdGVtcCcpCisKKyAgICBkZWYgdGVzdF9mbGFncyhzZWxmKToKKyAgICAgICAgIyBVc2UgZ2V0X2ZsYWdzKCksIHNldF9mbGFncygpLCBhZGRfZmxhZygpLCByZW1vdmVfZmxhZygpCisgICAgICAgIG1zZyA9IG1haWxib3gubWJveE1lc3NhZ2UoX3NhbXBsZV9tZXNzYWdlKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnLmdldF9mbGFncygpID09ICcnKQorICAgICAgICBtc2cuc2V0X2ZsYWdzKCdGJykKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1zZy5nZXRfZmxhZ3MoKSA9PSAnRicpCisgICAgICAgIG1zZy5zZXRfZmxhZ3MoJ1hPRFInKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnLmdldF9mbGFncygpID09ICdST0RYJykKKyAgICAgICAgbXNnLmFkZF9mbGFnKCdGQScpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X2ZsYWdzKCkgPT0gJ1JPREZBWCcpCisgICAgICAgIG1zZy5yZW1vdmVfZmxhZygnRkRYQScpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X2ZsYWdzKCkgPT0gJ1JPJykKKyAgICAgICAgc2VsZi5fY2hlY2tfc2FtcGxlKG1zZykKKworICAgIGRlZiBfY2hlY2tfZnJvbShzZWxmLCBtc2csIHNlbmRlcj1Ob25lKToKKyAgICAgICAgIyBDaGVjayBjb250ZW50cyBvZiAiRnJvbSAiIGxpbmUKKyAgICAgICAgaWYgc2VuZGVyIGlzIE5vbmU6CisgICAgICAgICAgICBzZW5kZXIgPSAiTUFJTEVSLURBRU1PTiIKKyAgICAgICAgc2VsZi5hc3NlcnRfKHJlLm1hdGNoKHNlbmRlciArIHIiIFx3ezN9IFx3ezN9IFtcZCBdXGQgW1xkIF1cZDpcZHsyfToiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByIlxkezJ9IFxkezR9IiwgbXNnLmdldF9mcm9tKCkpIGlzIG5vdCBOb25lKQorCisKK2NsYXNzIFRlc3RNYm94TWVzc2FnZShfVGVzdE1ib3hNTURGTWVzc2FnZSk6CisKKyAgICBfZmFjdG9yeSA9IG1haWxib3gubWJveE1lc3NhZ2UKKworCitjbGFzcyBUZXN0TUhNZXNzYWdlKFRlc3RNZXNzYWdlKToKKworICAgIF9mYWN0b3J5ID0gbWFpbGJveC5NSE1lc3NhZ2UKKworICAgIGRlZiBfcG9zdF9pbml0aWFsaXplX2hvb2soc2VsZiwgbXNnKToKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1zZy5fc2VxdWVuY2VzID09IFtdKQorCisgICAgZGVmIHRlc3Rfc2VxdWVuY2VzKHNlbGYpOgorICAgICAgICAjIEdldCwgc2V0LCBqb2luLCBhbmQgbGVhdmUgc2VxdWVuY2VzCisgICAgICAgIG1zZyA9IG1haWxib3guTUhNZXNzYWdlKF9zYW1wbGVfbWVzc2FnZSkKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1zZy5nZXRfc2VxdWVuY2VzKCkgPT0gW10pCisgICAgICAgIG1zZy5zZXRfc2VxdWVuY2VzKFsnZm9vYmFyJ10pCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X3NlcXVlbmNlcygpID09IFsnZm9vYmFyJ10pCisgICAgICAgIG1zZy5zZXRfc2VxdWVuY2VzKFtdKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnLmdldF9zZXF1ZW5jZXMoKSA9PSBbXSkKKyAgICAgICAgbXNnLmFkZF9zZXF1ZW5jZSgndW5zZWVuJykKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1zZy5nZXRfc2VxdWVuY2VzKCkgPT0gWyd1bnNlZW4nXSkKKyAgICAgICAgbXNnLmFkZF9zZXF1ZW5jZSgnZmxhZ2dlZCcpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X3NlcXVlbmNlcygpID09IFsndW5zZWVuJywgJ2ZsYWdnZWQnXSkKKyAgICAgICAgbXNnLmFkZF9zZXF1ZW5jZSgnZmxhZ2dlZCcpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X3NlcXVlbmNlcygpID09IFsndW5zZWVuJywgJ2ZsYWdnZWQnXSkKKyAgICAgICAgbXNnLnJlbW92ZV9zZXF1ZW5jZSgndW5zZWVuJykKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1zZy5nZXRfc2VxdWVuY2VzKCkgPT0gWydmbGFnZ2VkJ10pCisgICAgICAgIG1zZy5hZGRfc2VxdWVuY2UoJ2Zvb2JhcicpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X3NlcXVlbmNlcygpID09IFsnZmxhZ2dlZCcsICdmb29iYXInXSkKKyAgICAgICAgbXNnLnJlbW92ZV9zZXF1ZW5jZSgncmVwbGllZCcpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X3NlcXVlbmNlcygpID09IFsnZmxhZ2dlZCcsICdmb29iYXInXSkKKyAgICAgICAgbXNnLnNldF9zZXF1ZW5jZXMoWydmb29iYXInLCAncmVwbGllZCddKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnLmdldF9zZXF1ZW5jZXMoKSA9PSBbJ2Zvb2JhcicsICdyZXBsaWVkJ10pCisKKworY2xhc3MgVGVzdEJhYnlsTWVzc2FnZShUZXN0TWVzc2FnZSk6CisKKyAgICBfZmFjdG9yeSA9IG1haWxib3guQmFieWxNZXNzYWdlCisKKyAgICBkZWYgX3Bvc3RfaW5pdGlhbGl6ZV9ob29rKHNlbGYsIG1zZyk6CisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuX2xhYmVscyA9PSBbXSkKKworICAgIGRlZiB0ZXN0X2xhYmVscyhzZWxmKToKKyAgICAgICAgIyBHZXQsIHNldCwgam9pbiwgYW5kIGxlYXZlIGxhYmVscworICAgICAgICBtc2cgPSBtYWlsYm94LkJhYnlsTWVzc2FnZShfc2FtcGxlX21lc3NhZ2UpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X2xhYmVscygpID09IFtdKQorICAgICAgICBtc2cuc2V0X2xhYmVscyhbJ2Zvb2JhciddKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnLmdldF9sYWJlbHMoKSA9PSBbJ2Zvb2JhciddKQorICAgICAgICBtc2cuc2V0X2xhYmVscyhbXSkKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1zZy5nZXRfbGFiZWxzKCkgPT0gW10pCisgICAgICAgIG1zZy5hZGRfbGFiZWwoJ2ZpbGVkJykKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1zZy5nZXRfbGFiZWxzKCkgPT0gWydmaWxlZCddKQorICAgICAgICBtc2cuYWRkX2xhYmVsKCdyZXNlbnQnKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnLmdldF9sYWJlbHMoKSA9PSBbJ2ZpbGVkJywgJ3Jlc2VudCddKQorICAgICAgICBtc2cuYWRkX2xhYmVsKCdyZXNlbnQnKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnLmdldF9sYWJlbHMoKSA9PSBbJ2ZpbGVkJywgJ3Jlc2VudCddKQorICAgICAgICBtc2cucmVtb3ZlX2xhYmVsKCdmaWxlZCcpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X2xhYmVscygpID09IFsncmVzZW50J10pCisgICAgICAgIG1zZy5hZGRfbGFiZWwoJ2Zvb2JhcicpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X2xhYmVscygpID09IFsncmVzZW50JywgJ2Zvb2JhciddKQorICAgICAgICBtc2cucmVtb3ZlX2xhYmVsKCd1bnNlZW4nKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnLmdldF9sYWJlbHMoKSA9PSBbJ3Jlc2VudCcsICdmb29iYXInXSkKKyAgICAgICAgbXNnLnNldF9sYWJlbHMoWydmb29iYXInLCAnYW5zd2VyZWQnXSkKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1zZy5nZXRfbGFiZWxzKCkgPT0gWydmb29iYXInLCAnYW5zd2VyZWQnXSkKKworICAgIGRlZiB0ZXN0X3Zpc2libGUoc2VsZik6CisgICAgICAgICMgR2V0LCBzZXQsIGFuZCB1cGRhdGUgdmlzaWJsZSBoZWFkZXJzCisgICAgICAgIG1zZyA9IG1haWxib3guQmFieWxNZXNzYWdlKF9zYW1wbGVfbWVzc2FnZSkKKyAgICAgICAgdmlzaWJsZSA9IG1zZy5nZXRfdmlzaWJsZSgpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyh2aXNpYmxlLmtleXMoKSA9PSBbXSkKKyAgICAgICAgc2VsZi5hc3NlcnRfKHZpc2libGUuZ2V0X3BheWxvYWQoKSBpcyBOb25lKQorICAgICAgICB2aXNpYmxlWydVc2VyLUFnZW50J10gPSAnRm9vQmFyIDEuMCcKKyAgICAgICAgdmlzaWJsZVsnWC1XaGF0ZXZlciddID0gJ0JsYWgnCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X3Zpc2libGUoKS5rZXlzKCkgPT0gW10pCisgICAgICAgIG1zZy5zZXRfdmlzaWJsZSh2aXNpYmxlKQorICAgICAgICB2aXNpYmxlID0gbXNnLmdldF92aXNpYmxlKCkKKyAgICAgICAgc2VsZi5hc3NlcnRfKHZpc2libGUua2V5cygpID09IFsnVXNlci1BZ2VudCcsICdYLVdoYXRldmVyJ10pCisgICAgICAgIHNlbGYuYXNzZXJ0Xyh2aXNpYmxlWydVc2VyLUFnZW50J10gPT0gJ0Zvb0JhciAxLjAnKQorICAgICAgICBzZWxmLmFzc2VydF8odmlzaWJsZVsnWC1XaGF0ZXZlciddID09ICdCbGFoJykKKyAgICAgICAgc2VsZi5hc3NlcnRfKHZpc2libGUuZ2V0X3BheWxvYWQoKSBpcyBOb25lKQorICAgICAgICBtc2cudXBkYXRlX3Zpc2libGUoKQorICAgICAgICBzZWxmLmFzc2VydF8odmlzaWJsZS5rZXlzKCkgPT0gWydVc2VyLUFnZW50JywgJ1gtV2hhdGV2ZXInXSkKKyAgICAgICAgc2VsZi5hc3NlcnRfKHZpc2libGUuZ2V0X3BheWxvYWQoKSBpcyBOb25lKQorICAgICAgICB2aXNpYmxlID0gbXNnLmdldF92aXNpYmxlKCkKKyAgICAgICAgc2VsZi5hc3NlcnRfKHZpc2libGUua2V5cygpID09IFsnVXNlci1BZ2VudCcsICdEYXRlJywgJ0Zyb20nLCAnVG8nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdTdWJqZWN0J10pCisgICAgICAgIGZvciBoZWFkZXIgaW4gKCdVc2VyLUFnZW50JywgJ0RhdGUnLCAnRnJvbScsICdUbycsICdTdWJqZWN0Jyk6CisgICAgICAgICAgICBzZWxmLmFzc2VydF8odmlzaWJsZVtoZWFkZXJdID09IG1zZ1toZWFkZXJdKQorCisKK2NsYXNzIFRlc3RNTURGTWVzc2FnZShfVGVzdE1ib3hNTURGTWVzc2FnZSk6CisKKyAgICBfZmFjdG9yeSA9IG1haWxib3guTU1ERk1lc3NhZ2UKKworCitjbGFzcyBUZXN0TWVzc2FnZUNvbnZlcnNpb24oVGVzdEJhc2UpOgorCisgICAgZGVmIHRlc3RfcGxhaW5fdG9feChzZWxmKToKKyAgICAgICAgIyBDb252ZXJ0IE1lc3NhZ2UgdG8gYWxsIGZvcm1hdHMKKyAgICAgICAgZm9yIGNsYXNzXyBpbiAobWFpbGJveC5NZXNzYWdlLCBtYWlsYm94Lk1haWxkaXJNZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICBtYWlsYm94Lm1ib3hNZXNzYWdlLCBtYWlsYm94Lk1ITWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgbWFpbGJveC5CYWJ5bE1lc3NhZ2UsIG1haWxib3guTU1ERk1lc3NhZ2UpOgorICAgICAgICAgICAgbXNnX3BsYWluID0gbWFpbGJveC5NZXNzYWdlKF9zYW1wbGVfbWVzc2FnZSkKKyAgICAgICAgICAgIG1zZyA9IGNsYXNzXyhtc2dfcGxhaW4pCisgICAgICAgICAgICBzZWxmLl9jaGVja19zYW1wbGUobXNnKQorCisgICAgZGVmIHRlc3RfeF90b19wbGFpbihzZWxmKToKKyAgICAgICAgIyBDb252ZXJ0IGFsbCBmb3JtYXRzIHRvIE1lc3NhZ2UKKyAgICAgICAgZm9yIGNsYXNzXyBpbiAobWFpbGJveC5NZXNzYWdlLCBtYWlsYm94Lk1haWxkaXJNZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICBtYWlsYm94Lm1ib3hNZXNzYWdlLCBtYWlsYm94Lk1ITWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgbWFpbGJveC5CYWJ5bE1lc3NhZ2UsIG1haWxib3guTU1ERk1lc3NhZ2UpOgorICAgICAgICAgICAgbXNnID0gY2xhc3NfKF9zYW1wbGVfbWVzc2FnZSkKKyAgICAgICAgICAgIG1zZ19wbGFpbiA9IG1haWxib3guTWVzc2FnZShtc2cpCisgICAgICAgICAgICBzZWxmLl9jaGVja19zYW1wbGUobXNnX3BsYWluKQorCisgICAgZGVmIHRlc3RfeF90b19pbnZhbGlkKHNlbGYpOgorICAgICAgICAjIENvbnZlcnQgYWxsIGZvcm1hdHMgdG8gYW4gaW52YWxpZCBmb3JtYXQKKyAgICAgICAgZm9yIGNsYXNzXyBpbiAobWFpbGJveC5NZXNzYWdlLCBtYWlsYm94Lk1haWxkaXJNZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICBtYWlsYm94Lm1ib3hNZXNzYWdlLCBtYWlsYm94Lk1ITWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgbWFpbGJveC5CYWJ5bE1lc3NhZ2UsIG1haWxib3guTU1ERk1lc3NhZ2UpOgorICAgICAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yLCBsYW1iZGE6IGNsYXNzXyhGYWxzZSkpCisKKyAgICBkZWYgdGVzdF9tYWlsZGlyX3RvX21haWxkaXIoc2VsZik6CisgICAgICAgICMgQ29udmVydCBNYWlsZGlyTWVzc2FnZSB0byBNYWlsZGlyTWVzc2FnZQorICAgICAgICBtc2dfbWFpbGRpciA9IG1haWxib3guTWFpbGRpck1lc3NhZ2UoX3NhbXBsZV9tZXNzYWdlKQorICAgICAgICBtc2dfbWFpbGRpci5zZXRfZmxhZ3MoJ0RGUFJTVCcpCisgICAgICAgIG1zZ19tYWlsZGlyLnNldF9zdWJkaXIoJ2N1cicpCisgICAgICAgIGRhdGUgPSBtc2dfbWFpbGRpci5nZXRfZGF0ZSgpCisgICAgICAgIG1zZyA9IG1haWxib3guTWFpbGRpck1lc3NhZ2UobXNnX21haWxkaXIpCisgICAgICAgIHNlbGYuX2NoZWNrX3NhbXBsZShtc2cpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X2ZsYWdzKCkgPT0gJ0RGUFJTVCcpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X3N1YmRpcigpID09ICdjdXInKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnLmdldF9kYXRlKCkgPT0gZGF0ZSkKKworICAgIGRlZiB0ZXN0X21haWxkaXJfdG9fbWJveG1tZGYoc2VsZik6CisgICAgICAgICMgQ29udmVydCBNYWlsZGlyTWVzc2FnZSB0byBtYm94bWVzc2FnZSBhbmQgTU1ERk1lc3NhZ2UKKyAgICAgICAgcGFpcnMgPSAoKCdEJywgJycpLCAoJ0YnLCAnRicpLCAoJ1AnLCAnJyksICgnUicsICdBJyksICgnUycsICdSJyksCisgICAgICAgICAgICAgICAgICgnVCcsICdEJyksICgnREZQUlNUJywgJ1JERkEnKSkKKyAgICAgICAgZm9yIGNsYXNzXyBpbiAobWFpbGJveC5tYm94TWVzc2FnZSwgbWFpbGJveC5NTURGTWVzc2FnZSk6CisgICAgICAgICAgICBtc2dfbWFpbGRpciA9IG1haWxib3guTWFpbGRpck1lc3NhZ2UoX3NhbXBsZV9tZXNzYWdlKQorICAgICAgICAgICAgbXNnX21haWxkaXIuc2V0X2RhdGUoMC4wKQorICAgICAgICAgICAgZm9yIHNldHRpbmcsIHJlc3VsdCBpbiBwYWlyczoKKyAgICAgICAgICAgICAgICBtc2dfbWFpbGRpci5zZXRfZmxhZ3Moc2V0dGluZykKKyAgICAgICAgICAgICAgICBtc2cgPSBjbGFzc18obXNnX21haWxkaXIpCisgICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRfKG1zZy5nZXRfZmxhZ3MoKSA9PSByZXN1bHQpCisgICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRfKG1zZy5nZXRfZnJvbSgpID09ICdNQUlMRVItREFFTU9OICVzJyAlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWUuYXNjdGltZSh0aW1lLmdtdGltZSgwLjApKSkKKyAgICAgICAgICAgIG1zZ19tYWlsZGlyLnNldF9zdWJkaXIoJ2N1cicpCisgICAgICAgICAgICBzZWxmLmFzc2VydF8oY2xhc3NfKG1zZ19tYWlsZGlyKS5nZXRfZmxhZ3MoKSA9PSAnUk9ERkEnKQorCisgICAgZGVmIHRlc3RfbWFpbGRpcl90b19taChzZWxmKToKKyAgICAgICAgIyBDb252ZXJ0IE1haWxkaXJNZXNzYWdlIHRvIE1ITWVzc2FnZQorICAgICAgICBtc2dfbWFpbGRpciA9IG1haWxib3guTWFpbGRpck1lc3NhZ2UoX3NhbXBsZV9tZXNzYWdlKQorICAgICAgICBwYWlycyA9ICgoJ0QnLCBbJ3Vuc2VlbiddKSwgKCdGJywgWyd1bnNlZW4nLCAnZmxhZ2dlZCddKSwKKyAgICAgICAgICAgICAgICAgKCdQJywgWyd1bnNlZW4nXSksICgnUicsIFsndW5zZWVuJywgJ3JlcGxpZWQnXSksICgnUycsIFtdKSwKKyAgICAgICAgICAgICAgICAgKCdUJywgWyd1bnNlZW4nXSksICgnREZQUlNUJywgWydyZXBsaWVkJywgJ2ZsYWdnZWQnXSkpCisgICAgICAgIGZvciBzZXR0aW5nLCByZXN1bHQgaW4gcGFpcnM6CisgICAgICAgICAgICBtc2dfbWFpbGRpci5zZXRfZmxhZ3Moc2V0dGluZykKKyAgICAgICAgICAgIHNlbGYuYXNzZXJ0XyhtYWlsYm94Lk1ITWVzc2FnZShtc2dfbWFpbGRpcikuZ2V0X3NlcXVlbmNlcygpID09IFwKKyAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQpCisKKyAgICBkZWYgdGVzdF9tYWlsZGlyX3RvX2JhYnlsKHNlbGYpOgorICAgICAgICAjIENvbnZlcnQgTWFpbGRpck1lc3NhZ2UgdG8gQmFieWwKKyAgICAgICAgbXNnX21haWxkaXIgPSBtYWlsYm94Lk1haWxkaXJNZXNzYWdlKF9zYW1wbGVfbWVzc2FnZSkKKyAgICAgICAgcGFpcnMgPSAoKCdEJywgWyd1bnNlZW4nXSksICgnRicsIFsndW5zZWVuJ10pLAorICAgICAgICAgICAgICAgICAoJ1AnLCBbJ3Vuc2VlbicsICdmb3J3YXJkZWQnXSksICgnUicsIFsndW5zZWVuJywgJ2Fuc3dlcmVkJ10pLAorICAgICAgICAgICAgICAgICAoJ1MnLCBbXSksICgnVCcsIFsndW5zZWVuJywgJ2RlbGV0ZWQnXSksCisgICAgICAgICAgICAgICAgICgnREZQUlNUJywgWydkZWxldGVkJywgJ2Fuc3dlcmVkJywgJ2ZvcndhcmRlZCddKSkKKyAgICAgICAgZm9yIHNldHRpbmcsIHJlc3VsdCBpbiBwYWlyczoKKyAgICAgICAgICAgIG1zZ19tYWlsZGlyLnNldF9mbGFncyhzZXR0aW5nKQorICAgICAgICAgICAgc2VsZi5hc3NlcnRfKG1haWxib3guQmFieWxNZXNzYWdlKG1zZ19tYWlsZGlyKS5nZXRfbGFiZWxzKCkgPT0gXAorICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCkKKworICAgIGRlZiB0ZXN0X21ib3htbWRmX3RvX21haWxkaXIoc2VsZik6CisgICAgICAgICMgQ29udmVydCBtYm94TWVzc2FnZSBhbmQgTU1ERk1lc3NhZ2UgdG8gTWFpbGRpck1lc3NhZ2UKKyAgICAgICAgZm9yIGNsYXNzXyBpbiAobWFpbGJveC5tYm94TWVzc2FnZSwgbWFpbGJveC5NTURGTWVzc2FnZSk6CisgICAgICAgICAgICBtc2dfbWJveE1NREYgPSBjbGFzc18oX3NhbXBsZV9tZXNzYWdlKQorICAgICAgICAgICAgbXNnX21ib3hNTURGLnNldF9mcm9tKCdmb29AYmFyJywgdGltZS5nbXRpbWUoMC4wKSkKKyAgICAgICAgICAgIHBhaXJzID0gKCgnUicsICdTJyksICgnTycsICcnKSwgKCdEJywgJ1QnKSwgKCdGJywgJ0YnKSwgKCdBJywgJ1InKSwKKyAgICAgICAgICAgICAgICAgICAgICgnUk9ERkEnLCAnRlJTVCcpKQorICAgICAgICAgICAgZm9yIHNldHRpbmcsIHJlc3VsdCBpbiBwYWlyczoKKyAgICAgICAgICAgICAgICBtc2dfbWJveE1NREYuc2V0X2ZsYWdzKHNldHRpbmcpCisgICAgICAgICAgICAgICAgbXNnID0gbWFpbGJveC5NYWlsZGlyTWVzc2FnZShtc2dfbWJveE1NREYpCisgICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRfKG1zZy5nZXRfZmxhZ3MoKSA9PSByZXN1bHQpCisgICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRfKG1zZy5nZXRfZGF0ZSgpID09IDAuMCwgbXNnLmdldF9kYXRlKCkpCisgICAgICAgICAgICBtc2dfbWJveE1NREYuc2V0X2ZsYWdzKCdPJykKKyAgICAgICAgICAgIHNlbGYuYXNzZXJ0XyhtYWlsYm94Lk1haWxkaXJNZXNzYWdlKG1zZ19tYm94TU1ERikuZ2V0X3N1YmRpcigpID09IFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAnY3VyJykKKworICAgIGRlZiB0ZXN0X21ib3htbWRmX3RvX21ib3htbWRmKHNlbGYpOgorICAgICAgICAjIENvbnZlcnQgbWJveE1lc3NhZ2UgYW5kIE1NREZNZXNzYWdlIHRvIG1ib3hNZXNzYWdlIGFuZCBNTURGTWVzc2FnZQorICAgICAgICBmb3IgY2xhc3NfIGluIChtYWlsYm94Lm1ib3hNZXNzYWdlLCBtYWlsYm94Lk1NREZNZXNzYWdlKToKKyAgICAgICAgICAgIG1zZ19tYm94TU1ERiA9IGNsYXNzXyhfc2FtcGxlX21lc3NhZ2UpCisgICAgICAgICAgICBtc2dfbWJveE1NREYuc2V0X2ZsYWdzKCdST0RGQScpCisgICAgICAgICAgICBtc2dfbWJveE1NREYuc2V0X2Zyb20oJ2Zvb0BiYXInKQorICAgICAgICAgICAgZm9yIGNsYXNzMl8gaW4gKG1haWxib3gubWJveE1lc3NhZ2UsIG1haWxib3guTU1ERk1lc3NhZ2UpOgorICAgICAgICAgICAgICAgIG1zZzIgPSBjbGFzczJfKG1zZ19tYm94TU1ERikKKyAgICAgICAgICAgICAgICBzZWxmLmFzc2VydF8obXNnMi5nZXRfZmxhZ3MoKSA9PSAnUk9ERkEnKQorICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cyLmdldF9mcm9tKCkgPT0gJ2Zvb0BiYXInKQorCisgICAgZGVmIHRlc3RfbWJveG1tZGZfdG9fbWgoc2VsZik6CisgICAgICAgICMgQ29udmVydCBtYm94TWVzc2FnZSBhbmQgTU1ERk1lc3NhZ2UgdG8gTUhNZXNzYWdlCisgICAgICAgIGZvciBjbGFzc18gaW4gKG1haWxib3gubWJveE1lc3NhZ2UsIG1haWxib3guTU1ERk1lc3NhZ2UpOgorICAgICAgICAgICAgbXNnX21ib3hNTURGID0gY2xhc3NfKF9zYW1wbGVfbWVzc2FnZSkKKyAgICAgICAgICAgIHBhaXJzID0gKCgnUicsIFtdKSwgKCdPJywgWyd1bnNlZW4nXSksICgnRCcsIFsndW5zZWVuJ10pLAorICAgICAgICAgICAgICAgICAgICAgKCdGJywgWyd1bnNlZW4nLCAnZmxhZ2dlZCddKSwKKyAgICAgICAgICAgICAgICAgICAgICgnQScsIFsndW5zZWVuJywgJ3JlcGxpZWQnXSksCisgICAgICAgICAgICAgICAgICAgICAoJ1JPREZBJywgWydyZXBsaWVkJywgJ2ZsYWdnZWQnXSkpCisgICAgICAgICAgICBmb3Igc2V0dGluZywgcmVzdWx0IGluIHBhaXJzOgorICAgICAgICAgICAgICAgIG1zZ19tYm94TU1ERi5zZXRfZmxhZ3Moc2V0dGluZykKKyAgICAgICAgICAgICAgICBzZWxmLmFzc2VydF8obWFpbGJveC5NSE1lc3NhZ2UobXNnX21ib3hNTURGKS5nZXRfc2VxdWVuY2VzKCkgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PSByZXN1bHQpCisKKyAgICBkZWYgdGVzdF9tYm94bW1kZl90b19iYWJ5bChzZWxmKToKKyAgICAgICAgIyBDb252ZXJ0IG1ib3hNZXNzYWdlIGFuZCBNTURGTWVzc2FnZSB0byBCYWJ5bE1lc3NhZ2UKKyAgICAgICAgZm9yIGNsYXNzXyBpbiAobWFpbGJveC5tYm94TWVzc2FnZSwgbWFpbGJveC5NTURGTWVzc2FnZSk6CisgICAgICAgICAgICBtc2cgPSBjbGFzc18oX3NhbXBsZV9tZXNzYWdlKQorICAgICAgICAgICAgcGFpcnMgPSAoKCdSJywgW10pLCAoJ08nLCBbJ3Vuc2VlbiddKSwKKyAgICAgICAgICAgICAgICAgICAgICgnRCcsIFsndW5zZWVuJywgJ2RlbGV0ZWQnXSksICgnRicsIFsndW5zZWVuJ10pLAorICAgICAgICAgICAgICAgICAgICAgKCdBJywgWyd1bnNlZW4nLCAnYW5zd2VyZWQnXSksCisgICAgICAgICAgICAgICAgICAgICAoJ1JPREZBJywgWydkZWxldGVkJywgJ2Fuc3dlcmVkJ10pKQorICAgICAgICAgICAgZm9yIHNldHRpbmcsIHJlc3VsdCBpbiBwYWlyczoKKyAgICAgICAgICAgICAgICBtc2cuc2V0X2ZsYWdzKHNldHRpbmcpCisgICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRfKG1haWxib3guQmFieWxNZXNzYWdlKG1zZykuZ2V0X2xhYmVscygpID09IHJlc3VsdCkKKworICAgIGRlZiB0ZXN0X21oX3RvX21haWxkaXIoc2VsZik6CisgICAgICAgICMgQ29udmVydCBNSE1lc3NhZ2UgdG8gTWFpbGRpck1lc3NhZ2UKKyAgICAgICAgcGFpcnMgPSAoKCd1bnNlZW4nLCAnJyksICgncmVwbGllZCcsICdSUycpLCAoJ2ZsYWdnZWQnLCAnRlMnKSkKKyAgICAgICAgZm9yIHNldHRpbmcsIHJlc3VsdCBpbiBwYWlyczoKKyAgICAgICAgICAgIG1zZyA9IG1haWxib3guTUhNZXNzYWdlKF9zYW1wbGVfbWVzc2FnZSkKKyAgICAgICAgICAgIG1zZy5hZGRfc2VxdWVuY2Uoc2V0dGluZykKKyAgICAgICAgICAgIHNlbGYuYXNzZXJ0XyhtYWlsYm94Lk1haWxkaXJNZXNzYWdlKG1zZykuZ2V0X2ZsYWdzKCkgPT0gcmVzdWx0KQorICAgICAgICAgICAgc2VsZi5hc3NlcnRfKG1haWxib3guTWFpbGRpck1lc3NhZ2UobXNnKS5nZXRfc3ViZGlyKCkgPT0gJ2N1cicpCisgICAgICAgIG1zZyA9IG1haWxib3guTUhNZXNzYWdlKF9zYW1wbGVfbWVzc2FnZSkKKyAgICAgICAgbXNnLmFkZF9zZXF1ZW5jZSgndW5zZWVuJykKKyAgICAgICAgbXNnLmFkZF9zZXF1ZW5jZSgncmVwbGllZCcpCisgICAgICAgIG1zZy5hZGRfc2VxdWVuY2UoJ2ZsYWdnZWQnKQorICAgICAgICBzZWxmLmFzc2VydF8obWFpbGJveC5NYWlsZGlyTWVzc2FnZShtc2cpLmdldF9mbGFncygpID09ICdGUicpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhtYWlsYm94Lk1haWxkaXJNZXNzYWdlKG1zZykuZ2V0X3N1YmRpcigpID09ICdjdXInKQorCisgICAgZGVmIHRlc3RfbWhfdG9fbWJveG1tZGYoc2VsZik6CisgICAgICAgICMgQ29udmVydCBNSE1lc3NhZ2UgdG8gbWJveE1lc3NhZ2UgYW5kIE1NREZNZXNzYWdlCisgICAgICAgIHBhaXJzID0gKCgndW5zZWVuJywgJ08nKSwgKCdyZXBsaWVkJywgJ1JPQScpLCAoJ2ZsYWdnZWQnLCAnUk9GJykpCisgICAgICAgIGZvciBzZXR0aW5nLCByZXN1bHQgaW4gcGFpcnM6CisgICAgICAgICAgICBtc2cgPSBtYWlsYm94Lk1ITWVzc2FnZShfc2FtcGxlX21lc3NhZ2UpCisgICAgICAgICAgICBtc2cuYWRkX3NlcXVlbmNlKHNldHRpbmcpCisgICAgICAgICAgICBmb3IgY2xhc3NfIGluIChtYWlsYm94Lm1ib3hNZXNzYWdlLCBtYWlsYm94Lk1NREZNZXNzYWdlKToKKyAgICAgICAgICAgICAgICBzZWxmLmFzc2VydF8oY2xhc3NfKG1zZykuZ2V0X2ZsYWdzKCkgPT0gcmVzdWx0KQorICAgICAgICBtc2cgPSBtYWlsYm94Lk1ITWVzc2FnZShfc2FtcGxlX21lc3NhZ2UpCisgICAgICAgIG1zZy5hZGRfc2VxdWVuY2UoJ3Vuc2VlbicpCisgICAgICAgIG1zZy5hZGRfc2VxdWVuY2UoJ3JlcGxpZWQnKQorICAgICAgICBtc2cuYWRkX3NlcXVlbmNlKCdmbGFnZ2VkJykKKyAgICAgICAgZm9yIGNsYXNzXyBpbiAobWFpbGJveC5tYm94TWVzc2FnZSwgbWFpbGJveC5NTURGTWVzc2FnZSk6CisgICAgICAgICAgICBzZWxmLmFzc2VydF8oY2xhc3NfKG1zZykuZ2V0X2ZsYWdzKCkgPT0gJ09GQScpCisKKyAgICBkZWYgdGVzdF9taF90b19taChzZWxmKToKKyAgICAgICAgIyBDb252ZXJ0IE1ITWVzc2FnZSB0byBNSE1lc3NhZ2UKKyAgICAgICAgbXNnID0gbWFpbGJveC5NSE1lc3NhZ2UoX3NhbXBsZV9tZXNzYWdlKQorICAgICAgICBtc2cuYWRkX3NlcXVlbmNlKCd1bnNlZW4nKQorICAgICAgICBtc2cuYWRkX3NlcXVlbmNlKCdyZXBsaWVkJykKKyAgICAgICAgbXNnLmFkZF9zZXF1ZW5jZSgnZmxhZ2dlZCcpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhtYWlsYm94Lk1ITWVzc2FnZShtc2cpLmdldF9zZXF1ZW5jZXMoKSA9PSBcCisgICAgICAgICAgICAgICAgICAgICBbJ3Vuc2VlbicsICdyZXBsaWVkJywgJ2ZsYWdnZWQnXSkKKworICAgIGRlZiB0ZXN0X21oX3RvX2JhYnlsKHNlbGYpOgorICAgICAgICAjIENvbnZlcnQgTUhNZXNzYWdlIHRvIEJhYnlsTWVzc2FnZQorICAgICAgICBwYWlycyA9ICgoJ3Vuc2VlbicsIFsndW5zZWVuJ10pLCAoJ3JlcGxpZWQnLCBbJ2Fuc3dlcmVkJ10pLAorICAgICAgICAgICAgICAgICAoJ2ZsYWdnZWQnLCBbXSkpCisgICAgICAgIGZvciBzZXR0aW5nLCByZXN1bHQgaW4gcGFpcnM6CisgICAgICAgICAgICBtc2cgPSBtYWlsYm94Lk1ITWVzc2FnZShfc2FtcGxlX21lc3NhZ2UpCisgICAgICAgICAgICBtc2cuYWRkX3NlcXVlbmNlKHNldHRpbmcpCisgICAgICAgICAgICBzZWxmLmFzc2VydF8obWFpbGJveC5CYWJ5bE1lc3NhZ2UobXNnKS5nZXRfbGFiZWxzKCkgPT0gcmVzdWx0KQorICAgICAgICBtc2cgPSBtYWlsYm94Lk1ITWVzc2FnZShfc2FtcGxlX21lc3NhZ2UpCisgICAgICAgIG1zZy5hZGRfc2VxdWVuY2UoJ3Vuc2VlbicpCisgICAgICAgIG1zZy5hZGRfc2VxdWVuY2UoJ3JlcGxpZWQnKQorICAgICAgICBtc2cuYWRkX3NlcXVlbmNlKCdmbGFnZ2VkJykKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1haWxib3guQmFieWxNZXNzYWdlKG1zZykuZ2V0X2xhYmVscygpID09IFwKKyAgICAgICAgICAgICAgICAgICAgIFsndW5zZWVuJywgJ2Fuc3dlcmVkJ10pCisKKyAgICBkZWYgdGVzdF9iYWJ5bF90b19tYWlsZGlyKHNlbGYpOgorICAgICAgICAjIENvbnZlcnQgQmFieWxNZXNzYWdlIHRvIE1haWxkaXJNZXNzYWdlCisgICAgICAgIHBhaXJzID0gKCgndW5zZWVuJywgJycpLCAoJ2RlbGV0ZWQnLCAnU1QnKSwgKCdmaWxlZCcsICdTJyksCisgICAgICAgICAgICAgICAgICgnYW5zd2VyZWQnLCAnUlMnKSwgKCdmb3J3YXJkZWQnLCAnUFMnKSwgKCdlZGl0ZWQnLCAnUycpLAorICAgICAgICAgICAgICAgICAoJ3Jlc2VudCcsICdQUycpKQorICAgICAgICBmb3Igc2V0dGluZywgcmVzdWx0IGluIHBhaXJzOgorICAgICAgICAgICAgbXNnID0gbWFpbGJveC5CYWJ5bE1lc3NhZ2UoX3NhbXBsZV9tZXNzYWdlKQorICAgICAgICAgICAgbXNnLmFkZF9sYWJlbChzZXR0aW5nKQorICAgICAgICAgICAgc2VsZi5hc3NlcnRfKG1haWxib3guTWFpbGRpck1lc3NhZ2UobXNnKS5nZXRfZmxhZ3MoKSA9PSByZXN1bHQpCisgICAgICAgICAgICBzZWxmLmFzc2VydF8obWFpbGJveC5NYWlsZGlyTWVzc2FnZShtc2cpLmdldF9zdWJkaXIoKSA9PSAnY3VyJykKKyAgICAgICAgbXNnID0gbWFpbGJveC5CYWJ5bE1lc3NhZ2UoX3NhbXBsZV9tZXNzYWdlKQorICAgICAgICBmb3IgbGFiZWwgaW4gKCd1bnNlZW4nLCAnZGVsZXRlZCcsICdmaWxlZCcsICdhbnN3ZXJlZCcsICdmb3J3YXJkZWQnLAorICAgICAgICAgICAgICAgICAgICAgICdlZGl0ZWQnLCAncmVzZW50Jyk6CisgICAgICAgICAgICBtc2cuYWRkX2xhYmVsKGxhYmVsKQorICAgICAgICBzZWxmLmFzc2VydF8obWFpbGJveC5NYWlsZGlyTWVzc2FnZShtc2cpLmdldF9mbGFncygpID09ICdQUlQnKQorICAgICAgICBzZWxmLmFzc2VydF8obWFpbGJveC5NYWlsZGlyTWVzc2FnZShtc2cpLmdldF9zdWJkaXIoKSA9PSAnY3VyJykKKworICAgIGRlZiB0ZXN0X2JhYnlsX3RvX21ib3htbWRmKHNlbGYpOgorICAgICAgICAjIENvbnZlcnQgQmFieWxNZXNzYWdlIHRvIG1ib3hNZXNzYWdlIGFuZCBNTURGTWVzc2FnZQorICAgICAgICBwYWlycyA9ICgoJ3Vuc2VlbicsICdPJyksICgnZGVsZXRlZCcsICdST0QnKSwgKCdmaWxlZCcsICdSTycpLAorICAgICAgICAgICAgICAgICAoJ2Fuc3dlcmVkJywgJ1JPQScpLCAoJ2ZvcndhcmRlZCcsICdSTycpLCAoJ2VkaXRlZCcsICdSTycpLAorICAgICAgICAgICAgICAgICAoJ3Jlc2VudCcsICdSTycpKQorICAgICAgICBmb3Igc2V0dGluZywgcmVzdWx0IGluIHBhaXJzOgorICAgICAgICAgICAgZm9yIGNsYXNzXyBpbiAobWFpbGJveC5tYm94TWVzc2FnZSwgbWFpbGJveC5NTURGTWVzc2FnZSk6CisgICAgICAgICAgICAgICAgbXNnID0gbWFpbGJveC5CYWJ5bE1lc3NhZ2UoX3NhbXBsZV9tZXNzYWdlKQorICAgICAgICAgICAgICAgIG1zZy5hZGRfbGFiZWwoc2V0dGluZykKKyAgICAgICAgICAgICAgICBzZWxmLmFzc2VydF8oY2xhc3NfKG1zZykuZ2V0X2ZsYWdzKCkgPT0gcmVzdWx0KQorICAgICAgICBtc2cgPSBtYWlsYm94LkJhYnlsTWVzc2FnZShfc2FtcGxlX21lc3NhZ2UpCisgICAgICAgIGZvciBsYWJlbCBpbiAoJ3Vuc2VlbicsICdkZWxldGVkJywgJ2ZpbGVkJywgJ2Fuc3dlcmVkJywgJ2ZvcndhcmRlZCcsCisgICAgICAgICAgICAgICAgICAgICAgJ2VkaXRlZCcsICdyZXNlbnQnKToKKyAgICAgICAgICAgIG1zZy5hZGRfbGFiZWwobGFiZWwpCisgICAgICAgIGZvciBjbGFzc18gaW4gKG1haWxib3gubWJveE1lc3NhZ2UsIG1haWxib3guTU1ERk1lc3NhZ2UpOgorICAgICAgICAgICAgc2VsZi5hc3NlcnRfKGNsYXNzXyhtc2cpLmdldF9mbGFncygpID09ICdPREEnKQorCisgICAgZGVmIHRlc3RfYmFieWxfdG9fbWgoc2VsZik6CisgICAgICAgICMgQ29udmVydCBCYWJ5bE1lc3NhZ2UgdG8gTUhNZXNzYWdlCisgICAgICAgIHBhaXJzID0gKCgndW5zZWVuJywgWyd1bnNlZW4nXSksICgnZGVsZXRlZCcsIFtdKSwgKCdmaWxlZCcsIFtdKSwKKyAgICAgICAgICAgICAgICAgKCdhbnN3ZXJlZCcsIFsncmVwbGllZCddKSwgKCdmb3J3YXJkZWQnLCBbXSksICgnZWRpdGVkJywgW10pLAorICAgICAgICAgICAgICAgICAoJ3Jlc2VudCcsIFtdKSkKKyAgICAgICAgZm9yIHNldHRpbmcsIHJlc3VsdCBpbiBwYWlyczoKKyAgICAgICAgICAgIG1zZyA9IG1haWxib3guQmFieWxNZXNzYWdlKF9zYW1wbGVfbWVzc2FnZSkKKyAgICAgICAgICAgIG1zZy5hZGRfbGFiZWwoc2V0dGluZykKKyAgICAgICAgICAgIHNlbGYuYXNzZXJ0XyhtYWlsYm94Lk1ITWVzc2FnZShtc2cpLmdldF9zZXF1ZW5jZXMoKSA9PSByZXN1bHQpCisgICAgICAgIG1zZyA9IG1haWxib3guQmFieWxNZXNzYWdlKF9zYW1wbGVfbWVzc2FnZSkKKyAgICAgICAgZm9yIGxhYmVsIGluICgndW5zZWVuJywgJ2RlbGV0ZWQnLCAnZmlsZWQnLCAnYW5zd2VyZWQnLCAnZm9yd2FyZGVkJywKKyAgICAgICAgICAgICAgICAgICAgICAnZWRpdGVkJywgJ3Jlc2VudCcpOgorICAgICAgICAgICAgbXNnLmFkZF9sYWJlbChsYWJlbCkKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1haWxib3guTUhNZXNzYWdlKG1zZykuZ2V0X3NlcXVlbmNlcygpID09IFwKKyAgICAgICAgICAgICAgICAgICAgIFsndW5zZWVuJywgJ3JlcGxpZWQnXSkKKworICAgIGRlZiB0ZXN0X2JhYnlsX3RvX2JhYnlsKHNlbGYpOgorICAgICAgICAjIENvbnZlcnQgQmFieWxNZXNzYWdlIHRvIEJhYnlsTWVzc2FnZQorICAgICAgICBtc2cgPSBtYWlsYm94LkJhYnlsTWVzc2FnZShfc2FtcGxlX21lc3NhZ2UpCisgICAgICAgIG1zZy51cGRhdGVfdmlzaWJsZSgpCisgICAgICAgIGZvciBsYWJlbCBpbiAoJ3Vuc2VlbicsICdkZWxldGVkJywgJ2ZpbGVkJywgJ2Fuc3dlcmVkJywgJ2ZvcndhcmRlZCcsCisgICAgICAgICAgICAgICAgICAgICAgJ2VkaXRlZCcsICdyZXNlbnQnKToKKyAgICAgICAgICAgIG1zZy5hZGRfbGFiZWwobGFiZWwpICAgICAgIAorICAgICAgICBtc2cyID0gbWFpbGJveC5CYWJ5bE1lc3NhZ2UobXNnKQorICAgICAgICBzZWxmLmFzc2VydF8obXNnMi5nZXRfbGFiZWxzKCkgPT0gWyd1bnNlZW4nLCAnZGVsZXRlZCcsICdmaWxlZCcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2Fuc3dlcmVkJywgJ2ZvcndhcmRlZCcsICdlZGl0ZWQnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdyZXNlbnQnXSkKKyAgICAgICAgc2VsZi5hc3NlcnRfKG1zZy5nZXRfdmlzaWJsZSgpLmtleXMoKSA9PSBtc2cyLmdldF92aXNpYmxlKCkua2V5cygpKQorICAgICAgICBmb3Iga2V5IGluIG1zZy5nZXRfdmlzaWJsZSgpLmtleXMoKToKKyAgICAgICAgICAgIHNlbGYuYXNzZXJ0Xyhtc2cuZ2V0X3Zpc2libGUoKVtrZXldID09IG1zZzIuZ2V0X3Zpc2libGUoKVtrZXldKQorCisKK2NsYXNzIFRlc3RQcm94eUZpbGVCYXNlKFRlc3RCYXNlKToKKworICAgIGRlZiBfdGVzdF9yZWFkKHNlbGYsIHByb3h5KToKKyAgICAgICAgIyBSZWFkIGJ5IGJ5dGUKKyAgICAgICAgcHJveHkuc2VlaygwKQorICAgICAgICBzZWxmLmFzc2VydF8ocHJveHkucmVhZCgpID09ICdiYXInKQorICAgICAgICBwcm94eS5zZWVrKDEpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhwcm94eS5yZWFkKCkgPT0gJ2FyJykKKyAgICAgICAgcHJveHkuc2VlaygwKQorICAgICAgICBzZWxmLmFzc2VydF8ocHJveHkucmVhZCgyKSA9PSAnYmEnKQorICAgICAgICBwcm94eS5zZWVrKDEpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhwcm94eS5yZWFkKC0xKSA9PSAnYXInKQorICAgICAgICBwcm94eS5zZWVrKDIpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhwcm94eS5yZWFkKDEwMDApID09ICdyJykKKworICAgIGRlZiBfdGVzdF9yZWFkbGluZShzZWxmLCBwcm94eSk6CisgICAgICAgICMgUmVhZCBieSBsaW5lCisgICAgICAgIHByb3h5LnNlZWsoMCkKKyAgICAgICAgc2VsZi5hc3NlcnRfKHByb3h5LnJlYWRsaW5lKCkgPT0gJ2ZvbycgKyBvcy5saW5lc2VwKQorICAgICAgICBzZWxmLmFzc2VydF8ocHJveHkucmVhZGxpbmUoKSA9PSAnYmFyJyArIG9zLmxpbmVzZXApCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhwcm94eS5yZWFkbGluZSgpID09ICdmcmVkJyArIG9zLmxpbmVzZXApCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhwcm94eS5yZWFkbGluZSgpID09ICdib2InKQorICAgICAgICBwcm94eS5zZWVrKDIpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhwcm94eS5yZWFkbGluZSgpID09ICdvJyArIG9zLmxpbmVzZXApCisgICAgICAgIHByb3h5LnNlZWsoNiArIDIgKiBsZW4ob3MubGluZXNlcCkpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhwcm94eS5yZWFkbGluZSgpID09ICdmcmVkJyArIG9zLmxpbmVzZXApCisgICAgICAgIHByb3h5LnNlZWsoNiArIDIgKiBsZW4ob3MubGluZXNlcCkpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhwcm94eS5yZWFkbGluZSgyKSA9PSAnZnInKQorICAgICAgICBzZWxmLmFzc2VydF8ocHJveHkucmVhZGxpbmUoLTEwKSA9PSAnZWQnICsgb3MubGluZXNlcCkKKworICAgIGRlZiBfdGVzdF9yZWFkbGluZXMoc2VsZiwgcHJveHkpOgorICAgICAgICAjIFJlYWQgbXVsdGlwbGUgbGluZXMKKyAgICAgICAgcHJveHkuc2VlaygwKQorICAgICAgICBzZWxmLmFzc2VydF8ocHJveHkucmVhZGxpbmVzKCkgPT0gWydmb28nICsgb3MubGluZXNlcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYmFyJyArIG9zLmxpbmVzZXAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2ZyZWQnICsgb3MubGluZXNlcCwgJ2JvYiddKQorICAgICAgICBwcm94eS5zZWVrKDApCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhwcm94eS5yZWFkbGluZXMoMikgPT0gWydmb28nICsgb3MubGluZXNlcF0pCisgICAgICAgIHByb3h5LnNlZWsoMyArIGxlbihvcy5saW5lc2VwKSkKKyAgICAgICAgc2VsZi5hc3NlcnRfKHByb3h5LnJlYWRsaW5lcyg0ICsgbGVuKG9zLmxpbmVzZXApKSA9PQorICAgICAgICAgICAgICAgICAgICAgWydiYXInICsgb3MubGluZXNlcCwgJ2ZyZWQnICsgb3MubGluZXNlcF0pCisgICAgICAgIHByb3h5LnNlZWsoMykKKyAgICAgICAgc2VsZi5hc3NlcnRfKHByb3h5LnJlYWRsaW5lcygxMDAwKSA9PSBbb3MubGluZXNlcCwgJ2JhcicgKyBvcy5saW5lc2VwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZnJlZCcgKyBvcy5saW5lc2VwLCAnYm9iJ10pCisKKyAgICBkZWYgX3Rlc3RfaXRlcmF0aW9uKHNlbGYsIHByb3h5KToKKyAgICAgICAgIyBJdGVyYXRlIGJ5IGxpbmUKKyAgICAgICAgcHJveHkuc2VlaygwKQorICAgICAgICBpdGVyYXRvciA9IGl0ZXIocHJveHkpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhpdGVyYXRvci5uZXh0KCkgPT0gJ2ZvbycgKyBvcy5saW5lc2VwKQorICAgICAgICBzZWxmLmFzc2VydF8oaXRlcmF0b3IubmV4dCgpID09ICdiYXInICsgb3MubGluZXNlcCkKKyAgICAgICAgc2VsZi5hc3NlcnRfKGl0ZXJhdG9yLm5leHQoKSA9PSAnZnJlZCcgKyBvcy5saW5lc2VwKQorICAgICAgICBzZWxmLmFzc2VydF8oaXRlcmF0b3IubmV4dCgpID09ICdib2InKQorICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhTdG9wSXRlcmF0aW9uLCBsYW1iZGE6IGl0ZXJhdG9yLm5leHQoKSkKKworICAgIGRlZiBfdGVzdF9zZWVrX2FuZF90ZWxsKHNlbGYsIHByb3h5KToKKyAgICAgICAgIyBTZWVrIGFuZCB1c2UgdGVsbCB0byBjaGVjayBwb3NpdGlvbgorICAgICAgICBwcm94eS5zZWVrKDMpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhwcm94eS50ZWxsKCkgPT0gMykKKyAgICAgICAgc2VsZi5hc3NlcnRfKHByb3h5LnJlYWQobGVuKG9zLmxpbmVzZXApKSA9PSBvcy5saW5lc2VwKQorICAgICAgICBwcm94eS5zZWVrKDIsIDEpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhwcm94eS5yZWFkKDEgKyBsZW4ob3MubGluZXNlcCkpID09ICdyJyArIG9zLmxpbmVzZXApCisgICAgICAgIHByb3h5LnNlZWsoLTMgLSBsZW4ob3MubGluZXNlcCksIDIpCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhwcm94eS5yZWFkKDMpID09ICdiYXInKQorICAgICAgICBwcm94eS5zZWVrKDIsIDApCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhwcm94eS5yZWFkKCkgPT0gJ28nICsgb3MubGluZXNlcCArICdiYXInICsgb3MubGluZXNlcCkKKyAgICAgICAgcHJveHkuc2VlaygxMDApCisgICAgICAgIHNlbGYuYXNzZXJ0Xyhwcm94eS5yZWFkKCkgPT0gJycpCisKKyAgICBkZWYgX3Rlc3RfY2xvc2Uoc2VsZiwgcHJveHkpOgorICAgICAgICAjIENsb3NlIGEgZmlsZQorICAgICAgICBwcm94eS5jbG9zZSgpCisgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKEF0dHJpYnV0ZUVycm9yLCBsYW1iZGE6IHByb3h5LmNsb3NlKCkpCisKKworY2xhc3MgVGVzdFByb3h5RmlsZShUZXN0UHJveHlGaWxlQmFzZSk6CisKKyAgICBkZWYgc2V0VXAoc2VsZik6CisgICAgICAgIHNlbGYuX3BhdGggPSB0ZXN0X3N1cHBvcnQuVEVTVEZOCisgICAgICAgIHNlbGYuX2ZpbGUgPSBmaWxlKHNlbGYuX3BhdGgsICd3YisnKQorCisgICAgZGVmIHRlYXJEb3duKHNlbGYpOgorICAgICAgICBzZWxmLl9maWxlLmNsb3NlKCkKKyAgICAgICAgc2VsZi5fZGVsZXRlX3JlY3Vyc2l2ZWx5KHNlbGYuX3BhdGgpCisKKyAgICBkZWYgdGVzdF9pbml0aWFsaXplKHNlbGYpOgorICAgICAgICAjIEluaXRpYWxpemUgYW5kIGNoZWNrIHBvc2l0aW9uCisgICAgICAgIHNlbGYuX2ZpbGUud3JpdGUoJ2ZvbycpCisgICAgICAgIHBvcyA9IHNlbGYuX2ZpbGUudGVsbCgpCisgICAgICAgIHByb3h5MCA9IG1haWxib3guX1Byb3h5RmlsZShzZWxmLl9maWxlKQorICAgICAgICBzZWxmLmFzc2VydF8ocHJveHkwLnRlbGwoKSA9PSBwb3MpCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZWxmLl9maWxlLnRlbGwoKSA9PSBwb3MpCisgICAgICAgIHByb3h5MSA9IG1haWxib3guX1Byb3h5RmlsZShzZWxmLl9maWxlLCAwKQorICAgICAgICBzZWxmLmFzc2VydF8ocHJveHkxLnRlbGwoKSA9PSAwKQorICAgICAgICBzZWxmLmFzc2VydF8oc2VsZi5fZmlsZS50ZWxsKCkgPT0gcG9zKQorCisgICAgZGVmIHRlc3RfcmVhZChzZWxmKToKKyAgICAgICAgc2VsZi5fZmlsZS53cml0ZSgnYmFyJykKKyAgICAgICAgc2VsZi5fdGVzdF9yZWFkKG1haWxib3guX1Byb3h5RmlsZShzZWxmLl9maWxlKSkKKworICAgIGRlZiB0ZXN0X3JlYWRsaW5lKHNlbGYpOgorICAgICAgICBzZWxmLl9maWxlLndyaXRlKCdmb28lc2JhciVzZnJlZCVzYm9iJyAlIChvcy5saW5lc2VwLCBvcy5saW5lc2VwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcy5saW5lc2VwKSkKKyAgICAgICAgc2VsZi5fdGVzdF9yZWFkbGluZShtYWlsYm94Ll9Qcm94eUZpbGUoc2VsZi5fZmlsZSkpCisKKyAgICBkZWYgdGVzdF9yZWFkbGluZXMoc2VsZik6CisgICAgICAgIHNlbGYuX2ZpbGUud3JpdGUoJ2ZvbyVzYmFyJXNmcmVkJXNib2InICUgKG9zLmxpbmVzZXAsIG9zLmxpbmVzZXAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9zLmxpbmVzZXApKQorICAgICAgICBzZWxmLl90ZXN0X3JlYWRsaW5lcyhtYWlsYm94Ll9Qcm94eUZpbGUoc2VsZi5fZmlsZSkpCisKKyAgICBkZWYgdGVzdF9pdGVyYXRpb24oc2VsZik6CisgICAgICAgIHNlbGYuX2ZpbGUud3JpdGUoJ2ZvbyVzYmFyJXNmcmVkJXNib2InICUgKG9zLmxpbmVzZXAsIG9zLmxpbmVzZXAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9zLmxpbmVzZXApKQorICAgICAgICBzZWxmLl90ZXN0X2l0ZXJhdGlvbihtYWlsYm94Ll9Qcm94eUZpbGUoc2VsZi5fZmlsZSkpCisKKyAgICBkZWYgdGVzdF9zZWVrX2FuZF90ZWxsKHNlbGYpOgorICAgICAgICBzZWxmLl9maWxlLndyaXRlKCdmb28lc2JhciVzJyAlIChvcy5saW5lc2VwLCBvcy5saW5lc2VwKSkKKyAgICAgICAgc2VsZi5fdGVzdF9zZWVrX2FuZF90ZWxsKG1haWxib3guX1Byb3h5RmlsZShzZWxmLl9maWxlKSkKKworICAgIGRlZiB0ZXN0X2Nsb3NlKHNlbGYpOgorICAgICAgICBzZWxmLl9maWxlLndyaXRlKCdmb28lc2JhciVzJyAlIChvcy5saW5lc2VwLCBvcy5saW5lc2VwKSkKKyAgICAgICAgc2VsZi5fdGVzdF9jbG9zZShtYWlsYm94Ll9Qcm94eUZpbGUoc2VsZi5fZmlsZSkpCisKKworY2xhc3MgVGVzdFBhcnRpYWxGaWxlKFRlc3RQcm94eUZpbGVCYXNlKToKKworICAgIGRlZiBzZXRVcChzZWxmKToKKyAgICAgICAgc2VsZi5fcGF0aCA9IHRlc3Rfc3VwcG9ydC5URVNURk4KKyAgICAgICAgc2VsZi5fZmlsZSA9IGZpbGUoc2VsZi5fcGF0aCwgJ3diKycpCisKKyAgICBkZWYgdGVhckRvd24oc2VsZik6CisgICAgICAgIHNlbGYuX2ZpbGUuY2xvc2UoKQorICAgICAgICBzZWxmLl9kZWxldGVfcmVjdXJzaXZlbHkoc2VsZi5fcGF0aCkKKworICAgIGRlZiB0ZXN0X2luaXRpYWxpemUoc2VsZik6CisgICAgICAgICMgSW5pdGlhbGl6ZSBhbmQgY2hlY2sgcG9zaXRpb24KKyAgICAgICAgc2VsZi5fZmlsZS53cml0ZSgnZm9vJyArIG9zLmxpbmVzZXAgKyAnYmFyJykKKyAgICAgICAgcG9zID0gc2VsZi5fZmlsZS50ZWxsKCkKKyAgICAgICAgcHJveHkgPSBtYWlsYm94Ll9QYXJ0aWFsRmlsZShzZWxmLl9maWxlLCAyLCA1KQorICAgICAgICBzZWxmLmFzc2VydF8ocHJveHkudGVsbCgpID09IDApCisgICAgICAgIHNlbGYuYXNzZXJ0XyhzZWxmLl9maWxlLnRlbGwoKSA9PSBwb3MpCisKKyAgICBkZWYgdGVzdF9yZWFkKHNlbGYpOgorICAgICAgICBzZWxmLl9maWxlLndyaXRlKCcqKipiYXIqKionKQorICAgICAgICBzZWxmLl90ZXN0X3JlYWQobWFpbGJveC5fUGFydGlhbEZpbGUoc2VsZi5fZmlsZSwgMywgNikpCisKKyAgICBkZWYgdGVzdF9yZWFkbGluZShzZWxmKToKKyAgICAgICAgc2VsZi5fZmlsZS53cml0ZSgnISEhISFmb28lc2JhciVzZnJlZCVzYm9iISEhISEnICUKKyAgICAgICAgICAgICAgICAgICAgICAgICAob3MubGluZXNlcCwgb3MubGluZXNlcCwgb3MubGluZXNlcCkpCisgICAgICAgIHNlbGYuX3Rlc3RfcmVhZGxpbmUobWFpbGJveC5fUGFydGlhbEZpbGUoc2VsZi5fZmlsZSwgNSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxOCArIDMgKiBsZW4ob3MubGluZXNlcCkpKQorCisgICAgZGVmIHRlc3RfcmVhZGxpbmVzKHNlbGYpOgorICAgICAgICBzZWxmLl9maWxlLndyaXRlKCdmb28lc2JhciVzZnJlZCVzYm9iPz8/Pz8nICUKKyAgICAgICAgICAgICAgICAgICAgICAgICAob3MubGluZXNlcCwgb3MubGluZXNlcCwgb3MubGluZXNlcCkpCisgICAgICAgIHNlbGYuX3Rlc3RfcmVhZGxpbmVzKG1haWxib3guX1BhcnRpYWxGaWxlKHNlbGYuX2ZpbGUsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEzICsgMyAqIGxlbihvcy5saW5lc2VwKSkpCisKKyAgICBkZWYgdGVzdF9pdGVyYXRpb24oc2VsZik6CisgICAgICAgIHNlbGYuX2ZpbGUud3JpdGUoJ19fX19mb28lc2JhciVzZnJlZCVzYm9iIyMjIycgJQorICAgICAgICAgICAgICAgICAgICAgICAgIChvcy5saW5lc2VwLCBvcy5saW5lc2VwLCBvcy5saW5lc2VwKSkKKyAgICAgICAgc2VsZi5fdGVzdF9pdGVyYXRpb24obWFpbGJveC5fUGFydGlhbEZpbGUoc2VsZi5fZmlsZSwgNCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMTcgKyAzICogbGVuKG9zLmxpbmVzZXApKSkKKworICAgIGRlZiB0ZXN0X3NlZWtfYW5kX3RlbGwoc2VsZik6CisgICAgICAgIHNlbGYuX2ZpbGUud3JpdGUoJygoKGZvbyVzYmFyJXMkJCQnICUgKG9zLmxpbmVzZXAsIG9zLmxpbmVzZXApKQorICAgICAgICBzZWxmLl90ZXN0X3NlZWtfYW5kX3RlbGwobWFpbGJveC5fUGFydGlhbEZpbGUoc2VsZi5fZmlsZSwgMywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDkgKyAyICogbGVuKG9zLmxpbmVzZXApKSkKKworICAgIGRlZiB0ZXN0X2Nsb3NlKHNlbGYpOgorICAgICAgICBzZWxmLl9maWxlLndyaXRlKCcmZm9vJXNiYXIlc14nICUgKG9zLmxpbmVzZXAsIG9zLmxpbmVzZXApKQorICAgICAgICBzZWxmLl90ZXN0X2Nsb3NlKG1haWxib3guX1BhcnRpYWxGaWxlKHNlbGYuX2ZpbGUsIDEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNiArIDMgKiBsZW4ob3MubGluZXNlcCkpKQorCisKKyMjIFN0YXJ0OiB0ZXN0cyBmcm9tIHRoZSBvcmlnaW5hbCBtb2R1bGUgKGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5KS4KKwogRlJPTV8gPSAiRnJvbSBzb21lLmJvZHlAZHVtbXkuZG9tYWluICBTYXQgSnVsIDI0IDEzOjQzOjM1IDIwMDRcbiIKIERVTU1ZX01FU1NBR0UgPSAiIiJcCiBGcm9tOiBzb21lLmJvZHlAZHVtbXkuZG9tYWluCkBAIC02NSwxNSArMTYyMiwxNSBAQAogICAgICAgICAjIFRlc3QgZm9yIHJlZ3Jlc3Npb24gb24gYnVnICMxMTc0OTA6CiAgICAgICAgICMgTWFrZSBzdXJlIHRoZSBib3hlcyBhdHRyaWJ1dGUgYWN0dWFsbHkgZ2V0cyBzZXQuCiAgICAgICAgIHNlbGYubWJveCA9IG1haWxib3guTWFpbGRpcih0ZXN0X3N1cHBvcnQuVEVTVEZOKQotICAgICAgICBzZWxmLmFzc2VydF8oaGFzYXR0cihzZWxmLm1ib3gsICJib3hlcyIpKQotICAgICAgICBzZWxmLmFzc2VydF8obGVuKHNlbGYubWJveC5ib3hlcykgPT0gMCkKKyAgICAgICAgI3NlbGYuYXNzZXJ0XyhoYXNhdHRyKHNlbGYubWJveCwgImJveGVzIikpCisgICAgICAgICNzZWxmLmFzc2VydF8obGVuKHNlbGYubWJveC5ib3hlcykgPT0gMCkKICAgICAgICAgc2VsZi5hc3NlcnRfKHNlbGYubWJveC5uZXh0KCkgaXMgTm9uZSkKICAgICAgICAgc2VsZi5hc3NlcnRfKHNlbGYubWJveC5uZXh0KCkgaXMgTm9uZSkKIAogICAgIGRlZiB0ZXN0X25vbmVtcHR5X21haWxkaXJfY3VyKHNlbGYpOgogICAgICAgICBzZWxmLmNyZWF0ZU1lc3NhZ2UoImN1ciIpCiAgICAgICAgIHNlbGYubWJveCA9IG1haWxib3guTWFpbGRpcih0ZXN0X3N1cHBvcnQuVEVTVEZOKQotICAgICAgICBzZWxmLmFzc2VydF8obGVuKHNlbGYubWJveC5ib3hlcykgPT0gMSkKKyAgICAgICAgI3NlbGYuYXNzZXJ0XyhsZW4oc2VsZi5tYm94LmJveGVzKSA9PSAxKQogICAgICAgICBzZWxmLmFzc2VydF8oc2VsZi5tYm94Lm5leHQoKSBpcyBub3QgTm9uZSkKICAgICAgICAgc2VsZi5hc3NlcnRfKHNlbGYubWJveC5uZXh0KCkgaXMgTm9uZSkKICAgICAgICAgc2VsZi5hc3NlcnRfKHNlbGYubWJveC5uZXh0KCkgaXMgTm9uZSkKQEAgLTgxLDcgKzE2MzgsNyBAQAogICAgIGRlZiB0ZXN0X25vbmVtcHR5X21haWxkaXJfbmV3KHNlbGYpOgogICAgICAgICBzZWxmLmNyZWF0ZU1lc3NhZ2UoIm5ldyIpCiAgICAgICAgIHNlbGYubWJveCA9IG1haWxib3guTWFpbGRpcih0ZXN0X3N1cHBvcnQuVEVTVEZOKQotICAgICAgICBzZWxmLmFzc2VydF8obGVuKHNlbGYubWJveC5ib3hlcykgPT0gMSkKKyAgICAgICAgI3NlbGYuYXNzZXJ0XyhsZW4oc2VsZi5tYm94LmJveGVzKSA9PSAxKQogICAgICAgICBzZWxmLmFzc2VydF8oc2VsZi5tYm94Lm5leHQoKSBpcyBub3QgTm9uZSkKICAgICAgICAgc2VsZi5hc3NlcnRfKHNlbGYubWJveC5uZXh0KCkgaXMgTm9uZSkKICAgICAgICAgc2VsZi5hc3NlcnRfKHNlbGYubWJveC5uZXh0KCkgaXMgTm9uZSkKQEAgLTkwLDcgKzE2NDcsNyBAQAogICAgICAgICBzZWxmLmNyZWF0ZU1lc3NhZ2UoImN1ciIpCiAgICAgICAgIHNlbGYuY3JlYXRlTWVzc2FnZSgibmV3IikKICAgICAgICAgc2VsZi5tYm94ID0gbWFpbGJveC5NYWlsZGlyKHRlc3Rfc3VwcG9ydC5URVNURk4pCi0gICAgICAgIHNlbGYuYXNzZXJ0XyhsZW4oc2VsZi5tYm94LmJveGVzKSA9PSAyKQorICAgICAgICAjc2VsZi5hc3NlcnRfKGxlbihzZWxmLm1ib3guYm94ZXMpID09IDIpCiAgICAgICAgIHNlbGYuYXNzZXJ0XyhzZWxmLm1ib3gubmV4dCgpIGlzIG5vdCBOb25lKQogICAgICAgICBzZWxmLmFzc2VydF8oc2VsZi5tYm94Lm5leHQoKSBpcyBub3QgTm9uZSkKICAgICAgICAgc2VsZi5hc3NlcnRfKHNlbGYubWJveC5uZXh0KCkgaXMgTm9uZSkKQEAgLTEwOCwxMiArMTY2NSw5OSBAQAogICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oc3RyKG1zZykpLCBsZW4oRlJPTV8pK2xlbihEVU1NWV9NRVNTQUdFKSkKICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChuLCAxKQogCi0gICAgIyBYWFggV2Ugc3RpbGwgbmVlZCBtb3JlIHRlc3RzIQorIyMgRW5kOiBjbGFzc2VzIGZyb20gdGhlIG9yaWdpbmFsIG1vZHVsZSAoZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkpLgorCisKK19zYW1wbGVfbWVzc2FnZSA9ICIiIlwKK1JldHVybi1QYXRoOiA8Z2tqQGdyZWdvcnlram9obnNvbi5jb20+CitYLU9yaWdpbmFsLVRvOiBna2orcGVyc29uQGxvY2FsaG9zdAorRGVsaXZlcmVkLVRvOiBna2orcGVyc29uQGxvY2FsaG9zdAorUmVjZWl2ZWQ6IGZyb20gbG9jYWxob3N0IChsb2NhbGhvc3QgWzEyNy4wLjAuMV0pCisJYnkgYW5keS5ncmVnb3J5a2pvaG5zb24uY29tIChQb3N0Zml4KSB3aXRoIEVTTVRQIGlkIDM1NkVEOUREMTcKKwlmb3IgPGdraitwZXJzb25AbG9jYWxob3N0PjsgV2VkLCAxMyBKdWwgMjAwNSAxNzoyMzoxNiAtMDQwMCAoRURUKQorRGVsaXZlcmVkLVRvOiBna2pAc3VuZGFuY2UuZ3JlZ29yeWtqb2huc29uLmNvbQorUmVjZWl2ZWQ6IGZyb20gbG9jYWxob3N0IFsxMjcuMC4wLjFdCisJYnkgbG9jYWxob3N0IHdpdGggUE9QMyAoZmV0Y2htYWlsLTYuMi41KQorCWZvciBna2orcGVyc29uQGxvY2FsaG9zdCAoc2luZ2xlLWRyb3ApOyBXZWQsIDEzIEp1bCAyMDA1IDE3OjIzOjE2IC0wNDAwIChFRFQpCitSZWNlaXZlZDogZnJvbSBhbmR5LmdyZWdvcnlram9obnNvbi5jb20gKGFuZHkuZ3JlZ29yeWtqb2huc29uLmNvbSBbNjQuMzIuMjM1LjIyOF0pCisJYnkgc3VuZGFuY2UuZ3JlZ29yeWtqb2huc29uLmNvbSAoUG9zdGZpeCkgd2l0aCBFU01UUCBpZCA1QjA1NjMxNjc0NgorCWZvciA8Z2tqQGdyZWdvcnlram9obnNvbi5jb20+OyBXZWQsIDEzIEp1bCAyMDA1IDE3OjIzOjExIC0wNDAwIChFRFQpCitSZWNlaXZlZDogYnkgYW5keS5ncmVnb3J5a2pvaG5zb24uY29tIChQb3N0Zml4LCBmcm9tIHVzZXJpZCAxMDAwKQorCWlkIDQ5MENEOUREMTc7IFdlZCwgMTMgSnVsIDIwMDUgMTc6MjM6MTEgLTA0MDAgKEVEVCkKK0RhdGU6IFdlZCwgMTMgSnVsIDIwMDUgMTc6MjM6MTEgLTA0MDAKK0Zyb206ICJHcmVnb3J5IEsuIEpvaG5zb24iIDxna2pAZ3JlZ29yeWtqb2huc29uLmNvbT4KK1RvOiBna2pAZ3JlZ29yeWtqb2huc29uLmNvbQorU3ViamVjdDogU2FtcGxlIG1lc3NhZ2UKK01lc3NhZ2UtSUQ6IDwyMDA1MDcxMzIxMjMxMS5HQzQ3MDFAYW5keS5ncmVnb3J5a2pvaG5zb24uY29tPgorTWltZS1WZXJzaW9uOiAxLjAKK0NvbnRlbnQtVHlwZTogbXVsdGlwYXJ0L21peGVkOyBib3VuZGFyeT0iTk11TXo5bnQwNXc4MGQ0KyIKK0NvbnRlbnQtRGlzcG9zaXRpb246IGlubGluZQorVXNlci1BZ2VudDogTXV0dC8xLjUuOWkKKworCistLU5NdU16OW50MDV3ODBkNCsKK0NvbnRlbnQtVHlwZTogdGV4dC9wbGFpbjsgY2hhcnNldD11cy1hc2NpaQorQ29udGVudC1EaXNwb3NpdGlvbjogaW5saW5lCisKK1RoaXMgaXMgYSBzYW1wbGUgbWVzc2FnZS4KKworLS0gCitHcmVnb3J5IEsuIEpvaG5zb24KKworLS1OTXVNejludDA1dzgwZDQrCitDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbQorQ29udGVudC1EaXNwb3NpdGlvbjogYXR0YWNobWVudDsgZmlsZW5hbWU9InRleHQuZ3oiCitDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKKworSDRzSUNNMkQxVUlBQTNSbGVIUUFDOG5JTEZZQW9rU0ZrdFNLRW9XMHpKeFVQYTd3ekpJTWhaTHlmSVdjekx6VVlqMHVBSFRzCiszRllsQUFBQQorCistLU5NdU16OW50MDV3ODBkNCstLQorIiIiCisKK19zYW1wbGVfaGVhZGVycyA9IHsKKyAgICAiUmV0dXJuLVBhdGgiOiI8Z2tqQGdyZWdvcnlram9obnNvbi5jb20+IiwKKyAgICAiWC1PcmlnaW5hbC1UbyI6ImdraitwZXJzb25AbG9jYWxob3N0IiwKKyAgICAiRGVsaXZlcmVkLVRvIjoiZ2tqK3BlcnNvbkBsb2NhbGhvc3QiLAorICAgICJSZWNlaXZlZCI6IiIiZnJvbSBsb2NhbGhvc3QgKGxvY2FsaG9zdCBbMTI3LjAuMC4xXSkKKwlieSBhbmR5LmdyZWdvcnlram9obnNvbi5jb20gKFBvc3RmaXgpIHdpdGggRVNNVFAgaWQgMzU2RUQ5REQxNworCWZvciA8Z2tqK3BlcnNvbkBsb2NhbGhvc3Q+OyBXZWQsIDEzIEp1bCAyMDA1IDE3OjIzOjE2IC0wNDAwIChFRFQpIiIiLAorICAgICJEZWxpdmVyZWQtVG8iOiJna2pAc3VuZGFuY2UuZ3JlZ29yeWtqb2huc29uLmNvbSIsCisgICAgIlJlY2VpdmVkIjoiIiJmcm9tIGxvY2FsaG9zdCBbMTI3LjAuMC4xXQorCWJ5IGxvY2FsaG9zdCB3aXRoIFBPUDMgKGZldGNobWFpbC02LjIuNSkKKwlmb3IgZ2tqK3BlcnNvbkBsb2NhbGhvc3QgKHNpbmdsZS1kcm9wKTsgV2VkLCAxMyBKdWwgMjAwNSAxNzoyMzoxNiAtMDQwMCAoRURUKSIiIiwKKyAgICAiUmVjZWl2ZWQiOiIiImZyb20gYW5keS5ncmVnb3J5a2pvaG5zb24uY29tIChhbmR5LmdyZWdvcnlram9obnNvbi5jb20gWzY0LjMyLjIzNS4yMjhdKQorCWJ5IHN1bmRhbmNlLmdyZWdvcnlram9obnNvbi5jb20gKFBvc3RmaXgpIHdpdGggRVNNVFAgaWQgNUIwNTYzMTY3NDYKKwlmb3IgPGdrakBncmVnb3J5a2pvaG5zb24uY29tPjsgV2VkLCAxMyBKdWwgMjAwNSAxNzoyMzoxMSAtMDQwMCAoRURUKSIiIiwKKyAgICAiUmVjZWl2ZWQiOiIiImJ5IGFuZHkuZ3JlZ29yeWtqb2huc29uLmNvbSAoUG9zdGZpeCwgZnJvbSB1c2VyaWQgMTAwMCkKKwlpZCA0OTBDRDlERDE3OyBXZWQsIDEzIEp1bCAyMDA1IDE3OjIzOjExIC0wNDAwIChFRFQpIiIiLAorICAgICJEYXRlIjoiV2VkLCAxMyBKdWwgMjAwNSAxNzoyMzoxMSAtMDQwMCIsCisgICAgIkZyb20iOiIiIiJHcmVnb3J5IEsuIEpvaG5zb24iIDxna2pAZ3JlZ29yeWtqb2huc29uLmNvbT4iIiIsCisgICAgIlRvIjoiZ2tqQGdyZWdvcnlram9obnNvbi5jb20iLAorICAgICJTdWJqZWN0IjoiU2FtcGxlIG1lc3NhZ2UiLAorICAgICJNaW1lLVZlcnNpb24iOiIxLjAiLAorICAgICJDb250ZW50LVR5cGUiOiIiIm11bHRpcGFydC9taXhlZDsgYm91bmRhcnk9Ik5NdU16OW50MDV3ODBkNCtcIiIiIiwKKyAgICAiQ29udGVudC1EaXNwb3NpdGlvbiI6ImlubGluZSIsCisgICAgIlVzZXItQWdlbnQiOiAiTXV0dC8xLjUuOWkiIH0KKworX3NhbXBsZV9wYXlsb2FkcyA9ICgiIiJUaGlzIGlzIGEgc2FtcGxlIG1lc3NhZ2UuCisKKy0tIAorR3JlZ29yeSBLLiBKb2huc29uCisiIiIsCisiIiJINHNJQ00yRDFVSUFBM1JsZUhRQUM4bklMRllBb2tTRmt0U0tFb1cwekp4VVBhN3d6SklNaFpMeWZJV2N6THpVWWowdUFIVHMKKzNGWWxBQUFBCisiIiIpCiAKIAogZGVmIHRlc3RfbWFpbigpOgotICAgIHRlc3Rfc3VwcG9ydC5ydW5fdW5pdHRlc3QoTWFpbGRpclRlc3RDYXNlKQorICAgIHRlc3RzID0gKFRlc3RNYWlsYm94U3VwZXJjbGFzcywgVGVzdE1haWxkaXIsIFRlc3RNYm94LCBUZXN0TU1ERiwgVGVzdE1ILAorICAgICAgICAgICAgIFRlc3RCYWJ5bCwgVGVzdE1lc3NhZ2UsIFRlc3RNYWlsZGlyTWVzc2FnZSwgVGVzdE1ib3hNZXNzYWdlLAorICAgICAgICAgICAgIFRlc3RNSE1lc3NhZ2UsIFRlc3RCYWJ5bE1lc3NhZ2UsIFRlc3RNTURGTWVzc2FnZSwKKyAgICAgICAgICAgICBUZXN0TWVzc2FnZUNvbnZlcnNpb24sIFRlc3RQcm94eUZpbGUsIFRlc3RQYXJ0aWFsRmlsZSwKKyAgICAgICAgICAgICBNYWlsZGlyVGVzdENhc2UpCisgICAgdGVzdF9zdXBwb3J0LnJ1bl91bml0dGVzdCgqdGVzdHMpCiAKIAotaWYgX19uYW1lX18gPT0gIl9fbWFpbl9fIjoKK2lmIF9fbmFtZV9fID09ICdfX21haW5fXyc6CiAgICAgdGVzdF9tYWluKCkKZGlmZiAtLWdpdCBhL01pc2MvQUNLUyBiL01pc2MvQUNLUwppbmRleCBhODI0YTg2Li5kZTFkOGEyIDEwMDY0NAotLS0gYS9NaXNjL0FDS1MKKysrIGIvTWlzYy9BQ0tTCkBAIC0zMTMsNiArMzEzLDcgQEAKIEZsZW1taW5nIEtq5nIgSmVuc2VuCiBKaWJhCiBPcmphbiBKb2hhbnNlbgorR3JlZ29yeSBLLiBKb2huc29uCiBTaW1vbiBKb2huc3RvbgogRXZhbiBKb25lcwogUmljaGFyZCBKb25lcwpkaWZmIC0tZ2l0IGEvTWlzYy9ORVdTIGIvTWlzYy9ORVdTCmluZGV4IGI0MzUxMzYuLjg4MTNkN2YgMTAwNjQ0Ci0tLSBhL01pc2MvTkVXUworKysgYi9NaXNjL05FV1MKQEAgLTk5LDYgKzk5LDEwIEBACiAgIGFzIGBgd2Fsa19wYWNrYWdlcygpYGAgdG8gc3VwcG9ydCB3b3JraW5nIHdpdGggcGFja2FnZXMgdGhhdCBhcmUgZWl0aGVyCiAgIGluIHRoZSBmaWxlc3lzdGVtIG9yIHppcCBmaWxlcy4KIAorLSBUaGUgbWFpbGJveCBtb2R1bGUgY2FuIG5vdyBtb2RpZnkgYW5kIGRlbGV0ZSBtZXNzYWdlcyBmcm9tCisgIG1haWxib3hlcywgaW4gYWRkaXRpb24gdG8gc2ltcGx5IHJlYWRpbmcgdGhlbS4gIFRoYW5rcyB0byBHcmVnb3J5CisgIEsuIEpvaG5zb24gZm9yIHdyaXRpbmcgdGhlIGNvZGUsIGFuZCB0byB0aGUgMjAwNSBHb29nbGUgU3VtbWVyIG9mCisgIENvZGUgZm9yIGZ1bmRpbmcgaGlzIHdvcmsuCiAKIC0gVGhlIGBgX19kZWxfX2BgIG1ldGhvZCBvZiBjbGFzcyBgYGxvY2FsYGAgaW4gbW9kdWxlIGBgX3RocmVhZGluZ19sb2NhbGBgCiAgIHJldHVybmVkIGJlZm9yZSBhY2NvbXBsaXNoaW5nIGFueSBvZiBpdHMgaW50ZW5kZWQgY2xlYW51cC4KQEAgLTIwMiw4ICsyMDYsOCBAQAogICBlc3BlY2lhbGx5IGxvbmctcnVubmluZyBhcHBsaWNhdGlvbnMgdGhhdCwgZnJvbSB0aW1lIHRvIHRpbWUsIHRlbXBvcmFyaWx5CiAgIHVzZSBhIGxhcmdlIG51bWJlciBvZiBzbWFsbCBvYmplY3RzLiAgTm90ZSB0aGF0IHdoZW4gUHl0aG9uIHJldHVybnMgYW4KICAgYXJlbmEgdG8gdGhlIHBsYXRmb3JtIEMncyBgYGZyZWUoKWBgLCB0aGVyZSdzIG5vIGd1YXJhbnRlZSB0aGF0IHRoZQotICBwbGF0Zm9ybSBDIHdpbGwgaW4gdHVybiByZXR1cm4gdGhhdCBtZW1vcnkgdG8gdGhlIG9wZXJhdGluZyBzeXN0ZW0uICBUaGUKLSAgZWZmZWN0IG9mIHRoZSBwYXRjaCBpcyB0byBzdG9wIG1ha2luZyB0aGF0IGltcG9zc2libGUsIGFuZCBpbiB0ZXN0cyBpdAorICBwbGF0Zm9ybSBDIGxpYnJhcnkgd2lsbCBpbiB0dXJuIHJldHVybiB0aGF0IG1lbW9yeSB0byB0aGUgb3BlcmF0aW5nIHN5c3RlbS4KKyAgVGhlIGVmZmVjdCBvZiB0aGUgcGF0Y2ggaXMgdG8gc3RvcCBtYWtpbmcgdGhhdCBpbXBvc3NpYmxlLCBhbmQgaW4gdGVzdHMgaXQKICAgYXBwZWFycyB0byBiZSBlZmZlY3RpdmUgYXQgbGVhc3Qgb24gTWljcm9zb2Z0IEMgYW5kIGdjYy1iYXNlZCBzeXN0ZW1zLgogICBUaGFua3MgdG8gRXZhbiBKb25lcyBmb3IgaGFyZCB3b3JrIGFuZCBwYXRpZW5jZS4KIAo=