Ly8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KIAovLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQoKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KYXZhU2NyaXB0LmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSUphdmFTY3JpcHQuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19EZWZpbmUuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19PYmplY3QuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19WYWx1ZS5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L1B1YmxpY01ldGhvZHMuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19FdmVudEhhbmRsZXIuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9yZXNvdXJjZS5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0NvbnRleHQuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19WYWx1ZS5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L3V0aWwuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9GaWVsZC5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L2NvbG9yLmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfUnVudGltZS5oIgoKc3RhdGljIHY4OjpJc29sYXRlKiBHZXRJc29sYXRlKElGWEpTX0NvbnRleHQqIGNjKQp7CglDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKCglDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCk7CglBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7CgoJcmV0dXJuIHBSdW50aW1lLT5HZXRJc29sYXRlKCk7Cn0KCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDSlNfUHVibGljTWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKI2RlZmluZSBET1VCTEVfQ09SUkVDVAkwLjAwMDAwMDAwMDAwMDAwMQoKQkVHSU5fSlNfU1RBVElDX0dMT0JBTF9GVU4oQ0pTX1B1YmxpY01ldGhvZHMpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRk51bWJlcl9Gb3JtYXQsNikKCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGTnVtYmVyX0tleXN0cm9rZSw2KQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZQZXJjZW50X0Zvcm1hdCwyKQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZQZXJjZW50X0tleXN0cm9rZSwyKQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZEYXRlX0Zvcm1hdEV4LDEpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRkRhdGVfS2V5c3Ryb2tlRXgsMSkKCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGRGF0ZV9Gb3JtYXQsMSkKCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGRGF0ZV9LZXlzdHJva2UsMSkKCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGVGltZV9Gb3JtYXRFeCwxKQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZUaW1lX0tleXN0cm9rZUV4LDEpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlRpbWVfRm9ybWF0LDEpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlRpbWVfS2V5c3Ryb2tlLDEpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlNwZWNpYWxfRm9ybWF0LDEpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlNwZWNpYWxfS2V5c3Ryb2tlLDEpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlNwZWNpYWxfS2V5c3Ryb2tlRXgsMSkKCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGU2ltcGxlLDMpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRk1ha2VOdW1iZXIsMSkKCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGU2ltcGxlX0NhbGN1bGF0ZSwyKQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZSYW5nZV9WYWxpZGF0ZSw0KQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZNZXJnZUNoYW5nZSwxKQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZQYXJzZURhdGVFeCwyKQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZFeHRyYWN0TnVtcywxKQpFTkRfSlNfU1RBVElDX0dMT0JBTF9GVU4oKQoKSU1QTEVNRU5UX0pTX1NUQVRJQ19HTE9CQUxfRlVOKENKU19QdWJsaWNNZXRob2RzKQoKc3RydWN0IHN0cnVfVGJDb252ZXJ0CnsKCUZYX0xQQ1NUUiBscHN6SlNNYXJrOwoJRlhfTFBDU1RSIGxwc3pDcHBNYXJrOwp9OwoKc3RhdGljIGNvbnN0IHN0cnVfVGJDb252ZXJ0IGZjVGFibGVbXSA9IHsibW1tbSIsIiVCIiwKCSJtbW0iLCAiJWIiLAoJIm1tIiwgICIlbSIsCgkvLyJtIgoJImRkZGQiLCIlQSIsCgkiZGRkIiwgIiVhIiwKCSJkZCIsICAiJWQiLAoJLy8iZCIsICAgIiV3IiwKCSJ5eXl5IiwiJVkiLAoJInl5IiwgICIleSIsCgkiSEgiLCAgIiVIIiwKCS8vIkgiCgkiaGgiLCAgIiVJIiwKCS8vImgiCgkiTU0iLCAgIiVNIiwKCS8vIk0iCgkic3MiLCAgIiVTIiwKCS8vInMKCSJ0dCIsICAiJXAiCgkvLyJ0Igp9OwoKc3RhdGljIEZYX0xQQ1dTVFIgbW9udGhzW10gPQp7CgkoRlhfTFBDV1NUUilMIkphbiIsIChGWF9MUENXU1RSKUwiRmViIiwgKEZYX0xQQ1dTVFIpTCJNYXIiLCAoRlhfTFBDV1NUUilMIkFwciIsIChGWF9MUENXU1RSKUwiTWF5IiwgKEZYX0xQQ1dTVFIpTCJKdW4iLCAoRlhfTFBDV1NUUilMIkp1bCIsIChGWF9MUENXU1RSKUwiQXVnIiwgKEZYX0xQQ1dTVFIpTCJTZXAiLCAoRlhfTFBDV1NUUilMIk9jdCIsIChGWF9MUENXU1RSKUwiTm92IiwgKEZYX0xQQ1dTVFIpTCJEZWMiCn07CgpzdGF0aWMgRlhfTFBDV1NUUiBmdWxsbW9udGhzW10gPSAKeyAKCShGWF9MUENXU1RSKUwiSmFudWFyeSIsIChGWF9MUENXU1RSKUwiRmVicnVhcnkiLCAoRlhfTFBDV1NUUilMIk1hcmNoIiwgKEZYX0xQQ1dTVFIpTCJBcHJpbCIsIChGWF9MUENXU1RSKUwiTWF5IiwgKEZYX0xQQ1dTVFIpTCJKdW5lIiwgKEZYX0xQQ1dTVFIpTCJKdWx5IiwgKEZYX0xQQ1dTVFIpTCJBdWd1c3QiLCAoRlhfTFBDV1NUUilMIlNlcHRlbWJlciIsIChGWF9MUENXU1RSKUwiT2N0b2JlciIsIChGWF9MUENXU1RSKUwiTm92ZW1iZXIiLCAoRlhfTFBDV1NUUilMIkRlY2VtYmVyIiAKfTsKCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OklzTnVtYmVyKEZYX0xQQ1dTVFIgc3RyaW5nKQp7CglDRlhfV2lkZVN0cmluZyBzVHJpbSA9IFN0clRyaW0oc3RyaW5nKTsKCUZYX0xQQ1dTVFIgcFRyaW0gPSBzVHJpbTsKCUZYX0xQQ1dTVFIgcCA9IHBUcmltOwoKCglGWF9CT09MIGJEb3QgPSBGQUxTRTsKCUZYX0JPT0wgYktYSlMgPSBGQUxTRTsKCgl3Y2hhcl90IGM7Cgl3aGlsZSAoKGMgPSAqcCkpCgl7CgkJaWYgKGMgPT0gJy4nIHx8IGMgPT0gJywnKQoJCXsKCQkJaWYgKGJEb3QpIHJldHVybiBGQUxTRTsKCQkJYkRvdCA9IFRSVUU7CgkJfQoJCWVsc2UgaWYgKGMgPT0gJy0nIHx8IGMgPT0gJysnKQoJCXsKCQkJaWYgKHAgIT0gcFRyaW0pCgkJCQlyZXR1cm4gRkFMU0U7CgkJfQoJCWVsc2UgaWYgKGMgPT0gJ2UnIHx8IGMgPT0gJ0UnKQoJCXsKCQkJaWYgKGJLWEpTKSByZXR1cm4gRkFMU0U7CgoJCQlwKys7CgkJCWMgPSAqcDsKCQkJaWYgKGMgPT0gJysnIHx8IGMgPT0gJy0nKQoJCQl7CgkJCQliS1hKUyA9IFRSVUU7CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQlyZXR1cm4gRkFMU0U7CgkJCX0KCQl9CgkJZWxzZSBpZiAoIUlzRGlnaXQoYykpCgkJewoJCQlyZXR1cm4gRkFMU0U7CgkJfQoJCXArKzsKCX0KCglyZXR1cm4gVFJVRTsKfQoKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6SXNEaWdpdCh3Y2hhcl90IGNoKQp7CglyZXR1cm4gKGNoID49IEwnMCcgJiYgY2ggPD0gTCc5Jyk7Cn0KCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OklzRGlnaXQoY2hhciBjaCkKewoJcmV0dXJuIChjaCA+PSAnMCcgJiYgY2ggPD0gJzknKTsKfQoKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6SXNBbHBoYWJldGljKHdjaGFyX3QgY2gpCnsKCXJldHVybiAoKGNoID49IEwnYScgJiYgY2ggPD0gTCd6JykgfHwgKGNoID49IEwnQScgJiYgY2ggPD0gTCdaJykpOwp9CgpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpJc0FscGhhTnVtZXJpYyh3Y2hhcl90IGNoKQp7CglyZXR1cm4gKElzRGlnaXQoY2gpIHx8IElzQWxwaGFiZXRpYyhjaCkpOwp9CgpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjptYXNrU2F0aXNmaWVkKHdjaGFyX3QgY19DaGFuZ2Usd2NoYXJfdCBjX01hc2spCnsKCXN3aXRjaCAoY19NYXNrKQoJewoJY2FzZSBMJzknOgogICAgICAgIHJldHVybiBJc0RpZ2l0KGNfQ2hhbmdlKTsJCQogICAgY2FzZSBMJ0EnOgogICAgICAgIHJldHVybiBJc0FscGhhYmV0aWMoY19DaGFuZ2UpOwkJCiAgICBjYXNlIEwnTyc6CiAgICAgICAgcmV0dXJuIElzQWxwaGFOdW1lcmljKGNfQ2hhbmdlKTsJCQogICAgY2FzZSBMJ1gnOgogICAgICAgIHJldHVybiBUUlVFOwkJCglkZWZhdWx0OgogICAgICAgIHJldHVybiAoY19DaGFuZ2UgPT0gY19NYXNrKTsKCX0KfQoKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6aXNSZXNlcnZlZE1hc2tDaGFyKHdjaGFyX3QgY2gpCnsKCXJldHVybiBjaCA9PSBMJzknIHx8IGNoID09IEwnQScgfHwgY2ggPT0gTCdPJyB8fCBjaCA9PSBMJ1gnOwp9Cgpkb3VibGUgQ0pTX1B1YmxpY01ldGhvZHM6OkFGX1NpbXBsZShGWF9MUENXU1RSIHNGdWN0aW9uLCBkb3VibGUgZFZhbHVlMSwgZG91YmxlIGRWYWx1ZTIpCnsKCWlmIChGWFNZU193Y3NpY21wKHNGdWN0aW9uLChGWF9MUENXU1RSKUwiQVZHIikgPT0gMCB8fCBGWFNZU193Y3NpY21wKHNGdWN0aW9uLChGWF9MUENXU1RSKUwiU1VNIikgPT0gMCkKCXsKCQlyZXR1cm4gZFZhbHVlMSArIGRWYWx1ZTI7Cgl9CgllbHNlIGlmIChGWFNZU193Y3NpY21wKHNGdWN0aW9uLCAoRlhfTFBDV1NUUilMIlBSRCIpID09IDApCgl7CgkJcmV0dXJuIGRWYWx1ZTEgKiBkVmFsdWUyOwoJfQoJZWxzZSBpZiAoRlhTWVNfd2NzaWNtcChzRnVjdGlvbiwoRlhfTFBDV1NUUilMIk1JTiIpID09IDApCgl7CgkJcmV0dXJuIEZYX01JTihkVmFsdWUxLCBkVmFsdWUyKTsKCX0KCWVsc2UgaWYgKEZYU1lTX3djc2ljbXAoc0Z1Y3Rpb24sKEZYX0xQQ1dTVFIpTCJNQVgiKSA9PSAwKQoJewoJCXJldHVybiBGWF9NQVgoZFZhbHVlMSwgZFZhbHVlMik7Cgl9CgoJcmV0dXJuIGRWYWx1ZTE7Cn0KCkNGWF9XaWRlU3RyaW5nIENKU19QdWJsaWNNZXRob2RzOjpTdHJMVHJpbShGWF9MUENXU1RSIHBTdHIpCnsKCXdoaWxlICgqcFN0ciAmJiAqcFN0ciA9PSBMJyAnKSBwU3RyKys7CgoJcmV0dXJuIHBTdHI7Cn0KCkNGWF9XaWRlU3RyaW5nIENKU19QdWJsaWNNZXRob2RzOjpTdHJSVHJpbShGWF9MUENXU1RSIHBTdHIpCnsKCUZYX0xQQ1dTVFIgcCA9IHBTdHI7CgoJd2hpbGUgKCpwKSBwKys7CglwLS07CglpZiAocCA+PSBwU3RyKQoJewkJCgkJd2hpbGUgKCpwICYmICpwID09IEwnICcpIHAtLTsKCQlwKys7CgkJcmV0dXJuIENGWF9XaWRlU3RyaW5nKHBTdHIscC1wU3RyKTsKCX0KCXJldHVybiBMIiI7Cn0KCkNGWF9XaWRlU3RyaW5nIENKU19QdWJsaWNNZXRob2RzOjpTdHJUcmltKEZYX0xQQ1dTVFIgcFN0cikKewoJcmV0dXJuIFN0clJUcmltKFN0ckxUcmltKHBTdHIpKTsKfQoKQ0ZYX0J5dGVTdHJpbmcgQ0pTX1B1YmxpY01ldGhvZHM6OlN0ckxUcmltKEZYX0xQQ1NUUiBwU3RyKQp7Cgl3aGlsZSAoKnBTdHIgJiYgKnBTdHIgPT0gJyAnKSBwU3RyKys7CgogICAgcmV0dXJuIHBTdHI7Cn0KCkNGWF9CeXRlU3RyaW5nIENKU19QdWJsaWNNZXRob2RzOjpTdHJSVHJpbShGWF9MUENTVFIgcFN0cikKewoJRlhfTFBDU1RSIHAgPSBwU3RyOwoKCXdoaWxlICgqcCkgcCsrOwoJcC0tOwoJaWYgKHAgPj0gcFN0cikKCXsJCQoJCXdoaWxlICgqcCAmJiAqcCA9PSAnICcpIHAtLTsKCQlwKys7CgkJcmV0dXJuIENGWF9CeXRlU3RyaW5nKHBTdHIscC1wU3RyKTsKCX0KCXJldHVybiAiIjsKfQoKQ0ZYX0J5dGVTdHJpbmcgQ0pTX1B1YmxpY01ldGhvZHM6OlN0clRyaW0oRlhfTFBDU1RSIHBTdHIpCnsKCXJldHVybiBTdHJSVHJpbShTdHJMVHJpbShwU3RyKSk7Cn0KCmRvdWJsZSBDSlNfUHVibGljTWV0aG9kczo6UGFyc2VOdW1iZXIoRlhfTFBDV1NUUiBzd1NvdXJjZSwgRlhfQk9PTCYgYkFsbERpZ2l0cywgRlhfQk9PTCYgYkRvdCwgRlhfQk9PTCYgYlNpZ24sIEZYX0JPT0wmIGJLWEpTKQp7CgliRG90ID0gRkFMU0U7CgliU2lnbiA9IEZBTFNFOwoJYktYSlMgPSBGQUxTRTsKCglGWF9CT09MIGJEaWdpdEV4aXN0ID0gRkFMU0U7CgoJRlhfTFBDV1NUUiBwID0gc3dTb3VyY2U7Cgl3Y2hhcl90IGM7CgoJRlhfTFBDV1NUUiBwU3RhcnQgPSBOVUxMOwoJRlhfTFBDV1NUUiBwRW5kID0gTlVMTDsKCgl3aGlsZSAoKGMgPSAqcCkpCgl7CgkJaWYgKCFwU3RhcnQgJiYgYyAhPSBMJyAnKQoJCXsKCQkJcFN0YXJ0ID0gcDsKCQl9CgoJCXBFbmQgPSBwOwoJCXArKzsKCX0KCglpZiAoIXBTdGFydCkKCXsKCQliQWxsRGlnaXRzID0gRkFMU0U7CgkJcmV0dXJuIDA7Cgl9CgoJd2hpbGUgKHBFbmQgIT0gcFN0YXJ0KQoJewoJCWlmICgqcEVuZCA9PSBMJyAnKQoJCQlwRW5kIC0tOwoJCWVsc2UKCQkJYnJlYWs7Cgl9CgoJZG91YmxlIGRSZXQgPSAwOwoJcCA9IHBTdGFydDsKCWJBbGxEaWdpdHMgPSBUUlVFOwoJQ0ZYX1dpZGVTdHJpbmcgc3dEaWdpdHM7CgoJd2hpbGUgKHAgPD0gcEVuZCkKCXsJCgkJYyA9ICpwOwoKCQlpZiAoSXNEaWdpdChjKSkKCQl7CgkJCXN3RGlnaXRzICs9IGM7CgkJCWJEaWdpdEV4aXN0ID0gVFJVRTsKCQl9CgkJZWxzZSAKCQl7CgkJCXN3aXRjaCAoYykKCQkJewoJCQljYXNlIEwnICc6CgkJCQliQWxsRGlnaXRzID0gRkFMU0U7CgkJCQlicmVhazsKCQkJY2FzZSBMJy4nOgoJCQljYXNlIEwnLCc6CgkJCQlpZiAoIWJEb3QpCgkJCQl7CgkJCQkJaWYgKGJEaWdpdEV4aXN0KQoJCQkJCXsKCQkJCQkJc3dEaWdpdHMgKz0gTCcuJzsKCQkJCQl9CgkJCQkJZWxzZQoJCQkJCXsKCQkJCQkJc3dEaWdpdHMgKz0gTCcwJzsKCQkJCQkJc3dEaWdpdHMgKz0gTCcuJzsKCQkJCQkJYkRpZ2l0RXhpc3QgPSBUUlVFOwoJCQkJCX0KCgkJCQkJYkRvdCA9IFRSVUU7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCWNhc2UgJ2UnOgoJCQljYXNlICdFJzoKCQkJCWlmICghYktYSlMpCgkJCQl7CgkJCQkJcCsrOwoJCQkJCWMgPSAqcDsKCQkJCQlpZiAoYyA9PSAnKycgfHwgYyA9PSAnLScpCgkJCQkJewoJCQkJCQliS1hKUyA9IFRSVUU7CgkJCQkJCXN3RGlnaXRzICs9ICdlJzsKCQkJCQkJc3dEaWdpdHMgKz0gYzsKCQkJCQl9CgkJCQkJYnJlYWs7CgkJCQl9CgkJCWNhc2UgTCctJzoKCQkJCWlmICghYkRpZ2l0RXhpc3QgJiYgIWJTaWduKQoJCQkJewoJCQkJCXN3RGlnaXRzICs9IGM7CgkJCQkJYlNpZ24gPSBUUlVFOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQlkZWZhdWx0OgoJCQkJYkFsbERpZ2l0cyA9IEZBTFNFOwoKCQkJCWlmIChwICE9IHBTdGFydCAmJiAhYkRvdCAmJiBiRGlnaXRFeGlzdCkKCQkJCXsKCQkJCQlzd0RpZ2l0cyArPSBMJy4nOwoJCQkJCWJEb3QgPSBUUlVFOwoJCQkJfQoJCQkJZWxzZQoJCQkJewoJCQkJCWJEb3QgPSBGQUxTRTsKCQkJCQliRGlnaXRFeGlzdCA9IEZBTFNFOwoJCQkJCXN3RGlnaXRzID0gTCIiOwoJCQkJfQoJCQkJYnJlYWs7CgkJCX0KCQl9CgoJCXArKzsKCX0KCglpZiAoc3dEaWdpdHMuR2V0TGVuZ3RoKCkgPiAwICYmIHN3RGlnaXRzLkdldExlbmd0aCgpIDwgMTcpCgl7CgkJQ0ZYX0J5dGVTdHJpbmcgc0RpZ2l0cyA9IHN3RGlnaXRzLlVURjhFbmNvZGUoKTsKCgkJaWYgKGJLWEpTKQoJCXsKCQkJZFJldCA9IGF0b2Yoc0RpZ2l0cyk7CgkJfQoJCWVsc2UKCQl7CgkJCWlmIChiRG90KQoJCQl7CgkJCQljaGFyKiBwU3RvcFN0cmluZzsKCQkJCWRSZXQgPSA6OnN0cnRvZChzRGlnaXRzLCAmcFN0b3BTdHJpbmcpOwoJCQl9CgkJCWVsc2UKCQkJewoJCQkJZFJldCA9IGF0b2woc0RpZ2l0cyk7CgkJCX0KCQl9CgoJfQoKCXJldHVybiBkUmV0Owp9Cgpkb3VibGUgQ0pTX1B1YmxpY01ldGhvZHM6OlBhcnNlU3RyaW5nVG9OdW1iZXIoRlhfTFBDV1NUUiBzd1NvdXJjZSkKewoJRlhfQk9PTCBiQWxsRGlnaXRzID0gRkFMU0U7CglGWF9CT09MIGJEb3QgPSBGQUxTRTsKCUZYX0JPT0wgYlNpZ24gPSBGQUxTRTsKCUZYX0JPT0wgYktYSlMgPSBGQUxTRTsKCglyZXR1cm4gUGFyc2VOdW1iZXIoc3dTb3VyY2UsIGJBbGxEaWdpdHMsIGJEb3QsIGJTaWduLCBiS1hKUyk7Cn0KCkZYX0JPT0wJQ0pTX1B1YmxpY01ldGhvZHM6OkNvbnZlcnRTdHJpbmdUb051bWJlcihGWF9MUENXU1RSIHN3U291cmNlLCBkb3VibGUgJiBkUmV0LCBGWF9CT09MICYgYkRvdCkKewoJRlhfQk9PTCBiQWxsRGlnaXRzID0gRkFMU0U7CglGWF9CT09MIGJTaWduID0gRkFMU0U7CglGWF9CT09MIGJLWEpTID0gRkFMU0U7CgoJZFJldCA9IFBhcnNlTnVtYmVyKHN3U291cmNlLCBiQWxsRGlnaXRzLCBiRG90LCBiU2lnbiwgYktYSlMpOwoKCXJldHVybiBiQWxsRGlnaXRzOwp9CgpDSlNfQXJyYXkgQ0pTX1B1YmxpY01ldGhvZHM6OkFGX01ha2VBcnJheUZyb21MaXN0KHY4OjpJc29sYXRlKiBpc29sYXRlLCBDSlNfVmFsdWUgdmFsKQp7CglDSlNfQXJyYXkgU3RyQXJyYXkoaXNvbGF0ZSk7CglpZih2YWwuSXNBcnJheU9iamVjdCgpKQoJewoJCXZhbC5Db252ZXJ0VG9BcnJheShTdHJBcnJheSk7CgkJcmV0dXJuIFN0ckFycmF5OwoJfQoJQ0ZYX1dpZGVTdHJpbmcgd3NTdHIgPSB2YWwub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsKCUNGWF9CeXRlU3RyaW5nIHQgPSBDRlhfQnl0ZVN0cmluZzo6RnJvbVVuaWNvZGUod3NTdHIpOwoJY29uc3QgY2hhciAqIHAgPSAoY29uc3QgY2hhciAqKXQ7CgoKCWludCBjaCA9ICcsJyA7CglpbnQgbkluZGV4ID0gMDsKCgl3aGlsZSAoKnApCgl7CgkJY29uc3QgY2hhciAqIHBUZW1wID0gc3RyY2hyKHAsIGNoKTsKCQlpZiAocFRlbXAgPT0gTlVMTCkKCQl7CgkJCVN0ckFycmF5LlNldEVsZW1lbnQobkluZGV4LCBDSlNfVmFsdWUoaXNvbGF0ZSwoRlhfTFBDU1RSKVN0clRyaW0ocCkpKTsKCQkJYnJlYWs7CgkJfQoJCWVsc2UKCQl7CgkJCWNoYXIgKiBwU3ViID0gbmV3IGNoYXJbcFRlbXAgLSBwICsgMV07CgkJCXN0cm5jcHkocFN1YiwgcCwgcFRlbXAgLSBwKTsKCQkJKihwU3ViICsgKHBUZW1wIC0gcCkpID0gJ1wwJzsKCgkJCVN0ckFycmF5LlNldEVsZW1lbnQobkluZGV4LCBDSlNfVmFsdWUoaXNvbGF0ZSwoRlhfTFBDU1RSKVN0clRyaW0ocFN1YikpKTsKCQkJZGVsZXRlIFtdcFN1YjsKCQkJCgkJCW5JbmRleCArKzsKCQkJcCA9ICsrcFRlbXA7CgkJfQoJCQoJfQoJcmV0dXJuIFN0ckFycmF5Owp9CgppbnQgQ0pTX1B1YmxpY01ldGhvZHM6OlBhcnNlU3RyaW5nSW50ZWdlcihjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyaW5nLGludCBuU3RhcnQsaW50JiBuU2tpcCwgaW50IG5NYXhTdGVwKQp7CglpbnQgblJldCA9IDA7CgluU2tpcCA9IDA7Cglmb3IgKGludCBpPW5TdGFydCwgc3o9c3RyaW5nLkdldExlbmd0aCgpOyBpIDwgc3o7IGkrKykKCXsKCQlpZiAoaS1uU3RhcnQgPiAxMCkKCQkJYnJlYWs7CgoJCUZYX1dDSEFSIGMgPSBzdHJpbmcuR2V0QXQoaSk7CgkJaWYgKElzRGlnaXQoKHdjaGFyX3QpYykpCgkJewoJCQluUmV0ID0gblJldCAqIDEwICsgKGMgLSAnMCcpOwoJCQluU2tpcCA9IGkgLSBuU3RhcnQgKyAxOwoJCQlpZiAoblNraXAgPj0gbk1heFN0ZXApIAoJCQkJYnJlYWs7CgkJfQoJCWVsc2UKCQkJYnJlYWs7Cgl9CgoJcmV0dXJuIG5SZXQ7Cn0KCkNGWF9XaWRlU3RyaW5nIENKU19QdWJsaWNNZXRob2RzOjpQYXJzZVN0cmluZ1N0cmluZyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyaW5nLCBpbnQgblN0YXJ0LCBpbnQmIG5Ta2lwKQp7CglDRlhfV2lkZVN0cmluZyBzd1JldDsKCW5Ta2lwID0gMDsKCWZvciAoaW50IGk9blN0YXJ0LCBzej1zdHJpbmcuR2V0TGVuZ3RoKCk7IGkgPCBzejsgaSsrKQoJewoJCUZYX1dDSEFSIGMgPSBzdHJpbmcuR2V0QXQoaSk7CgkJaWYgKChjID49IEwnYScgJiYgYyA8PSBMJ3onKSB8fCAoYyA+PSBMJ0EnICYmIGMgPD0gTCdaJykpCgkJewoJCQlzd1JldCArPSBjOwoJCQluU2tpcCA9IGkgLSBuU3RhcnQgKyAxOwoJCX0KCQllbHNlCgkJCWJyZWFrOwoJfQoKCXJldHVybiBzd1JldDsKfQoKZG91YmxlIENKU19QdWJsaWNNZXRob2RzOjpQYXJzZU5vcm1hbERhdGUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcgJiB2YWx1ZSwgRlhfQk9PTCYgYldyb25nRm9ybWF0KQp7Cglkb3VibGUgZHQgPSBKU19HZXREYXRlVGltZSgpOwoKCWludCBuWWVhciA9IEpTX0dldFllYXJGcm9tVGltZShkdCk7CglpbnQgbk1vbnRoID0gSlNfR2V0TW9udGhGcm9tVGltZShkdCkgKyAxOwoJaW50IG5EYXkgPSBKU19HZXREYXlGcm9tVGltZShkdCk7CglpbnQgbkhvdXIgPSBKU19HZXRIb3VyRnJvbVRpbWUoZHQpOwoJaW50IG5NaW4gPSBKU19HZXRNaW5Gcm9tVGltZShkdCk7CglpbnQgblNlYyA9IEpTX0dldFNlY0Zyb21UaW1lKGR0KTsKCglpbnQgbnVtYmVyWzNdOwoKCWludCBuU2tpcCA9IDA7CglpbnQgbkxlbiA9IHZhbHVlLkdldExlbmd0aCgpOwoJaW50IG5JbmRleCA9IDA7CglpbnQgaSA9IDA7Cgl3aGlsZSAoaSA8IG5MZW4pCgl7CgkJaWYgKG5JbmRleCA+IDIpIGJyZWFrOwoKCQlGWF9XQ0hBUiBjID0gdmFsdWUuR2V0QXQoaSk7CgkJaWYgKElzRGlnaXQoKHdjaGFyX3QpYykpCgkJewoJCQludW1iZXJbbkluZGV4KytdID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBpLCBuU2tpcCwgNCk7CgkJCWkgKz0gblNraXA7CQkJCgkJfQoJCWVsc2UKCQl7CgkJCWkgKys7CgkJfQoJfQoKCWlmIChuSW5kZXggPT0gMikKCXsKCQkvLyBjYXNlMjogbW9udGgvZGF5CgkJLy8gY2FzZTM6IGRheS9tb250aAoJCWlmICgobnVtYmVyWzBdID49IDEgJiYgbnVtYmVyWzBdIDw9IDEyKSAmJiAobnVtYmVyWzFdID49IDEgJiYgbnVtYmVyWzFdIDw9IDMxKSkKCQl7CgkJCW5Nb250aCA9IG51bWJlclswXTsKCQkJbkRheSA9IG51bWJlclsxXTsKCQl9CgkJZWxzZSBpZiAoKG51bWJlclswXSA+PSAxICYmIG51bWJlclswXSA8PSAzMSkgJiYgKG51bWJlclsxXSA+PSAxICYmIG51bWJlclsxXSA8PSAxMikpCgkJewoJCQluRGF5ID0gbnVtYmVyWzBdOwoJCQluTW9udGggPSBudW1iZXJbMV07CgkJfQoKCQliV3JvbmdGb3JtYXQgPSBGQUxTRTsKCX0KCWVsc2UgaWYgKG5JbmRleCA9PSAzKQoJewoJCS8vIGNhc2UxOiB5ZWFyL21vbnRoL2RheQoJCS8vIGNhc2UyOiBtb250aC9kYXkveWVhcgoJCS8vIGNhc2UzOiBkYXkvbW9udGgveWVhcgoKCQlpZiAobnVtYmVyWzBdID4gMTIgJiYgKG51bWJlclsxXSA+PSAxICYmIG51bWJlclsxXSA8PSAxMikgJiYgKG51bWJlclsyXSA+PSAxICYmIG51bWJlclsyXSA8PSAzMSkpCgkJewoJCQluWWVhciA9IG51bWJlclswXTsKCQkJbk1vbnRoID0gbnVtYmVyWzFdOwoJCQluRGF5ID0gbnVtYmVyWzJdOwoJCX0KCQllbHNlIGlmICgobnVtYmVyWzBdID49IDEgJiYgbnVtYmVyWzBdIDw9IDEyKSAmJiAobnVtYmVyWzFdID49IDEgJiYgbnVtYmVyWzFdIDw9IDMxKSAmJiBudW1iZXJbMl0gPiAzMSkKCQl7CgkJCW5Nb250aCA9IG51bWJlclswXTsKCQkJbkRheSA9IG51bWJlclsxXTsKCQkJblllYXIgPSBudW1iZXJbMl07CgkJfQoJCWVsc2UgaWYgKChudW1iZXJbMF0gPj0gMSAmJiBudW1iZXJbMF0gPD0gMzEpICYmIChudW1iZXJbMV0gPj0gMSAmJiBudW1iZXJbMV0gPD0gMTIpICYmIG51bWJlclsyXSA+IDMxKQoJCXsKCQkJbkRheSA9IG51bWJlclswXTsKCQkJbk1vbnRoID0gbnVtYmVyWzFdOwoJCQluWWVhciA9IG51bWJlclsyXTsKCQl9CgoJCWJXcm9uZ0Zvcm1hdCA9IEZBTFNFOwoJfQoJZWxzZQoJewoJCWJXcm9uZ0Zvcm1hdCA9IFRSVUU7CgkJcmV0dXJuIGR0OwoJfQoKCUNGWF9XaWRlU3RyaW5nIHN3VGVtcDsKCXN3VGVtcC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlZC8lZC8lZCAlZDolZDolZCIsbk1vbnRoLG5EYXksblllYXIsbkhvdXIsbk1pbixuU2VjKTsKCXJldHVybiBKU19EYXRlUGFyc2Uoc3dUZW1wKTsKfQoKZG91YmxlIENKU19QdWJsaWNNZXRob2RzOjpNYWtlUmVndWxhckRhdGUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcgJiB2YWx1ZSwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcgJiBmb3JtYXQsIEZYX0JPT0wmIGJXcm9uZ0Zvcm1hdCkKewoJZG91YmxlIGR0ID0gSlNfR2V0RGF0ZVRpbWUoKTsKCglpZiAoZm9ybWF0LklzRW1wdHkoKSB8fCB2YWx1ZS5Jc0VtcHR5KCkpCgkJcmV0dXJuIGR0OwoKCWludCBuWWVhciA9IEpTX0dldFllYXJGcm9tVGltZShkdCk7CglpbnQgbk1vbnRoID0gSlNfR2V0TW9udGhGcm9tVGltZShkdCkgKyAxOwoJaW50IG5EYXkgPSBKU19HZXREYXlGcm9tVGltZShkdCk7CglpbnQgbkhvdXIgPSBKU19HZXRIb3VyRnJvbVRpbWUoZHQpOwoJaW50IG5NaW4gPSBKU19HZXRNaW5Gcm9tVGltZShkdCk7CglpbnQgblNlYyA9IEpTX0dldFNlY0Zyb21UaW1lKGR0KTsKCglpbnQgblllYXJTdWIgPSA5OTsgLy9uWWVhciAtIDIwMDA7CgoJRlhfQk9PTCBiUG0gPSBGQUxTRTsKCUZYX0JPT0wgYkV4aXQgPSBGQUxTRTsKCWJXcm9uZ0Zvcm1hdCA9IEZBTFNFOwoKCWludCBpPTA7CglpbnQgaj0wOwoKCXdoaWxlIChpIDwgZm9ybWF0LkdldExlbmd0aCgpKQoJewoJCWlmIChiRXhpdCkgYnJlYWs7CgoJCUZYX1dDSEFSIGMgPSBmb3JtYXQuR2V0QXQoaSk7CgkJc3dpdGNoIChjKQoJCXsKCQkJY2FzZSAnOic6CgkJCWNhc2UgJy4nOgoJCQljYXNlICctJzoKCQkJY2FzZSAnXFwnOgoJCQljYXNlICcvJzoKCQkJCWkrKzsKCQkJCWorKzsKCQkJCWJyZWFrOwoKCQkJY2FzZSAneSc6CgkJCWNhc2UgJ20nOgoJCQljYXNlICdkJzoKCQkJY2FzZSAnSCc6CgkJCWNhc2UgJ2gnOgoJCQljYXNlICdNJzoKCQkJY2FzZSAncyc6CgkJCWNhc2UgJ3QnOgoJCQkJewoJCQkJCWludCBvbGRqID0gajsKCQkJCQlpbnQgblNraXAgPSAwOwoJCQkJCWludCByZW1haW5pbmcgPSBmb3JtYXQuR2V0TGVuZ3RoKCkgLSBpIC0gMTsKCgkJCQkJaWYgKHJlbWFpbmluZyA9PSAwIHx8IGZvcm1hdC5HZXRBdChpKzEpICE9IGMpCgkJCQkJewoJCQkJCQlzd2l0Y2ggKGMpCgkJCQkJCXsKCQkJCQkJCWNhc2UgJ3knOgoJCQkJCQkJCWkrKzsKCQkJCQkJCQlqKys7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlICdtJzoKCQkJCQkJCQluTW9udGggPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAyKTsKCQkJCQkJCQlpKys7CgkJCQkJCQkJaiArPSBuU2tpcDsKCQkJCQkJCQlicmVhazsKCQkJCQkJCWNhc2UgJ2QnOgoJCQkJCQkJCW5EYXkgPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAyKTsKCQkJCQkJCQlpKys7CgkJCQkJCQkJaiArPSBuU2tpcDsKCQkJCQkJCQlicmVhazsKCQkJCQkJCWNhc2UgJ0gnOgoJCQkJCQkJCW5Ib3VyID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMik7CgkJCQkJCQkJaSsrOwoJCQkJCQkJCWogKz0gblNraXA7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlICdoJzoKCQkJCQkJCQluSG91ciA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDIpOwoJCQkJCQkJCWkrKzsKCQkJCQkJCQlqICs9IG5Ta2lwOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJY2FzZSAnTSc6CgkJCQkJCQkJbk1pbiA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDIpOwoJCQkJCQkJCWkrKzsKCQkJCQkJCQlqICs9IG5Ta2lwOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJY2FzZSAncyc6CgkJCQkJCQkJblNlYyA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDIpOwoJCQkJCQkJCWkrKzsKCQkJCQkJCQlqICs9IG5Ta2lwOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJY2FzZSAndCc6CgkJCQkJCQkJYlBtID0gKGogPCB2YWx1ZS5HZXRMZW5ndGgoKSAmJiB2YWx1ZS5HZXRBdChqKSA9PSAncCcpOwoJCQkJCQkJCWkrKzsKCQkJCQkJCQlqKys7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCX0KCQkJCQl9CgkJCQkJZWxzZSBpZiAocmVtYWluaW5nID09IDEgfHwgZm9ybWF0LkdldEF0KGkrMikgIT0gYykKCQkJCQl7CgkJCQkJCXN3aXRjaCAoYykKCQkJCQkJewoJCQkJCQkJY2FzZSAneSc6CgkJCQkJCQkJblllYXIgPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCA0KTsKCQkJCQkJCQlpICs9IDI7CgkJCQkJCQkJaiArPSBuU2tpcDsKCQkJCQkJCQlicmVhazsKCQkJCQkJCWNhc2UgJ20nOgoJCQkJCQkJCW5Nb250aCA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDIpOwoJCQkJCQkJCWkgKz0gMjsKCQkJCQkJCQlqICs9IG5Ta2lwOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJY2FzZSAnZCc6CgkJCQkJCQkJbkRheSA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDIpOwoJCQkJCQkJCWkgKz0gMjsKCQkJCQkJCQlqICs9IG5Ta2lwOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJY2FzZSAnSCc6CgkJCQkJCQkJbkhvdXIgPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAyKTsKCQkJCQkJCQlpICs9IDI7CgkJCQkJCQkJaiArPSBuU2tpcDsKCQkJCQkJCQlicmVhazsKCQkJCQkJCWNhc2UgJ2gnOgoJCQkJCQkJCW5Ib3VyID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMik7CgkJCQkJCQkJaSArPSAyOwoJCQkJCQkJCWogKz0gblNraXA7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlICdNJzoKCQkJCQkJCQluTWluID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMik7CgkJCQkJCQkJaSArPSAyOwoJCQkJCQkJCWogKz0gblNraXA7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlICdzJzoKCQkJCQkJCQluU2VjID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMik7CgkJCQkJCQkJaSArPSAyOwoJCQkJCQkJCWogKz0gblNraXA7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlICd0JzoKCQkJCQkJCQliUG0gPSAoaiArIDEgPCB2YWx1ZS5HZXRMZW5ndGgoKSAmJiB2YWx1ZS5HZXRBdChqKSA9PSAncCcgJiYgdmFsdWUuR2V0QXQoaisxKSA9PSAnbScpOwoJCQkJCQkJCWkgKz0gMjsKCQkJCQkJCQlqICs9IDI7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCX0KCQkJCQl9CgkJCQkJZWxzZSBpZiAocmVtYWluaW5nID09IDIgfHwgZm9ybWF0LkdldEF0KGkrMykgIT0gYykKCQkJCQl7CgkJCQkJCXN3aXRjaCAoYykKCQkJCQkJewoJCQkJCQkJY2FzZSAnbSc6CgkJCQkJCQkJewoJCQkJCQkJCQlDRlhfV2lkZVN0cmluZyBzTW9udGggPSBQYXJzZVN0cmluZ1N0cmluZyh2YWx1ZSwgaiwgblNraXApOwoJCQkJCQkJCQlGWF9CT09MIGJGaW5kID0gRkFMU0U7CgkJCQkJCQkJCWZvciAoaW50IG0gPSAwOyBtIDwgMTI7IG0rKykKCQkJCQkJCQkJewoJCQkJCQkJCQkJaWYgKHNNb250aC5Db21wYXJlTm9DYXNlKG1vbnRoc1ttXSkgPT0gMCkKCQkJCQkJCQkJCXsKCQkJCQkJCQkJCQluTW9udGggPSBtICsgMTsKCQkJCQkJCQkJCQlpKz0zOwoJCQkJCQkJCQkJCWorPW5Ta2lwOwoJCQkJCQkJCQkJCWJGaW5kID0gVFJVRTsKCQkJCQkJCQkJCQlicmVhazsKCQkJCQkJCQkJCX0KCQkJCQkJCQkJfQoKCQkJCQkJCQkJaWYgKCFiRmluZCkKCQkJCQkJCQkJewoJCQkJCQkJCQkJbk1vbnRoID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMyk7CgkJCQkJCQkJCQlpKz0zOwoJCQkJCQkJCQkJaiArPSBuU2tpcDsKCQkJCQkJCQkJfQoJCQkJCQkJCX0KCQkJCQkJCQlicmVhazsKCQkJCQkJCWNhc2UgJ3knOgoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJZGVmYXVsdDoKCQkJCQkJCQlpKz0zOwoJCQkJCQkJCWorPTM7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCX0KCQkJCQl9CgkJCQkJZWxzZSBpZiAocmVtYWluaW5nID09IDMgfHwgZm9ybWF0LkdldEF0KGkrNCkgIT0gYykKCQkJCQl7CgkJCQkJCXN3aXRjaCAoYykKCQkJCQkJewoKCgkJCQkJCQljYXNlICd5JzoKCQkJCQkJCQluWWVhciA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDQpOwoJCQkJCQkJCWogKz0gblNraXA7CgkJCQkJCQkJaSArPSA0OwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJY2FzZSAnbSc6CgkJCQkJCQkJewoJCQkJCQkJCQlGWF9CT09MIGJGaW5kID0gRkFMU0U7CgoJCQkJCQkJCQlDRlhfV2lkZVN0cmluZyBzTW9udGggPSBQYXJzZVN0cmluZ1N0cmluZyh2YWx1ZSwgaiwgblNraXApOwoJCQkJCQkJCQlzTW9udGguTWFrZUxvd2VyKCk7CgoJCQkJCQkJCQlmb3IgKGludCBtID0gMDsgbSA8IDEyOyBtKyspCgkJCQkJCQkJCXsKCQkJCQkJCQkJCUNGWF9XaWRlU3RyaW5nIHNGdWxsTW9udGhzID0gZnVsbG1vbnRoc1ttXTsKCQkJCQkJCQkJCXNGdWxsTW9udGhzLk1ha2VMb3dlcigpOwoKCQkJCQkJCQkJCWlmIChzRnVsbE1vbnRocy5GaW5kKHNNb250aCwgMCkgIT0gLTEpCgkJCQkJCQkJCQl7CgkJCQkJCQkJCQkJbk1vbnRoID0gbSArIDE7CgkJCQkJCQkJCQkJaSArPSA0OwoJCQkJCQkJCQkJCWogKz0gblNraXA7CgkJCQkJCQkJCQkJYkZpbmQgPSBUUlVFOwoJCQkJCQkJCQkJCWJyZWFrOwoJCQkJCQkJCQkJfQoJCQkJCQkJCQl9CgoJCQkJCQkJCQlpZiAoIWJGaW5kKQoJCQkJCQkJCQl7CgkJCQkJCQkJCQluTW9udGggPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCA0KTsKCQkJCQkJCQkJCWkrPTQ7CgkJCQkJCQkJCQlqICs9IG5Ta2lwOwoJCQkJCQkJCQl9CgkJCQkJCQkJfQoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJZGVmYXVsdDoKCQkJCQkJCQlpICs9IDQ7CgkJCQkJCQkJaiArPSA0OwoJCQkJCQkJCWJyZWFrOwoJCQkJCQl9CgkJCQkJfQoJCQkJCWVsc2UKCQkJCQl7CgkJCQkJCWlmIChqID49IHZhbHVlLkdldExlbmd0aCgpIHx8IGZvcm1hdC5HZXRBdChpKSAhPSB2YWx1ZS5HZXRBdChqKSkKCQkJCQkJewoJCQkJCQkJYldyb25nRm9ybWF0ID0gVFJVRTsKCQkJCQkJCWJFeGl0ID0gVFJVRTsKCQkJCQkJfQoJCQkJCQlpKys7CgkJCQkJCWorKzsKCQkJCQl9CgoJCQkJCWlmIChvbGRqID09IGopCgkJCQkJewoJCQkJCQliV3JvbmdGb3JtYXQgPSBUUlVFOwoJCQkJCQliRXhpdCA9IFRSVUU7CgkJCQkJfQoJCQkJfQoKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJaWYgKHZhbHVlLkdldExlbmd0aCgpIDw9IGopCgkJCQl7CgkJCQkJYkV4aXQgPSBUUlVFOwoJCQkJfQoJCQkJZWxzZSBpZiAoZm9ybWF0LkdldEF0KGkpICE9IHZhbHVlLkdldEF0KGopKQoJCQkJewoJCQkJCWJXcm9uZ0Zvcm1hdCA9IFRSVUU7CgkJCQkJYkV4aXQgPSBUUlVFOwoJCQkJfQoKCQkJCWkrKzsKCQkJCWorKzsKCQkJCWJyZWFrOwoJCX0KCX0KCglpZiAoYlBtKSBuSG91ciArPSAxMjsKCglpZiAoblllYXIgPj0gMCAmJiBuWWVhciA8PSBuWWVhclN1YikKCQluWWVhciArPSAyMDAwOwoKCWlmIChuTW9udGggPCAxIHx8IG5Nb250aCA+IDEyKQoJCWJXcm9uZ0Zvcm1hdCA9IFRSVUU7CgoJaWYgKG5EYXkgPCAxIHx8IG5EYXkgPiAzMSkKCQliV3JvbmdGb3JtYXQgPSBUUlVFOwoKCWlmIChuSG91ciA8IDAgfHwgbkhvdXIgPiAyNCkKCQliV3JvbmdGb3JtYXQgPSBUUlVFOwoKCWlmIChuTWluIDwgMCB8fCBuTWluID4gNjApCgkJYldyb25nRm9ybWF0ID0gVFJVRTsKCglpZiAoblNlYyA8IDAgfHwgblNlYyA+IDYwKQoJCWJXcm9uZ0Zvcm1hdCA9IFRSVUU7CgoJZG91YmxlIGRSZXQgPSAwOwoKCWlmIChiV3JvbmdGb3JtYXQpCgl7CgkJZFJldCA9IFBhcnNlTm9ybWFsRGF0ZSh2YWx1ZSwgYldyb25nRm9ybWF0KTsKCX0KCWVsc2UKCXsKCQlkUmV0ID0gSlNfTWFrZURhdGUoSlNfTWFrZURheShuWWVhcixuTW9udGggLSAxLG5EYXkpLEpTX01ha2VUaW1lKG5Ib3VyLCBuTWluLCBuU2VjLCAwKSk7CgoJCWlmIChKU19Qb3J0SXNOYW4oZFJldCkpCgkJewoJCQlkUmV0ID0gSlNfRGF0ZVBhcnNlKHZhbHVlKTsKCQl9Cgl9CgoJaWYgKEpTX1BvcnRJc05hbihkUmV0KSkKCXsKCQlkUmV0ID0gUGFyc2VOb3JtYWxEYXRlKHZhbHVlLCBiV3JvbmdGb3JtYXQpOwoJfQoKCXJldHVybiBkUmV0OwoKfQoKQ0ZYX1dpZGVTdHJpbmcgQ0pTX1B1YmxpY01ldGhvZHM6Ok1ha2VGb3JtYXREYXRlKGRvdWJsZSBkRGF0ZSwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcgJiBmb3JtYXQpCnsKCUNGWF9XaWRlU3RyaW5nIHNSZXQgPSBMIiIsc1BhcnQgPSBMIiI7CgoJaW50IG5ZZWFyID0gSlNfR2V0WWVhckZyb21UaW1lKGREYXRlKTsKCWludCBuTW9udGggPSBKU19HZXRNb250aEZyb21UaW1lKGREYXRlKSArIDE7CglpbnQgbkRheSA9IEpTX0dldERheUZyb21UaW1lKGREYXRlKTsKCWludCBuSG91ciA9IEpTX0dldEhvdXJGcm9tVGltZShkRGF0ZSk7CglpbnQgbk1pbiA9IEpTX0dldE1pbkZyb21UaW1lKGREYXRlKTsKCWludCBuU2VjID0gSlNfR2V0U2VjRnJvbVRpbWUoZERhdGUpOwoKCWludCBpID0gMDsKCUZYX1dDSEFSIGM7Cgl3aGlsZSAoaSA8IGZvcm1hdC5HZXRMZW5ndGgoKSkKCXsKCQljID0gZm9ybWF0LkdldEF0KGkpOwoJCXNQYXJ0ID0gTCIiOwoJCXN3aXRjaCAoYykKCQl7CgkJCWNhc2UgJ3knOgoJCQljYXNlICdtJzoKCQkJY2FzZSAnZCc6CgkJCWNhc2UgJ0gnOgoJCQljYXNlICdoJzoKCQkJY2FzZSAnTSc6CgkJCWNhc2UgJ3MnOgoJCQljYXNlICd0JzoKCQkJCWlmIChmb3JtYXQuR2V0QXQoaSsxKSAhPSBjKQoJCQkJewoJCQkJCXN3aXRjaCAoYykKCQkJCQl7CgkJCQkJCWNhc2UgJ3knOgoJCQkJCQkJc1BhcnQgKz0gYzsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICdtJzoKCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkIixuTW9udGgpOwoJCQkJCQkJYnJlYWs7CgkJCQkJCWNhc2UgJ2QnOgoJCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJWQiLG5EYXkpOwoJCQkJCQkJYnJlYWs7CgkJCQkJCWNhc2UgJ0gnOgoJCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJWQiLG5Ib3VyKTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICdoJzoKCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkIixuSG91cj4xMj9uSG91ciAtIDEyOm5Ib3VyKTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICdNJzoKCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkIixuTWluKTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICdzJzoKCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkIixuU2VjKTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICd0JzoJCQkJCgkJCQkJCQlzUGFydCArPSBuSG91cj4xMj8ncCc6J2EnOwoJCQkJCQkJYnJlYWs7CgkJCQkJfQkJCQkJCgkJCQkJaSsrOwoJCQkJfQoJCQkJZWxzZSBpZiAoZm9ybWF0LkdldEF0KGkrMSkgPT0gYyAmJiBmb3JtYXQuR2V0QXQoaSsyKSAhPSBjKQoJCQkJewoJCQkJCXN3aXRjaCAoYykKCQkJCQl7CgkJCQkJCWNhc2UgJ3knOgoJCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJTAyZCIsblllYXIgLSAoblllYXIgLyAxMDApICogMTAwKTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICdtJzoKCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiUwMmQiLG5Nb250aCk7CgkJCQkJCQlicmVhazsKCQkJCQkJY2FzZSAnZCc6CgkJCQkJCQlzUGFydC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlMDJkIixuRGF5KTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICdIJzoKCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiUwMmQiLG5Ib3VyKTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICdoJzoKCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiUwMmQiLG5Ib3VyPjEyP25Ib3VyIC0gMTI6bkhvdXIpOwoJCQkJCQkJYnJlYWs7CgkJCQkJCWNhc2UgJ00nOgoJCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJTAyZCIsbk1pbik7CgkJCQkJCQlicmVhazsKCQkJCQkJY2FzZSAncyc6CgkJCQkJCQlzUGFydC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlMDJkIixuU2VjKTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICd0JzoJCQkJCQkJCgkJCQkJCQlzUGFydCA9IG5Ib3VyPjEyPyAoRlhfTFBDV1NUUilMInBtIjogKEZYX0xQQ1dTVFIpTCJhbSI7CgkJCQkJCQlicmVhazsKCQkJCQl9CQkJCgkJCQkJaSs9MjsKCQkJCX0KCQkJCWVsc2UgaWYgKGZvcm1hdC5HZXRBdChpKzEpID09IGMgJiYgZm9ybWF0LkdldEF0KGkrMikgPT0gYyAmJiBmb3JtYXQuR2V0QXQoaSszKSAhPSBjKQoJCQkJewkJCgkJCQkJc3dpdGNoIChjKQoJCQkJCXsKCQkJCQkJY2FzZSAnbSc6CgkJCQkJCQlpKz0zOwoJCQkJCQkJaWYgKG5Nb250aCA+IDAmJm5Nb250aCA8PSAxMikKCQkJCQkJCQlzUGFydCArPSBtb250aHNbbk1vbnRoIC0gMV07CgkJCQkJCQlicmVhazsKCQkJCQkJZGVmYXVsdDoKCQkJCQkJCWkrPTM7CgkJCQkJCQlzUGFydCArPSBjOwoJCQkJCQkJc1BhcnQgKz0gYzsKCQkJCQkJCXNQYXJ0ICs9IGM7CgkJCQkJCQlicmVhazsKCQkJCQl9CQkJCQkKCQkJCX0KCQkJCWVsc2UgaWYgKGZvcm1hdC5HZXRBdChpKzEpID09IGMgJiYgZm9ybWF0LkdldEF0KGkrMikgPT0gYyAmJiBmb3JtYXQuR2V0QXQoaSszKSA9PSBjICYmIGZvcm1hdC5HZXRBdChpKzQpICE9IGMpCgkJCQl7CgkJCQkJc3dpdGNoIChjKQoJCQkJCXsKCQkJCQkJY2FzZSAneSc6CgkJCQkJCQlzUGFydC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlMDRkIixuWWVhcik7CgkJCQkJCQlpICs9IDQ7CgkJCQkJCQlicmVhazsJCgkJCQkJCWNhc2UgJ20nOgoJCQkJCQkJaSs9NDsKCQkJCQkJCWlmIChuTW9udGggPiAwJiZuTW9udGggPD0gMTIpCgkJCQkJCQkJc1BhcnQgKz0gZnVsbG1vbnRoc1tuTW9udGggLSAxXTsKCQkJCQkJCWJyZWFrOwoJCQkJCQlkZWZhdWx0OgoJCQkJCQkJaSArPSA0OwoJCQkJCQkJc1BhcnQgKz0gYzsKCQkJCQkJCXNQYXJ0ICs9IGM7CgkJCQkJCQlzUGFydCArPSBjOwoJCQkJCQkJc1BhcnQgKz0gYzsKCQkJCQkJCWJyZWFrOwoJCQkJCX0JCQkJCQoJCQkJfQoJCQkJZWxzZQoJCQkJewoJCQkJCWkrKzsKCQkJCQlzUGFydCArPSBjOwoJCQkJfQoJCQkJYnJlYWs7CQkJCgkJCWRlZmF1bHQ6CgkJCQlpKys7CgkJCQlzUGFydCArPSBjOwoJCQkJYnJlYWs7CgkJfQoJCQoJCXNSZXQgKz0gc1BhcnQ7Cgl9CgoJcmV0dXJuIHNSZXQ7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovL2Z1bmN0aW9uIEFGTnVtYmVyX0Zvcm1hdChuRGVjLCBzZXBTdHlsZSwgbmVnU3R5bGUsIGN1cnJTdHlsZSwgc3RyQ3VycmVuY3ksIGJDdXJyZW5jeVByZXBlbmQpCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGTnVtYmVyX0Zvcm1hdChPQkpfTUVUSE9EX1BBUkFNUykKewojaWYgX0ZYX09TXyAhPSBfRlhfQU5EUk9JRF8KCXY4OjpJc29sYXRlKiBpc29sYXRlID0gOjpHZXRJc29sYXRlKGNjKTsKCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOwoJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOwoJQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOwoJQVNTRVJUKHBFdmVudCAhPSBOVUxMKTsKCglpZiAocGFyYW1zLnNpemUoKSAhPSA2KQoJewoJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CgkJcmV0dXJuIEZBTFNFOwoJfQoJaWYoIXBFdmVudC0+bV9wVmFsdWUpCgkJcmV0dXJuIEZBTFNFOwoJQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlID0gcEV2ZW50LT5WYWx1ZSgpOwkKCUNGWF9CeXRlU3RyaW5nIHN0clZhbHVlID0gU3RyVHJpbShDRlhfQnl0ZVN0cmluZzo6RnJvbVVuaWNvZGUoVmFsdWUpKTsKCQoJaWYgKHN0clZhbHVlLklzRW1wdHkoKSkgcmV0dXJuIFRSVUU7CgkKCWludCBpRGVjID0gcGFyYW1zWzBdOwoJaW50IGlTZXBTdHlsZSA9IHBhcmFtc1sxXTsKCWludCBpTmVnU3R5bGUgPSBwYXJhbXNbMl07CglpbnQgaWN1cnJTdHlsZSA9IHBhcmFtc1szXTsgLy9pdCdzIG5vIHVzZSEKCXN0ZDo6d3N0cmluZyB3c3RyQ3VycmVuY3kocGFyYW1zWzRdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCkpOwoJRlhfQk9PTCBiQ3VycmVuY3lQcmVwZW5kID0gcGFyYW1zWzVdOwoJCglpZiAoaURlYyA8IDApIGlEZWMgPSAtaURlYzsKCQoJaWYgKGlTZXBTdHlsZSA8IDAgfHwgaVNlcFN0eWxlID4gMykKCQlpU2VwU3R5bGUgPSAwOwoJCglpZiAoaU5lZ1N0eWxlIDwgMCB8fCBpTmVnU3R5bGUgPiAzKQoJCWlOZWdTdHlsZSA9IDA7CgkKCQoJLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgkvL2ZvciBwcm9jZXNzaW5nIGRlY2ltYWwgcGxhY2VzCglzdHJWYWx1ZS5SZXBsYWNlKCIsIiwgIi4iKTsKCWRvdWJsZSBkVmFsdWUgPSBhdG9mKHN0clZhbHVlKTsKCWlmIChpRGVjID4gMCkKCQlkVmFsdWUgKz0gRE9VQkxFX0NPUlJFQ1Q7Ly8KCQkgICAgCglpbnQgaURlYzI7CglGWF9CT09MIGJOYWdhdGl2ZSA9IEZBTFNFOwoKCXN0clZhbHVlID0gZmN2dChkVmFsdWUsaURlYywmaURlYzIsJmJOYWdhdGl2ZSk7CglpZiAoc3RyVmFsdWUuSXNFbXB0eSgpKQoJewoJCWRWYWx1ZSA9IDA7CgkJc3RyVmFsdWUgPSBmY3Z0KGRWYWx1ZSxpRGVjLCZpRGVjMiwmYk5hZ2F0aXZlKTsKCQlpZiAoc3RyVmFsdWUuSXNFbXB0eSgpKQoJCXsKCQkJc3RyVmFsdWUgPSAiMCI7CgkJCWlEZWMyID0gMTsKCQl9CgoJfQoKCWlmIChpRGVjMiA8IDApCgl7CgkJZm9yIChpbnQgaU51bSA9IDA7aU51bSA8IGFicyhpRGVjMik7aU51bSsrKQoJCXsKCQkJc3RyVmFsdWUgPSAiMCIgKyBzdHJWYWx1ZTsKCQl9CgkJaURlYzIgPSAwOwoJCQoJfQoJaW50IGlNYXggPSBzdHJWYWx1ZS5HZXRMZW5ndGgoKTsKCWlmIChpRGVjMiA+IGlNYXgpCgl7CgkJZm9yIChpbnQgaU51bSA9IDA7aU51bSA8PSBpRGVjMiAtIGlNYXggO2lOdW0rKykKCQl7CgkJCXN0clZhbHVlICs9ICIwIjsKCQl9CgkJaU1heCA9IGlEZWMyKzE7CQkJCgl9CgkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCiAgICAvL2ZvciBwcm9jZXNzaW5nIHNlcGVyYXRvciBzdHlsZQoJaWYgKGlEZWMyIDwgaU1heCkKCXsKCQlpZiAoaVNlcFN0eWxlID09IDAgfHwgaVNlcFN0eWxlID09IDEpCgkJewoJCQlzdHJWYWx1ZS5JbnNlcnQoaURlYzIsICcuJyk7CgkJCWlNYXgrKzsKCQl9CgkJZWxzZSBpZiAoaVNlcFN0eWxlID09IDIgfHwgaVNlcFN0eWxlID09IDMpCgkJewoJCQlzdHJWYWx1ZS5JbnNlcnQoaURlYzIsICcsJyk7CgkJCWlNYXgrKzsKCQl9CgkJCgkJaWYgKGlEZWMyID09IDApCgkJCXN0clZhbHVlLkluc2VydChpRGVjMiwgJzAnKTsKCX0KCWlmIChpU2VwU3R5bGUgPT0gMCB8fCBpU2VwU3R5bGUgPT0gMikKCXsKCQljaGFyIGNTZXBlcmF0b3I7CgkJaWYgKGlTZXBTdHlsZSA9PSAwKQoJCQljU2VwZXJhdG9yID0gJywnOwoJCWVsc2UKCQkJY1NlcGVyYXRvciA9ICcuJzsKCQkKCQlpbnQgaURlY1Bvc2l0aXZlLGlEZWNOYWdhdGl2ZTsKCQlpRGVjUG9zaXRpdmUgPSBpRGVjMjsKCQlpRGVjTmFnYXRpdmUgPSBpRGVjMjsJCQoJCQoJCWZvciAoaURlY1Bvc2l0aXZlID0gaURlYzIgLTM7IGlEZWNQb3NpdGl2ZSA+IDA7aURlY1Bvc2l0aXZlIC09IDMpCgkJewoJCQlzdHJWYWx1ZS5JbnNlcnQoaURlY1Bvc2l0aXZlLCBjU2VwZXJhdG9yKTsKCQkJaU1heCsrOwoJCX0KCX0KCQoJLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwogICAgLy9mb3IgcHJvY2Vzc2luZyBjdXJyZW5jeSBzdHJpbmcKCglWYWx1ZSA9IENGWF9XaWRlU3RyaW5nOjpGcm9tTG9jYWwoc3RyVmFsdWUpOwoJCglzdGQ6OndzdHJpbmcgc3RyVmFsdWUyKFZhbHVlKTsKCglpZiAoYkN1cnJlbmN5UHJlcGVuZCkKCQlzdHJWYWx1ZTIgPSB3c3RyQ3VycmVuY3kgKyBzdHJWYWx1ZTI7CgllbHNlCgkJc3RyVmFsdWUyID0gc3RyVmFsdWUyICsgd3N0ckN1cnJlbmN5OwoJCgkKCQoJLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwoJLy9mb3IgcHJvY2Vzc2luZyBuZWdhdGl2ZSBzdHlsZQoJaWYgKGJOYWdhdGl2ZSkKCXsKCQlpZiAoaU5lZ1N0eWxlID09IDApCgkJewoJCQlzdHJWYWx1ZTIuaW5zZXJ0KDAsTCItIik7CgkJfQoJCWlmIChpTmVnU3R5bGUgPT0gMiB8fCBpTmVnU3R5bGUgPT0gMykKCQl7CgkJCXN0clZhbHVlMi5pbnNlcnQoMCxMIigiKTsKCQkJc3RyVmFsdWUyLmluc2VydChzdHJWYWx1ZTIubGVuZ3RoKCksTCIpIik7CgkJfQoJCWlmIChpTmVnU3R5bGUgPT0gMSB8fCBpTmVnU3R5bGUgPT0gMykKCQl7CgkJCWlmIChGaWVsZCAqIGZUYXJnZXQgPSBwRXZlbnQtPlRhcmdldF9GaWVsZCgpKQoJCQl7CgkJCQlDSlNfQXJyYXkgYXJDb2xvcihpc29sYXRlKTsKCQkJCUNKU19WYWx1ZSB2Q29sRWxtKGlzb2xhdGUpOwoJCQkJdkNvbEVsbSA9IEwiUkdCIjsKCQkJCWFyQ29sb3IuU2V0RWxlbWVudCgwLHZDb2xFbG0pOwoJCQkJdkNvbEVsbSA9IDE7CgkJCQlhckNvbG9yLlNldEVsZW1lbnQoMSx2Q29sRWxtKTsKCQkJCXZDb2xFbG0gPSAwOwoJCQkJYXJDb2xvci5TZXRFbGVtZW50KDIsdkNvbEVsbSk7CgkJCQkKCQkJCWFyQ29sb3IuU2V0RWxlbWVudCgzLHZDb2xFbG0pOwoJCQkJCgkJCQlDSlNfUHJvcFZhbHVlIHZQcm9wKGlzb2xhdGUpOwoJCQkJdlByb3AuU3RhcnRHZXR0aW5nKCk7CgkJCQl2UHJvcDw8YXJDb2xvcjsKCQkJCXZQcm9wLlN0YXJ0U2V0dGluZygpOwoJCQkJZlRhcmdldC0+dGV4dENvbG9yKGNjLHZQcm9wLHNFcnJvcik7Ly8gcmVkCgkJCX0KCQl9Cgl9CgllbHNlCgl7CgkJaWYgKGlOZWdTdHlsZSA9PSAxIHx8IGlOZWdTdHlsZSA9PSAzKQoJCXsKCQkJaWYgKEZpZWxkICpmVGFyZ2V0ID0gcEV2ZW50LT5UYXJnZXRfRmllbGQoKSkKCQkJewoJCQkJQ0pTX0FycmF5IGFyQ29sb3IoaXNvbGF0ZSk7CgkJCQlDSlNfVmFsdWUgdkNvbEVsbShpc29sYXRlKTsKCQkJCXZDb2xFbG0gPSBMIlJHQiI7CgkJCQlhckNvbG9yLlNldEVsZW1lbnQoMCx2Q29sRWxtKTsKCQkJCXZDb2xFbG0gPSAwOwoJCQkJYXJDb2xvci5TZXRFbGVtZW50KDEsdkNvbEVsbSk7CgkJCQlhckNvbG9yLlNldEVsZW1lbnQoMix2Q29sRWxtKTsKCQkJCWFyQ29sb3IuU2V0RWxlbWVudCgzLHZDb2xFbG0pOwoJCQkJCgkJCQlDSlNfUHJvcFZhbHVlIHZQcm9wKGlzb2xhdGUpOwoJCQkJdlByb3AuU3RhcnRHZXR0aW5nKCk7CgkJCQlmVGFyZ2V0LT50ZXh0Q29sb3IoY2MsdlByb3Asc0Vycm9yKTsKCQkJCQoJCQkJQ0pTX0FycmF5IGFQcm9wKGlzb2xhdGUpOwoJCQkJdlByb3AuQ29udmVydFRvQXJyYXkoYVByb3ApOwoKCQkJCUNQV0xfQ29sb3IgY3JQcm9wOwoJCQkJQ1BXTF9Db2xvciBjckNvbG9yOwoJCQkJY29sb3I6OkNvbnZlcnRBcnJheVRvUFdMQ29sb3IoYVByb3AsIGNyUHJvcCk7CgkJCQljb2xvcjo6Q29udmVydEFycmF5VG9QV0xDb2xvcihhckNvbG9yLCBjckNvbG9yKTsKCgkJCQlpZiAoY3JDb2xvciAhPSBjclByb3ApCgkJCQl7CgkJCQkJQ0pTX1Byb3BWYWx1ZSB2UHJvcDIoaXNvbGF0ZSk7CgkJCQkJdlByb3AyLlN0YXJ0R2V0dGluZygpOwoJCQkJCXZQcm9wMjw8YXJDb2xvcjsKCQkJCQl2UHJvcDIuU3RhcnRTZXR0aW5nKCk7CiAgICAgCQkJCWZUYXJnZXQtPnRleHRDb2xvcihjYyx2UHJvcDIsc0Vycm9yKTsKCQkJCX0KCQkJfQoJCX0KCX0KCVZhbHVlID0gc3RyVmFsdWUyLmNfc3RyKCk7CiNlbmRpZgoJcmV0dXJuIFRSVUU7Cn0KCi8vZnVuY3Rpb24gQUZOdW1iZXJfS2V5c3Ryb2tlKG5EZWMsIHNlcFN0eWxlLCBuZWdTdHlsZSwgY3VyclN0eWxlLCBzdHJDdXJyZW5jeSwgYkN1cnJlbmN5UHJlcGVuZCkKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZOdW1iZXJfS2V5c3Ryb2tlKE9CSl9NRVRIT0RfUEFSQU1TKQp7CglDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsKCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7CgkKCWlmKHBhcmFtcy5zaXplKCkgPCAyKQoJCXJldHVybiBGQUxTRTsKCWludCBpU2VwU3R5bGUgPSBwYXJhbXNbMV07CgkKCWlmIChpU2VwU3R5bGUgPCAwIHx8IGlTZXBTdHlsZSA+IDMpCgkJaVNlcFN0eWxlID0gMDsKCWlmKCFwRXZlbnQtPm1fcFZhbHVlKQoJCXJldHVybiBGQUxTRTsKCUNGWF9XaWRlU3RyaW5nICYgdmFsID0gcEV2ZW50LT5WYWx1ZSgpOwkKCUNGWF9XaWRlU3RyaW5nICYgd19zdHJDaGFuZ2UgPSBwRXZlbnQtPkNoYW5nZSgpOwogICAgQ0ZYX1dpZGVTdHJpbmcgd19zdHJWYWx1ZSA9IHZhbDsKCglpZiAocEV2ZW50LT5XaWxsQ29tbWl0KCkpCgl7CgkJQ0ZYX1dpZGVTdHJpbmcgd3N0ckNoYW5nZSA9IHdfc3RyQ2hhbmdlOwoJCUNGWF9XaWRlU3RyaW5nIHdzdHJWYWx1ZSA9IFN0ckxUcmltKHdfc3RyVmFsdWUpOwoJCWlmICh3c3RyVmFsdWUuSXNFbXB0eSgpKQoJCQlyZXR1cm4gVFJVRTsKCQkKCQlDRlhfV2lkZVN0cmluZyBzd1RlbXAgPSB3c3RyVmFsdWU7CgkJc3dUZW1wLlJlcGxhY2UoKEZYX0xQQ1dTVFIpTCIsIiwgKEZYX0xQQ1dTVFIpTCIuIik7CgkJaWYgKCFJc051bWJlcihzd1RlbXApKSAvLyEoSXNOdW1iZXIod3N0ckNoYW5nZSkgJiYgCgkJewoJCQlwRXZlbnQtPlJjKCkgPSBGQUxTRTsKCQkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNBRk5VTUJFUl9LRVlTVFJPS0UpOwoJCQlBbGVydChwQ29udGV4dCwgc0Vycm9yKTsKCQkJcmV0dXJuIFRSVUU7CgkJfQoJCXJldHVybiBUUlVFOyAvLyBpdCBoYXBwZW5zIGFmdGVyIHRoZSBsYXN0IGtleXN0cm9rZSBhbmQgYmVmb3JlIHZhbGlkYXRpbmcsCgl9CgkKCXN0ZDo6d3N0cmluZyB3X3N0clZhbHVlMiAod19zdHJWYWx1ZSk7CglzdGQ6OndzdHJpbmcgd19zdHJDaGFuZ2UyKHdfc3RyQ2hhbmdlKTsKCQoJc3RkOjp3c3RyaW5nIHdfc3RyU2VsZWN0ZWQ7CglpZigtMSAhPSBwRXZlbnQtPlNlbFN0YXJ0KCkpCgkJd19zdHJTZWxlY3RlZCA9IHdfc3RyVmFsdWUyLnN1YnN0cihwRXZlbnQtPlNlbFN0YXJ0KCksKHBFdmVudC0+U2VsRW5kKCkgLSBwRXZlbnQtPlNlbFN0YXJ0KCkpKTsKCUZYX0JPT0wgYkhhc1NpZ24gPSAod19zdHJWYWx1ZTIuZmluZCgnLScpICE9IC0xKSAmJiAod19zdHJTZWxlY3RlZC5maW5kKCctJykgPT0gLTEpOwoJaWYgKGJIYXNTaWduKQoJewoJCS8vY2FuJ3QgaW5zZXJ0ICJjaGFuZ2UiIGluIGZyb250IHRvIHNpZ24gcG9zdGlvbi4KCQlpZiAocEV2ZW50LT5TZWxTdGFydCgpID09IDApCgkJewogICAgICAgICAgICBGWF9CT09MICZiUmMgPSBwRXZlbnQtPlJjKCk7CgkJCWJSYyA9IEZBTFNFOwoJCQlyZXR1cm4gVFJVRTsKCQl9Cgl9CgoJY2hhciBjU2VwID0gTCcuJzsKCglzd2l0Y2ggKGlTZXBTdHlsZSkKCXsKCWNhc2UgMDoKCWNhc2UgMToKCQljU2VwID0gTCcuJzsKCQlicmVhazsKCWNhc2UgMjoKCWNhc2UgMzoKCQljU2VwID0gTCcsJzsKCQlicmVhazsKCX0KCQoJRlhfQk9PTCBiSGFzU2VwID0gKHdfc3RyVmFsdWUyLmZpbmQoY1NlcCkgIT0gLTEpOwoJZm9yIChzdGQ6OndzdHJpbmc6Oml0ZXJhdG9yIGl0ID0gd19zdHJDaGFuZ2UyLmJlZ2luKCk7IGl0ICE9IHdfc3RyQ2hhbmdlMi5lbmQoKTsgaXQrKykKCXsKCQlpZiAoKml0ID09IGNTZXApCgkJewoJCQlpZiAoYkhhc1NlcCkKCQkJewoJCQkJRlhfQk9PTCAmYlJjID0gcEV2ZW50LT5SYygpOwoJCQkJYlJjID0gRkFMU0U7CgkJCQlyZXR1cm4gVFJVRTsKCQkJfQoJCQllbHNlCgkJCXsKCQkJCWJIYXNTZXAgPSBUUlVFOwoJCQkJY29udGludWU7CgkJCX0KCQl9CgkJaWYgKCppdCA9PSBMJy0nKQoJCXsKCQkJaWYgKGJIYXNTaWduKQoJCQl7CgkJCQlGWF9CT09MICZiUmMgPSBwRXZlbnQtPlJjKCk7CgkJCQliUmMgPSBGQUxTRTsKCQkJCXJldHVybiBUUlVFOwoJCQl9CgkJCWVsc2UgaWYgKGl0ICE9IHdfc3RyQ2hhbmdlMi5iZWdpbigpKSAvL3NpZ24ncyBwb3NpdGlvbiBpcyBub3QgY29ycmVjdAoJCQl7CgkJCQlGWF9CT09MICZiUmMgPSBwRXZlbnQtPlJjKCk7CgkJCQliUmMgPSBGQUxTRTsKCQkJCXJldHVybiBUUlVFOwoJCQl9CgkJCWVsc2UgaWYgKHBFdmVudC0+U2VsU3RhcnQoKSAhPSAwKQoJCQl7CgkJCQlGWF9CT09MICZiUmMgPSBwRXZlbnQtPlJjKCk7CgkJCQliUmMgPSBGQUxTRTsKCQkJCXJldHVybiBUUlVFOwoJCQl9CgkJCWJIYXNTaWduID0gVFJVRTsKCQkJY29udGludWU7CgkJfQoJCQoJCWlmICghSXNEaWdpdCgqaXQpKQoJCXsJCQkKCQkJRlhfQk9PTCAmYlJjID0gcEV2ZW50LT5SYygpOwoJCQliUmMgPSBGQUxTRTsKCQkJcmV0dXJuIFRSVUU7CgkJfQoJfQoJCgkKCXN0ZDo6d3N0cmluZyB3X3ByZWZpeCA9IHdfc3RyVmFsdWUyLnN1YnN0cigwLHBFdmVudC0+U2VsU3RhcnQoKSk7CglzdGQ6OndzdHJpbmcgd19wb3N0Zml4OwoJaWYgKHBFdmVudC0+U2VsRW5kKCk8KGludCl3X3N0clZhbHVlMi5sZW5ndGgoKSkKCQl3X3Bvc3RmaXggID0gd19zdHJWYWx1ZTIuc3Vic3RyKHBFdmVudC0+U2VsRW5kKCkpOwoJd19zdHJWYWx1ZTIgPSB3X3ByZWZpeCArIHdfc3RyQ2hhbmdlMiArIHdfcG9zdGZpeDsKCXdfc3RyVmFsdWUgPSB3X3N0clZhbHVlMi5jX3N0cigpOwoJdmFsID0gd19zdHJWYWx1ZTsKCXJldHVybiBUUlVFOwkJCgkKfQoKLy9mdW5jdGlvbiBBRlBlcmNlbnRfRm9ybWF0KG5EZWMsIHNlcFN0eWxlKQpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRlBlcmNlbnRfRm9ybWF0KE9CSl9NRVRIT0RfUEFSQU1TKQp7CiNpZiBfRlhfT1NfICE9IF9GWF9BTkRST0lEXwoJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7CglBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CglDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7CglBU1NFUlQocEV2ZW50ICE9IE5VTEwpOwoKICAgIGlmIChwYXJhbXMuc2l6ZSgpICE9IDIpCgl7CgkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CglpZighcEV2ZW50LT5tX3BWYWx1ZSkKCQlyZXR1cm4gRkFMU0U7CglDRlhfV2lkZVN0cmluZyYgVmFsdWUgPSBwRXZlbnQtPlZhbHVlKCk7CgkKLy8gICAgIEhXTkQgaE1haW5GcmFtZSA9IE5VTEw7Ci8vIAkKLy8gCUNQREZTREtfRm9ybUZpbGxBcHAgKnBBcHAgPSBwQ29udGV4dC0+R2V0UmVhZGVyQXBwKCk7Ci8vIAlBU1NFUlQocEFwcCk7Ci8vIAloTWFpbkZyYW1lID0gcEFwcC0+R2V0TWFpbkZyYW1lV25kKCk7CgkJCglDRlhfQnl0ZVN0cmluZyBzdHJWYWx1ZSA9IFN0clRyaW0oQ0ZYX0J5dGVTdHJpbmc6OkZyb21Vbmljb2RlKFZhbHVlKSk7CgkKCWlmIChzdHJWYWx1ZS5Jc0VtcHR5KCkpCgkJcmV0dXJuIFRSVUU7CgkKCWludCBpRGVjID0gcGFyYW1zWzBdOwoJaW50IGlTZXBTdHlsZSA9IHBhcmFtc1sxXTsKCQoJLy9BU1NFUlQoaURlYyA+IDApOwoJaWYgKGlEZWMgPCAwKQoJCWlEZWMgPSAtaURlYzsKCQoJaWYgKGlTZXBTdHlsZSA8IDAgfHwgaVNlcFN0eWxlID4gMykKCQlpU2VwU3R5bGUgPSAwOwoJCgkKCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwoJLy9mb3IgcHJvY2Vzc2luZyBkZWNpbWFsIHBsYWNlcwoJZG91YmxlIGRWYWx1ZSA9IGF0b2Yoc3RyVmFsdWUpOwoJZFZhbHVlICo9IDEwMDsKCWlmIChpRGVjID4gMCkKCQlkVmFsdWUgKz0gRE9VQkxFX0NPUlJFQ1Q7Ly/Qo9X9CgoJaW50IGlEZWMyOwoJRlhfQk9PTCBiTmFnYXRpdmUgPSBGQUxTRTsKCXN0clZhbHVlID0gZmN2dChkVmFsdWUsaURlYywmaURlYzIsJmJOYWdhdGl2ZSk7CiAgICBpZiAoc3RyVmFsdWUuSXNFbXB0eSgpKQoJewoJCWRWYWx1ZSA9IDA7CgkJc3RyVmFsdWUgPSBmY3Z0KGRWYWx1ZSxpRGVjLCZpRGVjMiwmYk5hZ2F0aXZlKTsKCX0KCglpZiAoaURlYzIgPCAwKQoJewoJCWZvciAoaW50IGlOdW0gPSAwOyBpTnVtIDwgYWJzKGlEZWMyKTsgaU51bSsrKQoJCXsKCQkJc3RyVmFsdWUgPSAiMCIgKyBzdHJWYWx1ZTsKCQl9CgkJaURlYzIgPSAwOwoJCQoJfQoJaW50IGlNYXggPSBzdHJWYWx1ZS5HZXRMZW5ndGgoKTsKCWlmIChpRGVjMiA+IGlNYXgpCgl7CgkJZm9yIChpbnQgaU51bSA9IDA7IGlOdW0gPD0gaURlYzIgLSBpTWF4OyBpTnVtKyspCgkJewoJCQlzdHJWYWx1ZSArPSAiMCI7CgkJfQoJCWlNYXggPSBpRGVjMisxOwkJCQoJfQoJLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwogICAgLy9mb3IgcHJvY2Vzc2luZyBzZXBlcmF0b3Igc3R5bGUKCWlmIChpRGVjMiA8IGlNYXgpCgl7CgkJaWYgKGlTZXBTdHlsZSA9PSAwIHx8IGlTZXBTdHlsZSA9PSAxKQoJCXsKCQkJc3RyVmFsdWUuSW5zZXJ0KGlEZWMyLCAnLicpOwoJCQlpTWF4Kys7CgkJfQoJCWVsc2UgaWYgKGlTZXBTdHlsZSA9PSAyIHx8IGlTZXBTdHlsZSA9PSAzKQoJCXsKCQkJc3RyVmFsdWUuSW5zZXJ0KGlEZWMyLCAnLCcpOwoJCQlpTWF4Kys7CgkJfQoJCQoJCWlmIChpRGVjMiA9PSAwKQoJCQlzdHJWYWx1ZS5JbnNlcnQoaURlYzIsICcwJyk7Cgl9CglpZiAoaVNlcFN0eWxlID09IDAgfHwgaVNlcFN0eWxlID09IDIpCgl7CgkJY2hhciBjU2VwZXJhdG9yOwoJCWlmIChpU2VwU3R5bGUgPT0gMCkKCQkJY1NlcGVyYXRvciA9ICcsJzsKCQllbHNlCgkJCWNTZXBlcmF0b3IgPSAnLic7CgkJCgkJaW50IGlEZWNQb3NpdGl2ZSxpRGVjTmFnYXRpdmU7CgkJaURlY1Bvc2l0aXZlID0gaURlYzI7CgkJaURlY05hZ2F0aXZlID0gaURlYzI7CgkJCQoJCWZvciAoaURlY1Bvc2l0aXZlID0gaURlYzIgLTM7IGlEZWNQb3NpdGl2ZSA+IDA7IGlEZWNQb3NpdGl2ZSAtPSAzKQoJCXsKCQkJc3RyVmFsdWUuSW5zZXJ0KGlEZWNQb3NpdGl2ZSxjU2VwZXJhdG9yKTsKCQkJaU1heCsrOwoJCX0KCX0KCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgkvL25hZ2F0aXZlIG1hcmsKCWlmKGJOYWdhdGl2ZSkKCQlzdHJWYWx1ZSA9ICItIiArIHN0clZhbHVlOwoJc3RyVmFsdWUgKz0gIiUiOwoJVmFsdWUgPSBDRlhfV2lkZVN0cmluZzo6RnJvbUxvY2FsKHN0clZhbHVlKTsKI2VuZGlmCglyZXR1cm4gVFJVRTsKfQovL0FGUGVyY2VudF9LZXlzdHJva2UobkRlYywgc2VwU3R5bGUpCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGUGVyY2VudF9LZXlzdHJva2UoT0JKX01FVEhPRF9QQVJBTVMpCnsKCXJldHVybiBBRk51bWJlcl9LZXlzdHJva2UoY2MscGFyYW1zLHZSZXQsc0Vycm9yKTsKfQoKLy9mdW5jdGlvbiBBRkRhdGVfRm9ybWF0RXgoY0Zvcm1hdCkKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZEYXRlX0Zvcm1hdEV4KE9CSl9NRVRIT0RfUEFSQU1TKQp7CglDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsKCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7CgoJaWYgKHBhcmFtcy5zaXplKCkgIT0gMSkKCXsKCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOwoJCXJldHVybiBGQUxTRTsKCX0JCglpZighcEV2ZW50LT5tX3BWYWx1ZSkKCQlyZXR1cm4gRkFMU0U7CglDRlhfV2lkZVN0cmluZyYgdmFsID0gcEV2ZW50LT5WYWx1ZSgpOwoJCglDRlhfV2lkZVN0cmluZyBzdHJWYWx1ZSA9IHZhbDsJCglpZiAoc3RyVmFsdWUuSXNFbXB0eSgpKSByZXR1cm4gVFJVRTsJCQoKCUNGWF9XaWRlU3RyaW5nIHNGb3JtYXQgPSBwYXJhbXNbMF0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsKCglGWF9CT09MIGJXcm9uZ0Zvcm1hdCA9IEZBTFNFOwoJZG91YmxlIGREYXRlID0gMC4wZjsKCglpZihzdHJWYWx1ZS5GaW5kKEwiR01UIikgIT0gLTEpCgl7CgkJLy9mb3IgR01UIGZvcm1hdCB0aW1lCgkJLy9zdWNoIGFzICJUdWUgQXVnIDExIDE0OjI0OjE2IEdNVCswODAwMjAwOSIKCQlkRGF0ZSA9IE1ha2VJbnRlckRhdGUoc3RyVmFsdWUpOwoJfQoJZWxzZQoJewoJCWREYXRlID0gTWFrZVJlZ3VsYXJEYXRlKHN0clZhbHVlLHNGb3JtYXQsYldyb25nRm9ybWF0KTsKCX0KCglpZiAoSlNfUG9ydElzTmFuKGREYXRlKSkKCXsKCQlDRlhfV2lkZVN0cmluZyBzd01zZzsKCQlzd01zZy5Gb3JtYXQoSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJTRURBVEUpLCAoRlhfTFBDV1NUUilzRm9ybWF0KTsKCQlBbGVydChwQ29udGV4dCwgc3dNc2cpOwoJCXJldHVybiBGQUxTRTsKCX0KCQoJdmFsID0gIE1ha2VGb3JtYXREYXRlKGREYXRlLHNGb3JtYXQpOwoKCXJldHVybiBUUlVFOwp9Cgpkb3VibGUgQ0pTX1B1YmxpY01ldGhvZHM6Ok1ha2VJbnRlckRhdGUoQ0ZYX1dpZGVTdHJpbmcgc3RyVmFsdWUpCnsKCWludCBuSG91cjsKCWludCBuTWluOwoJaW50IG5TZWM7CglpbnQgblllYXI7CglpbnQgbk1vbnRoOwoJaW50IG5EYXk7CgoJQ0ZYX1dpZGVTdHJpbmdBcnJheSB3c0FycmF5OwoJQ0ZYX1dpZGVTdHJpbmcgc01vbnRoID0gTCIiOwoJQ0ZYX1dpZGVTdHJpbmcgc1RlbXAgPSBMIiI7CglpbnQgblNpemUgPSBzdHJWYWx1ZS5HZXRMZW5ndGgoKTsKCglmb3IoaW50IGkgPSAwOyBpIDwgblNpemU7IGkrKykKCXsKCQlGWF9XQ0hBUiBjID0gc3RyVmFsdWUuR2V0QXQoaSk7CgkJaWYoYyA9PSBMJyAnIHx8IGMgPT0gTCc6JykKCQl7CQoJCQl3c0FycmF5LkFkZChzVGVtcCk7CgkJCXNUZW1wID0gTCIiOwoJCQljb250aW51ZTsKCQl9CgoJCXNUZW1wICs9IGM7Cgl9CgkKCXdzQXJyYXkuQWRkKHNUZW1wKTsKCWlmKHdzQXJyYXkuR2V0U2l6ZSgpICE9IDgpcmV0dXJuIDA7CgoJc1RlbXAgPSB3c0FycmF5WzFdOwoJaWYoc1RlbXAuQ29tcGFyZShMIkphbiIpID09IDApIG5Nb250aCA9IDE7CglpZihzVGVtcC5Db21wYXJlKEwiRmViIikgPT0gMCkgbk1vbnRoID0gMjsKCWlmKHNUZW1wLkNvbXBhcmUoTCJNYXIiKSA9PSAwKSBuTW9udGggPSAzOwoJaWYoc1RlbXAuQ29tcGFyZShMIkFwciIpID09IDApIG5Nb250aCA9IDQ7CglpZihzVGVtcC5Db21wYXJlKEwiTWF5IikgPT0gMCkgbk1vbnRoID0gNTsKCWlmKHNUZW1wLkNvbXBhcmUoTCJKdW4iKSA9PSAwKSBuTW9udGggPSA2OwoJaWYoc1RlbXAuQ29tcGFyZShMIkp1bCIpID09IDApIG5Nb250aCA9IDc7CglpZihzVGVtcC5Db21wYXJlKEwiQXVnIikgPT0gMCkgbk1vbnRoID0gODsKCWlmKHNUZW1wLkNvbXBhcmUoTCJTZXAiKSA9PSAwKSBuTW9udGggPSA5OwoJaWYoc1RlbXAuQ29tcGFyZShMIk9jdCIpID09IDApIG5Nb250aCA9IDEwOwoJaWYoc1RlbXAuQ29tcGFyZShMIk5vdiIpID09IDApIG5Nb250aCA9IDExOwoJaWYoc1RlbXAuQ29tcGFyZShMIkRlYyIpID09IDApIG5Nb250aCA9IDEyOwoKCW5EYXkgPSAoaW50KVBhcnNlU3RyaW5nVG9OdW1iZXIod3NBcnJheVsyXSk7CgluSG91ciA9IChpbnQpUGFyc2VTdHJpbmdUb051bWJlcih3c0FycmF5WzNdKTsKCW5NaW4gPSAoaW50KVBhcnNlU3RyaW5nVG9OdW1iZXIod3NBcnJheVs0XSk7CgluU2VjID0gKGludClQYXJzZVN0cmluZ1RvTnVtYmVyKHdzQXJyYXlbNV0pOwoJblllYXIgPSAoaW50KVBhcnNlU3RyaW5nVG9OdW1iZXIod3NBcnJheVs3XSk7CgoJZG91YmxlIGRSZXQgPSBKU19NYWtlRGF0ZShKU19NYWtlRGF5KG5ZZWFyLG5Nb250aCAtIDEsbkRheSksSlNfTWFrZVRpbWUobkhvdXIsIG5NaW4sIG5TZWMsIDApKTsKCglpZiAoSlNfUG9ydElzTmFuKGRSZXQpKQoJewoJCWRSZXQgPSBKU19EYXRlUGFyc2Uoc3RyVmFsdWUpOwoJfQoJCglyZXR1cm4gZFJldDsKfQoKLy9BRkRhdGVfS2V5c3Ryb2tlRXgoY0Zvcm1hdCkKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZEYXRlX0tleXN0cm9rZUV4KE9CSl9NRVRIT0RfUEFSQU1TKQp7CglDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsKCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7CgoJaWYgKHBhcmFtcy5zaXplKCkgIT0gMSkKCXsKCQlzRXJyb3IgPSBMIkFGRGF0ZV9LZXlzdHJva2VFeCdzIHBhcmFtZXRlcnMnIHNpemUgciBub3QgY29ycmVjdCI7CgkJcmV0dXJuIEZBTFNFOwoJfQkKCQoJaWYgKHBFdmVudC0+V2lsbENvbW1pdCgpKQoJewoJCWlmKCFwRXZlbnQtPm1fcFZhbHVlKQoJCQlyZXR1cm4gRkFMU0U7CgkJQ0ZYX1dpZGVTdHJpbmcgc3RyVmFsdWUgPSBwRXZlbnQtPlZhbHVlKCk7CgkJaWYgKHN0clZhbHVlLklzRW1wdHkoKSkgcmV0dXJuIFRSVUU7CgoJCUNGWF9XaWRlU3RyaW5nIHNGb3JtYXQgPSBwYXJhbXNbMF0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsKCgkJRlhfQk9PTCBiV3JvbmdGb3JtYXQgPSBGQUxTRTsKCQlkb3VibGUgZFJldCA9IE1ha2VSZWd1bGFyRGF0ZShzdHJWYWx1ZSxzRm9ybWF0LGJXcm9uZ0Zvcm1hdCk7CgkJaWYgKGJXcm9uZ0Zvcm1hdCB8fCBKU19Qb3J0SXNOYW4oZFJldCkpCgkJewoJCQlDRlhfV2lkZVN0cmluZyBzd01zZzsKCQkJc3dNc2cuRm9ybWF0KEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSU0VEQVRFKSwgKEZYX0xQQ1dTVFIpc0Zvcm1hdCk7CgkJCUFsZXJ0KHBDb250ZXh0LCBzd01zZyk7CgkJCXBFdmVudC0+UmMoKSA9IEZBTFNFOwoJCQlyZXR1cm4gVFJVRTsKCQl9Cgl9CglyZXR1cm4gVFJVRTsKfQoKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZEYXRlX0Zvcm1hdChPQkpfTUVUSE9EX1BBUkFNUykKewoJdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSA6OkdldElzb2xhdGUoY2MpOwoKCWlmIChwYXJhbXMuc2l6ZSgpICE9IDEpCgl7CgkJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsKCQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CgoJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCWludCBpSW5kZXggPSBwYXJhbXNbMF07CglGWF9MUENXU1RSIGNGb3JtYXRzW10gPSAgeyhGWF9MUENXU1RSKUwibS9kIiwgKEZYX0xQQ1dTVFIpTCJtL2QveXkiLCAoRlhfTFBDV1NUUilMIm1tL2RkL3l5IiwgKEZYX0xQQ1dTVFIpTCJtbS95eSIsIChGWF9MUENXU1RSKUwiZC1tbW0iLCAoRlhfTFBDV1NUUilMImQtbW1tLXl5IiwgKEZYX0xQQ1dTVFIpTCJkZC1tbW0teXkiLAoJCShGWF9MUENXU1RSKUwieXktbW0tZGQiLCAoRlhfTFBDV1NUUilMIm1tbS15eSIsIChGWF9MUENXU1RSKUwibW1tbS15eSIsIChGWF9MUENXU1RSKUwibW1tIGQsIHl5eXkiLCAoRlhfTFBDV1NUUilMIm1tbW0gZCwgeXl5eSIsCgkJKEZYX0xQQ1dTVFIpTCJtL2QveXkgaDpNTSB0dCIsIChGWF9MUENXU1RSKUwibS9kL3l5IEhIOk1NIiB9OwoKCUFTU0VSVChpSW5kZXggPCBzaXplb2YoY0Zvcm1hdHMpL3NpemVvZihGWF9MUENXU1RSKSk7CgoJaWYgKGlJbmRleCA8IDApCgkJaUluZGV4ID0gMDsKCWlmIChpSW5kZXggPj0gc2l6ZW9mKGNGb3JtYXRzKS9zaXplb2YoRlhfTFBDV1NUUikpCgkJaUluZGV4ID0gMDsKCUNKU19QYXJhbWV0ZXJzIG5ld1BhcmFtczsKCUNKU19WYWx1ZSB2YWwoaXNvbGF0ZSxjRm9ybWF0c1tpSW5kZXhdKTsKCW5ld1BhcmFtcy5wdXNoX2JhY2sodmFsKTsKCXJldHVybiBBRkRhdGVfRm9ybWF0RXgoY2MsbmV3UGFyYW1zLHZSZXQsc0Vycm9yKTsKfQoKLy9BRkRhdGVfS2V5c3Ryb2tlRXgoY0Zvcm1hdCkKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZEYXRlX0tleXN0cm9rZShPQkpfTUVUSE9EX1BBUkFNUykKewoJdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSA6OkdldElzb2xhdGUoY2MpOwoKCWlmIChwYXJhbXMuc2l6ZSgpICE9IDEpCgl7CgkJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsKCQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CgoJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCWludCBpSW5kZXggPSBwYXJhbXNbMF07CglGWF9MUENXU1RSIGNGb3JtYXRzW10gPSAgeyhGWF9MUENXU1RSKUwibS9kIiwgKEZYX0xQQ1dTVFIpTCJtL2QveXkiLCAoRlhfTFBDV1NUUilMIm1tL2RkL3l5IiwgKEZYX0xQQ1dTVFIpTCJtbS95eSIsIChGWF9MUENXU1RSKUwiZC1tbW0iLCAoRlhfTFBDV1NUUilMImQtbW1tLXl5IiwgKEZYX0xQQ1dTVFIpTCJkZC1tbW0teXkiLAoJCShGWF9MUENXU1RSKUwieXktbW0tZGQiLCAoRlhfTFBDV1NUUilMIm1tbS15eSIsIChGWF9MUENXU1RSKUwibW1tbS15eSIsIChGWF9MUENXU1RSKUwibW1tIGQsIHl5eXkiLCAoRlhfTFBDV1NUUilMIm1tbW0gZCwgeXl5eSIsCgkJKEZYX0xQQ1dTVFIpTCJtL2QveXkgaDpNTSB0dCIsIChGWF9MUENXU1RSKUwibS9kL3l5IEhIOk1NIiB9OwoKCUFTU0VSVChpSW5kZXg8c2l6ZW9mKGNGb3JtYXRzKS9zaXplb2YoRlhfTFBDV1NUUikpOwoKCWlmIChpSW5kZXggPCAwKQoJCWlJbmRleCA9IDA7CglpZiAoaUluZGV4ID49IHNpemVvZihjRm9ybWF0cykvc2l6ZW9mKEZYX0xQQ1dTVFIpKQoJCWlJbmRleCA9IDA7CglDSlNfUGFyYW1ldGVycyBuZXdQYXJhbXM7CglDSlNfVmFsdWUgdmFsKGlzb2xhdGUsY0Zvcm1hdHNbaUluZGV4XSk7CgluZXdQYXJhbXMucHVzaF9iYWNrKHZhbCk7CglyZXR1cm4gQUZEYXRlX0tleXN0cm9rZUV4KGNjLG5ld1BhcmFtcyx2UmV0LHNFcnJvcik7Cn0KCi8vZnVuY3Rpb24gQUZUaW1lX0Zvcm1hdChwdGYpCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGVGltZV9Gb3JtYXQoT0JKX01FVEhPRF9QQVJBTVMpCnsKCXY4OjpJc29sYXRlKiBpc29sYXRlID0gOjpHZXRJc29sYXRlKGNjKTsKCglpZiAocGFyYW1zLnNpemUoKSAhPSAxKQoJewoJCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CgkJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOwoJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCWludCBpSW5kZXggPSBwYXJhbXNbMF07CglGWF9MUENXU1RSIGNGb3JtYXRzW10gPSB7KEZYX0xQQ1dTVFIpTCJISDpNTSIsIChGWF9MUENXU1RSKUwiaDpNTSB0dCIsIChGWF9MUENXU1RSKUwiSEg6TU06c3MiLCAoRlhfTFBDV1NUUilMImg6TU06c3MgdHQifTsKCglBU1NFUlQoaUluZGV4PHNpemVvZihjRm9ybWF0cykvc2l6ZW9mKEZYX0xQQ1dTVFIpKTsKCglpZiAoaUluZGV4IDwgMCkKCQlpSW5kZXggPSAwOwoJaWYgKGlJbmRleCA+PSBzaXplb2YoY0Zvcm1hdHMpL3NpemVvZihGWF9MUENXU1RSKSkKCQlpSW5kZXggPSAwOwoJQ0pTX1BhcmFtZXRlcnMgbmV3UGFyYW1zOwoJQ0pTX1ZhbHVlIHZhbChpc29sYXRlLGNGb3JtYXRzW2lJbmRleF0pOwoJbmV3UGFyYW1zLnB1c2hfYmFjayh2YWwpOwoJcmV0dXJuIEFGRGF0ZV9Gb3JtYXRFeChjYyxuZXdQYXJhbXMsdlJldCxzRXJyb3IpOwp9CgpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRlRpbWVfS2V5c3Ryb2tlKE9CSl9NRVRIT0RfUEFSQU1TKQp7Cgl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IDo6R2V0SXNvbGF0ZShjYyk7CglpZiAocGFyYW1zLnNpemUoKSAhPSAxKQoJewoJCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CgkJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOwoJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCWludCBpSW5kZXggPSBwYXJhbXNbMF07CglGWF9MUENXU1RSIGNGb3JtYXRzW10gPSB7KEZYX0xQQ1dTVFIpTCJISDpNTSIsIChGWF9MUENXU1RSKUwiaDpNTSB0dCIsIChGWF9MUENXU1RSKUwiSEg6TU06c3MiLCAoRlhfTFBDV1NUUilMImg6TU06c3MgdHQifTsKCglBU1NFUlQoaUluZGV4PHNpemVvZihjRm9ybWF0cykvc2l6ZW9mKEZYX0xQQ1dTVFIpKTsKCglpZiAoaUluZGV4IDwgMCkKCQlpSW5kZXggPSAwOwoJaWYgKGlJbmRleCA+PSBzaXplb2YoY0Zvcm1hdHMpL3NpemVvZihGWF9MUENXU1RSKSkKCQlpSW5kZXggPSAwOwoJQ0pTX1BhcmFtZXRlcnMgbmV3UGFyYW1zOwoJQ0pTX1ZhbHVlIHZhbChpc29sYXRlLGNGb3JtYXRzW2lJbmRleF0pOwoJbmV3UGFyYW1zLnB1c2hfYmFjayh2YWwpOwoJcmV0dXJuIEFGRGF0ZV9LZXlzdHJva2VFeChjYyxuZXdQYXJhbXMsdlJldCxzRXJyb3IpOwp9CgpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRlRpbWVfRm9ybWF0RXgoT0JKX01FVEhPRF9QQVJBTVMpCnsKCXJldHVybiBBRkRhdGVfRm9ybWF0RXgoY2MscGFyYW1zLHZSZXQsc0Vycm9yKTsKfQoKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZUaW1lX0tleXN0cm9rZUV4KE9CSl9NRVRIT0RfUEFSQU1TKQp7CglyZXR1cm4gQUZEYXRlX0tleXN0cm9rZUV4KGNjLHBhcmFtcyx2UmV0LHNFcnJvcik7Cn0KCi8vZnVuY3Rpb24gQUZTcGVjaWFsX0Zvcm1hdChwc2YpCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGU3BlY2lhbF9Gb3JtYXQoT0JKX01FVEhPRF9QQVJBTVMpCnsKCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOwoJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOwoKCWlmIChwYXJhbXMuc2l6ZSgpICE9IDEpCgl7CgkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJc3RkOjpzdHJpbmcgY0Zvcm1hdDsKCWludCBpSW5kZXggPSBwYXJhbXNbMF07CgoJQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOwoJQVNTRVJUKHBFdmVudCAhPSBOVUxMKTsKCglpZighcEV2ZW50LT5tX3BWYWx1ZSkKCQlyZXR1cm4gRkFMU0U7CglDRlhfV2lkZVN0cmluZyYgVmFsdWUgPSBwRXZlbnQtPlZhbHVlKCk7CQoJc3RkOjpzdHJpbmcgc3RyU3JjID0gKEZYX0xQQ1NUUilDRlhfQnl0ZVN0cmluZzo6RnJvbVVuaWNvZGUoVmFsdWUpOwoJCglzd2l0Y2ggKGlJbmRleCkgCgl7CgljYXNlIDA6ICAgICAgICAgICAgICAgICAgICAgICAgIAoJCWNGb3JtYXQgPSAiOTk5OTkiOwoJCWJyZWFrOwoJY2FzZSAxOiAgICAgICAgICAgICAgICAgICAgICAgICAKCQljRm9ybWF0ID0gIjk5OTk5LTk5OTkiOwoJCWJyZWFrOwoJY2FzZSAyOiAgICAgICAgICAgICAgICAgICAgICAgICAKCQl7CgkJCXN0ZDo6c3RyaW5nIE51bWJlclN0cjsKCQkJdXRpbDo6cHJpbnR4KCI5OTk5OTk5OTk5Iiwgc3RyU3JjLE51bWJlclN0cik7IAoJCQlpZiAoTnVtYmVyU3RyLmxlbmd0aCgpID49IDEwICkKCQkJCWNGb3JtYXQgPSAiKDk5OSkgOTk5LTk5OTkiOwoJCQllbHNlIAoJCQkJY0Zvcm1hdCA9ICI5OTktOTk5OSI7CgkJCWJyZWFrOwoJCX0KCWNhc2UgMzoKCQljRm9ybWF0ID0gIjk5OS05OS05OTk5IjsKCQlicmVhazsKCX0KCQoJc3RkOjpzdHJpbmcgc3RyRGVzOwoJdXRpbDo6cHJpbnR4KGNGb3JtYXQsc3RyU3JjLHN0ckRlcyk7CglWYWx1ZSA9IENGWF9XaWRlU3RyaW5nOjpGcm9tTG9jYWwoc3RyRGVzLmNfc3RyKCkpOwoJcmV0dXJuIFRSVUU7Cn0KCgovL2Z1bmN0aW9uIEFGU3BlY2lhbF9LZXlzdHJva2VFeChtYXNrKQpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRlNwZWNpYWxfS2V5c3Ryb2tlRXgoT0JKX01FVEhPRF9QQVJBTVMpCnsKCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOwoJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOwoJQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOwoKCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7CgoJaWYgKHBhcmFtcy5zaXplKCkgPCAxKQoJewoJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCWlmKCFwRXZlbnQtPm1fcFZhbHVlKQoJCXJldHVybiBGQUxTRTsKCUNGWF9XaWRlU3RyaW5nJiB2YWxFdmVudCA9IHBFdmVudC0+VmFsdWUoKTsKCglDRlhfV2lkZVN0cmluZyB3c3RyTWFzayA9IHBhcmFtc1swXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOwoJaWYgKHdzdHJNYXNrLklzRW1wdHkoKSkgcmV0dXJuIFRSVUU7CgkKCXN0ZDo6d3N0cmluZyB3c3RyVmFsdWUodmFsRXZlbnQpOwoJCglpZiAocEV2ZW50LT5XaWxsQ29tbWl0KCkpCgl7CgkJaWYgKHdzdHJWYWx1ZS5lbXB0eSgpKQoJCQlyZXR1cm4gVFJVRTsKCQlpbnQgaUluZGV4TWFzayA9IDA7CgkJZm9yIChzdGQ6OndzdHJpbmc6Oml0ZXJhdG9yIGl0ID0gd3N0clZhbHVlLmJlZ2luKCk7IGl0ICE9IHdzdHJWYWx1ZS5lbmQoKTsgaXQrKykKCQl7CgkJCXdjaGFyX3Qgd19WYWx1ZSA9ICppdDsKICAgICAgICAgICAgaWYgKCFtYXNrU2F0aXNmaWVkKHdfVmFsdWUsd3N0ck1hc2tbaUluZGV4TWFza10pKQoJCQkJYnJlYWs7CgkJCWlJbmRleE1hc2srKzsKCQl9CgoJCWlmIChpSW5kZXhNYXNrICE9IHdzdHJNYXNrLkdldExlbmd0aCgpIHx8IChpSW5kZXhNYXNrICE9IHdzdHJWYWx1ZS5zaXplKCkgJiYgd3N0ck1hc2suR2V0TGVuZ3RoKCkgIT0gMCkpCgkJewoJCQlBbGVydChwQ29udGV4dCwgSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNBRk5VTUJFUl9LRVlTVFJPS0UpKTsKCQkJcEV2ZW50LT5SYygpID0gRkFMU0U7CgkJfQoJCXJldHVybiBUUlVFOwoJfQoKCQoJQ0ZYX1dpZGVTdHJpbmcgJndpZGVDaGFuZ2UgPSBwRXZlbnQtPkNoYW5nZSgpOwoJc3RkOjp3c3RyaW5nIHdDaGFuZ2Uod2lkZUNoYW5nZSk7CgkKCWlmICh3Q2hhbmdlLmVtcHR5KCkpCgkJcmV0dXJuIFRSVUU7CiAgICBpbnQgaUluZGV4TWFzayA9IHBFdmVudC0+U2VsU3RhcnQoKTsKCS8vaUluZGV4TWFzaysrOwoJCgkKCWlmICh3c3RyVmFsdWUubGVuZ3RoKCkgLSAocEV2ZW50LT5TZWxFbmQoKS1wRXZlbnQtPlNlbFN0YXJ0KCkpICsgd0NoYW5nZS5sZW5ndGgoKSA+IChGWF9EV09SRCl3c3RyTWFzay5HZXRMZW5ndGgoKSkKCXsKCQlBbGVydChwQ29udGV4dCwgSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTV9UT09MT05HKSk7CgkJcEV2ZW50LT5SYygpID0gRkFMU0U7CgkJcmV0dXJuIFRSVUU7Cgl9CgkKCQoJaWYgKGlJbmRleE1hc2sgPj0gd3N0ck1hc2suR2V0TGVuZ3RoKCkgJiYgKCF3Q2hhbmdlLmVtcHR5KCkpKQoJewoJCUFsZXJ0KHBDb250ZXh0LCBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNX1RPT0xPTkcpKTsKCQlwRXZlbnQtPlJjKCkgPSBGQUxTRTsKCQlyZXR1cm4gVFJVRTsKCX0KCQoJZm9yIChzdGQ6OndzdHJpbmc6Oml0ZXJhdG9yIGl0ID0gd0NoYW5nZS5iZWdpbigpOyBpdCAhPSB3Q2hhbmdlLmVuZCgpOyBpdCsrKQoJewoJCWlmIChpSW5kZXhNYXNrID49IHdzdHJNYXNrLkdldExlbmd0aCgpKQoJCXsKCQkJQWxlcnQocENvbnRleHQsIEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1fVE9PTE9ORykpOwoJCQlwRXZlbnQtPlJjKCkgPSBGQUxTRTsKCQkJcmV0dXJuIFRSVUU7CgkJfQoJCXdjaGFyX3Qgd19NYXNrID0gd3N0ck1hc2tbaUluZGV4TWFza107CgkJaWYgKCFpc1Jlc2VydmVkTWFza0NoYXIod19NYXNrKSkKCQl7CgkJCS8vd0NoYW5nZS5pbnNlcnQoaXQsd19NYXNrKTsJCQkJCgkJCSppdCA9IHdfTWFzazsKCQl9CgkJd2NoYXJfdCB3X0NoYW5nZSA9ICppdDsKCQkKICAgICAgICBpZiAoIW1hc2tTYXRpc2ZpZWQod19DaGFuZ2Usd19NYXNrKSkKCQl7CgkJCXBFdmVudC0+UmMoKSA9IEZBTFNFOwoJCQlyZXR1cm4gVFJVRTsKCQl9CgkJaUluZGV4TWFzaysrOwoJfQoJCgl3aWRlQ2hhbmdlID0gd0NoYW5nZS5jX3N0cigpOwkKCQoJcmV0dXJuIFRSVUU7Cn0KCgovL2Z1bmN0aW9uIEFGU3BlY2lhbF9LZXlzdHJva2UocHNmKQpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRlNwZWNpYWxfS2V5c3Ryb2tlKE9CSl9NRVRIT0RfUEFSQU1TKQp7Cgl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IDo6R2V0SXNvbGF0ZShjYyk7CgoJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7CglBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CglDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7CglBU1NFUlQocEV2ZW50ICE9IE5VTEwpOwoKCWlmIChwYXJhbXMuc2l6ZSgpICE9IDEpCgl7CgkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJc3RkOjpzdHJpbmcgY0Zvcm1hdDsKCWludCBpSW5kZXggPSAoaW50KXBhcmFtc1swXTsJCgoJaWYoIXBFdmVudC0+bV9wVmFsdWUpCgkJcmV0dXJuIEZBTFNFOwoJLy9DSlNfVmFsdWUgdmFsID0gcEV2ZW50LT5WYWx1ZSgpOwoJQ0ZYX1dpZGVTdHJpbmcmIHZhbCA9IHBFdmVudC0+VmFsdWUoKTsKCXN0ZDo6c3RyaW5nIHN0clNyYyA9IChGWF9MUENTVFIpQ0ZYX0J5dGVTdHJpbmc6OkZyb21Vbmljb2RlKHZhbCk7CglzdGQ6OndzdHJpbmcgd3N0ckNoYW5nZShwRXZlbnQtPkNoYW5nZSgpKTsKCQoJc3dpdGNoIChpSW5kZXgpIAoJewoJY2FzZSAwOiAgICAgICAgICAgICAgICAgICAgICAgICAKCQljRm9ybWF0ID0gIjk5OTk5IjsKCQlicmVhazsKCWNhc2UgMTogICAgICAgICAgICAgICAgICAgICAgICAgCgkJLy9jRm9ybWF0ID0gIjk5OTk5LTk5OTkiOwoJCWNGb3JtYXQgPSAiOTk5OTk5OTk5IjsKCQlicmVhazsKCWNhc2UgMjogICAgICAgICAgICAgICAgICAgICAgICAgCgkJewoJCQlzdGQ6OnN0cmluZyBOdW1iZXJTdHI7CgkJCXV0aWw6OnByaW50eCgiOTk5OTk5OTk5OSIsIHN0clNyYyxOdW1iZXJTdHIpOyAKCQkJaWYgKHN0clNyYy5sZW5ndGgoKSArIHdzdHJDaGFuZ2UubGVuZ3RoKCkgPiA3ICkKCQkJCS8vY0Zvcm1hdCA9ICIoOTk5KSA5OTktOTk5OSI7CgkJCQljRm9ybWF0ID0gIjk5OTk5OTk5OTkiOwoJCQllbHNlIAoJCQkJLy9jRm9ybWF0ID0gIjk5OS05OTk5IjsKCQkJCWNGb3JtYXQgPSAiOTk5OTk5OSI7CgkJCWJyZWFrOwoJCX0KCWNhc2UgMzoKCQkvL2NGb3JtYXQgPSAiOTk5LTk5LTk5OTkiOwoJCWNGb3JtYXQgPSAiOTk5OTk5OTk5IjsKCQlicmVhazsKCX0KICAgIAoJQ0pTX1BhcmFtZXRlcnMgcGFyYW1zMjsKCUNKU19WYWx1ZSB2TWFzayhpc29sYXRlLCBjRm9ybWF0LmNfc3RyKCkpOwoJcGFyYW1zMi5wdXNoX2JhY2sodk1hc2spOwoJCiAgICByZXR1cm4gQUZTcGVjaWFsX0tleXN0cm9rZUV4KGNjLHBhcmFtczIsdlJldCxzRXJyb3IpOwp9CgpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRk1lcmdlQ2hhbmdlKE9CSl9NRVRIT0RfUEFSQU1TKQp7CglDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudEhhbmRsZXIgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7CglBU1NFUlQocEV2ZW50SGFuZGxlciAhPSBOVUxMKTsKCglpZiAocGFyYW1zLnNpemUoKSAhPSAxKQoJewoJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCUNGWF9XaWRlU3RyaW5nIHN3VmFsdWU7CglpZiAocEV2ZW50SGFuZGxlci0+bV9wVmFsdWUgIT0gTlVMTCkKCQlzd1ZhbHVlID0gcEV2ZW50SGFuZGxlci0+VmFsdWUoKTsKCglpZiAocEV2ZW50SGFuZGxlci0+V2lsbENvbW1pdCgpKQoJewoJCXZSZXQgPSBzd1ZhbHVlOwoJCXJldHVybiBUUlVFOwoJfQoKCUNGWF9XaWRlU3RyaW5nIHByZWZpeCxwb3N0Zml4OwoKCWlmIChwRXZlbnRIYW5kbGVyLT5TZWxTdGFydCgpID49IDApCgkJcHJlZml4ID0gc3dWYWx1ZS5NaWQoMCxwRXZlbnRIYW5kbGVyLT5TZWxTdGFydCgpKTsKCWVsc2UKCQlwcmVmaXggPSBMIiI7CgoKCWlmIChwRXZlbnRIYW5kbGVyLT5TZWxFbmQoKSA+PSAwICYmIHBFdmVudEhhbmRsZXItPlNlbEVuZCgpIDw9IHN3VmFsdWUuR2V0TGVuZ3RoKCkpCgkJcG9zdGZpeCA9IHN3VmFsdWUuTWlkKHBFdmVudEhhbmRsZXItPlNlbEVuZCgpLCBzd1ZhbHVlLkdldExlbmd0aCgpIC0gcEV2ZW50SGFuZGxlci0+U2VsRW5kKCkpOwoJZWxzZSBwb3N0Zml4ID0gTCIiOwoKCXZSZXQgPSBwcmVmaXggKyBwRXZlbnRIYW5kbGVyLT5DaGFuZ2UoKSArIHBvc3RmaXg7CgoJcmV0dXJuIFRSVUU7Cn0KCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGUGFyc2VEYXRlRXgoT0JKX01FVEhPRF9QQVJBTVMpCnsKCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOwoJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOwoKCWlmIChwYXJhbXMuc2l6ZSgpICE9IDIpCgl7CgkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJQ0ZYX1dpZGVTdHJpbmcgc1ZhbHVlID0gcGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CglDRlhfV2lkZVN0cmluZyBzRm9ybWF0ID0gcGFyYW1zWzFdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CgoJRlhfQk9PTCBiV3JvbmdGb3JtYXQgPSBGQUxTRTsKCWRvdWJsZSBkRGF0ZSA9IE1ha2VSZWd1bGFyRGF0ZShzVmFsdWUsc0Zvcm1hdCxiV3JvbmdGb3JtYXQpOwoKCWlmIChKU19Qb3J0SXNOYW4oZERhdGUpKQoJewoJCUNGWF9XaWRlU3RyaW5nIHN3TXNnOwoJCXN3TXNnLkZvcm1hdChKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUlNFREFURSksIChGWF9MUENXU1RSKXNGb3JtYXQpOwoJCUFsZXJ0KChDSlNfQ29udGV4dCAqKWNjLCBzd01zZyk7CgkJcmV0dXJuIEZBTFNFOwoJfQoJCgl2UmV0ID0gZERhdGU7CgoJcmV0dXJuIFRSVUU7Cn0KCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGU2ltcGxlKE9CSl9NRVRIT0RfUEFSQU1TKQp7CglpZiAocGFyYW1zLnNpemUoKSAhPSAzKQoJewoJCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOwoJCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKCgkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJdlJldCA9IChkb3VibGUpQUZfU2ltcGxlKHBhcmFtc1swXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpLCAoZG91YmxlKXBhcmFtc1sxXSwgKGRvdWJsZSlwYXJhbXNbMl0pOwoJcmV0dXJuIFRSVUU7Cn0KCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGTWFrZU51bWJlcihPQkpfTUVUSE9EX1BBUkFNUykKewoJaWYgKHBhcmFtcy5zaXplKCkgIT0gMSkKCXsKCQlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKCQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CgoJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CgkJcmV0dXJuIEZBTFNFOwoJfQogICAgdlJldCA9IFBhcnNlU3RyaW5nVG9OdW1iZXIocGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCkpOwoJcmV0dXJuIFRSVUU7Cn0KCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGU2ltcGxlX0NhbGN1bGF0ZShPQkpfTUVUSE9EX1BBUkFNUykKewoJdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSA6OkdldElzb2xhdGUoY2MpOwoKCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOwoJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOwoKCWlmIChwYXJhbXMuc2l6ZSgpICE9IDIpCgl7CgkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJQ0pTX1ZhbHVlIHBhcmFtczEgPSBwYXJhbXNbMV07CgoJaWYgKCFwYXJhbXMxLklzQXJyYXlPYmplY3QoKSAmJiBwYXJhbXMxLkdldFR5cGUoKSAhPSBWVF9zdHJpbmcpCgl7CgkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CgkKCUNQREZTREtfRG9jdW1lbnQqIHBSZWFkZXJEb2MgPSBwQ29udGV4dC0+R2V0UmVhZGVyRG9jdW1lbnQoKTsKICAgIEFTU0VSVChwUmVhZGVyRG9jICE9IE5VTEwpOwoKCUNQREZTREtfSW50ZXJGb3JtKiBwUmVhZGVySW50ZXJGb3JtID0gcFJlYWRlckRvYy0+R2V0SW50ZXJGb3JtKCk7CglBU1NFUlQocFJlYWRlckludGVyRm9ybSAhPSBOVUxMKTsKCglDUERGX0ludGVyRm9ybSogcEludGVyRm9ybSA9IHBSZWFkZXJJbnRlckZvcm0tPkdldEludGVyRm9ybSgpOwoJQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7CgoJZG91YmxlIGRWYWx1ZTsKCUNGWF9XaWRlU3RyaW5nIHNGdW5jdGlvbiA9IHBhcmFtc1swXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOwoJaWYgKHdjc2NtcChzRnVuY3Rpb24sIEwiUFJEIikgPT0gMCkKICAgIAlkVmFsdWUgPSAxLjA7CgllbHNlCgkJZFZhbHVlID0gMC4wOwoKCUNKU19BcnJheSBGaWVsZE5hbWVBcnJheSA9IEFGX01ha2VBcnJheUZyb21MaXN0KGlzb2xhdGUscGFyYW1zMSk7CgoJaW50IG5GaWVsZHNDb3VudCA9IDA7CgoJZm9yIChpbnQgaT0wLGlzej1GaWVsZE5hbWVBcnJheS5HZXRMZW5ndGgoKTsgaTxpc3o7IGkrKykKCXsKCQlDSlNfVmFsdWUganNWYWx1ZShpc29sYXRlKTsKCQlGaWVsZE5hbWVBcnJheS5HZXRFbGVtZW50KGksanNWYWx1ZSk7CiAgICAgICAgQ0ZYX1dpZGVTdHJpbmcgd3NGaWVsZE5hbWUgPSBqc1ZhbHVlLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CgogICAgICAgIGZvciAoaW50IGo9MCxqc3o9cEludGVyRm9ybS0+Q291bnRGaWVsZHMod3NGaWVsZE5hbWUpOyBqPGpzejsgaisrKQoJCXsKCQkJaWYgKENQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gcEludGVyRm9ybS0+R2V0RmllbGQoaiwgd3NGaWVsZE5hbWUpKQoJCQl7CgkJCQlkb3VibGUgZFRlbXAgPSAwLjA7CgoJCQkJc3dpdGNoIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSkKCQkJCXsKCQkJCWNhc2UgRklFTERUWVBFX1RFWFRGSUVMRDoKCQkJCWNhc2UgRklFTERUWVBFX0NPTUJPQk9YOgoJCQkJCXsKCQkJCQkJZFRlbXAgPSBQYXJzZVN0cmluZ1RvTnVtYmVyKHBGb3JtRmllbGQtPkdldFZhbHVlKCkpOwoJCQkJCQlicmVhazsKCQkJCQl9CgkJCQljYXNlIEZJRUxEVFlQRV9QVVNIQlVUVE9OOgoJCQkJCXsKCQkJCQkJZFRlbXAgPSAwLjA7CgkJCQkJCWJyZWFrOwoJCQkJCX0KCQkJCWNhc2UgRklFTERUWVBFX0NIRUNLQk9YOgoJCQkJY2FzZSBGSUVMRFRZUEVfUkFESU9CVVRUT046CgkJCQkJewoJCQkJCQlkVGVtcCA9IDAuMDsKCQkJCQkJZm9yIChpbnQgYz0wLGNzej1wRm9ybUZpZWxkLT5Db3VudENvbnRyb2xzKCk7IGM8Y3N6OyBjKyspCgkJCQkJCXsKCQkJCQkJCWlmIChDUERGX0Zvcm1Db250cm9sKiBwRm9ybUN0cmwgPSBwRm9ybUZpZWxkLT5HZXRDb250cm9sKGMpKQoJCQkJCQkJewoJCQkJCQkJCWlmIChwRm9ybUN0cmwtPklzQ2hlY2tlZCgpKQoJCQkJCQkJCXsKCQkJCQkJCQkJZFRlbXAgKz0gUGFyc2VTdHJpbmdUb051bWJlcihwRm9ybUN0cmwtPkdldEV4cG9ydFZhbHVlKCkpOwoJCQkJCQkJCQlicmVhazsKCQkJCQkJCQl9CgkJCQkJCQkJZWxzZQoJCQkJCQkJCQljb250aW51ZTsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCQlicmVhazsKCQkJCQl9CgkJCQljYXNlIEZJRUxEVFlQRV9MSVNUQk9YOgoJCQkJCXsKCQkJCQkJZFRlbXAgPSAwLjA7CgkJCQkJCWlmIChwRm9ybUZpZWxkLT5Db3VudFNlbGVjdGVkSXRlbXMoKSA+IDEpCgkJCQkJCQlicmVhazsKCQkJCQkJZWxzZQoJCQkJCQl7CgkJCQkJCQlkVGVtcCA9IFBhcnNlU3RyaW5nVG9OdW1iZXIocEZvcm1GaWVsZC0+R2V0VmFsdWUoKSk7CgkJCQkJCQlicmVhazsKCQkJCQkJfQoJCQkJCX0KCQkJCWRlZmF1bHQ6CgkJCQkJYnJlYWs7CgkJCQl9CgoJCQkJaWYgKGkgPT0gMCAmJiBqID09IDAgJiYgKHdjc2NtcChzRnVuY3Rpb24sTCJNSU4iKSA9PSAwIHx8IHdjc2NtcChzRnVuY3Rpb24sIEwiTUFYIikgPT0gMCkpCgkJCQkJZFZhbHVlID0gZFRlbXA7CgoJCQkJZFZhbHVlID0gQUZfU2ltcGxlKHNGdW5jdGlvbiwgZFZhbHVlLCBkVGVtcCk7CgoJCQkJbkZpZWxkc0NvdW50Kys7CgkJCX0KCQl9Cgl9CgoJaWYgKHdjc2NtcChzRnVuY3Rpb24sIEwiQVZHIikgPT0gMCAmJiBuRmllbGRzQ291bnQgPiAwKQoJCWRWYWx1ZSAvPSBuRmllbGRzQ291bnQ7CgoJZFZhbHVlID0gKGRvdWJsZSlmbG9vcihkVmFsdWUgKiBGWFNZU19wb3coKGRvdWJsZSkxMCwoZG91YmxlKTYpICsgMC40OSkgLyBGWFNZU19wb3coKGRvdWJsZSkxMCwoZG91YmxlKTYpOwoJQ0pTX1ZhbHVlIGpzVmFsdWUoaXNvbGF0ZSxkVmFsdWUpOwoJaWYoKENKU19FdmVudEhhbmRsZXIqKXBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKS0+bV9wVmFsdWUpCgkJKChDSlNfRXZlbnRIYW5kbGVyKilwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCkpLT5WYWx1ZSgpID0ganNWYWx1ZTsKCglyZXR1cm4gVFJVRTsKfQoKLyogVGhpcyBmdW5jdGlvbiB2YWxpZGF0ZXMgdGhlIGN1cnJlbnQgZXZlbnQgdG8gZW5zdXJlIHRoYXQgaXRzIHZhbHVlIGlzIAoqKiB3aXRoaW4gdGhlIHNwZWNpZmllZCByYW5nZS4gKi8KCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGUmFuZ2VfVmFsaWRhdGUoT0JKX01FVEhPRF9QQVJBTVMpCnsKCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOwoJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOwoJQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOwoJQVNTRVJUKHBFdmVudCAhPSBOVUxMKTsKCglpZiAocGFyYW1zLnNpemUoKSAhPSA0KSAKCXsKCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOwoJCXJldHVybiBGQUxTRTsKCX0KCglpZighcEV2ZW50LT5tX3BWYWx1ZSkKCQlyZXR1cm4gRkFMU0U7CglpZiAocEV2ZW50LT5WYWx1ZSgpLklzRW1wdHkoKSApCgkJcmV0dXJuIFRSVUU7Cglkb3VibGUgZEVlbnRWYWx1ZSA9IGF0b2YoQ0ZYX0J5dGVTdHJpbmc6OkZyb21Vbmljb2RlKHBFdmVudC0+VmFsdWUoKSkpOwoJRlhfQk9PTCBiR3JlYXRlclRoYW4sIGJMZXNzVGhhbjsKCWRvdWJsZSAgZEdyZWF0ZXJUaGFuLCBkTGVzc1RoYW47CiAgICBiR3JlYXRlclRoYW4gPSAoRlhfQk9PTClwYXJhbXNbMF07CglDRlhfV2lkZVN0cmluZyBzd01zZzsKCWRHcmVhdGVyVGhhbiA9IChkb3VibGUpcGFyYW1zWzFdOwoJYkxlc3NUaGFuID0gKEZYX0JPT0wpcGFyYW1zWzJdOwoJZExlc3NUaGFuID0gKGRvdWJsZSlwYXJhbXNbM107CgoJaWYgKGJHcmVhdGVyVGhhbiAmJiBiTGVzc1RoYW4pCgl7CgkJaWYgKGRFZW50VmFsdWUgPCBkR3JlYXRlclRoYW4gfHwgZEVlbnRWYWx1ZSA+IGRMZXNzVGhhbikKCQkJc3dNc2cuRm9ybWF0KEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUkFOR0UxKSwoRlhfTFBDV1NUUilwYXJhbXNbMV0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKSwgKEZYX0xQQ1dTVFIpcGFyYW1zWzNdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCkpOwoJfQoJZWxzZSBpZiAoYkdyZWF0ZXJUaGFuKQoJewoJCWlmIChkRWVudFZhbHVlIDwgZEdyZWF0ZXJUaGFuKQoJCQlzd01zZy5Gb3JtYXQoSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNSQU5HRTIpLCAoRlhfTFBDV1NUUilwYXJhbXNbMV0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKSk7Cgl9CgllbHNlIGlmIChiTGVzc1RoYW4pCgl7CgkJaWYgKGRFZW50VmFsdWUgPiBkTGVzc1RoYW4pCgkJCXN3TXNnLkZvcm1hdChKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1JBTkdFMyksIChGWF9MUENXU1RSKXBhcmFtc1szXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpKTsKCX0KCglpZiAoIXN3TXNnLklzRW1wdHkoKSkKCXsKCQlBbGVydChwQ29udGV4dCwgc3dNc2cpOwoJCXBFdmVudC0+UmMoKSA9IEZBTFNFOwoJfQoJcmV0dXJuIFRSVUU7Cn0KCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGRXh0cmFjdE51bXMoT0JKX01FVEhPRF9QQVJBTVMpCnsKCXY4OjpJc29sYXRlKiBpc29sYXRlID0gOjpHZXRJc29sYXRlKGNjKTsKCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CglBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CgoJaWYgKHBhcmFtcy5zaXplKCkgIT0gMSkgCgl7CgkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJQ0pTX0FycmF5IG51bXMoaXNvbGF0ZSk7CgoJQ0ZYX1dpZGVTdHJpbmcgc3RyID0gcGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CglDRlhfV2lkZVN0cmluZyBzUGFydDsKCglpZiAoc3RyLkdldEF0KDApID09IEwnLicgfHwgc3RyLkdldEF0KDApID09IEwnLCcpCgkJc3RyID0gTCIwIiArIHN0cjsKCglpbnQgbkluZGV4ID0gMDsKCWZvciAoaW50IGk9MCwgc3o9c3RyLkdldExlbmd0aCgpOyBpPHN6OyBpKyspCgl7CgkJRlhfV0NIQVIgd2MgPSBzdHIuR2V0QXQoaSk7CgkJaWYgKElzRGlnaXQoKHdjaGFyX3Qpd2MpKQoJCXsKCQkJc1BhcnQgKz0gd2M7CgkJfQoJCWVsc2UKCQl7CgkJCWlmIChzUGFydC5HZXRMZW5ndGgoKSA+IDApCgkJCXsKCQkJCW51bXMuU2V0RWxlbWVudChuSW5kZXgsQ0pTX1ZhbHVlKGlzb2xhdGUsKEZYX0xQQ1dTVFIpc1BhcnQpKTsKCQkJCXNQYXJ0ID0gTCIiOwoJCQkJbkluZGV4ICsrOwoJCQl9CgkJfQoJfQoKCWlmIChzUGFydC5HZXRMZW5ndGgoKSA+IDApCgl7CgkJbnVtcy5TZXRFbGVtZW50KG5JbmRleCxDSlNfVmFsdWUoaXNvbGF0ZSwoRlhfTFBDV1NUUilzUGFydCkpOwkKCX0KCglpZiAobnVtcy5HZXRMZW5ndGgoKSA+IDApCgkJdlJldCA9IG51bXM7CgllbHNlCgkJdlJldC5TZXROdWxsKCk7CgoJcmV0dXJuIFRSVUU7Cn0K