LyogSW1wbGVtZW50YXRpb24gb2YgdGhlIFRSQU5TUE9TRSBpbnRyaW5zaWMKICAgQ29weXJpZ2h0IDIwMDMgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuCiAgIENvbnRyaWJ1dGVkIGJ5IFRvYmlhcyBTY2hs/HRlcgoKVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEdOVSBGb3J0cmFuIDk1IHJ1bnRpbWUgbGlicmFyeSAobGliZ2ZvcnRyYW4pLgoKTGliZ2ZvcnRyYW4gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCm1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwpMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgoKSW4gYWRkaXRpb24gdG8gdGhlIHBlcm1pc3Npb25zIGluIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwgdGhlCkZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiBnaXZlcyB5b3UgdW5saW1pdGVkIHBlcm1pc3Npb24gdG8gbGluayB0aGUKY29tcGlsZWQgdmVyc2lvbiBvZiB0aGlzIGZpbGUgaW50byBjb21iaW5hdGlvbnMgd2l0aCBvdGhlciBwcm9ncmFtcywKYW5kIHRvIGRpc3RyaWJ1dGUgdGhvc2UgY29tYmluYXRpb25zIHdpdGhvdXQgYW55IHJlc3RyaWN0aW9uIGNvbWluZwpmcm9tIHRoZSB1c2Ugb2YgdGhpcyBmaWxlLiAgKFRoZSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHJlc3RyaWN0aW9ucwpkbyBhcHBseSBpbiBvdGhlciByZXNwZWN0czsgZm9yIGV4YW1wbGUsIHRoZXkgY292ZXIgbW9kaWZpY2F0aW9uIG9mCnRoZSBmaWxlLCBhbmQgZGlzdHJpYnV0aW9uIHdoZW4gbm90IGxpbmtlZCBpbnRvIGEgY29tYmluZQpleGVjdXRhYmxlLikKCkxpYmdmb3J0cmFuIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCmJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCk1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KCllvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwpMaWNlbnNlIGFsb25nIHdpdGggbGliZ2ZvcnRyYW47IHNlZSB0aGUgZmlsZSBDT1BZSU5HLiAgSWYgbm90LAp3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsCkJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLiAgKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgImxpYmdmb3J0cmFuLmgiCgpleHRlcm4gdm9pZCB0cmFuc3Bvc2UgKGdmY19hcnJheV9jaGFyICosIGdmY19hcnJheV9jaGFyICopOwpleHBvcnRfcHJvdG8odHJhbnNwb3NlKTsKCnZvaWQKdHJhbnNwb3NlIChnZmNfYXJyYXlfY2hhciAqcmV0LCBnZmNfYXJyYXlfY2hhciAqc291cmNlKQp7CiAgLyogci4qIGluZGljYXRlcyB0aGUgcmV0dXJuIGFycmF5LiAgKi8KICBpbmRleF90eXBlIHJ4c3RyaWRlLCByeXN0cmlkZTsKICBjaGFyICpycHRyOwogIC8qIHMuKiBpbmRpY2F0ZXMgdGhlIHNvdXJjZSBhcnJheS4gICovCiAgaW5kZXhfdHlwZSBzeHN0cmlkZSwgc3lzdHJpZGU7CiAgY29uc3QgY2hhciAqc3B0cjsKCiAgaW5kZXhfdHlwZSB4Y291bnQsIHljb3VudDsKICBpbmRleF90eXBlIHgsIHk7CiAgaW5kZXhfdHlwZSBzaXplOwoKICBhc3NlcnQgKEdGQ19ERVNDUklQVE9SX1JBTksgKHNvdXJjZSkgPT0gMgogICAgICAgICAgJiYgR0ZDX0RFU0NSSVBUT1JfUkFOSyAocmV0KSA9PSAyKTsKCiAgc2l6ZSA9IEdGQ19ERVNDUklQVE9SX1NJWkUgKHNvdXJjZSk7CgogIGlmIChyZXQtPmRhdGEgPT0gTlVMTCkKICAgIHsKICAgICAgYXNzZXJ0IChyZXQtPmR0eXBlID09IHNvdXJjZS0+ZHR5cGUpOwoKICAgICAgcmV0LT5kaW1bMF0ubGJvdW5kID0gMDsKICAgICAgcmV0LT5kaW1bMF0udWJvdW5kID0gc291cmNlLT5kaW1bMV0udWJvdW5kIC0gc291cmNlLT5kaW1bMV0ubGJvdW5kOwogICAgICByZXQtPmRpbVswXS5zdHJpZGUgPSAxOwoKICAgICAgcmV0LT5kaW1bMV0ubGJvdW5kID0gMDsKICAgICAgcmV0LT5kaW1bMV0udWJvdW5kID0gc291cmNlLT5kaW1bMF0udWJvdW5kIC0gc291cmNlLT5kaW1bMF0ubGJvdW5kOwogICAgICByZXQtPmRpbVsxXS5zdHJpZGUgPSByZXQtPmRpbVswXS51Ym91bmQrMTsKCiAgICAgIHJldC0+ZGF0YSA9IGludGVybmFsX21hbGxvY19zaXplIChzaXplICogc2l6ZTAgKChhcnJheV90KilyZXQpKTsKICAgICAgcmV0LT5iYXNlID0gMDsKICAgIH0KCiAgc3hzdHJpZGUgPSBzb3VyY2UtPmRpbVswXS5zdHJpZGUgKiBzaXplOwogIGlmIChzeHN0cmlkZSA9PSAwKQogICAgc3hzdHJpZGUgPSBzaXplOwogIHN5c3RyaWRlID0gc291cmNlLT5kaW1bMV0uc3RyaWRlICogc2l6ZTsKICB4Y291bnQgPSBzb3VyY2UtPmRpbVswXS51Ym91bmQgKyAxIC0gc291cmNlLT5kaW1bMF0ubGJvdW5kOwogIHljb3VudCA9IHNvdXJjZS0+ZGltWzFdLnVib3VuZCArIDEgLSBzb3VyY2UtPmRpbVsxXS5sYm91bmQ7CgogIHJ4c3RyaWRlID0gcmV0LT5kaW1bMF0uc3RyaWRlICogc2l6ZTsKICBpZiAocnhzdHJpZGUgPT0gMCkKICAgIHJ4c3RyaWRlID0gc2l6ZTsKICByeXN0cmlkZSA9IHJldC0+ZGltWzFdLnN0cmlkZSAqIHNpemU7CgogIHJwdHIgPSByZXQtPmRhdGE7CiAgc3B0ciA9IHNvdXJjZS0+ZGF0YTsKCiAgZm9yICh5ID0gMDsgeSA8IHljb3VudDsgeSsrKQogICAgewogICAgICBmb3IgKHggPSAwOyB4IDwgeGNvdW50OyB4KyspCiAgICAgICAgewogICAgICAgICAgbWVtY3B5IChycHRyLCBzcHRyLCBzaXplKTsKCiAgICAgICAgICBzcHRyICs9IHN4c3RyaWRlOwogICAgICAgICAgcnB0ciArPSByeXN0cmlkZTsKICAgICAgICB9CiAgICAgIHNwdHIgKz0gc3lzdHJpZGUgLSAoc3hzdHJpZGUgKiB4Y291bnQpOwogICAgICBycHRyICs9IHJ4c3RyaWRlIC0gKHJ5c3RyaWRlICogeGNvdW50KTsKICAgIH0KfQo=