LyoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIFN05HVibGkgRmF2ZXJnZXMgLSA8d3d3LnN0YXVibGkuY29tPgogKiBQaWVycmUgQVVCRVJUICBwLmF1YmVydEBzdGF1YmxpLmNvbQogKgogKiBTZWUgZmlsZSBDUkVESVRTIGZvciBsaXN0IG9mIHBlb3BsZSB3aG8gY29udHJpYnV0ZWQgdG8gdGhpcwogKiBwcm9qZWN0LgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mCiAqIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLAogKiBNQSAwMjExMS0xMzA3IFVTQQogKi8KCiNpbmNsdWRlIDxjb21tb24uaD4KI2luY2x1ZGUgPGNvbmZpZy5oPgojaW5jbHVkZSA8bWFsbG9jLmg+CgojaWYgKENPTkZJR19DT01NQU5EUyAmIENGR19DTURfRkRPUykKCiNpbmNsdWRlICJkb3MuaCIKI2luY2x1ZGUgImZkb3MuaCIKCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIGZhdF9kZWNvZGUgLS0gCiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICovCnVuc2lnbmVkIGludCBmYXRfZGVjb2RlIChGc190ICpmcywgdW5zaWduZWQgaW50IG51bSkKewogICAgdW5zaWduZWQgaW50IHN0YXJ0ID0gbnVtICogMyAvIDI7CiAgICB1bnNpZ25lZCBjaGFyICphZGRyZXNzID0gZnMgLT4gZmF0X2J1ZiArIHN0YXJ0OwogICAgCiAgICBpZiAobnVtIDwgMiB8fCBzdGFydCArIDEgPiAoZnMgLT4gZmF0X2xlbiAqIFNaX1NURF9TRUNUT1IpKQogICAgICAgIHJldHVybiAxOwogICAgCiAgICBpZiAobnVtICYgMSkKICAgICAgICByZXR1cm4gKChhZGRyZXNzIFsxXSAmIDB4ZmYpIDw8IDQpIHwgKChhZGRyZXNzIFswXSAmIDB4ZjAgKSA+PiA0KTsKICAgIGVsc2UKICAgICAgICByZXR1cm4gKChhZGRyZXNzIFsxXSAmIDB4ZikgPDwgOCkgfCAoYWRkcmVzcyBbMF0gJiAweGZmICk7Cn0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiBjaGVja19mYXQgLS0gCiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICovCnN0YXRpYyBpbnQgY2hlY2tfZmF0IChGc190ICpmcykKewogICAgaW50IGksIGY7CgogICAgLyogQ2x1c3RlciB2ZXJpZmljYXRpb24gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICBmb3IgKGkgPSAzIDsgaSA8IGZzIC0+IG51bV9jbHVzOyBpKyspewogICAgICAgIGYgPSBmYXRfZGVjb2RlIChmcywgaSk7CiAgICAgICAgaWYgKGYgPCBGQVQxMl9MQVNUICYmIGYgPiBmcyAtPiBudW1fY2x1cyl7CiAgICAgICAgICAgIC8qIFdyb25nIGNsdXN0ZXIgbnVtYmVyIGRldGVjdGVkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgcmV0dXJuICgtMSk7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuICgwKTsKfQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIHJlYWRfb25lX2ZhdCAtLSAKICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8Kc3RhdGljIGludCByZWFkX29uZV9mYXQgKEJvb3RTZWN0b3JfdCAqYm9vdCwgRnNfdCAqZnMsIGludCBuZmF0KQp7CiAgICBpZiAoZGV2X3JlYWQgKGZzIC0+IGZhdF9idWYsCiAgICAgICAgICAgICAgICAgIChmcyAtPiBmYXRfc3RhcnQgKyBuZmF0ICogZnMgLT4gZmF0X2xlbiksCiAgICAgICAgICAgICAgICAgIGZzIC0+IGZhdF9sZW4pIDwgMCkgewogICAgICAgIHJldHVybiAoLTEpOwogICAgfQoKICAgIGlmIChmcyAtPiBmYXRfYnVmIFswXSB8fCBmcyAtPiBmYXRfYnVmIFsxXSB8fCBmcyAtPiBmYXRfYnVmIFsyXSkgewogICAgICAgIGlmICgoZnMgLT4gZmF0X2J1ZiBbMF0gIT0gYm9vdCAtPiBkZXNjciAmJgogICAgICAgICAgICAgKGZzIC0+IGZhdF9idWYgWzBdICE9IDB4ZjkgfHwgYm9vdCAtPiBkZXNjciAhPSBNRURJQV9TVEQpKSB8fAogICAgICAgICAgICBmcyAtPiBmYXRfYnVmIFswXSA8IE1FRElBX1NURCl7CiAgICAgICAgICAgIC8qIFVua25vd24gTWVkaWEgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgcmV0dXJuICgtMSk7CiAgICAgICAgfQogICAgICAgIGlmIChmcyAtPiBmYXRfYnVmIFsxXSAhPSAweGZmIHx8IGZzIC0+IGZhdF9idWYgWzJdICE9IDB4ZmYpewogICAgICAgICAgICAvKiBGQVQgZG9lc24ndCBzdGFydCB3aXRoIGdvb2QgdmFsdWVzICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgIHJldHVybiAoLTEpOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoZnMgLT4gbnVtX2NsdXMgPj0gRkFUMTJfTUFYX05CKSB7CiAgICAgICAgLyogVG9vIG11Y2ggY2x1c3RlcnMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KCiAgICByZXR1cm4gY2hlY2tfZmF0IChmcyk7Cn0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiByZWFkX2ZhdCAtLSAKICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KaW50IHJlYWRfZmF0IChCb290U2VjdG9yX3QgKmJvb3QsIEZzX3QgKmZzKQp7CiAgICB1bnNpZ25lZCBpbnQgYnVmbGVuOwogICAgaW50IGk7CgogICAgLyogQWxsb2NhdGUgRmF0IEJ1ZmZlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICBidWZsZW4gPSBmcyAtPiBmYXRfbGVuICogU1pfU1REX1NFQ1RPUjsKICAgIGlmIChmcyAtPiBmYXRfYnVmKSB7CiAgICAgICAgZnJlZSAoZnMgLT4gZmF0X2J1Zik7CiAgICB9CgogICAgaWYgKChmcyAtPiBmYXRfYnVmID0gbWFsbG9jIChidWZsZW4pKSA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuICgtMSk7CiAgICB9CgogICAgLyogVHJ5IHRvIHJlYWQgZWFjaCBGYXQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICBmb3IgKGkgPSAwOyBpPCBmcyAtPiBuYl9mYXQ7IGkrKyl7CiAgICAgICAgaWYgKHJlYWRfb25lX2ZhdCAoYm9vdCwgZnMsIGkpID09IDApIHsKICAgICAgICAgICAgLyogRmF0IGlzIE9LICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICBmcyAtPiBudW1fZmF0ID0gaTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChpID09IGZzIC0+IG5iX2ZhdCl7CiAgICAgICAgcmV0dXJuICgtMSk7CiAgICB9CiAgICAKICAgIGlmIChmcyAtPiBmYXRfbGVuID4gKCgoZnMgLT4gbnVtX2NsdXMgKyAyKSAqCiAgICAgICAgICAgICAgICAgICAgICAgICAgKEZBVF9CSVRTIC8gNCkgLTEgKSAvIDIgLwogICAgICAgICAgICAgICAgICAgICAgICAgU1pfU1REX1NFQ1RPUiArIDEpKSB7CiAgICAgICAgcmV0dXJuICgtMSk7CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgoKIAoKI2VuZGlmCg==