LyoKICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCiAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAogKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCiAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCiAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCiAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqLwpwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy5pbWFnaW5nLmNvbG9yOwoKaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5pbWFnaW5nLnV0aWwuRGVidWc7CgpwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ29sb3JDb252ZXJzaW9ucwp7CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbG9yQ2llTGFiIGNvbnZlcnRYWVp0b0NJRUxhYihDb2xvclh5eiB4eXopCiAgICB7CiAgICAgICAgcmV0dXJuIGNvbnZlcnRYWVp0b0NJRUxhYih4eXouWCwgeHl6LlksIHh5ei5aKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBkb3VibGUgcmVmX1ggPSA5NS4wNDc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBkb3VibGUgcmVmX1kgPSAxMDAuMDAwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgZG91YmxlIHJlZl9aID0gMTA4Ljg4MzsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbG9yQ2llTGFiIGNvbnZlcnRYWVp0b0NJRUxhYihkb3VibGUgWCwgZG91YmxlIFksIGRvdWJsZSBaKQogICAgewoKICAgICAgICBkb3VibGUgdmFyX1ggPSBYIC8gcmVmX1g7IC8vcmVmX1ggPSAgOTUuMDQ3ICBPYnNlcnZlcj0gMrAsIElsbHVtaW5hbnQ9IEQ2NQogICAgICAgIGRvdWJsZSB2YXJfWSA9IFkgLyByZWZfWTsgLy9yZWZfWSA9IDEwMC4wMDAKICAgICAgICBkb3VibGUgdmFyX1ogPSBaIC8gcmVmX1o7IC8vcmVmX1ogPSAxMDguODgzCgogICAgICAgIGlmICh2YXJfWCA+IDAuMDA4ODU2KQogICAgICAgICAgICB2YXJfWCA9IE1hdGgucG93KHZhcl9YLCAoMSAvIDMuMCkpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgdmFyX1ggPSAoNy43ODcgKiB2YXJfWCkgKyAoMTYgLyAxMTYuMCk7CiAgICAgICAgaWYgKHZhcl9ZID4gMC4wMDg4NTYpCiAgICAgICAgICAgIHZhcl9ZID0gTWF0aC5wb3codmFyX1ksIDEgLyAzLjApOwogICAgICAgIGVsc2UKICAgICAgICAgICAgdmFyX1kgPSAoNy43ODcgKiB2YXJfWSkgKyAoMTYgLyAxMTYuMCk7CiAgICAgICAgaWYgKHZhcl9aID4gMC4wMDg4NTYpCiAgICAgICAgICAgIHZhcl9aID0gTWF0aC5wb3codmFyX1osIDEgLyAzLjApOwogICAgICAgIGVsc2UKICAgICAgICAgICAgdmFyX1ogPSAoNy43ODcgKiB2YXJfWikgKyAoMTYgLyAxMTYuMCk7CgogICAgICAgIGRvdWJsZSBMID0gKDExNiAqIHZhcl9ZKSAtIDE2OwogICAgICAgIGRvdWJsZSBhID0gNTAwICogKHZhcl9YIC0gdmFyX1kpOwogICAgICAgIGRvdWJsZSBiID0gMjAwICogKHZhcl9ZIC0gdmFyX1opOwogICAgICAgIHJldHVybiBuZXcgQ29sb3JDaWVMYWIoTCwgYSwgYik7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb2xvclh5eiBjb252ZXJ0Q0lFTGFidG9YWVooQ29sb3JDaWVMYWIgY2llbGFiKQogICAgewogICAgICAgIHJldHVybiBjb252ZXJ0Q0lFTGFidG9YWVooY2llbGFiLkwsIGNpZWxhYi5hLCBjaWVsYWIuYik7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb2xvclh5eiBjb252ZXJ0Q0lFTGFidG9YWVooZG91YmxlIEwsIGRvdWJsZSBhLCBkb3VibGUgYikKICAgIHsKICAgICAgICBkb3VibGUgdmFyX1kgPSAoTCArIDE2KSAvIDExNi4wOwogICAgICAgIGRvdWJsZSB2YXJfWCA9IGEgLyA1MDAgKyB2YXJfWTsKICAgICAgICBkb3VibGUgdmFyX1ogPSB2YXJfWSAtIGIgLyAyMDAuMDsKCiAgICAgICAgaWYgKE1hdGgucG93KHZhcl9ZLCAzKSA+IDAuMDA4ODU2KQogICAgICAgICAgICB2YXJfWSA9IE1hdGgucG93KHZhcl9ZLCAzKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHZhcl9ZID0gKHZhcl9ZIC0gMTYgLyAxMTYuMCkgLyA3Ljc4NzsKICAgICAgICBpZiAoTWF0aC5wb3codmFyX1gsIDMpID4gMC4wMDg4NTYpCiAgICAgICAgICAgIHZhcl9YID0gTWF0aC5wb3codmFyX1gsIDMpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgdmFyX1ggPSAodmFyX1ggLSAxNiAvIDExNi4wKSAvIDcuNzg3OwogICAgICAgIGlmIChNYXRoLnBvdyh2YXJfWiwgMykgPiAwLjAwODg1NikKICAgICAgICAgICAgdmFyX1ogPSBNYXRoLnBvdyh2YXJfWiwgMyk7CiAgICAgICAgZWxzZQogICAgICAgICAgICB2YXJfWiA9ICh2YXJfWiAtIDE2IC8gMTE2LjApIC8gNy43ODc7CgogICAgICAgIGRvdWJsZSBYID0gcmVmX1ggKiB2YXJfWDsgLy9yZWZfWCA9ICA5NS4wNDcgIE9ic2VydmVyPSAysCwgSWxsdW1pbmFudD0gRDY1CiAgICAgICAgZG91YmxlIFkgPSByZWZfWSAqIHZhcl9ZOyAvL3JlZl9ZID0gMTAwLjAwMAogICAgICAgIGRvdWJsZSBaID0gcmVmX1ogKiB2YXJfWjsgLy9yZWZfWiA9IDEwOC44ODMKCiAgICAgICAgcmV0dXJuIG5ldyBDb2xvclh5eihYLCBZLCBaKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbG9ySHVudGVyTGFiIGNvbnZlcnRYWVp0b0h1bnRlckxhYihDb2xvclh5eiB4eXopCiAgICB7CiAgICAgICAgcmV0dXJuIGNvbnZlcnRYWVp0b0h1bnRlckxhYih4eXouWCwgeHl6LlksIHh5ei5aKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbG9ySHVudGVyTGFiIGNvbnZlcnRYWVp0b0h1bnRlckxhYihkb3VibGUgWCwKICAgICAgICAgICAgZG91YmxlIFksIGRvdWJsZSBaKQogICAgewogICAgICAgIGRvdWJsZSBMID0gMTAgKiBNYXRoLnNxcnQoWSk7CiAgICAgICAgZG91YmxlIGEgPSAxNy41ICogKCgoMS4wMiAqIFgpIC0gWSkgLyBNYXRoLnNxcnQoWSkpOwogICAgICAgIGRvdWJsZSBiID0gNyAqICgoWSAtICgwLjg0NyAqIFopKSAvIE1hdGguc3FydChZKSk7CgogICAgICAgIHJldHVybiBuZXcgQ29sb3JIdW50ZXJMYWIoTCwgYSwgYik7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb2xvclh5eiBjb252ZXJ0SHVudGVyTGFidG9YWVooQ29sb3JIdW50ZXJMYWIgY2llbGFiKQogICAgewogICAgICAgIHJldHVybiBjb252ZXJ0SHVudGVyTGFidG9YWVooY2llbGFiLkwsIGNpZWxhYi5hLCBjaWVsYWIuYik7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb2xvclh5eiBjb252ZXJ0SHVudGVyTGFidG9YWVooZG91YmxlIEwsIGRvdWJsZSBhLAogICAgICAgICAgICBkb3VibGUgYikKICAgIHsKICAgICAgICBkb3VibGUgdmFyX1kgPSBMIC8gMTA7CiAgICAgICAgZG91YmxlIHZhcl9YID0gYSAvIDE3LjUgKiBMIC8gMTA7CiAgICAgICAgZG91YmxlIHZhcl9aID0gYiAvIDcgKiBMIC8gMTA7CgogICAgICAgIGRvdWJsZSBZID0gTWF0aC5wb3codmFyX1ksIDIpOwogICAgICAgIGRvdWJsZSBYID0gKHZhcl9YICsgWSkgLyAxLjAyOwogICAgICAgIGRvdWJsZSBaID0gLSh2YXJfWiAtIFkpIC8gMC44NDc7CgogICAgICAgIHJldHVybiBuZXcgQ29sb3JYeXooWCwgWSwgWik7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgY29udmVydFhZWnRvUkdCKENvbG9yWHl6IHh5eikKICAgIHsKICAgICAgICByZXR1cm4gY29udmVydFhZWnRvUkdCKHh5ei5YLCB4eXouWSwgeHl6LlopOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGNvbnZlcnRYWVp0b1JHQihkb3VibGUgWCwgZG91YmxlIFksIGRvdWJsZSBaKQogICAgewogICAgICAgIC8vT2JzZXJ2ZXIgPSAysCwgSWxsdW1pbmFudCA9IEQ2NQogICAgICAgIGRvdWJsZSB2YXJfWCA9IFggLyAxMDAuMDsgLy9XaGVyZSBYID0gMCD3ICA5NS4wNDcKICAgICAgICBkb3VibGUgdmFyX1kgPSBZIC8gMTAwLjA7IC8vV2hlcmUgWSA9IDAg9yAxMDAuMDAwCiAgICAgICAgZG91YmxlIHZhcl9aID0gWiAvIDEwMC4wOyAvL1doZXJlIFogPSAwIPcgMTA4Ljg4MwoKICAgICAgICBkb3VibGUgdmFyX1IgPSB2YXJfWCAqIDMuMjQwNiArIHZhcl9ZICogLTEuNTM3MiArIHZhcl9aICogLTAuNDk4NjsKICAgICAgICBkb3VibGUgdmFyX0cgPSB2YXJfWCAqIC0wLjk2ODkgKyB2YXJfWSAqIDEuODc1OCArIHZhcl9aICogMC4wNDE1OwogICAgICAgIGRvdWJsZSB2YXJfQiA9IHZhcl9YICogMC4wNTU3ICsgdmFyX1kgKiAtMC4yMDQwICsgdmFyX1ogKiAxLjA1NzA7CgogICAgICAgIGlmICh2YXJfUiA+IDAuMDAzMTMwOCkKICAgICAgICAgICAgdmFyX1IgPSAxLjA1NSAqIE1hdGgucG93KHZhcl9SLCAoMSAvIDIuNCkpIC0gMC4wNTU7CiAgICAgICAgZWxzZQogICAgICAgICAgICB2YXJfUiA9IDEyLjkyICogdmFyX1I7CiAgICAgICAgaWYgKHZhcl9HID4gMC4wMDMxMzA4KQogICAgICAgICAgICB2YXJfRyA9IDEuMDU1ICogTWF0aC5wb3codmFyX0csICgxIC8gMi40KSkgLSAwLjA1NTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHZhcl9HID0gMTIuOTIgKiB2YXJfRzsKICAgICAgICBpZiAodmFyX0IgPiAwLjAwMzEzMDgpCiAgICAgICAgICAgIHZhcl9CID0gMS4wNTUgKiBNYXRoLnBvdyh2YXJfQiwgKDEgLyAyLjQpKSAtIDAuMDU1OwogICAgICAgIGVsc2UKICAgICAgICAgICAgdmFyX0IgPSAxMi45MiAqIHZhcl9COwoKICAgICAgICBkb3VibGUgUiA9ICh2YXJfUiAqIDI1NSk7CiAgICAgICAgZG91YmxlIEcgPSAodmFyX0cgKiAyNTUpOwogICAgICAgIGRvdWJsZSBCID0gKHZhcl9CICogMjU1KTsKCiAgICAgICAgcmV0dXJuIGNvbnZlcnRSR0J0b1JHQihSLCBHLCBCKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbG9yWHl6IGNvbnZlcnRSR0J0b1hZWihpbnQgcmdiKQogICAgewogICAgICAgIGludCByID0gMHhmZiAmIChyZ2IgPj4gMTYpOwogICAgICAgIGludCBnID0gMHhmZiAmIChyZ2IgPj4gOCk7CiAgICAgICAgaW50IGIgPSAweGZmICYgKHJnYiA+PiAwKTsKCiAgICAgICAgZG91YmxlIHZhcl9SID0gciAvIDI1NS4wOyAvL1doZXJlIFIgPSAwIPcgMjU1CiAgICAgICAgZG91YmxlIHZhcl9HID0gZyAvIDI1NS4wOyAvL1doZXJlIEcgPSAwIPcgMjU1CiAgICAgICAgZG91YmxlIHZhcl9CID0gYiAvIDI1NS4wOyAvL1doZXJlIEIgPSAwIPcgMjU1CgogICAgICAgIGlmICh2YXJfUiA+IDAuMDQwNDUpCiAgICAgICAgICAgIHZhcl9SID0gTWF0aC5wb3coKHZhcl9SICsgMC4wNTUpIC8gMS4wNTUsIDIuNCk7CiAgICAgICAgZWxzZQogICAgICAgICAgICB2YXJfUiA9IHZhcl9SIC8gMTIuOTI7CiAgICAgICAgaWYgKHZhcl9HID4gMC4wNDA0NSkKICAgICAgICAgICAgdmFyX0cgPSBNYXRoLnBvdygodmFyX0cgKyAwLjA1NSkgLyAxLjA1NSwgMi40KTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHZhcl9HID0gdmFyX0cgLyAxMi45MjsKICAgICAgICBpZiAodmFyX0IgPiAwLjA0MDQ1KQogICAgICAgICAgICB2YXJfQiA9IE1hdGgucG93KCh2YXJfQiArIDAuMDU1KSAvIDEuMDU1LCAyLjQpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgdmFyX0IgPSB2YXJfQiAvIDEyLjkyOwoKICAgICAgICB2YXJfUiA9IHZhcl9SICogMTAwOwogICAgICAgIHZhcl9HID0gdmFyX0cgKiAxMDA7CiAgICAgICAgdmFyX0IgPSB2YXJfQiAqIDEwMDsKCiAgICAgICAgLy8gICAgICAgIE9ic2VydmVyLiA9IDKwLCBJbGx1bWluYW50ID0gRDY1CiAgICAgICAgZG91YmxlIFggPSB2YXJfUiAqIDAuNDEyNCArIHZhcl9HICogMC4zNTc2ICsgdmFyX0IgKiAwLjE4MDU7CiAgICAgICAgZG91YmxlIFkgPSB2YXJfUiAqIDAuMjEyNiArIHZhcl9HICogMC43MTUyICsgdmFyX0IgKiAwLjA3MjI7CiAgICAgICAgZG91YmxlIFogPSB2YXJfUiAqIDAuMDE5MyArIHZhcl9HICogMC4xMTkyICsgdmFyX0IgKiAwLjk1MDU7CgogICAgICAgIHJldHVybiBuZXcgQ29sb3JYeXooWCwgWSwgWik7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb2xvckNteSBjb252ZXJ0UkdCdG9DTVkoaW50IHJnYikKICAgIHsKICAgICAgICBpbnQgUiA9IDB4ZmYgJiAocmdiID4+IDE2KTsKICAgICAgICBpbnQgRyA9IDB4ZmYgJiAocmdiID4+IDgpOwogICAgICAgIGludCBCID0gMHhmZiAmIChyZ2IgPj4gMCk7CgogICAgICAgIC8vICAgICAgICBSR0IgdmFsdWVzID0gMCD3IDI1NQogICAgICAgIC8vICAgICAgICBDTVkgdmFsdWVzID0gMCD3IDEKCiAgICAgICAgZG91YmxlIEMgPSAxIC0gKFIgLyAyNTUuMCk7CiAgICAgICAgZG91YmxlIE0gPSAxIC0gKEcgLyAyNTUuMCk7CiAgICAgICAgZG91YmxlIFkgPSAxIC0gKEIgLyAyNTUuMCk7CgogICAgICAgIHJldHVybiBuZXcgQ29sb3JDbXkoQywgTSwgWSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgY29udmVydENNWXRvUkdCKENvbG9yQ215IGNteSkKICAgIHsKICAgICAgICAvLyBGcm9tIEdob3N0c2NyaXB0J3MgZ2RldmNkai5jOiAKICAgICAgICAvLyAqICAgR2hvc3RzY3JpcHQ6ICAgIFIgPSAoMS4wIC0gQykgKiAoMS4wIC0gSykKICAgICAgICAvLyAqICAgQWRvYmU6ICAgICAgICAgIFIgPSAxLjAgLSBtaW4oMS4wLCBDICsgSykKICAgICAgICAvLyBhbmQgc2ltaWxhcmx5IGZvciBHIGFuZCBCLgogICAgICAgIC8vIFRoaXMgaXMgR2hvc3RzY3JpcHQncyBmb3JtdWxhIHdpdGggSyA9IDAuCiAgICAgICAgCiAgICAgICAgLy8gICAgICAgIENNWSB2YWx1ZXMgPSAwIPcgMQogICAgICAgIC8vICAgICAgICBSR0IgdmFsdWVzID0gMCD3IDI1NQoKICAgICAgICBkb3VibGUgUiA9ICgxIC0gY215LkMpICogMjU1LjA7CiAgICAgICAgZG91YmxlIEcgPSAoMSAtIGNteS5NKSAqIDI1NS4wOwogICAgICAgIGRvdWJsZSBCID0gKDEgLSBjbXkuWSkgKiAyNTUuMDsKCiAgICAgICAgcmV0dXJuIGNvbnZlcnRSR0J0b1JHQihSLCBHLCBCKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbG9yQ215ayBjb252ZXJ0Q01ZdG9DTVlLKENvbG9yQ215IGNteSkKICAgIHsKICAgICAgICAvLyAgICAgICAgV2hlcmUgQ01ZSyBhbmQgQ01ZIHZhbHVlcyA9IDAg9yAxCgogICAgICAgIGRvdWJsZSBDID0gY215LkM7CiAgICAgICAgZG91YmxlIE0gPSBjbXkuTTsKICAgICAgICBkb3VibGUgWSA9IGNteS5ZOwoKICAgICAgICBkb3VibGUgdmFyX0sgPSAxLjA7CgogICAgICAgIGlmIChDIDwgdmFyX0spCiAgICAgICAgICAgIHZhcl9LID0gQzsKICAgICAgICBpZiAoTSA8IHZhcl9LKQogICAgICAgICAgICB2YXJfSyA9IE07CiAgICAgICAgaWYgKFkgPCB2YXJfSykKICAgICAgICAgICAgdmFyX0sgPSBZOwogICAgICAgIGlmICh2YXJfSyA9PSAxKQogICAgICAgIHsgLy9CbGFjawogICAgICAgICAgICBDID0gMDsKICAgICAgICAgICAgTSA9IDA7CiAgICAgICAgICAgIFkgPSAwOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBDID0gKEMgLSB2YXJfSykgLyAoMSAtIHZhcl9LKTsKICAgICAgICAgICAgTSA9IChNIC0gdmFyX0spIC8gKDEgLSB2YXJfSyk7CiAgICAgICAgICAgIFkgPSAoWSAtIHZhcl9LKSAvICgxIC0gdmFyX0spOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbmV3IENvbG9yQ215ayhDLCBNLCBZLCB2YXJfSyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb2xvckNteSBjb252ZXJ0Q01ZS3RvQ01ZKENvbG9yQ215ayBjbXlrKQogICAgewogICAgICAgIHJldHVybiBjb252ZXJ0Q01ZS3RvQ01ZKGNteWsuQywgY215ay5NLCBjbXlrLlksIGNteWsuSyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb2xvckNteSBjb252ZXJ0Q01ZS3RvQ01ZKGRvdWJsZSBDLCBkb3VibGUgTSwgZG91YmxlIFksCiAgICAgICAgICAgIGRvdWJsZSBLKQogICAgewogICAgICAgIC8vICAgIFdoZXJlIENNWUsgYW5kIENNWSB2YWx1ZXMgPSAwIPcgMQoKICAgICAgICBDID0gKEMgKiAoMSAtIEspICsgSyk7CiAgICAgICAgTSA9IChNICogKDEgLSBLKSArIEspOwogICAgICAgIFkgPSAoWSAqICgxIC0gSykgKyBLKTsKCiAgICAgICAgcmV0dXJuIG5ldyBDb2xvckNteShDLCBNLCBZKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBjb252ZXJ0Q01ZS3RvUkdCKGludCBjLCBpbnQgbSwgaW50IHksIGludCBrKQogICAgLy8gICAgdGhyb3dzIEltYWdlUmVhZEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24KICAgIHsKICAgICAgICBkb3VibGUgQyA9IGMgLyAyNTUuMDsKICAgICAgICBkb3VibGUgTSA9IG0gLyAyNTUuMDsKICAgICAgICBkb3VibGUgWSA9IHkgLyAyNTUuMDsKICAgICAgICBkb3VibGUgSyA9IGsgLyAyNTUuMDsKCiAgICAgICAgcmV0dXJuIGNvbnZlcnRDTVl0b1JHQihjb252ZXJ0Q01ZS3RvQ01ZKEMsIE0sIFksIEspKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbG9ySHNsIGNvbnZlcnRSR0J0b0hTTChpbnQgcmdiKQogICAgewoKICAgICAgICBpbnQgUiA9IDB4ZmYgJiAocmdiID4+IDE2KTsKICAgICAgICBpbnQgRyA9IDB4ZmYgJiAocmdiID4+IDgpOwogICAgICAgIGludCBCID0gMHhmZiAmIChyZ2IgPj4gMCk7CgogICAgICAgIGRvdWJsZSB2YXJfUiA9IChSIC8gMjU1LjApOyAvL1doZXJlIFJHQiB2YWx1ZXMgPSAwIPcgMjU1CiAgICAgICAgZG91YmxlIHZhcl9HID0gKEcgLyAyNTUuMCk7CiAgICAgICAgZG91YmxlIHZhcl9CID0gKEIgLyAyNTUuMCk7CgogICAgICAgIGRvdWJsZSB2YXJfTWluID0gTWF0aC5taW4odmFyX1IsIE1hdGgubWluKHZhcl9HLCB2YXJfQikpOyAvL01pbi4gdmFsdWUgb2YgUkdCCiAgICAgICAgZG91YmxlIHZhcl9NYXggPSBNYXRoLm1heCh2YXJfUiwgTWF0aC5tYXgodmFyX0csIHZhcl9CKSk7IC8vTWF4LiB2YWx1ZSBvZiBSR0IKICAgICAgICBkb3VibGUgZGVsX01heCA9IHZhcl9NYXggLSB2YXJfTWluOyAvL0RlbHRhIFJHQiB2YWx1ZQoKICAgICAgICBkb3VibGUgTCA9ICh2YXJfTWF4ICsgdmFyX01pbikgLyAyLjA7CgogICAgICAgIGRvdWJsZSBILCBTOwogICAgICAgIC8vICAgICAgICBEZWJ1Zy5kZWJ1ZygiZGVsX01heCIsIGRlbF9NYXgpOwogICAgICAgIGlmIChkZWxfTWF4ID09IDApIC8vVGhpcyBpcyBhIGdyYXksIG5vIGNocm9tYS4uLgogICAgICAgIHsKICAgICAgICAgICAgSCA9IDA7IC8vSFNMIHJlc3VsdHMgPSAwIPcgMQogICAgICAgICAgICBTID0gMDsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIC8vQ2hyb21hdGljIGRhdGEuLi4KICAgICAgICB7CiAgICAgICAgICAgIC8vICAgICAgICAgICAgRGVidWcuZGVidWcoIkwiLCBMKTsKCiAgICAgICAgICAgIGlmIChMIDwgMC41KQogICAgICAgICAgICAgICAgUyA9IGRlbF9NYXggLyAodmFyX01heCArIHZhcl9NaW4pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBTID0gZGVsX01heCAvICgyIC0gdmFyX01heCAtIHZhcl9NaW4pOwoKICAgICAgICAgICAgLy8gICAgICAgICAgICBEZWJ1Zy5kZWJ1ZygiUyIsIFMpOwoKICAgICAgICAgICAgZG91YmxlIGRlbF9SID0gKCgodmFyX01heCAtIHZhcl9SKSAvIDYpICsgKGRlbF9NYXggLyAyKSkgLyBkZWxfTWF4OwogICAgICAgICAgICBkb3VibGUgZGVsX0cgPSAoKCh2YXJfTWF4IC0gdmFyX0cpIC8gNikgKyAoZGVsX01heCAvIDIpKSAvIGRlbF9NYXg7CiAgICAgICAgICAgIGRvdWJsZSBkZWxfQiA9ICgoKHZhcl9NYXggLSB2YXJfQikgLyA2KSArIChkZWxfTWF4IC8gMikpIC8gZGVsX01heDsKCiAgICAgICAgICAgIGlmICh2YXJfUiA9PSB2YXJfTWF4KQogICAgICAgICAgICAgICAgSCA9IGRlbF9CIC0gZGVsX0c7CiAgICAgICAgICAgIGVsc2UgaWYgKHZhcl9HID09IHZhcl9NYXgpCiAgICAgICAgICAgICAgICBIID0gKDEgLyAzLjApICsgZGVsX1IgLSBkZWxfQjsKICAgICAgICAgICAgZWxzZSBpZiAodmFyX0IgPT0gdmFyX01heCkKICAgICAgICAgICAgICAgIEggPSAoMiAvIDMuMCkgKyBkZWxfRyAtIGRlbF9SOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIERlYnVnLmRlYnVnKCJ1aCBvaCIpOwogICAgICAgICAgICAgICAgSCA9IDA7IC8vIGNtYwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyAgICAgICAgICAgIERlYnVnLmRlYnVnKCJIMSIsIEgpOwoKICAgICAgICAgICAgaWYgKEggPCAwKQogICAgICAgICAgICAgICAgSCArPSAxOwogICAgICAgICAgICBpZiAoSCA+IDEpCiAgICAgICAgICAgICAgICBIIC09IDE7CgogICAgICAgICAgICAvLyAgICAgICAgICAgIERlYnVnLmRlYnVnKCJIMiIsIEgpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG5ldyBDb2xvckhzbChILCBTLCBMKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGludCBjb252ZXJ0SFNMdG9SR0IoQ29sb3JIc2wgaHNsKQogICAgewogICAgICAgIHJldHVybiBjb252ZXJ0SFNMdG9SR0IoaHNsLkgsIGhzbC5TLCBoc2wuTCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBpbnQgY29udmVydEhTTHRvUkdCKGRvdWJsZSBILCBkb3VibGUgUywgZG91YmxlIEwpCiAgICB7CiAgICAgICAgZG91YmxlIFIsIEcsIEI7CgogICAgICAgIGlmIChTID09IDApIC8vSFNMIHZhbHVlcyA9IDAg9yAxCiAgICAgICAgewogICAgICAgICAgICBSID0gTCAqIDI1NTsgLy9SR0IgcmVzdWx0cyA9IDAg9yAyNTUKICAgICAgICAgICAgRyA9IEwgKiAyNTU7CiAgICAgICAgICAgIEIgPSBMICogMjU1OwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBkb3VibGUgdmFyXzI7CgogICAgICAgICAgICBpZiAoTCA8IDAuNSkKICAgICAgICAgICAgICAgIHZhcl8yID0gTCAqICgxICsgUyk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHZhcl8yID0gKEwgKyBTKSAtIChTICogTCk7CgogICAgICAgICAgICBkb3VibGUgdmFyXzEgPSAyICogTCAtIHZhcl8yOwoKICAgICAgICAgICAgUiA9IDI1NSAqIGNvbnZlcnRIdWV0b1JHQih2YXJfMSwgdmFyXzIsIEggKyAoMSAvIDMuMCkpOwogICAgICAgICAgICBHID0gMjU1ICogY29udmVydEh1ZXRvUkdCKHZhcl8xLCB2YXJfMiwgSCk7CiAgICAgICAgICAgIEIgPSAyNTUgKiBjb252ZXJ0SHVldG9SR0IodmFyXzEsIHZhcl8yLCBIIC0gKDEgLyAzLjApKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBjb252ZXJ0UkdCdG9SR0IoUiwgRywgQik7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZG91YmxlIGNvbnZlcnRIdWV0b1JHQihkb3VibGUgdjEsIGRvdWJsZSB2MiwgZG91YmxlIHZIKSAvL0Z1bmN0aW9uIEh1ZV8yX1JHQgogICAgewogICAgICAgIGlmICh2SCA8IDApCiAgICAgICAgICAgIHZIICs9IDE7CiAgICAgICAgaWYgKHZIID4gMSkKICAgICAgICAgICAgdkggLT0gMTsKICAgICAgICBpZiAoKDYgKiB2SCkgPCAxKQogICAgICAgICAgICByZXR1cm4gKHYxICsgKHYyIC0gdjEpICogNiAqIHZIKTsKICAgICAgICBpZiAoKDIgKiB2SCkgPCAxKQogICAgICAgICAgICByZXR1cm4gKHYyKTsKICAgICAgICBpZiAoKDMgKiB2SCkgPCAyKQogICAgICAgICAgICByZXR1cm4gKHYxICsgKHYyIC0gdjEpICogKCgyIC8gMy4wKSAtIHZIKSAqIDYpOwogICAgICAgIHJldHVybiAodjEpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ29sb3JIc3YgY29udmVydFJHQnRvSFNWKGludCByZ2IpCiAgICB7CiAgICAgICAgaW50IFIgPSAweGZmICYgKHJnYiA+PiAxNik7CiAgICAgICAgaW50IEcgPSAweGZmICYgKHJnYiA+PiA4KTsKICAgICAgICBpbnQgQiA9IDB4ZmYgJiAocmdiID4+IDApOwoKICAgICAgICBkb3VibGUgdmFyX1IgPSAoUiAvIDI1NS4wKTsgLy9SR0IgdmFsdWVzID0gMCD3IDI1NQogICAgICAgIGRvdWJsZSB2YXJfRyA9IChHIC8gMjU1LjApOwogICAgICAgIGRvdWJsZSB2YXJfQiA9IChCIC8gMjU1LjApOwoKICAgICAgICBkb3VibGUgdmFyX01pbiA9IE1hdGgubWluKHZhcl9SLCBNYXRoLm1pbih2YXJfRywgdmFyX0IpKTsgLy9NaW4uIHZhbHVlIG9mIFJHQgogICAgICAgIGRvdWJsZSB2YXJfTWF4ID0gTWF0aC5tYXgodmFyX1IsIE1hdGgubWF4KHZhcl9HLCB2YXJfQikpOyAvL01heC4gdmFsdWUgb2YgUkdCCiAgICAgICAgZG91YmxlIGRlbF9NYXggPSB2YXJfTWF4IC0gdmFyX01pbjsgLy9EZWx0YSBSR0IgdmFsdWUKCiAgICAgICAgZG91YmxlIFYgPSB2YXJfTWF4OwoKICAgICAgICBkb3VibGUgSCwgUzsKICAgICAgICBpZiAoZGVsX01heCA9PSAwKSAvL1RoaXMgaXMgYSBncmF5LCBubyBjaHJvbWEuLi4KICAgICAgICB7CiAgICAgICAgICAgIEggPSAwOyAvL0hTViByZXN1bHRzID0gMCD3IDEKICAgICAgICAgICAgUyA9IDA7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICAvL0Nocm9tYXRpYyBkYXRhLi4uCiAgICAgICAgewogICAgICAgICAgICBTID0gZGVsX01heCAvIHZhcl9NYXg7CgogICAgICAgICAgICBkb3VibGUgZGVsX1IgPSAoKCh2YXJfTWF4IC0gdmFyX1IpIC8gNikgKyAoZGVsX01heCAvIDIpKSAvIGRlbF9NYXg7CiAgICAgICAgICAgIGRvdWJsZSBkZWxfRyA9ICgoKHZhcl9NYXggLSB2YXJfRykgLyA2KSArIChkZWxfTWF4IC8gMikpIC8gZGVsX01heDsKICAgICAgICAgICAgZG91YmxlIGRlbF9CID0gKCgodmFyX01heCAtIHZhcl9CKSAvIDYpICsgKGRlbF9NYXggLyAyKSkgLyBkZWxfTWF4OwoKICAgICAgICAgICAgaWYgKHZhcl9SID09IHZhcl9NYXgpCiAgICAgICAgICAgICAgICBIID0gZGVsX0IgLSBkZWxfRzsKICAgICAgICAgICAgZWxzZSBpZiAodmFyX0cgPT0gdmFyX01heCkKICAgICAgICAgICAgICAgIEggPSAoMSAvIDMuMCkgKyBkZWxfUiAtIGRlbF9COwogICAgICAgICAgICBlbHNlIGlmICh2YXJfQiA9PSB2YXJfTWF4KQogICAgICAgICAgICAgICAgSCA9ICgyIC8gMy4wKSArIGRlbF9HIC0gZGVsX1I7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRGVidWcuZGVidWcoInVoIG9oIik7CiAgICAgICAgICAgICAgICBIID0gMDsgLy8gY21jOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoSCA8IDApCiAgICAgICAgICAgICAgICBIICs9IDE7CiAgICAgICAgICAgIGlmIChIID4gMSkKICAgICAgICAgICAgICAgIEggLT0gMTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBuZXcgQ29sb3JIc3YoSCwgUywgVik7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBpbnQgY29udmVydEhTVnRvUkdCKENvbG9ySHN2IEhTVikKICAgIHsKICAgICAgICByZXR1cm4gY29udmVydEhTVnRvUkdCKEhTVi5ILCBIU1YuUywgSFNWLlYpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgaW50IGNvbnZlcnRIU1Z0b1JHQihkb3VibGUgSCwgZG91YmxlIFMsIGRvdWJsZSBWKQogICAgewogICAgICAgIGRvdWJsZSBSLCBHLCBCOwoKICAgICAgICBpZiAoUyA9PSAwKSAvL0hTViB2YWx1ZXMgPSAwIPcgMQogICAgICAgIHsKICAgICAgICAgICAgUiA9IFYgKiAyNTU7CiAgICAgICAgICAgIEcgPSBWICogMjU1OwogICAgICAgICAgICBCID0gViAqIDI1NTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgZG91YmxlIHZhcl9oID0gSCAqIDY7CiAgICAgICAgICAgIGlmICh2YXJfaCA9PSA2KQogICAgICAgICAgICAgICAgdmFyX2ggPSAwOyAvL0ggbXVzdCBiZSA8IDEKICAgICAgICAgICAgZG91YmxlIHZhcl9pID0gTWF0aC5mbG9vcih2YXJfaCk7IC8vT3IgLi4uIHZhcl9pID0gZmxvb3IoIHZhcl9oICkKICAgICAgICAgICAgZG91YmxlIHZhcl8xID0gViAqICgxIC0gUyk7CiAgICAgICAgICAgIGRvdWJsZSB2YXJfMiA9IFYgKiAoMSAtIFMgKiAodmFyX2ggLSB2YXJfaSkpOwogICAgICAgICAgICBkb3VibGUgdmFyXzMgPSBWICogKDEgLSBTICogKDEgLSAodmFyX2ggLSB2YXJfaSkpKTsKCiAgICAgICAgICAgIGRvdWJsZSB2YXJfciwgdmFyX2csIHZhcl9iOwoKICAgICAgICAgICAgaWYgKHZhcl9pID09IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhcl9yID0gVjsKICAgICAgICAgICAgICAgIHZhcl9nID0gdmFyXzM7CiAgICAgICAgICAgICAgICB2YXJfYiA9IHZhcl8xOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHZhcl9pID09IDEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhcl9yID0gdmFyXzI7CiAgICAgICAgICAgICAgICB2YXJfZyA9IFY7CiAgICAgICAgICAgICAgICB2YXJfYiA9IHZhcl8xOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHZhcl9pID09IDIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhcl9yID0gdmFyXzE7CiAgICAgICAgICAgICAgICB2YXJfZyA9IFY7CiAgICAgICAgICAgICAgICB2YXJfYiA9IHZhcl8zOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHZhcl9pID09IDMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhcl9yID0gdmFyXzE7CiAgICAgICAgICAgICAgICB2YXJfZyA9IHZhcl8yOwogICAgICAgICAgICAgICAgdmFyX2IgPSBWOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHZhcl9pID09IDQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhcl9yID0gdmFyXzM7CiAgICAgICAgICAgICAgICB2YXJfZyA9IHZhcl8xOwogICAgICAgICAgICAgICAgdmFyX2IgPSBWOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyX3IgPSBWOwogICAgICAgICAgICAgICAgdmFyX2cgPSB2YXJfMTsKICAgICAgICAgICAgICAgIHZhcl9iID0gdmFyXzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFIgPSB2YXJfciAqIDI1NTsgLy9SR0IgcmVzdWx0cyA9IDAg9yAyNTUKICAgICAgICAgICAgRyA9IHZhcl9nICogMjU1OwogICAgICAgICAgICBCID0gdmFyX2IgKiAyNTU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gY29udmVydFJHQnRvUkdCKFIsIEcsIEIpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGNvbnZlcnRDTVlLdG9SR0JfQWRvYmUoaW50IHNjLCBpbnQgc20sIGludCBzeSwgaW50IHNrKQogICAgLy8gICAgdGhyb3dzIEltYWdlUmVhZEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24KICAgIHsKICAgICAgICBpbnQgcmVkID0gMjU1IC0gKHNjICsgc2spOwogICAgICAgIGludCBncmVlbiA9IDI1NSAtIChzbSArIHNrKTsKICAgICAgICBpbnQgYmx1ZSA9IDI1NSAtIChzeSArIHNrKTsKCiAgICAgICAgcmV0dXJuIGNvbnZlcnRSR0J0b1JHQihyZWQsIGdyZWVuLCBibHVlKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBkb3VibGUgY3ViZShkb3VibGUgZikKICAgIHsKICAgICAgICByZXR1cm4gZiAqIGYgKiBmOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGRvdWJsZSBzcXVhcmUoZG91YmxlIGYpCiAgICB7CiAgICAgICAgcmV0dXJuIGYgKiBmOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGNvbnZlcnRDSUVMYWJ0b0FSR0JUZXN0KGludCBjaWVMLCBpbnQgY2llQSwgaW50IGNpZUIpCiAgICB7CiAgICAgICAgZG91YmxlIFgsIFksIFo7CgogICAgICAgIHsKCiAgICAgICAgICAgIGRvdWJsZSB2YXJfWSA9ICgoY2llTCAqIDEwMC4wIC8gMjU1LjApICsgMTYuMCkgLyAxMTYuMDsKICAgICAgICAgICAgZG91YmxlIHZhcl9YID0gY2llQSAvIDUwMC4wICsgdmFyX1k7CiAgICAgICAgICAgIGRvdWJsZSB2YXJfWiA9IHZhcl9ZIC0gY2llQiAvIDIwMC4wOwoKICAgICAgICAgICAgZG91YmxlIHZhcl94X2N1YmUgPSBjdWJlKHZhcl9YKTsKICAgICAgICAgICAgZG91YmxlIHZhcl95X2N1YmUgPSBjdWJlKHZhcl9ZKTsKICAgICAgICAgICAgZG91YmxlIHZhcl96X2N1YmUgPSBjdWJlKHZhcl9aKTsKCiAgICAgICAgICAgIGlmICh2YXJfeV9jdWJlID4gMC4wMDg4NTYpCiAgICAgICAgICAgICAgICB2YXJfWSA9IHZhcl95X2N1YmU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHZhcl9ZID0gKHZhcl9ZIC0gMTYgLyAxMTYuMCkgLyA3Ljc4NzsKCiAgICAgICAgICAgIGlmICh2YXJfeF9jdWJlID4gMC4wMDg4NTYpCiAgICAgICAgICAgICAgICB2YXJfWCA9IHZhcl94X2N1YmU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHZhcl9YID0gKHZhcl9YIC0gMTYgLyAxMTYuMCkgLyA3Ljc4NzsKCiAgICAgICAgICAgIGlmICh2YXJfel9jdWJlID4gMC4wMDg4NTYpCiAgICAgICAgICAgICAgICB2YXJfWiA9IHZhcl96X2N1YmU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHZhcl9aID0gKHZhcl9aIC0gMTYgLyAxMTYuMCkgLyA3Ljc4NzsKCiAgICAgICAgICAgIC8vICAgICAgICAgICAgZG91YmxlIHJlZl9YID0gOTUuMDQ3OwogICAgICAgICAgICAvLyAgICAgICAgICAgIGRvdWJsZSByZWZfWSA9IDEwMC4wMDA7CiAgICAgICAgICAgIC8vICAgICAgICAgICAgZG91YmxlIHJlZl9aID0gMTA4Ljg4MzsKCiAgICAgICAgICAgIFggPSByZWZfWCAqIHZhcl9YOyAvL3JlZl9YID0gIDk1LjA0NyAgT2JzZXJ2ZXI9IDKwLCBJbGx1bWluYW50PSBENjUKICAgICAgICAgICAgWSA9IHJlZl9ZICogdmFyX1k7IC8vcmVmX1kgPSAxMDAuMDAwCiAgICAgICAgICAgIFogPSByZWZfWiAqIHZhcl9aOyAvL3JlZl9aID0gMTA4Ljg4MwoKICAgICAgICB9CgogICAgICAgIGRvdWJsZSBSLCBHLCBCOwogICAgICAgIHsKICAgICAgICAgICAgZG91YmxlIHZhcl9YID0gWCAvIDEwMDsgLy9YID0gRnJvbSAwIHRvIHJlZl9YCiAgICAgICAgICAgIGRvdWJsZSB2YXJfWSA9IFkgLyAxMDA7IC8vWSA9IEZyb20gMCB0byByZWZfWQogICAgICAgICAgICBkb3VibGUgdmFyX1ogPSBaIC8gMTAwOyAvL1ogPSBGcm9tIDAgdG8gcmVmX1kKCiAgICAgICAgICAgIGRvdWJsZSB2YXJfUiA9IHZhcl9YICogMy4yNDA2ICsgdmFyX1kgKiAtMS41MzcyICsgdmFyX1ogKiAtMC40OTg2OwogICAgICAgICAgICBkb3VibGUgdmFyX0cgPSB2YXJfWCAqIC0wLjk2ODkgKyB2YXJfWSAqIDEuODc1OCArIHZhcl9aICogMC4wNDE1OwogICAgICAgICAgICBkb3VibGUgdmFyX0IgPSB2YXJfWCAqIDAuMDU1NyArIHZhcl9ZICogLTAuMjA0MCArIHZhcl9aICogMS4wNTcwOwoKICAgICAgICAgICAgaWYgKHZhcl9SID4gMC4wMDMxMzA4KQogICAgICAgICAgICAgICAgdmFyX1IgPSAxLjA1NSAqIE1hdGgucG93KHZhcl9SLCAoMSAvIDIuNCkpIC0gMC4wNTU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHZhcl9SID0gMTIuOTIgKiB2YXJfUjsKICAgICAgICAgICAgaWYgKHZhcl9HID4gMC4wMDMxMzA4KQogICAgICAgICAgICAgICAgdmFyX0cgPSAxLjA1NSAqIE1hdGgucG93KHZhcl9HLCAoMSAvIDIuNCkpIC0gMC4wNTU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHZhcl9HID0gMTIuOTIgKiB2YXJfRzsKCiAgICAgICAgICAgIGlmICh2YXJfQiA+IDAuMDAzMTMwOCkKICAgICAgICAgICAgICAgIHZhcl9CID0gMS4wNTUgKiBNYXRoLnBvdyh2YXJfQiwgKDEgLyAyLjQpKSAtIDAuMDU1OwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB2YXJfQiA9IDEyLjkyICogdmFyX0I7CgogICAgICAgICAgICBSID0gKHZhcl9SICogMjU1KTsKICAgICAgICAgICAgRyA9ICh2YXJfRyAqIDI1NSk7CiAgICAgICAgICAgIEIgPSAodmFyX0IgKiAyNTUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGNvbnZlcnRSR0J0b1JHQihSLCBHLCBCKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgY29udmVydFJHQnRvUkdCKGRvdWJsZSBSLCBkb3VibGUgRywgZG91YmxlIEIpCiAgICB7CiAgICAgICAgaW50IHJlZCA9IChpbnQpIE1hdGgucm91bmQoUik7CiAgICAgICAgaW50IGdyZWVuID0gKGludCkgTWF0aC5yb3VuZChHKTsKICAgICAgICBpbnQgYmx1ZSA9IChpbnQpIE1hdGgucm91bmQoQik7CgogICAgICAgIHJlZCA9IE1hdGgubWluKDI1NSwgTWF0aC5tYXgoMCwgcmVkKSk7CiAgICAgICAgZ3JlZW4gPSBNYXRoLm1pbigyNTUsIE1hdGgubWF4KDAsIGdyZWVuKSk7CiAgICAgICAgYmx1ZSA9IE1hdGgubWluKDI1NSwgTWF0aC5tYXgoMCwgYmx1ZSkpOwoKICAgICAgICBpbnQgYWxwaGEgPSAweGZmOwogICAgICAgIGludCByZ2IgPSAoYWxwaGEgPDwgMjQpIHwgKHJlZCA8PCAxNikgfCAoZ3JlZW4gPDwgOCkgfCAoYmx1ZSA8PCAwKTsKCiAgICAgICAgcmV0dXJuIHJnYjsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgY29udmVydFJHQnRvUkdCKGludCByZWQsIGludCBncmVlbiwgaW50IGJsdWUpCiAgICB7CiAgICAgICAgcmVkID0gTWF0aC5taW4oMjU1LCBNYXRoLm1heCgwLCByZWQpKTsKICAgICAgICBncmVlbiA9IE1hdGgubWluKDI1NSwgTWF0aC5tYXgoMCwgZ3JlZW4pKTsKICAgICAgICBibHVlID0gTWF0aC5taW4oMjU1LCBNYXRoLm1heCgwLCBibHVlKSk7CgogICAgICAgIGludCBhbHBoYSA9IDB4ZmY7CiAgICAgICAgaW50IHJnYiA9IChhbHBoYSA8PCAyNCkgfCAocmVkIDw8IDE2KSB8IChncmVlbiA8PCA4KSB8IChibHVlIDw8IDApOwoKICAgICAgICByZXR1cm4gcmdiOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgQ29sb3JDaWVMY2ggY29udmVydENJRUxhYnRvQ0lFTENIKENvbG9yQ2llTGFiIGNpZWxhYikKICAgIHsKICAgICAgICByZXR1cm4gY29udmVydENJRUxhYnRvQ0lFTENIKGNpZWxhYi5MLCBjaWVsYWIuYSwgY2llbGFiLmIpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgQ29sb3JDaWVMY2ggY29udmVydENJRUxhYnRvQ0lFTENIKGRvdWJsZSBMLCBkb3VibGUgYSwgZG91YmxlIGIpCiAgICB7CiAgICAgICAgZG91YmxlIHZhcl9IID0gTWF0aC5hdGFuMihiLCBhKTsgLy9RdWFkcmFudCBieSBzaWducwoKICAgICAgICBpZiAodmFyX0ggPiAwKQogICAgICAgICAgICB2YXJfSCA9ICh2YXJfSCAvIE1hdGguUEkpICogMTgwLjA7CiAgICAgICAgZWxzZQogICAgICAgICAgICB2YXJfSCA9IDM2MCAtIHJhZGlhbl8yX2RlZ3JlZShNYXRoLmFicyh2YXJfSCkpOwoKICAgICAgICAvLyAgICAgICAgTCA9IEw7CiAgICAgICAgZG91YmxlIEMgPSBNYXRoLnNxcnQoc3F1YXJlKGEpICsgc3F1YXJlKGIpKTsKICAgICAgICBkb3VibGUgSCA9IHZhcl9IOwoKICAgICAgICByZXR1cm4gbmV3IENvbG9yQ2llTGNoKEwsIEMsIEgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgQ29sb3JDaWVMYWIgY29udmVydENJRUxDSHRvQ0lFTGFiKENvbG9yQ2llTGNoIGNpZWxjaCkKICAgIHsKICAgICAgICByZXR1cm4gY29udmVydENJRUxDSHRvQ0lFTGFiKGNpZWxjaC5MLCBjaWVsY2guQywgY2llbGNoLkgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgQ29sb3JDaWVMYWIgY29udmVydENJRUxDSHRvQ0lFTGFiKGRvdWJsZSBMLCBkb3VibGUgQywgZG91YmxlIEgpCiAgICB7CiAgICAgICAgLy8gICAgICAgIFdoZXJlIENJRS1IsCA9IDAg9yAzNjCwCgogICAgICAgIC8vICAgICAgICBDSUUtTCogPSBDSUUtTDsKICAgICAgICBkb3VibGUgYSA9IE1hdGguY29zKGRlZ3JlZV8yX3JhZGlhbihIKSkgKiBDOwogICAgICAgIGRvdWJsZSBiID0gTWF0aC5zaW4oZGVncmVlXzJfcmFkaWFuKEgpKSAqIEM7CgogICAgICAgIHJldHVybiBuZXcgQ29sb3JDaWVMYWIoTCwgYSwgYik7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBkb3VibGUgZGVncmVlXzJfcmFkaWFuKGRvdWJsZSBkZWdyZWUpCiAgICB7CiAgICAgICAgcmV0dXJuIGRlZ3JlZSAqIE1hdGguUEkgLyAxODAuMDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGRvdWJsZSByYWRpYW5fMl9kZWdyZWUoZG91YmxlIHJhZGlhbikKICAgIHsKICAgICAgICByZXR1cm4gcmFkaWFuICogMTgwLjAgLyBNYXRoLlBJOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgQ29sb3JDaWVMdXYgY29udmVydFhZWnRvQ0lFTHV2KENvbG9yWHl6IHh5eikKICAgIHsKICAgICAgICByZXR1cm4gY29udmVydFhZWnRvQ0lFTHV2KHh5ei5YLCB4eXouWSwgeHl6LlopOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgQ29sb3JDaWVMdXYgY29udmVydFhZWnRvQ0lFTHV2KGRvdWJsZSBYLCBkb3VibGUgWSwgZG91YmxlIFopCiAgICB7CiAgICAgICAgLy8gcHJvYmxlbXMgaGVyZSB3aXRoIGRpdiBieSB6ZXJvCgogICAgICAgIGRvdWJsZSB2YXJfVSA9ICg0ICogWCkgLyAoWCArICgxNSAqIFkpICsgKDMgKiBaKSk7CiAgICAgICAgZG91YmxlIHZhcl9WID0gKDkgKiBZKSAvIChYICsgKDE1ICogWSkgKyAoMyAqIFopKTsKCiAgICAgICAgLy8gICAgICAgIERlYnVnLmRlYnVnKCJ2YXJfVSIsIHZhcl9VKTsKICAgICAgICAvLyAgICAgICAgRGVidWcuZGVidWcoInZhcl9WIiwgdmFyX1YpOwoKICAgICAgICBkb3VibGUgdmFyX1kgPSBZIC8gMTAwLjA7CiAgICAgICAgLy8gICAgICAgIERlYnVnLmRlYnVnKCJ2YXJfWSIsIHZhcl9ZKTsKCiAgICAgICAgaWYgKHZhcl9ZID4gMC4wMDg4NTYpCiAgICAgICAgICAgIHZhcl9ZID0gTWF0aC5wb3codmFyX1ksICgxIC8gMy4wKSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICB2YXJfWSA9ICg3Ljc4NyAqIHZhcl9ZKSArICgxNiAvIDExNi4wKTsKCiAgICAgICAgZG91YmxlIHJlZl9YID0gOTUuMDQ3OyAvL09ic2VydmVyPSAysCwgSWxsdW1pbmFudD0gRDY1CiAgICAgICAgZG91YmxlIHJlZl9ZID0gMTAwLjAwMDsKICAgICAgICBkb3VibGUgcmVmX1ogPSAxMDguODgzOwoKICAgICAgICAvLyAgICAgICAgRGVidWcuZGVidWcoInZhcl9ZIiwgdmFyX1kpOwoKICAgICAgICBkb3VibGUgcmVmX1UgPSAoNCAqIHJlZl9YKSAvIChyZWZfWCArICgxNSAqIHJlZl9ZKSArICgzICogcmVmX1opKTsKICAgICAgICBkb3VibGUgcmVmX1YgPSAoOSAqIHJlZl9ZKSAvIChyZWZfWCArICgxNSAqIHJlZl9ZKSArICgzICogcmVmX1opKTsKCiAgICAgICAgLy8gICAgICAgIERlYnVnLmRlYnVnKCJyZWZfVSIsIHJlZl9VKTsKICAgICAgICAvLyAgICAgICAgRGVidWcuZGVidWcoInJlZl9WIiwgcmVmX1YpOwoKICAgICAgICBkb3VibGUgTCA9ICgxMTYgKiB2YXJfWSkgLSAxNjsKICAgICAgICBkb3VibGUgdSA9IDEzICogTCAqICh2YXJfVSAtIHJlZl9VKTsKICAgICAgICBkb3VibGUgdiA9IDEzICogTCAqICh2YXJfViAtIHJlZl9WKTsKCiAgICAgICAgcmV0dXJuIG5ldyBDb2xvckNpZUx1dihMLCB1LCB2KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIENvbG9yWHl6IGNvbnZlcnRDSUVMdXZ0b1hZWihDb2xvckNpZUx1diBjaWVsY2gpCiAgICB7CiAgICAgICAgcmV0dXJuIGNvbnZlcnRDSUVMdXZ0b1hZWihjaWVsY2guTCwgY2llbGNoLnUsIGNpZWxjaC52KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIENvbG9yWHl6IGNvbnZlcnRDSUVMdXZ0b1hZWihkb3VibGUgTCwgZG91YmxlIHUsIGRvdWJsZSB2KQogICAgewogICAgICAgIC8vIHByb2JsZW1zIGhlcmUgd2l0aCBkaXYgYnkgemVybwoKICAgICAgICBkb3VibGUgdmFyX1kgPSAoTCArIDE2KSAvIDExNjsKICAgICAgICBpZiAoTWF0aC5wb3codmFyX1ksIDMpID4gMC4wMDg4NTYpCiAgICAgICAgICAgIHZhcl9ZID0gTWF0aC5wb3codmFyX1ksIDMpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgdmFyX1kgPSAodmFyX1kgLSAxNiAvIDExNikgLyA3Ljc4NzsKCiAgICAgICAgZG91YmxlIHJlZl9YID0gOTUuMDQ3OyAvL09ic2VydmVyPSAysCwgSWxsdW1pbmFudD0gRDY1CiAgICAgICAgZG91YmxlIHJlZl9ZID0gMTAwLjAwMDsKICAgICAgICBkb3VibGUgcmVmX1ogPSAxMDguODgzOwoKICAgICAgICBkb3VibGUgcmVmX1UgPSAoNCAqIHJlZl9YKSAvIChyZWZfWCArICgxNSAqIHJlZl9ZKSArICgzICogcmVmX1opKTsKICAgICAgICBkb3VibGUgcmVmX1YgPSAoOSAqIHJlZl9ZKSAvIChyZWZfWCArICgxNSAqIHJlZl9ZKSArICgzICogcmVmX1opKTsKICAgICAgICBkb3VibGUgdmFyX1UgPSB1IC8gKDEzICogTCkgKyByZWZfVTsKICAgICAgICBkb3VibGUgdmFyX1YgPSB2IC8gKDEzICogTCkgKyByZWZfVjsKCiAgICAgICAgZG91YmxlIFkgPSB2YXJfWSAqIDEwMDsKICAgICAgICBkb3VibGUgWCA9IC0oOSAqIFkgKiB2YXJfVSkgLyAoKHZhcl9VIC0gNCkgKiB2YXJfViAtIHZhcl9VICogdmFyX1YpOwogICAgICAgIGRvdWJsZSBaID0gKDkgKiBZIC0gKDE1ICogdmFyX1YgKiBZKSAtICh2YXJfViAqIFgpKSAvICgzICogdmFyX1YpOwoKICAgICAgICByZXR1cm4gbmV3IENvbG9yWHl6KFgsIFksIFopOwogICAgfQp9