LyogY29ubmVjdGlvbi5jIC0gdGhlIGNvbm5lY3Rpb24gdHlwZQogKgogKiBDb3B5cmlnaHQgKEMpIDIwMDQtMjAwNyBHZXJoYXJkIEjkcmluZyA8Z2hAZ2hhZXJpbmcuZGU+CiAqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHB5c3FsaXRlLgogKiAKICogVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWQKICogd2FycmFudHkuICBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlcwogKiBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLgogKgogKiBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSwKICogaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAogKiBmcmVlbHksIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyByZXN0cmljdGlvbnM6CiAqCiAqIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90CiAqICAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlCiAqICAgIGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQgaW4gdGhlIHByb2R1Y3QgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZQogKiAgICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLgogKiAyLiBBbHRlcmVkIHNvdXJjZSB2ZXJzaW9ucyBtdXN0IGJlIHBsYWlubHkgbWFya2VkIGFzIHN1Y2gsIGFuZCBtdXN0IG5vdCBiZQogKiAgICBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3JpZ2luYWwgc29mdHdhcmUuCiAqIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uCiAqLwoKI2luY2x1ZGUgImNhY2hlLmgiCiNpbmNsdWRlICJtb2R1bGUuaCIKI2luY2x1ZGUgImNvbm5lY3Rpb24uaCIKI2luY2x1ZGUgInN0YXRlbWVudC5oIgojaW5jbHVkZSAiY3Vyc29yLmgiCiNpbmNsdWRlICJwcmVwYXJlX3Byb3RvY29sLmgiCiNpbmNsdWRlICJ1dGlsLmgiCiNpbmNsdWRlICJzcWxpdGVjb21wYXQuaCIKCiNpbmNsdWRlICJweXRocmVhZC5oIgoKI2RlZmluZSBBQ1RJT05fRklOQUxJWkUgMQojZGVmaW5lIEFDVElPTl9SRVNFVCAyCgpzdGF0aWMgaW50IHB5c3FsaXRlX2Nvbm5lY3Rpb25fc2V0X2lzb2xhdGlvbl9sZXZlbChweXNxbGl0ZV9Db25uZWN0aW9uKiBzZWxmLCBQeU9iamVjdCogaXNvbGF0aW9uX2xldmVsKTsKCgp2b2lkIF9zcWxpdGUzX3Jlc3VsdF9lcnJvcihzcWxpdGUzX2NvbnRleHQqIGN0eCwgY29uc3QgY2hhciogZXJybXNnLCBpbnQgbGVuKQp7CiAgICAvKiBpbiBvbGRlciBTUUxpdGUgdmVyc2lvbnMsIGNhbGxpbmcgc3FsaXRlM19yZXN1bHRfZXJyb3IgaW4gY2FsbGJhY2tzCiAgICAgKiB0cmlnZ2VycyBhIGJ1ZyBpbiBTUUxpdGUgdGhhdCBsZWFkcyBlaXRoZXIgdG8gaXJyaXRhdGluZyByZXN1bHRzIG9yCiAgICAgKiBzZWdmYXVsdHMsIGRlcGVuZGluZyBvbiB0aGUgU1FMaXRlIHZlcnNpb24gKi8KI2lmIFNRTElURV9WRVJTSU9OX05VTUJFUiA+PSAzMDAzMDAzCiAgICBzcWxpdGUzX3Jlc3VsdF9lcnJvcihjdHgsIGVycm1zZywgbGVuKTsKI2Vsc2UKICAgIFB5RXJyX1NldFN0cmluZyhweXNxbGl0ZV9PcGVyYXRpb25hbEVycm9yLCBlcnJtc2cpOwojZW5kaWYKfQoKaW50IHB5c3FsaXRlX2Nvbm5lY3Rpb25faW5pdChweXNxbGl0ZV9Db25uZWN0aW9uKiBzZWxmLCBQeU9iamVjdCogYXJncywgUHlPYmplY3QqIGt3YXJncykKewogICAgc3RhdGljIGNoYXIgKmt3bGlzdFtdID0geyJkYXRhYmFzZSIsICJ0aW1lb3V0IiwgImRldGVjdF90eXBlcyIsICJpc29sYXRpb25fbGV2ZWwiLCAiY2hlY2tfc2FtZV90aHJlYWQiLCAiZmFjdG9yeSIsICJjYWNoZWRfc3RhdGVtZW50cyIsIE5VTEwsIE5VTEx9OwoKICAgIGNoYXIqIGRhdGFiYXNlOwogICAgaW50IGRldGVjdF90eXBlcyA9IDA7CiAgICBQeU9iamVjdCogaXNvbGF0aW9uX2xldmVsID0gTlVMTDsKICAgIFB5T2JqZWN0KiBmYWN0b3J5ID0gTlVMTDsKICAgIGludCBjaGVja19zYW1lX3RocmVhZCA9IDE7CiAgICBpbnQgY2FjaGVkX3N0YXRlbWVudHMgPSAxMDA7CiAgICBkb3VibGUgdGltZW91dCA9IDUuMDsKICAgIGludCByYzsKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGVBbmRLZXl3b3JkcyhhcmdzLCBrd2FyZ3MsICJzfGRpT2lPaSIsIGt3bGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZkYXRhYmFzZSwgJnRpbWVvdXQsICZkZXRlY3RfdHlwZXMsICZpc29sYXRpb25fbGV2ZWwsICZjaGVja19zYW1lX3RocmVhZCwgJmZhY3RvcnksICZjYWNoZWRfc3RhdGVtZW50cykpCiAgICB7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIHNlbGYtPmJlZ2luX3N0YXRlbWVudCA9IE5VTEw7CgogICAgc2VsZi0+c3RhdGVtZW50X2NhY2hlID0gTlVMTDsKICAgIHNlbGYtPnN0YXRlbWVudHMgPSBOVUxMOwoKICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgIHNlbGYtPnJvd19mYWN0b3J5ID0gUHlfTm9uZTsKCiAgICBQeV9JTkNSRUYoJlB5VW5pY29kZV9UeXBlKTsKICAgIHNlbGYtPnRleHRfZmFjdG9yeSA9IChQeU9iamVjdCopJlB5VW5pY29kZV9UeXBlOwoKICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKICAgIHJjID0gc3FsaXRlM19vcGVuKGRhdGFiYXNlLCAmc2VsZi0+ZGIpOwogICAgUHlfRU5EX0FMTE9XX1RIUkVBRFMKCiAgICBpZiAocmMgIT0gU1FMSVRFX09LKSB7CiAgICAgICAgX3B5c3FsaXRlX3NldGVycm9yKHNlbGYtPmRiLCBOVUxMKTsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgaWYgKCFpc29sYXRpb25fbGV2ZWwpIHsKICAgICAgICBpc29sYXRpb25fbGV2ZWwgPSBQeVVuaWNvZGVfRnJvbVN0cmluZygiIik7CiAgICAgICAgaWYgKCFpc29sYXRpb25fbGV2ZWwpIHsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgUHlfSU5DUkVGKGlzb2xhdGlvbl9sZXZlbCk7CiAgICB9CiAgICBzZWxmLT5pc29sYXRpb25fbGV2ZWwgPSBOVUxMOwogICAgcHlzcWxpdGVfY29ubmVjdGlvbl9zZXRfaXNvbGF0aW9uX2xldmVsKHNlbGYsIGlzb2xhdGlvbl9sZXZlbCk7CiAgICBQeV9ERUNSRUYoaXNvbGF0aW9uX2xldmVsKTsKCiAgICBzZWxmLT5zdGF0ZW1lbnRfY2FjaGUgPSAocHlzcWxpdGVfQ2FjaGUqKVB5T2JqZWN0X0NhbGxGdW5jdGlvbigoUHlPYmplY3QqKSZweXNxbGl0ZV9DYWNoZVR5cGUsICJPaSIsIHNlbGYsIGNhY2hlZF9zdGF0ZW1lbnRzKTsKICAgIGlmIChQeUVycl9PY2N1cnJlZCgpKSB7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIHNlbGYtPnN0YXRlbWVudHMgPSBQeUxpc3RfTmV3KDApOwogICAgaWYgKCFzZWxmLT5zdGF0ZW1lbnRzKSB7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQogICAgc2VsZi0+Y3JlYXRlZF9zdGF0ZW1lbnRzID0gMDsKCiAgICAvKiBCeSBkZWZhdWx0LCB0aGUgQ2FjaGUgY2xhc3MgSU5DUkVGcyB0aGUgZmFjdG9yeSBpbiBpdHMgaW5pdGlhbGl6ZXIsIGFuZAogICAgICogZGVjcmVmcyBpdCBpbiBpdHMgZGVhbGxvY2F0b3IgbWV0aG9kLiBTaW5jZSB0aGlzIHdvdWxkIGNyZWF0ZSBhIGNpcmN1bGFyCiAgICAgKiByZWZlcmVuY2UgaGVyZSwgd2UncmUgYnJlYWtpbmcgaXQgYnkgZGVjcmVtZW50aW5nIHNlbGYsIGFuZCB0ZWxsaW5nIHRoZQogICAgICogY2FjaGUgY2xhc3MgdG8gbm90IGRlY3JlZiB0aGUgZmFjdG9yeSAoc2VsZikgaW4gaXRzIGRlYWxsb2NhdG9yLgogICAgICovCiAgICBzZWxmLT5zdGF0ZW1lbnRfY2FjaGUtPmRlY3JlZl9mYWN0b3J5ID0gMDsKICAgIFB5X0RFQ1JFRihzZWxmKTsKCiAgICBzZWxmLT5pblRyYW5zYWN0aW9uID0gMDsKICAgIHNlbGYtPmRldGVjdF90eXBlcyA9IGRldGVjdF90eXBlczsKICAgIHNlbGYtPnRpbWVvdXQgPSB0aW1lb3V0OwogICAgKHZvaWQpc3FsaXRlM19idXN5X3RpbWVvdXQoc2VsZi0+ZGIsIChpbnQpKHRpbWVvdXQqMTAwMCkpOwoKICAgIHNlbGYtPnRocmVhZF9pZGVudCA9IFB5VGhyZWFkX2dldF90aHJlYWRfaWRlbnQoKTsKICAgIHNlbGYtPmNoZWNrX3NhbWVfdGhyZWFkID0gY2hlY2tfc2FtZV90aHJlYWQ7CgogICAgc2VsZi0+ZnVuY3Rpb25fcGluYm9hcmQgPSBQeURpY3RfTmV3KCk7CiAgICBpZiAoIXNlbGYtPmZ1bmN0aW9uX3BpbmJvYXJkKSB7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIHNlbGYtPmNvbGxhdGlvbnMgPSBQeURpY3RfTmV3KCk7CiAgICBpZiAoIXNlbGYtPmNvbGxhdGlvbnMpIHsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgc2VsZi0+V2FybmluZyAgICAgICAgICAgICAgID0gcHlzcWxpdGVfV2FybmluZzsKICAgIHNlbGYtPkVycm9yICAgICAgICAgICAgICAgICA9IHB5c3FsaXRlX0Vycm9yOwogICAgc2VsZi0+SW50ZXJmYWNlRXJyb3IgICAgICAgID0gcHlzcWxpdGVfSW50ZXJmYWNlRXJyb3I7CiAgICBzZWxmLT5EYXRhYmFzZUVycm9yICAgICAgICAgPSBweXNxbGl0ZV9EYXRhYmFzZUVycm9yOwogICAgc2VsZi0+RGF0YUVycm9yICAgICAgICAgICAgID0gcHlzcWxpdGVfRGF0YUVycm9yOwogICAgc2VsZi0+T3BlcmF0aW9uYWxFcnJvciAgICAgID0gcHlzcWxpdGVfT3BlcmF0aW9uYWxFcnJvcjsKICAgIHNlbGYtPkludGVncml0eUVycm9yICAgICAgICA9IHB5c3FsaXRlX0ludGVncml0eUVycm9yOwogICAgc2VsZi0+SW50ZXJuYWxFcnJvciAgICAgICAgID0gcHlzcWxpdGVfSW50ZXJuYWxFcnJvcjsKICAgIHNlbGYtPlByb2dyYW1taW5nRXJyb3IgICAgICA9IHB5c3FsaXRlX1Byb2dyYW1taW5nRXJyb3I7CiAgICBzZWxmLT5Ob3RTdXBwb3J0ZWRFcnJvciAgICAgPSBweXNxbGl0ZV9Ob3RTdXBwb3J0ZWRFcnJvcjsKCiAgICByZXR1cm4gMDsKfQoKLyogRW1wdHkgdGhlIGVudGlyZSBzdGF0ZW1lbnQgY2FjaGUgb2YgdGhpcyBjb25uZWN0aW9uICovCnZvaWQgcHlzcWxpdGVfZmx1c2hfc3RhdGVtZW50X2NhY2hlKHB5c3FsaXRlX0Nvbm5lY3Rpb24qIHNlbGYpCnsKICAgIHB5c3FsaXRlX05vZGUqIG5vZGU7CiAgICBweXNxbGl0ZV9TdGF0ZW1lbnQqIHN0YXRlbWVudDsKCiAgICBub2RlID0gc2VsZi0+c3RhdGVtZW50X2NhY2hlLT5maXJzdDsKCiAgICB3aGlsZSAobm9kZSkgewogICAgICAgIHN0YXRlbWVudCA9IChweXNxbGl0ZV9TdGF0ZW1lbnQqKShub2RlLT5kYXRhKTsKICAgICAgICAodm9pZClweXNxbGl0ZV9zdGF0ZW1lbnRfZmluYWxpemUoc3RhdGVtZW50KTsKICAgICAgICBub2RlID0gbm9kZS0+bmV4dDsKICAgIH0KCiAgICBQeV9ERUNSRUYoc2VsZi0+c3RhdGVtZW50X2NhY2hlKTsKICAgIHNlbGYtPnN0YXRlbWVudF9jYWNoZSA9IChweXNxbGl0ZV9DYWNoZSopUHlPYmplY3RfQ2FsbEZ1bmN0aW9uKChQeU9iamVjdCopJnB5c3FsaXRlX0NhY2hlVHlwZSwgIk8iLCBzZWxmKTsKICAgIFB5X0RFQ1JFRihzZWxmKTsKICAgIHNlbGYtPnN0YXRlbWVudF9jYWNoZS0+ZGVjcmVmX2ZhY3RvcnkgPSAwOwp9CgovKiBhY3Rpb24gaW4gKEFDVElPTl9SRVNFVCwgQUNUSU9OX0ZJTkFMSVpFKSAqLwp2b2lkIHB5c3FsaXRlX2RvX2FsbF9zdGF0ZW1lbnRzKHB5c3FsaXRlX0Nvbm5lY3Rpb24qIHNlbGYsIGludCBhY3Rpb24pCnsKICAgIGludCBpOwogICAgUHlPYmplY3QqIHdlYWtyZWY7CiAgICBQeU9iamVjdCogc3RhdGVtZW50OwoKICAgIGZvciAoaSA9IDA7IGkgPCBQeUxpc3RfU2l6ZShzZWxmLT5zdGF0ZW1lbnRzKTsgaSsrKSB7CiAgICAgICAgd2Vha3JlZiA9IFB5TGlzdF9HZXRJdGVtKHNlbGYtPnN0YXRlbWVudHMsIGkpOwogICAgICAgIHN0YXRlbWVudCA9IFB5V2Vha3JlZl9HZXRPYmplY3Qod2Vha3JlZik7CiAgICAgICAgaWYgKHN0YXRlbWVudCAhPSBQeV9Ob25lKSB7CiAgICAgICAgICAgIGlmIChhY3Rpb24gPT0gQUNUSU9OX1JFU0VUKSB7CiAgICAgICAgICAgICAgICAodm9pZClweXNxbGl0ZV9zdGF0ZW1lbnRfcmVzZXQoKHB5c3FsaXRlX1N0YXRlbWVudCopc3RhdGVtZW50KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICh2b2lkKXB5c3FsaXRlX3N0YXRlbWVudF9maW5hbGl6ZSgocHlzcWxpdGVfU3RhdGVtZW50KilzdGF0ZW1lbnQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9Cgp2b2lkIHB5c3FsaXRlX2Nvbm5lY3Rpb25fZGVhbGxvYyhweXNxbGl0ZV9Db25uZWN0aW9uKiBzZWxmKQp7CiAgICBQeV9YREVDUkVGKHNlbGYtPnN0YXRlbWVudF9jYWNoZSk7CgogICAgLyogQ2xlYW4gdXAgaWYgdXNlciBoYXMgbm90IGNhbGxlZCAuY2xvc2UoKSBleHBsaWNpdGx5LiAqLwogICAgaWYgKHNlbGYtPmRiKSB7CiAgICAgICAgUHlfQkVHSU5fQUxMT1dfVEhSRUFEUwogICAgICAgIHNxbGl0ZTNfY2xvc2Uoc2VsZi0+ZGIpOwogICAgICAgIFB5X0VORF9BTExPV19USFJFQURTCiAgICB9CgogICAgaWYgKHNlbGYtPmJlZ2luX3N0YXRlbWVudCkgewogICAgICAgIFB5TWVtX0ZyZWUoc2VsZi0+YmVnaW5fc3RhdGVtZW50KTsKICAgIH0KICAgIFB5X1hERUNSRUYoc2VsZi0+aXNvbGF0aW9uX2xldmVsKTsKICAgIFB5X1hERUNSRUYoc2VsZi0+ZnVuY3Rpb25fcGluYm9hcmQpOwogICAgUHlfWERFQ1JFRihzZWxmLT5yb3dfZmFjdG9yeSk7CiAgICBQeV9YREVDUkVGKHNlbGYtPnRleHRfZmFjdG9yeSk7CiAgICBQeV9YREVDUkVGKHNlbGYtPmNvbGxhdGlvbnMpOwogICAgUHlfWERFQ1JFRihzZWxmLT5zdGF0ZW1lbnRzKTsKCiAgICBQeV9UWVBFKHNlbGYpLT50cF9mcmVlKChQeU9iamVjdCopc2VsZik7Cn0KClB5T2JqZWN0KiBweXNxbGl0ZV9jb25uZWN0aW9uX2N1cnNvcihweXNxbGl0ZV9Db25uZWN0aW9uKiBzZWxmLCBQeU9iamVjdCogYXJncywgUHlPYmplY3QqIGt3YXJncykKewogICAgc3RhdGljIGNoYXIgKmt3bGlzdFtdID0geyJmYWN0b3J5IiwgTlVMTCwgTlVMTH07CiAgICBQeU9iamVjdCogZmFjdG9yeSA9IE5VTEw7CiAgICBQeU9iamVjdCogY3Vyc29yOwoKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGVBbmRLZXl3b3JkcyhhcmdzLCBrd2FyZ3MsICJ8TyIsIGt3bGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZmYWN0b3J5KSkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIGlmICghcHlzcWxpdGVfY2hlY2tfdGhyZWFkKHNlbGYpIHx8ICFweXNxbGl0ZV9jaGVja19jb25uZWN0aW9uKHNlbGYpKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgaWYgKGZhY3RvcnkgPT0gTlVMTCkgewogICAgICAgIGZhY3RvcnkgPSAoUHlPYmplY3QqKSZweXNxbGl0ZV9DdXJzb3JUeXBlOwogICAgfQoKICAgIGN1cnNvciA9IFB5T2JqZWN0X0NhbGxGdW5jdGlvbihmYWN0b3J5LCAiTyIsIHNlbGYpOwoKICAgIGlmIChjdXJzb3IgJiYgc2VsZi0+cm93X2ZhY3RvcnkgIT0gUHlfTm9uZSkgewogICAgICAgIFB5X1hERUNSRUYoKChweXNxbGl0ZV9DdXJzb3IqKWN1cnNvciktPnJvd19mYWN0b3J5KTsKICAgICAgICBQeV9JTkNSRUYoc2VsZi0+cm93X2ZhY3RvcnkpOwogICAgICAgICgocHlzcWxpdGVfQ3Vyc29yKiljdXJzb3IpLT5yb3dfZmFjdG9yeSA9IHNlbGYtPnJvd19mYWN0b3J5OwogICAgfQoKICAgIHJldHVybiBjdXJzb3I7Cn0KClB5T2JqZWN0KiBweXNxbGl0ZV9jb25uZWN0aW9uX2Nsb3NlKHB5c3FsaXRlX0Nvbm5lY3Rpb24qIHNlbGYsIFB5T2JqZWN0KiBhcmdzKQp7CiAgICBpbnQgcmM7CgogICAgaWYgKCFweXNxbGl0ZV9jaGVja190aHJlYWQoc2VsZikpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBweXNxbGl0ZV9kb19hbGxfc3RhdGVtZW50cyhzZWxmLCBBQ1RJT05fRklOQUxJWkUpOwoKICAgIGlmIChzZWxmLT5kYikgewogICAgICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKICAgICAgICByYyA9IHNxbGl0ZTNfY2xvc2Uoc2VsZi0+ZGIpOwogICAgICAgIFB5X0VORF9BTExPV19USFJFQURTCgogICAgICAgIGlmIChyYyAhPSBTUUxJVEVfT0spIHsKICAgICAgICAgICAgX3B5c3FsaXRlX3NldGVycm9yKHNlbGYtPmRiLCBOVUxMKTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc2VsZi0+ZGIgPSBOVUxMOwogICAgICAgIH0KICAgIH0KCiAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICByZXR1cm4gUHlfTm9uZTsKfQoKLyoKICogQ2hlY2tzIGlmIGEgY29ubmVjdGlvbiBvYmplY3QgaXMgdXNhYmxlIChpLiBlLiBub3QgY2xvc2VkKS4KICoKICogMCA9PiBlcnJvcjsgMSA9PiBvawogKi8KaW50IHB5c3FsaXRlX2NoZWNrX2Nvbm5lY3Rpb24ocHlzcWxpdGVfQ29ubmVjdGlvbiogY29uKQp7CiAgICBpZiAoIWNvbi0+ZGIpIHsKICAgICAgICBQeUVycl9TZXRTdHJpbmcocHlzcWxpdGVfUHJvZ3JhbW1pbmdFcnJvciwgIkNhbm5vdCBvcGVyYXRlIG9uIGEgY2xvc2VkIGRhdGFiYXNlLiIpOwogICAgICAgIHJldHVybiAwOwogICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gMTsKICAgIH0KfQoKUHlPYmplY3QqIF9weXNxbGl0ZV9jb25uZWN0aW9uX2JlZ2luKHB5c3FsaXRlX0Nvbm5lY3Rpb24qIHNlbGYpCnsKICAgIGludCByYzsKICAgIGNvbnN0IGNoYXIqIHRhaWw7CiAgICBzcWxpdGUzX3N0bXQqIHN0YXRlbWVudDsKCiAgICBQeV9CRUdJTl9BTExPV19USFJFQURTCiAgICByYyA9IHNxbGl0ZTNfcHJlcGFyZShzZWxmLT5kYiwgc2VsZi0+YmVnaW5fc3RhdGVtZW50LCAtMSwgJnN0YXRlbWVudCwgJnRhaWwpOwogICAgUHlfRU5EX0FMTE9XX1RIUkVBRFMKCiAgICBpZiAocmMgIT0gU1FMSVRFX09LKSB7CiAgICAgICAgX3B5c3FsaXRlX3NldGVycm9yKHNlbGYtPmRiLCBzdGF0ZW1lbnQpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgcmMgPSBfc3FsaXRlX3N0ZXBfd2l0aF9idXN5aGFuZGxlcihzdGF0ZW1lbnQsIHNlbGYpOwogICAgaWYgKHJjID09IFNRTElURV9ET05FKSB7CiAgICAgICAgc2VsZi0+aW5UcmFuc2FjdGlvbiA9IDE7CiAgICB9IGVsc2UgewogICAgICAgIF9weXNxbGl0ZV9zZXRlcnJvcihzZWxmLT5kYiwgc3RhdGVtZW50KTsKICAgIH0KCiAgICBQeV9CRUdJTl9BTExPV19USFJFQURTCiAgICByYyA9IHNxbGl0ZTNfZmluYWxpemUoc3RhdGVtZW50KTsKICAgIFB5X0VORF9BTExPV19USFJFQURTCgogICAgaWYgKHJjICE9IFNRTElURV9PSyAmJiAhUHlFcnJfT2NjdXJyZWQoKSkgewogICAgICAgIF9weXNxbGl0ZV9zZXRlcnJvcihzZWxmLT5kYiwgTlVMTCk7CiAgICB9CgplcnJvcjoKICAgIGlmIChQeUVycl9PY2N1cnJlZCgpKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9IGVsc2UgewogICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgICAgICByZXR1cm4gUHlfTm9uZTsKICAgIH0KfQoKUHlPYmplY3QqIHB5c3FsaXRlX2Nvbm5lY3Rpb25fY29tbWl0KHB5c3FsaXRlX0Nvbm5lY3Rpb24qIHNlbGYsIFB5T2JqZWN0KiBhcmdzKQp7CiAgICBpbnQgcmM7CiAgICBjb25zdCBjaGFyKiB0YWlsOwogICAgc3FsaXRlM19zdG10KiBzdGF0ZW1lbnQ7CgogICAgaWYgKCFweXNxbGl0ZV9jaGVja190aHJlYWQoc2VsZikgfHwgIXB5c3FsaXRlX2NoZWNrX2Nvbm5lY3Rpb24oc2VsZikpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBpZiAoc2VsZi0+aW5UcmFuc2FjdGlvbikgewogICAgICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKICAgICAgICByYyA9IHNxbGl0ZTNfcHJlcGFyZShzZWxmLT5kYiwgIkNPTU1JVCIsIC0xLCAmc3RhdGVtZW50LCAmdGFpbCk7CiAgICAgICAgUHlfRU5EX0FMTE9XX1RIUkVBRFMKICAgICAgICBpZiAocmMgIT0gU1FMSVRFX09LKSB7CiAgICAgICAgICAgIF9weXNxbGl0ZV9zZXRlcnJvcihzZWxmLT5kYiwgTlVMTCk7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQoKICAgICAgICByYyA9IF9zcWxpdGVfc3RlcF93aXRoX2J1c3loYW5kbGVyKHN0YXRlbWVudCwgc2VsZik7CiAgICAgICAgaWYgKHJjID09IFNRTElURV9ET05FKSB7CiAgICAgICAgICAgIHNlbGYtPmluVHJhbnNhY3Rpb24gPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIF9weXNxbGl0ZV9zZXRlcnJvcihzZWxmLT5kYiwgc3RhdGVtZW50KTsKICAgICAgICB9CgogICAgICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKICAgICAgICByYyA9IHNxbGl0ZTNfZmluYWxpemUoc3RhdGVtZW50KTsKICAgICAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUwogICAgICAgIGlmIChyYyAhPSBTUUxJVEVfT0sgJiYgIVB5RXJyX09jY3VycmVkKCkpIHsKICAgICAgICAgICAgX3B5c3FsaXRlX3NldGVycm9yKHNlbGYtPmRiLCBOVUxMKTsKICAgICAgICB9CgogICAgfQoKZXJyb3I6CiAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfSBlbHNlIHsKICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICAgICAgcmV0dXJuIFB5X05vbmU7CiAgICB9Cn0KClB5T2JqZWN0KiBweXNxbGl0ZV9jb25uZWN0aW9uX3JvbGxiYWNrKHB5c3FsaXRlX0Nvbm5lY3Rpb24qIHNlbGYsIFB5T2JqZWN0KiBhcmdzKQp7CiAgICBpbnQgcmM7CiAgICBjb25zdCBjaGFyKiB0YWlsOwogICAgc3FsaXRlM19zdG10KiBzdGF0ZW1lbnQ7CgogICAgaWYgKCFweXNxbGl0ZV9jaGVja190aHJlYWQoc2VsZikgfHwgIXB5c3FsaXRlX2NoZWNrX2Nvbm5lY3Rpb24oc2VsZikpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBpZiAoc2VsZi0+aW5UcmFuc2FjdGlvbikgewogICAgICAgIHB5c3FsaXRlX2RvX2FsbF9zdGF0ZW1lbnRzKHNlbGYsIEFDVElPTl9SRVNFVCk7CgogICAgICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKICAgICAgICByYyA9IHNxbGl0ZTNfcHJlcGFyZShzZWxmLT5kYiwgIlJPTExCQUNLIiwgLTEsICZzdGF0ZW1lbnQsICZ0YWlsKTsKICAgICAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUwogICAgICAgIGlmIChyYyAhPSBTUUxJVEVfT0spIHsKICAgICAgICAgICAgX3B5c3FsaXRlX3NldGVycm9yKHNlbGYtPmRiLCBOVUxMKTsKICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CgogICAgICAgIHJjID0gX3NxbGl0ZV9zdGVwX3dpdGhfYnVzeWhhbmRsZXIoc3RhdGVtZW50LCBzZWxmKTsKICAgICAgICBpZiAocmMgPT0gU1FMSVRFX0RPTkUpIHsKICAgICAgICAgICAgc2VsZi0+aW5UcmFuc2FjdGlvbiA9IDA7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgX3B5c3FsaXRlX3NldGVycm9yKHNlbGYtPmRiLCBzdGF0ZW1lbnQpOwogICAgICAgIH0KCiAgICAgICAgUHlfQkVHSU5fQUxMT1dfVEhSRUFEUwogICAgICAgIHJjID0gc3FsaXRlM19maW5hbGl6ZShzdGF0ZW1lbnQpOwogICAgICAgIFB5X0VORF9BTExPV19USFJFQURTCiAgICAgICAgaWYgKHJjICE9IFNRTElURV9PSyAmJiAhUHlFcnJfT2NjdXJyZWQoKSkgewogICAgICAgICAgICBfcHlzcWxpdGVfc2V0ZXJyb3Ioc2VsZi0+ZGIsIE5VTEwpOwogICAgICAgIH0KCiAgICB9CgplcnJvcjoKICAgIGlmIChQeUVycl9PY2N1cnJlZCgpKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9IGVsc2UgewogICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgICAgICByZXR1cm4gUHlfTm9uZTsKICAgIH0KfQoKdm9pZCBfcHlzcWxpdGVfc2V0X3Jlc3VsdChzcWxpdGUzX2NvbnRleHQqIGNvbnRleHQsIFB5T2JqZWN0KiBweV92YWwpCnsKICAgIGxvbmcgbG9uZ3ZhbDsKICAgIGNvbnN0IGNoYXIqIGJ1ZmZlcjsKICAgIFB5X3NzaXplX3QgYnVmbGVuOwoKICAgIGlmICgoIXB5X3ZhbCkgfHwgUHlFcnJfT2NjdXJyZWQoKSkgewogICAgICAgIHNxbGl0ZTNfcmVzdWx0X251bGwoY29udGV4dCk7CiAgICB9IGVsc2UgaWYgKHB5X3ZhbCA9PSBQeV9Ob25lKSB7CiAgICAgICAgc3FsaXRlM19yZXN1bHRfbnVsbChjb250ZXh0KTsKICAgIH0gZWxzZSBpZiAoUHlMb25nX0NoZWNrKHB5X3ZhbCkpIHsKICAgICAgICBsb25ndmFsID0gUHlMb25nX0FzTG9uZyhweV92YWwpOwogICAgICAgIHNxbGl0ZTNfcmVzdWx0X2ludDY0KGNvbnRleHQsIChQWV9MT05HX0xPTkcpbG9uZ3ZhbCk7CiAgICB9IGVsc2UgaWYgKFB5RmxvYXRfQ2hlY2socHlfdmFsKSkgewogICAgICAgIHNxbGl0ZTNfcmVzdWx0X2RvdWJsZShjb250ZXh0LCBQeUZsb2F0X0FzRG91YmxlKHB5X3ZhbCkpOwogICAgfSBlbHNlIGlmIChQeVVuaWNvZGVfQ2hlY2socHlfdmFsKSkgewogICAgICAgIHNxbGl0ZTNfcmVzdWx0X3RleHQoY29udGV4dCwgUHlVbmljb2RlX0FzU3RyaW5nKHB5X3ZhbCksIC0xLCBTUUxJVEVfVFJBTlNJRU5UKTsKICAgIH0gZWxzZSBpZiAoUHlPYmplY3RfQ2hlY2tCdWZmZXIocHlfdmFsKSkgewogICAgICAgIGlmIChQeU9iamVjdF9Bc0NoYXJCdWZmZXIocHlfdmFsLCAmYnVmZmVyLCAmYnVmbGVuKSAhPSAwKSB7CiAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAiY291bGQgbm90IGNvbnZlcnQgQkxPQiB0byBidWZmZXIiKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzcWxpdGUzX3Jlc3VsdF9ibG9iKGNvbnRleHQsIGJ1ZmZlciwgYnVmbGVuLCBTUUxJVEVfVFJBTlNJRU5UKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIC8qIFRPRE86IHJhaXNlIGVycm9yICovCiAgICB9Cn0KClB5T2JqZWN0KiBfcHlzcWxpdGVfYnVpbGRfcHlfcGFyYW1zKHNxbGl0ZTNfY29udGV4dCAqY29udGV4dCwgaW50IGFyZ2MsIHNxbGl0ZTNfdmFsdWUqKiBhcmd2KQp7CiAgICBQeU9iamVjdCogYXJnczsKICAgIGludCBpOwogICAgc3FsaXRlM192YWx1ZSogY3VyX3ZhbHVlOwogICAgUHlPYmplY3QqIGN1cl9weV92YWx1ZTsKICAgIGNvbnN0IGNoYXIqIHZhbF9zdHI7CiAgICBQWV9MT05HX0xPTkcgdmFsX2ludDsKICAgIFB5X3NzaXplX3QgYnVmbGVuOwoKICAgIGFyZ3MgPSBQeVR1cGxlX05ldyhhcmdjKTsKICAgIGlmICghYXJncykgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIGZvciAoaSA9IDA7IGkgPCBhcmdjOyBpKyspIHsKICAgICAgICBjdXJfdmFsdWUgPSBhcmd2W2ldOwogICAgICAgIHN3aXRjaCAoc3FsaXRlM192YWx1ZV90eXBlKGFyZ3ZbaV0pKSB7CiAgICAgICAgICAgIGNhc2UgU1FMSVRFX0lOVEVHRVI6CiAgICAgICAgICAgICAgICB2YWxfaW50ID0gc3FsaXRlM192YWx1ZV9pbnQ2NChjdXJfdmFsdWUpOwogICAgICAgICAgICAgICAgY3VyX3B5X3ZhbHVlID0gUHlMb25nX0Zyb21Mb25nKChsb25nKXZhbF9pbnQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU1FMSVRFX0ZMT0FUOgogICAgICAgICAgICAgICAgY3VyX3B5X3ZhbHVlID0gUHlGbG9hdF9Gcm9tRG91YmxlKHNxbGl0ZTNfdmFsdWVfZG91YmxlKGN1cl92YWx1ZSkpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU1FMSVRFX1RFWFQ6CiAgICAgICAgICAgICAgICB2YWxfc3RyID0gKGNvbnN0IGNoYXIqKXNxbGl0ZTNfdmFsdWVfdGV4dChjdXJfdmFsdWUpOwogICAgICAgICAgICAgICAgY3VyX3B5X3ZhbHVlID0gUHlVbmljb2RlX0Zyb21TdHJpbmcodmFsX3N0cik7CiAgICAgICAgICAgICAgICAvKiBUT0RPOiBoYXZlIGEgd2F5IHRvIHNob3cgZXJyb3JzIGhlcmUgKi8KICAgICAgICAgICAgICAgIGlmICghY3VyX3B5X3ZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKICAgICAgICAgICAgICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICAgICAgICAgICAgICAgICAgY3VyX3B5X3ZhbHVlID0gUHlfTm9uZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFNRTElURV9CTE9COgogICAgICAgICAgICAgICAgYnVmbGVuID0gc3FsaXRlM192YWx1ZV9ieXRlcyhjdXJfdmFsdWUpOwogICAgICAgICAgICAgICAgY3VyX3B5X3ZhbHVlID0gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUoCiAgICAgICAgICAgICAgICAgICAgc3FsaXRlM192YWx1ZV9ibG9iKGN1cl92YWx1ZSksIGJ1Zmxlbik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBTUUxJVEVfTlVMTDoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgICAgICAgICAgICAgIGN1cl9weV92YWx1ZSA9IFB5X05vbmU7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWN1cl9weV92YWx1ZSkgewogICAgICAgICAgICBQeV9ERUNSRUYoYXJncyk7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KCiAgICAgICAgUHlUdXBsZV9TZXRJdGVtKGFyZ3MsIGksIGN1cl9weV92YWx1ZSk7CgogICAgfQoKICAgIHJldHVybiBhcmdzOwp9Cgp2b2lkIF9weXNxbGl0ZV9mdW5jX2NhbGxiYWNrKHNxbGl0ZTNfY29udGV4dCogY29udGV4dCwgaW50IGFyZ2MsIHNxbGl0ZTNfdmFsdWUqKiBhcmd2KQp7CiAgICBQeU9iamVjdCogYXJnczsKICAgIFB5T2JqZWN0KiBweV9mdW5jOwogICAgUHlPYmplY3QqIHB5X3JldHZhbCA9IE5VTEw7CgogICAgUHlHSUxTdGF0ZV9TVEFURSB0aHJlYWRzdGF0ZTsKCiAgICB0aHJlYWRzdGF0ZSA9IFB5R0lMU3RhdGVfRW5zdXJlKCk7CgogICAgcHlfZnVuYyA9IChQeU9iamVjdCopc3FsaXRlM191c2VyX2RhdGEoY29udGV4dCk7CgogICAgYXJncyA9IF9weXNxbGl0ZV9idWlsZF9weV9wYXJhbXMoY29udGV4dCwgYXJnYywgYXJndik7CiAgICBpZiAoYXJncykgewogICAgICAgIHB5X3JldHZhbCA9IFB5T2JqZWN0X0NhbGxPYmplY3QocHlfZnVuYywgYXJncyk7CiAgICAgICAgUHlfREVDUkVGKGFyZ3MpOwogICAgfQoKICAgIGlmIChweV9yZXR2YWwpIHsKICAgICAgICBfcHlzcWxpdGVfc2V0X3Jlc3VsdChjb250ZXh0LCBweV9yZXR2YWwpOwogICAgICAgIFB5X0RFQ1JFRihweV9yZXR2YWwpOwogICAgfSBlbHNlIHsKICAgICAgICBpZiAoX2VuYWJsZV9jYWxsYmFja190cmFjZWJhY2tzKSB7CiAgICAgICAgICAgIFB5RXJyX1ByaW50KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgX3NxbGl0ZTNfcmVzdWx0X2Vycm9yKGNvbnRleHQsICJ1c2VyLWRlZmluZWQgZnVuY3Rpb24gcmFpc2VkIGV4Y2VwdGlvbiIsIC0xKTsKICAgIH0KCiAgICBQeUdJTFN0YXRlX1JlbGVhc2UodGhyZWFkc3RhdGUpOwp9CgpzdGF0aWMgdm9pZCBfcHlzcWxpdGVfc3RlcF9jYWxsYmFjayhzcWxpdGUzX2NvbnRleHQgKmNvbnRleHQsIGludCBhcmdjLCBzcWxpdGUzX3ZhbHVlKiogcGFyYW1zKQp7CiAgICBQeU9iamVjdCogYXJnczsKICAgIFB5T2JqZWN0KiBmdW5jdGlvbl9yZXN1bHQgPSBOVUxMOwogICAgUHlPYmplY3QqIGFnZ3JlZ2F0ZV9jbGFzczsKICAgIFB5T2JqZWN0KiogYWdncmVnYXRlX2luc3RhbmNlOwogICAgUHlPYmplY3QqIHN0ZXBtZXRob2QgPSBOVUxMOwoKICAgIFB5R0lMU3RhdGVfU1RBVEUgdGhyZWFkc3RhdGU7CgogICAgdGhyZWFkc3RhdGUgPSBQeUdJTFN0YXRlX0Vuc3VyZSgpOwoKICAgIGFnZ3JlZ2F0ZV9jbGFzcyA9IChQeU9iamVjdCopc3FsaXRlM191c2VyX2RhdGEoY29udGV4dCk7CgogICAgYWdncmVnYXRlX2luc3RhbmNlID0gKFB5T2JqZWN0Kiopc3FsaXRlM19hZ2dyZWdhdGVfY29udGV4dChjb250ZXh0LCBzaXplb2YoUHlPYmplY3QqKSk7CgogICAgaWYgKCphZ2dyZWdhdGVfaW5zdGFuY2UgPT0gMCkgewogICAgICAgICphZ2dyZWdhdGVfaW5zdGFuY2UgPSBQeU9iamVjdF9DYWxsRnVuY3Rpb24oYWdncmVnYXRlX2NsYXNzLCAiIik7CgogICAgICAgIGlmIChQeUVycl9PY2N1cnJlZCgpKSB7CiAgICAgICAgICAgICphZ2dyZWdhdGVfaW5zdGFuY2UgPSAwOwogICAgICAgICAgICBpZiAoX2VuYWJsZV9jYWxsYmFja190cmFjZWJhY2tzKSB7CiAgICAgICAgICAgICAgICBQeUVycl9QcmludCgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBfc3FsaXRlM19yZXN1bHRfZXJyb3IoY29udGV4dCwgInVzZXItZGVmaW5lZCBhZ2dyZWdhdGUncyAnX19pbml0X18nIG1ldGhvZCByYWlzZWQgZXJyb3IiLCAtMSk7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgfQoKICAgIHN0ZXBtZXRob2QgPSBQeU9iamVjdF9HZXRBdHRyU3RyaW5nKCphZ2dyZWdhdGVfaW5zdGFuY2UsICJzdGVwIik7CiAgICBpZiAoIXN0ZXBtZXRob2QpIHsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIGFyZ3MgPSBfcHlzcWxpdGVfYnVpbGRfcHlfcGFyYW1zKGNvbnRleHQsIGFyZ2MsIHBhcmFtcyk7CiAgICBpZiAoIWFyZ3MpIHsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIGZ1bmN0aW9uX3Jlc3VsdCA9IFB5T2JqZWN0X0NhbGxPYmplY3Qoc3RlcG1ldGhvZCwgYXJncyk7CiAgICBQeV9ERUNSRUYoYXJncyk7CgogICAgaWYgKCFmdW5jdGlvbl9yZXN1bHQpIHsKICAgICAgICBpZiAoX2VuYWJsZV9jYWxsYmFja190cmFjZWJhY2tzKSB7CiAgICAgICAgICAgIFB5RXJyX1ByaW50KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgX3NxbGl0ZTNfcmVzdWx0X2Vycm9yKGNvbnRleHQsICJ1c2VyLWRlZmluZWQgYWdncmVnYXRlJ3MgJ3N0ZXAnIG1ldGhvZCByYWlzZWQgZXJyb3IiLCAtMSk7CiAgICB9CgplcnJvcjoKICAgIFB5X1hERUNSRUYoc3RlcG1ldGhvZCk7CiAgICBQeV9YREVDUkVGKGZ1bmN0aW9uX3Jlc3VsdCk7CgogICAgUHlHSUxTdGF0ZV9SZWxlYXNlKHRocmVhZHN0YXRlKTsKfQoKdm9pZCBfcHlzcWxpdGVfZmluYWxfY2FsbGJhY2soc3FsaXRlM19jb250ZXh0KiBjb250ZXh0KQp7CiAgICBQeU9iamVjdCogZnVuY3Rpb25fcmVzdWx0ID0gTlVMTDsKICAgIFB5T2JqZWN0KiogYWdncmVnYXRlX2luc3RhbmNlOwogICAgUHlPYmplY3QqIGFnZ3JlZ2F0ZV9jbGFzczsKCiAgICBQeUdJTFN0YXRlX1NUQVRFIHRocmVhZHN0YXRlOwoKICAgIHRocmVhZHN0YXRlID0gUHlHSUxTdGF0ZV9FbnN1cmUoKTsKCiAgICBhZ2dyZWdhdGVfY2xhc3MgPSAoUHlPYmplY3QqKXNxbGl0ZTNfdXNlcl9kYXRhKGNvbnRleHQpOwoKICAgIGFnZ3JlZ2F0ZV9pbnN0YW5jZSA9IChQeU9iamVjdCoqKXNxbGl0ZTNfYWdncmVnYXRlX2NvbnRleHQoY29udGV4dCwgc2l6ZW9mKFB5T2JqZWN0KikpOwogICAgaWYgKCEqYWdncmVnYXRlX2luc3RhbmNlKSB7CiAgICAgICAgLyogdGhpcyBicmFuY2ggaXMgZXhlY3V0ZWQgaWYgdGhlcmUgd2FzIGFuIGV4Y2VwdGlvbiBpbiB0aGUgYWdncmVnYXRlJ3MKICAgICAgICAgKiBfX2luaXRfXyAqLwoKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIGZ1bmN0aW9uX3Jlc3VsdCA9IFB5T2JqZWN0X0NhbGxNZXRob2QoKmFnZ3JlZ2F0ZV9pbnN0YW5jZSwgImZpbmFsaXplIiwgIiIpOwogICAgaWYgKCFmdW5jdGlvbl9yZXN1bHQpIHsKICAgICAgICBpZiAoX2VuYWJsZV9jYWxsYmFja190cmFjZWJhY2tzKSB7CiAgICAgICAgICAgIFB5RXJyX1ByaW50KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgX3NxbGl0ZTNfcmVzdWx0X2Vycm9yKGNvbnRleHQsICJ1c2VyLWRlZmluZWQgYWdncmVnYXRlJ3MgJ2ZpbmFsaXplJyBtZXRob2QgcmFpc2VkIGVycm9yIiwgLTEpOwogICAgfSBlbHNlIHsKICAgICAgICBfcHlzcWxpdGVfc2V0X3Jlc3VsdChjb250ZXh0LCBmdW5jdGlvbl9yZXN1bHQpOwogICAgfQoKZXJyb3I6CiAgICBQeV9YREVDUkVGKCphZ2dyZWdhdGVfaW5zdGFuY2UpOwogICAgUHlfWERFQ1JFRihmdW5jdGlvbl9yZXN1bHQpOwoKICAgIFB5R0lMU3RhdGVfUmVsZWFzZSh0aHJlYWRzdGF0ZSk7Cn0KCnZvaWQgX3B5c3FsaXRlX2Ryb3BfdW51c2VkX3N0YXRlbWVudF9yZWZlcmVuY2VzKHB5c3FsaXRlX0Nvbm5lY3Rpb24qIHNlbGYpCnsKICAgIFB5T2JqZWN0KiBuZXdfbGlzdDsKICAgIFB5T2JqZWN0KiB3ZWFrcmVmOwogICAgaW50IGk7CgogICAgLyogd2Ugb25seSBuZWVkIHRvIGRvIHRoaXMgb25jZSBpbiBhIHdoaWxlICovCiAgICBpZiAoc2VsZi0+Y3JlYXRlZF9zdGF0ZW1lbnRzKysgPCAyMDApIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgc2VsZi0+Y3JlYXRlZF9zdGF0ZW1lbnRzID0gMDsKCiAgICBuZXdfbGlzdCA9IFB5TGlzdF9OZXcoMCk7CiAgICBpZiAoIW5ld19saXN0KSB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGZvciAoaSA9IDA7IGkgPCBQeUxpc3RfU2l6ZShzZWxmLT5zdGF0ZW1lbnRzKTsgaSsrKSB7CiAgICAgICAgd2Vha3JlZiA9IFB5TGlzdF9HZXRJdGVtKHNlbGYtPnN0YXRlbWVudHMsIGkpOwogICAgICAgIGlmIChQeVdlYWtyZWZfR2V0T2JqZWN0KHdlYWtyZWYpICE9IFB5X05vbmUpIHsKICAgICAgICAgICAgaWYgKFB5TGlzdF9BcHBlbmQobmV3X2xpc3QsIHdlYWtyZWYpICE9IDApIHsKICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihuZXdfbGlzdCk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgUHlfREVDUkVGKHNlbGYtPnN0YXRlbWVudHMpOwogICAgc2VsZi0+c3RhdGVtZW50cyA9IG5ld19saXN0Owp9CgpQeU9iamVjdCogcHlzcWxpdGVfY29ubmVjdGlvbl9jcmVhdGVfZnVuY3Rpb24ocHlzcWxpdGVfQ29ubmVjdGlvbiogc2VsZiwgUHlPYmplY3QqIGFyZ3MsIFB5T2JqZWN0KiBrd2FyZ3MpCnsKICAgIHN0YXRpYyBjaGFyICprd2xpc3RbXSA9IHsibmFtZSIsICJuYXJnIiwgImZ1bmMiLCBOVUxMLCBOVUxMfTsKCiAgICBQeU9iamVjdCogZnVuYzsKICAgIGNoYXIqIG5hbWU7CiAgICBpbnQgbmFyZzsKICAgIGludCByYzsKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGVBbmRLZXl3b3JkcyhhcmdzLCBrd2FyZ3MsICJzaU8iLCBrd2xpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbmFtZSwgJm5hcmcsICZmdW5jKSkKICAgIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByYyA9IHNxbGl0ZTNfY3JlYXRlX2Z1bmN0aW9uKHNlbGYtPmRiLCBuYW1lLCBuYXJnLCBTUUxJVEVfVVRGOCwgKHZvaWQqKWZ1bmMsIF9weXNxbGl0ZV9mdW5jX2NhbGxiYWNrLCBOVUxMLCBOVUxMKTsKCiAgICBpZiAocmMgIT0gU1FMSVRFX09LKSB7CiAgICAgICAgLyogV29ya2Fyb3VuZCBmb3IgU1FMaXRlIGJ1Zzogbm8gZXJyb3IgY29kZSBvciBzdHJpbmcgaXMgYXZhaWxhYmxlIGhlcmUgKi8KICAgICAgICBQeUVycl9TZXRTdHJpbmcocHlzcWxpdGVfT3BlcmF0aW9uYWxFcnJvciwgIkVycm9yIGNyZWF0aW5nIGZ1bmN0aW9uIik7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9IGVsc2UgewogICAgICAgIFB5RGljdF9TZXRJdGVtKHNlbGYtPmZ1bmN0aW9uX3BpbmJvYXJkLCBmdW5jLCBQeV9Ob25lKTsKCiAgICAgICAgUHlfSU5DUkVGKFB5X05vbmUpOwogICAgICAgIHJldHVybiBQeV9Ob25lOwogICAgfQp9CgpQeU9iamVjdCogcHlzcWxpdGVfY29ubmVjdGlvbl9jcmVhdGVfYWdncmVnYXRlKHB5c3FsaXRlX0Nvbm5lY3Rpb24qIHNlbGYsIFB5T2JqZWN0KiBhcmdzLCBQeU9iamVjdCoga3dhcmdzKQp7CiAgICBQeU9iamVjdCogYWdncmVnYXRlX2NsYXNzOwoKICAgIGludCBuX2FyZzsKICAgIGNoYXIqIG5hbWU7CiAgICBzdGF0aWMgY2hhciAqa3dsaXN0W10gPSB7ICJuYW1lIiwgIm5fYXJnIiwgImFnZ3JlZ2F0ZV9jbGFzcyIsIE5VTEwgfTsKICAgIGludCByYzsKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGVBbmRLZXl3b3JkcyhhcmdzLCBrd2FyZ3MsICJzaU86Y3JlYXRlX2FnZ3JlZ2F0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga3dsaXN0LCAmbmFtZSwgJm5fYXJnLCAmYWdncmVnYXRlX2NsYXNzKSkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIHJjID0gc3FsaXRlM19jcmVhdGVfZnVuY3Rpb24oc2VsZi0+ZGIsIG5hbWUsIG5fYXJnLCBTUUxJVEVfVVRGOCwgKHZvaWQqKWFnZ3JlZ2F0ZV9jbGFzcywgMCwgJl9weXNxbGl0ZV9zdGVwX2NhbGxiYWNrLCAmX3B5c3FsaXRlX2ZpbmFsX2NhbGxiYWNrKTsKICAgIGlmIChyYyAhPSBTUUxJVEVfT0spIHsKICAgICAgICAvKiBXb3JrYXJvdW5kIGZvciBTUUxpdGUgYnVnOiBubyBlcnJvciBjb2RlIG9yIHN0cmluZyBpcyBhdmFpbGFibGUgaGVyZSAqLwogICAgICAgIFB5RXJyX1NldFN0cmluZyhweXNxbGl0ZV9PcGVyYXRpb25hbEVycm9yLCAiRXJyb3IgY3JlYXRpbmcgYWdncmVnYXRlIik7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9IGVsc2UgewogICAgICAgIFB5RGljdF9TZXRJdGVtKHNlbGYtPmZ1bmN0aW9uX3BpbmJvYXJkLCBhZ2dyZWdhdGVfY2xhc3MsIFB5X05vbmUpOwoKICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICAgICAgcmV0dXJuIFB5X05vbmU7CiAgICB9Cn0KCnN0YXRpYyBpbnQgX2F1dGhvcml6ZXJfY2FsbGJhY2sodm9pZCogdXNlcl9hcmcsIGludCBhY3Rpb24sIGNvbnN0IGNoYXIqIGFyZzEsIGNvbnN0IGNoYXIqIGFyZzIgLCBjb25zdCBjaGFyKiBkYm5hbWUsIGNvbnN0IGNoYXIqIGFjY2Vzc19hdHRlbXB0X3NvdXJjZSkKewogICAgUHlPYmplY3QgKnJldDsKICAgIGludCByYzsKICAgIFB5R0lMU3RhdGVfU1RBVEUgZ2lsc3RhdGU7CgogICAgZ2lsc3RhdGUgPSBQeUdJTFN0YXRlX0Vuc3VyZSgpOwogICAgcmV0ID0gUHlPYmplY3RfQ2FsbEZ1bmN0aW9uKChQeU9iamVjdCopdXNlcl9hcmcsICJpc3NzcyIsIGFjdGlvbiwgYXJnMSwgYXJnMiwgZGJuYW1lLCBhY2Nlc3NfYXR0ZW1wdF9zb3VyY2UpOwoKICAgIGlmICghcmV0KSB7CiAgICAgICAgaWYgKF9lbmFibGVfY2FsbGJhY2tfdHJhY2ViYWNrcykgewogICAgICAgICAgICBQeUVycl9QcmludCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFB5RXJyX0NsZWFyKCk7CiAgICAgICAgfQoKICAgICAgICByYyA9IFNRTElURV9ERU5ZOwogICAgfSBlbHNlIHsKICAgICAgICBpZiAoUHlMb25nX0NoZWNrKHJldCkpIHsKICAgICAgICAgICAgcmMgPSAoaW50KVB5TG9uZ19Bc0xvbmcocmV0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByYyA9IFNRTElURV9ERU5ZOwogICAgICAgIH0KICAgICAgICBQeV9ERUNSRUYocmV0KTsKICAgIH0KCiAgICBQeUdJTFN0YXRlX1JlbGVhc2UoZ2lsc3RhdGUpOwogICAgcmV0dXJuIHJjOwp9CgpzdGF0aWMgaW50IF9wcm9ncmVzc19oYW5kbGVyKHZvaWQqIHVzZXJfYXJnKQp7CiAgICBpbnQgcmM7CiAgICBQeU9iamVjdCAqcmV0OwogICAgUHlHSUxTdGF0ZV9TVEFURSBnaWxzdGF0ZTsKCiAgICBnaWxzdGF0ZSA9IFB5R0lMU3RhdGVfRW5zdXJlKCk7CiAgICByZXQgPSBQeU9iamVjdF9DYWxsRnVuY3Rpb24oKFB5T2JqZWN0Kil1c2VyX2FyZywgIiIpOwoKICAgIGlmICghcmV0KSB7CiAgICAgICAgaWYgKF9lbmFibGVfY2FsbGJhY2tfdHJhY2ViYWNrcykgewogICAgICAgICAgICBQeUVycl9QcmludCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFB5RXJyX0NsZWFyKCk7CiAgICAgICAgfQoKICAgICAgICAvKiBhYm9ydCBxdWVyeSBpZiBlcnJvciBvY2N1cmVkICovCiAgICAgICAgcmMgPSAxOyAKICAgIH0gZWxzZSB7CiAgICAgICAgcmMgPSAoaW50KVB5T2JqZWN0X0lzVHJ1ZShyZXQpOwogICAgICAgIFB5X0RFQ1JFRihyZXQpOwogICAgfQoKICAgIFB5R0lMU3RhdGVfUmVsZWFzZShnaWxzdGF0ZSk7CiAgICByZXR1cm4gcmM7Cn0KClB5T2JqZWN0KiBweXNxbGl0ZV9jb25uZWN0aW9uX3NldF9hdXRob3JpemVyKHB5c3FsaXRlX0Nvbm5lY3Rpb24qIHNlbGYsIFB5T2JqZWN0KiBhcmdzLCBQeU9iamVjdCoga3dhcmdzKQp7CiAgICBQeU9iamVjdCogYXV0aG9yaXplcl9jYjsKCiAgICBzdGF0aWMgY2hhciAqa3dsaXN0W10gPSB7ICJhdXRob3JpemVyX2NhbGxiYWNrIiwgTlVMTCB9OwogICAgaW50IHJjOwoKICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZUFuZEtleXdvcmRzKGFyZ3MsIGt3YXJncywgIk86c2V0X2F1dGhvcml6ZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGt3bGlzdCwgJmF1dGhvcml6ZXJfY2IpKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgcmMgPSBzcWxpdGUzX3NldF9hdXRob3JpemVyKHNlbGYtPmRiLCBfYXV0aG9yaXplcl9jYWxsYmFjaywgKHZvaWQqKWF1dGhvcml6ZXJfY2IpOwoKICAgIGlmIChyYyAhPSBTUUxJVEVfT0spIHsKICAgICAgICBQeUVycl9TZXRTdHJpbmcocHlzcWxpdGVfT3BlcmF0aW9uYWxFcnJvciwgIkVycm9yIHNldHRpbmcgYXV0aG9yaXplciBjYWxsYmFjayIpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfSBlbHNlIHsKICAgICAgICBQeURpY3RfU2V0SXRlbShzZWxmLT5mdW5jdGlvbl9waW5ib2FyZCwgYXV0aG9yaXplcl9jYiwgUHlfTm9uZSk7CgogICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgICAgICByZXR1cm4gUHlfTm9uZTsKICAgIH0KfQoKUHlPYmplY3QqIHB5c3FsaXRlX2Nvbm5lY3Rpb25fc2V0X3Byb2dyZXNzX2hhbmRsZXIocHlzcWxpdGVfQ29ubmVjdGlvbiogc2VsZiwgUHlPYmplY3QqIGFyZ3MsIFB5T2JqZWN0KiBrd2FyZ3MpCnsKICAgIFB5T2JqZWN0KiBwcm9ncmVzc19oYW5kbGVyOwogICAgaW50IG47CgogICAgc3RhdGljIGNoYXIgKmt3bGlzdFtdID0geyAicHJvZ3Jlc3NfaGFuZGxlciIsICJuIiwgTlVMTCB9OwoKICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZUFuZEtleXdvcmRzKGFyZ3MsIGt3YXJncywgIk9pOnNldF9wcm9ncmVzc19oYW5kbGVyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrd2xpc3QsICZwcm9ncmVzc19oYW5kbGVyLCAmbikpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBpZiAocHJvZ3Jlc3NfaGFuZGxlciA9PSBQeV9Ob25lKSB7CiAgICAgICAgLyogTm9uZSBjbGVhcnMgdGhlIHByb2dyZXNzIGhhbmRsZXIgcHJldmlvdXNseSBzZXQgKi8KICAgICAgICBzcWxpdGUzX3Byb2dyZXNzX2hhbmRsZXIoc2VsZi0+ZGIsIDAsIDAsICh2b2lkKikwKTsKICAgIH0gZWxzZSB7CiAgICAgICAgc3FsaXRlM19wcm9ncmVzc19oYW5kbGVyKHNlbGYtPmRiLCBuLCBfcHJvZ3Jlc3NfaGFuZGxlciwgcHJvZ3Jlc3NfaGFuZGxlcik7CiAgICAgICAgUHlEaWN0X1NldEl0ZW0oc2VsZi0+ZnVuY3Rpb25fcGluYm9hcmQsIHByb2dyZXNzX2hhbmRsZXIsIFB5X05vbmUpOwogICAgfQoKICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgIHJldHVybiBQeV9Ob25lOwp9CgppbnQgcHlzcWxpdGVfY2hlY2tfdGhyZWFkKHB5c3FsaXRlX0Nvbm5lY3Rpb24qIHNlbGYpCnsKICAgIGlmIChzZWxmLT5jaGVja19zYW1lX3RocmVhZCkgewogICAgICAgIGlmIChQeVRocmVhZF9nZXRfdGhyZWFkX2lkZW50KCkgIT0gc2VsZi0+dGhyZWFkX2lkZW50KSB7CiAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChweXNxbGl0ZV9Qcm9ncmFtbWluZ0Vycm9yLAogICAgICAgICAgICAgICAgICAgICAgICAiU1FMaXRlIG9iamVjdHMgY3JlYXRlZCBpbiBhIHRocmVhZCBjYW4gb25seSBiZSB1c2VkIGluIHRoYXQgc2FtZSB0aHJlYWQuIgogICAgICAgICAgICAgICAgICAgICAgICAiVGhlIG9iamVjdCB3YXMgY3JlYXRlZCBpbiB0aHJlYWQgaWQgJWxkIGFuZCB0aGlzIGlzIHRocmVhZCBpZCAlbGQiLAogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT50aHJlYWRfaWRlbnQsIFB5VGhyZWFkX2dldF90aHJlYWRfaWRlbnQoKSk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICB9CgogICAgcmV0dXJuIDE7Cn0KCnN0YXRpYyBQeU9iamVjdCogcHlzcWxpdGVfY29ubmVjdGlvbl9nZXRfaXNvbGF0aW9uX2xldmVsKHB5c3FsaXRlX0Nvbm5lY3Rpb24qIHNlbGYsIHZvaWQqIHVudXNlZCkKewogICAgUHlfSU5DUkVGKHNlbGYtPmlzb2xhdGlvbl9sZXZlbCk7CiAgICByZXR1cm4gc2VsZi0+aXNvbGF0aW9uX2xldmVsOwp9CgpzdGF0aWMgUHlPYmplY3QqIHB5c3FsaXRlX2Nvbm5lY3Rpb25fZ2V0X3RvdGFsX2NoYW5nZXMocHlzcWxpdGVfQ29ubmVjdGlvbiogc2VsZiwgdm9pZCogdW51c2VkKQp7CiAgICBpZiAoIXB5c3FsaXRlX2NoZWNrX2Nvbm5lY3Rpb24oc2VsZikpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIFB5X0J1aWxkVmFsdWUoImkiLCBzcWxpdGUzX3RvdGFsX2NoYW5nZXMoc2VsZi0+ZGIpKTsKICAgIH0KfQoKc3RhdGljIGludCBweXNxbGl0ZV9jb25uZWN0aW9uX3NldF9pc29sYXRpb25fbGV2ZWwocHlzcWxpdGVfQ29ubmVjdGlvbiogc2VsZiwgUHlPYmplY3QqIGlzb2xhdGlvbl9sZXZlbCkKewogICAgUHlPYmplY3QqIHJlczsKICAgIFB5T2JqZWN0KiBiZWdpbl9zdGF0ZW1lbnQ7CiAgICBzdGF0aWMgUHlPYmplY3QqIGJlZ2luX3dvcmQ7CgogICAgUHlfWERFQ1JFRihzZWxmLT5pc29sYXRpb25fbGV2ZWwpOwoKICAgIGlmIChzZWxmLT5iZWdpbl9zdGF0ZW1lbnQpIHsKICAgICAgICBQeU1lbV9GcmVlKHNlbGYtPmJlZ2luX3N0YXRlbWVudCk7CiAgICAgICAgc2VsZi0+YmVnaW5fc3RhdGVtZW50ID0gTlVMTDsKICAgIH0KCiAgICBpZiAoaXNvbGF0aW9uX2xldmVsID09IFB5X05vbmUpIHsKICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICAgICAgc2VsZi0+aXNvbGF0aW9uX2xldmVsID0gUHlfTm9uZTsKCiAgICAgICAgcmVzID0gcHlzcWxpdGVfY29ubmVjdGlvbl9jb21taXQoc2VsZiwgTlVMTCk7CiAgICAgICAgaWYgKCFyZXMpIHsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgICAgICBQeV9ERUNSRUYocmVzKTsKCiAgICAgICAgc2VsZi0+aW5UcmFuc2FjdGlvbiA9IDA7CiAgICB9IGVsc2UgewogICAgICAgIGNvbnN0IGNoYXIgKnN0YXRlbWVudDsKICAgICAgICBQeV9zc2l6ZV90IHNpemU7CgogICAgICAgIFB5X0lOQ1JFRihpc29sYXRpb25fbGV2ZWwpOwogICAgICAgIHNlbGYtPmlzb2xhdGlvbl9sZXZlbCA9IGlzb2xhdGlvbl9sZXZlbDsKCiAgICAgICAgaWYgKCFiZWdpbl93b3JkKSB7CiAgICAgICAgICAgIGJlZ2luX3dvcmQgPSBQeVVuaWNvZGVfRnJvbVN0cmluZygiQkVHSU4gIik7CiAgICAgICAgICAgIGlmICghYmVnaW5fd29yZCkgcmV0dXJuIC0xOwogICAgICAgIH0KICAgICAgICBiZWdpbl9zdGF0ZW1lbnQgPSBQeVVuaWNvZGVfQ29uY2F0KGJlZ2luX3dvcmQsIGlzb2xhdGlvbl9sZXZlbCk7CiAgICAgICAgaWYgKCFiZWdpbl9zdGF0ZW1lbnQpIHsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KCiAgICAgICAgc3RhdGVtZW50ID0gUHlVbmljb2RlX0FzU3RyaW5nQW5kU2l6ZShiZWdpbl9zdGF0ZW1lbnQsICZzaXplKTsKICAgICAgICBzZWxmLT5iZWdpbl9zdGF0ZW1lbnQgPSBQeU1lbV9NYWxsb2Moc2l6ZSArIDIpOwogICAgICAgIGlmICghc2VsZi0+YmVnaW5fc3RhdGVtZW50KSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CgogICAgICAgIHN0cmNweShzZWxmLT5iZWdpbl9zdGF0ZW1lbnQsIHN0YXRlbWVudCk7CiAgICAgICAgUHlfREVDUkVGKGJlZ2luX3N0YXRlbWVudCk7CiAgICB9CgogICAgcmV0dXJuIDA7Cn0KClB5T2JqZWN0KiBweXNxbGl0ZV9jb25uZWN0aW9uX2NhbGwocHlzcWxpdGVfQ29ubmVjdGlvbiogc2VsZiwgUHlPYmplY3QqIGFyZ3MsIFB5T2JqZWN0KiBrd2FyZ3MpCnsKICAgIFB5T2JqZWN0KiBzcWw7CiAgICBweXNxbGl0ZV9TdGF0ZW1lbnQqIHN0YXRlbWVudDsKICAgIFB5T2JqZWN0KiB3ZWFrcmVmOwogICAgaW50IHJjOwoKICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiTyIsICZzcWwpKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgX3B5c3FsaXRlX2Ryb3BfdW51c2VkX3N0YXRlbWVudF9yZWZlcmVuY2VzKHNlbGYpOwoKICAgIHN0YXRlbWVudCA9IFB5T2JqZWN0X05ldyhweXNxbGl0ZV9TdGF0ZW1lbnQsICZweXNxbGl0ZV9TdGF0ZW1lbnRUeXBlKTsKICAgIGlmICghc3RhdGVtZW50KSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgcmMgPSBweXNxbGl0ZV9zdGF0ZW1lbnRfY3JlYXRlKHN0YXRlbWVudCwgc2VsZiwgc3FsKTsKCiAgICBpZiAocmMgIT0gU1FMSVRFX09LKSB7CiAgICAgICAgaWYgKHJjID09IFBZU1FMSVRFX1RPT19NVUNIX1NRTCkgewogICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcocHlzcWxpdGVfV2FybmluZywgIllvdSBjYW4gb25seSBleGVjdXRlIG9uZSBzdGF0ZW1lbnQgYXQgYSB0aW1lLiIpOwogICAgICAgIH0gZWxzZSBpZiAocmMgPT0gUFlTUUxJVEVfU1FMX1dST05HX1RZUEUpIHsKICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKHB5c3FsaXRlX1dhcm5pbmcsICJTUUwgaXMgb2Ygd3JvbmcgdHlwZS4gTXVzdCBiZSBzdHJpbmcgb3IgdW5pY29kZS4iKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAodm9pZClweXNxbGl0ZV9zdGF0ZW1lbnRfcmVzZXQoc3RhdGVtZW50KTsKICAgICAgICAgICAgX3B5c3FsaXRlX3NldGVycm9yKHNlbGYtPmRiLCBOVUxMKTsKICAgICAgICB9CgogICAgICAgIFB5X0RFQ1JFRihzdGF0ZW1lbnQpOwogICAgICAgIHN0YXRlbWVudCA9IDA7CiAgICB9IGVsc2UgewogICAgICAgIHdlYWtyZWYgPSBQeVdlYWtyZWZfTmV3UmVmKChQeU9iamVjdCopc3RhdGVtZW50LCBOVUxMKTsKICAgICAgICBpZiAoIXdlYWtyZWYpIHsKICAgICAgICAgICAgUHlfREVDUkVGKHN0YXRlbWVudCk7CiAgICAgICAgICAgIHN0YXRlbWVudCA9IDA7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQoKICAgICAgICBpZiAoUHlMaXN0X0FwcGVuZChzZWxmLT5zdGF0ZW1lbnRzLCB3ZWFrcmVmKSAhPSAwKSB7CiAgICAgICAgICAgIFB5X0RFQ1JFRih3ZWFrcmVmKTsKICAgICAgICAgICAgc3RhdGVtZW50ID0gMDsKICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CgogICAgICAgIFB5X0RFQ1JFRih3ZWFrcmVmKTsKICAgIH0KCmVycm9yOgogICAgcmV0dXJuIChQeU9iamVjdCopc3RhdGVtZW50Owp9CgpQeU9iamVjdCogcHlzcWxpdGVfY29ubmVjdGlvbl9leGVjdXRlKHB5c3FsaXRlX0Nvbm5lY3Rpb24qIHNlbGYsIFB5T2JqZWN0KiBhcmdzLCBQeU9iamVjdCoga3dhcmdzKQp7CiAgICBQeU9iamVjdCogY3Vyc29yID0gMDsKICAgIFB5T2JqZWN0KiByZXN1bHQgPSAwOwogICAgUHlPYmplY3QqIG1ldGhvZCA9IDA7CgogICAgY3Vyc29yID0gUHlPYmplY3RfQ2FsbE1ldGhvZCgoUHlPYmplY3QqKXNlbGYsICJjdXJzb3IiLCAiIik7CiAgICBpZiAoIWN1cnNvcikgewogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgbWV0aG9kID0gUHlPYmplY3RfR2V0QXR0clN0cmluZyhjdXJzb3IsICJleGVjdXRlIik7CiAgICBpZiAoIW1ldGhvZCkgewogICAgICAgIFB5X0RFQ1JFRihjdXJzb3IpOwogICAgICAgIGN1cnNvciA9IDA7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICByZXN1bHQgPSBQeU9iamVjdF9DYWxsT2JqZWN0KG1ldGhvZCwgYXJncyk7CiAgICBpZiAoIXJlc3VsdCkgewogICAgICAgIFB5X0RFQ1JFRihjdXJzb3IpOwogICAgICAgIGN1cnNvciA9IDA7CiAgICB9CgplcnJvcjoKICAgIFB5X1hERUNSRUYocmVzdWx0KTsKICAgIFB5X1hERUNSRUYobWV0aG9kKTsKCiAgICByZXR1cm4gY3Vyc29yOwp9CgpQeU9iamVjdCogcHlzcWxpdGVfY29ubmVjdGlvbl9leGVjdXRlbWFueShweXNxbGl0ZV9Db25uZWN0aW9uKiBzZWxmLCBQeU9iamVjdCogYXJncywgUHlPYmplY3QqIGt3YXJncykKewogICAgUHlPYmplY3QqIGN1cnNvciA9IDA7CiAgICBQeU9iamVjdCogcmVzdWx0ID0gMDsKICAgIFB5T2JqZWN0KiBtZXRob2QgPSAwOwoKICAgIGN1cnNvciA9IFB5T2JqZWN0X0NhbGxNZXRob2QoKFB5T2JqZWN0KilzZWxmLCAiY3Vyc29yIiwgIiIpOwogICAgaWYgKCFjdXJzb3IpIHsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIG1ldGhvZCA9IFB5T2JqZWN0X0dldEF0dHJTdHJpbmcoY3Vyc29yLCAiZXhlY3V0ZW1hbnkiKTsKICAgIGlmICghbWV0aG9kKSB7CiAgICAgICAgUHlfREVDUkVGKGN1cnNvcik7CiAgICAgICAgY3Vyc29yID0gMDsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIHJlc3VsdCA9IFB5T2JqZWN0X0NhbGxPYmplY3QobWV0aG9kLCBhcmdzKTsKICAgIGlmICghcmVzdWx0KSB7CiAgICAgICAgUHlfREVDUkVGKGN1cnNvcik7CiAgICAgICAgY3Vyc29yID0gMDsKICAgIH0KCmVycm9yOgogICAgUHlfWERFQ1JFRihyZXN1bHQpOwogICAgUHlfWERFQ1JFRihtZXRob2QpOwoKICAgIHJldHVybiBjdXJzb3I7Cn0KClB5T2JqZWN0KiBweXNxbGl0ZV9jb25uZWN0aW9uX2V4ZWN1dGVzY3JpcHQocHlzcWxpdGVfQ29ubmVjdGlvbiogc2VsZiwgUHlPYmplY3QqIGFyZ3MsIFB5T2JqZWN0KiBrd2FyZ3MpCnsKICAgIFB5T2JqZWN0KiBjdXJzb3IgPSAwOwogICAgUHlPYmplY3QqIHJlc3VsdCA9IDA7CiAgICBQeU9iamVjdCogbWV0aG9kID0gMDsKCiAgICBjdXJzb3IgPSBQeU9iamVjdF9DYWxsTWV0aG9kKChQeU9iamVjdCopc2VsZiwgImN1cnNvciIsICIiKTsKICAgIGlmICghY3Vyc29yKSB7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBtZXRob2QgPSBQeU9iamVjdF9HZXRBdHRyU3RyaW5nKGN1cnNvciwgImV4ZWN1dGVzY3JpcHQiKTsKICAgIGlmICghbWV0aG9kKSB7CiAgICAgICAgUHlfREVDUkVGKGN1cnNvcik7CiAgICAgICAgY3Vyc29yID0gMDsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIHJlc3VsdCA9IFB5T2JqZWN0X0NhbGxPYmplY3QobWV0aG9kLCBhcmdzKTsKICAgIGlmICghcmVzdWx0KSB7CiAgICAgICAgUHlfREVDUkVGKGN1cnNvcik7CiAgICAgICAgY3Vyc29yID0gMDsKICAgIH0KCmVycm9yOgogICAgUHlfWERFQ1JFRihyZXN1bHQpOwogICAgUHlfWERFQ1JFRihtZXRob2QpOwoKICAgIHJldHVybiBjdXJzb3I7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ09MTEFUSU9OIENPREUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpzdGF0aWMgaW50CnB5c3FsaXRlX2NvbGxhdGlvbl9jYWxsYmFjaygKICAgICAgICB2b2lkKiBjb250ZXh0LAogICAgICAgIGludCB0ZXh0MV9sZW5ndGgsIGNvbnN0IHZvaWQqIHRleHQxX2RhdGEsCiAgICAgICAgaW50IHRleHQyX2xlbmd0aCwgY29uc3Qgdm9pZCogdGV4dDJfZGF0YSkKewogICAgUHlPYmplY3QqIGNhbGxiYWNrID0gKFB5T2JqZWN0Kiljb250ZXh0OwogICAgUHlPYmplY3QqIHN0cmluZzEgPSAwOwogICAgUHlPYmplY3QqIHN0cmluZzIgPSAwOwogICAgUHlHSUxTdGF0ZV9TVEFURSBnaWxzdGF0ZTsKCiAgICBQeU9iamVjdCogcmV0dmFsID0gTlVMTDsKICAgIGludCByZXN1bHQgPSAwOwoKICAgIGdpbHN0YXRlID0gUHlHSUxTdGF0ZV9FbnN1cmUoKTsKCiAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkgewogICAgICAgIGdvdG8gZmluYWxseTsKICAgIH0KCiAgICBzdHJpbmcxID0gUHlVbmljb2RlX0Zyb21TdHJpbmdBbmRTaXplKChjb25zdCBjaGFyKil0ZXh0MV9kYXRhLCB0ZXh0MV9sZW5ndGgpOwogICAgc3RyaW5nMiA9IFB5VW5pY29kZV9Gcm9tU3RyaW5nQW5kU2l6ZSgoY29uc3QgY2hhciopdGV4dDJfZGF0YSwgdGV4dDJfbGVuZ3RoKTsKCiAgICBpZiAoIXN0cmluZzEgfHwgIXN0cmluZzIpIHsKICAgICAgICBnb3RvIGZpbmFsbHk7IC8qIGZhaWxlZCB0byBhbGxvY2F0ZSBzdHJpbmdzICovCiAgICB9CgogICAgcmV0dmFsID0gUHlPYmplY3RfQ2FsbEZ1bmN0aW9uT2JqQXJncyhjYWxsYmFjaywgc3RyaW5nMSwgc3RyaW5nMiwgTlVMTCk7CgogICAgaWYgKCFyZXR2YWwpIHsKICAgICAgICAvKiBleGVjdXRpb24gZmFpbGVkICovCiAgICAgICAgZ290byBmaW5hbGx5OwogICAgfQoKICAgIHJlc3VsdCA9IFB5TG9uZ19Bc0xvbmcocmV0dmFsKTsKICAgIGlmIChQeUVycl9PY2N1cnJlZCgpKSB7CiAgICAgICAgcmVzdWx0ID0gMDsKICAgIH0KCmZpbmFsbHk6CiAgICBQeV9YREVDUkVGKHN0cmluZzEpOwogICAgUHlfWERFQ1JFRihzdHJpbmcyKTsKICAgIFB5X1hERUNSRUYocmV0dmFsKTsKCiAgICBQeUdJTFN0YXRlX1JlbGVhc2UoZ2lsc3RhdGUpOwoKICAgIHJldHVybiByZXN1bHQ7Cn0KCnN0YXRpYyBQeU9iamVjdCAqCnB5c3FsaXRlX2Nvbm5lY3Rpb25faW50ZXJydXB0KHB5c3FsaXRlX0Nvbm5lY3Rpb24qIHNlbGYsIFB5T2JqZWN0KiBhcmdzKQp7CiAgICBQeU9iamVjdCogcmV0dmFsID0gTlVMTDsKCiAgICBpZiAoIXB5c3FsaXRlX2NoZWNrX2Nvbm5lY3Rpb24oc2VsZikpIHsKICAgICAgICBnb3RvIGZpbmFsbHk7CiAgICB9CgogICAgc3FsaXRlM19pbnRlcnJ1cHQoc2VsZi0+ZGIpOwoKICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgIHJldHZhbCA9IFB5X05vbmU7CgpmaW5hbGx5OgogICAgcmV0dXJuIHJldHZhbDsKfQoKLyogRnVuY3Rpb24gYXV0aG9yOiBQYXVsIEtpcHBlcyA8a2lwcGVzcEBnbWFpbC5jb20+CiAqIENsYXNzIG1ldGhvZCBvZiBDb25uZWN0aW9uIHRvIGNhbGwgdGhlIFB5dGhvbiBmdW5jdGlvbiBfaXRlcmR1bXAKICogb2YgdGhlIHNxbGl0ZTMgbW9kdWxlLgogKi8Kc3RhdGljIFB5T2JqZWN0ICoKcHlzcWxpdGVfY29ubmVjdGlvbl9pdGVyZHVtcChweXNxbGl0ZV9Db25uZWN0aW9uKiBzZWxmLCBQeU9iamVjdCogYXJncykKewogICAgUHlPYmplY3QqIHJldHZhbCA9IE5VTEw7CiAgICBQeU9iamVjdCogbW9kdWxlID0gTlVMTDsKICAgIFB5T2JqZWN0KiBtb2R1bGVfZGljdDsKICAgIFB5T2JqZWN0KiBweWZuX2l0ZXJkdW1wOwoKICAgIGlmICghcHlzcWxpdGVfY2hlY2tfY29ubmVjdGlvbihzZWxmKSkgewogICAgICAgIGdvdG8gZmluYWxseTsKICAgIH0KCiAgICBtb2R1bGUgPSBQeUltcG9ydF9JbXBvcnRNb2R1bGUoTU9EVUxFX05BTUUgIi5kdW1wIik7CiAgICBpZiAoIW1vZHVsZSkgewogICAgICAgIGdvdG8gZmluYWxseTsKICAgIH0KCiAgICBtb2R1bGVfZGljdCA9IFB5TW9kdWxlX0dldERpY3QobW9kdWxlKTsKICAgIGlmICghbW9kdWxlX2RpY3QpIHsKICAgICAgICBnb3RvIGZpbmFsbHk7CiAgICB9CgogICAgcHlmbl9pdGVyZHVtcCA9IFB5RGljdF9HZXRJdGVtU3RyaW5nKG1vZHVsZV9kaWN0LCAiX2l0ZXJkdW1wIik7CiAgICBpZiAoIXB5Zm5faXRlcmR1bXApIHsKICAgICAgICBQeUVycl9TZXRTdHJpbmcocHlzcWxpdGVfT3BlcmF0aW9uYWxFcnJvciwgIkZhaWxlZCB0byBvYnRhaW4gX2l0ZXJkdW1wKCkgcmVmZXJlbmNlIik7CiAgICAgICAgZ290byBmaW5hbGx5OwogICAgfQoKICAgIGFyZ3MgPSBQeVR1cGxlX05ldygxKTsKICAgIGlmICghYXJncykgewogICAgICAgIGdvdG8gZmluYWxseTsKICAgIH0KICAgIFB5X0lOQ1JFRihzZWxmKTsKICAgIFB5VHVwbGVfU2V0SXRlbShhcmdzLCAwLCAoUHlPYmplY3QqKXNlbGYpOwogICAgcmV0dmFsID0gUHlPYmplY3RfQ2FsbE9iamVjdChweWZuX2l0ZXJkdW1wLCBhcmdzKTsKCmZpbmFsbHk6CiAgICBQeV9YREVDUkVGKGFyZ3MpOwogICAgUHlfWERFQ1JFRihtb2R1bGUpOwogICAgcmV0dXJuIHJldHZhbDsKfQoKc3RhdGljIFB5T2JqZWN0ICoKcHlzcWxpdGVfY29ubmVjdGlvbl9jcmVhdGVfY29sbGF0aW9uKHB5c3FsaXRlX0Nvbm5lY3Rpb24qIHNlbGYsIFB5T2JqZWN0KiBhcmdzKQp7CiAgICBQeU9iamVjdCogY2FsbGFibGU7CiAgICBQeU9iamVjdCogdXBwZXJjYXNlX25hbWUgPSAwOwogICAgUHlPYmplY3QqIG5hbWU7CiAgICBQeU9iamVjdCogcmV0dmFsOwogICAgY2hhciogY2hrOwogICAgaW50IHJjOwoKICAgIGlmICghcHlzcWxpdGVfY2hlY2tfdGhyZWFkKHNlbGYpIHx8ICFweXNxbGl0ZV9jaGVja19jb25uZWN0aW9uKHNlbGYpKSB7CiAgICAgICAgZ290byBmaW5hbGx5OwogICAgfQoKICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiTyFPOmNyZWF0ZV9jb2xsYXRpb24obmFtZSwgY2FsbGJhY2spIiwgJlB5VW5pY29kZV9UeXBlLCAmbmFtZSwgJmNhbGxhYmxlKSkgewogICAgICAgIGdvdG8gZmluYWxseTsKICAgIH0KCiAgICB1cHBlcmNhc2VfbmFtZSA9IFB5T2JqZWN0X0NhbGxNZXRob2QobmFtZSwgInVwcGVyIiwgIiIpOwogICAgaWYgKCF1cHBlcmNhc2VfbmFtZSkgewogICAgICAgIGdvdG8gZmluYWxseTsKICAgIH0KCiAgICBjaGsgPSBQeVVuaWNvZGVfQXNTdHJpbmcodXBwZXJjYXNlX25hbWUpOwogICAgd2hpbGUgKCpjaGspIHsKICAgICAgICBpZiAoKCpjaGsgPj0gJzAnICYmICpjaGsgPD0gJzknKQogICAgICAgICB8fCAoKmNoayA+PSAnQScgJiYgKmNoayA8PSAnWicpCiAgICAgICAgIHx8ICgqY2hrID09ICdfJykpCiAgICAgICAgewogICAgICAgICAgICBjaGsrKzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcocHlzcWxpdGVfUHJvZ3JhbW1pbmdFcnJvciwgImludmFsaWQgY2hhcmFjdGVyIGluIGNvbGxhdGlvbiBuYW1lIik7CiAgICAgICAgICAgIGdvdG8gZmluYWxseTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKGNhbGxhYmxlICE9IFB5X05vbmUgJiYgIVB5Q2FsbGFibGVfQ2hlY2soY2FsbGFibGUpKSB7CiAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwgInBhcmFtZXRlciBtdXN0IGJlIGNhbGxhYmxlIik7CiAgICAgICAgZ290byBmaW5hbGx5OwogICAgfQoKICAgIGlmIChjYWxsYWJsZSAhPSBQeV9Ob25lKSB7CiAgICAgICAgUHlEaWN0X1NldEl0ZW0oc2VsZi0+Y29sbGF0aW9ucywgdXBwZXJjYXNlX25hbWUsIGNhbGxhYmxlKTsKICAgIH0gZWxzZSB7CiAgICAgICAgUHlEaWN0X0RlbEl0ZW0oc2VsZi0+Y29sbGF0aW9ucywgdXBwZXJjYXNlX25hbWUpOwogICAgfQoKICAgIHJjID0gc3FsaXRlM19jcmVhdGVfY29sbGF0aW9uKHNlbGYtPmRiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlVbmljb2RlX0FzU3RyaW5nKHVwcGVyY2FzZV9uYW1lKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNRTElURV9VVEY4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNhbGxhYmxlICE9IFB5X05vbmUpID8gY2FsbGFibGUgOiBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNhbGxhYmxlICE9IFB5X05vbmUpID8gcHlzcWxpdGVfY29sbGF0aW9uX2NhbGxiYWNrIDogTlVMTCk7CiAgICBpZiAocmMgIT0gU1FMSVRFX09LKSB7CiAgICAgICAgUHlEaWN0X0RlbEl0ZW0oc2VsZi0+Y29sbGF0aW9ucywgdXBwZXJjYXNlX25hbWUpOwogICAgICAgIF9weXNxbGl0ZV9zZXRlcnJvcihzZWxmLT5kYiwgTlVMTCk7CiAgICAgICAgZ290byBmaW5hbGx5OwogICAgfQoKZmluYWxseToKICAgIFB5X1hERUNSRUYodXBwZXJjYXNlX25hbWUpOwoKICAgIGlmIChQeUVycl9PY2N1cnJlZCgpKSB7CiAgICAgICAgcmV0dmFsID0gTlVMTDsKICAgIH0gZWxzZSB7CiAgICAgICAgUHlfSU5DUkVGKFB5X05vbmUpOwogICAgICAgIHJldHZhbCA9IFB5X05vbmU7CiAgICB9CgogICAgcmV0dXJuIHJldHZhbDsKfQoKLyogQ2FsbGVkIHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgdXNlZCBhcyBhIGNvbnRleHQgbWFuYWdlci4gUmV0dXJucyBpdHNlbGYgYXMgYQogKiBjb252ZW5pZW5jZSB0byB0aGUgY2FsbGVyLiAqLwpzdGF0aWMgUHlPYmplY3QgKgpweXNxbGl0ZV9jb25uZWN0aW9uX2VudGVyKHB5c3FsaXRlX0Nvbm5lY3Rpb24qIHNlbGYsIFB5T2JqZWN0KiBhcmdzKQp7CiAgICBQeV9JTkNSRUYoc2VsZik7CiAgICByZXR1cm4gKFB5T2JqZWN0KilzZWxmOwp9CgovKiogQ2FsbGVkIHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgdXNlZCBhcyBhIGNvbnRleHQgbWFuYWdlci4gSWYgdGhlcmUgd2FzIGFueQogKiBleGNlcHRpb24sIGEgcm9sbGJhY2sgdGFrZXMgcGxhY2U7IG90aGVyd2lzZSB3ZSBjb21taXQuICovCnN0YXRpYyBQeU9iamVjdCAqCnB5c3FsaXRlX2Nvbm5lY3Rpb25fZXhpdChweXNxbGl0ZV9Db25uZWN0aW9uKiBzZWxmLCBQeU9iamVjdCogYXJncykKewogICAgUHlPYmplY3QqIGV4Y190eXBlLCAqZXhjX3ZhbHVlLCAqZXhjX3RiOwogICAgY2hhciogbWV0aG9kX25hbWU7CiAgICBQeU9iamVjdCogcmVzdWx0OwoKICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiT09PIiwgJmV4Y190eXBlLCAmZXhjX3ZhbHVlLCAmZXhjX3RiKSkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIGlmIChleGNfdHlwZSA9PSBQeV9Ob25lICYmIGV4Y192YWx1ZSA9PSBQeV9Ob25lICYmIGV4Y190YiA9PSBQeV9Ob25lKSB7CiAgICAgICAgbWV0aG9kX25hbWUgPSAiY29tbWl0IjsKICAgIH0gZWxzZSB7CiAgICAgICAgbWV0aG9kX25hbWUgPSAicm9sbGJhY2siOwogICAgfQoKICAgIHJlc3VsdCA9IFB5T2JqZWN0X0NhbGxNZXRob2QoKFB5T2JqZWN0KilzZWxmLCBtZXRob2RfbmFtZSwgIiIpOwogICAgaWYgKCFyZXN1bHQpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIFB5X0RFQ1JFRihyZXN1bHQpOwoKICAgIFB5X1JFVFVSTl9GQUxTRTsKfQoKc3RhdGljIGNoYXIgY29ubmVjdGlvbl9kb2NbXSA9ClB5RG9jX1NUUigiU1FMaXRlIGRhdGFiYXNlIGNvbm5lY3Rpb24gb2JqZWN0LiIpOwoKc3RhdGljIFB5R2V0U2V0RGVmIGNvbm5lY3Rpb25fZ2V0c2V0W10gPSB7CiAgICB7Imlzb2xhdGlvbl9sZXZlbCIsICAoZ2V0dGVyKXB5c3FsaXRlX2Nvbm5lY3Rpb25fZ2V0X2lzb2xhdGlvbl9sZXZlbCwgKHNldHRlcilweXNxbGl0ZV9jb25uZWN0aW9uX3NldF9pc29sYXRpb25fbGV2ZWx9LAogICAgeyJ0b3RhbF9jaGFuZ2VzIiwgIChnZXR0ZXIpcHlzcWxpdGVfY29ubmVjdGlvbl9nZXRfdG90YWxfY2hhbmdlcywgKHNldHRlcikwfSwKICAgIHtOVUxMfQp9OwoKc3RhdGljIFB5TWV0aG9kRGVmIGNvbm5lY3Rpb25fbWV0aG9kc1tdID0gewogICAgeyJjdXJzb3IiLCAoUHlDRnVuY3Rpb24pcHlzcWxpdGVfY29ubmVjdGlvbl9jdXJzb3IsIE1FVEhfVkFSQVJHU3xNRVRIX0tFWVdPUkRTLAogICAgICAgIFB5RG9jX1NUUigiUmV0dXJuIGEgY3Vyc29yIGZvciB0aGUgY29ubmVjdGlvbi4iKX0sCiAgICB7ImNsb3NlIiwgKFB5Q0Z1bmN0aW9uKXB5c3FsaXRlX2Nvbm5lY3Rpb25fY2xvc2UsIE1FVEhfTk9BUkdTLAogICAgICAgIFB5RG9jX1NUUigiQ2xvc2VzIHRoZSBjb25uZWN0aW9uLiIpfSwKICAgIHsiY29tbWl0IiwgKFB5Q0Z1bmN0aW9uKXB5c3FsaXRlX2Nvbm5lY3Rpb25fY29tbWl0LCBNRVRIX05PQVJHUywKICAgICAgICBQeURvY19TVFIoIkNvbW1pdCB0aGUgY3VycmVudCB0cmFuc2FjdGlvbi4iKX0sCiAgICB7InJvbGxiYWNrIiwgKFB5Q0Z1bmN0aW9uKXB5c3FsaXRlX2Nvbm5lY3Rpb25fcm9sbGJhY2ssIE1FVEhfTk9BUkdTLAogICAgICAgIFB5RG9jX1NUUigiUm9sbCBiYWNrIHRoZSBjdXJyZW50IHRyYW5zYWN0aW9uLiIpfSwKICAgIHsiY3JlYXRlX2Z1bmN0aW9uIiwgKFB5Q0Z1bmN0aW9uKXB5c3FsaXRlX2Nvbm5lY3Rpb25fY3JlYXRlX2Z1bmN0aW9uLCBNRVRIX1ZBUkFSR1N8TUVUSF9LRVlXT1JEUywKICAgICAgICBQeURvY19TVFIoIkNyZWF0ZXMgYSBuZXcgZnVuY3Rpb24uIE5vbi1zdGFuZGFyZC4iKX0sCiAgICB7ImNyZWF0ZV9hZ2dyZWdhdGUiLCAoUHlDRnVuY3Rpb24pcHlzcWxpdGVfY29ubmVjdGlvbl9jcmVhdGVfYWdncmVnYXRlLCBNRVRIX1ZBUkFSR1N8TUVUSF9LRVlXT1JEUywKICAgICAgICBQeURvY19TVFIoIkNyZWF0ZXMgYSBuZXcgYWdncmVnYXRlLiBOb24tc3RhbmRhcmQuIil9LAogICAgeyJzZXRfYXV0aG9yaXplciIsIChQeUNGdW5jdGlvbilweXNxbGl0ZV9jb25uZWN0aW9uX3NldF9hdXRob3JpemVyLCBNRVRIX1ZBUkFSR1N8TUVUSF9LRVlXT1JEUywKICAgICAgICBQeURvY19TVFIoIlNldHMgYXV0aG9yaXplciBjYWxsYmFjay4gTm9uLXN0YW5kYXJkLiIpfSwKICAgIHsic2V0X3Byb2dyZXNzX2hhbmRsZXIiLCAoUHlDRnVuY3Rpb24pcHlzcWxpdGVfY29ubmVjdGlvbl9zZXRfcHJvZ3Jlc3NfaGFuZGxlciwgTUVUSF9WQVJBUkdTfE1FVEhfS0VZV09SRFMsCiAgICAgICAgUHlEb2NfU1RSKCJTZXRzIHByb2dyZXNzIGhhbmRsZXIgY2FsbGJhY2suIE5vbi1zdGFuZGFyZC4iKX0sCiAgICB7ImV4ZWN1dGUiLCAoUHlDRnVuY3Rpb24pcHlzcWxpdGVfY29ubmVjdGlvbl9leGVjdXRlLCBNRVRIX1ZBUkFSR1MsCiAgICAgICAgUHlEb2NfU1RSKCJFeGVjdXRlcyBhIFNRTCBzdGF0ZW1lbnQuIE5vbi1zdGFuZGFyZC4iKX0sCiAgICB7ImV4ZWN1dGVtYW55IiwgKFB5Q0Z1bmN0aW9uKXB5c3FsaXRlX2Nvbm5lY3Rpb25fZXhlY3V0ZW1hbnksIE1FVEhfVkFSQVJHUywKICAgICAgICBQeURvY19TVFIoIlJlcGVhdGVkbHkgZXhlY3V0ZXMgYSBTUUwgc3RhdGVtZW50LiBOb24tc3RhbmRhcmQuIil9LAogICAgeyJleGVjdXRlc2NyaXB0IiwgKFB5Q0Z1bmN0aW9uKXB5c3FsaXRlX2Nvbm5lY3Rpb25fZXhlY3V0ZXNjcmlwdCwgTUVUSF9WQVJBUkdTLAogICAgICAgIFB5RG9jX1NUUigiRXhlY3V0ZXMgYSBtdWx0aXBsZSBTUUwgc3RhdGVtZW50cyBhdCBvbmNlLiBOb24tc3RhbmRhcmQuIil9LAogICAgeyJjcmVhdGVfY29sbGF0aW9uIiwgKFB5Q0Z1bmN0aW9uKXB5c3FsaXRlX2Nvbm5lY3Rpb25fY3JlYXRlX2NvbGxhdGlvbiwgTUVUSF9WQVJBUkdTLAogICAgICAgIFB5RG9jX1NUUigiQ3JlYXRlcyBhIGNvbGxhdGlvbiBmdW5jdGlvbi4gTm9uLXN0YW5kYXJkLiIpfSwKICAgIHsiaW50ZXJydXB0IiwgKFB5Q0Z1bmN0aW9uKXB5c3FsaXRlX2Nvbm5lY3Rpb25faW50ZXJydXB0LCBNRVRIX05PQVJHUywKICAgICAgICBQeURvY19TVFIoIkFib3J0IGFueSBwZW5kaW5nIGRhdGFiYXNlIG9wZXJhdGlvbi4gTm9uLXN0YW5kYXJkLiIpfSwKICAgIHsiaXRlcmR1bXAiLCAoUHlDRnVuY3Rpb24pcHlzcWxpdGVfY29ubmVjdGlvbl9pdGVyZHVtcCwgTUVUSF9OT0FSR1MsCiAgICAgICAgUHlEb2NfU1RSKCJSZXR1cm5zIGl0ZXJhdG9yIHRvIHRoZSBkdW1wIG9mIHRoZSBkYXRhYmFzZSBpbiBhbiBTUUwgdGV4dCIKICAgICAgICAgICAgICAgICAgImZvcm1hdC4iKX0sCiAgICB7Il9fZW50ZXJfXyIsIChQeUNGdW5jdGlvbilweXNxbGl0ZV9jb25uZWN0aW9uX2VudGVyLCBNRVRIX05PQVJHUywKICAgICAgICBQeURvY19TVFIoIkZvciBjb250ZXh0IG1hbmFnZXIuIE5vbi1zdGFuZGFyZC4iKX0sCiAgICB7Il9fZXhpdF9fIiwgKFB5Q0Z1bmN0aW9uKXB5c3FsaXRlX2Nvbm5lY3Rpb25fZXhpdCwgTUVUSF9WQVJBUkdTLAogICAgICAgIFB5RG9jX1NUUigiRm9yIGNvbnRleHQgbWFuYWdlci4gTm9uLXN0YW5kYXJkLiIpfSwKICAgIHtOVUxMLCBOVUxMfQp9OwoKc3RhdGljIHN0cnVjdCBQeU1lbWJlckRlZiBjb25uZWN0aW9uX21lbWJlcnNbXSA9CnsKICAgIHsiV2FybmluZyIsIFRfT0JKRUNULCBvZmZzZXRvZihweXNxbGl0ZV9Db25uZWN0aW9uLCBXYXJuaW5nKSwgUkVBRE9OTFl9LAogICAgeyJFcnJvciIsIFRfT0JKRUNULCBvZmZzZXRvZihweXNxbGl0ZV9Db25uZWN0aW9uLCBFcnJvciksIFJFQURPTkxZfSwKICAgIHsiSW50ZXJmYWNlRXJyb3IiLCBUX09CSkVDVCwgb2Zmc2V0b2YocHlzcWxpdGVfQ29ubmVjdGlvbiwgSW50ZXJmYWNlRXJyb3IpLCBSRUFET05MWX0sCiAgICB7IkRhdGFiYXNlRXJyb3IiLCBUX09CSkVDVCwgb2Zmc2V0b2YocHlzcWxpdGVfQ29ubmVjdGlvbiwgRGF0YWJhc2VFcnJvciksIFJFQURPTkxZfSwKICAgIHsiRGF0YUVycm9yIiwgVF9PQkpFQ1QsIG9mZnNldG9mKHB5c3FsaXRlX0Nvbm5lY3Rpb24sIERhdGFFcnJvciksIFJFQURPTkxZfSwKICAgIHsiT3BlcmF0aW9uYWxFcnJvciIsIFRfT0JKRUNULCBvZmZzZXRvZihweXNxbGl0ZV9Db25uZWN0aW9uLCBPcGVyYXRpb25hbEVycm9yKSwgUkVBRE9OTFl9LAogICAgeyJJbnRlZ3JpdHlFcnJvciIsIFRfT0JKRUNULCBvZmZzZXRvZihweXNxbGl0ZV9Db25uZWN0aW9uLCBJbnRlZ3JpdHlFcnJvciksIFJFQURPTkxZfSwKICAgIHsiSW50ZXJuYWxFcnJvciIsIFRfT0JKRUNULCBvZmZzZXRvZihweXNxbGl0ZV9Db25uZWN0aW9uLCBJbnRlcm5hbEVycm9yKSwgUkVBRE9OTFl9LAogICAgeyJQcm9ncmFtbWluZ0Vycm9yIiwgVF9PQkpFQ1QsIG9mZnNldG9mKHB5c3FsaXRlX0Nvbm5lY3Rpb24sIFByb2dyYW1taW5nRXJyb3IpLCBSRUFET05MWX0sCiAgICB7Ik5vdFN1cHBvcnRlZEVycm9yIiwgVF9PQkpFQ1QsIG9mZnNldG9mKHB5c3FsaXRlX0Nvbm5lY3Rpb24sIE5vdFN1cHBvcnRlZEVycm9yKSwgUkVBRE9OTFl9LAogICAgeyJyb3dfZmFjdG9yeSIsIFRfT0JKRUNULCBvZmZzZXRvZihweXNxbGl0ZV9Db25uZWN0aW9uLCByb3dfZmFjdG9yeSl9LAogICAgeyJ0ZXh0X2ZhY3RvcnkiLCBUX09CSkVDVCwgb2Zmc2V0b2YocHlzcWxpdGVfQ29ubmVjdGlvbiwgdGV4dF9mYWN0b3J5KX0sCiAgICB7TlVMTH0KfTsKClB5VHlwZU9iamVjdCBweXNxbGl0ZV9Db25uZWN0aW9uVHlwZSA9IHsKICAgICAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoTlVMTCwgMCkKICAgICAgICBNT0RVTEVfTkFNRSAiLkNvbm5lY3Rpb24iLCAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9uYW1lICovCiAgICAgICAgc2l6ZW9mKHB5c3FsaXRlX0Nvbm5lY3Rpb24pLCAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzaWNzaXplICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlbXNpemUgKi8KICAgICAgICAoZGVzdHJ1Y3RvcilweXNxbGl0ZV9jb25uZWN0aW9uX2RlYWxsb2MsICAgICAgICAvKiB0cF9kZWFsbG9jICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcHJpbnQgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0ciAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NvbXBhcmUgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yZXByICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbnVtYmVyICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfc2VxdWVuY2UgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaGFzaCAqLwogICAgICAgICh0ZXJuYXJ5ZnVuYylweXNxbGl0ZV9jb25uZWN0aW9uX2NhbGwsICAgICAgICAgIC8qIHRwX2NhbGwgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRybyAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHJvICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCiAgICAgICAgUHlfVFBGTEFHU19ERUZBVUxUfFB5X1RQRkxBR1NfQkFTRVRZUEUsICAgICAgICAgLyogdHBfZmxhZ3MgKi8KICAgICAgICBjb25uZWN0aW9uX2RvYywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF90cmF2ZXJzZSAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF93ZWFrbGlzdG9mZnNldCAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVybmV4dCAqLwogICAgICAgIGNvbm5lY3Rpb25fbWV0aG9kcywgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21ldGhvZHMgKi8KICAgICAgICBjb25uZWN0aW9uX21lbWJlcnMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZW1iZXJzICovCiAgICAgICAgY29ubmVjdGlvbl9nZXRzZXQsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0c2V0ICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzZSAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3QgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9nZXQgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9zZXQgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0b2Zmc2V0ICovCiAgICAgICAgKGluaXRwcm9jKXB5c3FsaXRlX2Nvbm5lY3Rpb25faW5pdCwgICAgICAgICAgICAgLyogdHBfaW5pdCAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FsbG9jICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmV3ICovCiAgICAgICAgMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZnJlZSAqLwp9OwoKZXh0ZXJuIGludCBweXNxbGl0ZV9jb25uZWN0aW9uX3NldHVwX3R5cGVzKHZvaWQpCnsKICAgIHB5c3FsaXRlX0Nvbm5lY3Rpb25UeXBlLnRwX25ldyA9IFB5VHlwZV9HZW5lcmljTmV3OwogICAgcmV0dXJuIFB5VHlwZV9SZWFkeSgmcHlzcWxpdGVfQ29ubmVjdGlvblR5cGUpOwp9Cg==