LyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIGRyYXdFbGVtZW50cyBRdWFsaXR5IFByb2dyYW0gT3BlbkdMIEVTIDMuMCBNb2R1bGUKICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKgogKiBDb3B5cmlnaHQgMjAxNCBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKgogKi8vKiEKICogXGZpbGUKICogXGJyaWVmIEJ1ZmZlciBkYXRhIHVwbG9hZCBwZXJmb3JtYW5jZSB0ZXN0cy4KICovLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgojaW5jbHVkZSAiZXMzcEJ1ZmZlckRhdGFVcGxvYWRUZXN0cy5ocHAiCiNpbmNsdWRlICJnbHNDYWxpYnJhdGlvbi5ocHAiCiNpbmNsdWRlICJ0Y3VUZXN0TG9nLmhwcCIKI2luY2x1ZGUgInRjdVZlY3RvclV0aWwuaHBwIgojaW5jbHVkZSAidGN1U3VyZmFjZS5ocHAiCiNpbmNsdWRlICJ0Y3VDUFVXYXJtdXAuaHBwIgojaW5jbHVkZSAidGN1UmVuZGVyVGFyZ2V0LmhwcCIKI2luY2x1ZGUgImdsdVJlbmRlckNvbnRleHQuaHBwIgojaW5jbHVkZSAiZ2x1U2hhZGVyUHJvZ3JhbS5ocHAiCiNpbmNsdWRlICJnbHVTdHJVdGlsLmhwcCIKI2luY2x1ZGUgImdsdVBpeGVsVHJhbnNmZXIuaHBwIgojaW5jbHVkZSAiZ2x1T2JqZWN0V3JhcHBlci5ocHAiCiNpbmNsdWRlICJnbHdGdW5jdGlvbnMuaHBwIgojaW5jbHVkZSAiZ2x3RW51bXMuaHBwIgojaW5jbHVkZSAiZGVDbG9jay5oIgojaW5jbHVkZSAiZGVNYXRoLmgiCiNpbmNsdWRlICJkZVN0cmluZ1V0aWwuaHBwIgojaW5jbHVkZSAiZGVSYW5kb20uaHBwIgojaW5jbHVkZSAiZGVNZW1vcnkuaCIKI2luY2x1ZGUgImRlVGhyZWFkLmgiCiNpbmNsdWRlICJkZU1ldGEuaHBwIgoKI2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGlvbWFuaXA+CiNpbmNsdWRlIDxsaW1pdHM+CgpuYW1lc3BhY2UgZGVxcAp7Cm5hbWVzcGFjZSBnbGVzMwp7Cm5hbWVzcGFjZSBQZXJmb3JtYW5jZQp7Cm5hbWVzcGFjZQp7Cgp1c2luZyBnbHM6OnRoZWlsU2VuU2llZ2VsTGluZWFyUmVncmVzc2lvbjsKdXNpbmcgZ2xzOjpMaW5lUGFyYW1ldGVyc1dpdGhDb25maWRlbmNlOwp1c2luZyBkZTo6bWV0YTo6RW5hYmxlSWY7CnVzaW5nIGRlOjptZXRhOjpOb3Q7CgpzdGF0aWMgY29uc3QgY2hhciogY29uc3Qgc19kdW1teVZlcnRleFNoYWRlciA9CQkiI3ZlcnNpb24gMzAwIGVzXG4iCgkJCQkJCQkJCQkJCQkiaW4gaGlnaHAgdmVjNCBhX3Bvc2l0aW9uO1xuIgoJCQkJCQkJCQkJCQkJInZvaWQgbWFpbiAodm9pZClcbiIKCQkJCQkJCQkJCQkJCSJ7XG4iCgkJCQkJCQkJCQkJCQkiCWdsX1Bvc2l0aW9uID0gYV9wb3NpdGlvbjtcbiIKCQkJCQkJCQkJCQkJCSJ9XG4iOwoKc3RhdGljIGNvbnN0IGNoYXIqIGNvbnN0IHNfZHVtbXlGcmFnbmVudFNoYWRlciA9CSIjdmVyc2lvbiAzMDAgZXNcbiIKCQkJCQkJCQkJCQkJCSJsYXlvdXQobG9jYXRpb24gPSAwKSBvdXQgbWVkaXVtcCB2ZWM0IGRFUVBfRnJhZ0NvbG9yO1xuIgoJCQkJCQkJCQkJCQkJInZvaWQgbWFpbiAodm9pZClcbiIKCQkJCQkJCQkJCQkJCSJ7XG4iCgkJCQkJCQkJCQkJCQkiCWRFUVBfRnJhZ0NvbG9yID0gdmVjNCgxLjAsIDAuMCwgMC4wLCAxLjApO1xuIgoJCQkJCQkJCQkJCQkJIn1cbiI7CgpzdGF0aWMgY29uc3QgY2hhciogY29uc3Qgc19jb2xvclZlcnRleFNoYWRlciA9CQkiI3ZlcnNpb24gMzAwIGVzXG4iCgkJCQkJCQkJCQkJCQkiaW4gaGlnaHAgdmVjNCBhX3Bvc2l0aW9uO1xuIgoJCQkJCQkJCQkJCQkJImluIGhpZ2hwIHZlYzQgYV9jb2xvcjtcbiIKCQkJCQkJCQkJCQkJCSJvdXQgaGlnaHAgdmVjNCB2X2NvbG9yO1xuIgoJCQkJCQkJCQkJCQkJInZvaWQgbWFpbiAodm9pZClcbiIKCQkJCQkJCQkJCQkJCSJ7XG4iCgkJCQkJCQkJCQkJCQkiCWdsX1Bvc2l0aW9uID0gYV9wb3NpdGlvbjtcbiIKCQkJCQkJCQkJCQkJCSIJdl9jb2xvciA9IGFfY29sb3I7XG4iCgkJCQkJCQkJCQkJCQkifVxuIjsKCnN0YXRpYyBjb25zdCBjaGFyKiBjb25zdCBzX2NvbG9yRnJhZ21lbnRTaGFkZXIgPQkiI3ZlcnNpb24gMzAwIGVzXG4iCgkJCQkJCQkJCQkJCQkibGF5b3V0KGxvY2F0aW9uID0gMCkgb3V0IG1lZGl1bXAgdmVjNCBkRVFQX0ZyYWdDb2xvcjtcbiIKCQkJCQkJCQkJCQkJCSJpbiBtZWRpdW1wIHZlYzQgdl9jb2xvcjtcbiIKCQkJCQkJCQkJCQkJCSJ2b2lkIG1haW4gKHZvaWQpXG4iCgkJCQkJCQkJCQkJCQkie1xuIgoJCQkJCQkJCQkJCQkJIglkRVFQX0ZyYWdDb2xvciA9IHZfY29sb3I7XG4iCgkJCQkJCQkJCQkJCQkifVxuIjsKCnN0cnVjdCBTaW5nbGVPcGVyYXRpb25EdXJhdGlvbgp7CglkZVVpbnQ2NCB0b3RhbER1cmF0aW9uOwoJZGVVaW50NjQgZml0UmVzcG9uc2VEdXJhdGlvbjsgLy8gdXNlZCBmb3IgZml0dGluZwp9OwoKc3RydWN0IE1hcEJ1ZmZlclJhbmdlRHVyYXRpb24KewoJZGVVaW50NjQgbWFwRHVyYXRpb247CglkZVVpbnQ2NCB1bm1hcER1cmF0aW9uOwoJZGVVaW50NjQgd3JpdGVEdXJhdGlvbjsKCWRlVWludDY0IGFsbG9jRHVyYXRpb247CglkZVVpbnQ2NCB0b3RhbER1cmF0aW9uOwoKCWRlVWludDY0IGZpdFJlc3BvbnNlRHVyYXRpb247Cn07CgpzdHJ1Y3QgTWFwQnVmZmVyUmFuZ2VEdXJhdGlvbk5vQWxsb2MKewoJZGVVaW50NjQgbWFwRHVyYXRpb247CglkZVVpbnQ2NCB1bm1hcER1cmF0aW9uOwoJZGVVaW50NjQgd3JpdGVEdXJhdGlvbjsKCWRlVWludDY0IHRvdGFsRHVyYXRpb247CgoJZGVVaW50NjQgZml0UmVzcG9uc2VEdXJhdGlvbjsKfTsKCnN0cnVjdCBNYXBCdWZmZXJSYW5nZUZsdXNoRHVyYXRpb24KewoJZGVVaW50NjQgbWFwRHVyYXRpb247CglkZVVpbnQ2NCB1bm1hcER1cmF0aW9uOwoJZGVVaW50NjQgd3JpdGVEdXJhdGlvbjsKCWRlVWludDY0IGZsdXNoRHVyYXRpb247CglkZVVpbnQ2NCBhbGxvY0R1cmF0aW9uOwoJZGVVaW50NjQgdG90YWxEdXJhdGlvbjsKCglkZVVpbnQ2NCBmaXRSZXNwb25zZUR1cmF0aW9uOwp9OwoKc3RydWN0IE1hcEJ1ZmZlclJhbmdlRmx1c2hEdXJhdGlvbk5vQWxsb2MKewoJZGVVaW50NjQgbWFwRHVyYXRpb247CglkZVVpbnQ2NCB1bm1hcER1cmF0aW9uOwoJZGVVaW50NjQgd3JpdGVEdXJhdGlvbjsKCWRlVWludDY0IGZsdXNoRHVyYXRpb247CglkZVVpbnQ2NCB0b3RhbER1cmF0aW9uOwoKCWRlVWludDY0IGZpdFJlc3BvbnNlRHVyYXRpb247Cn07CgpzdHJ1Y3QgUmVuZGVyUmVhZER1cmF0aW9uCnsKCWRlVWludDY0IHJlbmRlckR1cmF0aW9uOwoJZGVVaW50NjQgcmVhZER1cmF0aW9uOwoJZGVVaW50NjQgcmVuZGVyUmVhZER1cmF0aW9uOwoJZGVVaW50NjQgdG90YWxEdXJhdGlvbjsKCglkZVVpbnQ2NCBmaXRSZXNwb25zZUR1cmF0aW9uOwp9OwoKc3RydWN0IFVucmVsYXRlZFVwbG9hZFJlbmRlclJlYWREdXJhdGlvbgp7CglkZVVpbnQ2NCByZW5kZXJEdXJhdGlvbjsKCWRlVWludDY0IHJlYWREdXJhdGlvbjsKCWRlVWludDY0IHJlbmRlclJlYWREdXJhdGlvbjsKCWRlVWludDY0IHRvdGFsRHVyYXRpb247CgoJZGVVaW50NjQgZml0UmVzcG9uc2VEdXJhdGlvbjsKfTsKCnN0cnVjdCBVcGxvYWRSZW5kZXJSZWFkRHVyYXRpb24KewoJZGVVaW50NjQgdXBsb2FkRHVyYXRpb247CglkZVVpbnQ2NCByZW5kZXJEdXJhdGlvbjsKCWRlVWludDY0IHJlYWREdXJhdGlvbjsKCWRlVWludDY0IHRvdGFsRHVyYXRpb247CglkZVVpbnQ2NCByZW5kZXJSZWFkRHVyYXRpb247CgoJZGVVaW50NjQgZml0UmVzcG9uc2VEdXJhdGlvbjsKfTsKCnN0cnVjdCBVcGxvYWRSZW5kZXJSZWFkRHVyYXRpb25XaXRoVW5yZWxhdGVkVXBsb2FkU2l6ZQp7CglkZVVpbnQ2NCB1cGxvYWREdXJhdGlvbjsKCWRlVWludDY0IHJlbmRlckR1cmF0aW9uOwoJZGVVaW50NjQgcmVhZER1cmF0aW9uOwoJZGVVaW50NjQgdG90YWxEdXJhdGlvbjsKCWRlVWludDY0IHJlbmRlclJlYWREdXJhdGlvbjsKCglkZVVpbnQ2NCBmaXRSZXNwb25zZUR1cmF0aW9uOwp9OwoKc3RydWN0IFJlbmRlclVwbG9hZFJlbmRlclJlYWREdXJhdGlvbgp7CglkZVVpbnQ2NCBmaXJzdFJlbmRlckR1cmF0aW9uOwoJZGVVaW50NjQgdXBsb2FkRHVyYXRpb247CglkZVVpbnQ2NCBzZWNvbmRSZW5kZXJEdXJhdGlvbjsKCWRlVWludDY0IHJlYWREdXJhdGlvbjsKCWRlVWludDY0IHRvdGFsRHVyYXRpb247CglkZVVpbnQ2NCByZW5kZXJSZWFkRHVyYXRpb247CgoJZGVVaW50NjQgZml0UmVzcG9uc2VEdXJhdGlvbjsKfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUPgpzdHJ1Y3QgVXBsb2FkU2FtcGxlUmVzdWx0CnsKCXR5cGVkZWYgU2FtcGxlVCBTYW1wbGVUeXBlOwoKCWludAkJCWJ1ZmZlclNpemU7CglpbnQJCQlhbGxvY2F0ZWRTaXplOwoJaW50CQkJd3JpdHRlblNpemU7CglTYW1wbGVUeXBlCWR1cmF0aW9uOwp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFNhbXBsZVQ+CnN0cnVjdCBSZW5kZXJTYW1wbGVSZXN1bHQKewoJdHlwZWRlZiBTYW1wbGVUIFNhbXBsZVR5cGU7CgoJaW50CQkJdXBsb2FkZWREYXRhU2l6ZTsKCWludAkJCXJlbmRlckRhdGFTaXplOwoJaW50CQkJdW5yZWxhdGVkRGF0YVNpemU7CglpbnQJCQludW1WZXJ0aWNlczsKCVNhbXBsZVQJCWR1cmF0aW9uOwp9OwoKc3RydWN0IFNpbmdsZU9wZXJhdGlvblN0YXRpc3RpY3MKewoJZmxvYXQgbWluVGltZTsKCWZsb2F0IG1heFRpbWU7CglmbG9hdCBtZWRpYW5UaW1lOwoJZmxvYXQgbWluMkRlY2lsZVRpbWU7CQkvLyAhPCBtaW5pbXVtIHZhbHVlIGluIHRoZSAybmQgZGVjaWxlCglmbG9hdCBtYXg5RGVjaWxlVGltZTsJCS8vICE8IG1heGltdW0gdmFsdWUgaW4gdGhlIDl0aCBkZWNpbGUKfTsKCnN0cnVjdCBTaW5nbGVDYWxsU3RhdGlzdGljcwp7CglTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzCXJlc3VsdDsKCglmbG9hdAkJCQkJCW1lZGlhblJhdGU7CglmbG9hdAkJCQkJCW1heERpZmZUaW1lOwoJZmxvYXQJCQkJCQltYXhEaWZmOURlY2lsZVRpbWU7CglmbG9hdAkJCQkJCW1lZGlhbkRpZmZUaW1lOwoKCWZsb2F0CQkJCQkJbWF4UmVsRGlmZlRpbWU7CglmbG9hdAkJCQkJCW1heDlEZWNpbGVSZWxEaWZmVGltZTsKCWZsb2F0CQkJCQkJbWVkaWFuUmVsRGlmZlRpbWU7Cn07CgpzdHJ1Y3QgTWFwQ2FsbFN0YXRpc3RpY3MKewoJU2luZ2xlT3BlcmF0aW9uU3RhdGlzdGljcwltYXA7CglTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzCXVubWFwOwoJU2luZ2xlT3BlcmF0aW9uU3RhdGlzdGljcwl3cml0ZTsKCVNpbmdsZU9wZXJhdGlvblN0YXRpc3RpY3MJYWxsb2M7CglTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzCXJlc3VsdDsKCglmbG9hdAkJCQkJCW1lZGlhblJhdGU7CglmbG9hdAkJCQkJCW1heERpZmZUaW1lOwoJZmxvYXQJCQkJCQltYXhEaWZmOURlY2lsZVRpbWU7CglmbG9hdAkJCQkJCW1lZGlhbkRpZmZUaW1lOwoKCWZsb2F0CQkJCQkJbWF4UmVsRGlmZlRpbWU7CglmbG9hdAkJCQkJCW1heDlEZWNpbGVSZWxEaWZmVGltZTsKCWZsb2F0CQkJCQkJbWVkaWFuUmVsRGlmZlRpbWU7Cn07CgpzdHJ1Y3QgTWFwRmx1c2hDYWxsU3RhdGlzdGljcwp7CglTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzCW1hcDsKCVNpbmdsZU9wZXJhdGlvblN0YXRpc3RpY3MJdW5tYXA7CglTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzCXdyaXRlOwoJU2luZ2xlT3BlcmF0aW9uU3RhdGlzdGljcwlmbHVzaDsKCVNpbmdsZU9wZXJhdGlvblN0YXRpc3RpY3MJYWxsb2M7CglTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzCXJlc3VsdDsKCglmbG9hdAkJCQkJCW1lZGlhblJhdGU7CglmbG9hdAkJCQkJCW1heERpZmZUaW1lOwoJZmxvYXQJCQkJCQltYXhEaWZmOURlY2lsZVRpbWU7CglmbG9hdAkJCQkJCW1lZGlhbkRpZmZUaW1lOwoKCWZsb2F0CQkJCQkJbWF4UmVsRGlmZlRpbWU7CglmbG9hdAkJCQkJCW1heDlEZWNpbGVSZWxEaWZmVGltZTsKCWZsb2F0CQkJCQkJbWVkaWFuUmVsRGlmZlRpbWU7Cn07CgpzdHJ1Y3QgUmVuZGVyUmVhZFN0YXRpc3RpY3MKewoJU2luZ2xlT3BlcmF0aW9uU3RhdGlzdGljcwlyZW5kZXI7CglTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzCXJlYWQ7CglTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzCXJlc3VsdDsKCVNpbmdsZU9wZXJhdGlvblN0YXRpc3RpY3MJdG90YWw7CgoJZmxvYXQJCQkJCQltZWRpYW5SYXRlOwoJZmxvYXQJCQkJCQltYXhEaWZmVGltZTsKCWZsb2F0CQkJCQkJbWF4RGlmZjlEZWNpbGVUaW1lOwoJZmxvYXQJCQkJCQltZWRpYW5EaWZmVGltZTsKCglmbG9hdAkJCQkJCW1heFJlbERpZmZUaW1lOwoJZmxvYXQJCQkJCQltYXg5RGVjaWxlUmVsRGlmZlRpbWU7CglmbG9hdAkJCQkJCW1lZGlhblJlbERpZmZUaW1lOwp9OwoKc3RydWN0IFVwbG9hZFJlbmRlclJlYWRTdGF0aXN0aWNzCnsKCVNpbmdsZU9wZXJhdGlvblN0YXRpc3RpY3MJdXBsb2FkOwoJU2luZ2xlT3BlcmF0aW9uU3RhdGlzdGljcwlyZW5kZXI7CglTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzCXJlYWQ7CglTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzCXJlc3VsdDsKCVNpbmdsZU9wZXJhdGlvblN0YXRpc3RpY3MJdG90YWw7CgoJZmxvYXQJCQkJCQltZWRpYW5SYXRlOwoJZmxvYXQJCQkJCQltYXhEaWZmVGltZTsKCWZsb2F0CQkJCQkJbWF4RGlmZjlEZWNpbGVUaW1lOwoJZmxvYXQJCQkJCQltZWRpYW5EaWZmVGltZTsKCglmbG9hdAkJCQkJCW1heFJlbERpZmZUaW1lOwoJZmxvYXQJCQkJCQltYXg5RGVjaWxlUmVsRGlmZlRpbWU7CglmbG9hdAkJCQkJCW1lZGlhblJlbERpZmZUaW1lOwp9OwoKc3RydWN0IFJlbmRlclVwbG9hZFJlbmRlclJlYWRTdGF0aXN0aWNzCnsKCVNpbmdsZU9wZXJhdGlvblN0YXRpc3RpY3MJZmlyc3RSZW5kZXI7CglTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzCXVwbG9hZDsKCVNpbmdsZU9wZXJhdGlvblN0YXRpc3RpY3MJc2Vjb25kUmVuZGVyOwoJU2luZ2xlT3BlcmF0aW9uU3RhdGlzdGljcwlyZWFkOwoJU2luZ2xlT3BlcmF0aW9uU3RhdGlzdGljcwlyZXN1bHQ7CglTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzCXRvdGFsOwoKCWZsb2F0CQkJCQkJbWVkaWFuUmF0ZTsKCWZsb2F0CQkJCQkJbWF4RGlmZlRpbWU7CglmbG9hdAkJCQkJCW1heERpZmY5RGVjaWxlVGltZTsKCWZsb2F0CQkJCQkJbWVkaWFuRGlmZlRpbWU7CgoJZmxvYXQJCQkJCQltYXhSZWxEaWZmVGltZTsKCWZsb2F0CQkJCQkJbWF4OURlY2lsZVJlbERpZmZUaW1lOwoJZmxvYXQJCQkJCQltZWRpYW5SZWxEaWZmVGltZTsKfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpzdHJ1Y3QgU2FtcGxlVHlwZVRyYWl0cwp7Cn07Cgp0ZW1wbGF0ZSA8PgpzdHJ1Y3QgU2FtcGxlVHlwZVRyYWl0czxTaW5nbGVPcGVyYXRpb25EdXJhdGlvbj4KewoJdHlwZWRlZiBTaW5nbGVDYWxsU3RhdGlzdGljcyBTdGF0c1R5cGU7CgoJZW51bSB7IEhBU19NQVBfU1RBVFMJCT0gMAl9OwoJZW51bSB7IEhBU19VTk1BUF9TVEFUUwkJPSAwCX07CgllbnVtIHsgSEFTX1dSSVRFX1NUQVRTCQk9IDAJfTsKCWVudW0geyBIQVNfRkxVU0hfU1RBVFMJCT0gMAl9OwoJZW51bSB7IEhBU19BTExPQ19TVEFUUwkJPSAwCX07CgllbnVtIHsgTE9HX0NPTlRSSUJVVElPTlMJPSAwCX07Cn07Cgp0ZW1wbGF0ZSA8PgpzdHJ1Y3QgU2FtcGxlVHlwZVRyYWl0czxNYXBCdWZmZXJSYW5nZUR1cmF0aW9uPgp7Cgl0eXBlZGVmIE1hcENhbGxTdGF0aXN0aWNzIFN0YXRzVHlwZTsKCgllbnVtIHsgSEFTX01BUF9TVEFUUwkJPSAxCX07CgllbnVtIHsgSEFTX1VOTUFQX1NUQVRTCQk9IDEJfTsKCWVudW0geyBIQVNfV1JJVEVfU1RBVFMJCT0gMQl9OwoJZW51bSB7IEhBU19GTFVTSF9TVEFUUwkJPSAwCX07CgllbnVtIHsgSEFTX0FMTE9DX1NUQVRTCQk9IDEJfTsKCWVudW0geyBMT0dfQ09OVFJJQlVUSU9OUwk9IDEJfTsKfTsKCnRlbXBsYXRlIDw+CnN0cnVjdCBTYW1wbGVUeXBlVHJhaXRzPE1hcEJ1ZmZlclJhbmdlRHVyYXRpb25Ob0FsbG9jPgp7Cgl0eXBlZGVmIE1hcENhbGxTdGF0aXN0aWNzIFN0YXRzVHlwZTsKCgllbnVtIHsgSEFTX01BUF9TVEFUUwkJPSAxCX07CgllbnVtIHsgSEFTX1VOTUFQX1NUQVRTCQk9IDEJfTsKCWVudW0geyBIQVNfV1JJVEVfU1RBVFMJCT0gMQl9OwoJZW51bSB7IEhBU19GTFVTSF9TVEFUUwkJPSAwCX07CgllbnVtIHsgSEFTX0FMTE9DX1NUQVRTCQk9IDAJfTsKCWVudW0geyBMT0dfQ09OVFJJQlVUSU9OUwk9IDEJfTsKfTsKCnRlbXBsYXRlIDw+CnN0cnVjdCBTYW1wbGVUeXBlVHJhaXRzPE1hcEJ1ZmZlclJhbmdlRmx1c2hEdXJhdGlvbj4KewoJdHlwZWRlZiBNYXBGbHVzaENhbGxTdGF0aXN0aWNzIFN0YXRzVHlwZTsKCgllbnVtIHsgSEFTX01BUF9TVEFUUwkJPSAxCX07CgllbnVtIHsgSEFTX1VOTUFQX1NUQVRTCQk9IDEJfTsKCWVudW0geyBIQVNfV1JJVEVfU1RBVFMJCT0gMQl9OwoJZW51bSB7IEhBU19GTFVTSF9TVEFUUwkJPSAxCX07CgllbnVtIHsgSEFTX0FMTE9DX1NUQVRTCQk9IDEJfTsKCWVudW0geyBMT0dfQ09OVFJJQlVUSU9OUwk9IDEJfTsKfTsKCnRlbXBsYXRlIDw+CnN0cnVjdCBTYW1wbGVUeXBlVHJhaXRzPE1hcEJ1ZmZlclJhbmdlRmx1c2hEdXJhdGlvbk5vQWxsb2M+CnsKCXR5cGVkZWYgTWFwRmx1c2hDYWxsU3RhdGlzdGljcyBTdGF0c1R5cGU7CgoJZW51bSB7IEhBU19NQVBfU1RBVFMJCT0gMQl9OwoJZW51bSB7IEhBU19VTk1BUF9TVEFUUwkJPSAxCX07CgllbnVtIHsgSEFTX1dSSVRFX1NUQVRTCQk9IDEJfTsKCWVudW0geyBIQVNfRkxVU0hfU1RBVFMJCT0gMQl9OwoJZW51bSB7IEhBU19BTExPQ19TVEFUUwkJPSAwCX07CgllbnVtIHsgTE9HX0NPTlRSSUJVVElPTlMJPSAxCX07Cn07Cgp0ZW1wbGF0ZSA8PgpzdHJ1Y3QgU2FtcGxlVHlwZVRyYWl0czxSZW5kZXJSZWFkRHVyYXRpb24+CnsKCXR5cGVkZWYgUmVuZGVyUmVhZFN0YXRpc3RpY3MgU3RhdHNUeXBlOwoKCWVudW0geyBIQVNfUkVOREVSX1NUQVRTCQkJPSAxCX07CgllbnVtIHsgSEFTX1JFQURfU1RBVFMJCQk9IDEJfTsKCWVudW0geyBIQVNfVVBMT0FEX1NUQVRTCQkJPSAwCX07CgllbnVtIHsgSEFTX1RPVEFMX1NUQVRTCQkJPSAxCX07CgllbnVtIHsgSEFTX0ZJUlNUX1JFTkRFUl9TVEFUUwk9IDAJfTsKCWVudW0geyBIQVNfU0VDT05EX1JFTkRFUl9TVEFUUwk9IDAJfTsKCgllbnVtIHsgTE9HX0NPTlRSSUJVVElPTlMJPSAxCX07Cn07Cgp0ZW1wbGF0ZSA8PgpzdHJ1Y3QgU2FtcGxlVHlwZVRyYWl0czxVbnJlbGF0ZWRVcGxvYWRSZW5kZXJSZWFkRHVyYXRpb24+CnsKCXR5cGVkZWYgUmVuZGVyUmVhZFN0YXRpc3RpY3MgU3RhdHNUeXBlOwoKCWVudW0geyBIQVNfUkVOREVSX1NUQVRTCQkJPSAxCX07CgllbnVtIHsgSEFTX1JFQURfU1RBVFMJCQk9IDEJfTsKCWVudW0geyBIQVNfVVBMT0FEX1NUQVRTCQkJPSAwCX07CgllbnVtIHsgSEFTX1RPVEFMX1NUQVRTCQkJPSAxCX07CgllbnVtIHsgSEFTX0ZJUlNUX1JFTkRFUl9TVEFUUwk9IDAJfTsKCWVudW0geyBIQVNfU0VDT05EX1JFTkRFUl9TVEFUUwk9IDAJfTsKCgllbnVtIHsgTE9HX0NPTlRSSUJVVElPTlMJPSAxCX07Cn07Cgp0ZW1wbGF0ZSA8PgpzdHJ1Y3QgU2FtcGxlVHlwZVRyYWl0czxVcGxvYWRSZW5kZXJSZWFkRHVyYXRpb24+CnsKCXR5cGVkZWYgVXBsb2FkUmVuZGVyUmVhZFN0YXRpc3RpY3MgU3RhdHNUeXBlOwoKCWVudW0geyBIQVNfUkVOREVSX1NUQVRTCQkJPSAxCX07CgllbnVtIHsgSEFTX1JFQURfU1RBVFMJCQk9IDEJfTsKCWVudW0geyBIQVNfVVBMT0FEX1NUQVRTCQkJPSAxCX07CgllbnVtIHsgSEFTX1RPVEFMX1NUQVRTCQkJPSAxCX07CgllbnVtIHsgSEFTX0ZJUlNUX1JFTkRFUl9TVEFUUwk9IDAJfTsKCWVudW0geyBIQVNfU0VDT05EX1JFTkRFUl9TVEFUUwk9IDAJfTsKCgllbnVtIHsgTE9HX0NPTlRSSUJVVElPTlMJCQk9IDEJfTsKCWVudW0geyBMT0dfVU5SRUxBVEVEX1VQTE9BRF9TSVpFCT0gMCB9Owp9OwoKdGVtcGxhdGUgPD4Kc3RydWN0IFNhbXBsZVR5cGVUcmFpdHM8VXBsb2FkUmVuZGVyUmVhZER1cmF0aW9uV2l0aFVucmVsYXRlZFVwbG9hZFNpemU+CnsKCXR5cGVkZWYgVXBsb2FkUmVuZGVyUmVhZFN0YXRpc3RpY3MgU3RhdHNUeXBlOwoKCWVudW0geyBIQVNfUkVOREVSX1NUQVRTCQkJPSAxCX07CgllbnVtIHsgSEFTX1JFQURfU1RBVFMJCQk9IDEJfTsKCWVudW0geyBIQVNfVVBMT0FEX1NUQVRTCQkJPSAxCX07CgllbnVtIHsgSEFTX1RPVEFMX1NUQVRTCQkJPSAxCX07CgllbnVtIHsgSEFTX0ZJUlNUX1JFTkRFUl9TVEFUUwk9IDAJfTsKCWVudW0geyBIQVNfU0VDT05EX1JFTkRFUl9TVEFUUwk9IDAJfTsKCgllbnVtIHsgTE9HX0NPTlRSSUJVVElPTlMJCQk9IDEJfTsKCWVudW0geyBMT0dfVU5SRUxBVEVEX1VQTE9BRF9TSVpFCT0gMSB9Owp9OwoKdGVtcGxhdGUgPD4Kc3RydWN0IFNhbXBsZVR5cGVUcmFpdHM8UmVuZGVyVXBsb2FkUmVuZGVyUmVhZER1cmF0aW9uPgp7Cgl0eXBlZGVmIFJlbmRlclVwbG9hZFJlbmRlclJlYWRTdGF0aXN0aWNzIFN0YXRzVHlwZTsKCgllbnVtIHsgSEFTX1JFTkRFUl9TVEFUUwkJCT0gMAl9OwoJZW51bSB7IEhBU19SRUFEX1NUQVRTCQkJPSAxCX07CgllbnVtIHsgSEFTX1VQTE9BRF9TVEFUUwkJCT0gMQl9OwoJZW51bSB7IEhBU19UT1RBTF9TVEFUUwkJCT0gMQl9OwoJZW51bSB7IEhBU19GSVJTVF9SRU5ERVJfU1RBVFMJPSAxCX07CgllbnVtIHsgSEFTX1NFQ09ORF9SRU5ERVJfU1RBVFMJPSAxCX07CgoJZW51bSB7IExPR19DT05UUklCVVRJT05TCQkJPSAxCX07CgllbnVtIHsgTE9HX1VOUkVMQVRFRF9VUExPQURfU0laRQk9IDEgfTsKfTsKCnN0cnVjdCBVcGxvYWRTYW1wbGVBbmFseXplUmVzdWx0CnsKCWZsb2F0IHRyYW5zZmVyUmF0ZU1lZGlhbjsKCWZsb2F0IHRyYW5zZmVyUmF0ZUF0UmFuZ2U7CglmbG9hdCB0cmFuc2ZlclJhdGVBdEluZmluaXR5Owp9OwoKc3RydWN0IFJlbmRlclNhbXBsZUFuYWx5emVSZXN1bHQKewoJZmxvYXQgcmVuZGVyUmF0ZU1lZGlhbjsKCWZsb2F0IHJlbmRlclJhdGVBdFJhbmdlOwoJZmxvYXQgcmVuZGVyUmF0ZUF0SW5maW5pdHk7Cn07CgpjbGFzcyBVbm1hcEZhaWx1cmVFcnJvciA6IHB1YmxpYyBzdGQ6OmV4Y2VwdGlvbgp7CnB1YmxpYzoKCVVubWFwRmFpbHVyZUVycm9yICh2b2lkKSA6IHN0ZDo6ZXhjZXB0aW9uKCkge30KfTsKCnN0YXRpYyBzdGQ6OnN0cmluZyBnZXRIdW1hblJlYWRhYmxlQnl0ZVNpemUgKGludCBudW1CeXRlcykKewoJc3RkOjpvc3RyaW5nc3RyZWFtIGJ1ZjsKCglpZiAobnVtQnl0ZXMgPCAxMDI0KQoJCWJ1ZiA8PCBudW1CeXRlcyA8PCAiIGJ5dGUocykiOwoJZWxzZSBpZiAobnVtQnl0ZXMgPCAxMDI0ICogMTAyNCkKCQlidWYgPDwgZGU6OmZsb2F0VG9TdHJpbmcoKGZsb2F0KW51bUJ5dGVzLzEwMjQuMGYsIDEpIDw8ICIgS2lCIjsKCWVsc2UKCQlidWYgPDwgZGU6OmZsb2F0VG9TdHJpbmcoKGZsb2F0KW51bUJ5dGVzLzEwMjQuMGYvMTAyNC4wZiwgMSkgPDwgIiBNaUIiOwoKCXJldHVybiBidWYuc3RyKCk7Cn0KCnN0YXRpYyBkZVVpbnQ2NCBtZWRpYW5UaW1lTWVtY3B5ICh2b2lkKiBkc3QsIGNvbnN0IHZvaWQqIHNyYywgaW50IG51bUJ5dGVzKQp7CgkvLyBUaW1lIHVzZWQgYnkgbWVtY3B5IGlzIGFzc3VtZWQgdG8gYmUgYXN5bXB0b3RpY2FsbHkgbGluZWFyCgoJLy8gV2l0aCBsYXJnZSBudW1CeXRlcywgdGhlIHByb2JhYmlsaXR5IG9mIGNvbnRleHQgc3dpdGNoIG9yIG90aGVyIHJhbmRvbQoJLy8gZXZlbnQgaXMgaGlnaC4gQXBwbHkgbWVtY3B5IGluIHBhcnRzIGFuZCByZXBvcnQgaG93IG11Y2ggdGltZSB3b3VsZAoJLy8gbWVtY3B5IGhhdmUgdXNlZCB3aXRoIHRoZSBtZWRpYW4gdHJhbnNmZXIgcmF0ZS4KCgkvLyBMZXNzIHRoYW4gMU1pQiwgbm8gbmVlZCB0byBkbyBhbnl0aGluZyBzcGVjaWFsCglpZiAobnVtQnl0ZXMgPCAxMDQ4NTc2KQoJewoJCWRlVWludDY0IHN0YXJ0VGltZTsKCQlkZVVpbnQ2NCBlbmRUaW1lOwoKCQlkZVlpZWxkKCk7CgoJCXN0YXJ0VGltZSA9IGRlR2V0TWljcm9zZWNvbmRzKCk7CgkJZGVNZW1jcHkoZHN0LCBzcmMsIG51bUJ5dGVzKTsKCQllbmRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCgkJcmV0dXJuIGVuZFRpbWUgLSBzdGFydFRpbWU7Cgl9CgllbHNlCgl7CgkJLy8gRG8gbWVtY3B5IGluIG11bHRpcGxlIHBhcnRzCgoJCWNvbnN0IGludAludW1TZWN0aW9ucwkJPSA1OwoJCWNvbnN0IGludAlzZWN0aW9uQWxpZ24JPSAxNjsKCgkJaW50CQkJc2VjdGlvblN0YXJ0c1tudW1TZWN0aW9ucysxXTsKCQlpbnQJCQlzZWN0aW9uTGVuc1tudW1TZWN0aW9uc107CgkJZGVVaW50NjQJc2VjdGlvblRpbWVzW251bVNlY3Rpb25zXTsKCQlkZVVpbnQ2NAltZWRpYW5UaW1lOwoJCWRlVWludDY0CWJlc3RUaW1lCQk9IDA7CgoJCWZvciAoaW50IHNlY3Rpb25OZHggPSAwOyBzZWN0aW9uTmR4IDwgbnVtU2VjdGlvbnM7ICsrc2VjdGlvbk5keCkKCQkJc2VjdGlvblN0YXJ0c1tzZWN0aW9uTmR4XSA9IGRlQWxpZ24zMigobnVtQnl0ZXMgKiBzZWN0aW9uTmR4IC8gbnVtU2VjdGlvbnMpLCBzZWN0aW9uQWxpZ24pOwoJCXNlY3Rpb25TdGFydHNbbnVtU2VjdGlvbnNdID0gbnVtQnl0ZXM7CgoJCWZvciAoaW50IHNlY3Rpb25OZHggPSAwOyBzZWN0aW9uTmR4IDwgbnVtU2VjdGlvbnM7ICsrc2VjdGlvbk5keCkKCQkJc2VjdGlvbkxlbnNbc2VjdGlvbk5keF0gPSBzZWN0aW9uU3RhcnRzW3NlY3Rpb25OZHgrMV0gLSBzZWN0aW9uU3RhcnRzW3NlY3Rpb25OZHhdOwoKCQkvLyBNZW1jcHkgaXMgdXN1YWxseSBjYWxsZWQgYWZ0ZXIgbWFwYnVmZmVyIHJhbmdlIHdoaWNoIG1heSB0YWtlCgkJLy8gYSBsb3Qgb2YgdGltZS4gVG8gcHJldmVudCBwb3dlciBtYW5hZ2VtZW50IGZyb20ga2lja2luZyBpbiBkdXJpbmcKCQkvLyBjb3B5LCB3YXJtIHVwIG1vcmUuCgkJewoJCQlkZVlpZWxkKCk7CgkJCXRjdTo6d2FybXVwQ1BVKCk7CgkJCWRlWWllbGQoKTsKCQl9CgoJCWZvciAoaW50IHNlY3Rpb25OZHggPSAwOyBzZWN0aW9uTmR4IDwgbnVtU2VjdGlvbnM7ICsrc2VjdGlvbk5keCkKCQl7CgkJCWRlVWludDY0IHN0YXJ0VGltZTsKCQkJZGVVaW50NjQgZW5kVGltZTsKCgkJCXN0YXJ0VGltZSA9IGRlR2V0TWljcm9zZWNvbmRzKCk7CgkJCWRlTWVtY3B5KChkZVVpbnQ4Kilkc3QgKyBzZWN0aW9uU3RhcnRzW3NlY3Rpb25OZHhdLCAoY29uc3QgZGVVaW50OCopc3JjICsgc2VjdGlvblN0YXJ0c1tzZWN0aW9uTmR4XSwgc2VjdGlvbkxlbnNbc2VjdGlvbk5keF0pOwoJCQllbmRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCgkJCXNlY3Rpb25UaW1lc1tzZWN0aW9uTmR4XSA9IGVuZFRpbWUgLSBzdGFydFRpbWU7CgoJCQlpZiAoIWJlc3RUaW1lIHx8IHNlY3Rpb25UaW1lc1tzZWN0aW9uTmR4XSA8IGJlc3RUaW1lKQoJCQkJYmVzdFRpbWUgPSBzZWN0aW9uVGltZXNbc2VjdGlvbk5keF07CgoJCQkvLyBEZXRlY3QgaWYgd3JpdGUgdGFrZXMgNTAlIGxvbmdlciB0aGFuIGl0IHNob3VsZCwgYW5kIHdhcm0gdXAgaWYgdGhhdCBoYXBwZW5lZAoJCQlpZiAoc2VjdGlvbk5keCAhPSBudW1TZWN0aW9ucy0xICYmIChmbG9hdClzZWN0aW9uVGltZXNbc2VjdGlvbk5keF0gPiAxLjVmICogKGZsb2F0KWJlc3RUaW1lKQoJCQl7CgkJCQlkZVlpZWxkKCk7CgkJCQl0Y3U6Ondhcm11cENQVSgpOwoJCQkJZGVZaWVsZCgpOwoJCQl9CgkJfQoKCQlzdGQ6OnNvcnQoc2VjdGlvblRpbWVzLCBzZWN0aW9uVGltZXMgKyBudW1TZWN0aW9ucyk7CgoJCWlmICgobnVtU2VjdGlvbnMgJSAyKSA9PSAwKQoJCQltZWRpYW5UaW1lID0gKHNlY3Rpb25UaW1lc1tudW1TZWN0aW9ucyAvIDIgLSAxXSArIHNlY3Rpb25UaW1lc1tudW1TZWN0aW9ucyAvIDJdKSAvIDI7CgkJZWxzZQoJCQltZWRpYW5UaW1lID0gc2VjdGlvblRpbWVzW251bVNlY3Rpb25zIC8gMl07CgoJCXJldHVybiBtZWRpYW5UaW1lKm51bVNlY3Rpb25zOwoJfQp9CgpzdGF0aWMgZmxvYXQgZHVtbXlDYWxjdWxhdGlvbiAoZmxvYXQgaW5pdGlhbCwgaW50IHdvcmtTaXplKQp7CglmbG9hdAlhID0gaW5pdGlhbDsKCWludAkJYiA9IDEyMzsKCglmb3IgKGludCBuZHggPSAwOyBuZHggPCB3b3JrU2l6ZTsgKytuZHgpCgl7CgkJYSA9IGRlRmxvYXRDb3MoYSArIChmbG9hdCliKTsKCQliID0gKGIgKyA2MykgJSAxMDcgKyBkZTo6YWJzKChpbnQpKGEqMTAuMGYpKTsKCX0KCglyZXR1cm4gYSArIChmbG9hdCliOwp9CgpzdGF0aWMgdm9pZCBidXN5V2FpdCAoaW50IG1pY3Jvc2Vjb25kcykKewoJY29uc3QgZGVVaW50NjQJbWF4U2luZ2xlV2FpdFRpbWUJPSAxMDAwOyAvLyAxbXMKCWNvbnN0IGRlVWludDY0CWVuZFRpbWUJCQkJPSBkZUdldE1pY3Jvc2Vjb25kcygpICsgbWljcm9zZWNvbmRzOwoJZmxvYXQJCQlkdW1teQkJCQk9ICp0Y3U6Ondhcm11cENQVUludGVybmFsOjpnX2R1bW15Lm1fdjsKCWludAkJCQl3b3JrU2l6ZQkJCT0gNTAwOwoKCS8vIGV4cG9uZW50aWFsbHkgaW5jcmVhc2Ugd29yaywgY2FwIHRvIDFtcwoJd2hpbGUgKGRlR2V0TWljcm9zZWNvbmRzKCkgPCBlbmRUaW1lKQoJewoJCWNvbnN0IGRlVWludDY0CXN0YXJ0VGltZQkJPSBkZUdldE1pY3Jvc2Vjb25kcygpOwoJCWRlVWludDY0CQl0b3RhbFRpbWU7CgoJCWR1bW15ID0gZHVtbXlDYWxjdWxhdGlvbihkdW1teSwgd29ya1NpemUpOwoKCQl0b3RhbFRpbWUgPSBkZUdldE1pY3Jvc2Vjb25kcygpIC0gc3RhcnRUaW1lOwoKCQlpZiAodG90YWxUaW1lID49IG1heFNpbmdsZVdhaXRUaW1lKQoJCQlicmVhazsKCQllbHNlCgkJCXdvcmtTaXplICo9IDI7Cgl9CgoJLy8gIndhaXQiCgl3aGlsZSAoZGVHZXRNaWNyb3NlY29uZHMoKSA8IGVuZFRpbWUpCgkJZHVtbXkgPSBkdW1teUNhbGN1bGF0aW9uKGR1bW15LCB3b3JrU2l6ZSk7CgoJKnRjdTo6d2FybXVwQ1BVSW50ZXJuYWw6OmdfZHVtbXkubV92ID0gZHVtbXk7Cn0KCi8vIFNhbXBsZSBmcm9tIGdpdmVuIHZhbHVlcyB1c2luZyBsaW5lYXIgaW50ZXJwb2xhdGlvbiBhdCBhIGdpdmVuIHBvc2l0aW9uIGFzIGlmIHZhbHVlcyB3ZXJlIGxhaWQgdG8gcmFuZ2UgWzAsIDFdCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpzdGF0aWMgZmxvYXQgbGluZWFyU2FtcGxlIChjb25zdCBzdGQ6OnZlY3RvcjxUPiYgdmFsdWVzLCBmbG9hdCBwb3NpdGlvbikKewoJREVfQVNTRVJUKHBvc2l0aW9uID49IDAuMGYpOwoJREVfQVNTRVJUKHBvc2l0aW9uIDw9IDEuMGYpOwoKCWNvbnN0IGZsb2F0CWZsb2F0TmR4CQkJPSAoZmxvYXQpKHZhbHVlcy5zaXplKCkgLSAxKSAqIHBvc2l0aW9uOwoJY29uc3QgaW50CWxvd2VyTmR4CQkJPSAoaW50KWRlRmxvYXRGbG9vcihmbG9hdE5keCk7Cgljb25zdCBpbnQJaGlnaGVyTmR4CQkJPSBsb3dlck5keCArIDE7Cgljb25zdCBmbG9hdAlpbnRlcnBvbGF0aW9uRmFjdG9yID0gZmxvYXROZHggLSAoZmxvYXQpbG93ZXJOZHg7CgoJREVfQVNTRVJUKGxvd2VyTmR4ID49IDAgJiYgbG93ZXJOZHggPCAoaW50KXZhbHVlcy5zaXplKCkpOwoJREVfQVNTRVJUKGhpZ2hlck5keCA+PSAwICYmIGhpZ2hlck5keCA8IChpbnQpdmFsdWVzLnNpemUoKSk7CglERV9BU1NFUlQoaW50ZXJwb2xhdGlvbkZhY3RvciA+PSAwICYmIGludGVycG9sYXRpb25GYWN0b3IgPCAxLjBmKTsKCglyZXR1cm4gdGN1OjptaXgoKGZsb2F0KXZhbHVlc1tsb3dlck5keF0sIChmbG9hdCl2YWx1ZXNbaGlnaGVyTmR4XSwgaW50ZXJwb2xhdGlvbkZhY3Rvcik7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzIGNhbGN1bGF0ZVNpbmdsZU9wZXJhdGlvblN0YXRpc3RpY3MgKGNvbnN0IHN0ZDo6dmVjdG9yPFQ+JiBzYW1wbGVzLCBkZVVpbnQ2NCBUOjpTYW1wbGVUeXBlOjoqdGFyZ2V0KQp7CglTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzCXN0YXRzOwoJc3RkOjp2ZWN0b3I8ZGVVaW50NjQ+CQl2YWx1ZXMoc2FtcGxlcy5zaXplKCkpOwoKCWZvciAoaW50IG5keCA9IDA7IG5keCA8IChpbnQpc2FtcGxlcy5zaXplKCk7ICsrbmR4KQoJCXZhbHVlc1tuZHhdID0gc2FtcGxlc1tuZHhdLmR1cmF0aW9uLip0YXJnZXQ7CgoJc3RkOjpzb3J0KHZhbHVlcy5iZWdpbigpLCB2YWx1ZXMuZW5kKCkpOwoKCXN0YXRzLm1pblRpbWUJCQk9IChmbG9hdCl2YWx1ZXMuZnJvbnQoKTsKCXN0YXRzLm1heFRpbWUJCQk9IChmbG9hdCl2YWx1ZXMuYmFjaygpOwoJc3RhdHMubWVkaWFuVGltZQkJPSBsaW5lYXJTYW1wbGUodmFsdWVzLCAwLjVmKTsKCXN0YXRzLm1pbjJEZWNpbGVUaW1lCT0gbGluZWFyU2FtcGxlKHZhbHVlcywgMC4xZik7CglzdGF0cy5tYXg5RGVjaWxlVGltZQk9IGxpbmVhclNhbXBsZSh2YWx1ZXMsIDAuOWYpOwoKCXJldHVybiBzdGF0czsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFN0YXRpc3RpY3NUeXBlLCB0eXBlbmFtZSBTYW1wbGVUeXBlPgp2b2lkIGNhbGN1bGF0ZUJhc2ljU3RhdGlzdGljcyAoU3RhdGlzdGljc1R5cGUmIHN0YXRzLCBjb25zdCBMaW5lUGFyYW1ldGVyc1dpdGhDb25maWRlbmNlJiBmaXQsIGNvbnN0IHN0ZDo6dmVjdG9yPFNhbXBsZVR5cGU+JiBzYW1wbGVzLCBpbnQgU2FtcGxlVHlwZTo6KnByZWRpY3RvcikKewoJc3RkOjp2ZWN0b3I8ZGVVaW50NjQ+IHZhbHVlcyhzYW1wbGVzLnNpemUoKSk7CgoJZm9yIChpbnQgbmR4ID0gMDsgbmR4IDwgKGludClzYW1wbGVzLnNpemUoKTsgKytuZHgpCgkJdmFsdWVzW25keF0gPSBzYW1wbGVzW25keF0uZHVyYXRpb24uZml0UmVzcG9uc2VEdXJhdGlvbjsKCgkvLyBtZWRpYW4gcmF0ZQoJewoJCXN0ZDo6dmVjdG9yPGZsb2F0PiBwcm9jZXNzaW5nUmF0ZXMoc2FtcGxlcy5zaXplKCkpOwoKCQlmb3IgKGludCBuZHggPSAwOyBuZHggPCAoaW50KXNhbXBsZXMuc2l6ZSgpOyArK25keCkKCQl7CgkJCWNvbnN0IGZsb2F0IHRpbWVJblNlY29uZHMgPSAoZmxvYXQpdmFsdWVzW25keF0gLyAxMDAwLjBmIC8gMTAwMC4wZjsKCQkJcHJvY2Vzc2luZ1JhdGVzW25keF0gPSAoZmxvYXQpKHNhbXBsZXNbbmR4XS4qcHJlZGljdG9yKSAvIHRpbWVJblNlY29uZHM7CgkJfQoKCQlzdGQ6OnNvcnQocHJvY2Vzc2luZ1JhdGVzLmJlZ2luKCksIHByb2Nlc3NpbmdSYXRlcy5lbmQoKSk7CgoJCXN0YXRzLm1lZGlhblJhdGUgPSBsaW5lYXJTYW1wbGUocHJvY2Vzc2luZ1JhdGVzLCAwLjVmKTsKCX0KCgkvLyByZXN1bHRzIGNvbXBhcmVkIHRvIHRoZSBhcHByb3hpbWF0aW9uCgl7CgkJc3RkOjp2ZWN0b3I8ZmxvYXQ+IHRpbWVEaWZmcyhzYW1wbGVzLnNpemUoKSk7CgoJCWZvciAoaW50IG5keCA9IDA7IG5keCA8IChpbnQpc2FtcGxlcy5zaXplKCk7ICsrbmR4KQoJCXsKCQkJY29uc3QgZmxvYXQgcHJlZGljdGlvbgk9IChmbG9hdCkoc2FtcGxlc1tuZHhdLipwcmVkaWN0b3IpICogZml0LmNvZWZmaWNpZW50ICsgZml0Lm9mZnNldDsKCQkJY29uc3QgZmxvYXQgYWN0dWFsCQk9IChmbG9hdCl2YWx1ZXNbbmR4XTsKCQkJdGltZURpZmZzW25keF0gPSBhY3R1YWwgLSBwcmVkaWN0aW9uOwoJCX0KCQlzdGQ6OnNvcnQodGltZURpZmZzLmJlZ2luKCksIHRpbWVEaWZmcy5lbmQoKSk7CgoJCXN0YXRzLm1heERpZmZUaW1lCQkJPSB0aW1lRGlmZnMuYmFjaygpOwoJCXN0YXRzLm1heERpZmY5RGVjaWxlVGltZQk9IGxpbmVhclNhbXBsZSh0aW1lRGlmZnMsIDAuOWYpOwoJCXN0YXRzLm1lZGlhbkRpZmZUaW1lCQk9IGxpbmVhclNhbXBsZSh0aW1lRGlmZnMsIDAuNWYpOwoJfQoKCS8vIHJlbGF0aXZlIGNvbXBhcmlzb24gdG8gdGhlIGFwcHJveGltYXRpb24KCXsKCQlzdGQ6OnZlY3RvcjxmbG9hdD4gcmVsYXRpdmVEaWZmcyhzYW1wbGVzLnNpemUoKSk7CgoJCWZvciAoaW50IG5keCA9IDA7IG5keCA8IChpbnQpc2FtcGxlcy5zaXplKCk7ICsrbmR4KQoJCXsKCQkJY29uc3QgZmxvYXQgcHJlZGljdGlvbgk9IChmbG9hdCkoc2FtcGxlc1tuZHhdLipwcmVkaWN0b3IpICogZml0LmNvZWZmaWNpZW50ICsgZml0Lm9mZnNldDsKCQkJY29uc3QgZmxvYXQgYWN0dWFsCQk9IChmbG9hdCl2YWx1ZXNbbmR4XTsKCgkJCS8vIElnbm9yZSBjYXNlcyB3aGVyZSB3ZSBwcmVkaWN0IG5lZ2F0aXZlIHRpbWVzLCBvciBpZgoJCQkvLyByYXRpbyB3b3VsZCBiZSAobmVhcmx5KSBpbmZpbml0ZTogaWdub3JlIGlmIHByZWRpY3RlZAoJCQkvLyB0aW1lIGlzIGxlc3MgdGhhbiAxIG1pY3Jvc2Vjb25kCgkJCWlmIChwcmVkaWN0aW9uIDwgMS4wZikKCQkJCXJlbGF0aXZlRGlmZnNbbmR4XSA9IDAuMGY7CgkJCWVsc2UKCQkJCXJlbGF0aXZlRGlmZnNbbmR4XSA9IChhY3R1YWwgLSBwcmVkaWN0aW9uKSAvIHByZWRpY3Rpb247CgkJfQoJCXN0ZDo6c29ydChyZWxhdGl2ZURpZmZzLmJlZ2luKCksIHJlbGF0aXZlRGlmZnMuZW5kKCkpOwoKCQlzdGF0cy5tYXhSZWxEaWZmVGltZQkJPSByZWxhdGl2ZURpZmZzLmJhY2soKTsKCQlzdGF0cy5tYXg5RGVjaWxlUmVsRGlmZlRpbWUJPSBsaW5lYXJTYW1wbGUocmVsYXRpdmVEaWZmcywgMC45Zik7CgkJc3RhdHMubWVkaWFuUmVsRGlmZlRpbWUJCT0gbGluZWFyU2FtcGxlKHJlbGF0aXZlRGlmZnMsIDAuNWYpOwoJfQoKCS8vIHZhbHVlcyBjYWxjdWxhdGVkIHVzaW5nIHNvcnRlZCB0aW1pbmdzCgoJc3RkOjpzb3J0KHZhbHVlcy5iZWdpbigpLCB2YWx1ZXMuZW5kKCkpOwoKCXN0YXRzLnJlc3VsdC5taW5UaW1lID0gKGZsb2F0KXZhbHVlcy5mcm9udCgpOwoJc3RhdHMucmVzdWx0Lm1heFRpbWUgPSAoZmxvYXQpdmFsdWVzLmJhY2soKTsKCXN0YXRzLnJlc3VsdC5tZWRpYW5UaW1lID0gbGluZWFyU2FtcGxlKHZhbHVlcywgMC41Zik7CglzdGF0cy5yZXN1bHQubWluMkRlY2lsZVRpbWUgPSBsaW5lYXJTYW1wbGUodmFsdWVzLCAwLjFmKTsKCXN0YXRzLnJlc3VsdC5tYXg5RGVjaWxlVGltZSA9IGxpbmVhclNhbXBsZSh2YWx1ZXMsIDAuOWYpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU3RhdGlzdGljc1R5cGUsIHR5cGVuYW1lIFNhbXBsZVR5cGU+CnZvaWQgY2FsY3VsYXRlQmFzaWNUcmFuc2ZlclN0YXRpc3RpY3MgKFN0YXRpc3RpY3NUeXBlJiBzdGF0cywgY29uc3QgTGluZVBhcmFtZXRlcnNXaXRoQ29uZmlkZW5jZSYgZml0LCBjb25zdCBzdGQ6OnZlY3RvcjxTYW1wbGVUeXBlPiYgc2FtcGxlcykKewoJY2FsY3VsYXRlQmFzaWNTdGF0aXN0aWNzKHN0YXRzLCBmaXQsIHNhbXBsZXMsICZTYW1wbGVUeXBlOjp3cml0dGVuU2l6ZSk7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTdGF0aXN0aWNzVHlwZSwgdHlwZW5hbWUgU2FtcGxlVHlwZT4Kdm9pZCBjYWxjdWxhdGVCYXNpY1JlbmRlclN0YXRpc3RpY3MgKFN0YXRpc3RpY3NUeXBlJiBzdGF0cywgY29uc3QgTGluZVBhcmFtZXRlcnNXaXRoQ29uZmlkZW5jZSYgZml0LCBjb25zdCBzdGQ6OnZlY3RvcjxTYW1wbGVUeXBlPiYgc2FtcGxlcykKewoJY2FsY3VsYXRlQmFzaWNTdGF0aXN0aWNzKHN0YXRzLCBmaXQsIHNhbXBsZXMsICZTYW1wbGVUeXBlOjpyZW5kZXJEYXRhU2l6ZSk7Cn0KCnN0YXRpYyBTaW5nbGVDYWxsU3RhdGlzdGljcyBjYWxjdWxhdGVTYW1wbGVTdGF0aXN0aWNzIChjb25zdCBMaW5lUGFyYW1ldGVyc1dpdGhDb25maWRlbmNlJiBmaXQsIGNvbnN0IHN0ZDo6dmVjdG9yPFVwbG9hZFNhbXBsZVJlc3VsdDxTaW5nbGVPcGVyYXRpb25EdXJhdGlvbj4gPiYgc2FtcGxlcykKewoJU2luZ2xlQ2FsbFN0YXRpc3RpY3Mgc3RhdHM7CgoJY2FsY3VsYXRlQmFzaWNUcmFuc2ZlclN0YXRpc3RpY3Moc3RhdHMsIGZpdCwgc2FtcGxlcyk7CgoJcmV0dXJuIHN0YXRzOwp9CgpzdGF0aWMgTWFwQ2FsbFN0YXRpc3RpY3MgY2FsY3VsYXRlU2FtcGxlU3RhdGlzdGljcyAoY29uc3QgTGluZVBhcmFtZXRlcnNXaXRoQ29uZmlkZW5jZSYgZml0LCBjb25zdCBzdGQ6OnZlY3RvcjxVcGxvYWRTYW1wbGVSZXN1bHQ8TWFwQnVmZmVyUmFuZ2VEdXJhdGlvbj4gPiYgc2FtcGxlcykKewoJTWFwQ2FsbFN0YXRpc3RpY3Mgc3RhdHM7CgoJY2FsY3VsYXRlQmFzaWNUcmFuc2ZlclN0YXRpc3RpY3Moc3RhdHMsIGZpdCwgc2FtcGxlcyk7CgoJc3RhdHMubWFwCT0gY2FsY3VsYXRlU2luZ2xlT3BlcmF0aW9uU3RhdGlzdGljcyhzYW1wbGVzLCAmTWFwQnVmZmVyUmFuZ2VEdXJhdGlvbjo6bWFwRHVyYXRpb24pOwoJc3RhdHMudW5tYXAJPSBjYWxjdWxhdGVTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzKHNhbXBsZXMsICZNYXBCdWZmZXJSYW5nZUR1cmF0aW9uOjp1bm1hcER1cmF0aW9uKTsKCXN0YXRzLndyaXRlCT0gY2FsY3VsYXRlU2luZ2xlT3BlcmF0aW9uU3RhdGlzdGljcyhzYW1wbGVzLCAmTWFwQnVmZmVyUmFuZ2VEdXJhdGlvbjo6d3JpdGVEdXJhdGlvbik7CglzdGF0cy5hbGxvYwk9IGNhbGN1bGF0ZVNpbmdsZU9wZXJhdGlvblN0YXRpc3RpY3Moc2FtcGxlcywgJk1hcEJ1ZmZlclJhbmdlRHVyYXRpb246OmFsbG9jRHVyYXRpb24pOwoKCXJldHVybiBzdGF0czsKfQoKc3RhdGljIE1hcEZsdXNoQ2FsbFN0YXRpc3RpY3MgY2FsY3VsYXRlU2FtcGxlU3RhdGlzdGljcyAoY29uc3QgTGluZVBhcmFtZXRlcnNXaXRoQ29uZmlkZW5jZSYgZml0LCBjb25zdCBzdGQ6OnZlY3RvcjxVcGxvYWRTYW1wbGVSZXN1bHQ8TWFwQnVmZmVyUmFuZ2VGbHVzaER1cmF0aW9uPiA+JiBzYW1wbGVzKQp7CglNYXBGbHVzaENhbGxTdGF0aXN0aWNzIHN0YXRzOwoKCWNhbGN1bGF0ZUJhc2ljVHJhbnNmZXJTdGF0aXN0aWNzKHN0YXRzLCBmaXQsIHNhbXBsZXMpOwoKCXN0YXRzLm1hcAk9IGNhbGN1bGF0ZVNpbmdsZU9wZXJhdGlvblN0YXRpc3RpY3Moc2FtcGxlcywgJk1hcEJ1ZmZlclJhbmdlRmx1c2hEdXJhdGlvbjo6bWFwRHVyYXRpb24pOwoJc3RhdHMudW5tYXAJPSBjYWxjdWxhdGVTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzKHNhbXBsZXMsICZNYXBCdWZmZXJSYW5nZUZsdXNoRHVyYXRpb246OnVubWFwRHVyYXRpb24pOwoJc3RhdHMud3JpdGUJPSBjYWxjdWxhdGVTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzKHNhbXBsZXMsICZNYXBCdWZmZXJSYW5nZUZsdXNoRHVyYXRpb246OndyaXRlRHVyYXRpb24pOwoJc3RhdHMuZmx1c2gJPSBjYWxjdWxhdGVTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzKHNhbXBsZXMsICZNYXBCdWZmZXJSYW5nZUZsdXNoRHVyYXRpb246OmZsdXNoRHVyYXRpb24pOwoJc3RhdHMuYWxsb2MJPSBjYWxjdWxhdGVTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzKHNhbXBsZXMsICZNYXBCdWZmZXJSYW5nZUZsdXNoRHVyYXRpb246OmFsbG9jRHVyYXRpb24pOwoKCXJldHVybiBzdGF0czsKfQoKc3RhdGljIE1hcENhbGxTdGF0aXN0aWNzIGNhbGN1bGF0ZVNhbXBsZVN0YXRpc3RpY3MgKGNvbnN0IExpbmVQYXJhbWV0ZXJzV2l0aENvbmZpZGVuY2UmIGZpdCwgY29uc3Qgc3RkOjp2ZWN0b3I8VXBsb2FkU2FtcGxlUmVzdWx0PE1hcEJ1ZmZlclJhbmdlRHVyYXRpb25Ob0FsbG9jPiA+JiBzYW1wbGVzKQp7CglNYXBDYWxsU3RhdGlzdGljcyBzdGF0czsKCgljYWxjdWxhdGVCYXNpY1RyYW5zZmVyU3RhdGlzdGljcyhzdGF0cywgZml0LCBzYW1wbGVzKTsKCglzdGF0cy5tYXAJPSBjYWxjdWxhdGVTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzKHNhbXBsZXMsICZNYXBCdWZmZXJSYW5nZUR1cmF0aW9uTm9BbGxvYzo6bWFwRHVyYXRpb24pOwoJc3RhdHMudW5tYXAJPSBjYWxjdWxhdGVTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzKHNhbXBsZXMsICZNYXBCdWZmZXJSYW5nZUR1cmF0aW9uTm9BbGxvYzo6dW5tYXBEdXJhdGlvbik7CglzdGF0cy53cml0ZQk9IGNhbGN1bGF0ZVNpbmdsZU9wZXJhdGlvblN0YXRpc3RpY3Moc2FtcGxlcywgJk1hcEJ1ZmZlclJhbmdlRHVyYXRpb25Ob0FsbG9jOjp3cml0ZUR1cmF0aW9uKTsKCglyZXR1cm4gc3RhdHM7Cn0KCnN0YXRpYyBNYXBGbHVzaENhbGxTdGF0aXN0aWNzIGNhbGN1bGF0ZVNhbXBsZVN0YXRpc3RpY3MgKGNvbnN0IExpbmVQYXJhbWV0ZXJzV2l0aENvbmZpZGVuY2UmIGZpdCwgY29uc3Qgc3RkOjp2ZWN0b3I8VXBsb2FkU2FtcGxlUmVzdWx0PE1hcEJ1ZmZlclJhbmdlRmx1c2hEdXJhdGlvbk5vQWxsb2M+ID4mIHNhbXBsZXMpCnsKCU1hcEZsdXNoQ2FsbFN0YXRpc3RpY3Mgc3RhdHM7CgoJY2FsY3VsYXRlQmFzaWNUcmFuc2ZlclN0YXRpc3RpY3Moc3RhdHMsIGZpdCwgc2FtcGxlcyk7CgoJc3RhdHMubWFwCT0gY2FsY3VsYXRlU2luZ2xlT3BlcmF0aW9uU3RhdGlzdGljcyhzYW1wbGVzLCAmTWFwQnVmZmVyUmFuZ2VGbHVzaER1cmF0aW9uTm9BbGxvYzo6bWFwRHVyYXRpb24pOwoJc3RhdHMudW5tYXAJPSBjYWxjdWxhdGVTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzKHNhbXBsZXMsICZNYXBCdWZmZXJSYW5nZUZsdXNoRHVyYXRpb25Ob0FsbG9jOjp1bm1hcER1cmF0aW9uKTsKCXN0YXRzLndyaXRlCT0gY2FsY3VsYXRlU2luZ2xlT3BlcmF0aW9uU3RhdGlzdGljcyhzYW1wbGVzLCAmTWFwQnVmZmVyUmFuZ2VGbHVzaER1cmF0aW9uTm9BbGxvYzo6d3JpdGVEdXJhdGlvbik7CglzdGF0cy5mbHVzaAk9IGNhbGN1bGF0ZVNpbmdsZU9wZXJhdGlvblN0YXRpc3RpY3Moc2FtcGxlcywgJk1hcEJ1ZmZlclJhbmdlRmx1c2hEdXJhdGlvbk5vQWxsb2M6OmZsdXNoRHVyYXRpb24pOwoKCXJldHVybiBzdGF0czsKfQoKc3RhdGljIFJlbmRlclJlYWRTdGF0aXN0aWNzIGNhbGN1bGF0ZVNhbXBsZVN0YXRpc3RpY3MgKGNvbnN0IExpbmVQYXJhbWV0ZXJzV2l0aENvbmZpZGVuY2UmIGZpdCwgY29uc3Qgc3RkOjp2ZWN0b3I8UmVuZGVyU2FtcGxlUmVzdWx0PFJlbmRlclJlYWREdXJhdGlvbj4gPiYgc2FtcGxlcykKewoJUmVuZGVyUmVhZFN0YXRpc3RpY3Mgc3RhdHM7CgoJY2FsY3VsYXRlQmFzaWNSZW5kZXJTdGF0aXN0aWNzKHN0YXRzLCBmaXQsIHNhbXBsZXMpOwoKCXN0YXRzLnJlbmRlcgk9IGNhbGN1bGF0ZVNpbmdsZU9wZXJhdGlvblN0YXRpc3RpY3Moc2FtcGxlcywgJlJlbmRlclJlYWREdXJhdGlvbjo6cmVuZGVyRHVyYXRpb24pOwoJc3RhdHMucmVhZAkJPSBjYWxjdWxhdGVTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzKHNhbXBsZXMsICZSZW5kZXJSZWFkRHVyYXRpb246OnJlYWREdXJhdGlvbik7CglzdGF0cy50b3RhbAkJPSBjYWxjdWxhdGVTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzKHNhbXBsZXMsICZSZW5kZXJSZWFkRHVyYXRpb246OnRvdGFsRHVyYXRpb24pOwoKCXJldHVybiBzdGF0czsKfQoKc3RhdGljIFJlbmRlclJlYWRTdGF0aXN0aWNzIGNhbGN1bGF0ZVNhbXBsZVN0YXRpc3RpY3MgKGNvbnN0IExpbmVQYXJhbWV0ZXJzV2l0aENvbmZpZGVuY2UmIGZpdCwgY29uc3Qgc3RkOjp2ZWN0b3I8UmVuZGVyU2FtcGxlUmVzdWx0PFVucmVsYXRlZFVwbG9hZFJlbmRlclJlYWREdXJhdGlvbj4gPiYgc2FtcGxlcykKewoJUmVuZGVyUmVhZFN0YXRpc3RpY3Mgc3RhdHM7CgoJY2FsY3VsYXRlQmFzaWNSZW5kZXJTdGF0aXN0aWNzKHN0YXRzLCBmaXQsIHNhbXBsZXMpOwoKCXN0YXRzLnJlbmRlcgk9IGNhbGN1bGF0ZVNpbmdsZU9wZXJhdGlvblN0YXRpc3RpY3Moc2FtcGxlcywgJlVucmVsYXRlZFVwbG9hZFJlbmRlclJlYWREdXJhdGlvbjo6cmVuZGVyRHVyYXRpb24pOwoJc3RhdHMucmVhZAkJPSBjYWxjdWxhdGVTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzKHNhbXBsZXMsICZVbnJlbGF0ZWRVcGxvYWRSZW5kZXJSZWFkRHVyYXRpb246OnJlYWREdXJhdGlvbik7CglzdGF0cy50b3RhbAkJPSBjYWxjdWxhdGVTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzKHNhbXBsZXMsICZVbnJlbGF0ZWRVcGxvYWRSZW5kZXJSZWFkRHVyYXRpb246OnRvdGFsRHVyYXRpb24pOwoKCXJldHVybiBzdGF0czsKfQoKc3RhdGljIFVwbG9hZFJlbmRlclJlYWRTdGF0aXN0aWNzIGNhbGN1bGF0ZVNhbXBsZVN0YXRpc3RpY3MgKGNvbnN0IExpbmVQYXJhbWV0ZXJzV2l0aENvbmZpZGVuY2UmIGZpdCwgY29uc3Qgc3RkOjp2ZWN0b3I8UmVuZGVyU2FtcGxlUmVzdWx0PFVwbG9hZFJlbmRlclJlYWREdXJhdGlvbj4gPiYgc2FtcGxlcykKewoJVXBsb2FkUmVuZGVyUmVhZFN0YXRpc3RpY3Mgc3RhdHM7CgoJY2FsY3VsYXRlQmFzaWNSZW5kZXJTdGF0aXN0aWNzKHN0YXRzLCBmaXQsIHNhbXBsZXMpOwoKCXN0YXRzLnVwbG9hZAk9IGNhbGN1bGF0ZVNpbmdsZU9wZXJhdGlvblN0YXRpc3RpY3Moc2FtcGxlcywgJlVwbG9hZFJlbmRlclJlYWREdXJhdGlvbjo6dXBsb2FkRHVyYXRpb24pOwoJc3RhdHMucmVuZGVyCT0gY2FsY3VsYXRlU2luZ2xlT3BlcmF0aW9uU3RhdGlzdGljcyhzYW1wbGVzLCAmVXBsb2FkUmVuZGVyUmVhZER1cmF0aW9uOjpyZW5kZXJEdXJhdGlvbik7CglzdGF0cy5yZWFkCQk9IGNhbGN1bGF0ZVNpbmdsZU9wZXJhdGlvblN0YXRpc3RpY3Moc2FtcGxlcywgJlVwbG9hZFJlbmRlclJlYWREdXJhdGlvbjo6cmVhZER1cmF0aW9uKTsKCXN0YXRzLnRvdGFsCQk9IGNhbGN1bGF0ZVNpbmdsZU9wZXJhdGlvblN0YXRpc3RpY3Moc2FtcGxlcywgJlVwbG9hZFJlbmRlclJlYWREdXJhdGlvbjo6dG90YWxEdXJhdGlvbik7CgoJcmV0dXJuIHN0YXRzOwp9CgpzdGF0aWMgVXBsb2FkUmVuZGVyUmVhZFN0YXRpc3RpY3MgY2FsY3VsYXRlU2FtcGxlU3RhdGlzdGljcyAoY29uc3QgTGluZVBhcmFtZXRlcnNXaXRoQ29uZmlkZW5jZSYgZml0LCBjb25zdCBzdGQ6OnZlY3RvcjxSZW5kZXJTYW1wbGVSZXN1bHQ8VXBsb2FkUmVuZGVyUmVhZER1cmF0aW9uV2l0aFVucmVsYXRlZFVwbG9hZFNpemU+ID4mIHNhbXBsZXMpCnsKCVVwbG9hZFJlbmRlclJlYWRTdGF0aXN0aWNzIHN0YXRzOwoKCWNhbGN1bGF0ZUJhc2ljUmVuZGVyU3RhdGlzdGljcyhzdGF0cywgZml0LCBzYW1wbGVzKTsKCglzdGF0cy51cGxvYWQJPSBjYWxjdWxhdGVTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzKHNhbXBsZXMsICZVcGxvYWRSZW5kZXJSZWFkRHVyYXRpb25XaXRoVW5yZWxhdGVkVXBsb2FkU2l6ZTo6dXBsb2FkRHVyYXRpb24pOwoJc3RhdHMucmVuZGVyCT0gY2FsY3VsYXRlU2luZ2xlT3BlcmF0aW9uU3RhdGlzdGljcyhzYW1wbGVzLCAmVXBsb2FkUmVuZGVyUmVhZER1cmF0aW9uV2l0aFVucmVsYXRlZFVwbG9hZFNpemU6OnJlbmRlckR1cmF0aW9uKTsKCXN0YXRzLnJlYWQJCT0gY2FsY3VsYXRlU2luZ2xlT3BlcmF0aW9uU3RhdGlzdGljcyhzYW1wbGVzLCAmVXBsb2FkUmVuZGVyUmVhZER1cmF0aW9uV2l0aFVucmVsYXRlZFVwbG9hZFNpemU6OnJlYWREdXJhdGlvbik7CglzdGF0cy50b3RhbAkJPSBjYWxjdWxhdGVTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzKHNhbXBsZXMsICZVcGxvYWRSZW5kZXJSZWFkRHVyYXRpb25XaXRoVW5yZWxhdGVkVXBsb2FkU2l6ZTo6dG90YWxEdXJhdGlvbik7CgoJcmV0dXJuIHN0YXRzOwp9CgpzdGF0aWMgUmVuZGVyVXBsb2FkUmVuZGVyUmVhZFN0YXRpc3RpY3MgY2FsY3VsYXRlU2FtcGxlU3RhdGlzdGljcyAoY29uc3QgTGluZVBhcmFtZXRlcnNXaXRoQ29uZmlkZW5jZSYgZml0LCBjb25zdCBzdGQ6OnZlY3RvcjxSZW5kZXJTYW1wbGVSZXN1bHQ8UmVuZGVyVXBsb2FkUmVuZGVyUmVhZER1cmF0aW9uPiA+JiBzYW1wbGVzKQp7CglSZW5kZXJVcGxvYWRSZW5kZXJSZWFkU3RhdGlzdGljcyBzdGF0czsKCgljYWxjdWxhdGVCYXNpY1JlbmRlclN0YXRpc3RpY3Moc3RhdHMsIGZpdCwgc2FtcGxlcyk7CgoJc3RhdHMuZmlyc3RSZW5kZXIJPSBjYWxjdWxhdGVTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzKHNhbXBsZXMsICZSZW5kZXJVcGxvYWRSZW5kZXJSZWFkRHVyYXRpb246OmZpcnN0UmVuZGVyRHVyYXRpb24pOwoJc3RhdHMudXBsb2FkCQk9IGNhbGN1bGF0ZVNpbmdsZU9wZXJhdGlvblN0YXRpc3RpY3Moc2FtcGxlcywgJlJlbmRlclVwbG9hZFJlbmRlclJlYWREdXJhdGlvbjo6dXBsb2FkRHVyYXRpb24pOwoJc3RhdHMuc2Vjb25kUmVuZGVyCT0gY2FsY3VsYXRlU2luZ2xlT3BlcmF0aW9uU3RhdGlzdGljcyhzYW1wbGVzLCAmUmVuZGVyVXBsb2FkUmVuZGVyUmVhZER1cmF0aW9uOjpzZWNvbmRSZW5kZXJEdXJhdGlvbik7CglzdGF0cy5yZWFkCQkJPSBjYWxjdWxhdGVTaW5nbGVPcGVyYXRpb25TdGF0aXN0aWNzKHNhbXBsZXMsICZSZW5kZXJVcGxvYWRSZW5kZXJSZWFkRHVyYXRpb246OnJlYWREdXJhdGlvbik7CglzdGF0cy50b3RhbAkJCT0gY2FsY3VsYXRlU2luZ2xlT3BlcmF0aW9uU3RhdGlzdGljcyhzYW1wbGVzLCAmUmVuZGVyVXBsb2FkUmVuZGVyUmVhZER1cmF0aW9uOjp0b3RhbER1cmF0aW9uKTsKCglyZXR1cm4gc3RhdHM7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBEdXJhdGlvblR5cGU+CnN0YXRpYyBMaW5lUGFyYW1ldGVyc1dpdGhDb25maWRlbmNlIGZpdExpbmVUb1NhbXBsZXMgKGNvbnN0IHN0ZDo6dmVjdG9yPFVwbG9hZFNhbXBsZVJlc3VsdDxEdXJhdGlvblR5cGU+ID4mIHNhbXBsZXMsIGludCBiZWdpbk5keCwgaW50IGVuZE5keCwgaW50IHN0ZXAsIGRlVWludDY0IER1cmF0aW9uVHlwZTo6KnRhcmdldCA9ICZEdXJhdGlvblR5cGU6OmZpdFJlc3BvbnNlRHVyYXRpb24pCnsKCXN0ZDo6dmVjdG9yPHRjdTo6VmVjMj4gc2FtcGxlUG9pbnRzOwoKCWZvciAoaW50IHNhbXBsZU5keCA9IGJlZ2luTmR4OyBzYW1wbGVOZHggPCBlbmROZHg7IHNhbXBsZU5keCArPSBzdGVwKQoJewoJCXRjdTo6VmVjMiBwb2ludDsKCgkJcG9pbnQueCgpID0gKGZsb2F0KShzYW1wbGVzW3NhbXBsZU5keF0ud3JpdHRlblNpemUpOwoJCXBvaW50LnkoKSA9IChmbG9hdCkoc2FtcGxlc1tzYW1wbGVOZHhdLmR1cmF0aW9uLip0YXJnZXQpOwoKCQlzYW1wbGVQb2ludHMucHVzaF9iYWNrKHBvaW50KTsKCX0KCglyZXR1cm4gdGhlaWxTZW5TaWVnZWxMaW5lYXJSZWdyZXNzaW9uKHNhbXBsZVBvaW50cywgMC42Zik7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBEdXJhdGlvblR5cGU+CnN0YXRpYyBMaW5lUGFyYW1ldGVyc1dpdGhDb25maWRlbmNlIGZpdExpbmVUb1NhbXBsZXMgKGNvbnN0IHN0ZDo6dmVjdG9yPFJlbmRlclNhbXBsZVJlc3VsdDxEdXJhdGlvblR5cGU+ID4mIHNhbXBsZXMsIGludCBiZWdpbk5keCwgaW50IGVuZE5keCwgaW50IHN0ZXAsIGRlVWludDY0IER1cmF0aW9uVHlwZTo6KnRhcmdldCA9ICZEdXJhdGlvblR5cGU6OmZpdFJlc3BvbnNlRHVyYXRpb24pCnsKCXN0ZDo6dmVjdG9yPHRjdTo6VmVjMj4gc2FtcGxlUG9pbnRzOwoKCWZvciAoaW50IHNhbXBsZU5keCA9IGJlZ2luTmR4OyBzYW1wbGVOZHggPCBlbmROZHg7IHNhbXBsZU5keCArPSBzdGVwKQoJewoJCXRjdTo6VmVjMiBwb2ludDsKCgkJcG9pbnQueCgpID0gKGZsb2F0KShzYW1wbGVzW3NhbXBsZU5keF0ucmVuZGVyRGF0YVNpemUpOwoJCXBvaW50LnkoKSA9IChmbG9hdCkoc2FtcGxlc1tzYW1wbGVOZHhdLmR1cmF0aW9uLip0YXJnZXQpOwoKCQlzYW1wbGVQb2ludHMucHVzaF9iYWNrKHBvaW50KTsKCX0KCglyZXR1cm4gdGhlaWxTZW5TaWVnZWxMaW5lYXJSZWdyZXNzaW9uKHNhbXBsZVBvaW50cywgMC42Zik7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpzdGF0aWMgTGluZVBhcmFtZXRlcnNXaXRoQ29uZmlkZW5jZSBmaXRMaW5lVG9TYW1wbGVzIChjb25zdCBzdGQ6OnZlY3RvcjxUPiYgc2FtcGxlcywgaW50IGJlZ2luTmR4LCBpbnQgZW5kTmR4LCBkZVVpbnQ2NCBUOjpTYW1wbGVUeXBlOjoqdGFyZ2V0ID0gJlQ6OlNhbXBsZVR5cGU6OmZpdFJlc3BvbnNlRHVyYXRpb24pCnsKCXJldHVybiBmaXRMaW5lVG9TYW1wbGVzKHNhbXBsZXMsIGJlZ2luTmR4LCBlbmROZHgsIDEsIHRhcmdldCk7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpzdGF0aWMgTGluZVBhcmFtZXRlcnNXaXRoQ29uZmlkZW5jZSBmaXRMaW5lVG9TYW1wbGVzIChjb25zdCBzdGQ6OnZlY3RvcjxUPiYgc2FtcGxlcywgZGVVaW50NjQgVDo6U2FtcGxlVHlwZTo6KnRhcmdldCA9ICZUOjpTYW1wbGVUeXBlOjpmaXRSZXNwb25zZUR1cmF0aW9uKQp7CglyZXR1cm4gZml0TGluZVRvU2FtcGxlcyhzYW1wbGVzLCAwLCAoaW50KXNhbXBsZXMuc2l6ZSgpLCB0YXJnZXQpOwp9CgpzdGF0aWMgZmxvYXQgZ2V0QXJlYUJldHdlZW5MaW5lcyAoZmxvYXQgeG1pbiwgZmxvYXQgeG1heCwgZmxvYXQgbGluZUFPZmZzZXQsIGZsb2F0IGxpbmVBQ29lZmZpY2llbnQsIGZsb2F0IGxpbmVCT2Zmc2V0LCBmbG9hdCBsaW5lQkNvZWZmaWNpZW50KQp7Cgljb25zdCBmbG9hdCBsaW5lQU1pbgkJPSBsaW5lQU9mZnNldCArIGxpbmVBQ29lZmZpY2llbnQgKiB4bWluOwoJY29uc3QgZmxvYXQgbGluZUFNYXgJCT0gbGluZUFPZmZzZXQgKyBsaW5lQUNvZWZmaWNpZW50ICogeG1heDsKCWNvbnN0IGZsb2F0IGxpbmVCTWluCQk9IGxpbmVCT2Zmc2V0ICsgbGluZUJDb2VmZmljaWVudCAqIHhtaW47Cgljb25zdCBmbG9hdCBsaW5lQk1heAkJPSBsaW5lQk9mZnNldCArIGxpbmVCQ29lZmZpY2llbnQgKiB4bWF4OwoJY29uc3QgYm9vbAlhT3ZlckJBdEJlZ2luCT0gKGxpbmVBTWluID4gbGluZUJNaW4pOwoJY29uc3QgYm9vbAlhT3ZlckJBdEVuZAkJPSAobGluZUFNYXggPiBsaW5lQk1heCk7CgoJaWYgKGFPdmVyQkF0QmVnaW4gPT0gYU92ZXJCQXRFbmQpCgl7CgkJLy8gbGluZXMgZG8gbm90IGludGVyc2VjdAoKCQljb25zdCBmbG9hdCBtaWRwb2ludAk9ICh4bWluICsgeG1heCkgLyAyLjBmOwoJCWNvbnN0IGZsb2F0IHdpZHRoCQk9ICh4bWF4IC0geG1pbik7CgoJCWNvbnN0IGZsb2F0IGxpbmVBSGVpZ2h0CT0gbGluZUFPZmZzZXQgKyBsaW5lQUNvZWZmaWNpZW50ICogbWlkcG9pbnQ7CgkJY29uc3QgZmxvYXQgbGluZUJIZWlnaHQJPSBsaW5lQk9mZnNldCArIGxpbmVCQ29lZmZpY2llbnQgKiBtaWRwb2ludDsKCgkJcmV0dXJuIHdpZHRoICogZGU6OmFicyhsaW5lQUhlaWdodCAtIGxpbmVCSGVpZ2h0KTsKCX0KCWVsc2UKCXsKCgkJLy8gbGluZXMgaW50ZXJzZWN0CgoJCWNvbnN0IGZsb2F0IGFwcHJvYWNoQ29lZmZpZW50CT0gZGU6OmFicyhsaW5lQUNvZWZmaWNpZW50IC0gbGluZUJDb2VmZmljaWVudCk7CgkJY29uc3QgZmxvYXQgZXBzaWxvbgkJCQk9IDAuMDAwMWY7CgkJY29uc3QgZmxvYXQgbGVmdEhlaWdodAkJCT0gZGU6OmFicyhsaW5lQU1pbiAtIGxpbmVCTWluKTsKCQljb25zdCBmbG9hdCByaWdodEhlaWdodAkJCT0gZGU6OmFicyhsaW5lQU1heCAtIGxpbmVCTWF4KTsKCgkJaWYgKGFwcHJvYWNoQ29lZmZpZW50IDwgZXBzaWxvbikKCQkJcmV0dXJuIDAuMGY7CgoJCXJldHVybiAoMC41ZiAqIGxlZnRIZWlnaHQgKiAobGVmdEhlaWdodCAvIGFwcHJvYWNoQ29lZmZpZW50KSkgKyAoMC41ZiAqIHJpZ2h0SGVpZ2h0ICogKHJpZ2h0SGVpZ2h0IC8gYXBwcm9hY2hDb2VmZmllbnQpKTsKCX0KfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CnN0YXRpYyBmbG9hdCBjYWxjdWxhdGVTYW1wbGVGaXRMaW5lYXJpdHkgKGNvbnN0IHN0ZDo6dmVjdG9yPFQ+JiBzYW1wbGVzLCBpbnQgVDo6KnByZWRpY3RvcikKewoJLy8gQ29tcGFyZSB0aGUgZml0dGVkIGxpbmUgb2YgZmlyc3QgaGFsZiBvZiB0aGUgc2FtcGxlcyB0byB0aGUgZml0dGVkIGxpbmUgb2YKCS8vIHRoZSBzZWNvbmQgaGFsZiBvZiB0aGUgc2FtcGxlcy4gQ2FsY3VsYXRlIGEgQUFCQiB0aGF0IGZ1bGx5IGNvbnRhaW5zIGV2ZXJ5CgkvLyBzYW1wbGUncyB4IGNvbXBvbmVudCBhbmQgYm90aCBmaXQgbGluZXMgaW4gdGhpcyByYW5nZS4gQ2FsY3VsYXRlIHRoZSByYXRpbwoJLy8gb2YgdGhlIGFyZWEgYmV0d2VlbiB0aGUgbGluZXMgYW5kIHRoZSBBQUJCLgoKCWNvbnN0IGZsb2F0CQkJCWVwc2lsb24JCQkJPSAxLmUtNmY7Cgljb25zdCBpbnQJCQkJbWlkUG9pbnQJCQk9IChpbnQpc2FtcGxlcy5zaXplKCkgLyAyOwoJY29uc3QgTGluZVBhcmFtZXRlcnNXaXRoQ29uZmlkZW5jZQlzdGFydEFwcHJveGltYXRpb24JPSBmaXRMaW5lVG9TYW1wbGVzKHNhbXBsZXMsIDAsIG1pZFBvaW50LCAmVDo6U2FtcGxlVHlwZTo6Zml0UmVzcG9uc2VEdXJhdGlvbik7Cgljb25zdCBMaW5lUGFyYW1ldGVyc1dpdGhDb25maWRlbmNlCWVuZEFwcHJveGltYXRpb24JPSBmaXRMaW5lVG9TYW1wbGVzKHNhbXBsZXMsIG1pZFBvaW50LCAoaW50KXNhbXBsZXMuc2l6ZSgpLCAmVDo6U2FtcGxlVHlwZTo6Zml0UmVzcG9uc2VEdXJhdGlvbik7CgoJY29uc3QgZmxvYXQJCQkJYWFiYk1pblgJCQk9IChmbG9hdCkoc2FtcGxlcy5mcm9udCgpLipwcmVkaWN0b3IpOwoJY29uc3QgZmxvYXQJCQkJYWFiYk1pblkJCQk9IGRlOjptaW4oc3RhcnRBcHByb3hpbWF0aW9uLm9mZnNldCArIHN0YXJ0QXBwcm94aW1hdGlvbi5jb2VmZmljaWVudCphYWJiTWluWCwgZW5kQXBwcm94aW1hdGlvbi5vZmZzZXQgKyBlbmRBcHByb3hpbWF0aW9uLmNvZWZmaWNpZW50KmFhYmJNaW5YKTsKCWNvbnN0IGZsb2F0CQkJCWFhYmJNYXhYCQkJPSAoZmxvYXQpKHNhbXBsZXMuYmFjaygpLipwcmVkaWN0b3IpOwoJY29uc3QgZmxvYXQJCQkJYWFiYk1heFkJCQk9IGRlOjptYXgoc3RhcnRBcHByb3hpbWF0aW9uLm9mZnNldCArIHN0YXJ0QXBwcm94aW1hdGlvbi5jb2VmZmljaWVudCphYWJiTWF4WCwgZW5kQXBwcm94aW1hdGlvbi5vZmZzZXQgKyBlbmRBcHByb3hpbWF0aW9uLmNvZWZmaWNpZW50KmFhYmJNYXhYKTsKCgljb25zdCBmbG9hdAkJCQlhYWJiQXJlYQkJCT0gKGFhYmJNYXhYIC0gYWFiYk1pblgpICogKGFhYmJNYXhZIC0gYWFiYk1pblkpOwoJY29uc3QgZmxvYXQJCQkJYXJlYUJldHdlZW5MaW5lcwk9IGdldEFyZWFCZXR3ZWVuTGluZXMoYWFiYk1pblgsIGFhYmJNYXhYLCBzdGFydEFwcHJveGltYXRpb24ub2Zmc2V0LCBzdGFydEFwcHJveGltYXRpb24uY29lZmZpY2llbnQsIGVuZEFwcHJveGltYXRpb24ub2Zmc2V0LCBlbmRBcHByb3hpbWF0aW9uLmNvZWZmaWNpZW50KTsKCWNvbnN0IGZsb2F0CQkJCWVycm9yQXJlYVJhdGlvCQk9IChhYWJiQXJlYSA8IGVwc2lsb24pID8gKDEuMGYpIDogKGFyZWFCZXR3ZWVuTGluZXMgLyBhYWJiQXJlYSk7CgoJcmV0dXJuIGRlOjpjbGFtcCgxLjBmIC0gZXJyb3JBcmVhUmF0aW8sIDAuMGYsIDEuMGYpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgRHVyYXRpb25UeXBlPgpzdGF0aWMgZmxvYXQgY2FsY3VsYXRlU2FtcGxlRml0TGluZWFyaXR5IChjb25zdCBzdGQ6OnZlY3RvcjxVcGxvYWRTYW1wbGVSZXN1bHQ8RHVyYXRpb25UeXBlPiA+JiBzYW1wbGVzKQp7CglyZXR1cm4gY2FsY3VsYXRlU2FtcGxlRml0TGluZWFyaXR5KHNhbXBsZXMsICZVcGxvYWRTYW1wbGVSZXN1bHQ8RHVyYXRpb25UeXBlPjo6d3JpdHRlblNpemUpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgRHVyYXRpb25UeXBlPgpzdGF0aWMgZmxvYXQgY2FsY3VsYXRlU2FtcGxlRml0TGluZWFyaXR5IChjb25zdCBzdGQ6OnZlY3RvcjxSZW5kZXJTYW1wbGVSZXN1bHQ8RHVyYXRpb25UeXBlPiA+JiBzYW1wbGVzKQp7CglyZXR1cm4gY2FsY3VsYXRlU2FtcGxlRml0TGluZWFyaXR5KHNhbXBsZXMsICZSZW5kZXJTYW1wbGVSZXN1bHQ8RHVyYXRpb25UeXBlPjo6cmVuZGVyRGF0YVNpemUpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4Kc3RhdGljIGZsb2F0IGNhbGN1bGF0ZVNhbXBsZVRlbXBvcmFsU3RhYmlsaXR5IChjb25zdCBzdGQ6OnZlY3RvcjxUPiYgc2FtcGxlcywgaW50IFQ6OipwcmVkaWN0b3IpCnsKCS8vIFNhbXBsZXMgYXJlIHNhbXBsZWQgaW4gdGhlIGZvbGxvd2luZyBvcmRlcjogMSkgZXZlbiBzYW1wbGVzIChpbiByYW5kb20gb3JkZXIpIDIpIG9kZCBzYW1wbGVzIChpbiByYW5kb20gb3JkZXIpCgkvLyBDb21wYXJlIHRoZSBmaXR0ZWQgbGluZSBvZiBldmVuIHNhbXBsZXMgdG8gdGhlIGZpdHRlZCBsaW5lIG9mIHRoZSBvZGQgc2FtcGxlcy4gQ2FsY3VsYXRlIGEgQUFCQiB0aGF0IGZ1bGx5CgkvLyBjb250YWlucyBldmVyeSBzYW1wbGUncyB4IGNvbXBvbmVudCBhbmQgYm90aCBmaXQgbGluZXMgaW4gdGhpcyByYW5nZS4gQ2FsY3VsYXRlIHRoZSByYXRpbyBvZiB0aGUgYXJlYSBiZXR3ZWVuCgkvLyB0aGUgbGluZXMgYW5kIHRoZSBBQUJCLgoKCWNvbnN0IGZsb2F0CQkJCWVwc2lsb24JCQkJPSAxLmUtNmY7Cgljb25zdCBMaW5lUGFyYW1ldGVyc1dpdGhDb25maWRlbmNlCWV2ZW5BcHByb3hpbWF0aW9uCT0gZml0TGluZVRvU2FtcGxlcyhzYW1wbGVzLCAwLCAoaW50KXNhbXBsZXMuc2l6ZSgpLCAyLCAmVDo6U2FtcGxlVHlwZTo6Zml0UmVzcG9uc2VEdXJhdGlvbik7Cgljb25zdCBMaW5lUGFyYW1ldGVyc1dpdGhDb25maWRlbmNlCW9kZEFwcHJveGltYXRpb24JPSBmaXRMaW5lVG9TYW1wbGVzKHNhbXBsZXMsIDEsIChpbnQpc2FtcGxlcy5zaXplKCksIDIsICZUOjpTYW1wbGVUeXBlOjpmaXRSZXNwb25zZUR1cmF0aW9uKTsKCgljb25zdCBmbG9hdAkJCQlhYWJiTWluWAkJCT0gKGZsb2F0KShzYW1wbGVzLmZyb250KCkuKnByZWRpY3Rvcik7Cgljb25zdCBmbG9hdAkJCQlhYWJiTWluWQkJCT0gZGU6Om1pbihldmVuQXBwcm94aW1hdGlvbi5vZmZzZXQgKyBldmVuQXBwcm94aW1hdGlvbi5jb2VmZmljaWVudCphYWJiTWluWCwgb2RkQXBwcm94aW1hdGlvbi5vZmZzZXQgKyBvZGRBcHByb3hpbWF0aW9uLmNvZWZmaWNpZW50KmFhYmJNaW5YKTsKCWNvbnN0IGZsb2F0CQkJCWFhYmJNYXhYCQkJPSAoZmxvYXQpKHNhbXBsZXMuYmFjaygpLipwcmVkaWN0b3IpOwoJY29uc3QgZmxvYXQJCQkJYWFiYk1heFkJCQk9IGRlOjptYXgoZXZlbkFwcHJveGltYXRpb24ub2Zmc2V0ICsgZXZlbkFwcHJveGltYXRpb24uY29lZmZpY2llbnQqYWFiYk1heFgsIG9kZEFwcHJveGltYXRpb24ub2Zmc2V0ICsgb2RkQXBwcm94aW1hdGlvbi5jb2VmZmljaWVudCphYWJiTWF4WCk7CgoJY29uc3QgZmxvYXQJCQkJYWFiYkFyZWEJCQk9IChhYWJiTWF4WCAtIGFhYmJNaW5YKSAqIChhYWJiTWF4WSAtIGFhYmJNaW5ZKTsKCWNvbnN0IGZsb2F0CQkJCWFyZWFCZXR3ZWVuTGluZXMJPSBnZXRBcmVhQmV0d2VlbkxpbmVzKGFhYmJNaW5YLCBhYWJiTWF4WCwgZXZlbkFwcHJveGltYXRpb24ub2Zmc2V0LCBldmVuQXBwcm94aW1hdGlvbi5jb2VmZmljaWVudCwgb2RkQXBwcm94aW1hdGlvbi5vZmZzZXQsIG9kZEFwcHJveGltYXRpb24uY29lZmZpY2llbnQpOwoJY29uc3QgZmxvYXQJCQkJZXJyb3JBcmVhUmF0aW8JCT0gKGFhYmJBcmVhIDwgZXBzaWxvbikgPyAoMS4wZikgOiAoYXJlYUJldHdlZW5MaW5lcyAvIGFhYmJBcmVhKTsKCglyZXR1cm4gZGU6OmNsYW1wKDEuMGYgLSBlcnJvckFyZWFSYXRpbywgMC4wZiwgMS4wZik7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBEdXJhdGlvblR5cGU+CnN0YXRpYyBmbG9hdCBjYWxjdWxhdGVTYW1wbGVUZW1wb3JhbFN0YWJpbGl0eSAoY29uc3Qgc3RkOjp2ZWN0b3I8VXBsb2FkU2FtcGxlUmVzdWx0PER1cmF0aW9uVHlwZT4gPiYgc2FtcGxlcykKewoJcmV0dXJuIGNhbGN1bGF0ZVNhbXBsZVRlbXBvcmFsU3RhYmlsaXR5KHNhbXBsZXMsICZVcGxvYWRTYW1wbGVSZXN1bHQ8RHVyYXRpb25UeXBlPjo6d3JpdHRlblNpemUpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgRHVyYXRpb25UeXBlPgpzdGF0aWMgZmxvYXQgY2FsY3VsYXRlU2FtcGxlVGVtcG9yYWxTdGFiaWxpdHkgKGNvbnN0IHN0ZDo6dmVjdG9yPFJlbmRlclNhbXBsZVJlc3VsdDxEdXJhdGlvblR5cGU+ID4mIHNhbXBsZXMpCnsKCXJldHVybiBjYWxjdWxhdGVTYW1wbGVUZW1wb3JhbFN0YWJpbGl0eShzYW1wbGVzLCAmUmVuZGVyU2FtcGxlUmVzdWx0PER1cmF0aW9uVHlwZT46OnJlbmRlckRhdGFTaXplKTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIER1cmF0aW9uVHlwZT4Kc3RhdGljIHZvaWQgYnVja2V0aXplU2FtcGxlc1VuaWZvcm1seSAoY29uc3Qgc3RkOjp2ZWN0b3I8VXBsb2FkU2FtcGxlUmVzdWx0PER1cmF0aW9uVHlwZT4gPiYgc2FtcGxlcywgc3RkOjp2ZWN0b3I8VXBsb2FkU2FtcGxlUmVzdWx0PER1cmF0aW9uVHlwZT4gPiogYnVja2V0cywgaW50IG51bUJ1Y2tldHMsIGludCYgbWluQnVmZmVyU2l6ZSwgaW50JiBtYXhCdWZmZXJTaXplKQp7CgltaW5CdWZmZXJTaXplID0gMDsKCW1heEJ1ZmZlclNpemUgPSAwOwoKCWZvciAoaW50IHNhbXBsZU5keCA9IDA7IHNhbXBsZU5keCA8IChpbnQpc2FtcGxlcy5zaXplKCk7ICsrc2FtcGxlTmR4KQoJewoJCURFX0FTU0VSVChzYW1wbGVzW3NhbXBsZU5keF0uYWxsb2NhdGVkU2l6ZSAhPSAwKTsKCgkJaWYgKCFtaW5CdWZmZXJTaXplIHx8IHNhbXBsZXNbc2FtcGxlTmR4XS5hbGxvY2F0ZWRTaXplIDwgbWluQnVmZmVyU2l6ZSkKCQkJbWluQnVmZmVyU2l6ZSA9IHNhbXBsZXNbc2FtcGxlTmR4XS5hbGxvY2F0ZWRTaXplOwoJCWlmICghbWF4QnVmZmVyU2l6ZSB8fCBzYW1wbGVzW3NhbXBsZU5keF0uYWxsb2NhdGVkU2l6ZSA+IG1heEJ1ZmZlclNpemUpCgkJCW1heEJ1ZmZlclNpemUgPSBzYW1wbGVzW3NhbXBsZU5keF0uYWxsb2NhdGVkU2l6ZTsKCX0KCglmb3IgKGludCBzYW1wbGVOZHggPSAwOyBzYW1wbGVOZHggPCAoaW50KXNhbXBsZXMuc2l6ZSgpOyArK3NhbXBsZU5keCkKCXsKCQljb25zdCBmbG9hdCBidWNrZXROZHhGbG9hdAk9IChmbG9hdCkoc2FtcGxlc1tzYW1wbGVOZHhdLmFsbG9jYXRlZFNpemUgLSBtaW5CdWZmZXJTaXplKSAvIChmbG9hdCkobWF4QnVmZmVyU2l6ZSAtIG1pbkJ1ZmZlclNpemUpICogKGZsb2F0KW51bUJ1Y2tldHM7CgkJY29uc3QgaW50IGJ1Y2tldE5keAkJCT0gZGU6OmNsYW1wKChpbnQpZGVGbG9hdEZsb29yKGJ1Y2tldE5keEZsb2F0KSwgMCwgbnVtQnVja2V0cy0xKTsKCgkJYnVja2V0c1tidWNrZXROZHhdLnB1c2hfYmFjayhzYW1wbGVzW3NhbXBsZU5keF0pOwoJfQp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4Kc3RhdGljIHR5cGVuYW1lIEVuYWJsZUlmPHZvaWQsIFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OkhBU19NQVBfU1RBVFM+OjpUeXBlIGxvZ01hcFJhbmdlU3RhdHMgKHRjdTo6VGVzdExvZyYgbG9nLCBjb25zdCB0eXBlbmFtZSBTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpTdGF0c1R5cGUmIHN0YXRzKQp7Cglsb2cJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiTWFwUmFuZ2VNaW4iLCAiTWFwUmFuZ2U6IE1pbiB0aW1lIiwgInVzIiwgUVBfS0VZX1RBR19USU1FLCBzdGF0cy5tYXAubWluVGltZSkKCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJNYXBSYW5nZU1heCIsICJNYXBSYW5nZTogTWF4IHRpbWUiLCAidXMiLCBRUF9LRVlfVEFHX1RJTUUsIHN0YXRzLm1hcC5tYXhUaW1lKQoJCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIk1hcFJhbmdlTWluOTAiLCAiTWFwUmFuZ2U6IDkwJS1NaW4gdGltZSIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgc3RhdHMubWFwLm1pbjJEZWNpbGVUaW1lKQoJCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIk1hcFJhbmdlTWF4OTAiLCAiTWFwUmFuZ2U6IDkwJS1NYXggdGltZSIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgc3RhdHMubWFwLm1heDlEZWNpbGVUaW1lKQoJCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIk1hcFJhbmdlTWVkaWFuIiwgIk1hcFJhbmdlOiBNZWRpYW4gdGltZSIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgc3RhdHMubWFwLm1lZGlhblRpbWUpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4Kc3RhdGljIHR5cGVuYW1lIEVuYWJsZUlmPHZvaWQsIFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OkhBU19VTk1BUF9TVEFUUz46OlR5cGUgbG9nVW5tYXBTdGF0cyAodGN1OjpUZXN0TG9nJiBsb2csIGNvbnN0IHR5cGVuYW1lIFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OlN0YXRzVHlwZSYgc3RhdHMpCnsKCWxvZwk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJVbm1hcE1pbiIsICJVbm1hcDogTWluIHRpbWUiLCAidXMiLCBRUF9LRVlfVEFHX1RJTUUsIHN0YXRzLnVubWFwLm1pblRpbWUpCgkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiVW5tYXBNYXgiLCAiVW5tYXA6IE1heCB0aW1lIiwgInVzIiwgUVBfS0VZX1RBR19USU1FLCBzdGF0cy51bm1hcC5tYXhUaW1lKQoJCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIlVubWFwTWluOTAiLCAiVW5tYXA6IDkwJS1NaW4gdGltZSIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgc3RhdHMudW5tYXAubWluMkRlY2lsZVRpbWUpCgkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiVW5tYXBNYXg5MCIsICJVbm1hcDogOTAlLU1heCB0aW1lIiwgInVzIiwgUVBfS0VZX1RBR19USU1FLCBzdGF0cy51bm1hcC5tYXg5RGVjaWxlVGltZSkKCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJVbm1hcE1lZGlhbiIsICJVbm1hcDogTWVkaWFuIHRpbWUiLCAidXMiLCBRUF9LRVlfVEFHX1RJTUUsIHN0YXRzLnVubWFwLm1lZGlhblRpbWUpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4Kc3RhdGljIHR5cGVuYW1lIEVuYWJsZUlmPHZvaWQsIFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OkhBU19XUklURV9TVEFUUz46OlR5cGUgbG9nV3JpdGVTdGF0cyAodGN1OjpUZXN0TG9nJiBsb2csIGNvbnN0IHR5cGVuYW1lIFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OlN0YXRzVHlwZSYgc3RhdHMpCnsKCWxvZwk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJXcml0ZU1pbiIsICJXcml0ZTogTWluIHRpbWUiLCAidXMiLCBRUF9LRVlfVEFHX1RJTUUsIHN0YXRzLndyaXRlLm1pblRpbWUpCgkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiV3JpdGVNYXgiLCAiV3JpdGU6IE1heCB0aW1lIiwgInVzIiwgUVBfS0VZX1RBR19USU1FLCBzdGF0cy53cml0ZS5tYXhUaW1lKQoJCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIldyaXRlTWluOTAiLCAiV3JpdGU6IDkwJS1NaW4gdGltZSIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgc3RhdHMud3JpdGUubWluMkRlY2lsZVRpbWUpCgkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiV3JpdGVNYXg5MCIsICJXcml0ZTogOTAlLU1heCB0aW1lIiwgInVzIiwgUVBfS0VZX1RBR19USU1FLCBzdGF0cy53cml0ZS5tYXg5RGVjaWxlVGltZSkKCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJXcml0ZU1lZGlhbiIsICJXcml0ZTogTWVkaWFuIHRpbWUiLCAidXMiLCBRUF9LRVlfVEFHX1RJTUUsIHN0YXRzLndyaXRlLm1lZGlhblRpbWUpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4Kc3RhdGljIHR5cGVuYW1lIEVuYWJsZUlmPHZvaWQsIFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OkhBU19GTFVTSF9TVEFUUz46OlR5cGUgbG9nRmx1c2hTdGF0cyAodGN1OjpUZXN0TG9nJiBsb2csIGNvbnN0IHR5cGVuYW1lIFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OlN0YXRzVHlwZSYgc3RhdHMpCnsKCWxvZwk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJGbHVzaE1pbiIsICJGbHVzaDogTWluIHRpbWUiLCAidXMiLCBRUF9LRVlfVEFHX1RJTUUsIHN0YXRzLmZsdXNoLm1pblRpbWUpCgkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiRmx1c2hNYXgiLCAiRmx1c2g6IE1heCB0aW1lIiwgInVzIiwgUVBfS0VZX1RBR19USU1FLCBzdGF0cy5mbHVzaC5tYXhUaW1lKQoJCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIkZsdXNoTWluOTAiLCAiRmx1c2g6IDkwJS1NaW4gdGltZSIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgc3RhdHMuZmx1c2gubWluMkRlY2lsZVRpbWUpCgkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiRmx1c2hNYXg5MCIsICJGbHVzaDogOTAlLU1heCB0aW1lIiwgInVzIiwgUVBfS0VZX1RBR19USU1FLCBzdGF0cy5mbHVzaC5tYXg5RGVjaWxlVGltZSkKCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJGbHVzaE1lZGlhbiIsICJGbHVzaDogTWVkaWFuIHRpbWUiLCAidXMiLCBRUF9LRVlfVEFHX1RJTUUsIHN0YXRzLmZsdXNoLm1lZGlhblRpbWUpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4Kc3RhdGljIHR5cGVuYW1lIEVuYWJsZUlmPHZvaWQsIFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OkhBU19BTExPQ19TVEFUUz46OlR5cGUgbG9nQWxsb2NTdGF0cyAodGN1OjpUZXN0TG9nJiBsb2csIGNvbnN0IHR5cGVuYW1lIFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OlN0YXRzVHlwZSYgc3RhdHMpCnsKCWxvZwk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJBbGxvY01pbiIsICJBbGxvYzogTWluIHRpbWUiLCAidXMiLCBRUF9LRVlfVEFHX1RJTUUsIHN0YXRzLmFsbG9jLm1pblRpbWUpCgkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiQWxsb2NNYXgiLCAiQWxsb2M6IE1heCB0aW1lIiwgInVzIiwgUVBfS0VZX1RBR19USU1FLCBzdGF0cy5hbGxvYy5tYXhUaW1lKQoJCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIkFsbG9jTWluOTAiLCAiQWxsb2M6IDkwJS1NaW4gdGltZSIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgc3RhdHMuYWxsb2MubWluMkRlY2lsZVRpbWUpCgkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiQWxsb2NNYXg5MCIsICJBbGxvYzogOTAlLU1heCB0aW1lIiwgInVzIiwgUVBfS0VZX1RBR19USU1FLCBzdGF0cy5hbGxvYy5tYXg5RGVjaWxlVGltZSkKCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJBbGxvY01lZGlhbiIsICJBbGxvYzogTWVkaWFuIHRpbWUiLCAidXMiLCBRUF9LRVlfVEFHX1RJTUUsIHN0YXRzLmFsbG9jLm1lZGlhblRpbWUpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4Kc3RhdGljIHR5cGVuYW1lIEVuYWJsZUlmPHZvaWQsIE5vdDxTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpIQVNfTUFQX1NUQVRTPjo6VmFsdWU+OjpUeXBlIGxvZ01hcFJhbmdlU3RhdHMgKHRjdTo6VGVzdExvZyYgbG9nLCBjb25zdCB0eXBlbmFtZSBTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpTdGF0c1R5cGUmIHN0YXRzKQp7CglERV9VTlJFRihsb2cpOwoJREVfVU5SRUYoc3RhdHMpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4Kc3RhdGljIHR5cGVuYW1lIEVuYWJsZUlmPHZvaWQsIE5vdDxTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpIQVNfVU5NQVBfU1RBVFM+OjpWYWx1ZT46OlR5cGUgbG9nVW5tYXBTdGF0cyAodGN1OjpUZXN0TG9nJiBsb2csIGNvbnN0IHR5cGVuYW1lIFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OlN0YXRzVHlwZSYgc3RhdHMpCnsKCURFX1VOUkVGKGxvZyk7CglERV9VTlJFRihzdGF0cyk7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgpzdGF0aWMgdHlwZW5hbWUgRW5hYmxlSWY8dm9pZCwgTm90PFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OkhBU19XUklURV9TVEFUUz46OlZhbHVlPjo6VHlwZSBsb2dXcml0ZVN0YXRzICh0Y3U6OlRlc3RMb2cmIGxvZywgY29uc3QgdHlwZW5hbWUgU2FtcGxlVHlwZVRyYWl0czxTYW1wbGVUeXBlPjo6U3RhdHNUeXBlJiBzdGF0cykKewoJREVfVU5SRUYobG9nKTsKCURFX1VOUkVGKHN0YXRzKTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFNhbXBsZVR5cGU+CnN0YXRpYyB0eXBlbmFtZSBFbmFibGVJZjx2b2lkLCBOb3Q8U2FtcGxlVHlwZVRyYWl0czxTYW1wbGVUeXBlPjo6SEFTX0ZMVVNIX1NUQVRTPjo6VmFsdWU+OjpUeXBlIGxvZ0ZsdXNoU3RhdHMgKHRjdTo6VGVzdExvZyYgbG9nLCBjb25zdCB0eXBlbmFtZSBTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpTdGF0c1R5cGUmIHN0YXRzKQp7CglERV9VTlJFRihsb2cpOwoJREVfVU5SRUYoc3RhdHMpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4Kc3RhdGljIHR5cGVuYW1lIEVuYWJsZUlmPHZvaWQsIE5vdDxTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpIQVNfQUxMT0NfU1RBVFM+OjpWYWx1ZT46OlR5cGUgbG9nQWxsb2NTdGF0cyAodGN1OjpUZXN0TG9nJiBsb2csIGNvbnN0IHR5cGVuYW1lIFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OlN0YXRzVHlwZSYgc3RhdHMpCnsKCURFX1VOUkVGKGxvZyk7CglERV9VTlJFRihzdGF0cyk7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgpzdGF0aWMgdHlwZW5hbWUgRW5hYmxlSWY8dm9pZCwgU2FtcGxlVHlwZVRyYWl0czxTYW1wbGVUeXBlPjo6SEFTX01BUF9TVEFUUz46OlR5cGUgbG9nTWFwQ29udHJpYnV0aW9uICh0Y3U6OlRlc3RMb2cmIGxvZywgY29uc3Qgc3RkOjp2ZWN0b3I8VXBsb2FkU2FtcGxlUmVzdWx0PFNhbXBsZVR5cGU+ID4mIHNhbXBsZXMsIGNvbnN0IHR5cGVuYW1lIFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OlN0YXRzVHlwZSYgc3RhdHMpCnsKCWNvbnN0IExpbmVQYXJhbWV0ZXJzV2l0aENvbmZpZGVuY2UgY29udHJpYnV0aW9uRml0dGluZyA9IGZpdExpbmVUb1NhbXBsZXMoc2FtcGxlcywgJlNhbXBsZVR5cGU6Om1hcER1cmF0aW9uKTsKCWxvZwk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJNYXBDb25zdGFudENvc3QiLCAiTWFwOiBBcHByb3hpbWF0ZWQgY29udGFudCBjb3N0IiwgInVzIiwgUVBfS0VZX1RBR19USU1FLCBjb250cmlidXRpb25GaXR0aW5nLm9mZnNldCkKCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJNYXBMaW5lYXJDb3N0IiwgIk1hcDogQXBwcm94aW1hdGVkIGxpbmVhciBjb3N0IiwgInVzIC8gTUIiLCBRUF9LRVlfVEFHX1RJTUUsIGNvbnRyaWJ1dGlvbkZpdHRpbmcuY29lZmZpY2llbnQgKiAxMDI0LjBmICogMTAyNC4wZikKCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJNYXBNZWRpYW5Db3N0IiwgIk1hcDogTWVkaWFuIGNvc3QiLCAidXMiLCBRUF9LRVlfVEFHX1RJTUUsIHN0YXRzLm1hcC5tZWRpYW5UaW1lKTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFNhbXBsZVR5cGU+CnN0YXRpYyB0eXBlbmFtZSBFbmFibGVJZjx2b2lkLCBTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpIQVNfVU5NQVBfU1RBVFM+OjpUeXBlIGxvZ1VubWFwQ29udHJpYnV0aW9uICh0Y3U6OlRlc3RMb2cmIGxvZywgY29uc3Qgc3RkOjp2ZWN0b3I8VXBsb2FkU2FtcGxlUmVzdWx0PFNhbXBsZVR5cGU+ID4mIHNhbXBsZXMsIGNvbnN0IHR5cGVuYW1lIFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OlN0YXRzVHlwZSYgc3RhdHMpCnsKCWNvbnN0IExpbmVQYXJhbWV0ZXJzV2l0aENvbmZpZGVuY2UgY29udHJpYnV0aW9uRml0dGluZyA9IGZpdExpbmVUb1NhbXBsZXMoc2FtcGxlcywgJlNhbXBsZVR5cGU6OnVubWFwRHVyYXRpb24pOwoJbG9nCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIlVubWFwQ29uc3RhbnRDb3N0IiwgIlVubWFwOiBBcHByb3hpbWF0ZWQgY29udGFudCBjb3N0IiwgInVzIiwgUVBfS0VZX1RBR19USU1FLCBjb250cmlidXRpb25GaXR0aW5nLm9mZnNldCkKCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJVbm1hcExpbmVhckNvc3QiLCAiVW5tYXA6IEFwcHJveGltYXRlZCBsaW5lYXIgY29zdCIsICJ1cyAvIE1CIiwgUVBfS0VZX1RBR19USU1FLCBjb250cmlidXRpb25GaXR0aW5nLmNvZWZmaWNpZW50ICogMTAyNC4wZiAqIDEwMjQuMGYpCgkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiVW5tYXBNZWRpYW5Db3N0IiwgIlVubWFwOiBNZWRpYW4gY29zdCIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgc3RhdHMudW5tYXAubWVkaWFuVGltZSk7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgpzdGF0aWMgdHlwZW5hbWUgRW5hYmxlSWY8dm9pZCwgU2FtcGxlVHlwZVRyYWl0czxTYW1wbGVUeXBlPjo6SEFTX1dSSVRFX1NUQVRTPjo6VHlwZSBsb2dXcml0ZUNvbnRyaWJ1dGlvbiAodGN1OjpUZXN0TG9nJiBsb2csIGNvbnN0IHN0ZDo6dmVjdG9yPFVwbG9hZFNhbXBsZVJlc3VsdDxTYW1wbGVUeXBlPiA+JiBzYW1wbGVzLCBjb25zdCB0eXBlbmFtZSBTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpTdGF0c1R5cGUmIHN0YXRzKQp7Cgljb25zdCBMaW5lUGFyYW1ldGVyc1dpdGhDb25maWRlbmNlIGNvbnRyaWJ1dGlvbkZpdHRpbmcgPSBmaXRMaW5lVG9TYW1wbGVzKHNhbXBsZXMsICZTYW1wbGVUeXBlOjp3cml0ZUR1cmF0aW9uKTsKCWxvZwk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJXcml0ZUNvbnN0YW50Q29zdCIsICJXcml0ZTogQXBwcm94aW1hdGVkIGNvbnRhbnQgY29zdCIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgY29udHJpYnV0aW9uRml0dGluZy5vZmZzZXQpCgkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiV3JpdGVMaW5lYXJDb3N0IiwgIldyaXRlOiBBcHByb3hpbWF0ZWQgbGluZWFyIGNvc3QiLCAidXMgLyBNQiIsIFFQX0tFWV9UQUdfVElNRSwgY29udHJpYnV0aW9uRml0dGluZy5jb2VmZmljaWVudCAqIDEwMjQuMGYgKiAxMDI0LjBmKQoJCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIldyaXRlTWVkaWFuQ29zdCIsICJXcml0ZTogTWVkaWFuIGNvc3QiLCAidXMiLCBRUF9LRVlfVEFHX1RJTUUsIHN0YXRzLndyaXRlLm1lZGlhblRpbWUpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4Kc3RhdGljIHR5cGVuYW1lIEVuYWJsZUlmPHZvaWQsIFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OkhBU19GTFVTSF9TVEFUUz46OlR5cGUgbG9nRmx1c2hDb250cmlidXRpb24gKHRjdTo6VGVzdExvZyYgbG9nLCBjb25zdCBzdGQ6OnZlY3RvcjxVcGxvYWRTYW1wbGVSZXN1bHQ8U2FtcGxlVHlwZT4gPiYgc2FtcGxlcywgY29uc3QgdHlwZW5hbWUgU2FtcGxlVHlwZVRyYWl0czxTYW1wbGVUeXBlPjo6U3RhdHNUeXBlJiBzdGF0cykKewoJY29uc3QgTGluZVBhcmFtZXRlcnNXaXRoQ29uZmlkZW5jZSBjb250cmlidXRpb25GaXR0aW5nID0gZml0TGluZVRvU2FtcGxlcyhzYW1wbGVzLCAmU2FtcGxlVHlwZTo6Zmx1c2hEdXJhdGlvbik7Cglsb2cJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiRmx1c2hDb25zdGFudENvc3QiLCAiRmx1c2g6IEFwcHJveGltYXRlZCBjb250YW50IGNvc3QiLCAidXMiLCBRUF9LRVlfVEFHX1RJTUUsIGNvbnRyaWJ1dGlvbkZpdHRpbmcub2Zmc2V0KQoJCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIkZsdXNoTGluZWFyQ29zdCIsICJGbHVzaDogQXBwcm94aW1hdGVkIGxpbmVhciBjb3N0IiwgInVzIC8gTUIiLCBRUF9LRVlfVEFHX1RJTUUsIGNvbnRyaWJ1dGlvbkZpdHRpbmcuY29lZmZpY2llbnQgKiAxMDI0LjBmICogMTAyNC4wZikKCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJGbHVzaE1lZGlhbkNvc3QiLCAiRmx1c2g6IE1lZGlhbiBjb3N0IiwgInVzIiwgUVBfS0VZX1RBR19USU1FLCBzdGF0cy5mbHVzaC5tZWRpYW5UaW1lKTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFNhbXBsZVR5cGU+CnN0YXRpYyB0eXBlbmFtZSBFbmFibGVJZjx2b2lkLCBTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpIQVNfQUxMT0NfU1RBVFM+OjpUeXBlIGxvZ0FsbG9jQ29udHJpYnV0aW9uICh0Y3U6OlRlc3RMb2cmIGxvZywgY29uc3Qgc3RkOjp2ZWN0b3I8VXBsb2FkU2FtcGxlUmVzdWx0PFNhbXBsZVR5cGU+ID4mIHNhbXBsZXMsIGNvbnN0IHR5cGVuYW1lIFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OlN0YXRzVHlwZSYgc3RhdHMpCnsKCWNvbnN0IExpbmVQYXJhbWV0ZXJzV2l0aENvbmZpZGVuY2UgY29udHJpYnV0aW9uRml0dGluZyA9IGZpdExpbmVUb1NhbXBsZXMoc2FtcGxlcywgJlNhbXBsZVR5cGU6OmFsbG9jRHVyYXRpb24pOwoJbG9nCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIkFsbG9jQ29uc3RhbnRDb3N0IiwgIkFsbG9jOiBBcHByb3hpbWF0ZWQgY29udGFudCBjb3N0IiwgInVzIiwgUVBfS0VZX1RBR19USU1FLCBjb250cmlidXRpb25GaXR0aW5nLm9mZnNldCkKCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJBbGxvY0xpbmVhckNvc3QiLCAiQWxsb2M6IEFwcHJveGltYXRlZCBsaW5lYXIgY29zdCIsICJ1cyAvIE1CIiwgUVBfS0VZX1RBR19USU1FLCBjb250cmlidXRpb25GaXR0aW5nLmNvZWZmaWNpZW50ICogMTAyNC4wZiAqIDEwMjQuMGYpCgkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiQWxsb2NNZWRpYW5Db3N0IiwgIkFsbG9jOiBNZWRpYW4gY29zdCIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgc3RhdHMuYWxsb2MubWVkaWFuVGltZSk7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgpzdGF0aWMgdHlwZW5hbWUgRW5hYmxlSWY8dm9pZCwgU2FtcGxlVHlwZVRyYWl0czxTYW1wbGVUeXBlPjo6SEFTX1JFTkRFUl9TVEFUUz46OlR5cGUgbG9nUmVuZGVyQ29udHJpYnV0aW9uICh0Y3U6OlRlc3RMb2cmIGxvZywgY29uc3Qgc3RkOjp2ZWN0b3I8UmVuZGVyU2FtcGxlUmVzdWx0PFNhbXBsZVR5cGU+ID4mIHNhbXBsZXMsIGNvbnN0IHR5cGVuYW1lIFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OlN0YXRzVHlwZSYgc3RhdHMpCnsKCWNvbnN0IExpbmVQYXJhbWV0ZXJzV2l0aENvbmZpZGVuY2UgY29udHJpYnV0aW9uRml0dGluZyA9IGZpdExpbmVUb1NhbXBsZXMoc2FtcGxlcywgJlNhbXBsZVR5cGU6OnJlbmRlckR1cmF0aW9uKTsKCWxvZwk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJEcmF3Q2FsbENvbnN0YW50Q29zdCIsICJEcmF3Q2FsbDogQXBwcm94aW1hdGVkIGNvbnRhbnQgY29zdCIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgY29udHJpYnV0aW9uRml0dGluZy5vZmZzZXQpCgkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiRHJhd0NhbGxMaW5lYXJDb3N0IiwgIkRyYXdDYWxsOiBBcHByb3hpbWF0ZWQgbGluZWFyIGNvc3QiLCAidXMgLyBNQiIsIFFQX0tFWV9UQUdfVElNRSwgY29udHJpYnV0aW9uRml0dGluZy5jb2VmZmljaWVudCAqIDEwMjQuMGYgKiAxMDI0LjBmKQoJCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIkRyYXdDYWxsTWVkaWFuQ29zdCIsICJEcmF3Q2FsbDogTWVkaWFuIGNvc3QiLCAidXMiLCBRUF9LRVlfVEFHX1RJTUUsIHN0YXRzLnJlbmRlci5tZWRpYW5UaW1lKTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFNhbXBsZVR5cGU+CnN0YXRpYyB0eXBlbmFtZSBFbmFibGVJZjx2b2lkLCBTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpIQVNfUkVBRF9TVEFUUz46OlR5cGUgbG9nUmVhZENvbnRyaWJ1dGlvbiAodGN1OjpUZXN0TG9nJiBsb2csIGNvbnN0IHN0ZDo6dmVjdG9yPFJlbmRlclNhbXBsZVJlc3VsdDxTYW1wbGVUeXBlPiA+JiBzYW1wbGVzLCBjb25zdCB0eXBlbmFtZSBTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpTdGF0c1R5cGUmIHN0YXRzKQp7Cgljb25zdCBMaW5lUGFyYW1ldGVyc1dpdGhDb25maWRlbmNlIGNvbnRyaWJ1dGlvbkZpdHRpbmcgPSBmaXRMaW5lVG9TYW1wbGVzKHNhbXBsZXMsICZTYW1wbGVUeXBlOjpyZWFkRHVyYXRpb24pOwoJbG9nCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIlJlYWRDb25zdGFudENvc3QiLCAiUmVhZDogQXBwcm94aW1hdGVkIGNvbnRhbnQgY29zdCIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgY29udHJpYnV0aW9uRml0dGluZy5vZmZzZXQpCgkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiUmVhZExpbmVhckNvc3QiLCAiUmVhZDogQXBwcm94aW1hdGVkIGxpbmVhciBjb3N0IiwgInVzIC8gTUIiLCBRUF9LRVlfVEFHX1RJTUUsIGNvbnRyaWJ1dGlvbkZpdHRpbmcuY29lZmZpY2llbnQgKiAxMDI0LjBmICogMTAyNC4wZikKCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJSZWFkTWVkaWFuQ29zdCIsICJSZWFkOiBNZWRpYW4gY29zdCIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgc3RhdHMucmVhZC5tZWRpYW5UaW1lKTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFNhbXBsZVR5cGU+CnN0YXRpYyB0eXBlbmFtZSBFbmFibGVJZjx2b2lkLCBTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpIQVNfVVBMT0FEX1NUQVRTPjo6VHlwZSBsb2dVcGxvYWRDb250cmlidXRpb24gKHRjdTo6VGVzdExvZyYgbG9nLCBjb25zdCBzdGQ6OnZlY3RvcjxSZW5kZXJTYW1wbGVSZXN1bHQ8U2FtcGxlVHlwZT4gPiYgc2FtcGxlcywgY29uc3QgdHlwZW5hbWUgU2FtcGxlVHlwZVRyYWl0czxTYW1wbGVUeXBlPjo6U3RhdHNUeXBlJiBzdGF0cykKewoJY29uc3QgTGluZVBhcmFtZXRlcnNXaXRoQ29uZmlkZW5jZSBjb250cmlidXRpb25GaXR0aW5nID0gZml0TGluZVRvU2FtcGxlcyhzYW1wbGVzLCAmU2FtcGxlVHlwZTo6dXBsb2FkRHVyYXRpb24pOwoJbG9nCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIlVwbG9hZENvbnN0YW50Q29zdCIsICJVcGxvYWQ6IEFwcHJveGltYXRlZCBjb250YW50IGNvc3QiLCAidXMiLCBRUF9LRVlfVEFHX1RJTUUsIGNvbnRyaWJ1dGlvbkZpdHRpbmcub2Zmc2V0KQoJCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIlVwbG9hZExpbmVhckNvc3QiLCAiVXBsb2FkOiBBcHByb3hpbWF0ZWQgbGluZWFyIGNvc3QiLCAidXMgLyBNQiIsIFFQX0tFWV9UQUdfVElNRSwgY29udHJpYnV0aW9uRml0dGluZy5jb2VmZmljaWVudCAqIDEwMjQuMGYgKiAxMDI0LjBmKQoJCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIlVwbG9hZE1lZGlhbkNvc3QiLCAiVXBsb2FkOiBNZWRpYW4gY29zdCIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgc3RhdHMudXBsb2FkLm1lZGlhblRpbWUpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4Kc3RhdGljIHR5cGVuYW1lIEVuYWJsZUlmPHZvaWQsIFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OkhBU19UT1RBTF9TVEFUUz46OlR5cGUgbG9nVG90YWxDb250cmlidXRpb24gKHRjdTo6VGVzdExvZyYgbG9nLCBjb25zdCBzdGQ6OnZlY3RvcjxSZW5kZXJTYW1wbGVSZXN1bHQ8U2FtcGxlVHlwZT4gPiYgc2FtcGxlcywgY29uc3QgdHlwZW5hbWUgU2FtcGxlVHlwZVRyYWl0czxTYW1wbGVUeXBlPjo6U3RhdHNUeXBlJiBzdGF0cykKewoJY29uc3QgTGluZVBhcmFtZXRlcnNXaXRoQ29uZmlkZW5jZSBjb250cmlidXRpb25GaXR0aW5nID0gZml0TGluZVRvU2FtcGxlcyhzYW1wbGVzLCAmU2FtcGxlVHlwZTo6dG90YWxEdXJhdGlvbik7Cglsb2cJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiVG90YWxDb25zdGFudENvc3QiLCAiVG90YWw6IEFwcHJveGltYXRlZCBjb250YW50IGNvc3QiLCAidXMiLCBRUF9LRVlfVEFHX1RJTUUsIGNvbnRyaWJ1dGlvbkZpdHRpbmcub2Zmc2V0KQoJCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIlRvdGFsTGluZWFyQ29zdCIsICJUb3RhbDogQXBwcm94aW1hdGVkIGxpbmVhciBjb3N0IiwgInVzIC8gTUIiLCBRUF9LRVlfVEFHX1RJTUUsIGNvbnRyaWJ1dGlvbkZpdHRpbmcuY29lZmZpY2llbnQgKiAxMDI0LjBmICogMTAyNC4wZikKCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJUb3RhbE1lZGlhbkNvc3QiLCAiVG90YWw6IE1lZGlhbiBjb3N0IiwgInVzIiwgUVBfS0VZX1RBR19USU1FLCBzdGF0cy50b3RhbC5tZWRpYW5UaW1lKTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFNhbXBsZVR5cGU+CnN0YXRpYyB0eXBlbmFtZSBFbmFibGVJZjx2b2lkLCBTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpIQVNfRklSU1RfUkVOREVSX1NUQVRTPjo6VHlwZSBsb2dGaXJzdFJlbmRlckNvbnRyaWJ1dGlvbiAodGN1OjpUZXN0TG9nJiBsb2csIGNvbnN0IHN0ZDo6dmVjdG9yPFJlbmRlclNhbXBsZVJlc3VsdDxTYW1wbGVUeXBlPiA+JiBzYW1wbGVzLCBjb25zdCB0eXBlbmFtZSBTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpTdGF0c1R5cGUmIHN0YXRzKQp7Cgljb25zdCBMaW5lUGFyYW1ldGVyc1dpdGhDb25maWRlbmNlIGNvbnRyaWJ1dGlvbkZpdHRpbmcgPSBmaXRMaW5lVG9TYW1wbGVzKHNhbXBsZXMsICZTYW1wbGVUeXBlOjpmaXJzdFJlbmRlckR1cmF0aW9uKTsKCWxvZwk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJGaXJzdERyYXdDYWxsQ29uc3RhbnRDb3N0IiwgIkZpcnN0IERyYXdDYWxsOiBBcHByb3hpbWF0ZWQgY29udGFudCBjb3N0IiwgInVzIiwgUVBfS0VZX1RBR19USU1FLCBjb250cmlidXRpb25GaXR0aW5nLm9mZnNldCkKCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJGaXJzdERyYXdDYWxsTGluZWFyQ29zdCIsICJGaXJzdCBEcmF3Q2FsbDogQXBwcm94aW1hdGVkIGxpbmVhciBjb3N0IiwgInVzIC8gTUIiLCBRUF9LRVlfVEFHX1RJTUUsIGNvbnRyaWJ1dGlvbkZpdHRpbmcuY29lZmZpY2llbnQgKiAxMDI0LjBmICogMTAyNC4wZikKCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJGaXJzdERyYXdDYWxsTWVkaWFuQ29zdCIsICJGaXJzdCBEcmF3Q2FsbDogTWVkaWFuIGNvc3QiLCAidXMiLCBRUF9LRVlfVEFHX1RJTUUsIHN0YXRzLmZpcnN0UmVuZGVyLm1lZGlhblRpbWUpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4Kc3RhdGljIHR5cGVuYW1lIEVuYWJsZUlmPHZvaWQsIFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OkhBU19TRUNPTkRfUkVOREVSX1NUQVRTPjo6VHlwZSBsb2dTZWNvbmRSZW5kZXJDb250cmlidXRpb24gKHRjdTo6VGVzdExvZyYgbG9nLCBjb25zdCBzdGQ6OnZlY3RvcjxSZW5kZXJTYW1wbGVSZXN1bHQ8U2FtcGxlVHlwZT4gPiYgc2FtcGxlcywgY29uc3QgdHlwZW5hbWUgU2FtcGxlVHlwZVRyYWl0czxTYW1wbGVUeXBlPjo6U3RhdHNUeXBlJiBzdGF0cykKewoJY29uc3QgTGluZVBhcmFtZXRlcnNXaXRoQ29uZmlkZW5jZSBjb250cmlidXRpb25GaXR0aW5nID0gZml0TGluZVRvU2FtcGxlcyhzYW1wbGVzLCAmU2FtcGxlVHlwZTo6c2Vjb25kUmVuZGVyRHVyYXRpb24pOwoJbG9nCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIlNlY29uZERyYXdDYWxsQ29uc3RhbnRDb3N0IiwgIlNlY29uZCBEcmF3Q2FsbDogQXBwcm94aW1hdGVkIGNvbnRhbnQgY29zdCIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgY29udHJpYnV0aW9uRml0dGluZy5vZmZzZXQpCgkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiU2Vjb25kRHJhd0NhbGxMaW5lYXJDb3N0IiwgIlNlY29uZCBEcmF3Q2FsbDogQXBwcm94aW1hdGVkIGxpbmVhciBjb3N0IiwgInVzIC8gTUIiLCBRUF9LRVlfVEFHX1RJTUUsIGNvbnRyaWJ1dGlvbkZpdHRpbmcuY29lZmZpY2llbnQgKiAxMDI0LjBmICogMTAyNC4wZikKCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJTZWNvbmREcmF3Q2FsbE1lZGlhbkNvc3QiLCAiU2Vjb25kIERyYXdDYWxsOiBNZWRpYW4gY29zdCIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgc3RhdHMuc2Vjb25kUmVuZGVyLm1lZGlhblRpbWUpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4Kc3RhdGljIHR5cGVuYW1lIEVuYWJsZUlmPHZvaWQsIE5vdDxTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpIQVNfTUFQX1NUQVRTPjo6VmFsdWU+OjpUeXBlIGxvZ01hcENvbnRyaWJ1dGlvbiAodGN1OjpUZXN0TG9nJiBsb2csIGNvbnN0IHN0ZDo6dmVjdG9yPFVwbG9hZFNhbXBsZVJlc3VsdDxTYW1wbGVUeXBlPiA+JiBzYW1wbGVzLCBjb25zdCB0eXBlbmFtZSBTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpTdGF0c1R5cGUmIHN0YXRzKQp7CglERV9VTlJFRihsb2cpOwoJREVfVU5SRUYoc2FtcGxlcyk7CglERV9VTlJFRihzdGF0cyk7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgpzdGF0aWMgdHlwZW5hbWUgRW5hYmxlSWY8dm9pZCwgTm90PFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OkhBU19VTk1BUF9TVEFUUz46OlZhbHVlPjo6VHlwZSBsb2dVbm1hcENvbnRyaWJ1dGlvbiAodGN1OjpUZXN0TG9nJiBsb2csIGNvbnN0IHN0ZDo6dmVjdG9yPFVwbG9hZFNhbXBsZVJlc3VsdDxTYW1wbGVUeXBlPiA+JiBzYW1wbGVzLCBjb25zdCB0eXBlbmFtZSBTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpTdGF0c1R5cGUmIHN0YXRzKQp7CglERV9VTlJFRihsb2cpOwoJREVfVU5SRUYoc2FtcGxlcyk7CglERV9VTlJFRihzdGF0cyk7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgpzdGF0aWMgdHlwZW5hbWUgRW5hYmxlSWY8dm9pZCwgTm90PFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OkhBU19XUklURV9TVEFUUz46OlZhbHVlPjo6VHlwZSBsb2dXcml0ZUNvbnRyaWJ1dGlvbiAodGN1OjpUZXN0TG9nJiBsb2csIGNvbnN0IHN0ZDo6dmVjdG9yPFVwbG9hZFNhbXBsZVJlc3VsdDxTYW1wbGVUeXBlPiA+JiBzYW1wbGVzLCBjb25zdCB0eXBlbmFtZSBTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpTdGF0c1R5cGUmIHN0YXRzKQp7CglERV9VTlJFRihsb2cpOwoJREVfVU5SRUYoc2FtcGxlcyk7CglERV9VTlJFRihzdGF0cyk7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgpzdGF0aWMgdHlwZW5hbWUgRW5hYmxlSWY8dm9pZCwgTm90PFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OkhBU19GTFVTSF9TVEFUUz46OlZhbHVlPjo6VHlwZSBsb2dGbHVzaENvbnRyaWJ1dGlvbiAodGN1OjpUZXN0TG9nJiBsb2csIGNvbnN0IHN0ZDo6dmVjdG9yPFVwbG9hZFNhbXBsZVJlc3VsdDxTYW1wbGVUeXBlPiA+JiBzYW1wbGVzLCBjb25zdCB0eXBlbmFtZSBTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpTdGF0c1R5cGUmIHN0YXRzKQp7CglERV9VTlJFRihsb2cpOwoJREVfVU5SRUYoc2FtcGxlcyk7CglERV9VTlJFRihzdGF0cyk7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgpzdGF0aWMgdHlwZW5hbWUgRW5hYmxlSWY8dm9pZCwgTm90PFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OkhBU19BTExPQ19TVEFUUz46OlZhbHVlPjo6VHlwZSBsb2dBbGxvY0NvbnRyaWJ1dGlvbiAodGN1OjpUZXN0TG9nJiBsb2csIGNvbnN0IHN0ZDo6dmVjdG9yPFVwbG9hZFNhbXBsZVJlc3VsdDxTYW1wbGVUeXBlPiA+JiBzYW1wbGVzLCBjb25zdCB0eXBlbmFtZSBTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpTdGF0c1R5cGUmIHN0YXRzKQp7CglERV9VTlJFRihsb2cpOwoJREVfVU5SRUYoc2FtcGxlcyk7CglERV9VTlJFRihzdGF0cyk7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgpzdGF0aWMgdHlwZW5hbWUgRW5hYmxlSWY8dm9pZCwgTm90PFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OkhBU19SRU5ERVJfU1RBVFM+OjpWYWx1ZT46OlR5cGUgbG9nUmVuZGVyQ29udHJpYnV0aW9uICh0Y3U6OlRlc3RMb2cmIGxvZywgY29uc3Qgc3RkOjp2ZWN0b3I8UmVuZGVyU2FtcGxlUmVzdWx0PFNhbXBsZVR5cGU+ID4mIHNhbXBsZXMsIGNvbnN0IHR5cGVuYW1lIFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OlN0YXRzVHlwZSYgc3RhdHMpCnsKCURFX1VOUkVGKGxvZyk7CglERV9VTlJFRihzYW1wbGVzKTsKCURFX1VOUkVGKHN0YXRzKTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFNhbXBsZVR5cGU+CnN0YXRpYyB0eXBlbmFtZSBFbmFibGVJZjx2b2lkLCBOb3Q8U2FtcGxlVHlwZVRyYWl0czxTYW1wbGVUeXBlPjo6SEFTX1JFQURfU1RBVFM+OjpWYWx1ZT46OlR5cGUgbG9nUmVhZENvbnRyaWJ1dGlvbiAodGN1OjpUZXN0TG9nJiBsb2csIGNvbnN0IHN0ZDo6dmVjdG9yPFJlbmRlclNhbXBsZVJlc3VsdDxTYW1wbGVUeXBlPiA+JiBzYW1wbGVzLCBjb25zdCB0eXBlbmFtZSBTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpTdGF0c1R5cGUmIHN0YXRzKQp7CglERV9VTlJFRihsb2cpOwoJREVfVU5SRUYoc2FtcGxlcyk7CglERV9VTlJFRihzdGF0cyk7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgpzdGF0aWMgdHlwZW5hbWUgRW5hYmxlSWY8dm9pZCwgTm90PFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OkhBU19VUExPQURfU1RBVFM+OjpWYWx1ZT46OlR5cGUgbG9nVXBsb2FkQ29udHJpYnV0aW9uICh0Y3U6OlRlc3RMb2cmIGxvZywgY29uc3Qgc3RkOjp2ZWN0b3I8UmVuZGVyU2FtcGxlUmVzdWx0PFNhbXBsZVR5cGU+ID4mIHNhbXBsZXMsIGNvbnN0IHR5cGVuYW1lIFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OlN0YXRzVHlwZSYgc3RhdHMpCnsKCURFX1VOUkVGKGxvZyk7CglERV9VTlJFRihzYW1wbGVzKTsKCURFX1VOUkVGKHN0YXRzKTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFNhbXBsZVR5cGU+CnN0YXRpYyB0eXBlbmFtZSBFbmFibGVJZjx2b2lkLCBOb3Q8U2FtcGxlVHlwZVRyYWl0czxTYW1wbGVUeXBlPjo6SEFTX1RPVEFMX1NUQVRTPjo6VmFsdWU+OjpUeXBlIGxvZ1RvdGFsQ29udHJpYnV0aW9uICh0Y3U6OlRlc3RMb2cmIGxvZywgY29uc3Qgc3RkOjp2ZWN0b3I8UmVuZGVyU2FtcGxlUmVzdWx0PFNhbXBsZVR5cGU+ID4mIHNhbXBsZXMsIGNvbnN0IHR5cGVuYW1lIFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OlN0YXRzVHlwZSYgc3RhdHMpCnsKCURFX1VOUkVGKGxvZyk7CglERV9VTlJFRihzYW1wbGVzKTsKCURFX1VOUkVGKHN0YXRzKTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFNhbXBsZVR5cGU+CnN0YXRpYyB0eXBlbmFtZSBFbmFibGVJZjx2b2lkLCBOb3Q8U2FtcGxlVHlwZVRyYWl0czxTYW1wbGVUeXBlPjo6SEFTX0ZJUlNUX1JFTkRFUl9TVEFUUz46OlZhbHVlPjo6VHlwZSBsb2dGaXJzdFJlbmRlckNvbnRyaWJ1dGlvbiAodGN1OjpUZXN0TG9nJiBsb2csIGNvbnN0IHN0ZDo6dmVjdG9yPFJlbmRlclNhbXBsZVJlc3VsdDxTYW1wbGVUeXBlPiA+JiBzYW1wbGVzLCBjb25zdCB0eXBlbmFtZSBTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpTdGF0c1R5cGUmIHN0YXRzKQp7CglERV9VTlJFRihsb2cpOwoJREVfVU5SRUYoc2FtcGxlcyk7CglERV9VTlJFRihzdGF0cyk7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgpzdGF0aWMgdHlwZW5hbWUgRW5hYmxlSWY8dm9pZCwgTm90PFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OkhBU19TRUNPTkRfUkVOREVSX1NUQVRTPjo6VmFsdWU+OjpUeXBlIGxvZ1NlY29uZFJlbmRlckNvbnRyaWJ1dGlvbiAodGN1OjpUZXN0TG9nJiBsb2csIGNvbnN0IHN0ZDo6dmVjdG9yPFJlbmRlclNhbXBsZVJlc3VsdDxTYW1wbGVUeXBlPiA+JiBzYW1wbGVzLCBjb25zdCB0eXBlbmFtZSBTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpTdGF0c1R5cGUmIHN0YXRzKQp7CglERV9VTlJFRihsb2cpOwoJREVfVU5SRUYoc2FtcGxlcyk7CglERV9VTlJFRihzdGF0cyk7Cn0KCnZvaWQgbG9nU2FtcGxlTGlzdCAodGN1OjpUZXN0TG9nJiBsb2csIGNvbnN0IExpbmVQYXJhbWV0ZXJzV2l0aENvbmZpZGVuY2UmIHRoZWlsU2VuRml0dGluZywgY29uc3Qgc3RkOjp2ZWN0b3I8VXBsb2FkU2FtcGxlUmVzdWx0PFNpbmdsZU9wZXJhdGlvbkR1cmF0aW9uPiA+JiBzYW1wbGVzKQp7Cglsb2cgPDwgdGN1OjpUZXN0TG9nOjpTYW1wbGVMaXN0KCJTYW1wbGVzIiwgIlNhbXBsZXMiKQoJCTw8IHRjdTo6VGVzdExvZzo6U2FtcGxlSW5mbwoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJXcml0dGVuU2l6ZSIsCQkiV3JpdHRlbiBzaXplIiwJCQkiYnl0ZXMiLAlRUF9TQU1QTEVfVkFMVUVfVEFHX1BSRURJQ1RPUikKCQk8PCB0Y3U6OlRlc3RMb2c6OlZhbHVlSW5mbygiQnVmZmVyU2l6ZSIsCQkiQnVmZmVyIHNpemUiLAkJCSJieXRlcyIsCVFQX1NBTVBMRV9WQUxVRV9UQUdfUFJFRElDVE9SKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJVcGxvYWRUaW1lIiwJCSJVcGxvYWQgdGltZSIsCQkJInVzIiwJCVFQX1NBTVBMRV9WQUxVRV9UQUdfUkVTUE9OU0UpCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIkZpdFJlc2lkdWFsIiwJCSJGaXQgcmVzaWR1YWwiLAkJCSJ1cyIsCQlRUF9TQU1QTEVfVkFMVUVfVEFHX1JFU1BPTlNFKQoJCTw8IHRjdTo6VGVzdExvZzo6RW5kU2FtcGxlSW5mbzsKCglmb3IgKGludCBzYW1wbGVOZHggPSAwOyBzYW1wbGVOZHggPCAoaW50KXNhbXBsZXMuc2l6ZSgpOyArK3NhbXBsZU5keCkKCXsKCQljb25zdCBmbG9hdCBmaXRSZXNpZHVhbCA9IChmbG9hdClzYW1wbGVzW3NhbXBsZU5keF0uZHVyYXRpb24uZml0UmVzcG9uc2VEdXJhdGlvbiAtICh0aGVpbFNlbkZpdHRpbmcub2Zmc2V0ICsgdGhlaWxTZW5GaXR0aW5nLmNvZWZmaWNpZW50ICogKGZsb2F0KXNhbXBsZXNbc2FtcGxlTmR4XS53cml0dGVuU2l6ZSk7CgkJbG9nCTw8IHRjdTo6VGVzdExvZzo6U2FtcGxlCgkJCTw8IHNhbXBsZXNbc2FtcGxlTmR4XS53cml0dGVuU2l6ZQoJCQk8PCBzYW1wbGVzW3NhbXBsZU5keF0uYnVmZmVyU2l6ZQoJCQk8PCAoaW50KXNhbXBsZXNbc2FtcGxlTmR4XS5kdXJhdGlvbi50b3RhbER1cmF0aW9uCgkJCTw8IGZpdFJlc2lkdWFsCgkJCTw8IHRjdTo6VGVzdExvZzo6RW5kU2FtcGxlOwoJfQoKCWxvZyA8PCB0Y3U6OlRlc3RMb2c6OkVuZFNhbXBsZUxpc3Q7Cn0KCnZvaWQgbG9nU2FtcGxlTGlzdCAodGN1OjpUZXN0TG9nJiBsb2csIGNvbnN0IExpbmVQYXJhbWV0ZXJzV2l0aENvbmZpZGVuY2UmIHRoZWlsU2VuRml0dGluZywgY29uc3Qgc3RkOjp2ZWN0b3I8VXBsb2FkU2FtcGxlUmVzdWx0PE1hcEJ1ZmZlclJhbmdlRHVyYXRpb24+ID4mIHNhbXBsZXMpCnsKCWxvZyA8PCB0Y3U6OlRlc3RMb2c6OlNhbXBsZUxpc3QoIlNhbXBsZXMiLCAiU2FtcGxlcyIpCgkJPDwgdGN1OjpUZXN0TG9nOjpTYW1wbGVJbmZvCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIldyaXR0ZW5TaXplIiwJCSJXcml0dGVuIHNpemUiLAkJCSJieXRlcyIsCVFQX1NBTVBMRV9WQUxVRV9UQUdfUFJFRElDVE9SKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJCdWZmZXJTaXplIiwJCSJCdWZmZXIgc2l6ZSIsCQkJImJ5dGVzIiwJUVBfU0FNUExFX1ZBTFVFX1RBR19QUkVESUNUT1IpCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIlRvdGFsVGltZSIsCQkJIlRvdGFsIHRpbWUiLAkJCSJ1cyIsCQlRUF9TQU1QTEVfVkFMVUVfVEFHX1JFU1BPTlNFKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJBbGxvY1RpbWUiLAkJCSJBbGxvYyB0aW1lIiwJCQkidXMiLAkJUVBfU0FNUExFX1ZBTFVFX1RBR19SRVNQT05TRSkKCQk8PCB0Y3U6OlRlc3RMb2c6OlZhbHVlSW5mbygiTWFwVGltZSIsCQkJIk1hcCB0aW1lIiwJCQkJInVzIiwJCVFQX1NBTVBMRV9WQUxVRV9UQUdfUkVTUE9OU0UpCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIlVubWFwVGltZSIsCQkJIlVubWFwIHRpbWUiLAkJCSJ1cyIsCQlRUF9TQU1QTEVfVkFMVUVfVEFHX1JFU1BPTlNFKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJXcml0ZVRpbWUiLAkJCSJXcml0ZSB0aW1lIiwJCQkidXMiLAkJUVBfU0FNUExFX1ZBTFVFX1RBR19SRVNQT05TRSkKCQk8PCB0Y3U6OlRlc3RMb2c6OlZhbHVlSW5mbygiRml0UmVzaWR1YWwiLAkJIkZpdCByZXNpZHVhbCIsCQkJInVzIiwJCVFQX1NBTVBMRV9WQUxVRV9UQUdfUkVTUE9OU0UpCgkJPDwgdGN1OjpUZXN0TG9nOjpFbmRTYW1wbGVJbmZvOwoKCWZvciAoaW50IHNhbXBsZU5keCA9IDA7IHNhbXBsZU5keCA8IChpbnQpc2FtcGxlcy5zaXplKCk7ICsrc2FtcGxlTmR4KQoJewoJCWNvbnN0IGZsb2F0IGZpdFJlc2lkdWFsID0gKGZsb2F0KXNhbXBsZXNbc2FtcGxlTmR4XS5kdXJhdGlvbi5maXRSZXNwb25zZUR1cmF0aW9uIC0gKHRoZWlsU2VuRml0dGluZy5vZmZzZXQgKyB0aGVpbFNlbkZpdHRpbmcuY29lZmZpY2llbnQgKiAoZmxvYXQpc2FtcGxlc1tzYW1wbGVOZHhdLndyaXR0ZW5TaXplKTsKCQlsb2cJPDwgdGN1OjpUZXN0TG9nOjpTYW1wbGUKCQkJPDwgc2FtcGxlc1tzYW1wbGVOZHhdLndyaXR0ZW5TaXplCgkJCTw8IHNhbXBsZXNbc2FtcGxlTmR4XS5idWZmZXJTaXplCgkJCTw8IChpbnQpc2FtcGxlc1tzYW1wbGVOZHhdLmR1cmF0aW9uLnRvdGFsRHVyYXRpb24KCQkJPDwgKGludClzYW1wbGVzW3NhbXBsZU5keF0uZHVyYXRpb24uYWxsb2NEdXJhdGlvbgoJCQk8PCAoaW50KXNhbXBsZXNbc2FtcGxlTmR4XS5kdXJhdGlvbi5tYXBEdXJhdGlvbgoJCQk8PCAoaW50KXNhbXBsZXNbc2FtcGxlTmR4XS5kdXJhdGlvbi51bm1hcER1cmF0aW9uCgkJCTw8IChpbnQpc2FtcGxlc1tzYW1wbGVOZHhdLmR1cmF0aW9uLndyaXRlRHVyYXRpb24KCQkJPDwgZml0UmVzaWR1YWwKCQkJPDwgdGN1OjpUZXN0TG9nOjpFbmRTYW1wbGU7Cgl9CgoJbG9nIDw8IHRjdTo6VGVzdExvZzo6RW5kU2FtcGxlTGlzdDsKfQoKdm9pZCBsb2dTYW1wbGVMaXN0ICh0Y3U6OlRlc3RMb2cmIGxvZywgY29uc3QgTGluZVBhcmFtZXRlcnNXaXRoQ29uZmlkZW5jZSYgdGhlaWxTZW5GaXR0aW5nLCBjb25zdCBzdGQ6OnZlY3RvcjxVcGxvYWRTYW1wbGVSZXN1bHQ8TWFwQnVmZmVyUmFuZ2VEdXJhdGlvbk5vQWxsb2M+ID4mIHNhbXBsZXMpCnsKCWxvZyA8PCB0Y3U6OlRlc3RMb2c6OlNhbXBsZUxpc3QoIlNhbXBsZXMiLCAiU2FtcGxlcyIpCgkJPDwgdGN1OjpUZXN0TG9nOjpTYW1wbGVJbmZvCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIldyaXR0ZW5TaXplIiwJCSJXcml0dGVuIHNpemUiLAkJCSJieXRlcyIsCVFQX1NBTVBMRV9WQUxVRV9UQUdfUFJFRElDVE9SKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJCdWZmZXJTaXplIiwJCSJCdWZmZXIgc2l6ZSIsCQkJImJ5dGVzIiwJUVBfU0FNUExFX1ZBTFVFX1RBR19QUkVESUNUT1IpCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIlRvdGFsVGltZSIsCQkJIlRvdGFsIHRpbWUiLAkJCSJ1cyIsCQlRUF9TQU1QTEVfVkFMVUVfVEFHX1JFU1BPTlNFKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJNYXBUaW1lIiwJCQkiTWFwIHRpbWUiLAkJCQkidXMiLAkJUVBfU0FNUExFX1ZBTFVFX1RBR19SRVNQT05TRSkKCQk8PCB0Y3U6OlRlc3RMb2c6OlZhbHVlSW5mbygiVW5tYXBUaW1lIiwJCQkiVW5tYXAgdGltZSIsCQkJInVzIiwJCVFQX1NBTVBMRV9WQUxVRV9UQUdfUkVTUE9OU0UpCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIldyaXRlVGltZSIsCQkJIldyaXRlIHRpbWUiLAkJCSJ1cyIsCQlRUF9TQU1QTEVfVkFMVUVfVEFHX1JFU1BPTlNFKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJGaXRSZXNpZHVhbCIsCQkiRml0IHJlc2lkdWFsIiwJCQkidXMiLAkJUVBfU0FNUExFX1ZBTFVFX1RBR19SRVNQT05TRSkKCQk8PCB0Y3U6OlRlc3RMb2c6OkVuZFNhbXBsZUluZm87CgoJZm9yIChpbnQgc2FtcGxlTmR4ID0gMDsgc2FtcGxlTmR4IDwgKGludClzYW1wbGVzLnNpemUoKTsgKytzYW1wbGVOZHgpCgl7CgkJY29uc3QgZmxvYXQgZml0UmVzaWR1YWwgPSAoZmxvYXQpc2FtcGxlc1tzYW1wbGVOZHhdLmR1cmF0aW9uLmZpdFJlc3BvbnNlRHVyYXRpb24gLSAodGhlaWxTZW5GaXR0aW5nLm9mZnNldCArIHRoZWlsU2VuRml0dGluZy5jb2VmZmljaWVudCAqIChmbG9hdClzYW1wbGVzW3NhbXBsZU5keF0ud3JpdHRlblNpemUpOwoJCWxvZwk8PCB0Y3U6OlRlc3RMb2c6OlNhbXBsZQoJCQk8PCBzYW1wbGVzW3NhbXBsZU5keF0ud3JpdHRlblNpemUKCQkJPDwgc2FtcGxlc1tzYW1wbGVOZHhdLmJ1ZmZlclNpemUKCQkJPDwgKGludClzYW1wbGVzW3NhbXBsZU5keF0uZHVyYXRpb24udG90YWxEdXJhdGlvbgoJCQk8PCAoaW50KXNhbXBsZXNbc2FtcGxlTmR4XS5kdXJhdGlvbi5tYXBEdXJhdGlvbgoJCQk8PCAoaW50KXNhbXBsZXNbc2FtcGxlTmR4XS5kdXJhdGlvbi51bm1hcER1cmF0aW9uCgkJCTw8IChpbnQpc2FtcGxlc1tzYW1wbGVOZHhdLmR1cmF0aW9uLndyaXRlRHVyYXRpb24KCQkJPDwgZml0UmVzaWR1YWwKCQkJPDwgdGN1OjpUZXN0TG9nOjpFbmRTYW1wbGU7Cgl9CgoJbG9nIDw8IHRjdTo6VGVzdExvZzo6RW5kU2FtcGxlTGlzdDsKfQoKdm9pZCBsb2dTYW1wbGVMaXN0ICh0Y3U6OlRlc3RMb2cmIGxvZywgY29uc3QgTGluZVBhcmFtZXRlcnNXaXRoQ29uZmlkZW5jZSYgdGhlaWxTZW5GaXR0aW5nLCBjb25zdCBzdGQ6OnZlY3RvcjxVcGxvYWRTYW1wbGVSZXN1bHQ8TWFwQnVmZmVyUmFuZ2VGbHVzaER1cmF0aW9uPiA+JiBzYW1wbGVzKQp7Cglsb2cgPDwgdGN1OjpUZXN0TG9nOjpTYW1wbGVMaXN0KCJTYW1wbGVzIiwgIlNhbXBsZXMiKQoJCTw8IHRjdTo6VGVzdExvZzo6U2FtcGxlSW5mbwoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJXcml0dGVuU2l6ZSIsCQkiV3JpdHRlbiBzaXplIiwJCQkiYnl0ZXMiLAlRUF9TQU1QTEVfVkFMVUVfVEFHX1BSRURJQ1RPUikKCQk8PCB0Y3U6OlRlc3RMb2c6OlZhbHVlSW5mbygiQnVmZmVyU2l6ZSIsCQkiQnVmZmVyIHNpemUiLAkJCSJieXRlcyIsCVFQX1NBTVBMRV9WQUxVRV9UQUdfUFJFRElDVE9SKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJUb3RhbFRpbWUiLAkJCSJUb3RhbCB0aW1lIiwJCQkidXMiLAkJUVBfU0FNUExFX1ZBTFVFX1RBR19SRVNQT05TRSkKCQk8PCB0Y3U6OlRlc3RMb2c6OlZhbHVlSW5mbygiQWxsb2NUaW1lIiwJCQkiQWxsb2MgdGltZSIsCQkJInVzIiwJCVFQX1NBTVBMRV9WQUxVRV9UQUdfUkVTUE9OU0UpCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIk1hcFRpbWUiLAkJCSJNYXAgdGltZSIsCQkJCSJ1cyIsCQlRUF9TQU1QTEVfVkFMVUVfVEFHX1JFU1BPTlNFKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJVbm1hcFRpbWUiLAkJCSJVbm1hcCB0aW1lIiwJCQkidXMiLAkJUVBfU0FNUExFX1ZBTFVFX1RBR19SRVNQT05TRSkKCQk8PCB0Y3U6OlRlc3RMb2c6OlZhbHVlSW5mbygiV3JpdGVUaW1lIiwJCQkiV3JpdGUgdGltZSIsCQkJInVzIiwJCVFQX1NBTVBMRV9WQUxVRV9UQUdfUkVTUE9OU0UpCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIkZsdXNoVGltZSIsCQkJIkZsdXNoIHRpbWUiLAkJCSJ1cyIsCQlRUF9TQU1QTEVfVkFMVUVfVEFHX1JFU1BPTlNFKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJGaXRSZXNpZHVhbCIsCQkiRml0IHJlc2lkdWFsIiwJCQkidXMiLAkJUVBfU0FNUExFX1ZBTFVFX1RBR19SRVNQT05TRSkKCQk8PCB0Y3U6OlRlc3RMb2c6OkVuZFNhbXBsZUluZm87CgoJZm9yIChpbnQgc2FtcGxlTmR4ID0gMDsgc2FtcGxlTmR4IDwgKGludClzYW1wbGVzLnNpemUoKTsgKytzYW1wbGVOZHgpCgl7CgkJY29uc3QgZmxvYXQgZml0UmVzaWR1YWwgPSAoZmxvYXQpc2FtcGxlc1tzYW1wbGVOZHhdLmR1cmF0aW9uLmZpdFJlc3BvbnNlRHVyYXRpb24gLSAodGhlaWxTZW5GaXR0aW5nLm9mZnNldCArIHRoZWlsU2VuRml0dGluZy5jb2VmZmljaWVudCAqIChmbG9hdClzYW1wbGVzW3NhbXBsZU5keF0ud3JpdHRlblNpemUpOwoJCWxvZwk8PCB0Y3U6OlRlc3RMb2c6OlNhbXBsZQoJCQk8PCBzYW1wbGVzW3NhbXBsZU5keF0ud3JpdHRlblNpemUKCQkJPDwgc2FtcGxlc1tzYW1wbGVOZHhdLmJ1ZmZlclNpemUKCQkJPDwgKGludClzYW1wbGVzW3NhbXBsZU5keF0uZHVyYXRpb24udG90YWxEdXJhdGlvbgoJCQk8PCAoaW50KXNhbXBsZXNbc2FtcGxlTmR4XS5kdXJhdGlvbi5hbGxvY0R1cmF0aW9uCgkJCTw8IChpbnQpc2FtcGxlc1tzYW1wbGVOZHhdLmR1cmF0aW9uLm1hcER1cmF0aW9uCgkJCTw8IChpbnQpc2FtcGxlc1tzYW1wbGVOZHhdLmR1cmF0aW9uLnVubWFwRHVyYXRpb24KCQkJPDwgKGludClzYW1wbGVzW3NhbXBsZU5keF0uZHVyYXRpb24ud3JpdGVEdXJhdGlvbgoJCQk8PCAoaW50KXNhbXBsZXNbc2FtcGxlTmR4XS5kdXJhdGlvbi5mbHVzaER1cmF0aW9uCgkJCTw8IGZpdFJlc2lkdWFsCgkJCTw8IHRjdTo6VGVzdExvZzo6RW5kU2FtcGxlOwoJfQoKCWxvZyA8PCB0Y3U6OlRlc3RMb2c6OkVuZFNhbXBsZUxpc3Q7Cn0KCnZvaWQgbG9nU2FtcGxlTGlzdCAodGN1OjpUZXN0TG9nJiBsb2csIGNvbnN0IExpbmVQYXJhbWV0ZXJzV2l0aENvbmZpZGVuY2UmIHRoZWlsU2VuRml0dGluZywgY29uc3Qgc3RkOjp2ZWN0b3I8VXBsb2FkU2FtcGxlUmVzdWx0PE1hcEJ1ZmZlclJhbmdlRmx1c2hEdXJhdGlvbk5vQWxsb2M+ID4mIHNhbXBsZXMpCnsKCWxvZyA8PCB0Y3U6OlRlc3RMb2c6OlNhbXBsZUxpc3QoIlNhbXBsZXMiLCAiU2FtcGxlcyIpCgkJPDwgdGN1OjpUZXN0TG9nOjpTYW1wbGVJbmZvCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIldyaXR0ZW5TaXplIiwJCSJXcml0dGVuIHNpemUiLAkJCSJieXRlcyIsCVFQX1NBTVBMRV9WQUxVRV9UQUdfUFJFRElDVE9SKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJCdWZmZXJTaXplIiwJCSJCdWZmZXIgc2l6ZSIsCQkJImJ5dGVzIiwJUVBfU0FNUExFX1ZBTFVFX1RBR19QUkVESUNUT1IpCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIlRvdGFsVGltZSIsCQkJIlRvdGFsIHRpbWUiLAkJCSJ1cyIsCQlRUF9TQU1QTEVfVkFMVUVfVEFHX1JFU1BPTlNFKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJNYXBUaW1lIiwJCQkiTWFwIHRpbWUiLAkJCQkidXMiLAkJUVBfU0FNUExFX1ZBTFVFX1RBR19SRVNQT05TRSkKCQk8PCB0Y3U6OlRlc3RMb2c6OlZhbHVlSW5mbygiVW5tYXBUaW1lIiwJCQkiVW5tYXAgdGltZSIsCQkJInVzIiwJCVFQX1NBTVBMRV9WQUxVRV9UQUdfUkVTUE9OU0UpCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIldyaXRlVGltZSIsCQkJIldyaXRlIHRpbWUiLAkJCSJ1cyIsCQlRUF9TQU1QTEVfVkFMVUVfVEFHX1JFU1BPTlNFKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJGbHVzaFRpbWUiLAkJCSJGbHVzaCB0aW1lIiwJCQkidXMiLAkJUVBfU0FNUExFX1ZBTFVFX1RBR19SRVNQT05TRSkKCQk8PCB0Y3U6OlRlc3RMb2c6OlZhbHVlSW5mbygiRml0UmVzaWR1YWwiLAkJIkZpdCByZXNpZHVhbCIsCQkJInVzIiwJCVFQX1NBTVBMRV9WQUxVRV9UQUdfUkVTUE9OU0UpCgkJPDwgdGN1OjpUZXN0TG9nOjpFbmRTYW1wbGVJbmZvOwoKCWZvciAoaW50IHNhbXBsZU5keCA9IDA7IHNhbXBsZU5keCA8IChpbnQpc2FtcGxlcy5zaXplKCk7ICsrc2FtcGxlTmR4KQoJewoJCWNvbnN0IGZsb2F0IGZpdFJlc2lkdWFsID0gKGZsb2F0KXNhbXBsZXNbc2FtcGxlTmR4XS5kdXJhdGlvbi5maXRSZXNwb25zZUR1cmF0aW9uIC0gKHRoZWlsU2VuRml0dGluZy5vZmZzZXQgKyB0aGVpbFNlbkZpdHRpbmcuY29lZmZpY2llbnQgKiAoZmxvYXQpc2FtcGxlc1tzYW1wbGVOZHhdLndyaXR0ZW5TaXplKTsKCQlsb2cJPDwgdGN1OjpUZXN0TG9nOjpTYW1wbGUKCQkJPDwgc2FtcGxlc1tzYW1wbGVOZHhdLndyaXR0ZW5TaXplCgkJCTw8IHNhbXBsZXNbc2FtcGxlTmR4XS5idWZmZXJTaXplCgkJCTw8IChpbnQpc2FtcGxlc1tzYW1wbGVOZHhdLmR1cmF0aW9uLnRvdGFsRHVyYXRpb24KCQkJPDwgKGludClzYW1wbGVzW3NhbXBsZU5keF0uZHVyYXRpb24ubWFwRHVyYXRpb24KCQkJPDwgKGludClzYW1wbGVzW3NhbXBsZU5keF0uZHVyYXRpb24udW5tYXBEdXJhdGlvbgoJCQk8PCAoaW50KXNhbXBsZXNbc2FtcGxlTmR4XS5kdXJhdGlvbi53cml0ZUR1cmF0aW9uCgkJCTw8IChpbnQpc2FtcGxlc1tzYW1wbGVOZHhdLmR1cmF0aW9uLmZsdXNoRHVyYXRpb24KCQkJPDwgZml0UmVzaWR1YWwKCQkJPDwgdGN1OjpUZXN0TG9nOjpFbmRTYW1wbGU7Cgl9CgoJbG9nIDw8IHRjdTo6VGVzdExvZzo6RW5kU2FtcGxlTGlzdDsKfQoKdm9pZCBsb2dTYW1wbGVMaXN0ICh0Y3U6OlRlc3RMb2cmIGxvZywgY29uc3QgTGluZVBhcmFtZXRlcnNXaXRoQ29uZmlkZW5jZSYgdGhlaWxTZW5GaXR0aW5nLCBjb25zdCBzdGQ6OnZlY3RvcjxSZW5kZXJTYW1wbGVSZXN1bHQ8UmVuZGVyUmVhZER1cmF0aW9uPiA+JiBzYW1wbGVzKQp7Cglsb2cgPDwgdGN1OjpUZXN0TG9nOjpTYW1wbGVMaXN0KCJTYW1wbGVzIiwgIlNhbXBsZXMiKQoJCTw8IHRjdTo6VGVzdExvZzo6U2FtcGxlSW5mbwoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJEYXRhU2l6ZSIsCQkJIkRhdGEgcHJvY2Vzc2VkIiwJCSJieXRlcyIsCVFQX1NBTVBMRV9WQUxVRV9UQUdfUFJFRElDVE9SKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJWZXJ0ZXhDb3VudCIsCQkiTnVtYmVyIG9mIHZlcnRpY2VzIiwJInZlcnRpY2VzIiwJUVBfU0FNUExFX1ZBTFVFX1RBR19QUkVESUNUT1IpCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIlRvdGFsVGltZSIsCQkJIlRvdGFsIHRpbWUiLAkJCSJ1cyIsCQlRUF9TQU1QTEVfVkFMVUVfVEFHX1JFU1BPTlNFKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJEcmF3Q2FsbFRpbWUiLAkJIkRyYXcgY2FsbCB0aW1lIiwJCSJ1cyIsCQlRUF9TQU1QTEVfVkFMVUVfVEFHX1JFU1BPTlNFKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJSZWFkVGltZSIsCQkJIlJlYWRQaXhlbHMgdGltZSIsCQkidXMiLAkJUVBfU0FNUExFX1ZBTFVFX1RBR19SRVNQT05TRSkKCQk8PCB0Y3U6OlRlc3RMb2c6OlZhbHVlSW5mbygiRml0UmVzaWR1YWwiLAkJIkZpdCByZXNpZHVhbCIsCQkJInVzIiwJCVFQX1NBTVBMRV9WQUxVRV9UQUdfUkVTUE9OU0UpCgkJPDwgdGN1OjpUZXN0TG9nOjpFbmRTYW1wbGVJbmZvOwoKCWZvciAoaW50IHNhbXBsZU5keCA9IDA7IHNhbXBsZU5keCA8IChpbnQpc2FtcGxlcy5zaXplKCk7ICsrc2FtcGxlTmR4KQoJewoJCWNvbnN0IGZsb2F0IGZpdFJlc2lkdWFsID0gKGZsb2F0KXNhbXBsZXNbc2FtcGxlTmR4XS5kdXJhdGlvbi5maXRSZXNwb25zZUR1cmF0aW9uIC0gKHRoZWlsU2VuRml0dGluZy5vZmZzZXQgKyB0aGVpbFNlbkZpdHRpbmcuY29lZmZpY2llbnQgKiAoZmxvYXQpc2FtcGxlc1tzYW1wbGVOZHhdLnJlbmRlckRhdGFTaXplKTsKCQlsb2cJPDwgdGN1OjpUZXN0TG9nOjpTYW1wbGUKCQkJPDwgc2FtcGxlc1tzYW1wbGVOZHhdLnJlbmRlckRhdGFTaXplCgkJCTw8IHNhbXBsZXNbc2FtcGxlTmR4XS5udW1WZXJ0aWNlcwoJCQk8PCAoaW50KXNhbXBsZXNbc2FtcGxlTmR4XS5kdXJhdGlvbi5yZW5kZXJSZWFkRHVyYXRpb24KCQkJPDwgKGludClzYW1wbGVzW3NhbXBsZU5keF0uZHVyYXRpb24ucmVuZGVyRHVyYXRpb24KCQkJPDwgKGludClzYW1wbGVzW3NhbXBsZU5keF0uZHVyYXRpb24ucmVhZER1cmF0aW9uCgkJCTw8IGZpdFJlc2lkdWFsCgkJCTw8IHRjdTo6VGVzdExvZzo6RW5kU2FtcGxlOwoJfQoKCWxvZyA8PCB0Y3U6OlRlc3RMb2c6OkVuZFNhbXBsZUxpc3Q7Cn0KCnZvaWQgbG9nU2FtcGxlTGlzdCAodGN1OjpUZXN0TG9nJiBsb2csIGNvbnN0IExpbmVQYXJhbWV0ZXJzV2l0aENvbmZpZGVuY2UmIHRoZWlsU2VuRml0dGluZywgY29uc3Qgc3RkOjp2ZWN0b3I8UmVuZGVyU2FtcGxlUmVzdWx0PFVucmVsYXRlZFVwbG9hZFJlbmRlclJlYWREdXJhdGlvbj4gPiYgc2FtcGxlcykKewoJbG9nIDw8IHRjdTo6VGVzdExvZzo6U2FtcGxlTGlzdCgiU2FtcGxlcyIsICJTYW1wbGVzIikKCQk8PCB0Y3U6OlRlc3RMb2c6OlNhbXBsZUluZm8KCQk8PCB0Y3U6OlRlc3RMb2c6OlZhbHVlSW5mbygiRGF0YVNpemUiLAkJCQkiRGF0YSBwcm9jZXNzZWQiLAkJCSJieXRlcyIsCVFQX1NBTVBMRV9WQUxVRV9UQUdfUFJFRElDVE9SKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJWZXJ0ZXhDb3VudCIsCQkJIk51bWJlciBvZiB2ZXJ0aWNlcyIsCQkidmVydGljZXMiLAlRUF9TQU1QTEVfVkFMVUVfVEFHX1BSRURJQ1RPUikKCQk8PCB0Y3U6OlRlc3RMb2c6OlZhbHVlSW5mbygiVW5yZWxhdGVkVXBsb2FkU2l6ZSIsCSJVbnJlbGF0ZWQgdXBsb2FkIHNpemUiLAkiYnl0ZXMiLAlRUF9TQU1QTEVfVkFMVUVfVEFHX1BSRURJQ1RPUikKCQk8PCB0Y3U6OlRlc3RMb2c6OlZhbHVlSW5mbygiVG90YWxUaW1lIiwJCQkJIlRvdGFsIHRpbWUiLAkJCQkidXMiLAkJUVBfU0FNUExFX1ZBTFVFX1RBR19SRVNQT05TRSkKCQk8PCB0Y3U6OlRlc3RMb2c6OlZhbHVlSW5mbygiRHJhd0NhbGxUaW1lIiwJCQkiRHJhdyBjYWxsIHRpbWUiLAkJCSJ1cyIsCQlRUF9TQU1QTEVfVkFMVUVfVEFHX1JFU1BPTlNFKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJSZWFkVGltZSIsCQkJCSJSZWFkUGl4ZWxzIHRpbWUiLAkJCSJ1cyIsCQlRUF9TQU1QTEVfVkFMVUVfVEFHX1JFU1BPTlNFKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJGaXRSZXNpZHVhbCIsCQkJIkZpdCByZXNpZHVhbCIsCQkJCSJ1cyIsCQlRUF9TQU1QTEVfVkFMVUVfVEFHX1JFU1BPTlNFKQoJCTw8IHRjdTo6VGVzdExvZzo6RW5kU2FtcGxlSW5mbzsKCglmb3IgKGludCBzYW1wbGVOZHggPSAwOyBzYW1wbGVOZHggPCAoaW50KXNhbXBsZXMuc2l6ZSgpOyArK3NhbXBsZU5keCkKCXsKCQljb25zdCBmbG9hdCBmaXRSZXNpZHVhbCA9IChmbG9hdClzYW1wbGVzW3NhbXBsZU5keF0uZHVyYXRpb24uZml0UmVzcG9uc2VEdXJhdGlvbiAtICh0aGVpbFNlbkZpdHRpbmcub2Zmc2V0ICsgdGhlaWxTZW5GaXR0aW5nLmNvZWZmaWNpZW50ICogKGZsb2F0KXNhbXBsZXNbc2FtcGxlTmR4XS5yZW5kZXJEYXRhU2l6ZSk7CgkJbG9nCTw8IHRjdTo6VGVzdExvZzo6U2FtcGxlCgkJCTw8IHNhbXBsZXNbc2FtcGxlTmR4XS5yZW5kZXJEYXRhU2l6ZQoJCQk8PCBzYW1wbGVzW3NhbXBsZU5keF0ubnVtVmVydGljZXMKCQkJPDwgc2FtcGxlc1tzYW1wbGVOZHhdLnVucmVsYXRlZERhdGFTaXplCgkJCTw8IChpbnQpc2FtcGxlc1tzYW1wbGVOZHhdLmR1cmF0aW9uLnJlbmRlclJlYWREdXJhdGlvbgoJCQk8PCAoaW50KXNhbXBsZXNbc2FtcGxlTmR4XS5kdXJhdGlvbi5yZW5kZXJEdXJhdGlvbgoJCQk8PCAoaW50KXNhbXBsZXNbc2FtcGxlTmR4XS5kdXJhdGlvbi5yZWFkRHVyYXRpb24KCQkJPDwgZml0UmVzaWR1YWwKCQkJPDwgdGN1OjpUZXN0TG9nOjpFbmRTYW1wbGU7Cgl9CgoJbG9nIDw8IHRjdTo6VGVzdExvZzo6RW5kU2FtcGxlTGlzdDsKfQoKdm9pZCBsb2dTYW1wbGVMaXN0ICh0Y3U6OlRlc3RMb2cmIGxvZywgY29uc3QgTGluZVBhcmFtZXRlcnNXaXRoQ29uZmlkZW5jZSYgdGhlaWxTZW5GaXR0aW5nLCBjb25zdCBzdGQ6OnZlY3RvcjxSZW5kZXJTYW1wbGVSZXN1bHQ8VXBsb2FkUmVuZGVyUmVhZER1cmF0aW9uPiA+JiBzYW1wbGVzKQp7Cglsb2cgPDwgdGN1OjpUZXN0TG9nOjpTYW1wbGVMaXN0KCJTYW1wbGVzIiwgIlNhbXBsZXMiKQoJCTw8IHRjdTo6VGVzdExvZzo6U2FtcGxlSW5mbwoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJEYXRhU2l6ZSIsCQkJIkRhdGEgcHJvY2Vzc2VkIiwJCQkJCSJieXRlcyIsCVFQX1NBTVBMRV9WQUxVRV9UQUdfUFJFRElDVE9SKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJVcGxvYWRTaXplIiwJCSJEYXRhIHVwbG9hZGVkIiwJCQkJCSJieXRlcyIsCVFQX1NBTVBMRV9WQUxVRV9UQUdfUFJFRElDVE9SKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJWZXJ0ZXhDb3VudCIsCQkiTnVtYmVyIG9mIHZlcnRpY2VzIiwJCQkJInZlcnRpY2VzIiwJUVBfU0FNUExFX1ZBTFVFX1RBR19QUkVESUNUT1IpCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIkRyYXdSZWFkVGltZSIsCQkiRHJhdyBjYWxsIGFuZCBSZWFkUGl4ZWxzIHRpbWUiLAkidXMiLAkJUVBfU0FNUExFX1ZBTFVFX1RBR19SRVNQT05TRSkKCQk8PCB0Y3U6OlRlc3RMb2c6OlZhbHVlSW5mbygiVG90YWxUaW1lIiwJCQkiVG90YWwgdGltZSIsCQkJCQkJInVzIiwJCVFQX1NBTVBMRV9WQUxVRV9UQUdfUkVTUE9OU0UpCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIlVwbG9hZCB0aW1lIiwJCSJVcGxvYWQgdGltZSIsCQkJCQkJInVzIiwJCVFQX1NBTVBMRV9WQUxVRV9UQUdfUkVTUE9OU0UpCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIkRyYXdDYWxsVGltZSIsCQkiRHJhdyBjYWxsIHRpbWUiLAkJCQkJInVzIiwJCVFQX1NBTVBMRV9WQUxVRV9UQUdfUkVTUE9OU0UpCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIlJlYWRUaW1lIiwJCQkiUmVhZFBpeGVscyB0aW1lIiwJCQkJCSJ1cyIsCQlRUF9TQU1QTEVfVkFMVUVfVEFHX1JFU1BPTlNFKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJGaXRSZXNpZHVhbCIsCQkiRml0IHJlc2lkdWFsIiwJCQkJCQkidXMiLAkJUVBfU0FNUExFX1ZBTFVFX1RBR19SRVNQT05TRSkKCQk8PCB0Y3U6OlRlc3RMb2c6OkVuZFNhbXBsZUluZm87CgoJZm9yIChpbnQgc2FtcGxlTmR4ID0gMDsgc2FtcGxlTmR4IDwgKGludClzYW1wbGVzLnNpemUoKTsgKytzYW1wbGVOZHgpCgl7CgkJY29uc3QgZmxvYXQgZml0UmVzaWR1YWwgPSAoZmxvYXQpc2FtcGxlc1tzYW1wbGVOZHhdLmR1cmF0aW9uLmZpdFJlc3BvbnNlRHVyYXRpb24gLSAodGhlaWxTZW5GaXR0aW5nLm9mZnNldCArIHRoZWlsU2VuRml0dGluZy5jb2VmZmljaWVudCAqIChmbG9hdClzYW1wbGVzW3NhbXBsZU5keF0ucmVuZGVyRGF0YVNpemUpOwoJCWxvZwk8PCB0Y3U6OlRlc3RMb2c6OlNhbXBsZQoJCQk8PCBzYW1wbGVzW3NhbXBsZU5keF0ucmVuZGVyRGF0YVNpemUKCQkJPDwgc2FtcGxlc1tzYW1wbGVOZHhdLnVwbG9hZGVkRGF0YVNpemUKCQkJPDwgc2FtcGxlc1tzYW1wbGVOZHhdLm51bVZlcnRpY2VzCgkJCTw8IChpbnQpc2FtcGxlc1tzYW1wbGVOZHhdLmR1cmF0aW9uLnJlbmRlclJlYWREdXJhdGlvbgoJCQk8PCAoaW50KXNhbXBsZXNbc2FtcGxlTmR4XS5kdXJhdGlvbi50b3RhbER1cmF0aW9uCgkJCTw8IChpbnQpc2FtcGxlc1tzYW1wbGVOZHhdLmR1cmF0aW9uLnVwbG9hZER1cmF0aW9uCgkJCTw8IChpbnQpc2FtcGxlc1tzYW1wbGVOZHhdLmR1cmF0aW9uLnJlbmRlckR1cmF0aW9uCgkJCTw8IChpbnQpc2FtcGxlc1tzYW1wbGVOZHhdLmR1cmF0aW9uLnJlYWREdXJhdGlvbgoJCQk8PCBmaXRSZXNpZHVhbAoJCQk8PCB0Y3U6OlRlc3RMb2c6OkVuZFNhbXBsZTsKCX0KCglsb2cgPDwgdGN1OjpUZXN0TG9nOjpFbmRTYW1wbGVMaXN0Owp9Cgp2b2lkIGxvZ1NhbXBsZUxpc3QgKHRjdTo6VGVzdExvZyYgbG9nLCBjb25zdCBMaW5lUGFyYW1ldGVyc1dpdGhDb25maWRlbmNlJiB0aGVpbFNlbkZpdHRpbmcsIGNvbnN0IHN0ZDo6dmVjdG9yPFJlbmRlclNhbXBsZVJlc3VsdDxVcGxvYWRSZW5kZXJSZWFkRHVyYXRpb25XaXRoVW5yZWxhdGVkVXBsb2FkU2l6ZT4gPiYgc2FtcGxlcykKewoJbG9nIDw8IHRjdTo6VGVzdExvZzo6U2FtcGxlTGlzdCgiU2FtcGxlcyIsICJTYW1wbGVzIikKCQk8PCB0Y3U6OlRlc3RMb2c6OlNhbXBsZUluZm8KCQk8PCB0Y3U6OlRlc3RMb2c6OlZhbHVlSW5mbygiRGF0YVNpemUiLAkJCQkiRGF0YSBwcm9jZXNzZWQiLAkJCQkJImJ5dGVzIiwJUVBfU0FNUExFX1ZBTFVFX1RBR19QUkVESUNUT1IpCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIlVwbG9hZFNpemUiLAkJCSJEYXRhIHVwbG9hZGVkIiwJCQkJCSJieXRlcyIsCVFQX1NBTVBMRV9WQUxVRV9UQUdfUFJFRElDVE9SKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJWZXJ0ZXhDb3VudCIsCQkJIk51bWJlciBvZiB2ZXJ0aWNlcyIsCQkJCSJ2ZXJ0aWNlcyIsCVFQX1NBTVBMRV9WQUxVRV9UQUdfUFJFRElDVE9SKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJVbnJlbGF0ZWRVcGxvYWRTaXplIiwJIlVucmVsYXRlZCB1cGxvYWQgc2l6ZSIsCQkJImJ5dGVzIiwJUVBfU0FNUExFX1ZBTFVFX1RBR19QUkVESUNUT1IpCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIkRyYXdSZWFkVGltZSIsCQkJIkRyYXcgY2FsbCBhbmQgUmVhZFBpeGVscyB0aW1lIiwJInVzIiwJCVFQX1NBTVBMRV9WQUxVRV9UQUdfUkVTUE9OU0UpCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIlRvdGFsVGltZSIsCQkJCSJUb3RhbCB0aW1lIiwJCQkJCQkidXMiLAkJUVBfU0FNUExFX1ZBTFVFX1RBR19SRVNQT05TRSkKCQk8PCB0Y3U6OlRlc3RMb2c6OlZhbHVlSW5mbygiVXBsb2FkIHRpbWUiLAkJCSJVcGxvYWQgdGltZSIsCQkJCQkJInVzIiwJCVFQX1NBTVBMRV9WQUxVRV9UQUdfUkVTUE9OU0UpCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIkRyYXdDYWxsVGltZSIsCQkJIkRyYXcgY2FsbCB0aW1lIiwJCQkJCSJ1cyIsCQlRUF9TQU1QTEVfVkFMVUVfVEFHX1JFU1BPTlNFKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJSZWFkVGltZSIsCQkJCSJSZWFkUGl4ZWxzIHRpbWUiLAkJCQkJInVzIiwJCVFQX1NBTVBMRV9WQUxVRV9UQUdfUkVTUE9OU0UpCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIkZpdFJlc2lkdWFsIiwJCQkiRml0IHJlc2lkdWFsIiwJCQkJCQkidXMiLAkJUVBfU0FNUExFX1ZBTFVFX1RBR19SRVNQT05TRSkKCQk8PCB0Y3U6OlRlc3RMb2c6OkVuZFNhbXBsZUluZm87CgoJZm9yIChpbnQgc2FtcGxlTmR4ID0gMDsgc2FtcGxlTmR4IDwgKGludClzYW1wbGVzLnNpemUoKTsgKytzYW1wbGVOZHgpCgl7CgkJY29uc3QgZmxvYXQgZml0UmVzaWR1YWwgPSAoZmxvYXQpc2FtcGxlc1tzYW1wbGVOZHhdLmR1cmF0aW9uLmZpdFJlc3BvbnNlRHVyYXRpb24gLSAodGhlaWxTZW5GaXR0aW5nLm9mZnNldCArIHRoZWlsU2VuRml0dGluZy5jb2VmZmljaWVudCAqIChmbG9hdClzYW1wbGVzW3NhbXBsZU5keF0ucmVuZGVyRGF0YVNpemUpOwoJCWxvZwk8PCB0Y3U6OlRlc3RMb2c6OlNhbXBsZQoJCQk8PCBzYW1wbGVzW3NhbXBsZU5keF0ucmVuZGVyRGF0YVNpemUKCQkJPDwgc2FtcGxlc1tzYW1wbGVOZHhdLnVwbG9hZGVkRGF0YVNpemUKCQkJPDwgc2FtcGxlc1tzYW1wbGVOZHhdLm51bVZlcnRpY2VzCgkJCTw8IHNhbXBsZXNbc2FtcGxlTmR4XS51bnJlbGF0ZWREYXRhU2l6ZQoJCQk8PCAoaW50KXNhbXBsZXNbc2FtcGxlTmR4XS5kdXJhdGlvbi5yZW5kZXJSZWFkRHVyYXRpb24KCQkJPDwgKGludClzYW1wbGVzW3NhbXBsZU5keF0uZHVyYXRpb24udG90YWxEdXJhdGlvbgoJCQk8PCAoaW50KXNhbXBsZXNbc2FtcGxlTmR4XS5kdXJhdGlvbi51cGxvYWREdXJhdGlvbgoJCQk8PCAoaW50KXNhbXBsZXNbc2FtcGxlTmR4XS5kdXJhdGlvbi5yZW5kZXJEdXJhdGlvbgoJCQk8PCAoaW50KXNhbXBsZXNbc2FtcGxlTmR4XS5kdXJhdGlvbi5yZWFkRHVyYXRpb24KCQkJPDwgZml0UmVzaWR1YWwKCQkJPDwgdGN1OjpUZXN0TG9nOjpFbmRTYW1wbGU7Cgl9CgoJbG9nIDw8IHRjdTo6VGVzdExvZzo6RW5kU2FtcGxlTGlzdDsKfQoKdm9pZCBsb2dTYW1wbGVMaXN0ICh0Y3U6OlRlc3RMb2cmIGxvZywgY29uc3QgTGluZVBhcmFtZXRlcnNXaXRoQ29uZmlkZW5jZSYgdGhlaWxTZW5GaXR0aW5nLCBjb25zdCBzdGQ6OnZlY3RvcjxSZW5kZXJTYW1wbGVSZXN1bHQ8UmVuZGVyVXBsb2FkUmVuZGVyUmVhZER1cmF0aW9uPiA+JiBzYW1wbGVzKQp7Cglsb2cgPDwgdGN1OjpUZXN0TG9nOjpTYW1wbGVMaXN0KCJTYW1wbGVzIiwgIlNhbXBsZXMiKQoJCTw8IHRjdTo6VGVzdExvZzo6U2FtcGxlSW5mbwoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJEYXRhU2l6ZSIsCQkJCSJEYXRhIHByb2Nlc3NlZCIsCQkJCQkJImJ5dGVzIiwJUVBfU0FNUExFX1ZBTFVFX1RBR19QUkVESUNUT1IpCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIlVwbG9hZFNpemUiLAkJCSJEYXRhIHVwbG9hZGVkIiwJCQkJCQkiYnl0ZXMiLAlRUF9TQU1QTEVfVkFMVUVfVEFHX1BSRURJQ1RPUikKCQk8PCB0Y3U6OlRlc3RMb2c6OlZhbHVlSW5mbygiVmVydGV4Q291bnQiLAkJCSJOdW1iZXIgb2YgdmVydGljZXMiLAkJCQkJInZlcnRpY2VzIiwJUVBfU0FNUExFX1ZBTFVFX1RBR19QUkVESUNUT1IpCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIkRyYXdSZWFkVGltZSIsCQkJIlNlY29uZCBkcmF3IGNhbGwgYW5kIFJlYWRQaXhlbHMgdGltZSIsCSJ1cyIsCQlRUF9TQU1QTEVfVkFMVUVfVEFHX1JFU1BPTlNFKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJUb3RhbFRpbWUiLAkJCQkiVG90YWwgdGltZSIsCQkJCQkJCSJ1cyIsCQlRUF9TQU1QTEVfVkFMVUVfVEFHX1JFU1BPTlNFKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJGaXJzdERyYXdDYWxsVGltZSIsCQkiRmlyc3QgZHJhdyBjYWxsIHRpbWUiLAkJCQkJInVzIiwJCVFQX1NBTVBMRV9WQUxVRV9UQUdfUkVTUE9OU0UpCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIlVwbG9hZCB0aW1lIiwJCQkiVXBsb2FkIHRpbWUiLAkJCQkJCQkidXMiLAkJUVBfU0FNUExFX1ZBTFVFX1RBR19SRVNQT05TRSkKCQk8PCB0Y3U6OlRlc3RMb2c6OlZhbHVlSW5mbygiU2Vjb25kRHJhd0NhbGxUaW1lIiwJIlNlY29uZCBkcmF3IGNhbGwgdGltZSIsCQkJCSJ1cyIsCQlRUF9TQU1QTEVfVkFMVUVfVEFHX1JFU1BPTlNFKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJSZWFkVGltZSIsCQkJCSJSZWFkUGl4ZWxzIHRpbWUiLAkJCQkJCSJ1cyIsCQlRUF9TQU1QTEVfVkFMVUVfVEFHX1JFU1BPTlNFKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJGaXRSZXNpZHVhbCIsCQkJIkZpdCByZXNpZHVhbCIsCQkJCQkJCSJ1cyIsCQlRUF9TQU1QTEVfVkFMVUVfVEFHX1JFU1BPTlNFKQoJCTw8IHRjdTo6VGVzdExvZzo6RW5kU2FtcGxlSW5mbzsKCglmb3IgKGludCBzYW1wbGVOZHggPSAwOyBzYW1wbGVOZHggPCAoaW50KXNhbXBsZXMuc2l6ZSgpOyArK3NhbXBsZU5keCkKCXsKCQljb25zdCBmbG9hdCBmaXRSZXNpZHVhbCA9IChmbG9hdClzYW1wbGVzW3NhbXBsZU5keF0uZHVyYXRpb24uZml0UmVzcG9uc2VEdXJhdGlvbiAtICh0aGVpbFNlbkZpdHRpbmcub2Zmc2V0ICsgdGhlaWxTZW5GaXR0aW5nLmNvZWZmaWNpZW50ICogKGZsb2F0KXNhbXBsZXNbc2FtcGxlTmR4XS5yZW5kZXJEYXRhU2l6ZSk7CgkJbG9nCTw8IHRjdTo6VGVzdExvZzo6U2FtcGxlCgkJCTw8IHNhbXBsZXNbc2FtcGxlTmR4XS5yZW5kZXJEYXRhU2l6ZQoJCQk8PCBzYW1wbGVzW3NhbXBsZU5keF0udXBsb2FkZWREYXRhU2l6ZQoJCQk8PCBzYW1wbGVzW3NhbXBsZU5keF0ubnVtVmVydGljZXMKCQkJPDwgKGludClzYW1wbGVzW3NhbXBsZU5keF0uZHVyYXRpb24ucmVuZGVyUmVhZER1cmF0aW9uCgkJCTw8IChpbnQpc2FtcGxlc1tzYW1wbGVOZHhdLmR1cmF0aW9uLnRvdGFsRHVyYXRpb24KCQkJPDwgKGludClzYW1wbGVzW3NhbXBsZU5keF0uZHVyYXRpb24uZmlyc3RSZW5kZXJEdXJhdGlvbgoJCQk8PCAoaW50KXNhbXBsZXNbc2FtcGxlTmR4XS5kdXJhdGlvbi51cGxvYWREdXJhdGlvbgoJCQk8PCAoaW50KXNhbXBsZXNbc2FtcGxlTmR4XS5kdXJhdGlvbi5zZWNvbmRSZW5kZXJEdXJhdGlvbgoJCQk8PCAoaW50KXNhbXBsZXNbc2FtcGxlTmR4XS5kdXJhdGlvbi5yZWFkRHVyYXRpb24KCQkJPDwgZml0UmVzaWR1YWwKCQkJPDwgdGN1OjpUZXN0TG9nOjpFbmRTYW1wbGU7Cgl9CgoJbG9nIDw8IHRjdTo6VGVzdExvZzo6RW5kU2FtcGxlTGlzdDsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFNhbXBsZVR5cGU+CnN0YXRpYyBVcGxvYWRTYW1wbGVBbmFseXplUmVzdWx0IGFuYWx5emVTYW1wbGVSZXN1bHRzICh0Y3U6OlRlc3RMb2cmIGxvZywgY29uc3Qgc3RkOjp2ZWN0b3I8VXBsb2FkU2FtcGxlUmVzdWx0PFNhbXBsZVR5cGU+ID4mIHNhbXBsZXMsIGJvb2wgbG9nQnVja2V0UGVyZm9ybWFuY2UpCnsKCS8vIEFzc3VtZSBkYXRhIGlzIGxpbmVhciB3aXRoIHNvbWUgb3V0bGllcnMsIGZpdCBhIGxpbmUKCWNvbnN0IExpbmVQYXJhbWV0ZXJzV2l0aENvbmZpZGVuY2UJCQkJCQl0aGVpbFNlbkZpdHRpbmcJCQkJCQk9IGZpdExpbmVUb1NhbXBsZXMoc2FtcGxlcyk7Cgljb25zdCB0eXBlbmFtZSBTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpTdGF0c1R5cGUJcmVzdWx0U3RhdHMJCQkJCQkJPSBjYWxjdWxhdGVTYW1wbGVTdGF0aXN0aWNzKHRoZWlsU2VuRml0dGluZywgc2FtcGxlcyk7CglmbG9hdAkJCQkJCQkJCQkJCQlhcHByb3hpbWF0ZWRUcmFuc2ZlclJhdGU7CglmbG9hdAkJCQkJCQkJCQkJCQlhcHByb3hpbWF0ZWRUcmFuc2ZlclJhdGVOb0NvbnN0YW50OwoKCS8vIE91dHB1dCByYXcgc2FtcGxlcwoJewoJCWNvbnN0IHRjdTo6U2NvcGVkTG9nU2VjdGlvbglzZWN0aW9uKGxvZywgIlNhbXBsZXMiLCAiU2FtcGxlcyIpOwoJCWxvZ1NhbXBsZUxpc3QobG9nLCB0aGVpbFNlbkZpdHRpbmcsIHNhbXBsZXMpOwoJfQoKCS8vIENhbGN1bGF0ZSByZXN1bHRzIGZvciBkaWZmZXJlbnQgcmFuZ2VzCglpZiAobG9nQnVja2V0UGVyZm9ybWFuY2UpCgl7CgkJY29uc3QgaW50CQkJCQkJCQkJCW51bUJ1Y2tldHMJCQkJPSA0OwoJCWludAkJCQkJCQkJCQkJCW1pbkJ1ZmZlclNpemUJCQk9IDA7CgkJaW50CQkJCQkJCQkJCQkJbWF4QnVmZmVyU2l6ZQkJCT0gMDsKCQlzdGQ6OnZlY3RvcjxVcGxvYWRTYW1wbGVSZXN1bHQ8U2FtcGxlVHlwZT4gPglidWNrZXRzW251bUJ1Y2tldHNdOwoKCQlidWNrZXRpemVTYW1wbGVzVW5pZm9ybWx5KHNhbXBsZXMsICZidWNrZXRzWzBdLCBudW1CdWNrZXRzLCBtaW5CdWZmZXJTaXplLCBtYXhCdWZmZXJTaXplKTsKCgkJZm9yIChpbnQgYnVja2V0TmR4ID0gMDsgYnVja2V0TmR4IDwgbnVtQnVja2V0czsgKytidWNrZXROZHgpCgkJewoJCQlpZiAoYnVja2V0c1tidWNrZXROZHhdLmVtcHR5KCkpCgkJCQljb250aW51ZTsKCgkJCS8vIFByaW50IGEgbmljZSByZXN1bHQgc3VtbWFyeQoKCQkJY29uc3QgaW50CQkJCQkJCQkJCQkJYnVja2V0UmFuZ2VNaW4JPSBtaW5CdWZmZXJTaXplICsgKGludCkoKChmbG9hdCkgYnVja2V0TmR4ICAgIC8gKGZsb2F0KW51bUJ1Y2tldHMpICogKGZsb2F0KShtYXhCdWZmZXJTaXplIC0gbWluQnVmZmVyU2l6ZSkpOwoJCQljb25zdCBpbnQJCQkJCQkJCQkJCQlidWNrZXRSYW5nZU1heAk9IG1pbkJ1ZmZlclNpemUgKyAoaW50KSgoKGZsb2F0KShidWNrZXROZHgrMSkgLyAoZmxvYXQpbnVtQnVja2V0cykgKiAoZmxvYXQpKG1heEJ1ZmZlclNpemUgLSBtaW5CdWZmZXJTaXplKSk7CgkJCWNvbnN0IHR5cGVuYW1lIFNhbXBsZVR5cGVUcmFpdHM8U2FtcGxlVHlwZT46OlN0YXRzVHlwZQlzdGF0cwkJCT0gY2FsY3VsYXRlU2FtcGxlU3RhdGlzdGljcyh0aGVpbFNlbkZpdHRpbmcsIGJ1Y2tldHNbYnVja2V0TmR4XSk7CgkJCWNvbnN0IHRjdTo6U2NvcGVkTG9nU2VjdGlvbgkJCQkJCQkJc2VjdGlvbgkJCShsb2csICJCdWZmZXJTaXplUmFuZ2UiLCBzdGQ6OnN0cmluZygiVHJhbnNmZXIgcGVyZm9ybWFuY2Ugd2l0aCBidWZmZXIgc2l6ZSBpbiByYW5nZSBbIikuYXBwZW5kKGdldEh1bWFuUmVhZGFibGVCeXRlU2l6ZShidWNrZXRSYW5nZU1pbikuYXBwZW5kKCIsICIpLmFwcGVuZChnZXRIdW1hblJlYWRhYmxlQnl0ZVNpemUoYnVja2V0UmFuZ2VNYXgpLmFwcGVuZCgiXSIpKSkpOwoKCQkJbG9nTWFwUmFuZ2VTdGF0czxTYW1wbGVUeXBlPihsb2csIHN0YXRzKTsKCQkJbG9nVW5tYXBTdGF0czxTYW1wbGVUeXBlPihsb2csIHN0YXRzKTsKCQkJbG9nV3JpdGVTdGF0czxTYW1wbGVUeXBlPihsb2csIHN0YXRzKTsKCQkJbG9nRmx1c2hTdGF0czxTYW1wbGVUeXBlPihsb2csIHN0YXRzKTsKCQkJbG9nQWxsb2NTdGF0czxTYW1wbGVUeXBlPihsb2csIHN0YXRzKTsKCgkJCWxvZwk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJNaW4iLCAiVG90YWw6IE1pbiB0aW1lIiwgInVzIiwgUVBfS0VZX1RBR19USU1FLCBzdGF0cy5yZXN1bHQubWluVGltZSkKCQkJCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIk1heCIsICJUb3RhbDogTWF4IHRpbWUiLCAidXMiLCBRUF9LRVlfVEFHX1RJTUUsIHN0YXRzLnJlc3VsdC5tYXhUaW1lKQoJCQkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiTWluOTAiLCAiVG90YWw6IDkwJS1NaW4gdGltZSIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgc3RhdHMucmVzdWx0Lm1pbjJEZWNpbGVUaW1lKQoJCQkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiTWF4OTAiLCAiVG90YWw6IDkwJS1NYXggdGltZSIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgc3RhdHMucmVzdWx0Lm1heDlEZWNpbGVUaW1lKQoJCQkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiTWVkaWFuIiwgIlRvdGFsOiBNZWRpYW4gdGltZSIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgc3RhdHMucmVzdWx0Lm1lZGlhblRpbWUpCgkJCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJNZWRpYW5UcmFuc2ZlciIsICJNZWRpYW4gdHJhbnNmZXIgcmF0ZSIsICJNQiAvIHMiLCBRUF9LRVlfVEFHX1BFUkZPUk1BTkNFLCBzdGF0cy5tZWRpYW5SYXRlIC8gMTAyNC4wZiAvIDEwMjQuMGYpCgkJCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJNYXhEaWZmIiwgIk1heCBkaWZmZXJlbmNlIHRvIGFwcHJveGltYXRlZCIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgc3RhdHMubWF4RGlmZlRpbWUpCgkJCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJNYXg5MERpZmYiLCAiOTAlLU1heCBkaWZmZXJlbmNlIHRvIGFwcHJveGltYXRlZCIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgc3RhdHMubWF4RGlmZjlEZWNpbGVUaW1lKQoJCQkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiTWVkaWFuRGlmZiIsICJNZWRpYW4gZGlmZmVyZW5jZSB0byBhcHByb3hpbWF0ZWQiLCAidXMiLCBRUF9LRVlfVEFHX1RJTUUsIHN0YXRzLm1lZGlhbkRpZmZUaW1lKQoJCQkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiTWF4UmVsRGlmZiIsICJNYXggcmVsYXRpdmUgZGlmZmVyZW5jZSB0byBhcHByb3hpbWF0ZWQiLCAiJSIsIFFQX0tFWV9UQUdfTk9ORSwgc3RhdHMubWF4UmVsRGlmZlRpbWUgKiAxMDAuMGYpCgkJCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJNYXg5MFJlbERpZmYiLCAiOTAlLU1heCByZWxhdGl2ZSBkaWZmZXJlbmNlIHRvIGFwcHJveGltYXRlZCIsICIlIiwgUVBfS0VZX1RBR19OT05FLCBzdGF0cy5tYXg5RGVjaWxlUmVsRGlmZlRpbWUgKiAxMDAuMGYpCgkJCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJNZWRpYW5SZWxEaWZmIiwgIk1lZGlhbiByZWxhdGl2ZSBkaWZmZXJlbmNlIHRvIGFwcHJveGltYXRlZCIsICIlIiwgUVBfS0VZX1RBR19OT05FLCBzdGF0cy5tZWRpYW5SZWxEaWZmVGltZSAqIDEwMC4wZik7CgkJfQoJfQoKCS8vIENvbnRyaWJ1dGlvbnMKCWlmIChTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpMT0dfQ09OVFJJQlVUSU9OUykKCXsKCQljb25zdCB0Y3U6OlNjb3BlZExvZ1NlY3Rpb24Jc2VjdGlvbihsb2csICJDb250cmlidXRpb24iLCAiQ29udHJpYnV0aW9ucyIpOwoKCQlsb2dNYXBDb250cmlidXRpb24obG9nLCBzYW1wbGVzLCByZXN1bHRTdGF0cyk7CgkJbG9nVW5tYXBDb250cmlidXRpb24obG9nLCBzYW1wbGVzLCByZXN1bHRTdGF0cyk7CgkJbG9nV3JpdGVDb250cmlidXRpb24obG9nLCBzYW1wbGVzLCByZXN1bHRTdGF0cyk7CgkJbG9nRmx1c2hDb250cmlidXRpb24obG9nLCBzYW1wbGVzLCByZXN1bHRTdGF0cyk7CgkJbG9nQWxsb2NDb250cmlidXRpb24obG9nLCBzYW1wbGVzLCByZXN1bHRTdGF0cyk7Cgl9CgoJLy8gUHJpbnQgcmVzdWx0cwoJewoJCWNvbnN0IHRjdTo6U2NvcGVkTG9nU2VjdGlvbglzZWN0aW9uKGxvZywgIlJlc3VsdHMiLCAiUmVzdWx0cyIpOwoKCQljb25zdCBpbnQJbWVkaWFuQnVmZmVyU2l6ZQkJCQkJPSAoc2FtcGxlcy5mcm9udCgpLmJ1ZmZlclNpemUgKyBzYW1wbGVzLmJhY2soKS5idWZmZXJTaXplKSAvIDI7CgkJY29uc3QgZmxvYXQJYXBwcm94aW1hdGVkVHJhbnNmZXJUaW1lCQkJPSAodGhlaWxTZW5GaXR0aW5nLm9mZnNldCArIHRoZWlsU2VuRml0dGluZy5jb2VmZmljaWVudCAqIChmbG9hdCltZWRpYW5CdWZmZXJTaXplKSAvIDEwMDAuMGYgLyAxMDAwLjBmOwoJCWNvbnN0IGZsb2F0CWFwcHJveGltYXRlZFRyYW5zZmVyVGltZU5vQ29uc3RhbnQJPSAodGhlaWxTZW5GaXR0aW5nLmNvZWZmaWNpZW50ICogKGZsb2F0KW1lZGlhbkJ1ZmZlclNpemUpIC8gMTAwMC4wZiAvIDEwMDAuMGY7CgkJY29uc3QgZmxvYXQJc2FtcGxlTGluZWFyaXR5CQkJCQkJPSBjYWxjdWxhdGVTYW1wbGVGaXRMaW5lYXJpdHkoc2FtcGxlcyk7CgkJY29uc3QgZmxvYXQJc2FtcGxlVGVtcG9yYWxTdGFiaWxpdHkJCQkJPSBjYWxjdWxhdGVTYW1wbGVUZW1wb3JhbFN0YWJpbGl0eShzYW1wbGVzKTsKCgkJYXBwcm94aW1hdGVkVHJhbnNmZXJSYXRlTm9Db25zdGFudAkJCQk9IChmbG9hdCltZWRpYW5CdWZmZXJTaXplIC8gYXBwcm94aW1hdGVkVHJhbnNmZXJUaW1lTm9Db25zdGFudDsKCQlhcHByb3hpbWF0ZWRUcmFuc2ZlclJhdGUJCQkJCQk9IChmbG9hdCltZWRpYW5CdWZmZXJTaXplIC8gYXBwcm94aW1hdGVkVHJhbnNmZXJUaW1lOwoKCQlsb2cJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiUmVzdWx0TGluZWFyaXR5IiwgIlNhbXBsZSBsaW5lYXJpdHkiLCAiJSIsIFFQX0tFWV9UQUdfUVVBTElUWSwgc2FtcGxlTGluZWFyaXR5ICogMTAwLjBmKQoJCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJTYW1wbGVUZW1wb3JhbFN0YWJpbGl0eSIsICJTYW1wbGUgdGVtcG9yYWwgc3RhYmlsaXR5IiwgIiUiLCBRUF9LRVlfVEFHX1FVQUxJVFksIHNhbXBsZVRlbXBvcmFsU3RhYmlsaXR5ICogMTAwLjBmKQoJCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJBcHByb3hpbWF0ZWRDb25zdGFudENvc3QiLCAiQXBwcm94aW1hdGVkIGNvbnRhbnQgY29zdCIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgdGhlaWxTZW5GaXR0aW5nLm9mZnNldCkKCQkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiQXBwcm94aW1hdGVkQ29uc3RhbnRDb3N0Q29uZmlkZW5jZTYwTG93ZXIiLCAiQXBwcm94aW1hdGVkIGNvbnRhbnQgY29zdCA2MCUgY29uZmlkZW5jZSBsb3dlciBsaW1pdCIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgdGhlaWxTZW5GaXR0aW5nLm9mZnNldENvbmZpZGVuY2VMb3dlcikKCQkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiQXBwcm94aW1hdGVkQ29uc3RhbnRDb3N0Q29uZmlkZW5jZTYwVXBwZXIiLCAiQXBwcm94aW1hdGVkIGNvbnRhbnQgY29zdCA2MCUgY29uZmlkZW5jZSB1cHBlciBsaW1pdCIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgdGhlaWxTZW5GaXR0aW5nLm9mZnNldENvbmZpZGVuY2VVcHBlcikKCQkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiQXBwcm94aW1hdGVkTGluZWFyQ29zdCIsICJBcHByb3hpbWF0ZWQgbGluZWFyIGNvc3QiLCAidXMgLyBNQiIsIFFQX0tFWV9UQUdfVElNRSwgdGhlaWxTZW5GaXR0aW5nLmNvZWZmaWNpZW50ICogMTAyNC4wZiAqIDEwMjQuMGYpCgkJCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIkFwcHJveGltYXRlZExpbmVhckNvc3RDb25maWRlbmNlNjBMb3dlciIsICJBcHByb3hpbWF0ZWQgbGluZWFyIGNvc3QgNjAlIGNvbmZpZGVuY2UgbG93ZXIgbGltaXQiLCAidXMgLyBNQiIsIFFQX0tFWV9UQUdfVElNRSwgdGhlaWxTZW5GaXR0aW5nLmNvZWZmaWNpZW50Q29uZmlkZW5jZUxvd2VyICogMTAyNC4wZiAqIDEwMjQuMGYpCgkJCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIkFwcHJveGltYXRlZExpbmVhckNvc3RDb25maWRlbmNlNjBVcHBlciIsICJBcHByb3hpbWF0ZWQgbGluZWFyIGNvc3QgNjAlIGNvbmZpZGVuY2UgdXBwZXIgbGltaXQiLCAidXMgLyBNQiIsIFFQX0tFWV9UQUdfVElNRSwgdGhlaWxTZW5GaXR0aW5nLmNvZWZmaWNpZW50Q29uZmlkZW5jZVVwcGVyICogMTAyNC4wZiAqIDEwMjQuMGYpCgkJCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIkFwcHJveGltYXRlZFRyYW5zZmVyUmF0ZSIsICJBcHByb3hpbWF0ZWQgdHJhbnNmZXIgcmF0ZSIsICJNQiAvIHMiLCBRUF9LRVlfVEFHX1BFUkZPUk1BTkNFLCBhcHByb3hpbWF0ZWRUcmFuc2ZlclJhdGUgLyAxMDI0LjBmIC8gMTAyNC4wZikKCQkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiQXBwcm94aW1hdGVkVHJhbnNmZXJSYXRlTm9Db25zdGFudCIsICJBcHByb3hpbWF0ZWQgdHJhbnNmZXIgcmF0ZSB3aXRob3V0IGNvbnN0YW50IGNvc3QiLCAiTUIgLyBzIiwgUVBfS0VZX1RBR19QRVJGT1JNQU5DRSwgYXBwcm94aW1hdGVkVHJhbnNmZXJSYXRlTm9Db25zdGFudCAvIDEwMjQuMGYgLyAxMDI0LjBmKQoJCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJTYW1wbGVNZWRpYW5UaW1lIiwgIk1lZGlhbiBzYW1wbGUgdGltZSIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgcmVzdWx0U3RhdHMucmVzdWx0Lm1lZGlhblRpbWUpCgkJCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIlNhbXBsZU1lZGlhblRyYW5zZmVyIiwgIk1lZGlhbiB0cmFuc2ZlciByYXRlIiwgIk1CIC8gcyIsIFFQX0tFWV9UQUdfUEVSRk9STUFOQ0UsIHJlc3VsdFN0YXRzLm1lZGlhblJhdGUgLyAxMDI0LjBmIC8gMTAyNC4wZik7Cgl9CgoJLy8gcmV0dXJuIGFwcHJveGltYXRlZCB0cmFuc2ZlciByYXRlCgl7CgkJVXBsb2FkU2FtcGxlQW5hbHl6ZVJlc3VsdCByZXN1bHQ7CgoJCXJlc3VsdC50cmFuc2ZlclJhdGVNZWRpYW4gPSByZXN1bHRTdGF0cy5tZWRpYW5SYXRlOwoJCXJlc3VsdC50cmFuc2ZlclJhdGVBdFJhbmdlID0gYXBwcm94aW1hdGVkVHJhbnNmZXJSYXRlOwoJCXJlc3VsdC50cmFuc2ZlclJhdGVBdEluZmluaXR5ID0gYXBwcm94aW1hdGVkVHJhbnNmZXJSYXRlTm9Db25zdGFudDsKCgkJcmV0dXJuIHJlc3VsdDsKCX0KfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFNhbXBsZVR5cGU+CnN0YXRpYyBSZW5kZXJTYW1wbGVBbmFseXplUmVzdWx0IGFuYWx5emVTYW1wbGVSZXN1bHRzICh0Y3U6OlRlc3RMb2cmIGxvZywgY29uc3Qgc3RkOjp2ZWN0b3I8UmVuZGVyU2FtcGxlUmVzdWx0PFNhbXBsZVR5cGU+ID4mIHNhbXBsZXMpCnsKCS8vIEFzc3VtZSBkYXRhIGlzIGxpbmVhciB3aXRoIHNvbWUgb3V0bGllcnMsIGZpdCBhIGxpbmUKCWNvbnN0IExpbmVQYXJhbWV0ZXJzV2l0aENvbmZpZGVuY2UJCQkJCQl0aGVpbFNlbkZpdHRpbmcJCQkJCQk9IGZpdExpbmVUb1NhbXBsZXMoc2FtcGxlcyk7Cgljb25zdCB0eXBlbmFtZSBTYW1wbGVUeXBlVHJhaXRzPFNhbXBsZVR5cGU+OjpTdGF0c1R5cGUJcmVzdWx0U3RhdHMJCQkJCQkJPSBjYWxjdWxhdGVTYW1wbGVTdGF0aXN0aWNzKHRoZWlsU2VuRml0dGluZywgc2FtcGxlcyk7CglmbG9hdAkJCQkJCQkJCQkJCQlhcHByb3hpbWF0ZWRQcm9jZXNzaW5nUmF0ZTsKCWZsb2F0CQkJCQkJCQkJCQkJCWFwcHJveGltYXRlZFByb2Nlc3NpbmdSYXRlTm9Db25zdGFudDsKCgkvLyBvdXRwdXQgcmF3IHNhbXBsZXMKCXsKCQljb25zdCB0Y3U6OlNjb3BlZExvZ1NlY3Rpb24Jc2VjdGlvbihsb2csICJTYW1wbGVzIiwgIlNhbXBsZXMiKTsKCQlsb2dTYW1wbGVMaXN0KGxvZywgdGhlaWxTZW5GaXR0aW5nLCBzYW1wbGVzKTsKCX0KCgkvLyBDb250cmlidXRpb25zCglpZiAoU2FtcGxlVHlwZVRyYWl0czxTYW1wbGVUeXBlPjo6TE9HX0NPTlRSSUJVVElPTlMpCgl7CgkJY29uc3QgdGN1OjpTY29wZWRMb2dTZWN0aW9uCXNlY3Rpb24obG9nLCAiQ29udHJpYnV0aW9uIiwgIkNvbnRyaWJ1dGlvbnMiKTsKCgkJbG9nRmlyc3RSZW5kZXJDb250cmlidXRpb24obG9nLCBzYW1wbGVzLCByZXN1bHRTdGF0cyk7CgkJbG9nVXBsb2FkQ29udHJpYnV0aW9uKGxvZywgc2FtcGxlcywgcmVzdWx0U3RhdHMpOwoJCWxvZ1JlbmRlckNvbnRyaWJ1dGlvbihsb2csIHNhbXBsZXMsIHJlc3VsdFN0YXRzKTsKCQlsb2dTZWNvbmRSZW5kZXJDb250cmlidXRpb24obG9nLCBzYW1wbGVzLCByZXN1bHRTdGF0cyk7CgkJbG9nUmVhZENvbnRyaWJ1dGlvbihsb2csIHNhbXBsZXMsIHJlc3VsdFN0YXRzKTsKCQlsb2dUb3RhbENvbnRyaWJ1dGlvbihsb2csIHNhbXBsZXMsIHJlc3VsdFN0YXRzKTsKCX0KCgkvLyBwcmludCByZXN1bHRzCgl7CgkJY29uc3QgdGN1OjpTY29wZWRMb2dTZWN0aW9uCXNlY3Rpb24obG9nLCAiUmVzdWx0cyIsICJSZXN1bHRzIik7CgoJCWNvbnN0IGludAltZWRpYW5EYXRhU2l6ZQkJCQkJCT0gKHNhbXBsZXMuZnJvbnQoKS5yZW5kZXJEYXRhU2l6ZSArIHNhbXBsZXMuYmFjaygpLnJlbmRlckRhdGFTaXplKSAvIDI7CgkJY29uc3QgZmxvYXQJYXBwcm94aW1hdGVkUmVuZGVyVGltZQkJCQk9ICh0aGVpbFNlbkZpdHRpbmcub2Zmc2V0ICsgdGhlaWxTZW5GaXR0aW5nLmNvZWZmaWNpZW50ICogKGZsb2F0KW1lZGlhbkRhdGFTaXplKSAvIDEwMDAuMGYgLyAxMDAwLjBmOwoJCWNvbnN0IGZsb2F0CWFwcHJveGltYXRlZFJlbmRlclRpbWVOb0NvbnN0YW50CT0gKHRoZWlsU2VuRml0dGluZy5jb2VmZmljaWVudCAqIChmbG9hdCltZWRpYW5EYXRhU2l6ZSkgLyAxMDAwLjBmIC8gMTAwMC4wZjsKCQljb25zdCBmbG9hdAlzYW1wbGVMaW5lYXJpdHkJCQkJCQk9IGNhbGN1bGF0ZVNhbXBsZUZpdExpbmVhcml0eShzYW1wbGVzKTsKCQljb25zdCBmbG9hdAlzYW1wbGVUZW1wb3JhbFN0YWJpbGl0eQkJCQk9IGNhbGN1bGF0ZVNhbXBsZVRlbXBvcmFsU3RhYmlsaXR5KHNhbXBsZXMpOwoKCQlhcHByb3hpbWF0ZWRQcm9jZXNzaW5nUmF0ZU5vQ29uc3RhbnQJCQk9IChmbG9hdCltZWRpYW5EYXRhU2l6ZSAvIGFwcHJveGltYXRlZFJlbmRlclRpbWVOb0NvbnN0YW50OwoJCWFwcHJveGltYXRlZFByb2Nlc3NpbmdSYXRlCQkJCQkJPSAoZmxvYXQpbWVkaWFuRGF0YVNpemUgLyBhcHByb3hpbWF0ZWRSZW5kZXJUaW1lOwoKCQlsb2cJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiUmVzdWx0TGluZWFyaXR5IiwgIlNhbXBsZSBsaW5lYXJpdHkiLCAiJSIsIFFQX0tFWV9UQUdfUVVBTElUWSwgc2FtcGxlTGluZWFyaXR5ICogMTAwLjBmKQoJCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJTYW1wbGVUZW1wb3JhbFN0YWJpbGl0eSIsICJTYW1wbGUgdGVtcG9yYWwgc3RhYmlsaXR5IiwgIiUiLCBRUF9LRVlfVEFHX1FVQUxJVFksIHNhbXBsZVRlbXBvcmFsU3RhYmlsaXR5ICogMTAwLjBmKQoJCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJBcHByb3hpbWF0ZWRDb25zdGFudENvc3QiLCAiQXBwcm94aW1hdGVkIGNvbnRhbnQgY29zdCIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgdGhlaWxTZW5GaXR0aW5nLm9mZnNldCkKCQkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiQXBwcm94aW1hdGVkQ29uc3RhbnRDb3N0Q29uZmlkZW5jZTYwTG93ZXIiLCAiQXBwcm94aW1hdGVkIGNvbnRhbnQgY29zdCA2MCUgY29uZmlkZW5jZSBsb3dlciBsaW1pdCIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgdGhlaWxTZW5GaXR0aW5nLm9mZnNldENvbmZpZGVuY2VMb3dlcikKCQkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiQXBwcm94aW1hdGVkQ29uc3RhbnRDb3N0Q29uZmlkZW5jZTYwVXBwZXIiLCAiQXBwcm94aW1hdGVkIGNvbnRhbnQgY29zdCA2MCUgY29uZmlkZW5jZSB1cHBlciBsaW1pdCIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgdGhlaWxTZW5GaXR0aW5nLm9mZnNldENvbmZpZGVuY2VVcHBlcikKCQkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiQXBwcm94aW1hdGVkTGluZWFyQ29zdCIsICJBcHByb3hpbWF0ZWQgbGluZWFyIGNvc3QiLCAidXMgLyBNQiIsIFFQX0tFWV9UQUdfVElNRSwgdGhlaWxTZW5GaXR0aW5nLmNvZWZmaWNpZW50ICogMTAyNC4wZiAqIDEwMjQuMGYpCgkJCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIkFwcHJveGltYXRlZExpbmVhckNvc3RDb25maWRlbmNlNjBMb3dlciIsICJBcHByb3hpbWF0ZWQgbGluZWFyIGNvc3QgNjAlIGNvbmZpZGVuY2UgbG93ZXIgbGltaXQiLCAidXMgLyBNQiIsIFFQX0tFWV9UQUdfVElNRSwgdGhlaWxTZW5GaXR0aW5nLmNvZWZmaWNpZW50Q29uZmlkZW5jZUxvd2VyICogMTAyNC4wZiAqIDEwMjQuMGYpCgkJCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIkFwcHJveGltYXRlZExpbmVhckNvc3RDb25maWRlbmNlNjBVcHBlciIsICJBcHByb3hpbWF0ZWQgbGluZWFyIGNvc3QgNjAlIGNvbmZpZGVuY2UgdXBwZXIgbGltaXQiLCAidXMgLyBNQiIsIFFQX0tFWV9UQUdfVElNRSwgdGhlaWxTZW5GaXR0aW5nLmNvZWZmaWNpZW50Q29uZmlkZW5jZVVwcGVyICogMTAyNC4wZiAqIDEwMjQuMGYpCgkJCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIkFwcHJveGltYXRlZFByb2Nlc3NSYXRlIiwgIkFwcHJveGltYXRlZCBwcm9jZXNzaW5nIHJhdGUiLCAiTUIgLyBzIiwgUVBfS0VZX1RBR19QRVJGT1JNQU5DRSwgYXBwcm94aW1hdGVkUHJvY2Vzc2luZ1JhdGUgLyAxMDI0LjBmIC8gMTAyNC4wZikKCQkJPDwgdGN1OjpUZXN0TG9nOjpGbG9hdCgiQXBwcm94aW1hdGVkUHJvY2Vzc1JhdGVOb0NvbnN0YW50IiwgIkFwcHJveGltYXRlZCBwcm9jZXNzaW5nIHJhdGUgd2l0aG91dCBjb25zdGFudCBjb3N0IiwgIk1CIC8gcyIsIFFQX0tFWV9UQUdfUEVSRk9STUFOQ0UsIGFwcHJveGltYXRlZFByb2Nlc3NpbmdSYXRlTm9Db25zdGFudCAvIDEwMjQuMGYgLyAxMDI0LjBmKQoJCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJTYW1wbGVNZWRpYW5UaW1lIiwgIk1lZGlhbiBzYW1wbGUgdGltZSIsICJ1cyIsIFFQX0tFWV9UQUdfVElNRSwgcmVzdWx0U3RhdHMucmVzdWx0Lm1lZGlhblRpbWUpCgkJCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIlNhbXBsZU1lZGlhblByb2Nlc3MiLCAiTWVkaWFuIHByb2Nlc3NpbmcgcmF0ZSIsICJNQiAvIHMiLCBRUF9LRVlfVEFHX1BFUkZPUk1BTkNFLCByZXN1bHRTdGF0cy5tZWRpYW5SYXRlIC8gMTAyNC4wZiAvIDEwMjQuMGYpOwoJfQoKCS8vIHJldHVybiBhcHByb3hpbWF0ZWQgcmVuZGVyIHJhdGUKCXsKCQlSZW5kZXJTYW1wbGVBbmFseXplUmVzdWx0IHJlc3VsdDsKCgkJcmVzdWx0LnJlbmRlclJhdGVNZWRpYW4JCT0gcmVzdWx0U3RhdHMubWVkaWFuUmF0ZTsKCQlyZXN1bHQucmVuZGVyUmF0ZUF0UmFuZ2UJPSBhcHByb3hpbWF0ZWRQcm9jZXNzaW5nUmF0ZTsKCQlyZXN1bHQucmVuZGVyUmF0ZUF0SW5maW5pdHkgPSBhcHByb3hpbWF0ZWRQcm9jZXNzaW5nUmF0ZU5vQ29uc3RhbnQ7CgoJCXJldHVybiByZXN1bHQ7Cgl9CglyZXR1cm4gUmVuZGVyU2FtcGxlQW5hbHl6ZVJlc3VsdCgpOwp9CgpzdGF0aWMgdm9pZCBnZW5lcmF0ZVR3b1Bhc3NSYW5kb21JdGVyYXRpb25PcmRlciAoc3RkOjp2ZWN0b3I8aW50PiYgaXRlcmF0aW9uT3JkZXIsIGludCBudW1TYW1wbGVzKQp7CglkZTo6UmFuZG9tCXJuZAkJCSgweGFiYyk7Cgljb25zdCBpbnQJbWlkUG9pbnQJPSAobnVtU2FtcGxlcysxKSAvIDI7CQkvLyAhPCBjZWlsKG1fbnVtU2FtcGxlcyAvIDIpCgoJREVfQVNTRVJUKChpbnQpaXRlcmF0aW9uT3JkZXIuc2l6ZSgpID09IG51bVNhbXBsZXMpOwoKCS8vIFR3byAicGFzc2VzIiBvdmVyIHJhbmdlLCByYW5kb21pemUgb3JkZXIgaW4gYm90aCBwYXNzZXMKCS8vIFRoaXMgYWxsb3dzIHRvIHVzIGRldGVjdCBpZiBpdGVyYXRpb25zIGFyZSBub3QgaW5kZXBlbmRlbnQKCS8vIChmaXJzdCBydW4gYW5kIGxhdGVyIHJ1biBzYW1wbGVzIGRpZmZlciBzaWduaWZpY2FudGx5PykKCglmb3IgKGludCBzYW1wbGVOZHggPSAwOyBzYW1wbGVOZHggPCBtaWRQb2ludDsgKytzYW1wbGVOZHgpCgkJaXRlcmF0aW9uT3JkZXJbc2FtcGxlTmR4XSA9IHNhbXBsZU5keCAqIDI7Cglmb3IgKGludCBzYW1wbGVOZHggPSBtaWRQb2ludDsgc2FtcGxlTmR4IDwgbnVtU2FtcGxlczsgKytzYW1wbGVOZHgpCgkJaXRlcmF0aW9uT3JkZXJbc2FtcGxlTmR4XSA9IChzYW1wbGVOZHggLSBtaWRQb2ludCkgKiAyICsgMTsKCglmb3IgKGludCBuZHggPSAwOyBuZHggPCBtaWRQb2ludDsgKytuZHgpCgkJc3RkOjpzd2FwKGl0ZXJhdGlvbk9yZGVyW25keF0sIGl0ZXJhdGlvbk9yZGVyW3JuZC5nZXRJbnQoMCwgbWlkUG9pbnQgLSAxKV0pOwoJZm9yIChpbnQgbmR4ID0gbWlkUG9pbnQ7IG5keCA8IChpbnQpaXRlcmF0aW9uT3JkZXIuc2l6ZSgpOyArK25keCkKCQlzdGQ6OnN3YXAoaXRlcmF0aW9uT3JkZXJbbmR4XSwgaXRlcmF0aW9uT3JkZXJbcm5kLmdldEludChtaWRQb2ludCwgKGludClpdGVyYXRpb25PcmRlci5zaXplKCktMSldKTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFNhbXBsZVR5cGU+CmNsYXNzIEJhc2ljQnVmZmVyQ2FzZSA6IHB1YmxpYyBUZXN0Q2FzZQp7CnB1YmxpYzoKCgllbnVtIEZsYWdzCgl7CgkJRkxBR19BTExPQ0FURV9MQVJHRVJfQlVGRkVSID0gMHgwMSwKCX07CgkJCQkJCQlCYXNpY0J1ZmZlckNhc2UJCShDb250ZXh0JiBjb250ZXh0LCBjb25zdCBjaGFyKiBuYW1lLCBjb25zdCBjaGFyKiBkZXNjLCBpbnQgYnVmZmVyU2l6ZU1pbiwgaW50IGJ1ZmZlclNpemVNYXgsIGludCBudW1TYW1wbGVzLCBpbnQgZmxhZ3MpOwoJCQkJCQkJfkJhc2ljQnVmZmVyQ2FzZQkodm9pZCk7CgoJdmlydHVhbCB2b2lkCQkJaW5pdAkJCQkodm9pZCk7Cgl2aXJ0dWFsIHZvaWQJCQlkZWluaXQJCQkJKHZvaWQpOwoKcHJvdGVjdGVkOgoJSXRlcmF0ZVJlc3VsdAkJCWl0ZXJhdGUJCQkJKHZvaWQpOwoKCXZpcnR1YWwgYm9vbAkJCXJ1blNhbXBsZQkJCShpbnQgaXRlcmF0aW9uLCBVcGxvYWRTYW1wbGVSZXN1bHQ8U2FtcGxlVHlwZT4mIHNhbXBsZSkgPSAwOwoJdmlydHVhbCB2b2lkCQkJbG9nQW5kU2V0VGVzdFJlc3VsdAkoY29uc3Qgc3RkOjp2ZWN0b3I8VXBsb2FkU2FtcGxlUmVzdWx0PFNhbXBsZVR5cGU+ID4mIHJlc3VsdHMpID0gMDsKCgl2b2lkCQkJCQlkaXNhYmxlR0xXYXJtdXAJCSh2b2lkKTsKCXZvaWQJCQkJCXdhaXRHTFJlc3VsdHMJCSh2b2lkKTsKCgllbnVtCgl7CgkJRFVNTVlfUkVOREVSX0FSRUFfU0laRSA9IDMyCgl9OwoKCWdsdTo6U2hhZGVyUHJvZ3JhbSoJCW1fZHVtbXlQcm9ncmFtOwoJZGVJbnQzMgkJCQkJbV9kdW1teVByb2dyYW1Qb3NMb2M7CglkZVVpbnQzMgkJCQltX2J1ZmZlcklEOwoKCWNvbnN0IGludAkJCQltX251bVNhbXBsZXM7Cgljb25zdCBpbnQJCQkJbV9idWZmZXJTaXplTWluOwoJY29uc3QgaW50CQkJCW1fYnVmZmVyU2l6ZU1heDsKCWNvbnN0IGJvb2wJCQkJbV9hbGxvY2F0ZUxhcmdlckJ1ZmZlcjsKCnByaXZhdGU6CglpbnQJCQkJCQltX2l0ZXJhdGlvbjsKCXN0ZDo6dmVjdG9yPGludD4JCW1faXRlcmF0aW9uT3JkZXI7CglzdGQ6OnZlY3RvcjxVcGxvYWRTYW1wbGVSZXN1bHQ8U2FtcGxlVHlwZT4gPiBtX3Jlc3VsdHM7CgoJYm9vbAkJCQkJbV91c2VHTDsKCWludAkJCQkJCW1fYnVmZmVyUmFuZG9taXplclRpbWVyOwp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFNhbXBsZVR5cGU+CkJhc2ljQnVmZmVyQ2FzZTxTYW1wbGVUeXBlPjo6QmFzaWNCdWZmZXJDYXNlIChDb250ZXh0JiBjb250ZXh0LCBjb25zdCBjaGFyKiBuYW1lLCBjb25zdCBjaGFyKiBkZXNjLCBpbnQgYnVmZmVyU2l6ZU1pbiwgaW50IGJ1ZmZlclNpemVNYXgsIGludCBudW1TYW1wbGVzLCBpbnQgZmxhZ3MpCgk6IFRlc3RDYXNlCQkJCQkoY29udGV4dCwgdGN1OjpOT0RFVFlQRV9QRVJGT1JNQU5DRSwgbmFtZSwgZGVzYykKCSwgbV9kdW1teVByb2dyYW0JCQkoREVfTlVMTCkKCSwgbV9kdW1teVByb2dyYW1Qb3NMb2MJCSgtMSkKCSwgbV9idWZmZXJJRAkJCQkoMCkKCSwgbV9udW1TYW1wbGVzCQkJCShudW1TYW1wbGVzKQoJLCBtX2J1ZmZlclNpemVNaW4JCQkoYnVmZmVyU2l6ZU1pbikKCSwgbV9idWZmZXJTaXplTWF4CQkJKGJ1ZmZlclNpemVNYXgpCgksIG1fYWxsb2NhdGVMYXJnZXJCdWZmZXIJKChmbGFncyAmIEZMQUdfQUxMT0NBVEVfTEFSR0VSX0JVRkZFUikgIT0gMCkKCSwgbV9pdGVyYXRpb24JCQkJKDApCgksIG1faXRlcmF0aW9uT3JkZXIJCQkobnVtU2FtcGxlcykKCSwgbV9yZXN1bHRzCQkJCQkobnVtU2FtcGxlcykKCSwgbV91c2VHTAkJCQkJKHRydWUpCgksIG1fYnVmZmVyUmFuZG9taXplclRpbWVyCSgwKQp7CgkvLyAicmFuZG9taXplIiBpdGVyYXRpb24gb3JkZXIuIERldGVybWluaXN0aWMsIHBhdHRlcm5sZXNzCglnZW5lcmF0ZVR3b1Bhc3NSYW5kb21JdGVyYXRpb25PcmRlcihtX2l0ZXJhdGlvbk9yZGVyLCBtX251bVNhbXBsZXMpOwoKCS8vIGNob29zZSBidWZmZXIgc2l6ZXMKCWZvciAoaW50IHNhbXBsZU5keCA9IDA7IHNhbXBsZU5keCA8IG1fbnVtU2FtcGxlczsgKytzYW1wbGVOZHgpCgl7CgkJY29uc3QgaW50IHJhd0J1ZmZlclNpemUJCQk9IChpbnQpZGVGbG9hdEZsb29yKChmbG9hdClidWZmZXJTaXplTWluICsgKGZsb2F0KShidWZmZXJTaXplTWF4IC0gYnVmZmVyU2l6ZU1pbikgKiAoKGZsb2F0KShzYW1wbGVOZHggKyAxKSAvIChmbG9hdCltX251bVNhbXBsZXMpKTsKCQljb25zdCBpbnQgYnVmZmVyU2l6ZQkJCT0gZGVBbGlnbjMyKHJhd0J1ZmZlclNpemUsIDE2KTsKCQljb25zdCBpbnQgYWxsb2NhdGVkQnVmZmVyU2l6ZQk9IGRlQWxpZ24zMigobV9hbGxvY2F0ZUxhcmdlckJ1ZmZlcikgPyAoKGludCkoKGZsb2F0KWJ1ZmZlclNpemUgKiAxLjVmKSkgOiAoYnVmZmVyU2l6ZSksIDE2KTsKCgkJbV9yZXN1bHRzW3NhbXBsZU5keF0uYnVmZmVyU2l6ZQkJPSBidWZmZXJTaXplOwoJCW1fcmVzdWx0c1tzYW1wbGVOZHhdLmFsbG9jYXRlZFNpemUJPSBhbGxvY2F0ZWRCdWZmZXJTaXplOwoJCW1fcmVzdWx0c1tzYW1wbGVOZHhdLndyaXR0ZW5TaXplCT0gLTE7Cgl9Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgpCYXNpY0J1ZmZlckNhc2U8U2FtcGxlVHlwZT46On5CYXNpY0J1ZmZlckNhc2UgKHZvaWQpCnsKCWRlaW5pdCgpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4Kdm9pZCBCYXNpY0J1ZmZlckNhc2U8U2FtcGxlVHlwZT46OmluaXQgKHZvaWQpCnsKCWNvbnN0IGdsdzo6RnVuY3Rpb25zJiBnbCA9IG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCkuZ2V0RnVuY3Rpb25zKCk7CgoJaWYgKCFtX3VzZUdMKQoJCXJldHVybjsKCgkvLyBcbm90ZSBWaWV3cG9ydCBzaXplIGlzIG5vdCBjaGVja2VkLCBpdCB3b24ndCBtYXR0ZXIgaWYgdGhlIHJlbmRlciB0YXJnZXQgYWN0dWFsbHkgaXMgc21hbGxlciBoaGFuIERVTU1ZX1JFTkRFUl9BUkVBX1NJWkUKCgkvLyBkdW1teSBzaGFkZXIKCgltX2R1bW15UHJvZ3JhbSA9IG5ldyBnbHU6OlNoYWRlclByb2dyYW0obV9jb250ZXh0LmdldFJlbmRlckNvbnRleHQoKSwgZ2x1OjpQcm9ncmFtU291cmNlcygpIDw8IGdsdTo6VmVydGV4U291cmNlKHNfZHVtbXlWZXJ0ZXhTaGFkZXIpIDw8IGdsdTo6RnJhZ21lbnRTb3VyY2Uoc19kdW1teUZyYWduZW50U2hhZGVyKSk7CglpZiAoIW1fZHVtbXlQcm9ncmFtLT5pc09rKCkpCgl7CgkJbV90ZXN0Q3R4LmdldExvZygpIDw8ICptX2R1bW15UHJvZ3JhbTsKCQl0aHJvdyB0Y3U6OlRlc3RFcnJvcigiZmFpbGVkIHRvIGJ1aWxkIHNoYWRlciBwcm9ncmFtIik7Cgl9CgoJbV9kdW1teVByb2dyYW1Qb3NMb2MgPSBnbC5nZXRBdHRyaWJMb2NhdGlvbihtX2R1bW15UHJvZ3JhbS0+Z2V0UHJvZ3JhbSgpLCAiYV9wb3NpdGlvbiIpOwoJaWYgKG1fZHVtbXlQcm9ncmFtUG9zTG9jID09IC0xKQoJCXRocm93IHRjdTo6VGVzdEVycm9yKCJhX3Bvc2l0aW9uIGxvY2F0aW9uIHdhcyAtMSIpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4Kdm9pZCBCYXNpY0J1ZmZlckNhc2U8U2FtcGxlVHlwZT46OmRlaW5pdCAodm9pZCkKewoJaWYgKG1fYnVmZmVySUQpCgl7CgkJbV9jb250ZXh0LmdldFJlbmRlckNvbnRleHQoKS5nZXRGdW5jdGlvbnMoKS5kZWxldGVCdWZmZXJzKDEsICZtX2J1ZmZlcklEKTsKCQltX2J1ZmZlcklEID0gMDsKCX0KCglkZWxldGUgbV9kdW1teVByb2dyYW07CgltX2R1bW15UHJvZ3JhbSA9IERFX05VTEw7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgpUZXN0Q2FzZTo6SXRlcmF0ZVJlc3VsdCBCYXNpY0J1ZmZlckNhc2U8U2FtcGxlVHlwZT46Oml0ZXJhdGUgKHZvaWQpCnsKCWNvbnN0IGdsdzo6RnVuY3Rpb25zJglnbAkJCQk9IG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCkuZ2V0RnVuY3Rpb25zKCk7CglzdGF0aWMgYm9vbAkJCQlidWZmZXJzV2FybWVkVXAJPSBmYWxzZTsKCglzdGF0aWMgY29uc3QgZGVVaW50MzIJdXNhZ2VzW10gPQoJewoJCUdMX1NUUkVBTV9EUkFXLCBHTF9TVFJFQU1fUkVBRCwgR0xfU1RSRUFNX0NPUFksCgkJR0xfU1RBVElDX0RSQVcsIEdMX1NUQVRJQ19SRUFELCBHTF9TVEFUSUNfQ09QWSwKCQlHTF9EWU5BTUlDX0RSQVcsIEdMX0RZTkFNSUNfUkVBRCwgR0xfRFlOQU1JQ19DT1BZLAoJfTsKCgkvLyBBbGxvY2F0ZSBzb21lIHJhbmRvbSBzaXplZCBidWZmZXJzIGFuZCByZW1vdmUgdGhlbSB0bwoJLy8gbWFrZSBzdXJlIHRoZSBmaXJzdCBzYW1wbGVzIHRvbyBoYXZlIHNvbWUgYnVmZmVycyByZW1vdmVkCgkvLyBqdXN0IGJlZm9yZSB0aGVpciBhbGxvY2F0aW9uLiBUaGlzIGlzIG9ubHkgbmVlZGVkIGJ5IHRoZQoJLy8gdGhlIGZpcnN0IHRlc3QuCgoJaWYgKG1fdXNlR0wgJiYgIWJ1ZmZlcnNXYXJtZWRVcCkKCXsKCQljb25zdCBpbnQJCQkJCW51bVJhbmRvbUJ1ZmZlcnMJCQkJPSA2OwoJCWNvbnN0IGludAkJCQkJbnVtUmVwZWF0cwkJCQkJCT0gMTA7CgkJY29uc3QgaW50CQkJCQltYXhCdWZmZXJTaXplCQkJCQk9IDE2Nzc3MjE2OwoJCWNvbnN0IHN0ZDo6dmVjdG9yPGRlVWludDg+CXplcm9EYXRhCQkJCQkJKG1heEJ1ZmZlclNpemUsIDB4MDApOwoJCWRlOjpSYW5kb20JCQkJCXJuZAkJCQkJCQkJKDB4MTIzNCk7CgkJZGVVaW50MzIJCQkJCWJ1ZmZlcklEc1tudW1SYW5kb21CdWZmZXJzXQkJPSB7MH07CgoJCWdsLnVzZVByb2dyYW0obV9kdW1teVByb2dyYW0tPmdldFByb2dyYW0oKSk7CgkJZ2wudmlld3BvcnQoMCwgMCwgRFVNTVlfUkVOREVSX0FSRUFfU0laRSwgRFVNTVlfUkVOREVSX0FSRUFfU0laRSk7CgkJZ2wuZW5hYmxlVmVydGV4QXR0cmliQXJyYXkobV9kdW1teVByb2dyYW1Qb3NMb2MpOwoKCQlmb3IgKGludCBuZHggPSAwOyBuZHggPCBudW1SZXBlYXRzOyArK25keCkKCQl7CgkJCS8vIENyZWF0ZSBidWZmZXIgYW5kIG1heWJlIGRyYXcgZnJvbSBpdAoJCQlmb3IgKGludCByYW5kb21CdWZmZXJOZHggPSAwOyByYW5kb21CdWZmZXJOZHggPCBudW1SYW5kb21CdWZmZXJzOyArK3JhbmRvbUJ1ZmZlck5keCkKCQkJewoJCQkJY29uc3QgaW50CQlyYW5kb21TaXplCT0gZGVBbGlnbjMyKHJuZC5nZXRJbnQoMSwgbWF4QnVmZmVyU2l6ZSksIDQqNCk7CgkJCQljb25zdCBkZVVpbnQzMgl1c2FnZQkJPSB1c2FnZXNbcm5kLmdldFVpbnQzMigpICUgKGRlVWludDMyKURFX0xFTkdUSF9PRl9BUlJBWSh1c2FnZXMpXTsKCgkJCQlnbC5nZW5CdWZmZXJzKDEsICZidWZmZXJJRHNbcmFuZG9tQnVmZmVyTmR4XSk7CgkJCQlnbC5iaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgYnVmZmVySURzW3JhbmRvbUJ1ZmZlck5keF0pOwoJCQkJZ2wuYnVmZmVyRGF0YShHTF9BUlJBWV9CVUZGRVIsIHJhbmRvbVNpemUsICZ6ZXJvRGF0YVswXSwgdXNhZ2UpOwoKCQkJCWlmIChybmQuZ2V0Qm9vbCgpKQoJCQkJewoJCQkJCWdsLnZlcnRleEF0dHJpYlBvaW50ZXIobV9kdW1teVByb2dyYW1Qb3NMb2MsIDQsIEdMX0ZMT0FULCBHTF9GQUxTRSwgMCwgREVfTlVMTCk7CgkJCQkJZ2wuZHJhd0FycmF5cyhHTF9QT0lOVFMsIDAsIDEpOwoJCQkJCWdsLmRyYXdBcnJheXMoR0xfUE9JTlRTLCByYW5kb21TaXplIC8gKGludClzaXplb2YoZmxvYXRbNF0pIC0gMSwgMSk7CgkJCQl9CgkJCX0KCgkJCWZvciAoaW50IHJhbmRvbUJ1ZmZlck5keCA9IDA7IHJhbmRvbUJ1ZmZlck5keCA8IG51bVJhbmRvbUJ1ZmZlcnM7ICsrcmFuZG9tQnVmZmVyTmR4KQoJCQkJZ2wuZGVsZXRlQnVmZmVycygxLCAmYnVmZmVySURzW3JhbmRvbUJ1ZmZlck5keF0pOwoKCQkJd2FpdEdMUmVzdWx0cygpOwoJCQlHTFVfRVhQRUNUX05PX0VSUk9SKGdsLmdldEVycm9yKCksICJCdWZmZXIgZ2VuIik7CgoJCQltX3Rlc3RDdHgudG91Y2hXYXRjaGRvZygpOwoJCX0KCgkJYnVmZmVyc1dhcm1lZFVwID0gdHJ1ZTsKCQlyZXR1cm4gQ09OVElOVUU7Cgl9CgllbHNlIGlmIChtX3VzZUdMICYmIG1fYnVmZmVyUmFuZG9taXplclRpbWVyKysgJSA4ID09IDApCgl7CgkJLy8gRG8gc29tZSByYW5kb20gYnVmZmVyIG9wZXJhdGlvbnMgdG8gZXZlcnkgbm93IGFuZCB0aGVuCgkJLy8gdG8gbWFrZSBzdXJlIHRoZSBwcmV2aW91cyB0ZXN0IGl0ZXJhdGlvbnMgd29uJ3QgYWZmZWN0CgkJLy8gZm9sbG93aW5nIHRlc3QgcnVucy4KCgkJY29uc3QgaW50CQkJCQludW1SYW5kb21CdWZmZXJzCQkJCT0gMzsKCQljb25zdCBpbnQJCQkJCW1heEJ1ZmZlclNpemUJCQkJCT0gMTY3NzcyMTY7CgkJY29uc3Qgc3RkOjp2ZWN0b3I8ZGVVaW50OD4JemVyb0RhdGEJCQkJCQkobWF4QnVmZmVyU2l6ZSwgMHgwMCk7CgkJZGU6OlJhbmRvbQkJCQkJcm5kCQkJCQkJCQkoMHgxMjM0ICsgMHhhYmMgKiBtX2J1ZmZlclJhbmRvbWl6ZXJUaW1lcik7CgoJCS8vIEJ1ZmZlckRhdGEKCQl7CgkJCWRlVWludDMyIGJ1ZmZlcklEc1tudW1SYW5kb21CdWZmZXJzXSA9IHswfTsKCgkJCWZvciAoaW50IHJhbmRvbUJ1ZmZlck5keCA9IDA7IHJhbmRvbUJ1ZmZlck5keCA8IG51bVJhbmRvbUJ1ZmZlcnM7ICsrcmFuZG9tQnVmZmVyTmR4KQoJCQl7CgkJCQljb25zdCBpbnQJCXJhbmRvbVNpemUJPSBkZUFsaWduMzIocm5kLmdldEludCgxLCBtYXhCdWZmZXJTaXplKSwgNCo0KTsKCQkJCWNvbnN0IGRlVWludDMyCXVzYWdlCQk9IHVzYWdlc1tybmQuZ2V0VWludDMyKCkgJSAoZGVVaW50MzIpREVfTEVOR1RIX09GX0FSUkFZKHVzYWdlcyldOwoKCQkJCWdsLmdlbkJ1ZmZlcnMoMSwgJmJ1ZmZlcklEc1tyYW5kb21CdWZmZXJOZHhdKTsKCQkJCWdsLmJpbmRCdWZmZXIoR0xfQVJSQVlfQlVGRkVSLCBidWZmZXJJRHNbcmFuZG9tQnVmZmVyTmR4XSk7CgkJCQlnbC5idWZmZXJEYXRhKEdMX0FSUkFZX0JVRkZFUiwgcmFuZG9tU2l6ZSwgJnplcm9EYXRhWzBdLCB1c2FnZSk7CgkJCX0KCgkJCWZvciAoaW50IHJhbmRvbUJ1ZmZlck5keCA9IDA7IHJhbmRvbUJ1ZmZlck5keCA8IG51bVJhbmRvbUJ1ZmZlcnM7ICsrcmFuZG9tQnVmZmVyTmR4KQoJCQkJZ2wuZGVsZXRlQnVmZmVycygxLCAmYnVmZmVySURzW3JhbmRvbUJ1ZmZlck5keF0pOwoJCX0KCgkJR0xVX0VYUEVDVF9OT19FUlJPUihnbC5nZXRFcnJvcigpLCAiYnVmZmVyIG9wcyIpOwoKCQkvLyBEbyBzb21lIG1lbW9yeSBtYXBwaW5ncwoJCXsKCQkJZGVVaW50MzIgYnVmZmVySURzW251bVJhbmRvbUJ1ZmZlcnNdID0gezB9OwoKCQkJZm9yIChpbnQgcmFuZG9tQnVmZmVyTmR4ID0gMDsgcmFuZG9tQnVmZmVyTmR4IDwgbnVtUmFuZG9tQnVmZmVyczsgKytyYW5kb21CdWZmZXJOZHgpCgkJCXsKCQkJCWNvbnN0IGludAkJcmFuZG9tU2l6ZQk9IGRlQWxpZ24zMihybmQuZ2V0SW50KDEsIG1heEJ1ZmZlclNpemUpLCA0KjQpOwoJCQkJY29uc3QgZGVVaW50MzIJdXNhZ2UJCT0gdXNhZ2VzW3JuZC5nZXRVaW50MzIoKSAlIChkZVVpbnQzMilERV9MRU5HVEhfT0ZfQVJSQVkodXNhZ2VzKV07CgkJCQl2b2lkKgkJCXB0cjsKCgkJCQlnbC5nZW5CdWZmZXJzKDEsICZidWZmZXJJRHNbcmFuZG9tQnVmZmVyTmR4XSk7CgkJCQlnbC5iaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgYnVmZmVySURzW3JhbmRvbUJ1ZmZlck5keF0pOwoJCQkJZ2wuYnVmZmVyRGF0YShHTF9BUlJBWV9CVUZGRVIsIHJhbmRvbVNpemUsICZ6ZXJvRGF0YVswXSwgdXNhZ2UpOwoKCQkJCWdsLnZlcnRleEF0dHJpYlBvaW50ZXIobV9kdW1teVByb2dyYW1Qb3NMb2MsIDQsIEdMX0ZMT0FULCBHTF9GQUxTRSwgMCwgREVfTlVMTCk7CgkJCQlnbC5kcmF3QXJyYXlzKEdMX1BPSU5UUywgMCwgMSk7CgkJCQlnbC5kcmF3QXJyYXlzKEdMX1BPSU5UUywgcmFuZG9tU2l6ZSAvIChpbnQpc2l6ZW9mKGZsb2F0WzRdKSAtIDEsIDEpOwoKCQkJCWlmIChybmQuZ2V0Qm9vbCgpKQoJCQkJCXdhaXRHTFJlc3VsdHMoKTsKCgkJCQlwdHIgPSBnbC5tYXBCdWZmZXJSYW5nZShHTF9BUlJBWV9CVUZGRVIsIDAsIHJhbmRvbVNpemUsIEdMX01BUF9XUklURV9CSVQpOwoJCQkJaWYgKHB0cikKCQkJCXsKCQkJCQltZWRpYW5UaW1lTWVtY3B5KHB0ciwgJnplcm9EYXRhWzBdLCByYW5kb21TaXplKTsKCQkJCQlnbC51bm1hcEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIpOwoJCQkJfQoJCQl9CgoJCQlmb3IgKGludCByYW5kb21CdWZmZXJOZHggPSAwOyByYW5kb21CdWZmZXJOZHggPCBudW1SYW5kb21CdWZmZXJzOyArK3JhbmRvbUJ1ZmZlck5keCkKCQkJCWdsLmRlbGV0ZUJ1ZmZlcnMoMSwgJmJ1ZmZlcklEc1tyYW5kb21CdWZmZXJOZHhdKTsKCgkJCXdhaXRHTFJlc3VsdHMoKTsKCQl9CgoJCUdMVV9FWFBFQ1RfTk9fRVJST1IoZ2wuZ2V0RXJyb3IoKSwgImJ1ZmZlciBtYXBzIik7CgkJcmV0dXJuIENPTlRJTlVFOwoJfQoJZWxzZQoJewoJCWNvbnN0IGludAljdXJyZW50SXRlcmF0aW9uCT0gbV9pdGVyYXRpb247CgkJY29uc3QgaW50CXNhbXBsZU5keAkJCT0gbV9pdGVyYXRpb25PcmRlcltjdXJyZW50SXRlcmF0aW9uXTsKCQljb25zdCBib29sCXNhbXBsZVJ1blN1Y2Nlc3NmdWwJPSBydW5TYW1wbGUoY3VycmVudEl0ZXJhdGlvbiwgbV9yZXN1bHRzW3NhbXBsZU5keF0pOwoKCQlHTFVfRVhQRUNUX05PX0VSUk9SKGdsLmdldEVycm9yKCksICJwb3N0IHJ1blNhbXBsZSgpIik7CgoJCS8vIFJldHJ5IGZhaWxlZCBzYW1wbGVzCgkJaWYgKCFzYW1wbGVSdW5TdWNjZXNzZnVsKQoJCQlyZXR1cm4gQ09OVElOVUU7CgoJCWlmICgrK21faXRlcmF0aW9uID49IG1fbnVtU2FtcGxlcykKCQl7CgkJCWxvZ0FuZFNldFRlc3RSZXN1bHQobV9yZXN1bHRzKTsKCQkJcmV0dXJuIFNUT1A7CgkJfQoJCWVsc2UKCQkJcmV0dXJuIENPTlRJTlVFOwoJfQp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4Kdm9pZCBCYXNpY0J1ZmZlckNhc2U8U2FtcGxlVHlwZT46OmRpc2FibGVHTFdhcm11cCAodm9pZCkKewoJbV91c2VHTCA9IGZhbHNlOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4Kdm9pZCBCYXNpY0J1ZmZlckNhc2U8U2FtcGxlVHlwZT46OndhaXRHTFJlc3VsdHMgKHZvaWQpCnsKCXRjdTo6U3VyZmFjZSBkdW1teVN1cmZhY2UoRFVNTVlfUkVOREVSX0FSRUFfU0laRSwgRFVNTVlfUkVOREVSX0FSRUFfU0laRSk7CglnbHU6OnJlYWRQaXhlbHMobV9jb250ZXh0LmdldFJlbmRlckNvbnRleHQoKSwgMCwgMCwgZHVtbXlTdXJmYWNlLmdldEFjY2VzcygpKTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFNhbXBsZVR5cGU+CmNsYXNzIEJhc2ljVXBsb2FkQ2FzZSA6IHB1YmxpYyBCYXNpY0J1ZmZlckNhc2U8U2FtcGxlVHlwZT4KewpwdWJsaWM6CgllbnVtIENhc2VUeXBlCgl7CgkJQ0FTRV9OT19CVUZGRVJTID0gMCwKCQlDQVNFX05FV19CVUZGRVIsCgkJQ0FTRV9VTlNQRUNJRklFRF9CVUZGRVIsCgkJQ0FTRV9TUEVDSUZJRURfQlVGRkVSLAoJCUNBU0VfVVNFRF9CVUZGRVIsCgkJQ0FTRV9VU0VEX0xBUkdFUl9CVUZGRVIsCgoJCUNBU0VfTEFTVAoJfTsKCgllbnVtIENhc2VGbGFncwoJewoJCUZMQUdfRE9OVF9MT0dfQlVGRkVSX0lORk8JCQkJPSAweDAxLAoJCUZMQUdfUkVTVUxUX0JVRkZFUl9VTlNQRUNJRklFRF9DT05URU5UCT0gMHgwMiwKCX07CgoJZW51bSBSZXN1bHRUeXBlCgl7CgkJUkVTVUxUX01FRElBTl9UUkFOU0ZFUl9SQVRFID0gMCwKCQlSRVNVTFRfQVNZTVBUT1RJQ19UUkFOU0ZFUl9SQVRFLAoJfTsKCgkJCQkJCUJhc2ljVXBsb2FkQ2FzZQkJKENvbnRleHQmIGNvbnRleHQsCgkJCQkJCQkJCQkJIGNvbnN0IGNoYXIqIG5hbWUsCgkJCQkJCQkJCQkJIGNvbnN0IGNoYXIqIGRlc2MsCgkJCQkJCQkJCQkJIGludCBidWZmZXJTaXplTWluLAoJCQkJCQkJCQkJCSBpbnQgYnVmZmVyU2l6ZU1heCwKCQkJCQkJCQkJCQkgaW50IG51bVNhbXBsZXMsCgkJCQkJCQkJCQkJIGRlVWludDMyIGJ1ZmZlclVzYWdlLAoJCQkJCQkJCQkJCSBDYXNlVHlwZSBjYXNlVHlwZSwKCQkJCQkJCQkJCQkgUmVzdWx0VHlwZSByZXN1bHRUeXBlLAoJCQkJCQkJCQkJCSBpbnQgZmxhZ3MgPSAwKTsKCgkJCQkJCX5CYXNpY1VwbG9hZENhc2UJKHZvaWQpOwoKCXZpcnR1YWwgdm9pZAkJaW5pdAkJCQkodm9pZCk7Cgl2aXJ0dWFsIHZvaWQJCWRlaW5pdAkJCQkodm9pZCk7Cgpwcml2YXRlOgoJYm9vbAkJCQlydW5TYW1wbGUJCQkoaW50IGl0ZXJhdGlvbiwgVXBsb2FkU2FtcGxlUmVzdWx0PFNhbXBsZVR5cGU+JiBzYW1wbGUpOwoJdm9pZAkJCQljcmVhdGVCdWZmZXIJCShpbnQgYnVmZmVyU2l6ZSwgaW50IGl0ZXJhdGlvbik7Cgl2b2lkCQkJCWRlbGV0ZUJ1ZmZlcgkJKGludCBidWZmZXJTaXplKTsKCXZvaWQJCQkJdXNlQnVmZmVyCQkJKGludCBidWZmZXJTaXplKTsKCgl2aXJ0dWFsIHZvaWQJCXRlc3RCdWZmZXJVcGxvYWQJKFVwbG9hZFNhbXBsZVJlc3VsdDxTYW1wbGVUeXBlPiYgcmVzdWx0LCBpbnQgd3JpdGVTaXplKSA9IDA7Cgl2b2lkCQkJCWxvZ0FuZFNldFRlc3RSZXN1bHQJKGNvbnN0IHN0ZDo6dmVjdG9yPFVwbG9hZFNhbXBsZVJlc3VsdDxTYW1wbGVUeXBlPiA+JiByZXN1bHRzKTsKCglkZVVpbnQzMgkJCW1fZHVtbXlCdWZmZXJJRDsKCnByb3RlY3RlZDoKCWNvbnN0IENhc2VUeXBlCQltX2Nhc2VUeXBlOwoJY29uc3QgUmVzdWx0VHlwZQltX3Jlc3VsdFR5cGU7Cgljb25zdCBkZVVpbnQzMgkJbV9idWZmZXJVc2FnZTsKCWNvbnN0IGJvb2wJCQltX2xvZ0J1ZmZlckluZm87Cgljb25zdCBib29sCQkJbV9idWZmZXJVbnNwZWNpZmllZENvbnRlbnQ7CglzdGQ6OnZlY3RvcjxkZVVpbnQ4PiBtX3plcm9EYXRhOwoKCXVzaW5nIEJhc2ljQnVmZmVyQ2FzZTxTYW1wbGVUeXBlPjo6bV90ZXN0Q3R4OwoJdXNpbmcgQmFzaWNCdWZmZXJDYXNlPFNhbXBsZVR5cGU+OjptX2NvbnRleHQ7CgoJdXNpbmcgQmFzaWNCdWZmZXJDYXNlPFNhbXBsZVR5cGU+OjpEVU1NWV9SRU5ERVJfQVJFQV9TSVpFOwoJdXNpbmcgQmFzaWNCdWZmZXJDYXNlPFNhbXBsZVR5cGU+OjptX2R1bW15UHJvZ3JhbTsKCXVzaW5nIEJhc2ljQnVmZmVyQ2FzZTxTYW1wbGVUeXBlPjo6bV9kdW1teVByb2dyYW1Qb3NMb2M7Cgl1c2luZyBCYXNpY0J1ZmZlckNhc2U8U2FtcGxlVHlwZT46Om1fYnVmZmVySUQ7Cgl1c2luZyBCYXNpY0J1ZmZlckNhc2U8U2FtcGxlVHlwZT46Om1fbnVtU2FtcGxlczsKCXVzaW5nIEJhc2ljQnVmZmVyQ2FzZTxTYW1wbGVUeXBlPjo6bV9idWZmZXJTaXplTWluOwoJdXNpbmcgQmFzaWNCdWZmZXJDYXNlPFNhbXBsZVR5cGU+OjptX2J1ZmZlclNpemVNYXg7Cgl1c2luZyBCYXNpY0J1ZmZlckNhc2U8U2FtcGxlVHlwZT46Om1fYWxsb2NhdGVMYXJnZXJCdWZmZXI7Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4KQmFzaWNVcGxvYWRDYXNlPFNhbXBsZVR5cGU+OjpCYXNpY1VwbG9hZENhc2UgKENvbnRleHQmIGNvbnRleHQsIGNvbnN0IGNoYXIqIG5hbWUsIGNvbnN0IGNoYXIqIGRlc2MsIGludCBidWZmZXJTaXplTWluLCBpbnQgYnVmZmVyU2l6ZU1heCwgaW50IG51bVNhbXBsZXMsIGRlVWludDMyIGJ1ZmZlclVzYWdlLCBDYXNlVHlwZSBjYXNlVHlwZSwgUmVzdWx0VHlwZSByZXN1bHRUeXBlLCBpbnQgZmxhZ3MpCgk6IEJhc2ljQnVmZmVyQ2FzZTxTYW1wbGVUeXBlPgkoY29udGV4dCwgbmFtZSwgZGVzYywgYnVmZmVyU2l6ZU1pbiwgYnVmZmVyU2l6ZU1heCwgbnVtU2FtcGxlcywgKGNhc2VUeXBlID09IENBU0VfVVNFRF9MQVJHRVJfQlVGRkVSKSA/IChCYXNpY0J1ZmZlckNhc2U8U2FtcGxlVHlwZT46OkZMQUdfQUxMT0NBVEVfTEFSR0VSX0JVRkZFUikgOiAoMCkpCgksIG1fZHVtbXlCdWZmZXJJRAkJCQkoMCkKCSwgbV9jYXNlVHlwZQkJCQkJKGNhc2VUeXBlKQoJLCBtX3Jlc3VsdFR5cGUJCQkJCShyZXN1bHRUeXBlKQoJLCBtX2J1ZmZlclVzYWdlCQkJCQkoYnVmZmVyVXNhZ2UpCgksIG1fbG9nQnVmZmVySW5mbwkJCQkoKGZsYWdzICYgRkxBR19ET05UX0xPR19CVUZGRVJfSU5GTykgPT0gMCkKCSwgbV9idWZmZXJVbnNwZWNpZmllZENvbnRlbnQJKChmbGFncyAmIEZMQUdfUkVTVUxUX0JVRkZFUl9VTlNQRUNJRklFRF9DT05URU5UKSAhPSAwKQoJLCBtX3plcm9EYXRhCQkJCQkoKQp7CglERV9BU1NFUlQobV9jYXNlVHlwZSA8IENBU0VfTEFTVCk7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgpCYXNpY1VwbG9hZENhc2U8U2FtcGxlVHlwZT46On5CYXNpY1VwbG9hZENhc2UgKHZvaWQpCnsKCWRlaW5pdCgpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4Kdm9pZCBCYXNpY1VwbG9hZENhc2U8U2FtcGxlVHlwZT46OmluaXQgKHZvaWQpCnsKCWNvbnN0IGdsdzo6RnVuY3Rpb25zJiBnbCA9IG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCkuZ2V0RnVuY3Rpb25zKCk7CgoJQmFzaWNCdWZmZXJDYXNlPFNhbXBsZVR5cGU+Ojppbml0KCk7CgoJLy8gemVybyBidWZmZXIgYXMgdXBsb2FkIHNvdXJjZQoJbV96ZXJvRGF0YS5yZXNpemUobV9idWZmZXJTaXplTWF4LCAweDAwKTsKCgkvLyBkdW1teSBidWZmZXIKCglnbC5nZW5CdWZmZXJzKDEsICZtX2R1bW15QnVmZmVySUQpOwoJR0xVX0VYUEVDVF9OT19FUlJPUihnbC5nZXRFcnJvcigpLCAiR2VuIGJ1ZiIpOwoKCS8vIGxvZyBiYXNpYyBpbmZvCgoJbV90ZXN0Q3R4LmdldExvZygpCgkJPDwgdGN1OjpUZXN0TG9nOjpNZXNzYWdlCgkJPDwgIlRlc3RpbmcgcGVyZm9ybWFuY2Ugd2l0aCAiIDw8IG1fbnVtU2FtcGxlcyA8PCAiIHRlc3Qgc2FtcGxlcy4gU2FtcGxlIG9yZGVyIGlzIHJhbmRvbWl6ZWQuIEFsbCBzYW1wbGVzIGF0IGV2ZW4gcG9zaXRpb25zIChmaXJzdCA9IDApIGFyZSB0ZXN0ZWQgYmVmb3JlIHNhbXBsZXMgYXQgb2RkIHBvc2l0aW9ucy5cbiIKCQk8PCAiQnVmZmVyIHNpemVzIGFyZSBpbiByYW5nZSBbIiA8PCBnZXRIdW1hblJlYWRhYmxlQnl0ZVNpemUobV9idWZmZXJTaXplTWluKSA8PCAiLCAiIDw8IGdldEh1bWFuUmVhZGFibGVCeXRlU2l6ZShtX2J1ZmZlclNpemVNYXgpIDw8ICJdLiIKCQk8PCB0Y3U6OlRlc3RMb2c6OkVuZE1lc3NhZ2U7CgoJaWYgKG1fbG9nQnVmZmVySW5mbykKCXsKCQlzd2l0Y2ggKG1fY2FzZVR5cGUpCgkJewoJCQljYXNlIENBU0VfTk9fQlVGRkVSUzoKCQkJCWJyZWFrOwoKCQkJY2FzZSBDQVNFX05FV19CVUZGRVI6CgkJCQltX3Rlc3RDdHguZ2V0TG9nKCkgPDwgdGN1OjpUZXN0TG9nOjpNZXNzYWdlIDw8ICJUYXJnZXQgYnVmZmVyIGlzIGdlbmVyYXRlZCBidXQgbm90IHNwZWNpZmllZCAoaS5lIGdsQnVmZmVyRGF0YSgpIG5vdCBjYWxsZWQpLiIgPDwgdGN1OjpUZXN0TG9nOjpFbmRNZXNzYWdlOwoJCQkJYnJlYWs7CgoJCQljYXNlIENBU0VfVU5TUEVDSUZJRURfQlVGRkVSOgoJCQkJbV90ZXN0Q3R4LmdldExvZygpIDw8IHRjdTo6VGVzdExvZzo6TWVzc2FnZSA8PCAiVGFyZ2V0IGJ1ZmZlciBpcyBhbGxvY2F0ZWQgd2l0aCBnbEJ1ZmZlckRhdGEoTlVMTCkuIiA8PCB0Y3U6OlRlc3RMb2c6OkVuZE1lc3NhZ2U7CgkJCQlicmVhazsKCgkJCWNhc2UgQ0FTRV9TUEVDSUZJRURfQlVGRkVSOgoJCQkJbV90ZXN0Q3R4LmdldExvZygpIDw8IHRjdTo6VGVzdExvZzo6TWVzc2FnZSA8PCAiVGFyZ2V0IGJ1ZmZlciBjb250ZW50cyBhcmUgc3BlY2lmaWVkIHByaW9yIHRlc3Rpbmcgd2l0aCBnbEJ1ZmZlckRhdGEoZGF0YSkuIiA8PCB0Y3U6OlRlc3RMb2c6OkVuZE1lc3NhZ2U7CgkJCQlicmVhazsKCgkJCWNhc2UgQ0FTRV9VU0VEX0JVRkZFUjoKCQkJCW1fdGVzdEN0eC5nZXRMb2coKSA8PCB0Y3U6OlRlc3RMb2c6Ok1lc3NhZ2UgPDwgIlRhcmdldCBidWZmZXIgaGFzIGJlZW4gdXNlZCBpbiBkcmF3aW5nIGJlZm9yZSB0ZXN0aW5nLiIgPDwgdGN1OjpUZXN0TG9nOjpFbmRNZXNzYWdlOwoJCQkJYnJlYWs7CgoJCQljYXNlIENBU0VfVVNFRF9MQVJHRVJfQlVGRkVSOgoJCQkJbV90ZXN0Q3R4LmdldExvZygpIDw8IHRjdTo6VGVzdExvZzo6TWVzc2FnZSA8PCAiVGFyZ2V0IGJ1ZmZlciBpcyBsYXJnZXIgYW5kIGhhcyBiZWVuIHVzZWQgaW4gZHJhd2luZyBiZWZvcmUgdGVzdGluZy4iIDw8IHRjdTo6VGVzdExvZzo6RW5kTWVzc2FnZTsKCQkJCWJyZWFrOwoKCQkJZGVmYXVsdDoKCQkJCURFX0FTU0VSVChmYWxzZSk7CgkJCQlicmVhazsKCQl9Cgl9CgoJaWYgKG1fcmVzdWx0VHlwZSA9PSBSRVNVTFRfTUVESUFOX1RSQU5TRkVSX1JBVEUpCgkJbV90ZXN0Q3R4LmdldExvZygpIDw8IHRjdTo6VGVzdExvZzo6TWVzc2FnZSA8PCAiVGVzdCByZXN1bHQgaXMgdGhlIG1lZGlhbiB0cmFuc2ZlciByYXRlIG9mIHRoZSB0ZXN0IHNhbXBsZXMuIiA8PCB0Y3U6OlRlc3RMb2c6OkVuZE1lc3NhZ2U7CgllbHNlIGlmIChtX3Jlc3VsdFR5cGUgPT0gUkVTVUxUX0FTWU1QVE9USUNfVFJBTlNGRVJfUkFURSkKCQltX3Rlc3RDdHguZ2V0TG9nKCkgPDwgdGN1OjpUZXN0TG9nOjpNZXNzYWdlIDw8ICJUZXN0IHJlc3VsdCBpcyB0aGUgYXN5bXB0b3RpYyB0cmFuc2ZlciByYXRlIGFzIHRoZSBidWZmZXIgc2l6ZSBhcHByb2FjaGVzIGluZmluaXR5LiIgPDwgdGN1OjpUZXN0TG9nOjpFbmRNZXNzYWdlOwoJZWxzZQoJCURFX0FTU0VSVChmYWxzZSk7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgp2b2lkIEJhc2ljVXBsb2FkQ2FzZTxTYW1wbGVUeXBlPjo6ZGVpbml0ICh2b2lkKQp7CglpZiAobV9kdW1teUJ1ZmZlcklEKQoJewoJCW1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCkuZ2V0RnVuY3Rpb25zKCkuZGVsZXRlQnVmZmVycygxLCAmbV9kdW1teUJ1ZmZlcklEKTsKCQltX2R1bW15QnVmZmVySUQgPSAwOwoJfQoKCW1femVyb0RhdGEgPSBzdGQ6OnZlY3RvcjxkZVVpbnQ4PigpOwoKCUJhc2ljQnVmZmVyQ2FzZTxTYW1wbGVUeXBlPjo6ZGVpbml0KCk7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgpib29sIEJhc2ljVXBsb2FkQ2FzZTxTYW1wbGVUeXBlPjo6cnVuU2FtcGxlIChpbnQgaXRlcmF0aW9uLCBVcGxvYWRTYW1wbGVSZXN1bHQ8U2FtcGxlVHlwZT4mIHNhbXBsZSkKewoJY29uc3QgZ2x3OjpGdW5jdGlvbnMmCWdsCQkJCQk9IG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCkuZ2V0RnVuY3Rpb25zKCk7Cgljb25zdCBpbnQJCQkJYWxsb2NhdGVkQnVmZmVyU2l6ZQk9IHNhbXBsZS5hbGxvY2F0ZWRTaXplOwoJY29uc3QgaW50CQkJCWJ1ZmZlclNpemUJCQk9IHNhbXBsZS5idWZmZXJTaXplOwoKCWlmIChtX2Nhc2VUeXBlICE9IENBU0VfTk9fQlVGRkVSUykKCQljcmVhdGVCdWZmZXIoaXRlcmF0aW9uLCBhbGxvY2F0ZWRCdWZmZXJTaXplKTsKCgkvLyB3YXJtdXAgQ1BVIGJlZm9yZSB0aGUgdGVzdCB0byBtYWtlIHN1cmUgdGhlIHBvd2VyIG1hbmFnZW1lbnQgZ292ZXJub3IKCS8vIGtlZXBzIHVzIGluIHRoZSAiaGlnaCBwZXJmb3JtYW5jZSIgbW9kZQoJewoJCWRlWWllbGQoKTsKCQl0Y3U6Ondhcm11cENQVSgpOwoJCWRlWWllbGQoKTsKCX0KCgl0ZXN0QnVmZmVyVXBsb2FkKHNhbXBsZSwgYnVmZmVyU2l6ZSk7CglHTFVfRVhQRUNUX05PX0VSUk9SKGdsLmdldEVycm9yKCksICJCdWZmZXIgdXBsb2FkIHNhbXBsZSIpOwoKCWlmIChtX2Nhc2VUeXBlICE9IENBU0VfTk9fQlVGRkVSUykKCQlkZWxldGVCdWZmZXIoYnVmZmVyU2l6ZSk7CgoJcmV0dXJuIHRydWU7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgp2b2lkIEJhc2ljVXBsb2FkQ2FzZTxTYW1wbGVUeXBlPjo6Y3JlYXRlQnVmZmVyIChpbnQgaXRlcmF0aW9uLCBpbnQgYnVmZmVyU2l6ZSkKewoJREVfQVNTRVJUKCFtX2J1ZmZlcklEKTsKCURFX0FTU0VSVChtX2Nhc2VUeXBlICE9IENBU0VfTk9fQlVGRkVSUyk7CgoJY29uc3QgZ2x3OjpGdW5jdGlvbnMmIGdsID0gbV9jb250ZXh0LmdldFJlbmRlckNvbnRleHQoKS5nZXRGdW5jdGlvbnMoKTsKCgkvLyBjcmVhdGUgYnVmZmVyCgoJaWYgKG1fY2FzZVR5cGUgPT0gQ0FTRV9OT19CVUZGRVJTKQoJCXJldHVybjsKCgkvLyBjcmVhdGUgZW1wdHkgYnVmZmVyCgoJZ2wuZ2VuQnVmZmVycygxLCAmbV9idWZmZXJJRCk7CglnbC5iaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgbV9idWZmZXJJRCk7CglHTFVfRVhQRUNUX05PX0VSUk9SKGdsLmdldEVycm9yKCksICJCdWZmZXIgZ2VuIik7CgoJaWYgKG1fY2FzZVR5cGUgPT0gQ0FTRV9ORVdfQlVGRkVSKQoJewoJCS8vIHVwbG9hZCBzb21ldGhpbmcgZWxzZSBmaXJzdCwgdGhpcyBzaG91bGQgcmVkdWNlIG5vaXNlIGluIHNhbXBsZXMKCgkJZGU6OlJhbmRvbQkJCQkJcm5nCQkJCSgweGJhZGMgKiBpdGVyYXRpb24pOwoJCWNvbnN0IGludAkJCQkJc2l6ZURlbHRhCQk9IHJuZy5nZXRJbnQoMCwgMjA5NzE0MCk7CgkJY29uc3QgaW50CQkJCQlkdW1teVVwbG9hZFNpemUgPSBkZUFsaWduMzIoMTA0ODU3NiArIHNpemVEZWx0YSwgNCo0KTsgLy8gVmFyeSBidWZmZXIgc2l6ZSB0byBtYWtlIHN1cmUgaXQgaXMgYWx3YXlzIHJlYWxsb2NhdGVkCgkJY29uc3Qgc3RkOjp2ZWN0b3I8ZGVVaW50OD4JZHVtbXlEYXRhCQkoZHVtbXlVcGxvYWRTaXplLCAweDIwKTsKCgkJZ2wuYmluZEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIsIG1fZHVtbXlCdWZmZXJJRCk7CgkJZ2wuYnVmZmVyRGF0YShHTF9BUlJBWV9CVUZGRVIsIGR1bW15VXBsb2FkU2l6ZSwgJmR1bW15RGF0YVswXSwgbV9idWZmZXJVc2FnZSk7CgoJCS8vIG1ha2Ugc3VyZSB1cGxvYWQgd29uJ3QgaW50ZXJmZXJlIHdpdGggdGhlIHRlc3QKCQl1c2VCdWZmZXIoZHVtbXlVcGxvYWRTaXplKTsKCgkJLy8gZG9uJ3Qga2lsbCB0aGUgYnVmZmVyIHNvIHRoYXQgdGhlIGZvbGxvd2luZyB1cGxvYWQgY2Fubm90IHBvdGVudGlhbGx5IHJldXNlIHRoZSBidWZmZXIKCgkJcmV0dXJuOwoJfQoKCS8vIHNwZWNpZnkgaXQKCglpZiAobV9jYXNlVHlwZSA9PSBDQVNFX1VOU1BFQ0lGSUVEX0JVRkZFUikKCQlnbC5idWZmZXJEYXRhKEdMX0FSUkFZX0JVRkZFUiwgYnVmZmVyU2l6ZSwgREVfTlVMTCwgbV9idWZmZXJVc2FnZSk7CgllbHNlCgl7CgkJY29uc3Qgc3RkOjp2ZWN0b3I8ZGVVaW50OD4gZHVtbXlEYXRhKGJ1ZmZlclNpemUsIDB4MjApOwoJCWdsLmJ1ZmZlckRhdGEoR0xfQVJSQVlfQlVGRkVSLCBidWZmZXJTaXplLCAmZHVtbXlEYXRhWzBdLCBtX2J1ZmZlclVzYWdlKTsKCX0KCglpZiAobV9jYXNlVHlwZSA9PSBDQVNFX1VOU1BFQ0lGSUVEX0JVRkZFUiB8fCBtX2Nhc2VUeXBlID09IENBU0VfU1BFQ0lGSUVEX0JVRkZFUikKCQlyZXR1cm47CgoJLy8gdXNlIGl0IGFuZCBtYWtlIHN1cmUgaXQgaXMgdXBsb2FkZWQKCgl1c2VCdWZmZXIoYnVmZmVyU2l6ZSk7CglERV9BU1NFUlQobV9jYXNlVHlwZSA9PSBDQVNFX1VTRURfQlVGRkVSIHx8IG1fY2FzZVR5cGUgPT0gQ0FTRV9VU0VEX0xBUkdFUl9CVUZGRVIpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4Kdm9pZCBCYXNpY1VwbG9hZENhc2U8U2FtcGxlVHlwZT46OmRlbGV0ZUJ1ZmZlciAoaW50IGJ1ZmZlclNpemUpCnsKCURFX0FTU0VSVChtX2J1ZmZlcklEKTsKCURFX0FTU0VSVChtX2Nhc2VUeXBlICE9IENBU0VfTk9fQlVGRkVSUyk7CgoJLy8gcmVuZGVyIGZyb20gdGhlIGJ1ZmZlciB0byBtYWtlIHN1cmUgaXQgYWN0dWFsbHkgbWFkZSBpdCB0byB0aGUgZ3B1LiBUaGlzIGlzIHRvCgkvLyBtYWtlIHN1cmUgdGhhdCBpZiB0aGUgdXBsb2FkIGFjdHVhbGx5IGhhcHBlbnMgbGF0ZXIgb3IgaXMgaGFwcGVuaW5nIHJpZ2h0IG5vdyBpbgoJLy8gdGhlIGJhY2tncm91bmQsIGl0IHdpbGwgbm90IGludGVyZmVyZSB3aXRoIGZ1cnRoZXIgdGVzdCBydW5zCgoJLy8gaWYgYnVmZmVyIGNvbnRhaW5zIHVuc3BlY2lmaWVkIGNvbnRlbnQsIHNvdXJjaW5nIGRhdGEgZnJvbSBpdCByZXN1bHRzIGluIHVuZGVmaW5lZAoJLy8gcmVzdWx0cywgcG9zc2libHkgaW5jbHVkaW5nIHByb2dyYW0gdGVybWluYXRpb24uIFNwZWNpZnkgYWxsIGRhdGEgdG8gcHJldmVudCBzdWNoCgkvLyBjYXNlIGZyb20gaGFwcGVuaW5nCgoJY29uc3QgZ2x3OjpGdW5jdGlvbnMmIGdsID0gbV9jb250ZXh0LmdldFJlbmRlckNvbnRleHQoKS5nZXRGdW5jdGlvbnMoKTsKCglnbC5iaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgbV9idWZmZXJJRCk7CgoJaWYgKG1fYnVmZmVyVW5zcGVjaWZpZWRDb250ZW50KQoJewoJCWNvbnN0IHN0ZDo6dmVjdG9yPGRlVWludDg+IGR1bW15RGF0YShidWZmZXJTaXplLCAweDIwKTsKCQlnbC5idWZmZXJEYXRhKEdMX0FSUkFZX0JVRkZFUiwgYnVmZmVyU2l6ZSwgJmR1bW15RGF0YVswXSwgbV9idWZmZXJVc2FnZSk7CgoJCUdMVV9FWFBFQ1RfTk9fRVJST1IoZ2wuZ2V0RXJyb3IoKSwgInJlLXNwZWNpZnkgYnVmZmVyIik7Cgl9CgoJdXNlQnVmZmVyKGJ1ZmZlclNpemUpOwoKCWdsLmRlbGV0ZUJ1ZmZlcnMoMSwgJm1fYnVmZmVySUQpOwoJbV9idWZmZXJJRCA9IDA7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgp2b2lkIEJhc2ljVXBsb2FkQ2FzZTxTYW1wbGVUeXBlPjo6dXNlQnVmZmVyIChpbnQgYnVmZmVyU2l6ZSkKewoJY29uc3QgZ2x3OjpGdW5jdGlvbnMmIGdsID0gbV9jb250ZXh0LmdldFJlbmRlckNvbnRleHQoKS5nZXRGdW5jdGlvbnMoKTsKCglnbC51c2VQcm9ncmFtKG1fZHVtbXlQcm9ncmFtLT5nZXRQcm9ncmFtKCkpOwoKCWdsLnZpZXdwb3J0KDAsIDAsIERVTU1ZX1JFTkRFUl9BUkVBX1NJWkUsIERVTU1ZX1JFTkRFUl9BUkVBX1NJWkUpOwoJZ2wudmVydGV4QXR0cmliUG9pbnRlcihtX2R1bW15UHJvZ3JhbVBvc0xvYywgNCwgR0xfRkxPQVQsIEdMX0ZBTFNFLCAwLCBERV9OVUxMKTsKCWdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KG1fZHVtbXlQcm9ncmFtUG9zTG9jKTsKCgkvLyB1c2Ugd2hvbGUgYnVmZmVyIHRvIG1ha2Ugc3VyZSBidWZmZXIgaXMgdXBsb2FkZWQgYnkgZHJhd2luZyBmaXJzdCBhbmQgbGFzdAoJREVfQVNTRVJUKGJ1ZmZlclNpemUgJSAoaW50KXNpemVvZihmbG9hdFs0XSkgPT0gMCk7CglnbC5kcmF3QXJyYXlzKEdMX1BPSU5UUywgMCwgMSk7CglnbC5kcmF3QXJyYXlzKEdMX1BPSU5UUywgYnVmZmVyU2l6ZSAvIChpbnQpc2l6ZW9mKGZsb2F0WzRdKSAtIDEsIDEpOwoKCUJhc2ljQnVmZmVyQ2FzZTxTYW1wbGVUeXBlPjo6d2FpdEdMUmVzdWx0cygpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4Kdm9pZCBCYXNpY1VwbG9hZENhc2U8U2FtcGxlVHlwZT46OmxvZ0FuZFNldFRlc3RSZXN1bHQgKGNvbnN0IHN0ZDo6dmVjdG9yPFVwbG9hZFNhbXBsZVJlc3VsdDxTYW1wbGVUeXBlPiA+JiByZXN1bHRzKQp7Cgljb25zdCBVcGxvYWRTYW1wbGVBbmFseXplUmVzdWx0CWFuYWx5c2lzCT0gYW5hbHl6ZVNhbXBsZVJlc3VsdHMobV90ZXN0Q3R4LmdldExvZygpLCByZXN1bHRzLCB0cnVlKTsKCgkvLyB3aXRoIHNtYWxsIGJ1ZmZlcnMsIHJlcG9ydCB0aGUgbWVkaWFuIHRyYW5zZmVyIHJhdGUgb2YgdGhlIHNhbXBsZXMKCS8vIHdpdGggbGFyZ2UgYnVmZmVycywgcmVwb3J0IHRoZSBleHBlY3RlZCBwcmVmb3JtYW5jZSBvZiBpbmZpbml0ZWx5IGxhcmdlIGJ1ZmZlcnMKCWNvbnN0IGZsb2F0CQkJCQkJcmF0ZQkJPSAobV9yZXN1bHRUeXBlID09IFJFU1VMVF9BU1lNUFRPVElDX1RSQU5TRkVSX1JBVEUpID8gKGFuYWx5c2lzLnRyYW5zZmVyUmF0ZUF0SW5maW5pdHkpIDogKGFuYWx5c2lzLnRyYW5zZmVyUmF0ZU1lZGlhbik7CgoJaWYgKHJhdGUgPT0gc3RkOjpudW1lcmljX2xpbWl0czxmbG9hdD46OmluZmluaXR5KCkpCgl7CgkJLy8gc2FtcGxlIHRpbWVzIGFyZSAxKSBpbnZhbGlkIG9yIDIpIHRpbWVyIHJlc29sdXRpb24gdG9vIGxvdwoJCS8vIHJlcG9ydCBzcGVlZCAwIGJ5dGVzIC8gcyBzaW5jZSByZWFsIHZhbHVlIGNhbm5vdCBiZSBkZXRlcm1pbmVkCgkJbV90ZXN0Q3R4LnNldFRlc3RSZXN1bHQoUVBfVEVTVF9SRVNVTFRfUEFTUywgZGU6OmZsb2F0VG9TdHJpbmcoMC4wZiwgMikuY19zdHIoKSk7Cgl9CgllbHNlCgl7CgkJLy8gcmVwb3J0IHRyYW5zZmVyIHJhdGUgaW4gTUIgLyBzCgkJbV90ZXN0Q3R4LnNldFRlc3RSZXN1bHQoUVBfVEVTVF9SRVNVTFRfUEFTUywgZGU6OmZsb2F0VG9TdHJpbmcocmF0ZSAvIDEwMjQuMGYgLyAxMDI0LjBmLCAyKS5jX3N0cigpKTsKCX0KfQoKY2xhc3MgUmVmZXJlbmNlTWVtY3B5Q2FzZSA6IHB1YmxpYyBCYXNpY1VwbG9hZENhc2U8U2luZ2xlT3BlcmF0aW9uRHVyYXRpb24+CnsKcHVibGljOgoJCQkJUmVmZXJlbmNlTWVtY3B5Q2FzZQkJKENvbnRleHQmIGN0eCwgY29uc3QgY2hhciogbmFtZSwgY29uc3QgY2hhciogZGVzYywgaW50IG1pbkJ1ZmZlclNpemUsIGludCBtYXhCdWZmZXJTaXplLCBpbnQgbnVtU2FtcGxlcywgYm9vbCBsYXJnZUJ1ZmZlcnNDYXNlKTsKCQkJCX5SZWZlcmVuY2VNZW1jcHlDYXNlCSh2b2lkKTsKCgl2b2lkCQlpbml0CQkJCQkodm9pZCk7Cgl2b2lkCQlkZWluaXQJCQkJCSh2b2lkKTsKcHJpdmF0ZToKCXZvaWQJCXRlc3RCdWZmZXJVcGxvYWQJCShVcGxvYWRTYW1wbGVSZXN1bHQ8U2luZ2xlT3BlcmF0aW9uRHVyYXRpb24+JiByZXN1bHQsIGludCBidWZmZXJTaXplKTsKCglzdGQ6OnZlY3RvcjxkZVVpbnQ4PiBtX2RzdEJ1ZjsKfTsKClJlZmVyZW5jZU1lbWNweUNhc2U6OlJlZmVyZW5jZU1lbWNweUNhc2UgKENvbnRleHQmIGN0eCwgY29uc3QgY2hhciogbmFtZSwgY29uc3QgY2hhciogZGVzYywgaW50IG1pbkJ1ZmZlclNpemUsIGludCBtYXhCdWZmZXJTaXplLCBpbnQgbnVtU2FtcGxlcywgYm9vbCBsYXJnZUJ1ZmZlcnNDYXNlKQoJOiBCYXNpY1VwbG9hZENhc2U8U2luZ2xlT3BlcmF0aW9uRHVyYXRpb24+CShjdHgsIG5hbWUsIGRlc2MsIG1pbkJ1ZmZlclNpemUsIG1heEJ1ZmZlclNpemUsIG51bVNhbXBsZXMsIDAsIENBU0VfTk9fQlVGRkVSUywgKGxhcmdlQnVmZmVyc0Nhc2UpID8gKFJFU1VMVF9BU1lNUFRPVElDX1RSQU5TRkVSX1JBVEUpIDogKFJFU1VMVF9NRURJQU5fVFJBTlNGRVJfUkFURSkpCgksIG1fZHN0QnVmCQkJCQkJCQkJKCkKewoJZGlzYWJsZUdMV2FybXVwKCk7Cn0KClJlZmVyZW5jZU1lbWNweUNhc2U6On5SZWZlcmVuY2VNZW1jcHlDYXNlICh2b2lkKQp7Cn0KCnZvaWQgUmVmZXJlbmNlTWVtY3B5Q2FzZTo6aW5pdCAodm9pZCkKewoJLy8gRGVzY3JpYmUgd2hhdCB0aGUgdGVzdCB0cmllcyB0byBkbwoJbV90ZXN0Q3R4LmdldExvZygpIDw8IHRjdTo6VGVzdExvZzo6TWVzc2FnZSA8PCAiVGVzdGluZyBwZXJmb3JtYW5jZSBvZiBtZW1jcHkoKS4iIDw8IHRjdTo6VGVzdExvZzo6RW5kTWVzc2FnZTsKCgltX2RzdEJ1Zi5yZXNpemUobV9idWZmZXJTaXplTWF4LCAweDAwKTsKCglCYXNpY1VwbG9hZENhc2U8U2luZ2xlT3BlcmF0aW9uRHVyYXRpb24+Ojppbml0KCk7Cn0KCnZvaWQgUmVmZXJlbmNlTWVtY3B5Q2FzZTo6ZGVpbml0ICh2b2lkKQp7CgltX2RzdEJ1ZiA9IHN0ZDo6dmVjdG9yPGRlVWludDg+KCk7CglCYXNpY1VwbG9hZENhc2U8U2luZ2xlT3BlcmF0aW9uRHVyYXRpb24+OjpkZWluaXQoKTsKfQoKdm9pZCBSZWZlcmVuY2VNZW1jcHlDYXNlOjp0ZXN0QnVmZmVyVXBsb2FkIChVcGxvYWRTYW1wbGVSZXN1bHQ8U2luZ2xlT3BlcmF0aW9uRHVyYXRpb24+JiByZXN1bHQsIGludCBidWZmZXJTaXplKQp7CgkvLyB3cml0ZQoJcmVzdWx0LmR1cmF0aW9uLnRvdGFsRHVyYXRpb24gPSBtZWRpYW5UaW1lTWVtY3B5KCZtX2RzdEJ1ZlswXSwgJm1femVyb0RhdGFbMF0sIGJ1ZmZlclNpemUpOwoJcmVzdWx0LmR1cmF0aW9uLmZpdFJlc3BvbnNlRHVyYXRpb24gPSByZXN1bHQuZHVyYXRpb24udG90YWxEdXJhdGlvbjsKCglyZXN1bHQud3JpdHRlblNpemUgPSBidWZmZXJTaXplOwp9CgpjbGFzcyBCdWZmZXJEYXRhVXBsb2FkQ2FzZSA6IHB1YmxpYyBCYXNpY1VwbG9hZENhc2U8U2luZ2xlT3BlcmF0aW9uRHVyYXRpb24+CnsKcHVibGljOgoJCQkJQnVmZmVyRGF0YVVwbG9hZENhc2UJKENvbnRleHQmIGN0eCwgY29uc3QgY2hhciogbmFtZSwgY29uc3QgY2hhciogZGVzYywgaW50IG1pbkJ1ZmZlclNpemUsIGludCBtYXhCdWZmZXJTaXplLCBpbnQgbnVtU2FtcGxlcywgZGVVaW50MzIgYnVmZmVyVXNhZ2UsIENhc2VUeXBlIGNhc2VUeXBlKTsKCQkJCX5CdWZmZXJEYXRhVXBsb2FkQ2FzZQkodm9pZCk7CgoJdm9pZAkJaW5pdAkJCQkJKHZvaWQpOwpwcml2YXRlOgoJdm9pZAkJdGVzdEJ1ZmZlclVwbG9hZAkJKFVwbG9hZFNhbXBsZVJlc3VsdDxTaW5nbGVPcGVyYXRpb25EdXJhdGlvbj4mIHJlc3VsdCwgaW50IGJ1ZmZlclNpemUpOwp9OwoKQnVmZmVyRGF0YVVwbG9hZENhc2U6OkJ1ZmZlckRhdGFVcGxvYWRDYXNlIChDb250ZXh0JiBjdHgsIGNvbnN0IGNoYXIqIG5hbWUsIGNvbnN0IGNoYXIqIGRlc2MsIGludCBtaW5CdWZmZXJTaXplLCBpbnQgbWF4QnVmZmVyU2l6ZSwgaW50IG51bVNhbXBsZXMsIGRlVWludDMyIGJ1ZmZlclVzYWdlLCBDYXNlVHlwZSBjYXNlVHlwZSkKCTogQmFzaWNVcGxvYWRDYXNlPFNpbmdsZU9wZXJhdGlvbkR1cmF0aW9uPihjdHgsIG5hbWUsIGRlc2MsIG1pbkJ1ZmZlclNpemUsIG1heEJ1ZmZlclNpemUsIG51bVNhbXBsZXMsIGJ1ZmZlclVzYWdlLCBjYXNlVHlwZSwgUkVTVUxUX01FRElBTl9UUkFOU0ZFUl9SQVRFKQp7Cn0KCkJ1ZmZlckRhdGFVcGxvYWRDYXNlOjp+QnVmZmVyRGF0YVVwbG9hZENhc2UgKHZvaWQpCnsKfQoKdm9pZCBCdWZmZXJEYXRhVXBsb2FkQ2FzZTo6aW5pdCAodm9pZCkKewoJLy8gRGVzY3JpYmUgd2hhdCB0aGUgdGVzdCB0cmllcyB0byBkbwoJbV90ZXN0Q3R4LmdldExvZygpIDw8IHRjdTo6VGVzdExvZzo6TWVzc2FnZSA8PCAiVGVzdGluZyBnbEJ1ZmZlckRhdGEoKSBmdW5jdGlvbi4iIDw8IHRjdTo6VGVzdExvZzo6RW5kTWVzc2FnZTsKCglCYXNpY1VwbG9hZENhc2U8U2luZ2xlT3BlcmF0aW9uRHVyYXRpb24+Ojppbml0KCk7Cn0KCnZvaWQgQnVmZmVyRGF0YVVwbG9hZENhc2U6OnRlc3RCdWZmZXJVcGxvYWQgKFVwbG9hZFNhbXBsZVJlc3VsdDxTaW5nbGVPcGVyYXRpb25EdXJhdGlvbj4mIHJlc3VsdCwgaW50IGJ1ZmZlclNpemUpCnsKCWNvbnN0IGdsdzo6RnVuY3Rpb25zJiBnbCA9IG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCkuZ2V0RnVuY3Rpb25zKCk7CgoJZ2wuYmluZEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIsIG1fYnVmZmVySUQpOwoKCS8vIHVwbG9hZAoJewoJCWRlVWludDY0IHN0YXJ0VGltZTsKCQlkZVVpbnQ2NCBlbmRUaW1lOwoKCQlzdGFydFRpbWUgPSBkZUdldE1pY3Jvc2Vjb25kcygpOwoJCWdsLmJ1ZmZlckRhdGEoR0xfQVJSQVlfQlVGRkVSLCBidWZmZXJTaXplLCAmbV96ZXJvRGF0YVswXSwgbV9idWZmZXJVc2FnZSk7CgkJZW5kVGltZSA9IGRlR2V0TWljcm9zZWNvbmRzKCk7CgoJCXJlc3VsdC5kdXJhdGlvbi50b3RhbER1cmF0aW9uID0gZW5kVGltZSAtIHN0YXJ0VGltZTsKCQlyZXN1bHQuZHVyYXRpb24uZml0UmVzcG9uc2VEdXJhdGlvbiA9IHJlc3VsdC5kdXJhdGlvbi50b3RhbER1cmF0aW9uOwoJCXJlc3VsdC53cml0dGVuU2l6ZSA9IGJ1ZmZlclNpemU7Cgl9Cn0KCmNsYXNzIEJ1ZmZlclN1YkRhdGFVcGxvYWRDYXNlIDogcHVibGljIEJhc2ljVXBsb2FkQ2FzZTxTaW5nbGVPcGVyYXRpb25EdXJhdGlvbj4KewpwdWJsaWM6CgllbnVtIEZsYWdzCgl7CgkJRkxBR19GVUxMX1VQTE9BRAkJCT0gMHgwMSwKCQlGTEFHX1BBUlRJQUxfVVBMT0FECQkJPSAweDAyLAoJCUZMQUdfSU5WQUxJREFURV9CRUZPUkVfVVNFCT0gMHgwNCwKCX07CgoJCQkJQnVmZmVyU3ViRGF0YVVwbG9hZENhc2UJCShDb250ZXh0JiBjdHgsIGNvbnN0IGNoYXIqIG5hbWUsIGNvbnN0IGNoYXIqIGRlc2MsIGludCBtaW5CdWZmZXJTaXplLCBpbnQgbWF4QnVmZmVyU2l6ZSwgaW50IG51bVNhbXBsZXMsIGRlVWludDMyIGJ1ZmZlclVzYWdlLCBDYXNlVHlwZSBwYXJlbnRDYXNlLCBpbnQgZmxhZ3MpOwoJCQkJfkJ1ZmZlclN1YkRhdGFVcGxvYWRDYXNlCSh2b2lkKTsKCgl2b2lkCQlpbml0CQkJCQkJKHZvaWQpOwpwcml2YXRlOgoJdm9pZAkJdGVzdEJ1ZmZlclVwbG9hZAkJCShVcGxvYWRTYW1wbGVSZXN1bHQ8U2luZ2xlT3BlcmF0aW9uRHVyYXRpb24+JiByZXN1bHQsIGludCBidWZmZXJTaXplKTsKCgljb25zdCBib29sCW1fZnVsbFVwbG9hZDsKCWNvbnN0IGJvb2wJbV9pbnZhbGlkYXRlQmVmb3JlVXNlOwp9OwoKQnVmZmVyU3ViRGF0YVVwbG9hZENhc2U6OkJ1ZmZlclN1YkRhdGFVcGxvYWRDYXNlIChDb250ZXh0JiBjdHgsIGNvbnN0IGNoYXIqIG5hbWUsIGNvbnN0IGNoYXIqIGRlc2MsIGludCBtaW5CdWZmZXJTaXplLCBpbnQgbWF4QnVmZmVyU2l6ZSwgaW50IG51bVNhbXBsZXMsIGRlVWludDMyIGJ1ZmZlclVzYWdlLCBDYXNlVHlwZSBwYXJlbnRDYXNlLCBpbnQgZmxhZ3MpCgk6IEJhc2ljVXBsb2FkQ2FzZTxTaW5nbGVPcGVyYXRpb25EdXJhdGlvbj4JKGN0eCwgbmFtZSwgZGVzYywgbWluQnVmZmVyU2l6ZSwgbWF4QnVmZmVyU2l6ZSwgbnVtU2FtcGxlcywgYnVmZmVyVXNhZ2UsIHBhcmVudENhc2UsIFJFU1VMVF9NRURJQU5fVFJBTlNGRVJfUkFURSkKCSwgbV9mdWxsVXBsb2FkCQkJCQkJCQkoKGZsYWdzICYgRkxBR19GVUxMX1VQTE9BRCkgIT0gMCkKCSwgbV9pbnZhbGlkYXRlQmVmb3JlVXNlCQkJCQkJKChmbGFncyAmIEZMQUdfSU5WQUxJREFURV9CRUZPUkVfVVNFKSAhPSAwKQp7CglERV9BU1NFUlQoKGZsYWdzICYgKEZMQUdfRlVMTF9VUExPQUQgfCBGTEFHX1BBUlRJQUxfVVBMT0FEKSkgIT0gMCk7CglERV9BU1NFUlQoKGZsYWdzICYgKEZMQUdfRlVMTF9VUExPQUQgfCBGTEFHX1BBUlRJQUxfVVBMT0FEKSkgIT0gKEZMQUdfRlVMTF9VUExPQUQgfCBGTEFHX1BBUlRJQUxfVVBMT0FEKSk7Cn0KCkJ1ZmZlclN1YkRhdGFVcGxvYWRDYXNlOjp+QnVmZmVyU3ViRGF0YVVwbG9hZENhc2UgKHZvaWQpCnsKfQoKdm9pZCBCdWZmZXJTdWJEYXRhVXBsb2FkQ2FzZTo6aW5pdCAodm9pZCkKewoJLy8gRGVzY3JpYmUgd2hhdCB0aGUgdGVzdCB0cmllcyB0byBkbwoJbV90ZXN0Q3R4LmdldExvZygpCgkJPDwgdGN1OjpUZXN0TG9nOjpNZXNzYWdlCgkJPDwgIlRlc3RpbmcgZ2xCdWZmZXJTdWJEYXRhKCkgZnVuY3Rpb24gY2FsbCBwZXJmb3JtYW5jZS4gIgoJCTw8ICgobV9mdWxsVXBsb2FkKSA/ICgiVGhlIHdob2xlIGJ1ZmZlciBpcyB1cGRhdGVkIHdpdGggZ2xCdWZmZXJTdWJEYXRhLiAiKSA6ICgiSGFsZiBvZiB0aGUgYnVmZmVyIGRhdGEgaXMgdXBkYXRlZCB3aXRoIGdsQnVmZmVyU3ViRGF0YS4gIikpCgkJPDwgKChtX2ludmFsaWRhdGVCZWZvcmVVc2UpID8gKCJUaGUgYnVmZmVyIGlzIGNsZWFyZWQgd2l0aCBnbEJ1ZmZlckRhdGEoLi4uLCBOVUxMKSBiZWZvcmUgZ2xCdWZmZXJTdWJEYXRhIHVwbG9hZC4iKSA6ICgiIikpIDw8ICJcbiIKCQk8PCB0Y3U6OlRlc3RMb2c6OkVuZE1lc3NhZ2U7CgoJQmFzaWNVcGxvYWRDYXNlPFNpbmdsZU9wZXJhdGlvbkR1cmF0aW9uPjo6aW5pdCgpOwp9Cgp2b2lkIEJ1ZmZlclN1YkRhdGFVcGxvYWRDYXNlOjp0ZXN0QnVmZmVyVXBsb2FkIChVcGxvYWRTYW1wbGVSZXN1bHQ8U2luZ2xlT3BlcmF0aW9uRHVyYXRpb24+JiByZXN1bHQsIGludCBidWZmZXJTaXplKQp7Cgljb25zdCBnbHc6OkZ1bmN0aW9ucyYgZ2wgPSBtX2NvbnRleHQuZ2V0UmVuZGVyQ29udGV4dCgpLmdldEZ1bmN0aW9ucygpOwoKCWdsLmJpbmRCdWZmZXIoR0xfQVJSQVlfQlVGRkVSLCBtX2J1ZmZlcklEKTsKCgkvLyAiaW52YWxpZGF0ZSIsIHVwbG9hZCBudWxsCglpZiAobV9pbnZhbGlkYXRlQmVmb3JlVXNlKQoJCWdsLmJ1ZmZlckRhdGEoR0xfQVJSQVlfQlVGRkVSLCBidWZmZXJTaXplLCBERV9OVUxMLCBtX2J1ZmZlclVzYWdlKTsKCgkvLyB1cGxvYWQKCXsKCQlkZVVpbnQ2NCBzdGFydFRpbWU7CgkJZGVVaW50NjQgZW5kVGltZTsKCgkJc3RhcnRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCgkJaWYgKG1fZnVsbFVwbG9hZCkKCQkJZ2wuYnVmZmVyU3ViRGF0YShHTF9BUlJBWV9CVUZGRVIsIDAsIGJ1ZmZlclNpemUsICZtX3plcm9EYXRhWzBdKTsKCQllbHNlCgkJewoJCQkvLyB1cGxvYWQgdG8gYnVmZmVyIGNlbnRlcgoJCQlnbC5idWZmZXJTdWJEYXRhKEdMX0FSUkFZX0JVRkZFUiwgYnVmZmVyU2l6ZSAvIDQsIGJ1ZmZlclNpemUgLyAyLCAmbV96ZXJvRGF0YVswXSk7CgkJfQoKCQllbmRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCgkJcmVzdWx0LmR1cmF0aW9uLnRvdGFsRHVyYXRpb24gPSBlbmRUaW1lIC0gc3RhcnRUaW1lOwoJCXJlc3VsdC5kdXJhdGlvbi5maXRSZXNwb25zZUR1cmF0aW9uID0gcmVzdWx0LmR1cmF0aW9uLnRvdGFsRHVyYXRpb247CgoJCWlmIChtX2Z1bGxVcGxvYWQpCgkJCXJlc3VsdC53cml0dGVuU2l6ZSA9IGJ1ZmZlclNpemU7CgkJZWxzZQoJCQlyZXN1bHQud3JpdHRlblNpemUgPSBidWZmZXJTaXplIC8gMjsKCX0KfQoKY2xhc3MgTWFwQnVmZmVyUmFuZ2VDYXNlIDogcHVibGljIEJhc2ljVXBsb2FkQ2FzZTxNYXBCdWZmZXJSYW5nZUR1cmF0aW9uPgp7CnB1YmxpYzoKCWVudW0gRmxhZ3MKCXsKCQlGTEFHX1BBUlRJQUwJCQkJCQk9IDB4MDEsCgkJRkxBR19NQU5VQUxfSU5WQUxJREFUSU9OCQkJPSAweDAyLAoJCUZMQUdfVVNFX1VOVVNFRF9VTlNQRUNJRklFRF9CVUZGRVIJPSAweDA0LAoJCUZMQUdfVVNFX1VOVVNFRF9TUEVDSUZJRURfQlVGRkVSCT0gMHgwOCwKCX07CgoJCQkJCU1hcEJ1ZmZlclJhbmdlQ2FzZQkJCShDb250ZXh0JiBjdHgsIGNvbnN0IGNoYXIqIG5hbWUsIGNvbnN0IGNoYXIqIGRlc2MsIGludCBtaW5CdWZmZXJTaXplLCBpbnQgbWF4QnVmZmVyU2l6ZSwgaW50IG51bVNhbXBsZXMsIGRlVWludDMyIGJ1ZmZlclVzYWdlLCBkZVVpbnQzMiBtYXBGbGFncywgaW50IGNhc2VGbGFncyk7CgkJCQkJfk1hcEJ1ZmZlclJhbmdlQ2FzZQkJCSh2b2lkKTsKCgl2b2lkCQkJaW5pdAkJCQkJCSh2b2lkKTsKcHJpdmF0ZToKCXN0YXRpYyBDYXNlVHlwZSBnZXRCYXNlQ2FzZVR5cGUJCQkJKGludCBjYXNlRmxhZ3MpOwoJc3RhdGljIGludAkJZ2V0QmFzZUZsYWdzCQkJCShkZVVpbnQzMiBtYXBGbGFncywgaW50IGNhc2VGbGFncyk7CgoJdm9pZAkJCXRlc3RCdWZmZXJVcGxvYWQJCQkoVXBsb2FkU2FtcGxlUmVzdWx0PE1hcEJ1ZmZlclJhbmdlRHVyYXRpb24+JiByZXN1bHQsIGludCBidWZmZXJTaXplKTsKCXZvaWQJCQlhdHRlbXB0QnVmZmVyTWFwCQkJKFVwbG9hZFNhbXBsZVJlc3VsdDxNYXBCdWZmZXJSYW5nZUR1cmF0aW9uPiYgcmVzdWx0LCBpbnQgYnVmZmVyU2l6ZSk7CgoJY29uc3QgYm9vbAkJbV9tYW51YWxJbnZhbGlkYXRpb247Cgljb25zdCBib29sCQltX2Z1bGxVcGxvYWQ7Cgljb25zdCBib29sCQltX3VzZVVudXNlZFVuc3BlY2lmaWVkQnVmZmVyOwoJY29uc3QgYm9vbAkJbV91c2VVbnVzZWRTcGVjaWZpZWRCdWZmZXI7Cgljb25zdCBkZVVpbnQzMgltX21hcEZsYWdzOwoJaW50CQkJCW1fdW5tYXBGYWlsdXJlczsKfTsKCk1hcEJ1ZmZlclJhbmdlQ2FzZTo6TWFwQnVmZmVyUmFuZ2VDYXNlIChDb250ZXh0JiBjdHgsIGNvbnN0IGNoYXIqIG5hbWUsIGNvbnN0IGNoYXIqIGRlc2MsIGludCBtaW5CdWZmZXJTaXplLCBpbnQgbWF4QnVmZmVyU2l6ZSwgaW50IG51bVNhbXBsZXMsIGRlVWludDMyIGJ1ZmZlclVzYWdlLCBkZVVpbnQzMiBtYXBGbGFncywgaW50IGNhc2VGbGFncykKCTogQmFzaWNVcGxvYWRDYXNlPE1hcEJ1ZmZlclJhbmdlRHVyYXRpb24+CShjdHgsIG5hbWUsIGRlc2MsIG1pbkJ1ZmZlclNpemUsIG1heEJ1ZmZlclNpemUsIG51bVNhbXBsZXMsIGJ1ZmZlclVzYWdlLCBnZXRCYXNlQ2FzZVR5cGUoY2FzZUZsYWdzKSwgUkVTVUxUX01FRElBTl9UUkFOU0ZFUl9SQVRFLCBnZXRCYXNlRmxhZ3MobWFwRmxhZ3MsIGNhc2VGbGFncykpCgksIG1fbWFudWFsSW52YWxpZGF0aW9uCQkJCQkJKChjYXNlRmxhZ3MmRkxBR19NQU5VQUxfSU5WQUxJREFUSU9OKSAhPSAwKQoJLCBtX2Z1bGxVcGxvYWQJCQkJCQkJCSgoY2FzZUZsYWdzJkZMQUdfUEFSVElBTCkgPT0gMCkKCSwgbV91c2VVbnVzZWRVbnNwZWNpZmllZEJ1ZmZlcgkJCQkoKGNhc2VGbGFncyZGTEFHX1VTRV9VTlVTRURfVU5TUEVDSUZJRURfQlVGRkVSKSAhPSAwKQoJLCBtX3VzZVVudXNlZFNwZWNpZmllZEJ1ZmZlcgkJCQkoKGNhc2VGbGFncyZGTEFHX1VTRV9VTlVTRURfU1BFQ0lGSUVEX0JVRkZFUikgIT0gMCkKCSwgbV9tYXBGbGFncwkJCQkJCQkJKG1hcEZsYWdzKQoJLCBtX3VubWFwRmFpbHVyZXMJCQkJCQkJKDApCnsKCURFX0FTU0VSVCghKG1fdXNlVW51c2VkVW5zcGVjaWZpZWRCdWZmZXIgJiYgbV91c2VVbnVzZWRTcGVjaWZpZWRCdWZmZXIpKTsKCURFX0FTU0VSVCghKChtX3VzZVVudXNlZFVuc3BlY2lmaWVkQnVmZmVyIHx8IG1fdXNlVW51c2VkU3BlY2lmaWVkQnVmZmVyKSAmJiBtX21hbnVhbEludmFsaWRhdGlvbikpOwp9CgpNYXBCdWZmZXJSYW5nZUNhc2U6On5NYXBCdWZmZXJSYW5nZUNhc2UgKHZvaWQpCnsKfQoKdm9pZCBNYXBCdWZmZXJSYW5nZUNhc2U6OmluaXQgKHZvaWQpCnsKCS8vIERlc2NyaWJlIHdoYXQgdGhlIHRlc3QgdHJpZXMgdG8gZG8KCW1fdGVzdEN0eC5nZXRMb2coKQoJCTw8IHRjdTo6VGVzdExvZzo6TWVzc2FnZQoJCTw8ICJUZXN0aW5nIGdsTWFwQnVmZmVyUmFuZ2UoKSBhbmQgZ2xVbm1hcEJ1ZmZlcigpIGZ1bmN0aW9uIGNhbGwgcGVyZm9ybWFuY2UuXG4iCgkJPDwgKChtX2Z1bGxVcGxvYWQpID8gKCJUaGUgd2hvbGUgYnVmZmVyIGlzIG1hcHBlZC4iKSA6ICgiSGFsZiBvZiB0aGUgYnVmZmVyIGlzIG1hcHBlZC4iKSkgPDwgIlxuIgoJCTw8ICgobV91c2VVbnVzZWRVbnNwZWNpZmllZEJ1ZmZlcikgPyAoIlRoZSBidWZmZXIgaGFzIG5vdCBiZWVuIHVzZWQgYmVmb3JlIG1hcHBpbmcgYW5kIGlzIGFsbG9jYXRlZCB3aXRoIHVuc3BlY2lmaWVkIGNvbnRlbnRzLlxuIikgOiAoIiIpKQoJCTw8ICgobV91c2VVbnVzZWRTcGVjaWZpZWRCdWZmZXIpID8gKCJUaGUgYnVmZmVyIGhhcyBub3QgYmVlbiB1c2VkIGJlZm9yZSBtYXBwaW5nIGFuZCBpcyBhbGxvY2F0ZWQgd2l0aCBzcGVjaWZpZWQgY29udGVudHMuXG4iKSA6ICgiIikpCgkJPDwgKCghbV91c2VVbnVzZWRTcGVjaWZpZWRCdWZmZXIgJiYgIW1fdXNlVW51c2VkVW5zcGVjaWZpZWRCdWZmZXIpID8gKCJUaGUgYnVmZmVyIGhhcyBwcmV2aW91c2x5IGJlZW4gdXNlZCBpbiBhIGRyYXdpbmcgb3BlcmF0aW9uLlxuIikgOiAoIiIpKQoJCTw8ICgobV9tYW51YWxJbnZhbGlkYXRpb24pID8gKCJUaGUgYnVmZmVyIGlzIGNsZWFyZWQgd2l0aCBnbEJ1ZmZlckRhdGEoLi4uLCBOVUxMKSBiZWZvcmUgbWFwcGluZy5cbiIpIDogKCIiKSkKCQk8PCAiTWFwIGJpdHM6XG4iCgkJPDwgKChtX21hcEZsYWdzICYgR0xfTUFQX1dSSVRFX0JJVCkgPyAoIlx0R0xfTUFQX1dSSVRFX0JJVFxuIikgOiAoIiIpKQoJCTw8ICgobV9tYXBGbGFncyAmIEdMX01BUF9SRUFEX0JJVCkgPyAoIlx0R0xfTUFQX1JFQURfQklUXG4iKSA6ICgiIikpCgkJPDwgKChtX21hcEZsYWdzICYgR0xfTUFQX0lOVkFMSURBVEVfUkFOR0VfQklUKSA/ICgiXHRHTF9NQVBfSU5WQUxJREFURV9SQU5HRV9CSVRcbiIpIDogKCIiKSkKCQk8PCAoKG1fbWFwRmxhZ3MgJiBHTF9NQVBfSU5WQUxJREFURV9CVUZGRVJfQklUKSA/ICgiXHRHTF9NQVBfSU5WQUxJREFURV9CVUZGRVJfQklUXG4iKSA6ICgiIikpCgkJPDwgKChtX21hcEZsYWdzICYgR0xfTUFQX1VOU1lOQ0hST05JWkVEX0JJVCkgPyAoIlx0R0xfTUFQX1VOU1lOQ0hST05JWkVEX0JJVFxuIikgOiAoIiIpKQoJCTw8IHRjdTo6VGVzdExvZzo6RW5kTWVzc2FnZTsKCglCYXNpY1VwbG9hZENhc2U8TWFwQnVmZmVyUmFuZ2VEdXJhdGlvbj46OmluaXQoKTsKfQoKTWFwQnVmZmVyUmFuZ2VDYXNlOjpDYXNlVHlwZSBNYXBCdWZmZXJSYW5nZUNhc2U6OmdldEJhc2VDYXNlVHlwZSAoaW50IGNhc2VGbGFncykKewoJaWYgKChjYXNlRmxhZ3MgJiBGTEFHX1VTRV9VTlVTRURfVU5TUEVDSUZJRURfQlVGRkVSKSA9PSAwICYmIChjYXNlRmxhZ3MgJiBGTEFHX1VTRV9VTlVTRURfU1BFQ0lGSUVEX0JVRkZFUikgPT0gMCkKCQlyZXR1cm4gQ0FTRV9VU0VEX0JVRkZFUjsKCWVsc2UKCQlyZXR1cm4gQ0FTRV9ORVdfQlVGRkVSOwp9CgppbnQgTWFwQnVmZmVyUmFuZ2VDYXNlOjpnZXRCYXNlRmxhZ3MgKGRlVWludDMyIG1hcEZsYWdzLCBpbnQgY2FzZUZsYWdzKQp7CglpbnQgZmxhZ3MgPSBGTEFHX0RPTlRfTE9HX0JVRkZFUl9JTkZPOwoKCS8vIElmIGJ1ZmZlciBjb250YWlucyB1bnNwZWNpZmllZCBkYXRhIHdoZW4gaXQgaXMgc291cmNlZCAoaS5lIGRyYXduKQoJLy8gcmVzdWx0cyBhcmUgdW5kZWZpbmVkLCBhbmQgc3lzdGVtIGVycm9ycyBtYXkgb2NjdXIuIFNpZ25hbCBwYXJlbnQKCS8vIGNsYXNzIHRvIHRha2UgdGhpcyBpbnRvIGFjY291bnQKCWlmIChjYXNlRmxhZ3MgJiBGTEFHX1BBUlRJQUwpCgl7CgkJaWYgKChtYXBGbGFncyAmIEdMX01BUF9JTlZBTElEQVRFX0JVRkZFUl9CSVQpICE9IDAJCQl8fAoJCQkoY2FzZUZsYWdzICYgRkxBR19NQU5VQUxfSU5WQUxJREFUSU9OKSAhPSAwCQkJCXx8CgkJCShjYXNlRmxhZ3MgJiBGTEFHX1VTRV9VTlVTRURfVU5TUEVDSUZJRURfQlVGRkVSKSAhPSAwKQoJCXsKCQkJZmxhZ3MgfD0gRkxBR19SRVNVTFRfQlVGRkVSX1VOU1BFQ0lGSUVEX0NPTlRFTlQ7CgkJfQoJfQoKCXJldHVybiBmbGFnczsKfQoKdm9pZCBNYXBCdWZmZXJSYW5nZUNhc2U6OnRlc3RCdWZmZXJVcGxvYWQgKFVwbG9hZFNhbXBsZVJlc3VsdDxNYXBCdWZmZXJSYW5nZUR1cmF0aW9uPiYgcmVzdWx0LCBpbnQgYnVmZmVyU2l6ZSkKewoJY29uc3QgaW50IHVubWFwRmFpbHVyZVRocmVzaG9sZCA9IDQ7CgoJZm9yICg7IG1fdW5tYXBGYWlsdXJlcyA8IHVubWFwRmFpbHVyZVRocmVzaG9sZDsgKyttX3VubWFwRmFpbHVyZXMpCgl7CgkJdHJ5CgkJewoJCQlhdHRlbXB0QnVmZmVyTWFwKHJlc3VsdCwgYnVmZmVyU2l6ZSk7CgkJCXJldHVybjsKCQl9CgkJY2F0Y2ggKFVubWFwRmFpbHVyZUVycm9yJikKCQl7CgkJfQoJfQoKCXRocm93IHRjdTo6VGVzdEVycm9yKCJVbm1hcHBpbmcgZmFpbHVyZXMgZXhjZWVkZWQgbGltaXQiKTsKfQoKdm9pZCBNYXBCdWZmZXJSYW5nZUNhc2U6OmF0dGVtcHRCdWZmZXJNYXAgKFVwbG9hZFNhbXBsZVJlc3VsdDxNYXBCdWZmZXJSYW5nZUR1cmF0aW9uPiYgcmVzdWx0LCBpbnQgYnVmZmVyU2l6ZSkKewoJY29uc3QgZ2x3OjpGdW5jdGlvbnMmIGdsID0gbV9jb250ZXh0LmdldFJlbmRlckNvbnRleHQoKS5nZXRGdW5jdGlvbnMoKTsKCglnbC5iaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgbV9idWZmZXJJRCk7CgoJaWYgKG1fZnVsbFVwbG9hZCkKCQlyZXN1bHQud3JpdHRlblNpemUgPSBidWZmZXJTaXplOwoJZWxzZQoJCXJlc3VsdC53cml0dGVuU2l6ZSA9IGJ1ZmZlclNpemUgLyAyOwoKCS8vIENyZWF0ZSB1bnVzZWQgYnVmZmVyCgoJaWYgKG1fbWFudWFsSW52YWxpZGF0aW9uIHx8IG1fdXNlVW51c2VkVW5zcGVjaWZpZWRCdWZmZXIpCgl7CgkJZGVVaW50NjQgc3RhcnRUaW1lOwoJCWRlVWludDY0IGVuZFRpbWU7CgoJCS8vICJpbnZhbGlkYXRlIiBvciBhbGxvY2F0ZSwgdXBsb2FkIG51bGwKCQlzdGFydFRpbWUgPSBkZUdldE1pY3Jvc2Vjb25kcygpOwoJCWdsLmJ1ZmZlckRhdGEoR0xfQVJSQVlfQlVGRkVSLCBidWZmZXJTaXplLCBERV9OVUxMLCBtX2J1ZmZlclVzYWdlKTsKCQllbmRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCgkJcmVzdWx0LmR1cmF0aW9uLmFsbG9jRHVyYXRpb24gPSBlbmRUaW1lIC0gc3RhcnRUaW1lOwoJfQoJZWxzZSBpZiAobV91c2VVbnVzZWRTcGVjaWZpZWRCdWZmZXIpCgl7CgkJZGVVaW50NjQgc3RhcnRUaW1lOwoJCWRlVWludDY0IGVuZFRpbWU7CgoJCS8vIFNwZWNpZnkgYnVmZmVyIGNvbnRlbnRzCgkJc3RhcnRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCQlnbC5idWZmZXJEYXRhKEdMX0FSUkFZX0JVRkZFUiwgYnVmZmVyU2l6ZSwgJm1femVyb0RhdGFbMF0sIG1fYnVmZmVyVXNhZ2UpOwoJCWVuZFRpbWUgPSBkZUdldE1pY3Jvc2Vjb25kcygpOwoKCQlyZXN1bHQuZHVyYXRpb24uYWxsb2NEdXJhdGlvbiA9IGVuZFRpbWUgLSBzdGFydFRpbWU7Cgl9CgllbHNlCgl7CgkJLy8gTm8gYWxsb2MsIG5vIHRpbWUKCQlyZXN1bHQuZHVyYXRpb24uYWxsb2NEdXJhdGlvbiA9IDA7Cgl9CgoJLy8gdXBsb2FkCgl7CgkJdm9pZCogbWFwUHRyOwoKCQkvLyBNYXAKCQl7CgkJCWRlVWludDY0IHN0YXJ0VGltZTsKCQkJZGVVaW50NjQgZW5kVGltZTsKCgkJCXN0YXJ0VGltZSA9IGRlR2V0TWljcm9zZWNvbmRzKCk7CgkJCWlmIChtX2Z1bGxVcGxvYWQpCgkJCQltYXBQdHIgPSBnbC5tYXBCdWZmZXJSYW5nZShHTF9BUlJBWV9CVUZGRVIsIDAsIHJlc3VsdC53cml0dGVuU2l6ZSwgbV9tYXBGbGFncyk7CgkJCWVsc2UKCQkJewoJCQkJLy8gdXBsb2FkIHRvIGJ1ZmZlciBjZW50ZXIKCQkJCW1hcFB0ciA9IGdsLm1hcEJ1ZmZlclJhbmdlKEdMX0FSUkFZX0JVRkZFUiwgYnVmZmVyU2l6ZSAvIDQsIHJlc3VsdC53cml0dGVuU2l6ZSwgbV9tYXBGbGFncyk7CgkJCX0KCQkJZW5kVGltZSA9IGRlR2V0TWljcm9zZWNvbmRzKCk7CgoJCQlpZiAoIW1hcFB0cikKCQkJCXRocm93IHRjdTo6RXhjZXB0aW9uKCJNYXBCdWZmZXJSYW5nZSByZXR1cm5lZCBOVUxMIik7CgoJCQlyZXN1bHQuZHVyYXRpb24ubWFwRHVyYXRpb24gPSBlbmRUaW1lIC0gc3RhcnRUaW1lOwoJCX0KCgkJLy8gV3JpdGUKCQl7CgkJCXJlc3VsdC5kdXJhdGlvbi53cml0ZUR1cmF0aW9uID0gbWVkaWFuVGltZU1lbWNweShtYXBQdHIsICZtX3plcm9EYXRhWzBdLCByZXN1bHQud3JpdHRlblNpemUpOwoJCX0KCgkJLy8gVW5tYXAKCQl7CgkJCWRlVWludDY0CQlzdGFydFRpbWU7CgkJCWRlVWludDY0CQllbmRUaW1lOwoJCQlnbHc6OkdMYm9vbGVhbgl1bm1hcFN1Y2Nlc3NmdWw7CgoJCQlzdGFydFRpbWUgPSBkZUdldE1pY3Jvc2Vjb25kcygpOwoJCQl1bm1hcFN1Y2Nlc3NmdWwgPSBnbC51bm1hcEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIpOwoJCQllbmRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCgkJCS8vIGlmIHVubWFwcGluZyBmYWlscywganVzdCB0cnkgYWdhaW4gbGF0ZXIKCQkJaWYgKCF1bm1hcFN1Y2Nlc3NmdWwpCgkJCQl0aHJvdyBVbm1hcEZhaWx1cmVFcnJvcigpOwoKCQkJcmVzdWx0LmR1cmF0aW9uLnVubWFwRHVyYXRpb24gPSBlbmRUaW1lIC0gc3RhcnRUaW1lOwoJCX0KCgkJcmVzdWx0LmR1cmF0aW9uLnRvdGFsRHVyYXRpb24gPSByZXN1bHQuZHVyYXRpb24ubWFwRHVyYXRpb24gKyByZXN1bHQuZHVyYXRpb24ud3JpdGVEdXJhdGlvbiArIHJlc3VsdC5kdXJhdGlvbi51bm1hcER1cmF0aW9uICsgcmVzdWx0LmR1cmF0aW9uLmFsbG9jRHVyYXRpb247CgkJcmVzdWx0LmR1cmF0aW9uLmZpdFJlc3BvbnNlRHVyYXRpb24gPSByZXN1bHQuZHVyYXRpb24udG90YWxEdXJhdGlvbjsKCX0KfQoKY2xhc3MgTWFwQnVmZmVyUmFuZ2VGbHVzaENhc2UgOiBwdWJsaWMgQmFzaWNVcGxvYWRDYXNlPE1hcEJ1ZmZlclJhbmdlRmx1c2hEdXJhdGlvbj4KewpwdWJsaWM6CgllbnVtIEZsYWdzCgl7CgkJRkxBR19QQVJUSUFMCQkJCQkJPSAweDAxLAoJCUZMQUdfRkxVU0hfSU5fUEFSVFMJCQkJCT0gMHgwMiwKCQlGTEFHX1VTRV9VTlVTRURfVU5TUEVDSUZJRURfQlVGRkVSCT0gMHgwNCwKCQlGTEFHX1VTRV9VTlVTRURfU1BFQ0lGSUVEX0JVRkZFUgk9IDB4MDgsCgkJRkxBR19GTFVTSF9QQVJUSUFMCQkJCQk9IDB4MTAsCgl9OwoKCQkJCQlNYXBCdWZmZXJSYW5nZUZsdXNoQ2FzZQkJKENvbnRleHQmIGN0eCwgY29uc3QgY2hhciogbmFtZSwgY29uc3QgY2hhciogZGVzYywgaW50IG1pbkJ1ZmZlclNpemUsIGludCBtYXhCdWZmZXJTaXplLCBpbnQgbnVtU2FtcGxlcywgZGVVaW50MzIgYnVmZmVyVXNhZ2UsIGRlVWludDMyIG1hcEZsYWdzLCBpbnQgY2FzZUZsYWdzKTsKCQkJCQl+TWFwQnVmZmVyUmFuZ2VGbHVzaENhc2UJKHZvaWQpOwoKCXZvaWQJCQlpbml0CQkJCQkJKHZvaWQpOwpwcml2YXRlOgoJc3RhdGljIENhc2VUeXBlIGdldEJhc2VDYXNlVHlwZQkJCQkoaW50IGNhc2VGbGFncyk7CglzdGF0aWMgaW50CQlnZXRCYXNlRmxhZ3MJCQkJKGRlVWludDMyIG1hcEZsYWdzLCBpbnQgY2FzZUZsYWdzKTsKCgl2b2lkCQkJdGVzdEJ1ZmZlclVwbG9hZAkJCShVcGxvYWRTYW1wbGVSZXN1bHQ8TWFwQnVmZmVyUmFuZ2VGbHVzaER1cmF0aW9uPiYgcmVzdWx0LCBpbnQgYnVmZmVyU2l6ZSk7Cgl2b2lkCQkJYXR0ZW1wdEJ1ZmZlck1hcAkJCShVcGxvYWRTYW1wbGVSZXN1bHQ8TWFwQnVmZmVyUmFuZ2VGbHVzaER1cmF0aW9uPiYgcmVzdWx0LCBpbnQgYnVmZmVyU2l6ZSk7CgoJY29uc3QgYm9vbAkJbV9mdWxsVXBsb2FkOwoJY29uc3QgYm9vbAkJbV9mbHVzaEluUGFydHM7Cgljb25zdCBib29sCQltX2ZsdXNoUGFydGlhbDsKCWNvbnN0IGJvb2wJCW1fdXNlVW51c2VkVW5zcGVjaWZpZWRCdWZmZXI7Cgljb25zdCBib29sCQltX3VzZVVudXNlZFNwZWNpZmllZEJ1ZmZlcjsKCWNvbnN0IGRlVWludDMyCW1fbWFwRmxhZ3M7CglpbnQJCQkJbV91bm1hcEZhaWx1cmVzOwp9OwoKTWFwQnVmZmVyUmFuZ2VGbHVzaENhc2U6Ok1hcEJ1ZmZlclJhbmdlRmx1c2hDYXNlIChDb250ZXh0JiBjdHgsIGNvbnN0IGNoYXIqIG5hbWUsIGNvbnN0IGNoYXIqIGRlc2MsIGludCBtaW5CdWZmZXJTaXplLCBpbnQgbWF4QnVmZmVyU2l6ZSwgaW50IG51bVNhbXBsZXMsIGRlVWludDMyIGJ1ZmZlclVzYWdlLCBkZVVpbnQzMiBtYXBGbGFncywgaW50IGNhc2VGbGFncykKCTogQmFzaWNVcGxvYWRDYXNlPE1hcEJ1ZmZlclJhbmdlRmx1c2hEdXJhdGlvbj4JKGN0eCwgbmFtZSwgZGVzYywgbWluQnVmZmVyU2l6ZSwgbWF4QnVmZmVyU2l6ZSwgbnVtU2FtcGxlcywgYnVmZmVyVXNhZ2UsIGdldEJhc2VDYXNlVHlwZShjYXNlRmxhZ3MpLCBSRVNVTFRfTUVESUFOX1RSQU5TRkVSX1JBVEUsIGdldEJhc2VGbGFncyhtYXBGbGFncywgY2FzZUZsYWdzKSkKCSwgbV9mdWxsVXBsb2FkCQkJCQkJCQkJKChjYXNlRmxhZ3MmRkxBR19QQVJUSUFMKSA9PSAwKQoJLCBtX2ZsdXNoSW5QYXJ0cwkJCQkJCQkJKChjYXNlRmxhZ3MmRkxBR19GTFVTSF9JTl9QQVJUUykgIT0gMCkKCSwgbV9mbHVzaFBhcnRpYWwJCQkJCQkJCSgoY2FzZUZsYWdzJkZMQUdfRkxVU0hfUEFSVElBTCkgIT0gMCkKCSwgbV91c2VVbnVzZWRVbnNwZWNpZmllZEJ1ZmZlcgkJCQkJKChjYXNlRmxhZ3MmRkxBR19VU0VfVU5VU0VEX1VOU1BFQ0lGSUVEX0JVRkZFUikgIT0gMCkKCSwgbV91c2VVbnVzZWRTcGVjaWZpZWRCdWZmZXIJCQkJCSgoY2FzZUZsYWdzJkZMQUdfVVNFX1VOVVNFRF9TUEVDSUZJRURfQlVGRkVSKSAhPSAwKQoJLCBtX21hcEZsYWdzCQkJCQkJCQkJKG1hcEZsYWdzKQoJLCBtX3VubWFwRmFpbHVyZXMJCQkJCQkJCSgwKQp7CglERV9BU1NFUlQoIShtX2ZsdXNoUGFydGlhbCAmJiBtX2ZsdXNoSW5QYXJ0cykpOwoJREVfQVNTRVJUKCEobV9mbHVzaFBhcnRpYWwgJiYgIW1fZnVsbFVwbG9hZCkpOwp9CgpNYXBCdWZmZXJSYW5nZUZsdXNoQ2FzZTo6fk1hcEJ1ZmZlclJhbmdlRmx1c2hDYXNlICh2b2lkKQp7Cn0KCnZvaWQgTWFwQnVmZmVyUmFuZ2VGbHVzaENhc2U6OmluaXQgKHZvaWQpCnsKCS8vIERlc2NyaWJlIHdoYXQgdGhlIHRlc3QgdHJpZXMgdG8gZG8KCW1fdGVzdEN0eC5nZXRMb2coKQoJCTw8IHRjdTo6VGVzdExvZzo6TWVzc2FnZQoJCTw8ICJUZXN0aW5nIGdsTWFwQnVmZmVyUmFuZ2UoKSwgZ2xGbHVzaE1hcHBlZEJ1ZmZlclJhbmdlKCkgYW5kIGdsVW5tYXBCdWZmZXIoKSBmdW5jdGlvbiBjYWxsIHBlcmZvcm1hbmNlLlxuIgoJCTw8ICgobV9mdWxsVXBsb2FkKSA/ICgiVGhlIHdob2xlIGJ1ZmZlciBpcyBtYXBwZWQuIikgOiAoIkhhbGYgb2YgdGhlIGJ1ZmZlciBpcyBtYXBwZWQuIikpIDw8ICJcbiIKCQk8PCAoKG1fZmx1c2hJblBhcnRzKSA/CgkJCSgiVGhlIG1hcHBlZCByYW5nZSBpcyBwYXJ0aXRpb25lZCB0byA0IHN1YnJhbmdlcyBhbmQgZWFjaCBwYXJ0aXRpb24gaXMgZmx1c2hlZCBzZXBhcmF0ZWx5LiIpIDoKCQkJKG1fZmx1c2hQYXJ0aWFsKSA/CgkJCQkoIkhhbGYgb2YgdGhlIGJ1ZmZlciByYW5nZSBpcyBmbHVzaGVkLiIpIDoKCQkJCSgiVGhlIHdob2xlIG1hcHBlZCByYW5nZSBpcyBmbHVzaGVkIGluIG9uZSBmbHVzaCBjYWxsLiIpKSA8PCAiXG4iCgkJPDwgKChtX3VzZVVudXNlZFVuc3BlY2lmaWVkQnVmZmVyKSA/ICgiVGhlIGJ1ZmZlciBoYXMgbm90IGJlZW4gdXNlZCBiZWZvcmUgbWFwcGluZyBhbmQgaXMgYWxsb2NhdGVkIHdpdGggdW5zcGVjaWZpZWQgY29udGVudHMuXG4iKSA6ICgiIikpCgkJPDwgKChtX3VzZVVudXNlZFNwZWNpZmllZEJ1ZmZlcikgPyAoIlRoZSBidWZmZXIgaGFzIG5vdCBiZWVuIHVzZWQgYmVmb3JlIG1hcHBpbmcgYW5kIGlzIGFsbG9jYXRlZCB3aXRoIHNwZWNpZmllZCBjb250ZW50cy5cbiIpIDogKCIiKSkKCQk8PCAoKCFtX3VzZVVudXNlZFNwZWNpZmllZEJ1ZmZlciAmJiAhbV91c2VVbnVzZWRVbnNwZWNpZmllZEJ1ZmZlcikgPyAoIlRoZSBidWZmZXIgaGFzIHByZXZpb3VzbHkgYmVlbiB1c2VkIGluIGEgZHJhd2luZyBvcGVyYXRpb24uXG4iKSA6ICgiIikpCgkJPDwgIk1hcCBiaXRzOlxuIgoJCTw8ICgobV9tYXBGbGFncyAmIEdMX01BUF9XUklURV9CSVQpID8gKCJcdEdMX01BUF9XUklURV9CSVRcbiIpIDogKCIiKSkKCQk8PCAoKG1fbWFwRmxhZ3MgJiBHTF9NQVBfUkVBRF9CSVQpID8gKCJcdEdMX01BUF9SRUFEX0JJVFxuIikgOiAoIiIpKQoJCTw8ICgobV9tYXBGbGFncyAmIEdMX01BUF9JTlZBTElEQVRFX1JBTkdFX0JJVCkgPyAoIlx0R0xfTUFQX0lOVkFMSURBVEVfUkFOR0VfQklUXG4iKSA6ICgiIikpCgkJPDwgKChtX21hcEZsYWdzICYgR0xfTUFQX0lOVkFMSURBVEVfQlVGRkVSX0JJVCkgPyAoIlx0R0xfTUFQX0lOVkFMSURBVEVfQlVGRkVSX0JJVFxuIikgOiAoIiIpKQoJCTw8ICgobV9tYXBGbGFncyAmIEdMX01BUF9VTlNZTkNIUk9OSVpFRF9CSVQpID8gKCJcdEdMX01BUF9VTlNZTkNIUk9OSVpFRF9CSVRcbiIpIDogKCIiKSkKCQk8PCAoKG1fbWFwRmxhZ3MgJiBHTF9NQVBfRkxVU0hfRVhQTElDSVRfQklUKSA/ICgiXHRHTF9NQVBfRkxVU0hfRVhQTElDSVRfQklUXG4iKSA6ICgiIikpCgkJPDwgdGN1OjpUZXN0TG9nOjpFbmRNZXNzYWdlOwoKCUJhc2ljVXBsb2FkQ2FzZTxNYXBCdWZmZXJSYW5nZUZsdXNoRHVyYXRpb24+Ojppbml0KCk7Cn0KCk1hcEJ1ZmZlclJhbmdlRmx1c2hDYXNlOjpDYXNlVHlwZSBNYXBCdWZmZXJSYW5nZUZsdXNoQ2FzZTo6Z2V0QmFzZUNhc2VUeXBlIChpbnQgY2FzZUZsYWdzKQp7CglpZiAoKGNhc2VGbGFncyAmIEZMQUdfVVNFX1VOVVNFRF9VTlNQRUNJRklFRF9CVUZGRVIpID09IDAgJiYgKGNhc2VGbGFncyAmIEZMQUdfVVNFX1VOVVNFRF9TUEVDSUZJRURfQlVGRkVSKSA9PSAwKQoJCXJldHVybiBDQVNFX1VTRURfQlVGRkVSOwoJZWxzZQoJCXJldHVybiBDQVNFX05FV19CVUZGRVI7Cn0KCmludCBNYXBCdWZmZXJSYW5nZUZsdXNoQ2FzZTo6Z2V0QmFzZUZsYWdzIChkZVVpbnQzMiBtYXBGbGFncywgaW50IGNhc2VGbGFncykKewoJaW50IGZsYWdzID0gRkxBR19ET05UX0xPR19CVUZGRVJfSU5GTzsKCgkvLyBJZiBidWZmZXIgY29udGFpbnMgdW5zcGVjaWZpZWQgZGF0YSB3aGVuIGl0IGlzIHNvdXJjZWQgKGkuZSBkcmF3bikKCS8vIHJlc3VsdHMgYXJlIHVuZGVmaW5lZCwgYW5kIHN5c3RlbSBlcnJvcnMgbWF5IG9jY3VyLiBTaWduYWwgcGFyZW50CgkvLyBjbGFzcyB0byB0YWtlIHRoaXMgaW50byBhY2NvdW50CglpZiAoY2FzZUZsYWdzICYgRkxBR19QQVJUSUFMKQoJewoJCWlmICgobWFwRmxhZ3MgJiBHTF9NQVBfSU5WQUxJREFURV9CVUZGRVJfQklUKSAhPSAwCQkJfHwKCQkJKGNhc2VGbGFncyAmIEZMQUdfVVNFX1VOVVNFRF9VTlNQRUNJRklFRF9CVUZGRVIpICE9IDAJfHwKCQkJKGNhc2VGbGFncyAmIEZMQUdfRkxVU0hfUEFSVElBTCkgIT0gMCkKCQl7CgkJCWZsYWdzIHw9IEZMQUdfUkVTVUxUX0JVRkZFUl9VTlNQRUNJRklFRF9DT05URU5UOwoJCX0KCX0KCglyZXR1cm4gZmxhZ3M7Cn0KCnZvaWQgTWFwQnVmZmVyUmFuZ2VGbHVzaENhc2U6OnRlc3RCdWZmZXJVcGxvYWQgKFVwbG9hZFNhbXBsZVJlc3VsdDxNYXBCdWZmZXJSYW5nZUZsdXNoRHVyYXRpb24+JiByZXN1bHQsIGludCBidWZmZXJTaXplKQp7Cgljb25zdCBpbnQgdW5tYXBGYWlsdXJlVGhyZXNob2xkID0gNDsKCglmb3IgKDsgbV91bm1hcEZhaWx1cmVzIDwgdW5tYXBGYWlsdXJlVGhyZXNob2xkOyArK21fdW5tYXBGYWlsdXJlcykKCXsKCQl0cnkKCQl7CgkJCWF0dGVtcHRCdWZmZXJNYXAocmVzdWx0LCBidWZmZXJTaXplKTsKCQkJcmV0dXJuOwoJCX0KCQljYXRjaCAoVW5tYXBGYWlsdXJlRXJyb3ImKQoJCXsKCQl9Cgl9CgoJdGhyb3cgdGN1OjpUZXN0RXJyb3IoIlVubWFwcGluZyBmYWlsdXJlcyBleGNlZWRlZCBsaW1pdCIpOwp9Cgp2b2lkIE1hcEJ1ZmZlclJhbmdlRmx1c2hDYXNlOjphdHRlbXB0QnVmZmVyTWFwIChVcGxvYWRTYW1wbGVSZXN1bHQ8TWFwQnVmZmVyUmFuZ2VGbHVzaER1cmF0aW9uPiYgcmVzdWx0LCBpbnQgYnVmZmVyU2l6ZSkKewoJY29uc3QgZ2x3OjpGdW5jdGlvbnMmCWdsCQkJPSBtX2NvbnRleHQuZ2V0UmVuZGVyQ29udGV4dCgpLmdldEZ1bmN0aW9ucygpOwoJY29uc3QgaW50CQkJCW1hcHBlZFNpemUJPSAobV9mdWxsVXBsb2FkKSA/IChidWZmZXJTaXplKSA6IChidWZmZXJTaXplIC8gMik7CgoJaWYgKG1fZnVsbFVwbG9hZCAmJiAhbV9mbHVzaFBhcnRpYWwpCgkJcmVzdWx0LndyaXR0ZW5TaXplID0gYnVmZmVyU2l6ZTsKCWVsc2UKCQlyZXN1bHQud3JpdHRlblNpemUgPSBidWZmZXJTaXplIC8gMjsKCglnbC5iaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgbV9idWZmZXJJRCk7CgoJLy8gQ3JlYXRlIHVudXNlZCBidWZmZXIKCglpZiAobV91c2VVbnVzZWRVbnNwZWNpZmllZEJ1ZmZlcikKCXsKCQlkZVVpbnQ2NCBzdGFydFRpbWU7CgkJZGVVaW50NjQgZW5kVGltZTsKCgkJLy8gRG9uJ3Qgc3BlY2lmeSBjb250ZW50cwoJCXN0YXJ0VGltZSA9IGRlR2V0TWljcm9zZWNvbmRzKCk7CgkJZ2wuYnVmZmVyRGF0YShHTF9BUlJBWV9CVUZGRVIsIGJ1ZmZlclNpemUsIERFX05VTEwsIG1fYnVmZmVyVXNhZ2UpOwoJCWVuZFRpbWUgPSBkZUdldE1pY3Jvc2Vjb25kcygpOwoKCQlyZXN1bHQuZHVyYXRpb24uYWxsb2NEdXJhdGlvbiA9IGVuZFRpbWUgLSBzdGFydFRpbWU7Cgl9CgllbHNlIGlmIChtX3VzZVVudXNlZFNwZWNpZmllZEJ1ZmZlcikKCXsKCQlkZVVpbnQ2NCBzdGFydFRpbWU7CgkJZGVVaW50NjQgZW5kVGltZTsKCgkJLy8gU3BlY2lmeSBidWZmZXIgY29udGVudHMKCQlzdGFydFRpbWUgPSBkZUdldE1pY3Jvc2Vjb25kcygpOwoJCWdsLmJ1ZmZlckRhdGEoR0xfQVJSQVlfQlVGRkVSLCBidWZmZXJTaXplLCAmbV96ZXJvRGF0YVswXSwgbV9idWZmZXJVc2FnZSk7CgkJZW5kVGltZSA9IGRlR2V0TWljcm9zZWNvbmRzKCk7CgoJCXJlc3VsdC5kdXJhdGlvbi5hbGxvY0R1cmF0aW9uID0gZW5kVGltZSAtIHN0YXJ0VGltZTsKCX0KCWVsc2UKCXsKCQkvLyBObyBhbGxvYywgbm8gdGltZQoJCXJlc3VsdC5kdXJhdGlvbi5hbGxvY0R1cmF0aW9uID0gMDsKCX0KCgkvLyB1cGxvYWQKCXsKCQl2b2lkKiBtYXBQdHI7CgoJCS8vIE1hcAoJCXsKCQkJZGVVaW50NjQgc3RhcnRUaW1lOwoJCQlkZVVpbnQ2NCBlbmRUaW1lOwoKCQkJc3RhcnRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCQkJaWYgKG1fZnVsbFVwbG9hZCkKCQkJCW1hcFB0ciA9IGdsLm1hcEJ1ZmZlclJhbmdlKEdMX0FSUkFZX0JVRkZFUiwgMCwgbWFwcGVkU2l6ZSwgbV9tYXBGbGFncyk7CgkJCWVsc2UKCQkJewoJCQkJLy8gdXBsb2FkIHRvIGJ1ZmZlciBjZW50ZXIKCQkJCW1hcFB0ciA9IGdsLm1hcEJ1ZmZlclJhbmdlKEdMX0FSUkFZX0JVRkZFUiwgYnVmZmVyU2l6ZSAvIDQsIG1hcHBlZFNpemUsIG1fbWFwRmxhZ3MpOwoJCQl9CgkJCWVuZFRpbWUgPSBkZUdldE1pY3Jvc2Vjb25kcygpOwoKCQkJaWYgKCFtYXBQdHIpCgkJCQl0aHJvdyB0Y3U6OkV4Y2VwdGlvbigiTWFwQnVmZmVyUmFuZ2UgcmV0dXJuZWQgTlVMTCIpOwoKCQkJcmVzdWx0LmR1cmF0aW9uLm1hcER1cmF0aW9uID0gZW5kVGltZSAtIHN0YXJ0VGltZTsKCQl9CgoJCS8vIFdyaXRlCgkJewoJCQlpZiAoIW1fZmx1c2hQYXJ0aWFsKQoJCQkJcmVzdWx0LmR1cmF0aW9uLndyaXRlRHVyYXRpb24gPSBtZWRpYW5UaW1lTWVtY3B5KG1hcFB0ciwgJm1femVyb0RhdGFbMF0sIHJlc3VsdC53cml0dGVuU2l6ZSk7CgkJCWVsc2UKCQkJCXJlc3VsdC5kdXJhdGlvbi53cml0ZUR1cmF0aW9uID0gbWVkaWFuVGltZU1lbWNweSgoZGVVaW50OCopbWFwUHRyICsgYnVmZmVyU2l6ZSAvIDQsICZtX3plcm9EYXRhWzBdLCByZXN1bHQud3JpdHRlblNpemUpOwoJCX0KCgkJLy8gRmx1c2gKCQl7CgkJCWRlVWludDY0CXN0YXJ0VGltZTsKCQkJZGVVaW50NjQJZW5kVGltZTsKCgkJCXN0YXJ0VGltZSA9IGRlR2V0TWljcm9zZWNvbmRzKCk7CgoJCQlpZiAobV9mbHVzaFBhcnRpYWwpCgkJCQlnbC5mbHVzaE1hcHBlZEJ1ZmZlclJhbmdlKEdMX0FSUkFZX0JVRkZFUiwgbWFwcGVkU2l6ZS80LCBtYXBwZWRTaXplLzIpOwoJCQllbHNlIGlmICghbV9mbHVzaEluUGFydHMpCgkJCQlnbC5mbHVzaE1hcHBlZEJ1ZmZlclJhbmdlKEdMX0FSUkFZX0JVRkZFUiwgMCwgbWFwcGVkU2l6ZSk7CgkJCWVsc2UKCQkJewoJCQkJY29uc3QgaW50IHAxID0gMDsKCQkJCWNvbnN0IGludCBwMiA9IG1hcHBlZFNpemUgLyAzOwoJCQkJY29uc3QgaW50IHAzID0gbWFwcGVkU2l6ZSAvIDI7CgkJCQljb25zdCBpbnQgcDQgPSBtYXBwZWRTaXplICogMiAvIDQ7CgkJCQljb25zdCBpbnQgcDUgPSBtYXBwZWRTaXplOwoKCQkJCS8vIGZsdXNoIGluIG1peGVkIG9yZGVyCgkJCQlnbC5mbHVzaE1hcHBlZEJ1ZmZlclJhbmdlKEdMX0FSUkFZX0JVRkZFUiwgcDIsCXAzLXAyKTsKCQkJCWdsLmZsdXNoTWFwcGVkQnVmZmVyUmFuZ2UoR0xfQVJSQVlfQlVGRkVSLCBwMSwJcDItcDEpOwoJCQkJZ2wuZmx1c2hNYXBwZWRCdWZmZXJSYW5nZShHTF9BUlJBWV9CVUZGRVIsIHA0LAlwNS1wNCk7CgkJCQlnbC5mbHVzaE1hcHBlZEJ1ZmZlclJhbmdlKEdMX0FSUkFZX0JVRkZFUiwgcDMsCXA0LXAzKTsKCQkJfQoKCQkJZW5kVGltZSA9IGRlR2V0TWljcm9zZWNvbmRzKCk7CgoJCQlyZXN1bHQuZHVyYXRpb24uZmx1c2hEdXJhdGlvbiA9IGVuZFRpbWUgLSBzdGFydFRpbWU7CgkJfQoKCQkvLyBVbm1hcAoJCXsKCQkJZGVVaW50NjQJCXN0YXJ0VGltZTsKCQkJZGVVaW50NjQJCWVuZFRpbWU7CgkJCWdsdzo6R0xib29sZWFuCXVubWFwU3VjY2Vzc2Z1bDsKCgkJCXN0YXJ0VGltZSA9IGRlR2V0TWljcm9zZWNvbmRzKCk7CgkJCXVubWFwU3VjY2Vzc2Z1bCA9IGdsLnVubWFwQnVmZmVyKEdMX0FSUkFZX0JVRkZFUik7CgkJCWVuZFRpbWUgPSBkZUdldE1pY3Jvc2Vjb25kcygpOwoKCQkJLy8gaWYgdW5tYXBwaW5nIGZhaWxzLCBqdXN0IHRyeSBhZ2FpbiBsYXRlcgoJCQlpZiAoIXVubWFwU3VjY2Vzc2Z1bCkKCQkJCXRocm93IFVubWFwRmFpbHVyZUVycm9yKCk7CgoJCQlyZXN1bHQuZHVyYXRpb24udW5tYXBEdXJhdGlvbiA9IGVuZFRpbWUgLSBzdGFydFRpbWU7CgkJfQoKCQlyZXN1bHQuZHVyYXRpb24udG90YWxEdXJhdGlvbiA9IHJlc3VsdC5kdXJhdGlvbi5tYXBEdXJhdGlvbiArIHJlc3VsdC5kdXJhdGlvbi53cml0ZUR1cmF0aW9uICsgcmVzdWx0LmR1cmF0aW9uLmZsdXNoRHVyYXRpb24gKyByZXN1bHQuZHVyYXRpb24udW5tYXBEdXJhdGlvbiArIHJlc3VsdC5kdXJhdGlvbi5hbGxvY0R1cmF0aW9uOwoJCXJlc3VsdC5kdXJhdGlvbi5maXRSZXNwb25zZUR1cmF0aW9uID0gcmVzdWx0LmR1cmF0aW9uLnRvdGFsRHVyYXRpb247Cgl9Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgpjbGFzcyBNb2RpZnlBZnRlckJhc2ljQ2FzZSA6IHB1YmxpYyBCYXNpY0J1ZmZlckNhc2U8U2FtcGxlVHlwZT4KewpwdWJsaWM6CgkJCQkJCU1vZGlmeUFmdGVyQmFzaWNDYXNlCShDb250ZXh0JiBjb250ZXh0LCBjb25zdCBjaGFyKiBuYW1lLCBjb25zdCBjaGFyKiBkZXNjcmlwdGlvbiwgaW50IGJ1ZmZlclNpemVNaW4sIGludCBidWZmZXJTaXplTWF4LCBkZVVpbnQzMiB1c2FnZSwgYm9vbCBidWZmZXJVbnNwZWNpZmllZEFmdGVyVGVzdCk7CgkJCQkJCX5Nb2RpZnlBZnRlckJhc2ljQ2FzZQkodm9pZCk7CgoJdm9pZAkJCQlpbml0CQkJCQkodm9pZCk7Cgl2b2lkCQkJCWRlaW5pdAkJCQkJKHZvaWQpOwoKcHJvdGVjdGVkOgoJdm9pZAkJCQlkcmF3QnVmZmVyUmFuZ2UJCQkoaW50IGJlZ2luLCBpbnQgZW5kKTsKCnByaXZhdGU6CgllbnVtCgl7CgkJTlVNX1NBTVBMRVMgPSAyMCwKCX07CgoKCWJvb2wJCQkJcnVuU2FtcGxlCQkJCShpbnQgaXRlcmF0aW9uLCBVcGxvYWRTYW1wbGVSZXN1bHQ8U2FtcGxlVHlwZT4mIHNhbXBsZSk7Cglib29sCQkJCXByZXBhcmVBbmRSdW5UZXN0CQkoaW50IGl0ZXJhdGlvbiwgVXBsb2FkU2FtcGxlUmVzdWx0PFNhbXBsZVR5cGU+JiByZXN1bHQsIGludCBidWZmZXJTaXplKTsKCXZvaWQJCQkJbG9nQW5kU2V0VGVzdFJlc3VsdAkJKGNvbnN0IHN0ZDo6dmVjdG9yPFVwbG9hZFNhbXBsZVJlc3VsdDxTYW1wbGVUeXBlPiA+JiByZXN1bHRzKTsKCgl2aXJ0dWFsIHZvaWQJCXRlc3RXaXRoQnVmZmVyU2l6ZQkJKFVwbG9hZFNhbXBsZVJlc3VsdDxTYW1wbGVUeXBlPiYgcmVzdWx0LCBpbnQgYnVmZmVyU2l6ZSkgPSAwOwoKCWludAkJCQkJbV91bm1hcHBpbmdFcnJvcnM7Cgpwcm90ZWN0ZWQ6Cgljb25zdCBib29sCQkJbV9idWZmZXJVbnNwZWNpZmllZEFmdGVyVGVzdDsKCWNvbnN0IGRlVWludDMyCQltX2J1ZmZlclVzYWdlOwoJc3RkOjp2ZWN0b3I8ZGVVaW50OD4gbV96ZXJvRGF0YTsKCgl1c2luZyBCYXNpY0J1ZmZlckNhc2U8U2FtcGxlVHlwZT46Om1fdGVzdEN0eDsKCXVzaW5nIEJhc2ljQnVmZmVyQ2FzZTxTYW1wbGVUeXBlPjo6bV9jb250ZXh0OwoKCXVzaW5nIEJhc2ljQnVmZmVyQ2FzZTxTYW1wbGVUeXBlPjo6RFVNTVlfUkVOREVSX0FSRUFfU0laRTsKCXVzaW5nIEJhc2ljQnVmZmVyQ2FzZTxTYW1wbGVUeXBlPjo6bV9kdW1teVByb2dyYW07Cgl1c2luZyBCYXNpY0J1ZmZlckNhc2U8U2FtcGxlVHlwZT46Om1fZHVtbXlQcm9ncmFtUG9zTG9jOwoJdXNpbmcgQmFzaWNCdWZmZXJDYXNlPFNhbXBsZVR5cGU+OjptX2J1ZmZlcklEOwoJdXNpbmcgQmFzaWNCdWZmZXJDYXNlPFNhbXBsZVR5cGU+OjptX251bVNhbXBsZXM7Cgl1c2luZyBCYXNpY0J1ZmZlckNhc2U8U2FtcGxlVHlwZT46Om1fYnVmZmVyU2l6ZU1pbjsKCXVzaW5nIEJhc2ljQnVmZmVyQ2FzZTxTYW1wbGVUeXBlPjo6bV9idWZmZXJTaXplTWF4OwoJdXNpbmcgQmFzaWNCdWZmZXJDYXNlPFNhbXBsZVR5cGU+OjptX2FsbG9jYXRlTGFyZ2VyQnVmZmVyOwp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFNhbXBsZVR5cGU+Ck1vZGlmeUFmdGVyQmFzaWNDYXNlPFNhbXBsZVR5cGU+OjpNb2RpZnlBZnRlckJhc2ljQ2FzZSAoQ29udGV4dCYgY29udGV4dCwgY29uc3QgY2hhciogbmFtZSwgY29uc3QgY2hhciogZGVzY3JpcHRpb24sIGludCBidWZmZXJTaXplTWluLCBpbnQgYnVmZmVyU2l6ZU1heCwgZGVVaW50MzIgdXNhZ2UsIGJvb2wgYnVmZmVyVW5zcGVjaWZpZWRBZnRlclRlc3QpCgk6IEJhc2ljQnVmZmVyQ2FzZTxTYW1wbGVUeXBlPgkoY29udGV4dCwgbmFtZSwgZGVzY3JpcHRpb24sIGJ1ZmZlclNpemVNaW4sIGJ1ZmZlclNpemVNYXgsIE5VTV9TQU1QTEVTLCAwKQoJLCBtX3VubWFwcGluZ0Vycm9ycwkJCQkoMCkKCSwgbV9idWZmZXJVbnNwZWNpZmllZEFmdGVyVGVzdAkoYnVmZmVyVW5zcGVjaWZpZWRBZnRlclRlc3QpCgksIG1fYnVmZmVyVXNhZ2UJCQkJCSh1c2FnZSkKCSwgbV96ZXJvRGF0YQkJCQkJKCkKewp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4KTW9kaWZ5QWZ0ZXJCYXNpY0Nhc2U8U2FtcGxlVHlwZT46On5Nb2RpZnlBZnRlckJhc2ljQ2FzZSAodm9pZCkKewoJQmFzaWNCdWZmZXJDYXNlPFNhbXBsZVR5cGU+OjpkZWluaXQoKTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFNhbXBsZVR5cGU+CnZvaWQgTW9kaWZ5QWZ0ZXJCYXNpY0Nhc2U8U2FtcGxlVHlwZT46OmluaXQgKHZvaWQpCnsKCWNvbnN0IGdsdzo6RnVuY3Rpb25zJiBnbCA9IG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCkuZ2V0RnVuY3Rpb25zKCk7CgoJLy8gaW5pdCBwYXJlbnQKCglCYXNpY0J1ZmZlckNhc2U8U2FtcGxlVHlwZT46OmluaXQoKTsKCgkvLyB1cGxvYWQgc291cmNlCgltX3plcm9EYXRhLnJlc2l6ZShtX2J1ZmZlclNpemVNYXgsIDB4MDApOwoKCS8vIGxvZyBiYXNpYyBpbmZvCgoJbV90ZXN0Q3R4LmdldExvZygpCgkJPDwgdGN1OjpUZXN0TG9nOjpNZXNzYWdlCgkJPDwgIlRlc3RpbmcgcGVyZm9ybWFuY2Ugd2l0aCAiIDw8IChpbnQpTlVNX1NBTVBMRVMgPDwgIiB0ZXN0IHNhbXBsZXMuIFNhbXBsZSBvcmRlciBpcyByYW5kb21pemVkLiBBbGwgc2FtcGxlcyBhdCBldmVuIHBvc2l0aW9ucyAoZmlyc3QgPSAwKSBhcmUgdGVzdGVkIGJlZm9yZSBzYW1wbGVzIGF0IG9kZCBwb3NpdGlvbnMuXG4iCgkJPDwgIkJ1ZmZlciBzaXplcyBhcmUgaW4gcmFuZ2UgWyIgPDwgZ2V0SHVtYW5SZWFkYWJsZUJ5dGVTaXplKG1fYnVmZmVyU2l6ZU1pbikgPDwgIiwgIiA8PCBnZXRIdW1hblJlYWRhYmxlQnl0ZVNpemUobV9idWZmZXJTaXplTWF4KSA8PCAiXS4iCgkJPDwgdGN1OjpUZXN0TG9nOjpFbmRNZXNzYWdlOwoKCS8vIGxvZyB3aGljaCB0cmFuc2ZlciByYXRlIGlzIHRoZSB0ZXN0IHJlc3VsdCBhbmQgYnVmZmVyIGluZm8KCgltX3Rlc3RDdHguZ2V0TG9nKCkKCQk8PCB0Y3U6OlRlc3RMb2c6Ok1lc3NhZ2UKCQk8PCAiVGVzdCByZXN1bHQgaXMgdGhlIG1lZGlhbiB0cmFuc2ZlciByYXRlIG9mIHRoZSB0ZXN0IHNhbXBsZXMuXG4iCgkJPDwgIkJ1ZmZlciB1c2FnZSA9ICIgPDwgZ2x1OjpnZXRVc2FnZU5hbWUobV9idWZmZXJVc2FnZSkKCQk8PCB0Y3U6OlRlc3RMb2c6OkVuZE1lc3NhZ2U7CgoJLy8gU2V0IHN0YXRlIGZvciBkcmF3aW5nIHNvIHRoYXQgd2UgZG9uJ3QgaGF2ZSB0byBjaGFuZ2UgdGhlc2UgZHVyaW5nIHRoZSBpdGVyYXRpb24KCXsKCQlnbC51c2VQcm9ncmFtKG1fZHVtbXlQcm9ncmFtLT5nZXRQcm9ncmFtKCkpOwoJCWdsLnZpZXdwb3J0KDAsIDAsIERVTU1ZX1JFTkRFUl9BUkVBX1NJWkUsIERVTU1ZX1JFTkRFUl9BUkVBX1NJWkUpOwoJCWdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KG1fZHVtbXlQcm9ncmFtUG9zTG9jKTsKCX0KfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFNhbXBsZVR5cGU+CnZvaWQgTW9kaWZ5QWZ0ZXJCYXNpY0Nhc2U8U2FtcGxlVHlwZT46OmRlaW5pdCAodm9pZCkKewoJbV96ZXJvRGF0YSA9IHN0ZDo6dmVjdG9yPGRlVWludDg+KCk7CgoJQmFzaWNCdWZmZXJDYXNlPFNhbXBsZVR5cGU+OjpkZWluaXQoKTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFNhbXBsZVR5cGU+CnZvaWQgTW9kaWZ5QWZ0ZXJCYXNpY0Nhc2U8U2FtcGxlVHlwZT46OmRyYXdCdWZmZXJSYW5nZSAoaW50IGJlZ2luLCBpbnQgZW5kKQp7CglERV9BU1NFUlQoYmVnaW4gJSAoaW50KXNpemVvZihmbG9hdFs0XSkgPT0gMCk7CglERV9BU1NFUlQoZW5kICUgKGludClzaXplb2YoZmxvYXRbNF0pID09IDApOwoKCWNvbnN0IGdsdzo6RnVuY3Rpb25zJiBnbCA9IG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCkuZ2V0RnVuY3Rpb25zKCk7CgoJLy8gdXNlIGdpdmVuIHJhbmdlCglnbC5kcmF3QXJyYXlzKEdMX1BPSU5UUywgYmVnaW4gLyAoaW50KXNpemVvZihmbG9hdFs0XSksIDEpOwoJZ2wuZHJhd0FycmF5cyhHTF9QT0lOVFMsIGVuZCAvIChpbnQpc2l6ZW9mKGZsb2F0WzRdKSAtIDEsIDEpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4KYm9vbCBNb2RpZnlBZnRlckJhc2ljQ2FzZTxTYW1wbGVUeXBlPjo6cnVuU2FtcGxlIChpbnQgaXRlcmF0aW9uLCBVcGxvYWRTYW1wbGVSZXN1bHQ8U2FtcGxlVHlwZT4mIHNhbXBsZSkKewoJY29uc3QgZ2x3OjpGdW5jdGlvbnMmCWdsCQkJCQk9IG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCkuZ2V0RnVuY3Rpb25zKCk7Cgljb25zdCBpbnQJCQkJYnVmZmVyU2l6ZQkJCT0gc2FtcGxlLmJ1ZmZlclNpemU7Cglib29sCQkJCQl0ZXN0T2s7CgoJdGVzdE9rID0gcHJlcGFyZUFuZFJ1blRlc3QoaXRlcmF0aW9uLCBzYW1wbGUsIGJ1ZmZlclNpemUpOwoJR0xVX0VYUEVDVF9OT19FUlJPUihnbC5nZXRFcnJvcigpLCAiQnVmZmVyIHVwbG9hZCBzYW1wbGUiKTsKCglpZiAoIXRlc3RPaykKCXsKCQljb25zdCBpbnQgdW5tYXBGYWlsdXJlVGhyZXNob2xkID0gNDsKCgkJLy8gb25seSB1bm1hcHBpbmcgZXJyb3IgY2FuIGNhdXNlIGl0ZXJhdGlvbiBmYWlsdXJlCgkJaWYgKCsrbV91bm1hcHBpbmdFcnJvcnMgPj0gdW5tYXBGYWlsdXJlVGhyZXNob2xkKQoJCQl0aHJvdyB0Y3U6OlRlc3RFcnJvcigiVG9vIG1hbnkgdW5tYXBwaW5nIGVycm9ycywgY2Fubm90IGNvbnRpbnVlLiIpOwoKCQkvLyBqdXN0IHRyeSBhZ2FpbgoJCXJldHVybiBmYWxzZTsKCX0KCglyZXR1cm4gdHJ1ZTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFNhbXBsZVR5cGU+CmJvb2wgTW9kaWZ5QWZ0ZXJCYXNpY0Nhc2U8U2FtcGxlVHlwZT46OnByZXBhcmVBbmRSdW5UZXN0IChpbnQgaXRlcmF0aW9uLCBVcGxvYWRTYW1wbGVSZXN1bHQ8U2FtcGxlVHlwZT4mIHJlc3VsdCwgaW50IGJ1ZmZlclNpemUpCnsKCURFX1VOUkVGKGl0ZXJhdGlvbik7CgoJREVfQVNTRVJUKCFtX2J1ZmZlcklEKTsKCURFX0FTU0VSVChkZUlzQWxpZ25lZDMyKGJ1ZmZlclNpemUsIDQqNCkpOyAvLyBhbGlnbmVkIHRvIHZlYzQKCgljb25zdCBnbHc6OkZ1bmN0aW9ucyYJCWdsCQkJCT0gbV9jb250ZXh0LmdldFJlbmRlckNvbnRleHQoKS5nZXRGdW5jdGlvbnMoKTsKCWJvb2wJCQkJCQl0ZXN0UnVuT2sJCT0gdHJ1ZTsKCWJvb2wJCQkJCQl1bm1hcHBpbmdGYWlsZWQJPSBmYWxzZTsKCgkvLyBVcGxvYWQgaW5pdGlhbCBidWZmZXIgdG8gdGhlIEdQVS4uLgoJZ2wuZ2VuQnVmZmVycygxLCAmbV9idWZmZXJJRCk7CglnbC5iaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgbV9idWZmZXJJRCk7CglnbC5idWZmZXJEYXRhKEdMX0FSUkFZX0JVRkZFUiwgYnVmZmVyU2l6ZSwgJm1femVyb0RhdGFbMF0sIG1fYnVmZmVyVXNhZ2UpOwoKCS8vIC4uLnVzZSBpdC4uLgoJZ2wudmVydGV4QXR0cmliUG9pbnRlcihtX2R1bW15UHJvZ3JhbVBvc0xvYywgNCwgR0xfRkxPQVQsIEdMX0ZBTFNFLCAwLCBERV9OVUxMKTsKCWRyYXdCdWZmZXJSYW5nZSgwLCBidWZmZXJTaXplKTsKCgkvLyAuLmFuZCBtYWtlIHN1cmUgaXQgaXMgdXBsb2FkZWQKCUJhc2ljQnVmZmVyQ2FzZTxTYW1wbGVUeXBlPjo6d2FpdEdMUmVzdWx0cygpOwoKCS8vIHdhcm11cCBDUFUgYmVmb3JlIHRoZSB0ZXN0IHRvIG1ha2Ugc3VyZSB0aGUgcG93ZXIgbWFuYWdlbWVudCBnb3Zlcm5vcgoJLy8ga2VlcHMgdXMgaW4gdGhlICJoaWdoIHBlcmZvcm1hbmNlIiBtb2RlCgl7CgkJZGVZaWVsZCgpOwoJCXRjdTo6d2FybXVwQ1BVKCk7CgkJZGVZaWVsZCgpOwoJfQoKCS8vIHRlc3QKCXRyeQoJewoJCS8vIGJ1ZmZlciBpcyB1cGxvYWRlZCB0byB0aGUgR1BVLiBEcmF3IGZyb20gaXQuCgkJZHJhd0J1ZmZlclJhbmdlKDAsIGJ1ZmZlclNpemUpOwoKCQkvLyBhbmQgdGVzdCB1cGxvYWQKCQl0ZXN0V2l0aEJ1ZmZlclNpemUocmVzdWx0LCBidWZmZXJTaXplKTsKCX0KCWNhdGNoIChVbm1hcEZhaWx1cmVFcnJvciYpCgl7CgkJdGVzdFJ1bk9rID0gZmFsc2U7CgkJdW5tYXBwaW5nRmFpbGVkID0gdHJ1ZTsKCX0KCgkvLyBjbGVhbiB1cDogbWFrZSBzdXJlIGJ1ZmZlciBpcyBub3QgaW4gdXBsb2FkIHF1ZXVlIGFuZCBkZWxldGUgaXQKCgkvLyBzb3VyY2luZyB1bnNwZWNpZmllZCBkYXRhIGNhdXNlcyB1bmRlZmluZWQgcmVzdWx0cywgcG9zc2libHkgcHJvZ3JhbSB0ZXJtaW5hdGlvbgoJaWYgKG1fYnVmZmVyVW5zcGVjaWZpZWRBZnRlclRlc3QgfHwgdW5tYXBwaW5nRmFpbGVkKQoJCWdsLmJ1ZmZlckRhdGEoR0xfQVJSQVlfQlVGRkVSLCBidWZmZXJTaXplLCAmbV96ZXJvRGF0YVswXSwgbV9idWZmZXJVc2FnZSk7CgoJZHJhd0J1ZmZlclJhbmdlKDAsIGJ1ZmZlclNpemUpOwoJQmFzaWNCdWZmZXJDYXNlPFNhbXBsZVR5cGU+Ojp3YWl0R0xSZXN1bHRzKCk7CgoJZ2wuZGVsZXRlQnVmZmVycygxLCAmbV9idWZmZXJJRCk7CgltX2J1ZmZlcklEID0gMDsKCglyZXR1cm4gdGVzdFJ1bk9rOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4Kdm9pZCBNb2RpZnlBZnRlckJhc2ljQ2FzZTxTYW1wbGVUeXBlPjo6bG9nQW5kU2V0VGVzdFJlc3VsdCAoY29uc3Qgc3RkOjp2ZWN0b3I8VXBsb2FkU2FtcGxlUmVzdWx0PFNhbXBsZVR5cGU+ID4mIHJlc3VsdHMpCnsKCWNvbnN0IFVwbG9hZFNhbXBsZUFuYWx5emVSZXN1bHQgYW5hbHlzaXMgPSBhbmFseXplU2FtcGxlUmVzdWx0cyhtX3Rlc3RDdHguZ2V0TG9nKCksIHJlc3VsdHMsIGZhbHNlKTsKCgkvLyBSZXR1cm4gbWVkaWFuIHRyYW5zZmVyIHJhdGUgb2YgdGhlIHNhbXBsZXMKCglpZiAoYW5hbHlzaXMudHJhbnNmZXJSYXRlTWVkaWFuID09IHN0ZDo6bnVtZXJpY19saW1pdHM8ZmxvYXQ+OjppbmZpbml0eSgpKQoJewoJCS8vIHNhbXBsZSB0aW1lcyBhcmUgMSkgaW52YWxpZCBvciAyKSB0aW1lciByZXNvbHV0aW9uIHRvbyBsb3cKCQkvLyByZXBvcnQgc3BlZWQgMCBieXRlcyAvIHMgc2luY2UgcmVhbCB2YWx1ZSBjYW5ub3QgYmUgZGV0ZXJtaW5lZAoJCW1fdGVzdEN0eC5zZXRUZXN0UmVzdWx0KFFQX1RFU1RfUkVTVUxUX1BBU1MsIGRlOjpmbG9hdFRvU3RyaW5nKDAuMGYsIDIpLmNfc3RyKCkpOwoJfQoJZWxzZQoJewoJCS8vIHJlcG9ydCB0cmFuc2ZlciByYXRlIGluIE1CIC8gcwoJCW1fdGVzdEN0eC5zZXRUZXN0UmVzdWx0KFFQX1RFU1RfUkVTVUxUX1BBU1MsIGRlOjpmbG9hdFRvU3RyaW5nKGFuYWx5c2lzLnRyYW5zZmVyUmF0ZU1lZGlhbiAvIDEwMjQuMGYgLyAxMDI0LjBmLCAyKS5jX3N0cigpKTsKCX0KfQoKY2xhc3MgTW9kaWZ5QWZ0ZXJXaXRoQnVmZmVyRGF0YUNhc2UgOiBwdWJsaWMgTW9kaWZ5QWZ0ZXJCYXNpY0Nhc2U8U2luZ2xlT3BlcmF0aW9uRHVyYXRpb24+CnsKcHVibGljOgoKCWVudW0gQ2FzZUZsYWdzCgl7CgkJRkxBR19SRVNQRUNJRllfU0laRQkJPSAweDEsCgkJRkxBR19VUExPQURfUkVQRUFURUQJPSAweDIsCgl9OwoKCQkJCQlNb2RpZnlBZnRlcldpdGhCdWZmZXJEYXRhQ2FzZQkoQ29udGV4dCYgY29udGV4dCwgY29uc3QgY2hhciogbmFtZSwgY29uc3QgY2hhciogZGVzYywgaW50IGJ1ZmZlclNpemVNaW4sIGludCBidWZmZXJTaXplTWF4LCBkZVVpbnQzMiB1c2FnZSwgaW50IGZsYWdzKTsKCQkJCQl+TW9kaWZ5QWZ0ZXJXaXRoQnVmZmVyRGF0YUNhc2UJKHZvaWQpOwoKCXZvaWQJCQlpbml0CQkJCQkJCSh2b2lkKTsKCXZvaWQJCQlkZWluaXQJCQkJCQkJKHZvaWQpOwpwcml2YXRlOgoJdm9pZAkJCXRlc3RXaXRoQnVmZmVyU2l6ZQkJCQkoVXBsb2FkU2FtcGxlUmVzdWx0PFNpbmdsZU9wZXJhdGlvbkR1cmF0aW9uPiYgcmVzdWx0LCBpbnQgYnVmZmVyU2l6ZSk7CgoJZW51bQoJewoJCU5VTV9SRVBFQVRTID0gMgoJfTsKCgljb25zdCBib29sCQltX3Jlc3BlY2lmeVNpemU7Cgljb25zdCBib29sCQltX3JlcGVhdGVkVXBsb2FkOwoJY29uc3QgZmxvYXQJCW1fc2l6ZURpZmZlcmVuY2VGYWN0b3I7Cn07CgpNb2RpZnlBZnRlcldpdGhCdWZmZXJEYXRhQ2FzZTo6TW9kaWZ5QWZ0ZXJXaXRoQnVmZmVyRGF0YUNhc2UgKENvbnRleHQmIGNvbnRleHQsIGNvbnN0IGNoYXIqIG5hbWUsIGNvbnN0IGNoYXIqIGRlc2MsIGludCBidWZmZXJTaXplTWluLCBpbnQgYnVmZmVyU2l6ZU1heCwgZGVVaW50MzIgdXNhZ2UsIGludCBmbGFncykKCTogTW9kaWZ5QWZ0ZXJCYXNpY0Nhc2U8U2luZ2xlT3BlcmF0aW9uRHVyYXRpb24+IChjb250ZXh0LCBuYW1lLCBkZXNjLCBidWZmZXJTaXplTWluLCBidWZmZXJTaXplTWF4LCB1c2FnZSwgZmFsc2UpCgksIG1fcmVzcGVjaWZ5U2l6ZQkJCQkJCQkJKChmbGFncyAmIEZMQUdfUkVTUEVDSUZZX1NJWkUpICE9IDApCgksIG1fcmVwZWF0ZWRVcGxvYWQJCQkJCQkJCSgoZmxhZ3MgJiBGTEFHX1VQTE9BRF9SRVBFQVRFRCkgIT0gMCkKCSwgbV9zaXplRGlmZmVyZW5jZUZhY3RvcgkJCQkJCSgxLjNmKQp7CglERV9BU1NFUlQoIShtX3JlcGVhdGVkVXBsb2FkICYmIG1fcmVzcGVjaWZ5U2l6ZSkpOwp9CgpNb2RpZnlBZnRlcldpdGhCdWZmZXJEYXRhQ2FzZTo6fk1vZGlmeUFmdGVyV2l0aEJ1ZmZlckRhdGFDYXNlICh2b2lkKQp7CglkZWluaXQoKTsKfQoKdm9pZCBNb2RpZnlBZnRlcldpdGhCdWZmZXJEYXRhQ2FzZTo6aW5pdCAodm9pZCkKewoJLy8gTG9nIHRoZSBwdXJwb3NlIG9mIHRoZSB0ZXN0CgoJaWYgKG1fcmVwZWF0ZWRVcGxvYWQpCgkJbV90ZXN0Q3R4LmdldExvZygpIDw8IHRjdTo6VGVzdExvZzo6TWVzc2FnZSA8PCAiVGVzdGluZyBwZXJmb3JtYW5jZSBvZiBCdWZmZXJEYXRhKCkgY29tbWFuZCBhZnRlciBcInNwZWNpZnkgYnVmZmVyIGNvbnRlbnRzIC0gZHJhdyBidWZmZXJcIiBjb21tYW5kIHBhaXIgaXMgcmVwZWF0ZWQgIiA8PCAoaW50KU5VTV9SRVBFQVRTIDw8ICIgdGltZXMuIiA8PCB0Y3U6OlRlc3RMb2c6OkVuZE1lc3NhZ2U7CgllbHNlCgkJbV90ZXN0Q3R4LmdldExvZygpIDw8IHRjdTo6VGVzdExvZzo6TWVzc2FnZSA8PCAiVGVzdGluZyBwZXJmb3JtYW5jZSBvZiBCdWZmZXJEYXRhKCkgY29tbWFuZCBhZnRlciBhIGRyYXcgY29tbWFuZCB0aGF0IHNvdXJjZXMgZGF0YSBmcm9tIHRoZSB0YXJnZXQgYnVmZmVyLiIgPDwgdGN1OjpUZXN0TG9nOjpFbmRNZXNzYWdlOwoKCW1fdGVzdEN0eC5nZXRMb2coKQoJCTw8IHRjdTo6VGVzdExvZzo6TWVzc2FnZQoJCTw8ICgobV9yZXNwZWNpZnlTaXplKSA/CgkJCSgiQnVmZmVyIHNpemUgaXMgaW5jcmVhc2VkIGFuZCBjb250ZW50cyBhcmUgbW9kaWZpZWQgd2l0aCBCdWZmZXJEYXRhKCkuXG4iKSA6CgkJCSgiQnVmZmVyIGNvbnRlbnRzIGFyZSBtb2RpZmllZCB3aXRoIEJ1ZmZlckRhdGEoKS5cbiIpKQoJCTw8IHRjdTo6VGVzdExvZzo6RW5kTWVzc2FnZTsKCgkvLyBpbml0IHBhcmVudAoJTW9kaWZ5QWZ0ZXJCYXNpY0Nhc2U8U2luZ2xlT3BlcmF0aW9uRHVyYXRpb24+Ojppbml0KCk7CgoJLy8gbWFrZSBzdXJlIG91ciB6ZXJvQnVmZmVyIGlzIGxhcmdlIGVub3VnaAoJaWYgKG1fcmVzcGVjaWZ5U2l6ZSkKCXsKCQljb25zdCBpbnQgbGFyZ2VyQnVmZmVyU2l6ZSA9IGRlQWxpZ24zMigoaW50KSgoZmxvYXQpbV9idWZmZXJTaXplTWF4ICogbV9zaXplRGlmZmVyZW5jZUZhY3RvciksIDQqNCk7CgkJbV96ZXJvRGF0YS5yZXNpemUobGFyZ2VyQnVmZmVyU2l6ZSwgMHgwMCk7Cgl9Cn0KCnZvaWQgTW9kaWZ5QWZ0ZXJXaXRoQnVmZmVyRGF0YUNhc2U6OmRlaW5pdCAodm9pZCkKewoJTW9kaWZ5QWZ0ZXJCYXNpY0Nhc2U8U2luZ2xlT3BlcmF0aW9uRHVyYXRpb24+OjpkZWluaXQoKTsKfQoKdm9pZCBNb2RpZnlBZnRlcldpdGhCdWZmZXJEYXRhQ2FzZTo6dGVzdFdpdGhCdWZmZXJTaXplIChVcGxvYWRTYW1wbGVSZXN1bHQ8U2luZ2xlT3BlcmF0aW9uRHVyYXRpb24+JiByZXN1bHQsIGludCBidWZmZXJTaXplKQp7CgkvLyBhbHdheXMgZHJhdyB0aGUgc2FtZSBhbW91bnQgdG8gbWFrZSBjb21wYXJlcyBiZXR3ZWVuIGNhc2VzIHNlbnNpYmxlCgljb25zdCBpbnQJCQkJCWRyYXdTdGFydAkJCT0gZGVBbGlnbjMyKGJ1ZmZlclNpemUgLyA0LCA0KjQpOwoJY29uc3QgaW50CQkJCQlkcmF3RW5kCQkJCT0gZGVBbGlnbjMyKGJ1ZmZlclNpemUgKiAzIC8gNCwgNCo0KTsKCgljb25zdCBnbHc6OkZ1bmN0aW9ucyYJCWdsCQkJCQk9IG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCkuZ2V0RnVuY3Rpb25zKCk7Cgljb25zdCBpbnQJCQkJCWxhcmdlckJ1ZmZlclNpemUJPSBkZUFsaWduMzIoKGludCkoKGZsb2F0KWJ1ZmZlclNpemUgKiBtX3NpemVEaWZmZXJlbmNlRmFjdG9yKSwgNCo0KTsKCWNvbnN0IGludAkJCQkJbmV3QnVmZmVyU2l6ZQkJPSAobV9yZXNwZWNpZnlTaXplKSA/IChsYXJnZXJCdWZmZXJTaXplKSA6IChidWZmZXJTaXplKTsKCWRlVWludDY0CQkJCQlzdGFydFRpbWU7CglkZVVpbnQ2NAkJCQkJZW5kVGltZTsKCgkvLyByZXBlYXQgdXBsb2FkLWRyYXcKCWlmIChtX3JlcGVhdGVkVXBsb2FkKQoJewoJCWZvciAoaW50IHJlcGVhdE5keCA9IDA7IHJlcGVhdE5keCA8IE5VTV9SRVBFQVRTOyArK3JlcGVhdE5keCkKCQl7CgkJCWdsLmJ1ZmZlckRhdGEoR0xfQVJSQVlfQlVGRkVSLCBuZXdCdWZmZXJTaXplLCAmbV96ZXJvRGF0YVswXSwgbV9idWZmZXJVc2FnZSk7CgkJCWRyYXdCdWZmZXJSYW5nZShkcmF3U3RhcnQsIGRyYXdFbmQpOwoJCX0KCX0KCgkvLyB0ZXN0IHVwbG9hZAoJc3RhcnRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCWdsLmJ1ZmZlckRhdGEoR0xfQVJSQVlfQlVGRkVSLCBuZXdCdWZmZXJTaXplLCAmbV96ZXJvRGF0YVswXSwgbV9idWZmZXJVc2FnZSk7CgllbmRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCglyZXN1bHQuZHVyYXRpb24udG90YWxEdXJhdGlvbiA9IGVuZFRpbWUgLSBzdGFydFRpbWU7CglyZXN1bHQuZHVyYXRpb24uZml0UmVzcG9uc2VEdXJhdGlvbiA9IHJlc3VsdC5kdXJhdGlvbi50b3RhbER1cmF0aW9uOwoJcmVzdWx0LndyaXR0ZW5TaXplID0gbmV3QnVmZmVyU2l6ZTsKfQoKY2xhc3MgTW9kaWZ5QWZ0ZXJXaXRoQnVmZmVyU3ViRGF0YUNhc2UgOiBwdWJsaWMgTW9kaWZ5QWZ0ZXJCYXNpY0Nhc2U8U2luZ2xlT3BlcmF0aW9uRHVyYXRpb24+CnsKcHVibGljOgoKCWVudW0gQ2FzZUZsYWdzCgl7CgkJRkxBR19QQVJUSUFMCQkJPSAweDEsCgkJRkxBR19VUExPQURfUkVQRUFURUQJPSAweDIsCgl9OwoKCQkJCQlNb2RpZnlBZnRlcldpdGhCdWZmZXJTdWJEYXRhQ2FzZQkoQ29udGV4dCYgY29udGV4dCwgY29uc3QgY2hhciogbmFtZSwgY29uc3QgY2hhciogZGVzYywgaW50IGJ1ZmZlclNpemVNaW4sIGludCBidWZmZXJTaXplTWF4LCBkZVVpbnQzMiB1c2FnZSwgaW50IGZsYWdzKTsKCQkJCQl+TW9kaWZ5QWZ0ZXJXaXRoQnVmZmVyU3ViRGF0YUNhc2UJKHZvaWQpOwoKCXZvaWQJCQlpbml0CQkJCQkJCQkodm9pZCk7Cgl2b2lkCQkJZGVpbml0CQkJCQkJCQkodm9pZCk7CnByaXZhdGU6Cgl2b2lkCQkJdGVzdFdpdGhCdWZmZXJTaXplCQkJCQkoVXBsb2FkU2FtcGxlUmVzdWx0PFNpbmdsZU9wZXJhdGlvbkR1cmF0aW9uPiYgcmVzdWx0LCBpbnQgYnVmZmVyU2l6ZSk7CgoJZW51bQoJewoJCU5VTV9SRVBFQVRTID0gMgoJfTsKCgljb25zdCBib29sCQltX3BhcnRpYWxVcGxvYWQ7Cgljb25zdCBib29sCQltX3JlcGVhdGVkVXBsb2FkOwp9OwoKTW9kaWZ5QWZ0ZXJXaXRoQnVmZmVyU3ViRGF0YUNhc2U6Ok1vZGlmeUFmdGVyV2l0aEJ1ZmZlclN1YkRhdGFDYXNlIChDb250ZXh0JiBjb250ZXh0LCBjb25zdCBjaGFyKiBuYW1lLCBjb25zdCBjaGFyKiBkZXNjLCBpbnQgYnVmZmVyU2l6ZU1pbiwgaW50IGJ1ZmZlclNpemVNYXgsIGRlVWludDMyIHVzYWdlLCBpbnQgZmxhZ3MpCgk6IE1vZGlmeUFmdGVyQmFzaWNDYXNlPFNpbmdsZU9wZXJhdGlvbkR1cmF0aW9uPgkoY29udGV4dCwgbmFtZSwgZGVzYywgYnVmZmVyU2l6ZU1pbiwgYnVmZmVyU2l6ZU1heCwgdXNhZ2UsIGZhbHNlKQoJLCBtX3BhcnRpYWxVcGxvYWQJCQkJCQkJCSgoZmxhZ3MgJiBGTEFHX1BBUlRJQUwpICE9IDApCgksIG1fcmVwZWF0ZWRVcGxvYWQJCQkJCQkJCSgoZmxhZ3MgJiBGTEFHX1VQTE9BRF9SRVBFQVRFRCkgIT0gMCkKewp9CgpNb2RpZnlBZnRlcldpdGhCdWZmZXJTdWJEYXRhQ2FzZTo6fk1vZGlmeUFmdGVyV2l0aEJ1ZmZlclN1YkRhdGFDYXNlICh2b2lkKQp7CglkZWluaXQoKTsKfQoKdm9pZCBNb2RpZnlBZnRlcldpdGhCdWZmZXJTdWJEYXRhQ2FzZTo6aW5pdCAodm9pZCkKewoJLy8gTG9nIHRoZSBwdXJwb3NlIG9mIHRoZSB0ZXN0CgoJaWYgKG1fcmVwZWF0ZWRVcGxvYWQpCgkJbV90ZXN0Q3R4LmdldExvZygpIDw8IHRjdTo6VGVzdExvZzo6TWVzc2FnZSA8PCAiVGVzdGluZyBwZXJmb3JtYW5jZSBvZiBCdWZmZXJTdWJEYXRhKCkgY29tbWFuZCBhZnRlciBcInNwZWNpZnkgYnVmZmVyIGNvbnRlbnRzIC0gZHJhdyBidWZmZXJcIiBjb21tYW5kIHBhaXIgaXMgcmVwZWF0ZWQgIiA8PCAoaW50KU5VTV9SRVBFQVRTIDw8ICIgdGltZXMuIiA8PCB0Y3U6OlRlc3RMb2c6OkVuZE1lc3NhZ2U7CgllbHNlCgkJbV90ZXN0Q3R4LmdldExvZygpIDw8IHRjdTo6VGVzdExvZzo6TWVzc2FnZSA8PCAiVGVzdGluZyBwZXJmb3JtYW5jZSBvZiBCdWZmZXJTdWJEYXRhKCkgY29tbWFuZCBhZnRlciBhIGRyYXcgY29tbWFuZCB0aGF0IHNvdXJjZXMgZGF0YSBmcm9tIHRoZSB0YXJnZXQgYnVmZmVyLiIgPDwgdGN1OjpUZXN0TG9nOjpFbmRNZXNzYWdlOwoKCW1fdGVzdEN0eC5nZXRMb2coKQoJCTw8IHRjdTo6VGVzdExvZzo6TWVzc2FnZQoJCTw8ICgobV9wYXJ0aWFsVXBsb2FkKSA/CgkJCSgiSGFsZiBvZiB0aGUgYnVmZmVyIGNvbnRlbnRzIGFyZSBtb2RpZmllZC5cbiIpIDoKCQkJKCJCdWZmZXIgY29udGVudHMgYXJlIGZ1bGx5IHJlc3BlY2lmaWVkLlxuIikpCgkJPDwgdGN1OjpUZXN0TG9nOjpFbmRNZXNzYWdlOwoKCU1vZGlmeUFmdGVyQmFzaWNDYXNlPFNpbmdsZU9wZXJhdGlvbkR1cmF0aW9uPjo6aW5pdCgpOwp9Cgp2b2lkIE1vZGlmeUFmdGVyV2l0aEJ1ZmZlclN1YkRhdGFDYXNlOjpkZWluaXQgKHZvaWQpCnsKCU1vZGlmeUFmdGVyQmFzaWNDYXNlPFNpbmdsZU9wZXJhdGlvbkR1cmF0aW9uPjo6ZGVpbml0KCk7Cn0KCnZvaWQgTW9kaWZ5QWZ0ZXJXaXRoQnVmZmVyU3ViRGF0YUNhc2U6OnRlc3RXaXRoQnVmZmVyU2l6ZSAoVXBsb2FkU2FtcGxlUmVzdWx0PFNpbmdsZU9wZXJhdGlvbkR1cmF0aW9uPiYgcmVzdWx0LCBpbnQgYnVmZmVyU2l6ZSkKewoJLy8gYWx3YXlzIGRyYXcgdGhlIHNhbWUgYW1vdW50IHRvIG1ha2UgY29tcGFyZXMgYmV0d2VlbiBjYXNlcyBzZW5zaWJsZQoJY29uc3QgaW50CQkJCQlkcmF3U3RhcnQJCQk9IGRlQWxpZ24zMihidWZmZXJTaXplIC8gNCwgNCo0KTsKCWNvbnN0IGludAkJCQkJZHJhd0VuZAkJCQk9IGRlQWxpZ24zMihidWZmZXJTaXplICogMyAvIDQsIDQqNCk7CgoJY29uc3QgZ2x3OjpGdW5jdGlvbnMmCQlnbAkJCQkJPSBtX2NvbnRleHQuZ2V0UmVuZGVyQ29udGV4dCgpLmdldEZ1bmN0aW9ucygpOwoJY29uc3QgaW50CQkJCQlzdWJkYXRhT2Zmc2V0CQk9IGRlQWxpZ24zMigobV9wYXJ0aWFsVXBsb2FkKSA/IChidWZmZXJTaXplIC8gNCkgOiAoMCksIDQqNCk7Cgljb25zdCBpbnQJCQkJCXN1YmRhdGFTaXplCQkJPSBkZUFsaWduMzIoKG1fcGFydGlhbFVwbG9hZCkgPyAoYnVmZmVyU2l6ZSAvIDIpIDogKGJ1ZmZlclNpemUpLCA0KjQpOwoJZGVVaW50NjQJCQkJCXN0YXJ0VGltZTsKCWRlVWludDY0CQkJCQllbmRUaW1lOwoKCS8vIG1ha2UgdXBsb2FkLWRyYXcgc3RyZWFtCglpZiAobV9yZXBlYXRlZFVwbG9hZCkKCXsKCQlmb3IgKGludCByZXBlYXROZHggPSAwOyByZXBlYXROZHggPCBOVU1fUkVQRUFUUzsgKytyZXBlYXROZHgpCgkJewoJCQlnbC5idWZmZXJTdWJEYXRhKEdMX0FSUkFZX0JVRkZFUiwgc3ViZGF0YU9mZnNldCwgc3ViZGF0YVNpemUsICZtX3plcm9EYXRhWzBdKTsKCQkJZHJhd0J1ZmZlclJhbmdlKGRyYXdTdGFydCwgZHJhd0VuZCk7CgkJfQoJfQoKCS8vIHRlc3QgdXBsb2FkCglzdGFydFRpbWUgPSBkZUdldE1pY3Jvc2Vjb25kcygpOwoJZ2wuYnVmZmVyU3ViRGF0YShHTF9BUlJBWV9CVUZGRVIsIHN1YmRhdGFPZmZzZXQsIHN1YmRhdGFTaXplLCAmbV96ZXJvRGF0YVswXSk7CgllbmRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCglyZXN1bHQuZHVyYXRpb24udG90YWxEdXJhdGlvbiA9IGVuZFRpbWUgLSBzdGFydFRpbWU7CglyZXN1bHQuZHVyYXRpb24uZml0UmVzcG9uc2VEdXJhdGlvbiA9IHJlc3VsdC5kdXJhdGlvbi50b3RhbER1cmF0aW9uOwoJcmVzdWx0LndyaXR0ZW5TaXplID0gc3ViZGF0YVNpemU7Cn0KCmNsYXNzIE1vZGlmeUFmdGVyV2l0aE1hcEJ1ZmZlclJhbmdlQ2FzZSA6IHB1YmxpYyBNb2RpZnlBZnRlckJhc2ljQ2FzZTxNYXBCdWZmZXJSYW5nZUR1cmF0aW9uTm9BbGxvYz4KewpwdWJsaWM6CgoJZW51bSBDYXNlRmxhZ3MKCXsKCQlGTEFHX1BBUlRJQUwgPSAweDEsCgl9OwoKCQkJCQlNb2RpZnlBZnRlcldpdGhNYXBCdWZmZXJSYW5nZUNhc2UJKENvbnRleHQmIGNvbnRleHQsIGNvbnN0IGNoYXIqIG5hbWUsIGNvbnN0IGNoYXIqIGRlc2MsIGludCBidWZmZXJTaXplTWluLCBpbnQgYnVmZmVyU2l6ZU1heCwgZGVVaW50MzIgdXNhZ2UsIGludCBmbGFncywgZGVVaW50MzIgZ2xNYXBGbGFncyk7CgkJCQkJfk1vZGlmeUFmdGVyV2l0aE1hcEJ1ZmZlclJhbmdlQ2FzZQkodm9pZCk7CgoJdm9pZAkJCWluaXQJCQkJCQkJCSh2b2lkKTsKCXZvaWQJCQlkZWluaXQJCQkJCQkJCSh2b2lkKTsKcHJpdmF0ZToKCXN0YXRpYyBib29sCQlpc0J1ZmZlclVuc3BlY2lmaWVkQWZ0ZXJVcGxvYWQJCShpbnQgZmxhZ3MsIGRlVWludDMyIG1hcEZsYWdzKTsKCXZvaWQJCQl0ZXN0V2l0aEJ1ZmZlclNpemUJCQkJCShVcGxvYWRTYW1wbGVSZXN1bHQ8TWFwQnVmZmVyUmFuZ2VEdXJhdGlvbk5vQWxsb2M+JiByZXN1bHQsIGludCBidWZmZXJTaXplKTsKCgljb25zdCBib29sCQltX3BhcnRpYWxVcGxvYWQ7Cgljb25zdCBkZVVpbnQzMgltX21hcEZsYWdzOwp9OwoKTW9kaWZ5QWZ0ZXJXaXRoTWFwQnVmZmVyUmFuZ2VDYXNlOjpNb2RpZnlBZnRlcldpdGhNYXBCdWZmZXJSYW5nZUNhc2UgKENvbnRleHQmIGNvbnRleHQsIGNvbnN0IGNoYXIqIG5hbWUsIGNvbnN0IGNoYXIqIGRlc2MsIGludCBidWZmZXJTaXplTWluLCBpbnQgYnVmZmVyU2l6ZU1heCwgZGVVaW50MzIgdXNhZ2UsIGludCBmbGFncywgZGVVaW50MzIgZ2xNYXBGbGFncykKCTogTW9kaWZ5QWZ0ZXJCYXNpY0Nhc2U8TWFwQnVmZmVyUmFuZ2VEdXJhdGlvbk5vQWxsb2M+CShjb250ZXh0LCBuYW1lLCBkZXNjLCBidWZmZXJTaXplTWluLCBidWZmZXJTaXplTWF4LCB1c2FnZSwgaXNCdWZmZXJVbnNwZWNpZmllZEFmdGVyVXBsb2FkKGZsYWdzLCBnbE1hcEZsYWdzKSkKCSwgbV9wYXJ0aWFsVXBsb2FkCQkJCQkJCQkJCSgoZmxhZ3MgJiBGTEFHX1BBUlRJQUwpICE9IDApCgksIG1fbWFwRmxhZ3MJCQkJCQkJCQkJCShnbE1hcEZsYWdzKQp7Cn0KCk1vZGlmeUFmdGVyV2l0aE1hcEJ1ZmZlclJhbmdlQ2FzZTo6fk1vZGlmeUFmdGVyV2l0aE1hcEJ1ZmZlclJhbmdlQ2FzZSAodm9pZCkKewoJZGVpbml0KCk7Cn0KCnZvaWQgTW9kaWZ5QWZ0ZXJXaXRoTWFwQnVmZmVyUmFuZ2VDYXNlOjppbml0ICh2b2lkKQp7CgkvLyBMb2cgdGhlIHB1cnBvc2Ugb2YgdGhlIHRlc3QKCgltX3Rlc3RDdHguZ2V0TG9nKCkKCQk8PCB0Y3U6OlRlc3RMb2c6Ok1lc3NhZ2UKCQk8PCAiVGVzdGluZyBwZXJmb3JtYW5jZSBvZiBNYXBCdWZmZXJSYW5nZSgpIGNvbW1hbmQgYWZ0ZXIgYSBkcmF3IGNvbW1hbmQgdGhhdCBzb3VyY2VzIGRhdGEgZnJvbSB0aGUgdGFyZ2V0IGJ1ZmZlci5cbiIKCQk8PCAoKG1fcGFydGlhbFVwbG9hZCkgPwoJCQkoIkhhbGYgb2YgdGhlIGJ1ZmZlciBpcyBtYXBwZWQuXG4iKSA6CgkJCSgiV2hvbGUgYnVmZmVyIGlzIG1hcHBlZC5cbiIpKQoJCTw8ICJNYXAgYml0czpcbiIKCQk8PCAoKG1fbWFwRmxhZ3MgJiBHTF9NQVBfV1JJVEVfQklUKSA/ICgiXHRHTF9NQVBfV1JJVEVfQklUXG4iKSA6ICgiIikpCgkJPDwgKChtX21hcEZsYWdzICYgR0xfTUFQX1JFQURfQklUKSA/ICgiXHRHTF9NQVBfUkVBRF9CSVRcbiIpIDogKCIiKSkKCQk8PCAoKG1fbWFwRmxhZ3MgJiBHTF9NQVBfSU5WQUxJREFURV9SQU5HRV9CSVQpID8gKCJcdEdMX01BUF9JTlZBTElEQVRFX1JBTkdFX0JJVFxuIikgOiAoIiIpKQoJCTw8ICgobV9tYXBGbGFncyAmIEdMX01BUF9JTlZBTElEQVRFX0JVRkZFUl9CSVQpID8gKCJcdEdMX01BUF9JTlZBTElEQVRFX0JVRkZFUl9CSVRcbiIpIDogKCIiKSkKCQk8PCAoKG1fbWFwRmxhZ3MgJiBHTF9NQVBfVU5TWU5DSFJPTklaRURfQklUKSA/ICgiXHRHTF9NQVBfVU5TWU5DSFJPTklaRURfQklUXG4iKSA6ICgiIikpCgkJPDwgKChtX21hcEZsYWdzICYgR0xfTUFQX0ZMVVNIX0VYUExJQ0lUX0JJVCkgPyAoIlx0R0xfTUFQX0ZMVVNIX0VYUExJQ0lUX0JJVFxuIikgOiAoIiIpKQoJCTw8IHRjdTo6VGVzdExvZzo6RW5kTWVzc2FnZTsKCglNb2RpZnlBZnRlckJhc2ljQ2FzZTxNYXBCdWZmZXJSYW5nZUR1cmF0aW9uTm9BbGxvYz46OmluaXQoKTsKfQoKdm9pZCBNb2RpZnlBZnRlcldpdGhNYXBCdWZmZXJSYW5nZUNhc2U6OmRlaW5pdCAodm9pZCkKewoJTW9kaWZ5QWZ0ZXJCYXNpY0Nhc2U8TWFwQnVmZmVyUmFuZ2VEdXJhdGlvbk5vQWxsb2M+OjpkZWluaXQoKTsKfQoKYm9vbCBNb2RpZnlBZnRlcldpdGhNYXBCdWZmZXJSYW5nZUNhc2U6OmlzQnVmZmVyVW5zcGVjaWZpZWRBZnRlclVwbG9hZCAoaW50IGZsYWdzLCBkZVVpbnQzMiBtYXBGbGFncykKewoJaWYgKChmbGFncyAmIEZMQUdfUEFSVElBTCkgIT0gMCAmJiAoKG1hcEZsYWdzICYgR0xfTUFQX0lOVkFMSURBVEVfQlVGRkVSX0JJVCkgIT0gMCkpCgkJcmV0dXJuIHRydWU7CgoJcmV0dXJuIGZhbHNlOwp9Cgp2b2lkIE1vZGlmeUFmdGVyV2l0aE1hcEJ1ZmZlclJhbmdlQ2FzZTo6dGVzdFdpdGhCdWZmZXJTaXplIChVcGxvYWRTYW1wbGVSZXN1bHQ8TWFwQnVmZmVyUmFuZ2VEdXJhdGlvbk5vQWxsb2M+JiByZXN1bHQsIGludCBidWZmZXJTaXplKQp7Cgljb25zdCBnbHc6OkZ1bmN0aW9ucyYJCWdsCQkJCQk9IG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCkuZ2V0RnVuY3Rpb25zKCk7Cgljb25zdCBpbnQJCQkJCXN1YmRhdGFPZmZzZXQJCT0gZGVBbGlnbjMyKChtX3BhcnRpYWxVcGxvYWQpID8gKGJ1ZmZlclNpemUgLyA0KSA6ICgwKSwgNCo0KTsKCWNvbnN0IGludAkJCQkJc3ViZGF0YVNpemUJCQk9IGRlQWxpZ24zMigobV9wYXJ0aWFsVXBsb2FkKSA/IChidWZmZXJTaXplIC8gMikgOiAoYnVmZmVyU2l6ZSksIDQqNCk7Cgl2b2lkKgkJCQkJCW1hcFB0cjsKCgkvLyBtYXAKCXsKCQlkZVVpbnQ2NCBzdGFydFRpbWU7CgkJZGVVaW50NjQgZW5kVGltZTsKCgkJc3RhcnRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCQltYXBQdHIgPSBnbC5tYXBCdWZmZXJSYW5nZShHTF9BUlJBWV9CVUZGRVIsIHN1YmRhdGFPZmZzZXQsIHN1YmRhdGFTaXplLCBtX21hcEZsYWdzKTsKCQllbmRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCgkJaWYgKCFtYXBQdHIpCgkJCXRocm93IHRjdTo6VGVzdEVycm9yKCJtYXBCdWZmZXJSYW5nZSByZXR1cm5lZCBudWxsIik7CgoJCXJlc3VsdC5kdXJhdGlvbi5tYXBEdXJhdGlvbiA9IGVuZFRpbWUgLSBzdGFydFRpbWU7Cgl9CgoJLy8gd3JpdGUKCXsKCQlyZXN1bHQuZHVyYXRpb24ud3JpdGVEdXJhdGlvbiA9IG1lZGlhblRpbWVNZW1jcHkobWFwUHRyLCAmbV96ZXJvRGF0YVswXSwgc3ViZGF0YVNpemUpOwoJfQoKCS8vIHVubWFwCgl7CgkJZGVVaW50NjQJCXN0YXJ0VGltZTsKCQlkZVVpbnQ2NAkJZW5kVGltZTsKCQlnbHc6OkdMYm9vbGVhbgl1bm1hcFN1Y2NlZWRlZDsKCgkJc3RhcnRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCQl1bm1hcFN1Y2NlZWRlZCA9IGdsLnVubWFwQnVmZmVyKEdMX0FSUkFZX0JVRkZFUik7CgkJZW5kVGltZSA9IGRlR2V0TWljcm9zZWNvbmRzKCk7CgoJCWlmICh1bm1hcFN1Y2NlZWRlZCAhPSBHTF9UUlVFKQoJCQl0aHJvdyBVbm1hcEZhaWx1cmVFcnJvcigpOwoKCQlyZXN1bHQuZHVyYXRpb24udW5tYXBEdXJhdGlvbiA9IGVuZFRpbWUgLSBzdGFydFRpbWU7Cgl9CgoJcmVzdWx0LmR1cmF0aW9uLnRvdGFsRHVyYXRpb24gPSByZXN1bHQuZHVyYXRpb24ubWFwRHVyYXRpb24gKyByZXN1bHQuZHVyYXRpb24ud3JpdGVEdXJhdGlvbiArIHJlc3VsdC5kdXJhdGlvbi51bm1hcER1cmF0aW9uOwoJcmVzdWx0LmR1cmF0aW9uLmZpdFJlc3BvbnNlRHVyYXRpb24gPSByZXN1bHQuZHVyYXRpb24udG90YWxEdXJhdGlvbjsKCXJlc3VsdC53cml0dGVuU2l6ZSA9IHN1YmRhdGFTaXplOwp9CgpjbGFzcyBNb2RpZnlBZnRlcldpdGhNYXBCdWZmZXJGbHVzaENhc2UgOiBwdWJsaWMgTW9kaWZ5QWZ0ZXJCYXNpY0Nhc2U8TWFwQnVmZmVyUmFuZ2VGbHVzaER1cmF0aW9uTm9BbGxvYz4KewpwdWJsaWM6CgoJZW51bSBDYXNlRmxhZ3MKCXsKCQlGTEFHX1BBUlRJQUwgPSAweDEsCgl9OwoKCQkJCQlNb2RpZnlBZnRlcldpdGhNYXBCdWZmZXJGbHVzaENhc2UJKENvbnRleHQmIGNvbnRleHQsIGNvbnN0IGNoYXIqIG5hbWUsIGNvbnN0IGNoYXIqIGRlc2MsIGludCBidWZmZXJTaXplTWluLCBpbnQgYnVmZmVyU2l6ZU1heCwgZGVVaW50MzIgdXNhZ2UsIGludCBmbGFncywgZGVVaW50MzIgZ2xNYXBGbGFncyk7CgkJCQkJfk1vZGlmeUFmdGVyV2l0aE1hcEJ1ZmZlckZsdXNoQ2FzZQkodm9pZCk7CgoJdm9pZAkJCWluaXQJCQkJCQkJCSh2b2lkKTsKCXZvaWQJCQlkZWluaXQJCQkJCQkJCSh2b2lkKTsKcHJpdmF0ZToKCXN0YXRpYyBib29sCQlpc0J1ZmZlclVuc3BlY2lmaWVkQWZ0ZXJVcGxvYWQJCShpbnQgZmxhZ3MsIGRlVWludDMyIG1hcEZsYWdzKTsKCXZvaWQJCQl0ZXN0V2l0aEJ1ZmZlclNpemUJCQkJCShVcGxvYWRTYW1wbGVSZXN1bHQ8TWFwQnVmZmVyUmFuZ2VGbHVzaER1cmF0aW9uTm9BbGxvYz4mIHJlc3VsdCwgaW50IGJ1ZmZlclNpemUpOwoKCWNvbnN0IGJvb2wJCW1fcGFydGlhbFVwbG9hZDsKCWNvbnN0IGRlVWludDMyCW1fbWFwRmxhZ3M7Cn07CgpNb2RpZnlBZnRlcldpdGhNYXBCdWZmZXJGbHVzaENhc2U6Ok1vZGlmeUFmdGVyV2l0aE1hcEJ1ZmZlckZsdXNoQ2FzZSAoQ29udGV4dCYgY29udGV4dCwgY29uc3QgY2hhciogbmFtZSwgY29uc3QgY2hhciogZGVzYywgaW50IGJ1ZmZlclNpemVNaW4sIGludCBidWZmZXJTaXplTWF4LCBkZVVpbnQzMiB1c2FnZSwgaW50IGZsYWdzLCBkZVVpbnQzMiBnbE1hcEZsYWdzKQoJOiBNb2RpZnlBZnRlckJhc2ljQ2FzZTxNYXBCdWZmZXJSYW5nZUZsdXNoRHVyYXRpb25Ob0FsbG9jPgkoY29udGV4dCwgbmFtZSwgZGVzYywgYnVmZmVyU2l6ZU1pbiwgYnVmZmVyU2l6ZU1heCwgdXNhZ2UsIGlzQnVmZmVyVW5zcGVjaWZpZWRBZnRlclVwbG9hZChmbGFncywgZ2xNYXBGbGFncykpCgksIG1fcGFydGlhbFVwbG9hZAkJCQkJCQkJCQkJKChmbGFncyAmIEZMQUdfUEFSVElBTCkgIT0gMCkKCSwgbV9tYXBGbGFncwkJCQkJCQkJCQkJCShnbE1hcEZsYWdzKQp7Cn0KCk1vZGlmeUFmdGVyV2l0aE1hcEJ1ZmZlckZsdXNoQ2FzZTo6fk1vZGlmeUFmdGVyV2l0aE1hcEJ1ZmZlckZsdXNoQ2FzZSAodm9pZCkKewoJZGVpbml0KCk7Cn0KCnZvaWQgTW9kaWZ5QWZ0ZXJXaXRoTWFwQnVmZmVyRmx1c2hDYXNlOjppbml0ICh2b2lkKQp7CgkvLyBMb2cgdGhlIHB1cnBvc2Ugb2YgdGhlIHRlc3QKCgltX3Rlc3RDdHguZ2V0TG9nKCkKCQk8PCB0Y3U6OlRlc3RMb2c6Ok1lc3NhZ2UKCQk8PCAiVGVzdGluZyBwZXJmb3JtYW5jZSBvZiBNYXBCdWZmZXJSYW5nZSgpIGNvbW1hbmQgYWZ0ZXIgYSBkcmF3IGNvbW1hbmQgdGhhdCBzb3VyY2VzIGRhdGEgZnJvbSB0aGUgdGFyZ2V0IGJ1ZmZlci5cbiIKCQk8PCAoKG1fcGFydGlhbFVwbG9hZCkgPwoJCQkoIkhhbGYgb2YgdGhlIGJ1ZmZlciBpcyBtYXBwZWQuXG4iKSA6CgkJCSgiV2hvbGUgYnVmZmVyIGlzIG1hcHBlZC5cbiIpKQoJCTw8ICJNYXAgYml0czpcbiIKCQk8PCAoKG1fbWFwRmxhZ3MgJiBHTF9NQVBfV1JJVEVfQklUKSA/ICgiXHRHTF9NQVBfV1JJVEVfQklUXG4iKSA6ICgiIikpCgkJPDwgKChtX21hcEZsYWdzICYgR0xfTUFQX1JFQURfQklUKSA/ICgiXHRHTF9NQVBfUkVBRF9CSVRcbiIpIDogKCIiKSkKCQk8PCAoKG1fbWFwRmxhZ3MgJiBHTF9NQVBfSU5WQUxJREFURV9SQU5HRV9CSVQpID8gKCJcdEdMX01BUF9JTlZBTElEQVRFX1JBTkdFX0JJVFxuIikgOiAoIiIpKQoJCTw8ICgobV9tYXBGbGFncyAmIEdMX01BUF9JTlZBTElEQVRFX0JVRkZFUl9CSVQpID8gKCJcdEdMX01BUF9JTlZBTElEQVRFX0JVRkZFUl9CSVRcbiIpIDogKCIiKSkKCQk8PCAoKG1fbWFwRmxhZ3MgJiBHTF9NQVBfVU5TWU5DSFJPTklaRURfQklUKSA/ICgiXHRHTF9NQVBfVU5TWU5DSFJPTklaRURfQklUXG4iKSA6ICgiIikpCgkJPDwgKChtX21hcEZsYWdzICYgR0xfTUFQX0ZMVVNIX0VYUExJQ0lUX0JJVCkgPyAoIlx0R0xfTUFQX0ZMVVNIX0VYUExJQ0lUX0JJVFxuIikgOiAoIiIpKQoJCTw8IHRjdTo6VGVzdExvZzo6RW5kTWVzc2FnZTsKCglNb2RpZnlBZnRlckJhc2ljQ2FzZTxNYXBCdWZmZXJSYW5nZUZsdXNoRHVyYXRpb25Ob0FsbG9jPjo6aW5pdCgpOwp9Cgp2b2lkIE1vZGlmeUFmdGVyV2l0aE1hcEJ1ZmZlckZsdXNoQ2FzZTo6ZGVpbml0ICh2b2lkKQp7CglNb2RpZnlBZnRlckJhc2ljQ2FzZTxNYXBCdWZmZXJSYW5nZUZsdXNoRHVyYXRpb25Ob0FsbG9jPjo6ZGVpbml0KCk7Cn0KCmJvb2wgTW9kaWZ5QWZ0ZXJXaXRoTWFwQnVmZmVyRmx1c2hDYXNlOjppc0J1ZmZlclVuc3BlY2lmaWVkQWZ0ZXJVcGxvYWQgKGludCBmbGFncywgZGVVaW50MzIgbWFwRmxhZ3MpCnsKCWlmICgoZmxhZ3MgJiBGTEFHX1BBUlRJQUwpICE9IDAgJiYgKChtYXBGbGFncyAmIEdMX01BUF9JTlZBTElEQVRFX0JVRkZFUl9CSVQpICE9IDApKQoJCXJldHVybiB0cnVlOwoKCXJldHVybiBmYWxzZTsKfQoKdm9pZCBNb2RpZnlBZnRlcldpdGhNYXBCdWZmZXJGbHVzaENhc2U6OnRlc3RXaXRoQnVmZmVyU2l6ZSAoVXBsb2FkU2FtcGxlUmVzdWx0PE1hcEJ1ZmZlclJhbmdlRmx1c2hEdXJhdGlvbk5vQWxsb2M+JiByZXN1bHQsIGludCBidWZmZXJTaXplKQp7Cgljb25zdCBnbHc6OkZ1bmN0aW9ucyYJCWdsCQkJCQk9IG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCkuZ2V0RnVuY3Rpb25zKCk7Cgljb25zdCBpbnQJCQkJCXN1YmRhdGFPZmZzZXQJCT0gZGVBbGlnbjMyKChtX3BhcnRpYWxVcGxvYWQpID8gKGJ1ZmZlclNpemUgLyA0KSA6ICgwKSwgNCo0KTsKCWNvbnN0IGludAkJCQkJc3ViZGF0YVNpemUJCQk9IGRlQWxpZ24zMigobV9wYXJ0aWFsVXBsb2FkKSA/IChidWZmZXJTaXplIC8gMikgOiAoYnVmZmVyU2l6ZSksIDQqNCk7Cgl2b2lkKgkJCQkJCW1hcFB0cjsKCgkvLyBtYXAKCXsKCQlkZVVpbnQ2NCBzdGFydFRpbWU7CgkJZGVVaW50NjQgZW5kVGltZTsKCgkJc3RhcnRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCQltYXBQdHIgPSBnbC5tYXBCdWZmZXJSYW5nZShHTF9BUlJBWV9CVUZGRVIsIHN1YmRhdGFPZmZzZXQsIHN1YmRhdGFTaXplLCBtX21hcEZsYWdzKTsKCQllbmRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCgkJaWYgKCFtYXBQdHIpCgkJCXRocm93IHRjdTo6VGVzdEVycm9yKCJtYXBCdWZmZXJSYW5nZSByZXR1cm5lZCBudWxsIik7CgoJCXJlc3VsdC5kdXJhdGlvbi5tYXBEdXJhdGlvbiA9IGVuZFRpbWUgLSBzdGFydFRpbWU7Cgl9CgoJLy8gd3JpdGUKCXsKCQlyZXN1bHQuZHVyYXRpb24ud3JpdGVEdXJhdGlvbiA9IG1lZGlhblRpbWVNZW1jcHkobWFwUHRyLCAmbV96ZXJvRGF0YVswXSwgc3ViZGF0YVNpemUpOwoJfQoKCS8vIGZsdXNoCgl7CgkJZGVVaW50NjQgc3RhcnRUaW1lOwoJCWRlVWludDY0IGVuZFRpbWU7CgoJCXN0YXJ0VGltZSA9IGRlR2V0TWljcm9zZWNvbmRzKCk7CgkJZ2wuZmx1c2hNYXBwZWRCdWZmZXJSYW5nZShHTF9BUlJBWV9CVUZGRVIsIDAsIHN1YmRhdGFTaXplKTsKCQllbmRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCgkJcmVzdWx0LmR1cmF0aW9uLmZsdXNoRHVyYXRpb24gPSBlbmRUaW1lIC0gc3RhcnRUaW1lOwoJfQoKCS8vIHVubWFwCgl7CgkJZGVVaW50NjQJCXN0YXJ0VGltZTsKCQlkZVVpbnQ2NAkJZW5kVGltZTsKCQlnbHc6OkdMYm9vbGVhbgl1bm1hcFN1Y2NlZWRlZDsKCgkJc3RhcnRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCQl1bm1hcFN1Y2NlZWRlZCA9IGdsLnVubWFwQnVmZmVyKEdMX0FSUkFZX0JVRkZFUik7CgkJZW5kVGltZSA9IGRlR2V0TWljcm9zZWNvbmRzKCk7CgoJCWlmICh1bm1hcFN1Y2NlZWRlZCAhPSBHTF9UUlVFKQoJCQl0aHJvdyBVbm1hcEZhaWx1cmVFcnJvcigpOwoKCQlyZXN1bHQuZHVyYXRpb24udW5tYXBEdXJhdGlvbiA9IGVuZFRpbWUgLSBzdGFydFRpbWU7Cgl9CgoJcmVzdWx0LmR1cmF0aW9uLnRvdGFsRHVyYXRpb24gPSByZXN1bHQuZHVyYXRpb24ubWFwRHVyYXRpb24gKyByZXN1bHQuZHVyYXRpb24ud3JpdGVEdXJhdGlvbiArIHJlc3VsdC5kdXJhdGlvbi51bm1hcER1cmF0aW9uICsgcmVzdWx0LmR1cmF0aW9uLmZsdXNoRHVyYXRpb247CglyZXN1bHQuZHVyYXRpb24uZml0UmVzcG9uc2VEdXJhdGlvbiA9IHJlc3VsdC5kdXJhdGlvbi50b3RhbER1cmF0aW9uOwoJcmVzdWx0LndyaXR0ZW5TaXplID0gc3ViZGF0YVNpemU7Cn0KCmVudW0gRHJhd01ldGhvZAp7CglEUkFXTUVUSE9EX0RSQVdfQVJSQVlTID0gMCwKCURSQVdNRVRIT0RfRFJBV19FTEVNRU5UUywKCglEUkFXTUVUSE9EX0xBU1QKfTsKCmVudW0gVGFyZ2V0QnVmZmVyCnsKCVRBUkdFVEJVRkZFUl9WRVJURVggPSAwLAoJVEFSR0VUQlVGRkVSX0lOREVYLAoKCVRBUkdFVEJVRkZFUl9MQVNUCn07CgplbnVtIEJ1ZmZlclN0YXRlCnsKCUJVRkZFUlNUQVRFX05FVyA9IDAsCglCVUZGRVJTVEFURV9FWElTVElORywKCglCVUZGRVJTVEFURV9MQVNUCn07CgplbnVtIFVwbG9hZE1ldGhvZAp7CglVUExPQURNRVRIT0RfQlVGRkVSX0RBVEEgPSAwLAoJVVBMT0FETUVUSE9EX0JVRkZFUl9TVUJfREFUQSwKCVVQTE9BRE1FVEhPRF9NQVBfQlVGRkVSX1JBTkdFLAoKCVVQTE9BRE1FVEhPRF9MQVNUCn07CgplbnVtIFVucmVsYXRlZEJ1ZmZlclR5cGUKewoJVU5SRUxBVEVEQlVGRkVSVFlQRV9OT05FID0gMCwKCVVOUkVMQVRFREJVRkZFUlRZUEVfVkVSVEVYLAoKCVVOUkVMQVRFREJVRkZFUlRZUEVfTEFTVAp9OwoKZW51bSBVcGxvYWRSYW5nZQp7CglVUExPQURSQU5HRV9GVUxMID0gMCwKCVVQTE9BRFJBTkdFX1BBUlRJQUwsCgoJVVBMT0FEUkFOR0VfTEFTVAp9OwoKc3RydWN0IExheWVyZWRHcmlkU3BlYwp7CglpbnQgZ3JpZFdpZHRoOwoJaW50IGdyaWRIZWlnaHQ7CglpbnQgZ3JpZExheWVyczsKfTsKCnN0YXRpYyBpbnQgZ2V0TGF5ZXJlZEdyaWROdW1WZXJ0aWNlcyAoY29uc3QgTGF5ZXJlZEdyaWRTcGVjJiBzY2VuZSkKewoJcmV0dXJuIHNjZW5lLmdyaWRXaWR0aCAqIHNjZW5lLmdyaWRIZWlnaHQgKiBzY2VuZS5ncmlkTGF5ZXJzICogNjsKfQoKc3RhdGljIHZvaWQgZ2VuZXJhdGVMYXllcmVkR3JpZFZlcnRleEF0dHJpYkRhdGE0QzRWIChzdGQ6OnZlY3Rvcjx0Y3U6OlZlYzQ+JiB2ZXJ0ZXhEYXRhLCBjb25zdCBMYXllcmVkR3JpZFNwZWMmIHNjZW5lKQp7CgkvLyBpbnRlcmxlYXZlIGNvbG9yICYgdmVydGV4IGRhdGEKCWNvbnN0IHRjdTo6VmVjNCBncmVlbgkoMC4wZiwgMS4wZiwgMC4wZiwgMC43Zik7Cgljb25zdCB0Y3U6OlZlYzQgeWVsbG93CSgxLjBmLCAxLjBmLCAwLjBmLCAwLjhmKTsKCgl2ZXJ0ZXhEYXRhLnJlc2l6ZShnZXRMYXllcmVkR3JpZE51bVZlcnRpY2VzKHNjZW5lKSAqIDIpOwoKCWZvciAoaW50IGNlbGxZID0gMDsgY2VsbFkgPCBzY2VuZS5ncmlkSGVpZ2h0OyArK2NlbGxZKQoJZm9yIChpbnQgY2VsbFggPSAwOyBjZWxsWCA8IHNjZW5lLmdyaWRXaWR0aDsgKytjZWxsWCkKCWZvciAoaW50IGNlbGxaID0gMDsgY2VsbFogPCBzY2VuZS5ncmlkTGF5ZXJzOyArK2NlbGxaKQoJewoJCWNvbnN0IHRjdTo6VmVjNAljb2xvcgkJPSAoKChjZWxsWCArIGNlbGxZICsgY2VsbFopICUgMikgPT0gMCkgPyAoZ3JlZW4pIDogKHllbGxvdyk7CgkJY29uc3QgZmxvYXQJCWNlbGxMZWZ0CT0gKGZsb2F0KGNlbGxYICApIC8gKGZsb2F0KXNjZW5lLmdyaWRXaWR0aCAgLSAwLjVmKSAqIDIuMGY7CgkJY29uc3QgZmxvYXQJCWNlbGxSaWdodAk9IChmbG9hdChjZWxsWCsxKSAvIChmbG9hdClzY2VuZS5ncmlkV2lkdGggIC0gMC41ZikgKiAyLjBmOwoJCWNvbnN0IGZsb2F0CQljZWxsVG9wCQk9IChmbG9hdChjZWxsWSsxKSAvIChmbG9hdClzY2VuZS5ncmlkSGVpZ2h0IC0gMC41ZikgKiAyLjBmOwoJCWNvbnN0IGZsb2F0CQljZWxsQm90dG9tCT0gKGZsb2F0KGNlbGxZICApIC8gKGZsb2F0KXNjZW5lLmdyaWRIZWlnaHQgLSAwLjVmKSAqIDIuMGY7CgoJCXZlcnRleERhdGFbKGNlbGxZICogc2NlbmUuZ3JpZFdpZHRoICogc2NlbmUuZ3JpZExheWVycyArIGNlbGxYICogc2NlbmUuZ3JpZExheWVycyArIGNlbGxaKSAqIDEyICsgIDBdID0gY29sb3I7CgkJdmVydGV4RGF0YVsoY2VsbFkgKiBzY2VuZS5ncmlkV2lkdGggKiBzY2VuZS5ncmlkTGF5ZXJzICsgY2VsbFggKiBzY2VuZS5ncmlkTGF5ZXJzICsgY2VsbFopICogMTIgKyAgMV0gPSB0Y3U6OlZlYzQoY2VsbExlZnQsIGNlbGxUb3AsIDAuMGYsIDEuMGYpOwoKCQl2ZXJ0ZXhEYXRhWyhjZWxsWSAqIHNjZW5lLmdyaWRXaWR0aCAqIHNjZW5lLmdyaWRMYXllcnMgKyBjZWxsWCAqIHNjZW5lLmdyaWRMYXllcnMgKyBjZWxsWikgKiAxMiArICAyXSA9IGNvbG9yOwoJCXZlcnRleERhdGFbKGNlbGxZICogc2NlbmUuZ3JpZFdpZHRoICogc2NlbmUuZ3JpZExheWVycyArIGNlbGxYICogc2NlbmUuZ3JpZExheWVycyArIGNlbGxaKSAqIDEyICsgIDNdID0gdGN1OjpWZWM0KGNlbGxMZWZ0LCBjZWxsQm90dG9tLCAwLjBmLCAxLjBmKTsKCgkJdmVydGV4RGF0YVsoY2VsbFkgKiBzY2VuZS5ncmlkV2lkdGggKiBzY2VuZS5ncmlkTGF5ZXJzICsgY2VsbFggKiBzY2VuZS5ncmlkTGF5ZXJzICsgY2VsbFopICogMTIgKyAgNF0gPSBjb2xvcjsKCQl2ZXJ0ZXhEYXRhWyhjZWxsWSAqIHNjZW5lLmdyaWRXaWR0aCAqIHNjZW5lLmdyaWRMYXllcnMgKyBjZWxsWCAqIHNjZW5lLmdyaWRMYXllcnMgKyBjZWxsWikgKiAxMiArICA1XSA9IHRjdTo6VmVjNChjZWxsUmlnaHQsIGNlbGxCb3R0b20sIDAuMGYsIDEuMGYpOwoKCQl2ZXJ0ZXhEYXRhWyhjZWxsWSAqIHNjZW5lLmdyaWRXaWR0aCAqIHNjZW5lLmdyaWRMYXllcnMgKyBjZWxsWCAqIHNjZW5lLmdyaWRMYXllcnMgKyBjZWxsWikgKiAxMiArICA2XSA9IGNvbG9yOwoJCXZlcnRleERhdGFbKGNlbGxZICogc2NlbmUuZ3JpZFdpZHRoICogc2NlbmUuZ3JpZExheWVycyArIGNlbGxYICogc2NlbmUuZ3JpZExheWVycyArIGNlbGxaKSAqIDEyICsgIDddID0gdGN1OjpWZWM0KGNlbGxMZWZ0LCBjZWxsVG9wLCAwLjBmLCAxLjBmKTsKCgkJdmVydGV4RGF0YVsoY2VsbFkgKiBzY2VuZS5ncmlkV2lkdGggKiBzY2VuZS5ncmlkTGF5ZXJzICsgY2VsbFggKiBzY2VuZS5ncmlkTGF5ZXJzICsgY2VsbFopICogMTIgKyAgOF0gPSBjb2xvcjsKCQl2ZXJ0ZXhEYXRhWyhjZWxsWSAqIHNjZW5lLmdyaWRXaWR0aCAqIHNjZW5lLmdyaWRMYXllcnMgKyBjZWxsWCAqIHNjZW5lLmdyaWRMYXllcnMgKyBjZWxsWikgKiAxMiArICA5XSA9IHRjdTo6VmVjNChjZWxsUmlnaHQsIGNlbGxCb3R0b20sIDAuMGYsIDEuMGYpOwoKCQl2ZXJ0ZXhEYXRhWyhjZWxsWSAqIHNjZW5lLmdyaWRXaWR0aCAqIHNjZW5lLmdyaWRMYXllcnMgKyBjZWxsWCAqIHNjZW5lLmdyaWRMYXllcnMgKyBjZWxsWikgKiAxMiArIDEwXSA9IGNvbG9yOwoJCXZlcnRleERhdGFbKGNlbGxZICogc2NlbmUuZ3JpZFdpZHRoICogc2NlbmUuZ3JpZExheWVycyArIGNlbGxYICogc2NlbmUuZ3JpZExheWVycyArIGNlbGxaKSAqIDEyICsgMTFdID0gdGN1OjpWZWM0KGNlbGxSaWdodCwgY2VsbFRvcCwgMC4wZiwgMS4wZik7Cgl9Cn0KCnN0YXRpYyB2b2lkIGdlbmVyYXRlTGF5ZXJlZEdyaWRJbmRleERhdGEgKHN0ZDo6dmVjdG9yPGRlVWludDMyPiYgaW5kZXhEYXRhLCBjb25zdCBMYXllcmVkR3JpZFNwZWMmIHNjZW5lKQp7CglpbmRleERhdGEucmVzaXplKGdldExheWVyZWRHcmlkTnVtVmVydGljZXMoc2NlbmUpICogMik7CgoJZm9yIChpbnQgbmR4ID0gMDsgbmR4IDwgc2NlbmUuZ3JpZExheWVycyAqIHNjZW5lLmdyaWRIZWlnaHQgKiBzY2VuZS5ncmlkV2lkdGggKiA2OyArK25keCkKCQlpbmRleERhdGFbbmR4XSA9IG5keDsKfQoKY2xhc3MgUmVuZGVyUGVyZm9ybWFuY2VUZXN0QmFzZSA6IHB1YmxpYyBUZXN0Q2FzZQp7CnB1YmxpYzoKCQkJCQkJCVJlbmRlclBlcmZvcm1hbmNlVGVzdEJhc2UJKENvbnRleHQmIGNvbnRleHQsIGNvbnN0IGNoYXIqIG5hbWUsIGNvbnN0IGNoYXIqIGRlc2NyaXB0aW9uKTsKCQkJCQkJCX5SZW5kZXJQZXJmb3JtYW5jZVRlc3RCYXNlCSh2b2lkKTsKCnByb3RlY3RlZDoKCXZvaWQJCQkJCWluaXQJCQkJCQkodm9pZCk7Cgl2b2lkCQkJCQlkZWluaXQJCQkJCQkodm9pZCk7CgoJdm9pZAkJCQkJd2FpdEdMUmVzdWx0cwkJCQkodm9pZCkgY29uc3Q7Cgl2b2lkCQkJCQlzZXR1cFZlcnRleEF0dHJpYnMJCQkodm9pZCkgY29uc3Q7CgoJZW51bQoJewoJCVJFTkRFUl9BUkVBX1NJWkUgPSAxMjgKCX07Cgpwcml2YXRlOgoJZ2x1OjpTaGFkZXJQcm9ncmFtKgkJbV9yZW5kZXJQcm9ncmFtOwoJaW50CQkJCQkJbV9jb2xvckxvYzsKCWludAkJCQkJCW1fcG9zaXRpb25Mb2M7Cn07CgpSZW5kZXJQZXJmb3JtYW5jZVRlc3RCYXNlOjpSZW5kZXJQZXJmb3JtYW5jZVRlc3RCYXNlIChDb250ZXh0JiBjb250ZXh0LCBjb25zdCBjaGFyKiBuYW1lLCBjb25zdCBjaGFyKiBkZXNjcmlwdGlvbikKCTogVGVzdENhc2UJCQkoY29udGV4dCwgdGN1OjpOT0RFVFlQRV9QRVJGT1JNQU5DRSwgbmFtZSwgZGVzY3JpcHRpb24pCgksIG1fcmVuZGVyUHJvZ3JhbQkoREVfTlVMTCkKCSwgbV9jb2xvckxvYwkJKDApCgksIG1fcG9zaXRpb25Mb2MJCSgwKQp7Cn0KClJlbmRlclBlcmZvcm1hbmNlVGVzdEJhc2U6On5SZW5kZXJQZXJmb3JtYW5jZVRlc3RCYXNlICh2b2lkKQp7CglkZWluaXQoKTsKfQoKdm9pZCBSZW5kZXJQZXJmb3JtYW5jZVRlc3RCYXNlOjppbml0ICh2b2lkKQp7Cgljb25zdCBnbHc6OkZ1bmN0aW9ucyYgZ2wgPSBtX2NvbnRleHQuZ2V0UmVuZGVyQ29udGV4dCgpLmdldEZ1bmN0aW9ucygpOwoKCW1fcmVuZGVyUHJvZ3JhbSA9IG5ldyBnbHU6OlNoYWRlclByb2dyYW0obV9jb250ZXh0LmdldFJlbmRlckNvbnRleHQoKSwgZ2x1OjpQcm9ncmFtU291cmNlcygpIDw8IGdsdTo6VmVydGV4U291cmNlKHNfY29sb3JWZXJ0ZXhTaGFkZXIpIDw8IGdsdTo6RnJhZ21lbnRTb3VyY2Uoc19jb2xvckZyYWdtZW50U2hhZGVyKSk7CglpZiAoIW1fcmVuZGVyUHJvZ3JhbS0+aXNPaygpKQoJewoJCW1fdGVzdEN0eC5nZXRMb2coKSA8PCAqbV9yZW5kZXJQcm9ncmFtOwoJCXRocm93IHRjdTo6VGVzdEVycm9yKCJjb3VsZCBub3QgYnVpbGQgcHJvZ3JhbSIpOwoJfQoKCW1fY29sb3JMb2MgPSBnbC5nZXRBdHRyaWJMb2NhdGlvbihtX3JlbmRlclByb2dyYW0tPmdldFByb2dyYW0oKSwgImFfY29sb3IiKTsKCW1fcG9zaXRpb25Mb2MgPSBnbC5nZXRBdHRyaWJMb2NhdGlvbihtX3JlbmRlclByb2dyYW0tPmdldFByb2dyYW0oKSwgImFfcG9zaXRpb24iKTsKCglpZiAobV9jb2xvckxvYyA9PSAtMSkKCQl0aHJvdyB0Y3U6OlRlc3RFcnJvcigiTG9jYXRpb24gb2YgYXR0cmlidXRlIGFfY29sb3Igd2FzIC0xIik7CglpZiAobV9wb3NpdGlvbkxvYyA9PSAtMSkKCQl0aHJvdyB0Y3U6OlRlc3RFcnJvcigiTG9jYXRpb24gb2YgYXR0cmlidXRlIGFfcG9zaXRpb24gd2FzIC0xIik7Cn0KCnZvaWQgUmVuZGVyUGVyZm9ybWFuY2VUZXN0QmFzZTo6ZGVpbml0ICh2b2lkKQp7CglkZWxldGUgbV9yZW5kZXJQcm9ncmFtOwoJbV9yZW5kZXJQcm9ncmFtID0gREVfTlVMTDsKfQoKdm9pZCBSZW5kZXJQZXJmb3JtYW5jZVRlc3RCYXNlOjpzZXR1cFZlcnRleEF0dHJpYnMgKHZvaWQpIGNvbnN0CnsKCWNvbnN0IGdsdzo6RnVuY3Rpb25zJiBnbCA9IG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCkuZ2V0RnVuY3Rpb25zKCk7CgoJLy8gYnVmZmVycyBhcmUgYm91bmQKCglnbC5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheShtX2NvbG9yTG9jKTsKCWdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KG1fcG9zaXRpb25Mb2MpOwoKCWdsLnZlcnRleEF0dHJpYlBvaW50ZXIobV9jb2xvckxvYywgICAgNCwgR0xfRkxPQVQsIEdMX0ZBTFNFLCAoZ2x3OjpHTHNpemVpKSg4ICogc2l6ZW9mKGZsb2F0KSksIChjb25zdCB0Y3U6OlZlYzQqKURFX05VTEwgKyAwKTsKCWdsLnZlcnRleEF0dHJpYlBvaW50ZXIobV9wb3NpdGlvbkxvYywgNCwgR0xfRkxPQVQsIEdMX0ZBTFNFLCAoZ2x3OjpHTHNpemVpKSg4ICogc2l6ZW9mKGZsb2F0KSksIChjb25zdCB0Y3U6OlZlYzQqKURFX05VTEwgKyAxKTsKCglnbC51c2VQcm9ncmFtKG1fcmVuZGVyUHJvZ3JhbS0+Z2V0UHJvZ3JhbSgpKTsKCglHTFVfRVhQRUNUX05PX0VSUk9SKGdsLmdldEVycm9yKCksICJzZXQgdXAgcmVuZGVyaW5nIik7Cn0KCnZvaWQgUmVuZGVyUGVyZm9ybWFuY2VUZXN0QmFzZTo6d2FpdEdMUmVzdWx0cyAodm9pZCkgY29uc3QKewoJdGN1OjpTdXJmYWNlIGR1bW15U3VyZmFjZShSRU5ERVJfQVJFQV9TSVpFLCBSRU5ERVJfQVJFQV9TSVpFKTsKCWdsdTo6cmVhZFBpeGVscyhtX2NvbnRleHQuZ2V0UmVuZGVyQ29udGV4dCgpLCAwLCAwLCBkdW1teVN1cmZhY2UuZ2V0QWNjZXNzKCkpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4KY2xhc3MgUmVuZGVyQ2FzZSA6IHB1YmxpYyBSZW5kZXJQZXJmb3JtYW5jZVRlc3RCYXNlCnsKcHVibGljOgoJCQkJCQkJCQlSZW5kZXJDYXNlCQkJCQkJKENvbnRleHQmIGNvbnRleHQsIGNvbnN0IGNoYXIqIG5hbWUsIGNvbnN0IGNoYXIqIGRlc2NyaXB0aW9uLCBEcmF3TWV0aG9kIGRyYXdNZXRob2QpOwoJCQkJCQkJCQl+UmVuZGVyQ2FzZQkJCQkJCSh2b2lkKTsKCnByb3RlY3RlZDoKCXZvaWQJCQkJCQkJaW5pdAkJCQkJCQkodm9pZCk7Cgl2b2lkCQkJCQkJCWRlaW5pdAkJCQkJCQkodm9pZCk7Cgpwcml2YXRlOgoJSXRlcmF0ZVJlc3VsdAkJCQkJaXRlcmF0ZQkJCQkJCQkodm9pZCk7Cgpwcm90ZWN0ZWQ6CglzdHJ1Y3QgU2FtcGxlUmVzdWx0Cgl7CgkJTGF5ZXJlZEdyaWRTcGVjCQkJCQlzY2VuZTsKCQlSZW5kZXJTYW1wbGVSZXN1bHQ8U2FtcGxlVHlwZT4JcmVzdWx0OwoJfTsKCglpbnQJCQkJCQkJCWdldE1pbldvcmtsb2FkU2l6ZQkJCQkodm9pZCkgY29uc3Q7CglpbnQJCQkJCQkJCWdldE1heFdvcmtsb2FkU2l6ZQkJCQkodm9pZCkgY29uc3Q7CglpbnQJCQkJCQkJCWdldE1pbldvcmtsb2FkRGF0YVNpemUJCQkodm9pZCkgY29uc3Q7CglpbnQJCQkJCQkJCWdldE1heFdvcmtsb2FkRGF0YVNpemUJCQkodm9pZCkgY29uc3Q7CglpbnQJCQkJCQkJCWdldFZlcnRleERhdGFTaXplCQkJCSh2b2lkKSBjb25zdDsKCWludAkJCQkJCQkJZ2V0TnVtU2FtcGxlcwkJCQkJKHZvaWQpIGNvbnN0OwoJdm9pZAkJCQkJCQl1cGxvYWRTY2VuZQkJCQkJCShjb25zdCBMYXllcmVkR3JpZFNwZWMmIHNjZW5lKTsKCgl2aXJ0dWFsIHZvaWQJCQkJCXJ1blNhbXBsZQkJCQkJCShTYW1wbGVSZXN1bHQmIHNhbXBsZSkgPSAwOwoJdmlydHVhbCB2b2lkCQkJCQlsb2dBbmRTZXRUZXN0UmVzdWx0CQkJCShjb25zdCBzdGQ6OnZlY3RvcjxTYW1wbGVSZXN1bHQ+JiByZXN1bHRzKTsKCgl2b2lkCQkJCQkJCW1hcFJlc3VsdHNUb1JlbmRlclJhdGVGb3JtYXQJKHN0ZDo6dmVjdG9yPFJlbmRlclNhbXBsZVJlc3VsdDxTYW1wbGVUeXBlPiA+JiBkc3QsIGNvbnN0IHN0ZDo6dmVjdG9yPFNhbXBsZVJlc3VsdD4mIHNyYykgY29uc3Q7CgoJY29uc3QgRHJhd01ldGhvZAkJCQltX2RyYXdNZXRob2Q7Cgpwcml2YXRlOgoJZ2x3OjpHTHVpbnQJCQkJCQltX2F0dHJpYnV0ZUJ1ZmZlcklEOwoJZ2x3OjpHTHVpbnQJCQkJCQltX2luZGV4QnVmZmVySUQ7CglpbnQJCQkJCQkJCW1faXRlcmF0aW9uTmR4OwoJc3RkOjp2ZWN0b3I8aW50PgkJCQltX2l0ZXJhdGlvbk9yZGVyOwoJc3RkOjp2ZWN0b3I8U2FtcGxlUmVzdWx0PgkJbV9yZXN1bHRzOwoJaW50CQkJCQkJCQltX251bVVubWFwRmFpbHVyZXM7Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4KUmVuZGVyQ2FzZTxTYW1wbGVUeXBlPjo6UmVuZGVyQ2FzZSAoQ29udGV4dCYgY29udGV4dCwgY29uc3QgY2hhciogbmFtZSwgY29uc3QgY2hhciogZGVzY3JpcHRpb24sIERyYXdNZXRob2QgZHJhd01ldGhvZCkKCTogUmVuZGVyUGVyZm9ybWFuY2VUZXN0QmFzZQkoY29udGV4dCwgbmFtZSwgZGVzY3JpcHRpb24pCgksIG1fZHJhd01ldGhvZAkJCQkoZHJhd01ldGhvZCkKCSwgbV9hdHRyaWJ1dGVCdWZmZXJJRAkJKDApCgksIG1faW5kZXhCdWZmZXJJRAkJCSgwKQoJLCBtX2l0ZXJhdGlvbk5keAkJCSgwKQoJLCBtX251bVVubWFwRmFpbHVyZXMJCSgwKQp7CglERV9BU1NFUlQoZHJhd01ldGhvZCA8IERSQVdNRVRIT0RfTEFTVCk7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgpSZW5kZXJDYXNlPFNhbXBsZVR5cGU+Ojp+UmVuZGVyQ2FzZSAodm9pZCkKewoJZGVpbml0KCk7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgp2b2lkIFJlbmRlckNhc2U8U2FtcGxlVHlwZT46OmluaXQgKHZvaWQpCnsKCWNvbnN0IGdsdzo6RnVuY3Rpb25zJiBnbCA9IG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCkuZ2V0RnVuY3Rpb25zKCk7CgoJUmVuZGVyUGVyZm9ybWFuY2VUZXN0QmFzZTo6aW5pdCgpOwoKCS8vIHJlcXVpcmVtZW50cwoKCWlmIChtX2NvbnRleHQuZ2V0UmVuZGVyVGFyZ2V0KCkuZ2V0V2lkdGgoKSA8IFJFTkRFUl9BUkVBX1NJWkUgfHwKCQltX2NvbnRleHQuZ2V0UmVuZGVyVGFyZ2V0KCkuZ2V0SGVpZ2h0KCkgPCBSRU5ERVJfQVJFQV9TSVpFKQoJCXRocm93IHRjdTo6Tm90U3VwcG9ydGVkRXJyb3IoIlRlc3QgY2FzZSByZXF1aXJlcyAiICsgZGU6OnRvU3RyaW5nPGludD4oUkVOREVSX0FSRUFfU0laRSkgKyAieCIgKyBkZTo6dG9TdHJpbmc8aW50PihSRU5ERVJfQVJFQV9TSVpFKSArICIgcmVuZGVyIHRhcmdldCIpOwoKCS8vIGdsIHN0YXRlCgoJZ2wudmlld3BvcnQoMCwgMCwgUkVOREVSX0FSRUFfU0laRSwgUkVOREVSX0FSRUFfU0laRSk7CgoJLy8gZW5hYmxlIGJsZWRpbmcgdG8gcHJldmVudCBncmlkIGxheWVycyBmcm9tIGJlaW5nIGRpc2NhcmRlZAoJZ2wuYmxlbmRGdW5jKEdMX1NSQ19BTFBIQSwgR0xfT05FX01JTlVTX1NSQ19BTFBIQSk7CglnbC5ibGVuZEVxdWF0aW9uKEdMX0ZVTkNfQUREKTsKCWdsLmVuYWJsZShHTF9CTEVORCk7CgoJLy8gZ2VuZXJhdGUgaXRlcmF0aW9ucwoKCXsKCQljb25zdCBpbnQgZ3JpZFNpemVzW10gPSB7IDIwLCAyNiwgMzIsIDM4LCA0NCwgNTAsIDU2LCA2MiwgNjgsIDc0LCA4MCwgIDg2LCAgOTIsICA5OCwgIDEwNCwgMTEwLCAxMTYsIDEyMiwgMTI4IH07CgoJCWZvciAoaW50IGdyaWROZHggPSAwOyBncmlkTmR4IDwgREVfTEVOR1RIX09GX0FSUkFZKGdyaWRTaXplcyk7ICsrZ3JpZE5keCkKCQl7CgkJCW1fcmVzdWx0cy5wdXNoX2JhY2soU2FtcGxlUmVzdWx0KCkpOwoKCQkJbV9yZXN1bHRzLmJhY2soKS5zY2VuZS5ncmlkSGVpZ2h0ID0gZ3JpZFNpemVzW2dyaWROZHhdOwoJCQltX3Jlc3VsdHMuYmFjaygpLnNjZW5lLmdyaWRXaWR0aCA9IGdyaWRTaXplc1tncmlkTmR4XTsKCQkJbV9yZXN1bHRzLmJhY2soKS5zY2VuZS5ncmlkTGF5ZXJzID0gNTsKCgkJCW1fcmVzdWx0cy5iYWNrKCkucmVzdWx0Lm51bVZlcnRpY2VzID0gZ2V0TGF5ZXJlZEdyaWROdW1WZXJ0aWNlcyhtX3Jlc3VsdHMuYmFjaygpLnNjZW5lKTsKCgkJCS8vIHRlc3QgY2FzZXMgc2V0IHRoZXNlLCBpbml0aWFsaXplIHRvIGR1bW15IHZhbHVlcwoJCQltX3Jlc3VsdHMuYmFjaygpLnJlc3VsdC5yZW5kZXJEYXRhU2l6ZSA9IC0xOwoJCQltX3Jlc3VsdHMuYmFjaygpLnJlc3VsdC51cGxvYWRlZERhdGFTaXplID0gLTE7CgkJCW1fcmVzdWx0cy5iYWNrKCkucmVzdWx0LnVucmVsYXRlZERhdGFTaXplID0gLTE7CgkJfQoJfQoKCS8vIHJhbmRvbWl6ZSBpdGVyYXRpb24gb3JkZXIKCXsKCQltX2l0ZXJhdGlvbk9yZGVyLnJlc2l6ZShtX3Jlc3VsdHMuc2l6ZSgpKTsKCQlnZW5lcmF0ZVR3b1Bhc3NSYW5kb21JdGVyYXRpb25PcmRlcihtX2l0ZXJhdGlvbk9yZGVyLCAoaW50KW1faXRlcmF0aW9uT3JkZXIuc2l6ZSgpKTsKCX0KfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFNhbXBsZVR5cGU+CnZvaWQgUmVuZGVyQ2FzZTxTYW1wbGVUeXBlPjo6ZGVpbml0ICh2b2lkKQp7CglSZW5kZXJQZXJmb3JtYW5jZVRlc3RCYXNlOjpkZWluaXQoKTsKCglpZiAobV9hdHRyaWJ1dGVCdWZmZXJJRCkKCXsKCQltX2NvbnRleHQuZ2V0UmVuZGVyQ29udGV4dCgpLmdldEZ1bmN0aW9ucygpLmRlbGV0ZUJ1ZmZlcnMoMSwgJm1fYXR0cmlidXRlQnVmZmVySUQpOwoJCW1fYXR0cmlidXRlQnVmZmVySUQgPSAwOwoJfQoKCWlmIChtX2luZGV4QnVmZmVySUQpCgl7CgkJbV9jb250ZXh0LmdldFJlbmRlckNvbnRleHQoKS5nZXRGdW5jdGlvbnMoKS5kZWxldGVCdWZmZXJzKDEsICZtX2luZGV4QnVmZmVySUQpOwoJCW1faW5kZXhCdWZmZXJJRCA9IDA7Cgl9Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgp0eXBlbmFtZSBSZW5kZXJDYXNlPFNhbXBsZVR5cGU+OjpJdGVyYXRlUmVzdWx0IFJlbmRlckNhc2U8U2FtcGxlVHlwZT46Oml0ZXJhdGUgKHZvaWQpCnsKCWNvbnN0IGludAkJdW5tYXBGYWlsdXJlVGhyZXNob2xkCT0gMzsKCWNvbnN0IGludAkJY3VycmVudEl0ZXJhdGlvbgkJPSBtX2l0ZXJhdGlvbk5keDsKCWNvbnN0IGludAkJY3VycmVudENvbmZpZ05keAkJPSBtX2l0ZXJhdGlvbk9yZGVyW2N1cnJlbnRJdGVyYXRpb25dOwoJU2FtcGxlUmVzdWx0JgljdXJyZW50U2FtcGxlCQkJPSBtX3Jlc3VsdHNbY3VycmVudENvbmZpZ05keF07CgoJdHJ5Cgl7CgkJcnVuU2FtcGxlKGN1cnJlbnRTYW1wbGUpOwoJCSsrbV9pdGVyYXRpb25OZHg7Cgl9CgljYXRjaCAoY29uc3QgVW5tYXBGYWlsdXJlRXJyb3ImIGV4KQoJewoJCURFX1VOUkVGKGV4KTsKCQkrK21fbnVtVW5tYXBGYWlsdXJlczsKCX0KCglpZiAobV9udW1Vbm1hcEZhaWx1cmVzID4gdW5tYXBGYWlsdXJlVGhyZXNob2xkKQoJCXRocm93IHRjdTo6VGVzdEVycm9yKCJHb3QgdG9vIG1hbnkgdW5tYXAgZXJyb3JzIik7CgoJaWYgKG1faXRlcmF0aW9uTmR4IDwgKGludCltX2l0ZXJhdGlvbk9yZGVyLnNpemUoKSkKCQlyZXR1cm4gQ09OVElOVUU7CgoJbG9nQW5kU2V0VGVzdFJlc3VsdChtX3Jlc3VsdHMpOwoJcmV0dXJuIFNUT1A7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgppbnQgUmVuZGVyQ2FzZTxTYW1wbGVUeXBlPjo6Z2V0TWluV29ya2xvYWRTaXplICh2b2lkKSBjb25zdAp7CglpbnQgcmVzdWx0ID0gZ2V0TGF5ZXJlZEdyaWROdW1WZXJ0aWNlcyhtX3Jlc3VsdHNbMF0uc2NlbmUpOwoKCWZvciAoaW50IG5keCA9IDE7IG5keCA8IChpbnQpbV9yZXN1bHRzLnNpemUoKTsgKytuZHgpCgl7CgkJY29uc3QgaW50IHdvcmtsb2FkU2l6ZSA9IGdldExheWVyZWRHcmlkTnVtVmVydGljZXMobV9yZXN1bHRzW25keF0uc2NlbmUpOwoJCXJlc3VsdCA9IGRlOjptaW4ocmVzdWx0LCB3b3JrbG9hZFNpemUpOwoJfQoKCXJldHVybiByZXN1bHQ7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgppbnQgUmVuZGVyQ2FzZTxTYW1wbGVUeXBlPjo6Z2V0TWF4V29ya2xvYWRTaXplICh2b2lkKSBjb25zdAp7CglpbnQgcmVzdWx0ID0gZ2V0TGF5ZXJlZEdyaWROdW1WZXJ0aWNlcyhtX3Jlc3VsdHNbMF0uc2NlbmUpOwoKCWZvciAoaW50IG5keCA9IDE7IG5keCA8IChpbnQpbV9yZXN1bHRzLnNpemUoKTsgKytuZHgpCgl7CgkJY29uc3QgaW50IHdvcmtsb2FkU2l6ZSA9IGdldExheWVyZWRHcmlkTnVtVmVydGljZXMobV9yZXN1bHRzW25keF0uc2NlbmUpOwoJCXJlc3VsdCA9IGRlOjptYXgocmVzdWx0LCB3b3JrbG9hZFNpemUpOwoJfQoKCXJldHVybiByZXN1bHQ7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgppbnQgUmVuZGVyQ2FzZTxTYW1wbGVUeXBlPjo6Z2V0TWluV29ya2xvYWREYXRhU2l6ZSAodm9pZCkgY29uc3QKewoJcmV0dXJuIGdldE1pbldvcmtsb2FkU2l6ZSgpICogZ2V0VmVydGV4RGF0YVNpemUoKTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFNhbXBsZVR5cGU+CmludCBSZW5kZXJDYXNlPFNhbXBsZVR5cGU+OjpnZXRNYXhXb3JrbG9hZERhdGFTaXplICh2b2lkKSBjb25zdAp7CglyZXR1cm4gZ2V0TWF4V29ya2xvYWRTaXplKCkgKiBnZXRWZXJ0ZXhEYXRhU2l6ZSgpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4KaW50IFJlbmRlckNhc2U8U2FtcGxlVHlwZT46OmdldFZlcnRleERhdGFTaXplICh2b2lkKSBjb25zdAp7Cgljb25zdCBpbnQgbnVtVmVjdG9ycwk9IDI7Cgljb25zdCBpbnQgdmVjNFNpemUJCT0gNCAqIHNpemVvZihmbG9hdCk7CgoJcmV0dXJuIG51bVZlY3RvcnMgKiB2ZWM0U2l6ZTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFNhbXBsZVR5cGU+CmludCBSZW5kZXJDYXNlPFNhbXBsZVR5cGU+OjpnZXROdW1TYW1wbGVzICh2b2lkKSBjb25zdAp7CglyZXR1cm4gKGludCltX3Jlc3VsdHMuc2l6ZSgpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4Kdm9pZCBSZW5kZXJDYXNlPFNhbXBsZVR5cGU+Ojp1cGxvYWRTY2VuZSAoY29uc3QgTGF5ZXJlZEdyaWRTcGVjJiBzY2VuZSkKewoJY29uc3QgZ2x3OjpGdW5jdGlvbnMmIGdsID0gbV9jb250ZXh0LmdldFJlbmRlckNvbnRleHQoKS5nZXRGdW5jdGlvbnMoKTsKCgkvLyB2ZXJ0ZXggYnVmZmVyCgl7CgkJc3RkOjp2ZWN0b3I8dGN1OjpWZWM0PiB2ZXJ0ZXhEYXRhOwoKCQlnZW5lcmF0ZUxheWVyZWRHcmlkVmVydGV4QXR0cmliRGF0YTRDNFYodmVydGV4RGF0YSwgc2NlbmUpOwoKCQlpZiAobV9hdHRyaWJ1dGVCdWZmZXJJRCA9PSAwKQoJCQlnbC5nZW5CdWZmZXJzKDEsICZtX2F0dHJpYnV0ZUJ1ZmZlcklEKTsKCQlnbC5iaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgbV9hdHRyaWJ1dGVCdWZmZXJJRCk7CgkJZ2wuYnVmZmVyRGF0YShHTF9BUlJBWV9CVUZGRVIsIChpbnQpKHZlcnRleERhdGEuc2l6ZSgpICogc2l6ZW9mKHRjdTo6VmVjNCkpLCAmdmVydGV4RGF0YVswXSwgR0xfU1RBVElDX0RSQVcpOwoJfQoKCS8vIGluZGV4IGJ1ZmZlcgoJaWYgKG1fZHJhd01ldGhvZCA9PSBEUkFXTUVUSE9EX0RSQVdfRUxFTUVOVFMpCgl7CgkJc3RkOjp2ZWN0b3I8ZGVVaW50MzI+IGluZGV4RGF0YTsKCgkJZ2VuZXJhdGVMYXllcmVkR3JpZEluZGV4RGF0YShpbmRleERhdGEsIHNjZW5lKTsKCgkJaWYgKG1faW5kZXhCdWZmZXJJRCA9PSAwKQoJCQlnbC5nZW5CdWZmZXJzKDEsICZtX2luZGV4QnVmZmVySUQpOwoJCWdsLmJpbmRCdWZmZXIoR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVIsIG1faW5kZXhCdWZmZXJJRCk7CgkJZ2wuYnVmZmVyRGF0YShHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUiwgKGludCkoaW5kZXhEYXRhLnNpemUoKSAqIHNpemVvZihkZVVpbnQzMikpLCAmaW5kZXhEYXRhWzBdLCBHTF9TVEFUSUNfRFJBVyk7Cgl9CgoJR0xVX0VYUEVDVF9OT19FUlJPUihnbC5nZXRFcnJvcigpLCAiY3JlYXRlIGJ1ZmZlcnMiKTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFNhbXBsZVR5cGU+CnZvaWQgUmVuZGVyQ2FzZTxTYW1wbGVUeXBlPjo6bG9nQW5kU2V0VGVzdFJlc3VsdCAoY29uc3Qgc3RkOjp2ZWN0b3I8U2FtcGxlUmVzdWx0PiYgcmVzdWx0cykKewoJc3RkOjp2ZWN0b3I8UmVuZGVyU2FtcGxlUmVzdWx0PFNhbXBsZVR5cGU+ID4gbWFwcGVkUmVzdWx0czsKCgltYXBSZXN1bHRzVG9SZW5kZXJSYXRlRm9ybWF0KG1hcHBlZFJlc3VsdHMsIHJlc3VsdHMpOwoKCXsKCQljb25zdCBSZW5kZXJTYW1wbGVBbmFseXplUmVzdWx0CWFuYWx5c2lzCT0gYW5hbHl6ZVNhbXBsZVJlc3VsdHMobV90ZXN0Q3R4LmdldExvZygpLCBtYXBwZWRSZXN1bHRzKTsKCQljb25zdCBmbG9hdAkJCQkJCXJhdGUJCT0gYW5hbHlzaXMucmVuZGVyUmF0ZUF0UmFuZ2U7CgoJCWlmIChyYXRlID09IHN0ZDo6bnVtZXJpY19saW1pdHM8ZmxvYXQ+OjppbmZpbml0eSgpKQoJCXsKCQkJLy8gc2FtcGxlIHRpbWVzIGFyZSAxKSBpbnZhbGlkIG9yIDIpIHRpbWVyIHJlc29sdXRpb24gdG9vIGxvdwoJCQltX3Rlc3RDdHguc2V0VGVzdFJlc3VsdChRUF9URVNUX1JFU1VMVF9QQVNTLCBkZTo6ZmxvYXRUb1N0cmluZygwLjBmLCAyKS5jX3N0cigpKTsKCQl9CgkJZWxzZQoJCXsKCQkJLy8gcmVwb3J0IHRyYW5zZmVyIHJhdGUgaW4gbWlsbGlvbnMgb2YgTWlCL3MKCQkJbV90ZXN0Q3R4LnNldFRlc3RSZXN1bHQoUVBfVEVTVF9SRVNVTFRfUEFTUywgZGU6OmZsb2F0VG9TdHJpbmcocmF0ZSAvIDEwMjQuMGYgLyAxMDI0LjBmLCAyKS5jX3N0cigpKTsKCQl9Cgl9Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgp2b2lkIFJlbmRlckNhc2U8U2FtcGxlVHlwZT46Om1hcFJlc3VsdHNUb1JlbmRlclJhdGVGb3JtYXQgKHN0ZDo6dmVjdG9yPFJlbmRlclNhbXBsZVJlc3VsdDxTYW1wbGVUeXBlPiA+JiBkc3QsIGNvbnN0IHN0ZDo6dmVjdG9yPFNhbXBsZVJlc3VsdD4mIHNyYykgY29uc3QKewoJZHN0LnJlc2l6ZShzcmMuc2l6ZSgpKTsKCglmb3IgKGludCBuZHggPSAwOyBuZHggPCAoaW50KXNyYy5zaXplKCk7ICsrbmR4KQoJCWRzdFtuZHhdID0gc3JjW25keF0ucmVzdWx0Owp9CgpjbGFzcyBSZWZlcmVuY2VSZW5kZXJUaW1lQ2FzZSA6IHB1YmxpYyBSZW5kZXJDYXNlPFJlbmRlclJlYWREdXJhdGlvbj4KewpwdWJsaWM6CgkJCVJlZmVyZW5jZVJlbmRlclRpbWVDYXNlCQkoQ29udGV4dCYgY29udGV4dCwgY29uc3QgY2hhciogbmFtZSwgY29uc3QgY2hhciogZGVzY3JpcHRpb24sIERyYXdNZXRob2QgZHJhd01ldGhvZCk7Cgpwcml2YXRlOgoJdm9pZAlpbml0CQkJCQkJKHZvaWQpOwoJdm9pZAlydW5TYW1wbGUJCQkJCShTYW1wbGVSZXN1bHQmIHNhbXBsZSk7Cn07CgpSZWZlcmVuY2VSZW5kZXJUaW1lQ2FzZTo6UmVmZXJlbmNlUmVuZGVyVGltZUNhc2UgKENvbnRleHQmIGNvbnRleHQsIGNvbnN0IGNoYXIqIG5hbWUsIGNvbnN0IGNoYXIqIGRlc2NyaXB0aW9uLCBEcmF3TWV0aG9kIGRyYXdNZXRob2QpCgk6IFJlbmRlckNhc2U8UmVuZGVyUmVhZER1cmF0aW9uPgkoY29udGV4dCwgbmFtZSwgZGVzY3JpcHRpb24sIGRyYXdNZXRob2QpCnsKfQoKdm9pZCBSZWZlcmVuY2VSZW5kZXJUaW1lQ2FzZTo6aW5pdCAodm9pZCkKewoJY29uc3QgY2hhciogY29uc3QgdGFyZ2V0RnVuY3Rpb25OYW1lID0gKG1fZHJhd01ldGhvZCA9PSBEUkFXTUVUSE9EX0RSQVdfQVJSQVlTKSA/ICgiZHJhd0FycmF5cyIpIDogKCJkcmF3RWxlbWVudHMiKTsKCgkvLyBpbml0IHBhcmVudAoJUmVuZGVyQ2FzZTxSZW5kZXJSZWFkRHVyYXRpb24+Ojppbml0KCk7CgoJLy8gbG9nCgltX3Rlc3RDdHguZ2V0TG9nKCkKCQk8PCB0Y3U6OlRlc3RMb2c6Ok1lc3NhZ2UKCQk8PCAiTWVhc3VyaW5nIHRoZSB0aW1lIHVzZWQgaW4gIiA8PCB0YXJnZXRGdW5jdGlvbk5hbWUgPDwgIiBhbmQgcmVhZFBpeGVscyBjYWxsIHdpdGggZGlmZmVyZW50IHJlbmRlcmluZyB3b3JrbG9hZHMuXG4iCgkJPDwgZ2V0TnVtU2FtcGxlcygpIDw8ICIgdGVzdCBzYW1wbGVzLiBTYW1wbGUgb3JkZXIgaXMgcmFuZG9taXplZC5cbiIKCQk8PCAiQWxsIHNhbXBsZXMgYXQgZXZlbiBwb3NpdGlvbnMgKGZpcnN0ID0gMCkgYXJlIHRlc3RlZCBiZWZvcmUgc2FtcGxlcyBhdCBvZGQgcG9zaXRpb25zLlxuIgoJCTw8ICJHZW5lcmF0ZWQgd29ya2xvYWQgaXMgbXVsdGlwbGUgdmlld3BvcnQtY292ZXJpbmcgZ3JpZHMgd2l0aCB2YXJ5aW5nIG51bWJlciBvZiBjZWxscywgZWFjaCBjZWxsIGlzIHR3byBzZXBhcmF0ZSB0cmlhbmdsZXMuXG4iCgkJPDwgIldvcmtsb2FkIHNpemVzIGFyZSBpbiB0aGUgcmFuZ2UgWyIKCQkJPDwgZ2V0TWluV29ya2xvYWRTaXplKCkgPDwgIiwgICIKCQkJPDwgZ2V0TWF4V29ya2xvYWRTaXplKCkgPDwgIl0gdmVydGljZXMgKFsiCgkJCTw8IGdldEh1bWFuUmVhZGFibGVCeXRlU2l6ZShnZXRNaW5Xb3JrbG9hZERhdGFTaXplKCkpIDw8ICIsIgoJCQk8PCBnZXRIdW1hblJlYWRhYmxlQnl0ZVNpemUoZ2V0TWF4V29ya2xvYWREYXRhU2l6ZSgpKSA8PCAiXSB0byBiZSBwcm9jZXNzZWQpLlxuIgoJCTw8ICJUZXN0IHJlc3VsdCBpcyB0aGUgYXBwcm94aW1hdGVkIHRvdGFsIHByb2Nlc3NpbmcgcmF0ZSBpbiBNaUIgLyBzLlxuIgoJCTw8ICgobV9kcmF3TWV0aG9kID09IERSQVdNRVRIT0RfRFJBV19FTEVNRU5UUykgPyAoIk5vdGUgdGhhdCBpbmRleCBhcnJheSBzaXplIGlzIG5vdCBpbmNsdWRlZCBpbiB0aGUgcHJvY2Vzc2VkIHNpemUuXG4iKSA6ICgiIikpCgkJPDwgIk5vdGUhIFRlc3QgcmVzdWx0IHNob3VsZCBvbmx5IGJlIHVzZWQgYXMgYSBiYXNlbGluZSByZWZlcmVuY2UgcmVzdWx0IGZvciBidWZmZXIuZGF0YV91cGxvYWQuKiB0ZXN0IGdyb3VwIHJlc3VsdHMuIgoJCTw8IHRjdTo6VGVzdExvZzo6RW5kTWVzc2FnZTsKfQoKdm9pZCBSZWZlcmVuY2VSZW5kZXJUaW1lQ2FzZTo6cnVuU2FtcGxlIChTYW1wbGVSZXN1bHQmIHNhbXBsZSkKewoJY29uc3QgZ2x3OjpGdW5jdGlvbnMmCWdsCQkJCT0gbV9jb250ZXh0LmdldFJlbmRlckNvbnRleHQoKS5nZXRGdW5jdGlvbnMoKTsKCXRjdTo6U3VyZmFjZQkJCXJlc3VsdFN1cmZhY2UJKFJFTkRFUl9BUkVBX1NJWkUsIFJFTkRFUl9BUkVBX1NJWkUpOwoJY29uc3QgaW50CQkJCW51bVZlcnRpY2VzCQk9IGdldExheWVyZWRHcmlkTnVtVmVydGljZXMoc2FtcGxlLnNjZW5lKTsKCWNvbnN0IGdsdTo6QnVmZmVyCQlhcnJheUJ1ZmZlcgkJKG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCkpOwoJY29uc3QgZ2x1OjpCdWZmZXIJCWluZGV4QnVmZmVyCQkobV9jb250ZXh0LmdldFJlbmRlckNvbnRleHQoKSk7CglzdGQ6OnZlY3Rvcjx0Y3U6OlZlYzQ+CXZlcnRleERhdGE7CglzdGQ6OnZlY3RvcjxkZVVpbnQzMj4JaW5kZXhEYXRhOwoJZGVVaW50NjQJCQkJc3RhcnRUaW1lOwoJZGVVaW50NjQJCQkJZW5kVGltZTsKCgkvLyBnZW5lcmF0ZSBhbmQgdXBsb2FkIGJ1ZmZlcnMKCglnZW5lcmF0ZUxheWVyZWRHcmlkVmVydGV4QXR0cmliRGF0YTRDNFYodmVydGV4RGF0YSwgc2FtcGxlLnNjZW5lKTsKCWdsLmJpbmRCdWZmZXIoR0xfQVJSQVlfQlVGRkVSLCAqYXJyYXlCdWZmZXIpOwoJZ2wuYnVmZmVyRGF0YShHTF9BUlJBWV9CVUZGRVIsIChpbnQpKHZlcnRleERhdGEuc2l6ZSgpICogc2l6ZW9mKHRjdTo6VmVjNCkpLCAmdmVydGV4RGF0YVswXSwgR0xfU1RBVElDX0RSQVcpOwoKCWlmIChtX2RyYXdNZXRob2QgPT0gRFJBV01FVEhPRF9EUkFXX0VMRU1FTlRTKQoJewoJCWdlbmVyYXRlTGF5ZXJlZEdyaWRJbmRleERhdGEoaW5kZXhEYXRhLCBzYW1wbGUuc2NlbmUpOwoJCWdsLmJpbmRCdWZmZXIoR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVIsICppbmRleEJ1ZmZlcik7CgkJZ2wuYnVmZmVyRGF0YShHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUiwgKGludCkoaW5kZXhEYXRhLnNpemUoKSAqIHNpemVvZihkZVVpbnQzMikpLCAmaW5kZXhEYXRhWzBdLCBHTF9TVEFUSUNfRFJBVyk7Cgl9CgoJc2V0dXBWZXJ0ZXhBdHRyaWJzKCk7CgoJLy8gbWFrZSBzdXJlIGRhdGEgaXMgdXBsb2FkZWQKCglpZiAobV9kcmF3TWV0aG9kID09IERSQVdNRVRIT0RfRFJBV19BUlJBWVMpCgkJZ2wuZHJhd0FycmF5cyhHTF9UUklBTkdMRVMsIDAsIG51bVZlcnRpY2VzKTsKCWVsc2UgaWYgKG1fZHJhd01ldGhvZCA9PSBEUkFXTUVUSE9EX0RSQVdfRUxFTUVOVFMpCgkJZ2wuZHJhd0VsZW1lbnRzKEdMX1RSSUFOR0xFUywgbnVtVmVydGljZXMsIEdMX1VOU0lHTkVEX0lOVCwgREVfTlVMTCk7CgllbHNlCgkJREVfQVNTRVJUKGZhbHNlKTsKCXdhaXRHTFJlc3VsdHMoKTsKCglnbC5jbGVhckNvbG9yKDAuMGYsIDAuMGYsIDAuMGYsIDEuMGYpOwoJZ2wuY2xlYXIoR0xfQ09MT1JfQlVGRkVSX0JJVCk7Cgl3YWl0R0xSZXN1bHRzKCk7CgoJdGN1Ojp3YXJtdXBDUFUoKTsKCgkvLyBNZWFzdXJlIGJvdGggZHJhdyBhbmQgYXNzb2NpYXRlZCByZWFkcGl4ZWxzCgl7CgkJc3RhcnRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCgkJaWYgKG1fZHJhd01ldGhvZCA9PSBEUkFXTUVUSE9EX0RSQVdfQVJSQVlTKQoJCQlnbC5kcmF3QXJyYXlzKEdMX1RSSUFOR0xFUywgMCwgbnVtVmVydGljZXMpOwoJCWVsc2UgaWYgKG1fZHJhd01ldGhvZCA9PSBEUkFXTUVUSE9EX0RSQVdfRUxFTUVOVFMpCgkJCWdsLmRyYXdFbGVtZW50cyhHTF9UUklBTkdMRVMsIG51bVZlcnRpY2VzLCBHTF9VTlNJR05FRF9JTlQsIERFX05VTEwpOwoJCWVsc2UKCQkJREVfQVNTRVJUKGZhbHNlKTsKCgkJZW5kVGltZSA9IGRlR2V0TWljcm9zZWNvbmRzKCk7CgoJCXNhbXBsZS5yZXN1bHQuZHVyYXRpb24ucmVuZGVyRHVyYXRpb24gPSBlbmRUaW1lIC0gc3RhcnRUaW1lOwoJfQoKCXsKCQlzdGFydFRpbWUgPSBkZUdldE1pY3Jvc2Vjb25kcygpOwoJCWdsdTo6cmVhZFBpeGVscyhtX2NvbnRleHQuZ2V0UmVuZGVyQ29udGV4dCgpLCAwLCAwLCByZXN1bHRTdXJmYWNlLmdldEFjY2VzcygpKTsKCQllbmRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCgkJc2FtcGxlLnJlc3VsdC5kdXJhdGlvbi5yZWFkRHVyYXRpb24gPSBlbmRUaW1lIC0gc3RhcnRUaW1lOwoJfQoKCXNhbXBsZS5yZXN1bHQucmVuZGVyRGF0YVNpemUgPSBnZXRWZXJ0ZXhEYXRhU2l6ZSgpICogc2FtcGxlLnJlc3VsdC5udW1WZXJ0aWNlczsKCXNhbXBsZS5yZXN1bHQudXBsb2FkZWREYXRhU2l6ZSA9IDA7CglzYW1wbGUucmVzdWx0LnVucmVsYXRlZERhdGFTaXplID0gMDsKCXNhbXBsZS5yZXN1bHQuZHVyYXRpb24ucmVuZGVyUmVhZER1cmF0aW9uID0gc2FtcGxlLnJlc3VsdC5kdXJhdGlvbi5yZW5kZXJEdXJhdGlvbiArIHNhbXBsZS5yZXN1bHQuZHVyYXRpb24ucmVhZER1cmF0aW9uOwoJc2FtcGxlLnJlc3VsdC5kdXJhdGlvbi50b3RhbER1cmF0aW9uID0gc2FtcGxlLnJlc3VsdC5kdXJhdGlvbi5yZW5kZXJEdXJhdGlvbiArIHNhbXBsZS5yZXN1bHQuZHVyYXRpb24ucmVhZER1cmF0aW9uOwoJc2FtcGxlLnJlc3VsdC5kdXJhdGlvbi5maXRSZXNwb25zZUR1cmF0aW9uID0gc2FtcGxlLnJlc3VsdC5kdXJhdGlvbi5yZW5kZXJSZWFkRHVyYXRpb247Cn0KCmNsYXNzIFVucmVsYXRlZFVwbG9hZFJlbmRlclRpbWVDYXNlIDogcHVibGljIFJlbmRlckNhc2U8VW5yZWxhdGVkVXBsb2FkUmVuZGVyUmVhZER1cmF0aW9uPgp7CnB1YmxpYzoKCQkJCQkJCQkJVW5yZWxhdGVkVXBsb2FkUmVuZGVyVGltZUNhc2UJKENvbnRleHQmIGNvbnRleHQsIGNvbnN0IGNoYXIqIG5hbWUsIGNvbnN0IGNoYXIqIGRlc2NyaXB0aW9uLCBEcmF3TWV0aG9kIGRyYXdNZXRob2QsIFVwbG9hZE1ldGhvZCB1bnJlbGF0ZWRVcGxvYWRNZXRob2QpOwoKcHJpdmF0ZToKCXZvaWQJCQkJCQkJaW5pdAkJCQkJCQkodm9pZCk7Cgl2b2lkCQkJCQkJCXJ1blNhbXBsZQkJCQkJCShTYW1wbGVSZXN1bHQmIHNhbXBsZSk7CgoJY29uc3QgVXBsb2FkTWV0aG9kCQkJCW1fdW5yZWxhdGVkVXBsb2FkTWV0aG9kOwp9OwoKVW5yZWxhdGVkVXBsb2FkUmVuZGVyVGltZUNhc2U6OlVucmVsYXRlZFVwbG9hZFJlbmRlclRpbWVDYXNlIChDb250ZXh0JiBjb250ZXh0LCBjb25zdCBjaGFyKiBuYW1lLCBjb25zdCBjaGFyKiBkZXNjcmlwdGlvbiwgRHJhd01ldGhvZCBkcmF3TWV0aG9kLCBVcGxvYWRNZXRob2QgdW5yZWxhdGVkVXBsb2FkTWV0aG9kKQoJOiBSZW5kZXJDYXNlPFVucmVsYXRlZFVwbG9hZFJlbmRlclJlYWREdXJhdGlvbj4JKGNvbnRleHQsIG5hbWUsIGRlc2NyaXB0aW9uLCBkcmF3TWV0aG9kKQoJLCBtX3VucmVsYXRlZFVwbG9hZE1ldGhvZAkJCQkJCSh1bnJlbGF0ZWRVcGxvYWRNZXRob2QpCnsKCURFX0FTU0VSVChtX3VucmVsYXRlZFVwbG9hZE1ldGhvZCA8IFVQTE9BRE1FVEhPRF9MQVNUKTsKfQoKdm9pZCBVbnJlbGF0ZWRVcGxvYWRSZW5kZXJUaW1lQ2FzZTo6aW5pdCAodm9pZCkKewoJY29uc3QgY2hhciogY29uc3QJdGFyZ2V0RnVuY3Rpb25OYW1lCT0gKG1fZHJhd01ldGhvZCA9PSBEUkFXTUVUSE9EX0RSQVdfQVJSQVlTKSA/ICgiZHJhd0FycmF5cyIpIDogKCJkcmF3RWxlbWVudHMiKTsKCXRjdTo6TWVzc2FnZUJ1aWxkZXIJbWVzc2FnZQkJCQkoJm1fdGVzdEN0eC5nZXRMb2coKSk7CgoJLy8gaW5pdCBwYXJlbnQKCVJlbmRlckNhc2U8VW5yZWxhdGVkVXBsb2FkUmVuZGVyUmVhZER1cmF0aW9uPjo6aW5pdCgpOwoKCS8vIGxvZwoKCW1lc3NhZ2UKCQk8PCAiTWVhc3VyaW5nIHRoZSB0aW1lIHVzZWQgaW4gIiA8PCB0YXJnZXRGdW5jdGlvbk5hbWUgPDwgIiBhbmQgcmVhZFBpeGVscyBjYWxsIHdpdGggZGlmZmVyZW50IHJlbmRlcmluZyB3b3JrbG9hZHMuXG4iCgkJPDwgIlVwbG9hZGluZyBhbiB1bnJlbGF0ZWQgYnVmZmVyIGp1c3QgYmVmb3JlIGlzc3VpbmcgdGhlIHJlbmRlcmluZyBjb21tYW5kIHdpdGggIgoJCQk8PCAoKG1fdW5yZWxhdGVkVXBsb2FkTWV0aG9kICE9IFVQTE9BRE1FVEhPRF9CVUZGRVJfREFUQSkJCT8gKCJidWZmZXJEYXRhIikJCToKCQkJCShtX3VucmVsYXRlZFVwbG9hZE1ldGhvZCAhPSBVUExPQURNRVRIT0RfQlVGRkVSX1NVQl9EQVRBKQk/ICgiYnVmZmVyU3ViRGF0YSIpCQk6CgkJCQkobV91bnJlbGF0ZWRVcGxvYWRNZXRob2QgIT0gVVBMT0FETUVUSE9EX01BUF9CVUZGRVJfUkFOR0UpCT8gKCJtYXBCdWZmZXJSYW5nZSIpCToKCQkJCSgoY29uc3QgY2hhciopREVfTlVMTCkpCgkJCTw8ICIuXG4iCgkJPDwgZ2V0TnVtU2FtcGxlcygpIDw8ICIgdGVzdCBzYW1wbGVzLiBTYW1wbGUgb3JkZXIgaXMgcmFuZG9taXplZC5cbiIKCQk8PCAiQWxsIHNhbXBsZXMgYXQgZXZlbiBwb3NpdGlvbnMgKGZpcnN0ID0gMCkgYXJlIHRlc3RlZCBiZWZvcmUgc2FtcGxlcyBhdCBvZGQgcG9zaXRpb25zLlxuIgoJCTw8ICJHZW5lcmF0ZWQgd29ya2xvYWQgaXMgbXVsdGlwbGUgdmlld3BvcnQtY292ZXJpbmcgZ3JpZHMgd2l0aCB2YXJ5aW5nIG51bWJlciBvZiBjZWxscywgZWFjaCBjZWxsIGlzIHR3byBzZXBhcmF0ZSB0cmlhbmdsZXMuXG4iCgkJPDwgIldvcmtsb2FkIHNpemVzIGFyZSBpbiB0aGUgcmFuZ2UgWyIKCQkJPDwgZ2V0TWluV29ya2xvYWRTaXplKCkgPDwgIiwgICIKCQkJPDwgZ2V0TWF4V29ya2xvYWRTaXplKCkgPDwgIl0gdmVydGljZXMgKFsiCgkJCTw8IGdldEh1bWFuUmVhZGFibGVCeXRlU2l6ZShnZXRNaW5Xb3JrbG9hZERhdGFTaXplKCkpIDw8ICIsIgoJCQk8PCBnZXRIdW1hblJlYWRhYmxlQnl0ZVNpemUoZ2V0TWF4V29ya2xvYWREYXRhU2l6ZSgpKSA8PCAiXSB0byBiZSBwcm9jZXNzZWQpLlxuIgoJCTw8ICJVbnJlbGF0ZWQgdXBsb2FkIHNpemVzIGFyZSBpbiB0aGUgcmFuZ2UgWyIKCQkJPDwgZ2V0SHVtYW5SZWFkYWJsZUJ5dGVTaXplKGdldE1pbldvcmtsb2FkRGF0YVNpemUoKSkgPDwgIiwgIgoJCQk8PCBnZXRIdW1hblJlYWRhYmxlQnl0ZVNpemUoZ2V0TWF4V29ya2xvYWREYXRhU2l6ZSgpKSA8PCAiXVxuIgoJCTw8ICJUZXN0IHJlc3VsdCBpcyB0aGUgYXBwcm94aW1hdGVkIHRvdGFsIHByb2Nlc3NpbmcgcmF0ZSBpbiBNaUIgLyBzLlxuIgoJCTw8ICgobV9kcmF3TWV0aG9kID09IERSQVdNRVRIT0RfRFJBV19FTEVNRU5UUykgPyAoIk5vdGUgdGhhdCBpbmRleCBhcnJheSBzaXplIGlzIG5vdCBpbmNsdWRlZCBpbiB0aGUgcHJvY2Vzc2VkIHNpemUuXG4iKSA6ICgiIikpCgkJPDwgIk5vdGUgdGhhdCB0aGUgZGF0YSBzaXplIGFuZCB0aGUgdGltZSB1c2VkIGluIHRoZSB1bnJlbGF0ZWQgdXBsb2FkIGlzIG5vdCBpbmNsdWRlZCBpbiB0aGUgcmVzdWx0cy5cbiIKCQk8PCAiTm90ZSEgVGVzdCByZXN1bHQgbWF5IG5vdCBiZSB1c2VmdWwgYXMgaXMgYnV0IGluc3RlYWQgc2hvdWxkIGJlIGNvbXBhcmVkIGFnYWluc3QgdGhlIHJlZmVyZW5jZS4qIGdyb3VwIGFuZCB1cGxvYWRfYW5kX2RyYXcuKl9hbmRfdW5yZWxhdGVkX3VwbG9hZCBncm91cCByZXN1bHRzLlxuIgoJCTw8IHRjdTo6VGVzdExvZzo6RW5kTWVzc2FnZTsKfQoKdm9pZCBVbnJlbGF0ZWRVcGxvYWRSZW5kZXJUaW1lQ2FzZTo6cnVuU2FtcGxlIChTYW1wbGVSZXN1bHQmIHNhbXBsZSkKewoJY29uc3QgZ2x3OjpGdW5jdGlvbnMmCWdsCQkJCQk9IG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCkuZ2V0RnVuY3Rpb25zKCk7Cgl0Y3U6OlN1cmZhY2UJCQlyZXN1bHRTdXJmYWNlCQkoUkVOREVSX0FSRUFfU0laRSwgUkVOREVSX0FSRUFfU0laRSk7Cgljb25zdCBpbnQJCQkJbnVtVmVydGljZXMJCQk9IGdldExheWVyZWRHcmlkTnVtVmVydGljZXMoc2FtcGxlLnNjZW5lKTsKCWNvbnN0IGdsdTo6QnVmZmVyCQlhcnJheUJ1ZmZlcgkJCShtX2NvbnRleHQuZ2V0UmVuZGVyQ29udGV4dCgpKTsKCWNvbnN0IGdsdTo6QnVmZmVyCQlpbmRleEJ1ZmZlcgkJCShtX2NvbnRleHQuZ2V0UmVuZGVyQ29udGV4dCgpKTsKCWNvbnN0IGdsdTo6QnVmZmVyCQl1bnJlbGF0ZWRCdWZmZXIJCShtX2NvbnRleHQuZ2V0UmVuZGVyQ29udGV4dCgpKTsKCWludAkJCQkJCXVucmVsYXRlZFVwbG9hZFNpemUJPSAtMTsKCWludAkJCQkJCXJlbmRlclVwbG9hZFNpemU7CglzdGQ6OnZlY3Rvcjx0Y3U6OlZlYzQ+CXZlcnRleERhdGE7CglzdGQ6OnZlY3RvcjxkZVVpbnQzMj4JaW5kZXhEYXRhOwoJZGVVaW50NjQJCQkJc3RhcnRUaW1lOwoJZGVVaW50NjQJCQkJZW5kVGltZTsKCgkvLyBnZW5lcmF0ZSBhbmQgdXBsb2FkIGJ1ZmZlcnMKCglnZW5lcmF0ZUxheWVyZWRHcmlkVmVydGV4QXR0cmliRGF0YTRDNFYodmVydGV4RGF0YSwgc2FtcGxlLnNjZW5lKTsKCXJlbmRlclVwbG9hZFNpemUgPSAoaW50KSh2ZXJ0ZXhEYXRhLnNpemUoKSAqIHNpemVvZih0Y3U6OlZlYzQpKTsKCglnbC5iaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgKmFycmF5QnVmZmVyKTsKCWdsLmJ1ZmZlckRhdGEoR0xfQVJSQVlfQlVGRkVSLCByZW5kZXJVcGxvYWRTaXplLCAmdmVydGV4RGF0YVswXSwgR0xfU1RBVElDX0RSQVcpOwoKCWlmIChtX2RyYXdNZXRob2QgPT0gRFJBV01FVEhPRF9EUkFXX0VMRU1FTlRTKQoJewoJCWdlbmVyYXRlTGF5ZXJlZEdyaWRJbmRleERhdGEoaW5kZXhEYXRhLCBzYW1wbGUuc2NlbmUpOwoJCWdsLmJpbmRCdWZmZXIoR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVIsICppbmRleEJ1ZmZlcik7CgkJZ2wuYnVmZmVyRGF0YShHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUiwgKGludCkoaW5kZXhEYXRhLnNpemUoKSAqIHNpemVvZihkZVVpbnQzMikpLCAmaW5kZXhEYXRhWzBdLCBHTF9TVEFUSUNfRFJBVyk7Cgl9CgoJc2V0dXBWZXJ0ZXhBdHRyaWJzKCk7CgoJLy8gbWFrZSBzdXJlIGRhdGEgaXMgdXBsb2FkZWQKCglpZiAobV9kcmF3TWV0aG9kID09IERSQVdNRVRIT0RfRFJBV19BUlJBWVMpCgkJZ2wuZHJhd0FycmF5cyhHTF9UUklBTkdMRVMsIDAsIG51bVZlcnRpY2VzKTsKCWVsc2UgaWYgKG1fZHJhd01ldGhvZCA9PSBEUkFXTUVUSE9EX0RSQVdfRUxFTUVOVFMpCgkJZ2wuZHJhd0VsZW1lbnRzKEdMX1RSSUFOR0xFUywgbnVtVmVydGljZXMsIEdMX1VOU0lHTkVEX0lOVCwgREVfTlVMTCk7CgllbHNlCgkJREVfQVNTRVJUKGZhbHNlKTsKCXdhaXRHTFJlc3VsdHMoKTsKCglnbC5jbGVhckNvbG9yKDAuMGYsIDAuMGYsIDAuMGYsIDEuMGYpOwoJZ2wuY2xlYXIoR0xfQ09MT1JfQlVGRkVSX0JJVCk7Cgl3YWl0R0xSZXN1bHRzKCk7CgoJdGN1Ojp3YXJtdXBDUFUoKTsKCgkvLyBVbnJlbGF0ZWQgdXBsb2FkCglpZiAobV91bnJlbGF0ZWRVcGxvYWRNZXRob2QgPT0gVVBMT0FETUVUSE9EX0JVRkZFUl9EQVRBKQoJewoJCXVucmVsYXRlZFVwbG9hZFNpemUgPSAoaW50KSh2ZXJ0ZXhEYXRhLnNpemUoKSAqIHNpemVvZih0Y3U6OlZlYzQpKTsKCgkJZ2wuYmluZEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIsICp1bnJlbGF0ZWRCdWZmZXIpOwoJCWdsLmJ1ZmZlckRhdGEoR0xfQVJSQVlfQlVGRkVSLCB1bnJlbGF0ZWRVcGxvYWRTaXplLCAmdmVydGV4RGF0YVswXSwgR0xfU1RBVElDX0RSQVcpOwoJfQoJZWxzZSBpZiAobV91bnJlbGF0ZWRVcGxvYWRNZXRob2QgPT0gVVBMT0FETUVUSE9EX0JVRkZFUl9TVUJfREFUQSkKCXsKCQl1bnJlbGF0ZWRVcGxvYWRTaXplID0gKGludCkodmVydGV4RGF0YS5zaXplKCkgKiBzaXplb2YodGN1OjpWZWM0KSk7CgoJCWdsLmJpbmRCdWZmZXIoR0xfQVJSQVlfQlVGRkVSLCAqdW5yZWxhdGVkQnVmZmVyKTsKCQlnbC5idWZmZXJEYXRhKEdMX0FSUkFZX0JVRkZFUiwgdW5yZWxhdGVkVXBsb2FkU2l6ZSwgREVfTlVMTCwgR0xfU1RBVElDX0RSQVcpOwoJCWdsLmJ1ZmZlclN1YkRhdGEoR0xfQVJSQVlfQlVGRkVSLCAwLCB1bnJlbGF0ZWRVcGxvYWRTaXplLCAmdmVydGV4RGF0YVswXSk7Cgl9CgllbHNlIGlmIChtX3VucmVsYXRlZFVwbG9hZE1ldGhvZCA9PSBVUExPQURNRVRIT0RfTUFQX0JVRkZFUl9SQU5HRSkKCXsKCQl2b2lkKgkJCW1hcFB0cjsKCQlnbHc6OkdMYm9vbGVhbgl1bm1hcFN1Y2Nlc3NmdWw7CgoJCXVucmVsYXRlZFVwbG9hZFNpemUgPSAoaW50KSh2ZXJ0ZXhEYXRhLnNpemUoKSAqIHNpemVvZih0Y3U6OlZlYzQpKTsKCgkJZ2wuYmluZEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIsICp1bnJlbGF0ZWRCdWZmZXIpOwoJCWdsLmJ1ZmZlckRhdGEoR0xfQVJSQVlfQlVGRkVSLCB1bnJlbGF0ZWRVcGxvYWRTaXplLCBERV9OVUxMLCBHTF9TVEFUSUNfRFJBVyk7CgoJCW1hcFB0ciA9IGdsLm1hcEJ1ZmZlclJhbmdlKEdMX0FSUkFZX0JVRkZFUiwgMCwgdW5yZWxhdGVkVXBsb2FkU2l6ZSwgR0xfTUFQX1dSSVRFX0JJVCB8IEdMX01BUF9JTlZBTElEQVRFX1JBTkdFX0JJVCB8IEdMX01BUF9JTlZBTElEQVRFX0JVRkZFUl9CSVQgfCBHTF9NQVBfVU5TWU5DSFJPTklaRURfQklUKTsKCQlpZiAoIW1hcFB0cikKCQkJdGhyb3cgdGN1OjpFeGNlcHRpb24oIk1hcEJ1ZmZlclJhbmdlIHJldHVybmVkIE5VTEwiKTsKCgkJZGVNZW1jcHkobWFwUHRyLCAmdmVydGV4RGF0YVswXSwgdW5yZWxhdGVkVXBsb2FkU2l6ZSk7CgoJCS8vIGlmIHVubWFwcGluZyBmYWlscywganVzdCB0cnkgYWdhaW4gbGF0ZXIKCQl1bm1hcFN1Y2Nlc3NmdWwgPSBnbC51bm1hcEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIpOwoJCWlmICghdW5tYXBTdWNjZXNzZnVsKQoJCQl0aHJvdyBVbm1hcEZhaWx1cmVFcnJvcigpOwoJfQoJZWxzZQoJCURFX0FTU0VSVChmYWxzZSk7CgoJREVfQVNTRVJUKHVucmVsYXRlZFVwbG9hZFNpemUgIT0gLTEpOwoKCS8vIE1lYXN1cmUgYm90aCBkcmF3IGFuZCBhc3NvY2lhdGVkIHJlYWRwaXhlbHMKCXsKCQlzdGFydFRpbWUgPSBkZUdldE1pY3Jvc2Vjb25kcygpOwoKCQlpZiAobV9kcmF3TWV0aG9kID09IERSQVdNRVRIT0RfRFJBV19BUlJBWVMpCgkJCWdsLmRyYXdBcnJheXMoR0xfVFJJQU5HTEVTLCAwLCBudW1WZXJ0aWNlcyk7CgkJZWxzZSBpZiAobV9kcmF3TWV0aG9kID09IERSQVdNRVRIT0RfRFJBV19FTEVNRU5UUykKCQkJZ2wuZHJhd0VsZW1lbnRzKEdMX1RSSUFOR0xFUywgbnVtVmVydGljZXMsIEdMX1VOU0lHTkVEX0lOVCwgREVfTlVMTCk7CgkJZWxzZQoJCQlERV9BU1NFUlQoZmFsc2UpOwoKCQllbmRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCgkJc2FtcGxlLnJlc3VsdC5kdXJhdGlvbi5yZW5kZXJEdXJhdGlvbiA9IGVuZFRpbWUgLSBzdGFydFRpbWU7Cgl9CgoJewoJCXN0YXJ0VGltZSA9IGRlR2V0TWljcm9zZWNvbmRzKCk7CgkJZ2x1OjpyZWFkUGl4ZWxzKG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCksIDAsIDAsIHJlc3VsdFN1cmZhY2UuZ2V0QWNjZXNzKCkpOwoJCWVuZFRpbWUgPSBkZUdldE1pY3Jvc2Vjb25kcygpOwoKCQlzYW1wbGUucmVzdWx0LmR1cmF0aW9uLnJlYWREdXJhdGlvbiA9IGVuZFRpbWUgLSBzdGFydFRpbWU7Cgl9CgoJc2FtcGxlLnJlc3VsdC5yZW5kZXJEYXRhU2l6ZSA9IGdldFZlcnRleERhdGFTaXplKCkgKiBzYW1wbGUucmVzdWx0Lm51bVZlcnRpY2VzOwoJc2FtcGxlLnJlc3VsdC51cGxvYWRlZERhdGFTaXplID0gcmVuZGVyVXBsb2FkU2l6ZTsKCXNhbXBsZS5yZXN1bHQudW5yZWxhdGVkRGF0YVNpemUgPSB1bnJlbGF0ZWRVcGxvYWRTaXplOwoJc2FtcGxlLnJlc3VsdC5kdXJhdGlvbi5yZW5kZXJSZWFkRHVyYXRpb24gPSBzYW1wbGUucmVzdWx0LmR1cmF0aW9uLnJlbmRlckR1cmF0aW9uICsgc2FtcGxlLnJlc3VsdC5kdXJhdGlvbi5yZWFkRHVyYXRpb247CglzYW1wbGUucmVzdWx0LmR1cmF0aW9uLnRvdGFsRHVyYXRpb24gPSBzYW1wbGUucmVzdWx0LmR1cmF0aW9uLnJlbmRlckR1cmF0aW9uICsgc2FtcGxlLnJlc3VsdC5kdXJhdGlvbi5yZWFkRHVyYXRpb247CglzYW1wbGUucmVzdWx0LmR1cmF0aW9uLmZpdFJlc3BvbnNlRHVyYXRpb24gPSBzYW1wbGUucmVzdWx0LmR1cmF0aW9uLnJlbmRlclJlYWREdXJhdGlvbjsKfQoKY2xhc3MgUmVmZXJlbmNlUmVhZFBpeGVsc1RpbWVDYXNlIDogcHVibGljIFRlc3RDYXNlCnsKcHVibGljOgoJCQkJCVJlZmVyZW5jZVJlYWRQaXhlbHNUaW1lQ2FzZQkJKENvbnRleHQmIGNvbnRleHQsIGNvbnN0IGNoYXIqIG5hbWUsIGNvbnN0IGNoYXIqIGRlc2NyaXB0aW9uKTsKCnByaXZhdGU6Cgl2b2lkCQkJaW5pdAkJCQkJCQkodm9pZCk7CglJdGVyYXRlUmVzdWx0CWl0ZXJhdGUJCQkJCQkJKHZvaWQpOwoJdm9pZAkJCWxvZ0FuZFNldFRlc3RSZXN1bHQJCQkJKHZvaWQpOwoKCWVudW0KCXsKCQlSRU5ERVJfQVJFQV9TSVpFID0gMTI4Cgl9OwoKCWNvbnN0IGludAkJCW1fbnVtU2FtcGxlczsKCWludAkJCQkJbV9zYW1wbGVOZHg7CglzdGQ6OnZlY3RvcjxpbnQ+CW1fc2FtcGxlczsKfTsKClJlZmVyZW5jZVJlYWRQaXhlbHNUaW1lQ2FzZTo6UmVmZXJlbmNlUmVhZFBpeGVsc1RpbWVDYXNlIChDb250ZXh0JiBjb250ZXh0LCBjb25zdCBjaGFyKiBuYW1lLCBjb25zdCBjaGFyKiBkZXNjcmlwdGlvbikKCTogVGVzdENhc2UJCShjb250ZXh0LCB0Y3U6Ok5PREVUWVBFX1BFUkZPUk1BTkNFLCBuYW1lLCBkZXNjcmlwdGlvbikKCSwgbV9udW1TYW1wbGVzCSgyMCkKCSwgbV9zYW1wbGVOZHgJKDApCgksIG1fc2FtcGxlcwkJKG1fbnVtU2FtcGxlcykKewp9Cgp2b2lkIFJlZmVyZW5jZVJlYWRQaXhlbHNUaW1lQ2FzZTo6aW5pdCAodm9pZCkKewoJbV90ZXN0Q3R4LmdldExvZygpCgkJPDwgdGN1OjpUZXN0TG9nOjpNZXNzYWdlCgkJPDwgIk1lYXN1cmluZyB0aGUgdGltZSB1c2VkIGluIGEgc2luZ2xlIHJlYWRQaXhlbHMgY2FsbCB3aXRoICIgPDwgbV9udW1TYW1wbGVzIDw8ICIgdGVzdCBzYW1wbGVzLlxuIgoJCTw8ICJUZXN0IHJlc3VsdCBpcyB0aGUgbWVkaWFuIG9mIHRoZSBzYW1wbGVzIGluIG1pY3Jvc2Vjb25kcy5cbiIKCQk8PCAiTm90ZSEgVGVzdCByZXN1bHQgc2hvdWxkIG9ubHkgYmUgdXNlZCBhcyBhIGJhc2VsaW5lIHJlZmVyZW5jZSByZXN1bHQgZm9yIGJ1ZmZlci5kYXRhX3VwbG9hZC4qIHRlc3QgZ3JvdXAgcmVzdWx0cy4iCgkJPDwgdGN1OjpUZXN0TG9nOjpFbmRNZXNzYWdlOwp9CgpSZWZlcmVuY2VSZWFkUGl4ZWxzVGltZUNhc2U6Okl0ZXJhdGVSZXN1bHQgUmVmZXJlbmNlUmVhZFBpeGVsc1RpbWVDYXNlOjppdGVyYXRlICh2b2lkKQp7Cgljb25zdCBnbHc6OkZ1bmN0aW9ucyYJZ2wJCQkJPSBtX2NvbnRleHQuZ2V0UmVuZGVyQ29udGV4dCgpLmdldEZ1bmN0aW9ucygpOwoJdGN1OjpTdXJmYWNlCQkJcmVzdWx0U3VyZmFjZQkoUkVOREVSX0FSRUFfU0laRSwgUkVOREVSX0FSRUFfU0laRSk7CglkZVVpbnQ2NAkJCQlzdGFydFRpbWU7CglkZVVpbnQ2NAkJCQllbmRUaW1lOwoKCWRlWWllbGQoKTsKCXRjdTo6d2FybXVwQ1BVKCk7CglkZVlpZWxkKCk7CgoJLy8gIlJlbmRlciIgc29tZXRoaW5nIGFuZCB3YWl0IGZvciBpdAoJZ2wuY2xlYXJDb2xvcigwLjBmLCAxLjBmLCBmbG9hdChtX3NhbXBsZU5keCkgLyBmbG9hdChtX251bVNhbXBsZXMpLCAxLjBmKTsKCWdsLmNsZWFyKEdMX0NPTE9SX0JVRkZFUl9CSVQpOwoKCS8vIHdhaXQgZm9yIHJlc3VsdHMKCWdsdTo6cmVhZFBpeGVscyhtX2NvbnRleHQuZ2V0UmVuZGVyQ29udGV4dCgpLCAwLCAwLCByZXN1bHRTdXJmYWNlLmdldEFjY2VzcygpKTsKCgkvLyBtZWFzdXJlIHRpbWUgdXNlZCBpbiByZWFkUGl4ZWxzCglzdGFydFRpbWUgPSBkZUdldE1pY3Jvc2Vjb25kcygpOwoJZ2x1OjpyZWFkUGl4ZWxzKG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCksIDAsIDAsIHJlc3VsdFN1cmZhY2UuZ2V0QWNjZXNzKCkpOwoJZW5kVGltZSA9IGRlR2V0TWljcm9zZWNvbmRzKCk7CgoJbV9zYW1wbGVzW21fc2FtcGxlTmR4XSA9IChpbnQpKGVuZFRpbWUgLSBzdGFydFRpbWUpOwoKCWlmICgrK21fc2FtcGxlTmR4IDwgbV9udW1TYW1wbGVzKQoJCXJldHVybiBDT05USU5VRTsKCglsb2dBbmRTZXRUZXN0UmVzdWx0KCk7CglyZXR1cm4gU1RPUDsKfQoKdm9pZCBSZWZlcmVuY2VSZWFkUGl4ZWxzVGltZUNhc2U6OmxvZ0FuZFNldFRlc3RSZXN1bHQgKHZvaWQpCnsKCS8vIExvZyBzYW1wbGUgbGlzdAoJewoJCW1fdGVzdEN0eC5nZXRMb2coKQoJCQk8PCB0Y3U6OlRlc3RMb2c6OlNhbXBsZUxpc3QoIlNhbXBsZXMiLCAiU2FtcGxlcyIpCgkJCTw8IHRjdTo6VGVzdExvZzo6U2FtcGxlSW5mbwoJCQk8PCB0Y3U6OlRlc3RMb2c6OlZhbHVlSW5mbygiUmVhZFRpbWUiLCAiUmVhZFBpeGVscyB0aW1lIiwgInVzIiwgUVBfU0FNUExFX1ZBTFVFX1RBR19SRVNQT05TRSkKCQkJPDwgdGN1OjpUZXN0TG9nOjpFbmRTYW1wbGVJbmZvOwoKCQlmb3IgKGludCBzYW1wbGVOZHggPSAwOyBzYW1wbGVOZHggPCAoaW50KW1fc2FtcGxlcy5zaXplKCk7ICsrc2FtcGxlTmR4KQoJCQltX3Rlc3RDdHguZ2V0TG9nKCkKCQkJCTw8IHRjdTo6VGVzdExvZzo6U2FtcGxlCgkJCQk8PCBtX3NhbXBsZXNbc2FtcGxlTmR4XQoJCQkJPDwgdGN1OjpUZXN0TG9nOjpFbmRTYW1wbGU7CgoJCW1fdGVzdEN0eC5nZXRMb2coKSA8PCB0Y3U6OlRlc3RMb2c6OkVuZFNhbXBsZUxpc3Q7Cgl9CgoJLy8gTG9nIG1lZGlhbgoJewoJCWZsb2F0IG1lZGlhbjsKCQlmbG9hdCBsaW1pdDYwTG93OwoJCWZsb2F0IGxpbWl0NjBVcDsKCgkJc3RkOjpzb3J0KG1fc2FtcGxlcy5iZWdpbigpLCBtX3NhbXBsZXMuZW5kKCkpOwoJCW1lZGlhbgkJPSBsaW5lYXJTYW1wbGUobV9zYW1wbGVzLCAwLjVmKTsKCQlsaW1pdDYwTG93CT0gbGluZWFyU2FtcGxlKG1fc2FtcGxlcywgMC4yZik7CgkJbGltaXQ2MFVwCT0gbGluZWFyU2FtcGxlKG1fc2FtcGxlcywgMC44Zik7CgoJCW1fdGVzdEN0eC5nZXRMb2coKQoJCQk8PCB0Y3U6OlRlc3RMb2c6OkZsb2F0KCJNZWRpYW4iLCAiTWVkaWFuIiwgInVzIiwgUVBfS0VZX1RBR19USU1FLCBtZWRpYW4pCgkJCTw8IHRjdTo6VGVzdExvZzo6TWVzc2FnZQoJCQk8PCAiNjAgJSBvZiBzYW1wbGVzIHdpdGhpbiByYW5nZTpcbiIKCQkJPDwgdGN1OjpUZXN0TG9nOjpFbmRNZXNzYWdlCgkJCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIkxvdzYwUmFuZ2UiLCAiTG93ZXIiLCAidXMiLCBRUF9LRVlfVEFHX1RJTUUsIGxpbWl0NjBMb3cpCgkJCTw8IHRjdTo6VGVzdExvZzo6RmxvYXQoIkhpZ2g2MFJhbmdlIiwgIlVwcGVyIiwgInVzIiwgUVBfS0VZX1RBR19USU1FLCBsaW1pdDYwVXApOwoKCQltX3Rlc3RDdHguc2V0VGVzdFJlc3VsdChRUF9URVNUX1JFU1VMVF9QQVNTLCBkZTo6ZmxvYXRUb1N0cmluZyhtZWRpYW4sIDIpLmNfc3RyKCkpOwoJfQp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgU2FtcGxlVHlwZT4KY2xhc3MgR2VuZXJpY1VwbG9hZFJlbmRlclRpbWVDYXNlIDogcHVibGljIFJlbmRlckNhc2U8U2FtcGxlVHlwZT4KewpwdWJsaWM6Cgl0eXBlZGVmIHR5cGVuYW1lIFJlbmRlckNhc2U8U2FtcGxlVHlwZT46OlNhbXBsZVJlc3VsdCBTYW1wbGVSZXN1bHQ7CgoJCQkJCQkJR2VuZXJpY1VwbG9hZFJlbmRlclRpbWVDYXNlCShDb250ZXh0JgkJCQljb250ZXh0LAoJCQkJCQkJCQkJCQkJCSBjb25zdCBjaGFyKgkJCW5hbWUsCgkJCQkJCQkJCQkJCQkJIGNvbnN0IGNoYXIqCQkJZGVzY3JpcHRpb24sCgkJCQkJCQkJCQkJCQkJIERyYXdNZXRob2QJCQkJbWV0aG9kLAoJCQkJCQkJCQkJCQkJCSBUYXJnZXRCdWZmZXIJCQl0YXJnZXRCdWZmZXIsCgkJCQkJCQkJCQkJCQkJIFVwbG9hZE1ldGhvZAkJCXVwbG9hZE1ldGhvZCwKCQkJCQkJCQkJCQkJCQkgQnVmZmVyU3RhdGUJCQlidWZmZXJTdGF0ZSwKCQkJCQkJCQkJCQkJCQkgVXBsb2FkUmFuZ2UJCQl1cGxvYWRSYW5nZSwKCQkJCQkJCQkJCQkJCQkgVW5yZWxhdGVkQnVmZmVyVHlwZQl1bnJlbGF0ZWRCdWZmZXJUeXBlKTsKCnByaXZhdGU6Cgl2b2lkCQkJCQkJaW5pdAkJCQkJKHZvaWQpOwoJdm9pZAkJCQkJCXJ1blNhbXBsZQkJCQkoU2FtcGxlUmVzdWx0JiBzYW1wbGUpOwoKCXVzaW5nIFJlbmRlckNhc2U8U2FtcGxlVHlwZT46OlJFTkRFUl9BUkVBX1NJWkU7CgoJY29uc3QgVGFyZ2V0QnVmZmVyCQkJbV90YXJnZXRCdWZmZXI7Cgljb25zdCBCdWZmZXJTdGF0ZQkJCW1fYnVmZmVyU3RhdGU7Cgljb25zdCBVcGxvYWRNZXRob2QJCQltX3VwbG9hZE1ldGhvZDsKCWNvbnN0IFVucmVsYXRlZEJ1ZmZlclR5cGUJbV91bnJlbGF0ZWRCdWZmZXJUeXBlOwoJY29uc3QgVXBsb2FkUmFuZ2UJCQltX3VwbG9hZFJhbmdlOwoKCXVzaW5nIFJlbmRlckNhc2U8U2FtcGxlVHlwZT46Om1fY29udGV4dDsKCXVzaW5nIFJlbmRlckNhc2U8U2FtcGxlVHlwZT46Om1fdGVzdEN0eDsKCXVzaW5nIFJlbmRlckNhc2U8U2FtcGxlVHlwZT46Om1fZHJhd01ldGhvZDsKfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgpHZW5lcmljVXBsb2FkUmVuZGVyVGltZUNhc2U8U2FtcGxlVHlwZT46OkdlbmVyaWNVcGxvYWRSZW5kZXJUaW1lQ2FzZSAoQ29udGV4dCYJCQkJY29udGV4dCwKCQkJCQkJCQkJCQkJCQkJCQkgIGNvbnN0IGNoYXIqCQkJbmFtZSwKCQkJCQkJCQkJCQkJCQkJCQkgIGNvbnN0IGNoYXIqCQkJZGVzY3JpcHRpb24sCgkJCQkJCQkJCQkJCQkJCQkJICBEcmF3TWV0aG9kCQkJbWV0aG9kLAoJCQkJCQkJCQkJCQkJCQkJCSAgVGFyZ2V0QnVmZmVyCQkJdGFyZ2V0QnVmZmVyLAoJCQkJCQkJCQkJCQkJCQkJCSAgVXBsb2FkTWV0aG9kCQkJdXBsb2FkTWV0aG9kLAoJCQkJCQkJCQkJCQkJCQkJCSAgQnVmZmVyU3RhdGUJCQlidWZmZXJTdGF0ZSwKCQkJCQkJCQkJCQkJCQkJCQkgIFVwbG9hZFJhbmdlCQkJdXBsb2FkUmFuZ2UsCgkJCQkJCQkJCQkJCQkJCQkJICBVbnJlbGF0ZWRCdWZmZXJUeXBlCXVucmVsYXRlZEJ1ZmZlclR5cGUpCgk6IFJlbmRlckNhc2U8U2FtcGxlVHlwZT4JKGNvbnRleHQsIG5hbWUsIGRlc2NyaXB0aW9uLCBtZXRob2QpCgksIG1fdGFyZ2V0QnVmZmVyCQkJKHRhcmdldEJ1ZmZlcikKCSwgbV9idWZmZXJTdGF0ZQkJCQkoYnVmZmVyU3RhdGUpCgksIG1fdXBsb2FkTWV0aG9kCQkJKHVwbG9hZE1ldGhvZCkKCSwgbV91bnJlbGF0ZWRCdWZmZXJUeXBlCQkodW5yZWxhdGVkQnVmZmVyVHlwZSkKCSwgbV91cGxvYWRSYW5nZQkJCQkodXBsb2FkUmFuZ2UpCnsKCURFX0FTU0VSVChtX3RhcmdldEJ1ZmZlciA8IFRBUkdFVEJVRkZFUl9MQVNUKTsKCURFX0FTU0VSVChtX2J1ZmZlclN0YXRlIDwgQlVGRkVSU1RBVEVfTEFTVCk7CglERV9BU1NFUlQobV91cGxvYWRNZXRob2QgPCBVUExPQURNRVRIT0RfTEFTVCk7CglERV9BU1NFUlQobV91bnJlbGF0ZWRCdWZmZXJUeXBlIDwgVU5SRUxBVEVEQlVGRkVSVFlQRV9MQVNUKTsKCURFX0FTU0VSVChtX3VwbG9hZFJhbmdlIDwgVVBMT0FEUkFOR0VfTEFTVCk7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgp2b2lkIEdlbmVyaWNVcGxvYWRSZW5kZXJUaW1lQ2FzZTxTYW1wbGVUeXBlPjo6aW5pdCAodm9pZCkKewoJLy8gaW5pdCBwYXJlbnQKCVJlbmRlckNhc2U8U2FtcGxlVHlwZT46OmluaXQoKTsKCgkvLyBsb2cKCXsKCQljb25zdCBjaGFyKiBjb25zdAl0YXJnZXRGdW5jdGlvbk5hbWUJCT0gKG1fZHJhd01ldGhvZCA9PSBEUkFXTUVUSE9EX0RSQVdfQVJSQVlTKSA/ICgiZHJhd0FycmF5cyIpIDogKCJkcmF3RWxlbWVudHMiKTsKCQljb25zdCBpbnQJCQlwZXJWZXJ0ZXhTaXplCQkJPSAobV90YXJnZXRCdWZmZXIgPT0gVEFSR0VUQlVGRkVSX0lOREVYKSA/ICgoaW50KXNpemVvZihkZVVpbnQzMikpIDogKChpbnQpc2l6ZW9mKHRjdTo6VmVjNFsyXSkpOwoJCWNvbnN0IGludAkJCWZ1bGxNaW5VcGxvYWRTaXplCQk9IFJlbmRlckNhc2U8U2FtcGxlVHlwZT46OmdldE1pbldvcmtsb2FkU2l6ZSgpICogcGVyVmVydGV4U2l6ZTsKCQljb25zdCBpbnQJCQlmdWxsTWF4VXBsb2FkU2l6ZQkJPSBSZW5kZXJDYXNlPFNhbXBsZVR5cGU+OjpnZXRNYXhXb3JrbG9hZFNpemUoKSAqIHBlclZlcnRleFNpemU7CgkJY29uc3QgaW50CQkJbWluVXBsb2FkU2l6ZQkJCT0gKG1fdXBsb2FkUmFuZ2UgPT0gVVBMT0FEUkFOR0VfRlVMTCkgPyAoZnVsbE1pblVwbG9hZFNpemUpIDogKGRlQWxpZ24zMihmdWxsTWluVXBsb2FkU2l6ZS8yLCA0KSk7CgkJY29uc3QgaW50CQkJbWF4VXBsb2FkU2l6ZQkJCT0gKG1fdXBsb2FkUmFuZ2UgPT0gVVBMT0FEUkFOR0VfRlVMTCkgPyAoZnVsbE1heFVwbG9hZFNpemUpIDogKGRlQWxpZ24zMihmdWxsTWF4VXBsb2FkU2l6ZS8yLCA0KSk7CgkJY29uc3QgaW50CQkJbWluVW5yZWxhdGVkVXBsb2FkU2l6ZQk9IFJlbmRlckNhc2U8U2FtcGxlVHlwZT46OmdldE1pbldvcmtsb2FkU2l6ZSgpICogKGludClzaXplb2YodGN1OjpWZWM0WzJdKTsKCQljb25zdCBpbnQJCQltYXhVbnJlbGF0ZWRVcGxvYWRTaXplCT0gUmVuZGVyQ2FzZTxTYW1wbGVUeXBlPjo6Z2V0TWF4V29ya2xvYWRTaXplKCkgKiAoaW50KXNpemVvZih0Y3U6OlZlYzRbMl0pOwoKCQltX3Rlc3RDdHguZ2V0TG9nKCkKCQkJPDwgdGN1OjpUZXN0TG9nOjpNZXNzYWdlCgkJCTw8ICJNZWFzdXJpbmcgdGhlIHRpbWUgdXNlZCBpbiAiIDw8IHRhcmdldEZ1bmN0aW9uTmFtZSA8PCAiIGFuZCByZWFkUGl4ZWxzIGNhbGwgd2l0aCBkaWZmZXJlbnQgcmVuZGVyaW5nIHdvcmtsb2Fkcy5cbiIKCQkJPDwgIlRoZSAiCgkJCQk8PCAoKG1fdGFyZ2V0QnVmZmVyID09IFRBUkdFVEJVRkZFUl9JTkRFWCkgPyAoImluZGV4IikgOiAoInZlcnRleCBhdHRyaWIiKSkKCQkJCTw8ICIgYnVmZmVyICIKCQkJCTw8ICgobV9idWZmZXJTdGF0ZSA9PSBCVUZGRVJTVEFURV9ORVcpID8gKCIiKSA6ICgiY29udGVudHMgIikpCgkJCQk8PCAic291cmNlZCBieSB0aGUgcmVuZGVyaW5nIGNvbW1hbmQgIgoJCQkJPDwgKChtX2J1ZmZlclN0YXRlID09IEJVRkZFUlNUQVRFX05FVykJCT8gKCJpcyB1cGxvYWRlZCAiKSA6CgkJCQkJKG1fdXBsb2FkUmFuZ2UgPT0gVVBMT0FEUkFOR0VfRlVMTCkJCT8gKCJhcmUgc3BlY2lmaWVkICIpIDoKCQkJCQkobV91cGxvYWRSYW5nZSA9PSBVUExPQURSQU5HRV9QQVJUSUFMKQk/ICgiYXJlIHVwZGF0ZWQgKHBhcnRpYWwgdXBsb2FkKSAiKSA6CgkJCQkJKChjb25zdCBjaGFyKilERV9OVUxMKSkKCQkJCTw8ICJqdXN0IGJlZm9yZSBpc3N1aW5nIHRoZSByZW5kZXJpbmcgY29tbWFuZC5cbiIKCQkJPDwgKChtX2J1ZmZlclN0YXRlID09IEJVRkZFUlNUQVRFX0VYSVNUSU5HKSA/ICgiVGhlIGJ1ZmZlciBoYXMgYmVlbiB1c2VkIGluIHJlbmRlcmluZy5cbiIpIDogKCJUaGUgYnVmZmVyIGlzIGdlbmVyYXRlZCBqdXN0IGJlZm9yZSB1cGxvYWRpbmcuXG4iKSkKCQkJPDwgIkJ1ZmZlciAiCgkJCQk8PCAoKG1fYnVmZmVyU3RhdGUgPT0gQlVGRkVSU1RBVEVfTkVXKQkJPyAoImlzIHVwbG9hZGVkIikgOgoJCQkJCShtX3VwbG9hZFJhbmdlID09IFVQTE9BRFJBTkdFX0ZVTEwpCQk/ICgiY29udGVudHMgYXJlIHNwZWNpZmllZCIpIDoKCQkJCQkobV91cGxvYWRSYW5nZSA9PSBVUExPQURSQU5HRV9QQVJUSUFMKQk/ICgiY29udGVudHMgYXJlIHBhcnRpYWxseSB1cGRhdGVkIikgOgoJCQkJCSgoY29uc3QgY2hhciopREVfTlVMTCkpCgkJCQk8PCAiIHdpdGggIgoJCQkJPDwgKChtX3VwbG9hZE1ldGhvZCA9PSBVUExPQURNRVRIT0RfQlVGRkVSX0RBVEEpID8gKCJidWZmZXJEYXRhIikgOiAobV91cGxvYWRNZXRob2QgPT0gVVBMT0FETUVUSE9EX0JVRkZFUl9TVUJfREFUQSkgPyAoImJ1ZmZlclN1YkRhdGEiKSA6ICgibWFwQnVmZmVyUmFuZ2UiKSkKCQkJCTw8ICIgY29tbWFuZC4gVXNhZ2Ugb2YgdGhlIHRhcmdldCBidWZmZXIgaXMgRFlOQU1JQ19EUkFXLlxuIgoJCQk8PCAoKG1fdXBsb2FkTWV0aG9kID09IFVQTE9BRE1FVEhPRF9NQVBfQlVGRkVSX1JBTkdFKSA/ICgiTWFwcGluZyBidWZmZXIgd2l0aCBiaXRzIE1BUF9XUklURV9CSVQgfCBNQVBfSU5WQUxJREFURV9SQU5HRV9CSVQgfCBNQVBfSU5WQUxJREFURV9CVUZGRVJfQklUIHwgTUFQX1VOU1lOQ0hST05JWkVEX0JJVFxuIikgOiAoIiIpKQoJCQk8PCAoKG1fdW5yZWxhdGVkQnVmZmVyVHlwZSA9PSBVTlJFTEFURURCVUZGRVJUWVBFX1ZFUlRFWCkgPyAoIlVwbG9hZGluZyBhbiB1bnJlbGF0ZWQgYnVmZmVyIGp1c3QgYmVmb3JlIGlzc3VpbmcgdGhlIHJlbmRlcmluZyBjb21tYW5kIHdpdGggYnVmZmVyRGF0YS5cbiIpIDogKCIiKSkKCQkJPDwgUmVuZGVyQ2FzZTxTYW1wbGVUeXBlPjo6Z2V0TnVtU2FtcGxlcygpIDw8ICIgdGVzdCBzYW1wbGVzLiBTYW1wbGUgb3JkZXIgaXMgcmFuZG9taXplZC5cbiIKCQkJPDwgIkFsbCBzYW1wbGVzIGF0IGV2ZW4gcG9zaXRpb25zIChmaXJzdCA9IDApIGFyZSB0ZXN0ZWQgYmVmb3JlIHNhbXBsZXMgYXQgb2RkIHBvc2l0aW9ucy5cbiIKCQkJPDwgIkdlbmVyYXRlZCB3b3JrbG9hZCBpcyBtdWx0aXBsZSB2aWV3cG9ydC1jb3ZlcmluZyBncmlkcyB3aXRoIHZhcnlpbmcgbnVtYmVyIG9mIGNlbGxzLCBlYWNoIGNlbGwgaXMgdHdvIHNlcGFyYXRlIHRyaWFuZ2xlcy5cbiIKCQkJPDwgIldvcmtsb2FkIHNpemVzIGFyZSBpbiB0aGUgcmFuZ2UgWyIKCQkJCTw8IFJlbmRlckNhc2U8U2FtcGxlVHlwZT46OmdldE1pbldvcmtsb2FkU2l6ZSgpIDw8ICIsICAiCgkJCQk8PCBSZW5kZXJDYXNlPFNhbXBsZVR5cGU+OjpnZXRNYXhXb3JrbG9hZFNpemUoKSA8PCAiXSB2ZXJ0aWNlcyAiCgkJCQk8PCAiKFsiCgkJCQk8PCBnZXRIdW1hblJlYWRhYmxlQnl0ZVNpemUoUmVuZGVyQ2FzZTxTYW1wbGVUeXBlPjo6Z2V0TWluV29ya2xvYWREYXRhU2l6ZSgpKSA8PCAiLCIKCQkJCTw8IGdldEh1bWFuUmVhZGFibGVCeXRlU2l6ZShSZW5kZXJDYXNlPFNhbXBsZVR5cGU+OjpnZXRNYXhXb3JrbG9hZERhdGFTaXplKCkpIDw8ICJdIHRvIGJlIHByb2Nlc3NlZCkuXG4iCgkJCTw8ICJVcGxvYWQgc2l6ZXMgYXJlIGluIHRoZSByYW5nZSBbIgoJCQkJPDwgZ2V0SHVtYW5SZWFkYWJsZUJ5dGVTaXplKG1pblVwbG9hZFNpemUpIDw8ICIsIgoJCQkJPDwgZ2V0SHVtYW5SZWFkYWJsZUJ5dGVTaXplKG1heFVwbG9hZFNpemUpIDw8ICJdLlxuIgoJCQk8PCAoKG1fZHJhd01ldGhvZCA9PSBEUkFXTUVUSE9EX0RSQVdfRUxFTUVOVFMpID8KCQkJCSgiVW5yZWxhdGVkIHVwbG9hZCBzaXplcyBhcmUgaW4gdGhlIHJhbmdlIFsiICsgZ2V0SHVtYW5SZWFkYWJsZUJ5dGVTaXplKG1pblVucmVsYXRlZFVwbG9hZFNpemUpICsgIiwgIiArIGdldEh1bWFuUmVhZGFibGVCeXRlU2l6ZShtYXhVbnJlbGF0ZWRVcGxvYWRTaXplKSArICJdXG4iKSA6CgkJCQkoIiIpKQoJCQk8PCAiVGVzdCByZXN1bHQgaXMgdGhlIGFwcHJveGltYXRlZCBwcm9jZXNzaW5nIHJhdGUgaW4gTWlCIC8gcy5cbiIKCQkJPDwgIk5vdGUgdGhhdCB3aGlsZSB1cGxvYWQgdGltZSBpcyBtZWFzdXJlZCwgdGhlIHRpbWUgdXNlZCBpcyBub3QgaW5jbHVkZWQgaW4gdGhlIHJlc3VsdHMuXG4iCgkJCTw8ICgobV91bnJlbGF0ZWRCdWZmZXJUeXBlID09IFVOUkVMQVRFREJVRkZFUlRZUEVfVkVSVEVYKSA/ICgiTm90ZSB0aGF0IHRoZSBkYXRhIHNpemUgYW5kIHRoZSB0aW1lIHVzZWQgaW4gdGhlIHVucmVsYXRlZCB1cGxvYWQgaXMgbm90IGluY2x1ZGVkIGluIHRoZSByZXN1bHRzLlxuIikgOiAoIiIpKQoJCQk8PCAoKG1fZHJhd01ldGhvZCA9PSBEUkFXTUVUSE9EX0RSQVdfRUxFTUVOVFMpID8gKCJOb3RlIHRoYXQgaW5kZXggYXJyYXkgc2l6ZSBpcyBub3QgaW5jbHVkZWQgaW4gdGhlIHByb2Nlc3NlZCBzaXplLlxuIikgOiAoIiIpKQoJCQk8PCAiTm90ZSEgVGVzdCByZXN1bHQgbWF5IG5vdCBiZSB1c2VmdWwgYXMgaXMgYnV0IGluc3RlYWQgc2hvdWxkIGJlIGNvbXBhcmVkIGFnYWluc3QgdGhlIHJlZmVyZW5jZS4qIGdyb3VwIGFuZCBvdGhlciB1cGxvYWRfYW5kX2RyYXcuKiBncm91cCByZXN1bHRzLlxuIgoJCQk8PCB0Y3U6OlRlc3RMb2c6OkVuZE1lc3NhZ2U7Cgl9Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBTYW1wbGVUeXBlPgp2b2lkIEdlbmVyaWNVcGxvYWRSZW5kZXJUaW1lQ2FzZTxTYW1wbGVUeXBlPjo6cnVuU2FtcGxlIChTYW1wbGVSZXN1bHQmIHNhbXBsZSkKewoJY29uc3QgZ2x3OjpGdW5jdGlvbnMmCWdsCQkJCQk9IG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCkuZ2V0RnVuY3Rpb25zKCk7Cgljb25zdCBnbHU6OkJ1ZmZlcgkJYXJyYXlCdWZmZXIJCQkobV9jb250ZXh0LmdldFJlbmRlckNvbnRleHQoKSk7Cgljb25zdCBnbHU6OkJ1ZmZlcgkJaW5kZXhCdWZmZXIJCQkobV9jb250ZXh0LmdldFJlbmRlckNvbnRleHQoKSk7Cgljb25zdCBnbHU6OkJ1ZmZlcgkJdW5yZWxhdGVkQnVmZmVyCQkobV9jb250ZXh0LmdldFJlbmRlckNvbnRleHQoKSk7Cgljb25zdCBpbnQJCQkJbnVtVmVydGljZXMJCQk9IGdldExheWVyZWRHcmlkTnVtVmVydGljZXMoc2FtcGxlLnNjZW5lKTsKCXRjdTo6U3VyZmFjZQkJCXJlc3VsdFN1cmZhY2UJCShSRU5ERVJfQVJFQV9TSVpFLCBSRU5ERVJfQVJFQV9TSVpFKTsKCWRlVWludDY0CQkJCXN0YXJ0VGltZTsKCWRlVWludDY0CQkJCWVuZFRpbWU7CglzdGQ6OnZlY3Rvcjx0Y3U6OlZlYzQ+CXZlcnRleERhdGE7CglzdGQ6OnZlY3RvcjxkZVVpbnQzMj4JaW5kZXhEYXRhOwoKCS8vIGNyZWF0ZSBkYXRhCgoJZ2VuZXJhdGVMYXllcmVkR3JpZFZlcnRleEF0dHJpYkRhdGE0QzRWKHZlcnRleERhdGEsIHNhbXBsZS5zY2VuZSk7CglpZiAobV9kcmF3TWV0aG9kID09IERSQVdNRVRIT0RfRFJBV19FTEVNRU5UUykKCQlnZW5lcmF0ZUxheWVyZWRHcmlkSW5kZXhEYXRhKGluZGV4RGF0YSwgc2FtcGxlLnNjZW5lKTsKCglnbC5iaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgKmFycmF5QnVmZmVyKTsKCWdsLmJpbmRCdWZmZXIoR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVIsICppbmRleEJ1ZmZlcik7CglSZW5kZXJDYXNlPFNhbXBsZVR5cGU+OjpzZXR1cFZlcnRleEF0dHJpYnMoKTsKCgkvLyB0YXJnZXQgc2hvdWxkIGJlIGFuIGV4aXNpdGluZyBidWZmZXI/IERyYXcgZnJvbSBpdCBvbmNlIHRvIG1ha2Ugc3VyZSBpdCBleGlzdHMgb24gdGhlIGdwdQoKCWlmIChtX2RyYXdNZXRob2QgPT0gRFJBV01FVEhPRF9EUkFXX0FSUkFZUyAmJiBtX2J1ZmZlclN0YXRlID09IEJVRkZFUlNUQVRFX0VYSVNUSU5HKQoJewoJCWdsLmJ1ZmZlckRhdGEoR0xfQVJSQVlfQlVGRkVSLCAoZ2x3OjpHTHNpemVpcHRyKSh2ZXJ0ZXhEYXRhLnNpemUoKSAqIHNpemVvZih0Y3U6OlZlYzQpKSwgJnZlcnRleERhdGFbMF0sIEdMX0RZTkFNSUNfRFJBVyk7CgkJZ2wuZHJhd0FycmF5cyhHTF9UUklBTkdMRVMsIDAsIG51bVZlcnRpY2VzKTsKCX0KCWVsc2UgaWYgKG1fZHJhd01ldGhvZCA9PSBEUkFXTUVUSE9EX0RSQVdfQVJSQVlTICYmIG1fYnVmZmVyU3RhdGUgPT0gQlVGRkVSU1RBVEVfTkVXKQoJewoJCS8vIGRvIG5vdCB0b3VjaCB0aGUgdmVydGV4IGJ1ZmZlcgoJfQoJZWxzZSBpZiAobV9kcmF3TWV0aG9kID09IERSQVdNRVRIT0RfRFJBV19FTEVNRU5UUyAmJiBtX2J1ZmZlclN0YXRlID09IEJVRkZFUlNUQVRFX0VYSVNUSU5HKQoJewoJCS8vIGhpbnQgdGhhdCB0aGUgdGFyZ2V0IGJ1ZmZlciB3aWxsIGJlIG1vZGlmaWVkIHNvb24KCQljb25zdCBnbHc6OkdMZW51bSB2ZXJ0ZXhEYXRhVXNhZ2UJPSAobV90YXJnZXRCdWZmZXIgPT0gVEFSR0VUQlVGRkVSX1ZFUlRFWCkgPyAoR0xfRFlOQU1JQ19EUkFXKSA6IChHTF9TVEFUSUNfRFJBVyk7CgkJY29uc3QgZ2x3OjpHTGVudW0gaW5kZXhEYXRhVXNhZ2UJPSAobV90YXJnZXRCdWZmZXIgPT0gVEFSR0VUQlVGRkVSX0lOREVYKSA/IChHTF9EWU5BTUlDX0RSQVcpIDogKEdMX1NUQVRJQ19EUkFXKTsKCgkJZ2wuYnVmZmVyRGF0YShHTF9BUlJBWV9CVUZGRVIsIChnbHc6OkdMc2l6ZWlwdHIpKHZlcnRleERhdGEuc2l6ZSgpICogc2l6ZW9mKHRjdTo6VmVjNCkpLCAmdmVydGV4RGF0YVswXSwgdmVydGV4RGF0YVVzYWdlKTsKCQlnbC5idWZmZXJEYXRhKEdMX0VMRU1FTlRfQVJSQVlfQlVGRkVSLCAoZ2x3OjpHTHNpemVpcHRyKShpbmRleERhdGEuc2l6ZSgpICogc2l6ZW9mKGRlVWludDMyKSksICZpbmRleERhdGFbMF0sIGluZGV4RGF0YVVzYWdlKTsKCQlnbC5kcmF3RWxlbWVudHMoR0xfVFJJQU5HTEVTLCBudW1WZXJ0aWNlcywgR0xfVU5TSUdORURfSU5ULCBERV9OVUxMKTsKCX0KCWVsc2UgaWYgKG1fZHJhd01ldGhvZCA9PSBEUkFXTUVUSE9EX0RSQVdfRUxFTUVOVFMgJiYgbV9idWZmZXJTdGF0ZSA9PSBCVUZGRVJTVEFURV9ORVcpCgl7CgkJaWYgKG1fdGFyZ2V0QnVmZmVyID09IFRBUkdFVEJVRkZFUl9WRVJURVgpCgkJewoJCQkvLyBtYWtlIHRoZSBpbmRleCBidWZmZXIgcHJlc2VudCBvbiB0aGUgZ3B1CgkJCS8vIHVzZSBhbm90aGVyIHZlcnRleCBidWZmZXIgdG8ga2VlcCBvcmlnaW5hbCBidWZmZXIgaW4gdW51c2VkIHN0YXRlCgkJCWNvbnN0IGdsdTo6QnVmZmVyIHZlcnRleENvcHlCdWZmZXIobV9jb250ZXh0LmdldFJlbmRlckNvbnRleHQoKSk7CgoJCQlnbC5iaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgKnZlcnRleENvcHlCdWZmZXIpOwoJCQlSZW5kZXJDYXNlPFNhbXBsZVR5cGU+OjpzZXR1cFZlcnRleEF0dHJpYnMoKTsKCgkJCWdsLmJ1ZmZlckRhdGEoR0xfQVJSQVlfQlVGRkVSLCAoZ2x3OjpHTHNpemVpcHRyKSh2ZXJ0ZXhEYXRhLnNpemUoKSAqIHNpemVvZih0Y3U6OlZlYzQpKSwgJnZlcnRleERhdGFbMF0sIEdMX1NUQVRJQ19EUkFXKTsKCQkJZ2wuYnVmZmVyRGF0YShHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUiwgKGdsdzo6R0xzaXplaXB0cikoaW5kZXhEYXRhLnNpemUoKSAqIHNpemVvZihkZVVpbnQzMikpLCAmaW5kZXhEYXRhWzBdLCBHTF9TVEFUSUNfRFJBVyk7CgkJCWdsLmRyYXdFbGVtZW50cyhHTF9UUklBTkdMRVMsIG51bVZlcnRpY2VzLCBHTF9VTlNJR05FRF9JTlQsIERFX05VTEwpOwoKCQkJLy8gcmVzdG9yZSBvcmlnaW5hbCBzdGF0ZQoJCQlnbC5iaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgKmFycmF5QnVmZmVyKTsKCQkJUmVuZGVyQ2FzZTxTYW1wbGVUeXBlPjo6c2V0dXBWZXJ0ZXhBdHRyaWJzKCk7CgkJfQoJCWVsc2UgaWYgKG1fdGFyZ2V0QnVmZmVyID09IFRBUkdFVEJVRkZFUl9JTkRFWCkKCQl7CgkJCS8vIG1ha2UgdGhlIHZlcnRleCBidWZmZXIgcHJlc2VudCBvbiB0aGUgZ3B1CgkJCWdsLmJ1ZmZlckRhdGEoR0xfQVJSQVlfQlVGRkVSLCAoZ2x3OjpHTHNpemVpcHRyKSh2ZXJ0ZXhEYXRhLnNpemUoKSAqIHNpemVvZih0Y3U6OlZlYzQpKSwgJnZlcnRleERhdGFbMF0sIEdMX1NUQVRJQ19EUkFXKTsKCQkJZ2wuZHJhd0FycmF5cyhHTF9UUklBTkdMRVMsIDAsIG51bVZlcnRpY2VzKTsKCQl9CgkJZWxzZQoJCQlERV9BU1NFUlQoZmFsc2UpOwoJfQoJZWxzZQoJCURFX0FTU0VSVChmYWxzZSk7CgoJUmVuZGVyQ2FzZTxTYW1wbGVUeXBlPjo6d2FpdEdMUmVzdWx0cygpOwoJR0xVX0VYUEVDVF9OT19FUlJPUihnbC5nZXRFcnJvcigpLCAicG9zdCBidWZmZXIgcHJlcGFyZSIpOwoKCWdsLmNsZWFyQ29sb3IoMC4wZiwgMC4wZiwgMC4wZiwgMS4wZik7CglnbC5jbGVhcihHTF9DT0xPUl9CVUZGRVJfQklUKTsKCVJlbmRlckNhc2U8U2FtcGxlVHlwZT46OndhaXRHTFJlc3VsdHMoKTsKCgl0Y3U6Ondhcm11cENQVSgpOwoKCS8vIHVwbG9hZAoKCXsKCQlnbHc6OkdMZW51bQkJdGFyZ2V0OwoJCWdsdzo6R0xzaXplaXB0cglzaXplOwoJCWdsdzo6R0xpbnRwdHIJb2Zmc2V0ID0gMDsKCQljb25zdCB2b2lkKgkJc291cmNlOwoKCQlpZiAobV90YXJnZXRCdWZmZXIgPT0gVEFSR0VUQlVGRkVSX1ZFUlRFWCAmJiBtX3VwbG9hZFJhbmdlID09IFVQTE9BRFJBTkdFX0ZVTEwpCgkJewoJCQl0YXJnZXQJPSBHTF9BUlJBWV9CVUZGRVI7CgkJCXNpemUJPSAoZ2x3OjpHTHNpemVpcHRyKSh2ZXJ0ZXhEYXRhLnNpemUoKSAqIHNpemVvZih0Y3U6OlZlYzQpKTsKCQkJc291cmNlCT0gJnZlcnRleERhdGFbMF07CgkJfQoJCWVsc2UgaWYgKG1fdGFyZ2V0QnVmZmVyID09IFRBUkdFVEJVRkZFUl9JTkRFWCAmJiBtX3VwbG9hZFJhbmdlID09IFVQTE9BRFJBTkdFX0ZVTEwpCgkJewoJCQl0YXJnZXQJPSBHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUjsKCQkJc2l6ZQk9IChnbHc6OkdMc2l6ZWlwdHIpKGluZGV4RGF0YS5zaXplKCkgKiBzaXplb2YoZGVVaW50MzIpKTsKCQkJc291cmNlCT0gJmluZGV4RGF0YVswXTsKCQl9CgkJZWxzZSBpZiAobV90YXJnZXRCdWZmZXIgPT0gVEFSR0VUQlVGRkVSX1ZFUlRFWCAmJiBtX3VwbG9hZFJhbmdlID09IFVQTE9BRFJBTkdFX1BBUlRJQUwpCgkJewoJCQlERV9BU1NFUlQobV9idWZmZXJTdGF0ZSA9PSBCVUZGRVJTVEFURV9FWElTVElORyk7CgoJCQl0YXJnZXQJPSBHTF9BUlJBWV9CVUZGRVI7CgkJCXNpemUJPSAoZ2x3OjpHTHNpemVpcHRyKWRlQWxpZ24zMigoaW50KSh2ZXJ0ZXhEYXRhLnNpemUoKSAqIHNpemVvZih0Y3U6OlZlYzQpKSAvIDIsIDQpOwoJCQlvZmZzZXQJPSAoZ2x3OjpHTGludHB0cilkZUFsaWduMzIoKGludClzaXplIC8gMiwgNCk7CgkJCXNvdXJjZQk9IChjb25zdCBkZVVpbnQ4KikmdmVydGV4RGF0YVswXSArIG9mZnNldDsKCQl9CgkJZWxzZSBpZiAobV90YXJnZXRCdWZmZXIgPT0gVEFSR0VUQlVGRkVSX0lOREVYICYmIG1fdXBsb2FkUmFuZ2UgPT0gVVBMT0FEUkFOR0VfUEFSVElBTCkKCQl7CgkJCURFX0FTU0VSVChtX2J1ZmZlclN0YXRlID09IEJVRkZFUlNUQVRFX0VYSVNUSU5HKTsKCgkJCS8vIHVwbG9hZCB0byAyNSUgLSA3NSUgcmFuZ2UKCQkJdGFyZ2V0CT0gR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVI7CgkJCXNpemUJPSAoZ2x3OjpHTHNpemVpcHRyKWRlQWxpZ24zMigoZGVJbnQzMikoaW5kZXhEYXRhLnNpemUoKSAqIHNpemVvZihkZVVpbnQzMikpIC8gMiwgNCk7CgkJCW9mZnNldAk9IChnbHc6OkdMaW50cHRyKWRlQWxpZ24zMigoaW50KXNpemUgLyAyLCA0KTsKCQkJc291cmNlCT0gKGNvbnN0IGRlVWludDgqKSZpbmRleERhdGFbMF0gKyBvZmZzZXQ7CgkJfQoJCWVsc2UKCQl7CgkJCURFX0FTU0VSVChmYWxzZSk7CgkJCXJldHVybjsKCQl9CgoJCXN0YXJ0VGltZSA9IGRlR2V0TWljcm9zZWNvbmRzKCk7CgoJCWlmIChtX3VwbG9hZE1ldGhvZCA9PSBVUExPQURNRVRIT0RfQlVGRkVSX0RBVEEpCgkJCWdsLmJ1ZmZlckRhdGEodGFyZ2V0LCBzaXplLCBzb3VyY2UsIEdMX0RZTkFNSUNfRFJBVyk7CgkJZWxzZSBpZiAobV91cGxvYWRNZXRob2QgPT0gVVBMT0FETUVUSE9EX0JVRkZFUl9TVUJfREFUQSkKCQl7CgkJCS8vIGNyZWF0ZSBidWZmZXIgc3RvcmFnZQoJCQlpZiAobV9idWZmZXJTdGF0ZSA9PSBCVUZGRVJTVEFURV9ORVcpCgkJCQlnbC5idWZmZXJEYXRhKHRhcmdldCwgc2l6ZSwgREVfTlVMTCwgR0xfRFlOQU1JQ19EUkFXKTsKCQkJZ2wuYnVmZmVyU3ViRGF0YSh0YXJnZXQsIG9mZnNldCwgc2l6ZSwgc291cmNlKTsKCQl9CgkJZWxzZSBpZiAobV91cGxvYWRNZXRob2QgPT0gVVBMT0FETUVUSE9EX01BUF9CVUZGRVJfUkFOR0UpCgkJewoJCQl2b2lkKgkJCW1hcFB0cjsKCQkJZ2x3OjpHTGJvb2xlYW4JdW5tYXBTdWNjZXNzZnVsOwoKCQkJLy8gY3JlYXRlIGJ1ZmZlciBzdG9yYWdlCgkJCWlmIChtX2J1ZmZlclN0YXRlID09IEJVRkZFUlNUQVRFX05FVykKCQkJCWdsLmJ1ZmZlckRhdGEodGFyZ2V0LCBzaXplLCBERV9OVUxMLCBHTF9EWU5BTUlDX0RSQVcpOwoKCQkJbWFwUHRyID0gZ2wubWFwQnVmZmVyUmFuZ2UodGFyZ2V0LCBvZmZzZXQsIHNpemUsIEdMX01BUF9XUklURV9CSVQgfCBHTF9NQVBfSU5WQUxJREFURV9SQU5HRV9CSVQgfCBHTF9NQVBfSU5WQUxJREFURV9CVUZGRVJfQklUIHwgR0xfTUFQX1VOU1lOQ0hST05JWkVEX0JJVCk7CgkJCWlmICghbWFwUHRyKQoJCQkJdGhyb3cgdGN1OjpFeGNlcHRpb24oIk1hcEJ1ZmZlclJhbmdlIHJldHVybmVkIE5VTEwiKTsKCgkJCWRlTWVtY3B5KG1hcFB0ciwgc291cmNlLCAoaW50KXNpemUpOwoKCQkJLy8gaWYgdW5tYXBwaW5nIGZhaWxzLCBqdXN0IHRyeSBhZ2FpbiBsYXRlcgoJCQl1bm1hcFN1Y2Nlc3NmdWwgPSBnbC51bm1hcEJ1ZmZlcih0YXJnZXQpOwoJCQlpZiAoIXVubWFwU3VjY2Vzc2Z1bCkKCQkJCXRocm93IFVubWFwRmFpbHVyZUVycm9yKCk7CgkJfQoJCWVsc2UKCQkJREVfQVNTRVJUKGZhbHNlKTsKCgkJZW5kVGltZSA9IGRlR2V0TWljcm9zZWNvbmRzKCk7CgoJCXNhbXBsZS5yZXN1bHQudXBsb2FkZWREYXRhU2l6ZSA9IChpbnQpc2l6ZTsKCQlzYW1wbGUucmVzdWx0LmR1cmF0aW9uLnVwbG9hZER1cmF0aW9uID0gZW5kVGltZSAtIHN0YXJ0VGltZTsKCX0KCgkvLyB1bnJlbGF0ZWQKCWlmIChtX3VucmVsYXRlZEJ1ZmZlclR5cGUgPT0gVU5SRUxBVEVEQlVGRkVSVFlQRV9WRVJURVgpCgl7CgkJY29uc3QgaW50IHVucmVsYXRlZFVwbG9hZFNpemUgPSAoaW50KSh2ZXJ0ZXhEYXRhLnNpemUoKSAqIHNpemVvZih0Y3U6OlZlYzQpKTsKCgkJZ2wuYmluZEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIsICp1bnJlbGF0ZWRCdWZmZXIpOwoJCWdsLmJ1ZmZlckRhdGEoR0xfQVJSQVlfQlVGRkVSLCB1bnJlbGF0ZWRVcGxvYWRTaXplLCAmdmVydGV4RGF0YVswXSwgR0xfU1RBVElDX0RSQVcpOwoJCS8vIEF0dGlidXRlIHBvaW50ZXJzIGFyZSBub3QgbW9kaWZpZWQsIG5vIG5lZWQgcmVzdG9yZSBzdGF0ZQoKCQlzYW1wbGUucmVzdWx0LnVucmVsYXRlZERhdGFTaXplID0gdW5yZWxhdGVkVXBsb2FkU2l6ZTsKCX0KCgkvLyBkcmF3Cgl7CgkJc3RhcnRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCgkJaWYgKG1fZHJhd01ldGhvZCA9PSBEUkFXTUVUSE9EX0RSQVdfQVJSQVlTKQoJCQlnbC5kcmF3QXJyYXlzKEdMX1RSSUFOR0xFUywgMCwgbnVtVmVydGljZXMpOwoJCWVsc2UgaWYgKG1fZHJhd01ldGhvZCA9PSBEUkFXTUVUSE9EX0RSQVdfRUxFTUVOVFMpCgkJCWdsLmRyYXdFbGVtZW50cyhHTF9UUklBTkdMRVMsIG51bVZlcnRpY2VzLCBHTF9VTlNJR05FRF9JTlQsIERFX05VTEwpOwoJCWVsc2UKCQkJREVfQVNTRVJUKGZhbHNlKTsKCgkJZW5kVGltZSA9IGRlR2V0TWljcm9zZWNvbmRzKCk7CgoJCXNhbXBsZS5yZXN1bHQuZHVyYXRpb24ucmVuZGVyRHVyYXRpb24gPSBlbmRUaW1lIC0gc3RhcnRUaW1lOwoJfQoKCS8vIHJlYWQKCXsKCQlzdGFydFRpbWUgPSBkZUdldE1pY3Jvc2Vjb25kcygpOwoJCWdsdTo6cmVhZFBpeGVscyhtX2NvbnRleHQuZ2V0UmVuZGVyQ29udGV4dCgpLCAwLCAwLCByZXN1bHRTdXJmYWNlLmdldEFjY2VzcygpKTsKCQllbmRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCgkJc2FtcGxlLnJlc3VsdC5kdXJhdGlvbi5yZWFkRHVyYXRpb24gPSBlbmRUaW1lIC0gc3RhcnRUaW1lOwoJfQoKCS8vIHNldCByZXN1bHRzCgoJc2FtcGxlLnJlc3VsdC5yZW5kZXJEYXRhU2l6ZSA9IFJlbmRlckNhc2U8U2FtcGxlVHlwZT46OmdldFZlcnRleERhdGFTaXplKCkgKiBzYW1wbGUucmVzdWx0Lm51bVZlcnRpY2VzOwoKCXNhbXBsZS5yZXN1bHQuZHVyYXRpb24ucmVuZGVyUmVhZER1cmF0aW9uID0gc2FtcGxlLnJlc3VsdC5kdXJhdGlvbi5yZW5kZXJEdXJhdGlvbiArIHNhbXBsZS5yZXN1bHQuZHVyYXRpb24ucmVhZER1cmF0aW9uOwoJc2FtcGxlLnJlc3VsdC5kdXJhdGlvbi50b3RhbER1cmF0aW9uID0gc2FtcGxlLnJlc3VsdC5kdXJhdGlvbi51cGxvYWREdXJhdGlvbiArIHNhbXBsZS5yZXN1bHQuZHVyYXRpb24ucmVuZGVyRHVyYXRpb24gKyBzYW1wbGUucmVzdWx0LmR1cmF0aW9uLnJlYWREdXJhdGlvbjsKCXNhbXBsZS5yZXN1bHQuZHVyYXRpb24uZml0UmVzcG9uc2VEdXJhdGlvbiA9IHNhbXBsZS5yZXN1bHQuZHVyYXRpb24ucmVuZGVyUmVhZER1cmF0aW9uOwp9CgpjbGFzcyBCdWZmZXJJblVzZVJlbmRlclRpbWVDYXNlIDogcHVibGljIFJlbmRlckNhc2U8UmVuZGVyVXBsb2FkUmVuZGVyUmVhZER1cmF0aW9uPgp7CnB1YmxpYzoKCWVudW0gTWFwRmxhZ3MKCXsKCQlNQVBGTEFHX05PTkUgPSAwLAoJCU1BUEZMQUdfSU5WQUxJREFURV9CVUZGRVIsCgkJTUFQRkxBR19JTlZBTElEQVRFX1JBTkdFLAoKCQlNQVBGTEFHX0xBU1QKCX07CgllbnVtIFVwbG9hZEJ1ZmZlclRhcmdldAoJewoJCVVQTE9BREJVRkZFUlRBUkdFVF9ESUZGRVJFTlRfQlVGRkVSID0gMCwKCQlVUExPQURCVUZGRVJUQVJHRVRfU0FNRV9CVUZGRVIsCgoJCVVQTE9BREJVRkZFUlRBUkdFVF9MQVNUCgl9OwoJCQkJCQkJCUJ1ZmZlckluVXNlUmVuZGVyVGltZUNhc2UJKENvbnRleHQmCQkJY29udGV4dCwKCQkJCQkJCQkJCQkJCQkJIGNvbnN0IGNoYXIqCQluYW1lLAoJCQkJCQkJCQkJCQkJCQkgY29uc3QgY2hhcioJCWRlc2NyaXB0aW9uLAoJCQkJCQkJCQkJCQkJCQkgRHJhd01ldGhvZAkJCW1ldGhvZCwKCQkJCQkJCQkJCQkJCQkJIE1hcEZsYWdzCQkJbWFwRmxhZ3MsCgkJCQkJCQkJCQkJCQkJCSBUYXJnZXRCdWZmZXIJCXRhcmdldEJ1ZmZlciwKCQkJCQkJCQkJCQkJCQkJIFVwbG9hZE1ldGhvZAkJdXBsb2FkTWV0aG9kLAoJCQkJCQkJCQkJCQkJCQkgVXBsb2FkUmFuZ2UJCXVwbG9hZFJhbmdlLAoJCQkJCQkJCQkJCQkJCQkgVXBsb2FkQnVmZmVyVGFyZ2V0CXVwbG9hZFRhcmdldCk7Cgpwcml2YXRlOgoJdm9pZAkJCQkJCWluaXQJCQkJCQkodm9pZCk7Cgl2b2lkCQkJCQkJcnVuU2FtcGxlCQkJCQkoU2FtcGxlUmVzdWx0JiBzYW1wbGUpOwoKCWNvbnN0IFRhcmdldEJ1ZmZlcgkJCW1fdGFyZ2V0QnVmZmVyOwoJY29uc3QgVXBsb2FkTWV0aG9kCQkJbV91cGxvYWRNZXRob2Q7Cgljb25zdCBVcGxvYWRSYW5nZQkJCW1fdXBsb2FkUmFuZ2U7Cgljb25zdCBNYXBGbGFncwkJCQltX21hcEZsYWdzOwoJY29uc3QgVXBsb2FkQnVmZmVyVGFyZ2V0CW1fdXBsb2FkQnVmZmVyVGFyZ2V0Owp9OwoKQnVmZmVySW5Vc2VSZW5kZXJUaW1lQ2FzZTo6QnVmZmVySW5Vc2VSZW5kZXJUaW1lQ2FzZSAoQ29udGV4dCYJCQkJY29udGV4dCwKCQkJCQkJCQkJCQkJCSAgY29uc3QgY2hhcioJCQluYW1lLAoJCQkJCQkJCQkJCQkJICBjb25zdCBjaGFyKgkJCWRlc2NyaXB0aW9uLAoJCQkJCQkJCQkJCQkJICBEcmF3TWV0aG9kCQkJbWV0aG9kLAoJCQkJCQkJCQkJCQkJICBNYXBGbGFncwkJCQltYXBGbGFncywKCQkJCQkJCQkJCQkJCSAgVGFyZ2V0QnVmZmVyCQkJdGFyZ2V0QnVmZmVyLAoJCQkJCQkJCQkJCQkJICBVcGxvYWRNZXRob2QJCQl1cGxvYWRNZXRob2QsCgkJCQkJCQkJCQkJCQkgIFVwbG9hZFJhbmdlCQkJdXBsb2FkUmFuZ2UsCgkJCQkJCQkJCQkJCQkgIFVwbG9hZEJ1ZmZlclRhcmdldAl1cGxvYWRUYXJnZXQpCgk6IFJlbmRlckNhc2U8UmVuZGVyVXBsb2FkUmVuZGVyUmVhZER1cmF0aW9uPgkoY29udGV4dCwgbmFtZSwgZGVzY3JpcHRpb24sIG1ldGhvZCkKCSwgbV90YXJnZXRCdWZmZXIJCQkJCQkJCSh0YXJnZXRCdWZmZXIpCgksIG1fdXBsb2FkTWV0aG9kCQkJCQkJCQkodXBsb2FkTWV0aG9kKQoJLCBtX3VwbG9hZFJhbmdlCQkJCQkJCQkJKHVwbG9hZFJhbmdlKQoJLCBtX21hcEZsYWdzCQkJCQkJCQkJKG1hcEZsYWdzKQoJLCBtX3VwbG9hZEJ1ZmZlclRhcmdldAkJCQkJCQkodXBsb2FkVGFyZ2V0KQp7CglERV9BU1NFUlQobV90YXJnZXRCdWZmZXIgPCBUQVJHRVRCVUZGRVJfTEFTVCk7CglERV9BU1NFUlQobV91cGxvYWRNZXRob2QgPCBVUExPQURNRVRIT0RfTEFTVCk7CglERV9BU1NFUlQobV91cGxvYWRSYW5nZSA8IFVQTE9BRFJBTkdFX0xBU1QpOwoJREVfQVNTRVJUKG1fbWFwRmxhZ3MgPCBNQVBGTEFHX0xBU1QpOwoJREVfQVNTRVJUKG1fdXBsb2FkQnVmZmVyVGFyZ2V0IDwgVVBMT0FEQlVGRkVSVEFSR0VUX0xBU1QpOwp9Cgp2b2lkIEJ1ZmZlckluVXNlUmVuZGVyVGltZUNhc2U6OmluaXQgKHZvaWQpCnsKCVJlbmRlckNhc2U8UmVuZGVyVXBsb2FkUmVuZGVyUmVhZER1cmF0aW9uPjo6aW5pdCgpOwoKCS8vIGxvZwoJewoJCWNvbnN0IGNoYXIqIGNvbnN0CXRhcmdldEZ1bmN0aW9uTmFtZQkJPSAobV9kcmF3TWV0aG9kID09IERSQVdNRVRIT0RfRFJBV19BUlJBWVMpID8gKCJkcmF3QXJyYXlzIikgOiAoImRyYXdFbGVtZW50cyIpOwoJCWNvbnN0IGNoYXIqIGNvbnN0CXVwbG9hZEZ1bmN0aW9uTmFtZQkJPSAobV91cGxvYWRNZXRob2QgPT0gVVBMT0FETUVUSE9EX0JVRkZFUl9EQVRBKSA/ICgiYnVmZmVyRGF0YSIpIDogKG1fdXBsb2FkTWV0aG9kID09IFVQTE9BRE1FVEhPRF9CVUZGRVJfU1VCX0RBVEEpID8gKCJidWZmZXJTdWJEYXRhIikgOiAoIm1hcEJ1ZmZlclJhbmdlIik7CgkJY29uc3QgYm9vbAkJCWlzUmVmZXJlbmNlQ2FzZQkJCT0gKG1fdXBsb2FkQnVmZmVyVGFyZ2V0ID09IFVQTE9BREJVRkZFUlRBUkdFVF9ESUZGRVJFTlRfQlVGRkVSKTsKCQl0Y3U6Ok1lc3NhZ2VCdWlsZGVyCW1lc3NhZ2UJCQkJCSgmbV90ZXN0Q3R4LmdldExvZygpKTsKCgkJbWVzc2FnZQk8PCAiTWVhc3VyaW5nIHRoZSB0aW1lIHVzZWQgaW4gIiA8PCB0YXJnZXRGdW5jdGlvbk5hbWUgPDwgIiBjYWxsLCBhIGJ1ZmZlciB1cGxvYWQsICIKCQkJCTw8IHRhcmdldEZ1bmN0aW9uTmFtZSA8PCAiIGNhbGwgdXNpbmcgdGhlIHVwbG9hZGVkIGJ1ZmZlciBhbmQgcmVhZFBpeGVscyBjYWxsIHdpdGggZGlmZmVyZW50IHVwbG9hZCBzaXplcy5cbiI7CgoJCWlmIChpc1JlZmVyZW5jZUNhc2UpCgkJCW1lc3NhZ2UgPDwgIlJlbmRlcmluZzpcbiIKCQkJCQk8PCAiICAgIGJlZm9yZSB0ZXN0OiBjcmVhdGUgYW5kIHVzZSBidWZmZXJzIEIgYW5kIENcbiIKCQkJCQk8PCAiICAgIGZpcnN0IGRyYXc6IHJlbmRlciB1c2luZyBidWZmZXIgQlxuIgoJCQkJCTw8ICgobV91cGxvYWRSYW5nZSA9PSBVUExPQURSQU5HRV9GVUxMKQkJPyAoIiAgICB1cGxvYWQ6IHJlc3BlY2lmeSBidWZmZXIgQyBjb250ZW50c1xuIikJOgoJCQkJCQkobV91cGxvYWRSYW5nZSA9PSBVUExPQURSQU5HRV9QQVJUSUFMKQk/ICgiICAgIHVwbG9hZDogbW9kaWZ5IGJ1ZmZlciBDIGNvbnRlbnRzXG4iKQk6CgkJCQkJCSgoY29uc3QgY2hhciopREVfTlVMTCkpCgkJCQkJPDwgIiAgICBzZWNvbmQgZHJhdzogcmVuZGVyIHVzaW5nIGJ1ZmZlciBDXG4iCgkJCQkJPDwgIiAgICByZWFkOiByZWFkUGl4ZWxzXG4iOwoJCWVsc2UKCQkJbWVzc2FnZSA8PCAiUmVuZGVyaW5nOlxuIgoJCQkJCTw8ICIgICAgYmVmb3JlIHRlc3Q6IGNyZWF0ZSBhbmQgdXNlIGJ1ZmZlciBCXG4iCgkJCQkJPDwgIiAgICBmaXJzdCBkcmF3OiByZW5kZXIgdXNpbmcgYnVmZmVyIEJcbiIKCQkJCQk8PCAoKG1fdXBsb2FkUmFuZ2UgPT0gVVBMT0FEUkFOR0VfRlVMTCkJCT8gKCIgICAgdXBsb2FkOiByZXNwZWNpZnkgYnVmZmVyIEIgY29udGVudHNcbiIpCToKCQkJCQkJKG1fdXBsb2FkUmFuZ2UgPT0gVVBMT0FEUkFOR0VfUEFSVElBTCkJPyAoIiAgICB1cGxvYWQ6IG1vZGlmeSBidWZmZXIgQiBjb250ZW50c1xuIikJOgoJCQkJCQkoKGNvbnN0IGNoYXIqKURFX05VTEwpKQoJCQkJCTw8ICIgICAgc2Vjb25kIGRyYXc6IHJlbmRlciB1c2luZyBidWZmZXIgQlxuIgoJCQkJCTw8ICIgICAgcmVhZDogcmVhZFBpeGVsc1xuIjsKCgkJbWVzc2FnZQk8PCAiVXBsb2FkaW5nIHVzaW5nICIgPDwgdXBsb2FkRnVuY3Rpb25OYW1lCgkJCQkJPDwgKChtX21hcEZsYWdzID09IE1BUEZMQUdfSU5WQUxJREFURV9SQU5HRSkJPyAoIiwgZmxhZ3MgPSBNQVBfV1JJVEVfQklUIHwgTUFQX0lOVkFMSURBVEVfUkFOR0VfQklUIikJOgoJCQkJCQkobV9tYXBGbGFncyA9PSBNQVBGTEFHX0lOVkFMSURBVEVfQlVGRkVSKQk/ICgiLCBmbGFncyA9IE1BUF9XUklURV9CSVQgfCBNQVBfSU5WQUxJREFURV9CVUZGRVJfQklUIikJOgoJCQkJCQkobV9tYXBGbGFncyA9PSBNQVBGTEFHX05PTkUpCQkJCT8gKCIiKQkJCQkJCQkJCQkJCQkJOgoJCQkJCQkoKGNvbnN0IGNoYXIqKURFX05VTEwpKQoJCQkJCTw8ICJcbiIKCQkJCTw8IGdldE51bVNhbXBsZXMoKSA8PCAiIHRlc3Qgc2FtcGxlcy4gU2FtcGxlIG9yZGVyIGlzIHJhbmRvbWl6ZWQuXG4iCgkJCQk8PCAiQWxsIHNhbXBsZXMgYXQgZXZlbiBwb3NpdGlvbnMgKGZpcnN0ID0gMCkgYXJlIHRlc3RlZCBiZWZvcmUgc2FtcGxlcyBhdCBvZGQgcG9zaXRpb25zLlxuIgoJCQkJPDwgIldvcmtsb2FkIHNpemVzIGFyZSBpbiB0aGUgcmFuZ2UgWyIKCQkJCQk8PCBnZXRNaW5Xb3JrbG9hZFNpemUoKSA8PCAiLCAgIgoJCQkJCTw8IGdldE1heFdvcmtsb2FkU2l6ZSgpIDw8ICJdIHZlcnRpY2VzICIKCQkJCQk8PCAiKFsiCgkJCQkJPDwgZ2V0SHVtYW5SZWFkYWJsZUJ5dGVTaXplKGdldE1pbldvcmtsb2FkRGF0YVNpemUoKSkgPDwgIiwiCgkJCQkJPDwgZ2V0SHVtYW5SZWFkYWJsZUJ5dGVTaXplKGdldE1heFdvcmtsb2FkRGF0YVNpemUoKSkgPDwgIl0gdG8gYmUgcHJvY2Vzc2VkKS5cbiIKCQkJCTw8ICJUZXN0IHJlc3VsdCBpcyB0aGUgYXBwcm94aW1hdGVkIHByb2Nlc3NpbmcgcmF0ZSBpbiBNaUIgLyBzIG9mIHRoZSBzZWNvbmQgZHJhdyBjYWxsIGFuZCB0aGUgcmVhZFBpeGVscyBjYWxsLlxuIjsKCgkJaWYgKGlzUmVmZXJlbmNlQ2FzZSkKCQkJbWVzc2FnZQk8PCAiTm90ZSEgVGVzdCByZXN1bHQgc2hvdWxkIG9ubHkgYmUgdXNlZCBhcyBhIGJhc2VsaW5lIHJlZmVyZW5jZSByZXN1bHQgZm9yIGJ1ZmZlci5yZW5kZXJfYWZ0ZXJfdXBsb2FkLmRyYXdfbW9kaWZ5X2RyYXcgdGVzdCBncm91cCByZXN1bHRzLiI7CgkJZWxzZQoJCQltZXNzYWdlCTw8ICJOb3RlISBUZXN0IHJlc3VsdCBtYXkgbm90IGJlIHVzZWZ1bCBhcyBpcyBidXQgaW5zdGVhZCBzaG91bGQgYmUgY29tcGFyZWQgYWdhaW5zdCB0aGUgYnVmZmVyLnJlbmRlcl9hZnRlcl91cGxvYWQucmVmZXJlbmNlLmRyYXdfdXBsb2FkX2RyYXcgZ3JvdXAgcmVzdWx0cy5cbiI7CgoJCW1lc3NhZ2UgPDwgdGN1OjpUZXN0TG9nOjpFbmRNZXNzYWdlOwoJfQp9Cgp2b2lkIEJ1ZmZlckluVXNlUmVuZGVyVGltZUNhc2U6OnJ1blNhbXBsZSAoU2FtcGxlUmVzdWx0JiBzYW1wbGUpCnsKCWNvbnN0IGdsdzo6RnVuY3Rpb25zJglnbAkJCQkJCT0gbV9jb250ZXh0LmdldFJlbmRlckNvbnRleHQoKS5nZXRGdW5jdGlvbnMoKTsKCWNvbnN0IGdsdTo6QnVmZmVyCQlhcnJheUJ1ZmZlcgkJCQkobV9jb250ZXh0LmdldFJlbmRlckNvbnRleHQoKSk7Cgljb25zdCBnbHU6OkJ1ZmZlcgkJaW5kZXhCdWZmZXIJCQkJKG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCkpOwoJY29uc3QgZ2x1OjpCdWZmZXIJCWFsdGVybmF0aXZlVXBsb2FkQnVmZmVyCShtX2NvbnRleHQuZ2V0UmVuZGVyQ29udGV4dCgpKTsKCWNvbnN0IGludAkJCQludW1WZXJ0aWNlcwkJCQk9IGdldExheWVyZWRHcmlkTnVtVmVydGljZXMoc2FtcGxlLnNjZW5lKTsKCXRjdTo6U3VyZmFjZQkJCXJlc3VsdFN1cmZhY2UJCQkoUkVOREVSX0FSRUFfU0laRSwgUkVOREVSX0FSRUFfU0laRSk7CglkZVVpbnQ2NAkJCQlzdGFydFRpbWU7CglkZVVpbnQ2NAkJCQllbmRUaW1lOwoJc3RkOjp2ZWN0b3I8dGN1OjpWZWM0Pgl2ZXJ0ZXhEYXRhOwoJc3RkOjp2ZWN0b3I8ZGVVaW50MzI+CWluZGV4RGF0YTsKCgkvLyBjcmVhdGUgZGF0YQoKCWdlbmVyYXRlTGF5ZXJlZEdyaWRWZXJ0ZXhBdHRyaWJEYXRhNEM0Vih2ZXJ0ZXhEYXRhLCBzYW1wbGUuc2NlbmUpOwoJaWYgKG1fZHJhd01ldGhvZCA9PSBEUkFXTUVUSE9EX0RSQVdfRUxFTUVOVFMpCgkJZ2VuZXJhdGVMYXllcmVkR3JpZEluZGV4RGF0YShpbmRleERhdGEsIHNhbXBsZS5zY2VuZSk7CgoJLy8gbWFrZSBidWZmZXJzIHVzZWQKCglnbC5iaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgKmFycmF5QnVmZmVyKTsKCWdsLmJpbmRCdWZmZXIoR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVIsICppbmRleEJ1ZmZlcik7CglzZXR1cFZlcnRleEF0dHJpYnMoKTsKCglpZiAobV9kcmF3TWV0aG9kID09IERSQVdNRVRIT0RfRFJBV19BUlJBWVMpCgl7CgkJZ2wuYnVmZmVyRGF0YShHTF9BUlJBWV9CVUZGRVIsIChnbHc6OkdMc2l6ZWlwdHIpKHZlcnRleERhdGEuc2l6ZSgpICogc2l6ZW9mKHRjdTo6VmVjNCkpLCAmdmVydGV4RGF0YVswXSwgR0xfU1RSRUFNX0RSQVcpOwoJCWdsLmRyYXdBcnJheXMoR0xfVFJJQU5HTEVTLCAwLCBudW1WZXJ0aWNlcyk7Cgl9CgllbHNlIGlmIChtX2RyYXdNZXRob2QgPT0gRFJBV01FVEhPRF9EUkFXX0VMRU1FTlRTKQoJewoJCWdsLmJ1ZmZlckRhdGEoR0xfQVJSQVlfQlVGRkVSLCAoZ2x3OjpHTHNpemVpcHRyKSh2ZXJ0ZXhEYXRhLnNpemUoKSAqIHNpemVvZih0Y3U6OlZlYzQpKSwgJnZlcnRleERhdGFbMF0sIEdMX1NUUkVBTV9EUkFXKTsKCQlnbC5idWZmZXJEYXRhKEdMX0VMRU1FTlRfQVJSQVlfQlVGRkVSLCAoZ2x3OjpHTHNpemVpcHRyKShpbmRleERhdGEuc2l6ZSgpICogc2l6ZW9mKGRlVWludDMyKSksICZpbmRleERhdGFbMF0sIEdMX1NUUkVBTV9EUkFXKTsKCQlnbC5kcmF3RWxlbWVudHMoR0xfVFJJQU5HTEVTLCBudW1WZXJ0aWNlcywgR0xfVU5TSUdORURfSU5ULCBERV9OVUxMKTsKCX0KCWVsc2UKCQlERV9BU1NFUlQoZmFsc2UpOwoKCS8vIGFub3RoZXIgcGFpciBvZiBidWZmZXJzIGZvciByZWZlcmVuY2UgY2FzZQoJaWYgKG1fdXBsb2FkQnVmZmVyVGFyZ2V0ID09IFVQTE9BREJVRkZFUlRBUkdFVF9ESUZGRVJFTlRfQlVGRkVSKQoJewoJCWlmIChtX3RhcmdldEJ1ZmZlciA9PSBUQVJHRVRCVUZGRVJfVkVSVEVYKQoJCXsKCQkJZ2wuYmluZEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIsICphbHRlcm5hdGl2ZVVwbG9hZEJ1ZmZlcik7CgkJCWdsLmJ1ZmZlckRhdGEoR0xfQVJSQVlfQlVGRkVSLCAoZ2x3OjpHTHNpemVpcHRyKSh2ZXJ0ZXhEYXRhLnNpemUoKSAqIHNpemVvZih0Y3U6OlZlYzQpKSwgJnZlcnRleERhdGFbMF0sIEdMX1NUUkVBTV9EUkFXKTsKCgkJCXNldHVwVmVydGV4QXR0cmlicygpOwoJCQlnbC5kcmF3QXJyYXlzKEdMX1RSSUFOR0xFUywgMCwgbnVtVmVydGljZXMpOwoJCX0KCQllbHNlIGlmIChtX3RhcmdldEJ1ZmZlciA9PSBUQVJHRVRCVUZGRVJfSU5ERVgpCgkJewoJCQlnbC5iaW5kQnVmZmVyKEdMX0VMRU1FTlRfQVJSQVlfQlVGRkVSLCAqYWx0ZXJuYXRpdmVVcGxvYWRCdWZmZXIpOwoJCQlnbC5idWZmZXJEYXRhKEdMX0VMRU1FTlRfQVJSQVlfQlVGRkVSLCAoZ2x3OjpHTHNpemVpcHRyKShpbmRleERhdGEuc2l6ZSgpICogc2l6ZW9mKGRlVWludDMyKSksICZpbmRleERhdGFbMF0sIEdMX1NUUkVBTV9EUkFXKTsKCQkJZ2wuZHJhd0VsZW1lbnRzKEdMX1RSSUFOR0xFUywgbnVtVmVydGljZXMsIEdMX1VOU0lHTkVEX0lOVCwgREVfTlVMTCk7CgkJfQoJCWVsc2UKCQkJREVfQVNTRVJUKGZhbHNlKTsKCgkJLy8gcmVzdG9yZSBzdGF0ZQoJCWdsLmJpbmRCdWZmZXIoR0xfQVJSQVlfQlVGRkVSLCAqYXJyYXlCdWZmZXIpOwoJCWdsLmJpbmRCdWZmZXIoR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVIsICppbmRleEJ1ZmZlcik7CgkJc2V0dXBWZXJ0ZXhBdHRyaWJzKCk7Cgl9CgoJd2FpdEdMUmVzdWx0cygpOwoJR0xVX0VYUEVDVF9OT19FUlJPUihnbC5nZXRFcnJvcigpLCAicG9zdCBidWZmZXIgcHJlcGFyZSIpOwoKCWdsLmNsZWFyQ29sb3IoMC4wZiwgMC4wZiwgMC4wZiwgMS4wZik7CglnbC5jbGVhcihHTF9DT0xPUl9CVUZGRVJfQklUKTsKCXdhaXRHTFJlc3VsdHMoKTsKCgl0Y3U6Ondhcm11cENQVSgpOwoKCS8vIGZpcnN0IGRyYXcKCXsKCQlzdGFydFRpbWUgPSBkZUdldE1pY3Jvc2Vjb25kcygpOwoKCQlpZiAobV9kcmF3TWV0aG9kID09IERSQVdNRVRIT0RfRFJBV19BUlJBWVMpCgkJCWdsLmRyYXdBcnJheXMoR0xfVFJJQU5HTEVTLCAwLCBudW1WZXJ0aWNlcyk7CgkJZWxzZSBpZiAobV9kcmF3TWV0aG9kID09IERSQVdNRVRIT0RfRFJBV19FTEVNRU5UUykKCQkJZ2wuZHJhd0VsZW1lbnRzKEdMX1RSSUFOR0xFUywgbnVtVmVydGljZXMsIEdMX1VOU0lHTkVEX0lOVCwgREVfTlVMTCk7CgkJZWxzZQoJCQlERV9BU1NFUlQoZmFsc2UpOwoKCQllbmRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCgkJc2FtcGxlLnJlc3VsdC5kdXJhdGlvbi5maXJzdFJlbmRlckR1cmF0aW9uID0gZW5kVGltZSAtIHN0YXJ0VGltZTsKCX0KCgkvLyB1cGxvYWQKCXsKCQlnbHc6OkdMZW51bQkJdGFyZ2V0OwoJCWdsdzo6R0xzaXplaXB0cglzaXplOwoJCWdsdzo6R0xpbnRwdHIJb2Zmc2V0ID0gMDsKCQljb25zdCB2b2lkKgkJc291cmNlOwoKCQlpZiAobV90YXJnZXRCdWZmZXIgPT0gVEFSR0VUQlVGRkVSX1ZFUlRFWCAmJiBtX3VwbG9hZFJhbmdlID09IFVQTE9BRFJBTkdFX0ZVTEwpCgkJewoJCQl0YXJnZXQJPSBHTF9BUlJBWV9CVUZGRVI7CgkJCXNpemUJPSAoZ2x3OjpHTHNpemVpcHRyKSh2ZXJ0ZXhEYXRhLnNpemUoKSAqIHNpemVvZih0Y3U6OlZlYzQpKTsKCQkJc291cmNlCT0gJnZlcnRleERhdGFbMF07CgkJfQoJCWVsc2UgaWYgKG1fdGFyZ2V0QnVmZmVyID09IFRBUkdFVEJVRkZFUl9JTkRFWCAmJiBtX3VwbG9hZFJhbmdlID09IFVQTE9BRFJBTkdFX0ZVTEwpCgkJewoJCQl0YXJnZXQJPSBHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUjsKCQkJc2l6ZQk9IChnbHc6OkdMc2l6ZWlwdHIpKGluZGV4RGF0YS5zaXplKCkgKiBzaXplb2YoZGVVaW50MzIpKTsKCQkJc291cmNlCT0gJmluZGV4RGF0YVswXTsKCQl9CgkJZWxzZSBpZiAobV90YXJnZXRCdWZmZXIgPT0gVEFSR0VUQlVGRkVSX1ZFUlRFWCAmJiBtX3VwbG9hZFJhbmdlID09IFVQTE9BRFJBTkdFX1BBUlRJQUwpCgkJewoJCQl0YXJnZXQJPSBHTF9BUlJBWV9CVUZGRVI7CgkJCXNpemUJPSAoZ2x3OjpHTHNpemVpcHRyKWRlQWxpZ24zMigoaW50KSh2ZXJ0ZXhEYXRhLnNpemUoKSAqIHNpemVvZih0Y3U6OlZlYzQpKSAvIDIsIDQpOwoJCQlvZmZzZXQJPSAoZ2x3OjpHTGludHB0cilkZUFsaWduMzIoKGludClzaXplIC8gMiwgNCk7CgkJCXNvdXJjZQk9IChjb25zdCBkZVVpbnQ4KikmdmVydGV4RGF0YVswXSArIG9mZnNldDsKCQl9CgkJZWxzZSBpZiAobV90YXJnZXRCdWZmZXIgPT0gVEFSR0VUQlVGRkVSX0lOREVYICYmIG1fdXBsb2FkUmFuZ2UgPT0gVVBMT0FEUkFOR0VfUEFSVElBTCkKCQl7CgkJCS8vIHVwbG9hZCB0byAyNSUgLSA3NSUgcmFuZ2UKCQkJdGFyZ2V0CT0gR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVI7CgkJCXNpemUJPSAoZ2x3OjpHTHNpemVpcHRyKWRlQWxpZ24zMigoZGVJbnQzMikoaW5kZXhEYXRhLnNpemUoKSAqIHNpemVvZihkZVVpbnQzMikpIC8gMiwgNCk7CgkJCW9mZnNldAk9IChnbHc6OkdMaW50cHRyKWRlQWxpZ24zMigoaW50KXNpemUgLyAyLCA0KTsKCQkJc291cmNlCT0gKGNvbnN0IGRlVWludDgqKSZpbmRleERhdGFbMF0gKyBvZmZzZXQ7CgkJfQoJCWVsc2UKCQl7CgkJCURFX0FTU0VSVChmYWxzZSk7CgkJCXJldHVybjsKCQl9CgoJCS8vIHJlZmVyZW5jZSBjYXNlPyBkb24ndCBtb2RpZnkgdGhlIGJ1ZmZlciBpbiB1c2UKCQlpZiAobV91cGxvYWRCdWZmZXJUYXJnZXQgPT0gVVBMT0FEQlVGRkVSVEFSR0VUX0RJRkZFUkVOVF9CVUZGRVIpCgkJCWdsLmJpbmRCdWZmZXIodGFyZ2V0LCAqYWx0ZXJuYXRpdmVVcGxvYWRCdWZmZXIpOwoKCQlzdGFydFRpbWUgPSBkZUdldE1pY3Jvc2Vjb25kcygpOwoKCQlpZiAobV91cGxvYWRNZXRob2QgPT0gVVBMT0FETUVUSE9EX0JVRkZFUl9EQVRBKQoJCQlnbC5idWZmZXJEYXRhKHRhcmdldCwgc2l6ZSwgc291cmNlLCBHTF9TVFJFQU1fRFJBVyk7CgkJZWxzZSBpZiAobV91cGxvYWRNZXRob2QgPT0gVVBMT0FETUVUSE9EX0JVRkZFUl9TVUJfREFUQSkKCQkJZ2wuYnVmZmVyU3ViRGF0YSh0YXJnZXQsIG9mZnNldCwgc2l6ZSwgc291cmNlKTsKCQllbHNlIGlmIChtX3VwbG9hZE1ldGhvZCA9PSBVUExPQURNRVRIT0RfTUFQX0JVRkZFUl9SQU5HRSkKCQl7CgkJCWNvbnN0IGludAkJbWFwRmxhZ3MJPSAobV9tYXBGbGFncyA9PSBNQVBGTEFHX0lOVkFMSURBVEVfQlVGRkVSKQk/IChHTF9NQVBfV1JJVEVfQklUIHwgR0xfTUFQX0lOVkFMSURBVEVfQlVGRkVSX0JJVCkJOgoJCQkJCQkJCQkJICAobV9tYXBGbGFncyA9PSBNQVBGTEFHX0lOVkFMSURBVEVfUkFOR0UpCT8gKEdMX01BUF9XUklURV9CSVQgfCBHTF9NQVBfSU5WQUxJREFURV9SQU5HRV9CSVQpCToKCQkJCQkJCQkJCSAgKC0xKTsKCQkJdm9pZCoJCQltYXBQdHI7CgkJCWdsdzo6R0xib29sZWFuCXVubWFwU3VjY2Vzc2Z1bDsKCgkJCW1hcFB0ciA9IGdsLm1hcEJ1ZmZlclJhbmdlKHRhcmdldCwgb2Zmc2V0LCBzaXplLCBtYXBGbGFncyk7CgkJCWlmICghbWFwUHRyKQoJCQkJdGhyb3cgdGN1OjpFeGNlcHRpb24oIk1hcEJ1ZmZlclJhbmdlIHJldHVybmVkIE5VTEwiKTsKCgkJCWRlTWVtY3B5KG1hcFB0ciwgc291cmNlLCAoaW50KXNpemUpOwoKCQkJLy8gaWYgdW5tYXBwaW5nIGZhaWxzLCBqdXN0IHRyeSBhZ2FpbiBsYXRlcgoJCQl1bm1hcFN1Y2Nlc3NmdWwgPSBnbC51bm1hcEJ1ZmZlcih0YXJnZXQpOwoJCQlpZiAoIXVubWFwU3VjY2Vzc2Z1bCkKCQkJCXRocm93IFVubWFwRmFpbHVyZUVycm9yKCk7CgkJfQoJCWVsc2UKCQkJREVfQVNTRVJUKGZhbHNlKTsKCgkJZW5kVGltZSA9IGRlR2V0TWljcm9zZWNvbmRzKCk7CgoJCXNhbXBsZS5yZXN1bHQudXBsb2FkZWREYXRhU2l6ZSA9IChpbnQpc2l6ZTsKCQlzYW1wbGUucmVzdWx0LmR1cmF0aW9uLnVwbG9hZER1cmF0aW9uID0gZW5kVGltZSAtIHN0YXJ0VGltZTsKCX0KCgkvLyBzZWNvbmQgZHJhdwoJewoJCS8vIFNvdXJjZSB2ZXJ0ZXggZGF0YSBmcm9tIGFsdGVybmF0aXZlIGJ1ZmZlciBpbiByZWZlcm5jZSBjYXNlCgkJaWYgKG1fdXBsb2FkQnVmZmVyVGFyZ2V0ID09IFVQTE9BREJVRkZFUlRBUkdFVF9ESUZGRVJFTlRfQlVGRkVSICYmIG1fdGFyZ2V0QnVmZmVyID09IFRBUkdFVEJVRkZFUl9WRVJURVgpCgkJCXNldHVwVmVydGV4QXR0cmlicygpOwoKCQlzdGFydFRpbWUgPSBkZUdldE1pY3Jvc2Vjb25kcygpOwoKCQlpZiAobV9kcmF3TWV0aG9kID09IERSQVdNRVRIT0RfRFJBV19BUlJBWVMpCgkJCWdsLmRyYXdBcnJheXMoR0xfVFJJQU5HTEVTLCAwLCBudW1WZXJ0aWNlcyk7CgkJZWxzZSBpZiAobV9kcmF3TWV0aG9kID09IERSQVdNRVRIT0RfRFJBV19FTEVNRU5UUykKCQkJZ2wuZHJhd0VsZW1lbnRzKEdMX1RSSUFOR0xFUywgbnVtVmVydGljZXMsIEdMX1VOU0lHTkVEX0lOVCwgREVfTlVMTCk7CgkJZWxzZQoJCQlERV9BU1NFUlQoZmFsc2UpOwoKCQllbmRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCgkJc2FtcGxlLnJlc3VsdC5kdXJhdGlvbi5zZWNvbmRSZW5kZXJEdXJhdGlvbiA9IGVuZFRpbWUgLSBzdGFydFRpbWU7Cgl9CgoJLy8gcmVhZAoJewoJCXN0YXJ0VGltZSA9IGRlR2V0TWljcm9zZWNvbmRzKCk7CgkJZ2x1OjpyZWFkUGl4ZWxzKG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCksIDAsIDAsIHJlc3VsdFN1cmZhY2UuZ2V0QWNjZXNzKCkpOwoJCWVuZFRpbWUgPSBkZUdldE1pY3Jvc2Vjb25kcygpOwoKCQlzYW1wbGUucmVzdWx0LmR1cmF0aW9uLnJlYWREdXJhdGlvbiA9IGVuZFRpbWUgLSBzdGFydFRpbWU7Cgl9CgoJLy8gc2V0IHJlc3VsdHMKCglzYW1wbGUucmVzdWx0LnJlbmRlckRhdGFTaXplID0gZ2V0VmVydGV4RGF0YVNpemUoKSAqIHNhbXBsZS5yZXN1bHQubnVtVmVydGljZXM7CgoJc2FtcGxlLnJlc3VsdC5kdXJhdGlvbi5yZW5kZXJSZWFkRHVyYXRpb24JPSBzYW1wbGUucmVzdWx0LmR1cmF0aW9uLnNlY29uZFJlbmRlckR1cmF0aW9uICsgc2FtcGxlLnJlc3VsdC5kdXJhdGlvbi5yZWFkRHVyYXRpb247CglzYW1wbGUucmVzdWx0LmR1cmF0aW9uLnRvdGFsRHVyYXRpb24JCT0gc2FtcGxlLnJlc3VsdC5kdXJhdGlvbi5maXJzdFJlbmRlckR1cmF0aW9uICsKCQkJCQkJCQkJCQkJICBzYW1wbGUucmVzdWx0LmR1cmF0aW9uLnVwbG9hZER1cmF0aW9uICsKCQkJCQkJCQkJCQkJICBzYW1wbGUucmVzdWx0LmR1cmF0aW9uLnNlY29uZFJlbmRlckR1cmF0aW9uICsKCQkJCQkJCQkJCQkJICBzYW1wbGUucmVzdWx0LmR1cmF0aW9uLnJlYWREdXJhdGlvbjsKCXNhbXBsZS5yZXN1bHQuZHVyYXRpb24uZml0UmVzcG9uc2VEdXJhdGlvbgk9IHNhbXBsZS5yZXN1bHQuZHVyYXRpb24ucmVuZGVyUmVhZER1cmF0aW9uOwp9CgpjbGFzcyBVcGxvYWRXYWl0RHJhd0Nhc2UgOiBwdWJsaWMgUmVuZGVyUGVyZm9ybWFuY2VUZXN0QmFzZQp7CnB1YmxpYzoKCXN0cnVjdCBTYW1wbGUKCXsKCQlpbnQJCQludW1GcmFtZXM7CgkJZGVVaW50NjQJdXBsb2FkQ2FsbEVuZFRpbWU7Cgl9OwoJc3RydWN0IFJlc3VsdAoJewoJCWRlVWludDY0CXVwbG9hZER1cmF0aW9uOwoJCWRlVWludDY0CXJlbmRlckR1cmF0aW9uOwoJCWRlVWludDY0CXJlYWREdXJhdGlvbjsKCQlkZVVpbnQ2NAlyZW5kZXJSZWFkRHVyYXRpb247CgoJCWRlVWludDY0CXRpbWVCZWZvcmVVc2U7Cgl9OwoKCQkJCQkJCVVwbG9hZFdhaXREcmF3Q2FzZQkJCQkoQ29udGV4dCYJCWNvbnRleHQsCgkJCQkJCQkJCQkJCQkJCSBjb25zdCBjaGFyKgluYW1lLAoJCQkJCQkJCQkJCQkJCQkgY29uc3QgY2hhcioJZGVzY3JpcHRpb24sCgkJCQkJCQkJCQkJCQkJCSBEcmF3TWV0aG9kCQlkcmF3TWV0aG9kLAoJCQkJCQkJCQkJCQkJCQkgVGFyZ2V0QnVmZmVyCXRhcmdldEJ1ZmZlciwKCQkJCQkJCQkJCQkJCQkJIFVwbG9hZE1ldGhvZAl1cGxvYWRNZXRob2QsCgkJCQkJCQkJCQkJCQkJCSBCdWZmZXJTdGF0ZQlidWZmZXJTdGF0ZSk7CgkJCQkJCQl+VXBsb2FkV2FpdERyYXdDYXNlCQkJCSh2b2lkKTsKCnByaXZhdGU6Cgl2b2lkCQkJCQlpbml0CQkJCQkJCSh2b2lkKTsKCXZvaWQJCQkJCWRlaW5pdAkJCQkJCQkodm9pZCk7CglJdGVyYXRlUmVzdWx0CQkJaXRlcmF0ZQkJCQkJCQkodm9pZCk7CgoJdm9pZAkJCQkJdXBsb2FkQnVmZmVyCQkJCQkoU2FtcGxlJiBzYW1wbGUsIFJlc3VsdCYgcmVzdWx0KTsKCXZvaWQJCQkJCWRyYXdGcm9tQnVmZmVyCQkJCQkoU2FtcGxlJiBzYW1wbGUsIFJlc3VsdCYgcmVzdWx0KTsKCXZvaWQJCQkJCXJldXNlQW5kRGVsZXRlQnVmZmVyCQkJKHZvaWQpOwoJdm9pZAkJCQkJbG9nQW5kU2V0VGVzdFJlc3VsdAkJCQkodm9pZCk7Cgl2b2lkCQkJCQlsb2dTYW1wbGVzCQkJCQkJKHZvaWQpOwoJdm9pZAkJCQkJZHJhd01pc2MJCQkJCQkodm9pZCk7CglpbnQJCQkJCQlmaW5kU3RhYmlsaXphdGlvblNhbXBsZQkJCShkZVVpbnQ2NCAoUmVzdWx0OjoqdGFyZ2V0KSwgY29uc3QgY2hhciogZGVzY3JpcHRpb24pOwoJYm9vbAkJCQkJY2hlY2tTYW1wbGVUZW1wb3JhbFN0YWJpbGl0eQkoZGVVaW50NjQgKFJlc3VsdDo6KnRhcmdldCksIGNvbnN0IGNoYXIqIGRlc2NyaXB0aW9uKTsKCgljb25zdCBEcmF3TWV0aG9kCQltX2RyYXdNZXRob2Q7Cgljb25zdCBUYXJnZXRCdWZmZXIJCW1fdGFyZ2V0QnVmZmVyOwoJY29uc3QgVXBsb2FkTWV0aG9kCQltX3VwbG9hZE1ldGhvZDsKCWNvbnN0IEJ1ZmZlclN0YXRlCQltX2J1ZmZlclN0YXRlOwoKCWNvbnN0IGludAkJCQltX251bVNhbXBsZXNQZXJTd2FwOwoJY29uc3QgaW50CQkJCW1fbnVtTWF4U3dhcHM7CgoJaW50CQkJCQkJbV9mcmFtZU5keDsKCWludAkJCQkJCW1fc2FtcGxlTmR4OwoJaW50CQkJCQkJbV9udW1WZXJ0aWNlczsKCglzdGQ6OnZlY3Rvcjx0Y3U6OlZlYzQ+CW1fdmVydGV4RGF0YTsKCXN0ZDo6dmVjdG9yPGRlVWludDMyPgltX2luZGV4RGF0YTsKCXN0ZDo6dmVjdG9yPFNhbXBsZT4JCW1fc2FtcGxlczsKCXN0ZDo6dmVjdG9yPFJlc3VsdD4JCW1fcmVzdWx0czsKCXN0ZDo6dmVjdG9yPGludD4JCW1faXRlcmF0aW9uT3JkZXI7CgoJZGVVaW50MzIJCQkJbV92ZXJ0ZXhCdWZmZXI7CglkZVVpbnQzMgkJCQltX2luZGV4QnVmZmVyOwoJZGVVaW50MzIJCQkJbV9taXNjQnVmZmVyOwoJaW50CQkJCQkJbV9udW1NaXNjVmVydGljZXM7Cn07CgpVcGxvYWRXYWl0RHJhd0Nhc2U6OlVwbG9hZFdhaXREcmF3Q2FzZSAoQ29udGV4dCYJCWNvbnRleHQsCgkJCQkJCQkJCQljb25zdCBjaGFyKgkJbmFtZSwKCQkJCQkJCQkJCWNvbnN0IGNoYXIqCQlkZXNjcmlwdGlvbiwKCQkJCQkJCQkJCURyYXdNZXRob2QJCWRyYXdNZXRob2QsCgkJCQkJCQkJCQlUYXJnZXRCdWZmZXIJdGFyZ2V0QnVmZmVyLAoJCQkJCQkJCQkJVXBsb2FkTWV0aG9kCXVwbG9hZE1ldGhvZCwKCQkJCQkJCQkJCUJ1ZmZlclN0YXRlCQlidWZmZXJTdGF0ZSkKCTogUmVuZGVyUGVyZm9ybWFuY2VUZXN0QmFzZQkoY29udGV4dCwgbmFtZSwgZGVzY3JpcHRpb24pCgksIG1fZHJhd01ldGhvZAkJCQkoZHJhd01ldGhvZCkKCSwgbV90YXJnZXRCdWZmZXIJCQkodGFyZ2V0QnVmZmVyKQoJLCBtX3VwbG9hZE1ldGhvZAkJCSh1cGxvYWRNZXRob2QpCgksIG1fYnVmZmVyU3RhdGUJCQkJKGJ1ZmZlclN0YXRlKQoJLCBtX251bVNhbXBsZXNQZXJTd2FwCQkoMTApCgksIG1fbnVtTWF4U3dhcHMJCQkJKDQpCgksIG1fZnJhbWVOZHgJCQkJKDApCgksIG1fc2FtcGxlTmR4CQkJCSgwKQoJLCBtX251bVZlcnRpY2VzCQkJCSgtMSkKCSwgbV92ZXJ0ZXhCdWZmZXIJCQkoMCkKCSwgbV9pbmRleEJ1ZmZlcgkJCQkoMCkKCSwgbV9taXNjQnVmZmVyCQkJCSgwKQoJLCBtX251bU1pc2NWZXJ0aWNlcwkJCSgtMSkKewp9CgpVcGxvYWRXYWl0RHJhd0Nhc2U6On5VcGxvYWRXYWl0RHJhd0Nhc2UgKHZvaWQpCnsKCWRlaW5pdCgpOwp9Cgp2b2lkIFVwbG9hZFdhaXREcmF3Q2FzZTo6aW5pdCAodm9pZCkKewoJY29uc3QgZ2x3OjpGdW5jdGlvbnMmCWdsCQkJCQkJPSBtX2NvbnRleHQuZ2V0UmVuZGVyQ29udGV4dCgpLmdldEZ1bmN0aW9ucygpOwoJY29uc3QgaW50CQkJCXZlcnRleEF0dHJpYlNpemUJCT0gKGludClzaXplb2YodGN1OjpWZWM0KSAqIDI7IC8vIGNvbG9yNCwgcG9zaXRpb240Cgljb25zdCBpbnQJCQkJdmVydGV4SW5kZXhTaXplCQkJPSAoaW50KXNpemVvZihkZVVpbnQzMik7Cgljb25zdCBpbnQJCQkJdmVydGV4VXBsb2FkRGF0YVNpemUJPSAobV90YXJnZXRCdWZmZXIgPT0gVEFSR0VUQlVGRkVSX1ZFUlRFWCkgPyAodmVydGV4QXR0cmliU2l6ZSkgOiAodmVydGV4SW5kZXhTaXplKTsKCglSZW5kZXJQZXJmb3JtYW5jZVRlc3RCYXNlOjppbml0KCk7CgoJLy8gcmVxdWlyZW1lbnRzCgoJaWYgKG1fY29udGV4dC5nZXRSZW5kZXJUYXJnZXQoKS5nZXRXaWR0aCgpIDwgUkVOREVSX0FSRUFfU0laRSB8fAoJCW1fY29udGV4dC5nZXRSZW5kZXJUYXJnZXQoKS5nZXRIZWlnaHQoKSA8IFJFTkRFUl9BUkVBX1NJWkUpCgkJdGhyb3cgdGN1OjpOb3RTdXBwb3J0ZWRFcnJvcigiVGVzdCBjYXNlIHJlcXVpcmVzICIgKyBkZTo6dG9TdHJpbmc8aW50PihSRU5ERVJfQVJFQV9TSVpFKSArICJ4IiArIGRlOjp0b1N0cmluZzxpbnQ+KFJFTkRFUl9BUkVBX1NJWkUpICsgIiByZW5kZXIgdGFyZ2V0Iik7CgoJLy8gZ2wgc3RhdGUKCglnbC52aWV3cG9ydCgwLCAwLCBSRU5ERVJfQVJFQV9TSVpFLCBSRU5ERVJfQVJFQV9TSVpFKTsKCgkvLyBlbmFibGUgYmxlZGluZyB0byBwcmV2ZW50IGdyaWQgbGF5ZXJzIGZyb20gYmVpbmcgZGlzY2FyZGVkCgoJZ2wuYmxlbmRGdW5jKEdMX1NSQ19BTFBIQSwgR0xfT05FX01JTlVTX1NSQ19BTFBIQSk7CglnbC5ibGVuZEVxdWF0aW9uKEdMX0ZVTkNfQUREKTsKCWdsLmVuYWJsZShHTF9CTEVORCk7CgoJLy8gc2NlbmUKCgl7CgkJTGF5ZXJlZEdyaWRTcGVjIHNjZW5lOwoKCQkvLyBjcmVhdGUgfjhNQiB3b3JrbG9hZCB3aXRoIHNpbWlsYXIgY2hhcmFjdGVyaXN0aWNzIGFzIGluIHRoZSBvdGhlciB0ZXN0CgkJLy8gPT4gbWFrZXMgY29tcGFyaXNvbiB0byBvdGhlciByZXN1bHRzIG1vcmUgc3RyYWlnaHRmb3J3YXJkCgkJc2NlbmUuZ3JpZFdpZHRoID0gOTM7CgkJc2NlbmUuZ3JpZEhlaWdodCA9IDkzOwoJCXNjZW5lLmdyaWRMYXllcnMgPSA1OwoKCQlnZW5lcmF0ZUxheWVyZWRHcmlkVmVydGV4QXR0cmliRGF0YTRDNFYobV92ZXJ0ZXhEYXRhLCBzY2VuZSk7CgkJZ2VuZXJhdGVMYXllcmVkR3JpZEluZGV4RGF0YShtX2luZGV4RGF0YSwgc2NlbmUpOwoJCW1fbnVtVmVydGljZXMgPSBnZXRMYXllcmVkR3JpZE51bVZlcnRpY2VzKHNjZW5lKTsKCX0KCgkvLyBidWZmZXJzCgoJaWYgKG1fYnVmZmVyU3RhdGUgPT0gQlVGRkVSU1RBVEVfTkVXKQoJewoJCWlmIChtX2RyYXdNZXRob2QgPT0gRFJBV01FVEhPRF9EUkFXX0VMRU1FTlRTKQoJCXsKCQkJLy8gcmVhZHMgZnJvbSB0d28gYnVmZmVycywgcHJlcGFyZSB0aGUgc3RhdGljIGJ1ZmZlcgoKCQkJaWYgKG1fdGFyZ2V0QnVmZmVyID09IFRBUkdFVEJVRkZFUl9WRVJURVgpCgkJCXsKCQkJCS8vIGluZGV4IGJ1ZmZlciBpcyBzdGF0aWMsIHVzZSBhbm90aGVyIHZlcnRleCBidWZmZXIgdG8ga2VlcCBvcmlnaW5hbCBidWZmZXIgaW4gdW51c2VkIHN0YXRlCgkJCQljb25zdCBnbHU6OkJ1ZmZlciB2ZXJ0ZXhDb3B5QnVmZmVyKG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCkpOwoKCQkJCWdsLmdlbkJ1ZmZlcnMoMSwgJm1faW5kZXhCdWZmZXIpOwoJCQkJZ2wuYmluZEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIsICp2ZXJ0ZXhDb3B5QnVmZmVyKTsKCQkJCWdsLmJpbmRCdWZmZXIoR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVIsIG1faW5kZXhCdWZmZXIpOwoJCQkJZ2wuYnVmZmVyRGF0YShHTF9BUlJBWV9CVUZGRVIsIChnbHc6OkdMc2l6ZWlwdHIpKG1fdmVydGV4RGF0YS5zaXplKCkgKiBzaXplb2YodGN1OjpWZWM0KSksICZtX3ZlcnRleERhdGFbMF0sIEdMX1NUQVRJQ19EUkFXKTsKCQkJCWdsLmJ1ZmZlckRhdGEoR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVIsIChnbHc6OkdMc2l6ZWlwdHIpKG1faW5kZXhEYXRhLnNpemUoKSAqIHNpemVvZihkZVVpbnQzMikpLCAmbV9pbmRleERhdGFbMF0sIEdMX1NUQVRJQ19EUkFXKTsKCgkJCQlzZXR1cFZlcnRleEF0dHJpYnMoKTsKCQkJCWdsLmRyYXdFbGVtZW50cyhHTF9UUklBTkdMRVMsIG1fbnVtVmVydGljZXMsIEdMX1VOU0lHTkVEX0lOVCwgREVfTlVMTCk7CgkJCX0KCQkJZWxzZSBpZiAobV90YXJnZXRCdWZmZXIgPT0gVEFSR0VUQlVGRkVSX0lOREVYKQoJCQl7CgkJCQkvLyB2ZXJ0ZXggYnVmZmVyIGlzIHN0YXRpYwoJCQkJZ2wuZ2VuQnVmZmVycygxLCAmbV92ZXJ0ZXhCdWZmZXIpOwoJCQkJZ2wuYmluZEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIsIG1fdmVydGV4QnVmZmVyKTsKCQkJCWdsLmJ1ZmZlckRhdGEoR0xfQVJSQVlfQlVGRkVSLCAoZ2x3OjpHTHNpemVpcHRyKShtX3ZlcnRleERhdGEuc2l6ZSgpICogc2l6ZW9mKHRjdTo6VmVjNCkpLCAmbV92ZXJ0ZXhEYXRhWzBdLCBHTF9TVEFUSUNfRFJBVyk7CgoJCQkJc2V0dXBWZXJ0ZXhBdHRyaWJzKCk7CgkJCQlnbC5kcmF3QXJyYXlzKEdMX1RSSUFOR0xFUywgMCwgbV9udW1WZXJ0aWNlcyk7CgkJCX0KCQkJZWxzZQoJCQkJREVfQVNTRVJUKGZhbHNlKTsKCQl9Cgl9CgllbHNlIGlmIChtX2J1ZmZlclN0YXRlID09IEJVRkZFUlNUQVRFX0VYSVNUSU5HKQoJewoJCWNvbnN0IGdsdzo6R0xlbnVtIHZlcnRleFVzYWdlCT0gKG1fdGFyZ2V0QnVmZmVyID09IFRBUkdFVEJVRkZFUl9WRVJURVgpID8gKEdMX1NUQVRJQ19EUkFXKSA6IChHTF9TVEFUSUNfRFJBVyk7CgkJY29uc3QgZ2x3OjpHTGVudW0gaW5kZXhVc2FnZQk9IChtX3RhcmdldEJ1ZmZlciA9PSBUQVJHRVRCVUZGRVJfSU5ERVgpID8gKEdMX1NUQVRJQ19EUkFXKSA6IChHTF9TVEFUSUNfRFJBVyk7CgoJCWdsLmdlbkJ1ZmZlcnMoMSwgJm1fdmVydGV4QnVmZmVyKTsKCQlnbC5iaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgbV92ZXJ0ZXhCdWZmZXIpOwoJCWdsLmJ1ZmZlckRhdGEoR0xfQVJSQVlfQlVGRkVSLCAoZ2x3OjpHTHNpemVpcHRyKShtX3ZlcnRleERhdGEuc2l6ZSgpICogc2l6ZW9mKHRjdTo6VmVjNCkpLCAmbV92ZXJ0ZXhEYXRhWzBdLCB2ZXJ0ZXhVc2FnZSk7CgoJCWlmIChtX2RyYXdNZXRob2QgPT0gRFJBV01FVEhPRF9EUkFXX0VMRU1FTlRTKQoJCXsKCQkJZ2wuZ2VuQnVmZmVycygxLCAmbV9pbmRleEJ1ZmZlcik7CgkJCWdsLmJpbmRCdWZmZXIoR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVIsIG1faW5kZXhCdWZmZXIpOwoJCQlnbC5idWZmZXJEYXRhKEdMX0VMRU1FTlRfQVJSQVlfQlVGRkVSLCAoZ2x3OjpHTHNpemVpcHRyKShtX2luZGV4RGF0YS5zaXplKCkgKiBzaXplb2YoZGVVaW50MzIpKSwgJm1faW5kZXhEYXRhWzBdLCBpbmRleFVzYWdlKTsKCQl9CgoJCXNldHVwVmVydGV4QXR0cmlicygpOwoKCQlpZiAobV9kcmF3TWV0aG9kID09IERSQVdNRVRIT0RfRFJBV19BUlJBWVMpCgkJCWdsLmRyYXdBcnJheXMoR0xfVFJJQU5HTEVTLCAwLCBtX251bVZlcnRpY2VzKTsKCQllbHNlIGlmIChtX2RyYXdNZXRob2QgPT0gRFJBV01FVEhPRF9EUkFXX0VMRU1FTlRTKQoJCQlnbC5kcmF3RWxlbWVudHMoR0xfVFJJQU5HTEVTLCBtX251bVZlcnRpY2VzLCBHTF9VTlNJR05FRF9JTlQsIERFX05VTEwpOwoJCWVsc2UKCQkJREVfQVNTRVJUKGZhbHNlKTsKCX0KCWVsc2UKCQlERV9BU1NFUlQoZmFsc2UpOwoKCS8vIG1pc2MgZHJhdyBidWZmZXIKCXsKCQlzdGQ6OnZlY3Rvcjx0Y3U6OlZlYzQ+CXZlcnRleERhdGE7CgkJTGF5ZXJlZEdyaWRTcGVjCQkJc2NlbmU7CgoJCS8vIGNyZWF0ZSB+MS41TUIgd29ya2xvYWQgd2l0aCBzaW1pbGFyIGNoYXJhY3RlcmlzdGljcwoJCXNjZW5lLmdyaWRXaWR0aCA9IDQwOwoJCXNjZW5lLmdyaWRIZWlnaHQgPSA0MDsKCQlzY2VuZS5ncmlkTGF5ZXJzID0gNTsKCgkJZ2VuZXJhdGVMYXllcmVkR3JpZFZlcnRleEF0dHJpYkRhdGE0QzRWKHZlcnRleERhdGEsIHNjZW5lKTsKCgkJZ2wuZ2VuQnVmZmVycygxLCAmbV9taXNjQnVmZmVyKTsKCQlnbC5iaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgbV9taXNjQnVmZmVyKTsKCQlnbC5idWZmZXJEYXRhKEdMX0FSUkFZX0JVRkZFUiwgKGdsdzo6R0xzaXplaXB0cikoc2l6ZW9mKHRjdTo6VmVjNCkgKiB2ZXJ0ZXhEYXRhLnNpemUoKSksICZ2ZXJ0ZXhEYXRhWzBdLCBHTF9TVEFUSUNfRFJBVyk7CgoJCW1fbnVtTWlzY1ZlcnRpY2VzID0gZ2V0TGF5ZXJlZEdyaWROdW1WZXJ0aWNlcyhzY2VuZSk7Cgl9CgoJLy8gaXRlcmF0aW9ucwoJewoJCW1fc2FtcGxlcy5yZXNpemUoKG1fbnVtTWF4U3dhcHMrMSkgKiBtX251bVNhbXBsZXNQZXJTd2FwKTsKCQltX3Jlc3VsdHMucmVzaXplKChtX251bU1heFN3YXBzKzEpICogbV9udW1TYW1wbGVzUGVyU3dhcCk7CgoJCWZvciAoaW50IG51bVN3YXBzID0gMDsgbnVtU3dhcHMgPD0gbV9udW1NYXhTd2FwczsgKytudW1Td2FwcykKCQlmb3IgKGludCBzYW1wbGVOZHggPSAwOyBzYW1wbGVOZHggPCBtX251bVNhbXBsZXNQZXJTd2FwOyArK3NhbXBsZU5keCkKCQl7CgkJCWNvbnN0IGludCBpbmRleCA9IG51bVN3YXBzKm1fbnVtU2FtcGxlc1BlclN3YXAgKyBzYW1wbGVOZHg7CgoJCQltX3NhbXBsZXNbaW5kZXhdLm51bUZyYW1lcyA9IG51bVN3YXBzOwoJCX0KCgkJbV9pdGVyYXRpb25PcmRlci5yZXNpemUobV9zYW1wbGVzLnNpemUoKSk7CgkJZ2VuZXJhdGVUd29QYXNzUmFuZG9tSXRlcmF0aW9uT3JkZXIobV9pdGVyYXRpb25PcmRlciwgKGludCltX3NhbXBsZXMuc2l6ZSgpKTsKCX0KCgkvLyBsb2cKCW1fdGVzdEN0eC5nZXRMb2coKQoJCTw8IHRjdTo6VGVzdExvZzo6TWVzc2FnZQoJCTw8ICJNZWFzdXJpbmcgdGltZSB1c2VkIGluICIgPDwgKChtX2RyYXdNZXRob2QgPT0gRFJBV01FVEhPRF9EUkFXX0FSUkFZUykgPyAoImRyYXdBcnJheXMiKSA6ICgiZHJhd0VsZW1lbnRzIikpIDw8ICIgYW5kIHJlYWRQaXhlbHMgY2FsbC5cbiIKCQk8PCAiRHJhd2luZyB1c2luZyBhIGJ1ZmZlciB0aGF0IGhhcyBiZWVuIHVwbG9hZGVkIE4gZnJhbWVzIGFnby4gVGVzdGluZyB3aXRoIE4gd2l0aGluIHJhbmdlIFswLCAiIDw8IG1fbnVtTWF4U3dhcHMgPDwgIl0uXG4iCgkJPDwgIlVwbG9hZGVkIGJ1ZmZlciBpcyBhICIgPDwgKChtX3RhcmdldEJ1ZmZlciA9PSBUQVJHRVRCVUZGRVJfVkVSVEVYKSA/ICgidmVydGV4IGF0dHJpYnV0ZSIpIDogKCJpbmRleCIpKSA8PCAiIGJ1ZmZlci5cbiIKCQk8PCAiVXBsb2FkaW5nIHVzaW5nICIKCQkJPDwgKChtX3VwbG9hZE1ldGhvZCA9PSBVUExPQURNRVRIT0RfQlVGRkVSX0RBVEEpCQk/ICgiYnVmZmVyRGF0YSIpCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQk6CgkJCQkobV91cGxvYWRNZXRob2QgPT0gVVBMT0FETUVUSE9EX0JVRkZFUl9TVUJfREFUQSkJPyAoImJ1ZmZlclN1YkRhdGEiKQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJOgoJCQkJKG1fdXBsb2FkTWV0aG9kID09IFVQTE9BRE1FVEhPRF9NQVBfQlVGRkVSX1JBTkdFKQk/ICgibWFwQnVmZmVyUmFuZ2UsIGZsYWdzID0gR0xfTUFQX1dSSVRFX0JJVCB8IEdMX01BUF9JTlZBTElEQVRFX0JVRkZFUl9CSVQgfCBHTF9NQVBfVU5TWU5DSFJPTklaRURfQklUIikJOgoJCQkJKChjb25zdCBjaGFyKilERV9OVUxMKSkKCQkJPDwgIlxuIgoJCTw8ICJVcGxvYWQgc2l6ZSBpcyAiIDw8IGdldEh1bWFuUmVhZGFibGVCeXRlU2l6ZShtX251bVZlcnRpY2VzICogdmVydGV4VXBsb2FkRGF0YVNpemUpIDw8ICIuXG4iCgkJPDwgKChtX2J1ZmZlclN0YXRlID09IEJVRkZFUlNUQVRFX0VYSVNUSU5HKSA/ICgiQWxsIHRlc3Qgc2FtcGxlcyB1c2UgdGhlIHNhbWUgYnVmZmVyIG9iamVjdC5cbiIpIDogKCIiKSkKCQk8PCAiVGVzdCByZXN1bHQgaXMgdGhlIG51bWJlciBvZiBmcmFtZXMgKHN3YXBzKSByZXF1aXJlZCBmb3IgdGhlIHJlbmRlciB0aW1lIHRvIHN0YWJpbGl6ZS5cbiIKCQk8PCAiQXNzdW1pbmcgY29tYmluZWQgdGltZSB1c2VkIGluIHRoZSBkcmF3IGNhbGwgYW5kIHJlYWRQaXhlbHMgY2FsbCBpcyBzdGFiaWxpemVzIHRvIGEgY29uc3RhbnQgdmFsdWUuXG4iCgkJPDwgdGN1OjpUZXN0TG9nOjpFbmRNZXNzYWdlOwp9Cgp2b2lkIFVwbG9hZFdhaXREcmF3Q2FzZTo6ZGVpbml0ICh2b2lkKQp7CglSZW5kZXJQZXJmb3JtYW5jZVRlc3RCYXNlOjpkZWluaXQoKTsKCglpZiAobV92ZXJ0ZXhCdWZmZXIpCgl7CgkJbV9jb250ZXh0LmdldFJlbmRlckNvbnRleHQoKS5nZXRGdW5jdGlvbnMoKS5kZWxldGVCdWZmZXJzKDEsICZtX3ZlcnRleEJ1ZmZlcik7CgkJbV92ZXJ0ZXhCdWZmZXIgPSAwOwoJfQoJaWYgKG1faW5kZXhCdWZmZXIpCgl7CgkJbV9jb250ZXh0LmdldFJlbmRlckNvbnRleHQoKS5nZXRGdW5jdGlvbnMoKS5kZWxldGVCdWZmZXJzKDEsICZtX2luZGV4QnVmZmVyKTsKCQltX2luZGV4QnVmZmVyID0gMDsKCX0KCWlmIChtX21pc2NCdWZmZXIpCgl7CgkJbV9jb250ZXh0LmdldFJlbmRlckNvbnRleHQoKS5nZXRGdW5jdGlvbnMoKS5kZWxldGVCdWZmZXJzKDEsICZtX21pc2NCdWZmZXIpOwoJCW1fbWlzY0J1ZmZlciA9IDA7Cgl9Cn0KClVwbG9hZFdhaXREcmF3Q2FzZTo6SXRlcmF0ZVJlc3VsdCBVcGxvYWRXYWl0RHJhd0Nhc2U6Oml0ZXJhdGUgKHZvaWQpCnsKCWNvbnN0IGdsdzo6RnVuY3Rpb25zJglnbAkJCQkJCQkJPSBtX2NvbnRleHQuZ2V0UmVuZGVyQ29udGV4dCgpLmdldEZ1bmN0aW9ucygpOwoJY29uc3QgaW50CQkJCWJldHdlZW5JdGVyYXRpb25EdW1teUZyYW1lQ291bnQgPSA1OyAvLyBkcmF3IG1pc2MgYmV0d2VlbiB0ZXN0IHNhbXBsZXMKCWNvbnN0IGludAkJCQlmcmFtZU5keAkJCQkJCT0gbV9mcmFtZU5keCsrOwoJY29uc3QgaW50CQkJCWN1cnJlbnRTYW1wbGVOZHgJCQkJPSBtX2l0ZXJhdGlvbk9yZGVyW21fc2FtcGxlTmR4XTsKCgkvLyBTaW11bGF0ZSB3b3JrIGZvciBhYm91dCA4bXMKCWJ1c3lXYWl0KDgwMDApOwoKCS8vIER1bW15IHJlbmRlcmluZyBkdXJpbmcgZHVtbXkgZnJhbWVzCglpZiAoZnJhbWVOZHggIT0gbV9zYW1wbGVzW2N1cnJlbnRTYW1wbGVOZHhdLm51bUZyYW1lcykKCXsKCQkvLyBkcmF3IHNpbWlsYXIgZnJvbSBhbm90aGVyIGJ1ZmZlcgoJCWRyYXdNaXNjKCk7Cgl9CgoJaWYgKGZyYW1lTmR4ID09IDApCgl7CgkJLy8gdXBsb2FkIGFuZCBzdGFydCB0aGUgY2xvY2sKCQl1cGxvYWRCdWZmZXIobV9zYW1wbGVzW2N1cnJlbnRTYW1wbGVOZHhdLCBtX3Jlc3VsdHNbY3VycmVudFNhbXBsZU5keF0pOwoJfQoKCWlmIChmcmFtZU5keCA9PSBtX3NhbXBsZXNbY3VycmVudFNhbXBsZU5keF0ubnVtRnJhbWVzKSAvLyBcbm90ZTogbm90IGVsc2UgaWYsIG1fc2FtcGxlc1tjdXJyZW50U2FtcGxlTmR4XS5udW1GcmFtZXMgY2FuIGJlIDAKCXsKCQkvLyBkcmF3IHVzaW5nIHRoZSB1cGxvYWRlZCBidWZmZXIKCQlkcmF3RnJvbUJ1ZmZlcihtX3NhbXBsZXNbY3VycmVudFNhbXBsZU5keF0sIG1fcmVzdWx0c1tjdXJyZW50U2FtcGxlTmR4XSk7CgoJCS8vIHJlLXVzZSBidWZmZXIgZm9yIHNvbWV0aGluZyBlbHNlIHRvIG1ha2Ugc3VyZSB0ZXN0IGl0ZXJhdGlvbiBkbyBub3QgYWZmZWN0IGVhY2ggb3RoZXIKCQlpZiAobV9idWZmZXJTdGF0ZSA9PSBCVUZGRVJTVEFURV9ORVcpCgkJCXJldXNlQW5kRGVsZXRlQnVmZmVyKCk7Cgl9CgllbHNlIGlmIChmcmFtZU5keCA9PSBtX3NhbXBsZXNbY3VycmVudFNhbXBsZU5keF0ubnVtRnJhbWVzICsgYmV0d2Vlbkl0ZXJhdGlvbkR1bW15RnJhbWVDb3VudCkKCXsKCQkvLyBuZXh0IHNhbXBsZQoJCSsrbV9zYW1wbGVOZHg7CgkJbV9mcmFtZU5keCA9IDA7Cgl9CgoJR0xVX0VYUEVDVF9OT19FUlJPUihnbC5nZXRFcnJvcigpLCAicG9zdC1pdGVyYXRlIik7CgoJaWYgKG1fc2FtcGxlTmR4IDwgKGludCltX3NhbXBsZXMuc2l6ZSgpKQoJCXJldHVybiBDT05USU5VRTsKCglsb2dBbmRTZXRUZXN0UmVzdWx0KCk7CglyZXR1cm4gU1RPUDsKfQoKdm9pZCBVcGxvYWRXYWl0RHJhd0Nhc2U6OnVwbG9hZEJ1ZmZlciAoU2FtcGxlJiBzYW1wbGUsIFJlc3VsdCYgcmVzdWx0KQp7Cgljb25zdCBnbHc6OkZ1bmN0aW9ucyYJZ2wJCQk9IG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCkuZ2V0RnVuY3Rpb25zKCk7CglkZVVpbnQ2NAkJCQlzdGFydFRpbWU7CglkZVVpbnQ2NAkJCQllbmRUaW1lOwoJZ2x3OjpHTGVudW0JCQkJdGFyZ2V0OwoJZ2x3OjpHTHNpemVpcHRyCQkJc2l6ZTsKCWNvbnN0IHZvaWQqCQkJCXNvdXJjZTsKCgkvLyBkYXRhIHNvdXJjZQoKCWlmIChtX3RhcmdldEJ1ZmZlciA9PSBUQVJHRVRCVUZGRVJfVkVSVEVYKQoJewoJCURFX0FTU0VSVCgobV92ZXJ0ZXhCdWZmZXIgPT0gMCkgPT0gKG1fYnVmZmVyU3RhdGUgPT0gQlVGRkVSU1RBVEVfTkVXKSk7CgoJCXRhcmdldAk9IEdMX0FSUkFZX0JVRkZFUjsKCQlzaXplCT0gKGdsdzo6R0xzaXplaXB0cikobV92ZXJ0ZXhEYXRhLnNpemUoKSAqIHNpemVvZih0Y3U6OlZlYzQpKTsKCQlzb3VyY2UJPSAmbV92ZXJ0ZXhEYXRhWzBdOwoJfQoJZWxzZSBpZiAobV90YXJnZXRCdWZmZXIgPT0gVEFSR0VUQlVGRkVSX0lOREVYKQoJewoJCURFX0FTU0VSVCgobV9pbmRleEJ1ZmZlciA9PSAwKSA9PSAobV9idWZmZXJTdGF0ZSA9PSBCVUZGRVJTVEFURV9ORVcpKTsKCgkJdGFyZ2V0CT0gR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVI7CgkJc2l6ZQk9IChnbHc6OkdMc2l6ZWlwdHIpKG1faW5kZXhEYXRhLnNpemUoKSAqIHNpemVvZihkZVVpbnQzMikpOwoJCXNvdXJjZQk9ICZtX2luZGV4RGF0YVswXTsKCX0KCWVsc2UKCXsKCQlERV9BU1NFUlQoZmFsc2UpOwoJCXJldHVybjsKCX0KCgkvLyBnZW4gYnVmZmVyCgoJaWYgKG1fYnVmZmVyU3RhdGUgPT0gQlVGRkVSU1RBVEVfTkVXKQoJewoJCWlmIChtX3RhcmdldEJ1ZmZlciA9PSBUQVJHRVRCVUZGRVJfVkVSVEVYKQoJCXsKCQkJZ2wuZ2VuQnVmZmVycygxLCAmbV92ZXJ0ZXhCdWZmZXIpOwoJCQlnbC5iaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgbV92ZXJ0ZXhCdWZmZXIpOwoJCX0KCQllbHNlIGlmIChtX3RhcmdldEJ1ZmZlciA9PSBUQVJHRVRCVUZGRVJfSU5ERVgpCgkJewoJCQlnbC5nZW5CdWZmZXJzKDEsICZtX2luZGV4QnVmZmVyKTsKCQkJZ2wuYmluZEJ1ZmZlcihHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUiwgbV9pbmRleEJ1ZmZlcik7CgkJfQoJCWVsc2UKCQkJREVfQVNTRVJUKGZhbHNlKTsKCgkJaWYgKG1fdXBsb2FkTWV0aG9kID09IFVQTE9BRE1FVEhPRF9CVUZGRVJfU1VCX0RBVEEgfHwKCQkJbV91cGxvYWRNZXRob2QgPT0gVVBMT0FETUVUSE9EX01BUF9CVUZGRVJfUkFOR0UpCgkJewoJCQlnbC5idWZmZXJEYXRhKHRhcmdldCwgc2l6ZSwgREVfTlVMTCwgR0xfU1RBVElDX0RSQVcpOwoJCX0KCX0KCWVsc2UgaWYgKG1fYnVmZmVyU3RhdGUgPT0gQlVGRkVSU1RBVEVfRVhJU1RJTkcpCgl7CgkJaWYgKG1fdGFyZ2V0QnVmZmVyID09IFRBUkdFVEJVRkZFUl9WRVJURVgpCgkJCWdsLmJpbmRCdWZmZXIoR0xfQVJSQVlfQlVGRkVSLCBtX3ZlcnRleEJ1ZmZlcik7CgkJZWxzZSBpZiAobV90YXJnZXRCdWZmZXIgPT0gVEFSR0VUQlVGRkVSX0lOREVYKQoJCQlnbC5iaW5kQnVmZmVyKEdMX0VMRU1FTlRfQVJSQVlfQlVGRkVSLCBtX2luZGV4QnVmZmVyKTsKCQllbHNlCgkJCURFX0FTU0VSVChmYWxzZSk7Cgl9CgllbHNlCgkJREVfQVNTRVJUKGZhbHNlKTsKCgkvLyB1cGxvYWQKCglzdGFydFRpbWUgPSBkZUdldE1pY3Jvc2Vjb25kcygpOwoKCWlmIChtX3VwbG9hZE1ldGhvZCA9PSBVUExPQURNRVRIT0RfQlVGRkVSX0RBVEEpCgkJZ2wuYnVmZmVyRGF0YSh0YXJnZXQsIHNpemUsIHNvdXJjZSwgR0xfU1RBVElDX0RSQVcpOwoJZWxzZSBpZiAobV91cGxvYWRNZXRob2QgPT0gVVBMT0FETUVUSE9EX0JVRkZFUl9TVUJfREFUQSkKCQlnbC5idWZmZXJTdWJEYXRhKHRhcmdldCwgMCwgc2l6ZSwgc291cmNlKTsKCWVsc2UgaWYgKG1fdXBsb2FkTWV0aG9kID09IFVQTE9BRE1FVEhPRF9NQVBfQlVGRkVSX1JBTkdFKQoJewoJCXZvaWQqCQkJbWFwUHRyOwoJCWdsdzo6R0xib29sZWFuCXVubWFwU3VjY2Vzc2Z1bDsKCgkJbWFwUHRyID0gZ2wubWFwQnVmZmVyUmFuZ2UodGFyZ2V0LCAwLCBzaXplLCBHTF9NQVBfV1JJVEVfQklUIHwgR0xfTUFQX0lOVkFMSURBVEVfQlVGRkVSX0JJVCB8IEdMX01BUF9VTlNZTkNIUk9OSVpFRF9CSVQpOwoJCWlmICghbWFwUHRyKQoJCQl0aHJvdyB0Y3U6OkV4Y2VwdGlvbigiTWFwQnVmZmVyUmFuZ2UgcmV0dXJuZWQgTlVMTCIpOwoKCQlkZU1lbWNweShtYXBQdHIsIHNvdXJjZSwgKGludClzaXplKTsKCgkJLy8gaWYgdW5tYXBwaW5nIGZhaWxzLCBqdXN0IHRyeSBhZ2FpbiBsYXRlcgoJCXVubWFwU3VjY2Vzc2Z1bCA9IGdsLnVubWFwQnVmZmVyKHRhcmdldCk7CgkJaWYgKCF1bm1hcFN1Y2Nlc3NmdWwpCgkJCXRocm93IFVubWFwRmFpbHVyZUVycm9yKCk7Cgl9CgllbHNlCgkJREVfQVNTRVJUKGZhbHNlKTsKCgllbmRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCglzYW1wbGUudXBsb2FkQ2FsbEVuZFRpbWUgPSBlbmRUaW1lOwoJcmVzdWx0LnVwbG9hZER1cmF0aW9uID0gZW5kVGltZSAtIHN0YXJ0VGltZTsKfQoKdm9pZCBVcGxvYWRXYWl0RHJhd0Nhc2U6OmRyYXdGcm9tQnVmZmVyIChTYW1wbGUmIHNhbXBsZSwgUmVzdWx0JiByZXN1bHQpCnsKCWNvbnN0IGdsdzo6RnVuY3Rpb25zJglnbAkJCQk9IG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCkuZ2V0RnVuY3Rpb25zKCk7Cgl0Y3U6OlN1cmZhY2UJCQlyZXN1bHRTdXJmYWNlCShSRU5ERVJfQVJFQV9TSVpFLCBSRU5ERVJfQVJFQV9TSVpFKTsKCWRlVWludDY0CQkJCXN0YXJ0VGltZTsKCWRlVWludDY0CQkJCWVuZFRpbWU7CgoJREVfQVNTRVJUKG1fdmVydGV4QnVmZmVyICE9IDApOwoJaWYgKG1fZHJhd01ldGhvZCA9PSBEUkFXTUVUSE9EX0RSQVdfQVJSQVlTKQoJCURFX0FTU0VSVChtX2luZGV4QnVmZmVyID09IDApOwoJZWxzZSBpZiAobV9kcmF3TWV0aG9kID09IERSQVdNRVRIT0RfRFJBV19FTEVNRU5UUykKCQlERV9BU1NFUlQobV9pbmRleEJ1ZmZlciAhPSAwKTsKCWVsc2UKCQlERV9BU1NFUlQoZmFsc2UpOwoKCS8vIGRyYXcKCXsKCQlnbC5iaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgbV92ZXJ0ZXhCdWZmZXIpOwoJCWlmIChtX2RyYXdNZXRob2QgPT0gRFJBV01FVEhPRF9EUkFXX0VMRU1FTlRTKQoJCQlnbC5iaW5kQnVmZmVyKEdMX0VMRU1FTlRfQVJSQVlfQlVGRkVSLCBtX2luZGV4QnVmZmVyKTsKCgkJc2V0dXBWZXJ0ZXhBdHRyaWJzKCk7CgoJCS8vIG1pY3Jvc2Vjb25kcyBwYXNzZWQgc2luY2UgcmV0dXJuIGZyb20gdXBsb2FkIGNhbGwKCQlyZXN1bHQudGltZUJlZm9yZVVzZSA9IGRlR2V0TWljcm9zZWNvbmRzKCkgLSBzYW1wbGUudXBsb2FkQ2FsbEVuZFRpbWU7CgoJCXN0YXJ0VGltZSA9IGRlR2V0TWljcm9zZWNvbmRzKCk7CgoJCWlmIChtX2RyYXdNZXRob2QgPT0gRFJBV01FVEhPRF9EUkFXX0FSUkFZUykKCQkJZ2wuZHJhd0FycmF5cyhHTF9UUklBTkdMRVMsIDAsIG1fbnVtVmVydGljZXMpOwoJCWVsc2UgaWYgKG1fZHJhd01ldGhvZCA9PSBEUkFXTUVUSE9EX0RSQVdfRUxFTUVOVFMpCgkJCWdsLmRyYXdFbGVtZW50cyhHTF9UUklBTkdMRVMsIG1fbnVtVmVydGljZXMsIEdMX1VOU0lHTkVEX0lOVCwgREVfTlVMTCk7CgkJZWxzZQoJCQlERV9BU1NFUlQoZmFsc2UpOwoKCQllbmRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCgkJcmVzdWx0LnJlbmRlckR1cmF0aW9uID0gZW5kVGltZSAtIHN0YXJ0VGltZTsKCX0KCgkvLyByZWFkCgl7CgkJc3RhcnRUaW1lID0gZGVHZXRNaWNyb3NlY29uZHMoKTsKCQlnbHU6OnJlYWRQaXhlbHMobV9jb250ZXh0LmdldFJlbmRlckNvbnRleHQoKSwgMCwgMCwgcmVzdWx0U3VyZmFjZS5nZXRBY2Nlc3MoKSk7CgkJZW5kVGltZSA9IGRlR2V0TWljcm9zZWNvbmRzKCk7CgoJCXJlc3VsdC5yZWFkRHVyYXRpb24gPSBlbmRUaW1lIC0gc3RhcnRUaW1lOwoJfQoKCXJlc3VsdC5yZW5kZXJSZWFkRHVyYXRpb24gPSByZXN1bHQucmVuZGVyRHVyYXRpb24gKyByZXN1bHQucmVhZER1cmF0aW9uOwp9Cgp2b2lkIFVwbG9hZFdhaXREcmF3Q2FzZTo6cmV1c2VBbmREZWxldGVCdWZmZXIgKHZvaWQpCnsKCWNvbnN0IGdsdzo6RnVuY3Rpb25zJiBnbCA9IG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCkuZ2V0RnVuY3Rpb25zKCk7CgoJaWYgKG1fdGFyZ2V0QnVmZmVyID09IFRBUkdFVEJVRkZFUl9JTkRFWCkKCXsKCQkvLyByZXNwZWNpZnkgYW5kIGRlbGV0ZSBpbmRleCBidWZmZXIKCQlzdGF0aWMgY29uc3QgZGVVaW50MzIgaW5kaWNlc1szXSA9IHsxLCAzLCA4fTsKCgkJREVfQVNTRVJUKG1faW5kZXhCdWZmZXIgIT0gMCk7CgoJCWdsLmJ1ZmZlckRhdGEoR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVIsIHNpemVvZihpbmRpY2VzKSwgaW5kaWNlcywgR0xfU1RBVElDX0RSQVcpOwoJCWdsLmRyYXdFbGVtZW50cyhHTF9UUklBTkdMRVMsIDMsIEdMX1VOU0lHTkVEX0lOVCwgREVfTlVMTCk7CgkJZ2wuZGVsZXRlQnVmZmVycygxLCAmbV9pbmRleEJ1ZmZlcik7CgkJbV9pbmRleEJ1ZmZlciA9IDA7Cgl9CgllbHNlIGlmIChtX3RhcmdldEJ1ZmZlciA9PSBUQVJHRVRCVUZGRVJfVkVSVEVYKQoJewoJCS8vIHJlc3BlY2lmeSBhbmQgZGVsZXRlIHZlcnRleCBidWZmZXIKCQlzdGF0aWMgY29uc3QgdGN1OjpWZWM0IGNvbG9yZWRUcmlhbmdsZVs2XSA9CgkJewoJCQl0Y3U6OlZlYzQoMS4wZiwgMC4wZiwgMC4wZiwgMS4wZiksIHRjdTo6VmVjNCgtMC40ZiwgLTAuNGYsIDAuMGYsIDEuMGYpLAoJCQl0Y3U6OlZlYzQoMS4wZiwgMC4wZiwgMC4wZiwgMS4wZiksIHRjdTo6VmVjNCgtMC4yZiwgIDAuNGYsIDAuMGYsIDEuMGYpLAoJCQl0Y3U6OlZlYzQoMS4wZiwgMC4wZiwgMC4wZiwgMS4wZiksIHRjdTo6VmVjNCggMC44ZiwgLTAuMWYsIDAuMGYsIDEuMGYpLAoJCX07CgoJCURFX0FTU0VSVChtX3ZlcnRleEJ1ZmZlciAhPSAwKTsKCgkJZ2wuYnVmZmVyRGF0YShHTF9BUlJBWV9CVUZGRVIsIHNpemVvZihjb2xvcmVkVHJpYW5nbGUpLCBjb2xvcmVkVHJpYW5nbGUsIEdMX1NUQVRJQ19EUkFXKTsKCQlnbC5kcmF3QXJyYXlzKEdMX1RSSUFOR0xFUywgMCwgMyk7CgkJZ2wuZGVsZXRlQnVmZmVycygxLCAmbV92ZXJ0ZXhCdWZmZXIpOwoJCW1fdmVydGV4QnVmZmVyID0gMDsKCX0KCgl3YWl0R0xSZXN1bHRzKCk7Cn0KCnZvaWQgVXBsb2FkV2FpdERyYXdDYXNlOjpsb2dBbmRTZXRUZXN0UmVzdWx0ICh2b2lkKQp7CglpbnQJCXVwbG9hZFN0YWJpbGl6YXRpb247CglpbnQJCXJlbmRlclJlYWRTdGFiaWxpemF0aW9uOwoJaW50CQlyZW5kZXJTdGFiaWxpemF0aW9uOwoJaW50CQlyZWFkU3RhYmlsaXphdGlvbjsKCWJvb2wJdGVtcG9yYWxseVN0YWJsZTsKCgl7CgkJY29uc3QgdGN1OjpTY29wZWRMb2dTZWN0aW9uIHNlY3Rpb24obV90ZXN0Q3R4LmdldExvZygpLCAiU2FtcGxlcyIsICJSZXN1bHQgc2FtcGxlcyIpOwoJCWxvZ1NhbXBsZXMoKTsKCX0KCgl7CgkJY29uc3QgdGN1OjpTY29wZWRMb2dTZWN0aW9uIHNlY3Rpb24obV90ZXN0Q3R4LmdldExvZygpLCAiU3RhYmlsaXphdGlvbiIsICJTYW1wbGUgc3RhYmlsaXR5Iik7CgoJCS8vIGxvZyBzdGFiaWxpemF0aW9uIHBvaW50cwoJCXJlbmRlclJlYWRTdGFiaWxpemF0aW9uCT0gZmluZFN0YWJpbGl6YXRpb25TYW1wbGUoJlJlc3VsdDo6cmVuZGVyUmVhZER1cmF0aW9uLCAiQ29tYmluZWQgZHJhdyBhbmQgcmVhZCIpOwoJCXVwbG9hZFN0YWJpbGl6YXRpb24JCT0gZmluZFN0YWJpbGl6YXRpb25TYW1wbGUoJlJlc3VsdDo6dXBsb2FkRHVyYXRpb24sICJVcGxvYWQgdGltZSIpOwoJCXJlbmRlclN0YWJpbGl6YXRpb24JCT0gZmluZFN0YWJpbGl6YXRpb25TYW1wbGUoJlJlc3VsdDo6cmVuZGVyRHVyYXRpb24sICJEcmF3IGNhbGwgdGltZSIpOwoJCXJlYWRTdGFiaWxpemF0aW9uCQk9IGZpbmRTdGFiaWxpemF0aW9uU2FtcGxlKCZSZXN1bHQ6OnJlYWREdXJhdGlvbiwgIlJlYWRQaXhlbHMgdGltZSIpOwoKCQl0ZW1wb3JhbGx5U3RhYmxlCQk9IHRydWU7CgkJdGVtcG9yYWxseVN0YWJsZQkJJj0gY2hlY2tTYW1wbGVUZW1wb3JhbFN0YWJpbGl0eSgmUmVzdWx0OjpyZW5kZXJSZWFkRHVyYXRpb24sICJDb21iaW5lZCBkcmF3IGFuZCByZWFkIik7CgkJdGVtcG9yYWxseVN0YWJsZQkJJj0gY2hlY2tTYW1wbGVUZW1wb3JhbFN0YWJpbGl0eSgmUmVzdWx0Ojp1cGxvYWREdXJhdGlvbiwgIlVwbG9hZCB0aW1lIik7CgkJdGVtcG9yYWxseVN0YWJsZQkJJj0gY2hlY2tTYW1wbGVUZW1wb3JhbFN0YWJpbGl0eSgmUmVzdWx0OjpyZW5kZXJEdXJhdGlvbiwgIkRyYXcgY2FsbCB0aW1lIik7CgkJdGVtcG9yYWxseVN0YWJsZQkJJj0gY2hlY2tTYW1wbGVUZW1wb3JhbFN0YWJpbGl0eSgmUmVzdWx0OjpyZWFkRHVyYXRpb24sICJSZWFkUGl4ZWxzIHRpbWUiKTsKCX0KCgl7CgkJY29uc3QgdGN1OjpTY29wZWRMb2dTZWN0aW9uIHNlY3Rpb24obV90ZXN0Q3R4LmdldExvZygpLCAiUmVzdWx0cyIsICJSZXN1bHRzIik7CgoJCS8vIENoZWNrIHJlc3VsdCBzYW5pbHkKCQlpZiAodXBsb2FkU3RhYmlsaXphdGlvbiAhPSAwKQoJCQltX3Rlc3RDdHguZ2V0TG9nKCkgPDwgdGN1OjpUZXN0TG9nOjpNZXNzYWdlIDw8ICJXYXJuaW5nISBVcGxvYWQgdGltZXMgYXJlIG5vdCBzdGFibGUsIHRlc3QgcmVzdWx0IG1heSBub3QgYmUgYWNjdXJhdGUuIiA8PCB0Y3U6OlRlc3RMb2c6OkVuZE1lc3NhZ2U7CgkJaWYgKCF0ZW1wb3JhbGx5U3RhYmxlKQoJCQltX3Rlc3RDdHguZ2V0TG9nKCkgPDwgdGN1OjpUZXN0TG9nOjpNZXNzYWdlIDw8ICJXYXJuaW5nISBUaW1lIHNhbXBsZXMgZG8gbm90IHNlZW0gdG8gYmUgdGVtcG9yYWxseSBzdGFibGUsIHNhbXBsZSB0aW1lcyBzZWVtIHRvIGRyaWZ0IHRvIG9uZSBkaXJlY3Rpb24gZHVyaW5nIHRlc3QgZXhlY3V0aW9uLiIgPDwgdGN1OjpUZXN0TG9nOjpFbmRNZXNzYWdlOwoKCQkvLyByZW5kZXIgJiByZWFkCgkJaWYgKHJlbmRlclJlYWRTdGFiaWxpemF0aW9uID09IC0xKQoJCQltX3Rlc3RDdHguZ2V0TG9nKCkgPDwgdGN1OjpUZXN0TG9nOjpNZXNzYWdlIDw8ICJDb21iaW5lZCB0aW1lIHVzZWQgaW4gZHJhdyBjYWxsIGFuZCBSZWFkUGl4ZWxzIGRpZCBub3Qgc3RhYmlsaXplLiIgPDwgdGN1OjpUZXN0TG9nOjpFbmRNZXNzYWdlOwoJCWVsc2UKCQkJbV90ZXN0Q3R4LmdldExvZygpIDw8IHRjdTo6VGVzdExvZzo6SW50ZWdlcigiUmVuZGVyUmVhZFN0YWJpbGl6YXRpb25Qb2ludCIsICJDb21iaW5lZCBkcmF3IGNhbGwgYW5kIFJlYWRQaXhlbHMgY2FsbCB0aW1lIHN0YWJpbGl6YXRpb24gdGltZSIsICJmcmFtZXMiLCBRUF9LRVlfVEFHX1RJTUUsIHJlbmRlclJlYWRTdGFiaWxpemF0aW9uKTsKCgkJLy8gZHJhdyBjYWxsCgkJaWYgKHJlbmRlclN0YWJpbGl6YXRpb24gPT0gLTEpCgkJCW1fdGVzdEN0eC5nZXRMb2coKSA8PCB0Y3U6OlRlc3RMb2c6Ok1lc3NhZ2UgPDwgIlRpbWUgdXNlZCBpbiBkcmF3IGNhbGwgZGlkIG5vdCBzdGFiaWxpemUuIiA8PCB0Y3U6OlRlc3RMb2c6OkVuZE1lc3NhZ2U7CgkJZWxzZQoJCQltX3Rlc3RDdHguZ2V0TG9nKCkgPDwgdGN1OjpUZXN0TG9nOjpJbnRlZ2VyKCJEcmF3Q2FsbFN0YWJpbGl6YXRpb25Qb2ludCIsICJEcmF3IGNhbGwgdGltZSBzdGFiaWxpemF0aW9uIHRpbWUiLCAiZnJhbWVzIiwgUVBfS0VZX1RBR19USU1FLCByZW5kZXJTdGFiaWxpemF0aW9uKTsKCgkJLy8gcmVhZHBpeGVscwoJCWlmIChyZWFkU3RhYmlsaXphdGlvbiA9PSAtMSkKCQkJbV90ZXN0Q3R4LmdldExvZygpIDw8IHRjdTo6VGVzdExvZzo6TWVzc2FnZSA8PCAiVGltZSB1c2VkIGluIFJlYWRQaXhlbHMgZGlkIG5vdCBzdGFiaWxpemUuIiA8PCB0Y3U6OlRlc3RMb2c6OkVuZE1lc3NhZ2U7CgkJZWxzZQoJCQltX3Rlc3RDdHguZ2V0TG9nKCkgPDwgdGN1OjpUZXN0TG9nOjpJbnRlZ2VyKCJSZWFkUGl4ZWxzU3RhYmlsaXphdGlvblBvaW50IiwgIlJlYWRQaXhlbHMgY2FsbCB0aW1lIHN0YWJpbGl6YXRpb24gdGltZSIsICJmcmFtZXMiLCBRUF9LRVlfVEFHX1RJTUUsIHJlYWRTdGFiaWxpemF0aW9uKTsKCgkJLy8gUmVwb3J0IHJlbmRlclJlYWRTdGFiaWxpemF0aW9uCgkJaWYgKHJlbmRlclJlYWRTdGFiaWxpemF0aW9uICE9IC0xKQoJCQltX3Rlc3RDdHguc2V0VGVzdFJlc3VsdChRUF9URVNUX1JFU1VMVF9QQVNTLCBkZTo6dG9TdHJpbmcocmVuZGVyUmVhZFN0YWJpbGl6YXRpb24pLmNfc3RyKCkpOwoJCWVsc2UKCQkJbV90ZXN0Q3R4LnNldFRlc3RSZXN1bHQoUVBfVEVTVF9SRVNVTFRfUEFTUywgZGU6OnRvU3RyaW5nKG1fbnVtTWF4U3dhcHMpLmNfc3RyKCkpOyAvLyBkb24ndCByZXBvcnQgLTEKCX0KfQoKdm9pZCBVcGxvYWRXYWl0RHJhd0Nhc2U6OmxvZ1NhbXBsZXMgKHZvaWQpCnsKCS8vIEludmVyc2UgbV9pdGVyYXRpb25PcmRlcgoKCXN0ZDo6dmVjdG9yPGludD4gcnVuT3JkZXIobV9pdGVyYXRpb25PcmRlci5zaXplKCkpOwoJZm9yIChpbnQgbmR4ID0gMDsgbmR4IDwgKGludCltX2l0ZXJhdGlvbk9yZGVyLnNpemUoKTsgKytuZHgpCgkJcnVuT3JkZXJbbV9pdGVyYXRpb25PcmRlcltuZHhdXSA9IG5keDsKCgkvLyBMb2cgc2FtcGxlcwoKCW1fdGVzdEN0eC5nZXRMb2coKQoJCTw8IHRjdTo6VGVzdExvZzo6U2FtcGxlTGlzdCgiU2FtcGxlcyIsICJTYW1wbGVzIikKCQk8PCB0Y3U6OlRlc3RMb2c6OlNhbXBsZUluZm8KCQk8PCB0Y3U6OlRlc3RMb2c6OlZhbHVlSW5mbygiTnVtU3dhcHMiLAkJIlN3YXBCdWZmZXJzIGJlZm9yZSB1c2UiLAkJCSIiLAkJUVBfU0FNUExFX1ZBTFVFX1RBR19QUkVESUNUT1IpCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIkRlbGF5IiwJCQkiVGltZSBiZWZvcmUgdXNlIiwJCQkJCSJ1cyIsCVFQX1NBTVBMRV9WQUxVRV9UQUdfUFJFRElDVE9SKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJSdW5PcmRlciIsCQkiU2FtcGxlIHJ1biBvcmRlciIsCQkJCQkiIiwJCVFQX1NBTVBMRV9WQUxVRV9UQUdfUFJFRElDVE9SKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJEcmF3UmVhZFRpbWUiLAkiRHJhdyBjYWxsIGFuZCBSZWFkUGl4ZWxzIHRpbWUiLAkidXMiLAlRUF9TQU1QTEVfVkFMVUVfVEFHX1JFU1BPTlNFKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJUb3RhbFRpbWUiLAkJIlRvdGFsIHRpbWUiLAkJCQkJCSJ1cyIsCVFQX1NBTVBMRV9WQUxVRV9UQUdfUkVTUE9OU0UpCgkJPDwgdGN1OjpUZXN0TG9nOjpWYWx1ZUluZm8oIlVwbG9hZCB0aW1lIiwJIlVwbG9hZCB0aW1lIiwJCQkJCQkidXMiLAlRUF9TQU1QTEVfVkFMVUVfVEFHX1JFU1BPTlNFKQoJCTw8IHRjdTo6VGVzdExvZzo6VmFsdWVJbmZvKCJEcmF3Q2FsbFRpbWUiLAkiRHJhdyBjYWxsIHRpbWUiLAkJCQkJInVzIiwJUVBfU0FNUExFX1ZBTFVFX1RBR19SRVNQT05TRSkKCQk8PCB0Y3U6OlRlc3RMb2c6OlZhbHVlSW5mbygiUmVhZFRpbWUiLAkJIlJlYWRQaXhlbHMgdGltZSIsCQkJCQkidXMiLAlRUF9TQU1QTEVfVkFMVUVfVEFHX1JFU1BPTlNFKQoJCTw8IHRjdTo6VGVzdExvZzo6RW5kU2FtcGxlSW5mbzsKCglmb3IgKGludCBzYW1wbGVOZHggPSAwOyBzYW1wbGVOZHggPCAoaW50KW1fc2FtcGxlcy5zaXplKCk7ICsrc2FtcGxlTmR4KQoJCW1fdGVzdEN0eC5nZXRMb2coKQoJCQk8PCB0Y3U6OlRlc3RMb2c6OlNhbXBsZQoJCQk8PCBtX3NhbXBsZXNbc2FtcGxlTmR4XS5udW1GcmFtZXMKCQkJPDwgKGludCltX3Jlc3VsdHNbc2FtcGxlTmR4XS50aW1lQmVmb3JlVXNlCgkJCTw8IHJ1bk9yZGVyW3NhbXBsZU5keF0KCQkJPDwgKGludCltX3Jlc3VsdHNbc2FtcGxlTmR4XS5yZW5kZXJSZWFkRHVyYXRpb24KCQkJPDwgKGludCkobV9yZXN1bHRzW3NhbXBsZU5keF0ucmVuZGVyUmVhZER1cmF0aW9uICsgbV9yZXN1bHRzW3NhbXBsZU5keF0udXBsb2FkRHVyYXRpb24pCgkJCTw8IChpbnQpbV9yZXN1bHRzW3NhbXBsZU5keF0udXBsb2FkRHVyYXRpb24KCQkJPDwgKGludCltX3Jlc3VsdHNbc2FtcGxlTmR4XS5yZW5kZXJEdXJhdGlvbgoJCQk8PCAoaW50KW1fcmVzdWx0c1tzYW1wbGVOZHhdLnJlYWREdXJhdGlvbgoJCQk8PCB0Y3U6OlRlc3RMb2c6OkVuZFNhbXBsZTsKCgltX3Rlc3RDdHguZ2V0TG9nKCkgPDwgdGN1OjpUZXN0TG9nOjpFbmRTYW1wbGVMaXN0Owp9Cgp2b2lkIFVwbG9hZFdhaXREcmF3Q2FzZTo6ZHJhd01pc2MgKHZvaWQpCnsKCWNvbnN0IGdsdzo6RnVuY3Rpb25zJiBnbCA9IG1fY29udGV4dC5nZXRSZW5kZXJDb250ZXh0KCkuZ2V0RnVuY3Rpb25zKCk7CgoJZ2wuYmluZEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIsIG1fbWlzY0J1ZmZlcik7CglzZXR1cFZlcnRleEF0dHJpYnMoKTsKCWdsLmRyYXdBcnJheXMoR0xfVFJJQU5HTEVTLCAwLCBtX251bU1pc2NWZXJ0aWNlcyk7Cn0KCnN0cnVjdCBEaXN0cmlidXRpb25Db21wYXJlUmVzdWx0CnsKCWJvb2wJZXF1YWw7CglmbG9hdAlzdGFuZGFyZERldmlhdGlvbnM7Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgQ29tcGFyZXI+CnN0YXRpYyBmbG9hdCBzdW1PZlJhbmtzIChjb25zdCBzdGQ6OnZlY3RvcjxkZVVpbnQ2ND4mIHRlc3RTYW1wbGVzLCBjb25zdCBzdGQ6OnZlY3RvcjxkZVVpbnQ2ND4mIGFsbFNhbXBsZXMsIGNvbnN0IENvbXBhcmVyJiBjb21wYXJlcikKewoJZmxvYXQgc3VtID0gMDsKCglmb3IgKGludCBzYW1wbGVOZHggPSAwOyBzYW1wbGVOZHggPCAoaW50KXRlc3RTYW1wbGVzLnNpemUoKTsgKytzYW1wbGVOZHgpCgl7CgkJY29uc3QgZGVVaW50NjQJdGVzdFNhbXBsZQkJPSB0ZXN0U2FtcGxlc1tzYW1wbGVOZHhdOwoJCWNvbnN0IGludAkJbG93ZXJJbmRleAkJPSAoaW50KShzdGQ6Omxvd2VyX2JvdW5kKGFsbFNhbXBsZXMuYmVnaW4oKSwgYWxsU2FtcGxlcy5lbmQoKSwgdGVzdFNhbXBsZSwgY29tcGFyZXIpIC0gYWxsU2FtcGxlcy5iZWdpbigpKTsKCQljb25zdCBpbnQJCXVwcGVySW5kZXgJCT0gKGludCkoc3RkOjp1cHBlcl9ib3VuZChhbGxTYW1wbGVzLmJlZ2luKCksIGFsbFNhbXBsZXMuZW5kKCksIHRlc3RTYW1wbGUsIGNvbXBhcmVyKSAtIGFsbFNhbXBsZXMuYmVnaW4oKSk7CgkJY29uc3QgaW50CQlsb3dlclJhbmsJCT0gbG93ZXJJbmRleCArIDE7CS8vIGNvbnZlcnQgemVyby1pbmRleGVkIHRvIHJhbmsKCQljb25zdCBpbnQJCXVwcGVyUmFuawkJPSB1cHBlckluZGV4OwkJLy8gY29udmVydCB6ZXJvLWluZGV4ZWQgdG8gcmFuaywgdXBwZXJJbmRleCBpcyBsYXN0IGVxdWFsICsgMQoJCWNvbnN0IGZsb2F0CQlyYW5rTWlkcG9pbnQJPSAoZmxvYXQpKGxvd2VyUmFuayArIHVwcGVyUmFuaykgLyAyLjBmOwoKCQlzdW0gKz0gcmFua01pZHBvaW50OwoJfQoKCXJldHVybiBzdW07Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBDb21wYXJlcj4Kc3RhdGljIERpc3RyaWJ1dGlvbkNvbXBhcmVSZXN1bHQgZGlzdHJpYnV0aW9uQ29tcGFyZSAoY29uc3Qgc3RkOjp2ZWN0b3I8ZGVVaW50NjQ+JiBvcmRlcmVkT2JzZXJ2YXRpb25zQSwgY29uc3Qgc3RkOjp2ZWN0b3I8ZGVVaW50NjQ+JiBvcmRlcmVkT2JzZXJ2YXRpb25zQiwgY29uc3QgQ29tcGFyZXImIGNvbXBhcmVyKQp7CgkvLyBNYW5ulldoaXRuZXkgVSB0ZXN0CgoJY29uc3QgaW50CQkJCW4xCQkJPSAoaW50KW9yZGVyZWRPYnNlcnZhdGlvbnNBLnNpemUoKTsKCWNvbnN0IGludAkJCQluMgkJCT0gKGludClvcmRlcmVkT2JzZXJ2YXRpb25zQi5zaXplKCk7CglzdGQ6OnZlY3RvcjxkZVVpbnQ2ND4JYWxsU2FtcGxlcwkobjEgKyBuMik7CgoJc3RkOjpjb3B5KG9yZGVyZWRPYnNlcnZhdGlvbnNBLmJlZ2luKCksIG9yZGVyZWRPYnNlcnZhdGlvbnNBLmVuZCgpLCBhbGxTYW1wbGVzLmJlZ2luKCkpOwoJc3RkOjpjb3B5KG9yZGVyZWRPYnNlcnZhdGlvbnNCLmJlZ2luKCksIG9yZGVyZWRPYnNlcnZhdGlvbnNCLmVuZCgpLCBhbGxTYW1wbGVzLmJlZ2luKCkgKyBuMSk7CglzdGQ6OnNvcnQoYWxsU2FtcGxlcy5iZWdpbigpLCBhbGxTYW1wbGVzLmVuZCgpKTsKCgl7CgkJY29uc3QgZmxvYXQJCQkJCVIxCQk9IHN1bU9mUmFua3Mob3JkZXJlZE9ic2VydmF0aW9uc0EsIGFsbFNhbXBsZXMsIGNvbXBhcmVyKTsKCgkJY29uc3QgZmxvYXQJCQkJCVUxCQk9IChmbG9hdCkobjEqbjIgKyBuMSoobjEgKyAxKS8yKSAtIFIxOwoJCWNvbnN0IGZsb2F0CQkJCQlVMgkJPSAoZmxvYXQpKG4xICogbjIpIC0gVTE7CgkJY29uc3QgZmxvYXQJCQkJCVUJCT0gZGU6Om1pbihVMSwgVTIpOwoKCQkvLyBcbm90ZTogc2FtcGxlIHNpemVzIG1pZ2h0IG5vdCBiZSBsYXJnZSBlbm91Z2ggdG8gZXhwZWN0IG5vcm1hbCBkaXN0cmlidXRpb24gYnV0IHdlIGRvIGl0IGFueXdheQoKCQljb25zdCBmbG9hdAkJCQkJbVUJCT0gKGZsb2F0KShuMSAqIG4yKSAvIDIuMGY7CgkJY29uc3QgZmxvYXQJCQkJCXNpZ21hVQk9IGRlRmxvYXRTcXJ0KChmbG9hdCkobjEqbjIqKG4xK24yKzEpKSAvIDEyLjBmKTsKCQljb25zdCBmbG9hdAkJCQkJegkJPSAoVSAtIG1VKSAvIHNpZ21hVTsKCgkJRGlzdHJpYnV0aW9uQ29tcGFyZVJlc3VsdAlyZXN1bHQ7CgoJCXJlc3VsdC5lcXVhbAkJCQk9IChkZTo6YWJzKHopIDw9IDEuOTZmKTsgLy8gYWNjZXB0IHdpdGhpbiA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbAoJCXJlc3VsdC5zdGFuZGFyZERldmlhdGlvbnMJPSB6OwoKCQlyZXR1cm4gcmVzdWx0OwoJfQp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4Kc3RydWN0IFRocmVzaG9sZENvbXBhcmVyCnsKCWZsb2F0CXJlbGF0aXZlVGhyZXNob2xkOwoJVAkJYWJzb2x1dGVUaHJlc2hvbGQ7CgoJYm9vbCBvcGVyYXRvcigpIChjb25zdCBUJiBhLCBjb25zdCBUJiBiKSBjb25zdAoJewoJCWNvbnN0IGZsb2F0IGRpZmYgPSBkZTo6YWJzKChmbG9hdClhIC0gKGZsb2F0KWIpOwoKCQkvLyB0aHJlc2hvbGRzCgkJaWYgKGRpZmYgPD0gKGZsb2F0KWFic29sdXRlVGhyZXNob2xkKQoJCQlyZXR1cm4gZmFsc2U7CgkJaWYgKGRpZmYgPD0gZmxvYXQoYSkqcmVsYXRpdmVUaHJlc2hvbGQgfHwKCQkJZGlmZiA8PSBmbG9hdChiKSpyZWxhdGl2ZVRocmVzaG9sZCkKCQkJcmV0dXJuIGZhbHNlOwoKCQkvLyBjbXAKCQlyZXR1cm4gYSA8IGI7Cgl9Cn07CgppbnQgVXBsb2FkV2FpdERyYXdDYXNlOjpmaW5kU3RhYmlsaXphdGlvblNhbXBsZSAoZGVVaW50NjQgKFVwbG9hZFdhaXREcmF3Q2FzZTo6UmVzdWx0OjoqdGFyZ2V0KSwgY29uc3QgY2hhciogZGVzY3JpcHRpb24pCnsKCXN0ZDo6dmVjdG9yPHN0ZDo6dmVjdG9yPGRlVWludDY0PiA+CXNhbXBsZU9ic2VydmF0aW9ucyhtX251bU1heFN3YXBzKzEpOwoJVGhyZXNob2xkQ29tcGFyZXI8ZGVVaW50NjQ+CQkJY29tcGFyZXI7CgoJY29tcGFyZXIucmVsYXRpdmVUaHJlc2hvbGQgPSAwLjE1ZjsJLy8gMTUlCgljb21wYXJlci5hYnNvbHV0ZVRocmVzaG9sZCA9IDEwMDsJLy8gKHVzKSwgYXNzdW1lZCBzYW1wbGluZyBwcmVjaXNpb24KCgkvLyBnZXQgb2JzZXJ2YXRpb25zIGFuZCBvcmRlciB0aGVtCgoJZm9yIChpbnQgc3dhcE5keCA9IDA7IHN3YXBOZHggPD0gbV9udW1NYXhTd2FwczsgKytzd2FwTmR4KQoJewoJCWludCBpbnNlcnROZHggPSAwOwoKCQlzYW1wbGVPYnNlcnZhdGlvbnNbc3dhcE5keF0ucmVzaXplKG1fbnVtU2FtcGxlc1BlclN3YXApOwoKCQlmb3IgKGludCBuZHggPSAwOyBuZHggPCAoaW50KW1fc2FtcGxlcy5zaXplKCk7ICsrbmR4KQoJCQlpZiAobV9zYW1wbGVzW25keF0ubnVtRnJhbWVzID09IHN3YXBOZHgpCgkJCQlzYW1wbGVPYnNlcnZhdGlvbnNbc3dhcE5keF1baW5zZXJ0TmR4KytdID0gbV9yZXN1bHRzW25keF0uKnRhcmdldDsKCgkJREVfQVNTRVJUKGluc2VydE5keCA9PSBtX251bVNhbXBsZXNQZXJTd2FwKTsKCgkJc3RkOjpzb3J0KHNhbXBsZU9ic2VydmF0aW9uc1tzd2FwTmR4XS5iZWdpbigpLCBzYW1wbGVPYnNlcnZhdGlvbnNbc3dhcE5keF0uZW5kKCkpOwoJfQoKCS8vIGZpbmQgc3RhYmlsaXphdGlvbiBwb2ludAoKCWZvciAoaW50IHNhbXBsZU5keCA9IG1fbnVtTWF4U3dhcHMtMTsgc2FtcGxlTmR4ICE9IC0xOyAtLXNhbXBsZU5keCApCgl7CgkJLy8gRGlzdHJpYnV0aW9uIGlzIGVxdWFsIHRvIGFsbCBmb2xsb3dpbmcgZGlzdHJpYnV0aW9ucwoJCWZvciAoaW50IGNtcFRhcmdldERpc3RyaWJ1dGlvbiA9IHNhbXBsZU5keCsxOyBjbXBUYXJnZXREaXN0cmlidXRpb24gPD0gbV9udW1NYXhTd2FwczsgKytjbXBUYXJnZXREaXN0cmlidXRpb24pCgkJewoJCQkvLyBTdGFibGUgc2VjdGlvbiBlbmRzIGhlcmU/CgkJCWNvbnN0IERpc3RyaWJ1dGlvbkNvbXBhcmVSZXN1bHQgcmVzdWx0ID0gZGlzdHJpYnV0aW9uQ29tcGFyZShzYW1wbGVPYnNlcnZhdGlvbnNbc2FtcGxlTmR4XSwgc2FtcGxlT2JzZXJ2YXRpb25zW2NtcFRhcmdldERpc3RyaWJ1dGlvbl0sIGNvbXBhcmVyKTsKCQkJaWYgKCFyZXN1bHQuZXF1YWwpCgkJCXsKCQkJCS8vIExhc3QgdHdvIHNhbXBsZXMgYXJlIG5vdCBlcXVhbD8gU2FtcGxlcyBuZXZlciBzdGFiaWxpemVkCgkJCQlpZiAoc2FtcGxlTmR4ID09IG1fbnVtTWF4U3dhcHMtMSkKCQkJCXsKCQkJCQltX3Rlc3RDdHguZ2V0TG9nKCkKCQkJCQkJPDwgdGN1OjpUZXN0TG9nOjpNZXNzYWdlCgkJCQkJCTw8IGRlc2NyaXB0aW9uIDw8ICI6IFNhbXBsZXMgd2l0aCBzd2FwIGNvdW50ICIgPDwgc2FtcGxlTmR4IDw8ICIgYW5kICIgPDwgY21wVGFyZ2V0RGlzdHJpYnV0aW9uIDw8ICIgZG8gbm90IHNlZW0gdG8gaGF2ZSB0aGUgc2FtZSBkaXN0cmlidXRpb246XG4iCgkJCQkJCTw8ICJcdERpZmZlcmVuY2UgaW4gc3RhbmRhcmQgZGV2aWF0aW9uczogIiA8PCByZXN1bHQuc3RhbmRhcmREZXZpYXRpb25zIDw8ICJcbiIKCQkJCQkJPDwgIlx0U3dhcCBjb3VudCAiIDw8IHNhbXBsZU5keCA8PCAiIG1lZGlhbjogIiA8PCBsaW5lYXJTYW1wbGUoc2FtcGxlT2JzZXJ2YXRpb25zW3NhbXBsZU5keF0sIDAuNWYpIDw8ICJcbiIKCQkJCQkJPDwgIlx0U3dhcCBjb3VudCAiIDw8IGNtcFRhcmdldERpc3RyaWJ1dGlvbiA8PCAiIG1lZGlhbjogIiA8PCBsaW5lYXJTYW1wbGUoc2FtcGxlT2JzZXJ2YXRpb25zW2NtcFRhcmdldERpc3RyaWJ1dGlvbl0sIDAuNWYpIDw8ICJcbiIKCQkJCQkJPDwgdGN1OjpUZXN0TG9nOjpFbmRNZXNzYWdlOwoJCQkJCXJldHVybiAtMTsKCQkJCX0KCQkJCWVsc2UKCQkJCXsKCQkJCQltX3Rlc3RDdHguZ2V0TG9nKCkKCQkJCQkJPDwgdGN1OjpUZXN0TG9nOjpNZXNzYWdlCgkJCQkJCTw8IGRlc2NyaXB0aW9uIDw8ICI6IFNhbXBsZXMgd2l0aCBzd2FwIGNvdW50ICIgPDwgc2FtcGxlTmR4IDw8ICIgYW5kICIgPDwgY21wVGFyZ2V0RGlzdHJpYnV0aW9uIDw8ICIgZG8gbm90IHNlZW0gdG8gaGF2ZSB0aGUgc2FtZSBkaXN0cmlidXRpb246XG4iCgkJCQkJCTw8ICJcdFNhbXBsZXMgd2l0aCBzd2FwIGNvdW50ICIgPDwgc2FtcGxlTmR4IDw8ICIgYXJlIG5vdCBwYXJ0IG9mIHRoZSB0YWlsIG9mIHN0YWJsZSByZXN1bHRzLlxuIgoJCQkJCQk8PCAiXHREaWZmZXJlbmNlIGluIHN0YW5kYXJkIGRldmlhdGlvbnM6ICIgPDwgcmVzdWx0LnN0YW5kYXJkRGV2aWF0aW9ucyA8PCAiXG4iCgkJCQkJCTw8ICJcdFN3YXAgY291bnQgIiA8PCBzYW1wbGVOZHggPDwgIiBtZWRpYW46ICIgPDwgbGluZWFyU2FtcGxlKHNhbXBsZU9ic2VydmF0aW9uc1tzYW1wbGVOZHhdLCAwLjVmKSA8PCAiXG4iCgkJCQkJCTw8ICJcdFN3YXAgY291bnQgIiA8PCBjbXBUYXJnZXREaXN0cmlidXRpb24gPDwgIiBtZWRpYW46ICIgPDwgbGluZWFyU2FtcGxlKHNhbXBsZU9ic2VydmF0aW9uc1tjbXBUYXJnZXREaXN0cmlidXRpb25dLCAwLjVmKSA8PCAiXG4iCgkJCQkJCTw8IHRjdTo6VGVzdExvZzo6RW5kTWVzc2FnZTsKCgkJCQkJcmV0dXJuIHNhbXBsZU5keCsxOwoJCQkJfQoJCQl9CgkJfQoJfQoKCW1fdGVzdEN0eC5nZXRMb2coKQoJCTw8IHRjdTo6VGVzdExvZzo6TWVzc2FnZQoJCTw8IGRlc2NyaXB0aW9uIDw8ICI6IEFsbCBzYW1wbGVzIHNlZW0gdG8gaGF2ZSB0aGUgc2FtZSBkaXN0cmlidXRpb24iCgkJPDwgdGN1OjpUZXN0TG9nOjpFbmRNZXNzYWdlOwoKCS8vIGFsbCBkaXN0cmlidXRpb25zIGVxdWFsCglyZXR1cm4gMDsKfQoKYm9vbCBVcGxvYWRXYWl0RHJhd0Nhc2U6OmNoZWNrU2FtcGxlVGVtcG9yYWxTdGFiaWxpdHkgKGRlVWludDY0IChVcGxvYWRXYWl0RHJhd0Nhc2U6OlJlc3VsdDo6KnRhcmdldCksIGNvbnN0IGNoYXIqIGRlc2NyaXB0aW9uKQp7CgkvLyBUcnkgdG8gZmluZCBjb3JyZWxhdGlvbiB3aXRoIHNhbXBsZSBvcmRlciBhbmQgc2FtcGxlIHRpbWVzCgoJY29uc3QgaW50CQkJCQkJbnVtRGF0YVBvaW50cwk9IChpbnQpbV9pdGVyYXRpb25PcmRlci5zaXplKCk7CglzdGQ6OnZlY3Rvcjx0Y3U6OlZlYzI+CQkJZGF0YVBvaW50cwkJKG1faXRlcmF0aW9uT3JkZXIuc2l6ZSgpKTsKCUxpbmVQYXJhbWV0ZXJzV2l0aENvbmZpZGVuY2UJbGluZUZpdDsKCglmb3IgKGludCBuZHggPSAwOyBuZHggPCAoaW50KW1faXRlcmF0aW9uT3JkZXIuc2l6ZSgpOyArK25keCkKCXsKCQlkYXRhUG9pbnRzW21faXRlcmF0aW9uT3JkZXJbbmR4XV0ueCgpID0gKGZsb2F0KW5keDsKCQlkYXRhUG9pbnRzW21faXRlcmF0aW9uT3JkZXJbbmR4XV0ueSgpID0gKGZsb2F0KShtX3Jlc3VsdHNbbV9pdGVyYXRpb25PcmRlcltuZHhdXS4qdGFyZ2V0KTsKCX0KCglsaW5lRml0ID0gdGhlaWxTZW5TaWVnZWxMaW5lYXJSZWdyZXNzaW9uKGRhdGFQb2ludHMsIDAuNmYpOwoKCS8vIERpZmZlcmVuY2Ugb2YgbW9yZSB0aGFuIDI1JSBvZiB0aGUgb2Zmc2V0IGFsb25nIHRoZSB3aG9sZSBzYW1wbGUgcmFuZ2UKCWlmIChkZTo6YWJzKGxpbmVGaXQuY29lZmZpY2llbnQpICogKGZsb2F0KW51bURhdGFQb2ludHMgPiBkZTo6YWJzKGxpbmVGaXQub2Zmc2V0KSAqIDAuMjVmKQoJewoJCW1fdGVzdEN0eC5nZXRMb2coKQoJCQk8PCB0Y3U6OlRlc3RMb2c6Ok1lc3NhZ2UKCQkJPDwgZGVzY3JpcHRpb24gPDwgIjogQ29ycmVsYXRpb24gd2l0aCBkYXRhIHBvaW50IG9ic2VydmF0aW9uIG9yZGVyIGFuZCByZXN1bHQgdGltZS4gUmVzdWx0cyBhcmUgbm90IHRlbXBvcmFsbHkgc3RhYmxlLCBvYnNlcnZhdGlvbnMgYXJlIG5vdCBpbmRlcGVuZGVudC5cbiIKCQkJPDwgIlx0Q29lZmZpY2llbnQ6ICIgPDwgbGluZUZpdC5jb2VmZmljaWVudCA8PCAiICh1cyAvIG9ic2VydmF0aW9uKVxuIgoJCQk8PCB0Y3U6OlRlc3RMb2c6OkVuZE1lc3NhZ2U7CgoJCXJldHVybiBmYWxzZTsKCX0KCWVsc2UKCQlyZXR1cm4gdHJ1ZTsKfQoKfSAvLyBhbm9ueW1vdXMKCkJ1ZmZlckRhdGFVcGxvYWRUZXN0czo6QnVmZmVyRGF0YVVwbG9hZFRlc3RzIChDb250ZXh0JiBjb250ZXh0KQoJOiBUZXN0Q2FzZUdyb3VwKGNvbnRleHQsICJkYXRhX3VwbG9hZCIsICJCdWZmZXIgZGF0YSB1cGxvYWQgcGVyZm9ybWFuY2UgdGVzdHMiKQp7Cn0KCkJ1ZmZlckRhdGFVcGxvYWRUZXN0czo6fkJ1ZmZlckRhdGFVcGxvYWRUZXN0cyAodm9pZCkKewp9Cgp2b2lkIEJ1ZmZlckRhdGFVcGxvYWRUZXN0czo6aW5pdCAodm9pZCkKewoJc3RhdGljIGNvbnN0IHN0cnVjdCBCdWZmZXJVc2FnZQoJewoJCWNvbnN0IGNoYXIqIG5hbWU7CgkJZGVVaW50MzIJdXNhZ2U7CgkJYm9vbAkJcHJpbWFyeVVzYWdlOwoJfSBidWZmZXJVc2FnZXNbXSA9Cgl7CgkJeyAic3RyZWFtX2RyYXciLAlHTF9TVFJFQU1fRFJBVywJCXRydWUJfSwKCQl7ICJzdHJlYW1fcmVhZCIsCUdMX1NUUkVBTV9SRUFELAkJZmFsc2UJfSwKCQl7ICJzdHJlYW1fY29weSIsCUdMX1NUUkVBTV9DT1BZLAkJZmFsc2UJfSwKCQl7ICJzdGF0aWNfZHJhdyIsCUdMX1NUQVRJQ19EUkFXLAkJdHJ1ZQl9LAoJCXsgInN0YXRpY19yZWFkIiwJR0xfU1RBVElDX1JFQUQsCQlmYWxzZQl9LAoJCXsgInN0YXRpY19jb3B5IiwJR0xfU1RBVElDX0NPUFksCQlmYWxzZQl9LAoJCXsgImR5bmFtaWNfZHJhdyIsCUdMX0RZTkFNSUNfRFJBVywJdHJ1ZQl9LAoJCXsgImR5bmFtaWNfcmVhZCIsCUdMX0RZTkFNSUNfUkVBRCwJZmFsc2UJfSwKCQl7ICJkeW5hbWljX2NvcHkiLAlHTF9EWU5BTUlDX0NPUFksCWZhbHNlCX0sCgl9OwoKCXRjdTo6VGVzdENhc2VHcm91cCogY29uc3QgcmVmZXJlbmNlR3JvdXAJCQk9IG5ldyB0Y3U6OlRlc3RDYXNlR3JvdXAobV90ZXN0Q3R4LCAicmVmZXJlbmNlIiwJCQkiUmVmZXJlbmNlIGZ1bmN0aW9ucyIpOwoJdGN1OjpUZXN0Q2FzZUdyb3VwKiBjb25zdCBmdW5jdGlvbkNhbGxHcm91cAkJCT0gbmV3IHRjdTo6VGVzdENhc2VHcm91cChtX3Rlc3RDdHgsICJmdW5jdGlvbl9jYWxsIiwJCSJGdW5jdGlvbiBjYWxsIHRpbWluZyIpOwoJdGN1OjpUZXN0Q2FzZUdyb3VwKiBjb25zdCBtb2RpZnlBZnRlclVzZUdyb3VwCQk9IG5ldyB0Y3U6OlRlc3RDYXNlR3JvdXAobV90ZXN0Q3R4LCAibW9kaWZ5X2FmdGVyX3VzZSIsCQkiRnVuY3Rpb24gY2FsbCB0aW1lIGFmdGVyIGJ1ZmZlciBoYXMgYmVlbiB1c2VkIik7Cgl0Y3U6OlRlc3RDYXNlR3JvdXAqIGNvbnN0IHJlbmRlckFmdGVyVXBsb2FkR3JvdXAJPSBuZXcgdGN1OjpUZXN0Q2FzZUdyb3VwKG1fdGVzdEN0eCwgInJlbmRlcl9hZnRlcl91cGxvYWQiLAkiRnVuY3Rpb24gY2FsbCB0aW1lIG9mIGRyYXcgY29tbWFuZHMgYWZ0ZXIgYnVmZmVyIGhhcyBiZWVuIG1vZGlmaWVkIik7CgoJYWRkQ2hpbGQocmVmZXJlbmNlR3JvdXApOwoJYWRkQ2hpbGQoZnVuY3Rpb25DYWxsR3JvdXApOwoJYWRkQ2hpbGQobW9kaWZ5QWZ0ZXJVc2VHcm91cCk7CglhZGRDaGlsZChyZW5kZXJBZnRlclVwbG9hZEdyb3VwKTsKCgkvLyAucmVmZXJlbmNlCgl7CgkJc3RhdGljIGNvbnN0IHN0cnVjdCBCdWZmZXJTaXplUmFuZ2UKCQl7CgkJCWNvbnN0IGNoYXIqIG5hbWU7CgkJCWludAkJCW1pbkJ1ZmZlclNpemU7CgkJCWludAkJCW1heEJ1ZmZlclNpemU7CgkJCWludAkJCW51bVNhbXBsZXM7CgkJCWJvb2wJCWxhcmdlQnVmZmVyc0Nhc2U7CgkJfSBzaXplUmFuZ2VzW10gPQoJCXsKCQkJeyAic21hbGxfYnVmZmVycyIsIDAsCQkxIDw8IDE4LAk2NCwJCWZhbHNlCX0sIC8vICE8IDBrQiAtIDI1NmtCCgkJCXsgImxhcmdlX2J1ZmZlcnMiLCAxIDw8IDE4LAkxIDw8IDI0LAkzMiwJCXRydWUJfSwgLy8gITwgMjU2a0IgLSAxNk1CCgkJfTsKCgkJZm9yIChpbnQgYnVmZmVyU2l6ZVJhbmdlTmR4ID0gMDsgYnVmZmVyU2l6ZVJhbmdlTmR4IDwgREVfTEVOR1RIX09GX0FSUkFZKHNpemVSYW5nZXMpOyArK2J1ZmZlclNpemVSYW5nZU5keCkKCQl7CgkJCXJlZmVyZW5jZUdyb3VwLT5hZGRDaGlsZChuZXcgUmVmZXJlbmNlTWVtY3B5Q2FzZShtX2NvbnRleHQsCgkJCQkJCQkJCQkJCQkJCSBzdGQ6OnN0cmluZygibWVtY3B5XyIpLmFwcGVuZChzaXplUmFuZ2VzW2J1ZmZlclNpemVSYW5nZU5keF0ubmFtZSkuY19zdHIoKSwKCQkJCQkJCQkJCQkJCQkJICJUZXN0IG1lbWNweSBwZXJmb3JtYW5jZSIsCgkJCQkJCQkJCQkJCQkJCSBzaXplUmFuZ2VzW2J1ZmZlclNpemVSYW5nZU5keF0ubWluQnVmZmVyU2l6ZSwKCQkJCQkJCQkJCQkJCQkJIHNpemVSYW5nZXNbYnVmZmVyU2l6ZVJhbmdlTmR4XS5tYXhCdWZmZXJTaXplLAoJCQkJCQkJCQkJCQkJCQkgc2l6ZVJhbmdlc1tidWZmZXJTaXplUmFuZ2VOZHhdLm51bVNhbXBsZXMsCgkJCQkJCQkJCQkJCQkJCSBzaXplUmFuZ2VzW2J1ZmZlclNpemVSYW5nZU5keF0ubGFyZ2VCdWZmZXJzQ2FzZSkpOwoJCX0KCX0KCgkvLyAuZnVuY3Rpb25fY2FsbAoJewoJCWNvbnN0IGludCBtaW5CdWZmZXJTaXplCQk9IDA7CQkvLyAhPCAwa2lCCgkJY29uc3QgaW50IG1heEJ1ZmZlclNpemUJCT0gMSA8PCAyNDsJLy8gITwgMTZNaUIKCQljb25zdCBpbnQgbnVtRGF0YVNhbXBsZXMJPSAyNTsKCQljb25zdCBpbnQgbnVtTWFwU2FtcGxlcwkJPSAyNTsKCgkJdGN1OjpUZXN0Q2FzZUdyb3VwKiBjb25zdCBidWZmZXJEYXRhTWV0aG9kR3JvdXAJCT0gbmV3IHRjdTo6VGVzdENhc2VHcm91cChtX3Rlc3RDdHgsICJidWZmZXJfZGF0YSIsICJVc2UgZ2xCdWZmZXJEYXRhIik7CgkJdGN1OjpUZXN0Q2FzZUdyb3VwKiBjb25zdCBidWZmZXJTdWJEYXRhTWV0aG9kR3JvdXAJPSBuZXcgdGN1OjpUZXN0Q2FzZUdyb3VwKG1fdGVzdEN0eCwgImJ1ZmZlcl9zdWJfZGF0YSIsICJVc2UgZ2xCdWZmZXJTdWJEYXRhIik7CgkJdGN1OjpUZXN0Q2FzZUdyb3VwKiBjb25zdCBtYXBCdWZmZXJSYW5nZU1ldGhvZEdyb3VwCT0gbmV3IHRjdTo6VGVzdENhc2VHcm91cChtX3Rlc3RDdHgsICJtYXBfYnVmZmVyX3JhbmdlIiwgIlVzZSBnbE1hcEJ1ZmZlclJhbmdlIik7CgoJCWZ1bmN0aW9uQ2FsbEdyb3VwLT5hZGRDaGlsZChidWZmZXJEYXRhTWV0aG9kR3JvdXApOwoJCWZ1bmN0aW9uQ2FsbEdyb3VwLT5hZGRDaGlsZChidWZmZXJTdWJEYXRhTWV0aG9kR3JvdXApOwoJCWZ1bmN0aW9uQ2FsbEdyb3VwLT5hZGRDaGlsZChtYXBCdWZmZXJSYW5nZU1ldGhvZEdyb3VwKTsKCgkJLy8gLmJ1ZmZlcl9kYXRhCgkJewoJCQlzdGF0aWMgY29uc3Qgc3RydWN0IFRhcmdldENhc2UKCQkJewoJCQkJdGN1OjpUZXN0Q2FzZUdyb3VwKgkJCQlncm91cDsKCQkJCUJ1ZmZlckRhdGFVcGxvYWRDYXNlOjpDYXNlVHlwZQljYXNlVHlwZTsKCQkJCWJvb2wJCQkJCQkJYWxsVXNhZ2VzOwoJCQl9IHRhcmdldENhc2VzW10gPQoJCQl7CgkJCQl7IG5ldyB0Y3U6OlRlc3RDYXNlR3JvdXAobV90ZXN0Q3R4LCAibmV3X2J1ZmZlciIsCQkJCSJUYXJnZXQgbmV3IGJ1ZmZlciIpLAkJCQkJCQlCdWZmZXJEYXRhVXBsb2FkQ2FzZTo6Q0FTRV9ORVdfQlVGRkVSLAkJCXRydWUJfSwKCQkJCXsgbmV3IHRjdTo6VGVzdENhc2VHcm91cChtX3Rlc3RDdHgsICJ1bnNwZWNpZmllZF9idWZmZXIiLAkJIlRhcmdldCBuZXcgdW5zcGVjaWZpZWQgYnVmZmVyIiksCQkJCUJ1ZmZlckRhdGFVcGxvYWRDYXNlOjpDQVNFX1VOU1BFQ0lGSUVEX0JVRkZFUiwJdHJ1ZQl9LAoJCQkJeyBuZXcgdGN1OjpUZXN0Q2FzZUdyb3VwKG1fdGVzdEN0eCwgInNwZWNpZmllZF9idWZmZXIiLAkJCSJUYXJnZXQgbmV3IHNwZWNpZmllZCBidWZmZXIiKSwJCQkJCUJ1ZmZlckRhdGFVcGxvYWRDYXNlOjpDQVNFX1NQRUNJRklFRF9CVUZGRVIsCXRydWUJfSwKCQkJCXsgbmV3IHRjdTo6VGVzdENhc2VHcm91cChtX3Rlc3RDdHgsICJ1c2VkX2J1ZmZlciIsCQkJCSJUYXJnZXQgYnVmZmVyIHRoYXQgd2FzIHVzZWQgaW4gZHJhdyIpLAkJCUJ1ZmZlckRhdGFVcGxvYWRDYXNlOjpDQVNFX1VTRURfQlVGRkVSLAkJCXRydWUJfSwKCQkJCXsgbmV3IHRjdTo6VGVzdENhc2VHcm91cChtX3Rlc3RDdHgsICJsYXJnZXJfdXNlZF9idWZmZXIiLAkJIlRhcmdldCBsYXJnZXIgYnVmZmVyIHRoYXQgd2FzIHVzZWQgaW4gZHJhdyIpLAlCdWZmZXJEYXRhVXBsb2FkQ2FzZTo6Q0FTRV9VU0VEX0xBUkdFUl9CVUZGRVIsCWZhbHNlCX0sCgkJCX07CgoJCQlmb3IgKGludCB0YXJnZXROZHggPSAwOyB0YXJnZXROZHggPCBERV9MRU5HVEhfT0ZfQVJSQVkodGFyZ2V0Q2FzZXMpOyArK3RhcmdldE5keCkKCQkJewoJCQkJYnVmZmVyRGF0YU1ldGhvZEdyb3VwLT5hZGRDaGlsZCh0YXJnZXRDYXNlc1t0YXJnZXROZHhdLmdyb3VwKTsKCgkJCQlmb3IgKGludCB1c2FnZU5keCA9IDA7IHVzYWdlTmR4IDwgREVfTEVOR1RIX09GX0FSUkFZKGJ1ZmZlclVzYWdlcyk7ICsrdXNhZ2VOZHgpCgkJCQkJaWYgKGJ1ZmZlclVzYWdlc1t1c2FnZU5keF0ucHJpbWFyeVVzYWdlIHx8IHRhcmdldENhc2VzW3RhcmdldE5keF0uYWxsVXNhZ2VzKQoJCQkJCQl0YXJnZXRDYXNlc1t0YXJnZXROZHhdLmdyb3VwLT5hZGRDaGlsZChuZXcgQnVmZmVyRGF0YVVwbG9hZENhc2UobV9jb250ZXh0LAoJCQkJCQkJCQkJCQkJCQkJCQkJCQkJc3RkOjpzdHJpbmcoInVzYWdlXyIpLmFwcGVuZChidWZmZXJVc2FnZXNbdXNhZ2VOZHhdLm5hbWUpLmNfc3RyKCksCgkJCQkJCQkJCQkJCQkJCQkJCQkJCQlzdGQ6OnN0cmluZygiVGVzdCB3aXRoIHVzYWdlID0gIikuYXBwZW5kKGJ1ZmZlclVzYWdlc1t1c2FnZU5keF0ubmFtZSkuY19zdHIoKSwKCQkJCQkJCQkJCQkJCQkJCQkJCQkJCW1pbkJ1ZmZlclNpemUsCgkJCQkJCQkJCQkJCQkJCQkJCQkJCQltYXhCdWZmZXJTaXplLAoJCQkJCQkJCQkJCQkJCQkJCQkJCQkJbnVtRGF0YVNhbXBsZXMsCgkJCQkJCQkJCQkJCQkJCQkJCQkJCQlidWZmZXJVc2FnZXNbdXNhZ2VOZHhdLnVzYWdlLAoJCQkJCQkJCQkJCQkJCQkJCQkJCQkJdGFyZ2V0Q2FzZXNbdGFyZ2V0TmR4XS5jYXNlVHlwZSkpOwoJCQl9CgkJfQoKCQkvLyAuYnVmZmVyX3N1Yl9kYXRhCgkJewoJCQlzdGF0aWMgY29uc3Qgc3RydWN0IEZsYWdDYXNlCgkJCXsKCQkJCXRjdTo6VGVzdENhc2VHcm91cCoJCQkJCWdyb3VwOwoJCQkJQnVmZmVyU3ViRGF0YVVwbG9hZENhc2U6OkNhc2VUeXBlCXBhcmVudENhc2U7CgkJCQlib29sCQkJCQkJCQlhbGxVc2FnZXM7CgkJCQlpbnQJCQkJCQkJCQlmbGFnczsKCQkJfSBmbGFnQ2FzZXNbXSA9CgkJCXsKCQkJCXsgbmV3IHRjdTo6VGVzdENhc2VHcm91cChtX3Rlc3RDdHgsICJ1c2VkX2J1ZmZlcl9mdWxsX3VwbG9hZCIsCQkJCQkgICAgIiIpLAkJCQkJCQkJCQkJCQkJCUJ1ZmZlclN1YkRhdGFVcGxvYWRDYXNlOjpDQVNFX1VTRURfQlVGRkVSLAl0cnVlLAlCdWZmZXJTdWJEYXRhVXBsb2FkQ2FzZTo6RkxBR19GVUxMX1VQTE9BRAkJCQkJCQkJCQkJCQkJCX0sCgkJCQl7IG5ldyB0Y3U6OlRlc3RDYXNlR3JvdXAobV90ZXN0Q3R4LCAidXNlZF9idWZmZXJfaW52YWxpZGF0ZV9iZWZvcmVfZnVsbF91cGxvYWQiLCAgICAiQ2xlYXIgYnVmZmVyIHdpdGggYnVmZmVyRGF0YSguLi4sTlVMTCkgYmVmb3JlIHN1YiBkYXRhIGNhbGwiKSwJQnVmZmVyU3ViRGF0YVVwbG9hZENhc2U6OkNBU0VfVVNFRF9CVUZGRVIsCWZhbHNlLAlCdWZmZXJTdWJEYXRhVXBsb2FkQ2FzZTo6RkxBR19GVUxMX1VQTE9BRCAgICB8IEJ1ZmZlclN1YkRhdGFVcGxvYWRDYXNlOjpGTEFHX0lOVkFMSURBVEVfQkVGT1JFX1VTRQl9LAoJCQkJeyBuZXcgdGN1OjpUZXN0Q2FzZUdyb3VwKG1fdGVzdEN0eCwgInVzZWRfYnVmZmVyX3BhcnRpYWxfdXBsb2FkIiwgICAgICAgICAgICAgICAgICAgIiIpLAkJCQkJCQkJCQkJCQkJCUJ1ZmZlclN1YkRhdGFVcGxvYWRDYXNlOjpDQVNFX1VTRURfQlVGRkVSLAl0cnVlLAlCdWZmZXJTdWJEYXRhVXBsb2FkQ2FzZTo6RkxBR19QQVJUSUFMX1VQTE9BRAkJCQkJCQkJCQkJCQkJfSwKCQkJCXsgbmV3IHRjdTo6VGVzdENhc2VHcm91cChtX3Rlc3RDdHgsICJ1c2VkX2J1ZmZlcl9pbnZhbGlkYXRlX2JlZm9yZV9wYXJ0aWFsX3VwbG9hZCIsICJDbGVhciBidWZmZXIgd2l0aCBidWZmZXJEYXRhKC4uLixOVUxMKSBiZWZvcmUgc3ViIGRhdGEgY2FsbCIpLAlCdWZmZXJTdWJEYXRhVXBsb2FkQ2FzZTo6Q0FTRV9VU0VEX0JVRkZFUiwJZmFsc2UsCUJ1ZmZlclN1YkRhdGFVcGxvYWRDYXNlOjpGTEFHX1BBUlRJQUxfVVBMT0FEIHwgQnVmZmVyU3ViRGF0YVVwbG9hZENhc2U6OkZMQUdfSU5WQUxJREFURV9CRUZPUkVfVVNFCX0sCgkJCX07CgoJCQlmb3IgKGludCBmbGFnTmR4ID0gMDsgZmxhZ05keCA8IERFX0xFTkdUSF9PRl9BUlJBWShmbGFnQ2FzZXMpOyArK2ZsYWdOZHgpCgkJCXsKCQkJCWJ1ZmZlclN1YkRhdGFNZXRob2RHcm91cC0+YWRkQ2hpbGQoZmxhZ0Nhc2VzW2ZsYWdOZHhdLmdyb3VwKTsKCgkJCQlmb3IgKGludCB1c2FnZU5keCA9IDA7IHVzYWdlTmR4IDwgREVfTEVOR1RIX09GX0FSUkFZKGJ1ZmZlclVzYWdlcyk7ICsrdXNhZ2VOZHgpCgkJCQkJaWYgKGJ1ZmZlclVzYWdlc1t1c2FnZU5keF0ucHJpbWFyeVVzYWdlIHx8IGZsYWdDYXNlc1tmbGFnTmR4XS5hbGxVc2FnZXMpCgkJCQkJCQlmbGFnQ2FzZXNbZmxhZ05keF0uZ3JvdXAtPmFkZENoaWxkKG5ldyBCdWZmZXJTdWJEYXRhVXBsb2FkQ2FzZShtX2NvbnRleHQsCgkJCQkJCQkJCQkJCQkJCQkJCQkJCQkgICBzdGQ6OnN0cmluZygidXNhZ2VfIikuYXBwZW5kKGJ1ZmZlclVzYWdlc1t1c2FnZU5keF0ubmFtZSkuY19zdHIoKSwKCQkJCQkJCQkJCQkJCQkJCQkJCQkJCSAgIHN0ZDo6c3RyaW5nKCJUZXN0IHdpdGggdXNhZ2UgPSAiKS5hcHBlbmQoYnVmZmVyVXNhZ2VzW3VzYWdlTmR4XS5uYW1lKS5jX3N0cigpLAoJCQkJCQkJCQkJCQkJCQkJCQkJCQkJICAgbWluQnVmZmVyU2l6ZSwKCQkJCQkJCQkJCQkJCQkJCQkJCQkJCSAgIG1heEJ1ZmZlclNpemUsCgkJCQkJCQkJCQkJCQkJCQkJCQkJCQkgICBudW1EYXRhU2FtcGxlcywKCQkJCQkJCQkJCQkJCQkJCQkJCQkJCSAgIGJ1ZmZlclVzYWdlc1t1c2FnZU5keF0udXNhZ2UsCgkJCQkJCQkJCQkJCQkJCQkJCQkJCQkgICBmbGFnQ2FzZXNbZmxhZ05keF0ucGFyZW50Q2FzZSwKCQkJCQkJCQkJCQkJCQkJCQkJCQkJCSAgIGZsYWdDYXNlc1tmbGFnTmR4XS5mbGFncykpOwoJCQl9CgkJfQoKCQkvLyAubWFwX2J1ZmZlcl9yYW5nZQoJCXsKCQkJc3RhdGljIGNvbnN0IHN0cnVjdCBGbGFnQ2FzZQoJCQl7CgkJCQljb25zdCBjaGFyKgluYW1lOwoJCQkJYm9vbAkJdXNlZnVsRm9yVW51c2VkQnVmZmVyczsKCQkJCWJvb2wJCWFsbFVzYWdlczsKCQkJCWludAkJCWdsRmxhZ3M7CgkJCQlpbnQJCQljYXNlRmxhZ3M7CgkJCX0gZmxhZ0Nhc2VzW10gPQoJCQl7CgkJCQl7ICJmbGFnX3dyaXRlX2Z1bGwiLAkJCQkJCQkJCQl0cnVlLAl0cnVlLAlHTF9NQVBfV1JJVEVfQklULAkJCQkJCQkJCQkJCQkJCQkwCQkJCQkJCQkJCQkJCQkJCQkJCQl9LAoJCQkJeyAiZmxhZ193cml0ZV9wYXJ0aWFsIiwJCQkJCQkJCQkJdHJ1ZSwJdHJ1ZSwJR0xfTUFQX1dSSVRFX0JJVCwJCQkJCQkJCQkJCQkJCQkJTWFwQnVmZmVyUmFuZ2VDYXNlOjpGTEFHX1BBUlRJQUwJCQkJCQkJCQkJCQl9LAoJCQkJeyAiZmxhZ19yZWFkX3dyaXRlX2Z1bGwiLAkJCQkJCQkJCXRydWUsCXRydWUsCUdMX01BUF9XUklURV9CSVQgfCBHTF9NQVBfUkVBRF9CSVQsCQkJCQkJCQkJCQkJMAkJCQkJCQkJCQkJCQkJCQkJCQkJfSwKCQkJCXsgImZsYWdfcmVhZF93cml0ZV9wYXJ0aWFsIiwJCQkJCQkJCXRydWUsCXRydWUsCUdMX01BUF9XUklURV9CSVQgfCBHTF9NQVBfUkVBRF9CSVQsCQkJCQkJCQkJCQkJTWFwQnVmZmVyUmFuZ2VDYXNlOjpGTEFHX1BBUlRJQUwJCQkJCQkJCQkJCQl9LAoJCQkJeyAiZmxhZ19pbnZhbGlkYXRlX3JhbmdlX2Z1bGwiLAkJCQkJCQkJdHJ1ZSwJZmFsc2UsCUdMX01BUF9XUklURV9CSVQgfCBHTF9NQVBfSU5WQUxJREFURV9SQU5HRV9CSVQsCQkJCQkJCQkJMAkJCQkJCQkJCQkJCQkJCQkJCQkJfSwKCQkJCXsgImZsYWdfaW52YWxpZGF0ZV9yYW5nZV9wYXJ0aWFsIiwJCQkJCQkJdHJ1ZSwJZmFsc2UsCUdMX01BUF9XUklURV9CSVQgfCBHTF9NQVBfSU5WQUxJREFURV9SQU5HRV9CSVQsCQkJCQkJCQkJTWFwQnVmZmVyUmFuZ2VDYXNlOjpGTEFHX1BBUlRJQUwJCQkJCQkJCQkJCQl9LAoJCQkJeyAiZmxhZ19pbnZhbGlkYXRlX2J1ZmZlcl9mdWxsIiwJCQkJCQkJdHJ1ZSwJZmFsc2UsCUdMX01BUF9XUklURV9CSVQgfCBHTF9NQVBfSU5WQUxJREFURV9CVUZGRVJfQklULAkJCQkJCQkJMAkJCQkJCQkJCQkJCQkJCQkJCQkJfSwKCQkJCXsgImZsYWdfaW52YWxpZGF0ZV9idWZmZXJfcGFydGlhbCIsCQkJCQkJCXRydWUsCWZhbHNlLAlHTF9NQVBfV1JJVEVfQklUIHwgR0xfTUFQX0lOVkFMSURBVEVfQlVGRkVSX0JJVCwJCQkJCQkJCU1hcEJ1ZmZlclJhbmdlQ2FzZTo6RkxBR19QQVJUSUFMCQkJCQkJCQkJCQkJfSwKCQkJCXsgImZsYWdfd3JpdGVfZnVsbF9tYW51YWxfaW52YWxpZGF0ZV9idWZmZXIiLAkJCQlmYWxzZSwJZmFsc2UsCUdMX01BUF9XUklURV9CSVQgfCBHTF9NQVBfSU5WQUxJREFURV9SQU5HRV9CSVQsCQkJCQkJCQkJTWFwQnVmZmVyUmFuZ2VDYXNlOjpGTEFHX01BTlVBTF9JTlZBTElEQVRJT04JCQkJCQkJCQl9LAoJCQkJeyAiZmxhZ193cml0ZV9wYXJ0aWFsX21hbnVhbF9pbnZhbGlkYXRlX2J1ZmZlciIsCQkJZmFsc2UsCWZhbHNlLAlHTF9NQVBfV1JJVEVfQklUIHwgR0xfTUFQX0lOVkFMSURBVEVfUkFOR0VfQklULAkJCQkJCQkJCU1hcEJ1ZmZlclJhbmdlQ2FzZTo6RkxBR19QQVJUSUFMIHwgTWFwQnVmZmVyUmFuZ2VDYXNlOjpGTEFHX01BTlVBTF9JTlZBTElEQVRJT04JfSwKCQkJCXsgImZsYWdfdW5zeW5jaHJvbml6ZWRfZnVsbCIsCQkJCQkJCQl0cnVlLAlmYWxzZSwJR0xfTUFQX1dSSVRFX0JJVCB8IEdMX01BUF9VTlNZTkNIUk9OSVpFRF9CSVQsCQkJCQkJCQkJMAkJCQkJCQkJCQkJCQkJCQkJCQkJfSwKCQkJCXsgImZsYWdfdW5zeW5jaHJvbml6ZWRfcGFydGlhbCIsCQkJCQkJCXRydWUsCWZhbHNlLAlHTF9NQVBfV1JJVEVfQklUIHwgR0xfTUFQX1VOU1lOQ0hST05JWkVEX0JJVCwJCQkJCQkJCQlNYXBCdWZmZXJSYW5nZUNhc2U6OkZMQUdfUEFSVElBTAkJCQkJCQkJCQkJCX0sCgkJCQl7ICJmbGFnX3Vuc3luY2hyb25pemVkX2FuZF9pbnZhbGlkYXRlX2J1ZmZlcl9mdWxsIiwJCQl0cnVlLAlmYWxzZSwJR0xfTUFQX1dSSVRFX0JJVCB8IEdMX01BUF9VTlNZTkNIUk9OSVpFRF9CSVQgfCBHTF9NQVBfSU5WQUxJREFURV9CVUZGRVJfQklULAkwCQkJCQkJCQkJCQkJCQkJCQkJCQl9LAoJCQkJeyAiZmxhZ191bnN5bmNocm9uaXplZF9hbmRfaW52YWxpZGF0ZV9idWZmZXJfcGFydGlhbCIsCQl0cnVlLAlmYWxzZSwJR0xfTUFQX1dSSVRFX0JJVCB8IEdMX01BUF9VTlNZTkNIUk9OSVpFRF9CSVQgfCBHTF9NQVBfSU5WQUxJREFURV9CVUZGRVJfQklULAlNYXBCdWZmZXJSYW5nZUNhc2U6OkZMQUdfUEFSVElBTAkJCQkJCQkJCQkJCX0sCgkJCX07CgkJCXN0YXRpYyBjb25zdCBzdHJ1Y3QgRmx1c2hDYXNlcwoJCQl7CgkJCQljb25zdCBjaGFyKgluYW1lOwoJCQkJaW50CQkJZ2xGbGFnczsKCQkJCWludAkJCWNhc2VGbGFnczsKCQkJfSBmbHVzaENhc2VzW10gPQoJCQl7CgkJCQl7ICJmbGFnX2ZsdXNoX2V4cGxpY2l0X21hcF9mdWxsIiwJCQkJCUdMX01BUF9XUklURV9CSVQgfCBHTF9NQVBfRkxVU0hfRVhQTElDSVRfQklULAkwCQkJCQkJCQkJCQkJfSwKCQkJCXsgImZsYWdfZmx1c2hfZXhwbGljaXRfbWFwX3BhcnRpYWwiLAkJCQlHTF9NQVBfV1JJVEVfQklUIHwgR0xfTUFQX0ZMVVNIX0VYUExJQ0lUX0JJVCwJTWFwQnVmZmVyUmFuZ2VGbHVzaENhc2U6OkZMQUdfUEFSVElBTAkJCX0sCgkJCQl7ICJmbGFnX2ZsdXNoX2V4cGxpY2l0X21hcF9mdWxsX2ZsdXNoX2luX3BhcnRzIiwJR0xfTUFQX1dSSVRFX0JJVCB8IEdMX01BUF9GTFVTSF9FWFBMSUNJVF9CSVQsCU1hcEJ1ZmZlclJhbmdlRmx1c2hDYXNlOjpGTEFHX0ZMVVNIX0lOX1BBUlRTCX0sCgkJCQl7ICJmbGFnX2ZsdXNoX2V4cGxpY2l0X21hcF9mdWxsX2ZsdXNoX3BhcnRpYWwiLAkJR0xfTUFQX1dSSVRFX0JJVCB8IEdMX01BUF9GTFVTSF9FWFBMSUNJVF9CSVQsCU1hcEJ1ZmZlclJhbmdlRmx1c2hDYXNlOjpGTEFHX0ZMVVNIX1BBUlRJQUwJCX0sCgkJCX07CgkJCXN0YXRpYyBjb25zdCBzdHJ1Y3QgTWFwVGVzdEdyb3VwCgkJCXsKCQkJCWludAkJCQkJZmxhZ3M7CgkJCQlib29sCQkJCXVudXNlZEJ1ZmZlckNhc2U7CgkJCQl0Y3U6OlRlc3RDYXNlR3JvdXAqIGdyb3VwOwoJCQl9IGdyb3Vwc1tdID0KCQkJewoJCQkJeyBNYXBCdWZmZXJSYW5nZUNhc2U6OkZMQUdfVVNFX1VOVVNFRF9VTlNQRUNJRklFRF9CVUZGRVIsCXRydWUsCW5ldyB0Y3U6OlRlc3RDYXNlR3JvdXAobV90ZXN0Q3R4LCAibmV3X3Vuc3BlY2lmaWVkX2J1ZmZlciIsICJUZXN0IHdpdGggdW51c2VkLCB1bnNwZWNpZmllZCBidWZmZXJzIiksCQkJCX0sCgkJCQl7IE1hcEJ1ZmZlclJhbmdlQ2FzZTo6RkxBR19VU0VfVU5VU0VEX1NQRUNJRklFRF9CVUZGRVIsCQl0cnVlLAluZXcgdGN1OjpUZXN0Q2FzZUdyb3VwKG1fdGVzdEN0eCwgIm5ld19zcGVjaWZpZWRfYnVmZmVyIiwgIlRlc3Qgd2l0aCB1bnVzZWQsIHNwZWNpZmllZCBidWZmZXJzIiksCQkJCQl9LAoJCQkJeyAwLAkJCQkJCQkJCQkJCQkJZmFsc2UsCW5ldyB0Y3U6OlRlc3RDYXNlR3JvdXAobV90ZXN0Q3R4LCAidXNlZF9idWZmZXIiLCAiVGVzdCB3aXRoIHVzZWQgKGRhdGEgaGFzIGJlZW4gc291cmNlZCBmcm9tIGEgYnVmZmVyKSBidWZmZXJzIikJfSwKCQkJfTsKCgkJCS8vIHdlIE9SIHNhbWUgZmxhZ3MgdG8gYm90aCByYW5nZSBhbmQgZmx1c2hSYW5nZSBjYXNlcywgbWFrZSBzdXJlIGl0IGlzIGxlZ2FsCgkJCURFX1NUQVRJQ19BU1NFUlQoKGludClNYXBCdWZmZXJSYW5nZUNhc2U6OkZMQUdfVVNFX1VOVVNFRF9TUEVDSUZJRURfQlVGRkVSID09IChpbnQpTWFwQnVmZmVyUmFuZ2VGbHVzaENhc2U6OkZMQUdfVVNFX1VOVVNFRF9TUEVDSUZJRURfQlVGRkVSKTsKCQkJREVfU1RBVElDX0FTU0VSVCgoaW50KU1hcEJ1ZmZlclJhbmdlQ2FzZTo6RkxBR19VU0VfVU5VU0VEX1VOU1BFQ0lGSUVEX0JVRkZFUiA9PSAoaW50KU1hcEJ1ZmZlclJhbmdlRmx1c2hDYXNlOjpGTEFHX1VTRV9VTlVTRURfVU5TUEVDSUZJRURfQlVGRkVSKTsKCgkJCWZvciAoaW50IGdyb3VwTmR4ID0gMDsgZ3JvdXBOZHggPCBERV9MRU5HVEhfT0ZfQVJSQVkoZ3JvdXBzKTsgKytncm91cE5keCkKCQkJewoJCQkJdGN1OjpUZXN0Q2FzZUdyb3VwKiBjb25zdCBidWZmZXJUeXBlR3JvdXAgPSBncm91cHNbZ3JvdXBOZHhdLmdyb3VwOwoKCQkJCW1hcEJ1ZmZlclJhbmdlTWV0aG9kR3JvdXAtPmFkZENoaWxkKGJ1ZmZlclR5cGVHcm91cCk7CgoJCQkJZm9yIChpbnQgY2FzZU5keCA9IDA7IGNhc2VOZHggPCBERV9MRU5HVEhfT0ZfQVJSQVkoZmxhZ0Nhc2VzKTsgKytjYXNlTmR4KQoJCQkJewoJCQkJCWlmIChncm91cHNbZ3JvdXBOZHhdLnVudXNlZEJ1ZmZlckNhc2UgJiYgIWZsYWdDYXNlc1tjYXNlTmR4XS51c2VmdWxGb3JVbnVzZWRCdWZmZXJzKQoJCQkJCQljb250aW51ZTsKCgkJCQkJdGN1OjpUZXN0Q2FzZUdyb3VwKiBjb25zdCBidWZmZXJVc2FnZUdyb3VwID0gbmV3IHRjdTo6VGVzdENhc2VHcm91cChtX3Rlc3RDdHgsIGZsYWdDYXNlc1tjYXNlTmR4XS5uYW1lLCAiIik7CgkJCQkJYnVmZmVyVHlwZUdyb3VwLT5hZGRDaGlsZChidWZmZXJVc2FnZUdyb3VwKTsKCgkJCQkJZm9yIChpbnQgdXNhZ2VOZHggPSAwOyB1c2FnZU5keCA8IERFX0xFTkdUSF9PRl9BUlJBWShidWZmZXJVc2FnZXMpOyArK3VzYWdlTmR4KQoJCQkJCQlpZiAoYnVmZmVyVXNhZ2VzW3VzYWdlTmR4XS5wcmltYXJ5VXNhZ2UgfHwgZmxhZ0Nhc2VzW2Nhc2VOZHhdLmFsbFVzYWdlcykKCQkJCQkJCWJ1ZmZlclVzYWdlR3JvdXAtPmFkZENoaWxkKG5ldyBNYXBCdWZmZXJSYW5nZUNhc2UobV9jb250ZXh0LAoJCQkJCQkJCQkJCQkJCQkJCQkJICBidWZmZXJVc2FnZXNbdXNhZ2VOZHhdLm5hbWUsCgkJCQkJCQkJCQkJCQkJCQkJCQkgIHN0ZDo6c3RyaW5nKCJUZXN0IHdpdGggdXNhZ2UgPSAiKS5hcHBlbmQoYnVmZmVyVXNhZ2VzW3VzYWdlTmR4XS5uYW1lKS5jX3N0cigpLAoJCQkJCQkJCQkJCQkJCQkJCQkJICBtaW5CdWZmZXJTaXplLAoJCQkJCQkJCQkJCQkJCQkJCQkJICBtYXhCdWZmZXJTaXplLAoJCQkJCQkJCQkJCQkJCQkJCQkJICBudW1NYXBTYW1wbGVzLAoJCQkJCQkJCQkJCQkJCQkJCQkJICBidWZmZXJVc2FnZXNbdXNhZ2VOZHhdLnVzYWdlLAoJCQkJCQkJCQkJCQkJCQkJCQkJICBmbGFnQ2FzZXNbY2FzZU5keF0uZ2xGbGFncywKCQkJCQkJCQkJCQkJCQkJCQkJCSAgZmxhZ0Nhc2VzW2Nhc2VOZHhdLmNhc2VGbGFncyB8IGdyb3Vwc1tncm91cE5keF0uZmxhZ3MpKTsKCQkJCX0KCgkJCQlmb3IgKGludCBjYXNlTmR4ID0gMDsgY2FzZU5keCA8IERFX0xFTkdUSF9PRl9BUlJBWShmbHVzaENhc2VzKTsgKytjYXNlTmR4KQoJCQkJewoJCQkJCXRjdTo6VGVzdENhc2VHcm91cCogY29uc3QgYnVmZmVyVXNhZ2VHcm91cCA9IG5ldyB0Y3U6OlRlc3RDYXNlR3JvdXAobV90ZXN0Q3R4LCBmbHVzaENhc2VzW2Nhc2VOZHhdLm5hbWUsICIiKTsKCQkJCQlidWZmZXJUeXBlR3JvdXAtPmFkZENoaWxkKGJ1ZmZlclVzYWdlR3JvdXApOwoKCQkJCQlmb3IgKGludCB1c2FnZU5keCA9IDA7IHVzYWdlTmR4IDwgREVfTEVOR1RIX09GX0FSUkFZKGJ1ZmZlclVzYWdlcyk7ICsrdXNhZ2VOZHgpCgkJCQkJCWlmIChidWZmZXJVc2FnZXNbdXNhZ2VOZHhdLnByaW1hcnlVc2FnZSkKCQkJCQkJCWJ1ZmZlclVzYWdlR3JvdXAtPmFkZENoaWxkKG5ldyBNYXBCdWZmZXJSYW5nZUZsdXNoQ2FzZShtX2NvbnRleHQsCgkJCQkJCQkJCQkJCQkJCQkJCQkJICAgYnVmZmVyVXNhZ2VzW3VzYWdlTmR4XS5uYW1lLAoJCQkJCQkJCQkJCQkJCQkJCQkJCSAgIHN0ZDo6c3RyaW5nKCJUZXN0IHdpdGggdXNhZ2UgPSAiKS5hcHBlbmQoYnVmZmVyVXNhZ2VzW3VzYWdlTmR4XS5uYW1lKS5jX3N0cigpLAoJCQkJCQkJCQkJCQkJCQkJCQkJCSAgIG1pbkJ1ZmZlclNpemUsCgkJCQkJCQkJCQkJCQkJCQkJCQkJICAgbWF4QnVmZmVyU2l6ZSwKCQkJCQkJCQkJCQkJCQkJCQkJCQkgICBudW1NYXBTYW1wbGVzLAoJCQkJCQkJCQkJCQkJCQkJCQkJCSAgIGJ1ZmZlclVzYWdlc1t1c2FnZU5keF0udXNhZ2UsCgkJCQkJCQkJCQkJCQkJCQkJCQkJICAgZmx1c2hDYXNlc1tjYXNlTmR4XS5nbEZsYWdzLAoJCQkJCQkJCQkJCQkJCQkJCQkJCSAgIGZsdXNoQ2FzZXNbY2FzZU5keF0uY2FzZUZsYWdzIHwgZ3JvdXBzW2dyb3VwTmR4XS5mbGFncykpOwoJCQkJfQoJCQl9CgkJfQoJfQoKCS8vIC5tb2RpZnlfYWZ0ZXJfdXNlCgl7CgkJY29uc3QgaW50IG1pbkJ1ZmZlclNpemUJPSAwOwkJLy8gITwgMGtpQgoJCWNvbnN0IGludCBtYXhCdWZmZXJTaXplCT0gMSA8PCAyNDsJLy8gITwgMTZNaUIKCgkJc3RhdGljIGNvbnN0IHN0cnVjdCBVc2FnZQoJCXsKCQkJY29uc3QgY2hhciogbmFtZTsKCQkJY29uc3QgY2hhciogZGVzY3JpcHRpb247CgkJCWRlVWludDMyCXVzYWdlOwoJCX0gdXNhZ2VzW10gPQoJCXsKCQkJeyAic3RhdGljX2RyYXciLAkiVGVzdCB3aXRoIEdMX1NUQVRJQ19EUkFXIiwJCUdMX1NUQVRJQ19EUkFXCX0sCgkJCXsgImR5bmFtaWNfZHJhdyIsCSJUZXN0IHdpdGggR0xfRFlOQU1JQ19EUkFXIiwJR0xfRFlOQU1JQ19EUkFXCX0sCgkJCXsgInN0cmVhbV9kcmF3IiwJIlRlc3Qgd2l0aCBHTF9TVFJFQU1fRFJBVyIsCQlHTF9TVFJFQU1fRFJBVyB9LAoKCQl9OwoKCQlmb3IgKGludCB1c2FnZU5keCA9IDA7IHVzYWdlTmR4IDwgREVfTEVOR1RIX09GX0FSUkFZKHVzYWdlcyk7ICsrdXNhZ2VOZHgpCgkJewoJCQl0Y3U6OlRlc3RDYXNlR3JvdXAqIGNvbnN0IHVzYWdlR3JvdXAgPSBuZXcgdGN1OjpUZXN0Q2FzZUdyb3VwKG1fdGVzdEN0eCwgdXNhZ2VzW3VzYWdlTmR4XS5uYW1lLCB1c2FnZXNbdXNhZ2VOZHhdLmRlc2NyaXB0aW9uKTsKCQkJbW9kaWZ5QWZ0ZXJVc2VHcm91cC0+YWRkQ2hpbGQodXNhZ2VHcm91cCk7CgoJCQl1c2FnZUdyb3VwLT5hZGRDaGlsZChuZXcgTW9kaWZ5QWZ0ZXJXaXRoQnVmZmVyRGF0YUNhc2UJCShtX2NvbnRleHQsICJidWZmZXJfZGF0YSIsCQkJCQkJCSJSZXNwZWNpZnkgYnVmZmVyIGNvbnRlbnRzIGFmdGVyIHVzZSIsCQkJCQltaW5CdWZmZXJTaXplLCBtYXhCdWZmZXJTaXplLCB1c2FnZXNbdXNhZ2VOZHhdLnVzYWdlLCAwKSk7CgkJCXVzYWdlR3JvdXAtPmFkZENoaWxkKG5ldyBNb2RpZnlBZnRlcldpdGhCdWZmZXJEYXRhQ2FzZQkJKG1fY29udGV4dCwgImJ1ZmZlcl9kYXRhX2RpZmZlcmVudF9zaXplIiwJCQkiUmVzcGVjaWZ5IGJ1ZmZlciBjb250ZW50cyBhbmQgc2l6ZSBhZnRlciB1c2UiLAkJCW1pbkJ1ZmZlclNpemUsIG1heEJ1ZmZlclNpemUsIHVzYWdlc1t1c2FnZU5keF0udXNhZ2UsIE1vZGlmeUFmdGVyV2l0aEJ1ZmZlckRhdGFDYXNlOjpGTEFHX1JFU1BFQ0lGWV9TSVpFKSk7CgkJCXVzYWdlR3JvdXAtPmFkZENoaWxkKG5ldyBNb2RpZnlBZnRlcldpdGhCdWZmZXJEYXRhQ2FzZQkJKG1fY29udGV4dCwgImJ1ZmZlcl9kYXRhX3JlcGVhdGVkIiwJCQkJCSJSZXNwZWNpZnkgYnVmZmVyIGNvbnRlbnRzIGFmdGVyIHVwbG9hZCBhbmQgdXNlIiwJCW1pbkJ1ZmZlclNpemUsIG1heEJ1ZmZlclNpemUsIHVzYWdlc1t1c2FnZU5keF0udXNhZ2UsIE1vZGlmeUFmdGVyV2l0aEJ1ZmZlckRhdGFDYXNlOjpGTEFHX1VQTE9BRF9SRVBFQVRFRCkpOwoKCQkJdXNhZ2VHcm91cC0+YWRkQ2hpbGQobmV3IE1vZGlmeUFmdGVyV2l0aEJ1ZmZlclN1YkRhdGFDYXNlCShtX2NvbnRleHQsICJidWZmZXJfc3ViX2RhdGFfZnVsbCIsCQkJCQkiUmVzcGVjaWZ5IGJ1ZmZlciBjb250ZW50cyBhZnRlciB1c2UiLAkJCQkJbWluQnVmZmVyU2l6ZSwgbWF4QnVmZmVyU2l6ZSwgdXNhZ2VzW3VzYWdlTmR4XS51c2FnZSwgMCkpOwoJCQl1c2FnZUdyb3VwLT5hZGRDaGlsZChuZXcgTW9kaWZ5QWZ0ZXJXaXRoQnVmZmVyU3ViRGF0YUNhc2UJKG1fY29udGV4dCwgImJ1ZmZlcl9zdWJfZGF0YV9wYXJ0aWFsIiwJCQkJIlJlc3BlY2lmeSBidWZmZXIgY29udGVudHMgcGFydGlhbGx5IHVzZSIsCQkJCW1pbkJ1ZmZlclNpemUsIG1heEJ1ZmZlclNpemUsIHVzYWdlc1t1c2FnZU5keF0udXNhZ2UsIE1vZGlmeUFmdGVyV2l0aEJ1ZmZlclN1YkRhdGFDYXNlOjpGTEFHX1BBUlRJQUwpKTsKCQkJdXNhZ2VHcm91cC0+YWRkQ2hpbGQobmV3IE1vZGlmeUFmdGVyV2l0aEJ1ZmZlclN1YkRhdGFDYXNlCShtX2NvbnRleHQsICJidWZmZXJfc3ViX2RhdGFfZnVsbF9yZXBlYXRlZCIsCQkiUmVzcGVjaWZ5IGJ1ZmZlciBjb250ZW50cyBhZnRlciB1cGxvYWQgYW5kIHVzZSIsCQltaW5CdWZmZXJTaXplLCBtYXhCdWZmZXJTaXplLCB1c2FnZXNbdXNhZ2VOZHhdLnVzYWdlLCBNb2RpZnlBZnRlcldpdGhCdWZmZXJTdWJEYXRhQ2FzZTo6RkxBR19VUExPQURfUkVQRUFURUQpKTsKCQkJdXNhZ2VHcm91cC0+YWRkQ2hpbGQobmV3IE1vZGlmeUFmdGVyV2l0aEJ1ZmZlclN1YkRhdGFDYXNlCShtX2NvbnRleHQsICJidWZmZXJfc3ViX2RhdGFfcGFydGlhbF9yZXBlYXRlZCIsCQkiUmVzcGVjaWZ5IGJ1ZmZlciBjb250ZW50cyBwYXJ0aWFsbHkgdXBsb2FkIGFuZCB1c2UiLAltaW5CdWZmZXJTaXplLCBtYXhCdWZmZXJTaXplLCB1c2FnZXNbdXNhZ2VOZHhdLnVzYWdlLCBNb2RpZnlBZnRlcldpdGhCdWZmZXJTdWJEYXRhQ2FzZTo6RkxBR19VUExPQURfUkVQRUFURUQgfCBNb2RpZnlBZnRlcldpdGhCdWZmZXJTdWJEYXRhQ2FzZTo6RkxBR19QQVJUSUFMKSk7CgoJCQl1c2FnZUdyb3VwLT5hZGRDaGlsZChuZXcgTW9kaWZ5QWZ0ZXJXaXRoTWFwQnVmZmVyUmFuZ2VDYXNlCShtX2NvbnRleHQsICJtYXBfZmxhZ193cml0ZV9mdWxsIiwJCQkJCSJSZXNwZWNpZnkgYnVmZmVyIGNvbnRlbnRzIGFmdGVyIHVzZSIsCQkJCQltaW5CdWZmZXJTaXplLCBtYXhCdWZmZXJTaXplLCB1c2FnZXNbdXNhZ2VOZHhdLnVzYWdlLCAwLAkJCQkJCQkJCQkJCUdMX01BUF9XUklURV9CSVQpKTsKCQkJdXNhZ2VHcm91cC0+YWRkQ2hpbGQobmV3IE1vZGlmeUFmdGVyV2l0aE1hcEJ1ZmZlclJhbmdlQ2FzZQkobV9jb250ZXh0LCAibWFwX2ZsYWdfd3JpdGVfcGFydGlhbCIsCQkJCSJSZXNwZWNpZnkgYnVmZmVyIGNvbnRlbnRzIHBhcnRpYWxseSBhZnRlciB1c2UiLAkJbWluQnVmZmVyU2l6ZSwgbWF4QnVmZmVyU2l6ZSwgdXNhZ2VzW3VzYWdlTmR4XS51c2FnZSwgTW9kaWZ5QWZ0ZXJXaXRoTWFwQnVmZmVyUmFuZ2VDYXNlOjpGTEFHX1BBUlRJQUwsCUdMX01BUF9XUklURV9CSVQpKTsKCQkJdXNhZ2VHcm91cC0+YWRkQ2hpbGQobmV3IE1vZGlmeUFmdGVyV2l0aE1hcEJ1ZmZlclJhbmdlQ2FzZQkobV9jb250ZXh0LCAibWFwX2ZsYWdfcmVhZF93cml0ZV9mdWxsIiwJCQkJIlJlc3BlY2lmeSBidWZmZXIgY29udGVudHMgYWZ0ZXIgdXNlIiwJCQkJCW1pbkJ1ZmZlclNpemUsIG1heEJ1ZmZlclNpemUsIHVzYWdlc1t1c2FnZU5keF0udXNhZ2UsIDAsCQkJCQkJCQkJCQkJR0xfTUFQX1JFQURfQklUIHwgR0xfTUFQX1dSSVRFX0JJVCkpOwoJCQl1c2FnZUdyb3VwLT5hZGRDaGlsZChuZXcgTW9kaWZ5QWZ0ZXJXaXRoTWFwQnVmZmVyUmFuZ2VDYXNlCShtX2NvbnRleHQsICJtYXBfZmxhZ19yZWFkX3dyaXRlX3BhcnRpYWwiLAkJCSJSZXNwZWNpZnkgYnVmZmVyIGNvbnRlbnRzIHBhcnRpYWxseSBhZnRlciB1c2UiLAkJbWluQnVmZmVyU2l6ZSwgbWF4QnVmZmVyU2l6ZSwgdXNhZ2VzW3VzYWdlTmR4XS51c2FnZSwgTW9kaWZ5QWZ0ZXJXaXRoTWFwQnVmZmVyUmFuZ2VDYXNlOjpGTEFHX1BBUlRJQUwsCUdMX01BUF9SRUFEX0JJVCB8IEdMX01BUF9XUklURV9CSVQpKTsKCQkJdXNhZ2VHcm91cC0+YWRkQ2hpbGQobmV3IE1vZGlmeUFmdGVyV2l0aE1hcEJ1ZmZlclJhbmdlQ2FzZQkobV9jb250ZXh0LCAibWFwX2ZsYWdfaW52YWxpZGF0ZV9yYW5nZV9mdWxsIiwJCSJSZXNwZWNpZnkgYnVmZmVyIGNvbnRlbnRzIGFmdGVyIHVzZSIsCQkJCQltaW5CdWZmZXJTaXplLCBtYXhCdWZmZXJTaXplLCB1c2FnZXNbdXNhZ2VOZHhdLnVzYWdlLCAwLAkJCQkJCQkJCQkJCUdMX01BUF9XUklURV9CSVQgfCBHTF9NQVBfSU5WQUxJREFURV9SQU5HRV9CSVQpKTsKCQkJdXNhZ2VHcm91cC0+YWRkQ2hpbGQobmV3IE1vZGlmeUFmdGVyV2l0aE1hcEJ1ZmZlclJhbmdlQ2FzZQkobV9jb250ZXh0LCAibWFwX2ZsYWdfaW52YWxpZGF0ZV9yYW5nZV9wYXJ0aWFsIiwJIlJlc3BlY2lmeSBidWZmZXIgY29udGVudHMgcGFydGlhbGx5IGFmdGVyIHVzZSIsCQltaW5CdWZmZXJTaXplLCBtYXhCdWZmZXJTaXplLCB1c2FnZXNbdXNhZ2VOZHhdLnVzYWdlLCBNb2RpZnlBZnRlcldpdGhNYXBCdWZmZXJSYW5nZUNhc2U6OkZMQUdfUEFSVElBTCwJR0xfTUFQX1dSSVRFX0JJVCB8IEdMX01BUF9JTlZBTElEQVRFX1JBTkdFX0JJVCkpOwoJCQl1c2FnZUdyb3VwLT5hZGRDaGlsZChuZXcgTW9kaWZ5QWZ0ZXJXaXRoTWFwQnVmZmVyUmFuZ2VDYXNlCShtX2NvbnRleHQsICJtYXBfZmxhZ19pbnZhbGlkYXRlX2J1ZmZlcl9mdWxsIiwJCSJSZXNwZWNpZnkgYnVmZmVyIGNvbnRlbnRzIGFmdGVyIHVzZSIsCQkJCQltaW5CdWZmZXJTaXplLCBtYXhCdWZmZXJTaXplLCB1c2FnZXNbdXNhZ2VOZHhdLnVzYWdlLCAwLAkJCQkJCQkJCQkJCUdMX01BUF9XUklURV9CSVQgfCBHTF9NQVBfSU5WQUxJREFURV9CVUZGRVJfQklUKSk7CgkJCXVzYWdlR3JvdXAtPmFkZENoaWxkKG5ldyBNb2RpZnlBZnRlcldpdGhNYXBCdWZmZXJSYW5nZUNhc2UJKG1fY29udGV4dCwgIm1hcF9mbGFnX2ludmFsaWRhdGVfYnVmZmVyX3BhcnRpYWwiLAkiUmVzcGVjaWZ5IGJ1ZmZlciBjb250ZW50cyBwYXJ0aWFsbHkgYWZ0ZXIgdXNlIiwJCW1pbkJ1ZmZlclNpemUsIG1heEJ1ZmZlclNpemUsIHVzYWdlc1t1c2FnZU5keF0udXNhZ2UsIE1vZGlmeUFmdGVyV2l0aE1hcEJ1ZmZlclJhbmdlQ2FzZTo6RkxBR19QQVJUSUFMLAlHTF9NQVBfV1JJVEVfQklUIHwgR0xfTUFQX0lOVkFMSURBVEVfQlVGRkVSX0JJVCkpOwoJCQl1c2FnZUdyb3VwLT5hZGRDaGlsZChuZXcgTW9kaWZ5QWZ0ZXJXaXRoTWFwQnVmZmVyUmFuZ2VDYXNlCShtX2NvbnRleHQsICJtYXBfZmxhZ191bnN5bmNocm9uaXplZF9mdWxsIiwJCQkiUmVzcGVjaWZ5IGJ1ZmZlciBjb250ZW50cyBhZnRlciB1c2UiLAkJCQkJbWluQnVmZmVyU2l6ZSwgbWF4QnVmZmVyU2l6ZSwgdXNhZ2VzW3VzYWdlTmR4XS51c2FnZSwgMCwJCQkJCQkJCQkJCQlHTF9NQVBfV1JJVEVfQklUIHwgR0xfTUFQX1VOU1lOQ0hST05JWkVEX0JJVCkpOwoJCQl1c2FnZUdyb3VwLT5hZGRDaGlsZChuZXcgTW9kaWZ5QWZ0ZXJXaXRoTWFwQnVmZmVyUmFuZ2VDYXNlCShtX2NvbnRleHQsICJtYXBfZmxhZ191bnN5bmNocm9uaXplZF9wYXJ0aWFsIiwJCSJSZXNwZWNpZnkgYnVmZmVyIGNvbnRlbnRzIHBhcnRpYWxseSBhZnRlciB1c2UiLAkJbWluQnVmZmVyU2l6ZSwgbWF4QnVmZmVyU2l6ZSwgdXNhZ2VzW3VzYWdlTmR4XS51c2FnZSwgTW9kaWZ5QWZ0ZXJXaXRoTWFwQnVmZmVyUmFuZ2VDYXNlOjpGTEFHX1BBUlRJQUwsCUdMX01BUF9XUklURV9CSVQgfCBHTF9NQVBfVU5TWU5DSFJPTklaRURfQklUKSk7CgoJCQl1c2FnZUdyb3VwLT5hZGRDaGlsZChuZXcgTW9kaWZ5QWZ0ZXJXaXRoTWFwQnVmZmVyRmx1c2hDYXNlCShtX2NvbnRleHQsICJtYXBfZmxhZ19mbHVzaF9leHBsaWNpdF9mdWxsIiwJCQkiUmVzcGVjaWZ5IGJ1ZmZlciBjb250ZW50cyBhZnRlciB1c2UiLAkJCQkJbWluQnVmZmVyU2l6ZSwgbWF4QnVmZmVyU2l6ZSwgdXNhZ2VzW3VzYWdlTmR4XS51c2FnZSwgMCwJCQkJCQkJCQkJCQlHTF9NQVBfV1JJVEVfQklUIHwgR0xfTUFQX0ZMVVNIX0VYUExJQ0lUX0JJVCkpOwoJCQl1c2FnZUdyb3VwLT5hZGRDaGlsZChuZXcgTW9kaWZ5QWZ0ZXJXaXRoTWFwQnVmZmVyRmx1c2hDYXNlCShtX2NvbnRleHQsICJtYXBfZmxhZ19mbHVzaF9leHBsaWNpdF9wYXJ0aWFsIiwJCSJSZXNwZWNpZnkgYnVmZmVyIGNvbnRlbnRzIHBhcnRpYWxseSBhZnRlciB1c2UiLAkJbWluQnVmZmVyU2l6ZSwgbWF4QnVmZmVyU2l6ZSwgdXNhZ2VzW3VzYWdlTmR4XS51c2FnZSwgTW9kaWZ5QWZ0ZXJXaXRoTWFwQnVmZmVyRmx1c2hDYXNlOjpGTEFHX1BBUlRJQUwsCUdMX01BUF9XUklURV9CSVQgfCBHTF9NQVBfRkxVU0hfRVhQTElDSVRfQklUKSk7CgkJfQoJfQoKCS8vIC5yZW5kZXJfYWZ0ZXJfdXBsb2FkCgl7CgkJLy8gLnJlZmVyZW5jZQoJCXsKCQkJdGN1OjpUZXN0Q2FzZUdyb3VwKiBjb25zdCByZW5kZXJSZWZlcmVuY2VHcm91cCA9IG5ldyB0Y3U6OlRlc3RDYXNlR3JvdXAobV90ZXN0Q3R4LCAicmVmZXJlbmNlIiwgIkJhc2VsaW5lIHJlc3VsdHMiKTsKCQkJcmVuZGVyQWZ0ZXJVcGxvYWRHcm91cC0+YWRkQ2hpbGQocmVuZGVyUmVmZXJlbmNlR3JvdXApOwoKCQkJLy8gLmRyYXcKCQkJewoJCQkJdGN1OjpUZXN0Q2FzZUdyb3VwKiBjb25zdCBkcmF3R3JvdXAgPSBuZXcgdGN1OjpUZXN0Q2FzZUdyb3VwKG1fdGVzdEN0eCwgImRyYXciLCAiVGltZSB1c2FnZSBvZiBmdW5jdGlvbnMgd2l0aCBub24tbW9kaWZpZWQgYnVmZmVycyIpOwoJCQkJcmVuZGVyUmVmZXJlbmNlR3JvdXAtPmFkZENoaWxkKGRyYXdHcm91cCk7CgoJCQkJLy8gVGltZSBjb25zdW1lZCBieSByZWFkUGl4ZWxzCgkJCQlkcmF3R3JvdXAtPmFkZENoaWxkKG5ldyBSZWZlcmVuY2VSZWFkUGl4ZWxzVGltZUNhc2UJKG1fY29udGV4dCwgInJlYWRfcGl4ZWxzIiwJCSJNZWFzdXJlIHRpbWUgY29uc3VtZWQgYnkgcmVhZFBpeGVscygpIGZ1bmN0aW9uIGNhbGwiKSk7CgoJCQkJLy8gVGltZSBjb25zdW1lZCBieSByZW5kZXJpbmcKCQkJCWRyYXdHcm91cC0+YWRkQ2hpbGQobmV3IFJlZmVyZW5jZVJlbmRlclRpbWVDYXNlCQkobV9jb250ZXh0LCAiZHJhd19hcnJheXMiLAkJIk1lYXN1cmUgdGltZSBjb25zdW1lZCBieSBkcmF3QXJyYXlzKCkgZnVuY3Rpb24gY2FsbCIsCQlEUkFXTUVUSE9EX0RSQVdfQVJSQVlTKSk7CgkJCQlkcmF3R3JvdXAtPmFkZENoaWxkKG5ldyBSZWZlcmVuY2VSZW5kZXJUaW1lQ2FzZQkJKG1fY29udGV4dCwgImRyYXdfZWxlbWVudHMiLAkiTWVhc3VyZSB0aW1lIGNvbnN1bWVkIGJ5IGRyYXdFbGVtZW50cygpIGZ1bmN0aW9uIGNhbGwiLAlEUkFXTUVUSE9EX0RSQVdfRUxFTUVOVFMpKTsKCQkJfQoKCQkJLy8gLmRyYXdfdXBsb2FkX2RyYXcKCQkJewoJCQkJc3RhdGljIGNvbnN0IHN0cnVjdAoJCQkJewoJCQkJCWNvbnN0IGNoYXIqCQluYW1lOwoJCQkJCWNvbnN0IGNoYXIqCQlkZXNjcmlwdGlvbjsKCQkJCQlEcmF3TWV0aG9kCQlkcmF3TWV0aG9kOwoJCQkJCVRhcmdldEJ1ZmZlcgl0YXJnZXRCdWZmZXI7CgkJCQkJYm9vbAkJCXBhcnRpYWw7CgkJCQl9IHVwbG9hZFRhcmdldHNbXSA9CgkJCQl7CgkJCQkJewoJCQkJCQkiZHJhd19hcnJheXNfdXBsb2FkX3ZlcnRpY2VzIiwKCQkJCQkJIk1lYXN1cmUgdGltZSBjb25zdW1lZCBieSBkcmF3QXJyYXlzLCB2ZXJ0ZXggYXR0cmlidXRlIHVwbG9hZCwgYW5vdGhlciBkcmF3QXJyYXlzLCBhbmQgcmVhZFBpeGVscyBmdW5jdGlvbiBjYWxscy4iLAoJCQkJCQlEUkFXTUVUSE9EX0RSQVdfQVJSQVlTLAoJCQkJCQlUQVJHRVRCVUZGRVJfVkVSVEVYLAoJCQkJCQlmYWxzZQoJCQkJCX0sCgkJCQkJewoJCQkJCQkiZHJhd19hcnJheXNfdXBsb2FkX3ZlcnRpY2VzX3BhcnRpYWwiLAoJCQkJCQkiTWVhc3VyZSB0aW1lIGNvbnN1bWVkIGJ5IGRyYXdBcnJheXMsIHBhcnRpYWwgdmVydGV4IGF0dHJpYnV0ZSB1cGxvYWQsIGFub3RoZXIgZHJhd0FycmF5cywgYW5kIHJlYWRQaXhlbHMgZnVuY3Rpb24gY2FsbHMuIiwKCQkJCQkJRFJBV01FVEhPRF9EUkFXX0FSUkFZUywKCQkJCQkJVEFSR0VUQlVGRkVSX1ZFUlRFWCwKCQkJCQkJdHJ1ZQoJCQkJCX0sCgkJCQkJewoJCQkJCQkiZHJhd19lbGVtZW50c191cGxvYWRfdmVydGljZXMiLAoJCQkJCQkiTWVhc3VyZSB0aW1lIGNvbnN1bWVkIGJ5IGRyYXdFbGVtZW50cywgdmVydGV4IGF0dHJpYnV0ZSB1cGxvYWQsIGFub3RoZXIgZHJhd0VsZW1lbnRzLCBhbmQgcmVhZFBpeGVscyBmdW5jdGlvbiBjYWxscy4iLAoJCQkJCQlEUkFXTUVUSE9EX0RSQVdfRUxFTUVOVFMsCgkJCQkJCVRBUkdFVEJVRkZFUl9WRVJURVgsCgkJCQkJCWZhbHNlCgkJCQkJfSwKCQkJCQl7CgkJCQkJCSJkcmF3X2VsZW1lbnRzX3VwbG9hZF9pbmRpY2VzIiwKCQkJCQkJIk1lYXN1cmUgdGltZSBjb25zdW1lZCBieSBkcmF3RWxlbWVudHMsIGluZGV4IHVwbG9hZCwgYW5vdGhlciBkcmF3RWxlbWVudHMsIGFuZCByZWFkUGl4ZWxzIGZ1bmN0aW9uIGNhbGxzLiIsCgkJCQkJCURSQVdNRVRIT0RfRFJBV19FTEVNRU5UUywKCQkJCQkJVEFSR0VUQlVGRkVSX0lOREVYLAoJCQkJCQlmYWxzZQoJCQkJCX0sCgkJCQkJewoJCQkJCQkiZHJhd19lbGVtZW50c191cGxvYWRfaW5kaWNlc19wYXJ0aWFsIiwKCQkJCQkJIk1lYXN1cmUgdGltZSBjb25zdW1lZCBieSBkcmF3RWxlbWVudHMsIHBhcnRpYWwgaW5kZXggdXBsb2FkLCBhbm90aGVyIGRyYXdFbGVtZW50cywgYW5kIHJlYWRQaXhlbHMgZnVuY3Rpb24gY2FsbHMuIiwKCQkJCQkJRFJBV01FVEhPRF9EUkFXX0VMRU1FTlRTLAoJCQkJCQlUQVJHRVRCVUZGRVJfSU5ERVgsCgkJCQkJCXRydWUKCQkJCQl9LAoJCQkJfTsKCQkJCXN0YXRpYyBjb25zdCBzdHJ1Y3QKCQkJCXsKCQkJCQljb25zdCBjaGFyKgkJCQkJCQluYW1lOwoJCQkJCWNvbnN0IGNoYXIqCQkJCQkJCWRlc2NyaXB0aW9uOwoJCQkJCVVwbG9hZE1ldGhvZAkJCQkJCXVwbG9hZE1ldGhvZDsKCQkJCQlCdWZmZXJJblVzZVJlbmRlclRpbWVDYXNlOjpNYXBGbGFncwltYXBGbGFnczsKCQkJCQlib29sCQkJCQkJCQlzdXBwb3J0c1BhcnRpYWxVcGxvYWQ7CgkJCQl9IHVwbG9hZE1ldGhvZHNbXSA9CgkJCQl7CgkJCQkJeyAiYnVmZmVyX2RhdGEiLAkJCQkJCSJidWZmZXJEYXRhIiwJCVVQTE9BRE1FVEhPRF9CVUZGRVJfREFUQSwJCUJ1ZmZlckluVXNlUmVuZGVyVGltZUNhc2U6Ok1BUEZMQUdfTk9ORSwJCQkJZmFsc2UJfSwKCQkJCQl7ICJidWZmZXJfc3ViX2RhdGEiLAkJCQkJImJ1ZmZlclN1YkRhdGEiLAlVUExPQURNRVRIT0RfQlVGRkVSX1NVQl9EQVRBLAlCdWZmZXJJblVzZVJlbmRlclRpbWVDYXNlOjpNQVBGTEFHX05PTkUsCQkJCXRydWUJfSwKCQkJCQl7ICJtYXBfYnVmZmVyX3JhbmdlX2ludmFsaWRhdGVfcmFuZ2UiLAkibWFwQnVmZmVyUmFuZ2UiLAlVUExPQURNRVRIT0RfTUFQX0JVRkZFUl9SQU5HRSwJQnVmZmVySW5Vc2VSZW5kZXJUaW1lQ2FzZTo6TUFQRkxBR19JTlZBTElEQVRFX1JBTkdFLAl0cnVlCX0sCgkJCQkJeyAibWFwX2J1ZmZlcl9yYW5nZV9pbnZhbGlkYXRlX2J1ZmZlciIsCSJtYXBCdWZmZXJSYW5nZSIsCVVQTE9BRE1FVEhPRF9NQVBfQlVGRkVSX1JBTkdFLAlCdWZmZXJJblVzZVJlbmRlclRpbWVDYXNlOjpNQVBGTEFHX0lOVkFMSURBVEVfQlVGRkVSLAlmYWxzZQl9LAoJCQkJfTsKCgkJCQl0Y3U6OlRlc3RDYXNlR3JvdXAqIGNvbnN0IGRyYXdVcGxvYWREcmF3R3JvdXAgPSBuZXcgdGN1OjpUZXN0Q2FzZUdyb3VwKG1fdGVzdEN0eCwgImRyYXdfdXBsb2FkX2RyYXciLCAiVGltZSB1c2FnZSBvZiBmdW5jdGlvbnMgZHJhdywgdXBsb2FkIGFuZCBhbm90aGVyIGRyYXciKTsKCQkJCXJlbmRlclJlZmVyZW5jZUdyb3VwLT5hZGRDaGlsZChkcmF3VXBsb2FkRHJhd0dyb3VwKTsKCgkJCQlmb3IgKGludCB1cGxvYWRUYXJnZXROZHggPSAwOyB1cGxvYWRUYXJnZXROZHggPCBERV9MRU5HVEhfT0ZfQVJSQVkodXBsb2FkVGFyZ2V0cyk7ICsrdXBsb2FkVGFyZ2V0TmR4KQoJCQkJZm9yIChpbnQgdXBsb2FkTWV0aG9kTmR4ID0gMDsgdXBsb2FkTWV0aG9kTmR4IDwgREVfTEVOR1RIX09GX0FSUkFZKHVwbG9hZE1ldGhvZHMpOyArK3VwbG9hZE1ldGhvZE5keCkKCQkJCXsKCQkJCQljb25zdCBzdGQ6OnN0cmluZyBuYW1lID0gc3RkOjpzdHJpbmcoKSArIHVwbG9hZFRhcmdldHNbdXBsb2FkVGFyZ2V0TmR4XS5uYW1lICsgIl93aXRoXyIgKyB1cGxvYWRNZXRob2RzW3VwbG9hZE1ldGhvZE5keF0ubmFtZTsKCgkJCQkJaWYgKHVwbG9hZFRhcmdldHNbdXBsb2FkVGFyZ2V0TmR4XS5wYXJ0aWFsICYmICF1cGxvYWRNZXRob2RzW3VwbG9hZE1ldGhvZE5keF0uc3VwcG9ydHNQYXJ0aWFsVXBsb2FkKQoJCQkJCQljb250aW51ZTsKCgkJCQkJZHJhd1VwbG9hZERyYXdHcm91cC0+YWRkQ2hpbGQobmV3IEJ1ZmZlckluVXNlUmVuZGVyVGltZUNhc2UobV9jb250ZXh0LAoJCQkJCQkJCQkJCQkJCQkJCQkJCW5hbWUuY19zdHIoKSwKCQkJCQkJCQkJCQkJCQkJCQkJCQl1cGxvYWRUYXJnZXRzW3VwbG9hZFRhcmdldE5keF0uZGVzY3JpcHRpb24sCgkJCQkJCQkJCQkJCQkJCQkJCQkJdXBsb2FkVGFyZ2V0c1t1cGxvYWRUYXJnZXROZHhdLmRyYXdNZXRob2QsCgkJCQkJCQkJCQkJCQkJCQkJCQkJdXBsb2FkTWV0aG9kc1t1cGxvYWRNZXRob2ROZHhdLm1hcEZsYWdzLAoJCQkJCQkJCQkJCQkJCQkJCQkJCXVwbG9hZFRhcmdldHNbdXBsb2FkVGFyZ2V0TmR4XS50YXJnZXRCdWZmZXIsCgkJCQkJCQkJCQkJCQkJCQkJCQkJdXBsb2FkTWV0aG9kc1t1cGxvYWRNZXRob2ROZHhdLnVwbG9hZE1ldGhvZCwKCQkJCQkJCQkJCQkJCQkJCQkJCQkodXBsb2FkVGFyZ2V0c1t1cGxvYWRUYXJnZXROZHhdLnBhcnRpYWwpID8gKFVQTE9BRFJBTkdFX1BBUlRJQUwpIDogKFVQTE9BRFJBTkdFX0ZVTEwpLAoJCQkJCQkJCQkJCQkJCQkJCQkJCUJ1ZmZlckluVXNlUmVuZGVyVGltZUNhc2U6OlVQTE9BREJVRkZFUlRBUkdFVF9ESUZGRVJFTlRfQlVGRkVSKSk7CgkJCQl9CgkJCX0KCQl9CgoJCS8vIC51cGxvYWRfdW5yZWxhdGVkX2FuZF9kcmF3CgkJewoJCQlzdGF0aWMgY29uc3Qgc3RydWN0CgkJCXsKCQkJCWNvbnN0IGNoYXIqCQluYW1lOwoJCQkJY29uc3QgY2hhcioJCWRlc2NyaXB0aW9uOwoJCQkJRHJhd01ldGhvZAkJZHJhd01ldGhvZDsKCQkJfSBkcmF3TWV0aG9kc1tdID0KCQkJewoJCQkJeyAiZHJhd19hcnJheXMiLAkiZHJhd0FycmF5cyIsCURSQVdNRVRIT0RfRFJBV19BUlJBWVMJCX0sCgkJCQl7ICJkcmF3X2VsZW1lbnRzIiwJImRyYXdFbGVtZW50cyIsCURSQVdNRVRIT0RfRFJBV19FTEVNRU5UUwl9LAoJCQl9OwoKCQkJc3RhdGljIGNvbnN0IHN0cnVjdAoJCQl7CgkJCQljb25zdCBjaGFyKgkJbmFtZTsKCQkJCVVwbG9hZE1ldGhvZAl1cGxvYWRNZXRob2Q7CgkJCX0gdXBsb2FkTWV0aG9kc1tdID0KCQkJewoJCQkJeyAiYnVmZmVyX2RhdGEiLAkJVVBMT0FETUVUSE9EX0JVRkZFUl9EQVRBCQl9LAoJCQkJeyAiYnVmZmVyX3N1Yl9kYXRhIiwJVVBMT0FETUVUSE9EX0JVRkZFUl9TVUJfREFUQQl9LAoJCQkJeyAibWFwX2J1ZmZlcl9yYW5nZSIsCVVQTE9BRE1FVEhPRF9NQVBfQlVGRkVSX1JBTkdFCX0sCgkJCX07CgoJCQl0Y3U6OlRlc3RDYXNlR3JvdXAqIGNvbnN0IHVwbG9hZFVucmVsYXRlZEdyb3VwID0gbmV3IHRjdTo6VGVzdENhc2VHcm91cChtX3Rlc3RDdHgsICJ1cGxvYWRfdW5yZWxhdGVkX2FuZF9kcmF3IiwgIlRpbWUgdXNhZ2Ugb2YgZnVuY3Rpb25zIGFmdGVyIGFuIHVucmVsYXRlZCB1cGxvYWQiKTsKCQkJcmVuZGVyQWZ0ZXJVcGxvYWRHcm91cC0+YWRkQ2hpbGQodXBsb2FkVW5yZWxhdGVkR3JvdXApOwoKCQkJZm9yIChpbnQgZHJhd01ldGhvZE5keCA9IDA7IGRyYXdNZXRob2ROZHggPCBERV9MRU5HVEhfT0ZfQVJSQVkoZHJhd01ldGhvZHMpOyArK2RyYXdNZXRob2ROZHgpCgkJCWZvciAoaW50IHVwbG9hZE1ldGhvZE5keCA9IDA7IHVwbG9hZE1ldGhvZE5keCA8IERFX0xFTkdUSF9PRl9BUlJBWSh1cGxvYWRNZXRob2RzKTsgKyt1cGxvYWRNZXRob2ROZHgpCgkJCXsKCQkJCWNvbnN0IHN0ZDo6c3RyaW5nIG5hbWUgPSBzdGQ6OnN0cmluZygpICsgZHJhd01ldGhvZHNbZHJhd01ldGhvZE5keF0ubmFtZSArICJfdXBsb2FkX3VucmVsYXRlZF93aXRoXyIgKyB1cGxvYWRNZXRob2RzW3VwbG9hZE1ldGhvZE5keF0ubmFtZTsKCQkJCWNvbnN0IHN0ZDo6c3RyaW5nIGRlc2MgPSBzdGQ6OnN0cmluZygpICsgIk1lYXN1cmUgdGltZSBjb25zdW1lZCBieSAiICsgZHJhd01ldGhvZHNbZHJhd01ldGhvZE5keF0uZGVzY3JpcHRpb24gKyAiIGZ1bmN0aW9uIGNhbGwgYWZ0ZXIgYW4gdW5yZWxhdGVkIHVwbG9hZCI7CgoJCQkJLy8gVGltZSBjb25zdW1lZCBieSByZW5kZXJpbmcgY29tbWFuZCBhZnRlciBhbiB1bnJlbGF0ZWQgdXBsb2FkCgoJCQkJdXBsb2FkVW5yZWxhdGVkR3JvdXAtPmFkZENoaWxkKG5ldyBVbnJlbGF0ZWRVcGxvYWRSZW5kZXJUaW1lQ2FzZShtX2NvbnRleHQsIG5hbWUuY19zdHIoKSwgZGVzYy5jX3N0cigpLCBkcmF3TWV0aG9kc1tkcmF3TWV0aG9kTmR4XS5kcmF3TWV0aG9kLCB1cGxvYWRNZXRob2RzW3VwbG9hZE1ldGhvZE5keF0udXBsb2FkTWV0aG9kKSk7CgkJCX0KCQl9CgoJCS8vIC51cGxvYWRfYW5kX2RyYXcKCQl7CgkJCXN0YXRpYyBjb25zdCBzdHJ1Y3QKCQkJewoJCQkJY29uc3QgY2hhcioJCQluYW1lOwoJCQkJY29uc3QgY2hhcioJCQlkZXNjcmlwdGlvbjsKCQkJCUJ1ZmZlclN0YXRlCQkJYnVmZmVyU3RhdGU7CgkJCQlVbnJlbGF0ZWRCdWZmZXJUeXBlCXVucmVsYXRlZEJ1ZmZlcjsKCQkJCWJvb2wJCQkJc3VwcG9ydHNQYXJ0aWFsVXBsb2FkOwoJCQl9IGJ1ZmZlckNvbmZpZ3NbXSA9CgkJCXsKCQkJCXsgInVzZWRfYnVmZmVyIiwJCQkJCQkiVXBsb2FkIHRvIGFuIHVzZWQgYnVmZmVyIiwJCQkJCQkJCQkJCUJVRkZFUlNUQVRFX0VYSVNUSU5HLAlVTlJFTEFURURCVUZGRVJUWVBFX05PTkUsCXRydWUJfSwKCQkJCXsgIm5ld19idWZmZXIiLAkJCQkJCQkiVXBsb2FkIHRvIGEgbmV3IGJ1ZmZlciIsCQkJCQkJCQkJCQlCVUZGRVJTVEFURV9ORVcsCQlVTlJFTEFURURCVUZGRVJUWVBFX05PTkUsCWZhbHNlCX0sCgkJCQl7ICJ1c2VkX2J1ZmZlcl9hbmRfdW5yZWxhdGVkX3VwbG9hZCIsCSJVcGxvYWQgdG8gYW4gdXNlZCBidWZmZXIgYW5kIGFuIHVucmVsYXRlZCBidWZmZXIgYW5kIHRoZW4gZHJhdyIsCUJVRkZFUlNUQVRFX0VYSVNUSU5HLAlVTlJFTEFURURCVUZGRVJUWVBFX1ZFUlRFWCwJdHJ1ZQl9LAoJCQkJeyAibmV3X2J1ZmZlcl9hbmRfdW5yZWxhdGVkX3VwbG9hZCIsCSJVcGxvYWQgdG8gYSBuZXcgYnVmZmVyIGFuZCBhbiB1bnJlbGF0ZWQgYnVmZmVyIGFuZCB0aGVuIGRyYXciLAkJQlVGRkVSU1RBVEVfTkVXLAkJVU5SRUxBVEVEQlVGRkVSVFlQRV9WRVJURVgsCWZhbHNlCX0sCgkJCX07CgoJCQl0Y3U6OlRlc3RDYXNlR3JvdXAqIGNvbnN0IHVwbG9hZEFuZERyYXdHcm91cCA9IG5ldyB0Y3U6OlRlc3RDYXNlR3JvdXAobV90ZXN0Q3R4LCAidXBsb2FkX2FuZF9kcmF3IiwgIlRpbWUgdXNhZ2Ugb2YgcmVuZGVyaW5nIGZ1bmN0aW9ucyB3aXRoIG1vZGlmaWVkIGJ1ZmZlcnMiKTsKCQkJcmVuZGVyQWZ0ZXJVcGxvYWRHcm91cC0+YWRkQ2hpbGQodXBsb2FkQW5kRHJhd0dyb3VwKTsKCgkJCS8vIC51c2VkX2J1ZmZlcgoJCQkvLyAubmV3X2J1ZmZlcgoJCQkvLyAudXNlZF9idWZmZXJfYW5kX3VucmVsYXRlZF91cGxvYWQKCQkJLy8gLm5ld19idWZmZXJfYW5kX3VucmVsYXRlZF91cGxvYWQKCQkJZm9yIChpbnQgc3RhdGVOZHggPSAwOyBzdGF0ZU5keCA8IERFX0xFTkdUSF9PRl9BUlJBWShidWZmZXJDb25maWdzKTsgKytzdGF0ZU5keCkKCQkJewoJCQkJc3RhdGljIGNvbnN0IHN0cnVjdAoJCQkJewoJCQkJCWNvbnN0IGNoYXIqCQluYW1lOwoJCQkJCWNvbnN0IGNoYXIqCQlkZXNjcmlwdGlvbjsKCQkJCQlEcmF3TWV0aG9kCQlkcmF3TWV0aG9kOwoJCQkJCVRhcmdldEJ1ZmZlcgl0YXJnZXRCdWZmZXI7CgkJCQkJYm9vbAkJCXBhcnRpYWw7CgkJCQl9IHVwbG9hZFRhcmdldHNbXSA9CgkJCQl7CgkJCQkJewoJCQkJCQkiZHJhd19hcnJheXNfdXBsb2FkX3ZlcnRpY2VzIiwKCQkJCQkJIk1lYXN1cmUgdGltZSBjb25zdW1lZCBieSB2ZXJ0ZXggYXR0cmlidXRlIHVwbG9hZCwgZHJhd0FycmF5cywgYW5kIHJlYWRQaXhlbHMgZnVuY3Rpb24gY2FsbHMiLAoJCQkJCQlEUkFXTUVUSE9EX0RSQVdfQVJSQVlTLAoJCQkJCQlUQVJHRVRCVUZGRVJfVkVSVEVYLAoJCQkJCQlmYWxzZQoJCQkJCX0sCgkJCQkJewoJCQkJCQkiZHJhd19hcnJheXNfdXBsb2FkX3ZlcnRpY2VzX3BhcnRpYWwiLAoJCQkJCQkiTWVhc3VyZSB0aW1lIGNvbnN1bWVkIGJ5IHBhcnRpYWwgdmVydGV4IGF0dHJpYnV0ZSB1cGxvYWQsIGRyYXdBcnJheXMsIGFuZCByZWFkUGl4ZWxzIGZ1bmN0aW9uIGNhbGxzIiwKCQkJCQkJRFJBV01FVEhPRF9EUkFXX0FSUkFZUywKCQkJCQkJVEFSR0VUQlVGRkVSX1ZFUlRFWCwKCQkJCQkJdHJ1ZQoJCQkJCX0sCgkJCQkJewoJCQkJCQkiZHJhd19lbGVtZW50c191cGxvYWRfdmVydGljZXMiLAoJCQkJCQkiTWVhc3VyZSB0aW1lIGNvbnN1bWVkIGJ5IHZlcnRleCBhdHRyaWJ1dGUgdXBsb2FkLCBkcmF3RWxlbWVudHMsIGFuZCByZWFkUGl4ZWxzIGZ1bmN0aW9uIGNhbGxzIiwKCQkJCQkJRFJBV01FVEhPRF9EUkFXX0VMRU1FTlRTLAoJCQkJCQlUQVJHRVRCVUZGRVJfVkVSVEVYLAoJCQkJCQlmYWxzZQoJCQkJCX0sCgkJCQkJewoJCQkJCQkiZHJhd19lbGVtZW50c191cGxvYWRfaW5kaWNlcyIsCgkJCQkJCSJNZWFzdXJlIHRpbWUgY29uc3VtZWQgYnkgaW5kZXggdXBsb2FkLCBkcmF3RWxlbWVudHMsIGFuZCByZWFkUGl4ZWxzIGZ1bmN0aW9uIGNhbGxzIiwKCQkJCQkJRFJBV01FVEhPRF9EUkFXX0VMRU1FTlRTLAoJCQkJCQlUQVJHRVRCVUZGRVJfSU5ERVgsCgkJCQkJCWZhbHNlCgkJCQkJfSwKCQkJCQl7CgkJCQkJCSJkcmF3X2VsZW1lbnRzX3VwbG9hZF9pbmRpY2VzX3BhcnRpYWwiLAoJCQkJCQkiTWVhc3VyZSB0aW1lIGNvbnN1bWVkIGJ5IHBhcnRpYWwgaW5kZXggdXBsb2FkLCBkcmF3RWxlbWVudHMsIGFuZCByZWFkUGl4ZWxzIGZ1bmN0aW9uIGNhbGxzIiwKCQkJCQkJRFJBV01FVEhPRF9EUkFXX0VMRU1FTlRTLAoJCQkJCQlUQVJHRVRCVUZGRVJfSU5ERVgsCgkJCQkJCXRydWUKCQkJCQl9LAoJCQkJfTsKCQkJCXN0YXRpYyBjb25zdCBzdHJ1Y3QKCQkJCXsKCQkJCQljb25zdCBjaGFyKgkJbmFtZTsKCQkJCQljb25zdCBjaGFyKgkJZGVzY3JpcHRpb247CgkJCQkJVXBsb2FkTWV0aG9kCXVwbG9hZE1ldGhvZDsKCQkJCQlib29sCQkJc3VwcG9ydHNQYXJ0aWFsVXBsb2FkOwoJCQkJfSB1cGxvYWRNZXRob2RzW10gPQoJCQkJewoJCQkJCXsgImJ1ZmZlcl9kYXRhIiwJCSJidWZmZXJEYXRhIiwJCVVQTE9BRE1FVEhPRF9CVUZGRVJfREFUQSwJCWZhbHNlCX0sCgkJCQkJeyAiYnVmZmVyX3N1Yl9kYXRhIiwJImJ1ZmZlclN1YkRhdGEiLAlVUExPQURNRVRIT0RfQlVGRkVSX1NVQl9EQVRBLAl0cnVlCX0sCgkJCQkJeyAibWFwX2J1ZmZlcl9yYW5nZSIsCSJtYXBCdWZmZXJSYW5nZSIsCVVQTE9BRE1FVEhPRF9NQVBfQlVGRkVSX1JBTkdFLAl0cnVlCX0sCgkJCQl9OwoKCQkJCXRjdTo6VGVzdENhc2VHcm91cCogY29uc3QgZ3JvdXAgPSBuZXcgdGN1OjpUZXN0Q2FzZUdyb3VwKG1fdGVzdEN0eCwgYnVmZmVyQ29uZmlnc1tzdGF0ZU5keF0ubmFtZSwgYnVmZmVyQ29uZmlnc1tzdGF0ZU5keF0uZGVzY3JpcHRpb24pOwoJCQkJdXBsb2FkQW5kRHJhd0dyb3VwLT5hZGRDaGlsZChncm91cCk7CgoJCQkJZm9yIChpbnQgdXBsb2FkVGFyZ2V0TmR4ID0gMDsgdXBsb2FkVGFyZ2V0TmR4IDwgREVfTEVOR1RIX09GX0FSUkFZKHVwbG9hZFRhcmdldHMpOyArK3VwbG9hZFRhcmdldE5keCkKCQkJCWZvciAoaW50IHVwbG9hZE1ldGhvZE5keCA9IDA7IHVwbG9hZE1ldGhvZE5keCA8IERFX0xFTkdUSF9PRl9BUlJBWSh1cGxvYWRNZXRob2RzKTsgKyt1cGxvYWRNZXRob2ROZHgpCgkJCQl7CgkJCQkJY29uc3Qgc3RkOjpzdHJpbmcgbmFtZSA9IHN0ZDo6c3RyaW5nKCkgKyB1cGxvYWRUYXJnZXRzW3VwbG9hZFRhcmdldE5keF0ubmFtZSArICJfd2l0aF8iICsgdXBsb2FkTWV0aG9kc1t1cGxvYWRNZXRob2ROZHhdLm5hbWU7CgoJCQkJCWlmICh1cGxvYWRUYXJnZXRzW3VwbG9hZFRhcmdldE5keF0ucGFydGlhbCAmJiAhdXBsb2FkTWV0aG9kc1t1cGxvYWRNZXRob2ROZHhdLnN1cHBvcnRzUGFydGlhbFVwbG9hZCkKCQkJCQkJY29udGludWU7CgkJCQkJaWYgKHVwbG9hZFRhcmdldHNbdXBsb2FkVGFyZ2V0TmR4XS5wYXJ0aWFsICYmICFidWZmZXJDb25maWdzW3N0YXRlTmR4XS5zdXBwb3J0c1BhcnRpYWxVcGxvYWQpCgkJCQkJCWNvbnRpbnVlOwoKCQkJCQkvLyBEb24ndCBsb2cgdW5yZWxhdGVkIGJ1ZmZlciBpbmZvcm1hdGlvbiB0byBzYW1wbGVzIGlmIHRoZXJlIGlzIG5vIHN1Y2ggYnVmZmVyCgoJCQkJCWlmIChidWZmZXJDb25maWdzW3N0YXRlTmR4XS51bnJlbGF0ZWRCdWZmZXIgPT0gVU5SRUxBVEVEQlVGRkVSVFlQRV9OT05FKQoJCQkJCXsKCQkJCQkJdHlwZWRlZiBVcGxvYWRSZW5kZXJSZWFkRHVyYXRpb24JCQkJU2FtcGxlVHlwZTsKCQkJCQkJdHlwZWRlZiBHZW5lcmljVXBsb2FkUmVuZGVyVGltZUNhc2U8U2FtcGxlVHlwZT4JVGVzdFR5cGU7CgoJCQkJCQlncm91cC0+YWRkQ2hpbGQobmV3IFRlc3RUeXBlKG1fY29udGV4dCwKCQkJCQkJCQkJCQkJCSBuYW1lLmNfc3RyKCksCgkJCQkJCQkJCQkJCQkgdXBsb2FkVGFyZ2V0c1t1cGxvYWRUYXJnZXROZHhdLmRlc2NyaXB0aW9uLAoJCQkJCQkJCQkJCQkJIHVwbG9hZFRhcmdldHNbdXBsb2FkVGFyZ2V0TmR4XS5kcmF3TWV0aG9kLAoJCQkJCQkJCQkJCQkJIHVwbG9hZFRhcmdldHNbdXBsb2FkVGFyZ2V0TmR4XS50YXJnZXRCdWZmZXIsCgkJCQkJCQkJCQkJCQkgdXBsb2FkTWV0aG9kc1t1cGxvYWRNZXRob2ROZHhdLnVwbG9hZE1ldGhvZCwKCQkJCQkJCQkJCQkJCSBidWZmZXJDb25maWdzW3N0YXRlTmR4XS5idWZmZXJTdGF0ZSwKCQkJCQkJCQkJCQkJCSAodXBsb2FkVGFyZ2V0c1t1cGxvYWRUYXJnZXROZHhdLnBhcnRpYWwpID8gKFVQTE9BRFJBTkdFX1BBUlRJQUwpIDogKFVQTE9BRFJBTkdFX0ZVTEwpLAoJCQkJCQkJCQkJCQkJIGJ1ZmZlckNvbmZpZ3Nbc3RhdGVOZHhdLnVucmVsYXRlZEJ1ZmZlcikpOwoJCQkJCX0KCQkJCQllbHNlCgkJCQkJewoJCQkJCQl0eXBlZGVmIFVwbG9hZFJlbmRlclJlYWREdXJhdGlvbldpdGhVbnJlbGF0ZWRVcGxvYWRTaXplCVNhbXBsZVR5cGU7CgkJCQkJCXR5cGVkZWYgR2VuZXJpY1VwbG9hZFJlbmRlclRpbWVDYXNlPFNhbXBsZVR5cGU+CQkJVGVzdFR5cGU7CgoJCQkJCQlncm91cC0+YWRkQ2hpbGQobmV3IFRlc3RUeXBlKG1fY29udGV4dCwKCQkJCQkJCQkJCQkJCSBuYW1lLmNfc3RyKCksCgkJCQkJCQkJCQkJCQkgdXBsb2FkVGFyZ2V0c1t1cGxvYWRUYXJnZXROZHhdLmRlc2NyaXB0aW9uLAoJCQkJCQkJCQkJCQkJIHVwbG9hZFRhcmdldHNbdXBsb2FkVGFyZ2V0TmR4XS5kcmF3TWV0aG9kLAoJCQkJCQkJCQkJCQkJIHVwbG9hZFRhcmdldHNbdXBsb2FkVGFyZ2V0TmR4XS50YXJnZXRCdWZmZXIsCgkJCQkJCQkJCQkJCQkgdXBsb2FkTWV0aG9kc1t1cGxvYWRNZXRob2ROZHhdLnVwbG9hZE1ldGhvZCwKCQkJCQkJCQkJCQkJCSBidWZmZXJDb25maWdzW3N0YXRlTmR4XS5idWZmZXJTdGF0ZSwKCQkJCQkJCQkJCQkJCSAodXBsb2FkVGFyZ2V0c1t1cGxvYWRUYXJnZXROZHhdLnBhcnRpYWwpID8gKFVQTE9BRFJBTkdFX1BBUlRJQUwpIDogKFVQTE9BRFJBTkdFX0ZVTEwpLAoJCQkJCQkJCQkJCQkJIGJ1ZmZlckNvbmZpZ3Nbc3RhdGVOZHhdLnVucmVsYXRlZEJ1ZmZlcikpOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCgkJLy8gLmRyYXdfbW9kaWZ5X2RyYXcKCQl7CgkJCXN0YXRpYyBjb25zdCBzdHJ1Y3QKCQkJewoJCQkJY29uc3QgY2hhcioJCW5hbWU7CgkJCQljb25zdCBjaGFyKgkJZGVzY3JpcHRpb247CgkJCQlEcmF3TWV0aG9kCQlkcmF3TWV0aG9kOwoJCQkJVGFyZ2V0QnVmZmVyCXRhcmdldEJ1ZmZlcjsKCQkJCWJvb2wJCQlwYXJ0aWFsOwoJCQl9IHVwbG9hZFRhcmdldHNbXSA9CgkJCXsKCQkJCXsKCQkJCQkiZHJhd19hcnJheXNfdXBsb2FkX3ZlcnRpY2VzIiwKCQkJCQkiTWVhc3VyZSB0aW1lIGNvbnN1bWVkIGJ5IGRyYXdBcnJheXMsIHZlcnRleCBhdHRyaWJ1dGUgdXBsb2FkLCBhbm90aGVyIGRyYXdBcnJheXMsIGFuZCByZWFkUGl4ZWxzIGZ1bmN0aW9uIGNhbGxzLiIsCgkJCQkJRFJBV01FVEhPRF9EUkFXX0FSUkFZUywKCQkJCQlUQVJHRVRCVUZGRVJfVkVSVEVYLAoJCQkJCWZhbHNlCgkJCQl9LAoJCQkJewoJCQkJCSJkcmF3X2FycmF5c191cGxvYWRfdmVydGljZXNfcGFydGlhbCIsCgkJCQkJIk1lYXN1cmUgdGltZSBjb25zdW1lZCBieSBkcmF3QXJyYXlzLCBwYXJ0aWFsIHZlcnRleCBhdHRyaWJ1dGUgdXBsb2FkLCBhbm90aGVyIGRyYXdBcnJheXMsIGFuZCByZWFkUGl4ZWxzIGZ1bmN0aW9uIGNhbGxzLiIsCgkJCQkJRFJBV01FVEhPRF9EUkFXX0FSUkFZUywKCQkJCQlUQVJHRVRCVUZGRVJfVkVSVEVYLAoJCQkJCXRydWUKCQkJCX0sCgkJCQl7CgkJCQkJImRyYXdfZWxlbWVudHNfdXBsb2FkX3ZlcnRpY2VzIiwKCQkJCQkiTWVhc3VyZSB0aW1lIGNvbnN1bWVkIGJ5IGRyYXdFbGVtZW50cywgdmVydGV4IGF0dHJpYnV0ZSB1cGxvYWQsIGFub3RoZXIgZHJhd0VsZW1lbnRzLCBhbmQgcmVhZFBpeGVscyBmdW5jdGlvbiBjYWxscy4iLAoJCQkJCURSQVdNRVRIT0RfRFJBV19FTEVNRU5UUywKCQkJCQlUQVJHRVRCVUZGRVJfVkVSVEVYLAoJCQkJCWZhbHNlCgkJCQl9LAoJCQkJewoJCQkJCSJkcmF3X2VsZW1lbnRzX3VwbG9hZF9pbmRpY2VzIiwKCQkJCQkiTWVhc3VyZSB0aW1lIGNvbnN1bWVkIGJ5IGRyYXdFbGVtZW50cywgaW5kZXggdXBsb2FkLCBhbm90aGVyIGRyYXdFbGVtZW50cywgYW5kIHJlYWRQaXhlbHMgZnVuY3Rpb24gY2FsbHMuIiwKCQkJCQlEUkFXTUVUSE9EX0RSQVdfRUxFTUVOVFMsCgkJCQkJVEFSR0VUQlVGRkVSX0lOREVYLAoJCQkJCWZhbHNlCgkJCQl9LAoJCQkJewoJCQkJCSJkcmF3X2VsZW1lbnRzX3VwbG9hZF9pbmRpY2VzX3BhcnRpYWwiLAoJCQkJCSJNZWFzdXJlIHRpbWUgY29uc3VtZWQgYnkgZHJhd0VsZW1lbnRzLCBwYXJ0aWFsIGluZGV4IHVwbG9hZCwgYW5vdGhlciBkcmF3RWxlbWVudHMsIGFuZCByZWFkUGl4ZWxzIGZ1bmN0aW9uIGNhbGxzLiIsCgkJCQkJRFJBV01FVEhPRF9EUkFXX0VMRU1FTlRTLAoJCQkJCVRBUkdFVEJVRkZFUl9JTkRFWCwKCQkJCQl0cnVlCgkJCQl9LAoJCQl9OwoJCQlzdGF0aWMgY29uc3Qgc3RydWN0CgkJCXsKCQkJCWNvbnN0IGNoYXIqCQkJCQkJCW5hbWU7CgkJCQljb25zdCBjaGFyKgkJCQkJCQlkZXNjcmlwdGlvbjsKCQkJCVVwbG9hZE1ldGhvZAkJCQkJCXVwbG9hZE1ldGhvZDsKCQkJCUJ1ZmZlckluVXNlUmVuZGVyVGltZUNhc2U6Ok1hcEZsYWdzCW1hcEZsYWdzOwoJCQkJYm9vbAkJCQkJCQkJc3VwcG9ydHNQYXJ0aWFsVXBsb2FkOwoJCQl9IHVwbG9hZE1ldGhvZHNbXSA9CgkJCXsKCQkJCXsgImJ1ZmZlcl9kYXRhIiwJCQkJCQkiYnVmZmVyRGF0YSIsCQlVUExPQURNRVRIT0RfQlVGRkVSX0RBVEEsCQlCdWZmZXJJblVzZVJlbmRlclRpbWVDYXNlOjpNQVBGTEFHX05PTkUsCQkJCWZhbHNlCX0sCgkJCQl7ICJidWZmZXJfc3ViX2RhdGEiLAkJCQkJImJ1ZmZlclN1YkRhdGEiLAlVUExPQURNRVRIT0RfQlVGRkVSX1NVQl9EQVRBLAlCdWZmZXJJblVzZVJlbmRlclRpbWVDYXNlOjpNQVBGTEFHX05PTkUsCQkJCXRydWUJfSwKCQkJCXsgIm1hcF9idWZmZXJfcmFuZ2VfaW52YWxpZGF0ZV9yYW5nZSIsCSJtYXBCdWZmZXJSYW5nZSIsCVVQTE9BRE1FVEhPRF9NQVBfQlVGRkVSX1JBTkdFLAlCdWZmZXJJblVzZVJlbmRlclRpbWVDYXNlOjpNQVBGTEFHX0lOVkFMSURBVEVfUkFOR0UsCXRydWUJfSwKCQkJCXsgIm1hcF9idWZmZXJfcmFuZ2VfaW52YWxpZGF0ZV9idWZmZXIiLAkibWFwQnVmZmVyUmFuZ2UiLAlVUExPQURNRVRIT0RfTUFQX0JVRkZFUl9SQU5HRSwJQnVmZmVySW5Vc2VSZW5kZXJUaW1lQ2FzZTo6TUFQRkxBR19JTlZBTElEQVRFX0JVRkZFUiwJZmFsc2UJfSwKCQkJfTsKCgkJCXRjdTo6VGVzdENhc2VHcm91cCogY29uc3QgZHJhd01vZGlmeURyYXdHcm91cCA9IG5ldyB0Y3U6OlRlc3RDYXNlR3JvdXAobV90ZXN0Q3R4LCAiZHJhd19tb2RpZnlfZHJhdyIsICJUaW1lIHVzZWQgaW4gcmVuZGVyaW5nIGZ1bmN0aW9ucyB3aXRoIG1vZGlmaWVkIGJ1ZmZlcnMgd2hpbGUgb3JpZ2luYWwgYnVmZmVyIGlzIHN0aWxsIGluIHVzZSIpOwoJCQlyZW5kZXJBZnRlclVwbG9hZEdyb3VwLT5hZGRDaGlsZChkcmF3TW9kaWZ5RHJhd0dyb3VwKTsKCgkJCWZvciAoaW50IHVwbG9hZFRhcmdldE5keCA9IDA7IHVwbG9hZFRhcmdldE5keCA8IERFX0xFTkdUSF9PRl9BUlJBWSh1cGxvYWRUYXJnZXRzKTsgKyt1cGxvYWRUYXJnZXROZHgpCgkJCWZvciAoaW50IHVwbG9hZE1ldGhvZE5keCA9IDA7IHVwbG9hZE1ldGhvZE5keCA8IERFX0xFTkdUSF9PRl9BUlJBWSh1cGxvYWRNZXRob2RzKTsgKyt1cGxvYWRNZXRob2ROZHgpCgkJCXsKCQkJCWNvbnN0IHN0ZDo6c3RyaW5nIG5hbWUgPSBzdGQ6OnN0cmluZygpICsgdXBsb2FkVGFyZ2V0c1t1cGxvYWRUYXJnZXROZHhdLm5hbWUgKyAiX3dpdGhfIiArIHVwbG9hZE1ldGhvZHNbdXBsb2FkTWV0aG9kTmR4XS5uYW1lOwoKCQkJCWlmICh1cGxvYWRUYXJnZXRzW3VwbG9hZFRhcmdldE5keF0ucGFydGlhbCAmJiAhdXBsb2FkTWV0aG9kc1t1cGxvYWRNZXRob2ROZHhdLnN1cHBvcnRzUGFydGlhbFVwbG9hZCkKCQkJCQljb250aW51ZTsKCgkJCQlkcmF3TW9kaWZ5RHJhd0dyb3VwLT5hZGRDaGlsZChuZXcgQnVmZmVySW5Vc2VSZW5kZXJUaW1lQ2FzZShtX2NvbnRleHQsCgkJCQkJCQkJCQkJCQkJCQkJCQluYW1lLmNfc3RyKCksCgkJCQkJCQkJCQkJCQkJCQkJCQl1cGxvYWRUYXJnZXRzW3VwbG9hZFRhcmdldE5keF0uZGVzY3JpcHRpb24sCgkJCQkJCQkJCQkJCQkJCQkJCQl1cGxvYWRUYXJnZXRzW3VwbG9hZFRhcmdldE5keF0uZHJhd01ldGhvZCwKCQkJCQkJCQkJCQkJCQkJCQkJCXVwbG9hZE1ldGhvZHNbdXBsb2FkTWV0aG9kTmR4XS5tYXBGbGFncywKCQkJCQkJCQkJCQkJCQkJCQkJCXVwbG9hZFRhcmdldHNbdXBsb2FkVGFyZ2V0TmR4XS50YXJnZXRCdWZmZXIsCgkJCQkJCQkJCQkJCQkJCQkJCQl1cGxvYWRNZXRob2RzW3VwbG9hZE1ldGhvZE5keF0udXBsb2FkTWV0aG9kLAoJCQkJCQkJCQkJCQkJCQkJCQkJKHVwbG9hZFRhcmdldHNbdXBsb2FkVGFyZ2V0TmR4XS5wYXJ0aWFsKSA/IChVUExPQURSQU5HRV9QQVJUSUFMKSA6IChVUExPQURSQU5HRV9GVUxMKSwKCQkJCQkJCQkJCQkJCQkJCQkJCUJ1ZmZlckluVXNlUmVuZGVyVGltZUNhc2U6OlVQTE9BREJVRkZFUlRBUkdFVF9TQU1FX0JVRkZFUikpOwoJCQl9CgkJfQoKCQkvLyAudXBsb2FkX3dhaXRfZHJhdwoJCXsKCQkJc3RhdGljIGNvbnN0IHN0cnVjdAoJCQl7CgkJCQljb25zdCBjaGFyKgluYW1lOwoJCQkJY29uc3QgY2hhcioJZGVzY3JpcHRpb247CgkJCQlCdWZmZXJTdGF0ZQlidWZmZXJTdGF0ZTsKCQkJfSBidWZmZXJTdGF0ZXNbXSA9CgkJCXsKCQkJCXsgIm5ld19idWZmZXIiLAkJIlVwbG9hZGluZyB0byBqdXN0IGdlbmVyYXRlZCBuYW1lIiwJQlVGRkVSU1RBVEVfTkVXCQkJfSwKCQkJCXsgInVzZWRfYnVmZmVyIiwJIlVwbG9hZGluZyB0byBhIHVzZWQgYnVmZmVyIiwJCUJVRkZFUlNUQVRFX0VYSVNUSU5HCX0sCgkJCX07CgkJCXN0YXRpYyBjb25zdCBzdHJ1Y3QKCQkJewoJCQkJY29uc3QgY2hhcioJCW5hbWU7CgkJCQljb25zdCBjaGFyKgkJZGVzY3JpcHRpb247CgkJCQlEcmF3TWV0aG9kCQlkcmF3TWV0aG9kOwoJCQkJVGFyZ2V0QnVmZmVyCXRhcmdldEJ1ZmZlcjsKCQkJfSB1cGxvYWRUYXJnZXRzW10gPQoJCQl7CgkJCQl7ICJkcmF3X2FycmF5c192ZXJ0aWNlcyIsCSJVcGxvYWQgdmVydGV4IGRhdGEsIGRyYXcgd2l0aCBkcmF3QXJyYXlzIiwJCURSQVdNRVRIT0RfRFJBV19BUlJBWVMsCQlUQVJHRVRCVUZGRVJfVkVSVEVYCX0sCgkJCQl7ICJkcmF3X2VsZW1lbnRzX3ZlcnRpY2VzIiwJIlVwbG9hZCB2ZXJ0ZXggZGF0YSwgZHJhdyB3aXRoIGRyYXdFbGVtZW50cyIsCURSQVdNRVRIT0RfRFJBV19FTEVNRU5UUywJVEFSR0VUQlVGRkVSX1ZFUlRFWAl9LAoJCQkJeyAiZHJhd19lbGVtZW50c19pbmRpY2VzIiwJIlVwbG9hZCBpbmRleCBkYXRhLCBkcmF3IHdpdGggZHJhd0VsZW1lbnRzIiwJRFJBV01FVEhPRF9EUkFXX0VMRU1FTlRTLAlUQVJHRVRCVUZGRVJfSU5ERVgJfSwKCQkJfTsKCQkJc3RhdGljIGNvbnN0IHN0cnVjdAoJCQl7CgkJCQljb25zdCBjaGFyKgkJbmFtZTsKCQkJCWNvbnN0IGNoYXIqCQlkZXNjcmlwdGlvbjsKCQkJCVVwbG9hZE1ldGhvZAl1cGxvYWRNZXRob2Q7CgkJCX0gdXBsb2FkTWV0aG9kc1tdID0KCQkJewoJCQkJeyAiYnVmZmVyX2RhdGEiLAkJImJ1ZmZlckRhdGEiLAkJVVBMT0FETUVUSE9EX0JVRkZFUl9EQVRBCQl9LAoJCQkJeyAiYnVmZmVyX3N1Yl9kYXRhIiwJImJ1ZmZlclN1YkRhdGEiLAlVUExPQURNRVRIT0RfQlVGRkVSX1NVQl9EQVRBCX0sCgkJCQl7ICJtYXBfYnVmZmVyX3JhbmdlIiwJIm1hcEJ1ZmZlclJhbmdlIiwJVVBMT0FETUVUSE9EX01BUF9CVUZGRVJfUkFOR0UJfSwKCQkJfTsKCgkJCXRjdTo6VGVzdENhc2VHcm91cCogY29uc3QgdXBsb2FkU3dhcERyYXdHcm91cCA9IG5ldyB0Y3U6OlRlc3RDYXNlR3JvdXAobV90ZXN0Q3R4LCAidXBsb2FkX3dhaXRfZHJhdyIsICJUaW1lIHVzZWQgaW4gcmVuZGVyaW5nIGZ1bmN0aW9ucyBhZnRlciBhIGJ1ZmZlciB1cGxvYWQgTiBmcmFtZXMgYWdvIik7CgkJCXJlbmRlckFmdGVyVXBsb2FkR3JvdXAtPmFkZENoaWxkKHVwbG9hZFN3YXBEcmF3R3JvdXApOwoKCQkJZm9yIChpbnQgYnVmZmVyU3RhdGVOZHggPSAwOyBidWZmZXJTdGF0ZU5keCA8IERFX0xFTkdUSF9PRl9BUlJBWShidWZmZXJTdGF0ZXMpOyArK2J1ZmZlclN0YXRlTmR4KQoJCQl7CgkJCQl0Y3U6OlRlc3RDYXNlR3JvdXAqIGNvbnN0IGJ1ZmZlckdyb3VwID0gbmV3IHRjdTo6VGVzdENhc2VHcm91cChtX3Rlc3RDdHgsIGJ1ZmZlclN0YXRlc1tidWZmZXJTdGF0ZU5keF0ubmFtZSwgYnVmZmVyU3RhdGVzW2J1ZmZlclN0YXRlTmR4XS5kZXNjcmlwdGlvbik7CgkJCQl1cGxvYWRTd2FwRHJhd0dyb3VwLT5hZGRDaGlsZChidWZmZXJHcm91cCk7CgoJCQkJZm9yIChpbnQgdXBsb2FkVGFyZ2V0TmR4ID0gMDsgdXBsb2FkVGFyZ2V0TmR4IDwgREVfTEVOR1RIX09GX0FSUkFZKHVwbG9hZFRhcmdldHMpOyArK3VwbG9hZFRhcmdldE5keCkKCQkJCWZvciAoaW50IHVwbG9hZE1ldGhvZE5keCA9IDA7IHVwbG9hZE1ldGhvZE5keCA8IERFX0xFTkdUSF9PRl9BUlJBWSh1cGxvYWRNZXRob2RzKTsgKyt1cGxvYWRNZXRob2ROZHgpCgkJCQl7CgkJCQkJY29uc3Qgc3RkOjpzdHJpbmcgbmFtZSA9IHN0ZDo6c3RyaW5nKCkgKyB1cGxvYWRUYXJnZXRzW3VwbG9hZFRhcmdldE5keF0ubmFtZSArICJfd2l0aF8iICsgdXBsb2FkTWV0aG9kc1t1cGxvYWRNZXRob2ROZHhdLm5hbWU7CgoJCQkJCWJ1ZmZlckdyb3VwLT5hZGRDaGlsZChuZXcgVXBsb2FkV2FpdERyYXdDYXNlKG1fY29udGV4dCwKCQkJCQkJCQkJCQkJCQkJCSBuYW1lLmNfc3RyKCksCgkJCQkJCQkJCQkJCQkJCQkgdXBsb2FkVGFyZ2V0c1t1cGxvYWRUYXJnZXROZHhdLmRlc2NyaXB0aW9uLAoJCQkJCQkJCQkJCQkJCQkJIHVwbG9hZFRhcmdldHNbdXBsb2FkVGFyZ2V0TmR4XS5kcmF3TWV0aG9kLAoJCQkJCQkJCQkJCQkJCQkJIHVwbG9hZFRhcmdldHNbdXBsb2FkVGFyZ2V0TmR4XS50YXJnZXRCdWZmZXIsCgkJCQkJCQkJCQkJCQkJCQkgdXBsb2FkTWV0aG9kc1t1cGxvYWRNZXRob2ROZHhdLnVwbG9hZE1ldGhvZCwKCQkJCQkJCQkJCQkJCQkJCSBidWZmZXJTdGF0ZXNbYnVmZmVyU3RhdGVOZHhdLmJ1ZmZlclN0YXRlKSk7CgkJCQl9CgkJCX0KCQl9Cgl9Cn0KCn0gLy8gUGVyZm9ybWFuY2UKfSAvLyBnbGVzMwp9IC8vIGRlcXAK