Ly89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8KLy8gT3V0cHV0RGV2LmgKLy8KLy8gQ29weXJpZ2h0IDE5OTYtMjAwMyBHbHlwaCAmIENvZywgTExDCi8vCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLwovLyBNb2RpZmllZCB1bmRlciB0aGUgUG9wcGxlciBwcm9qZWN0IC0gaHR0cDovL3BvcHBsZXIuZnJlZWRlc2t0b3Aub3JnCi8vCi8vIEFsbCBjaGFuZ2VzIG1hZGUgdW5kZXIgdGhlIFBvcHBsZXIgcHJvamVjdCB0byB0aGlzIGZpbGUgYXJlIGxpY2Vuc2VkCi8vIHVuZGVyIEdQTCB2ZXJzaW9uIDIgb3IgbGF0ZXIKLy8KLy8gQ29weXJpZ2h0IChDKSAyMDA1IEpvbmF0aGFuIEJsYW5kZm9yZCA8anJiQHJlZGhhdC5jb20+Ci8vIENvcHlyaWdodCAoQykgMjAwNiBUaG9ya2lsZCBTdHJheSA8dGhvcmtpbGRAaWZpLnVpby5ubz4KLy8gQ29weXJpZ2h0IChDKSAyMDA3IEplZmYgTXVpemVsYWFyIDxqZWZmQGluZmlkaWdtLm5ldD4KLy8gQ29weXJpZ2h0IChDKSAyMDA3LCAyMDExLCAyMDE3IEFkcmlhbiBKb2huc29uIDxham9obnNvbkByZWRuZW9uLmNvbT4KLy8gQ29weXJpZ2h0IChDKSAyMDA5LTIwMTMsIDIwMTUgVGhvbWFzIEZyZWl0YWcgPFRob21hcy5GcmVpdGFnQGFsZmEuZGU+Ci8vIENvcHlyaWdodCAoQykgMjAwOSwgMjAxMSBDYXJsb3MgR2FyY2lhIENhbXBvcyA8Y2FybG9zZ2NAZ25vbWUub3JnPgovLyBDb3B5cmlnaHQgKEMpIDIwMDksIDIwMTIsIDIwMTMsIDIwMTggQWxiZXJ0IEFzdGFscyBDaWQgPGFhY2lkQGtkZS5vcmc+Ci8vIENvcHlyaWdodCAoQykgMjAxMCBDaHJpc3RpYW4gRmV1ZXJz5G5nZXIgPGNmZXVlcnNhZW5nZXJAZ29vZ2xlbWFpbC5jb20+Ci8vIENvcHlyaWdodCAoQykgMjAxMiBGYWJpbyBEJ1Vyc28gPGZhYmlvZHVyc29AaG90bWFpbC5pdD4KLy8gQ29weXJpZ2h0IChDKSAyMDEyIFdpbGxpYW0gQmFkZXIgPHdpbGxpYW1iYWRlckBob3RtYWlsLmNvbT4KLy8gQ29weXJpZ2h0IChDKSAyMDE3LCAyMDE4IE9saXZlciBTYW5kZXIgPG9saXZlci5zYW5kZXJAdHUtZHJlc2Rlbi5kZT4KLy8gQ29weXJpZ2h0IChDKSAyMDE4IEtsYXLkbHZkYWxlbnMgRGF0YWtvbnN1bHQgQUIsIGEgS0RBQiBHcm91cCBjb21wYW55LCA8aW5mb0BrZGFiLmNvbT4uIFdvcmsgc3BvbnNvcmVkIGJ5IHRoZSBMaU11eCBwcm9qZWN0IG9mIHRoZSBjaXR5IG9mIE11bmljaAovLyBDb3B5cmlnaHQgKEMpIDIwMTggQWRhbSBSZWljaG9sZCA8YWRhbS5yZWljaG9sZEB0LW9ubGluZS5kZT4KLy8KLy8gVG8gc2VlIGEgZGVzY3JpcHRpb24gb2YgdGhlIGNoYW5nZXMgcGxlYXNlIHNlZSB0aGUgQ2hhbmdlbG9nIGZpbGUgdGhhdAovLyBjYW1lIHdpdGggeW91ciB0YXJiYWxsIG9yIHR5cGUgbWFrZSBDaGFuZ2VMb2cgaWYgeW91IGFyZSBidWlsZGluZyBmcm9tIGdpdAovLwovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKI2lmbmRlZiBPVVRQVVRERVZfSAojZGVmaW5lIE9VVFBVVERFVl9ICgojaW5jbHVkZSAicG9wcGxlci1jb25maWcuaCIKI2luY2x1ZGUgIkNoYXJUeXBlcy5oIgojaW5jbHVkZSAiT2JqZWN0LmgiCiNpbmNsdWRlICJQb3BwbGVyQ2FjaGUuaCIKI2luY2x1ZGUgIlByb2ZpbGVEYXRhLmgiCiNpbmNsdWRlIDxtZW1vcnk+CiNpbmNsdWRlIDx1bm9yZGVyZWRfbWFwPgojaW5jbHVkZSA8c3RyaW5nPgoKY2xhc3MgQW5ub3Q7CmNsYXNzIERpY3Q7CmNsYXNzIEdvb1N0cmluZzsKY2xhc3MgR2Z4U3RhdGU7CmNsYXNzIEdmeDsKc3RydWN0IEdmeENvbG9yOwpjbGFzcyBHZnhDb2xvclNwYWNlOwojaWZkZWYgVVNFX0NNUwpjbGFzcyBHZnhJQ0NCYXNlZENvbG9yU3BhY2U7CiNlbmRpZgpjbGFzcyBHZnhJbWFnZUNvbG9yTWFwOwpjbGFzcyBHZnhGdW5jdGlvblNoYWRpbmc7CmNsYXNzIEdmeEF4aWFsU2hhZGluZzsKY2xhc3MgR2Z4R291cmF1ZFRyaWFuZ2xlU2hhZGluZzsKY2xhc3MgR2Z4UGF0Y2hNZXNoU2hhZGluZzsKY2xhc3MgR2Z4UmFkaWFsU2hhZGluZzsKY2xhc3MgR2Z4R291cmF1ZFRyaWFuZ2xlU2hhZGluZzsKY2xhc3MgR2Z4UGF0Y2hNZXNoU2hhZGluZzsKY2xhc3MgU3RyZWFtOwpjbGFzcyBMaW5rczsKY2xhc3MgQW5ub3RMaW5rOwpjbGFzcyBDYXRhbG9nOwpjbGFzcyBQYWdlOwpjbGFzcyBGdW5jdGlvbjsKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIE91dHB1dERldgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKY2xhc3MgT3V0cHV0RGV2IHsKcHVibGljOgoKICAvLyBDb25zdHJ1Y3Rvci4KICBPdXRwdXREZXYoKTsKCiAgLy8gRGVzdHJ1Y3Rvci4KICB2aXJ0dWFsIH5PdXRwdXREZXYoKTsKCiAgLy8tLS0tLSBnZXQgaW5mbyBhYm91dCBvdXRwdXQgZGV2aWNlCgogIC8vIERvZXMgdGhpcyBkZXZpY2UgdXNlIHVwc2lkZS1kb3duIGNvb3JkaW5hdGVzPwogIC8vIChVcHNpZGUtZG93biBtZWFucyAoMCwwKSBpcyB0aGUgdG9wIGxlZnQgY29ybmVyIG9mIHRoZSBwYWdlLikKICB2aXJ0dWFsIGJvb2wgdXBzaWRlRG93bigpID0gMDsKCiAgLy8gRG9lcyB0aGlzIGRldmljZSB1c2UgZHJhd0NoYXIoKSBvciBkcmF3U3RyaW5nKCk/CiAgdmlydHVhbCBib29sIHVzZURyYXdDaGFyKCkgPSAwOwoKICAvLyBEb2VzIHRoaXMgZGV2aWNlIHVzZSB0aWxpbmdQYXR0ZXJuRmlsbCgpPyAgSWYgdGhpcyByZXR1cm5zIGZhbHNlLAogIC8vIHRpbGluZyBwYXR0ZXJuIGZpbGxzIHdpbGwgYmUgcmVkdWNlZCB0byBhIHNlcmllcyBvZiBvdGhlciBkcmF3aW5nCiAgLy8gb3BlcmF0aW9ucy4KICB2aXJ0dWFsIGJvb2wgdXNlVGlsaW5nUGF0dGVybkZpbGwoKSB7IHJldHVybiBmYWxzZTsgfQoKICAvLyBEb2VzIHRoaXMgZGV2aWNlIHN1cHBvcnQgc3BlY2lmaWMgc2hhZGluZyB0eXBlcz8KICAvLyBzZWUgZ291cmF1ZFRyaWFuZ2xlU2hhZGVkRmlsbCgpIGFuZCBwYXRjaE1lc2hTaGFkZWRGaWxsKCkKICB2aXJ0dWFsIGJvb2wgdXNlU2hhZGVkRmlsbHMoaW50IHR5cGUpIHsgcmV0dXJuIGZhbHNlOyB9CgogIC8vIERvZXMgdGhpcyBkZXZpY2UgdXNlIEZpbGxDb2xvclN0b3AoKT8KICB2aXJ0dWFsIGJvb2wgdXNlRmlsbENvbG9yU3RvcCgpIHsgcmV0dXJuIGZhbHNlOyB9CgogIC8vIERvZXMgdGhpcyBkZXZpY2UgdXNlIGRyYXdGb3JtKCk/ICBJZiB0aGlzIHJldHVybnMgZmFsc2UsCiAgLy8gZm9ybS10eXBlIFhPYmplY3RzIHdpbGwgYmUgaW50ZXJwcmV0ZWQgKGkuZS4sIHVucm9sbGVkKS4KICB2aXJ0dWFsIGJvb2wgdXNlRHJhd0Zvcm0oKSB7IHJldHVybiBmYWxzZTsgfQoKICAvLyBEb2VzIHRoaXMgZGV2aWNlIHVzZSBiZWdpblR5cGUzQ2hhci9lbmRUeXBlM0NoYXI/ICBPdGhlcndpc2UsCiAgLy8gdGV4dCBpbiBUeXBlIDMgZm9udHMgd2lsbCBiZSBkcmF3biB3aXRoIGRyYXdDaGFyL2RyYXdTdHJpbmcuCiAgdmlydHVhbCBib29sIGludGVycHJldFR5cGUzQ2hhcnMoKSA9IDA7CgogIC8vIERvZXMgdGhpcyBkZXZpY2UgbmVlZCBub24tdGV4dCBjb250ZW50PwogIHZpcnR1YWwgYm9vbCBuZWVkTm9uVGV4dCgpIHsgcmV0dXJuIHRydWU7IH0KCiAgLy8gRG9lcyB0aGlzIGRldmljZSByZXF1aXJlIGluY0NoYXJDb3VudCB0byBiZSBjYWxsZWQgZm9yIHRleHQgb24KICAvLyBub24tc2hvd24gbGF5ZXJzPwogIHZpcnR1YWwgYm9vbCBuZWVkQ2hhckNvdW50KCkgeyByZXR1cm4gZmFsc2U7IH0KICAKICAvLyBEb2VzIHRoaXMgZGV2aWNlIG5lZWQgdG8gY2xpcCBwYWdlcyB0byB0aGUgY3JvcCBib3ggZXZlbiB3aGVuIHRoZQogIC8vIGJveCBpcyB0aGUgY3JvcCBib3g/CiAgdmlydHVhbCBib29sIG5lZWRDbGlwVG9Dcm9wQm94KCkgeyByZXR1cm4gZmFsc2U7IH0KCiAgLy8tLS0tLSBpbml0aWFsaXphdGlvbiBhbmQgY29udHJvbAoKICAvLyBTZXQgZGVmYXVsdCB0cmFuc2Zvcm0gbWF0cml4LgogIHZpcnR1YWwgdm9pZCBzZXREZWZhdWx0Q1RNKGNvbnN0IGRvdWJsZSAqY3RtKTsKCiAgLy8gQ2hlY2sgdG8gc2VlIGlmIGEgcGFnZSBzbGljZSBzaG91bGQgYmUgZGlzcGxheWVkLiAgSWYgdGhpcwogIC8vIHJldHVybnMgZmFsc2UsIHRoZSBwYWdlIGRpc3BsYXkgaXMgYWJvcnRlZC4gIFR5cGljYWxseSwgYW4KICAvLyBPdXRwdXREZXYgd2lsbCB1c2Ugc29tZSBhbHRlcm5hdGUgbWVhbnMgdG8gZGlzcGxheSB0aGUgcGFnZQogIC8vIGJlZm9yZSByZXR1cm5pbmcgZmFsc2UuCiAgdmlydHVhbCBib29sIGNoZWNrUGFnZVNsaWNlKFBhZ2UgKnBhZ2UsIGRvdWJsZSBoRFBJLCBkb3VibGUgdkRQSSwKCQkJICAgICAgIGludCByb3RhdGUsIGJvb2wgdXNlTWVkaWFCb3gsIGJvb2wgY3JvcCwKCQkJICAgICAgIGludCBzbGljZVgsIGludCBzbGljZVksIGludCBzbGljZVcsIGludCBzbGljZUgsCgkJCSAgICAgICBib29sIHByaW50aW5nLAoJCQkgICAgICAgYm9vbCAoKiBhYm9ydENoZWNrQ2JrKSh2b2lkICpkYXRhKSA9IG51bGxwdHIsCgkJCSAgICAgICB2b2lkICogYWJvcnRDaGVja0Nia0RhdGEgPSBudWxscHRyLAoJCQkgICAgICAgYm9vbCAoKmFubm90RGlzcGxheURlY2lkZUNiaykoQW5ub3QgKmFubm90LCB2b2lkICp1c2VyX2RhdGEpID0gbnVsbHB0ciwKCQkJICAgICAgIHZvaWQgKmFubm90RGlzcGxheURlY2lkZUNia0RhdGEgPSBudWxscHRyKQogICAgeyByZXR1cm4gdHJ1ZTsgfQoKICAvLyBTdGFydCBhIHBhZ2UuCiAgdmlydHVhbCB2b2lkIHN0YXJ0UGFnZShpbnQgcGFnZU51bSwgR2Z4U3RhdGUgKnN0YXRlLCBYUmVmICp4cmVmKSB7fQoKICAvLyBFbmQgYSBwYWdlLgogIHZpcnR1YWwgdm9pZCBlbmRQYWdlKCkge30KCiAgLy8gRHVtcCBwYWdlIGNvbnRlbnRzIHRvIGRpc3BsYXkuCiAgdmlydHVhbCB2b2lkIGR1bXAoKSB7fQoKICAvLy0tLS0tIGNvb3JkaW5hdGUgY29udmVyc2lvbgoKICAvLyBDb252ZXJ0IGJldHdlZW4gZGV2aWNlIGFuZCB1c2VyIGNvb3JkaW5hdGVzLgogIHZpcnR1YWwgdm9pZCBjdnREZXZUb1VzZXIoZG91YmxlIGR4LCBkb3VibGUgZHksIGRvdWJsZSAqdXgsIGRvdWJsZSAqdXkpOwogIHZpcnR1YWwgdm9pZCBjdnRVc2VyVG9EZXYoZG91YmxlIHV4LCBkb3VibGUgdXksIGludCAqZHgsIGludCAqZHkpOwoKICBjb25zdCBkb3VibGUgKmdldERlZkNUTSgpIGNvbnN0IHsgcmV0dXJuIGRlZkNUTTsgfQogIGNvbnN0IGRvdWJsZSAqZ2V0RGVmSUNUTSgpIGNvbnN0IHsgcmV0dXJuIGRlZklDVE07IH0KCiAgLy8tLS0tLSBzYXZlL3Jlc3RvcmUgZ3JhcGhpY3Mgc3RhdGUKICB2aXJ0dWFsIHZvaWQgc2F2ZVN0YXRlKEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCByZXN0b3JlU3RhdGUoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CgogIC8vLS0tLS0gdXBkYXRlIGdyYXBoaWNzIHN0YXRlCiAgdmlydHVhbCB2b2lkIHVwZGF0ZUFsbChHZnhTdGF0ZSAqc3RhdGUpOwoKICAvLyBVcGRhdGUgdGhlIEN1cnJlbnQgVHJhbnNmb3JtYXRpb24gTWF0cml4IChDVE0pLCBpLmUuLCB0aGUgbmV3IG1hdHJpeAogIC8vIGdpdmVuIGluIG0xMSwgLi4uLCBtMzIgaXMgY29tYmluZWQgd2l0aCB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgQ1RNLgogIC8vIEF0IHRoZSBzYW1lIHRpbWUsIHdoZW4gdGhpcyBtZXRob2QgaXMgY2FsbGVkLCBzdGF0ZS0+Z2V0Q1RNKCkgYWxyZWFkeQogIC8vIGNvbnRhaW5zIHRoZSBjb3JyZWN0IG5ldyBDVE0sIHNvIG9uZSBtYXkgYXMgd2VsbCByZXBsYWNlIHRoZQogIC8vIENUTSBvZiB0aGUgcmVuZGVyZXIgd2l0aCB0aGF0LgogIHZpcnR1YWwgdm9pZCB1cGRhdGVDVE0oR2Z4U3RhdGUgKiAvKnN0YXRlKi8sIGRvdWJsZSAvKm0xMSovLCBkb3VibGUgLyptMTIqLywKCQkJIGRvdWJsZSAvKm0yMSovLCBkb3VibGUgLyptMjIqLywgZG91YmxlIC8qbTMxKi8sIGRvdWJsZSAvKm0zMiovKSB7fQogIHZpcnR1YWwgdm9pZCB1cGRhdGVMaW5lRGFzaChHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgdXBkYXRlRmxhdG5lc3MoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUxpbmVKb2luKEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCB1cGRhdGVMaW5lQ2FwKEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCB1cGRhdGVNaXRlckxpbWl0KEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCB1cGRhdGVMaW5lV2lkdGgoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIHVwZGF0ZVN0cm9rZUFkanVzdChHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgdXBkYXRlQWxwaGFJc1NoYXBlKEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCB1cGRhdGVUZXh0S25vY2tvdXQoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUZpbGxDb2xvclNwYWNlKEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCB1cGRhdGVTdHJva2VDb2xvclNwYWNlKEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCB1cGRhdGVGaWxsQ29sb3IoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIHVwZGF0ZVN0cm9rZUNvbG9yKEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCB1cGRhdGVCbGVuZE1vZGUoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUZpbGxPcGFjaXR5KEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCB1cGRhdGVTdHJva2VPcGFjaXR5KEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCB1cGRhdGVQYXR0ZXJuT3BhY2l0eShHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgY2xlYXJQYXR0ZXJuT3BhY2l0eShHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgdXBkYXRlRmlsbE92ZXJwcmludChHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgdXBkYXRlU3Ryb2tlT3ZlcnByaW50KEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCB1cGRhdGVPdmVycHJpbnRNb2RlKEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCB1cGRhdGVUcmFuc2ZlcihHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgdXBkYXRlRmlsbENvbG9yU3RvcChHZnhTdGF0ZSAqIC8qc3RhdGUqLywgZG91YmxlIC8qb2Zmc2V0Ki8pIHt9CgogIC8vLS0tLS0gdXBkYXRlIHRleHQgc3RhdGUKICB2aXJ0dWFsIHZvaWQgdXBkYXRlRm9udChHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgdXBkYXRlVGV4dE1hdChHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgdXBkYXRlQ2hhclNwYWNlKEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCB1cGRhdGVSZW5kZXIoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIHVwZGF0ZVJpc2UoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIHVwZGF0ZVdvcmRTcGFjZShHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgdXBkYXRlSG9yaXpTY2FsaW5nKEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCB1cGRhdGVUZXh0UG9zKEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCB1cGRhdGVUZXh0U2hpZnQoR2Z4U3RhdGUgKiAvKnN0YXRlKi8sIGRvdWJsZSAvKnNoaWZ0Ki8pIHt9CiAgdmlydHVhbCB2b2lkIHNhdmVUZXh0UG9zKEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCByZXN0b3JlVGV4dFBvcyhHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KCiAgLy8tLS0tLSBwYXRoIHBhaW50aW5nCiAgdmlydHVhbCB2b2lkIHN0cm9rZShHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgZmlsbChHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgZW9GaWxsKEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgYm9vbCB0aWxpbmdQYXR0ZXJuRmlsbChHZnhTdGF0ZSAqIC8qc3RhdGUqLywgR2Z4ICogLypnZngqLywgQ2F0YWxvZyAqIC8qY2F0Ki8sIE9iamVjdCAqIC8qc3RyKi8sCgkJCQkgIGNvbnN0IGRvdWJsZSAqIC8qcG1hdCovLCBpbnQgLypwYWludFR5cGUqLywgaW50IC8qdGlsaW5nVHlwZSovLCBEaWN0ICogLypyZXNEaWN0Ki8sCgkJCQkgIGNvbnN0IGRvdWJsZSAqIC8qbWF0Ki8sIGNvbnN0IGRvdWJsZSAqIC8qYmJveCovLAoJCQkJICBpbnQgLyp4MCovLCBpbnQgLyp5MCovLCBpbnQgLyp4MSovLCBpbnQgLyp5MSovLAoJCQkJICBkb3VibGUgLyp4U3RlcCovLCBkb3VibGUgLyp5U3RlcCovKQogICAgeyByZXR1cm4gZmFsc2U7IH0KICB2aXJ0dWFsIGJvb2wgZnVuY3Rpb25TaGFkZWRGaWxsKEdmeFN0YXRlICogLypzdGF0ZSovLAoJCQkJICAgR2Z4RnVuY3Rpb25TaGFkaW5nICogLypzaGFkaW5nKi8pCiAgICB7IHJldHVybiBmYWxzZTsgfQogIHZpcnR1YWwgYm9vbCBheGlhbFNoYWRlZEZpbGwoR2Z4U3RhdGUgKiAvKnN0YXRlKi8sIEdmeEF4aWFsU2hhZGluZyAqIC8qc2hhZGluZyovLCBkb3VibGUgLyp0TWluKi8sIGRvdWJsZSAvKnRNYXgqLykKICAgIHsgcmV0dXJuIGZhbHNlOyB9CiAgdmlydHVhbCBib29sIGF4aWFsU2hhZGVkU3VwcG9ydEV4dGVuZChHZnhTdGF0ZSAqIC8qc3RhdGUqLywgR2Z4QXhpYWxTaGFkaW5nICogLypzaGFkaW5nKi8pCiAgICB7IHJldHVybiBmYWxzZTsgfQogIHZpcnR1YWwgYm9vbCByYWRpYWxTaGFkZWRGaWxsKEdmeFN0YXRlICogLypzdGF0ZSovLCBHZnhSYWRpYWxTaGFkaW5nICogLypzaGFkaW5nKi8sIGRvdWJsZSAvKnNNaW4qLywgZG91YmxlIC8qc01heCovKQogICAgeyByZXR1cm4gZmFsc2U7IH0KICB2aXJ0dWFsIGJvb2wgcmFkaWFsU2hhZGVkU3VwcG9ydEV4dGVuZChHZnhTdGF0ZSAqIC8qc3RhdGUqLywgR2Z4UmFkaWFsU2hhZGluZyAqIC8qc2hhZGluZyovKQogICAgeyByZXR1cm4gZmFsc2U7IH0KICB2aXJ0dWFsIGJvb2wgZ291cmF1ZFRyaWFuZ2xlU2hhZGVkRmlsbChHZnhTdGF0ZSAqc3RhdGUsIEdmeEdvdXJhdWRUcmlhbmdsZVNoYWRpbmcgKnNoYWRpbmcpCiAgICB7IHJldHVybiBmYWxzZTsgfQogIHZpcnR1YWwgYm9vbCBwYXRjaE1lc2hTaGFkZWRGaWxsKEdmeFN0YXRlICpzdGF0ZSwgR2Z4UGF0Y2hNZXNoU2hhZGluZyAqc2hhZGluZykKICAgIHsgcmV0dXJuIGZhbHNlOyB9CgogIC8vLS0tLS0gcGF0aCBjbGlwcGluZwoKICAvLyBVcGRhdGUgdGhlIGNsaXBwaW5nIHBhdGguICBUaGUgbmV3IHBhdGggaXMgdGhlIGludGVyc2VjdGlvbiBvZiB0aGUgb2xkIHBhdGgKICAvLyB3aXRoIHRoZSBwYXRoIGdpdmVuIGluICdzdGF0ZScuCiAgLy8gQWRkaXRpb25hbGx5LCBzZXQgdGhlIGNsaXBwaW5nIG1vZGUgdG8gdGhlICdub256ZXJvIHdpbmRpbmcgbnVtYmVyIHJ1bGUnLgogIC8vIFRoYXQgaXMsIGEgcG9pbnQgaXMgaW5zaWRlIHRoZSBjbGlwcGluZyByZWdpb24gaWYgaXRzIHdpbmRpbmcgbnVtYmVyCiAgLy8gd2l0aCByZXNwZWN0IHRvIHRoZSBjbGlwcGluZyBwYXRoIGlzIG5vbnplcm8uCiAgdmlydHVhbCB2b2lkIGNsaXAoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CgogIC8vIFVwZGF0ZSB0aGUgY2xpcHBpbmcgcGF0aC4gIFRoZSBuZXcgcGF0aCBpcyB0aGUgaW50ZXJzZWN0aW9uIG9mIHRoZSBvbGQgcGF0aAogIC8vIHdpdGggdGhlIHBhdGggZ2l2ZW4gaW4gJ3N0YXRlJy4KICAvLyBBZGRpdGlvbmFsbHksIHNldCB0aGUgY2xpcHBpbmcgbW9kZSB0byB0aGUgJ2V2ZW4tb2RkIHJ1bGUnLiAgVGhhdCBpcywgYSBwb2ludCBpcwogIC8vIGluc2lkZSB0aGUgY2xpcHBpbmcgcmVnaW9uIGlmIGEgcmF5IGZyb20gaXQgdG8gaW5maW5pdHkgd2lsbCBjcm9zcyB0aGUgY2xpcHBpbmcKICAvLyBwYXRoIGFuIG9kZCBudW1iZXIgb2YgdGltZXMgKGRpc3JlZ2FyZGluZyB0aGUgcGF0aCBvcmllbnRhdGlvbikuCiAgdmlydHVhbCB2b2lkIGVvQ2xpcChHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgY2xpcFRvU3Ryb2tlUGF0aChHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KCiAgLy8tLS0tLSB0ZXh0IGRyYXdpbmcKICB2aXJ0dWFsIHZvaWQgYmVnaW5TdHJpbmdPcChHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgZW5kU3RyaW5nT3AoR2Z4U3RhdGUgKiAvKnN0YXRlKi8pIHt9CiAgdmlydHVhbCB2b2lkIGJlZ2luU3RyaW5nKEdmeFN0YXRlICogLypzdGF0ZSovLCBjb25zdCBHb29TdHJpbmcgKiAvKnMqLykge30KICB2aXJ0dWFsIHZvaWQgZW5kU3RyaW5nKEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQoKICAvLyBEcmF3IG9uZSBnbHlwaCBhdCBhIHNwZWNpZmllZCBwb3NpdGlvbgogIC8vCiAgLy8gQXJndW1lbnRzIGFyZToKICAvLyBDaGFyQ29kZSBjb2RlOiBUaGlzIGlzIHRoZSBjaGFyYWN0ZXIgY29kZSBpbiB0aGUgY29udGVudCBzdHJlYW0uIEl0IG5lZWRzIHRvIGJlIG1hcHBlZCBiYWNrIHRvIGEgZ2x5cGggaW5kZXguCiAgLy8gaW50IG5CeXRlczogVGhlIHRleHQgc3RyaW5ncyBpbiB0aGUgY29udGVudCBzdHJlYW0gY2FuIGNvbnNpc3RzIG9mIGVpdGhlciA4LWJpdCBvciAxNi1iaXQKICAvLyAgICAgICAgICAgICBjaGFyYWN0ZXIgY29kZXMgZGVwZW5kaW5nIG9uIHRoZSBmb250LiBuQnl0ZXMgaXMgdGhlIG51bWJlciBvZiBieXRlcyBpbiB0aGUgY2hhcmFjdGVyIGNvZGUuCiAgLy8gVW5pY29kZSAqdTogVGhlIFVDUy00IG1hcHBpbmcgdXNlZCBmb3IgdGV4dCBleHRyYWN0aW9uIChUZXh0T3V0cHV0RGV2KS4KICAvLyBpbnQgdUxlbjogVGhlIG51bWJlciBvZiB1bmljb2RlIGVudHJpZXMgaW4gdS4gIFVzdWFsbHkgJzEnLCBmb3IgYSBzaW5nbGUgY2hhcmFjdGVyLAogIC8vICAgICAgICAgICBidXQgaXQgbWF5IGFsc28gaGF2ZSBsYXJnZXIgdmFsdWVzLCBmb3IgZXhhbXBsZSBmb3IgbGlnYXR1cmVzLgogIHZpcnR1YWwgdm9pZCBkcmF3Q2hhcihHZnhTdGF0ZSAqIC8qc3RhdGUqLywgZG91YmxlIC8qeCovLCBkb3VibGUgLyp5Ki8sCgkJCWRvdWJsZSAvKmR4Ki8sIGRvdWJsZSAvKmR5Ki8sCgkJCWRvdWJsZSAvKm9yaWdpblgqLywgZG91YmxlIC8qb3JpZ2luWSovLAoJCQlDaGFyQ29kZSAvKmNvZGUqLywgaW50IC8qbkJ5dGVzKi8sIFVuaWNvZGUgKiAvKnUqLywgaW50IC8qdUxlbiovKSB7fQogIHZpcnR1YWwgdm9pZCBkcmF3U3RyaW5nKEdmeFN0YXRlICogLypzdGF0ZSovLCBjb25zdCBHb29TdHJpbmcgKiAvKnMqLykge30KICB2aXJ0dWFsIGJvb2wgYmVnaW5UeXBlM0NoYXIoR2Z4U3RhdGUgKiAvKnN0YXRlKi8sIGRvdWJsZSAvKngqLywgZG91YmxlIC8qeSovLAoJCQkgICAgICAgZG91YmxlIC8qZHgqLywgZG91YmxlIC8qZHkqLywKCQkJICAgICAgIENoYXJDb2RlIC8qY29kZSovLCBVbmljb2RlICogLyp1Ki8sIGludCAvKnVMZW4qLyk7CiAgdmlydHVhbCB2b2lkIGVuZFR5cGUzQ2hhcihHZnhTdGF0ZSAqIC8qc3RhdGUqLykge30KICB2aXJ0dWFsIHZvaWQgYmVnaW5UZXh0T2JqZWN0KEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCBlbmRUZXh0T2JqZWN0KEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCBpbmNDaGFyQ291bnQoaW50IC8qbkNoYXJzKi8pIHt9CiAgdmlydHVhbCB2b2lkIGJlZ2luQWN0dWFsVGV4dChHZnhTdGF0ZSAqIC8qc3RhdGUqLywgY29uc3QgR29vU3RyaW5nICogLyp0ZXh0Ki8gKSB7fQogIHZpcnR1YWwgdm9pZCBlbmRBY3R1YWxUZXh0KEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQoKICAvLy0tLS0tIGltYWdlIGRyYXdpbmcKICAvLyBEcmF3IGFuIGltYWdlIG1hc2suICBBbiBpbWFnZSBtYXNrIGlzIGEgb25lLWJpdC1wZXItcGl4ZWwgaW1hZ2UsIHdoZXJlIGVhY2ggcGl4ZWwKICAvLyBjYW4gb25seSBiZSAnZmlsbCBjb2xvcicgb3IgJ3RyYW5zcGFyZW50Jy4KICAvLwogIC8vIElmICdpbnZlcnQnIGlzIGZhbHNlLCBhIHNhbXBsZSB2YWx1ZSBvZiAwIG1hcmtzIHRoZSBwYWdlIHdpdGggdGhlIGN1cnJlbnQgY29sb3IsCiAgLy8gYW5kIGEgMSBsZWF2ZXMgdGhlIHByZXZpb3VzIGNvbnRlbnRzIHVuY2hhbmdlZC4gSWYgJ2ludmVydCcgaXMgdHJ1ZSwgdGhlc2UgbWVhbmluZ3MgYXJlIHJldmVyc2VkLgogIHZpcnR1YWwgdm9pZCBkcmF3SW1hZ2VNYXNrKEdmeFN0YXRlICpzdGF0ZSwgT2JqZWN0ICpyZWYsIFN0cmVhbSAqc3RyLAoJCQkgICAgIGludCB3aWR0aCwgaW50IGhlaWdodCwgYm9vbCBpbnZlcnQsIGJvb2wgaW50ZXJwb2xhdGUsCgkJCSAgICAgYm9vbCBpbmxpbmVJbWcpOwogIHZpcnR1YWwgdm9pZCBzZXRTb2Z0TWFza0Zyb21JbWFnZU1hc2soR2Z4U3RhdGUgKnN0YXRlLAoJCQkJCU9iamVjdCAqcmVmLCBTdHJlYW0gKnN0ciwKCQkJCQlpbnQgd2lkdGgsIGludCBoZWlnaHQsIGJvb2wgaW52ZXJ0LAoJCQkJCWJvb2wgaW5saW5lSW1nLCBkb3VibGUgKmJhc2VNYXRyaXgpOwogIHZpcnR1YWwgdm9pZCB1bnNldFNvZnRNYXNrRnJvbUltYWdlTWFzayhHZnhTdGF0ZSAqc3RhdGUsIGRvdWJsZSAqYmFzZU1hdHJpeCk7CiAgdmlydHVhbCB2b2lkIGRyYXdJbWFnZShHZnhTdGF0ZSAqc3RhdGUsIE9iamVjdCAqcmVmLCBTdHJlYW0gKnN0ciwKCQkJIGludCB3aWR0aCwgaW50IGhlaWdodCwgR2Z4SW1hZ2VDb2xvck1hcCAqY29sb3JNYXAsCgkJCSBib29sIGludGVycG9sYXRlLCBpbnQgKm1hc2tDb2xvcnMsIGJvb2wgaW5saW5lSW1nKTsKICB2aXJ0dWFsIHZvaWQgZHJhd01hc2tlZEltYWdlKEdmeFN0YXRlICpzdGF0ZSwgT2JqZWN0ICpyZWYsIFN0cmVhbSAqc3RyLAoJCQkgICAgICAgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LAoJCQkgICAgICAgR2Z4SW1hZ2VDb2xvck1hcCAqY29sb3JNYXAsIGJvb2wgaW50ZXJwb2xhdGUsCgkJCSAgICAgICBTdHJlYW0gKm1hc2tTdHIsIGludCBtYXNrV2lkdGgsIGludCBtYXNrSGVpZ2h0LAoJCQkgICAgICAgYm9vbCBtYXNrSW52ZXJ0LCBib29sIG1hc2tJbnRlcnBvbGF0ZSk7CiAgdmlydHVhbCB2b2lkIGRyYXdTb2Z0TWFza2VkSW1hZ2UoR2Z4U3RhdGUgKnN0YXRlLCBPYmplY3QgKnJlZiwgU3RyZWFtICpzdHIsCgkJCQkgICBpbnQgd2lkdGgsIGludCBoZWlnaHQsCgkJCQkgICBHZnhJbWFnZUNvbG9yTWFwICpjb2xvck1hcCwKCQkJCSAgIGJvb2wgaW50ZXJwb2xhdGUsCgkJCQkgICBTdHJlYW0gKm1hc2tTdHIsCgkJCQkgICBpbnQgbWFza1dpZHRoLCBpbnQgbWFza0hlaWdodCwKCQkJCSAgIEdmeEltYWdlQ29sb3JNYXAgKm1hc2tDb2xvck1hcCwKCQkJCSAgIGJvb2wgbWFza0ludGVycG9sYXRlKTsKCiAgLy8tLS0tLSBncm91cGluZyBvcGVyYXRvcnMKCiAgdmlydHVhbCB2b2lkIGVuZE1hcmtlZENvbnRlbnQoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgYmVnaW5NYXJrZWRDb250ZW50KGNvbnN0IGNoYXIgKm5hbWUsIERpY3QgKnByb3BlcnRpZXMpOwogIHZpcnR1YWwgdm9pZCBtYXJrUG9pbnQoY29uc3QgY2hhciAqbmFtZSk7CiAgdmlydHVhbCB2b2lkIG1hcmtQb2ludChjb25zdCBjaGFyICpuYW1lLCBEaWN0ICpwcm9wZXJ0aWVzKTsKCgoKI2lmZGVmIE9QSV9TVVBQT1JUCiAgLy8tLS0tLSBPUEkgZnVuY3Rpb25zCiAgdmlydHVhbCB2b2lkIG9waUJlZ2luKEdmeFN0YXRlICpzdGF0ZSwgRGljdCAqb3BpRGljdCk7CiAgdmlydHVhbCB2b2lkIG9waUVuZChHZnhTdGF0ZSAqc3RhdGUsIERpY3QgKm9waURpY3QpOwojZW5kaWYKCiAgLy8tLS0tLSBUeXBlIDMgZm9udCBvcGVyYXRvcnMKICB2aXJ0dWFsIHZvaWQgdHlwZTNEMChHZnhTdGF0ZSAqIC8qc3RhdGUqLywgZG91YmxlIC8qd3gqLywgZG91YmxlIC8qd3kqLykge30KICB2aXJ0dWFsIHZvaWQgdHlwZTNEMShHZnhTdGF0ZSAqIC8qc3RhdGUqLywgZG91YmxlIC8qd3gqLywgZG91YmxlIC8qd3kqLywKCQkgICAgICAgZG91YmxlIC8qbGx4Ki8sIGRvdWJsZSAvKmxseSovLCBkb3VibGUgLyp1cngqLywgZG91YmxlIC8qdXJ5Ki8pIHt9CgogIC8vLS0tLS0gZm9ybSBYT2JqZWN0cwogIHZpcnR1YWwgdm9pZCBkcmF3Rm9ybShSZWYgLyppZCovKSB7fQoKICAvLy0tLS0tIFBvc3RTY3JpcHQgWE9iamVjdHMKICB2aXJ0dWFsIHZvaWQgcHNYT2JqZWN0KFN0cmVhbSAqIC8qcHNTdHJlYW0qLywgU3RyZWFtICogLypsZXZlbDFTdHJlYW0qLykge30KCiAgLy8tLS0tLSBQcm9maWxpbmcKICB2b2lkIHN0YXJ0UHJvZmlsZSgpOwogIHN0ZDo6dW5vcmRlcmVkX21hcDxzdGQ6OnN0cmluZywgUHJvZmlsZURhdGE+KiBnZXRQcm9maWxlSGFzaCgpIGNvbnN0IHsgcmV0dXJuIHByb2ZpbGVIYXNoLmdldCgpOyB9CiAgc3RkOjp1bmlxdWVfcHRyPHN0ZDo6dW5vcmRlcmVkX21hcDxzdGQ6OnN0cmluZywgUHJvZmlsZURhdGE+PiBlbmRQcm9maWxlKCk7CgogIC8vLS0tLS0gdHJhbnNwYXJlbmN5IGdyb3VwcyBhbmQgc29mdCBtYXNrcwogIHZpcnR1YWwgYm9vbCBjaGVja1RyYW5zcGFyZW5jeUdyb3VwKEdmeFN0YXRlICogLypzdGF0ZSovLCBib29sIC8qa25vY2tvdXQqLykgeyByZXR1cm4gdHJ1ZTsgfQogIHZpcnR1YWwgdm9pZCBiZWdpblRyYW5zcGFyZW5jeUdyb3VwKEdmeFN0YXRlICogLypzdGF0ZSovLCBjb25zdCBkb3VibGUgKiAvKmJib3gqLywKCQkJCSAgICAgIEdmeENvbG9yU3BhY2UgKiAvKmJsZW5kaW5nQ29sb3JTcGFjZSovLAoJCQkJICAgICAgYm9vbCAvKmlzb2xhdGVkKi8sIGJvb2wgLyprbm9ja291dCovLAoJCQkJICAgICAgYm9vbCAvKmZvclNvZnRNYXNrKi8pIHt9CiAgdmlydHVhbCB2b2lkIGVuZFRyYW5zcGFyZW5jeUdyb3VwKEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQogIHZpcnR1YWwgdm9pZCBwYWludFRyYW5zcGFyZW5jeUdyb3VwKEdmeFN0YXRlICogLypzdGF0ZSovLCBjb25zdCBkb3VibGUgKiAvKmJib3gqLykge30KICB2aXJ0dWFsIHZvaWQgc2V0U29mdE1hc2soR2Z4U3RhdGUgKiAvKnN0YXRlKi8sIGNvbnN0IGRvdWJsZSAqIC8qYmJveCovLCBib29sIC8qYWxwaGEqLywKCQkJICAgRnVuY3Rpb24gKiAvKnRyYW5zZmVyRnVuYyovLCBHZnhDb2xvciAqIC8qYmFja2Ryb3BDb2xvciovKSB7fQogIHZpcnR1YWwgdm9pZCBjbGVhclNvZnRNYXNrKEdmeFN0YXRlICogLypzdGF0ZSovKSB7fQoKICAvLy0tLS0tIGxpbmtzCiAgdmlydHVhbCB2b2lkIHByb2Nlc3NMaW5rKEFubm90TGluayAqIC8qbGluayovKSB7fQoKI2lmIDEgLy9+dG1wOiB0dXJuIG9mZiBhbnRpLWFsaWFzaW5nIHRlbXBvcmFyaWx5CiAgdmlydHVhbCBib29sIGdldFZlY3RvckFudGlhbGlhcygpIHsgcmV0dXJuIGZhbHNlOyB9CiAgdmlydHVhbCB2b2lkIHNldFZlY3RvckFudGlhbGlhcyhib29sIC8qdmFhKi8pIHt9CiNlbmRpZgoKI2lmZGVmIFVTRV9DTVMKICBQb3BwbGVyQ2FjaGU8UmVmLCBHZnhJQ0NCYXNlZENvbG9yU3BhY2U+ICpnZXRJY2NDb2xvclNwYWNlQ2FjaGUoKSB7IHJldHVybiAmaWNjQ29sb3JTcGFjZUNhY2hlOyB9CiNlbmRpZgoKcHJpdmF0ZToKCiAgZG91YmxlIGRlZkNUTVs2XTsJCS8vIGRlZmF1bHQgY29vcmRpbmF0ZSB0cmFuc2Zvcm0gbWF0cml4CiAgZG91YmxlIGRlZklDVE1bNl07CQkvLyBpbnZlcnNlIG9mIGRlZmF1bHQgQ1RNCiAgc3RkOjp1bmlxdWVfcHRyPHN0ZDo6dW5vcmRlcmVkX21hcDxzdGQ6OnN0cmluZywgUHJvZmlsZURhdGE+PiBwcm9maWxlSGFzaDsKCiNpZmRlZiBVU0VfQ01TCiAgUG9wcGxlckNhY2hlPFJlZiwgR2Z4SUNDQmFzZWRDb2xvclNwYWNlPiBpY2NDb2xvclNwYWNlQ2FjaGU7CiNlbmRpZgp9OwoKI2VuZGlmCg==