LyoKICogMkQgU3VyZmFjZSBpbXBsZW1lbnRhdGlvbiB3aXRob3V0IE9wZW5HTAogKgogKiBDb3B5cmlnaHQgMTk5Ny0yMDAwIE1hcmN1cyBNZWlzc25lcgogKiBDb3B5cmlnaHQgMTk5OC0yMDAwIExpb25lbCBVbG1lcgogKiBDb3B5cmlnaHQgMjAwMC0yMDAxIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcyBJbmMuCiAqIENvcHlyaWdodCAyMDAyLTIwMDUgSmFzb24gRWRtZWFkZXMKICogQ29weXJpZ2h0IDIwMDItMjAwMyBSYXBoYWVsIEp1bnF1ZWlyYQogKiBDb3B5cmlnaHQgMjAwNCBDaHJpc3RpYW4gQ29zdGEKICogQ29weXJpZ2h0IDIwMDUgT2xpdmVyIFN0aWViZXIKICogQ29weXJpZ2h0IDIwMDYgU3RlZmFuIET2c2luZ2VyCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgojaW5jbHVkZSAid2luZWQzZF9wcml2YXRlLmgiCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKLyogVXNlIHRoZSBkM2Rfc3VyZmFjZSBkZWJ1ZyBjaGFubmVsIHRvIGhhdmUgb25lIGNoYW5uZWwgZm9yIGFsbCBzdXJmYWNlcyAqLwpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkM2Rfc3VyZmFjZSk7CldJTkVfREVDTEFSRV9ERUJVR19DSEFOTkVMKGZwcyk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogeDExX2NvcHlfdG9fc2NyZWVuCiAqCiAqIEhlbHBlciBmdW5jdGlvbiB0aGF0IGJsdHMgdGhlIGZyb250IGJ1ZmZlciBjb250ZW50cyB0byB0aGUgdGFyZ2V0IHdpbmRvdwogKgogKiBQYXJhbXM6CiAqICBUaGlzOiBTdXJmYWNlIHRvIGNvcHkgZnJvbQogKiAgcmM6IFJlY3RhbmdsZSB0byBjb3B5CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIHZvaWQKeDExX2NvcHlfdG9fc2NyZWVuKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMsCiAgICAgICAgICAgICAgICAgICBMUFJFQ1QgcmMpCnsKICAgIGlmKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkKICAgIHsKICAgICAgICBQT0lOVCBvZmZzZXQgPSB7MCwwfTsKICAgICAgICBIV05EIGhEaXNwbGF5V25kOwogICAgICAgIEhEQyBoRGlzcGxheURDOwogICAgICAgIEhEQyBoU3VyZmFjZURDID0gMDsKICAgICAgICBSRUNUIGRyYXdyZWN0OwogICAgICAgIFRSQUNFKCIoJXApLT4oJXApOiBDb3B5aW5nIHRvIHNjcmVlblxuIiwgVGhpcywgcmMpOwoKICAgICAgICBoU3VyZmFjZURDID0gVGhpcy0+aERDOwoKICAgICAgICBoRGlzcGxheVduZCA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UtPmRkcmF3X3dpbmRvdzsKICAgICAgICBoRGlzcGxheURDID0gR2V0RENFeChoRGlzcGxheVduZCwgMCwgRENYX0NMSVBTSUJMSU5HU3xEQ1hfQ0FDSEUpOwogICAgICAgIGlmKHJjKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIiBjb3B5aW5nIHJlY3QgKCVkLCVkKS0+KCVkLCVkKSwgb2Zmc2V0ICglZCwlZClcbiIsCiAgICAgICAgICAgIHJjLT5sZWZ0LCByYy0+dG9wLCByYy0+cmlnaHQsIHJjLT5ib3R0b20sIG9mZnNldC54LCBvZmZzZXQueSk7CiAgICAgICAgfQojaWYgMAogICAgICAgIC8qIEZJWE1FOiB0aGlzIGRvZXNuJ3Qgd29yay4uLiBpZiB1c2VycyByZWFsbHkgd2FudCB0byBydW4KICAgICAgICAqIFggaW4gOGJwcCwgdGhlbiB3ZSBuZWVkIHRvIGNhbGwgZGlyZWN0bHkgaW50byBkaXNwbGF5LmRydgogICAgICAgICogKG9yIFdpbmUncyBlcXVpdmFsZW50KSwgYW5kIGZvcmNlIGEgcHJpdmF0ZSBjb2xvcm1hcAogICAgICAgICogd2l0aG91dCBkZWZhdWx0IGVudHJpZXMuICovCiAgICAgICAgaWYgKFRoaXMtPnBhbGV0dGUpIHsKICAgICAgICAgICAgU2VsZWN0UGFsZXR0ZShoRGlzcGxheURDLCBUaGlzLT5wYWxldHRlLT5ocGFsLCBGQUxTRSk7CiAgICAgICAgICAgIFJlYWxpemVQYWxldHRlKGhEaXNwbGF5REMpOyAvKiBzZW5kcyBtZXNzYWdlcyA9PiBkZWFkbG9ja3MgKi8KICAgICAgICB9CiNlbmRpZgogICAgICAgIGRyYXdyZWN0LmxlZnQJPSAwOwogICAgICAgIGRyYXdyZWN0LnJpZ2h0CT0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgZHJhd3JlY3QudG9wCT0gMDsKICAgICAgICBkcmF3cmVjdC5ib3R0b20JPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CgojaWYgMAogICAgICAgIC8qIFRPRE86IFN1cHBvcnQgY2xpcHBlcnMgKi8KICAgICAgICBpZiAoVGhpcy0+Y2xpcHBlcikKICAgICAgICB7CiAgICAgICAgICAgIFJFQ1QgeHJjOwogICAgICAgICAgICBIV05EIGh3bmQgPSBUaGlzLT5jbGlwcGVyLT5oV25kOwogICAgICAgICAgICBpZiAoaHduZCAmJiBHZXRDbGllbnRSZWN0KGh3bmQsJnhyYykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIE9mZnNldFJlY3QoJnhyYyxvZmZzZXQueCxvZmZzZXQueSk7CiAgICAgICAgICAgICAgICBJbnRlcnNlY3RSZWN0KCZkcmF3cmVjdCwmZHJhd3JlY3QsJnhyYyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiNlbmRpZgogICAgICAgIGlmIChyYykKICAgICAgICB7CiAgICAgICAgICAgIEludGVyc2VjdFJlY3QoJmRyYXdyZWN0LCZkcmF3cmVjdCxyYyk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8qIE9ubHkgdXNlIHRoaXMgaWYgdGhlIGNhbGxlciBkaWQgbm90IHBhc3MgYSByZWN0YW5nbGUsIHNpbmNlCiAgICAgICAgICAgICAqIGR1ZSB0byBkb3VibGUgbG9ja2luZyB0aGlzIGNvdWxkIGJlIHRoZSB3cm9uZyBvbmUgLi4uCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoVGhpcy0+bG9ja2VkUmVjdC5sZWZ0ICE9IFRoaXMtPmxvY2tlZFJlY3QucmlnaHQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEludGVyc2VjdFJlY3QoJmRyYXdyZWN0LCZkcmF3cmVjdCwmVGhpcy0+bG9ja2VkUmVjdCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEJpdEJsdChoRGlzcGxheURDLAogICAgICAgICAgICAgICBkcmF3cmVjdC5sZWZ0LW9mZnNldC54LCBkcmF3cmVjdC50b3Atb2Zmc2V0LnksCiAgICAgICAgICAgICAgIGRyYXdyZWN0LnJpZ2h0LWRyYXdyZWN0LmxlZnQsIGRyYXdyZWN0LmJvdHRvbS1kcmF3cmVjdC50b3AsCiAgICAgICAgICAgICAgIGhTdXJmYWNlREMsCiAgICAgICAgICAgICAgIGRyYXdyZWN0LmxlZnQsIGRyYXdyZWN0LnRvcCwKICAgICAgICAgICAgICAgU1JDQ09QWSk7CiAgICAgICAgUmVsZWFzZURDKGhEaXNwbGF5V25kLCBoRGlzcGxheURDKTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElXaW5lRDNEU3VyZmFjZTo6UHJlTG9hZCwgR0RJIHZlcnNpb24KICoKICogVGhpcyBjYWxsIGlzIHVuc3VwcG9ydGVkIG9uIEdESSBzdXJmYWNlcywgaWYgaXQncyBjYWxsZWQgc29tZXRoaW5nIHdlbnQKICogd3JvbmcgaW4gdGhlIHBhcmVudCBsaWJyYXJ5LiBXcml0ZSBhbiBpbmZvcm1hdGl2ZSB3YXJuaW5nCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIHZvaWQgV0lOQVBJCklXaW5lR0RJU3VyZmFjZUltcGxfUHJlTG9hZChJV2luZUQzRFN1cmZhY2UgKmlmYWNlKQp7CiAgICBFUlIoIiglcCk6IFByZUxvYWQgaXMgbm90IHN1cHBvcnRlZCBvbiBYMTEgc3VyZmFjZXMhXG4iLCBpZmFjZSk7CiAgICBFUlIoIiglcCk6IE1vc3QgbGlrZWx5IHRoZSBwYXJlbnQgbGlicmFyeSBkaWQgc29tZXRoaW5nIHdyb25nLlxuIiwgaWZhY2UpOwogICAgRVJSKCIoJXApOiBQbGVhc2UgcmVwb3J0IHRvIHdpbmUtZGV2ZWxcbiIsIGlmYWNlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElXaW5lRDNEU3VyZmFjZTo6TG9ja1JlY3QsIEdESSB2ZXJzaW9uCiAqCiAqIExvY2tzIHRoZSBzdXJmYWNlIGFuZCByZXR1cm5zIGEgcG9pbnRlciB0byB0aGUgc3VyZmFjZSBtZW1vcnkKICoKICogUGFyYW1zOgogKiAgcExvY2tlZFJlY3Q6IEFkZHJlc3MgdG8gcmV0dXJuIHRoZSBsb2NraW5nIGluZm8gYXQKICogIHBSZWN0OiBSZWN0YW5nbGUgdG8gbG9jawogKiAgRmxhZ3M6IFNvbWUgZmxhZ3MKICoKICogUmV0dXJuczoKICogIFdJTkVEM0RfT0sgb24gc3VjY2VzcwogKiAgV0lORUQzREVSUl9JTlZBTElEQ0FMTCBvbiBlcnJvcnMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSVdpbmVHRElTdXJmYWNlSW1wbF9Mb2NrUmVjdChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RMT0NLRURfUkVDVCogcExvY2tlZFJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09OU1QgUkVDVCogcFJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwoKICAgIC8qIEFscmVhZHkgbG9ja2VkPyAqLwogICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19MT0NLRUQpCiAgICB7CiAgICAgICAgRVJSKCIoJXApIFN1cmZhY2UgYWxyZWFkeSBsb2NrZWRcbiIsIFRoaXMpOwogICAgICAgIC8qIFdoYXQgc2hvdWxkIEkgcmV0dXJuIGhlcmU/ICovCiAgICAgICAgcmV0dXJuIEQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBpZiAoIShUaGlzLT5GbGFncyAmIFNGTEFHX0xPQ0tBQkxFKSkKICAgIHsKICAgICAgICAvKiBUaGlzIGlzIHNvbWUgR0wgc3BlY2lmaWMgdGhpbmcsIHNlZSB0aGUgT3BlbkdMIHZlcnNpb24gb2YKICAgICAgICAgKiB0aGlzIG1ldGhvZCwgYnV0IGNoZWNrIGZvciB0aGUgZmxhZyBhbmQgd3JpdGUgYSB0cmFjZQogICAgICAgICAqLwogICAgICAgIFRSQUNFKCJXYXJuaW5nOiB0cnlpbmcgdG8gbG9jayB1bmxvY2thYmxlIHN1cmZAJXBcbiIsIFRoaXMpOwogICAgfQoKICAgIFRSQUNFKCIoJXApIDogcmVjdEAlcCBmbGFncyglMDh4KSwgb3V0cHV0IGxvY2tlZFJlY3RAJXAsIG1lbW9yeUAlcFxuIiwKICAgICAgICAgIFRoaXMsIHBSZWN0LCBGbGFncywgcExvY2tlZFJlY3QsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CgogICAgaWYoIVRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgewogICAgICAgIEhEQyBoZGM7CiAgICAgICAgSFJFU1VMVCBocjsKICAgICAgICAvKiBUaGlzIGhhcHBlbnMgb24gZ2RpIHN1cmZhY2VzIGlmIHRoZSBhcHBsaWNhdGlvbiBzZXQgYSB1c2VyIHBvaW50ZXIgYW5kIHJlc2V0cyBpdC4KICAgICAgICAgKiBSZWNyZWF0ZSB0aGUgRElCIHNlY3Rpb24KICAgICAgICAgKi8KICAgICAgICBociA9IElXaW5lRDNEU3VyZmFjZV9HZXREQyhpZmFjZSwgJmhkYyk7ICAvKiB3aWxsIHJlY3Vyc2l2ZWx5IGNhbGwgbG9ja3JlY3QsIGRvIG5vdCBzZXQgdGhlIExPQ0tFRCBmbGFnIHRvIHRoaXMgbGluZSAqLwogICAgICAgIGlmKGhyICE9IFdJTkVEM0RfT0spIHJldHVybiBocjsKICAgICAgICBociA9IElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlREMoaWZhY2UsIGhkYyk7CiAgICAgICAgaWYoaHIgIT0gV0lORUQzRF9PSykgcmV0dXJuIGhyOwogICAgfQoKICAgIHBMb2NrZWRSZWN0LT5QaXRjaCA9IElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaChpZmFjZSk7CgogICAgaWYgKE5VTEwgPT0gcFJlY3QpCiAgICB7CiAgICAgICAgcExvY2tlZFJlY3QtPnBCaXRzID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QubGVmdCAgID0gMDsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LnRvcCAgICA9IDA7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5yaWdodCAgPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKCiAgICAgICAgVFJBQ0UoIkxvY2tlZCBSZWN0ICglcCkgPSBsICVkLCB0ICVkLCByICVkLCBiICVkXG4iLAogICAgICAgICZUaGlzLT5sb2NrZWRSZWN0LCBUaGlzLT5sb2NrZWRSZWN0LmxlZnQsIFRoaXMtPmxvY2tlZFJlY3QudG9wLAogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QucmlnaHQsIFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBUUkFDRSgiTG9jayBSZWN0ICglcCkgPSBsICVkLCB0ICVkLCByICVkLCBiICVkXG4iLAogICAgICAgICAgICAgIHBSZWN0LCBwUmVjdC0+bGVmdCwgcFJlY3QtPnRvcCwgcFJlY3QtPnJpZ2h0LCBwUmVjdC0+Ym90dG9tKTsKCiAgICAgICAgaWYgKChwUmVjdC0+dG9wIDwgMCkgfHwKICAgICAgICAgICAgIChwUmVjdC0+bGVmdCA8IDApIHx8CiAgICAgICAgICAgICAocFJlY3QtPmxlZnQgPj0gcFJlY3QtPnJpZ2h0KSB8fAogICAgICAgICAgICAgKHBSZWN0LT50b3AgPj0gcFJlY3QtPmJvdHRvbSkgfHwKICAgICAgICAgICAgIChwUmVjdC0+cmlnaHQgPiBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCkgfHwKICAgICAgICAgICAgIChwUmVjdC0+Ym90dG9tID4gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KSkKICAgICAgICB7CiAgICAgICAgICAgIFdBUk4oIiBJbnZhbGlkIHZhbHVlcyBpbiBwUmVjdCAhISFcbiIpOwogICAgICAgICAgICByZXR1cm4gRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgIH0KCiAgICAgICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEpCiAgICAgICAgewogICAgICAgICAgICAvKiBEWFQxIGlzIGhhbGYgYnl0ZSBwZXIgcGl4ZWwgKi8KICAgICAgICAgICAgcExvY2tlZFJlY3QtPnBCaXRzID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChwTG9ja2VkUmVjdC0+UGl0Y2ggKiBwUmVjdC0+dG9wKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKHBSZWN0LT5sZWZ0ICogVGhpcy0+Ynl0ZXNQZXJQaXhlbCAvIDIpKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgcExvY2tlZFJlY3QtPnBCaXRzID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHBMb2NrZWRSZWN0LT5QaXRjaCAqIHBSZWN0LT50b3ApICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHBSZWN0LT5sZWZ0ICogVGhpcy0+Ynl0ZXNQZXJQaXhlbCk7CiAgICAgICAgfQogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QubGVmdCAgID0gcFJlY3QtPmxlZnQ7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC50b3AgICAgPSBwUmVjdC0+dG9wOwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgID0gcFJlY3QtPnJpZ2h0OwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tID0gcFJlY3QtPmJvdHRvbTsKICAgIH0KCiAgICAvKiBObyBkaXJ0aWZ5aW5nIGlzIG5lZWRlZCBmb3IgdGhpcyBzdXJmYWNlIGltcGxlbWVudGF0aW9uICovCiAgICBUUkFDRSgicmV0dXJuaW5nIG1lbW9yeUAlcCwgcGl0Y2goJWQpXG4iLCBwTG9ja2VkUmVjdC0+cEJpdHMsIHBMb2NrZWRSZWN0LT5QaXRjaCk7CgogICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfTE9DS0VEOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRFN1cmZhY2U6OlVubG9ja1JlY3QsIEdESSB2ZXJzaW9uCiAqCiAqIFVubG9ja3MgYSBzdXJmYWNlLiBUaGlzIGltcGxlbWVudGF0aW9uIGRvZXNuJ3QgZG8gbXVjaCwgZXhjZXB0IHVwZGF0aW5nCiAqIHRoZSB3aW5kb3cgaWYgdGhlIGZyb250IGJ1ZmZlciBpcyB1bmxvY2tlZAogKgogKiBSZXR1cm5zOgogKiAgV0lORUQzRF9PSyBvbiBzdWNjZXNzCiAqICBXSU5FRDNERVJSX0lOVkFMSURDQUxMIG9uIGZhaWx1cmUKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSVdpbmVHRElTdXJmYWNlSW1wbF9VbmxvY2tSZWN0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpCnsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXYgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgaWYgKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19MT0NLRUQpKQogICAgewogICAgICAgIFdBUk4oInRyeWluZyB0byBVbmxvY2sgYW4gdW5sb2NrZWQgc3VyZkAlcFxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogQ2FuIGJlIHVzZWZ1bCBmb3IgZGVidWdnaW5nICovCiNpZiAwCiAgICAgICAgewogICAgICAgICAgICBzdGF0aWMgdW5zaWduZWQgaW50IGdlbiA9IDA7CiAgICAgICAgICAgIGNoYXIgYnVmZmVyWzQwOTZdOwogICAgICAgICAgICArK2dlbjsKICAgICAgICAgICAgaWYgKChnZW4gJSAxMCkgPT0gMCkgewogICAgICAgICAgICAgICAgc25wcmludGYoYnVmZmVyLCBzaXplb2YoYnVmZmVyKSwgIi90bXAvc3VyZmFjZSVwX3R5cGUldV9sZXZlbCV1XyV1LnBwbSIsIFRoaXMsIFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCBnZW4pOwogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TYXZlU25hcHNob3QoaWZhY2UsIGJ1ZmZlcik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogZGVidWdnaW5nIGNyYXNoIGNvZGUKICAgICAgICAgICAgaWYgKGdlbiA9PSAyNTApIHsKICAgICAgICAgICAgICB2b2lkKiogdGVzdCA9IE5VTEw7CiAgICAgICAgICAgICAgKnRlc3QgPSAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgICovCiAgICAgICAgfQojZW5kaWYKCiAgICAvKiBVcGRhdGUgdGhlIHNjcmVlbiAqLwogICAgaWYoVGhpcyA9PSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBkZXYtPmRkcmF3X3ByaW1hcnkpCiAgICB7CiAgICAgICAgeDExX2NvcHlfdG9fc2NyZWVuKFRoaXMsICZUaGlzLT5sb2NrZWRSZWN0KTsKICAgIH0KCiAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfTE9DS0VEOwogICAgbWVtc2V0KCZUaGlzLT5sb2NrZWRSZWN0LCAwLCBzaXplb2YoUkVDVCkpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRFN1cmZhY2U6OkZsaXAsIEdESSB2ZXJzaW9uCiAqCiAqIEZsaXBzIDIgZmxpcHBpbmcgZW5hYmxlZCBzdXJmYWNlcy4gRGV0ZXJtaW5pbmcgdGhlIDIgdGFyZ2V0cyBpcyBkb25lIGJ5CiAqIHRoZSBwYXJlbnQgbGlicmFyeS4gVGhpcyBpbXBsZW1lbnRhdGlvbiBjaGFuZ2VzIHRoZSBkYXRhIHBvaW50ZXJzIG9mIHRoZQogKiBzdXJmYWNlcyBhbmQgY29waWVzIHRoZSBuZXcgZnJvbnQgYnVmZmVyIGNvbnRlbnQgdG8gdGhlIHNjcmVlbgogKgogKiBQYXJhbXM6CiAqICBvdmVycmlkZTogRmxpcHBpbmcgdGFyZ2V0KGUuZy4gYmFjayBidWZmZXIpCiAqCiAqIFJldHVybnM6CiAqICBXSU5FRDNEX09LIG9uIHN1Y2Nlc3MKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSVdpbmVHRElTdXJmYWNlSW1wbF9GbGlwKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2UgKm92ZXJyaWRlLAogICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRhcmdldCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIG92ZXJyaWRlOwogICAgVFJBQ0UoIiglcCktPiglcCwleClcbiIsIFRoaXMsIG92ZXJyaWRlLCBGbGFncyk7CgogICAgVFJBQ0UoIiglcCkgRmxpcHBpbmcgdG8gc3VyZmFjZSAlcFxuIiwgVGhpcywgVGFyZ2V0KTsKCiAgICBpZihUYXJnZXQgPT0gTlVMTCkKICAgIHsKICAgICAgICBFUlIoIiglcCk6IENhbid0IGZsaXAgd2l0aG91dCBhIHRhcmdldFxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogRmxpcCB0aGUgREMgKi8KICAgIHsKICAgICAgICBIREMgdG1wOwogICAgICAgIHRtcCA9IFRoaXMtPmhEQzsKICAgICAgICBUaGlzLT5oREMgPSBUYXJnZXQtPmhEQzsKICAgICAgICBUYXJnZXQtPmhEQyA9IHRtcDsKICAgIH0KCiAgICAvKiBGbGlwIHRoZSBESUJzZWN0aW9uICovCiAgICB7CiAgICAgICAgSEJJVE1BUCB0bXA7CiAgICAgICAgdG1wID0gVGhpcy0+ZGliLkRJQnNlY3Rpb247CiAgICAgICAgVGhpcy0+ZGliLkRJQnNlY3Rpb24gPSBUYXJnZXQtPmRpYi5ESUJzZWN0aW9uOwogICAgICAgIFRhcmdldC0+ZGliLkRJQnNlY3Rpb24gPSB0bXA7CiAgICB9CgogICAgLyogRmxpcCB0aGUgc3VyZmFjZSBkYXRhICovCiAgICB7CiAgICAgICAgdm9pZCogdG1wOwoKICAgICAgICB0bXAgPSBUaGlzLT5kaWIuYml0bWFwX2RhdGE7CiAgICAgICAgVGhpcy0+ZGliLmJpdG1hcF9kYXRhID0gVGFyZ2V0LT5kaWIuYml0bWFwX2RhdGE7CiAgICAgICAgVGFyZ2V0LT5kaWIuYml0bWFwX2RhdGEgPSB0bXA7CgogICAgICAgIHRtcCA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBUYXJnZXQtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICBUYXJnZXQtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IHRtcDsKICAgIH0KCiAgICAvKiBjbGllbnRfbWVtb3J5IHNob3VsZCBub3QgYmUgZGlmZmVyZW50LCBidXQganVzdCBpbiBjYXNlICovCiAgICB7CiAgICAgICAgQk9PTCB0bXA7CiAgICAgICAgdG1wID0gVGhpcy0+ZGliLmNsaWVudF9tZW1vcnk7CiAgICAgICAgVGhpcy0+ZGliLmNsaWVudF9tZW1vcnkgPSBUYXJnZXQtPmRpYi5jbGllbnRfbWVtb3J5OwogICAgICAgIFRhcmdldC0+ZGliLmNsaWVudF9tZW1vcnkgPSB0bXA7CiAgICB9CgogICAgLyogVXNlZnVsIGZvciBkZWJ1Z2dpbmcgKi8KI2lmIDAKICAgICAgICB7CiAgICAgICAgICAgIHN0YXRpYyB1bnNpZ25lZCBpbnQgZ2VuID0gMDsKICAgICAgICAgICAgY2hhciBidWZmZXJbNDA5Nl07CiAgICAgICAgICAgICsrZ2VuOwogICAgICAgICAgICBpZiAoKGdlbiAlIDEwKSA9PSAwKSB7CiAgICAgICAgICAgICAgICBzbnByaW50ZihidWZmZXIsIHNpemVvZihidWZmZXIpLCAiL3RtcC9zdXJmYWNlJXBfdHlwZSV1X2xldmVsJXVfJXUucHBtIiwgVGhpcywgVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIGdlbik7CiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NhdmVTbmFwc2hvdChpZmFjZSwgYnVmZmVyKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBkZWJ1Z2dpbmcgY3Jhc2ggY29kZQogICAgICAgICAgICBpZiAoZ2VuID09IDI1MCkgewogICAgICAgICAgICAgIHZvaWQqKiB0ZXN0ID0gTlVMTDsKICAgICAgICAgICAgICAqdGVzdCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgKi8KICAgICAgICB9CiNlbmRpZgoKICAgIC8qIFVwZGF0ZSB0aGUgc2NyZWVuICovCiAgICB4MTFfY29weV90b19zY3JlZW4oVGhpcywgTlVMTCk7CgogICAgLyogRlBTIHN1cHBvcnQgKi8KICAgIGlmIChUUkFDRV9PTihmcHMpKQogICAgewogICAgICAgIHN0YXRpYyBsb25nIHByZXZfdGltZSwgZnJhbWVzOwoKICAgICAgICBEV09SRCB0aW1lID0gR2V0VGlja0NvdW50KCk7CiAgICAgICAgZnJhbWVzKys7CiAgICAgICAgLyogZXZlcnkgMS41IHNlY29uZHMgKi8KICAgICAgICBpZiAodGltZSAtIHByZXZfdGltZSA+IDE1MDApIHsKICAgICAgICAgICAgVFJBQ0VfKGZwcykoIkAgYXBwcm94ICUuMmZmcHNcbiIsIDEwMDAuMCpmcmFtZXMvKHRpbWUgLSBwcmV2X3RpbWUpKTsKICAgICAgICAgICAgcHJldl90aW1lID0gdGltZTsKICAgICAgICAgICAgZnJhbWVzID0gMDsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfQmx0X0NvbG9yRmlsbAogKgogKiBIZWxwZXIgZnVuY3Rpb24gdGhhdCBmaWxscyBhIG1lbW9yeSBhcmVhIHdpdGggYSBzcGVjaWZpYyBjb2xvcgogKgogKiBQYXJhbXM6CiAqICBidWY6IG1lbW9yeSBhZGRyZXNzIHRvIHN0YXJ0IGZpbGxpbmcgYXQKICogIHdpZHRoLCBoZWlnaHQ6IERpbWVuc2lvbnMgb2YgdGhlIGFyZWEgdG8gZmlsbAogKiAgYnBwOiBCaXQgZGVwdGggb2YgdGhlIHN1cmZhY2UKICogIGxQaXRjaDogcGl0Y2ggb2YgdGhlIHN1cmZhY2UKICogIGNvbG9yOiBDb2xvciB0byBmaWxsIHdpdGgKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApfQmx0X0NvbG9yRmlsbChCWVRFICpidWYsCiAgICAgICAgICAgICAgIGludCB3aWR0aCwgaW50IGhlaWdodCwKICAgICAgICAgICAgICAgaW50IGJwcCwgTE9ORyBsUGl0Y2gsCiAgICAgICAgICAgICAgIERXT1JEIGNvbG9yKQp7CiAgICBpbnQgeCwgeTsKICAgIExQQllURSBmaXJzdDsKCiAgICAvKiBEbyBmaXJzdCByb3cgKi8KCiNkZWZpbmUgQ09MT1JGSUxMX1JPVyh0eXBlKSBcCnsgXAogICAgdHlwZSAqZCA9ICh0eXBlICopIGJ1ZjsgXAogICAgZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KyspIFwKCWRbeF0gPSAodHlwZSkgY29sb3I7IFwKICAgIGJyZWFrOyBcCn0KICAgIHN3aXRjaChicHApCiAgICB7CiAgICAgICAgY2FzZSAxOiBDT0xPUkZJTExfUk9XKEJZVEUpCiAgICAgICAgY2FzZSAyOiBDT0xPUkZJTExfUk9XKFdPUkQpCiAgICAgICAgY2FzZSAzOgogICAgICAgIHsKICAgICAgICAgICAgQllURSAqZCA9IChCWVRFICopIGJ1ZjsKICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KyssZCs9MykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZFswXSA9IChjb2xvciAgICApICYgMHhGRjsKICAgICAgICAgICAgICAgIGRbMV0gPSAoY29sb3I+PiA4KSAmIDB4RkY7CiAgICAgICAgICAgICAgICBkWzJdID0gKGNvbG9yPj4xNikgJiAweEZGOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIDQ6IENPTE9SRklMTF9ST1coRFdPUkQpCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRklYTUUoIkNvbG9yIGZpbGwgbm90IGltcGxlbWVudGVkIGZvciBicHAgJWQhXG4iLCBicHAqOCk7CiAgICAgICAgICAgIHJldHVybiBEREVSUl9VTlNVUFBPUlRFRDsKICAgIH0KCiN1bmRlZiBDT0xPUkZJTExfUk9XCgogICAgLyogTm93IGNvcHkgZmlyc3Qgcm93ICovCiAgICBmaXJzdCA9IGJ1ZjsKICAgIGZvciAoeSA9IDE7IHkgPCBoZWlnaHQ7IHkrKykKICAgIHsKICAgICAgICBidWYgKz0gbFBpdGNoOwogICAgICAgIG1lbWNweShidWYsIGZpcnN0LCB3aWR0aCAqIGJwcCk7CiAgICB9CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRFN1cmZhY2U6OkJsdCwgR0RJIHZlcnNpb24KICoKICogUGVyZm9ybXMgYmxpdHMgdG8gYSBzdXJmYWNlLCBlaWdoZXIgZnJvbSBhIHNvdXJjZSBvZiBzb3VyY2UtbGVzcyBibHRzCiAqIFRoaXMgaXMgdGhlIG1haW4gZnVuY3Rpb25hbGl0eSBvZiBEaXJlY3REcmF3CiAqCiAqIFBhcmFtczoKICogIERlc3RSZWN0OiBEZXN0aW5hdGlvbiByZWN0YW5nbGUgdG8gd3JpdGUgdG8KICogIFNyY1N1cmZhY2U6IFNvdXJjZSBzdXJmYWNlLCBjYW4gYmUgTlVMTAogKiAgU3JjUmVjdDogU291cmNlIHJlY3RhbmdsZQogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkhSRVNVTFQgV0lOQVBJCklXaW5lR0RJU3VyZmFjZUltcGxfQmx0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgIFJFQ1QgKkRlc3RSZWN0LAogICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2UgKlNyY1N1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgIFJFQ1QgKlNyY1JlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICBEREJMVEZYICpEREJsdEZ4KQp7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpTcmMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBTcmNTdXJmYWNlOwogICAgUkVDVAkJeGRzdCx4c3JjOwogICAgSFJFU1VMVAkJcmV0ID0gRERfT0s7CiAgICBXSU5FRDNETE9DS0VEX1JFQ1QgIGRsb2NrLCBzbG9jazsKICAgIFdJTkVEM0RGT1JNQVQgICAgICAgZGZtdCA9IFdJTkVEM0RGTVRfVU5LTk9XTiwgc2ZtdCA9IFdJTkVEM0RGTVRfVU5LTk9XTjsKICAgIGludCBicHAsIHNyY2hlaWdodCwgc3Jjd2lkdGgsIGRzdGhlaWdodCwgZHN0d2lkdGgsIHdpZHRoOwogICAgaW50IHgsIHk7CiAgICBjb25zdCBQaXhlbEZvcm1hdERlc2MgKnNFbnRyeSwgKmRFbnRyeTsKICAgIExQQllURSBkYnVmLCBzYnVmOwogICAgVFJBQ0UoIiglcCktPiglcCwlcCwlcCwleCwlcClcbiIsIFRoaXMsIERlc3RSZWN0LCBTcmMsIFNyY1JlY3QsIEZsYWdzLCBEREJsdEZ4KTsKCiAgICBpZiAoVFJBQ0VfT04oZDNkX3N1cmZhY2UpKQogICAgewogICAgICAgIGlmIChEZXN0UmVjdCkgVFJBQ0UoIlx0ZGVzdHJlY3QgOiVkeCVkLSVkeCVkXG4iLAogICAgICAgIERlc3RSZWN0LT5sZWZ0LCBEZXN0UmVjdC0+dG9wLCBEZXN0UmVjdC0+cmlnaHQsIERlc3RSZWN0LT5ib3R0b20pOwogICAgICAgIGlmIChTcmNSZWN0KSBUUkFDRSgiXHRzcmNyZWN0ICA6JWR4JWQtJWR4JWRcbiIsCiAgICAgICAgU3JjUmVjdC0+bGVmdCwgU3JjUmVjdC0+dG9wLCBTcmNSZWN0LT5yaWdodCwgU3JjUmVjdC0+Ym90dG9tKTsKI2lmIDAKICAgICAgICBUUkFDRSgiXHRmbGFnczogIik7CiAgICAgICAgRERSQVdfZHVtcF9EREJMVChGbGFncyk7CiAgICAgICAgaWYgKEZsYWdzICYgRERCTFRfRERGWCkKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCJcdGJsaXRmeDogIik7CiAgICAgICAgICAgIEREUkFXX2R1bXBfRERCTFRGWChEREJsdEZ4LT5kd0RERlgpOwogICAgICAgIH0KI2VuZGlmCiAgICB9CgogICAgaWYgKCAoVGhpcy0+RmxhZ3MgJiBTRkxBR19MT0NLRUQpIHx8ICgoU3JjICE9IE5VTEwpICYmIChTcmMtPkZsYWdzICYgU0ZMQUdfTE9DS0VEKSkpCiAgICB7CiAgICAgICAgV0FSTigiIFN1cmZhY2UgaXMgYnVzeSwgcmV0dXJuaW5nIERERVJSX1NVUkZBQ0VCVVNZXG4iKTsKICAgICAgICByZXR1cm4gRERFUlJfU1VSRkFDRUJVU1k7CiAgICB9CgogICAgaWYgKFNyYyA9PSBUaGlzKQogICAgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9Mb2NrUmVjdChpZmFjZSwgJmRsb2NrLCBOVUxMLCAwKTsKICAgICAgICBkZm10ID0gVGhpcy0+cmVzb3VyY2UuZm9ybWF0OwogICAgICAgIHNsb2NrID0gZGxvY2s7CiAgICAgICAgc2ZtdCA9IGRmbXQ7CiAgICAgICAgc0VudHJ5ID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KHNmbXQpOwogICAgICAgIGRFbnRyeSA9IHNFbnRyeTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBpZiAoU3JjKQogICAgICAgIHsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KFNyY1N1cmZhY2UsICZzbG9jaywgTlVMTCwgV0lORUQzRExPQ0tfUkVBRE9OTFkpOwogICAgICAgICAgICBzZm10ID0gU3JjLT5yZXNvdXJjZS5mb3JtYXQ7CiAgICAgICAgfQogICAgICAgIHNFbnRyeSA9IGdldEZvcm1hdERlc2NFbnRyeShzZm10KTsKICAgICAgICBkZm10ID0gVGhpcy0+cmVzb3VyY2UuZm9ybWF0OwogICAgICAgIGRFbnRyeSA9IGdldEZvcm1hdERlc2NFbnRyeShkZm10KTsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QoaWZhY2UsICZkbG9jayxOVUxMLDApOwogICAgfQoKICAgIGlmICghRERCbHRGeCB8fCAhKEREQmx0RngtPmR3RERGWCkpIEZsYWdzICY9IH5EREJMVF9EREZYOwoKICAgIGlmIChzRW50cnktPmlzRm91cmNjICYmIGRFbnRyeS0+aXNGb3VyY2MpCiAgICB7CiAgICAgICAgaWYgKHNmbXQgIT0gZGZtdCkKICAgICAgICB7CiAgICAgICAgICAgIEZJWE1FKCJGT1VSQ0MtPkZPVVJDQyBjb3B5IG9ubHkgc3VwcG9ydGVkIGZvciB0aGUgc2FtZSB0eXBlIG9mIHN1cmZhY2VcbiIpOwogICAgICAgICAgICByZXQgPSBEREVSUl9JTlZBTElEUElYRUxGT1JNQVQ7CiAgICAgICAgICAgIGdvdG8gcmVsZWFzZTsKICAgICAgICB9CiAgICAgICAgVFJBQ0UoIkZvdXJjYy0+Rm91cmNjIGNvcHkpXG4iKTsKICAgICAgICBtZW1jcHkoZGxvY2sucEJpdHMsIHNsb2NrLnBCaXRzLCBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQgKiBkbG9jay5QaXRjaCk7CiAgICAgICAgZ290byByZWxlYXNlOwogICAgfQoKICAgIGlmIChzRW50cnktPmlzRm91cmNjICYmICFkRW50cnktPmlzRm91cmNjKQogICAgewogICAgICAgIEZJWE1FKCJEWFRDIGRlY29tcHJlc3Npb24gbm90IHN1cHBvcnRlZCByaWdodCBub3dcbiIpOwogICAgICAgIGdvdG8gcmVsZWFzZTsKICAgIH0KCiAgICBpZiAoRGVzdFJlY3QpCiAgICB7CiAgICAgICAgbWVtY3B5KCZ4ZHN0LERlc3RSZWN0LHNpemVvZih4ZHN0KSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgeGRzdC50b3AJPSAwOwogICAgICAgIHhkc3QuYm90dG9tCT0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgICAgIHhkc3QubGVmdAk9IDA7CiAgICAgICAgeGRzdC5yaWdodAk9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgfQoKICAgIGlmIChTcmNSZWN0KQogICAgewogICAgICAgIG1lbWNweSgmeHNyYyxTcmNSZWN0LHNpemVvZih4c3JjKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaWYgKFNyYykKICAgICAgICB7CiAgICAgICAgICAgIHhzcmMudG9wCT0gMDsKICAgICAgICAgICAgeHNyYy5ib3R0b20JPSBTcmMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICAgICAgeHNyYy5sZWZ0CT0gMDsKICAgICAgICAgICAgeHNyYy5yaWdodAk9IFNyYy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIG1lbXNldCgmeHNyYywwLHNpemVvZih4c3JjKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIEZpcnN0IGNoZWNrIGZvciB0aGUgdmFsaWRpdHkgb2Ygc291cmNlIC8gZGVzdGluYXRpb24gcmVjdGFuZ2xlcy4gVGhpcyB3YXMKICAgICAgdmVyaWZpZWQgdXNpbmcgYSB0ZXN0IGFwcGxpY2F0aW9uICsgYnkgTVNETi4KICAgICovCiAgICBpZiAoKFNyYyAhPSBOVUxMKSAmJgogICAgICAgICgoeHNyYy5ib3R0b20gPiBTcmMtPmN1cnJlbnREZXNjLkhlaWdodCkgfHwgKHhzcmMuYm90dG9tIDwgMCkgfHwKICAgICAgICAoeHNyYy50b3AgICAgID4gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpIHx8ICh4c3JjLnRvcCAgICA8IDApIHx8CiAgICAgICAgKHhzcmMubGVmdCAgICA+IFNyYy0+Y3VycmVudERlc2MuV2lkdGgpICB8fCAoeHNyYy5sZWZ0ICAgPCAwKSB8fAogICAgICAgICh4c3JjLnJpZ2h0ICAgPiBTcmMtPmN1cnJlbnREZXNjLldpZHRoKSAgfHwgKHhzcmMucmlnaHQgIDwgMCkgfHwKICAgICAgICAoeHNyYy5yaWdodCAgIDwgeHNyYy5sZWZ0KSAgICAgICAgICAgICAgIHx8ICh4c3JjLmJvdHRvbSA8IHhzcmMudG9wKSkpCiAgICB7CiAgICAgICAgV0FSTigiQXBwbGljYXRpb24gZ2F2ZSB1cyBiYWQgc291cmNlIHJlY3RhbmdsZSBmb3IgQmx0LlxuIik7CiAgICAgICAgcmV0ID0gRERFUlJfSU5WQUxJRFJFQ1Q7CiAgICAgICAgZ290byByZWxlYXNlOwogICAgfQogICAgLyogRm9yIHRoZSBEZXN0aW5hdGlvbiByZWN0LCBpdCBjYW4gYmUgb3V0IG9mIGJvdW5kcyBvbiB0aGUgY29uZGl0aW9uIHRoYXQgYSBjbGlwcGVyCiAgICAgIGlzIHNldCBmb3IgdGhlIGdpdmVuIHN1cmZhY2UuCiAgICAqLwogICAgaWYgKCgvKlRoaXMtPmNsaXBwZXIgPT0gTlVMTCovIFRSVUUpICYmCiAgICAgICAgKCh4ZHN0LmJvdHRvbSAgPiBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpIHx8ICh4ZHN0LmJvdHRvbSA8IDApIHx8CiAgICAgICAgKHhkc3QudG9wICAgICAgPiBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpIHx8ICh4ZHN0LnRvcCAgICA8IDApIHx8CiAgICAgICAgKHhkc3QubGVmdCAgICAgPiBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCkgIHx8ICh4ZHN0LmxlZnQgICA8IDApIHx8CiAgICAgICAgKHhkc3QucmlnaHQgICAgPiBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCkgIHx8ICh4ZHN0LnJpZ2h0ICA8IDApIHx8CiAgICAgICAgKHhkc3QucmlnaHQgICAgPCB4ZHN0LmxlZnQpICAgICAgICAgICAgICAgIHx8ICh4ZHN0LmJvdHRvbSA8IHhkc3QudG9wKSkpCiAgICB7CiAgICAgICAgV0FSTigiQXBwbGljYXRpb24gZ2F2ZSB1cyBiYWQgZGVzdGluYXRpb24gcmVjdGFuZ2xlIGZvciBCbHQgd2l0aG91dCBhIGNsaXBwZXIgc2V0LlxuIik7CiAgICAgICAgcmV0ID0gRERFUlJfSU5WQUxJRFJFQ1Q7CiAgICAgICAgZ290byByZWxlYXNlOwogICAgfQoKICAgIC8qIE5vdyBoYW5kbGUgbmVnYXRpdmUgdmFsdWVzIGluIHRoZSByZWN0YW5nbGVzLiBXYXJuaW5nOiBvbmx5IHN1cHBvcnRlZCBmb3Igbm93CiAgICAgIGluIHRoZSAnc2ltcGxlJyBjYXNlcyAoaWUgbm90IGluIGFueSBzdHJldGNoaW5nIC8gcm90YXRpb24gY2FzZXMpLgoKICAgICAgRmlyc3QsIHRoZSBjYXNlIHdoZXJlIG5vdGhpbmcgaXMgdG8gYmUgZG9uZS4KICAgICovCiAgICBpZiAoKCh4ZHN0LmJvdHRvbSA8PSAwKSB8fCAoeGRzdC5yaWdodCA8PSAwKSAgICAgICAgIHx8CiAgICAgICAgICh4ZHN0LnRvcCAgICA+PSAoaW50KSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpIHx8CiAgICAgICAgICh4ZHN0LmxlZnQgICA+PSAoaW50KSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCkpIHx8CiAgICAgICAgKChTcmMgIT0gTlVMTCkgJiYKICAgICAgICAoKHhzcmMuYm90dG9tIDw9IDApIHx8ICh4c3JjLnJpZ2h0IDw9IDApICAgICB8fAogICAgICAgICAoeHNyYy50b3AgPj0gKGludCkgU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpIHx8CiAgICAgICAgICh4c3JjLmxlZnQgPj0gKGludCkgU3JjLT5jdXJyZW50RGVzYy5XaWR0aCkpICApKQogICAgewogICAgICAgIFRSQUNFKCJOb3RoaW5nIHRvIGJlIGRvbmUgIVxuIik7CiAgICAgICAgZ290byByZWxlYXNlOwogICAgfQoKICAgIC8qIFRoZSBlYXN5IGNhc2UgOiB0aGUgc291cmNlLWxlc3MgYmxpdHMuLi4uICovCiAgICBpZiAoU3JjID09IE5VTEwpCiAgICB7CiAgICAgICAgUkVDVCBmdWxsX3JlY3Q7CiAgICAgICAgUkVDVCB0ZW1wX3JlY3Q7IC8qIE5vIGlkZWEgaWYgaW50ZXJzZWN0IHJlY3QgY2FuIGJlIHRoZSBzYW1lIGFzIG9uZSBvZiB0aGUgc291cmNlIHJlY3QgKi8KCiAgICAgICAgZnVsbF9yZWN0LmxlZnQgICA9IDA7CiAgICAgICAgZnVsbF9yZWN0LnRvcCAgICA9IDA7CiAgICAgICAgZnVsbF9yZWN0LnJpZ2h0ICA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgIGZ1bGxfcmVjdC5ib3R0b20gPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgSW50ZXJzZWN0UmVjdCgmdGVtcF9yZWN0LCAmZnVsbF9yZWN0LCAmeGRzdCk7CiAgICAgICAgeGRzdCA9IHRlbXBfcmVjdDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAvKiBPbmx5IGhhbmRsZSBjbGlwcGluZyBvbiB0aGUgZGVzdGluYXRpb24gcmVjdGFuZ2xlICovCiAgICAgICAgaW50IGNsaXBfaG9yaXogPSAoeGRzdC5sZWZ0IDwgMCkgfHwgKHhkc3QucmlnaHQgID4gKGludCkgVGhpcy0+Y3VycmVudERlc2MuV2lkdGggKTsKICAgICAgICBpbnQgY2xpcF92ZXJ0ICA9ICh4ZHN0LnRvcCAgPCAwKSB8fCAoeGRzdC5ib3R0b20gPiAoaW50KSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpOwogICAgICAgIGlmIChjbGlwX3ZlcnQgfHwgY2xpcF9ob3JpeikKICAgICAgICB7CiAgICAgICAgICAgIC8qIE5vdyBjaGVjayBpZiB0aGlzIGlzIGEgc3BlY2lhbCBjYXNlIG9yIG5vdC4uLiAqLwogICAgICAgICAgICBpZiAoKCgoeGRzdC5ib3R0b20gLSB4ZHN0LnRvcCApICE9ICh4c3JjLmJvdHRvbSAtIHhzcmMudG9wICkpICYmIGNsaXBfdmVydCApIHx8CiAgICAgICAgICAgICAgICAoKCh4ZHN0LnJpZ2h0ICAtIHhkc3QubGVmdCkgIT0gKHhzcmMucmlnaHQgIC0geHNyYy5sZWZ0KSkgJiYgY2xpcF9ob3JpeikgfHwKICAgICAgICAgICAgICAgIChGbGFncyAmIEREQkxUX0RERlgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXQVJOKCJPdXQgb2Ygc2NyZWVuIHJlY3RhbmdsZSBpbiBzcGVjaWFsIGNhc2UuIE5vdCBoYW5kbGVkIHJpZ2h0IG5vdy5cbiIpOwogICAgICAgICAgICAgICAgZ290byByZWxlYXNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY2xpcF9ob3JpeikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHhkc3QubGVmdCA8IDApIHsgeHNyYy5sZWZ0IC09IHhkc3QubGVmdDsgeGRzdC5sZWZ0ID0gMDsgfQogICAgICAgICAgICAgICAgaWYgKHhkc3QucmlnaHQgPiBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB4c3JjLnJpZ2h0IC09ICh4ZHN0LnJpZ2h0IC0gKGludCkgVGhpcy0+Y3VycmVudERlc2MuV2lkdGgpOwogICAgICAgICAgICAgICAgICAgIHhkc3QucmlnaHQgPSAoaW50KSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY2xpcF92ZXJ0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoeGRzdC50b3AgPCAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHhzcmMudG9wIC09IHhkc3QudG9wOwogICAgICAgICAgICAgICAgICAgIHhkc3QudG9wID0gMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICh4ZHN0LmJvdHRvbSA+IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB4c3JjLmJvdHRvbSAtPSAoeGRzdC5ib3R0b20gLSAoaW50KSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpOwogICAgICAgICAgICAgICAgICAgIHhkc3QuYm90dG9tID0gKGludCkgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIEFuZCBjaGVjayBpZiBhZnRlciBjbGlwcGluZyBzb21ldGhpbmcgaXMgc3RpbGwgdG8gYmUgZG9uZS4uLiAqLwogICAgICAgICAgICBpZiAoKHhkc3QuYm90dG9tIDw9IDApICAgfHwgKHhkc3QucmlnaHQgPD0gMCkgICAgICAgfHwKICAgICAgICAgICAgICAgICh4ZHN0LnRvcCAgID49IChpbnQpIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCkgIHx8CiAgICAgICAgICAgICAgICAoeGRzdC5sZWZ0ICA+PSAoaW50KSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCkgICB8fAogICAgICAgICAgICAgICAgKHhzcmMuYm90dG9tIDw9IDApICAgfHwgKHhzcmMucmlnaHQgPD0gMCkgICAgICAgfHwKICAgICAgICAgICAgICAgICh4c3JjLnRvcCA+PSAoaW50KSBTcmMtPmN1cnJlbnREZXNjLkhlaWdodCkgICAgIHx8CiAgICAgICAgICAgICAgICAoeHNyYy5sZWZ0ID49IChpbnQpIFNyYy0+Y3VycmVudERlc2MuV2lkdGgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBUUkFDRSgiTm90aGluZyB0byBiZSBkb25lIGFmdGVyIGNsaXBwaW5nICFcbiIpOwogICAgICAgICAgICAgICAgZ290byByZWxlYXNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGJwcCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWw7CiAgICBzcmNoZWlnaHQgPSB4c3JjLmJvdHRvbSAtIHhzcmMudG9wOwogICAgc3Jjd2lkdGggPSB4c3JjLnJpZ2h0IC0geHNyYy5sZWZ0OwogICAgZHN0aGVpZ2h0ID0geGRzdC5ib3R0b20gLSB4ZHN0LnRvcDsKICAgIGRzdHdpZHRoID0geGRzdC5yaWdodCAtIHhkc3QubGVmdDsKICAgIHdpZHRoID0gKHhkc3QucmlnaHQgLSB4ZHN0LmxlZnQpICogYnBwOwoKICAgIGFzc2VydCh3aWR0aCA8PSBkbG9jay5QaXRjaCk7CgogICAgZGJ1ZiA9IChCWVRFKilkbG9jay5wQml0cysoeGRzdC50b3AqZGxvY2suUGl0Y2gpKyh4ZHN0LmxlZnQqYnBwKTsKCiAgICBpZiAoRmxhZ3MgJiBEREJMVF9XQUlUKQogICAgewogICAgICAgIHN0YXRpYyBCT09MIGRpc3BsYXllZCA9IEZBTFNFOwogICAgICAgIGlmICghZGlzcGxheWVkKQogICAgICAgICAgICBGSVhNRSgiQ2FuJ3QgaGFuZGxlIEREQkxUX1dBSVQgZmxhZyByaWdodCBub3cuXG4iKTsKICAgICAgICBkaXNwbGF5ZWQgPSBUUlVFOwogICAgICAgIEZsYWdzICY9IH5EREJMVF9XQUlUOwogICAgfQogICAgaWYgKEZsYWdzICYgRERCTFRfQVNZTkMpCiAgICB7CiAgICAgICAgc3RhdGljIEJPT0wgZGlzcGxheWVkID0gRkFMU0U7CiAgICAgICAgaWYgKCFkaXNwbGF5ZWQpCiAgICAgICAgICAgIEZJWE1FKCJDYW4ndCBoYW5kbGUgRERCTFRfQVNZTkMgZmxhZyByaWdodCBub3cuXG4iKTsKICAgICAgICBkaXNwbGF5ZWQgPSBUUlVFOwogICAgICAgIEZsYWdzICY9IH5EREJMVF9BU1lOQzsKICAgIH0KICAgIGlmIChGbGFncyAmIEREQkxUX0RPTk9UV0FJVCkKICAgIHsKICAgICAgICAvKiBEREJMVF9ET05PVFdBSVQgYXBwZWFyZWQgaW4gRFg3ICovCiAgICAgICAgc3RhdGljIEJPT0wgZGlzcGxheWVkID0gRkFMU0U7CiAgICAgICAgaWYgKCFkaXNwbGF5ZWQpCiAgICAgICAgICAgIEZJWE1FKCJDYW4ndCBoYW5kbGUgRERCTFRfRE9OT1RXQUlUIGZsYWcgcmlnaHQgbm93LlxuIik7CiAgICAgICAgZGlzcGxheWVkID0gVFJVRTsKICAgICAgICBGbGFncyAmPSB+RERCTFRfRE9OT1RXQUlUOwogICAgfQoKICAgIC8qIEZpcnN0LCBhbGwgdGhlICdzb3VyY2UtbGVzcycgYmxpdHMgKi8KICAgIGlmIChGbGFncyAmIEREQkxUX0NPTE9SRklMTCkKICAgIHsKICAgICAgICByZXQgPSBfQmx0X0NvbG9yRmlsbChkYnVmLCBkc3R3aWR0aCwgZHN0aGVpZ2h0LCBicHAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkbG9jay5QaXRjaCwgRERCbHRGeC0+dTUuZHdGaWxsQ29sb3IpOwogICAgICAgIEZsYWdzICY9IH5EREJMVF9DT0xPUkZJTEw7CiAgICB9CgogICAgaWYgKEZsYWdzICYgRERCTFRfREVQVEhGSUxMKQogICAgewogICAgICAgIEZJWE1FKCJEREJMVF9ERVBUSEZJTEwgbmVlZHMgdG8gYmUgaW1wbGVtZW50ZWQhXG4iKTsKICAgIH0KICAgIGlmIChGbGFncyAmIEREQkxUX1JPUCkKICAgIHsKICAgICAgICAvKiBDYXRjaCBzb21lIGRlZ2VuZXJhdGUgY2FzZXMgaGVyZSAqLwogICAgICAgIHN3aXRjaChEREJsdEZ4LT5kd1JPUCkKICAgICAgICB7CiAgICAgICAgICAgIGNhc2UgQkxBQ0tORVNTOgogICAgICAgICAgICAgICAgcmV0ID0gX0JsdF9Db2xvckZpbGwoZGJ1Zixkc3R3aWR0aCxkc3RoZWlnaHQsYnBwLGRsb2NrLlBpdGNoLDApOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMHhBQTAwMjk6IC8qIE5vLW9wICovCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBXSElURU5FU1M6CiAgICAgICAgICAgICAgICByZXQgPSBfQmx0X0NvbG9yRmlsbChkYnVmLGRzdHdpZHRoLGRzdGhlaWdodCxicHAsZGxvY2suUGl0Y2gsfjApOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU1JDQ09QWTogLyogd2VsbCwgd2UgZG8gdGhhdCBiZWxvdyA/ICovCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIEZJWE1FKCJVbnN1cHBvcnRlZCByYXN0ZXIgb3A6ICUwOHggIFBhdHRlcm46ICVwXG4iLCBEREJsdEZ4LT5kd1JPUCwgRERCbHRGeC0+dTUubHBERFNQYXR0ZXJuKTsKICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgICAgIEZsYWdzICY9IH5EREJMVF9ST1A7CiAgICB9CiAgICBpZiAoRmxhZ3MgJiBEREJMVF9ERFJPUFMpCiAgICB7CiAgICAgICAgRklYTUUoIlx0RGRyYXcgUmFzdGVyIE9wczogJTA4eCAgUGF0dGVybjogJXBcbiIsIEREQmx0RngtPmR3RERST1AsIEREQmx0RngtPnU1LmxwRERTUGF0dGVybik7CiAgICB9CiAgICAvKiBOb3cgdGhlICd3aXRoIHNvdXJjZScgYmxpdHMgKi8KICAgIGlmIChTcmMpCiAgICB7CiAgICAgICAgTFBCWVRFIHNiYXNlOwogICAgICAgIGludCBzeCwgeGluYywgc3ksIHlpbmM7CgogICAgICAgIGlmICghZHN0d2lkdGggfHwgIWRzdGhlaWdodCkgLyogaG1tLi4uIHN0dXBpZCBwcm9ncmFtID8gKi8KICAgICAgICAgICAgZ290byByZWxlYXNlOwogICAgICAgIHNiYXNlID0gKEJZVEUqKXNsb2NrLnBCaXRzKyh4c3JjLnRvcCpzbG9jay5QaXRjaCkreHNyYy5sZWZ0KmJwcDsKICAgICAgICB4aW5jID0gKHNyY3dpZHRoIDw8IDE2KSAvIGRzdHdpZHRoOwogICAgICAgIHlpbmMgPSAoc3JjaGVpZ2h0IDw8IDE2KSAvIGRzdGhlaWdodDsKCiAgICAgICAgaWYgKCFGbGFncykKICAgICAgICB7CiAgICAgICAgICAgIC8qIE5vIGVmZmVjdHMsIHdlIGNhbiBjaGVhdCBoZXJlICovCiAgICAgICAgICAgIGlmIChkc3R3aWR0aCA9PSBzcmN3aWR0aCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGRzdGhlaWdodCA9PSBzcmNoZWlnaHQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogTm8gc3RyZXRjaGluZyBpbiBlaXRoZXIgZGlyZWN0aW9uLiBUaGlzIG5lZWRzIHRvIGJlIGFzCiAgICAgICAgICAgICAgICAgICAgKiBmYXN0IGFzIHBvc3NpYmxlICovCiAgICAgICAgICAgICAgICAgICAgc2J1ZiA9IHNiYXNlOwoKICAgICAgICAgICAgICAgICAgICAvKiBjaGVjayBmb3Igb3ZlcmxhcHBpbmcgc3VyZmFjZXMgKi8KICAgICAgICAgICAgICAgICAgICBpZiAoU3JjU3VyZmFjZSAhPSBpZmFjZSB8fCB4ZHN0LnRvcCA8IHhzcmMudG9wIHx8CiAgICAgICAgICAgICAgICAgICAgICAgIHhkc3QucmlnaHQgPD0geHNyYy5sZWZ0IHx8IHhzcmMucmlnaHQgPD0geGRzdC5sZWZ0KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogbm8gb3ZlcmxhcCwgb3IgZHN0IGFib3ZlIHNyYywgc28gY29weSBmcm9tIHRvcCBkb3dud2FyZHMgKi8KICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh5ID0gMDsgeSA8IGRzdGhlaWdodDsgeSsrKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW1jcHkoZGJ1Ziwgc2J1Ziwgd2lkdGgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2J1ZiArPSBzbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRidWYgKz0gZGxvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoeGRzdC50b3AgPiB4c3JjLnRvcCkgIC8qIGNvcHkgZnJvbSBib3R0b20gdXB3YXJkcyAqLwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2J1ZiArPSAoc2xvY2suUGl0Y2gqZHN0aGVpZ2h0KTsKICAgICAgICAgICAgICAgICAgICAgICAgZGJ1ZiArPSAoZGxvY2suUGl0Y2gqZHN0aGVpZ2h0KTsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh5ID0gMDsgeSA8IGRzdGhlaWdodDsgeSsrKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYnVmIC09IHNsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGJ1ZiAtPSBkbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lbWNweShkYnVmLCBzYnVmLCB3aWR0aCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSAvKiBzcmMgYW5kIGRzdCBvdmVybGFwcGluZyBvbiB0aGUgc2FtZSBsaW5lLCB1c2UgbWVtbW92ZSAqLwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh5ID0gMDsgeSA8IGRzdGhlaWdodDsgeSsrKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW1tb3ZlKGRidWYsIHNidWYsIHdpZHRoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNidWYgKz0gc2xvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYnVmICs9IGRsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvKiBTdHJldGNoaW5nIGluIFkgZGlyZWN0aW9uIG9ubHkgKi8KICAgICAgICAgICAgICAgICAgICBmb3IgKHkgPSBzeSA9IDA7IHkgPCBkc3RoZWlnaHQ7IHkrKywgc3kgKz0geWluYykgewogICAgICAgICAgICAgICAgICAgICAgICBzYnVmID0gc2Jhc2UgKyAoc3kgPj4gMTYpICogc2xvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgICAgIG1lbWNweShkYnVmLCBzYnVmLCB3aWR0aCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGRidWYgKz0gZGxvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogU3RyZXRjaGluZyBpbiBYIGRpcmVjdGlvbiAqLwogICAgICAgICAgICAgICAgaW50IGxhc3Rfc3kgPSAtMTsKICAgICAgICAgICAgICAgIGZvciAoeSA9IHN5ID0gMDsgeSA8IGRzdGhlaWdodDsgeSsrLCBzeSArPSB5aW5jKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNidWYgPSBzYmFzZSArIChzeSA+PiAxNikgKiBzbG9jay5QaXRjaDsKCiAgICAgICAgICAgICAgICAgICAgaWYgKChzeSA+PiAxNikgPT0gKGxhc3Rfc3kgPj4gMTYpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogdGhpcyBzb3VyY2Vyb3cgaXMgdGhlIHNhbWUgYXMgbGFzdCBzb3VyY2Vyb3cgLQogICAgICAgICAgICAgICAgICAgICAgICAgKiBjb3B5IGFscmVhZHkgc3RyZXRjaGVkIHJvdwogICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgbWVtY3B5KGRidWYsIGRidWYgLSBkbG9jay5QaXRjaCwgd2lkdGgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewojZGVmaW5lIFNUUkVUQ0hfUk9XKHR5cGUpIHsgXAogICAgICAgICAgICAgICAgICAgIHR5cGUgKnMgPSAodHlwZSAqKSBzYnVmLCAqZCA9ICh0eXBlICopIGRidWY7IFwKICAgICAgICAgICAgICAgICAgICBmb3IgKHggPSBzeCA9IDA7IHggPCBkc3R3aWR0aDsgeCsrLCBzeCArPSB4aW5jKSBcCiAgICAgICAgICAgICAgICAgICAgZFt4XSA9IHNbc3ggPj4gMTZdOyBcCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7IH0KCiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKGJwcCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTogU1RSRVRDSF9ST1coQllURSkKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyOiBTVFJFVENIX1JPVyhXT1JEKQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDQ6IFNUUkVUQ0hfUk9XKERXT1JEKQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQllURSBzLGQgPSBkYnVmOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh4ID0gc3ggPSAwOyB4IDwgZHN0d2lkdGg7IHgrKywgc3grPSB4aW5jKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIHBpeGVsOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gc2J1ZiszKihzeD4+MTYpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpeGVsID0gc1swXXwoc1sxXTw8OCl8KHNbMl08PDE2KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkWzBdID0gKHBpeGVsICAgICkmMHhmZjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkWzFdID0gKHBpeGVsPj4gOCkmMHhmZjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkWzJdID0gKHBpeGVsPj4xNikmMHhmZjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkKz0zOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIEZJWE1FKCJTdHJldGNoZWQgYmxpdCBub3QgaW1wbGVtZW50ZWQgZm9yIGJwcCAlZCFcbiIsIGJwcCo4KTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0ID0gRERFUlJfVU5TVVBQT1JURUQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgICAgICAgICAgICAgfQojdW5kZWYgU1RSRVRDSF9ST1cKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZGJ1ZiArPSBkbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICBsYXN0X3N5ID0gc3k7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgIExPTkcgZHN0eWluYyA9IGRsb2NrLlBpdGNoLCBkc3R4aW5jID0gYnBwOwogICAgICAgICAgRFdPUkQga2V5bG93ID0gMHhGRkZGRkZGRiwga2V5aGlnaCA9IDAsIGtleW1hc2sgPSAweEZGRkZGRkZGOwogICAgICAgICAgRFdPUkQgZGVzdGtleWxvdyA9IDB4MCwgZGVzdGtleWhpZ2ggPSAweEZGRkZGRkZGLCBkZXN0a2V5bWFzayA9IDB4RkZGRkZGRkY7CiAgICAgICAgICBpZiAoRmxhZ3MgJiAoRERCTFRfS0VZU1JDIHwgRERCTFRfS0VZREVTVCB8IEREQkxUX0tFWVNSQ09WRVJSSURFIHwgRERCTFRfS0VZREVTVE9WRVJSSURFKSkKICAgICAgICAgIHsKICAgICAgICAgICAgICAvKiBUaGUgY29sb3Iga2V5aW5nIGZsYWdzIGFyZSBjaGVja2VkIGZvciBjb3JyZWN0bmVzcyBpbiBkZHJhdyAqLwogICAgICAgICAgICAgIGlmIChGbGFncyAmIEREQkxUX0tFWVNSQykKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBrZXlsb3cgID0gU3JjLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlOwogICAgICAgICAgICAgICAga2V5aGlnaCA9IFNyYy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWU7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGVsc2UgIGlmIChGbGFncyAmIEREQkxUX0tFWVNSQ09WRVJSSURFKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGtleWxvdyAgPSBEREJsdEZ4LT5kZGNrU3JjQ29sb3JrZXkuZHdDb2xvclNwYWNlTG93VmFsdWU7CiAgICAgICAgICAgICAgICBrZXloaWdoID0gRERCbHRGeC0+ZGRja1NyY0NvbG9ya2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIGlmIChGbGFncyAmIEREQkxUX0tFWURFU1QpCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogRGVzdGluYXRpb24gY29sb3Iga2V5cyBhcmUgdGFrZW4gZnJvbSB0aGUgc291cmNlIHN1cmZhY2UgISAqLwogICAgICAgICAgICAgICAgZGVzdGtleWxvdyAgPSBTcmMtPkRlc3RCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlOwogICAgICAgICAgICAgICAgZGVzdGtleWhpZ2ggPSBTcmMtPkRlc3RCbHRDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgZWxzZSBpZiAoRmxhZ3MgJiBEREJMVF9LRVlERVNUT1ZFUlJJREUpCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZGVzdGtleWxvdyAgPSBEREJsdEZ4LT5kZGNrRGVzdENvbG9ya2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlOwogICAgICAgICAgICAgICAgZGVzdGtleWhpZ2ggPSBEREJsdEZ4LT5kZGNrRGVzdENvbG9ya2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIGlmKGJwcCA9PSAxKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAga2V5bWFzayA9IDB4ZmY7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgIGtleW1hc2sgPSBzRW50cnktPnJlZE1hc2sgICB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzRW50cnktPmdyZWVuTWFzayB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzRW50cnktPmJsdWVNYXNrOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBGbGFncyAmPSB+KEREQkxUX0tFWVNSQyB8IEREQkxUX0tFWURFU1QgfCBEREJMVF9LRVlTUkNPVkVSUklERSB8IEREQkxUX0tFWURFU1RPVkVSUklERSk7CiAgICAgICAgICB9CgogICAgICAgICAgaWYgKEZsYWdzICYgRERCTFRfRERGWCkKICAgICAgICAgIHsKICAgICAgICAgICAgICBMUEJZVEUgZFRvcExlZnQsIGRUb3BSaWdodCwgZEJvdHRvbUxlZnQsIGRCb3R0b21SaWdodCwgdG1wOwogICAgICAgICAgICAgIExPTkcgdG1weHk7CiAgICAgICAgICAgICAgZFRvcExlZnQgICAgID0gZGJ1ZjsKICAgICAgICAgICAgICBkVG9wUmlnaHQgICAgPSBkYnVmKygoZHN0d2lkdGgtMSkqYnBwKTsKICAgICAgICAgICAgICBkQm90dG9tTGVmdCAgPSBkVG9wTGVmdCsoKGRzdGhlaWdodC0xKSpkbG9jay5QaXRjaCk7CiAgICAgICAgICAgICAgZEJvdHRvbVJpZ2h0ID0gZEJvdHRvbUxlZnQrKChkc3R3aWR0aC0xKSpicHApOwoKICAgICAgICAgICAgICBpZiAoRERCbHRGeC0+ZHdEREZYICYgRERCTFRGWF9BUklUSFNUUkVUQ0hZKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIEkgZG9uJ3QgdGhpbmsgd2UgbmVlZCB0byBkbyBhbnl0aGluZyBhYm91dCB0aGlzIGZsYWcgKi8KICAgICAgICAgICAgICAgIFdBUk4oIkZsYWdzPUREQkxUX0RERlggbm90aGluZyBkb25lIGZvciBEREJMVEZYX0FSSVRIU1RSRVRDSFlcbiIpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZiAoRERCbHRGeC0+ZHdEREZYICYgRERCTFRGWF9NSVJST1JMRUZUUklHSFQpCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdG1wICAgICAgICAgID0gZFRvcFJpZ2h0OwogICAgICAgICAgICAgICAgZFRvcFJpZ2h0ICAgID0gZFRvcExlZnQ7CiAgICAgICAgICAgICAgICBkVG9wTGVmdCAgICAgPSB0bXA7CiAgICAgICAgICAgICAgICB0bXAgICAgICAgICAgPSBkQm90dG9tUmlnaHQ7CiAgICAgICAgICAgICAgICBkQm90dG9tUmlnaHQgPSBkQm90dG9tTGVmdDsKICAgICAgICAgICAgICAgIGRCb3R0b21MZWZ0ICA9IHRtcDsKICAgICAgICAgICAgICAgIGRzdHhpbmMgPSBkc3R4aW5jICotMTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgaWYgKEREQmx0RngtPmR3RERGWCAmIEREQkxURlhfTUlSUk9SVVBET1dOKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRtcCAgICAgICAgICA9IGRUb3BMZWZ0OwogICAgICAgICAgICAgICAgZFRvcExlZnQgICAgID0gZEJvdHRvbUxlZnQ7CiAgICAgICAgICAgICAgICBkQm90dG9tTGVmdCAgPSB0bXA7CiAgICAgICAgICAgICAgICB0bXAgICAgICAgICAgPSBkVG9wUmlnaHQ7CiAgICAgICAgICAgICAgICBkVG9wUmlnaHQgICAgPSBkQm90dG9tUmlnaHQ7CiAgICAgICAgICAgICAgICBkQm90dG9tUmlnaHQgPSB0bXA7CiAgICAgICAgICAgICAgICBkc3R5aW5jID0gZHN0eWluYyAqLTE7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGlmIChEREJsdEZ4LT5kd0RERlggJiBEREJMVEZYX05PVEVBUklORykKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBJIGRvbid0IHRoaW5rIHdlIG5lZWQgdG8gZG8gYW55dGhpbmcgYWJvdXQgdGhpcyBmbGFnICovCiAgICAgICAgICAgICAgICBXQVJOKCJGbGFncz1EREJMVF9EREZYIG5vdGhpbmcgZG9uZSBmb3IgRERCTFRGWF9OT1RFQVJJTkdcbiIpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZiAoRERCbHRGeC0+ZHdEREZYICYgRERCTFRGWF9ST1RBVEUxODApCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdG1wICAgICAgICAgID0gZEJvdHRvbVJpZ2h0OwogICAgICAgICAgICAgICAgZEJvdHRvbVJpZ2h0ID0gZFRvcExlZnQ7CiAgICAgICAgICAgICAgICBkVG9wTGVmdCAgICAgPSB0bXA7CiAgICAgICAgICAgICAgICB0bXAgICAgICAgICAgPSBkQm90dG9tTGVmdDsKICAgICAgICAgICAgICAgIGRCb3R0b21MZWZ0ICA9IGRUb3BSaWdodDsKICAgICAgICAgICAgICAgIGRUb3BSaWdodCAgICA9IHRtcDsKICAgICAgICAgICAgICAgIGRzdHhpbmMgPSBkc3R4aW5jICogLTE7CiAgICAgICAgICAgICAgICBkc3R5aW5jID0gZHN0eWluYyAqIC0xOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZiAoRERCbHRGeC0+ZHdEREZYICYgRERCTFRGWF9ST1RBVEUyNzApCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdG1wICAgICAgICAgID0gZFRvcExlZnQ7CiAgICAgICAgICAgICAgICBkVG9wTGVmdCAgICAgPSBkQm90dG9tTGVmdDsKICAgICAgICAgICAgICAgIGRCb3R0b21MZWZ0ICA9IGRCb3R0b21SaWdodDsKICAgICAgICAgICAgICAgIGRCb3R0b21SaWdodCA9IGRUb3BSaWdodDsKICAgICAgICAgICAgICAgIGRUb3BSaWdodCAgICA9IHRtcDsKICAgICAgICAgICAgICAgIHRtcHh5ICAgPSBkc3R4aW5jOwogICAgICAgICAgICAgICAgZHN0eGluYyA9IGRzdHlpbmM7CiAgICAgICAgICAgICAgICBkc3R5aW5jID0gdG1weHk7CiAgICAgICAgICAgICAgICBkc3R4aW5jID0gZHN0eGluYyAqIC0xOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZiAoRERCbHRGeC0+ZHdEREZYICYgRERCTFRGWF9ST1RBVEU5MCkKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0bXAgICAgICAgICAgPSBkVG9wTGVmdDsKICAgICAgICAgICAgICAgIGRUb3BMZWZ0ICAgICA9IGRUb3BSaWdodDsKICAgICAgICAgICAgICAgIGRUb3BSaWdodCAgICA9IGRCb3R0b21SaWdodDsKICAgICAgICAgICAgICAgIGRCb3R0b21SaWdodCA9IGRCb3R0b21MZWZ0OwogICAgICAgICAgICAgICAgZEJvdHRvbUxlZnQgID0gdG1wOwogICAgICAgICAgICAgICAgdG1weHkgICA9IGRzdHhpbmM7CiAgICAgICAgICAgICAgICBkc3R4aW5jID0gZHN0eWluYzsKICAgICAgICAgICAgICAgIGRzdHlpbmMgPSB0bXB4eTsKICAgICAgICAgICAgICAgIGRzdHlpbmMgPSBkc3R5aW5jICogLTE7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGlmIChEREJsdEZ4LT5kd0RERlggJiBEREJMVEZYX1pCVUZGRVJCQVNFREVTVCkKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBJIGRvbid0IHRoaW5rIHdlIG5lZWQgdG8gZG8gYW55dGhpbmcgYWJvdXQgdGhpcyBmbGFnICovCiAgICAgICAgICAgICAgICBXQVJOKCJGbGFncz1EREJMVF9EREZYIG5vdGhpbmcgZG9uZSBmb3IgRERCTFRGWF9aQlVGRkVSQkFTRURFU1RcbiIpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBkYnVmID0gZFRvcExlZnQ7CiAgICAgICAgICAgICAgRmxhZ3MgJj0gfihEREJMVF9EREZYKTsKICAgICAgICAgIH0KCiNkZWZpbmUgQ09QWV9DT0xPUktFWV9GWCh0eXBlKSB7IFwKICAgICAgICAgICAgdHlwZSAqcywgKmQgPSAodHlwZSAqKSBkYnVmLCAqZHgsIHRtcDsgXAogICAgICAgICAgICBmb3IgKHkgPSBzeSA9IDA7IHkgPCBkc3RoZWlnaHQ7IHkrKywgc3kgKz0geWluYykgeyBcCiAgICAgICAgICAgICAgcyA9ICh0eXBlKikoc2Jhc2UgKyAoc3kgPj4gMTYpICogc2xvY2suUGl0Y2gpOyBcCiAgICAgICAgICAgICAgZHggPSBkOyBcCiAgICAgICAgICAgICAgZm9yICh4ID0gc3ggPSAwOyB4IDwgZHN0d2lkdGg7IHgrKywgc3ggKz0geGluYykgeyBcCiAgICAgICAgICAgICAgICAgIHRtcCA9IHNbc3ggPj4gMTZdOyBcCiAgICAgICAgICAgICAgICAgIGlmICgoKHRtcCAmIGtleW1hc2spIDwga2V5bG93IHx8ICh0bXAgJiBrZXltYXNrKSA+IGtleWhpZ2gpICYmIFwKICAgICAgICAgICAgICAgICAgICAgICgoZHhbMF0gJiBkZXN0a2V5bWFzaykgPj0gZGVzdGtleWxvdyAmJiAoZHhbMF0gJiBkZXN0a2V5bWFzaykgPD0gZGVzdGtleWhpZ2gpKSB7IFwKICAgICAgICAgICAgICAgICAgICAgICBkeFswXSA9IHRtcDsgXAogICAgICAgICAgICAgICAgICAgICB9IFwKICAgICAgICAgICAgICAgICAgZHggPSAodHlwZSopKCgoTFBCWVRFKWR4KStkc3R4aW5jKTsgXAogICAgICAgICAgICAgIH0gXAogICAgICAgICAgICAgIGQgPSAodHlwZSopKCgoTFBCWVRFKWQpK2RzdHlpbmMpOyBcCiAgICAgICAgICAgIH0gXAogICAgICAgICAgICBicmVhazsgfQoKICAgICAgICAgICAgc3dpdGNoIChicHApIHsKICAgICAgICAgICAgY2FzZSAxOiBDT1BZX0NPTE9SS0VZX0ZYKEJZVEUpCiAgICAgICAgICAgIGNhc2UgMjogQ09QWV9DT0xPUktFWV9GWChXT1JEKQogICAgICAgICAgICBjYXNlIDQ6IENPUFlfQ09MT1JLRVlfRlgoRFdPUkQpCiAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTFBCWVRFIHMsZCA9IGRidWYsIGR4OwogICAgICAgICAgICAgICAgZm9yICh5ID0gc3kgPSAwOyB5IDwgZHN0aGVpZ2h0OyB5KyssIHN5ICs9IHlpbmMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc2J1ZiA9IHNiYXNlICsgKHN5ID4+IDE2KSAqIHNsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgIGR4ID0gZDsKICAgICAgICAgICAgICAgICAgICBmb3IgKHggPSBzeCA9IDA7IHggPCBkc3R3aWR0aDsgeCsrLCBzeCs9IHhpbmMpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBwaXhlbCwgZHBpeGVsID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgcyA9IHNidWYrMyooc3g+PjE2KTsKICAgICAgICAgICAgICAgICAgICAgICAgcGl4ZWwgPSBzWzBdfChzWzFdPDw4KXwoc1syXTw8MTYpOwogICAgICAgICAgICAgICAgICAgICAgICBkcGl4ZWwgPSBkeFswXXwoZHhbMV08PDgpfChkeFsyXTw8MTYpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoKChwaXhlbCAmIGtleW1hc2spIDwga2V5bG93IHx8IChwaXhlbCAmIGtleW1hc2spID4ga2V5aGlnaCkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoZHBpeGVsICYga2V5bWFzaykgPj0gZGVzdGtleWxvdyB8fCAoZHBpeGVsICYga2V5bWFzaykgPD0ga2V5aGlnaCkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR4WzBdID0gKHBpeGVsICAgICkmMHhmZjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR4WzFdID0gKHBpeGVsPj4gOCkmMHhmZjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR4WzJdID0gKHBpeGVsPj4xNikmMHhmZjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBkeCs9IGRzdHhpbmM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGQgKz0gZHN0eWluYzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgRklYTUUoIiVzIGNvbG9yLWtleWVkIGJsaXQgbm90IGltcGxlbWVudGVkIGZvciBicHAgJWQhXG4iLAogICAgICAgICAgICAgICAgICAoRmxhZ3MgJiBEREJMVF9LRVlTUkMpID8gIlNvdXJjZSIgOiAiRGVzdGluYXRpb24iLCBicHAqOCk7CiAgICAgICAgICAgICAgICAgIHJldCA9IERERVJSX1VOU1VQUE9SVEVEOwogICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOwojdW5kZWYgQ09QWV9DT0xPUktFWV9GWAogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKZXJyb3I6CiAgICBpZiAoRmxhZ3MgJiYgRklYTUVfT04oZDNkX3N1cmZhY2UpKQogICAgewogICAgICAgIEZJWE1FKCJcdFVuc3VwcG9ydGVkIGZsYWdzOiAlMDh4XG4iLCBGbGFncyk7CiAgICB9CgpyZWxlYXNlOgogICAgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QoaWZhY2UpOwogICAgaWYgKFNyY1N1cmZhY2UgJiYgU3JjU3VyZmFjZSAhPSBpZmFjZSkgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QoU3JjU3VyZmFjZSk7CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0RTdXJmYWNlOjpCbHRGYXN0LCBHREkgdmVyc2lvbgogKgogKiBUaGlzIGlzIHRoZSBzb2Z0d2FyZSBpbXBsZW1lbnRhdGlvbiBvZiBCbHRGYXN0LCBhcyB1c2VkIGJ5IEdESSBzdXJmYWNlcwogKiBhbmQgYXMgYSBmYWxsYmFjayBmb3IgT3BlbkdMIHN1cmZhY2VzLiBUaGlzIGNvZGUgaXMgdGFrZW4gZnJvbSB0aGUgb2xkCiAqIERpcmVjdERyYXcgY29kZSwgYW5kIHdhcyBvcmlnaW5hbGx5IHdyaXR0ZW4gYnkgVHJhbnNHYW1pbmcuCiAqCiAqIFBhcmFtczoKICogIGRzdHg6CiAqICBkc3R5OgogKiAgU291cmNlOiBTb3VyY2Ugc3VyZmFjZSB0byBjb3B5IGZyb20KICogIHJzcmM6IFNvdXJjZSByZWN0YW5nbGUKICogIHRyYW5zOiBTb21lIEZsYWdzCiAqCiAqIFJldHVybnM6CiAqICBXSU5FRDNEX09LIG9uIHN1Y2Nlc3MKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpIUkVTVUxUIFdJTkFQSQpJV2luZUdESVN1cmZhY2VJbXBsX0JsdEZhc3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGRzdHgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkc3R5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlICpTb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUNUICpyc3JjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgdHJhbnMpCnsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlNyYyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFNvdXJjZTsKCiAgICBpbnQgICAgICAgICAgICAgICAgIGJwcCwgdywgaCwgeCwgeTsKICAgIFdJTkVEM0RMT0NLRURfUkVDVCAgZGxvY2ssc2xvY2s7CiAgICBIUkVTVUxUICAgICAgICAgICAgIHJldCA9IEREX09LOwogICAgUkVDVCAgICAgICAgICAgICAgICByc3JjMjsKICAgIFJFQ1QgICAgICAgICAgICAgICAgbG9ja19zcmMsIGxvY2tfZHN0LCBsb2NrX3VuaW9uOwogICAgQllURSAgICAgICAgICAgICAgICAqc2J1ZiwgKmRidWY7CiAgICBjb25zdCBQaXhlbEZvcm1hdERlc2MgKnNFbnRyeSwgKmRFbnRyeTsKCiAgICBpZiAoVFJBQ0VfT04oZDNkX3N1cmZhY2UpKQogICAgewogICAgICAgIFRSQUNFKCIoJXApLT4oJWQsJWQsJXAsJXAsJTA4eClcbiIsIFRoaXMsZHN0eCxkc3R5LFNyYyxyc3JjLHRyYW5zKTsKCiAgICAgICAgaWYgKHJzcmMpCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiXHRzcmNyZWN0OiAlZHglZC0lZHglZFxuIixyc3JjLT5sZWZ0LHJzcmMtPnRvcCwKICAgICAgICAgICAgICAgICAgcnNyYy0+cmlnaHQscnNyYy0+Ym90dG9tKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIiBzcmNyZWN0OiBOVUxMXG4iKTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKChUaGlzLT5GbGFncyAmIFNGTEFHX0xPQ0tFRCkgfHwKICAgICAgICAoKFNyYyAhPSBOVUxMKSAmJiAoU3JjLT5GbGFncyAmIFNGTEFHX0xPQ0tFRCkpKQogICAgewogICAgICAgIFdBUk4oIiBTdXJmYWNlIGlzIGJ1c3ksIHJldHVybmluZyBEREVSUl9TVVJGQUNFQlVTWVxuIik7CiAgICAgICAgcmV0dXJuIERERVJSX1NVUkZBQ0VCVVNZOwogICAgfQoKICAgIGlmICghcnNyYykKICAgIHsKICAgICAgICBXQVJOKCJyc3JjIGlzIE5VTEwhXG4iKTsKICAgICAgICByc3JjID0gJnJzcmMyOwogICAgICAgIHJzcmMtPmxlZnQgPSAwOwogICAgICAgIHJzcmMtPnRvcCA9IDA7CiAgICAgICAgcnNyYy0+cmlnaHQgPSBTcmMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgIHJzcmMtPmJvdHRvbSA9IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgfQoKICAgIC8qIENoZWNrIHNvdXJjZSByZWN0IGZvciB2YWxpZGl0eS4gQ29waWVkIGZyb20gbm9ybWFsIEJsdC4gRml4ZXMgQmFsZHVyJ3MgR2F0ZS4qLwogICAgaWYgKChyc3JjLT5ib3R0b20gPiBTcmMtPmN1cnJlbnREZXNjLkhlaWdodCkgfHwgKHJzcmMtPmJvdHRvbSA8IDApIHx8CiAgICAgICAgKHJzcmMtPnRvcCAgICA+IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0KSB8fCAocnNyYy0+dG9wICAgIDwgMCkgfHwKICAgICAgICAocnNyYy0+bGVmdCAgID4gU3JjLT5jdXJyZW50RGVzYy5XaWR0aCkgIHx8IChyc3JjLT5sZWZ0ICAgPCAwKSB8fAogICAgICAgIChyc3JjLT5yaWdodCAgPiBTcmMtPmN1cnJlbnREZXNjLldpZHRoKSAgfHwgKHJzcmMtPnJpZ2h0ICA8IDApIHx8CiAgICAgICAgKHJzcmMtPnJpZ2h0ICA8IHJzcmMtPmxlZnQpICAgICAgICAgICAgICB8fCAocnNyYy0+Ym90dG9tIDwgcnNyYy0+dG9wKSkKICAgIHsKICAgICAgICBXQVJOKCJBcHBsaWNhdGlvbiBnYXZlIHVzIGJhZCBzb3VyY2UgcmVjdGFuZ2xlIGZvciBCbHRGYXN0LlxuIik7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURSRUNUOwogICAgfQoKICAgIGggPSByc3JjLT5ib3R0b20gLSByc3JjLT50b3A7CiAgICBpZiAoaCA+IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodC1kc3R5KSBoID0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0LWRzdHk7CiAgICBpZiAoaCA+IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0LXJzcmMtPnRvcCkgaD1TcmMtPmN1cnJlbnREZXNjLkhlaWdodC1yc3JjLT50b3A7CiAgICBpZiAoaCA8PSAwKSByZXR1cm4gRERFUlJfSU5WQUxJRFJFQ1Q7CgogICAgdyA9IHJzcmMtPnJpZ2h0IC0gcnNyYy0+bGVmdDsKICAgIGlmICh3ID4gVGhpcy0+Y3VycmVudERlc2MuV2lkdGgtZHN0eCkgdyA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoLWRzdHg7CiAgICBpZiAodyA+IFNyYy0+Y3VycmVudERlc2MuV2lkdGgtcnNyYy0+bGVmdCkgdyA9IFNyYy0+Y3VycmVudERlc2MuV2lkdGgtcnNyYy0+bGVmdDsKICAgIGlmICh3IDw9IDApIHJldHVybiBEREVSUl9JTlZBTElEUkVDVDsKCiAgICAvKiBOb3cgY29tcHV0ZSB0aGUgbG9ja2luZyByZWN0YW5nbGUuLi4gKi8KICAgIGxvY2tfc3JjLmxlZnQgPSByc3JjLT5sZWZ0OwogICAgbG9ja19zcmMudG9wID0gcnNyYy0+dG9wOwogICAgbG9ja19zcmMucmlnaHQgPSBsb2NrX3NyYy5sZWZ0ICsgdzsKICAgIGxvY2tfc3JjLmJvdHRvbSA9IGxvY2tfc3JjLnRvcCArIGg7CgogICAgbG9ja19kc3QubGVmdCA9IGRzdHg7CiAgICBsb2NrX2RzdC50b3AgPSBkc3R5OwogICAgbG9ja19kc3QucmlnaHQgPSBkc3R4ICsgdzsKICAgIGxvY2tfZHN0LmJvdHRvbSA9IGRzdHkgKyBoOwoKICAgIGJwcCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWw7CgogICAgLyogV2UgbmVlZCB0byBsb2NrIHRoZSBzdXJmYWNlcywgb3Igd2Ugd29uJ3QgZ2V0IHJlZnJlc2hlcyB3aGVuIGRvbmUuICovCiAgICBpZiAoU3JjID09IFRoaXMpCiAgICB7CiAgICAgICAgaW50IHBpdGNoOwoKICAgICAgICBVbmlvblJlY3QoJmxvY2tfdW5pb24sICZsb2NrX3NyYywgJmxvY2tfZHN0KTsKCiAgICAgICAgLyogTG9jayB0aGUgdW5pb24gb2YgdGhlIHR3byByZWN0YW5nbGVzICovCiAgICAgICAgcmV0ID0gSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KGlmYWNlLCAmZGxvY2ssICZsb2NrX3VuaW9uLCAwKTsKICAgICAgICBpZihyZXQgIT0gV0lORUQzRF9PSykgZ290byBlcnJvcjsKCiAgICAgICAgcGl0Y2ggPSBkbG9jay5QaXRjaDsKICAgICAgICBzbG9jay5QaXRjaCA9IGRsb2NrLlBpdGNoOwoKICAgICAgICAvKiBTaW5jZSBzbG9jayB3YXMgb3JpZ2luYWxseSBjb3BpZWQgZnJvbSB0aGlzIHN1cmZhY2UncyBkZXNjcmlwdGlvbiwgd2UgY2FuIGp1c3QgcmV1c2UgaXQgKi8KICAgICAgICBhc3NlcnQoVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICE9IE5VTEwpOwogICAgICAgIHNidWYgPSAoQllURSAqKVRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSArIGxvY2tfc3JjLnRvcCAqIHBpdGNoICsgbG9ja19zcmMubGVmdCAqIGJwcDsKICAgICAgICBkYnVmID0gKEJZVEUgKilUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgKyBsb2NrX2RzdC50b3AgKiBwaXRjaCArIGxvY2tfZHN0LmxlZnQgKiBicHA7CiAgICAgICAgc0VudHJ5ID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KFNyYy0+cmVzb3VyY2UuZm9ybWF0KTsKICAgICAgICBkRW50cnkgPSBzRW50cnk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgcmV0ID0gSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KFNvdXJjZSwgJnNsb2NrLCAmbG9ja19zcmMsIFdJTkVEM0RMT0NLX1JFQURPTkxZKTsKICAgICAgICBpZihyZXQgIT0gV0lORUQzRF9PSykgZ290byBlcnJvcjsKICAgICAgICByZXQgPSBJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QoaWZhY2UsICZkbG9jaywgJmxvY2tfZHN0LCAwKTsKICAgICAgICBpZihyZXQgIT0gV0lORUQzRF9PSykgZ290byBlcnJvcjsKCiAgICAgICAgc2J1ZiA9IHNsb2NrLnBCaXRzOwogICAgICAgIGRidWYgPSBkbG9jay5wQml0czsKICAgICAgICBUUkFDRSgiRHN0IGlzIGF0ICVwLCBTcmMgaXMgYXQgJXBcbiIsIGRidWYsIHNidWYpOwoKICAgICAgICBzRW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoU3JjLT5yZXNvdXJjZS5mb3JtYXQpOwogICAgICAgIGRFbnRyeSA9IGdldEZvcm1hdERlc2NFbnRyeShUaGlzLT5yZXNvdXJjZS5mb3JtYXQpOwogICAgfQoKICAgIC8qIEhhbmRsZSBmaXJzdCB0aGUgRk9VUkNDIHN1cmZhY2VzLi4uICovCiAgICBpZiAoc0VudHJ5LT5pc0ZvdXJjYyAmJiBkRW50cnktPmlzRm91cmNjKQogICAgewogICAgICAgIFRSQUNFKCJGb3VyY2MgLT4gRm91cmNjIGNvcHlcbiIpOwogICAgICAgIGlmICh0cmFucykKICAgICAgICAgICAgRklYTUUoInRyYW5zIGFyZyBub3Qgc3VwcG9ydGVkIHdoZW4gYSBGT1VSQ0Mgc3VyZmFjZSBpcyBpbnZvbHZlZFxuIik7CiAgICAgICAgaWYgKGRzdHggfHwgZHN0eSkKICAgICAgICAgICAgRklYTUUoIm9mZnNldCBmb3IgZGVzdGluYXRpb24gc3VyZmFjZSBpcyBub3Qgc3VwcG9ydGVkXG4iKTsKICAgICAgICBpZiAoU3JjLT5yZXNvdXJjZS5mb3JtYXQgIT0gVGhpcy0+cmVzb3VyY2UuZm9ybWF0KQogICAgICAgIHsKICAgICAgICAgICAgRklYTUUoIkZPVVJDQy0+Rk9VUkNDIGNvcHkgb25seSBzdXBwb3J0ZWQgZm9yIHRoZSBzYW1lIHR5cGUgb2Ygc3VyZmFjZVxuIik7CiAgICAgICAgICAgIHJldCA9IERERVJSX0lOVkFMSURQSVhFTEZPUk1BVDsKICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CiAgICAgICAgLyogRklYTUU6IFdhdGNoIG91dCB0aGF0IHRoZSBzaXplIGlzIGNvcnJlY3QgZm9yIEZPVVJDQyBzdXJmYWNlcyAqLwogICAgICAgIG1lbWNweShkYnVmLCBzYnVmLCBUaGlzLT5yZXNvdXJjZS5zaXplKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQogICAgaWYgKHNFbnRyeS0+aXNGb3VyY2MgJiYgIWRFbnRyeS0+aXNGb3VyY2MpCiAgICB7CiAgICAgICAgLyogVE9ETzogVXNlIHRoZSBsaWJ0eGNfZHh0bi5zbyBzaGFyZWQgbGlicmFyeSB0byBkbwogICAgICAgICAqIHNvZnR3YXJlIGRlY29tcHJlc3Npb24KICAgICAgICAgKi8KICAgICAgICBFUlIoIkRYVEMgZGVjb21wcmVzc2lvbiBub3Qgc3VwcG9ydGVkIGJ5IG5vd1xuIik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBpZiAodHJhbnMgJiAoRERCTFRGQVNUX1NSQ0NPTE9SS0VZIHwgRERCTFRGQVNUX0RFU1RDT0xPUktFWSkpCiAgICB7CiAgICAgICAgRFdPUkQga2V5bG93LCBrZXloaWdoOwogICAgICAgIFRSQUNFKCJDb2xvciBrZXllZCBjb3B5XG4iKTsKICAgICAgICBpZiAodHJhbnMgJiBEREJMVEZBU1RfU1JDQ09MT1JLRVkpCiAgICAgICAgewogICAgICAgICAgICBrZXlsb3cgID0gU3JjLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlOwogICAgICAgICAgICBrZXloaWdoID0gU3JjLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgLyogSSdtIG5vdCBzdXJlIGlmIHRoaXMgaXMgY29ycmVjdCAqLwogICAgICAgICAgICBGSVhNRSgiRERCTFRGQVNUX0RFU1RDT0xPUktFWSBub3QgZnVsbHkgc3VwcG9ydGVkIHlldC5cbiIpOwogICAgICAgICAgICBrZXlsb3cgID0gVGhpcy0+RGVzdEJsdENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWU7CiAgICAgICAgICAgIGtleWhpZ2ggPSBUaGlzLT5EZXN0Qmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWU7CiAgICAgICAgfQoKI2RlZmluZSBDT1BZQk9YX0NPTE9SS0VZKHR5cGUpIHsgXAogICAgICAgICAgICB0eXBlICpkLCAqcywgdG1wOyBcCiAgICAgICAgICAgIHMgPSAodHlwZSAqKSBzYnVmOyBcCiAgICAgICAgICAgIGQgPSAodHlwZSAqKSBkYnVmOyBcCiAgICAgICAgICAgIGZvciAoeSA9IDA7IHkgPCBoOyB5KyspIHsgXAogICAgICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IHc7IHgrKykgeyBcCiAgICAgICAgICAgICAgICAgICAgdG1wID0gc1t4XTsgXAogICAgICAgICAgICAgICAgICAgIGlmICh0bXAgPCBrZXlsb3cgfHwgdG1wID4ga2V5aGlnaCkgZFt4XSA9IHRtcDsgXAogICAgICAgICAgICAgICAgfSBcCiAgICAgICAgICAgICAgICBzID0gKHR5cGUgKikoKEJZVEUgKilzICsgc2xvY2suUGl0Y2gpOyBcCiAgICAgICAgICAgICAgICBkID0gKHR5cGUgKikoKEJZVEUgKilkICsgZGxvY2suUGl0Y2gpOyBcCiAgICAgICAgICAgIH0gXAogICAgICAgICAgICBicmVhazsgXAogICAgICAgIH0KCiAgICAgICAgc3dpdGNoIChicHApIHsKICAgICAgICAgICAgY2FzZSAxOiBDT1BZQk9YX0NPTE9SS0VZKEJZVEUpCiAgICAgICAgICAgIGNhc2UgMjogQ09QWUJPWF9DT0xPUktFWShXT1JEKQogICAgICAgICAgICBjYXNlIDQ6IENPUFlCT1hfQ09MT1JLRVkoRFdPUkQpCiAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQllURSAqZCwgKnM7CiAgICAgICAgICAgICAgICBEV09SRCB0bXA7CiAgICAgICAgICAgICAgICBzID0gKEJZVEUgKikgc2J1ZjsKICAgICAgICAgICAgICAgIGQgPSAoQllURSAqKSBkYnVmOwogICAgICAgICAgICAgICAgZm9yICh5ID0gMDsgeSA8IGg7IHkrKykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgdyAqIDM7IHggKz0gMykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRtcCA9IChEV09SRClzW3hdICsgKChEV09SRClzW3ggKyAxXSA8PCA4KSArICgoRFdPUkQpc1t4ICsgMl0gPDwgMTYpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodG1wIDwga2V5bG93IHx8IHRtcCA+IGtleWhpZ2gpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRbeCArIDBdID0gc1t4ICsgMF07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkW3ggKyAxXSA9IHNbeCArIDFdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZFt4ICsgMl0gPSBzW3ggKyAyXTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBzICs9IHNsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgIGQgKz0gZGxvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgRklYTUUoIlNvdXJjZSBjb2xvciBrZXkgYmxpdHRpbmcgbm90IHN1cHBvcnRlZCBmb3IgYnBwICVkXG4iLGJwcCo4KTsKICAgICAgICAgICAgICAgIHJldCA9IERERVJSX1VOU1VQUE9SVEVEOwogICAgICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CiN1bmRlZiBDT1BZQk9YX0NPTE9SS0VZCiAgICAgICAgVFJBQ0UoIkNvcHkgRG9uZVxuIik7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaW50IHdpZHRoID0gdyAqIGJwcDsKICAgICAgICBUUkFDRSgiTk8gY29sb3Iga2V5IGNvcHlcbiIpOwogICAgICAgIGZvciAoeSA9IDA7IHkgPCBoOyB5KyspCiAgICAgICAgewogICAgICAgICAgICAvKiBUaGlzIGlzIHByZXR0eSBlYXN5LCBhIGxpbmUgZm9yIGxpbmUgbWVtY3B5ICovCiAgICAgICAgICAgIG1lbWNweShkYnVmLCBzYnVmLCB3aWR0aCk7CiAgICAgICAgICAgIHNidWYgKz0gc2xvY2suUGl0Y2g7CiAgICAgICAgICAgIGRidWYgKz0gZGxvY2suUGl0Y2g7CiAgICAgICAgfQogICAgICAgIFRSQUNFKCJDb3B5IGRvbmVcbiIpOwogICAgfQoKZXJyb3I6CiAgICBpZiAoU3JjID09IFRoaXMpCiAgICB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QoaWZhY2UpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9VbmxvY2tSZWN0KGlmYWNlKTsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfVW5sb2NrUmVjdChTb3VyY2UpOwogICAgfQoKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRFN1cmZhY2U6OkxvYWRUZXh0dXJlLCBHREkgdmVyc2lvbgogKgogKiBUaGlzIGlzIG11dHVhbGx5IHVuc3VwcG9ydGVkIGJ5IEdESSBzdXJmYWNlcwogKgogKiBSZXR1cm5zOgogKiAgRDNERVJSX0lOVkFMSURDQUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSFJFU1VMVCBXSU5BUEkKSVdpbmVHRElTdXJmYWNlSW1wbF9Mb2FkVGV4dHVyZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKQp7CiAgICBFUlIoIlVuc3VwcG9ydGVkIG9uIFgxMSBzdXJmYWNlc1xuIik7CiAgICByZXR1cm4gRDNERVJSX0lOVkFMSURDQUxMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0RTdXJmYWNlOjpTYXZlU25hcHNob3QsIEdESSB2ZXJzaW9uCiAqCiAqIFRoaXMgbWV0aG9kIHdyaXRlcyB0aGUgc3VyZmFjZSdzIGNvbnRlbnRzIHRvIHRoZSBpbiB0Z2EgZm9ybWF0IHRvIHRoZQogKiBmaWxlIHNwZWNpZmllZCBpbiBmaWxlbmFtZS4KICoKICogUGFyYW1zOgogKiAgZmlsZW5hbWU6IEZpbGUgdG8gd3JpdGUgdG8KICoKICogUmV0dXJuczoKICogIFdJTkVEM0RFUlJfSU5WQUxJRENBTEwgaWYgdGhlIGZpbGUgY291bGRuJ3QgYmUgb3BlbmVkCiAqICBXSU5FRDNEX09LIG9uIHN1Y2Nlc3MKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgaW50IGdldF9zaGlmdChEV09SRCBjb2xvcl9tYXNrKSB7CiAgICBpbnQgc2hpZnQgPSAwOwogICAgd2hpbGUgKGNvbG9yX21hc2sgPiAweEZGKSB7CiAgICAgICAgY29sb3JfbWFzayA+Pj0gMTsKICAgICAgICBzaGlmdCArPSAxOwogICAgfQogICAgd2hpbGUgKChjb2xvcl9tYXNrICYgMHg4MCkgPT0gMCkgewogICAgICAgIGNvbG9yX21hc2sgPDw9IDE7CiAgICAgICAgc2hpZnQgLT0gMTsKICAgIH0KICAgIHJldHVybiBzaGlmdDsKfQoKCkhSRVNVTFQgV0lOQVBJCklXaW5lR0RJU3VyZmFjZUltcGxfU2F2ZVNuYXBzaG90KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsCmNvbnN0IGNoYXIqIGZpbGVuYW1lKQp7CiAgICBGSUxFKiBmID0gTlVMTDsKICAgIFVJTlQgeSA9IDAsIHggPSAwOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBzdGF0aWMgY2hhciAqb3V0cHV0ID0gTlVMTDsKICAgIHN0YXRpYyBpbnQgc2l6ZSA9IDA7CiAgICBjb25zdCBQaXhlbEZvcm1hdERlc2MgKmZvcm1hdEVudHJ5ID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KFRoaXMtPnJlc291cmNlLmZvcm1hdCk7CgogICAgaWYgKFRoaXMtPnBvdzJXaWR0aCA+IHNpemUpIHsKICAgICAgICBvdXRwdXQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgVGhpcy0+cG93MldpZHRoICogMyk7CiAgICAgICAgc2l6ZSA9IFRoaXMtPnBvdzJXaWR0aDsKICAgIH0KCgogICAgZiA9IGZvcGVuKGZpbGVuYW1lLCAidysiKTsKICAgIGlmIChOVUxMID09IGYpIHsKICAgICAgICBFUlIoIm9wZW5pbmcgb2YgJXMgZmFpbGVkIHdpdGhcbiIsIGZpbGVuYW1lKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIGZwcmludGYoZiwgIlA2XG4lZCAlZFxuMjU1XG4iLCBUaGlzLT5wb3cyV2lkdGgsIFRoaXMtPnBvdzJIZWlnaHQpOwoKICAgIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9QOCkgewogICAgICAgIHVuc2lnbmVkIGNoYXIgdGFibGVbMjU2XVszXTsKICAgICAgICBpbnQgaTsKCiAgICAgICAgaWYgKFRoaXMtPnBhbGV0dGUgPT0gTlVMTCkgewogICAgICAgICAgICBmY2xvc2UoZik7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgIH0KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMjU2OyBpKyspIHsKICAgICAgICAgICAgdGFibGVbaV1bMF0gPSBUaGlzLT5wYWxldHRlLT5wYWxlbnRzW2ldLnBlUmVkOwogICAgICAgICAgICB0YWJsZVtpXVsxXSA9IFRoaXMtPnBhbGV0dGUtPnBhbGVudHNbaV0ucGVHcmVlbjsKICAgICAgICAgICAgdGFibGVbaV1bMl0gPSBUaGlzLT5wYWxldHRlLT5wYWxlbnRzW2ldLnBlQmx1ZTsKICAgICAgICB9CiAgICAgICAgZm9yICh5ID0gMDsgeSA8IFRoaXMtPnBvdzJIZWlnaHQ7IHkrKykgewogICAgICAgICAgICB1bnNpZ25lZCBjaGFyICpzcmMgPSAodW5zaWduZWQgY2hhciAqKSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgKyAoeSAqIDEgKiBJV2luZUQzRFN1cmZhY2VfR2V0UGl0Y2goaWZhY2UpKTsKICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IFRoaXMtPnBvdzJXaWR0aDsgeCsrKSB7CiAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyIGNvbG9yID0gKnNyYzsKICAgICAgICAgICAgICAgIHNyYyArPSAxOwoKICAgICAgICAgICAgICAgIG91dHB1dFszICogeCArIDBdID0gdGFibGVbY29sb3JdWzBdOwogICAgICAgICAgICAgICAgb3V0cHV0WzMgKiB4ICsgMV0gPSB0YWJsZVtjb2xvcl1bMV07CiAgICAgICAgICAgICAgICBvdXRwdXRbMyAqIHggKyAyXSA9IHRhYmxlW2NvbG9yXVsyXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmd3JpdGUob3V0cHV0LCAzICogVGhpcy0+cG93MldpZHRoLCAxLCBmKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIGludCByZWRfc2hpZnQsIGdyZWVuX3NoaWZ0LCBibHVlX3NoaWZ0LCBwaXhfd2lkdGg7CgogICAgICAgIHBpeF93aWR0aCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWw7CgogICAgICAgIHJlZF9zaGlmdCA9IGdldF9zaGlmdChmb3JtYXRFbnRyeS0+cmVkTWFzayk7CiAgICAgICAgZ3JlZW5fc2hpZnQgPSBnZXRfc2hpZnQoZm9ybWF0RW50cnktPmdyZWVuTWFzayk7CiAgICAgICAgYmx1ZV9zaGlmdCA9IGdldF9zaGlmdChmb3JtYXRFbnRyeS0+Ymx1ZU1hc2spOwoKICAgICAgICBmb3IgKHkgPSAwOyB5IDwgVGhpcy0+cG93MkhlaWdodDsgeSsrKSB7CiAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgKnNyYyA9ICh1bnNpZ25lZCBjaGFyICopIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSArICh5ICogMSAqIElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaChpZmFjZSkpOwogICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgVGhpcy0+cG93MldpZHRoOyB4KyspIHsJICAgIAogICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IGNvbG9yOwogICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IGNvbXA7CiAgICAgICAgICAgICAgICBpbnQgaTsKCiAgICAgICAgICAgICAgICBjb2xvciA9IDA7CiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgcGl4X3dpZHRoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBjb2xvciB8PSBzcmNbaV0gPDwgKDggKiBpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHNyYyArPSAxICogcGl4X3dpZHRoOwoKICAgICAgICAgICAgICAgIGNvbXAgPSBjb2xvciAmIGZvcm1hdEVudHJ5LT5yZWRNYXNrOwogICAgICAgICAgICAgICAgb3V0cHV0WzMgKiB4ICsgMF0gPSByZWRfc2hpZnQgPiAwID8gY29tcCA+PiByZWRfc2hpZnQgOiBjb21wIDw8IC1yZWRfc2hpZnQ7CiAgICAgICAgICAgICAgICBjb21wID0gY29sb3IgJiBmb3JtYXRFbnRyeS0+Z3JlZW5NYXNrOwogICAgICAgICAgICAgICAgb3V0cHV0WzMgKiB4ICsgMV0gPSBncmVlbl9zaGlmdCA+IDAgPyBjb21wID4+IGdyZWVuX3NoaWZ0IDogY29tcCA8PCAtZ3JlZW5fc2hpZnQ7CiAgICAgICAgICAgICAgICBjb21wID0gY29sb3IgJiBmb3JtYXRFbnRyeS0+Ymx1ZU1hc2s7CiAgICAgICAgICAgICAgICBvdXRwdXRbMyAqIHggKyAyXSA9IGJsdWVfc2hpZnQgPiAwID8gY29tcCA+PiBibHVlX3NoaWZ0IDogY29tcCA8PCAtYmx1ZV9zaGlmdDsKICAgICAgICAgICAgfQogICAgICAgICAgICBmd3JpdGUob3V0cHV0LCAzICogVGhpcy0+cG93MldpZHRoLCAxLCBmKTsKICAgICAgICB9CiAgICB9CiAgICBmY2xvc2UoZik7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElXaW5lRDNEU3VyZmFjZTo6UHJpdmF0ZVNldHVwLCBHREkgdmVyc2lvbgogKgogKiBJbml0aWFsaXplcyB0aGUgR0RJIHN1cmZhY2UsIGFrYSBjcmVhdGVzIHRoZSBESUIgc2VjdGlvbiB3ZSByZW5kZXIgdG8KICogVGhlIERJQiBzZWN0aW9uIGNyZWF0aW9uIGlzIGRvbmUgYnkgY2FsbGluZyBHZXREQywgd2hpY2ggd2lsbCBjcmVhdGUgdGhlCiAqIHNlY3Rpb24gYW5kIHJlbGVhc2luZyB0aGUgZGMgdG8gYWxsb3cgdGhlIGFwcCB0byB1c2UgaXQuIFRoZSBkaWIgc2VjdGlvbgogKiB3aWxsIHN0YXkgdW50aWwgdGhlIHN1cmZhY2UgaXMgcmVsZWFzZWQKICoKICogR0RJIHN1cmZhY2VzIGRvIG5vdCBuZWVkIHRvIGJlIGEgcG93ZXIgb2YgMiBpbiBzaXplLCBzbyB0aGUgcG93MiBzaXplcwogKiBhcmUgc2V0IHRvIHRoZSByZWFsIHNpemVzIHRvIHNhdmUgbWVtb3J5LiBUaGUgTk9OUE9XMiBmbGFnIGlzIHVuc2V0IHRvCiAqIGF2b2lkIGNvbmZ1c2lvbiBpbiB0aGUgc2hhcmVkIHN1cmZhY2UgY29kZS4KICoKICogUmV0dXJuczoKICogIFdJTkVEM0RfT0sgb24gc3VjY2VzcwogKiAgVGhlIHJldHVybiB2YWx1ZXMgb2YgY2FsbGVkIG1ldGhvZHMgb24gZmFpbHVyZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkhSRVNVTFQgV0lOQVBJCklXaW5lR0RJU3VyZmFjZUltcGxfUHJpdmF0ZVNldHVwKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpCnsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIEhSRVNVTFQgaHI7CiAgICBIREMgaGRjOwogICAgbG9uZyBvbGRzaXplID0gVGhpcy0+cmVzb3VyY2Uuc2l6ZTsKCiAgICBpZihUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9PVkVSTEFZKQogICAgewogICAgICAgIEVSUigiKCVwKSBPdmVybGF5cyBub3QgeWV0IHN1cHBvcnRlZCBieSBHREkgc3VyZmFjZXNcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgLyogU3lzbWVtIHRleHR1cmVzIGhhdmUgbWVtb3J5IGFscmVhZHkgYWxsb2NhdGVkIC0KICAgICAqIHJlbGVhc2UgaXQsIHRoaXMgYXZvaWRzIGFuIHVubmVjZXNzYXJ5IG1lbWNweQogICAgICovCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gTlVMTDsKCiAgICAvKiBXZSBkb24ndCBtaW5kIHRoZSBub25wb3cyIHN0dWZmIGluIEdESSAqLwogICAgVGhpcy0+cmVzb3VyY2Uuc2l6ZSA9IElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaChpZmFjZSkgKiBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICBUaGlzLT5wb3cyV2lkdGggPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgIFRoaXMtPnBvdzJIZWlnaHQgPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfTk9OUE9XMjsKCiAgICAvKiBBZGp1c3QgdGhlIG9wZW5nbCBtZW0gY291bnRlciAqLwogICAgZ2xvYmFsQ2hhbmdlR2xSYW0oVGhpcy0+cmVzb3VyY2Uuc2l6ZSAtIG9sZHNpemUpOwoKICAgIC8qIENhbGwgR2V0REMgdG8gY3JlYXRlIGEgRElCIHNlY3Rpb24uIFdlIHdpbGwgdXNlIHRoYXQKICAgICAqIERJQiBzZWN0aW9uIGZvciByZW5kZXJpbmcKICAgICAqCiAgICAgKiBSZWxlYXNlIHRoZSBEQyBhZnRlcndhcmRzIHRvIGFsbG93IHRoZSBhcHAgdG8gdXNlIGl0CiAgICAgKi8KICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0dldERDKGlmYWNlLCAmaGRjKTsKICAgIGlmKEZBSUxFRChocikpCiAgICB7CiAgICAgICAgRVJSKCIoJXApIElXaW5lRDNEU3VyZmFjZTo6R2V0REMgZmFpbGVkIHdpdGggaHIgJTA4eFxuIiwgVGhpcywgaHIpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2VEQyhpZmFjZSwgaGRjKTsKICAgIGlmKEZBSUxFRChocikpCiAgICB7CiAgICAgICAgRVJSKCIoJXApIElXaW5lRDNEU3VyZmFjZTo6UmVsZWFzZURDIGZhaWxlZCB3aXRoIGhyICUwOHhcbiIsIFRoaXMsIGhyKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCmNvbnN0IElXaW5lRDNEU3VyZmFjZVZ0YmwgSVdpbmVHRElTdXJmYWNlX1Z0YmwgPQp7CiAgICAvKiBJVW5rbm93biAqLwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9RdWVyeUludGVyZmFjZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfQWRkUmVmLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZWxlYXNlLAogICAgLyogSVdpbmVEM0RSZXNvdXJjZSAqLwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRQYXJlbnQsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldERldmljZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0UHJpdmF0ZURhdGEsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFByaXZhdGVEYXRhLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9GcmVlUHJpdmF0ZURhdGEsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldFByaW9yaXR5LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRQcmlvcml0eSwKICAgIElXaW5lR0RJU3VyZmFjZUltcGxfUHJlTG9hZCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0VHlwZSwKICAgIC8qIElXaW5lRDNEU3VyZmFjZSAqLwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRDb250YWluZXIsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldERlc2MsCiAgICBJV2luZUdESVN1cmZhY2VJbXBsX0xvY2tSZWN0LAogICAgSVdpbmVHRElTdXJmYWNlSW1wbF9VbmxvY2tSZWN0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREQywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfUmVsZWFzZURDLAogICAgSVdpbmVHRElTdXJmYWNlSW1wbF9GbGlwLAogICAgSVdpbmVHRElTdXJmYWNlSW1wbF9CbHQsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldEJsdFN0YXR1cywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0RmxpcFN0YXR1cywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfSXNMb3N0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZXN0b3JlLAogICAgSVdpbmVHRElTdXJmYWNlSW1wbF9CbHRGYXN0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRQYWxldHRlLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRQYWxldHRlLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZWFsaXplUGFsZXR0ZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0Q29sb3JLZXksCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFBpdGNoLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRNZW0sCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldE92ZXJsYXlQb3NpdGlvbiwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0T3ZlcmxheVBvc2l0aW9uLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9VcGRhdGVPdmVybGF5Wk9yZGVyLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9VcGRhdGVPdmVybGF5LAogICAgLyogSW50ZXJuYWwgdXNlOiAqLwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9DbGVhbkRpcnR5UmVjdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfQWRkRGlydHlSZWN0LAogICAgSVdpbmVHRElTdXJmYWNlSW1wbF9Mb2FkVGV4dHVyZSwKICAgIElXaW5lR0RJU3VyZmFjZUltcGxfU2F2ZVNuYXBzaG90LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRDb250YWluZXIsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldFBCdWZmZXJTdGF0ZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0R2xUZXh0dXJlRGVzYywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0R2xEZXNjLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREYXRhLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRGb3JtYXQsCiAgICBJV2luZUdESVN1cmZhY2VJbXBsX1ByaXZhdGVTZXR1cAp9Owo=