Ly8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KIAovLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQoKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KYXZhU2NyaXB0LmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSUphdmFTY3JpcHQuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19EZWZpbmUuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19PYmplY3QuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19WYWx1ZS5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L1B1YmxpY01ldGhvZHMuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19FdmVudEhhbmRsZXIuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9yZXNvdXJjZS5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0NvbnRleHQuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19WYWx1ZS5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L3V0aWwuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9GaWVsZC5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L2NvbG9yLmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfUnVudGltZS5oIgoKc3RhdGljIHY4OjpJc29sYXRlKiBHZXRJc29sYXRlKElGWEpTX0NvbnRleHQqIGNjKQp7CglDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKCglDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCk7CglBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7CgoJcmV0dXJuIHBSdW50aW1lLT5HZXRJc29sYXRlKCk7Cn0KCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDSlNfUHVibGljTWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKI2RlZmluZSBET1VCTEVfQ09SUkVDVAkwLjAwMDAwMDAwMDAwMDAwMQoKQkVHSU5fSlNfU1RBVElDX0dMT0JBTF9GVU4oQ0pTX1B1YmxpY01ldGhvZHMpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRk51bWJlcl9Gb3JtYXQsNikKCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGTnVtYmVyX0tleXN0cm9rZSw2KQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZQZXJjZW50X0Zvcm1hdCwyKQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZQZXJjZW50X0tleXN0cm9rZSwyKQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZEYXRlX0Zvcm1hdEV4LDEpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRkRhdGVfS2V5c3Ryb2tlRXgsMSkKCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGRGF0ZV9Gb3JtYXQsMSkKCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGRGF0ZV9LZXlzdHJva2UsMSkKCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGVGltZV9Gb3JtYXRFeCwxKQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZUaW1lX0tleXN0cm9rZUV4LDEpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlRpbWVfRm9ybWF0LDEpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlRpbWVfS2V5c3Ryb2tlLDEpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlNwZWNpYWxfRm9ybWF0LDEpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlNwZWNpYWxfS2V5c3Ryb2tlLDEpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlNwZWNpYWxfS2V5c3Ryb2tlRXgsMSkKCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGU2ltcGxlLDMpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRk1ha2VOdW1iZXIsMSkKCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGU2ltcGxlX0NhbGN1bGF0ZSwyKQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZSYW5nZV9WYWxpZGF0ZSw0KQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZNZXJnZUNoYW5nZSwxKQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZQYXJzZURhdGVFeCwyKQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZFeHRyYWN0TnVtcywxKQpFTkRfSlNfU1RBVElDX0dMT0JBTF9GVU4oKQoKSU1QTEVNRU5UX0pTX1NUQVRJQ19HTE9CQUxfRlVOKENKU19QdWJsaWNNZXRob2RzKQoKc3RydWN0IHN0cnVfVGJDb252ZXJ0CnsKCUZYX0xQQ1NUUiBscHN6SlNNYXJrOwoJRlhfTFBDU1RSIGxwc3pDcHBNYXJrOwp9OwoKc3RhdGljIGNvbnN0IHN0cnVfVGJDb252ZXJ0IGZjVGFibGVbXSA9IHsKCXsgIm1tbW0iLCIlQiIgfSwKCXsgIm1tbSIsICIlYiIgfSwKCXsgIm1tIiwgICIlbSIgfSwKCS8vIm0iCgl7ICJkZGRkIiwiJUEiIH0sCgl7ICJkZGQiLCAiJWEiIH0sCgl7ICJkZCIsICAiJWQiIH0sCgkvLyJkIiwgICAiJXciLAoJeyAieXl5eSIsIiVZIiB9LAoJeyAieXkiLCAgIiV5IiB9LAoJeyAiSEgiLCAgIiVIIiB9LAoJLy8iSCIKCXsgImhoIiwgICIlSSIgfSwKCS8vImgiCgl7ICJNTSIsICAiJU0iIH0sCgkvLyJNIgoJeyAic3MiLCAgIiVTIiB9LAoJLy8icwoJeyAidHQiLCAgIiVwIiB9LAoJLy8idCIKfTsKCnN0YXRpYyBGWF9MUENXU1RSIG1vbnRoc1tdID0KewoJKEZYX0xQQ1dTVFIpTCJKYW4iLCAoRlhfTFBDV1NUUilMIkZlYiIsIChGWF9MUENXU1RSKUwiTWFyIiwgKEZYX0xQQ1dTVFIpTCJBcHIiLCAoRlhfTFBDV1NUUilMIk1heSIsIChGWF9MUENXU1RSKUwiSnVuIiwgKEZYX0xQQ1dTVFIpTCJKdWwiLCAoRlhfTFBDV1NUUilMIkF1ZyIsIChGWF9MUENXU1RSKUwiU2VwIiwgKEZYX0xQQ1dTVFIpTCJPY3QiLCAoRlhfTFBDV1NUUilMIk5vdiIsIChGWF9MUENXU1RSKUwiRGVjIgp9OwoKc3RhdGljIEZYX0xQQ1dTVFIgZnVsbG1vbnRoc1tdID0gCnsgCgkoRlhfTFBDV1NUUilMIkphbnVhcnkiLCAoRlhfTFBDV1NUUilMIkZlYnJ1YXJ5IiwgKEZYX0xQQ1dTVFIpTCJNYXJjaCIsIChGWF9MUENXU1RSKUwiQXByaWwiLCAoRlhfTFBDV1NUUilMIk1heSIsIChGWF9MUENXU1RSKUwiSnVuZSIsIChGWF9MUENXU1RSKUwiSnVseSIsIChGWF9MUENXU1RSKUwiQXVndXN0IiwgKEZYX0xQQ1dTVFIpTCJTZXB0ZW1iZXIiLCAoRlhfTFBDV1NUUilMIk9jdG9iZXIiLCAoRlhfTFBDV1NUUilMIk5vdmVtYmVyIiwgKEZYX0xQQ1dTVFIpTCJEZWNlbWJlciIgCn07CgpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpJc051bWJlcihGWF9MUENXU1RSIHN0cmluZykKewoJQ0ZYX1dpZGVTdHJpbmcgc1RyaW0gPSBTdHJUcmltKHN0cmluZyk7CglGWF9MUENXU1RSIHBUcmltID0gc1RyaW07CglGWF9MUENXU1RSIHAgPSBwVHJpbTsKCgoJRlhfQk9PTCBiRG90ID0gRkFMU0U7CglGWF9CT09MIGJLWEpTID0gRkFMU0U7CgoJd2NoYXJfdCBjOwoJd2hpbGUgKChjID0gKnApKQoJewoJCWlmIChjID09ICcuJyB8fCBjID09ICcsJykKCQl7CgkJCWlmIChiRG90KSByZXR1cm4gRkFMU0U7CgkJCWJEb3QgPSBUUlVFOwoJCX0KCQllbHNlIGlmIChjID09ICctJyB8fCBjID09ICcrJykKCQl7CgkJCWlmIChwICE9IHBUcmltKQoJCQkJcmV0dXJuIEZBTFNFOwoJCX0KCQllbHNlIGlmIChjID09ICdlJyB8fCBjID09ICdFJykKCQl7CgkJCWlmIChiS1hKUykgcmV0dXJuIEZBTFNFOwoKCQkJcCsrOwoJCQljID0gKnA7CgkJCWlmIChjID09ICcrJyB8fCBjID09ICctJykKCQkJewoJCQkJYktYSlMgPSBUUlVFOwoJCQl9CgkJCWVsc2UKCQkJewoJCQkJcmV0dXJuIEZBTFNFOwoJCQl9CgkJfQoJCWVsc2UgaWYgKCFJc0RpZ2l0KGMpKQoJCXsKCQkJcmV0dXJuIEZBTFNFOwoJCX0KCQlwKys7Cgl9CgoJcmV0dXJuIFRSVUU7Cn0KCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OklzRGlnaXQod2NoYXJfdCBjaCkKewoJcmV0dXJuIChjaCA+PSBMJzAnICYmIGNoIDw9IEwnOScpOwp9CgpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpJc0RpZ2l0KGNoYXIgY2gpCnsKCXJldHVybiAoY2ggPj0gJzAnICYmIGNoIDw9ICc5Jyk7Cn0KCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OklzQWxwaGFiZXRpYyh3Y2hhcl90IGNoKQp7CglyZXR1cm4gKChjaCA+PSBMJ2EnICYmIGNoIDw9IEwneicpIHx8IChjaCA+PSBMJ0EnICYmIGNoIDw9IEwnWicpKTsKfQoKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6SXNBbHBoYU51bWVyaWMod2NoYXJfdCBjaCkKewoJcmV0dXJuIChJc0RpZ2l0KGNoKSB8fCBJc0FscGhhYmV0aWMoY2gpKTsKfQoKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6bWFza1NhdGlzZmllZCh3Y2hhcl90IGNfQ2hhbmdlLHdjaGFyX3QgY19NYXNrKQp7Cglzd2l0Y2ggKGNfTWFzaykKCXsKCWNhc2UgTCc5JzoKICAgICAgICByZXR1cm4gSXNEaWdpdChjX0NoYW5nZSk7CQkKICAgIGNhc2UgTCdBJzoKICAgICAgICByZXR1cm4gSXNBbHBoYWJldGljKGNfQ2hhbmdlKTsJCQogICAgY2FzZSBMJ08nOgogICAgICAgIHJldHVybiBJc0FscGhhTnVtZXJpYyhjX0NoYW5nZSk7CQkKICAgIGNhc2UgTCdYJzoKICAgICAgICByZXR1cm4gVFJVRTsJCQoJZGVmYXVsdDoKICAgICAgICByZXR1cm4gKGNfQ2hhbmdlID09IGNfTWFzayk7Cgl9Cn0KCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OmlzUmVzZXJ2ZWRNYXNrQ2hhcih3Y2hhcl90IGNoKQp7CglyZXR1cm4gY2ggPT0gTCc5JyB8fCBjaCA9PSBMJ0EnIHx8IGNoID09IEwnTycgfHwgY2ggPT0gTCdYJzsKfQoKZG91YmxlIENKU19QdWJsaWNNZXRob2RzOjpBRl9TaW1wbGUoRlhfTFBDV1NUUiBzRnVjdGlvbiwgZG91YmxlIGRWYWx1ZTEsIGRvdWJsZSBkVmFsdWUyKQp7CglpZiAoRlhTWVNfd2NzaWNtcChzRnVjdGlvbiwoRlhfTFBDV1NUUilMIkFWRyIpID09IDAgfHwgRlhTWVNfd2NzaWNtcChzRnVjdGlvbiwoRlhfTFBDV1NUUilMIlNVTSIpID09IDApCgl7CgkJcmV0dXJuIGRWYWx1ZTEgKyBkVmFsdWUyOwoJfQoJZWxzZSBpZiAoRlhTWVNfd2NzaWNtcChzRnVjdGlvbiwgKEZYX0xQQ1dTVFIpTCJQUkQiKSA9PSAwKQoJewoJCXJldHVybiBkVmFsdWUxICogZFZhbHVlMjsKCX0KCWVsc2UgaWYgKEZYU1lTX3djc2ljbXAoc0Z1Y3Rpb24sKEZYX0xQQ1dTVFIpTCJNSU4iKSA9PSAwKQoJewoJCXJldHVybiBGWF9NSU4oZFZhbHVlMSwgZFZhbHVlMik7Cgl9CgllbHNlIGlmIChGWFNZU193Y3NpY21wKHNGdWN0aW9uLChGWF9MUENXU1RSKUwiTUFYIikgPT0gMCkKCXsKCQlyZXR1cm4gRlhfTUFYKGRWYWx1ZTEsIGRWYWx1ZTIpOwoJfQoKCXJldHVybiBkVmFsdWUxOwp9CgpDRlhfV2lkZVN0cmluZyBDSlNfUHVibGljTWV0aG9kczo6U3RyTFRyaW0oRlhfTFBDV1NUUiBwU3RyKQp7Cgl3aGlsZSAoKnBTdHIgJiYgKnBTdHIgPT0gTCcgJykgcFN0cisrOwoKCXJldHVybiBwU3RyOwp9CgpDRlhfV2lkZVN0cmluZyBDSlNfUHVibGljTWV0aG9kczo6U3RyUlRyaW0oRlhfTFBDV1NUUiBwU3RyKQp7CglGWF9MUENXU1RSIHAgPSBwU3RyOwoJd2hpbGUgKCpwKSBwKys7Cgl3aGlsZSAocCA+IHBTdHIgJiYgKihwIC0gMSkgPT0gTCcgJykgcC0tOwoKCXJldHVybiBDRlhfV2lkZVN0cmluZyhwU3RyLCBwIC0gcFN0cik7Cn0KCkNGWF9XaWRlU3RyaW5nIENKU19QdWJsaWNNZXRob2RzOjpTdHJUcmltKEZYX0xQQ1dTVFIgcFN0cikKewoJcmV0dXJuIFN0clJUcmltKFN0ckxUcmltKHBTdHIpKTsKfQoKQ0ZYX0J5dGVTdHJpbmcgQ0pTX1B1YmxpY01ldGhvZHM6OlN0ckxUcmltKEZYX0xQQ1NUUiBwU3RyKQp7Cgl3aGlsZSAoKnBTdHIgJiYgKnBTdHIgPT0gJyAnKSBwU3RyKys7CgogICAgICAgIHJldHVybiBwU3RyOwp9CgpDRlhfQnl0ZVN0cmluZyBDSlNfUHVibGljTWV0aG9kczo6U3RyUlRyaW0oRlhfTFBDU1RSIHBTdHIpCnsKCUZYX0xQQ1NUUiBwID0gcFN0cjsKCXdoaWxlICgqcCkgcCsrOwoJd2hpbGUgKHAgPiBwU3RyICYmICoocCAtIDEpID09IEwnICcpIHAtLTsKCglyZXR1cm4gQ0ZYX0J5dGVTdHJpbmcocFN0cixwLXBTdHIpOwp9CgpDRlhfQnl0ZVN0cmluZyBDSlNfUHVibGljTWV0aG9kczo6U3RyVHJpbShGWF9MUENTVFIgcFN0cikKewoJcmV0dXJuIFN0clJUcmltKFN0ckxUcmltKHBTdHIpKTsKfQoKZG91YmxlIENKU19QdWJsaWNNZXRob2RzOjpQYXJzZU51bWJlcihGWF9MUENXU1RSIHN3U291cmNlLCBGWF9CT09MJiBiQWxsRGlnaXRzLCBGWF9CT09MJiBiRG90LCBGWF9CT09MJiBiU2lnbiwgRlhfQk9PTCYgYktYSlMpCnsKCWJEb3QgPSBGQUxTRTsKCWJTaWduID0gRkFMU0U7CgliS1hKUyA9IEZBTFNFOwoKCUZYX0JPT0wgYkRpZ2l0RXhpc3QgPSBGQUxTRTsKCglGWF9MUENXU1RSIHAgPSBzd1NvdXJjZTsKCXdjaGFyX3QgYzsKCglGWF9MUENXU1RSIHBTdGFydCA9IE5VTEw7CglGWF9MUENXU1RSIHBFbmQgPSBOVUxMOwoKCXdoaWxlICgoYyA9ICpwKSkKCXsKCQlpZiAoIXBTdGFydCAmJiBjICE9IEwnICcpCgkJewoJCQlwU3RhcnQgPSBwOwoJCX0KCgkJcEVuZCA9IHA7CgkJcCsrOwoJfQoKCWlmICghcFN0YXJ0KQoJewoJCWJBbGxEaWdpdHMgPSBGQUxTRTsKCQlyZXR1cm4gMDsKCX0KCgl3aGlsZSAocEVuZCAhPSBwU3RhcnQpCgl7CgkJaWYgKCpwRW5kID09IEwnICcpCgkJCXBFbmQgLS07CgkJZWxzZQoJCQlicmVhazsKCX0KCglkb3VibGUgZFJldCA9IDA7CglwID0gcFN0YXJ0OwoJYkFsbERpZ2l0cyA9IFRSVUU7CglDRlhfV2lkZVN0cmluZyBzd0RpZ2l0czsKCgl3aGlsZSAocCA8PSBwRW5kKQoJewkKCQljID0gKnA7CgoJCWlmIChJc0RpZ2l0KGMpKQoJCXsKCQkJc3dEaWdpdHMgKz0gYzsKCQkJYkRpZ2l0RXhpc3QgPSBUUlVFOwoJCX0KCQllbHNlIAoJCXsKCQkJc3dpdGNoIChjKQoJCQl7CgkJCWNhc2UgTCcgJzoKCQkJCWJBbGxEaWdpdHMgPSBGQUxTRTsKCQkJCWJyZWFrOwoJCQljYXNlIEwnLic6CgkJCWNhc2UgTCcsJzoKCQkJCWlmICghYkRvdCkKCQkJCXsKCQkJCQlpZiAoYkRpZ2l0RXhpc3QpCgkJCQkJewoJCQkJCQlzd0RpZ2l0cyArPSBMJy4nOwoJCQkJCX0KCQkJCQllbHNlCgkJCQkJewoJCQkJCQlzd0RpZ2l0cyArPSBMJzAnOwoJCQkJCQlzd0RpZ2l0cyArPSBMJy4nOwoJCQkJCQliRGlnaXRFeGlzdCA9IFRSVUU7CgkJCQkJfQoKCQkJCQliRG90ID0gVFJVRTsKCQkJCQlicmVhazsKCQkJCX0KCQkJY2FzZSAnZSc6CgkJCWNhc2UgJ0UnOgoJCQkJaWYgKCFiS1hKUykKCQkJCXsKCQkJCQlwKys7CgkJCQkJYyA9ICpwOwoJCQkJCWlmIChjID09ICcrJyB8fCBjID09ICctJykKCQkJCQl7CgkJCQkJCWJLWEpTID0gVFJVRTsKCQkJCQkJc3dEaWdpdHMgKz0gJ2UnOwoJCQkJCQlzd0RpZ2l0cyArPSBjOwoJCQkJCX0KCQkJCQlicmVhazsKCQkJCX0KCQkJY2FzZSBMJy0nOgoJCQkJaWYgKCFiRGlnaXRFeGlzdCAmJiAhYlNpZ24pCgkJCQl7CgkJCQkJc3dEaWdpdHMgKz0gYzsKCQkJCQliU2lnbiA9IFRSVUU7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCWRlZmF1bHQ6CgkJCQliQWxsRGlnaXRzID0gRkFMU0U7CgoJCQkJaWYgKHAgIT0gcFN0YXJ0ICYmICFiRG90ICYmIGJEaWdpdEV4aXN0KQoJCQkJewoJCQkJCXN3RGlnaXRzICs9IEwnLic7CgkJCQkJYkRvdCA9IFRSVUU7CgkJCQl9CgkJCQllbHNlCgkJCQl7CgkJCQkJYkRvdCA9IEZBTFNFOwoJCQkJCWJEaWdpdEV4aXN0ID0gRkFMU0U7CgkJCQkJc3dEaWdpdHMgPSBMIiI7CgkJCQl9CgkJCQlicmVhazsKCQkJfQoJCX0KCgkJcCsrOwoJfQoKCWlmIChzd0RpZ2l0cy5HZXRMZW5ndGgoKSA+IDAgJiYgc3dEaWdpdHMuR2V0TGVuZ3RoKCkgPCAxNykKCXsKCQlDRlhfQnl0ZVN0cmluZyBzRGlnaXRzID0gc3dEaWdpdHMuVVRGOEVuY29kZSgpOwoKCQlpZiAoYktYSlMpCgkJewoJCQlkUmV0ID0gYXRvZihzRGlnaXRzKTsKCQl9CgkJZWxzZQoJCXsKCQkJaWYgKGJEb3QpCgkJCXsKCQkJCWNoYXIqIHBTdG9wU3RyaW5nOwoJCQkJZFJldCA9IDo6c3RydG9kKHNEaWdpdHMsICZwU3RvcFN0cmluZyk7CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQlkUmV0ID0gYXRvbChzRGlnaXRzKTsKCQkJfQoJCX0KCgl9CgoJcmV0dXJuIGRSZXQ7Cn0KCmRvdWJsZSBDSlNfUHVibGljTWV0aG9kczo6UGFyc2VTdHJpbmdUb051bWJlcihGWF9MUENXU1RSIHN3U291cmNlKQp7CglGWF9CT09MIGJBbGxEaWdpdHMgPSBGQUxTRTsKCUZYX0JPT0wgYkRvdCA9IEZBTFNFOwoJRlhfQk9PTCBiU2lnbiA9IEZBTFNFOwoJRlhfQk9PTCBiS1hKUyA9IEZBTFNFOwoKCXJldHVybiBQYXJzZU51bWJlcihzd1NvdXJjZSwgYkFsbERpZ2l0cywgYkRvdCwgYlNpZ24sIGJLWEpTKTsKfQoKRlhfQk9PTAlDSlNfUHVibGljTWV0aG9kczo6Q29udmVydFN0cmluZ1RvTnVtYmVyKEZYX0xQQ1dTVFIgc3dTb3VyY2UsIGRvdWJsZSAmIGRSZXQsIEZYX0JPT0wgJiBiRG90KQp7CglGWF9CT09MIGJBbGxEaWdpdHMgPSBGQUxTRTsKCUZYX0JPT0wgYlNpZ24gPSBGQUxTRTsKCUZYX0JPT0wgYktYSlMgPSBGQUxTRTsKCglkUmV0ID0gUGFyc2VOdW1iZXIoc3dTb3VyY2UsIGJBbGxEaWdpdHMsIGJEb3QsIGJTaWduLCBiS1hKUyk7CgoJcmV0dXJuIGJBbGxEaWdpdHM7Cn0KCkNKU19BcnJheSBDSlNfUHVibGljTWV0aG9kczo6QUZfTWFrZUFycmF5RnJvbUxpc3Qodjg6Oklzb2xhdGUqIGlzb2xhdGUsIENKU19WYWx1ZSB2YWwpCnsKCUNKU19BcnJheSBTdHJBcnJheShpc29sYXRlKTsKCWlmKHZhbC5Jc0FycmF5T2JqZWN0KCkpCgl7CgkJdmFsLkNvbnZlcnRUb0FycmF5KFN0ckFycmF5KTsKCQlyZXR1cm4gU3RyQXJyYXk7Cgl9CglDRlhfV2lkZVN0cmluZyB3c1N0ciA9IHZhbC5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOwoJQ0ZYX0J5dGVTdHJpbmcgdCA9IENGWF9CeXRlU3RyaW5nOjpGcm9tVW5pY29kZSh3c1N0cik7Cgljb25zdCBjaGFyICogcCA9IChjb25zdCBjaGFyICopdDsKCgoJaW50IGNoID0gJywnIDsKCWludCBuSW5kZXggPSAwOwoKCXdoaWxlICgqcCkKCXsKCQljb25zdCBjaGFyICogcFRlbXAgPSBzdHJjaHIocCwgY2gpOwoJCWlmIChwVGVtcCA9PSBOVUxMKQoJCXsKCQkJU3RyQXJyYXkuU2V0RWxlbWVudChuSW5kZXgsIENKU19WYWx1ZShpc29sYXRlLChGWF9MUENTVFIpU3RyVHJpbShwKSkpOwoJCQlicmVhazsKCQl9CgkJZWxzZQoJCXsKCQkJY2hhciAqIHBTdWIgPSBuZXcgY2hhcltwVGVtcCAtIHAgKyAxXTsKCQkJc3RybmNweShwU3ViLCBwLCBwVGVtcCAtIHApOwoJCQkqKHBTdWIgKyAocFRlbXAgLSBwKSkgPSAnXDAnOwoKCQkJU3RyQXJyYXkuU2V0RWxlbWVudChuSW5kZXgsIENKU19WYWx1ZShpc29sYXRlLChGWF9MUENTVFIpU3RyVHJpbShwU3ViKSkpOwoJCQlkZWxldGUgW11wU3ViOwoJCQkKCQkJbkluZGV4ICsrOwoJCQlwID0gKytwVGVtcDsKCQl9CgkJCgl9CglyZXR1cm4gU3RyQXJyYXk7Cn0KCmludCBDSlNfUHVibGljTWV0aG9kczo6UGFyc2VTdHJpbmdJbnRlZ2VyKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHJpbmcsaW50IG5TdGFydCxpbnQmIG5Ta2lwLCBpbnQgbk1heFN0ZXApCnsKCWludCBuUmV0ID0gMDsKCW5Ta2lwID0gMDsKCWZvciAoaW50IGk9blN0YXJ0LCBzej1zdHJpbmcuR2V0TGVuZ3RoKCk7IGkgPCBzejsgaSsrKQoJewoJCWlmIChpLW5TdGFydCA+IDEwKQoJCQlicmVhazsKCgkJRlhfV0NIQVIgYyA9IHN0cmluZy5HZXRBdChpKTsKCQlpZiAoSXNEaWdpdCgod2NoYXJfdCljKSkKCQl7CgkJCW5SZXQgPSBuUmV0ICogMTAgKyAoYyAtICcwJyk7CgkJCW5Ta2lwID0gaSAtIG5TdGFydCArIDE7CgkJCWlmIChuU2tpcCA+PSBuTWF4U3RlcCkgCgkJCQlicmVhazsKCQl9CgkJZWxzZQoJCQlicmVhazsKCX0KCglyZXR1cm4gblJldDsKfQoKQ0ZYX1dpZGVTdHJpbmcgQ0pTX1B1YmxpY01ldGhvZHM6OlBhcnNlU3RyaW5nU3RyaW5nKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHJpbmcsIGludCBuU3RhcnQsIGludCYgblNraXApCnsKCUNGWF9XaWRlU3RyaW5nIHN3UmV0OwoJblNraXAgPSAwOwoJZm9yIChpbnQgaT1uU3RhcnQsIHN6PXN0cmluZy5HZXRMZW5ndGgoKTsgaSA8IHN6OyBpKyspCgl7CgkJRlhfV0NIQVIgYyA9IHN0cmluZy5HZXRBdChpKTsKCQlpZiAoKGMgPj0gTCdhJyAmJiBjIDw9IEwneicpIHx8IChjID49IEwnQScgJiYgYyA8PSBMJ1onKSkKCQl7CgkJCXN3UmV0ICs9IGM7CgkJCW5Ta2lwID0gaSAtIG5TdGFydCArIDE7CgkJfQoJCWVsc2UKCQkJYnJlYWs7Cgl9CgoJcmV0dXJuIHN3UmV0Owp9Cgpkb3VibGUgQ0pTX1B1YmxpY01ldGhvZHM6OlBhcnNlTm9ybWFsRGF0ZShjb25zdCBDRlhfV2lkZVN0cmluZyAmIHZhbHVlLCBGWF9CT09MJiBiV3JvbmdGb3JtYXQpCnsKCWRvdWJsZSBkdCA9IEpTX0dldERhdGVUaW1lKCk7CgoJaW50IG5ZZWFyID0gSlNfR2V0WWVhckZyb21UaW1lKGR0KTsKCWludCBuTW9udGggPSBKU19HZXRNb250aEZyb21UaW1lKGR0KSArIDE7CglpbnQgbkRheSA9IEpTX0dldERheUZyb21UaW1lKGR0KTsKCWludCBuSG91ciA9IEpTX0dldEhvdXJGcm9tVGltZShkdCk7CglpbnQgbk1pbiA9IEpTX0dldE1pbkZyb21UaW1lKGR0KTsKCWludCBuU2VjID0gSlNfR2V0U2VjRnJvbVRpbWUoZHQpOwoKCWludCBudW1iZXJbM107CgoJaW50IG5Ta2lwID0gMDsKCWludCBuTGVuID0gdmFsdWUuR2V0TGVuZ3RoKCk7CglpbnQgbkluZGV4ID0gMDsKCWludCBpID0gMDsKCXdoaWxlIChpIDwgbkxlbikKCXsKCQlpZiAobkluZGV4ID4gMikgYnJlYWs7CgoJCUZYX1dDSEFSIGMgPSB2YWx1ZS5HZXRBdChpKTsKCQlpZiAoSXNEaWdpdCgod2NoYXJfdCljKSkKCQl7CgkJCW51bWJlcltuSW5kZXgrK10gPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGksIG5Ta2lwLCA0KTsKCQkJaSArPSBuU2tpcDsJCQkKCQl9CgkJZWxzZQoJCXsKCQkJaSArKzsKCQl9Cgl9CgoJaWYgKG5JbmRleCA9PSAyKQoJewoJCS8vIGNhc2UyOiBtb250aC9kYXkKCQkvLyBjYXNlMzogZGF5L21vbnRoCgkJaWYgKChudW1iZXJbMF0gPj0gMSAmJiBudW1iZXJbMF0gPD0gMTIpICYmIChudW1iZXJbMV0gPj0gMSAmJiBudW1iZXJbMV0gPD0gMzEpKQoJCXsKCQkJbk1vbnRoID0gbnVtYmVyWzBdOwoJCQluRGF5ID0gbnVtYmVyWzFdOwoJCX0KCQllbHNlIGlmICgobnVtYmVyWzBdID49IDEgJiYgbnVtYmVyWzBdIDw9IDMxKSAmJiAobnVtYmVyWzFdID49IDEgJiYgbnVtYmVyWzFdIDw9IDEyKSkKCQl7CgkJCW5EYXkgPSBudW1iZXJbMF07CgkJCW5Nb250aCA9IG51bWJlclsxXTsKCQl9CgoJCWJXcm9uZ0Zvcm1hdCA9IEZBTFNFOwoJfQoJZWxzZSBpZiAobkluZGV4ID09IDMpCgl7CgkJLy8gY2FzZTE6IHllYXIvbW9udGgvZGF5CgkJLy8gY2FzZTI6IG1vbnRoL2RheS95ZWFyCgkJLy8gY2FzZTM6IGRheS9tb250aC95ZWFyCgoJCWlmIChudW1iZXJbMF0gPiAxMiAmJiAobnVtYmVyWzFdID49IDEgJiYgbnVtYmVyWzFdIDw9IDEyKSAmJiAobnVtYmVyWzJdID49IDEgJiYgbnVtYmVyWzJdIDw9IDMxKSkKCQl7CgkJCW5ZZWFyID0gbnVtYmVyWzBdOwoJCQluTW9udGggPSBudW1iZXJbMV07CgkJCW5EYXkgPSBudW1iZXJbMl07CgkJfQoJCWVsc2UgaWYgKChudW1iZXJbMF0gPj0gMSAmJiBudW1iZXJbMF0gPD0gMTIpICYmIChudW1iZXJbMV0gPj0gMSAmJiBudW1iZXJbMV0gPD0gMzEpICYmIG51bWJlclsyXSA+IDMxKQoJCXsKCQkJbk1vbnRoID0gbnVtYmVyWzBdOwoJCQluRGF5ID0gbnVtYmVyWzFdOwoJCQluWWVhciA9IG51bWJlclsyXTsKCQl9CgkJZWxzZSBpZiAoKG51bWJlclswXSA+PSAxICYmIG51bWJlclswXSA8PSAzMSkgJiYgKG51bWJlclsxXSA+PSAxICYmIG51bWJlclsxXSA8PSAxMikgJiYgbnVtYmVyWzJdID4gMzEpCgkJewoJCQluRGF5ID0gbnVtYmVyWzBdOwoJCQluTW9udGggPSBudW1iZXJbMV07CgkJCW5ZZWFyID0gbnVtYmVyWzJdOwoJCX0KCgkJYldyb25nRm9ybWF0ID0gRkFMU0U7Cgl9CgllbHNlCgl7CgkJYldyb25nRm9ybWF0ID0gVFJVRTsKCQlyZXR1cm4gZHQ7Cgl9CgoJQ0ZYX1dpZGVTdHJpbmcgc3dUZW1wOwoJc3dUZW1wLkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkLyVkLyVkICVkOiVkOiVkIixuTW9udGgsbkRheSxuWWVhcixuSG91cixuTWluLG5TZWMpOwoJcmV0dXJuIEpTX0RhdGVQYXJzZShzd1RlbXApOwp9Cgpkb3VibGUgQ0pTX1B1YmxpY01ldGhvZHM6Ok1ha2VSZWd1bGFyRGF0ZShjb25zdCBDRlhfV2lkZVN0cmluZyAmIHZhbHVlLCBjb25zdCBDRlhfV2lkZVN0cmluZyAmIGZvcm1hdCwgRlhfQk9PTCYgYldyb25nRm9ybWF0KQp7Cglkb3VibGUgZHQgPSBKU19HZXREYXRlVGltZSgpOwoKCWlmIChmb3JtYXQuSXNFbXB0eSgpIHx8IHZhbHVlLklzRW1wdHkoKSkKCQlyZXR1cm4gZHQ7CgoJaW50IG5ZZWFyID0gSlNfR2V0WWVhckZyb21UaW1lKGR0KTsKCWludCBuTW9udGggPSBKU19HZXRNb250aEZyb21UaW1lKGR0KSArIDE7CglpbnQgbkRheSA9IEpTX0dldERheUZyb21UaW1lKGR0KTsKCWludCBuSG91ciA9IEpTX0dldEhvdXJGcm9tVGltZShkdCk7CglpbnQgbk1pbiA9IEpTX0dldE1pbkZyb21UaW1lKGR0KTsKCWludCBuU2VjID0gSlNfR2V0U2VjRnJvbVRpbWUoZHQpOwoKCWludCBuWWVhclN1YiA9IDk5OyAvL25ZZWFyIC0gMjAwMDsKCglGWF9CT09MIGJQbSA9IEZBTFNFOwoJRlhfQk9PTCBiRXhpdCA9IEZBTFNFOwoJYldyb25nRm9ybWF0ID0gRkFMU0U7CgoJaW50IGk9MDsKCWludCBqPTA7CgoJd2hpbGUgKGkgPCBmb3JtYXQuR2V0TGVuZ3RoKCkpCgl7CgkJaWYgKGJFeGl0KSBicmVhazsKCgkJRlhfV0NIQVIgYyA9IGZvcm1hdC5HZXRBdChpKTsKCQlzd2l0Y2ggKGMpCgkJewoJCQljYXNlICc6JzoKCQkJY2FzZSAnLic6CgkJCWNhc2UgJy0nOgoJCQljYXNlICdcXCc6CgkJCWNhc2UgJy8nOgoJCQkJaSsrOwoJCQkJaisrOwoJCQkJYnJlYWs7CgoJCQljYXNlICd5JzoKCQkJY2FzZSAnbSc6CgkJCWNhc2UgJ2QnOgoJCQljYXNlICdIJzoKCQkJY2FzZSAnaCc6CgkJCWNhc2UgJ00nOgoJCQljYXNlICdzJzoKCQkJY2FzZSAndCc6CgkJCQl7CgkJCQkJaW50IG9sZGogPSBqOwoJCQkJCWludCBuU2tpcCA9IDA7CgkJCQkJaW50IHJlbWFpbmluZyA9IGZvcm1hdC5HZXRMZW5ndGgoKSAtIGkgLSAxOwoKCQkJCQlpZiAocmVtYWluaW5nID09IDAgfHwgZm9ybWF0LkdldEF0KGkrMSkgIT0gYykKCQkJCQl7CgkJCQkJCXN3aXRjaCAoYykKCQkJCQkJewoJCQkJCQkJY2FzZSAneSc6CgkJCQkJCQkJaSsrOwoJCQkJCQkJCWorKzsKCQkJCQkJCQlicmVhazsKCQkJCQkJCWNhc2UgJ20nOgoJCQkJCQkJCW5Nb250aCA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDIpOwoJCQkJCQkJCWkrKzsKCQkJCQkJCQlqICs9IG5Ta2lwOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJY2FzZSAnZCc6CgkJCQkJCQkJbkRheSA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDIpOwoJCQkJCQkJCWkrKzsKCQkJCQkJCQlqICs9IG5Ta2lwOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJY2FzZSAnSCc6CgkJCQkJCQkJbkhvdXIgPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAyKTsKCQkJCQkJCQlpKys7CgkJCQkJCQkJaiArPSBuU2tpcDsKCQkJCQkJCQlicmVhazsKCQkJCQkJCWNhc2UgJ2gnOgoJCQkJCQkJCW5Ib3VyID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMik7CgkJCQkJCQkJaSsrOwoJCQkJCQkJCWogKz0gblNraXA7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlICdNJzoKCQkJCQkJCQluTWluID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMik7CgkJCQkJCQkJaSsrOwoJCQkJCQkJCWogKz0gblNraXA7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlICdzJzoKCQkJCQkJCQluU2VjID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMik7CgkJCQkJCQkJaSsrOwoJCQkJCQkJCWogKz0gblNraXA7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlICd0JzoKCQkJCQkJCQliUG0gPSAoaiA8IHZhbHVlLkdldExlbmd0aCgpICYmIHZhbHVlLkdldEF0KGopID09ICdwJyk7CgkJCQkJCQkJaSsrOwoJCQkJCQkJCWorKzsKCQkJCQkJCQlicmVhazsKCQkJCQkJfQoJCQkJCX0KCQkJCQllbHNlIGlmIChyZW1haW5pbmcgPT0gMSB8fCBmb3JtYXQuR2V0QXQoaSsyKSAhPSBjKQoJCQkJCXsKCQkJCQkJc3dpdGNoIChjKQoJCQkJCQl7CgkJCQkJCQljYXNlICd5JzoKCQkJCQkJCQluWWVhciA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDQpOwoJCQkJCQkJCWkgKz0gMjsKCQkJCQkJCQlqICs9IG5Ta2lwOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJY2FzZSAnbSc6CgkJCQkJCQkJbk1vbnRoID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMik7CgkJCQkJCQkJaSArPSAyOwoJCQkJCQkJCWogKz0gblNraXA7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlICdkJzoKCQkJCQkJCQluRGF5ID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMik7CgkJCQkJCQkJaSArPSAyOwoJCQkJCQkJCWogKz0gblNraXA7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlICdIJzoKCQkJCQkJCQluSG91ciA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDIpOwoJCQkJCQkJCWkgKz0gMjsKCQkJCQkJCQlqICs9IG5Ta2lwOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJY2FzZSAnaCc6CgkJCQkJCQkJbkhvdXIgPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAyKTsKCQkJCQkJCQlpICs9IDI7CgkJCQkJCQkJaiArPSBuU2tpcDsKCQkJCQkJCQlicmVhazsKCQkJCQkJCWNhc2UgJ00nOgoJCQkJCQkJCW5NaW4gPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAyKTsKCQkJCQkJCQlpICs9IDI7CgkJCQkJCQkJaiArPSBuU2tpcDsKCQkJCQkJCQlicmVhazsKCQkJCQkJCWNhc2UgJ3MnOgoJCQkJCQkJCW5TZWMgPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAyKTsKCQkJCQkJCQlpICs9IDI7CgkJCQkJCQkJaiArPSBuU2tpcDsKCQkJCQkJCQlicmVhazsKCQkJCQkJCWNhc2UgJ3QnOgoJCQkJCQkJCWJQbSA9IChqICsgMSA8IHZhbHVlLkdldExlbmd0aCgpICYmIHZhbHVlLkdldEF0KGopID09ICdwJyAmJiB2YWx1ZS5HZXRBdChqKzEpID09ICdtJyk7CgkJCQkJCQkJaSArPSAyOwoJCQkJCQkJCWogKz0gMjsKCQkJCQkJCQlicmVhazsKCQkJCQkJfQoJCQkJCX0KCQkJCQllbHNlIGlmIChyZW1haW5pbmcgPT0gMiB8fCBmb3JtYXQuR2V0QXQoaSszKSAhPSBjKQoJCQkJCXsKCQkJCQkJc3dpdGNoIChjKQoJCQkJCQl7CgkJCQkJCQljYXNlICdtJzoKCQkJCQkJCQl7CgkJCQkJCQkJCUNGWF9XaWRlU3RyaW5nIHNNb250aCA9IFBhcnNlU3RyaW5nU3RyaW5nKHZhbHVlLCBqLCBuU2tpcCk7CgkJCQkJCQkJCUZYX0JPT0wgYkZpbmQgPSBGQUxTRTsKCQkJCQkJCQkJZm9yIChpbnQgbSA9IDA7IG0gPCAxMjsgbSsrKQoJCQkJCQkJCQl7CgkJCQkJCQkJCQlpZiAoc01vbnRoLkNvbXBhcmVOb0Nhc2UobW9udGhzW21dKSA9PSAwKQoJCQkJCQkJCQkJewoJCQkJCQkJCQkJCW5Nb250aCA9IG0gKyAxOwoJCQkJCQkJCQkJCWkrPTM7CgkJCQkJCQkJCQkJais9blNraXA7CgkJCQkJCQkJCQkJYkZpbmQgPSBUUlVFOwoJCQkJCQkJCQkJCWJyZWFrOwoJCQkJCQkJCQkJfQoJCQkJCQkJCQl9CgoJCQkJCQkJCQlpZiAoIWJGaW5kKQoJCQkJCQkJCQl7CgkJCQkJCQkJCQluTW9udGggPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAzKTsKCQkJCQkJCQkJCWkrPTM7CgkJCQkJCQkJCQlqICs9IG5Ta2lwOwoJCQkJCQkJCQl9CgkJCQkJCQkJfQoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJY2FzZSAneSc6CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQlkZWZhdWx0OgoJCQkJCQkJCWkrPTM7CgkJCQkJCQkJais9MzsKCQkJCQkJCQlicmVhazsKCQkJCQkJfQoJCQkJCX0KCQkJCQllbHNlIGlmIChyZW1haW5pbmcgPT0gMyB8fCBmb3JtYXQuR2V0QXQoaSs0KSAhPSBjKQoJCQkJCXsKCQkJCQkJc3dpdGNoIChjKQoJCQkJCQl7CgoKCQkJCQkJCWNhc2UgJ3knOgoJCQkJCQkJCW5ZZWFyID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgNCk7CgkJCQkJCQkJaiArPSBuU2tpcDsKCQkJCQkJCQlpICs9IDQ7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlICdtJzoKCQkJCQkJCQl7CgkJCQkJCQkJCUZYX0JPT0wgYkZpbmQgPSBGQUxTRTsKCgkJCQkJCQkJCUNGWF9XaWRlU3RyaW5nIHNNb250aCA9IFBhcnNlU3RyaW5nU3RyaW5nKHZhbHVlLCBqLCBuU2tpcCk7CgkJCQkJCQkJCXNNb250aC5NYWtlTG93ZXIoKTsKCgkJCQkJCQkJCWZvciAoaW50IG0gPSAwOyBtIDwgMTI7IG0rKykKCQkJCQkJCQkJewoJCQkJCQkJCQkJQ0ZYX1dpZGVTdHJpbmcgc0Z1bGxNb250aHMgPSBmdWxsbW9udGhzW21dOwoJCQkJCQkJCQkJc0Z1bGxNb250aHMuTWFrZUxvd2VyKCk7CgoJCQkJCQkJCQkJaWYgKHNGdWxsTW9udGhzLkZpbmQoc01vbnRoLCAwKSAhPSAtMSkKCQkJCQkJCQkJCXsKCQkJCQkJCQkJCQluTW9udGggPSBtICsgMTsKCQkJCQkJCQkJCQlpICs9IDQ7CgkJCQkJCQkJCQkJaiArPSBuU2tpcDsKCQkJCQkJCQkJCQliRmluZCA9IFRSVUU7CgkJCQkJCQkJCQkJYnJlYWs7CgkJCQkJCQkJCQl9CgkJCQkJCQkJCX0KCgkJCQkJCQkJCWlmICghYkZpbmQpCgkJCQkJCQkJCXsKCQkJCQkJCQkJCW5Nb250aCA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDQpOwoJCQkJCQkJCQkJaSs9NDsKCQkJCQkJCQkJCWogKz0gblNraXA7CgkJCQkJCQkJCX0KCQkJCQkJCQl9CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQlkZWZhdWx0OgoJCQkJCQkJCWkgKz0gNDsKCQkJCQkJCQlqICs9IDQ7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCX0KCQkJCQl9CgkJCQkJZWxzZQoJCQkJCXsKCQkJCQkJaWYgKGogPj0gdmFsdWUuR2V0TGVuZ3RoKCkgfHwgZm9ybWF0LkdldEF0KGkpICE9IHZhbHVlLkdldEF0KGopKQoJCQkJCQl7CgkJCQkJCQliV3JvbmdGb3JtYXQgPSBUUlVFOwoJCQkJCQkJYkV4aXQgPSBUUlVFOwoJCQkJCQl9CgkJCQkJCWkrKzsKCQkJCQkJaisrOwoJCQkJCX0KCgkJCQkJaWYgKG9sZGogPT0gaikKCQkJCQl7CgkJCQkJCWJXcm9uZ0Zvcm1hdCA9IFRSVUU7CgkJCQkJCWJFeGl0ID0gVFJVRTsKCQkJCQl9CgkJCQl9CgoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQlpZiAodmFsdWUuR2V0TGVuZ3RoKCkgPD0gaikKCQkJCXsKCQkJCQliRXhpdCA9IFRSVUU7CgkJCQl9CgkJCQllbHNlIGlmIChmb3JtYXQuR2V0QXQoaSkgIT0gdmFsdWUuR2V0QXQoaikpCgkJCQl7CgkJCQkJYldyb25nRm9ybWF0ID0gVFJVRTsKCQkJCQliRXhpdCA9IFRSVUU7CgkJCQl9CgoJCQkJaSsrOwoJCQkJaisrOwoJCQkJYnJlYWs7CgkJfQoJfQoKCWlmIChiUG0pIG5Ib3VyICs9IDEyOwoKCWlmIChuWWVhciA+PSAwICYmIG5ZZWFyIDw9IG5ZZWFyU3ViKQoJCW5ZZWFyICs9IDIwMDA7CgoJaWYgKG5Nb250aCA8IDEgfHwgbk1vbnRoID4gMTIpCgkJYldyb25nRm9ybWF0ID0gVFJVRTsKCglpZiAobkRheSA8IDEgfHwgbkRheSA+IDMxKQoJCWJXcm9uZ0Zvcm1hdCA9IFRSVUU7CgoJaWYgKG5Ib3VyIDwgMCB8fCBuSG91ciA+IDI0KQoJCWJXcm9uZ0Zvcm1hdCA9IFRSVUU7CgoJaWYgKG5NaW4gPCAwIHx8IG5NaW4gPiA2MCkKCQliV3JvbmdGb3JtYXQgPSBUUlVFOwoKCWlmIChuU2VjIDwgMCB8fCBuU2VjID4gNjApCgkJYldyb25nRm9ybWF0ID0gVFJVRTsKCglkb3VibGUgZFJldCA9IDA7CgoJaWYgKGJXcm9uZ0Zvcm1hdCkKCXsKCQlkUmV0ID0gUGFyc2VOb3JtYWxEYXRlKHZhbHVlLCBiV3JvbmdGb3JtYXQpOwoJfQoJZWxzZQoJewoJCWRSZXQgPSBKU19NYWtlRGF0ZShKU19NYWtlRGF5KG5ZZWFyLG5Nb250aCAtIDEsbkRheSksSlNfTWFrZVRpbWUobkhvdXIsIG5NaW4sIG5TZWMsIDApKTsKCgkJaWYgKEpTX1BvcnRJc05hbihkUmV0KSkKCQl7CgkJCWRSZXQgPSBKU19EYXRlUGFyc2UodmFsdWUpOwoJCX0KCX0KCglpZiAoSlNfUG9ydElzTmFuKGRSZXQpKQoJewoJCWRSZXQgPSBQYXJzZU5vcm1hbERhdGUodmFsdWUsIGJXcm9uZ0Zvcm1hdCk7Cgl9CgoJcmV0dXJuIGRSZXQ7Cgp9CgpDRlhfV2lkZVN0cmluZyBDSlNfUHVibGljTWV0aG9kczo6TWFrZUZvcm1hdERhdGUoZG91YmxlIGREYXRlLCBjb25zdCBDRlhfV2lkZVN0cmluZyAmIGZvcm1hdCkKewoJQ0ZYX1dpZGVTdHJpbmcgc1JldCA9IEwiIixzUGFydCA9IEwiIjsKCglpbnQgblllYXIgPSBKU19HZXRZZWFyRnJvbVRpbWUoZERhdGUpOwoJaW50IG5Nb250aCA9IEpTX0dldE1vbnRoRnJvbVRpbWUoZERhdGUpICsgMTsKCWludCBuRGF5ID0gSlNfR2V0RGF5RnJvbVRpbWUoZERhdGUpOwoJaW50IG5Ib3VyID0gSlNfR2V0SG91ckZyb21UaW1lKGREYXRlKTsKCWludCBuTWluID0gSlNfR2V0TWluRnJvbVRpbWUoZERhdGUpOwoJaW50IG5TZWMgPSBKU19HZXRTZWNGcm9tVGltZShkRGF0ZSk7CgoJaW50IGkgPSAwOwoJd2hpbGUgKGkgPCBmb3JtYXQuR2V0TGVuZ3RoKCkpCgl7CgkgICAgICAgIEZYX1dDSEFSIGMgPSBmb3JtYXQuR2V0QXQoaSk7CiAgICAgICAgICAgICAgICBpbnQgcmVtYWluaW5nID0gZm9ybWF0LkdldExlbmd0aCgpIC0gaSAtIDE7CgkJc1BhcnQgPSBMIiI7CgkJc3dpdGNoIChjKQoJCXsKCQkJY2FzZSAneSc6CgkJCWNhc2UgJ20nOgoJCQljYXNlICdkJzoKCQkJY2FzZSAnSCc6CgkJCWNhc2UgJ2gnOgoJCQljYXNlICdNJzoKCQkJY2FzZSAncyc6CgkJCWNhc2UgJ3QnOgoJCQkJaWYgKHJlbWFpbmluZyA9PSAwIHx8IGZvcm1hdC5HZXRBdChpKzEpICE9IGMpCgkJCQl7CgkJCQkJc3dpdGNoIChjKQoJCQkJCXsKCQkJCQkJY2FzZSAneSc6CgkJCQkJCQlzUGFydCArPSBjOwoJCQkJCQkJYnJlYWs7CgkJCQkJCWNhc2UgJ20nOgoJCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJWQiLG5Nb250aCk7CgkJCQkJCQlicmVhazsKCQkJCQkJY2FzZSAnZCc6CgkJCQkJCQlzUGFydC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlZCIsbkRheSk7CgkJCQkJCQlicmVhazsKCQkJCQkJY2FzZSAnSCc6CgkJCQkJCQlzUGFydC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlZCIsbkhvdXIpOwoJCQkJCQkJYnJlYWs7CgkJCQkJCWNhc2UgJ2gnOgoJCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJWQiLG5Ib3VyPjEyP25Ib3VyIC0gMTI6bkhvdXIpOwoJCQkJCQkJYnJlYWs7CgkJCQkJCWNhc2UgJ00nOgoJCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJWQiLG5NaW4pOwoJCQkJCQkJYnJlYWs7CgkJCQkJCWNhc2UgJ3MnOgoJCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJWQiLG5TZWMpOwoJCQkJCQkJYnJlYWs7CgkJCQkJCWNhc2UgJ3QnOgoJCQkJCQkJc1BhcnQgKz0gbkhvdXI+MTI/J3AnOidhJzsKCQkJCQkJCWJyZWFrOwoJCQkJCX0KCQkJCQlpKys7CgkJCQl9CgkJCQllbHNlIGlmIChyZW1haW5pbmcgPT0gMSB8fCBmb3JtYXQuR2V0QXQoaSsyKSAhPSBjKQoJCQkJewoJCQkJCXN3aXRjaCAoYykKCQkJCQl7CgkJCQkJCWNhc2UgJ3knOgoJCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJTAyZCIsblllYXIgLSAoblllYXIgLyAxMDApICogMTAwKTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICdtJzoKCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiUwMmQiLG5Nb250aCk7CgkJCQkJCQlicmVhazsKCQkJCQkJY2FzZSAnZCc6CgkJCQkJCQlzUGFydC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlMDJkIixuRGF5KTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICdIJzoKCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiUwMmQiLG5Ib3VyKTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICdoJzoKCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiUwMmQiLG5Ib3VyPjEyP25Ib3VyIC0gMTI6bkhvdXIpOwoJCQkJCQkJYnJlYWs7CgkJCQkJCWNhc2UgJ00nOgoJCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJTAyZCIsbk1pbik7CgkJCQkJCQlicmVhazsKCQkJCQkJY2FzZSAncyc6CgkJCQkJCQlzUGFydC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlMDJkIixuU2VjKTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICd0JzoKCQkJCQkJCXNQYXJ0ID0gbkhvdXI+MTI/IChGWF9MUENXU1RSKUwicG0iOiAoRlhfTFBDV1NUUilMImFtIjsKCQkJCQkJCWJyZWFrOwoJCQkJCX0KCQkJCQlpKz0yOwoJCQkJfQoJCQkJZWxzZSBpZiAocmVtYWluaW5nID09IDIgfHwgZm9ybWF0LkdldEF0KGkrMykgIT0gYykKCQkJCXsKCQkJCQlzd2l0Y2ggKGMpCgkJCQkJewoJCQkJCQljYXNlICdtJzoKCQkJCQkJCWkrPTM7CgkJCQkJCQlpZiAobk1vbnRoID4gMCYmbk1vbnRoIDw9IDEyKQoJCQkJCQkJCXNQYXJ0ICs9IG1vbnRoc1tuTW9udGggLSAxXTsKCQkJCQkJCWJyZWFrOwoJCQkJCQlkZWZhdWx0OgoJCQkJCQkJaSs9MzsKCQkJCQkJCXNQYXJ0ICs9IGM7CgkJCQkJCQlzUGFydCArPSBjOwoJCQkJCQkJc1BhcnQgKz0gYzsKCQkJCQkJCWJyZWFrOwoJCQkJCX0KCQkJCX0KCQkJCWVsc2UgaWYgKHJlbWFpbmluZyA9PSAzIHx8IGZvcm1hdC5HZXRBdChpKzQpICE9IGMpCgkJCQl7CgkJCQkJc3dpdGNoIChjKQoJCQkJCXsKCQkJCQkJY2FzZSAneSc6CgkJCQkJCQlzUGFydC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlMDRkIixuWWVhcik7CgkJCQkJCQlpICs9IDQ7CgkJCQkJCQlicmVhazsKCQkJCQkJY2FzZSAnbSc6CgkJCQkJCQlpKz00OwoJCQkJCQkJaWYgKG5Nb250aCA+IDAmJm5Nb250aCA8PSAxMikKCQkJCQkJCQlzUGFydCArPSBmdWxsbW9udGhzW25Nb250aCAtIDFdOwoJCQkJCQkJYnJlYWs7CgkJCQkJCWRlZmF1bHQ6CgkJCQkJCQlpICs9IDQ7CgkJCQkJCQlzUGFydCArPSBjOwoJCQkJCQkJc1BhcnQgKz0gYzsKCQkJCQkJCXNQYXJ0ICs9IGM7CgkJCQkJCQlzUGFydCArPSBjOwoJCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJfQoJCQkJZWxzZQoJCQkJewoJCQkJCWkrKzsKCQkJCQlzUGFydCArPSBjOwoJCQkJfQoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQlpKys7CgkJCQlzUGFydCArPSBjOwoJCQkJYnJlYWs7CgkJfQoKCQlzUmV0ICs9IHNQYXJ0OwoJfQoKCXJldHVybiBzUmV0Owp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKLy9mdW5jdGlvbiBBRk51bWJlcl9Gb3JtYXQobkRlYywgc2VwU3R5bGUsIG5lZ1N0eWxlLCBjdXJyU3R5bGUsIHN0ckN1cnJlbmN5LCBiQ3VycmVuY3lQcmVwZW5kKQpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRk51bWJlcl9Gb3JtYXQoT0JKX01FVEhPRF9QQVJBTVMpCnsKI2lmIF9GWF9PU18gIT0gX0ZYX0FORFJPSURfCgl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IDo6R2V0SXNvbGF0ZShjYyk7CglDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsKCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7CgoJaWYgKHBhcmFtcy5zaXplKCkgIT0gNikKCXsKCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOwoJCXJldHVybiBGQUxTRTsKCX0KCWlmKCFwRXZlbnQtPm1fcFZhbHVlKQoJCXJldHVybiBGQUxTRTsKCUNGWF9XaWRlU3RyaW5nJiBWYWx1ZSA9IHBFdmVudC0+VmFsdWUoKTsJCglDRlhfQnl0ZVN0cmluZyBzdHJWYWx1ZSA9IFN0clRyaW0oQ0ZYX0J5dGVTdHJpbmc6OkZyb21Vbmljb2RlKFZhbHVlKSk7CgkKCWlmIChzdHJWYWx1ZS5Jc0VtcHR5KCkpIHJldHVybiBUUlVFOwoJCglpbnQgaURlYyA9IHBhcmFtc1swXTsKCWludCBpU2VwU3R5bGUgPSBwYXJhbXNbMV07CglpbnQgaU5lZ1N0eWxlID0gcGFyYW1zWzJdOwoJLy8gcGFyYW1zWzNdIGlzIGlDdXJyU3R5bGUsIGl0J3Mgbm90IHVzZWQuCglzdGQ6OndzdHJpbmcgd3N0ckN1cnJlbmN5KHBhcmFtc1s0XS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpKTsKCUZYX0JPT0wgYkN1cnJlbmN5UHJlcGVuZCA9IHBhcmFtc1s1XTsKCQoJaWYgKGlEZWMgPCAwKSBpRGVjID0gLWlEZWM7CgkKCWlmIChpU2VwU3R5bGUgPCAwIHx8IGlTZXBTdHlsZSA+IDMpCgkJaVNlcFN0eWxlID0gMDsKCQoJaWYgKGlOZWdTdHlsZSA8IDAgfHwgaU5lZ1N0eWxlID4gMykKCQlpTmVnU3R5bGUgPSAwOwoJCgkKCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwoJLy9mb3IgcHJvY2Vzc2luZyBkZWNpbWFsIHBsYWNlcwoJc3RyVmFsdWUuUmVwbGFjZSgiLCIsICIuIik7Cglkb3VibGUgZFZhbHVlID0gYXRvZihzdHJWYWx1ZSk7CglpZiAoaURlYyA+IDApCgkJZFZhbHVlICs9IERPVUJMRV9DT1JSRUNUOy8vCgkJICAgIAoJaW50IGlEZWMyOwoJRlhfQk9PTCBiTmFnYXRpdmUgPSBGQUxTRTsKCglzdHJWYWx1ZSA9IGZjdnQoZFZhbHVlLGlEZWMsJmlEZWMyLCZiTmFnYXRpdmUpOwoJaWYgKHN0clZhbHVlLklzRW1wdHkoKSkKCXsKCQlkVmFsdWUgPSAwOwoJCXN0clZhbHVlID0gZmN2dChkVmFsdWUsaURlYywmaURlYzIsJmJOYWdhdGl2ZSk7CgkJaWYgKHN0clZhbHVlLklzRW1wdHkoKSkKCQl7CgkJCXN0clZhbHVlID0gIjAiOwoJCQlpRGVjMiA9IDE7CgkJfQoKCX0KCglpZiAoaURlYzIgPCAwKQoJewoJCWZvciAoaW50IGlOdW0gPSAwO2lOdW0gPCBhYnMoaURlYzIpO2lOdW0rKykKCQl7CgkJCXN0clZhbHVlID0gIjAiICsgc3RyVmFsdWU7CgkJfQoJCWlEZWMyID0gMDsKCQkKCX0KCWludCBpTWF4ID0gc3RyVmFsdWUuR2V0TGVuZ3RoKCk7CglpZiAoaURlYzIgPiBpTWF4KQoJewoJCWZvciAoaW50IGlOdW0gPSAwO2lOdW0gPD0gaURlYzIgLSBpTWF4IDtpTnVtKyspCgkJewoJCQlzdHJWYWx1ZSArPSAiMCI7CgkJfQoJCWlNYXggPSBpRGVjMisxOwkJCQoJfQoJLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwogICAgLy9mb3IgcHJvY2Vzc2luZyBzZXBlcmF0b3Igc3R5bGUKCWlmIChpRGVjMiA8IGlNYXgpCgl7CgkJaWYgKGlTZXBTdHlsZSA9PSAwIHx8IGlTZXBTdHlsZSA9PSAxKQoJCXsKCQkJc3RyVmFsdWUuSW5zZXJ0KGlEZWMyLCAnLicpOwoJCQlpTWF4Kys7CgkJfQoJCWVsc2UgaWYgKGlTZXBTdHlsZSA9PSAyIHx8IGlTZXBTdHlsZSA9PSAzKQoJCXsKCQkJc3RyVmFsdWUuSW5zZXJ0KGlEZWMyLCAnLCcpOwoJCQlpTWF4Kys7CgkJfQoJCQoJCWlmIChpRGVjMiA9PSAwKQoJCQlzdHJWYWx1ZS5JbnNlcnQoaURlYzIsICcwJyk7Cgl9CglpZiAoaVNlcFN0eWxlID09IDAgfHwgaVNlcFN0eWxlID09IDIpCgl7CgkJY2hhciBjU2VwZXJhdG9yOwoJCWlmIChpU2VwU3R5bGUgPT0gMCkKCQkJY1NlcGVyYXRvciA9ICcsJzsKCQllbHNlCgkJCWNTZXBlcmF0b3IgPSAnLic7CgkJCgkJaW50IGlEZWNQb3NpdGl2ZSxpRGVjTmFnYXRpdmU7CgkJaURlY1Bvc2l0aXZlID0gaURlYzI7CgkJaURlY05hZ2F0aXZlID0gaURlYzI7CQkKCQkKCQlmb3IgKGlEZWNQb3NpdGl2ZSA9IGlEZWMyIC0zOyBpRGVjUG9zaXRpdmUgPiAwO2lEZWNQb3NpdGl2ZSAtPSAzKQoJCXsKCQkJc3RyVmFsdWUuSW5zZXJ0KGlEZWNQb3NpdGl2ZSwgY1NlcGVyYXRvcik7CgkJCWlNYXgrKzsKCQl9Cgl9CgkKCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KICAgIC8vZm9yIHByb2Nlc3NpbmcgY3VycmVuY3kgc3RyaW5nCgoJVmFsdWUgPSBDRlhfV2lkZVN0cmluZzo6RnJvbUxvY2FsKHN0clZhbHVlKTsKCQoJc3RkOjp3c3RyaW5nIHN0clZhbHVlMihWYWx1ZSk7CgoJaWYgKGJDdXJyZW5jeVByZXBlbmQpCgkJc3RyVmFsdWUyID0gd3N0ckN1cnJlbmN5ICsgc3RyVmFsdWUyOwoJZWxzZQoJCXN0clZhbHVlMiA9IHN0clZhbHVlMiArIHdzdHJDdXJyZW5jeTsKCQoJCgkKCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCS8vZm9yIHByb2Nlc3NpbmcgbmVnYXRpdmUgc3R5bGUKCWlmIChiTmFnYXRpdmUpCgl7CgkJaWYgKGlOZWdTdHlsZSA9PSAwKQoJCXsKCQkJc3RyVmFsdWUyLmluc2VydCgwLEwiLSIpOwoJCX0KCQlpZiAoaU5lZ1N0eWxlID09IDIgfHwgaU5lZ1N0eWxlID09IDMpCgkJewoJCQlzdHJWYWx1ZTIuaW5zZXJ0KDAsTCIoIik7CgkJCXN0clZhbHVlMi5pbnNlcnQoc3RyVmFsdWUyLmxlbmd0aCgpLEwiKSIpOwoJCX0KCQlpZiAoaU5lZ1N0eWxlID09IDEgfHwgaU5lZ1N0eWxlID09IDMpCgkJewoJCQlpZiAoRmllbGQgKiBmVGFyZ2V0ID0gcEV2ZW50LT5UYXJnZXRfRmllbGQoKSkKCQkJewoJCQkJQ0pTX0FycmF5IGFyQ29sb3IoaXNvbGF0ZSk7CgkJCQlDSlNfVmFsdWUgdkNvbEVsbShpc29sYXRlKTsKCQkJCXZDb2xFbG0gPSBMIlJHQiI7CgkJCQlhckNvbG9yLlNldEVsZW1lbnQoMCx2Q29sRWxtKTsKCQkJCXZDb2xFbG0gPSAxOwoJCQkJYXJDb2xvci5TZXRFbGVtZW50KDEsdkNvbEVsbSk7CgkJCQl2Q29sRWxtID0gMDsKCQkJCWFyQ29sb3IuU2V0RWxlbWVudCgyLHZDb2xFbG0pOwoJCQkJCgkJCQlhckNvbG9yLlNldEVsZW1lbnQoMyx2Q29sRWxtKTsKCQkJCQoJCQkJQ0pTX1Byb3BWYWx1ZSB2UHJvcChpc29sYXRlKTsKCQkJCXZQcm9wLlN0YXJ0R2V0dGluZygpOwoJCQkJdlByb3A8PGFyQ29sb3I7CgkJCQl2UHJvcC5TdGFydFNldHRpbmcoKTsKCQkJCWZUYXJnZXQtPnRleHRDb2xvcihjYyx2UHJvcCxzRXJyb3IpOy8vIHJlZAoJCQl9CgkJfQoJfQoJZWxzZQoJewoJCWlmIChpTmVnU3R5bGUgPT0gMSB8fCBpTmVnU3R5bGUgPT0gMykKCQl7CgkJCWlmIChGaWVsZCAqZlRhcmdldCA9IHBFdmVudC0+VGFyZ2V0X0ZpZWxkKCkpCgkJCXsKCQkJCUNKU19BcnJheSBhckNvbG9yKGlzb2xhdGUpOwoJCQkJQ0pTX1ZhbHVlIHZDb2xFbG0oaXNvbGF0ZSk7CgkJCQl2Q29sRWxtID0gTCJSR0IiOwoJCQkJYXJDb2xvci5TZXRFbGVtZW50KDAsdkNvbEVsbSk7CgkJCQl2Q29sRWxtID0gMDsKCQkJCWFyQ29sb3IuU2V0RWxlbWVudCgxLHZDb2xFbG0pOwoJCQkJYXJDb2xvci5TZXRFbGVtZW50KDIsdkNvbEVsbSk7CgkJCQlhckNvbG9yLlNldEVsZW1lbnQoMyx2Q29sRWxtKTsKCQkJCQoJCQkJQ0pTX1Byb3BWYWx1ZSB2UHJvcChpc29sYXRlKTsKCQkJCXZQcm9wLlN0YXJ0R2V0dGluZygpOwoJCQkJZlRhcmdldC0+dGV4dENvbG9yKGNjLHZQcm9wLHNFcnJvcik7CgkJCQkKCQkJCUNKU19BcnJheSBhUHJvcChpc29sYXRlKTsKCQkJCXZQcm9wLkNvbnZlcnRUb0FycmF5KGFQcm9wKTsKCgkJCQlDUFdMX0NvbG9yIGNyUHJvcDsKCQkJCUNQV0xfQ29sb3IgY3JDb2xvcjsKCQkJCWNvbG9yOjpDb252ZXJ0QXJyYXlUb1BXTENvbG9yKGFQcm9wLCBjclByb3ApOwoJCQkJY29sb3I6OkNvbnZlcnRBcnJheVRvUFdMQ29sb3IoYXJDb2xvciwgY3JDb2xvcik7CgoJCQkJaWYgKGNyQ29sb3IgIT0gY3JQcm9wKQoJCQkJewoJCQkJCUNKU19Qcm9wVmFsdWUgdlByb3AyKGlzb2xhdGUpOwoJCQkJCXZQcm9wMi5TdGFydEdldHRpbmcoKTsKCQkJCQl2UHJvcDI8PGFyQ29sb3I7CgkJCQkJdlByb3AyLlN0YXJ0U2V0dGluZygpOwogICAgIAkJCQlmVGFyZ2V0LT50ZXh0Q29sb3IoY2MsdlByb3AyLHNFcnJvcik7CgkJCQl9CgkJCX0KCQl9Cgl9CglWYWx1ZSA9IHN0clZhbHVlMi5jX3N0cigpOwojZW5kaWYKCXJldHVybiBUUlVFOwp9CgovL2Z1bmN0aW9uIEFGTnVtYmVyX0tleXN0cm9rZShuRGVjLCBzZXBTdHlsZSwgbmVnU3R5bGUsIGN1cnJTdHlsZSwgc3RyQ3VycmVuY3ksIGJDdXJyZW5jeVByZXBlbmQpCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGTnVtYmVyX0tleXN0cm9rZShPQkpfTUVUSE9EX1BBUkFNUykKewoJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7CglBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CglDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7CglBU1NFUlQocEV2ZW50ICE9IE5VTEwpOwoJCglpZihwYXJhbXMuc2l6ZSgpIDwgMikKCQlyZXR1cm4gRkFMU0U7CglpbnQgaVNlcFN0eWxlID0gcGFyYW1zWzFdOwoJCglpZiAoaVNlcFN0eWxlIDwgMCB8fCBpU2VwU3R5bGUgPiAzKQoJCWlTZXBTdHlsZSA9IDA7CglpZighcEV2ZW50LT5tX3BWYWx1ZSkKCQlyZXR1cm4gRkFMU0U7CglDRlhfV2lkZVN0cmluZyAmIHZhbCA9IHBFdmVudC0+VmFsdWUoKTsJCglDRlhfV2lkZVN0cmluZyAmIHdfc3RyQ2hhbmdlID0gcEV2ZW50LT5DaGFuZ2UoKTsKICAgIENGWF9XaWRlU3RyaW5nIHdfc3RyVmFsdWUgPSB2YWw7CgoJaWYgKHBFdmVudC0+V2lsbENvbW1pdCgpKQoJewoJCUNGWF9XaWRlU3RyaW5nIHdzdHJDaGFuZ2UgPSB3X3N0ckNoYW5nZTsKCQlDRlhfV2lkZVN0cmluZyB3c3RyVmFsdWUgPSBTdHJMVHJpbSh3X3N0clZhbHVlKTsKCQlpZiAod3N0clZhbHVlLklzRW1wdHkoKSkKCQkJcmV0dXJuIFRSVUU7CgkJCgkJQ0ZYX1dpZGVTdHJpbmcgc3dUZW1wID0gd3N0clZhbHVlOwoJCXN3VGVtcC5SZXBsYWNlKChGWF9MUENXU1RSKUwiLCIsIChGWF9MUENXU1RSKUwiLiIpOwoJCWlmICghSXNOdW1iZXIoc3dUZW1wKSkgLy8hKElzTnVtYmVyKHdzdHJDaGFuZ2UpICYmIAoJCXsKCQkJcEV2ZW50LT5SYygpID0gRkFMU0U7CgkJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTQUZOVU1CRVJfS0VZU1RST0tFKTsKCQkJQWxlcnQocENvbnRleHQsIHNFcnJvcik7CgkJCXJldHVybiBUUlVFOwoJCX0KCQlyZXR1cm4gVFJVRTsgLy8gaXQgaGFwcGVucyBhZnRlciB0aGUgbGFzdCBrZXlzdHJva2UgYW5kIGJlZm9yZSB2YWxpZGF0aW5nLAoJfQoJCglzdGQ6OndzdHJpbmcgd19zdHJWYWx1ZTIgKHdfc3RyVmFsdWUpOwoJc3RkOjp3c3RyaW5nIHdfc3RyQ2hhbmdlMih3X3N0ckNoYW5nZSk7CgkKCXN0ZDo6d3N0cmluZyB3X3N0clNlbGVjdGVkOwoJaWYoLTEgIT0gcEV2ZW50LT5TZWxTdGFydCgpKQoJCXdfc3RyU2VsZWN0ZWQgPSB3X3N0clZhbHVlMi5zdWJzdHIocEV2ZW50LT5TZWxTdGFydCgpLChwRXZlbnQtPlNlbEVuZCgpIC0gcEV2ZW50LT5TZWxTdGFydCgpKSk7CglGWF9CT09MIGJIYXNTaWduID0gKHdfc3RyVmFsdWUyLmZpbmQoJy0nKSAhPSAtMSkgJiYgKHdfc3RyU2VsZWN0ZWQuZmluZCgnLScpID09IC0xKTsKCWlmIChiSGFzU2lnbikKCXsKCQkvL2Nhbid0IGluc2VydCAiY2hhbmdlIiBpbiBmcm9udCB0byBzaWduIHBvc3Rpb24uCgkJaWYgKHBFdmVudC0+U2VsU3RhcnQoKSA9PSAwKQoJCXsKICAgICAgICAgICAgRlhfQk9PTCAmYlJjID0gcEV2ZW50LT5SYygpOwoJCQliUmMgPSBGQUxTRTsKCQkJcmV0dXJuIFRSVUU7CgkJfQoJfQoKCWNoYXIgY1NlcCA9IEwnLic7CgoJc3dpdGNoIChpU2VwU3R5bGUpCgl7CgljYXNlIDA6CgljYXNlIDE6CgkJY1NlcCA9IEwnLic7CgkJYnJlYWs7CgljYXNlIDI6CgljYXNlIDM6CgkJY1NlcCA9IEwnLCc7CgkJYnJlYWs7Cgl9CgkKCUZYX0JPT0wgYkhhc1NlcCA9ICh3X3N0clZhbHVlMi5maW5kKGNTZXApICE9IC0xKTsKCWZvciAoc3RkOjp3c3RyaW5nOjppdGVyYXRvciBpdCA9IHdfc3RyQ2hhbmdlMi5iZWdpbigpOyBpdCAhPSB3X3N0ckNoYW5nZTIuZW5kKCk7IGl0KyspCgl7CgkJaWYgKCppdCA9PSBjU2VwKQoJCXsKCQkJaWYgKGJIYXNTZXApCgkJCXsKCQkJCUZYX0JPT0wgJmJSYyA9IHBFdmVudC0+UmMoKTsKCQkJCWJSYyA9IEZBTFNFOwoJCQkJcmV0dXJuIFRSVUU7CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQliSGFzU2VwID0gVFJVRTsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJfQoJCWlmICgqaXQgPT0gTCctJykKCQl7CgkJCWlmIChiSGFzU2lnbikKCQkJewoJCQkJRlhfQk9PTCAmYlJjID0gcEV2ZW50LT5SYygpOwoJCQkJYlJjID0gRkFMU0U7CgkJCQlyZXR1cm4gVFJVRTsKCQkJfQoJCQllbHNlIGlmIChpdCAhPSB3X3N0ckNoYW5nZTIuYmVnaW4oKSkgLy9zaWduJ3MgcG9zaXRpb24gaXMgbm90IGNvcnJlY3QKCQkJewoJCQkJRlhfQk9PTCAmYlJjID0gcEV2ZW50LT5SYygpOwoJCQkJYlJjID0gRkFMU0U7CgkJCQlyZXR1cm4gVFJVRTsKCQkJfQoJCQllbHNlIGlmIChwRXZlbnQtPlNlbFN0YXJ0KCkgIT0gMCkKCQkJewoJCQkJRlhfQk9PTCAmYlJjID0gcEV2ZW50LT5SYygpOwoJCQkJYlJjID0gRkFMU0U7CgkJCQlyZXR1cm4gVFJVRTsKCQkJfQoJCQliSGFzU2lnbiA9IFRSVUU7CgkJCWNvbnRpbnVlOwoJCX0KCQkKCQlpZiAoIUlzRGlnaXQoKml0KSkKCQl7CQkJCgkJCUZYX0JPT0wgJmJSYyA9IHBFdmVudC0+UmMoKTsKCQkJYlJjID0gRkFMU0U7CgkJCXJldHVybiBUUlVFOwoJCX0KCX0KCQoJCglzdGQ6OndzdHJpbmcgd19wcmVmaXggPSB3X3N0clZhbHVlMi5zdWJzdHIoMCxwRXZlbnQtPlNlbFN0YXJ0KCkpOwoJc3RkOjp3c3RyaW5nIHdfcG9zdGZpeDsKCWlmIChwRXZlbnQtPlNlbEVuZCgpPChpbnQpd19zdHJWYWx1ZTIubGVuZ3RoKCkpCgkJd19wb3N0Zml4ICA9IHdfc3RyVmFsdWUyLnN1YnN0cihwRXZlbnQtPlNlbEVuZCgpKTsKCXdfc3RyVmFsdWUyID0gd19wcmVmaXggKyB3X3N0ckNoYW5nZTIgKyB3X3Bvc3RmaXg7Cgl3X3N0clZhbHVlID0gd19zdHJWYWx1ZTIuY19zdHIoKTsKCXZhbCA9IHdfc3RyVmFsdWU7CglyZXR1cm4gVFJVRTsJCQoJCn0KCi8vZnVuY3Rpb24gQUZQZXJjZW50X0Zvcm1hdChuRGVjLCBzZXBTdHlsZSkKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZQZXJjZW50X0Zvcm1hdChPQkpfTUVUSE9EX1BBUkFNUykKewojaWYgX0ZYX09TXyAhPSBfRlhfQU5EUk9JRF8KCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOwoJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOwoJQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOwoJQVNTRVJUKHBFdmVudCAhPSBOVUxMKTsKCiAgICBpZiAocGFyYW1zLnNpemUoKSAhPSAyKQoJewoJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CgkJcmV0dXJuIEZBTFNFOwoJfQoJaWYoIXBFdmVudC0+bV9wVmFsdWUpCgkJcmV0dXJuIEZBTFNFOwoJQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlID0gcEV2ZW50LT5WYWx1ZSgpOwoJCi8vICAgICBIV05EIGhNYWluRnJhbWUgPSBOVUxMOwovLyAJCi8vIAlDUERGU0RLX0Zvcm1GaWxsQXBwICpwQXBwID0gcENvbnRleHQtPkdldFJlYWRlckFwcCgpOwovLyAJQVNTRVJUKHBBcHApOwovLyAJaE1haW5GcmFtZSA9IHBBcHAtPkdldE1haW5GcmFtZVduZCgpOwoJCQoJQ0ZYX0J5dGVTdHJpbmcgc3RyVmFsdWUgPSBTdHJUcmltKENGWF9CeXRlU3RyaW5nOjpGcm9tVW5pY29kZShWYWx1ZSkpOwoJCglpZiAoc3RyVmFsdWUuSXNFbXB0eSgpKQoJCXJldHVybiBUUlVFOwoJCglpbnQgaURlYyA9IHBhcmFtc1swXTsKCWludCBpU2VwU3R5bGUgPSBwYXJhbXNbMV07CgkKCS8vQVNTRVJUKGlEZWMgPiAwKTsKCWlmIChpRGVjIDwgMCkKCQlpRGVjID0gLWlEZWM7CgkKCWlmIChpU2VwU3R5bGUgPCAwIHx8IGlTZXBTdHlsZSA+IDMpCgkJaVNlcFN0eWxlID0gMDsKCQoJCgkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCS8vZm9yIHByb2Nlc3NpbmcgZGVjaW1hbCBwbGFjZXMKCWRvdWJsZSBkVmFsdWUgPSBhdG9mKHN0clZhbHVlKTsKCWRWYWx1ZSAqPSAxMDA7CglpZiAoaURlYyA+IDApCgkJZFZhbHVlICs9IERPVUJMRV9DT1JSRUNUOy8v0KPV/QoKCWludCBpRGVjMjsKCUZYX0JPT0wgYk5hZ2F0aXZlID0gRkFMU0U7CglzdHJWYWx1ZSA9IGZjdnQoZFZhbHVlLGlEZWMsJmlEZWMyLCZiTmFnYXRpdmUpOwogICAgaWYgKHN0clZhbHVlLklzRW1wdHkoKSkKCXsKCQlkVmFsdWUgPSAwOwoJCXN0clZhbHVlID0gZmN2dChkVmFsdWUsaURlYywmaURlYzIsJmJOYWdhdGl2ZSk7Cgl9CgoJaWYgKGlEZWMyIDwgMCkKCXsKCQlmb3IgKGludCBpTnVtID0gMDsgaU51bSA8IGFicyhpRGVjMik7IGlOdW0rKykKCQl7CgkJCXN0clZhbHVlID0gIjAiICsgc3RyVmFsdWU7CgkJfQoJCWlEZWMyID0gMDsKCQkKCX0KCWludCBpTWF4ID0gc3RyVmFsdWUuR2V0TGVuZ3RoKCk7CglpZiAoaURlYzIgPiBpTWF4KQoJewoJCWZvciAoaW50IGlOdW0gPSAwOyBpTnVtIDw9IGlEZWMyIC0gaU1heDsgaU51bSsrKQoJCXsKCQkJc3RyVmFsdWUgKz0gIjAiOwoJCX0KCQlpTWF4ID0gaURlYzIrMTsJCQkKCX0KCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KICAgIC8vZm9yIHByb2Nlc3Npbmcgc2VwZXJhdG9yIHN0eWxlCglpZiAoaURlYzIgPCBpTWF4KQoJewoJCWlmIChpU2VwU3R5bGUgPT0gMCB8fCBpU2VwU3R5bGUgPT0gMSkKCQl7CgkJCXN0clZhbHVlLkluc2VydChpRGVjMiwgJy4nKTsKCQkJaU1heCsrOwoJCX0KCQllbHNlIGlmIChpU2VwU3R5bGUgPT0gMiB8fCBpU2VwU3R5bGUgPT0gMykKCQl7CgkJCXN0clZhbHVlLkluc2VydChpRGVjMiwgJywnKTsKCQkJaU1heCsrOwoJCX0KCQkKCQlpZiAoaURlYzIgPT0gMCkKCQkJc3RyVmFsdWUuSW5zZXJ0KGlEZWMyLCAnMCcpOwoJfQoJaWYgKGlTZXBTdHlsZSA9PSAwIHx8IGlTZXBTdHlsZSA9PSAyKQoJewoJCWNoYXIgY1NlcGVyYXRvcjsKCQlpZiAoaVNlcFN0eWxlID09IDApCgkJCWNTZXBlcmF0b3IgPSAnLCc7CgkJZWxzZQoJCQljU2VwZXJhdG9yID0gJy4nOwoJCQoJCWludCBpRGVjUG9zaXRpdmUsaURlY05hZ2F0aXZlOwoJCWlEZWNQb3NpdGl2ZSA9IGlEZWMyOwoJCWlEZWNOYWdhdGl2ZSA9IGlEZWMyOwoJCQkKCQlmb3IgKGlEZWNQb3NpdGl2ZSA9IGlEZWMyIC0zOyBpRGVjUG9zaXRpdmUgPiAwOyBpRGVjUG9zaXRpdmUgLT0gMykKCQl7CgkJCXN0clZhbHVlLkluc2VydChpRGVjUG9zaXRpdmUsY1NlcGVyYXRvcik7CgkJCWlNYXgrKzsKCQl9Cgl9CgkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwoJLy9uYWdhdGl2ZSBtYXJrCglpZihiTmFnYXRpdmUpCgkJc3RyVmFsdWUgPSAiLSIgKyBzdHJWYWx1ZTsKCXN0clZhbHVlICs9ICIlIjsKCVZhbHVlID0gQ0ZYX1dpZGVTdHJpbmc6OkZyb21Mb2NhbChzdHJWYWx1ZSk7CiNlbmRpZgoJcmV0dXJuIFRSVUU7Cn0KLy9BRlBlcmNlbnRfS2V5c3Ryb2tlKG5EZWMsIHNlcFN0eWxlKQpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRlBlcmNlbnRfS2V5c3Ryb2tlKE9CSl9NRVRIT0RfUEFSQU1TKQp7CglyZXR1cm4gQUZOdW1iZXJfS2V5c3Ryb2tlKGNjLHBhcmFtcyx2UmV0LHNFcnJvcik7Cn0KCi8vZnVuY3Rpb24gQUZEYXRlX0Zvcm1hdEV4KGNGb3JtYXQpCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGRGF0ZV9Gb3JtYXRFeChPQkpfTUVUSE9EX1BBUkFNUykKewoJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7CglBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CglDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7CglBU1NFUlQocEV2ZW50ICE9IE5VTEwpOwoKCWlmIChwYXJhbXMuc2l6ZSgpICE9IDEpCgl7CgkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CQoJaWYoIXBFdmVudC0+bV9wVmFsdWUpCgkJcmV0dXJuIEZBTFNFOwoJQ0ZYX1dpZGVTdHJpbmcmIHZhbCA9IHBFdmVudC0+VmFsdWUoKTsKCQoJQ0ZYX1dpZGVTdHJpbmcgc3RyVmFsdWUgPSB2YWw7CQoJaWYgKHN0clZhbHVlLklzRW1wdHkoKSkgcmV0dXJuIFRSVUU7CQkKCglDRlhfV2lkZVN0cmluZyBzRm9ybWF0ID0gcGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CgoJRlhfQk9PTCBiV3JvbmdGb3JtYXQgPSBGQUxTRTsKCWRvdWJsZSBkRGF0ZSA9IDAuMGY7CgoJaWYoc3RyVmFsdWUuRmluZChMIkdNVCIpICE9IC0xKQoJewoJCS8vZm9yIEdNVCBmb3JtYXQgdGltZQoJCS8vc3VjaCBhcyAiVHVlIEF1ZyAxMSAxNDoyNDoxNiBHTVQrMDgwMDIwMDkiCgkJZERhdGUgPSBNYWtlSW50ZXJEYXRlKHN0clZhbHVlKTsKCX0KCWVsc2UKCXsKCQlkRGF0ZSA9IE1ha2VSZWd1bGFyRGF0ZShzdHJWYWx1ZSxzRm9ybWF0LGJXcm9uZ0Zvcm1hdCk7Cgl9CgoJaWYgKEpTX1BvcnRJc05hbihkRGF0ZSkpCgl7CgkJQ0ZYX1dpZGVTdHJpbmcgc3dNc2c7CgkJc3dNc2cuRm9ybWF0KEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSU0VEQVRFKSwgKEZYX0xQQ1dTVFIpc0Zvcm1hdCk7CgkJQWxlcnQocENvbnRleHQsIHN3TXNnKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CgkKCXZhbCA9ICBNYWtlRm9ybWF0RGF0ZShkRGF0ZSxzRm9ybWF0KTsKCglyZXR1cm4gVFJVRTsKfQoKZG91YmxlIENKU19QdWJsaWNNZXRob2RzOjpNYWtlSW50ZXJEYXRlKENGWF9XaWRlU3RyaW5nIHN0clZhbHVlKQp7CglpbnQgbkhvdXI7CglpbnQgbk1pbjsKCWludCBuU2VjOwoJaW50IG5ZZWFyOwoJaW50IG5Nb250aDsKCWludCBuRGF5OwoKCUNGWF9XaWRlU3RyaW5nQXJyYXkgd3NBcnJheTsKCUNGWF9XaWRlU3RyaW5nIHNNb250aCA9IEwiIjsKCUNGWF9XaWRlU3RyaW5nIHNUZW1wID0gTCIiOwoJaW50IG5TaXplID0gc3RyVmFsdWUuR2V0TGVuZ3RoKCk7CgoJZm9yKGludCBpID0gMDsgaSA8IG5TaXplOyBpKyspCgl7CgkJRlhfV0NIQVIgYyA9IHN0clZhbHVlLkdldEF0KGkpOwoJCWlmKGMgPT0gTCcgJyB8fCBjID09IEwnOicpCgkJewkKCQkJd3NBcnJheS5BZGQoc1RlbXApOwoJCQlzVGVtcCA9IEwiIjsKCQkJY29udGludWU7CgkJfQoKCQlzVGVtcCArPSBjOwoJfQoJCgl3c0FycmF5LkFkZChzVGVtcCk7CglpZih3c0FycmF5LkdldFNpemUoKSAhPSA4KXJldHVybiAwOwoKCXNUZW1wID0gd3NBcnJheVsxXTsKCWlmKHNUZW1wLkNvbXBhcmUoTCJKYW4iKSA9PSAwKSBuTW9udGggPSAxOwoJaWYoc1RlbXAuQ29tcGFyZShMIkZlYiIpID09IDApIG5Nb250aCA9IDI7CglpZihzVGVtcC5Db21wYXJlKEwiTWFyIikgPT0gMCkgbk1vbnRoID0gMzsKCWlmKHNUZW1wLkNvbXBhcmUoTCJBcHIiKSA9PSAwKSBuTW9udGggPSA0OwoJaWYoc1RlbXAuQ29tcGFyZShMIk1heSIpID09IDApIG5Nb250aCA9IDU7CglpZihzVGVtcC5Db21wYXJlKEwiSnVuIikgPT0gMCkgbk1vbnRoID0gNjsKCWlmKHNUZW1wLkNvbXBhcmUoTCJKdWwiKSA9PSAwKSBuTW9udGggPSA3OwoJaWYoc1RlbXAuQ29tcGFyZShMIkF1ZyIpID09IDApIG5Nb250aCA9IDg7CglpZihzVGVtcC5Db21wYXJlKEwiU2VwIikgPT0gMCkgbk1vbnRoID0gOTsKCWlmKHNUZW1wLkNvbXBhcmUoTCJPY3QiKSA9PSAwKSBuTW9udGggPSAxMDsKCWlmKHNUZW1wLkNvbXBhcmUoTCJOb3YiKSA9PSAwKSBuTW9udGggPSAxMTsKCWlmKHNUZW1wLkNvbXBhcmUoTCJEZWMiKSA9PSAwKSBuTW9udGggPSAxMjsKCgluRGF5ID0gKGludClQYXJzZVN0cmluZ1RvTnVtYmVyKHdzQXJyYXlbMl0pOwoJbkhvdXIgPSAoaW50KVBhcnNlU3RyaW5nVG9OdW1iZXIod3NBcnJheVszXSk7CgluTWluID0gKGludClQYXJzZVN0cmluZ1RvTnVtYmVyKHdzQXJyYXlbNF0pOwoJblNlYyA9IChpbnQpUGFyc2VTdHJpbmdUb051bWJlcih3c0FycmF5WzVdKTsKCW5ZZWFyID0gKGludClQYXJzZVN0cmluZ1RvTnVtYmVyKHdzQXJyYXlbN10pOwoKCWRvdWJsZSBkUmV0ID0gSlNfTWFrZURhdGUoSlNfTWFrZURheShuWWVhcixuTW9udGggLSAxLG5EYXkpLEpTX01ha2VUaW1lKG5Ib3VyLCBuTWluLCBuU2VjLCAwKSk7CgoJaWYgKEpTX1BvcnRJc05hbihkUmV0KSkKCXsKCQlkUmV0ID0gSlNfRGF0ZVBhcnNlKHN0clZhbHVlKTsKCX0KCQoJcmV0dXJuIGRSZXQ7Cn0KCi8vQUZEYXRlX0tleXN0cm9rZUV4KGNGb3JtYXQpCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGRGF0ZV9LZXlzdHJva2VFeChPQkpfTUVUSE9EX1BBUkFNUykKewoJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7CglBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CglDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7CglBU1NFUlQocEV2ZW50ICE9IE5VTEwpOwoKCWlmIChwYXJhbXMuc2l6ZSgpICE9IDEpCgl7CgkJc0Vycm9yID0gTCJBRkRhdGVfS2V5c3Ryb2tlRXgncyBwYXJhbWV0ZXJzJyBzaXplIHIgbm90IGNvcnJlY3QiOwoJCXJldHVybiBGQUxTRTsKCX0JCgkKCWlmIChwRXZlbnQtPldpbGxDb21taXQoKSkKCXsKCQlpZighcEV2ZW50LT5tX3BWYWx1ZSkKCQkJcmV0dXJuIEZBTFNFOwoJCUNGWF9XaWRlU3RyaW5nIHN0clZhbHVlID0gcEV2ZW50LT5WYWx1ZSgpOwoJCWlmIChzdHJWYWx1ZS5Jc0VtcHR5KCkpIHJldHVybiBUUlVFOwoKCQlDRlhfV2lkZVN0cmluZyBzRm9ybWF0ID0gcGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CgoJCUZYX0JPT0wgYldyb25nRm9ybWF0ID0gRkFMU0U7CgkJZG91YmxlIGRSZXQgPSBNYWtlUmVndWxhckRhdGUoc3RyVmFsdWUsc0Zvcm1hdCxiV3JvbmdGb3JtYXQpOwoJCWlmIChiV3JvbmdGb3JtYXQgfHwgSlNfUG9ydElzTmFuKGRSZXQpKQoJCXsKCQkJQ0ZYX1dpZGVTdHJpbmcgc3dNc2c7CgkJCXN3TXNnLkZvcm1hdChKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUlNFREFURSksIChGWF9MUENXU1RSKXNGb3JtYXQpOwoJCQlBbGVydChwQ29udGV4dCwgc3dNc2cpOwoJCQlwRXZlbnQtPlJjKCkgPSBGQUxTRTsKCQkJcmV0dXJuIFRSVUU7CgkJfQoJfQoJcmV0dXJuIFRSVUU7Cn0KCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGRGF0ZV9Gb3JtYXQoT0JKX01FVEhPRF9QQVJBTVMpCnsKCXY4OjpJc29sYXRlKiBpc29sYXRlID0gOjpHZXRJc29sYXRlKGNjKTsKCglpZiAocGFyYW1zLnNpemUoKSAhPSAxKQoJewoJCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CgkJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOwoKCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOwoJCXJldHVybiBGQUxTRTsKCX0KCglpbnQgaUluZGV4ID0gcGFyYW1zWzBdOwoJRlhfTFBDV1NUUiBjRm9ybWF0c1tdID0gIHsoRlhfTFBDV1NUUilMIm0vZCIsIChGWF9MUENXU1RSKUwibS9kL3l5IiwgKEZYX0xQQ1dTVFIpTCJtbS9kZC95eSIsIChGWF9MUENXU1RSKUwibW0veXkiLCAoRlhfTFBDV1NUUilMImQtbW1tIiwgKEZYX0xQQ1dTVFIpTCJkLW1tbS15eSIsIChGWF9MUENXU1RSKUwiZGQtbW1tLXl5IiwKCQkoRlhfTFBDV1NUUilMInl5LW1tLWRkIiwgKEZYX0xQQ1dTVFIpTCJtbW0teXkiLCAoRlhfTFBDV1NUUilMIm1tbW0teXkiLCAoRlhfTFBDV1NUUilMIm1tbSBkLCB5eXl5IiwgKEZYX0xQQ1dTVFIpTCJtbW1tIGQsIHl5eXkiLAoJCShGWF9MUENXU1RSKUwibS9kL3l5IGg6TU0gdHQiLCAoRlhfTFBDV1NUUilMIm0vZC95eSBISDpNTSIgfTsKCglBU1NFUlQoaUluZGV4IDwgc2l6ZW9mKGNGb3JtYXRzKS9zaXplb2YoRlhfTFBDV1NUUikpOwoKCWlmIChpSW5kZXggPCAwKQoJCWlJbmRleCA9IDA7CglpZiAoaUluZGV4ID49IHNpemVvZihjRm9ybWF0cykvc2l6ZW9mKEZYX0xQQ1dTVFIpKQoJCWlJbmRleCA9IDA7CglDSlNfUGFyYW1ldGVycyBuZXdQYXJhbXM7CglDSlNfVmFsdWUgdmFsKGlzb2xhdGUsY0Zvcm1hdHNbaUluZGV4XSk7CgluZXdQYXJhbXMucHVzaF9iYWNrKHZhbCk7CglyZXR1cm4gQUZEYXRlX0Zvcm1hdEV4KGNjLG5ld1BhcmFtcyx2UmV0LHNFcnJvcik7Cn0KCi8vQUZEYXRlX0tleXN0cm9rZUV4KGNGb3JtYXQpCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGRGF0ZV9LZXlzdHJva2UoT0JKX01FVEhPRF9QQVJBTVMpCnsKCXY4OjpJc29sYXRlKiBpc29sYXRlID0gOjpHZXRJc29sYXRlKGNjKTsKCglpZiAocGFyYW1zLnNpemUoKSAhPSAxKQoJewoJCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CgkJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOwoKCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOwoJCXJldHVybiBGQUxTRTsKCX0KCglpbnQgaUluZGV4ID0gcGFyYW1zWzBdOwoJRlhfTFBDV1NUUiBjRm9ybWF0c1tdID0gIHsoRlhfTFBDV1NUUilMIm0vZCIsIChGWF9MUENXU1RSKUwibS9kL3l5IiwgKEZYX0xQQ1dTVFIpTCJtbS9kZC95eSIsIChGWF9MUENXU1RSKUwibW0veXkiLCAoRlhfTFBDV1NUUilMImQtbW1tIiwgKEZYX0xQQ1dTVFIpTCJkLW1tbS15eSIsIChGWF9MUENXU1RSKUwiZGQtbW1tLXl5IiwKCQkoRlhfTFBDV1NUUilMInl5LW1tLWRkIiwgKEZYX0xQQ1dTVFIpTCJtbW0teXkiLCAoRlhfTFBDV1NUUilMIm1tbW0teXkiLCAoRlhfTFBDV1NUUilMIm1tbSBkLCB5eXl5IiwgKEZYX0xQQ1dTVFIpTCJtbW1tIGQsIHl5eXkiLAoJCShGWF9MUENXU1RSKUwibS9kL3l5IGg6TU0gdHQiLCAoRlhfTFBDV1NUUilMIm0vZC95eSBISDpNTSIgfTsKCglBU1NFUlQoaUluZGV4PHNpemVvZihjRm9ybWF0cykvc2l6ZW9mKEZYX0xQQ1dTVFIpKTsKCglpZiAoaUluZGV4IDwgMCkKCQlpSW5kZXggPSAwOwoJaWYgKGlJbmRleCA+PSBzaXplb2YoY0Zvcm1hdHMpL3NpemVvZihGWF9MUENXU1RSKSkKCQlpSW5kZXggPSAwOwoJQ0pTX1BhcmFtZXRlcnMgbmV3UGFyYW1zOwoJQ0pTX1ZhbHVlIHZhbChpc29sYXRlLGNGb3JtYXRzW2lJbmRleF0pOwoJbmV3UGFyYW1zLnB1c2hfYmFjayh2YWwpOwoJcmV0dXJuIEFGRGF0ZV9LZXlzdHJva2VFeChjYyxuZXdQYXJhbXMsdlJldCxzRXJyb3IpOwp9CgovL2Z1bmN0aW9uIEFGVGltZV9Gb3JtYXQocHRmKQpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRlRpbWVfRm9ybWF0KE9CSl9NRVRIT0RfUEFSQU1TKQp7Cgl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IDo6R2V0SXNvbGF0ZShjYyk7CgoJaWYgKHBhcmFtcy5zaXplKCkgIT0gMSkKCXsKCQlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQqKWNjOwoJCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOwoJCXJldHVybiBGQUxTRTsKCX0KCglpbnQgaUluZGV4ID0gcGFyYW1zWzBdOwoJRlhfTFBDV1NUUiBjRm9ybWF0c1tdID0geyhGWF9MUENXU1RSKUwiSEg6TU0iLCAoRlhfTFBDV1NUUilMImg6TU0gdHQiLCAoRlhfTFBDV1NUUilMIkhIOk1NOnNzIiwgKEZYX0xQQ1dTVFIpTCJoOk1NOnNzIHR0In07CgoJQVNTRVJUKGlJbmRleDxzaXplb2YoY0Zvcm1hdHMpL3NpemVvZihGWF9MUENXU1RSKSk7CgoJaWYgKGlJbmRleCA8IDApCgkJaUluZGV4ID0gMDsKCWlmIChpSW5kZXggPj0gc2l6ZW9mKGNGb3JtYXRzKS9zaXplb2YoRlhfTFBDV1NUUikpCgkJaUluZGV4ID0gMDsKCUNKU19QYXJhbWV0ZXJzIG5ld1BhcmFtczsKCUNKU19WYWx1ZSB2YWwoaXNvbGF0ZSxjRm9ybWF0c1tpSW5kZXhdKTsKCW5ld1BhcmFtcy5wdXNoX2JhY2sodmFsKTsKCXJldHVybiBBRkRhdGVfRm9ybWF0RXgoY2MsbmV3UGFyYW1zLHZSZXQsc0Vycm9yKTsKfQoKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZUaW1lX0tleXN0cm9rZShPQkpfTUVUSE9EX1BBUkFNUykKewoJdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSA6OkdldElzb2xhdGUoY2MpOwoJaWYgKHBhcmFtcy5zaXplKCkgIT0gMSkKCXsKCQlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQqKWNjOwoJCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOwoJCXJldHVybiBGQUxTRTsKCX0KCglpbnQgaUluZGV4ID0gcGFyYW1zWzBdOwoJRlhfTFBDV1NUUiBjRm9ybWF0c1tdID0geyhGWF9MUENXU1RSKUwiSEg6TU0iLCAoRlhfTFBDV1NUUilMImg6TU0gdHQiLCAoRlhfTFBDV1NUUilMIkhIOk1NOnNzIiwgKEZYX0xQQ1dTVFIpTCJoOk1NOnNzIHR0In07CgoJQVNTRVJUKGlJbmRleDxzaXplb2YoY0Zvcm1hdHMpL3NpemVvZihGWF9MUENXU1RSKSk7CgoJaWYgKGlJbmRleCA8IDApCgkJaUluZGV4ID0gMDsKCWlmIChpSW5kZXggPj0gc2l6ZW9mKGNGb3JtYXRzKS9zaXplb2YoRlhfTFBDV1NUUikpCgkJaUluZGV4ID0gMDsKCUNKU19QYXJhbWV0ZXJzIG5ld1BhcmFtczsKCUNKU19WYWx1ZSB2YWwoaXNvbGF0ZSxjRm9ybWF0c1tpSW5kZXhdKTsKCW5ld1BhcmFtcy5wdXNoX2JhY2sodmFsKTsKCXJldHVybiBBRkRhdGVfS2V5c3Ryb2tlRXgoY2MsbmV3UGFyYW1zLHZSZXQsc0Vycm9yKTsKfQoKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZUaW1lX0Zvcm1hdEV4KE9CSl9NRVRIT0RfUEFSQU1TKQp7CglyZXR1cm4gQUZEYXRlX0Zvcm1hdEV4KGNjLHBhcmFtcyx2UmV0LHNFcnJvcik7Cn0KCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGVGltZV9LZXlzdHJva2VFeChPQkpfTUVUSE9EX1BBUkFNUykKewoJcmV0dXJuIEFGRGF0ZV9LZXlzdHJva2VFeChjYyxwYXJhbXMsdlJldCxzRXJyb3IpOwp9CgovL2Z1bmN0aW9uIEFGU3BlY2lhbF9Gb3JtYXQocHNmKQpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRlNwZWNpYWxfRm9ybWF0KE9CSl9NRVRIT0RfUEFSQU1TKQp7CglDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKCglpZiAocGFyYW1zLnNpemUoKSAhPSAxKQoJewoJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCXN0ZDo6c3RyaW5nIGNGb3JtYXQ7CglpbnQgaUluZGV4ID0gcGFyYW1zWzBdOwoKCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsKCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7CgoJaWYoIXBFdmVudC0+bV9wVmFsdWUpCgkJcmV0dXJuIEZBTFNFOwoJQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlID0gcEV2ZW50LT5WYWx1ZSgpOwkKCXN0ZDo6c3RyaW5nIHN0clNyYyA9IChGWF9MUENTVFIpQ0ZYX0J5dGVTdHJpbmc6OkZyb21Vbmljb2RlKFZhbHVlKTsKCQoJc3dpdGNoIChpSW5kZXgpIAoJewoJY2FzZSAwOiAgICAgICAgICAgICAgICAgICAgICAgICAKCQljRm9ybWF0ID0gIjk5OTk5IjsKCQlicmVhazsKCWNhc2UgMTogICAgICAgICAgICAgICAgICAgICAgICAgCgkJY0Zvcm1hdCA9ICI5OTk5OS05OTk5IjsKCQlicmVhazsKCWNhc2UgMjogICAgICAgICAgICAgICAgICAgICAgICAgCgkJewoJCQlzdGQ6OnN0cmluZyBOdW1iZXJTdHI7CgkJCXV0aWw6OnByaW50eCgiOTk5OTk5OTk5OSIsIHN0clNyYyxOdW1iZXJTdHIpOyAKCQkJaWYgKE51bWJlclN0ci5sZW5ndGgoKSA+PSAxMCApCgkJCQljRm9ybWF0ID0gIig5OTkpIDk5OS05OTk5IjsKCQkJZWxzZSAKCQkJCWNGb3JtYXQgPSAiOTk5LTk5OTkiOwoJCQlicmVhazsKCQl9CgljYXNlIDM6CgkJY0Zvcm1hdCA9ICI5OTktOTktOTk5OSI7CgkJYnJlYWs7Cgl9CgkKCXN0ZDo6c3RyaW5nIHN0ckRlczsKCXV0aWw6OnByaW50eChjRm9ybWF0LHN0clNyYyxzdHJEZXMpOwoJVmFsdWUgPSBDRlhfV2lkZVN0cmluZzo6RnJvbUxvY2FsKHN0ckRlcy5jX3N0cigpKTsKCXJldHVybiBUUlVFOwp9CgoKLy9mdW5jdGlvbiBBRlNwZWNpYWxfS2V5c3Ryb2tlRXgobWFzaykKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZTcGVjaWFsX0tleXN0cm9rZUV4KE9CSl9NRVRIT0RfUEFSQU1TKQp7CglDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsKCglBU1NFUlQocEV2ZW50ICE9IE5VTEwpOwoKCWlmIChwYXJhbXMuc2l6ZSgpIDwgMSkKCXsKCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOwoJCXJldHVybiBGQUxTRTsKCX0KCglpZighcEV2ZW50LT5tX3BWYWx1ZSkKCQlyZXR1cm4gRkFMU0U7CglDRlhfV2lkZVN0cmluZyYgdmFsRXZlbnQgPSBwRXZlbnQtPlZhbHVlKCk7CgoJQ0ZYX1dpZGVTdHJpbmcgd3N0ck1hc2sgPSBwYXJhbXNbMF0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsKCWlmICh3c3RyTWFzay5Jc0VtcHR5KCkpIHJldHVybiBUUlVFOwoJCglzdGQ6OndzdHJpbmcgd3N0clZhbHVlKHZhbEV2ZW50KTsKCQoJaWYgKHBFdmVudC0+V2lsbENvbW1pdCgpKQoJewoJCWlmICh3c3RyVmFsdWUuZW1wdHkoKSkKCQkJcmV0dXJuIFRSVUU7CgkJaW50IGlJbmRleE1hc2sgPSAwOwoJCWZvciAoc3RkOjp3c3RyaW5nOjppdGVyYXRvciBpdCA9IHdzdHJWYWx1ZS5iZWdpbigpOyBpdCAhPSB3c3RyVmFsdWUuZW5kKCk7IGl0KyspCgkJewoJCQl3Y2hhcl90IHdfVmFsdWUgPSAqaXQ7CiAgICAgICAgICAgIGlmICghbWFza1NhdGlzZmllZCh3X1ZhbHVlLHdzdHJNYXNrW2lJbmRleE1hc2tdKSkKCQkJCWJyZWFrOwoJCQlpSW5kZXhNYXNrKys7CgkJfQoKCQlpZiAoaUluZGV4TWFzayAhPSB3c3RyTWFzay5HZXRMZW5ndGgoKSB8fCAoaUluZGV4TWFzayAhPSB3c3RyVmFsdWUuc2l6ZSgpICYmIHdzdHJNYXNrLkdldExlbmd0aCgpICE9IDApKQoJCXsKCQkJQWxlcnQocENvbnRleHQsIEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTQUZOVU1CRVJfS0VZU1RST0tFKSk7CgkJCXBFdmVudC0+UmMoKSA9IEZBTFNFOwoJCX0KCQlyZXR1cm4gVFJVRTsKCX0KCgkKCUNGWF9XaWRlU3RyaW5nICZ3aWRlQ2hhbmdlID0gcEV2ZW50LT5DaGFuZ2UoKTsKCXN0ZDo6d3N0cmluZyB3Q2hhbmdlKHdpZGVDaGFuZ2UpOwoJCglpZiAod0NoYW5nZS5lbXB0eSgpKQoJCXJldHVybiBUUlVFOwogICAgaW50IGlJbmRleE1hc2sgPSBwRXZlbnQtPlNlbFN0YXJ0KCk7CgkvL2lJbmRleE1hc2srKzsKCQoJCglpZiAod3N0clZhbHVlLmxlbmd0aCgpIC0gKHBFdmVudC0+U2VsRW5kKCktcEV2ZW50LT5TZWxTdGFydCgpKSArIHdDaGFuZ2UubGVuZ3RoKCkgPiAoRlhfRFdPUkQpd3N0ck1hc2suR2V0TGVuZ3RoKCkpCgl7CgkJQWxlcnQocENvbnRleHQsIEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1fVE9PTE9ORykpOwoJCXBFdmVudC0+UmMoKSA9IEZBTFNFOwoJCXJldHVybiBUUlVFOwoJfQoJCgkKCWlmIChpSW5kZXhNYXNrID49IHdzdHJNYXNrLkdldExlbmd0aCgpICYmICghd0NoYW5nZS5lbXB0eSgpKSkKCXsKCQlBbGVydChwQ29udGV4dCwgSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTV9UT09MT05HKSk7CgkJcEV2ZW50LT5SYygpID0gRkFMU0U7CgkJcmV0dXJuIFRSVUU7Cgl9CgkKCWZvciAoc3RkOjp3c3RyaW5nOjppdGVyYXRvciBpdCA9IHdDaGFuZ2UuYmVnaW4oKTsgaXQgIT0gd0NoYW5nZS5lbmQoKTsgaXQrKykKCXsKCQlpZiAoaUluZGV4TWFzayA+PSB3c3RyTWFzay5HZXRMZW5ndGgoKSkKCQl7CgkJCUFsZXJ0KHBDb250ZXh0LCBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNX1RPT0xPTkcpKTsKCQkJcEV2ZW50LT5SYygpID0gRkFMU0U7CgkJCXJldHVybiBUUlVFOwoJCX0KCQl3Y2hhcl90IHdfTWFzayA9IHdzdHJNYXNrW2lJbmRleE1hc2tdOwoJCWlmICghaXNSZXNlcnZlZE1hc2tDaGFyKHdfTWFzaykpCgkJewoJCQkvL3dDaGFuZ2UuaW5zZXJ0KGl0LHdfTWFzayk7CQkJCQoJCQkqaXQgPSB3X01hc2s7CgkJfQoJCXdjaGFyX3Qgd19DaGFuZ2UgPSAqaXQ7CgkJCiAgICAgICAgaWYgKCFtYXNrU2F0aXNmaWVkKHdfQ2hhbmdlLHdfTWFzaykpCgkJewoJCQlwRXZlbnQtPlJjKCkgPSBGQUxTRTsKCQkJcmV0dXJuIFRSVUU7CgkJfQoJCWlJbmRleE1hc2srKzsKCX0KCQoJd2lkZUNoYW5nZSA9IHdDaGFuZ2UuY19zdHIoKTsJCgkKCXJldHVybiBUUlVFOwp9CgoKLy9mdW5jdGlvbiBBRlNwZWNpYWxfS2V5c3Ryb2tlKHBzZikKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZTcGVjaWFsX0tleXN0cm9rZShPQkpfTUVUSE9EX1BBUkFNUykKewoJdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSA6OkdldElzb2xhdGUoY2MpOwoKCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOwoJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOwoJQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOwoJQVNTRVJUKHBFdmVudCAhPSBOVUxMKTsKCglpZiAocGFyYW1zLnNpemUoKSAhPSAxKQoJewoJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCXN0ZDo6c3RyaW5nIGNGb3JtYXQ7CglpbnQgaUluZGV4ID0gKGludClwYXJhbXNbMF07CQoKCWlmKCFwRXZlbnQtPm1fcFZhbHVlKQoJCXJldHVybiBGQUxTRTsKCS8vQ0pTX1ZhbHVlIHZhbCA9IHBFdmVudC0+VmFsdWUoKTsKCUNGWF9XaWRlU3RyaW5nJiB2YWwgPSBwRXZlbnQtPlZhbHVlKCk7CglzdGQ6OnN0cmluZyBzdHJTcmMgPSAoRlhfTFBDU1RSKUNGWF9CeXRlU3RyaW5nOjpGcm9tVW5pY29kZSh2YWwpOwoJc3RkOjp3c3RyaW5nIHdzdHJDaGFuZ2UocEV2ZW50LT5DaGFuZ2UoKSk7CgkKCXN3aXRjaCAoaUluZGV4KSAKCXsKCWNhc2UgMDogICAgICAgICAgICAgICAgICAgICAgICAgCgkJY0Zvcm1hdCA9ICI5OTk5OSI7CgkJYnJlYWs7CgljYXNlIDE6ICAgICAgICAgICAgICAgICAgICAgICAgIAoJCS8vY0Zvcm1hdCA9ICI5OTk5OS05OTk5IjsKCQljRm9ybWF0ID0gIjk5OTk5OTk5OSI7CgkJYnJlYWs7CgljYXNlIDI6ICAgICAgICAgICAgICAgICAgICAgICAgIAoJCXsKCQkJc3RkOjpzdHJpbmcgTnVtYmVyU3RyOwoJCQl1dGlsOjpwcmludHgoIjk5OTk5OTk5OTkiLCBzdHJTcmMsTnVtYmVyU3RyKTsgCgkJCWlmIChzdHJTcmMubGVuZ3RoKCkgKyB3c3RyQ2hhbmdlLmxlbmd0aCgpID4gNyApCgkJCQkvL2NGb3JtYXQgPSAiKDk5OSkgOTk5LTk5OTkiOwoJCQkJY0Zvcm1hdCA9ICI5OTk5OTk5OTk5IjsKCQkJZWxzZSAKCQkJCS8vY0Zvcm1hdCA9ICI5OTktOTk5OSI7CgkJCQljRm9ybWF0ID0gIjk5OTk5OTkiOwoJCQlicmVhazsKCQl9CgljYXNlIDM6CgkJLy9jRm9ybWF0ID0gIjk5OS05OS05OTk5IjsKCQljRm9ybWF0ID0gIjk5OTk5OTk5OSI7CgkJYnJlYWs7Cgl9CiAgICAKCUNKU19QYXJhbWV0ZXJzIHBhcmFtczI7CglDSlNfVmFsdWUgdk1hc2soaXNvbGF0ZSwgY0Zvcm1hdC5jX3N0cigpKTsKCXBhcmFtczIucHVzaF9iYWNrKHZNYXNrKTsKCQogICAgcmV0dXJuIEFGU3BlY2lhbF9LZXlzdHJva2VFeChjYyxwYXJhbXMyLHZSZXQsc0Vycm9yKTsKfQoKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZNZXJnZUNoYW5nZShPQkpfTUVUSE9EX1BBUkFNUykKewoJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7CglBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CglDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnRIYW5kbGVyID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOwoJQVNTRVJUKHBFdmVudEhhbmRsZXIgIT0gTlVMTCk7CgoJaWYgKHBhcmFtcy5zaXplKCkgIT0gMSkKCXsKCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOwoJCXJldHVybiBGQUxTRTsKCX0KCglDRlhfV2lkZVN0cmluZyBzd1ZhbHVlOwoJaWYgKHBFdmVudEhhbmRsZXItPm1fcFZhbHVlICE9IE5VTEwpCgkJc3dWYWx1ZSA9IHBFdmVudEhhbmRsZXItPlZhbHVlKCk7CgoJaWYgKHBFdmVudEhhbmRsZXItPldpbGxDb21taXQoKSkKCXsKCQl2UmV0ID0gc3dWYWx1ZTsKCQlyZXR1cm4gVFJVRTsKCX0KCglDRlhfV2lkZVN0cmluZyBwcmVmaXgscG9zdGZpeDsKCglpZiAocEV2ZW50SGFuZGxlci0+U2VsU3RhcnQoKSA+PSAwKQoJCXByZWZpeCA9IHN3VmFsdWUuTWlkKDAscEV2ZW50SGFuZGxlci0+U2VsU3RhcnQoKSk7CgllbHNlCgkJcHJlZml4ID0gTCIiOwoKCglpZiAocEV2ZW50SGFuZGxlci0+U2VsRW5kKCkgPj0gMCAmJiBwRXZlbnRIYW5kbGVyLT5TZWxFbmQoKSA8PSBzd1ZhbHVlLkdldExlbmd0aCgpKQoJCXBvc3RmaXggPSBzd1ZhbHVlLk1pZChwRXZlbnRIYW5kbGVyLT5TZWxFbmQoKSwgc3dWYWx1ZS5HZXRMZW5ndGgoKSAtIHBFdmVudEhhbmRsZXItPlNlbEVuZCgpKTsKCWVsc2UgcG9zdGZpeCA9IEwiIjsKCgl2UmV0ID0gcHJlZml4ICsgcEV2ZW50SGFuZGxlci0+Q2hhbmdlKCkgKyBwb3N0Zml4OwoKCXJldHVybiBUUlVFOwp9CgpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRlBhcnNlRGF0ZUV4KE9CSl9NRVRIT0RfUEFSQU1TKQp7CglDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKCglpZiAocGFyYW1zLnNpemUoKSAhPSAyKQoJewoJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCUNGWF9XaWRlU3RyaW5nIHNWYWx1ZSA9IHBhcmFtc1swXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOwoJQ0ZYX1dpZGVTdHJpbmcgc0Zvcm1hdCA9IHBhcmFtc1sxXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOwoKCUZYX0JPT0wgYldyb25nRm9ybWF0ID0gRkFMU0U7Cglkb3VibGUgZERhdGUgPSBNYWtlUmVndWxhckRhdGUoc1ZhbHVlLHNGb3JtYXQsYldyb25nRm9ybWF0KTsKCglpZiAoSlNfUG9ydElzTmFuKGREYXRlKSkKCXsKCQlDRlhfV2lkZVN0cmluZyBzd01zZzsKCQlzd01zZy5Gb3JtYXQoSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJTRURBVEUpLCAoRlhfTFBDV1NUUilzRm9ybWF0KTsKCQlBbGVydCgoQ0pTX0NvbnRleHQgKiljYywgc3dNc2cpOwoJCXJldHVybiBGQUxTRTsKCX0KCQoJdlJldCA9IGREYXRlOwoKCXJldHVybiBUUlVFOwp9CgpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRlNpbXBsZShPQkpfTUVUSE9EX1BBUkFNUykKewoJaWYgKHBhcmFtcy5zaXplKCkgIT0gMykKCXsKCQlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKCQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CgoJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCXZSZXQgPSAoZG91YmxlKUFGX1NpbXBsZShwYXJhbXNbMF0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKSwgKGRvdWJsZSlwYXJhbXNbMV0sIChkb3VibGUpcGFyYW1zWzJdKTsKCXJldHVybiBUUlVFOwp9CgpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRk1ha2VOdW1iZXIoT0JKX01FVEhPRF9QQVJBTVMpCnsKCWlmIChwYXJhbXMuc2l6ZSgpICE9IDEpCgl7CgkJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7CgkJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOwoKCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOwoJCXJldHVybiBGQUxTRTsKCX0KICAgIHZSZXQgPSBQYXJzZVN0cmluZ1RvTnVtYmVyKHBhcmFtc1swXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpKTsKCXJldHVybiBUUlVFOwp9CgpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRlNpbXBsZV9DYWxjdWxhdGUoT0JKX01FVEhPRF9QQVJBTVMpCnsKCXY4OjpJc29sYXRlKiBpc29sYXRlID0gOjpHZXRJc29sYXRlKGNjKTsKCglDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKCglpZiAocGFyYW1zLnNpemUoKSAhPSAyKQoJewoJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCUNKU19WYWx1ZSBwYXJhbXMxID0gcGFyYW1zWzFdOwoKCWlmICghcGFyYW1zMS5Jc0FycmF5T2JqZWN0KCkgJiYgcGFyYW1zMS5HZXRUeXBlKCkgIT0gVlRfc3RyaW5nKQoJewoJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CgkJcmV0dXJuIEZBTFNFOwoJfQoJCglDUERGU0RLX0RvY3VtZW50KiBwUmVhZGVyRG9jID0gcENvbnRleHQtPkdldFJlYWRlckRvY3VtZW50KCk7CiAgICBBU1NFUlQocFJlYWRlckRvYyAhPSBOVUxMKTsKCglDUERGU0RLX0ludGVyRm9ybSogcFJlYWRlckludGVyRm9ybSA9IHBSZWFkZXJEb2MtPkdldEludGVyRm9ybSgpOwoJQVNTRVJUKHBSZWFkZXJJbnRlckZvcm0gIT0gTlVMTCk7CgoJQ1BERl9JbnRlckZvcm0qIHBJbnRlckZvcm0gPSBwUmVhZGVySW50ZXJGb3JtLT5HZXRJbnRlckZvcm0oKTsKCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOwoKCWRvdWJsZSBkVmFsdWU7CglDRlhfV2lkZVN0cmluZyBzRnVuY3Rpb24gPSBwYXJhbXNbMF0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsKCWlmICh3Y3NjbXAoc0Z1bmN0aW9uLCBMIlBSRCIpID09IDApCiAgICAJZFZhbHVlID0gMS4wOwoJZWxzZQoJCWRWYWx1ZSA9IDAuMDsKCglDSlNfQXJyYXkgRmllbGROYW1lQXJyYXkgPSBBRl9NYWtlQXJyYXlGcm9tTGlzdChpc29sYXRlLHBhcmFtczEpOwoKCWludCBuRmllbGRzQ291bnQgPSAwOwoKCWZvciAoaW50IGk9MCxpc3o9RmllbGROYW1lQXJyYXkuR2V0TGVuZ3RoKCk7IGk8aXN6OyBpKyspCgl7CgkJQ0pTX1ZhbHVlIGpzVmFsdWUoaXNvbGF0ZSk7CgkJRmllbGROYW1lQXJyYXkuR2V0RWxlbWVudChpLGpzVmFsdWUpOwogICAgICAgIENGWF9XaWRlU3RyaW5nIHdzRmllbGROYW1lID0ganNWYWx1ZS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOwoKICAgICAgICBmb3IgKGludCBqPTAsanN6PXBJbnRlckZvcm0tPkNvdW50RmllbGRzKHdzRmllbGROYW1lKTsgajxqc3o7IGorKykKCQl7CgkJCWlmIChDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IHBJbnRlckZvcm0tPkdldEZpZWxkKGosIHdzRmllbGROYW1lKSkKCQkJewoJCQkJZG91YmxlIGRUZW1wID0gMC4wOwoKCQkJCXN3aXRjaCAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkpCgkJCQl7CgkJCQljYXNlIEZJRUxEVFlQRV9URVhURklFTEQ6CgkJCQljYXNlIEZJRUxEVFlQRV9DT01CT0JPWDoKCQkJCQl7CgkJCQkJCWRUZW1wID0gUGFyc2VTdHJpbmdUb051bWJlcihwRm9ybUZpZWxkLT5HZXRWYWx1ZSgpKTsKCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJY2FzZSBGSUVMRFRZUEVfUFVTSEJVVFRPTjoKCQkJCQl7CgkJCQkJCWRUZW1wID0gMC4wOwoJCQkJCQlicmVhazsKCQkJCQl9CgkJCQljYXNlIEZJRUxEVFlQRV9DSEVDS0JPWDoKCQkJCWNhc2UgRklFTERUWVBFX1JBRElPQlVUVE9OOgoJCQkJCXsKCQkJCQkJZFRlbXAgPSAwLjA7CgkJCQkJCWZvciAoaW50IGM9MCxjc3o9cEZvcm1GaWVsZC0+Q291bnRDb250cm9scygpOyBjPGNzejsgYysrKQoJCQkJCQl7CgkJCQkJCQlpZiAoQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1DdHJsID0gcEZvcm1GaWVsZC0+R2V0Q29udHJvbChjKSkKCQkJCQkJCXsKCQkJCQkJCQlpZiAocEZvcm1DdHJsLT5Jc0NoZWNrZWQoKSkKCQkJCQkJCQl7CgkJCQkJCQkJCWRUZW1wICs9IFBhcnNlU3RyaW5nVG9OdW1iZXIocEZvcm1DdHJsLT5HZXRFeHBvcnRWYWx1ZSgpKTsKCQkJCQkJCQkJYnJlYWs7CgkJCQkJCQkJfQoJCQkJCQkJCWVsc2UKCQkJCQkJCQkJY29udGludWU7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJY2FzZSBGSUVMRFRZUEVfTElTVEJPWDoKCQkJCQl7CgkJCQkJCWRUZW1wID0gMC4wOwoJCQkJCQlpZiAocEZvcm1GaWVsZC0+Q291bnRTZWxlY3RlZEl0ZW1zKCkgPiAxKQoJCQkJCQkJYnJlYWs7CgkJCQkJCWVsc2UKCQkJCQkJewoJCQkJCQkJZFRlbXAgPSBQYXJzZVN0cmluZ1RvTnVtYmVyKHBGb3JtRmllbGQtPkdldFZhbHVlKCkpOwoJCQkJCQkJYnJlYWs7CgkJCQkJCX0KCQkJCQl9CgkJCQlkZWZhdWx0OgoJCQkJCWJyZWFrOwoJCQkJfQoKCQkJCWlmIChpID09IDAgJiYgaiA9PSAwICYmICh3Y3NjbXAoc0Z1bmN0aW9uLEwiTUlOIikgPT0gMCB8fCB3Y3NjbXAoc0Z1bmN0aW9uLCBMIk1BWCIpID09IDApKQoJCQkJCWRWYWx1ZSA9IGRUZW1wOwoKCQkJCWRWYWx1ZSA9IEFGX1NpbXBsZShzRnVuY3Rpb24sIGRWYWx1ZSwgZFRlbXApOwoKCQkJCW5GaWVsZHNDb3VudCsrOwoJCQl9CgkJfQoJfQoKCWlmICh3Y3NjbXAoc0Z1bmN0aW9uLCBMIkFWRyIpID09IDAgJiYgbkZpZWxkc0NvdW50ID4gMCkKCQlkVmFsdWUgLz0gbkZpZWxkc0NvdW50OwoKCWRWYWx1ZSA9IChkb3VibGUpZmxvb3IoZFZhbHVlICogRlhTWVNfcG93KChkb3VibGUpMTAsKGRvdWJsZSk2KSArIDAuNDkpIC8gRlhTWVNfcG93KChkb3VibGUpMTAsKGRvdWJsZSk2KTsKCUNKU19WYWx1ZSBqc1ZhbHVlKGlzb2xhdGUsZFZhbHVlKTsKCWlmKChDSlNfRXZlbnRIYW5kbGVyKilwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCktPm1fcFZhbHVlKQoJCSgoQ0pTX0V2ZW50SGFuZGxlciopcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpKS0+VmFsdWUoKSA9IGpzVmFsdWU7CgoJcmV0dXJuIFRSVUU7Cn0KCi8qIFRoaXMgZnVuY3Rpb24gdmFsaWRhdGVzIHRoZSBjdXJyZW50IGV2ZW50IHRvIGVuc3VyZSB0aGF0IGl0cyB2YWx1ZSBpcyAKKiogd2l0aGluIHRoZSBzcGVjaWZpZWQgcmFuZ2UuICovCgpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRlJhbmdlX1ZhbGlkYXRlKE9CSl9NRVRIT0RfUEFSQU1TKQp7CglDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsKCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7CgoJaWYgKHBhcmFtcy5zaXplKCkgIT0gNCkgCgl7CgkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJaWYoIXBFdmVudC0+bV9wVmFsdWUpCgkJcmV0dXJuIEZBTFNFOwoJaWYgKHBFdmVudC0+VmFsdWUoKS5Jc0VtcHR5KCkgKQoJCXJldHVybiBUUlVFOwoJZG91YmxlIGRFZW50VmFsdWUgPSBhdG9mKENGWF9CeXRlU3RyaW5nOjpGcm9tVW5pY29kZShwRXZlbnQtPlZhbHVlKCkpKTsKCUZYX0JPT0wgYkdyZWF0ZXJUaGFuLCBiTGVzc1RoYW47Cglkb3VibGUgIGRHcmVhdGVyVGhhbiwgZExlc3NUaGFuOwogICAgYkdyZWF0ZXJUaGFuID0gKEZYX0JPT0wpcGFyYW1zWzBdOwoJQ0ZYX1dpZGVTdHJpbmcgc3dNc2c7CglkR3JlYXRlclRoYW4gPSAoZG91YmxlKXBhcmFtc1sxXTsKCWJMZXNzVGhhbiA9IChGWF9CT09MKXBhcmFtc1syXTsKCWRMZXNzVGhhbiA9IChkb3VibGUpcGFyYW1zWzNdOwoKCWlmIChiR3JlYXRlclRoYW4gJiYgYkxlc3NUaGFuKQoJewoJCWlmIChkRWVudFZhbHVlIDwgZEdyZWF0ZXJUaGFuIHx8IGRFZW50VmFsdWUgPiBkTGVzc1RoYW4pCgkJCXN3TXNnLkZvcm1hdChKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1JBTkdFMSksKEZYX0xQQ1dTVFIpcGFyYW1zWzFdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCksIChGWF9MUENXU1RSKXBhcmFtc1szXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpKTsKCX0KCWVsc2UgaWYgKGJHcmVhdGVyVGhhbikKCXsKCQlpZiAoZEVlbnRWYWx1ZSA8IGRHcmVhdGVyVGhhbikKCQkJc3dNc2cuRm9ybWF0KEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUkFOR0UyKSwgKEZYX0xQQ1dTVFIpcGFyYW1zWzFdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCkpOwoJfQoJZWxzZSBpZiAoYkxlc3NUaGFuKQoJewoJCWlmIChkRWVudFZhbHVlID4gZExlc3NUaGFuKQoJCQlzd01zZy5Gb3JtYXQoSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNSQU5HRTMpLCAoRlhfTFBDV1NUUilwYXJhbXNbM10ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKSk7Cgl9CgoJaWYgKCFzd01zZy5Jc0VtcHR5KCkpCgl7CgkJQWxlcnQocENvbnRleHQsIHN3TXNnKTsKCQlwRXZlbnQtPlJjKCkgPSBGQUxTRTsKCX0KCXJldHVybiBUUlVFOwp9CgpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRkV4dHJhY3ROdW1zKE9CSl9NRVRIT0RfUEFSQU1TKQp7Cgl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IDo6R2V0SXNvbGF0ZShjYyk7CglDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQqKWNjOwoJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOwoKCWlmIChwYXJhbXMuc2l6ZSgpICE9IDEpIAoJewoJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCUNKU19BcnJheSBudW1zKGlzb2xhdGUpOwoKCUNGWF9XaWRlU3RyaW5nIHN0ciA9IHBhcmFtc1swXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOwoJQ0ZYX1dpZGVTdHJpbmcgc1BhcnQ7CgoJaWYgKHN0ci5HZXRBdCgwKSA9PSBMJy4nIHx8IHN0ci5HZXRBdCgwKSA9PSBMJywnKQoJCXN0ciA9IEwiMCIgKyBzdHI7CgoJaW50IG5JbmRleCA9IDA7Cglmb3IgKGludCBpPTAsIHN6PXN0ci5HZXRMZW5ndGgoKTsgaTxzejsgaSsrKQoJewoJCUZYX1dDSEFSIHdjID0gc3RyLkdldEF0KGkpOwoJCWlmIChJc0RpZ2l0KCh3Y2hhcl90KXdjKSkKCQl7CgkJCXNQYXJ0ICs9IHdjOwoJCX0KCQllbHNlCgkJewoJCQlpZiAoc1BhcnQuR2V0TGVuZ3RoKCkgPiAwKQoJCQl7CgkJCQludW1zLlNldEVsZW1lbnQobkluZGV4LENKU19WYWx1ZShpc29sYXRlLChGWF9MUENXU1RSKXNQYXJ0KSk7CgkJCQlzUGFydCA9IEwiIjsKCQkJCW5JbmRleCArKzsKCQkJfQoJCX0KCX0KCglpZiAoc1BhcnQuR2V0TGVuZ3RoKCkgPiAwKQoJewoJCW51bXMuU2V0RWxlbWVudChuSW5kZXgsQ0pTX1ZhbHVlKGlzb2xhdGUsKEZYX0xQQ1dTVFIpc1BhcnQpKTsJCgl9CgoJaWYgKG51bXMuR2V0TGVuZ3RoKCkgPiAwKQoJCXZSZXQgPSBudW1zOwoJZWxzZQoJCXZSZXQuU2V0TnVsbCgpOwoKCXJldHVybiBUUlVFOwp9Cg==