LyoKCVdBU1RFIERlbW8gUHJvamVjdDoKCVNhbXBsZSBXQVNURSBPYmplY3QgSGFuZGxlcnMKCglDb3B5cmlnaHQgqSAxOTkzLTE5OTggTWFyY28gUGlvdmFuZWxsaQoJQWxsIFJpZ2h0cyBSZXNlcnZlZAoqLwoKI2luY2x1ZGUgIldFT2JqZWN0SGFuZGxlcnMuaCIKCiNpZm5kZWYgX19JQ09OU19fCiNpbmNsdWRlIDxJY29ucy5oPgojZW5kaWYKCiNpZm5kZWYgX19TT1VORF9fCiNpbmNsdWRlIDxTb3VuZC5oPgojZW5kaWYKCi8qIFBJQ1RVUkVTICovCgpwYXNjYWwgT1NFcnIgSGFuZGxlTmV3UGljdHVyZShQb2ludCAqZGVmYXVsdE9iamVjdFNpemUsIFdFT2JqZWN0UmVmZXJlbmNlIG9iamVjdFJlZikKewoJUGljSGFuZGxlIHRoZVBpY3R1cmU7CglSZWN0IGZyYW1lOwoKCS8qIGdldCBoYW5kbGUgdG8gb2JqZWN0IGRhdGEgKGluIHRoaXMgY2FzZSwgYSBwaWN0dXJlIGhhbmRsZSkgKi8KCXRoZVBpY3R1cmUgPSAoUGljSGFuZGxlKSBXRUdldE9iamVjdERhdGFIYW5kbGUob2JqZWN0UmVmKTsKCgkvKiBmaWd1cmUgb3V0IHRoZSBkZWZhdWx0IG9iamVjdCBzaXplIGJ5IGxvb2tpbmcgYXQgdGhlIHBpY0ZyYW1lIHJlY29yZCAqLwoJZnJhbWUgPSAoKnRoZVBpY3R1cmUpLT5waWNGcmFtZTsKCU9mZnNldFJlY3QoJmZyYW1lLCAtZnJhbWUubGVmdCwgLWZyYW1lLnRvcCk7CglkZWZhdWx0T2JqZWN0U2l6ZS0+diA9IGZyYW1lLmJvdHRvbTsKCWRlZmF1bHRPYmplY3RTaXplLT5oID0gZnJhbWUucmlnaHQ7CgoJcmV0dXJuIG5vRXJyOwp9CgpwYXNjYWwgT1NFcnIgSGFuZGxlRGlzcG9zZVBpY3R1cmUoV0VPYmplY3RSZWZlcmVuY2Ugb2JqZWN0UmVmKQp7CglQaWNIYW5kbGUgdGhlUGljdHVyZTsKCgkvKiBnZXQgaGFuZGxlIHRvIG9iamVjdCBkYXRhIChpbiB0aGlzIGNhc2UsIGEgcGljdHVyZSBoYW5kbGUpICovCgl0aGVQaWN0dXJlID0gKFBpY0hhbmRsZSkgV0VHZXRPYmplY3REYXRhSGFuZGxlKG9iamVjdFJlZik7CgoJLyoga2lsbCB0aGUgcGljdHVyZSAqLwoJS2lsbFBpY3R1cmUodGhlUGljdHVyZSk7CgoJcmV0dXJuIE1lbUVycm9yKCk7Cn0KCnBhc2NhbCBPU0VyciBIYW5kbGVEcmF3UGljdHVyZShjb25zdCBSZWN0ICpkZXN0UmVjdCwgV0VPYmplY3RSZWZlcmVuY2Ugb2JqZWN0UmVmKQp7CglQaWNIYW5kbGUgdGhlUGljdHVyZTsKCgkvKiBnZXQgaGFuZGxlIHRvIG9iamVjdCBkYXRhIChpbiB0aGlzIGNhc2UsIGEgcGljdHVyZSBoYW5kbGUpICovCgl0aGVQaWN0dXJlID0gKFBpY0hhbmRsZSkgV0VHZXRPYmplY3REYXRhSGFuZGxlKG9iamVjdFJlZik7CgoJLyogZHJhdyB0aGUgcGljdHVyZSAqLwoJRHJhd1BpY3R1cmUodGhlUGljdHVyZSwgZGVzdFJlY3QpOwoKCXJldHVybiBub0VycjsKfQoKCi8qIFNPVU5EICovCgpwYXNjYWwgT1NFcnIgSGFuZGxlTmV3U291bmQoUG9pbnQgKmRlZmF1bHRPYmplY3RTaXplLCBXRU9iamVjdFJlZmVyZW5jZSBvYmplY3RSZWYpCnsKI3ByYWdtYSB1bnVzZWQob2JqZWN0UmVmKQoKCS8qIHNvdW5kcyBhcmUgZHJhd24gYXMgc3RhbmRhcmQgMzJ4MzIgaWNvbnMgKi8KCWRlZmF1bHRPYmplY3RTaXplLT52ID0gMzI7CglkZWZhdWx0T2JqZWN0U2l6ZS0+aCA9IDMyOwoKCXJldHVybiBub0VycjsKfQoKcGFzY2FsIE9TRXJyIEhhbmRsZURyYXdTb3VuZChjb25zdCBSZWN0ICpkZXN0UmVjdCwgV0VPYmplY3RSZWZlcmVuY2Ugb2JqZWN0UmVmKQp7CiNwcmFnbWEgdW51c2VkKG9iamVjdFJlZikKCgkvKiBkcmF3IHRoZSBzb3VuZCBpY29uICovCglyZXR1cm4gUGxvdEljb25JRChkZXN0UmVjdCwga0FsaWduTm9uZSwga1RyYW5zZm9ybU5vbmUsIGtTb3VuZEljb25JRCk7Cn0KCnBhc2NhbCBCb29sZWFuIEhhbmRsZUNsaWNrU291bmQoUG9pbnQgaGl0UHQsIEV2ZW50TW9kaWZpZXJzIG1vZGlmaWVycywKCQkJCQlVSW50MzIgY2xpY2tUaW1lLCBXRU9iamVjdFJlZmVyZW5jZSBvYmplY3RSZWYpCnsKI3ByYWdtYSB1bnVzZWQoaGl0UHQsIGNsaWNrVGltZSkKCglTbmRMaXN0SGFuZGxlIHRoZVNvdW5kOwoKCS8qIFdBU1RFIHNldHMgdGhlIGxvdyBiaXQgb2YgbW9kaWZpZXJzIG9uIGRvdWJsZSAobXVsdGlwbGUpIGNsaWNrcyAqLwoJaWYgKG1vZGlmaWVycyAmIDB4MDAwMSkKCXsKCgkJLyogZ2V0IGEgaGFuZGxlIHRvIHRoZSBvYmplY3QgZGF0YSAoaW4gdGhpcyBjYXNlLCBhIHNvdW5kIGhhbmRsZSkgKi8KCQl0aGVTb3VuZCA9IChTbmRMaXN0SGFuZGxlKSBXRUdldE9iamVjdERhdGFIYW5kbGUob2JqZWN0UmVmKTsKCgkJLyogcGxheSB0aGUgc291bmQgKi8KCQlTbmRQbGF5KG5pbCwgdGhlU291bmQsIGZhbHNlKTsKCgkJLyogcmV0dXJuIFRSVUUgc28gV0FTVEUga25vd3Mgd2UgaGFuZGxlZCB0aGUgY2xpY2sgKi8KCQlyZXR1cm4gdHJ1ZTsKCX0KCWVsc2UKCXsKCQkvKiBub3QgYSBkb3VibGUgY2xpY2s6IGxldCBXQVNURSBoYW5kbGUgdGhlIG1vdXNlLWRvd24gKi8KCQlyZXR1cm4gZmFsc2U7Cgl9Cn0K