Ly8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KIAovLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQoKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KYXZhU2NyaXB0LmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSUphdmFTY3JpcHQuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19EZWZpbmUuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19PYmplY3QuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19WYWx1ZS5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L1B1YmxpY01ldGhvZHMuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19FdmVudEhhbmRsZXIuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9yZXNvdXJjZS5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0NvbnRleHQuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19WYWx1ZS5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L3V0aWwuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9GaWVsZC5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L2NvbG9yLmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfUnVudGltZS5oIgoKc3RhdGljIHY4OjpJc29sYXRlKiBHZXRJc29sYXRlKElGWEpTX0NvbnRleHQqIGNjKQp7CglDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKCglDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCk7CglBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7CgoJcmV0dXJuIHBSdW50aW1lLT5HZXRJc29sYXRlKCk7Cn0KCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDSlNfUHVibGljTWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKI2RlZmluZSBET1VCTEVfQ09SUkVDVAkwLjAwMDAwMDAwMDAwMDAwMQoKQkVHSU5fSlNfU1RBVElDX0dMT0JBTF9GVU4oQ0pTX1B1YmxpY01ldGhvZHMpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRk51bWJlcl9Gb3JtYXQsNikKCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGTnVtYmVyX0tleXN0cm9rZSw2KQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZQZXJjZW50X0Zvcm1hdCwyKQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZQZXJjZW50X0tleXN0cm9rZSwyKQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZEYXRlX0Zvcm1hdEV4LDEpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRkRhdGVfS2V5c3Ryb2tlRXgsMSkKCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGRGF0ZV9Gb3JtYXQsMSkKCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGRGF0ZV9LZXlzdHJva2UsMSkKCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGVGltZV9Gb3JtYXRFeCwxKQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZUaW1lX0tleXN0cm9rZUV4LDEpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlRpbWVfRm9ybWF0LDEpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlRpbWVfS2V5c3Ryb2tlLDEpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlNwZWNpYWxfRm9ybWF0LDEpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlNwZWNpYWxfS2V5c3Ryb2tlLDEpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlNwZWNpYWxfS2V5c3Ryb2tlRXgsMSkKCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGU2ltcGxlLDMpCglKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRk1ha2VOdW1iZXIsMSkKCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGU2ltcGxlX0NhbGN1bGF0ZSwyKQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZSYW5nZV9WYWxpZGF0ZSw0KQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZNZXJnZUNoYW5nZSwxKQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZQYXJzZURhdGVFeCwyKQoJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZFeHRyYWN0TnVtcywxKQpFTkRfSlNfU1RBVElDX0dMT0JBTF9GVU4oKQoKSU1QTEVNRU5UX0pTX1NUQVRJQ19HTE9CQUxfRlVOKENKU19QdWJsaWNNZXRob2RzKQoKc3RydWN0IHN0cnVfVGJDb252ZXJ0CnsKCUZYX0xQQ1NUUiBscHN6SlNNYXJrOwoJRlhfTFBDU1RSIGxwc3pDcHBNYXJrOwp9OwoKc3RhdGljIGNvbnN0IHN0cnVfVGJDb252ZXJ0IGZjVGFibGVbXSA9IHsibW1tbSIsIiVCIiwKCSJtbW0iLCAiJWIiLAoJIm1tIiwgICIlbSIsCgkvLyJtIgoJImRkZGQiLCIlQSIsCgkiZGRkIiwgIiVhIiwKCSJkZCIsICAiJWQiLAoJLy8iZCIsICAgIiV3IiwKCSJ5eXl5IiwiJVkiLAoJInl5IiwgICIleSIsCgkiSEgiLCAgIiVIIiwKCS8vIkgiCgkiaGgiLCAgIiVJIiwKCS8vImgiCgkiTU0iLCAgIiVNIiwKCS8vIk0iCgkic3MiLCAgIiVTIiwKCS8vInMKCSJ0dCIsICAiJXAiCgkvLyJ0Igp9OwoKc3RhdGljIEZYX0xQQ1dTVFIgbW9udGhzW10gPQp7CgkoRlhfTFBDV1NUUilMIkphbiIsIChGWF9MUENXU1RSKUwiRmViIiwgKEZYX0xQQ1dTVFIpTCJNYXIiLCAoRlhfTFBDV1NUUilMIkFwciIsIChGWF9MUENXU1RSKUwiTWF5IiwgKEZYX0xQQ1dTVFIpTCJKdW4iLCAoRlhfTFBDV1NUUilMIkp1bCIsIChGWF9MUENXU1RSKUwiQXVnIiwgKEZYX0xQQ1dTVFIpTCJTZXAiLCAoRlhfTFBDV1NUUilMIk9jdCIsIChGWF9MUENXU1RSKUwiTm92IiwgKEZYX0xQQ1dTVFIpTCJEZWMiCn07CgpzdGF0aWMgRlhfTFBDV1NUUiBmdWxsbW9udGhzW10gPSAKeyAKCShGWF9MUENXU1RSKUwiSmFudWFyeSIsIChGWF9MUENXU1RSKUwiRmVicnVhcnkiLCAoRlhfTFBDV1NUUilMIk1hcmNoIiwgKEZYX0xQQ1dTVFIpTCJBcHJpbCIsIChGWF9MUENXU1RSKUwiTWF5IiwgKEZYX0xQQ1dTVFIpTCJKdW5lIiwgKEZYX0xQQ1dTVFIpTCJKdWx5IiwgKEZYX0xQQ1dTVFIpTCJBdWd1c3QiLCAoRlhfTFBDV1NUUilMIlNlcHRlbWJlciIsIChGWF9MUENXU1RSKUwiT2N0b2JlciIsIChGWF9MUENXU1RSKUwiTm92ZW1iZXIiLCAoRlhfTFBDV1NUUilMIkRlY2VtYmVyIiAKfTsKCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OklzTnVtYmVyKEZYX0xQQ1dTVFIgc3RyaW5nKQp7CglDRlhfV2lkZVN0cmluZyBzVHJpbSA9IFN0clRyaW0oc3RyaW5nKTsKCUZYX0xQQ1dTVFIgcFRyaW0gPSBzVHJpbTsKCUZYX0xQQ1dTVFIgcCA9IHBUcmltOwoKCglGWF9CT09MIGJEb3QgPSBGQUxTRTsKCUZYX0JPT0wgYktYSlMgPSBGQUxTRTsKCgl3Y2hhcl90IGM7Cgl3aGlsZSAoKGMgPSAqcCkpCgl7CgkJaWYgKGMgPT0gJy4nIHx8IGMgPT0gJywnKQoJCXsKCQkJaWYgKGJEb3QpIHJldHVybiBGQUxTRTsKCQkJYkRvdCA9IFRSVUU7CgkJfQoJCWVsc2UgaWYgKGMgPT0gJy0nIHx8IGMgPT0gJysnKQoJCXsKCQkJaWYgKHAgIT0gcFRyaW0pCgkJCQlyZXR1cm4gRkFMU0U7CgkJfQoJCWVsc2UgaWYgKGMgPT0gJ2UnIHx8IGMgPT0gJ0UnKQoJCXsKCQkJaWYgKGJLWEpTKSByZXR1cm4gRkFMU0U7CgoJCQlwKys7CgkJCWMgPSAqcDsKCQkJaWYgKGMgPT0gJysnIHx8IGMgPT0gJy0nKQoJCQl7CgkJCQliS1hKUyA9IFRSVUU7CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQlyZXR1cm4gRkFMU0U7CgkJCX0KCQl9CgkJZWxzZSBpZiAoIUlzRGlnaXQoYykpCgkJewoJCQlyZXR1cm4gRkFMU0U7CgkJfQoJCXArKzsKCX0KCglyZXR1cm4gVFJVRTsKfQoKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6SXNEaWdpdCh3Y2hhcl90IGNoKQp7CglyZXR1cm4gKGNoID49IEwnMCcgJiYgY2ggPD0gTCc5Jyk7Cn0KCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OklzRGlnaXQoY2hhciBjaCkKewoJcmV0dXJuIChjaCA+PSAnMCcgJiYgY2ggPD0gJzknKTsKfQoKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6SXNBbHBoYWJldGljKHdjaGFyX3QgY2gpCnsKCXJldHVybiAoKGNoID49IEwnYScgJiYgY2ggPD0gTCd6JykgfHwgKGNoID49IEwnQScgJiYgY2ggPD0gTCdaJykpOwp9CgpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpJc0FscGhhTnVtZXJpYyh3Y2hhcl90IGNoKQp7CglyZXR1cm4gKElzRGlnaXQoY2gpIHx8IElzQWxwaGFiZXRpYyhjaCkpOwp9CgpGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjptYXNrU2F0aXNmaWVkKHdjaGFyX3QgY19DaGFuZ2Usd2NoYXJfdCBjX01hc2spCnsKCXN3aXRjaCAoY19NYXNrKQoJewoJY2FzZSBMJzknOgogICAgICAgIHJldHVybiBJc0RpZ2l0KGNfQ2hhbmdlKTsJCQogICAgY2FzZSBMJ0EnOgogICAgICAgIHJldHVybiBJc0FscGhhYmV0aWMoY19DaGFuZ2UpOwkJCiAgICBjYXNlIEwnTyc6CiAgICAgICAgcmV0dXJuIElzQWxwaGFOdW1lcmljKGNfQ2hhbmdlKTsJCQogICAgY2FzZSBMJ1gnOgogICAgICAgIHJldHVybiBUUlVFOwkJCglkZWZhdWx0OgogICAgICAgIHJldHVybiAoY19DaGFuZ2UgPT0gY19NYXNrKTsKCX0KfQoKRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6aXNSZXNlcnZlZE1hc2tDaGFyKHdjaGFyX3QgY2gpCnsKCXJldHVybiBjaCA9PSBMJzknIHx8IGNoID09IEwnQScgfHwgY2ggPT0gTCdPJyB8fCBjaCA9PSBMJ1gnOwp9Cgpkb3VibGUgQ0pTX1B1YmxpY01ldGhvZHM6OkFGX1NpbXBsZShGWF9MUENXU1RSIHNGdWN0aW9uLCBkb3VibGUgZFZhbHVlMSwgZG91YmxlIGRWYWx1ZTIpCnsKCWlmIChGWFNZU193Y3NpY21wKHNGdWN0aW9uLChGWF9MUENXU1RSKUwiQVZHIikgPT0gMCB8fCBGWFNZU193Y3NpY21wKHNGdWN0aW9uLChGWF9MUENXU1RSKUwiU1VNIikgPT0gMCkKCXsKCQlyZXR1cm4gZFZhbHVlMSArIGRWYWx1ZTI7Cgl9CgllbHNlIGlmIChGWFNZU193Y3NpY21wKHNGdWN0aW9uLCAoRlhfTFBDV1NUUilMIlBSRCIpID09IDApCgl7CgkJcmV0dXJuIGRWYWx1ZTEgKiBkVmFsdWUyOwoJfQoJZWxzZSBpZiAoRlhTWVNfd2NzaWNtcChzRnVjdGlvbiwoRlhfTFBDV1NUUilMIk1JTiIpID09IDApCgl7CgkJcmV0dXJuIEZYX01JTihkVmFsdWUxLCBkVmFsdWUyKTsKCX0KCWVsc2UgaWYgKEZYU1lTX3djc2ljbXAoc0Z1Y3Rpb24sKEZYX0xQQ1dTVFIpTCJNQVgiKSA9PSAwKQoJewoJCXJldHVybiBGWF9NQVgoZFZhbHVlMSwgZFZhbHVlMik7Cgl9CgoJcmV0dXJuIGRWYWx1ZTE7Cn0KCkNGWF9XaWRlU3RyaW5nIENKU19QdWJsaWNNZXRob2RzOjpTdHJMVHJpbShGWF9MUENXU1RSIHBTdHIpCnsKCXdoaWxlICgqcFN0ciAmJiAqcFN0ciA9PSBMJyAnKSBwU3RyKys7CgoJcmV0dXJuIHBTdHI7Cn0KCkNGWF9XaWRlU3RyaW5nIENKU19QdWJsaWNNZXRob2RzOjpTdHJSVHJpbShGWF9MUENXU1RSIHBTdHIpCnsKCUZYX0xQQ1dTVFIgcCA9IHBTdHI7Cgl3aGlsZSAoKnApIHArKzsKCXdoaWxlIChwID4gcFN0ciAmJiAqKHAgLSAxKSA9PSBMJyAnKSBwLS07CgoJcmV0dXJuIENGWF9XaWRlU3RyaW5nKHBTdHIsIHAgLSBwU3RyKTsKfQoKQ0ZYX1dpZGVTdHJpbmcgQ0pTX1B1YmxpY01ldGhvZHM6OlN0clRyaW0oRlhfTFBDV1NUUiBwU3RyKQp7CglyZXR1cm4gU3RyUlRyaW0oU3RyTFRyaW0ocFN0cikpOwp9CgpDRlhfQnl0ZVN0cmluZyBDSlNfUHVibGljTWV0aG9kczo6U3RyTFRyaW0oRlhfTFBDU1RSIHBTdHIpCnsKCXdoaWxlICgqcFN0ciAmJiAqcFN0ciA9PSAnICcpIHBTdHIrKzsKCiAgICAgICAgcmV0dXJuIHBTdHI7Cn0KCkNGWF9CeXRlU3RyaW5nIENKU19QdWJsaWNNZXRob2RzOjpTdHJSVHJpbShGWF9MUENTVFIgcFN0cikKewoJRlhfTFBDU1RSIHAgPSBwU3RyOwoJd2hpbGUgKCpwKSBwKys7Cgl3aGlsZSAocCA+IHBTdHIgJiYgKihwIC0gMSkgPT0gTCcgJykgcC0tOwoKCXJldHVybiBDRlhfQnl0ZVN0cmluZyhwU3RyLHAtcFN0cik7Cn0KCkNGWF9CeXRlU3RyaW5nIENKU19QdWJsaWNNZXRob2RzOjpTdHJUcmltKEZYX0xQQ1NUUiBwU3RyKQp7CglyZXR1cm4gU3RyUlRyaW0oU3RyTFRyaW0ocFN0cikpOwp9Cgpkb3VibGUgQ0pTX1B1YmxpY01ldGhvZHM6OlBhcnNlTnVtYmVyKEZYX0xQQ1dTVFIgc3dTb3VyY2UsIEZYX0JPT0wmIGJBbGxEaWdpdHMsIEZYX0JPT0wmIGJEb3QsIEZYX0JPT0wmIGJTaWduLCBGWF9CT09MJiBiS1hKUykKewoJYkRvdCA9IEZBTFNFOwoJYlNpZ24gPSBGQUxTRTsKCWJLWEpTID0gRkFMU0U7CgoJRlhfQk9PTCBiRGlnaXRFeGlzdCA9IEZBTFNFOwoKCUZYX0xQQ1dTVFIgcCA9IHN3U291cmNlOwoJd2NoYXJfdCBjOwoKCUZYX0xQQ1dTVFIgcFN0YXJ0ID0gTlVMTDsKCUZYX0xQQ1dTVFIgcEVuZCA9IE5VTEw7CgoJd2hpbGUgKChjID0gKnApKQoJewoJCWlmICghcFN0YXJ0ICYmIGMgIT0gTCcgJykKCQl7CgkJCXBTdGFydCA9IHA7CgkJfQoKCQlwRW5kID0gcDsKCQlwKys7Cgl9CgoJaWYgKCFwU3RhcnQpCgl7CgkJYkFsbERpZ2l0cyA9IEZBTFNFOwoJCXJldHVybiAwOwoJfQoKCXdoaWxlIChwRW5kICE9IHBTdGFydCkKCXsKCQlpZiAoKnBFbmQgPT0gTCcgJykKCQkJcEVuZCAtLTsKCQllbHNlCgkJCWJyZWFrOwoJfQoKCWRvdWJsZSBkUmV0ID0gMDsKCXAgPSBwU3RhcnQ7CgliQWxsRGlnaXRzID0gVFJVRTsKCUNGWF9XaWRlU3RyaW5nIHN3RGlnaXRzOwoKCXdoaWxlIChwIDw9IHBFbmQpCgl7CQoJCWMgPSAqcDsKCgkJaWYgKElzRGlnaXQoYykpCgkJewoJCQlzd0RpZ2l0cyArPSBjOwoJCQliRGlnaXRFeGlzdCA9IFRSVUU7CgkJfQoJCWVsc2UgCgkJewoJCQlzd2l0Y2ggKGMpCgkJCXsKCQkJY2FzZSBMJyAnOgoJCQkJYkFsbERpZ2l0cyA9IEZBTFNFOwoJCQkJYnJlYWs7CgkJCWNhc2UgTCcuJzoKCQkJY2FzZSBMJywnOgoJCQkJaWYgKCFiRG90KQoJCQkJewoJCQkJCWlmIChiRGlnaXRFeGlzdCkKCQkJCQl7CgkJCQkJCXN3RGlnaXRzICs9IEwnLic7CgkJCQkJfQoJCQkJCWVsc2UKCQkJCQl7CgkJCQkJCXN3RGlnaXRzICs9IEwnMCc7CgkJCQkJCXN3RGlnaXRzICs9IEwnLic7CgkJCQkJCWJEaWdpdEV4aXN0ID0gVFJVRTsKCQkJCQl9CgoJCQkJCWJEb3QgPSBUUlVFOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQljYXNlICdlJzoKCQkJY2FzZSAnRSc6CgkJCQlpZiAoIWJLWEpTKQoJCQkJewoJCQkJCXArKzsKCQkJCQljID0gKnA7CgkJCQkJaWYgKGMgPT0gJysnIHx8IGMgPT0gJy0nKQoJCQkJCXsKCQkJCQkJYktYSlMgPSBUUlVFOwoJCQkJCQlzd0RpZ2l0cyArPSAnZSc7CgkJCQkJCXN3RGlnaXRzICs9IGM7CgkJCQkJfQoJCQkJCWJyZWFrOwoJCQkJfQoJCQljYXNlIEwnLSc6CgkJCQlpZiAoIWJEaWdpdEV4aXN0ICYmICFiU2lnbikKCQkJCXsKCQkJCQlzd0RpZ2l0cyArPSBjOwoJCQkJCWJTaWduID0gVFJVRTsKCQkJCQlicmVhazsKCQkJCX0KCQkJZGVmYXVsdDoKCQkJCWJBbGxEaWdpdHMgPSBGQUxTRTsKCgkJCQlpZiAocCAhPSBwU3RhcnQgJiYgIWJEb3QgJiYgYkRpZ2l0RXhpc3QpCgkJCQl7CgkJCQkJc3dEaWdpdHMgKz0gTCcuJzsKCQkJCQliRG90ID0gVFJVRTsKCQkJCX0KCQkJCWVsc2UKCQkJCXsKCQkJCQliRG90ID0gRkFMU0U7CgkJCQkJYkRpZ2l0RXhpc3QgPSBGQUxTRTsKCQkJCQlzd0RpZ2l0cyA9IEwiIjsKCQkJCX0KCQkJCWJyZWFrOwoJCQl9CgkJfQoKCQlwKys7Cgl9CgoJaWYgKHN3RGlnaXRzLkdldExlbmd0aCgpID4gMCAmJiBzd0RpZ2l0cy5HZXRMZW5ndGgoKSA8IDE3KQoJewoJCUNGWF9CeXRlU3RyaW5nIHNEaWdpdHMgPSBzd0RpZ2l0cy5VVEY4RW5jb2RlKCk7CgoJCWlmIChiS1hKUykKCQl7CgkJCWRSZXQgPSBhdG9mKHNEaWdpdHMpOwoJCX0KCQllbHNlCgkJewoJCQlpZiAoYkRvdCkKCQkJewoJCQkJY2hhciogcFN0b3BTdHJpbmc7CgkJCQlkUmV0ID0gOjpzdHJ0b2Qoc0RpZ2l0cywgJnBTdG9wU3RyaW5nKTsKCQkJfQoJCQllbHNlCgkJCXsKCQkJCWRSZXQgPSBhdG9sKHNEaWdpdHMpOwoJCQl9CgkJfQoKCX0KCglyZXR1cm4gZFJldDsKfQoKZG91YmxlIENKU19QdWJsaWNNZXRob2RzOjpQYXJzZVN0cmluZ1RvTnVtYmVyKEZYX0xQQ1dTVFIgc3dTb3VyY2UpCnsKCUZYX0JPT0wgYkFsbERpZ2l0cyA9IEZBTFNFOwoJRlhfQk9PTCBiRG90ID0gRkFMU0U7CglGWF9CT09MIGJTaWduID0gRkFMU0U7CglGWF9CT09MIGJLWEpTID0gRkFMU0U7CgoJcmV0dXJuIFBhcnNlTnVtYmVyKHN3U291cmNlLCBiQWxsRGlnaXRzLCBiRG90LCBiU2lnbiwgYktYSlMpOwp9CgpGWF9CT09MCUNKU19QdWJsaWNNZXRob2RzOjpDb252ZXJ0U3RyaW5nVG9OdW1iZXIoRlhfTFBDV1NUUiBzd1NvdXJjZSwgZG91YmxlICYgZFJldCwgRlhfQk9PTCAmIGJEb3QpCnsKCUZYX0JPT0wgYkFsbERpZ2l0cyA9IEZBTFNFOwoJRlhfQk9PTCBiU2lnbiA9IEZBTFNFOwoJRlhfQk9PTCBiS1hKUyA9IEZBTFNFOwoKCWRSZXQgPSBQYXJzZU51bWJlcihzd1NvdXJjZSwgYkFsbERpZ2l0cywgYkRvdCwgYlNpZ24sIGJLWEpTKTsKCglyZXR1cm4gYkFsbERpZ2l0czsKfQoKQ0pTX0FycmF5IENKU19QdWJsaWNNZXRob2RzOjpBRl9NYWtlQXJyYXlGcm9tTGlzdCh2ODo6SXNvbGF0ZSogaXNvbGF0ZSwgQ0pTX1ZhbHVlIHZhbCkKewoJQ0pTX0FycmF5IFN0ckFycmF5KGlzb2xhdGUpOwoJaWYodmFsLklzQXJyYXlPYmplY3QoKSkKCXsKCQl2YWwuQ29udmVydFRvQXJyYXkoU3RyQXJyYXkpOwoJCXJldHVybiBTdHJBcnJheTsKCX0KCUNGWF9XaWRlU3RyaW5nIHdzU3RyID0gdmFsLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CglDRlhfQnl0ZVN0cmluZyB0ID0gQ0ZYX0J5dGVTdHJpbmc6OkZyb21Vbmljb2RlKHdzU3RyKTsKCWNvbnN0IGNoYXIgKiBwID0gKGNvbnN0IGNoYXIgKil0OwoKCglpbnQgY2ggPSAnLCcgOwoJaW50IG5JbmRleCA9IDA7CgoJd2hpbGUgKCpwKQoJewoJCWNvbnN0IGNoYXIgKiBwVGVtcCA9IHN0cmNocihwLCBjaCk7CgkJaWYgKHBUZW1wID09IE5VTEwpCgkJewoJCQlTdHJBcnJheS5TZXRFbGVtZW50KG5JbmRleCwgQ0pTX1ZhbHVlKGlzb2xhdGUsKEZYX0xQQ1NUUilTdHJUcmltKHApKSk7CgkJCWJyZWFrOwoJCX0KCQllbHNlCgkJewoJCQljaGFyICogcFN1YiA9IG5ldyBjaGFyW3BUZW1wIC0gcCArIDFdOwoJCQlzdHJuY3B5KHBTdWIsIHAsIHBUZW1wIC0gcCk7CgkJCSoocFN1YiArIChwVGVtcCAtIHApKSA9ICdcMCc7CgoJCQlTdHJBcnJheS5TZXRFbGVtZW50KG5JbmRleCwgQ0pTX1ZhbHVlKGlzb2xhdGUsKEZYX0xQQ1NUUilTdHJUcmltKHBTdWIpKSk7CgkJCWRlbGV0ZSBbXXBTdWI7CgkJCQoJCQluSW5kZXggKys7CgkJCXAgPSArK3BUZW1wOwoJCX0KCQkKCX0KCXJldHVybiBTdHJBcnJheTsKfQoKaW50IENKU19QdWJsaWNNZXRob2RzOjpQYXJzZVN0cmluZ0ludGVnZXIoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0cmluZyxpbnQgblN0YXJ0LGludCYgblNraXAsIGludCBuTWF4U3RlcCkKewoJaW50IG5SZXQgPSAwOwoJblNraXAgPSAwOwoJZm9yIChpbnQgaT1uU3RhcnQsIHN6PXN0cmluZy5HZXRMZW5ndGgoKTsgaSA8IHN6OyBpKyspCgl7CgkJaWYgKGktblN0YXJ0ID4gMTApCgkJCWJyZWFrOwoKCQlGWF9XQ0hBUiBjID0gc3RyaW5nLkdldEF0KGkpOwoJCWlmIChJc0RpZ2l0KCh3Y2hhcl90KWMpKQoJCXsKCQkJblJldCA9IG5SZXQgKiAxMCArIChjIC0gJzAnKTsKCQkJblNraXAgPSBpIC0gblN0YXJ0ICsgMTsKCQkJaWYgKG5Ta2lwID49IG5NYXhTdGVwKSAKCQkJCWJyZWFrOwoJCX0KCQllbHNlCgkJCWJyZWFrOwoJfQoKCXJldHVybiBuUmV0Owp9CgpDRlhfV2lkZVN0cmluZyBDSlNfUHVibGljTWV0aG9kczo6UGFyc2VTdHJpbmdTdHJpbmcoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0cmluZywgaW50IG5TdGFydCwgaW50JiBuU2tpcCkKewoJQ0ZYX1dpZGVTdHJpbmcgc3dSZXQ7CgluU2tpcCA9IDA7Cglmb3IgKGludCBpPW5TdGFydCwgc3o9c3RyaW5nLkdldExlbmd0aCgpOyBpIDwgc3o7IGkrKykKCXsKCQlGWF9XQ0hBUiBjID0gc3RyaW5nLkdldEF0KGkpOwoJCWlmICgoYyA+PSBMJ2EnICYmIGMgPD0gTCd6JykgfHwgKGMgPj0gTCdBJyAmJiBjIDw9IEwnWicpKQoJCXsKCQkJc3dSZXQgKz0gYzsKCQkJblNraXAgPSBpIC0gblN0YXJ0ICsgMTsKCQl9CgkJZWxzZQoJCQlicmVhazsKCX0KCglyZXR1cm4gc3dSZXQ7Cn0KCmRvdWJsZSBDSlNfUHVibGljTWV0aG9kczo6UGFyc2VOb3JtYWxEYXRlKGNvbnN0IENGWF9XaWRlU3RyaW5nICYgdmFsdWUsIEZYX0JPT0wmIGJXcm9uZ0Zvcm1hdCkKewoJZG91YmxlIGR0ID0gSlNfR2V0RGF0ZVRpbWUoKTsKCglpbnQgblllYXIgPSBKU19HZXRZZWFyRnJvbVRpbWUoZHQpOwoJaW50IG5Nb250aCA9IEpTX0dldE1vbnRoRnJvbVRpbWUoZHQpICsgMTsKCWludCBuRGF5ID0gSlNfR2V0RGF5RnJvbVRpbWUoZHQpOwoJaW50IG5Ib3VyID0gSlNfR2V0SG91ckZyb21UaW1lKGR0KTsKCWludCBuTWluID0gSlNfR2V0TWluRnJvbVRpbWUoZHQpOwoJaW50IG5TZWMgPSBKU19HZXRTZWNGcm9tVGltZShkdCk7CgoJaW50IG51bWJlclszXTsKCglpbnQgblNraXAgPSAwOwoJaW50IG5MZW4gPSB2YWx1ZS5HZXRMZW5ndGgoKTsKCWludCBuSW5kZXggPSAwOwoJaW50IGkgPSAwOwoJd2hpbGUgKGkgPCBuTGVuKQoJewoJCWlmIChuSW5kZXggPiAyKSBicmVhazsKCgkJRlhfV0NIQVIgYyA9IHZhbHVlLkdldEF0KGkpOwoJCWlmIChJc0RpZ2l0KCh3Y2hhcl90KWMpKQoJCXsKCQkJbnVtYmVyW25JbmRleCsrXSA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaSwgblNraXAsIDQpOwoJCQlpICs9IG5Ta2lwOwkJCQoJCX0KCQllbHNlCgkJewoJCQlpICsrOwoJCX0KCX0KCglpZiAobkluZGV4ID09IDIpCgl7CgkJLy8gY2FzZTI6IG1vbnRoL2RheQoJCS8vIGNhc2UzOiBkYXkvbW9udGgKCQlpZiAoKG51bWJlclswXSA+PSAxICYmIG51bWJlclswXSA8PSAxMikgJiYgKG51bWJlclsxXSA+PSAxICYmIG51bWJlclsxXSA8PSAzMSkpCgkJewoJCQluTW9udGggPSBudW1iZXJbMF07CgkJCW5EYXkgPSBudW1iZXJbMV07CgkJfQoJCWVsc2UgaWYgKChudW1iZXJbMF0gPj0gMSAmJiBudW1iZXJbMF0gPD0gMzEpICYmIChudW1iZXJbMV0gPj0gMSAmJiBudW1iZXJbMV0gPD0gMTIpKQoJCXsKCQkJbkRheSA9IG51bWJlclswXTsKCQkJbk1vbnRoID0gbnVtYmVyWzFdOwoJCX0KCgkJYldyb25nRm9ybWF0ID0gRkFMU0U7Cgl9CgllbHNlIGlmIChuSW5kZXggPT0gMykKCXsKCQkvLyBjYXNlMTogeWVhci9tb250aC9kYXkKCQkvLyBjYXNlMjogbW9udGgvZGF5L3llYXIKCQkvLyBjYXNlMzogZGF5L21vbnRoL3llYXIKCgkJaWYgKG51bWJlclswXSA+IDEyICYmIChudW1iZXJbMV0gPj0gMSAmJiBudW1iZXJbMV0gPD0gMTIpICYmIChudW1iZXJbMl0gPj0gMSAmJiBudW1iZXJbMl0gPD0gMzEpKQoJCXsKCQkJblllYXIgPSBudW1iZXJbMF07CgkJCW5Nb250aCA9IG51bWJlclsxXTsKCQkJbkRheSA9IG51bWJlclsyXTsKCQl9CgkJZWxzZSBpZiAoKG51bWJlclswXSA+PSAxICYmIG51bWJlclswXSA8PSAxMikgJiYgKG51bWJlclsxXSA+PSAxICYmIG51bWJlclsxXSA8PSAzMSkgJiYgbnVtYmVyWzJdID4gMzEpCgkJewoJCQluTW9udGggPSBudW1iZXJbMF07CgkJCW5EYXkgPSBudW1iZXJbMV07CgkJCW5ZZWFyID0gbnVtYmVyWzJdOwoJCX0KCQllbHNlIGlmICgobnVtYmVyWzBdID49IDEgJiYgbnVtYmVyWzBdIDw9IDMxKSAmJiAobnVtYmVyWzFdID49IDEgJiYgbnVtYmVyWzFdIDw9IDEyKSAmJiBudW1iZXJbMl0gPiAzMSkKCQl7CgkJCW5EYXkgPSBudW1iZXJbMF07CgkJCW5Nb250aCA9IG51bWJlclsxXTsKCQkJblllYXIgPSBudW1iZXJbMl07CgkJfQoKCQliV3JvbmdGb3JtYXQgPSBGQUxTRTsKCX0KCWVsc2UKCXsKCQliV3JvbmdGb3JtYXQgPSBUUlVFOwoJCXJldHVybiBkdDsKCX0KCglDRlhfV2lkZVN0cmluZyBzd1RlbXA7Cglzd1RlbXAuRm9ybWF0KChGWF9MUENXU1RSKUwiJWQvJWQvJWQgJWQ6JWQ6JWQiLG5Nb250aCxuRGF5LG5ZZWFyLG5Ib3VyLG5NaW4sblNlYyk7CglyZXR1cm4gSlNfRGF0ZVBhcnNlKHN3VGVtcCk7Cn0KCmRvdWJsZSBDSlNfUHVibGljTWV0aG9kczo6TWFrZVJlZ3VsYXJEYXRlKGNvbnN0IENGWF9XaWRlU3RyaW5nICYgdmFsdWUsIGNvbnN0IENGWF9XaWRlU3RyaW5nICYgZm9ybWF0LCBGWF9CT09MJiBiV3JvbmdGb3JtYXQpCnsKCWRvdWJsZSBkdCA9IEpTX0dldERhdGVUaW1lKCk7CgoJaWYgKGZvcm1hdC5Jc0VtcHR5KCkgfHwgdmFsdWUuSXNFbXB0eSgpKQoJCXJldHVybiBkdDsKCglpbnQgblllYXIgPSBKU19HZXRZZWFyRnJvbVRpbWUoZHQpOwoJaW50IG5Nb250aCA9IEpTX0dldE1vbnRoRnJvbVRpbWUoZHQpICsgMTsKCWludCBuRGF5ID0gSlNfR2V0RGF5RnJvbVRpbWUoZHQpOwoJaW50IG5Ib3VyID0gSlNfR2V0SG91ckZyb21UaW1lKGR0KTsKCWludCBuTWluID0gSlNfR2V0TWluRnJvbVRpbWUoZHQpOwoJaW50IG5TZWMgPSBKU19HZXRTZWNGcm9tVGltZShkdCk7CgoJaW50IG5ZZWFyU3ViID0gOTk7IC8vblllYXIgLSAyMDAwOwoKCUZYX0JPT0wgYlBtID0gRkFMU0U7CglGWF9CT09MIGJFeGl0ID0gRkFMU0U7CgliV3JvbmdGb3JtYXQgPSBGQUxTRTsKCglpbnQgaT0wOwoJaW50IGo9MDsKCgl3aGlsZSAoaSA8IGZvcm1hdC5HZXRMZW5ndGgoKSkKCXsKCQlpZiAoYkV4aXQpIGJyZWFrOwoKCQlGWF9XQ0hBUiBjID0gZm9ybWF0LkdldEF0KGkpOwoJCXN3aXRjaCAoYykKCQl7CgkJCWNhc2UgJzonOgoJCQljYXNlICcuJzoKCQkJY2FzZSAnLSc6CgkJCWNhc2UgJ1xcJzoKCQkJY2FzZSAnLyc6CgkJCQlpKys7CgkJCQlqKys7CgkJCQlicmVhazsKCgkJCWNhc2UgJ3knOgoJCQljYXNlICdtJzoKCQkJY2FzZSAnZCc6CgkJCWNhc2UgJ0gnOgoJCQljYXNlICdoJzoKCQkJY2FzZSAnTSc6CgkJCWNhc2UgJ3MnOgoJCQljYXNlICd0JzoKCQkJCXsKCQkJCQlpbnQgb2xkaiA9IGo7CgkJCQkJaW50IG5Ta2lwID0gMDsKCQkJCQlpbnQgcmVtYWluaW5nID0gZm9ybWF0LkdldExlbmd0aCgpIC0gaSAtIDE7CgoJCQkJCWlmIChyZW1haW5pbmcgPT0gMCB8fCBmb3JtYXQuR2V0QXQoaSsxKSAhPSBjKQoJCQkJCXsKCQkJCQkJc3dpdGNoIChjKQoJCQkJCQl7CgkJCQkJCQljYXNlICd5JzoKCQkJCQkJCQlpKys7CgkJCQkJCQkJaisrOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJY2FzZSAnbSc6CgkJCQkJCQkJbk1vbnRoID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMik7CgkJCQkJCQkJaSsrOwoJCQkJCQkJCWogKz0gblNraXA7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlICdkJzoKCQkJCQkJCQluRGF5ID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMik7CgkJCQkJCQkJaSsrOwoJCQkJCQkJCWogKz0gblNraXA7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlICdIJzoKCQkJCQkJCQluSG91ciA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDIpOwoJCQkJCQkJCWkrKzsKCQkJCQkJCQlqICs9IG5Ta2lwOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJY2FzZSAnaCc6CgkJCQkJCQkJbkhvdXIgPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAyKTsKCQkJCQkJCQlpKys7CgkJCQkJCQkJaiArPSBuU2tpcDsKCQkJCQkJCQlicmVhazsKCQkJCQkJCWNhc2UgJ00nOgoJCQkJCQkJCW5NaW4gPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAyKTsKCQkJCQkJCQlpKys7CgkJCQkJCQkJaiArPSBuU2tpcDsKCQkJCQkJCQlicmVhazsKCQkJCQkJCWNhc2UgJ3MnOgoJCQkJCQkJCW5TZWMgPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAyKTsKCQkJCQkJCQlpKys7CgkJCQkJCQkJaiArPSBuU2tpcDsKCQkJCQkJCQlicmVhazsKCQkJCQkJCWNhc2UgJ3QnOgoJCQkJCQkJCWJQbSA9IChqIDwgdmFsdWUuR2V0TGVuZ3RoKCkgJiYgdmFsdWUuR2V0QXQoaikgPT0gJ3AnKTsKCQkJCQkJCQlpKys7CgkJCQkJCQkJaisrOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQl9CgkJCQkJfQoJCQkJCWVsc2UgaWYgKHJlbWFpbmluZyA9PSAxIHx8IGZvcm1hdC5HZXRBdChpKzIpICE9IGMpCgkJCQkJewoJCQkJCQlzd2l0Y2ggKGMpCgkJCQkJCXsKCQkJCQkJCWNhc2UgJ3knOgoJCQkJCQkJCW5ZZWFyID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgNCk7CgkJCQkJCQkJaSArPSAyOwoJCQkJCQkJCWogKz0gblNraXA7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlICdtJzoKCQkJCQkJCQluTW9udGggPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAyKTsKCQkJCQkJCQlpICs9IDI7CgkJCQkJCQkJaiArPSBuU2tpcDsKCQkJCQkJCQlicmVhazsKCQkJCQkJCWNhc2UgJ2QnOgoJCQkJCQkJCW5EYXkgPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAyKTsKCQkJCQkJCQlpICs9IDI7CgkJCQkJCQkJaiArPSBuU2tpcDsKCQkJCQkJCQlicmVhazsKCQkJCQkJCWNhc2UgJ0gnOgoJCQkJCQkJCW5Ib3VyID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMik7CgkJCQkJCQkJaSArPSAyOwoJCQkJCQkJCWogKz0gblNraXA7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlICdoJzoKCQkJCQkJCQluSG91ciA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDIpOwoJCQkJCQkJCWkgKz0gMjsKCQkJCQkJCQlqICs9IG5Ta2lwOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJY2FzZSAnTSc6CgkJCQkJCQkJbk1pbiA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDIpOwoJCQkJCQkJCWkgKz0gMjsKCQkJCQkJCQlqICs9IG5Ta2lwOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJY2FzZSAncyc6CgkJCQkJCQkJblNlYyA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDIpOwoJCQkJCQkJCWkgKz0gMjsKCQkJCQkJCQlqICs9IG5Ta2lwOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJY2FzZSAndCc6CgkJCQkJCQkJYlBtID0gKGogKyAxIDwgdmFsdWUuR2V0TGVuZ3RoKCkgJiYgdmFsdWUuR2V0QXQoaikgPT0gJ3AnICYmIHZhbHVlLkdldEF0KGorMSkgPT0gJ20nKTsKCQkJCQkJCQlpICs9IDI7CgkJCQkJCQkJaiArPSAyOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQl9CgkJCQkJfQoJCQkJCWVsc2UgaWYgKHJlbWFpbmluZyA9PSAyIHx8IGZvcm1hdC5HZXRBdChpKzMpICE9IGMpCgkJCQkJewoJCQkJCQlzd2l0Y2ggKGMpCgkJCQkJCXsKCQkJCQkJCWNhc2UgJ20nOgoJCQkJCQkJCXsKCQkJCQkJCQkJQ0ZYX1dpZGVTdHJpbmcgc01vbnRoID0gUGFyc2VTdHJpbmdTdHJpbmcodmFsdWUsIGosIG5Ta2lwKTsKCQkJCQkJCQkJRlhfQk9PTCBiRmluZCA9IEZBTFNFOwoJCQkJCQkJCQlmb3IgKGludCBtID0gMDsgbSA8IDEyOyBtKyspCgkJCQkJCQkJCXsKCQkJCQkJCQkJCWlmIChzTW9udGguQ29tcGFyZU5vQ2FzZShtb250aHNbbV0pID09IDApCgkJCQkJCQkJCQl7CgkJCQkJCQkJCQkJbk1vbnRoID0gbSArIDE7CgkJCQkJCQkJCQkJaSs9MzsKCQkJCQkJCQkJCQlqKz1uU2tpcDsKCQkJCQkJCQkJCQliRmluZCA9IFRSVUU7CgkJCQkJCQkJCQkJYnJlYWs7CgkJCQkJCQkJCQl9CgkJCQkJCQkJCX0KCgkJCQkJCQkJCWlmICghYkZpbmQpCgkJCQkJCQkJCXsKCQkJCQkJCQkJCW5Nb250aCA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDMpOwoJCQkJCQkJCQkJaSs9MzsKCQkJCQkJCQkJCWogKz0gblNraXA7CgkJCQkJCQkJCX0KCQkJCQkJCQl9CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlICd5JzoKCQkJCQkJCQlicmVhazsKCQkJCQkJCWRlZmF1bHQ6CgkJCQkJCQkJaSs9MzsKCQkJCQkJCQlqKz0zOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQl9CgkJCQkJfQoJCQkJCWVsc2UgaWYgKHJlbWFpbmluZyA9PSAzIHx8IGZvcm1hdC5HZXRBdChpKzQpICE9IGMpCgkJCQkJewoJCQkJCQlzd2l0Y2ggKGMpCgkJCQkJCXsKCgoJCQkJCQkJY2FzZSAneSc6CgkJCQkJCQkJblllYXIgPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCA0KTsKCQkJCQkJCQlqICs9IG5Ta2lwOwoJCQkJCQkJCWkgKz0gNDsKCQkJCQkJCQlicmVhazsKCQkJCQkJCWNhc2UgJ20nOgoJCQkJCQkJCXsKCQkJCQkJCQkJRlhfQk9PTCBiRmluZCA9IEZBTFNFOwoKCQkJCQkJCQkJQ0ZYX1dpZGVTdHJpbmcgc01vbnRoID0gUGFyc2VTdHJpbmdTdHJpbmcodmFsdWUsIGosIG5Ta2lwKTsKCQkJCQkJCQkJc01vbnRoLk1ha2VMb3dlcigpOwoKCQkJCQkJCQkJZm9yIChpbnQgbSA9IDA7IG0gPCAxMjsgbSsrKQoJCQkJCQkJCQl7CgkJCQkJCQkJCQlDRlhfV2lkZVN0cmluZyBzRnVsbE1vbnRocyA9IGZ1bGxtb250aHNbbV07CgkJCQkJCQkJCQlzRnVsbE1vbnRocy5NYWtlTG93ZXIoKTsKCgkJCQkJCQkJCQlpZiAoc0Z1bGxNb250aHMuRmluZChzTW9udGgsIDApICE9IC0xKQoJCQkJCQkJCQkJewoJCQkJCQkJCQkJCW5Nb250aCA9IG0gKyAxOwoJCQkJCQkJCQkJCWkgKz0gNDsKCQkJCQkJCQkJCQlqICs9IG5Ta2lwOwoJCQkJCQkJCQkJCWJGaW5kID0gVFJVRTsKCQkJCQkJCQkJCQlicmVhazsKCQkJCQkJCQkJCX0KCQkJCQkJCQkJfQoKCQkJCQkJCQkJaWYgKCFiRmluZCkKCQkJCQkJCQkJewoJCQkJCQkJCQkJbk1vbnRoID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgNCk7CgkJCQkJCQkJCQlpKz00OwoJCQkJCQkJCQkJaiArPSBuU2tpcDsKCQkJCQkJCQkJfQoJCQkJCQkJCX0KCQkJCQkJCQlicmVhazsKCQkJCQkJCWRlZmF1bHQ6CgkJCQkJCQkJaSArPSA0OwoJCQkJCQkJCWogKz0gNDsKCQkJCQkJCQlicmVhazsKCQkJCQkJfQoJCQkJCX0KCQkJCQllbHNlCgkJCQkJewoJCQkJCQlpZiAoaiA+PSB2YWx1ZS5HZXRMZW5ndGgoKSB8fCBmb3JtYXQuR2V0QXQoaSkgIT0gdmFsdWUuR2V0QXQoaikpCgkJCQkJCXsKCQkJCQkJCWJXcm9uZ0Zvcm1hdCA9IFRSVUU7CgkJCQkJCQliRXhpdCA9IFRSVUU7CgkJCQkJCX0KCQkJCQkJaSsrOwoJCQkJCQlqKys7CgkJCQkJfQoKCQkJCQlpZiAob2xkaiA9PSBqKQoJCQkJCXsKCQkJCQkJYldyb25nRm9ybWF0ID0gVFJVRTsKCQkJCQkJYkV4aXQgPSBUUlVFOwoJCQkJCX0KCQkJCX0KCgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCWlmICh2YWx1ZS5HZXRMZW5ndGgoKSA8PSBqKQoJCQkJewoJCQkJCWJFeGl0ID0gVFJVRTsKCQkJCX0KCQkJCWVsc2UgaWYgKGZvcm1hdC5HZXRBdChpKSAhPSB2YWx1ZS5HZXRBdChqKSkKCQkJCXsKCQkJCQliV3JvbmdGb3JtYXQgPSBUUlVFOwoJCQkJCWJFeGl0ID0gVFJVRTsKCQkJCX0KCgkJCQlpKys7CgkJCQlqKys7CgkJCQlicmVhazsKCQl9Cgl9CgoJaWYgKGJQbSkgbkhvdXIgKz0gMTI7CgoJaWYgKG5ZZWFyID49IDAgJiYgblllYXIgPD0gblllYXJTdWIpCgkJblllYXIgKz0gMjAwMDsKCglpZiAobk1vbnRoIDwgMSB8fCBuTW9udGggPiAxMikKCQliV3JvbmdGb3JtYXQgPSBUUlVFOwoKCWlmIChuRGF5IDwgMSB8fCBuRGF5ID4gMzEpCgkJYldyb25nRm9ybWF0ID0gVFJVRTsKCglpZiAobkhvdXIgPCAwIHx8IG5Ib3VyID4gMjQpCgkJYldyb25nRm9ybWF0ID0gVFJVRTsKCglpZiAobk1pbiA8IDAgfHwgbk1pbiA+IDYwKQoJCWJXcm9uZ0Zvcm1hdCA9IFRSVUU7CgoJaWYgKG5TZWMgPCAwIHx8IG5TZWMgPiA2MCkKCQliV3JvbmdGb3JtYXQgPSBUUlVFOwoKCWRvdWJsZSBkUmV0ID0gMDsKCglpZiAoYldyb25nRm9ybWF0KQoJewoJCWRSZXQgPSBQYXJzZU5vcm1hbERhdGUodmFsdWUsIGJXcm9uZ0Zvcm1hdCk7Cgl9CgllbHNlCgl7CgkJZFJldCA9IEpTX01ha2VEYXRlKEpTX01ha2VEYXkoblllYXIsbk1vbnRoIC0gMSxuRGF5KSxKU19NYWtlVGltZShuSG91ciwgbk1pbiwgblNlYywgMCkpOwoKCQlpZiAoSlNfUG9ydElzTmFuKGRSZXQpKQoJCXsKCQkJZFJldCA9IEpTX0RhdGVQYXJzZSh2YWx1ZSk7CgkJfQoJfQoKCWlmIChKU19Qb3J0SXNOYW4oZFJldCkpCgl7CgkJZFJldCA9IFBhcnNlTm9ybWFsRGF0ZSh2YWx1ZSwgYldyb25nRm9ybWF0KTsKCX0KCglyZXR1cm4gZFJldDsKCn0KCkNGWF9XaWRlU3RyaW5nIENKU19QdWJsaWNNZXRob2RzOjpNYWtlRm9ybWF0RGF0ZShkb3VibGUgZERhdGUsIGNvbnN0IENGWF9XaWRlU3RyaW5nICYgZm9ybWF0KQp7CglDRlhfV2lkZVN0cmluZyBzUmV0ID0gTCIiLHNQYXJ0ID0gTCIiOwoKCWludCBuWWVhciA9IEpTX0dldFllYXJGcm9tVGltZShkRGF0ZSk7CglpbnQgbk1vbnRoID0gSlNfR2V0TW9udGhGcm9tVGltZShkRGF0ZSkgKyAxOwoJaW50IG5EYXkgPSBKU19HZXREYXlGcm9tVGltZShkRGF0ZSk7CglpbnQgbkhvdXIgPSBKU19HZXRIb3VyRnJvbVRpbWUoZERhdGUpOwoJaW50IG5NaW4gPSBKU19HZXRNaW5Gcm9tVGltZShkRGF0ZSk7CglpbnQgblNlYyA9IEpTX0dldFNlY0Zyb21UaW1lKGREYXRlKTsKCglpbnQgaSA9IDA7Cgl3aGlsZSAoaSA8IGZvcm1hdC5HZXRMZW5ndGgoKSkKCXsKCSAgICAgICAgRlhfV0NIQVIgYyA9IGZvcm1hdC5HZXRBdChpKTsKICAgICAgICAgICAgICAgIGludCByZW1haW5pbmcgPSBmb3JtYXQuR2V0TGVuZ3RoKCkgLSBpIC0gMTsKCQlzUGFydCA9IEwiIjsKCQlzd2l0Y2ggKGMpCgkJewoJCQljYXNlICd5JzoKCQkJY2FzZSAnbSc6CgkJCWNhc2UgJ2QnOgoJCQljYXNlICdIJzoKCQkJY2FzZSAnaCc6CgkJCWNhc2UgJ00nOgoJCQljYXNlICdzJzoKCQkJY2FzZSAndCc6CgkJCQlpZiAocmVtYWluaW5nID09IDAgfHwgZm9ybWF0LkdldEF0KGkrMSkgIT0gYykKCQkJCXsKCQkJCQlzd2l0Y2ggKGMpCgkJCQkJewoJCQkJCQljYXNlICd5JzoKCQkJCQkJCXNQYXJ0ICs9IGM7CgkJCQkJCQlicmVhazsKCQkJCQkJY2FzZSAnbSc6CgkJCQkJCQlzUGFydC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlZCIsbk1vbnRoKTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICdkJzoKCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkIixuRGF5KTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICdIJzoKCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkIixuSG91cik7CgkJCQkJCQlicmVhazsKCQkJCQkJY2FzZSAnaCc6CgkJCQkJCQlzUGFydC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlZCIsbkhvdXI+MTI/bkhvdXIgLSAxMjpuSG91cik7CgkJCQkJCQlicmVhazsKCQkJCQkJY2FzZSAnTSc6CgkJCQkJCQlzUGFydC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlZCIsbk1pbik7CgkJCQkJCQlicmVhazsKCQkJCQkJY2FzZSAncyc6CgkJCQkJCQlzUGFydC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlZCIsblNlYyk7CgkJCQkJCQlicmVhazsKCQkJCQkJY2FzZSAndCc6CgkJCQkJCQlzUGFydCArPSBuSG91cj4xMj8ncCc6J2EnOwoJCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJCWkrKzsKCQkJCX0KCQkJCWVsc2UgaWYgKHJlbWFpbmluZyA9PSAxIHx8IGZvcm1hdC5HZXRBdChpKzIpICE9IGMpCgkJCQl7CgkJCQkJc3dpdGNoIChjKQoJCQkJCXsKCQkJCQkJY2FzZSAneSc6CgkJCQkJCQlzUGFydC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlMDJkIixuWWVhciAtIChuWWVhciAvIDEwMCkgKiAxMDApOwoJCQkJCQkJYnJlYWs7CgkJCQkJCWNhc2UgJ20nOgoJCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJTAyZCIsbk1vbnRoKTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICdkJzoKCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiUwMmQiLG5EYXkpOwoJCQkJCQkJYnJlYWs7CgkJCQkJCWNhc2UgJ0gnOgoJCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJTAyZCIsbkhvdXIpOwoJCQkJCQkJYnJlYWs7CgkJCQkJCWNhc2UgJ2gnOgoJCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJTAyZCIsbkhvdXI+MTI/bkhvdXIgLSAxMjpuSG91cik7CgkJCQkJCQlicmVhazsKCQkJCQkJY2FzZSAnTSc6CgkJCQkJCQlzUGFydC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlMDJkIixuTWluKTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICdzJzoKCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiUwMmQiLG5TZWMpOwoJCQkJCQkJYnJlYWs7CgkJCQkJCWNhc2UgJ3QnOgoJCQkJCQkJc1BhcnQgPSBuSG91cj4xMj8gKEZYX0xQQ1dTVFIpTCJwbSI6IChGWF9MUENXU1RSKUwiYW0iOwoJCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJCWkrPTI7CgkJCQl9CgkJCQllbHNlIGlmIChyZW1haW5pbmcgPT0gMiB8fCBmb3JtYXQuR2V0QXQoaSszKSAhPSBjKQoJCQkJewoJCQkJCXN3aXRjaCAoYykKCQkJCQl7CgkJCQkJCWNhc2UgJ20nOgoJCQkJCQkJaSs9MzsKCQkJCQkJCWlmIChuTW9udGggPiAwJiZuTW9udGggPD0gMTIpCgkJCQkJCQkJc1BhcnQgKz0gbW9udGhzW25Nb250aCAtIDFdOwoJCQkJCQkJYnJlYWs7CgkJCQkJCWRlZmF1bHQ6CgkJCQkJCQlpKz0zOwoJCQkJCQkJc1BhcnQgKz0gYzsKCQkJCQkJCXNQYXJ0ICs9IGM7CgkJCQkJCQlzUGFydCArPSBjOwoJCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJfQoJCQkJZWxzZSBpZiAocmVtYWluaW5nID09IDMgfHwgZm9ybWF0LkdldEF0KGkrNCkgIT0gYykKCQkJCXsKCQkJCQlzd2l0Y2ggKGMpCgkJCQkJewoJCQkJCQljYXNlICd5JzoKCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiUwNGQiLG5ZZWFyKTsKCQkJCQkJCWkgKz0gNDsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICdtJzoKCQkJCQkJCWkrPTQ7CgkJCQkJCQlpZiAobk1vbnRoID4gMCYmbk1vbnRoIDw9IDEyKQoJCQkJCQkJCXNQYXJ0ICs9IGZ1bGxtb250aHNbbk1vbnRoIC0gMV07CgkJCQkJCQlicmVhazsKCQkJCQkJZGVmYXVsdDoKCQkJCQkJCWkgKz0gNDsKCQkJCQkJCXNQYXJ0ICs9IGM7CgkJCQkJCQlzUGFydCArPSBjOwoJCQkJCQkJc1BhcnQgKz0gYzsKCQkJCQkJCXNQYXJ0ICs9IGM7CgkJCQkJCQlicmVhazsKCQkJCQl9CgkJCQl9CgkJCQllbHNlCgkJCQl7CgkJCQkJaSsrOwoJCQkJCXNQYXJ0ICs9IGM7CgkJCQl9CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCWkrKzsKCQkJCXNQYXJ0ICs9IGM7CgkJCQlicmVhazsKCQl9CgoJCXNSZXQgKz0gc1BhcnQ7Cgl9CgoJcmV0dXJuIHNSZXQ7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovL2Z1bmN0aW9uIEFGTnVtYmVyX0Zvcm1hdChuRGVjLCBzZXBTdHlsZSwgbmVnU3R5bGUsIGN1cnJTdHlsZSwgc3RyQ3VycmVuY3ksIGJDdXJyZW5jeVByZXBlbmQpCkZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGTnVtYmVyX0Zvcm1hdChPQkpfTUVUSE9EX1BBUkFNUykKewojaWYgX0ZYX09TXyAhPSBfRlhfQU5EUk9JRF8KCXY4OjpJc29sYXRlKiBpc29sYXRlID0gOjpHZXRJc29sYXRlKGNjKTsKCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOwoJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOwoJQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOwoJQVNTRVJUKHBFdmVudCAhPSBOVUxMKTsKCglpZiAocGFyYW1zLnNpemUoKSAhPSA2KQoJewoJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CgkJcmV0dXJuIEZBTFNFOwoJfQoJaWYoIXBFdmVudC0+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