Ly89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8KLy8gU3BsYXNoQml0bWFwLmNjCi8vCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLwovLyBNb2RpZmllZCB1bmRlciB0aGUgUG9wcGxlciBwcm9qZWN0IC0gaHR0cDovL3BvcHBsZXIuZnJlZWRlc2t0b3Aub3JnCi8vCi8vIEFsbCBjaGFuZ2VzIG1hZGUgdW5kZXIgdGhlIFBvcHBsZXIgcHJvamVjdCB0byB0aGlzIGZpbGUgYXJlIGxpY2Vuc2VkCi8vIHVuZGVyIEdQTCB2ZXJzaW9uIDIgb3IgbGF0ZXIKLy8KLy8gQ29weXJpZ2h0IChDKSAyMDA2LCAyMDA5LCAyMDEwLCAyMDEyLCAyMDE1LCAyMDE4IEFsYmVydCBBc3RhbHMgQ2lkIDxhYWNpZEBrZGUub3JnPgovLyBDb3B5cmlnaHQgKEMpIDIwMDcgSWxtYXJpIEhlaWtraW5lbiA8aWxtYXJpLmhlaWtraW5lbkBnbWFpbC5jb20+Ci8vIENvcHlyaWdodCAoQykgMjAwOSBTaGVuIExpYW5nIDxzaGVuemh1eGlAZ21haWwuY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMDkgU3RlZmFuIFRob21hcyA8dGhvbWFzQGVsb2FkMjQuY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMTAsIDIwMTIsIDIwMTcgQWRyaWFuIEpvaG5zb24gPGFqb2huc29uQHJlZG5lb24uY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMTAgSGFycnkgUm9iZXJ0cyA8aGFycnkucm9iZXJ0c0BtaWRuaWdodC1sYWJzLm9yZz4KLy8gQ29weXJpZ2h0IChDKSAyMDEwIENocmlzdGlhbiBGZXVlcnPkbmdlciA8Y2ZldWVyc2FlbmdlckBnb29nbGVtYWlsLmNvbT4KLy8gQ29weXJpZ2h0IChDKSAyMDEwLCAyMDE1LCAyMDE5IFdpbGxpYW0gQmFkZXIgPHdpbGxpYW1iYWRlckBob3RtYWlsLmNvbT4KLy8gQ29weXJpZ2h0IChDKSAyMDExLTIwMTMgVGhvbWFzIEZyZWl0YWcgPFRob21hcy5GcmVpdGFnQGFsZmEuZGU+Ci8vIENvcHlyaWdodCAoQykgMjAxMiBBbnRob255IFdlc2xleSA8YXdlc2xleUBzbWFydG5ldHdvcmtzLmNvbS5hdT4KLy8gQ29weXJpZ2h0IChDKSAyMDE1LCAyMDE4IEFkYW0gUmVpY2hvbGQgPGFkYW1yZWljaG9sZEBteW9wZXJhLmNvbT4KLy8gQ29weXJpZ2h0IChDKSAyMDE2IEtlbmppIFVubyA8a3VAZGlnaXRhbGRvbHBoaW5zLmpwPgovLyBDb3B5cmlnaHQgKEMpIDIwMTggTWFydGluIFBhY2ttYW4gPGd6bGlzdEBnb29nbGVtYWlsLmNvbT4KLy8gQ29weXJpZ2h0IChDKSAyMDE5IENocmlzdGlhbiBQZXJzY2ggPGNocGVAc3JjLmdub21lLm9yZz4KLy8gQ29weXJpZ2h0IChDKSAyMDE5IE9saXZlciBTYW5kZXIgPG9saXZlci5zYW5kZXJAdHUtZHJlc2Rlbi5kZT4KLy8KLy8gVG8gc2VlIGEgZGVzY3JpcHRpb24gb2YgdGhlIGNoYW5nZXMgcGxlYXNlIHNlZSB0aGUgQ2hhbmdlbG9nIGZpbGUgdGhhdAovLyBjYW1lIHdpdGggeW91ciB0YXJiYWxsIG9yIHR5cGUgbWFrZSBDaGFuZ2VMb2cgaWYgeW91IGFyZSBidWlsZGluZyBmcm9tIGdpdAovLwovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKI2luY2x1ZGUgPGNvbmZpZy5oPgoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8bGltaXRzLmg+CiNpbmNsdWRlICJnb28vZ2ZpbGUuaCIKI2luY2x1ZGUgImdvby9nbWVtLmgiCiNpbmNsdWRlICJTcGxhc2hFcnJvckNvZGVzLmgiCiNpbmNsdWRlICJTcGxhc2hCaXRtYXAuaCIKI2luY2x1ZGUgInBvcHBsZXIvRXJyb3IuaCIKI2luY2x1ZGUgImdvby9KcGVnV3JpdGVyLmgiCiNpbmNsdWRlICJnb28vUE5HV3JpdGVyLmgiCiNpbmNsdWRlICJnb28vVGlmZldyaXRlci5oIgojaW5jbHVkZSAiZ29vL0ltZ1dyaXRlci5oIgoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gU3BsYXNoQml0bWFwCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpTcGxhc2hCaXRtYXA6OlNwbGFzaEJpdG1hcChpbnQgd2lkdGhBLCBpbnQgaGVpZ2h0QSwgaW50IHJvd1BhZEEsCgkJCSAgIFNwbGFzaENvbG9yTW9kZSBtb2RlQSwgYm9vbCBhbHBoYUEsCgkJCSAgIGJvb2wgdG9wRG93biwgc3RkOjp2ZWN0b3I8R2Z4U2VwYXJhdGlvbkNvbG9yU3BhY2UqPiAqc2VwYXJhdGlvbkxpc3RBKSB7CiAgd2lkdGggPSB3aWR0aEE7CiAgaGVpZ2h0ID0gaGVpZ2h0QTsKICBtb2RlID0gbW9kZUE7CiAgcm93UGFkID0gcm93UGFkQTsKICBzd2l0Y2ggKG1vZGUpIHsKICBjYXNlIHNwbGFzaE1vZGVNb25vMToKICAgIGlmICh3aWR0aCA+IDApIHsKICAgICAgcm93U2l6ZSA9ICh3aWR0aCArIDcpID4+IDM7CiAgICB9IGVsc2UgewogICAgICByb3dTaXplID0gLTE7CiAgICB9CiAgICBicmVhazsKICBjYXNlIHNwbGFzaE1vZGVNb25vODoKICAgIGlmICh3aWR0aCA+IDApIHsKICAgICAgcm93U2l6ZSA9IHdpZHRoOwogICAgfSBlbHNlIHsKICAgICAgcm93U2l6ZSA9IC0xOwogICAgfQogICAgYnJlYWs7CiAgY2FzZSBzcGxhc2hNb2RlUkdCODoKICBjYXNlIHNwbGFzaE1vZGVCR1I4OgogICAgaWYgKHdpZHRoID4gMCAmJiB3aWR0aCA8PSBJTlRfTUFYIC8gMykgewogICAgICByb3dTaXplID0gd2lkdGggKiAzOwogICAgfSBlbHNlIHsKICAgICAgcm93U2l6ZSA9IC0xOwogICAgfQogICAgYnJlYWs7CiAgY2FzZSBzcGxhc2hNb2RlWEJHUjg6CiAgICBpZiAod2lkdGggPiAwICYmIHdpZHRoIDw9IElOVF9NQVggLyA0KSB7CiAgICAgIHJvd1NpemUgPSB3aWR0aCAqIDQ7CiAgICB9IGVsc2UgewogICAgICByb3dTaXplID0gLTE7CiAgICB9CiAgICBicmVhazsKI2lmZGVmIFNQTEFTSF9DTVlLCiAgY2FzZSBzcGxhc2hNb2RlQ01ZSzg6CiAgICBpZiAod2lkdGggPiAwICYmIHdpZHRoIDw9IElOVF9NQVggLyA0KSB7CiAgICAgIHJvd1NpemUgPSB3aWR0aCAqIDQ7CiAgICB9IGVsc2UgewogICAgICByb3dTaXplID0gLTE7CiAgICB9CiAgICBicmVhazsKICBjYXNlIHNwbGFzaE1vZGVEZXZpY2VOODoKICAgIGlmICh3aWR0aCA+IDAgJiYgd2lkdGggPD0gSU5UX01BWCAvIDQpIHsKICAgICAgcm93U2l6ZSA9IHdpZHRoICogKFNQT1RfTkNPTVBTICsgNCk7CiAgICB9IGVsc2UgewogICAgICByb3dTaXplID0gLTE7CiAgICB9CiAgICBicmVhazsKI2VuZGlmCiAgfQogIGlmIChyb3dTaXplID4gMCkgewogICAgcm93U2l6ZSArPSByb3dQYWQgLSAxOwogICAgcm93U2l6ZSAtPSByb3dTaXplICUgcm93UGFkOwogIH0KICBkYXRhID0gKFNwbGFzaENvbG9yUHRyKWdtYWxsb2NuX2NoZWNrb3ZlcmZsb3cocm93U2l6ZSwgaGVpZ2h0KTsKICBpZiAoZGF0YSAhPSBudWxscHRyKSB7CiAgICBpZiAoIXRvcERvd24pIHsKICAgICAgZGF0YSArPSAoaGVpZ2h0IC0gMSkgKiByb3dTaXplOwogICAgICByb3dTaXplID0gLXJvd1NpemU7CiAgICB9CiAgICBpZiAoYWxwaGFBKSB7CiAgICAgIGFscGhhID0gKHVuc2lnbmVkIGNoYXIgKilnbWFsbG9jbih3aWR0aCwgaGVpZ2h0KTsKICAgIH0gZWxzZSB7CiAgICAgIGFscGhhID0gbnVsbHB0cjsKICAgIH0KICB9IGVsc2UgewogICAgYWxwaGEgPSBudWxscHRyOwogIH0KICBzZXBhcmF0aW9uTGlzdCA9IG5ldyBzdGQ6OnZlY3RvcjxHZnhTZXBhcmF0aW9uQ29sb3JTcGFjZSo+KCk7CiAgaWYgKHNlcGFyYXRpb25MaXN0QSAhPSBudWxscHRyKQogICAgZm9yIChzdGQ6OnNpemVfdCBpID0gMDsgaSA8IHNlcGFyYXRpb25MaXN0QS0+c2l6ZSgpOyBpKyspCiAgICAgIHNlcGFyYXRpb25MaXN0LT5wdXNoX2JhY2soKEdmeFNlcGFyYXRpb25Db2xvclNwYWNlKikoICgqc2VwYXJhdGlvbkxpc3RBKVtpXSktPmNvcHkoKSk7Cn0KClNwbGFzaEJpdG1hcCAqU3BsYXNoQml0bWFwOjpjb3B5KFNwbGFzaEJpdG1hcCAqc3JjKSB7CiAgU3BsYXNoQml0bWFwICpyZXN1bHQgPSBuZXcgU3BsYXNoQml0bWFwKHNyYy0+Z2V0V2lkdGgoKSwgc3JjLT5nZXRIZWlnaHQoKSwgc3JjLT5nZXRSb3dQYWQoKSwgCiAgICBzcmMtPmdldE1vZGUoKSwgc3JjLT5nZXRBbHBoYVB0cigpICE9IG51bGxwdHIsIHNyYy0+Z2V0Um93U2l6ZSgpID49IDAsIHNyYy0+Z2V0U2VwYXJhdGlvbkxpc3QoKSk7CiAgdW5zaWduZWQgY2hhciAqZGF0YVNvdXJjZSA9IHNyYy0+Z2V0RGF0YVB0cigpOwogIHVuc2lnbmVkIGNoYXIgKmRhdGFEZXN0ID0gcmVzdWx0LT5nZXREYXRhUHRyKCk7CiAgaW50IGFtb3VudCA9IHNyYy0+Z2V0Um93U2l6ZSgpOwogIGlmIChhbW91bnQgPCAwKSB7CiAgICBkYXRhU291cmNlID0gZGF0YVNvdXJjZSArIChzcmMtPmdldEhlaWdodCgpIC0gMSkgKiBhbW91bnQ7CiAgICBkYXRhRGVzdCA9IGRhdGFEZXN0ICsgKHNyYy0+Z2V0SGVpZ2h0KCkgLSAxKSAqIGFtb3VudDsKICAgIGFtb3VudCAqPSAtc3JjLT5nZXRIZWlnaHQoKTsKICB9IGVsc2UgewogICAgYW1vdW50ICo9IHNyYy0+Z2V0SGVpZ2h0KCk7CiAgfQogIG1lbWNweShkYXRhRGVzdCwgZGF0YVNvdXJjZSwgYW1vdW50KTsKICBpZiAoc3JjLT5nZXRBbHBoYVB0cigpICE9IG51bGxwdHIpIHsKICAgIG1lbWNweShyZXN1bHQtPmdldEFscGhhUHRyKCksIHNyYy0+Z2V0QWxwaGFQdHIoKSwgc3JjLT5nZXRXaWR0aCgpICogc3JjLT5nZXRIZWlnaHQoKSk7CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KClNwbGFzaEJpdG1hcDo6flNwbGFzaEJpdG1hcCgpIHsKICBpZiAoZGF0YSkgewogICAgaWYgKHJvd1NpemUgPCAwKSB7CiAgICAgIGdmcmVlKGRhdGEgKyAoaGVpZ2h0IC0gMSkgKiByb3dTaXplKTsKICAgIH0gZWxzZSB7CiAgICAgIGdmcmVlKGRhdGEpOwogICAgfQogIH0KICBnZnJlZShhbHBoYSk7CiAgZm9yIChhdXRvIGVudHJ5IDogKnNlcGFyYXRpb25MaXN0KSB7CiAgICBkZWxldGUgZW50cnk7CiAgfQogIGRlbGV0ZSBzZXBhcmF0aW9uTGlzdDsKfQoKClNwbGFzaEVycm9yIFNwbGFzaEJpdG1hcDo6d3JpdGVQTk1GaWxlKGNoYXIgKmZpbGVOYW1lKSB7CiAgRklMRSAqZjsKICBTcGxhc2hFcnJvciBlOwoKICBpZiAoIShmID0gb3BlbkZpbGUoZmlsZU5hbWUsICJ3YiIpKSkgewogICAgcmV0dXJuIHNwbGFzaEVyck9wZW5GaWxlOwogIH0KCiAgZSA9IHRoaXMtPndyaXRlUE5NRmlsZShmKTsKICAKICBmY2xvc2UoZik7CiAgcmV0dXJuIGU7Cn0KCgpTcGxhc2hFcnJvciBTcGxhc2hCaXRtYXA6OndyaXRlUE5NRmlsZShGSUxFICpmKSB7CiAgU3BsYXNoQ29sb3JQdHIgcm93LCBwOwogIGludCB4LCB5OwoKICBzd2l0Y2ggKG1vZGUpIHsKCiAgY2FzZSBzcGxhc2hNb2RlTW9ubzE6CiAgICBmcHJpbnRmKGYsICJQNFxuJWQgJWRcbiIsIHdpZHRoLCBoZWlnaHQpOwogICAgcm93ID0gZGF0YTsKICAgIGZvciAoeSA9IDA7IHkgPCBoZWlnaHQ7ICsreSkgewogICAgICBwID0gcm93OwogICAgICBmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHggKz0gOCkgewoJZnB1dGMoKnAgXiAweGZmLCBmKTsKCSsrcDsKICAgICAgfQogICAgICByb3cgKz0gcm93U2l6ZTsKICAgIH0KICAgIGJyZWFrOwoKICBjYXNlIHNwbGFzaE1vZGVNb25vODoKICAgIGZwcmludGYoZiwgIlA1XG4lZCAlZFxuMjU1XG4iLCB3aWR0aCwgaGVpZ2h0KTsKICAgIHJvdyA9IGRhdGE7CiAgICBmb3IgKHkgPSAwOyB5IDwgaGVpZ2h0OyArK3kpIHsKICAgICAgZndyaXRlKHJvdywgMSwgd2lkdGgsIGYpOwogICAgICByb3cgKz0gcm93U2l6ZTsKICAgIH0KICAgIGJyZWFrOwoKICBjYXNlIHNwbGFzaE1vZGVSR0I4OgogICAgZnByaW50ZihmLCAiUDZcbiVkICVkXG4yNTVcbiIsIHdpZHRoLCBoZWlnaHQpOwogICAgcm93ID0gZGF0YTsKICAgIGZvciAoeSA9IDA7IHkgPCBoZWlnaHQ7ICsreSkgewogICAgICBmd3JpdGUocm93LCAxLCAzICogd2lkdGgsIGYpOwogICAgICByb3cgKz0gcm93U2l6ZTsKICAgIH0KICAgIGJyZWFrOwoKICBjYXNlIHNwbGFzaE1vZGVYQkdSODoKICAgIGZwcmludGYoZiwgIlA2XG4lZCAlZFxuMjU1XG4iLCB3aWR0aCwgaGVpZ2h0KTsKICAgIHJvdyA9IGRhdGE7CiAgICBmb3IgKHkgPSAwOyB5IDwgaGVpZ2h0OyArK3kpIHsKICAgICAgcCA9IHJvdzsKICAgICAgZm9yICh4ID0gMDsgeCA8IHdpZHRoOyArK3gpIHsKCWZwdXRjKHNwbGFzaEJHUjhSKHApLCBmKTsKCWZwdXRjKHNwbGFzaEJHUjhHKHApLCBmKTsKCWZwdXRjKHNwbGFzaEJHUjhCKHApLCBmKTsKCXAgKz0gNDsKICAgICAgfQogICAgICByb3cgKz0gcm93U2l6ZTsKICAgIH0KICAgIGJyZWFrOwoKCiAgY2FzZSBzcGxhc2hNb2RlQkdSODoKICAgIGZwcmludGYoZiwgIlA2XG4lZCAlZFxuMjU1XG4iLCB3aWR0aCwgaGVpZ2h0KTsKICAgIHJvdyA9IGRhdGE7CiAgICBmb3IgKHkgPSAwOyB5IDwgaGVpZ2h0OyArK3kpIHsKICAgICAgcCA9IHJvdzsKICAgICAgZm9yICh4ID0gMDsgeCA8IHdpZHRoOyArK3gpIHsKCWZwdXRjKHNwbGFzaEJHUjhSKHApLCBmKTsKCWZwdXRjKHNwbGFzaEJHUjhHKHApLCBmKTsKCWZwdXRjKHNwbGFzaEJHUjhCKHApLCBmKTsKCXAgKz0gMzsKICAgICAgfQogICAgICByb3cgKz0gcm93U2l6ZTsKICAgIH0KICAgIGJyZWFrOwoKI2lmZGVmIFNQTEFTSF9DTVlLCiAgY2FzZSBzcGxhc2hNb2RlQ01ZSzg6CiAgY2FzZSBzcGxhc2hNb2RlRGV2aWNlTjg6CiAgICAvLyBQTk0gZG9lc24ndCBzdXBwb3J0IENNWUsKICAgIGVycm9yKGVyckludGVybmFsLCAtMSwgInVuc3VwcG9ydGVkIFNwbGFzaEJpdG1hcCBtb2RlIik7CiAgICByZXR1cm4gc3BsYXNoRXJyR2VuZXJpYzsKICAgIGJyZWFrOwojZW5kaWYKICB9CiAgcmV0dXJuIHNwbGFzaE9rOwp9CgpTcGxhc2hFcnJvciBTcGxhc2hCaXRtYXA6OndyaXRlQWxwaGFQR01GaWxlKGNoYXIgKmZpbGVOYW1lKSB7CiAgRklMRSAqZjsKCiAgaWYgKCFhbHBoYSkgewogICAgcmV0dXJuIHNwbGFzaEVyck1vZGVNaXNtYXRjaDsKICB9CiAgaWYgKCEoZiA9IG9wZW5GaWxlKGZpbGVOYW1lLCAid2IiKSkpIHsKICAgIHJldHVybiBzcGxhc2hFcnJPcGVuRmlsZTsKICB9CiAgZnByaW50ZihmLCAiUDVcbiVkICVkXG4yNTVcbiIsIHdpZHRoLCBoZWlnaHQpOwogIGZ3cml0ZShhbHBoYSwgMSwgd2lkdGggKiBoZWlnaHQsIGYpOwogIGZjbG9zZShmKTsKICByZXR1cm4gc3BsYXNoT2s7Cn0KCnZvaWQgU3BsYXNoQml0bWFwOjpnZXRQaXhlbChpbnQgeCwgaW50IHksIFNwbGFzaENvbG9yUHRyIHBpeGVsKSB7CiAgU3BsYXNoQ29sb3JQdHIgcDsKCiAgaWYgKHkgPCAwIHx8IHkgPj0gaGVpZ2h0IHx8IHggPCAwIHx8IHggPj0gd2lkdGggfHwgIWRhdGEpIHsKICAgIHJldHVybjsKICB9CiAgc3dpdGNoIChtb2RlKSB7CiAgY2FzZSBzcGxhc2hNb2RlTW9ubzE6CiAgICBwID0gJmRhdGFbeSAqIHJvd1NpemUgKyAoeCA+PiAzKV07CiAgICBwaXhlbFswXSA9IChwWzBdICYgKDB4ODAgPj4gKHggJiA3KSkpID8gMHhmZiA6IDB4MDA7CiAgICBicmVhazsKICBjYXNlIHNwbGFzaE1vZGVNb25vODoKICAgIHAgPSAmZGF0YVt5ICogcm93U2l6ZSArIHhdOwogICAgcGl4ZWxbMF0gPSBwWzBdOwogICAgYnJlYWs7CiAgY2FzZSBzcGxhc2hNb2RlUkdCODoKICAgIHAgPSAmZGF0YVt5ICogcm93U2l6ZSArIDMgKiB4XTsKICAgIHBpeGVsWzBdID0gcFswXTsKICAgIHBpeGVsWzFdID0gcFsxXTsKICAgIHBpeGVsWzJdID0gcFsyXTsKICAgIGJyZWFrOwogIGNhc2Ugc3BsYXNoTW9kZVhCR1I4OgogICAgcCA9ICZkYXRhW3kgKiByb3dTaXplICsgNCAqIHhdOwogICAgcGl4ZWxbMF0gPSBwWzJdOwogICAgcGl4ZWxbMV0gPSBwWzFdOwogICAgcGl4ZWxbMl0gPSBwWzBdOwogICAgcGl4ZWxbM10gPSBwWzNdOwogICAgYnJlYWs7CiAgY2FzZSBzcGxhc2hNb2RlQkdSODoKICAgIHAgPSAmZGF0YVt5ICogcm93U2l6ZSArIDMgKiB4XTsKICAgIHBpeGVsWzBdID0gcFsyXTsKICAgIHBpeGVsWzFdID0gcFsxXTsKICAgIHBpeGVsWzJdID0gcFswXTsKICAgIGJyZWFrOwojaWZkZWYgU1BMQVNIX0NNWUsKICBjYXNlIHNwbGFzaE1vZGVDTVlLODoKICAgIHAgPSAmZGF0YVt5ICogcm93U2l6ZSArIDQgKiB4XTsKICAgIHBpeGVsWzBdID0gcFswXTsKICAgIHBpeGVsWzFdID0gcFsxXTsKICAgIHBpeGVsWzJdID0gcFsyXTsKICAgIHBpeGVsWzNdID0gcFszXTsKICAgIGJyZWFrOwogIGNhc2Ugc3BsYXNoTW9kZURldmljZU44OgogICAgcCA9ICZkYXRhW3kgKiByb3dTaXplICsgKFNQT1RfTkNPTVBTICsgNCkgKiB4XTsKICAgIGZvciAoaW50IGNwID0gMDsgY3AgPCBTUE9UX05DT01QUyArIDQ7IGNwKyspCiAgICAgIHBpeGVsW2NwXSA9IHBbY3BdOwogICAgYnJlYWs7CiNlbmRpZgogIH0KfQoKdW5zaWduZWQgY2hhciBTcGxhc2hCaXRtYXA6OmdldEFscGhhKGludCB4LCBpbnQgeSkgewogIHJldHVybiBhbHBoYVt5ICogd2lkdGggKyB4XTsKfQoKU3BsYXNoQ29sb3JQdHIgU3BsYXNoQml0bWFwOjp0YWtlRGF0YSgpIHsKICBTcGxhc2hDb2xvclB0ciBkYXRhMjsKCiAgZGF0YTIgPSBkYXRhOwogIGRhdGEgPSBudWxscHRyOwogIHJldHVybiBkYXRhMjsKfQoKU3BsYXNoRXJyb3IgU3BsYXNoQml0bWFwOjp3cml0ZUltZ0ZpbGUoU3BsYXNoSW1hZ2VGaWxlRm9ybWF0IGZvcm1hdCwgY29uc3QgY2hhciAqZmlsZU5hbWUsIGludCBoRFBJLCBpbnQgdkRQSSwgV3JpdGVJbWdQYXJhbXMqIHBhcmFtcykgewogIEZJTEUgKmY7CiAgU3BsYXNoRXJyb3IgZTsKCiAgaWYgKCEoZiA9IG9wZW5GaWxlKGZpbGVOYW1lLCAid2IiKSkpIHsKICAgIHJldHVybiBzcGxhc2hFcnJPcGVuRmlsZTsKICB9CgogIGUgPSB3cml0ZUltZ0ZpbGUoZm9ybWF0LCBmLCBoRFBJLCB2RFBJLCBwYXJhbXMpOwoKICBmY2xvc2UoZik7CiAgcmV0dXJuIGU7Cn0KCnZvaWQgU3BsYXNoQml0bWFwOjpzZXRKcGVnUGFyYW1zKEltZ1dyaXRlciAqd3JpdGVyLCBXcml0ZUltZ1BhcmFtcyogcGFyYW1zKQp7CiNpZmRlZiBFTkFCTEVfTElCSlBFRwogIGlmIChwYXJhbXMpIHsKICAgIHN0YXRpY19jYXN0PEpwZWdXcml0ZXIqPih3cml0ZXIpLT5zZXRQcm9ncmVzc2l2ZShwYXJhbXMtPmpwZWdQcm9ncmVzc2l2ZSk7CiAgICBzdGF0aWNfY2FzdDxKcGVnV3JpdGVyKj4od3JpdGVyKS0+c2V0T3B0aW1pemUocGFyYW1zLT5qcGVnT3B0aW1pemUpOwogICAgaWYgKHBhcmFtcy0+anBlZ1F1YWxpdHkgPj0gMCkKICAgICAgc3RhdGljX2Nhc3Q8SnBlZ1dyaXRlcio+KHdyaXRlciktPnNldFF1YWxpdHkocGFyYW1zLT5qcGVnUXVhbGl0eSk7CiAgfQojZW5kaWYKfQoKU3BsYXNoRXJyb3IgU3BsYXNoQml0bWFwOjp3cml0ZUltZ0ZpbGUoU3BsYXNoSW1hZ2VGaWxlRm9ybWF0IGZvcm1hdCwgRklMRSAqZiwgaW50IGhEUEksIGludCB2RFBJLCBXcml0ZUltZ1BhcmFtcyogcGFyYW1zKSB7CiAgSW1nV3JpdGVyICp3cml0ZXI7CglTcGxhc2hFcnJvciBlOwogIAogIFNwbGFzaENvbG9yTW9kZSBpbWFnZVdyaXRlckZvcm1hdCA9IHNwbGFzaE1vZGVSR0I4OwoKICBzd2l0Y2ggKGZvcm1hdCkgewogICAgI2lmZGVmIEVOQUJMRV9MSUJQTkcKICAgIGNhc2Ugc3BsYXNoRm9ybWF0UG5nOgoJICB3cml0ZXIgPSBuZXcgUE5HV3JpdGVyKCk7CiAgICAgIGJyZWFrOwogICAgI2VuZGlmCgogICAgI2lmZGVmIEVOQUJMRV9MSUJKUEVHCiAgICAjaWZkZWYgU1BMQVNIX0NNWUsKICAgIGNhc2Ugc3BsYXNoRm9ybWF0SnBlZ0NNWUs6CiAgICAgIHdyaXRlciA9IG5ldyBKcGVnV3JpdGVyKEpwZWdXcml0ZXI6OkNNWUspOwogICAgICBzZXRKcGVnUGFyYW1zKHdyaXRlciwgcGFyYW1zKTsKICAgICAgYnJlYWs7CiAgICAjZW5kaWYKICAgIGNhc2Ugc3BsYXNoRm9ybWF0SnBlZzoKICAgICAgd3JpdGVyID0gbmV3IEpwZWdXcml0ZXIoKTsKICAgICAgc2V0SnBlZ1BhcmFtcyh3cml0ZXIsIHBhcmFtcyk7CiAgICAgIGJyZWFrOwogICAgI2VuZGlmCgkKICAgICNpZmRlZiBFTkFCTEVfTElCVElGRgogICAgY2FzZSBzcGxhc2hGb3JtYXRUaWZmOgogICAgICBzd2l0Y2ggKG1vZGUpIHsKICAgICAgY2FzZSBzcGxhc2hNb2RlTW9ubzE6CiAgICAgICAgd3JpdGVyID0gbmV3IFRpZmZXcml0ZXIoVGlmZldyaXRlcjo6TU9OT0NIUk9NRSk7CiAgICAgICAgaW1hZ2VXcml0ZXJGb3JtYXQgPSBzcGxhc2hNb2RlTW9ubzE7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2Ugc3BsYXNoTW9kZU1vbm84OgogICAgICAgIHdyaXRlciA9IG5ldyBUaWZmV3JpdGVyKFRpZmZXcml0ZXI6OkdSQVkpOwogICAgICAgIGltYWdlV3JpdGVyRm9ybWF0ID0gc3BsYXNoTW9kZU1vbm84OwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIHNwbGFzaE1vZGVSR0I4OgogICAgICBjYXNlIHNwbGFzaE1vZGVCR1I4OgogICAgICAgIHdyaXRlciA9IG5ldyBUaWZmV3JpdGVyKFRpZmZXcml0ZXI6OlJHQik7CiAgICAgICAgYnJlYWs7CiNpZmRlZiBTUExBU0hfQ01ZSwogICAgICBjYXNlIHNwbGFzaE1vZGVDTVlLODoKICAgICAgY2FzZSBzcGxhc2hNb2RlRGV2aWNlTjg6CiAgICAgICAgd3JpdGVyID0gbmV3IFRpZmZXcml0ZXIoVGlmZldyaXRlcjo6Q01ZSyk7CiAgICAgICAgYnJlYWs7CiNlbmRpZgogICAgICBkZWZhdWx0OgogICAgICAgIGZwcmludGYoc3RkZXJyLCAiVGlmZldyaXRlcjogTW9kZSAlZCBub3Qgc3VwcG9ydGVkXG4iLCBtb2RlKTsKICAgICAgICB3cml0ZXIgPSBuZXcgVGlmZldyaXRlcigpOwogICAgICB9CiAgICAgIGlmICh3cml0ZXIgJiYgcGFyYW1zKSB7CiAgICAgICAgKChUaWZmV3JpdGVyICopd3JpdGVyKS0+c2V0Q29tcHJlc3Npb25TdHJpbmcocGFyYW1zLT50aWZmQ29tcHJlc3Npb24uY19zdHIoKSk7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICAjZW5kaWYKCiAgICBkZWZhdWx0OgogICAgICAvLyBOb3QgdGhlIGdyZWF0ZXN0IGVycm9yIG1lc3NhZ2UsIGJ1dCB1c2VycyBvZiB0aGlzIGZ1bmN0aW9uIHNob3VsZAogICAgICAvLyBoYXZlIGFscmVhZHkgY2hlY2tlZCB3aGV0aGVyIHRoZWlyIGRlc2lyZWQgZm9ybWF0IGlzIGNvbXBpbGVkIGluLgogICAgICBlcnJvcihlcnJJbnRlcm5hbCwgLTEsICJTdXBwb3J0IGZvciB0aGlzIGltYWdlIHR5cGUgbm90IGNvbXBpbGVkIGluIik7CiAgICAgIHJldHVybiBzcGxhc2hFcnJHZW5lcmljOwogIH0KCgllID0gd3JpdGVJbWdGaWxlKHdyaXRlciwgZiwgaERQSSwgdkRQSSwgaW1hZ2VXcml0ZXJGb3JtYXQpOwoJZGVsZXRlIHdyaXRlcjsKCXJldHVybiBlOwp9CgojaW5jbHVkZSAicG9wcGxlci9HZnhTdGF0ZV9oZWxwZXJzLmgiCgp2b2lkIFNwbGFzaEJpdG1hcDo6Z2V0UkdCTGluZShpbnQgeWwsIFNwbGFzaENvbG9yUHRyIGxpbmUpIHsKICBTcGxhc2hDb2xvciBjb2w7CiAgZG91YmxlIGMsIG0sIHksIGssIGMxLCBtMSwgeTEsIGsxLCByLCBnLCBiOwoKICBmb3IgKGludCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKICAgIGdldFBpeGVsKHgsIHlsLCBjb2wpOwogICAgYyA9IGJ5dGVUb0RibChjb2xbMF0pOwogICAgbSA9IGJ5dGVUb0RibChjb2xbMV0pOwogICAgeSA9IGJ5dGVUb0RibChjb2xbMl0pOwogICAgayA9IGJ5dGVUb0RibChjb2xbM10pOwojaWZkZWYgU1BMQVNIX0NNWUsKICAgIGlmIChzZXBhcmF0aW9uTGlzdC0+c2l6ZSgpID4gMCkgewogICAgICBmb3IgKHN0ZDo6c2l6ZV90IGkgPSAwOyBpIDwgc2VwYXJhdGlvbkxpc3QtPnNpemUoKTsgaSsrKSB7CiAgICAgICAgaWYgKGNvbFtpKzRdID4gMCkgewogICAgICAgICAgR2Z4Q01ZSyBjbXlrOwogICAgICAgICAgR2Z4Q29sb3IgaW5wdXQ7CiAgICAgICAgICBpbnB1dC5jWzBdID0gYnl0ZVRvQ29sKGNvbFtpKzRdKTsKICAgICAgICAgIEdmeFNlcGFyYXRpb25Db2xvclNwYWNlICpzZXBDUyA9IChHZnhTZXBhcmF0aW9uQ29sb3JTcGFjZSAqKSgoKnNlcGFyYXRpb25MaXN0KVtpXSk7CiAgICAgICAgICBzZXBDUy0+Z2V0Q01ZSygmaW5wdXQsICZjbXlrKTsKICAgICAgICAgIGNvbFswXSA9IGNvbFRvQnl0ZShjbXlrLmMpOwogICAgICAgICAgY29sWzFdID0gY29sVG9CeXRlKGNteWsubSk7CiAgICAgICAgICBjb2xbMl0gPSBjb2xUb0J5dGUoY215ay55KTsKICAgICAgICAgIGNvbFszXSA9IGNvbFRvQnl0ZShjbXlrLmspOwogICAgICAgICAgYyArPSBieXRlVG9EYmwoY29sWzBdKTsKICAgICAgICAgIG0gKz0gYnl0ZVRvRGJsKGNvbFsxXSk7CiAgICAgICAgICB5ICs9IGJ5dGVUb0RibChjb2xbMl0pOwogICAgICAgICAgayArPSBieXRlVG9EYmwoY29sWzNdKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGMgPiAxKSBjID0gMTsKICAgICAgaWYgKG0gPiAxKSBtID0gMTsKICAgICAgaWYgKHkgPiAxKSB5ID0gMTsKICAgICAgaWYgKGsgPiAxKSBrID0gMTsKICAgIH0KI2VuZGlmCiAgICBjMSA9IDEgLSBjOwogICAgbTEgPSAxIC0gbTsKICAgIHkxID0gMSAtIHk7CiAgICBrMSA9IDEgLSBrOwogICAgY215a1RvUkdCTWF0cml4TXVsdGlwbGljYXRpb24oYywgbSwgeSwgaywgYzEsIG0xLCB5MSwgazEsIHIsIGcsIGIpOwogICAgKmxpbmUrKyA9IGRibFRvQnl0ZShjbGlwMDEocikpOwogICAgKmxpbmUrKyA9IGRibFRvQnl0ZShjbGlwMDEoZykpOwogICAgKmxpbmUrKyA9IGRibFRvQnl0ZShjbGlwMDEoYikpOwogIH0KfQoKdm9pZCBTcGxhc2hCaXRtYXA6OmdldFhCR1JMaW5lKGludCB5bCwgU3BsYXNoQ29sb3JQdHIgbGluZSwgQ29udmVyc2lvbk1vZGUgY29udmVyc2lvbk1vZGUpIHsKICBTcGxhc2hDb2xvciBjb2w7CiAgZG91YmxlIGMsIG0sIHksIGssIGMxLCBtMSwgeTEsIGsxLCByLCBnLCBiOwoKICBmb3IgKGludCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKICAgIGdldFBpeGVsKHgsIHlsLCBjb2wpOwogICAgYyA9IGJ5dGVUb0RibChjb2xbMF0pOwogICAgbSA9IGJ5dGVUb0RibChjb2xbMV0pOwogICAgeSA9IGJ5dGVUb0RibChjb2xbMl0pOwogICAgayA9IGJ5dGVUb0RibChjb2xbM10pOwojaWZkZWYgU1BMQVNIX0NNWUsKICAgIGlmIChzZXBhcmF0aW9uTGlzdC0+c2l6ZSgpID4gMCkgewogICAgICBmb3IgKHN0ZDo6c2l6ZV90IGkgPSAwOyBpIDwgc2VwYXJhdGlvbkxpc3QtPnNpemUoKTsgaSsrKSB7CiAgICAgICAgaWYgKGNvbFtpKzRdID4gMCkgewogICAgICAgICAgR2Z4Q01ZSyBjbXlrOwogICAgICAgICAgR2Z4Q29sb3IgaW5wdXQ7CiAgICAgICAgICBpbnB1dC5jWzBdID0gYnl0ZVRvQ29sKGNvbFtpKzRdKTsKICAgICAgICAgIEdmeFNlcGFyYXRpb25Db2xvclNwYWNlICpzZXBDUyA9IChHZnhTZXBhcmF0aW9uQ29sb3JTcGFjZSAqKSgoKnNlcGFyYXRpb25MaXN0KVtpXSk7CiAgICAgICAgICBzZXBDUy0+Z2V0Q01ZSygmaW5wdXQsICZjbXlrKTsKICAgICAgICAgIGNvbFswXSA9IGNvbFRvQnl0ZShjbXlrLmMpOwogICAgICAgICAgY29sWzFdID0gY29sVG9CeXRlKGNteWsubSk7CiAgICAgICAgICBjb2xbMl0gPSBjb2xUb0J5dGUoY215ay55KTsKICAgICAgICAgIGNvbFszXSA9IGNvbFRvQnl0ZShjbXlrLmspOwogICAgICAgICAgYyArPSBieXRlVG9EYmwoY29sWzBdKTsKICAgICAgICAgIG0gKz0gYnl0ZVRvRGJsKGNvbFsxXSk7CiAgICAgICAgICB5ICs9IGJ5dGVUb0RibChjb2xbMl0pOwogICAgICAgICAgayArPSBieXRlVG9EYmwoY29sWzNdKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGMgPiAxKSBjID0gMTsKICAgICAgaWYgKG0gPiAxKSBtID0gMTsKICAgICAgaWYgKHkgPiAxKSB5ID0gMTsKICAgICAgaWYgKGsgPiAxKSBrID0gMTsKICAgIH0KI2VuZGlmCiAgICBjMSA9IDEgLSBjOwogICAgbTEgPSAxIC0gbTsKICAgIHkxID0gMSAtIHk7CiAgICBrMSA9IDEgLSBrOwogICAgY215a1RvUkdCTWF0cml4TXVsdGlwbGljYXRpb24oYywgbSwgeSwgaywgYzEsIG0xLCB5MSwgazEsIHIsIGcsIGIpOwoKICAgIGlmIChjb252ZXJzaW9uTW9kZSA9PSBjb252ZXJzaW9uQWxwaGFQcmVtdWx0aXBsaWVkKSB7CiAgICAgICAgY29uc3QgZG91YmxlIGEgPSBnZXRBbHBoYSh4LCB5bCkgLyAyNTUuMDsKCiAgICAgICAgKmxpbmUrKyA9IGRibFRvQnl0ZShjbGlwMDEoYiAqIGEpKTsKICAgICAgICAqbGluZSsrID0gZGJsVG9CeXRlKGNsaXAwMShnICogYSkpOwogICAgICAgICpsaW5lKysgPSBkYmxUb0J5dGUoY2xpcDAxKHIgKiBhKSk7CiAgICB9IGVsc2UgewogICAgICAgICpsaW5lKysgPSBkYmxUb0J5dGUoY2xpcDAxKGIpKTsKICAgICAgICAqbGluZSsrID0gZGJsVG9CeXRlKGNsaXAwMShnKSk7CiAgICAgICAgKmxpbmUrKyA9IGRibFRvQnl0ZShjbGlwMDEocikpOwogICAgfQoKICAgIGlmIChjb252ZXJzaW9uTW9kZSAhPSBjb252ZXJzaW9uT3BhcXVlKSB7CiAgICAgICAgKmxpbmUrKyA9IGdldEFscGhhKHgsIHlsKTsKICAgIH0gZWxzZSB7CiAgICAgICAgKmxpbmUrKyA9IDI1NTsKICAgIH0KICB9Cn0KCnN0YXRpYyBpbmxpbmUgdW5zaWduZWQgY2hhciBkaXYyNTUoaW50IHgpIHsKICByZXR1cm4gKHVuc2lnbmVkIGNoYXIpKCh4ICsgKHggPj4gOCkgKyAweDgwKSA+PiA4KTsKfQoKYm9vbCBTcGxhc2hCaXRtYXA6OmNvbnZlcnRUb1hCR1IoQ29udmVyc2lvbk1vZGUgY29udmVyc2lvbk1vZGUpIHsKICBpZiAobW9kZSA9PSBzcGxhc2hNb2RlWEJHUjgpIHsKICAgIGlmIChjb252ZXJzaW9uTW9kZSAhPSBjb252ZXJzaW9uT3BhcXVlKSB7CiAgICAgIC8vIENvcHkgdGhlIGFscGhhIGNoYW5uZWwgaW50byB0aGUgZm91cnRoIGNvbXBvbmVudCBzbyB0aGF0IFhCR1IgYmVjb21lcyBBQkdSLgogICAgICBjb25zdCBTcGxhc2hDb2xvclB0ciBkYmVnaW4gPSBkYXRhOwogICAgICBjb25zdCBTcGxhc2hDb2xvclB0ciBkZW5kID0gZGF0YSArIHJvd1NpemUgKiBoZWlnaHQ7CgogICAgICB1bnNpZ25lZCBjaGFyICpjb25zdCBhYmVnaW4gPSBhbHBoYTsKICAgICAgdW5zaWduZWQgY2hhciAqY29uc3QgYWVuZCA9IGFscGhhICsgd2lkdGggKiBoZWlnaHQ7CgogICAgICBTcGxhc2hDb2xvclB0ciBkID0gZGJlZ2luOwogICAgICB1bnNpZ25lZCBjaGFyICphID0gYWJlZ2luOwoKICAgICAgaWYgKGNvbnZlcnNpb25Nb2RlID09IGNvbnZlcnNpb25BbHBoYVByZW11bHRpcGxpZWQpIHsKICAgICAgICAgIGZvciAoOyBkIDwgZGVuZCAmJiBhIDwgYWVuZDsgZCArPSA0LCBhICs9IDEpIHsKICAgICAgICAgICAgICBkWzBdID0gZGl2MjU1KGRbMF0gKiAqYSk7CiAgICAgICAgICAgICAgZFsxXSA9IGRpdjI1NShkWzFdICogKmEpOwogICAgICAgICAgICAgIGRbMl0gPSBkaXYyNTUoZFsyXSAqICphKTsKICAgICAgICAgICAgICBkWzNdID0gKmE7CiAgICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmb3IgKGQgKz0gMzsgZCA8IGRlbmQgJiYgYSA8IGFlbmQ7IGQgKz0gNCwgYSArPSAxKSB7CiAgICAgICAgICAgICAgKmQgPSAqYTsKICAgICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIHJldHVybiB0cnVlOwogIH0KICAKICBpbnQgbmV3cm93U2l6ZSA9IHdpZHRoICogNDsKICBTcGxhc2hDb2xvclB0ciBuZXdkYXRhID0gKFNwbGFzaENvbG9yUHRyKWdtYWxsb2NuX2NoZWNrb3ZlcmZsb3cobmV3cm93U2l6ZSwgaGVpZ2h0KTsKICBpZiAobmV3ZGF0YSAhPSBudWxscHRyKSB7CiAgICBmb3IgKGludCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CiAgICAgIHVuc2lnbmVkIGNoYXIgKnJvdyA9IG5ld2RhdGEgKyB5ICogbmV3cm93U2l6ZTsKICAgICAgZ2V0WEJHUkxpbmUoeSwgcm93LCBjb252ZXJzaW9uTW9kZSk7CiAgICB9CiAgICBpZiAocm93U2l6ZSA8IDApIHsKICAgICAgZ2ZyZWUoZGF0YSArIChoZWlnaHQgLSAxKSAqIHJvd1NpemUpOwogICAgfSBlbHNlIHsKICAgICAgZ2ZyZWUoZGF0YSk7CiAgICB9CiAgICBkYXRhID0gbmV3ZGF0YTsKICAgIHJvd1NpemUgPSBuZXdyb3dTaXplOwogICAgbW9kZSA9IHNwbGFzaE1vZGVYQkdSODsKICB9CiAgcmV0dXJuIG5ld2RhdGEgIT0gbnVsbHB0cjsKfQoKI2lmZGVmIFNQTEFTSF9DTVlLCnZvaWQgU3BsYXNoQml0bWFwOjpnZXRDTVlLTGluZShpbnQgeWwsIFNwbGFzaENvbG9yUHRyIGxpbmUpIHsKICBTcGxhc2hDb2xvciBjb2w7CgogIGZvciAoaW50IHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewogICAgZ2V0UGl4ZWwoeCwgeWwsIGNvbCk7CiAgICBpZiAoc2VwYXJhdGlvbkxpc3QtPnNpemUoKSA+IDApIHsKICAgICAgZG91YmxlIGMsIG0sIHksIGs7CiAgICAgIGMgPSBieXRlVG9EYmwoY29sWzBdKTsKICAgICAgbSA9IGJ5dGVUb0RibChjb2xbMV0pOwogICAgICB5ID0gYnl0ZVRvRGJsKGNvbFsyXSk7CiAgICAgIGsgPSBieXRlVG9EYmwoY29sWzNdKTsKICAgICAgZm9yIChzdGQ6OnNpemVfdCBpID0gMDsgaSA8IHNlcGFyYXRpb25MaXN0LT5zaXplKCk7IGkrKykgewogICAgICAgIGlmIChjb2xbaSs0XSA+IDApIHsKICAgICAgICAgIEdmeENNWUsgY215azsKICAgICAgICAgIEdmeENvbG9yIGlucHV0OwogICAgICAgICAgaW5wdXQuY1swXSA9IGJ5dGVUb0NvbChjb2xbaSs0XSk7CiAgICAgICAgICBHZnhTZXBhcmF0aW9uQ29sb3JTcGFjZSAqc2VwQ1MgPSAoR2Z4U2VwYXJhdGlvbkNvbG9yU3BhY2UgKikoKCpzZXBhcmF0aW9uTGlzdClbaV0pOwogICAgICAgICAgc2VwQ1MtPmdldENNWUsoJmlucHV0LCAmY215ayk7CiAgICAgICAgICBjb2xbMF0gPSBjb2xUb0J5dGUoY215ay5jKTsKICAgICAgICAgIGNvbFsxXSA9IGNvbFRvQnl0ZShjbXlrLm0pOwogICAgICAgICAgY29sWzJdID0gY29sVG9CeXRlKGNteWsueSk7CiAgICAgICAgICBjb2xbM10gPSBjb2xUb0J5dGUoY215ay5rKTsKICAgICAgICAgIGMgKz0gYnl0ZVRvRGJsKGNvbFswXSk7CiAgICAgICAgICBtICs9IGJ5dGVUb0RibChjb2xbMV0pOwogICAgICAgICAgeSArPSBieXRlVG9EYmwoY29sWzJdKTsKICAgICAgICAgIGsgKz0gYnl0ZVRvRGJsKGNvbFszXSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIGNvbFswXSA9IGRibFRvQnl0ZShjbGlwMDEoYykpOwogICAgICBjb2xbMV0gPSBkYmxUb0J5dGUoY2xpcDAxKG0pKTsKICAgICAgY29sWzJdID0gZGJsVG9CeXRlKGNsaXAwMSh5KSk7CiAgICAgIGNvbFszXSA9IGRibFRvQnl0ZShjbGlwMDEoaykpOwogICAgfQogICAgKmxpbmUrKyA9IGNvbFswXTsKICAgICpsaW5lKysgPSBjb2xbMV07CiAgICAqbGluZSsrID0gY29sWzJdOwogICAgKmxpbmUrKyA9IGNvbFszXTsKICB9Cn0KI2VuZGlmCgpTcGxhc2hFcnJvciBTcGxhc2hCaXRtYXA6OndyaXRlSW1nRmlsZShJbWdXcml0ZXIgKndyaXRlciwgRklMRSAqZiwgaW50IGhEUEksIGludCB2RFBJLCBTcGxhc2hDb2xvck1vZGUgaW1hZ2VXcml0ZXJGb3JtYXQpIHsKICBpZiAobW9kZSAhPSBzcGxhc2hNb2RlUkdCOCAmJiBtb2RlICE9IHNwbGFzaE1vZGVNb25vOCAmJiBtb2RlICE9IHNwbGFzaE1vZGVNb25vMSAmJiBtb2RlICE9IHNwbGFzaE1vZGVYQkdSOCAmJiBtb2RlICE9IHNwbGFzaE1vZGVCR1I4CiNpZmRlZiBTUExBU0hfQ01ZSwogICAgICAmJiBtb2RlICE9IHNwbGFzaE1vZGVDTVlLOCAmJiBtb2RlICE9IHNwbGFzaE1vZGVEZXZpY2VOOAojZW5kaWYKICAgICApIHsKICAgIGVycm9yKGVyckludGVybmFsLCAtMSwgInVuc3VwcG9ydGVkIFNwbGFzaEJpdG1hcCBtb2RlIik7CiAgICByZXR1cm4gc3BsYXNoRXJyR2VuZXJpYzsKICB9CgogIGlmICghd3JpdGVyLT5pbml0KGYsIHdpZHRoLCBoZWlnaHQsIGhEUEksIHZEUEkpKSB7CiAgICByZXR1cm4gc3BsYXNoRXJyR2VuZXJpYzsKICB9CgogIHN3aXRjaCAobW9kZSkgewojaWZkZWYgU1BMQVNIX0NNWUsKICAgIGNhc2Ugc3BsYXNoTW9kZUNNWUs4OgogICAgICBpZiAod3JpdGVyLT5zdXBwb3J0Q01ZSygpKSB7CiAgICAgICAgU3BsYXNoQ29sb3JQdHIgcm93OwogICAgICAgIHVuc2lnbmVkIGNoYXIgKipyb3dfcG9pbnRlcnMgPSBuZXcgdW5zaWduZWQgY2hhcipbaGVpZ2h0XTsKICAgICAgICByb3cgPSBkYXRhOwoKICAgICAgICBmb3IgKGludCB5ID0gMDsgeSA8IGhlaWdodDsgKyt5KSB7CiAgICAgICAgICByb3dfcG9pbnRlcnNbeV0gPSByb3c7CiAgICAgICAgICByb3cgKz0gcm93U2l6ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCF3cml0ZXItPndyaXRlUG9pbnRlcnMocm93X3BvaW50ZXJzLCBoZWlnaHQpKSB7CiAgICAgICAgICBkZWxldGVbXSByb3dfcG9pbnRlcnM7CiAgICAgICAgICByZXR1cm4gc3BsYXNoRXJyR2VuZXJpYzsKICAgICAgICB9CiAgICAgICAgZGVsZXRlW10gcm93X3BvaW50ZXJzOwogICAgICB9IGVsc2UgewogICAgICAgIHVuc2lnbmVkIGNoYXIgKnJvdyA9IG5ldyB1bnNpZ25lZCBjaGFyWzMgKiB3aWR0aF07CiAgICAgICAgZm9yIChpbnQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewogICAgICAgICAgZ2V0UkdCTGluZSh5LCByb3cpOwogICAgICAgICAgaWYgKCF3cml0ZXItPndyaXRlUm93KCZyb3cpKSB7CiAgICAgICAgICAgIGRlbGV0ZVtdIHJvdzsKICAgICAgICAgICAgcmV0dXJuIHNwbGFzaEVyckdlbmVyaWM7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGRlbGV0ZVtdIHJvdzsKICAgICAgfQogICAgYnJlYWs7CiAgICBjYXNlIHNwbGFzaE1vZGVEZXZpY2VOODoKICAgICAgaWYgKHdyaXRlci0+c3VwcG9ydENNWUsoKSkgewogICAgICAgIHVuc2lnbmVkIGNoYXIgKnJvdyA9IG5ldyB1bnNpZ25lZCBjaGFyWzQgKiB3aWR0aF07CiAgICAgICAgZm9yIChpbnQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewogICAgICAgICAgZ2V0Q01ZS0xpbmUoeSwgcm93KTsKICAgICAgICAgIGlmICghd3JpdGVyLT53cml0ZVJvdygmcm93KSkgewogICAgICAgICAgICBkZWxldGVbXSByb3c7CiAgICAgICAgICAgIHJldHVybiBzcGxhc2hFcnJHZW5lcmljOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBkZWxldGVbXSByb3c7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdW5zaWduZWQgY2hhciAqcm93ID0gbmV3IHVuc2lnbmVkIGNoYXJbMyAqIHdpZHRoXTsKICAgICAgICBmb3IgKGludCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CiAgICAgICAgICBnZXRSR0JMaW5lKHksIHJvdyk7CiAgICAgICAgICBpZiAoIXdyaXRlci0+d3JpdGVSb3coJnJvdykpIHsKICAgICAgICAgICAgZGVsZXRlW10gcm93OwogICAgICAgICAgICByZXR1cm4gc3BsYXNoRXJyR2VuZXJpYzsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZGVsZXRlW10gcm93OwogICAgICB9CiAgICBicmVhazsKI2VuZGlmCiAgICBjYXNlIHNwbGFzaE1vZGVSR0I4OgogICAgewogICAgICBTcGxhc2hDb2xvclB0ciByb3c7CiAgICAgIHVuc2lnbmVkIGNoYXIgKipyb3dfcG9pbnRlcnMgPSBuZXcgdW5zaWduZWQgY2hhcipbaGVpZ2h0XTsKICAgICAgcm93ID0gZGF0YTsKCiAgICAgIGZvciAoaW50IHkgPSAwOyB5IDwgaGVpZ2h0OyArK3kpIHsKICAgICAgICByb3dfcG9pbnRlcnNbeV0gPSByb3c7CiAgICAgICAgcm93ICs9IHJvd1NpemU7CiAgICAgIH0KICAgICAgaWYgKCF3cml0ZXItPndyaXRlUG9pbnRlcnMocm93X3BvaW50ZXJzLCBoZWlnaHQpKSB7CiAgICAgICAgZGVsZXRlW10gcm93X3BvaW50ZXJzOwogICAgICAgIHJldHVybiBzcGxhc2hFcnJHZW5lcmljOwogICAgICB9CiAgICAgIGRlbGV0ZVtdIHJvd19wb2ludGVyczsKICAgIH0KICAgIGJyZWFrOwogICAgCiAgICBjYXNlIHNwbGFzaE1vZGVCR1I4OgogICAgewogICAgICB1bnNpZ25lZCBjaGFyICpyb3cgPSBuZXcgdW5zaWduZWQgY2hhclszICogd2lkdGhdOwogICAgICBmb3IgKGludCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CiAgICAgICAgLy8gQ29udmVydCBpbnRvIGEgUE5HIHJvdwogICAgICAgIGZvciAoaW50IHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewogICAgICAgICAgcm93WzMqeF0gPSBkYXRhW3kgKiByb3dTaXplICsgeCAqIDMgKyAyXTsKICAgICAgICAgIHJvd1szKngrMV0gPSBkYXRhW3kgKiByb3dTaXplICsgeCAqIDMgKyAxXTsKICAgICAgICAgIHJvd1szKngrMl0gPSBkYXRhW3kgKiByb3dTaXplICsgeCAqIDNdOwogICAgICAgIH0KCiAgICAgICAgaWYgKCF3cml0ZXItPndyaXRlUm93KCZyb3cpKSB7CiAgICAgICAgICBkZWxldGVbXSByb3c7CiAgICAgICAgICByZXR1cm4gc3BsYXNoRXJyR2VuZXJpYzsKICAgICAgICB9CiAgICAgIH0KICAgICAgZGVsZXRlW10gcm93OwogICAgfQogICAgYnJlYWs7CiAgICAKICAgIGNhc2Ugc3BsYXNoTW9kZVhCR1I4OgogICAgewogICAgICB1bnNpZ25lZCBjaGFyICpyb3cgPSBuZXcgdW5zaWduZWQgY2hhclszICogd2lkdGhdOwogICAgICBmb3IgKGludCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CiAgICAgICAgLy8gQ29udmVydCBpbnRvIGEgUE5HIHJvdwogICAgICAgIGZvciAoaW50IHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewogICAgICAgICAgcm93WzMqeF0gPSBkYXRhW3kgKiByb3dTaXplICsgeCAqIDQgKyAyXTsKICAgICAgICAgIHJvd1szKngrMV0gPSBkYXRhW3kgKiByb3dTaXplICsgeCAqIDQgKyAxXTsKICAgICAgICAgIHJvd1szKngrMl0gPSBkYXRhW3kgKiByb3dTaXplICsgeCAqIDRdOwogICAgICAgIH0KCiAgICAgICAgaWYgKCF3cml0ZXItPndyaXRlUm93KCZyb3cpKSB7CiAgICAgICAgICBkZWxldGVbXSByb3c7CiAgICAgICAgICByZXR1cm4gc3BsYXNoRXJyR2VuZXJpYzsKICAgICAgICB9CiAgICAgIH0KICAgICAgZGVsZXRlW10gcm93OwogICAgfQogICAgYnJlYWs7CiAgICAKICAgIGNhc2Ugc3BsYXNoTW9kZU1vbm84OgogICAgewogICAgICBpZiAoaW1hZ2VXcml0ZXJGb3JtYXQgPT0gc3BsYXNoTW9kZU1vbm84KSB7CiAgICAgICAgU3BsYXNoQ29sb3JQdHIgcm93OwogICAgICAgIHVuc2lnbmVkIGNoYXIgKipyb3dfcG9pbnRlcnMgPSBuZXcgdW5zaWduZWQgY2hhcipbaGVpZ2h0XTsKICAgICAgICByb3cgPSBkYXRhOwoKICAgICAgICBmb3IgKGludCB5ID0gMDsgeSA8IGhlaWdodDsgKyt5KSB7CiAgICAgICAgICByb3dfcG9pbnRlcnNbeV0gPSByb3c7CiAgICAgICAgICByb3cgKz0gcm93U2l6ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCF3cml0ZXItPndyaXRlUG9pbnRlcnMocm93X3BvaW50ZXJzLCBoZWlnaHQpKSB7CiAgICAgICAgICBkZWxldGVbXSByb3dfcG9pbnRlcnM7CiAgICAgICAgICByZXR1cm4gc3BsYXNoRXJyR2VuZXJpYzsKICAgICAgICB9CiAgICAgICAgZGVsZXRlW10gcm93X3BvaW50ZXJzOwogICAgICB9IGVsc2UgaWYgKGltYWdlV3JpdGVyRm9ybWF0ID09IHNwbGFzaE1vZGVSR0I4KSB7CiAgICAgICAgdW5zaWduZWQgY2hhciAqcm93ID0gbmV3IHVuc2lnbmVkIGNoYXJbMyAqIHdpZHRoXTsKICAgICAgICBmb3IgKGludCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CiAgICAgICAgICAvLyBDb252ZXJ0IGludG8gYSBQTkcgcm93CiAgICAgICAgICBmb3IgKGludCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKICAgICAgICAgICAgcm93WzMqeF0gPSBkYXRhW3kgKiByb3dTaXplICsgeF07CiAgICAgICAgICAgIHJvd1szKngrMV0gPSBkYXRhW3kgKiByb3dTaXplICsgeF07CiAgICAgICAgICAgIHJvd1szKngrMl0gPSBkYXRhW3kgKiByb3dTaXplICsgeF07CiAgICAgICAgICB9CgogICAgICAgICAgaWYgKCF3cml0ZXItPndyaXRlUm93KCZyb3cpKSB7CiAgICAgICAgICAgIGRlbGV0ZVtdIHJvdzsKICAgICAgICAgICAgcmV0dXJuIHNwbGFzaEVyckdlbmVyaWM7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGRlbGV0ZVtdIHJvdzsKICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICAvLyBvbmx5IHNwbGFzaE1vZGVNb25vOCBvciBzcGxhc2hNb2RlUkdCOAogICAgICAgIHJldHVybiBzcGxhc2hFcnJHZW5lcmljOwogICAgICB9CiAgICB9CiAgICBicmVhazsKICAgIAogICAgY2FzZSBzcGxhc2hNb2RlTW9ubzE6CiAgICB7CiAgICAgIGlmIChpbWFnZVdyaXRlckZvcm1hdCA9PSBzcGxhc2hNb2RlTW9ubzEpIHsKICAgICAgICBTcGxhc2hDb2xvclB0ciByb3c7CiAgICAgICAgdW5zaWduZWQgY2hhciAqKnJvd19wb2ludGVycyA9IG5ldyB1bnNpZ25lZCBjaGFyKltoZWlnaHRdOwogICAgICAgIHJvdyA9IGRhdGE7CgogICAgICAgIGZvciAoaW50IHkgPSAwOyB5IDwgaGVpZ2h0OyArK3kpIHsKICAgICAgICAgIHJvd19wb2ludGVyc1t5XSA9IHJvdzsKICAgICAgICAgIHJvdyArPSByb3dTaXplOwogICAgICAgIH0KICAgICAgICBpZiAoIXdyaXRlci0+d3JpdGVQb2ludGVycyhyb3dfcG9pbnRlcnMsIGhlaWdodCkpIHsKICAgICAgICAgIGRlbGV0ZVtdIHJvd19wb2ludGVyczsKICAgICAgICAgIHJldHVybiBzcGxhc2hFcnJHZW5lcmljOwogICAgICAgIH0KICAgICAgICBkZWxldGVbXSByb3dfcG9pbnRlcnM7CiAgICAgIH0gZWxzZSBpZiAoaW1hZ2VXcml0ZXJGb3JtYXQgPT0gc3BsYXNoTW9kZVJHQjgpIHsKICAgICAgICB1bnNpZ25lZCBjaGFyICpyb3cgPSBuZXcgdW5zaWduZWQgY2hhclszICogd2lkdGhdOwogICAgICAgIGZvciAoaW50IHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKICAgICAgICAgIC8vIENvbnZlcnQgaW50byBhIFBORyByb3cKICAgICAgICAgIGZvciAoaW50IHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewogICAgICAgICAgICBnZXRQaXhlbCh4LCB5LCAmcm93WzMqeF0pOwogICAgICAgICAgICByb3dbMyp4KzFdID0gcm93WzMqeF07CiAgICAgICAgICAgIHJvd1szKngrMl0gPSByb3dbMyp4XTsKICAgICAgICAgIH0KCiAgICAgICAgICBpZiAoIXdyaXRlci0+d3JpdGVSb3coJnJvdykpIHsKICAgICAgICAgICAgZGVsZXRlW10gcm93OwogICAgICAgICAgICByZXR1cm4gc3BsYXNoRXJyR2VuZXJpYzsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZGVsZXRlW10gcm93OwogICAgICB9CiAgICAgIGVsc2UgewogICAgICAgIC8vIG9ubHkgc3BsYXNoTW9kZU1vbm8xIG9yIHNwbGFzaE1vZGVSR0I4CiAgICAgICAgcmV0dXJuIHNwbGFzaEVyckdlbmVyaWM7CiAgICAgIH0KICAgIH0KICAgIGJyZWFrOwogICAgCiAgICBkZWZhdWx0OgogICAgLy8gY2FuJ3QgaGFwcGVuCiAgICBicmVhazsKICB9CiAgCiAgaWYgKCF3cml0ZXItPmNsb3NlKCkpIHsKICAgIHJldHVybiBzcGxhc2hFcnJHZW5lcmljOwogIH0KCiAgcmV0dXJuIHNwbGFzaE9rOwp9Cg==