LyogY29ubmVjdGlvbi5jIC0gdGhlIGNvbm5lY3Rpb24gdHlwZQogKgogKiBDb3B5cmlnaHQgKEMpIDIwMDQtMjAwNiBHZXJoYXJkIEjkcmluZyA8Z2hAZ2hhZXJpbmcuZGU+CiAqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHB5c3FsaXRlLgogKiAKICogVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWQKICogd2FycmFudHkuICBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlcwogKiBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLgogKgogKiBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSwKICogaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAogKiBmcmVlbHksIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyByZXN0cmljdGlvbnM6CiAqCiAqIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90CiAqICAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlCiAqICAgIGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQgaW4gdGhlIHByb2R1Y3QgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZQogKiAgICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLgogKiAyLiBBbHRlcmVkIHNvdXJjZSB2ZXJzaW9ucyBtdXN0IGJlIHBsYWlubHkgbWFya2VkIGFzIHN1Y2gsIGFuZCBtdXN0IG5vdCBiZQogKiAgICBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3JpZ2luYWwgc29mdHdhcmUuCiAqIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uCiAqLwoKI2luY2x1ZGUgImNhY2hlLmgiCiNpbmNsdWRlICJtb2R1bGUuaCIKI2luY2x1ZGUgImNvbm5lY3Rpb24uaCIKI2luY2x1ZGUgInN0YXRlbWVudC5oIgojaW5jbHVkZSAiY3Vyc29yLmgiCiNpbmNsdWRlICJwcmVwYXJlX3Byb3RvY29sLmgiCiNpbmNsdWRlICJ1dGlsLmgiCiNpbmNsdWRlICJzcWxpdGVjb21wYXQuaCIKCiNpbmNsdWRlICJweXRocmVhZC5oIgoKc3RhdGljIGludCBjb25uZWN0aW9uX3NldF9pc29sYXRpb25fbGV2ZWwoQ29ubmVjdGlvbiogc2VsZiwgUHlPYmplY3QqIGlzb2xhdGlvbl9sZXZlbCk7CgoKdm9pZCBfc3FsaXRlM19yZXN1bHRfZXJyb3Ioc3FsaXRlM19jb250ZXh0KiBjdHgsIGNvbnN0IGNoYXIqIGVycm1zZywgaW50IGxlbikKewogICAgLyogaW4gb2xkZXIgU1FMaXRlIHZlcnNpb25zLCBjYWxsaW5nIHNxbGl0ZTNfcmVzdWx0X2Vycm9yIGluIGNhbGxiYWNrcwogICAgICogdHJpZ2dlcnMgYSBidWcgaW4gU1FMaXRlIHRoYXQgbGVhZHMgZWl0aGVyIHRvIGlycml0YXRpbmcgcmVzdWx0cyBvcgogICAgICogc2VnZmF1bHRzLCBkZXBlbmRpbmcgb24gdGhlIFNRTGl0ZSB2ZXJzaW9uICovCiNpZiBTUUxJVEVfVkVSU0lPTl9OVU1CRVIgPj0gMzAwMzAwMwogICAgc3FsaXRlM19yZXN1bHRfZXJyb3IoY3R4LCBlcnJtc2csIGxlbik7CiNlbHNlCiAgICBQeUVycl9TZXRTdHJpbmcoT3BlcmF0aW9uYWxFcnJvciwgZXJybXNnKTsKI2VuZGlmCn0KCmludCBjb25uZWN0aW9uX2luaXQoQ29ubmVjdGlvbiogc2VsZiwgUHlPYmplY3QqIGFyZ3MsIFB5T2JqZWN0KiBrd2FyZ3MpCnsKICAgIHN0YXRpYyBjaGFyICprd2xpc3RbXSA9IHsiZGF0YWJhc2UiLCAidGltZW91dCIsICJkZXRlY3RfdHlwZXMiLCAiaXNvbGF0aW9uX2xldmVsIiwgImNoZWNrX3NhbWVfdGhyZWFkIiwgImZhY3RvcnkiLCAiY2FjaGVkX3N0YXRlbWVudHMiLCBOVUxMLCBOVUxMfTsKCiAgICBjaGFyKiBkYXRhYmFzZTsKICAgIGludCBkZXRlY3RfdHlwZXMgPSAwOwogICAgUHlPYmplY3QqIGlzb2xhdGlvbl9sZXZlbCA9IE5VTEw7CiAgICBQeU9iamVjdCogZmFjdG9yeSA9IE5VTEw7CiAgICBpbnQgY2hlY2tfc2FtZV90aHJlYWQgPSAxOwogICAgaW50IGNhY2hlZF9zdGF0ZW1lbnRzID0gMTAwOwogICAgZG91YmxlIHRpbWVvdXQgPSA1LjA7CiAgICBpbnQgcmM7CgogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlQW5kS2V5d29yZHMoYXJncywga3dhcmdzLCAic3xkaU9pT2kiLCBrd2xpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZGF0YWJhc2UsICZ0aW1lb3V0LCAmZGV0ZWN0X3R5cGVzLCAmaXNvbGF0aW9uX2xldmVsLCAmY2hlY2tfc2FtZV90aHJlYWQsICZmYWN0b3J5LCAmY2FjaGVkX3N0YXRlbWVudHMpKQogICAgewogICAgICAgIHJldHVybiAtMTsgCiAgICB9CgogICAgc2VsZi0+YmVnaW5fc3RhdGVtZW50ID0gTlVMTDsKCiAgICBzZWxmLT5zdGF0ZW1lbnRfY2FjaGUgPSBOVUxMOwogICAgc2VsZi0+c3RhdGVtZW50cyA9IE5VTEw7CgogICAgUHlfSU5DUkVGKFB5X05vbmUpOwogICAgc2VsZi0+cm93X2ZhY3RvcnkgPSBQeV9Ob25lOwoKICAgIFB5X0lOQ1JFRigmUHlVbmljb2RlX1R5cGUpOwogICAgc2VsZi0+dGV4dF9mYWN0b3J5ID0gKFB5T2JqZWN0KikmUHlVbmljb2RlX1R5cGU7CgogICAgUHlfQkVHSU5fQUxMT1dfVEhSRUFEUwogICAgcmMgPSBzcWxpdGUzX29wZW4oZGF0YWJhc2UsICZzZWxmLT5kYik7CiAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUwoKICAgIGlmIChyYyAhPSBTUUxJVEVfT0spIHsKICAgICAgICBfc2V0ZXJyb3Ioc2VsZi0+ZGIpOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBpZiAoIWlzb2xhdGlvbl9sZXZlbCkgewogICAgICAgIGlzb2xhdGlvbl9sZXZlbCA9IFB5U3RyaW5nX0Zyb21TdHJpbmcoIiIpOwogICAgICAgIGlmICghaXNvbGF0aW9uX2xldmVsKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIFB5X0lOQ1JFRihpc29sYXRpb25fbGV2ZWwpOwogICAgfQogICAgc2VsZi0+aXNvbGF0aW9uX2xldmVsID0gTlVMTDsKICAgIGNvbm5lY3Rpb25fc2V0X2lzb2xhdGlvbl9sZXZlbChzZWxmLCBpc29sYXRpb25fbGV2ZWwpOwogICAgUHlfREVDUkVGKGlzb2xhdGlvbl9sZXZlbCk7CgogICAgc2VsZi0+c3RhdGVtZW50X2NhY2hlID0gKENhY2hlKilQeU9iamVjdF9DYWxsRnVuY3Rpb24oKFB5T2JqZWN0KikmQ2FjaGVUeXBlLCAiT2kiLCBzZWxmLCBjYWNoZWRfc3RhdGVtZW50cyk7CiAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkgewogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBzZWxmLT5zdGF0ZW1lbnRzID0gUHlMaXN0X05ldygwKTsKICAgIGlmICghc2VsZi0+c3RhdGVtZW50cykgewogICAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIHNlbGYtPmNyZWF0ZWRfc3RhdGVtZW50cyA9IDA7CgogICAgLyogQnkgZGVmYXVsdCwgdGhlIENhY2hlIGNsYXNzIElOQ1JFRnMgdGhlIGZhY3RvcnkgaW4gaXRzIGluaXRpYWxpemVyLCBhbmQKICAgICAqIGRlY3JlZnMgaXQgaW4gaXRzIGRlYWxsb2NhdG9yIG1ldGhvZC4gU2luY2UgdGhpcyB3b3VsZCBjcmVhdGUgYSBjaXJjdWxhcgogICAgICogcmVmZXJlbmNlIGhlcmUsIHdlJ3JlIGJyZWFraW5nIGl0IGJ5IGRlY3JlbWVudGluZyBzZWxmLCBhbmQgdGVsbGluZyB0aGUKICAgICAqIGNhY2hlIGNsYXNzIHRvIG5vdCBkZWNyZWYgdGhlIGZhY3RvcnkgKHNlbGYpIGluIGl0cyBkZWFsbG9jYXRvci4KICAgICAqLwogICAgc2VsZi0+c3RhdGVtZW50X2NhY2hlLT5kZWNyZWZfZmFjdG9yeSA9IDA7CiAgICBQeV9ERUNSRUYoc2VsZik7CgogICAgc2VsZi0+aW5UcmFuc2FjdGlvbiA9IDA7CiAgICBzZWxmLT5kZXRlY3RfdHlwZXMgPSBkZXRlY3RfdHlwZXM7CiAgICBzZWxmLT50aW1lb3V0ID0gdGltZW91dDsKICAgICh2b2lkKXNxbGl0ZTNfYnVzeV90aW1lb3V0KHNlbGYtPmRiLCAoaW50KSh0aW1lb3V0KjEwMDApKTsKCiAgICBzZWxmLT50aHJlYWRfaWRlbnQgPSBQeVRocmVhZF9nZXRfdGhyZWFkX2lkZW50KCk7CiAgICBzZWxmLT5jaGVja19zYW1lX3RocmVhZCA9IGNoZWNrX3NhbWVfdGhyZWFkOwoKICAgIHNlbGYtPmZ1bmN0aW9uX3BpbmJvYXJkID0gUHlEaWN0X05ldygpOwogICAgaWYgKCFzZWxmLT5mdW5jdGlvbl9waW5ib2FyZCkgewogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBzZWxmLT5jb2xsYXRpb25zID0gUHlEaWN0X05ldygpOwogICAgaWYgKCFzZWxmLT5jb2xsYXRpb25zKSB7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIHNlbGYtPldhcm5pbmcgPSBXYXJuaW5nOwogICAgc2VsZi0+RXJyb3IgPSBFcnJvcjsKICAgIHNlbGYtPkludGVyZmFjZUVycm9yID0gSW50ZXJmYWNlRXJyb3I7CiAgICBzZWxmLT5EYXRhYmFzZUVycm9yID0gRGF0YWJhc2VFcnJvcjsKICAgIHNlbGYtPkRhdGFFcnJvciA9IERhdGFFcnJvcjsKICAgIHNlbGYtPk9wZXJhdGlvbmFsRXJyb3IgPSBPcGVyYXRpb25hbEVycm9yOwogICAgc2VsZi0+SW50ZWdyaXR5RXJyb3IgPSBJbnRlZ3JpdHlFcnJvcjsKICAgIHNlbGYtPkludGVybmFsRXJyb3IgPSBJbnRlcm5hbEVycm9yOwogICAgc2VsZi0+UHJvZ3JhbW1pbmdFcnJvciA9IFByb2dyYW1taW5nRXJyb3I7CiAgICBzZWxmLT5Ob3RTdXBwb3J0ZWRFcnJvciA9IE5vdFN1cHBvcnRlZEVycm9yOwoKICAgIHJldHVybiAwOwp9CgovKiBFbXB0eSB0aGUgZW50aXJlIHN0YXRlbWVudCBjYWNoZSBvZiB0aGlzIGNvbm5lY3Rpb24gKi8Kdm9pZCBmbHVzaF9zdGF0ZW1lbnRfY2FjaGUoQ29ubmVjdGlvbiogc2VsZikKewogICAgTm9kZSogbm9kZTsKICAgIFN0YXRlbWVudCogc3RhdGVtZW50OwoKICAgIG5vZGUgPSBzZWxmLT5zdGF0ZW1lbnRfY2FjaGUtPmZpcnN0OwoKICAgIHdoaWxlIChub2RlKSB7CiAgICAgICAgc3RhdGVtZW50ID0gKFN0YXRlbWVudCopKG5vZGUtPmRhdGEpOwogICAgICAgICh2b2lkKXN0YXRlbWVudF9maW5hbGl6ZShzdGF0ZW1lbnQpOwogICAgICAgIG5vZGUgPSBub2RlLT5uZXh0OwogICAgfQoKICAgIFB5X0RFQ1JFRihzZWxmLT5zdGF0ZW1lbnRfY2FjaGUpOwogICAgc2VsZi0+c3RhdGVtZW50X2NhY2hlID0gKENhY2hlKilQeU9iamVjdF9DYWxsRnVuY3Rpb24oKFB5T2JqZWN0KikmQ2FjaGVUeXBlLCAiTyIsIHNlbGYpOwogICAgUHlfREVDUkVGKHNlbGYpOwogICAgc2VsZi0+c3RhdGVtZW50X2NhY2hlLT5kZWNyZWZfZmFjdG9yeSA9IDA7Cn0KCnZvaWQgcmVzZXRfYWxsX3N0YXRlbWVudHMoQ29ubmVjdGlvbiogc2VsZikKewogICAgaW50IGk7CiAgICBQeU9iamVjdCogd2Vha3JlZjsKICAgIFB5T2JqZWN0KiBzdGF0ZW1lbnQ7CgogICAgZm9yIChpID0gMDsgaSA8IFB5TGlzdF9TaXplKHNlbGYtPnN0YXRlbWVudHMpOyBpKyspIHsKICAgICAgICB3ZWFrcmVmID0gUHlMaXN0X0dldEl0ZW0oc2VsZi0+c3RhdGVtZW50cywgaSk7CiAgICAgICAgc3RhdGVtZW50ID0gUHlXZWFrcmVmX0dldE9iamVjdCh3ZWFrcmVmKTsKICAgICAgICBpZiAoc3RhdGVtZW50ICE9IFB5X05vbmUpIHsKICAgICAgICAgICAgKHZvaWQpc3RhdGVtZW50X3Jlc2V0KChTdGF0ZW1lbnQqKXN0YXRlbWVudCk7CiAgICAgICAgfQogICAgfQp9Cgp2b2lkIGNvbm5lY3Rpb25fZGVhbGxvYyhDb25uZWN0aW9uKiBzZWxmKQp7CiAgICBQeV9YREVDUkVGKHNlbGYtPnN0YXRlbWVudF9jYWNoZSk7CgogICAgLyogQ2xlYW4gdXAgaWYgdXNlciBoYXMgbm90IGNhbGxlZCAuY2xvc2UoKSBleHBsaWNpdGx5LiAqLwogICAgaWYgKHNlbGYtPmRiKSB7CiAgICAgICAgUHlfQkVHSU5fQUxMT1dfVEhSRUFEUwogICAgICAgIHNxbGl0ZTNfY2xvc2Uoc2VsZi0+ZGIpOwogICAgICAgIFB5X0VORF9BTExPV19USFJFQURTCiAgICB9CgogICAgaWYgKHNlbGYtPmJlZ2luX3N0YXRlbWVudCkgewogICAgICAgIFB5TWVtX0ZyZWUoc2VsZi0+YmVnaW5fc3RhdGVtZW50KTsKICAgIH0KICAgIFB5X1hERUNSRUYoc2VsZi0+aXNvbGF0aW9uX2xldmVsKTsKICAgIFB5X1hERUNSRUYoc2VsZi0+ZnVuY3Rpb25fcGluYm9hcmQpOwogICAgUHlfWERFQ1JFRihzZWxmLT5yb3dfZmFjdG9yeSk7CiAgICBQeV9YREVDUkVGKHNlbGYtPnRleHRfZmFjdG9yeSk7CiAgICBQeV9YREVDUkVGKHNlbGYtPmNvbGxhdGlvbnMpOwogICAgUHlfWERFQ1JFRihzZWxmLT5zdGF0ZW1lbnRzKTsKCiAgICBzZWxmLT5vYl90eXBlLT50cF9mcmVlKChQeU9iamVjdCopc2VsZik7Cn0KClB5T2JqZWN0KiBjb25uZWN0aW9uX2N1cnNvcihDb25uZWN0aW9uKiBzZWxmLCBQeU9iamVjdCogYXJncywgUHlPYmplY3QqIGt3YXJncykKewogICAgc3RhdGljIGNoYXIgKmt3bGlzdFtdID0geyJmYWN0b3J5IiwgTlVMTCwgTlVMTH07CiAgICBQeU9iamVjdCogZmFjdG9yeSA9IE5VTEw7CiAgICBQeU9iamVjdCogY3Vyc29yOwoKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGVBbmRLZXl3b3JkcyhhcmdzLCBrd2FyZ3MsICJ8TyIsIGt3bGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZmYWN0b3J5KSkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIGlmICghY2hlY2tfdGhyZWFkKHNlbGYpIHx8ICFjaGVja19jb25uZWN0aW9uKHNlbGYpKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgaWYgKGZhY3RvcnkgPT0gTlVMTCkgewogICAgICAgIGZhY3RvcnkgPSAoUHlPYmplY3QqKSZDdXJzb3JUeXBlOwogICAgfQoKICAgIGN1cnNvciA9IFB5T2JqZWN0X0NhbGxGdW5jdGlvbihmYWN0b3J5LCAiTyIsIHNlbGYpOwoKICAgIGlmIChjdXJzb3IgJiYgc2VsZi0+cm93X2ZhY3RvcnkgIT0gUHlfTm9uZSkgewogICAgICAgIFB5X1hERUNSRUYoKChDdXJzb3IqKWN1cnNvciktPnJvd19mYWN0b3J5KTsKICAgICAgICBQeV9JTkNSRUYoc2VsZi0+cm93X2ZhY3RvcnkpOwogICAgICAgICgoQ3Vyc29yKiljdXJzb3IpLT5yb3dfZmFjdG9yeSA9IHNlbGYtPnJvd19mYWN0b3J5OwogICAgfQoKICAgIHJldHVybiBjdXJzb3I7Cn0KClB5T2JqZWN0KiBjb25uZWN0aW9uX2Nsb3NlKENvbm5lY3Rpb24qIHNlbGYsIFB5T2JqZWN0KiBhcmdzKQp7CiAgICBpbnQgcmM7CgogICAgaWYgKCFjaGVja190aHJlYWQoc2VsZikpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBmbHVzaF9zdGF0ZW1lbnRfY2FjaGUoc2VsZik7CgogICAgaWYgKHNlbGYtPmRiKSB7CiAgICAgICAgUHlfQkVHSU5fQUxMT1dfVEhSRUFEUwogICAgICAgIHJjID0gc3FsaXRlM19jbG9zZShzZWxmLT5kYik7CiAgICAgICAgUHlfRU5EX0FMTE9XX1RIUkVBRFMKCiAgICAgICAgaWYgKHJjICE9IFNRTElURV9PSykgewogICAgICAgICAgICBfc2V0ZXJyb3Ioc2VsZi0+ZGIpOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzZWxmLT5kYiA9IE5VTEw7CiAgICAgICAgfQogICAgfQoKICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgIHJldHVybiBQeV9Ob25lOwp9CgovKgogKiBDaGVja3MgaWYgYSBjb25uZWN0aW9uIG9iamVjdCBpcyB1c2FibGUgKGkuIGUuIG5vdCBjbG9zZWQpLgogKgogKiAwID0+IGVycm9yOyAxID0+IG9rCiAqLwppbnQgY2hlY2tfY29ubmVjdGlvbihDb25uZWN0aW9uKiBjb24pCnsKICAgIGlmICghY29uLT5kYikgewogICAgICAgIFB5RXJyX1NldFN0cmluZyhQcm9ncmFtbWluZ0Vycm9yLCAiQ2Fubm90IG9wZXJhdGUgb24gYSBjbG9zZWQgZGF0YWJhc2UuIik7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAxOwogICAgfQp9CgpQeU9iamVjdCogX2Nvbm5lY3Rpb25fYmVnaW4oQ29ubmVjdGlvbiogc2VsZikKewogICAgaW50IHJjOwogICAgY29uc3QgY2hhciogdGFpbDsKICAgIHNxbGl0ZTNfc3RtdCogc3RhdGVtZW50OwoKICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKICAgIHJjID0gc3FsaXRlM19wcmVwYXJlKHNlbGYtPmRiLCBzZWxmLT5iZWdpbl9zdGF0ZW1lbnQsIC0xLCAmc3RhdGVtZW50LCAmdGFpbCk7CiAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUwoKICAgIGlmIChyYyAhPSBTUUxJVEVfT0spIHsKICAgICAgICBfc2V0ZXJyb3Ioc2VsZi0+ZGIpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgcmMgPSBfc3FsaXRlX3N0ZXBfd2l0aF9idXN5aGFuZGxlcihzdGF0ZW1lbnQsIHNlbGYpOwogICAgaWYgKHJjID09IFNRTElURV9ET05FKSB7CiAgICAgICAgc2VsZi0+aW5UcmFuc2FjdGlvbiA9IDE7CiAgICB9IGVsc2UgewogICAgICAgIF9zZXRlcnJvcihzZWxmLT5kYik7CiAgICB9CgogICAgUHlfQkVHSU5fQUxMT1dfVEhSRUFEUwogICAgcmMgPSBzcWxpdGUzX2ZpbmFsaXplKHN0YXRlbWVudCk7CiAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUwoKICAgIGlmIChyYyAhPSBTUUxJVEVfT0sgJiYgIVB5RXJyX09jY3VycmVkKCkpIHsKICAgICAgICBfc2V0ZXJyb3Ioc2VsZi0+ZGIpOwogICAgfQoKZXJyb3I6CiAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfSBlbHNlIHsKICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICAgICAgcmV0dXJuIFB5X05vbmU7CiAgICB9Cn0KClB5T2JqZWN0KiBjb25uZWN0aW9uX2NvbW1pdChDb25uZWN0aW9uKiBzZWxmLCBQeU9iamVjdCogYXJncykKewogICAgaW50IHJjOwogICAgY29uc3QgY2hhciogdGFpbDsKICAgIHNxbGl0ZTNfc3RtdCogc3RhdGVtZW50OwoKICAgIGlmICghY2hlY2tfdGhyZWFkKHNlbGYpIHx8ICFjaGVja19jb25uZWN0aW9uKHNlbGYpKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgaWYgKHNlbGYtPmluVHJhbnNhY3Rpb24pIHsKICAgICAgICBQeV9CRUdJTl9BTExPV19USFJFQURTCiAgICAgICAgcmMgPSBzcWxpdGUzX3ByZXBhcmUoc2VsZi0+ZGIsICJDT01NSVQiLCAtMSwgJnN0YXRlbWVudCwgJnRhaWwpOwogICAgICAgIFB5X0VORF9BTExPV19USFJFQURTCiAgICAgICAgaWYgKHJjICE9IFNRTElURV9PSykgewogICAgICAgICAgICBfc2V0ZXJyb3Ioc2VsZi0+ZGIpOwogICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgIH0KCiAgICAgICAgcmMgPSBfc3FsaXRlX3N0ZXBfd2l0aF9idXN5aGFuZGxlcihzdGF0ZW1lbnQsIHNlbGYpOwogICAgICAgIGlmIChyYyA9PSBTUUxJVEVfRE9ORSkgewogICAgICAgICAgICBzZWxmLT5pblRyYW5zYWN0aW9uID0gMDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBfc2V0ZXJyb3Ioc2VsZi0+ZGIpOwogICAgICAgIH0KCiAgICAgICAgUHlfQkVHSU5fQUxMT1dfVEhSRUFEUwogICAgICAgIHJjID0gc3FsaXRlM19maW5hbGl6ZShzdGF0ZW1lbnQpOwogICAgICAgIFB5X0VORF9BTExPV19USFJFQURTCiAgICAgICAgaWYgKHJjICE9IFNRTElURV9PSyAmJiAhUHlFcnJfT2NjdXJyZWQoKSkgewogICAgICAgICAgICBfc2V0ZXJyb3Ioc2VsZi0+ZGIpOwogICAgICAgIH0KCiAgICB9CgplcnJvcjoKICAgIGlmIChQeUVycl9PY2N1cnJlZCgpKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9IGVsc2UgewogICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgICAgICByZXR1cm4gUHlfTm9uZTsKICAgIH0KfQoKUHlPYmplY3QqIGNvbm5lY3Rpb25fcm9sbGJhY2soQ29ubmVjdGlvbiogc2VsZiwgUHlPYmplY3QqIGFyZ3MpCnsKICAgIGludCByYzsKICAgIGNvbnN0IGNoYXIqIHRhaWw7CiAgICBzcWxpdGUzX3N0bXQqIHN0YXRlbWVudDsKCiAgICBpZiAoIWNoZWNrX3RocmVhZChzZWxmKSB8fCAhY2hlY2tfY29ubmVjdGlvbihzZWxmKSkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIGlmIChzZWxmLT5pblRyYW5zYWN0aW9uKSB7CiAgICAgICAgcmVzZXRfYWxsX3N0YXRlbWVudHMoc2VsZik7CgogICAgICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKICAgICAgICByYyA9IHNxbGl0ZTNfcHJlcGFyZShzZWxmLT5kYiwgIlJPTExCQUNLIiwgLTEsICZzdGF0ZW1lbnQsICZ0YWlsKTsKICAgICAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUwogICAgICAgIGlmIChyYyAhPSBTUUxJVEVfT0spIHsKICAgICAgICAgICAgX3NldGVycm9yKHNlbGYtPmRiKTsKICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CgogICAgICAgIHJjID0gX3NxbGl0ZV9zdGVwX3dpdGhfYnVzeWhhbmRsZXIoc3RhdGVtZW50LCBzZWxmKTsKICAgICAgICBpZiAocmMgPT0gU1FMSVRFX0RPTkUpIHsKICAgICAgICAgICAgc2VsZi0+aW5UcmFuc2FjdGlvbiA9IDA7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgX3NldGVycm9yKHNlbGYtPmRiKTsKICAgICAgICB9CgogICAgICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKICAgICAgICByYyA9IHNxbGl0ZTNfZmluYWxpemUoc3RhdGVtZW50KTsKICAgICAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUwogICAgICAgIGlmIChyYyAhPSBTUUxJVEVfT0sgJiYgIVB5RXJyX09jY3VycmVkKCkpIHsKICAgICAgICAgICAgX3NldGVycm9yKHNlbGYtPmRiKTsKICAgICAgICB9CgogICAgfQoKZXJyb3I6CiAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfSBlbHNlIHsKICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICAgICAgcmV0dXJuIFB5X05vbmU7CiAgICB9Cn0KCnZvaWQgX3NldF9yZXN1bHQoc3FsaXRlM19jb250ZXh0KiBjb250ZXh0LCBQeU9iamVjdCogcHlfdmFsKQp7CiAgICBsb25nIGxvbmd2YWw7CiAgICBjb25zdCBjaGFyKiBidWZmZXI7CiAgICBQeV9zc2l6ZV90IGJ1ZmxlbjsKICAgIFB5T2JqZWN0KiBzdHJpbmd2YWw7CgogICAgaWYgKCghcHlfdmFsKSB8fCBQeUVycl9PY2N1cnJlZCgpKSB7CiAgICAgICAgc3FsaXRlM19yZXN1bHRfbnVsbChjb250ZXh0KTsKICAgIH0gZWxzZSBpZiAocHlfdmFsID09IFB5X05vbmUpIHsKICAgICAgICBzcWxpdGUzX3Jlc3VsdF9udWxsKGNvbnRleHQpOwogICAgfSBlbHNlIGlmIChQeUludF9DaGVjayhweV92YWwpKSB7CiAgICAgICAgbG9uZ3ZhbCA9IFB5SW50X0FzTG9uZyhweV92YWwpOwogICAgICAgIHNxbGl0ZTNfcmVzdWx0X2ludDY0KGNvbnRleHQsIChQWV9MT05HX0xPTkcpbG9uZ3ZhbCk7CiAgICB9IGVsc2UgaWYgKFB5RmxvYXRfQ2hlY2socHlfdmFsKSkgewogICAgICAgIHNxbGl0ZTNfcmVzdWx0X2RvdWJsZShjb250ZXh0LCBQeUZsb2F0X0FzRG91YmxlKHB5X3ZhbCkpOwogICAgfSBlbHNlIGlmIChQeUJ1ZmZlcl9DaGVjayhweV92YWwpKSB7CiAgICAgICAgaWYgKFB5T2JqZWN0X0FzQ2hhckJ1ZmZlcihweV92YWwsICZidWZmZXIsICZidWZsZW4pICE9IDApIHsKICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsICJjb3VsZCBub3QgY29udmVydCBCTE9CIHRvIGJ1ZmZlciIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNxbGl0ZTNfcmVzdWx0X2Jsb2IoY29udGV4dCwgYnVmZmVyLCBidWZsZW4sIFNRTElURV9UUkFOU0lFTlQpOwogICAgICAgIH0KICAgIH0gZWxzZSBpZiAoUHlTdHJpbmdfQ2hlY2socHlfdmFsKSkgewogICAgICAgIHNxbGl0ZTNfcmVzdWx0X3RleHQoY29udGV4dCwgUHlTdHJpbmdfQXNTdHJpbmcocHlfdmFsKSwgLTEsIFNRTElURV9UUkFOU0lFTlQpOwogICAgfSBlbHNlIGlmIChQeVVuaWNvZGVfQ2hlY2socHlfdmFsKSkgewogICAgICAgIHN0cmluZ3ZhbCA9IFB5VW5pY29kZV9Bc1VURjhTdHJpbmcocHlfdmFsKTsKICAgICAgICBpZiAoc3RyaW5ndmFsKSB7CiAgICAgICAgICAgIHNxbGl0ZTNfcmVzdWx0X3RleHQoY29udGV4dCwgUHlTdHJpbmdfQXNTdHJpbmcoc3RyaW5ndmFsKSwgLTEsIFNRTElURV9UUkFOU0lFTlQpOwogICAgICAgICAgICBQeV9ERUNSRUYoc3RyaW5ndmFsKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIC8qIFRPRE86IHJhaXNlIGVycm9yICovCiAgICB9Cn0KClB5T2JqZWN0KiBfYnVpbGRfcHlfcGFyYW1zKHNxbGl0ZTNfY29udGV4dCAqY29udGV4dCwgaW50IGFyZ2MsIHNxbGl0ZTNfdmFsdWUqKiBhcmd2KQp7CiAgICBQeU9iamVjdCogYXJnczsKICAgIGludCBpOwogICAgc3FsaXRlM192YWx1ZSogY3VyX3ZhbHVlOwogICAgUHlPYmplY3QqIGN1cl9weV92YWx1ZTsKICAgIGNvbnN0IGNoYXIqIHZhbF9zdHI7CiAgICBQWV9MT05HX0xPTkcgdmFsX2ludDsKICAgIFB5X3NzaXplX3QgYnVmbGVuOwogICAgdm9pZCogcmF3X2J1ZmZlcjsKCiAgICBhcmdzID0gUHlUdXBsZV9OZXcoYXJnYyk7CiAgICBpZiAoIWFyZ3MpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBmb3IgKGkgPSAwOyBpIDwgYXJnYzsgaSsrKSB7CiAgICAgICAgY3VyX3ZhbHVlID0gYXJndltpXTsKICAgICAgICBzd2l0Y2ggKHNxbGl0ZTNfdmFsdWVfdHlwZShhcmd2W2ldKSkgewogICAgICAgICAgICBjYXNlIFNRTElURV9JTlRFR0VSOgogICAgICAgICAgICAgICAgdmFsX2ludCA9IHNxbGl0ZTNfdmFsdWVfaW50NjQoY3VyX3ZhbHVlKTsKICAgICAgICAgICAgICAgIGN1cl9weV92YWx1ZSA9IFB5SW50X0Zyb21Mb25nKChsb25nKXZhbF9pbnQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU1FMSVRFX0ZMT0FUOgogICAgICAgICAgICAgICAgY3VyX3B5X3ZhbHVlID0gUHlGbG9hdF9Gcm9tRG91YmxlKHNxbGl0ZTNfdmFsdWVfZG91YmxlKGN1cl92YWx1ZSkpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU1FMSVRFX1RFWFQ6CiAgICAgICAgICAgICAgICB2YWxfc3RyID0gKGNvbnN0IGNoYXIqKXNxbGl0ZTNfdmFsdWVfdGV4dChjdXJfdmFsdWUpOwogICAgICAgICAgICAgICAgY3VyX3B5X3ZhbHVlID0gUHlVbmljb2RlX0RlY29kZVVURjgodmFsX3N0ciwgc3RybGVuKHZhbF9zdHIpLCBOVUxMKTsKICAgICAgICAgICAgICAgIC8qIFRPRE86IGhhdmUgYSB3YXkgdG8gc2hvdyBlcnJvcnMgaGVyZSAqLwogICAgICAgICAgICAgICAgaWYgKCFjdXJfcHlfdmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICBQeUVycl9DbGVhcigpOwogICAgICAgICAgICAgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgICAgICAgICAgICAgICAgICBjdXJfcHlfdmFsdWUgPSBQeV9Ob25lOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU1FMSVRFX0JMT0I6CiAgICAgICAgICAgICAgICBidWZsZW4gPSBzcWxpdGUzX3ZhbHVlX2J5dGVzKGN1cl92YWx1ZSk7CiAgICAgICAgICAgICAgICBjdXJfcHlfdmFsdWUgPSBQeUJ1ZmZlcl9OZXcoYnVmbGVuKTsKICAgICAgICAgICAgICAgIGlmICghY3VyX3B5X3ZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoUHlPYmplY3RfQXNXcml0ZUJ1ZmZlcihjdXJfcHlfdmFsdWUsICZyYXdfYnVmZmVyLCAmYnVmbGVuKSkgewogICAgICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihjdXJfcHlfdmFsdWUpOwogICAgICAgICAgICAgICAgICAgIGN1cl9weV92YWx1ZSA9IE5VTEw7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBtZW1jcHkocmF3X2J1ZmZlciwgc3FsaXRlM192YWx1ZV9ibG9iKGN1cl92YWx1ZSksIGJ1Zmxlbik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBTUUxJVEVfTlVMTDoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgICAgICAgICAgICAgIGN1cl9weV92YWx1ZSA9IFB5X05vbmU7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWN1cl9weV92YWx1ZSkgewogICAgICAgICAgICBQeV9ERUNSRUYoYXJncyk7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KCiAgICAgICAgUHlUdXBsZV9TZXRJdGVtKGFyZ3MsIGksIGN1cl9weV92YWx1ZSk7CgogICAgfQoKICAgIHJldHVybiBhcmdzOwp9Cgp2b2lkIF9mdW5jX2NhbGxiYWNrKHNxbGl0ZTNfY29udGV4dCogY29udGV4dCwgaW50IGFyZ2MsIHNxbGl0ZTNfdmFsdWUqKiBhcmd2KQp7CiAgICBQeU9iamVjdCogYXJnczsKICAgIFB5T2JqZWN0KiBweV9mdW5jOwogICAgUHlPYmplY3QqIHB5X3JldHZhbCA9IE5VTEw7CgogICAgUHlHSUxTdGF0ZV9TVEFURSB0aHJlYWRzdGF0ZTsKCiAgICB0aHJlYWRzdGF0ZSA9IFB5R0lMU3RhdGVfRW5zdXJlKCk7CgogICAgcHlfZnVuYyA9IChQeU9iamVjdCopc3FsaXRlM191c2VyX2RhdGEoY29udGV4dCk7CgogICAgYXJncyA9IF9idWlsZF9weV9wYXJhbXMoY29udGV4dCwgYXJnYywgYXJndik7CiAgICBpZiAoYXJncykgewogICAgICAgIHB5X3JldHZhbCA9IFB5T2JqZWN0X0NhbGxPYmplY3QocHlfZnVuYywgYXJncyk7CiAgICAgICAgUHlfREVDUkVGKGFyZ3MpOwogICAgfQoKICAgIGlmIChweV9yZXR2YWwpIHsKICAgICAgICBfc2V0X3Jlc3VsdChjb250ZXh0LCBweV9yZXR2YWwpOwogICAgICAgIFB5X0RFQ1JFRihweV9yZXR2YWwpOwogICAgfSBlbHNlIHsKICAgICAgICBpZiAoX2VuYWJsZV9jYWxsYmFja190cmFjZWJhY2tzKSB7CiAgICAgICAgICAgIFB5RXJyX1ByaW50KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgX3NxbGl0ZTNfcmVzdWx0X2Vycm9yKGNvbnRleHQsICJ1c2VyLWRlZmluZWQgZnVuY3Rpb24gcmFpc2VkIGV4Y2VwdGlvbiIsIC0xKTsKICAgIH0KCiAgICBQeUdJTFN0YXRlX1JlbGVhc2UodGhyZWFkc3RhdGUpOwp9CgpzdGF0aWMgdm9pZCBfc3RlcF9jYWxsYmFjayhzcWxpdGUzX2NvbnRleHQgKmNvbnRleHQsIGludCBhcmdjLCBzcWxpdGUzX3ZhbHVlKiogcGFyYW1zKQp7CiAgICBQeU9iamVjdCogYXJnczsKICAgIFB5T2JqZWN0KiBmdW5jdGlvbl9yZXN1bHQgPSBOVUxMOwogICAgUHlPYmplY3QqIGFnZ3JlZ2F0ZV9jbGFzczsKICAgIFB5T2JqZWN0KiogYWdncmVnYXRlX2luc3RhbmNlOwogICAgUHlPYmplY3QqIHN0ZXBtZXRob2QgPSBOVUxMOwoKICAgIFB5R0lMU3RhdGVfU1RBVEUgdGhyZWFkc3RhdGU7CgogICAgdGhyZWFkc3RhdGUgPSBQeUdJTFN0YXRlX0Vuc3VyZSgpOwoKICAgIGFnZ3JlZ2F0ZV9jbGFzcyA9IChQeU9iamVjdCopc3FsaXRlM191c2VyX2RhdGEoY29udGV4dCk7CgogICAgYWdncmVnYXRlX2luc3RhbmNlID0gKFB5T2JqZWN0Kiopc3FsaXRlM19hZ2dyZWdhdGVfY29udGV4dChjb250ZXh0LCBzaXplb2YoUHlPYmplY3QqKSk7CgogICAgaWYgKCphZ2dyZWdhdGVfaW5zdGFuY2UgPT0gMCkgewogICAgICAgICphZ2dyZWdhdGVfaW5zdGFuY2UgPSBQeU9iamVjdF9DYWxsRnVuY3Rpb24oYWdncmVnYXRlX2NsYXNzLCAiIik7CgogICAgICAgIGlmIChQeUVycl9PY2N1cnJlZCgpKSB7CiAgICAgICAgICAgICphZ2dyZWdhdGVfaW5zdGFuY2UgPSAwOwogICAgICAgICAgICBpZiAoX2VuYWJsZV9jYWxsYmFja190cmFjZWJhY2tzKSB7CiAgICAgICAgICAgICAgICBQeUVycl9QcmludCgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBfc3FsaXRlM19yZXN1bHRfZXJyb3IoY29udGV4dCwgInVzZXItZGVmaW5lZCBhZ2dyZWdhdGUncyAnX19pbml0X18nIG1ldGhvZCByYWlzZWQgZXJyb3IiLCAtMSk7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgfQoKICAgIHN0ZXBtZXRob2QgPSBQeU9iamVjdF9HZXRBdHRyU3RyaW5nKCphZ2dyZWdhdGVfaW5zdGFuY2UsICJzdGVwIik7CiAgICBpZiAoIXN0ZXBtZXRob2QpIHsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIGFyZ3MgPSBfYnVpbGRfcHlfcGFyYW1zKGNvbnRleHQsIGFyZ2MsIHBhcmFtcyk7CiAgICBpZiAoIWFyZ3MpIHsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIGZ1bmN0aW9uX3Jlc3VsdCA9IFB5T2JqZWN0X0NhbGxPYmplY3Qoc3RlcG1ldGhvZCwgYXJncyk7CiAgICBQeV9ERUNSRUYoYXJncyk7CgogICAgaWYgKCFmdW5jdGlvbl9yZXN1bHQpIHsKICAgICAgICBpZiAoX2VuYWJsZV9jYWxsYmFja190cmFjZWJhY2tzKSB7CiAgICAgICAgICAgIFB5RXJyX1ByaW50KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgX3NxbGl0ZTNfcmVzdWx0X2Vycm9yKGNvbnRleHQsICJ1c2VyLWRlZmluZWQgYWdncmVnYXRlJ3MgJ3N0ZXAnIG1ldGhvZCByYWlzZWQgZXJyb3IiLCAtMSk7CiAgICB9CgplcnJvcjoKICAgIFB5X1hERUNSRUYoc3RlcG1ldGhvZCk7CiAgICBQeV9YREVDUkVGKGZ1bmN0aW9uX3Jlc3VsdCk7CgogICAgUHlHSUxTdGF0ZV9SZWxlYXNlKHRocmVhZHN0YXRlKTsKfQoKdm9pZCBfZmluYWxfY2FsbGJhY2soc3FsaXRlM19jb250ZXh0KiBjb250ZXh0KQp7CiAgICBQeU9iamVjdCogZnVuY3Rpb25fcmVzdWx0ID0gTlVMTDsKICAgIFB5T2JqZWN0KiogYWdncmVnYXRlX2luc3RhbmNlOwogICAgUHlPYmplY3QqIGFnZ3JlZ2F0ZV9jbGFzczsKCiAgICBQeUdJTFN0YXRlX1NUQVRFIHRocmVhZHN0YXRlOwoKICAgIHRocmVhZHN0YXRlID0gUHlHSUxTdGF0ZV9FbnN1cmUoKTsKCiAgICBhZ2dyZWdhdGVfY2xhc3MgPSAoUHlPYmplY3QqKXNxbGl0ZTNfdXNlcl9kYXRhKGNvbnRleHQpOwoKICAgIGFnZ3JlZ2F0ZV9pbnN0YW5jZSA9IChQeU9iamVjdCoqKXNxbGl0ZTNfYWdncmVnYXRlX2NvbnRleHQoY29udGV4dCwgc2l6ZW9mKFB5T2JqZWN0KikpOwogICAgaWYgKCEqYWdncmVnYXRlX2luc3RhbmNlKSB7CiAgICAgICAgLyogdGhpcyBicmFuY2ggaXMgZXhlY3V0ZWQgaWYgdGhlcmUgd2FzIGFuIGV4Y2VwdGlvbiBpbiB0aGUgYWdncmVnYXRlJ3MKICAgICAgICAgKiBfX2luaXRfXyAqLwoKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIGZ1bmN0aW9uX3Jlc3VsdCA9IFB5T2JqZWN0X0NhbGxNZXRob2QoKmFnZ3JlZ2F0ZV9pbnN0YW5jZSwgImZpbmFsaXplIiwgIiIpOwogICAgaWYgKCFmdW5jdGlvbl9yZXN1bHQpIHsKICAgICAgICBpZiAoX2VuYWJsZV9jYWxsYmFja190cmFjZWJhY2tzKSB7CiAgICAgICAgICAgIFB5RXJyX1ByaW50KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgX3NxbGl0ZTNfcmVzdWx0X2Vycm9yKGNvbnRleHQsICJ1c2VyLWRlZmluZWQgYWdncmVnYXRlJ3MgJ2ZpbmFsaXplJyBtZXRob2QgcmFpc2VkIGVycm9yIiwgLTEpOwogICAgfSBlbHNlIHsKICAgICAgICBfc2V0X3Jlc3VsdChjb250ZXh0LCBmdW5jdGlvbl9yZXN1bHQpOwogICAgfQoKZXJyb3I6CiAgICBQeV9YREVDUkVGKCphZ2dyZWdhdGVfaW5zdGFuY2UpOwogICAgUHlfWERFQ1JFRihmdW5jdGlvbl9yZXN1bHQpOwoKICAgIFB5R0lMU3RhdGVfUmVsZWFzZSh0aHJlYWRzdGF0ZSk7Cn0KCnZvaWQgX2Ryb3BfdW51c2VkX3N0YXRlbWVudF9yZWZlcmVuY2VzKENvbm5lY3Rpb24qIHNlbGYpCnsKICAgIFB5T2JqZWN0KiBuZXdfbGlzdDsKICAgIFB5T2JqZWN0KiB3ZWFrcmVmOwogICAgaW50IGk7CgogICAgLyogd2Ugb25seSBuZWVkIHRvIGRvIHRoaXMgb25jZSBpbiBhIHdoaWxlICovCiAgICBpZiAoc2VsZi0+Y3JlYXRlZF9zdGF0ZW1lbnRzKysgPCAyMDApIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgc2VsZi0+Y3JlYXRlZF9zdGF0ZW1lbnRzID0gMDsKCiAgICBuZXdfbGlzdCA9IFB5TGlzdF9OZXcoMCk7CiAgICBpZiAoIW5ld19saXN0KSB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGZvciAoaSA9IDA7IGkgPCBQeUxpc3RfU2l6ZShzZWxmLT5zdGF0ZW1lbnRzKTsgaSsrKSB7CiAgICAgICAgd2Vha3JlZiA9IFB5TGlzdF9HZXRJdGVtKHNlbGYtPnN0YXRlbWVudHMsIGkpOwogICAgICAgIGlmIChQeVdlYWtyZWZfR2V0T2JqZWN0KHdlYWtyZWYpICE9IFB5X05vbmUpIHsKICAgICAgICAgICAgaWYgKFB5TGlzdF9BcHBlbmQobmV3X2xpc3QsIHdlYWtyZWYpICE9IDApIHsKICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihuZXdfbGlzdCk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgUHlfREVDUkVGKHNlbGYtPnN0YXRlbWVudHMpOwogICAgc2VsZi0+c3RhdGVtZW50cyA9IG5ld19saXN0Owp9CgpQeU9iamVjdCogY29ubmVjdGlvbl9jcmVhdGVfZnVuY3Rpb24oQ29ubmVjdGlvbiogc2VsZiwgUHlPYmplY3QqIGFyZ3MsIFB5T2JqZWN0KiBrd2FyZ3MpCnsKICAgIHN0YXRpYyBjaGFyICprd2xpc3RbXSA9IHsibmFtZSIsICJuYXJnIiwgImZ1bmMiLCBOVUxMLCBOVUxMfTsKCiAgICBQeU9iamVjdCogZnVuYzsKICAgIGNoYXIqIG5hbWU7CiAgICBpbnQgbmFyZzsKICAgIGludCByYzsKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGVBbmRLZXl3b3JkcyhhcmdzLCBrd2FyZ3MsICJzaU8iLCBrd2xpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbmFtZSwgJm5hcmcsICZmdW5jKSkKICAgIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByYyA9IHNxbGl0ZTNfY3JlYXRlX2Z1bmN0aW9uKHNlbGYtPmRiLCBuYW1lLCBuYXJnLCBTUUxJVEVfVVRGOCwgKHZvaWQqKWZ1bmMsIF9mdW5jX2NhbGxiYWNrLCBOVUxMLCBOVUxMKTsKCiAgICBpZiAocmMgIT0gU1FMSVRFX09LKSB7CiAgICAgICAgLyogV29ya2Fyb3VuZCBmb3IgU1FMaXRlIGJ1Zzogbm8gZXJyb3IgY29kZSBvciBzdHJpbmcgaXMgYXZhaWxhYmxlIGhlcmUgKi8KICAgICAgICBQeUVycl9TZXRTdHJpbmcoT3BlcmF0aW9uYWxFcnJvciwgIkVycm9yIGNyZWF0aW5nIGZ1bmN0aW9uIik7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9IGVsc2UgewogICAgICAgIFB5RGljdF9TZXRJdGVtKHNlbGYtPmZ1bmN0aW9uX3BpbmJvYXJkLCBmdW5jLCBQeV9Ob25lKTsKCiAgICAgICAgUHlfSU5DUkVGKFB5X05vbmUpOwogICAgICAgIHJldHVybiBQeV9Ob25lOwogICAgfQp9CgpQeU9iamVjdCogY29ubmVjdGlvbl9jcmVhdGVfYWdncmVnYXRlKENvbm5lY3Rpb24qIHNlbGYsIFB5T2JqZWN0KiBhcmdzLCBQeU9iamVjdCoga3dhcmdzKQp7CiAgICBQeU9iamVjdCogYWdncmVnYXRlX2NsYXNzOwoKICAgIGludCBuX2FyZzsKICAgIGNoYXIqIG5hbWU7CiAgICBzdGF0aWMgY2hhciAqa3dsaXN0W10gPSB7ICJuYW1lIiwgIm5fYXJnIiwgImFnZ3JlZ2F0ZV9jbGFzcyIsIE5VTEwgfTsKICAgIGludCByYzsKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGVBbmRLZXl3b3JkcyhhcmdzLCBrd2FyZ3MsICJzaU86Y3JlYXRlX2FnZ3JlZ2F0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga3dsaXN0LCAmbmFtZSwgJm5fYXJnLCAmYWdncmVnYXRlX2NsYXNzKSkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIHJjID0gc3FsaXRlM19jcmVhdGVfZnVuY3Rpb24oc2VsZi0+ZGIsIG5hbWUsIG5fYXJnLCBTUUxJVEVfVVRGOCwgKHZvaWQqKWFnZ3JlZ2F0ZV9jbGFzcywgMCwgJl9zdGVwX2NhbGxiYWNrLCAmX2ZpbmFsX2NhbGxiYWNrKTsKICAgIGlmIChyYyAhPSBTUUxJVEVfT0spIHsKICAgICAgICAvKiBXb3JrYXJvdW5kIGZvciBTUUxpdGUgYnVnOiBubyBlcnJvciBjb2RlIG9yIHN0cmluZyBpcyBhdmFpbGFibGUgaGVyZSAqLwogICAgICAgIFB5RXJyX1NldFN0cmluZyhPcGVyYXRpb25hbEVycm9yLCAiRXJyb3IgY3JlYXRpbmcgYWdncmVnYXRlIik7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9IGVsc2UgewogICAgICAgIFB5RGljdF9TZXRJdGVtKHNlbGYtPmZ1bmN0aW9uX3BpbmJvYXJkLCBhZ2dyZWdhdGVfY2xhc3MsIFB5X05vbmUpOwoKICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICAgICAgcmV0dXJuIFB5X05vbmU7CiAgICB9Cn0KCmludCBfYXV0aG9yaXplcl9jYWxsYmFjayh2b2lkKiB1c2VyX2FyZywgaW50IGFjdGlvbiwgY29uc3QgY2hhciogYXJnMSwgY29uc3QgY2hhciogYXJnMiAsIGNvbnN0IGNoYXIqIGRibmFtZSwgY29uc3QgY2hhciogYWNjZXNzX2F0dGVtcHRfc291cmNlKQp7CiAgICBQeU9iamVjdCAqcmV0OwogICAgaW50IHJjOwogICAgUHlHSUxTdGF0ZV9TVEFURSBnaWxzdGF0ZTsKCiAgICBnaWxzdGF0ZSA9IFB5R0lMU3RhdGVfRW5zdXJlKCk7CiAgICByZXQgPSBQeU9iamVjdF9DYWxsRnVuY3Rpb24oKFB5T2JqZWN0Kil1c2VyX2FyZywgImlzc3NzIiwgYWN0aW9uLCBhcmcxLCBhcmcyLCBkYm5hbWUsIGFjY2Vzc19hdHRlbXB0X3NvdXJjZSk7CgogICAgaWYgKCFyZXQpIHsKICAgICAgICBpZiAoX2VuYWJsZV9jYWxsYmFja190cmFjZWJhY2tzKSB7CiAgICAgICAgICAgIFB5RXJyX1ByaW50KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKICAgICAgICB9CgogICAgICAgIHJjID0gU1FMSVRFX0RFTlk7CiAgICB9IGVsc2UgewogICAgICAgIGlmIChQeUludF9DaGVjayhyZXQpKSB7CiAgICAgICAgICAgIHJjID0gKGludClQeUludF9Bc0xvbmcocmV0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByYyA9IFNRTElURV9ERU5ZOwogICAgICAgIH0KICAgICAgICBQeV9ERUNSRUYocmV0KTsKICAgIH0KCiAgICBQeUdJTFN0YXRlX1JlbGVhc2UoZ2lsc3RhdGUpOwogICAgcmV0dXJuIHJjOwp9CgpQeU9iamVjdCogY29ubmVjdGlvbl9zZXRfYXV0aG9yaXplcihDb25uZWN0aW9uKiBzZWxmLCBQeU9iamVjdCogYXJncywgUHlPYmplY3QqIGt3YXJncykKewogICAgUHlPYmplY3QqIGF1dGhvcml6ZXJfY2I7CgogICAgc3RhdGljIGNoYXIgKmt3bGlzdFtdID0geyAiYXV0aG9yaXplcl9jYWxsYmFjayIsIE5VTEwgfTsKICAgIGludCByYzsKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGVBbmRLZXl3b3JkcyhhcmdzLCBrd2FyZ3MsICJPOnNldF9hdXRob3JpemVyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrd2xpc3QsICZhdXRob3JpemVyX2NiKSkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIHJjID0gc3FsaXRlM19zZXRfYXV0aG9yaXplcihzZWxmLT5kYiwgX2F1dGhvcml6ZXJfY2FsbGJhY2ssICh2b2lkKilhdXRob3JpemVyX2NiKTsKCiAgICBpZiAocmMgIT0gU1FMSVRFX09LKSB7CiAgICAgICAgUHlFcnJfU2V0U3RyaW5nKE9wZXJhdGlvbmFsRXJyb3IsICJFcnJvciBzZXR0aW5nIGF1dGhvcml6ZXIgY2FsbGJhY2siKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0gZWxzZSB7CiAgICAgICAgUHlEaWN0X1NldEl0ZW0oc2VsZi0+ZnVuY3Rpb25fcGluYm9hcmQsIGF1dGhvcml6ZXJfY2IsIFB5X05vbmUpOwoKICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICAgICAgcmV0dXJuIFB5X05vbmU7CiAgICB9Cn0KCmludCBjaGVja190aHJlYWQoQ29ubmVjdGlvbiogc2VsZikKewogICAgaWYgKHNlbGYtPmNoZWNrX3NhbWVfdGhyZWFkKSB7CiAgICAgICAgaWYgKFB5VGhyZWFkX2dldF90aHJlYWRfaWRlbnQoKSAhPSBzZWxmLT50aHJlYWRfaWRlbnQpIHsKICAgICAgICAgICAgUHlFcnJfRm9ybWF0KFByb2dyYW1taW5nRXJyb3IsCiAgICAgICAgICAgICAgICAgICAgICAgICJTUUxpdGUgb2JqZWN0cyBjcmVhdGVkIGluIGEgdGhyZWFkIGNhbiBvbmx5IGJlIHVzZWQgaW4gdGhhdCBzYW1lIHRocmVhZC4iCiAgICAgICAgICAgICAgICAgICAgICAgICJUaGUgb2JqZWN0IHdhcyBjcmVhdGVkIGluIHRocmVhZCBpZCAlbGQgYW5kIHRoaXMgaXMgdGhyZWFkIGlkICVsZCIsCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPnRocmVhZF9pZGVudCwgUHlUaHJlYWRfZ2V0X3RocmVhZF9pZGVudCgpKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgIH0KCiAgICByZXR1cm4gMTsKfQoKc3RhdGljIFB5T2JqZWN0KiBjb25uZWN0aW9uX2dldF9pc29sYXRpb25fbGV2ZWwoQ29ubmVjdGlvbiogc2VsZiwgdm9pZCogdW51c2VkKQp7CiAgICBQeV9JTkNSRUYoc2VsZi0+aXNvbGF0aW9uX2xldmVsKTsKICAgIHJldHVybiBzZWxmLT5pc29sYXRpb25fbGV2ZWw7Cn0KCnN0YXRpYyBQeU9iamVjdCogY29ubmVjdGlvbl9nZXRfdG90YWxfY2hhbmdlcyhDb25uZWN0aW9uKiBzZWxmLCB2b2lkKiB1bnVzZWQpCnsKICAgIGlmICghY2hlY2tfY29ubmVjdGlvbihzZWxmKSkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gUHlfQnVpbGRWYWx1ZSgiaSIsIHNxbGl0ZTNfdG90YWxfY2hhbmdlcyhzZWxmLT5kYikpOwogICAgfQp9CgpzdGF0aWMgaW50IGNvbm5lY3Rpb25fc2V0X2lzb2xhdGlvbl9sZXZlbChDb25uZWN0aW9uKiBzZWxmLCBQeU9iamVjdCogaXNvbGF0aW9uX2xldmVsKQp7CiAgICBQeU9iamVjdCogcmVzOwogICAgUHlPYmplY3QqIGJlZ2luX3N0YXRlbWVudDsKICAgIGNoYXIqIGJlZ2luX3N0YXRlbWVudF9zdHI7CgogICAgUHlfWERFQ1JFRihzZWxmLT5pc29sYXRpb25fbGV2ZWwpOwoKICAgIGlmIChzZWxmLT5iZWdpbl9zdGF0ZW1lbnQpIHsKICAgICAgICBQeU1lbV9GcmVlKHNlbGYtPmJlZ2luX3N0YXRlbWVudCk7CiAgICAgICAgc2VsZi0+YmVnaW5fc3RhdGVtZW50ID0gTlVMTDsKICAgIH0KCiAgICBpZiAoaXNvbGF0aW9uX2xldmVsID09IFB5X05vbmUpIHsKICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICAgICAgc2VsZi0+aXNvbGF0aW9uX2xldmVsID0gUHlfTm9uZTsKCiAgICAgICAgcmVzID0gY29ubmVjdGlvbl9jb21taXQoc2VsZiwgTlVMTCk7CiAgICAgICAgaWYgKCFyZXMpIHsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgICAgICBQeV9ERUNSRUYocmVzKTsKCiAgICAgICAgc2VsZi0+aW5UcmFuc2FjdGlvbiA9IDA7CiAgICB9IGVsc2UgewogICAgICAgIFB5X0lOQ1JFRihpc29sYXRpb25fbGV2ZWwpOwogICAgICAgIHNlbGYtPmlzb2xhdGlvbl9sZXZlbCA9IGlzb2xhdGlvbl9sZXZlbDsKCiAgICAgICAgYmVnaW5fc3RhdGVtZW50ID0gUHlTdHJpbmdfRnJvbVN0cmluZygiQkVHSU4gIik7CiAgICAgICAgaWYgKCFiZWdpbl9zdGF0ZW1lbnQpIHsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgICAgICBQeVN0cmluZ19Db25jYXQoJmJlZ2luX3N0YXRlbWVudCwgaXNvbGF0aW9uX2xldmVsKTsKICAgICAgICBpZiAoIWJlZ2luX3N0YXRlbWVudCkgewogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQoKICAgICAgICBiZWdpbl9zdGF0ZW1lbnRfc3RyID0gUHlTdHJpbmdfQXNTdHJpbmcoYmVnaW5fc3RhdGVtZW50KTsKICAgICAgICBpZiAoIWJlZ2luX3N0YXRlbWVudF9zdHIpIHsKICAgICAgICAgICAgUHlfREVDUkVGKGJlZ2luX3N0YXRlbWVudCk7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICAgICAgc2VsZi0+YmVnaW5fc3RhdGVtZW50ID0gUHlNZW1fTWFsbG9jKHN0cmxlbihiZWdpbl9zdGF0ZW1lbnRfc3RyKSArIDIpOwogICAgICAgIGlmICghc2VsZi0+YmVnaW5fc3RhdGVtZW50KSB7CiAgICAgICAgICAgIFB5X0RFQ1JFRihiZWdpbl9zdGF0ZW1lbnQpOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQoKICAgICAgICBzdHJjcHkoc2VsZi0+YmVnaW5fc3RhdGVtZW50LCBiZWdpbl9zdGF0ZW1lbnRfc3RyKTsKICAgICAgICBQeV9ERUNSRUYoYmVnaW5fc3RhdGVtZW50KTsKICAgIH0KCiAgICByZXR1cm4gMDsKfQoKUHlPYmplY3QqIGNvbm5lY3Rpb25fY2FsbChDb25uZWN0aW9uKiBzZWxmLCBQeU9iamVjdCogYXJncywgUHlPYmplY3QqIGt3YXJncykKewogICAgUHlPYmplY3QqIHNxbDsKICAgIFN0YXRlbWVudCogc3RhdGVtZW50OwogICAgUHlPYmplY3QqIHdlYWtyZWY7CiAgICBpbnQgcmM7CgogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJPIiwgJnNxbCkpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBfZHJvcF91bnVzZWRfc3RhdGVtZW50X3JlZmVyZW5jZXMoc2VsZik7CgogICAgc3RhdGVtZW50ID0gUHlPYmplY3RfTmV3KFN0YXRlbWVudCwgJlN0YXRlbWVudFR5cGUpOwogICAgaWYgKCFzdGF0ZW1lbnQpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByYyA9IHN0YXRlbWVudF9jcmVhdGUoc3RhdGVtZW50LCBzZWxmLCBzcWwpOwoKICAgIGlmIChyYyAhPSBTUUxJVEVfT0spIHsKICAgICAgICBpZiAocmMgPT0gUFlTUUxJVEVfVE9PX01VQ0hfU1FMKSB7CiAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhXYXJuaW5nLCAiWW91IGNhbiBvbmx5IGV4ZWN1dGUgb25lIHN0YXRlbWVudCBhdCBhIHRpbWUuIik7CiAgICAgICAgfSBlbHNlIGlmIChyYyA9PSBQWVNRTElURV9TUUxfV1JPTkdfVFlQRSkgewogICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoV2FybmluZywgIlNRTCBpcyBvZiB3cm9uZyB0eXBlLiBNdXN0IGJlIHN0cmluZyBvciB1bmljb2RlLiIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIF9zZXRlcnJvcihzZWxmLT5kYik7CiAgICAgICAgfQoKICAgICAgICBQeV9ERUNSRUYoc3RhdGVtZW50KTsKICAgICAgICBzdGF0ZW1lbnQgPSAwOwogICAgfSBlbHNlIHsKICAgICAgICB3ZWFrcmVmID0gUHlXZWFrcmVmX05ld1JlZigoUHlPYmplY3QqKXN0YXRlbWVudCwgTlVMTCk7CiAgICAgICAgaWYgKCF3ZWFrcmVmKSB7CiAgICAgICAgICAgIFB5X0RFQ1JFRihzdGF0ZW1lbnQpOwogICAgICAgICAgICBzdGF0ZW1lbnQgPSAwOwogICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgIH0KCiAgICAgICAgaWYgKFB5TGlzdF9BcHBlbmQoc2VsZi0+c3RhdGVtZW50cywgd2Vha3JlZikgIT0gMCkgewogICAgICAgICAgICBQeV9ERUNSRUYod2Vha3JlZik7CiAgICAgICAgICAgIHN0YXRlbWVudCA9IDA7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQoKICAgICAgICBQeV9ERUNSRUYod2Vha3JlZik7CiAgICB9CgplcnJvcjoKICAgIHJldHVybiAoUHlPYmplY3QqKXN0YXRlbWVudDsKfQoKUHlPYmplY3QqIGNvbm5lY3Rpb25fZXhlY3V0ZShDb25uZWN0aW9uKiBzZWxmLCBQeU9iamVjdCogYXJncywgUHlPYmplY3QqIGt3YXJncykKewogICAgUHlPYmplY3QqIGN1cnNvciA9IDA7CiAgICBQeU9iamVjdCogcmVzdWx0ID0gMDsKICAgIFB5T2JqZWN0KiBtZXRob2QgPSAwOwoKICAgIGN1cnNvciA9IFB5T2JqZWN0X0NhbGxNZXRob2QoKFB5T2JqZWN0KilzZWxmLCAiY3Vyc29yIiwgIiIpOwogICAgaWYgKCFjdXJzb3IpIHsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIG1ldGhvZCA9IFB5T2JqZWN0X0dldEF0dHJTdHJpbmcoY3Vyc29yLCAiZXhlY3V0ZSIpOwogICAgaWYgKCFtZXRob2QpIHsKICAgICAgICBQeV9ERUNSRUYoY3Vyc29yKTsKICAgICAgICBjdXJzb3IgPSAwOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgcmVzdWx0ID0gUHlPYmplY3RfQ2FsbE9iamVjdChtZXRob2QsIGFyZ3MpOwogICAgaWYgKCFyZXN1bHQpIHsKICAgICAgICBQeV9ERUNSRUYoY3Vyc29yKTsKICAgICAgICBjdXJzb3IgPSAwOwogICAgfQoKZXJyb3I6CiAgICBQeV9YREVDUkVGKHJlc3VsdCk7CiAgICBQeV9YREVDUkVGKG1ldGhvZCk7CgogICAgcmV0dXJuIGN1cnNvcjsKfQoKUHlPYmplY3QqIGNvbm5lY3Rpb25fZXhlY3V0ZW1hbnkoQ29ubmVjdGlvbiogc2VsZiwgUHlPYmplY3QqIGFyZ3MsIFB5T2JqZWN0KiBrd2FyZ3MpCnsKICAgIFB5T2JqZWN0KiBjdXJzb3IgPSAwOwogICAgUHlPYmplY3QqIHJlc3VsdCA9IDA7CiAgICBQeU9iamVjdCogbWV0aG9kID0gMDsKCiAgICBjdXJzb3IgPSBQeU9iamVjdF9DYWxsTWV0aG9kKChQeU9iamVjdCopc2VsZiwgImN1cnNvciIsICIiKTsKICAgIGlmICghY3Vyc29yKSB7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBtZXRob2QgPSBQeU9iamVjdF9HZXRBdHRyU3RyaW5nKGN1cnNvciwgImV4ZWN1dGVtYW55Iik7CiAgICBpZiAoIW1ldGhvZCkgewogICAgICAgIFB5X0RFQ1JFRihjdXJzb3IpOwogICAgICAgIGN1cnNvciA9IDA7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICByZXN1bHQgPSBQeU9iamVjdF9DYWxsT2JqZWN0KG1ldGhvZCwgYXJncyk7CiAgICBpZiAoIXJlc3VsdCkgewogICAgICAgIFB5X0RFQ1JFRihjdXJzb3IpOwogICAgICAgIGN1cnNvciA9IDA7CiAgICB9CgplcnJvcjoKICAgIFB5X1hERUNSRUYocmVzdWx0KTsKICAgIFB5X1hERUNSRUYobWV0aG9kKTsKCiAgICByZXR1cm4gY3Vyc29yOwp9CgpQeU9iamVjdCogY29ubmVjdGlvbl9leGVjdXRlc2NyaXB0KENvbm5lY3Rpb24qIHNlbGYsIFB5T2JqZWN0KiBhcmdzLCBQeU9iamVjdCoga3dhcmdzKQp7CiAgICBQeU9iamVjdCogY3Vyc29yID0gMDsKICAgIFB5T2JqZWN0KiByZXN1bHQgPSAwOwogICAgUHlPYmplY3QqIG1ldGhvZCA9IDA7CgogICAgY3Vyc29yID0gUHlPYmplY3RfQ2FsbE1ldGhvZCgoUHlPYmplY3QqKXNlbGYsICJjdXJzb3IiLCAiIik7CiAgICBpZiAoIWN1cnNvcikgewogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgbWV0aG9kID0gUHlPYmplY3RfR2V0QXR0clN0cmluZyhjdXJzb3IsICJleGVjdXRlc2NyaXB0Iik7CiAgICBpZiAoIW1ldGhvZCkgewogICAgICAgIFB5X0RFQ1JFRihjdXJzb3IpOwogICAgICAgIGN1cnNvciA9IDA7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICByZXN1bHQgPSBQeU9iamVjdF9DYWxsT2JqZWN0KG1ldGhvZCwgYXJncyk7CiAgICBpZiAoIXJlc3VsdCkgewogICAgICAgIFB5X0RFQ1JFRihjdXJzb3IpOwogICAgICAgIGN1cnNvciA9IDA7CiAgICB9CgplcnJvcjoKICAgIFB5X1hERUNSRUYocmVzdWx0KTsKICAgIFB5X1hERUNSRUYobWV0aG9kKTsKCiAgICByZXR1cm4gY3Vyc29yOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENPTExBVElPTiBDT0RFIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKc3RhdGljIGludApjb2xsYXRpb25fY2FsbGJhY2soCiAgICAgICAgdm9pZCogY29udGV4dCwKICAgICAgICBpbnQgdGV4dDFfbGVuZ3RoLCBjb25zdCB2b2lkKiB0ZXh0MV9kYXRhLAogICAgICAgIGludCB0ZXh0Ml9sZW5ndGgsIGNvbnN0IHZvaWQqIHRleHQyX2RhdGEpCnsKICAgIFB5T2JqZWN0KiBjYWxsYmFjayA9IChQeU9iamVjdCopY29udGV4dDsKICAgIFB5T2JqZWN0KiBzdHJpbmcxID0gMDsKICAgIFB5T2JqZWN0KiBzdHJpbmcyID0gMDsKICAgIFB5R0lMU3RhdGVfU1RBVEUgZ2lsc3RhdGU7CgogICAgUHlPYmplY3QqIHJldHZhbCA9IE5VTEw7CiAgICBpbnQgcmVzdWx0ID0gMDsKCiAgICBnaWxzdGF0ZSA9IFB5R0lMU3RhdGVfRW5zdXJlKCk7CgogICAgaWYgKFB5RXJyX09jY3VycmVkKCkpIHsKICAgICAgICBnb3RvIGZpbmFsbHk7CiAgICB9CgogICAgc3RyaW5nMSA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKChjb25zdCBjaGFyKil0ZXh0MV9kYXRhLCB0ZXh0MV9sZW5ndGgpOwogICAgc3RyaW5nMiA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKChjb25zdCBjaGFyKil0ZXh0Ml9kYXRhLCB0ZXh0Ml9sZW5ndGgpOwoKICAgIGlmICghc3RyaW5nMSB8fCAhc3RyaW5nMikgewogICAgICAgIGdvdG8gZmluYWxseTsgLyogZmFpbGVkIHRvIGFsbG9jYXRlIHN0cmluZ3MgKi8KICAgIH0KCiAgICByZXR2YWwgPSBQeU9iamVjdF9DYWxsRnVuY3Rpb25PYmpBcmdzKGNhbGxiYWNrLCBzdHJpbmcxLCBzdHJpbmcyLCBOVUxMKTsKCiAgICBpZiAoIXJldHZhbCkgewogICAgICAgIC8qIGV4ZWN1dGlvbiBmYWlsZWQgKi8KICAgICAgICBnb3RvIGZpbmFsbHk7CiAgICB9CgogICAgcmVzdWx0ID0gUHlJbnRfQXNMb25nKHJldHZhbCk7CiAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkgewogICAgICAgIHJlc3VsdCA9IDA7CiAgICB9CgpmaW5hbGx5OgogICAgUHlfWERFQ1JFRihzdHJpbmcxKTsKICAgIFB5X1hERUNSRUYoc3RyaW5nMik7CiAgICBQeV9YREVDUkVGKHJldHZhbCk7CgogICAgUHlHSUxTdGF0ZV9SZWxlYXNlKGdpbHN0YXRlKTsKCiAgICByZXR1cm4gcmVzdWx0Owp9CgpzdGF0aWMgUHlPYmplY3QgKgpjb25uZWN0aW9uX2ludGVycnVwdChDb25uZWN0aW9uKiBzZWxmLCBQeU9iamVjdCogYXJncykKewogICAgUHlPYmplY3QqIHJldHZhbCA9IE5VTEw7CgogICAgaWYgKCFjaGVja19jb25uZWN0aW9uKHNlbGYpKSB7CiAgICAgICAgZ290byBmaW5hbGx5OwogICAgfQoKICAgIHNxbGl0ZTNfaW50ZXJydXB0KHNlbGYtPmRiKTsKCiAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICByZXR2YWwgPSBQeV9Ob25lOwoKZmluYWxseToKICAgIHJldHVybiByZXR2YWw7Cn0KCnN0YXRpYyBQeU9iamVjdCAqCmNvbm5lY3Rpb25fY3JlYXRlX2NvbGxhdGlvbihDb25uZWN0aW9uKiBzZWxmLCBQeU9iamVjdCogYXJncykKewogICAgUHlPYmplY3QqIGNhbGxhYmxlOwogICAgUHlPYmplY3QqIHVwcGVyY2FzZV9uYW1lID0gMDsKICAgIFB5T2JqZWN0KiBuYW1lOwogICAgUHlPYmplY3QqIHJldHZhbDsKICAgIGNoYXIqIGNoazsKICAgIGludCByYzsKCiAgICBpZiAoIWNoZWNrX3RocmVhZChzZWxmKSB8fCAhY2hlY2tfY29ubmVjdGlvbihzZWxmKSkgewogICAgICAgIGdvdG8gZmluYWxseTsKICAgIH0KCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIk8hTzpjcmVhdGVfY29sbGF0aW9uKG5hbWUsIGNhbGxiYWNrKSIsICZQeVN0cmluZ19UeXBlLCAmbmFtZSwgJmNhbGxhYmxlKSkgewogICAgICAgIGdvdG8gZmluYWxseTsKICAgIH0KCiAgICB1cHBlcmNhc2VfbmFtZSA9IFB5T2JqZWN0X0NhbGxNZXRob2QobmFtZSwgInVwcGVyIiwgIiIpOwogICAgaWYgKCF1cHBlcmNhc2VfbmFtZSkgewogICAgICAgIGdvdG8gZmluYWxseTsKICAgIH0KCiAgICBjaGsgPSBQeVN0cmluZ19Bc1N0cmluZyh1cHBlcmNhc2VfbmFtZSk7CiAgICB3aGlsZSAoKmNoaykgewogICAgICAgIGlmICgoKmNoayA+PSAnMCcgJiYgKmNoayA8PSAnOScpCiAgICAgICAgIHx8ICgqY2hrID49ICdBJyAmJiAqY2hrIDw9ICdaJykKICAgICAgICAgfHwgKCpjaGsgPT0gJ18nKSkKICAgICAgICB7CiAgICAgICAgICAgIGNoaysrOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQcm9ncmFtbWluZ0Vycm9yLCAiaW52YWxpZCBjaGFyYWN0ZXIgaW4gY29sbGF0aW9uIG5hbWUiKTsKICAgICAgICAgICAgZ290byBmaW5hbGx5OwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoY2FsbGFibGUgIT0gUHlfTm9uZSAmJiAhUHlDYWxsYWJsZV9DaGVjayhjYWxsYWJsZSkpIHsKICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAicGFyYW1ldGVyIG11c3QgYmUgY2FsbGFibGUiKTsKICAgICAgICBnb3RvIGZpbmFsbHk7CiAgICB9CgogICAgaWYgKGNhbGxhYmxlICE9IFB5X05vbmUpIHsKICAgICAgICBQeURpY3RfU2V0SXRlbShzZWxmLT5jb2xsYXRpb25zLCB1cHBlcmNhc2VfbmFtZSwgY2FsbGFibGUpOwogICAgfSBlbHNlIHsKICAgICAgICBQeURpY3RfRGVsSXRlbShzZWxmLT5jb2xsYXRpb25zLCB1cHBlcmNhc2VfbmFtZSk7CiAgICB9CgogICAgcmMgPSBzcWxpdGUzX2NyZWF0ZV9jb2xsYXRpb24oc2VsZi0+ZGIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVN0cmluZ19Bc1N0cmluZyh1cHBlcmNhc2VfbmFtZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTUUxJVEVfVVRGOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjYWxsYWJsZSAhPSBQeV9Ob25lKSA/IGNhbGxhYmxlIDogTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjYWxsYWJsZSAhPSBQeV9Ob25lKSA/IGNvbGxhdGlvbl9jYWxsYmFjayA6IE5VTEwpOwogICAgaWYgKHJjICE9IFNRTElURV9PSykgewogICAgICAgIFB5RGljdF9EZWxJdGVtKHNlbGYtPmNvbGxhdGlvbnMsIHVwcGVyY2FzZV9uYW1lKTsKICAgICAgICBfc2V0ZXJyb3Ioc2VsZi0+ZGIpOwogICAgICAgIGdvdG8gZmluYWxseTsKICAgIH0KCmZpbmFsbHk6CiAgICBQeV9YREVDUkVGKHVwcGVyY2FzZV9uYW1lKTsKCiAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkgewogICAgICAgIHJldHZhbCA9IE5VTEw7CiAgICB9IGVsc2UgewogICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgICAgICByZXR2YWwgPSBQeV9Ob25lOwogICAgfQoKICAgIHJldHVybiByZXR2YWw7Cn0KCnN0YXRpYyBjaGFyIGNvbm5lY3Rpb25fZG9jW10gPQpQeURvY19TVFIoIlNRTGl0ZSBkYXRhYmFzZSBjb25uZWN0aW9uIG9iamVjdC4iKTsKCnN0YXRpYyBQeUdldFNldERlZiBjb25uZWN0aW9uX2dldHNldFtdID0gewogICAgeyJpc29sYXRpb25fbGV2ZWwiLCAgKGdldHRlciljb25uZWN0aW9uX2dldF9pc29sYXRpb25fbGV2ZWwsIChzZXR0ZXIpY29ubmVjdGlvbl9zZXRfaXNvbGF0aW9uX2xldmVsfSwKICAgIHsidG90YWxfY2hhbmdlcyIsICAoZ2V0dGVyKWNvbm5lY3Rpb25fZ2V0X3RvdGFsX2NoYW5nZXMsIChzZXR0ZXIpMH0sCiAgICB7TlVMTH0KfTsKCnN0YXRpYyBQeU1ldGhvZERlZiBjb25uZWN0aW9uX21ldGhvZHNbXSA9IHsKICAgIHsiY3Vyc29yIiwgKFB5Q0Z1bmN0aW9uKWNvbm5lY3Rpb25fY3Vyc29yLCBNRVRIX1ZBUkFSR1N8TUVUSF9LRVlXT1JEUywKICAgICAgICBQeURvY19TVFIoIlJldHVybiBhIGN1cnNvciBmb3IgdGhlIGNvbm5lY3Rpb24uIil9LAogICAgeyJjbG9zZSIsIChQeUNGdW5jdGlvbiljb25uZWN0aW9uX2Nsb3NlLCBNRVRIX05PQVJHUywKICAgICAgICBQeURvY19TVFIoIkNsb3NlcyB0aGUgY29ubmVjdGlvbi4iKX0sCiAgICB7ImNvbW1pdCIsIChQeUNGdW5jdGlvbiljb25uZWN0aW9uX2NvbW1pdCwgTUVUSF9OT0FSR1MsCiAgICAgICAgUHlEb2NfU1RSKCJDb21taXQgdGhlIGN1cnJlbnQgdHJhbnNhY3Rpb24uIil9LAogICAgeyJyb2xsYmFjayIsIChQeUNGdW5jdGlvbiljb25uZWN0aW9uX3JvbGxiYWNrLCBNRVRIX05PQVJHUywKICAgICAgICBQeURvY19TVFIoIlJvbGwgYmFjayB0aGUgY3VycmVudCB0cmFuc2FjdGlvbi4iKX0sCiAgICB7ImNyZWF0ZV9mdW5jdGlvbiIsIChQeUNGdW5jdGlvbiljb25uZWN0aW9uX2NyZWF0ZV9mdW5jdGlvbiwgTUVUSF9WQVJBUkdTfE1FVEhfS0VZV09SRFMsCiAgICAgICAgUHlEb2NfU1RSKCJDcmVhdGVzIGEgbmV3IGZ1bmN0aW9uLiBOb24tc3RhbmRhcmQuIil9LAogICAgeyJjcmVhdGVfYWdncmVnYXRlIiwgKFB5Q0Z1bmN0aW9uKWNvbm5lY3Rpb25fY3JlYXRlX2FnZ3JlZ2F0ZSwgTUVUSF9WQVJBUkdTfE1FVEhfS0VZV09SRFMsCiAgICAgICAgUHlEb2NfU1RSKCJDcmVhdGVzIGEgbmV3IGFnZ3JlZ2F0ZS4gTm9uLXN0YW5kYXJkLiIpfSwKICAgIHsic2V0X2F1dGhvcml6ZXIiLCAoUHlDRnVuY3Rpb24pY29ubmVjdGlvbl9zZXRfYXV0aG9yaXplciwgTUVUSF9WQVJBUkdTfE1FVEhfS0VZV09SRFMsCiAgICAgICAgUHlEb2NfU1RSKCJTZXRzIGF1dGhvcml6ZXIgY2FsbGJhY2suIE5vbi1zdGFuZGFyZC4iKX0sCiAgICB7ImV4ZWN1dGUiLCAoUHlDRnVuY3Rpb24pY29ubmVjdGlvbl9leGVjdXRlLCBNRVRIX1ZBUkFSR1MsCiAgICAgICAgUHlEb2NfU1RSKCJFeGVjdXRlcyBhIFNRTCBzdGF0ZW1lbnQuIE5vbi1zdGFuZGFyZC4iKX0sCiAgICB7ImV4ZWN1dGVtYW55IiwgKFB5Q0Z1bmN0aW9uKWNvbm5lY3Rpb25fZXhlY3V0ZW1hbnksIE1FVEhfVkFSQVJHUywKICAgICAgICBQeURvY19TVFIoIlJlcGVhdGVkbHkgZXhlY3V0ZXMgYSBTUUwgc3RhdGVtZW50LiBOb24tc3RhbmRhcmQuIil9LAogICAgeyJleGVjdXRlc2NyaXB0IiwgKFB5Q0Z1bmN0aW9uKWNvbm5lY3Rpb25fZXhlY3V0ZXNjcmlwdCwgTUVUSF9WQVJBUkdTLAogICAgICAgIFB5RG9jX1NUUigiRXhlY3V0ZXMgYSBtdWx0aXBsZSBTUUwgc3RhdGVtZW50cyBhdCBvbmNlLiBOb24tc3RhbmRhcmQuIil9LAogICAgeyJjcmVhdGVfY29sbGF0aW9uIiwgKFB5Q0Z1bmN0aW9uKWNvbm5lY3Rpb25fY3JlYXRlX2NvbGxhdGlvbiwgTUVUSF9WQVJBUkdTLAogICAgICAgIFB5RG9jX1NUUigiQ3JlYXRlcyBhIGNvbGxhdGlvbiBmdW5jdGlvbi4gTm9uLXN0YW5kYXJkLiIpfSwKICAgIHsiaW50ZXJydXB0IiwgKFB5Q0Z1bmN0aW9uKWNvbm5lY3Rpb25faW50ZXJydXB0LCBNRVRIX05PQVJHUywKICAgICAgICBQeURvY19TVFIoIkFib3J0IGFueSBwZW5kaW5nIGRhdGFiYXNlIG9wZXJhdGlvbi4gTm9uLXN0YW5kYXJkLiIpfSwKICAgIHtOVUxMLCBOVUxMfQp9OwoKc3RhdGljIHN0cnVjdCBQeU1lbWJlckRlZiBjb25uZWN0aW9uX21lbWJlcnNbXSA9CnsKICAgIHsiV2FybmluZyIsIFRfT0JKRUNULCBvZmZzZXRvZihDb25uZWN0aW9uLCBXYXJuaW5nKSwgUk99LAogICAgeyJFcnJvciIsIFRfT0JKRUNULCBvZmZzZXRvZihDb25uZWN0aW9uLCBFcnJvciksIFJPfSwKICAgIHsiSW50ZXJmYWNlRXJyb3IiLCBUX09CSkVDVCwgb2Zmc2V0b2YoQ29ubmVjdGlvbiwgSW50ZXJmYWNlRXJyb3IpLCBST30sCiAgICB7IkRhdGFiYXNlRXJyb3IiLCBUX09CSkVDVCwgb2Zmc2V0b2YoQ29ubmVjdGlvbiwgRGF0YWJhc2VFcnJvciksIFJPfSwKICAgIHsiRGF0YUVycm9yIiwgVF9PQkpFQ1QsIG9mZnNldG9mKENvbm5lY3Rpb24sIERhdGFFcnJvciksIFJPfSwKICAgIHsiT3BlcmF0aW9uYWxFcnJvciIsIFRfT0JKRUNULCBvZmZzZXRvZihDb25uZWN0aW9uLCBPcGVyYXRpb25hbEVycm9yKSwgUk99LAogICAgeyJJbnRlZ3JpdHlFcnJvciIsIFRfT0JKRUNULCBvZmZzZXRvZihDb25uZWN0aW9uLCBJbnRlZ3JpdHlFcnJvciksIFJPfSwKICAgIHsiSW50ZXJuYWxFcnJvciIsIFRfT0JKRUNULCBvZmZzZXRvZihDb25uZWN0aW9uLCBJbnRlcm5hbEVycm9yKSwgUk99LAogICAgeyJQcm9ncmFtbWluZ0Vycm9yIiwgVF9PQkpFQ1QsIG9mZnNldG9mKENvbm5lY3Rpb24sIFByb2dyYW1taW5nRXJyb3IpLCBST30sCiAgICB7Ik5vdFN1cHBvcnRlZEVycm9yIiwgVF9PQkpFQ1QsIG9mZnNldG9mKENvbm5lY3Rpb24sIE5vdFN1cHBvcnRlZEVycm9yKSwgUk99LAogICAgeyJyb3dfZmFjdG9yeSIsIFRfT0JKRUNULCBvZmZzZXRvZihDb25uZWN0aW9uLCByb3dfZmFjdG9yeSl9LAogICAgeyJ0ZXh0X2ZhY3RvcnkiLCBUX09CSkVDVCwgb2Zmc2V0b2YoQ29ubmVjdGlvbiwgdGV4dF9mYWN0b3J5KX0sCiAgICB7TlVMTH0KfTsKClB5VHlwZU9iamVjdCBDb25uZWN0aW9uVHlwZSA9IHsKICAgICAgICBQeU9iamVjdF9IRUFEX0lOSVQoTlVMTCkKICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBvYl9zaXplICovCiAgICAgICAgTU9EVUxFX05BTUUgIi5Db25uZWN0aW9uIiwgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmFtZSAqLwogICAgICAgIHNpemVvZihDb25uZWN0aW9uKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2ljc2l6ZSAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZW1zaXplICovCiAgICAgICAgKGRlc3RydWN0b3IpY29ubmVjdGlvbl9kZWFsbG9jLCAgICAgICAgICAgICAgICAgLyogdHBfZGVhbGxvYyAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0ciAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHIgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmVwciAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX251bWJlciAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX3NlcXVlbmNlICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbWFwcGluZyAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2hhc2ggKi8KICAgICAgICAodGVybmFyeWZ1bmMpY29ubmVjdGlvbl9jYWxsLCAgICAgICAgICAgICAgICAgICAvKiB0cF9jYWxsICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc3RyICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0cm8gKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRybyAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX2J1ZmZlciAqLwogICAgICAgIFB5X1RQRkxBR1NfREVGQVVMVHxQeV9UUEZMQUdTX0JBU0VUWVBFLCAgICAgICAgIC8qIHRwX2ZsYWdzICovCiAgICAgICAgY29ubmVjdGlvbl9kb2MsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZG9jICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jbGVhciAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JpY2hjb21wYXJlICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVyICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlcm5leHQgKi8KICAgICAgICBjb25uZWN0aW9uX21ldGhvZHMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCiAgICAgICAgY29ubmVjdGlvbl9tZW1iZXJzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWVtYmVycyAqLwogICAgICAgIGNvbm5lY3Rpb25fZ2V0c2V0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldHNldCAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2UgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0ICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3JfZ2V0ICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3Jfc2V0ICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdG9mZnNldCAqLwogICAgICAgIChpbml0cHJvYyljb25uZWN0aW9uX2luaXQsICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2luaXQgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hbGxvYyAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX25ldyAqLwogICAgICAgIDAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2ZyZWUgKi8KfTsKCmV4dGVybiBpbnQgY29ubmVjdGlvbl9zZXR1cF90eXBlcyh2b2lkKQp7CiAgICBDb25uZWN0aW9uVHlwZS50cF9uZXcgPSBQeVR5cGVfR2VuZXJpY05ldzsKICAgIHJldHVybiBQeVR5cGVfUmVhZHkoJkNvbm5lY3Rpb25UeXBlKTsKfQo=