LyogbW9kdWxlLmMgLSB0aGUgbW9kdWxlIGl0c2VsZg0KICoNCiAqIENvcHlyaWdodCAoQykgMjAwNC0yMDEwIEdlcmhhcmQgSORyaW5nIDxnaEBnaGFlcmluZy5kZT4NCiAqDQogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBweXNxbGl0ZS4NCiAqDQogKiBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZA0KICogd2FycmFudHkuICBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlcw0KICogYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS4NCiAqDQogKiBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSwNCiAqIGluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXQNCiAqIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczoNCiAqDQogKiAxLiBUaGUgb3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50ZWQ7IHlvdSBtdXN0IG5vdA0KICogICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmUNCiAqICAgIGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQgaW4gdGhlIHByb2R1Y3QgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZQ0KICogICAgYXBwcmVjaWF0ZWQgYnV0IGlzIG5vdCByZXF1aXJlZC4NCiAqIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlDQogKiAgICBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3JpZ2luYWwgc29mdHdhcmUuDQogKiAzLiBUaGlzIG5vdGljZSBtYXkgbm90IGJlIHJlbW92ZWQgb3IgYWx0ZXJlZCBmcm9tIGFueSBzb3VyY2UgZGlzdHJpYnV0aW9uLg0KICovDQoNCiNpbmNsdWRlICJjb25uZWN0aW9uLmgiDQojaW5jbHVkZSAic3RhdGVtZW50LmgiDQojaW5jbHVkZSAiY3Vyc29yLmgiDQojaW5jbHVkZSAiY2FjaGUuaCINCiNpbmNsdWRlICJwcmVwYXJlX3Byb3RvY29sLmgiDQojaW5jbHVkZSAibWljcm9wcm90b2NvbHMuaCINCiNpbmNsdWRlICJyb3cuaCINCg0KI2lmIFNRTElURV9WRVJTSU9OX05VTUJFUiA+PSAzMDAzMDAzDQojZGVmaW5lIEhBVkVfU0hBUkVEX0NBQ0hFDQojZW5kaWYNCg0KLyogc3RhdGljIG9iamVjdHMgYXQgbW9kdWxlLWxldmVsICovDQoNClB5T2JqZWN0KiBweXNxbGl0ZV9FcnJvciwgKnB5c3FsaXRlX1dhcm5pbmcsICpweXNxbGl0ZV9JbnRlcmZhY2VFcnJvciwgKnB5c3FsaXRlX0RhdGFiYXNlRXJyb3IsDQogICAgKnB5c3FsaXRlX0ludGVybmFsRXJyb3IsICpweXNxbGl0ZV9PcGVyYXRpb25hbEVycm9yLCAqcHlzcWxpdGVfUHJvZ3JhbW1pbmdFcnJvciwNCiAgICAqcHlzcWxpdGVfSW50ZWdyaXR5RXJyb3IsICpweXNxbGl0ZV9EYXRhRXJyb3IsICpweXNxbGl0ZV9Ob3RTdXBwb3J0ZWRFcnJvciwgKnB5c3FsaXRlX09wdGltaXplZFVuaWNvZGU7DQoNClB5T2JqZWN0KiBjb252ZXJ0ZXJzOw0KaW50IF9lbmFibGVfY2FsbGJhY2tfdHJhY2ViYWNrczsNCmludCBweXNxbGl0ZV9CYXNlVHlwZUFkYXB0ZWQ7DQoNCnN0YXRpYyBQeU9iamVjdCogbW9kdWxlX2Nvbm5lY3QoUHlPYmplY3QqIHNlbGYsIFB5T2JqZWN0KiBhcmdzLCBQeU9iamVjdCoNCiAgICAgICAga3dhcmdzKQ0Kew0KICAgIC8qIFB5dGhvbiBzZWVtcyB0byBoYXZlIG5vIHdheSBvZiBleHRyYWN0aW5nIGEgc2luZ2xlIGtleXdvcmQtYXJnIGF0DQogICAgICogQy1sZXZlbCwgc28gdGhpcyBjb2RlIGlzIHJlZHVuZGFudCB3aXRoIHRoZSBvbmUgaW4gY29ubmVjdGlvbl9pbml0IGluDQogICAgICogY29ubmVjdGlvbi5jIGFuZCBtdXN0IGFsd2F5cyBiZSBjb3BpZWQgZnJvbSB0aGVyZSAuLi4gKi8NCg0KICAgIHN0YXRpYyBjaGFyICprd2xpc3RbXSA9IHsiZGF0YWJhc2UiLCAidGltZW91dCIsICJkZXRlY3RfdHlwZXMiLCAiaXNvbGF0aW9uX2xldmVsIiwgImNoZWNrX3NhbWVfdGhyZWFkIiwgImZhY3RvcnkiLCAiY2FjaGVkX3N0YXRlbWVudHMiLCBOVUxMLCBOVUxMfTsNCiAgICBQeU9iamVjdCogZGF0YWJhc2U7DQogICAgaW50IGRldGVjdF90eXBlcyA9IDA7DQogICAgUHlPYmplY3QqIGlzb2xhdGlvbl9sZXZlbDsNCiAgICBQeU9iamVjdCogZmFjdG9yeSA9IE5VTEw7DQogICAgaW50IGNoZWNrX3NhbWVfdGhyZWFkID0gMTsNCiAgICBpbnQgY2FjaGVkX3N0YXRlbWVudHM7DQogICAgZG91YmxlIHRpbWVvdXQgPSA1LjA7DQoNCiAgICBQeU9iamVjdCogcmVzdWx0Ow0KDQogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlQW5kS2V5d29yZHMoYXJncywga3dhcmdzLCAiT3xkaU9pT2kiLCBrd2xpc3QsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmRhdGFiYXNlLCAmdGltZW91dCwgJmRldGVjdF90eXBlcywgJmlzb2xhdGlvbl9sZXZlbCwgJmNoZWNrX3NhbWVfdGhyZWFkLCAmZmFjdG9yeSwgJmNhY2hlZF9zdGF0ZW1lbnRzKSkNCiAgICB7DQogICAgICAgIHJldHVybiBOVUxMOyANCiAgICB9DQoNCiAgICBpZiAoZmFjdG9yeSA9PSBOVUxMKSB7DQogICAgICAgIGZhY3RvcnkgPSAoUHlPYmplY3QqKSZweXNxbGl0ZV9Db25uZWN0aW9uVHlwZTsNCiAgICB9DQoNCiAgICByZXN1bHQgPSBQeU9iamVjdF9DYWxsKGZhY3RvcnksIGFyZ3MsIGt3YXJncyk7DQoNCiAgICByZXR1cm4gcmVzdWx0Ow0KfQ0KDQpQeURvY19TVFJWQVIobW9kdWxlX2Nvbm5lY3RfZG9jLA0KImNvbm5lY3QoZGF0YWJhc2VbLCB0aW1lb3V0LCBpc29sYXRpb25fbGV2ZWwsIGRldGVjdF90eXBlcywgZmFjdG9yeV0pXG5cDQpcblwNCk9wZW5zIGEgY29ubmVjdGlvbiB0byB0aGUgU1FMaXRlIGRhdGFiYXNlIGZpbGUgKmRhdGFiYXNlKi4gWW91IGNhbiB1c2VcblwNClwiOm1lbW9yeTpcIiB0byBvcGVuIGEgZGF0YWJhc2UgY29ubmVjdGlvbiB0byBhIGRhdGFiYXNlIHRoYXQgcmVzaWRlcyBpblxuXA0KUkFNIGluc3RlYWQgb2Ygb24gZGlzay4iKTsNCg0Kc3RhdGljIFB5T2JqZWN0KiBtb2R1bGVfY29tcGxldGUoUHlPYmplY3QqIHNlbGYsIFB5T2JqZWN0KiBhcmdzLCBQeU9iamVjdCoNCiAgICAgICAga3dhcmdzKQ0Kew0KICAgIHN0YXRpYyBjaGFyICprd2xpc3RbXSA9IHsic3RhdGVtZW50IiwgTlVMTCwgTlVMTH07DQogICAgY2hhciogc3RhdGVtZW50Ow0KDQogICAgUHlPYmplY3QqIHJlc3VsdDsNCg0KICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZUFuZEtleXdvcmRzKGFyZ3MsIGt3YXJncywgInMiLCBrd2xpc3QsICZzdGF0ZW1lbnQpKQ0KICAgIHsNCiAgICAgICAgcmV0dXJuIE5VTEw7IA0KICAgIH0NCg0KICAgIGlmIChzcWxpdGUzX2NvbXBsZXRlKHN0YXRlbWVudCkpIHsNCiAgICAgICAgcmVzdWx0ID0gUHlfVHJ1ZTsNCiAgICB9IGVsc2Ugew0KICAgICAgICByZXN1bHQgPSBQeV9GYWxzZTsNCiAgICB9DQoNCiAgICBQeV9JTkNSRUYocmVzdWx0KTsNCg0KICAgIHJldHVybiByZXN1bHQ7DQp9DQoNClB5RG9jX1NUUlZBUihtb2R1bGVfY29tcGxldGVfZG9jLA0KImNvbXBsZXRlX3N0YXRlbWVudChzcWwpXG5cDQpcblwNCkNoZWNrcyBpZiBhIHN0cmluZyBjb250YWlucyBhIGNvbXBsZXRlIFNRTCBzdGF0ZW1lbnQuIE5vbi1zdGFuZGFyZC4iKTsNCg0KI2lmZGVmIEhBVkVfU0hBUkVEX0NBQ0hFDQpzdGF0aWMgUHlPYmplY3QqIG1vZHVsZV9lbmFibGVfc2hhcmVkX2NhY2hlKFB5T2JqZWN0KiBzZWxmLCBQeU9iamVjdCogYXJncywgUHlPYmplY3QqDQogICAgICAgIGt3YXJncykNCnsNCiAgICBzdGF0aWMgY2hhciAqa3dsaXN0W10gPSB7ImRvX2VuYWJsZSIsIE5VTEwsIE5VTEx9Ow0KICAgIGludCBkb19lbmFibGU7DQogICAgaW50IHJjOw0KDQogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlQW5kS2V5d29yZHMoYXJncywga3dhcmdzLCAiaSIsIGt3bGlzdCwgJmRvX2VuYWJsZSkpDQogICAgew0KICAgICAgICByZXR1cm4gTlVMTDsgDQogICAgfQ0KDQogICAgcmMgPSBzcWxpdGUzX2VuYWJsZV9zaGFyZWRfY2FjaGUoZG9fZW5hYmxlKTsNCg0KICAgIGlmIChyYyAhPSBTUUxJVEVfT0spIHsNCiAgICAgICAgUHlFcnJfU2V0U3RyaW5nKHB5c3FsaXRlX09wZXJhdGlvbmFsRXJyb3IsICJDaGFuZ2luZyB0aGUgc2hhcmVkX2NhY2hlIGZsYWcgZmFpbGVkIik7DQogICAgICAgIHJldHVybiBOVUxMOw0KICAgIH0gZWxzZSB7DQogICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsNCiAgICAgICAgcmV0dXJuIFB5X05vbmU7DQogICAgfQ0KfQ0KDQpQeURvY19TVFJWQVIobW9kdWxlX2VuYWJsZV9zaGFyZWRfY2FjaGVfZG9jLA0KImVuYWJsZV9zaGFyZWRfY2FjaGUoZG9fZW5hYmxlKVxuXA0KXG5cDQpFbmFibGUgb3IgZGlzYWJsZSBzaGFyZWQgY2FjaGUgbW9kZSBmb3IgdGhlIGNhbGxpbmcgdGhyZWFkLlxuXA0KRXhwZXJpbWVudGFsL05vbi1zdGFuZGFyZC4iKTsNCiNlbmRpZiAvKiBIQVZFX1NIQVJFRF9DQUNIRSAqLw0KDQpzdGF0aWMgUHlPYmplY3QqIG1vZHVsZV9yZWdpc3Rlcl9hZGFwdGVyKFB5T2JqZWN0KiBzZWxmLCBQeU9iamVjdCogYXJncykNCnsNCiAgICBQeVR5cGVPYmplY3QqIHR5cGU7DQogICAgUHlPYmplY3QqIGNhc3RlcjsNCiAgICBpbnQgcmM7DQoNCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIk9PIiwgJnR5cGUsICZjYXN0ZXIpKSB7DQogICAgICAgIHJldHVybiBOVUxMOw0KICAgIH0NCg0KICAgIC8qIGEgYmFzaWMgdHlwZSBpcyBhZGFwdGVkOyB0aGVyZSdzIGEgcGVyZm9ybWFuY2Ugb3B0aW1pemF0aW9uIGlmIHRoYXQncyBub3QgdGhlIGNhc2UNCiAgICAgKiAoOTkgJSBvZiBhbGwgdXNhZ2VzKSAqLw0KICAgIGlmICh0eXBlID09ICZQeUludF9UeXBlIHx8IHR5cGUgPT0gJlB5TG9uZ19UeXBlIHx8IHR5cGUgPT0gJlB5RmxvYXRfVHlwZQ0KICAgICAgICAgICAgfHwgdHlwZSA9PSAmUHlTdHJpbmdfVHlwZSB8fCB0eXBlID09ICZQeVVuaWNvZGVfVHlwZSB8fCB0eXBlID09ICZQeUJ1ZmZlcl9UeXBlKSB7DQogICAgICAgIHB5c3FsaXRlX0Jhc2VUeXBlQWRhcHRlZCA9IDE7DQogICAgfQ0KDQogICAgcmMgPSBweXNxbGl0ZV9taWNyb3Byb3RvY29sc19hZGQodHlwZSwgKFB5T2JqZWN0KikmcHlzcWxpdGVfUHJlcGFyZVByb3RvY29sVHlwZSwgY2FzdGVyKTsNCiAgICBpZiAocmMgPT0gLTEpDQogICAgICAgIHJldHVybiBOVUxMOw0KDQogICAgUHlfSU5DUkVGKFB5X05vbmUpOw0KICAgIHJldHVybiBQeV9Ob25lOw0KfQ0KDQpQeURvY19TVFJWQVIobW9kdWxlX3JlZ2lzdGVyX2FkYXB0ZXJfZG9jLA0KInJlZ2lzdGVyX2FkYXB0ZXIodHlwZSwgY2FsbGFibGUpXG5cDQpcblwNClJlZ2lzdGVycyBhbiBhZGFwdGVyIHdpdGggcHlzcWxpdGUncyBhZGFwdGVyIHJlZ2lzdHJ5LiBOb24tc3RhbmRhcmQuIik7DQoNCnN0YXRpYyBQeU9iamVjdCogbW9kdWxlX3JlZ2lzdGVyX2NvbnZlcnRlcihQeU9iamVjdCogc2VsZiwgUHlPYmplY3QqIGFyZ3MpDQp7DQogICAgUHlPYmplY3QqIG9yaWdfbmFtZTsNCiAgICBQeU9iamVjdCogbmFtZSA9IE5VTEw7DQogICAgUHlPYmplY3QqIGNhbGxhYmxlOw0KICAgIFB5T2JqZWN0KiByZXR2YWwgPSBOVUxMOw0KDQogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJTTyIsICZvcmlnX25hbWUsICZjYWxsYWJsZSkpIHsNCiAgICAgICAgcmV0dXJuIE5VTEw7DQogICAgfQ0KDQogICAgLyogY29udmVydCB0aGUgbmFtZSB0byB1cHBlciBjYXNlICovDQogICAgbmFtZSA9IFB5T2JqZWN0X0NhbGxNZXRob2Qob3JpZ19uYW1lLCAidXBwZXIiLCAiIik7DQogICAgaWYgKCFuYW1lKSB7DQogICAgICAgIGdvdG8gZXJyb3I7DQogICAgfQ0KDQogICAgaWYgKFB5RGljdF9TZXRJdGVtKGNvbnZlcnRlcnMsIG5hbWUsIGNhbGxhYmxlKSAhPSAwKSB7DQogICAgICAgIGdvdG8gZXJyb3I7DQogICAgfQ0KDQogICAgUHlfSU5DUkVGKFB5X05vbmUpOw0KICAgIHJldHZhbCA9IFB5X05vbmU7DQplcnJvcjoNCiAgICBQeV9YREVDUkVGKG5hbWUpOw0KICAgIHJldHVybiByZXR2YWw7DQp9DQoNClB5RG9jX1NUUlZBUihtb2R1bGVfcmVnaXN0ZXJfY29udmVydGVyX2RvYywNCiJyZWdpc3Rlcl9jb252ZXJ0ZXIodHlwZW5hbWUsIGNhbGxhYmxlKVxuXA0KXG5cDQpSZWdpc3RlcnMgYSBjb252ZXJ0ZXIgd2l0aCBweXNxbGl0ZS4gTm9uLXN0YW5kYXJkLiIpOw0KDQpzdGF0aWMgUHlPYmplY3QqIGVuYWJsZV9jYWxsYmFja190cmFjZWJhY2tzKFB5T2JqZWN0KiBzZWxmLCBQeU9iamVjdCogYXJncykNCnsNCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgImkiLCAmX2VuYWJsZV9jYWxsYmFja190cmFjZWJhY2tzKSkgew0KICAgICAgICByZXR1cm4gTlVMTDsNCiAgICB9DQoNCiAgICBQeV9JTkNSRUYoUHlfTm9uZSk7DQogICAgcmV0dXJuIFB5X05vbmU7DQp9DQoNClB5RG9jX1NUUlZBUihlbmFibGVfY2FsbGJhY2tfdHJhY2ViYWNrc19kb2MsDQoiZW5hYmxlX2NhbGxiYWNrX3RyYWNlYmFja3MoZmxhZylcblwNClxuXA0KRW5hYmxlIG9yIGRpc2FibGUgY2FsbGJhY2sgZnVuY3Rpb25zIHRocm93aW5nIGVycm9ycyB0byBzdGRlcnIuIik7DQoNCnN0YXRpYyB2b2lkIGNvbnZlcnRlcnNfaW5pdChQeU9iamVjdCogZGljdCkNCnsNCiAgICBjb252ZXJ0ZXJzID0gUHlEaWN0X05ldygpOw0KICAgIGlmICghY29udmVydGVycykgew0KICAgICAgICByZXR1cm47DQogICAgfQ0KDQogICAgUHlEaWN0X1NldEl0ZW1TdHJpbmcoZGljdCwgImNvbnZlcnRlcnMiLCBjb252ZXJ0ZXJzKTsNCn0NCg0Kc3RhdGljIFB5TWV0aG9kRGVmIG1vZHVsZV9tZXRob2RzW10gPSB7DQogICAgeyJjb25uZWN0IiwgIChQeUNGdW5jdGlvbiltb2R1bGVfY29ubmVjdCwNCiAgICAgTUVUSF9WQVJBUkdTIHwgTUVUSF9LRVlXT1JEUywgbW9kdWxlX2Nvbm5lY3RfZG9jfSwNCiAgICB7ImNvbXBsZXRlX3N0YXRlbWVudCIsICAoUHlDRnVuY3Rpb24pbW9kdWxlX2NvbXBsZXRlLA0KICAgICBNRVRIX1ZBUkFSR1MgfCBNRVRIX0tFWVdPUkRTLCBtb2R1bGVfY29tcGxldGVfZG9jfSwNCiNpZmRlZiBIQVZFX1NIQVJFRF9DQUNIRQ0KICAgIHsiZW5hYmxlX3NoYXJlZF9jYWNoZSIsICAoUHlDRnVuY3Rpb24pbW9kdWxlX2VuYWJsZV9zaGFyZWRfY2FjaGUsDQogICAgIE1FVEhfVkFSQVJHUyB8IE1FVEhfS0VZV09SRFMsIG1vZHVsZV9lbmFibGVfc2hhcmVkX2NhY2hlX2RvY30sDQojZW5kaWYNCiAgICB7InJlZ2lzdGVyX2FkYXB0ZXIiLCAoUHlDRnVuY3Rpb24pbW9kdWxlX3JlZ2lzdGVyX2FkYXB0ZXIsDQogICAgIE1FVEhfVkFSQVJHUywgbW9kdWxlX3JlZ2lzdGVyX2FkYXB0ZXJfZG9jfSwNCiAgICB7InJlZ2lzdGVyX2NvbnZlcnRlciIsIChQeUNGdW5jdGlvbiltb2R1bGVfcmVnaXN0ZXJfY29udmVydGVyLA0KICAgICBNRVRIX1ZBUkFSR1MsIG1vZHVsZV9yZWdpc3Rlcl9jb252ZXJ0ZXJfZG9jfSwNCiAgICB7ImFkYXB0IiwgIChQeUNGdW5jdGlvbilweXNxbGl0ZV9hZGFwdCwgTUVUSF9WQVJBUkdTLA0KICAgICBweXNxbGl0ZV9hZGFwdF9kb2N9LA0KICAgIHsiZW5hYmxlX2NhbGxiYWNrX3RyYWNlYmFja3MiLCAgKFB5Q0Z1bmN0aW9uKWVuYWJsZV9jYWxsYmFja190cmFjZWJhY2tzLA0KICAgICBNRVRIX1ZBUkFSR1MsIGVuYWJsZV9jYWxsYmFja190cmFjZWJhY2tzX2RvY30sDQogICAge05VTEwsIE5VTEx9DQp9Ow0KDQpzdHJ1Y3QgX0ludENvbnN0YW50UGFpciB7DQogICAgY2hhciogY29uc3RhbnRfbmFtZTsNCiAgICBpbnQgY29uc3RhbnRfdmFsdWU7DQp9Ow0KDQp0eXBlZGVmIHN0cnVjdCBfSW50Q29uc3RhbnRQYWlyIEludENvbnN0YW50UGFpcjsNCg0Kc3RhdGljIEludENvbnN0YW50UGFpciBfaW50X2NvbnN0YW50c1tdID0gew0KICAgIHsiUEFSU0VfREVDTFRZUEVTIiwgUEFSU0VfREVDTFRZUEVTfSwNCiAgICB7IlBBUlNFX0NPTE5BTUVTIiwgUEFSU0VfQ09MTkFNRVN9LA0KDQogICAgeyJTUUxJVEVfT0siLCBTUUxJVEVfT0t9LA0KICAgIHsiU1FMSVRFX0RFTlkiLCBTUUxJVEVfREVOWX0sDQogICAgeyJTUUxJVEVfSUdOT1JFIiwgU1FMSVRFX0lHTk9SRX0sDQogICAgeyJTUUxJVEVfQ1JFQVRFX0lOREVYIiwgU1FMSVRFX0NSRUFURV9JTkRFWH0sDQogICAgeyJTUUxJVEVfQ1JFQVRFX1RBQkxFIiwgU1FMSVRFX0NSRUFURV9UQUJMRX0sDQogICAgeyJTUUxJVEVfQ1JFQVRFX1RFTVBfSU5ERVgiLCBTUUxJVEVfQ1JFQVRFX1RFTVBfSU5ERVh9LA0KICAgIHsiU1FMSVRFX0NSRUFURV9URU1QX1RBQkxFIiwgU1FMSVRFX0NSRUFURV9URU1QX1RBQkxFfSwNCiAgICB7IlNRTElURV9DUkVBVEVfVEVNUF9UUklHR0VSIiwgU1FMSVRFX0NSRUFURV9URU1QX1RSSUdHRVJ9LA0KICAgIHsiU1FMSVRFX0NSRUFURV9URU1QX1ZJRVciLCBTUUxJVEVfQ1JFQVRFX1RFTVBfVklFV30sDQogICAgeyJTUUxJVEVfQ1JFQVRFX1RSSUdHRVIiLCBTUUxJVEVfQ1JFQVRFX1RSSUdHRVJ9LA0KICAgIHsiU1FMSVRFX0NSRUFURV9WSUVXIiwgU1FMSVRFX0NSRUFURV9WSUVXfSwNCiAgICB7IlNRTElURV9ERUxFVEUiLCBTUUxJVEVfREVMRVRFfSwNCiAgICB7IlNRTElURV9EUk9QX0lOREVYIiwgU1FMSVRFX0RST1BfSU5ERVh9LA0KICAgIHsiU1FMSVRFX0RST1BfVEFCTEUiLCBTUUxJVEVfRFJPUF9UQUJMRX0sDQogICAgeyJTUUxJVEVfRFJPUF9URU1QX0lOREVYIiwgU1FMSVRFX0RST1BfVEVNUF9JTkRFWH0sDQogICAgeyJTUUxJVEVfRFJPUF9URU1QX1RBQkxFIiwgU1FMSVRFX0RST1BfVEVNUF9UQUJMRX0sDQogICAgeyJTUUxJVEVfRFJPUF9URU1QX1RSSUdHRVIiLCBTUUxJVEVfRFJPUF9URU1QX1RSSUdHRVJ9LA0KICAgIHsiU1FMSVRFX0RST1BfVEVNUF9WSUVXIiwgU1FMSVRFX0RST1BfVEVNUF9WSUVXfSwNCiAgICB7IlNRTElURV9EUk9QX1RSSUdHRVIiLCBTUUxJVEVfRFJPUF9UUklHR0VSfSwNCiAgICB7IlNRTElURV9EUk9QX1ZJRVciLCBTUUxJVEVfRFJPUF9WSUVXfSwNCiAgICB7IlNRTElURV9JTlNFUlQiLCBTUUxJVEVfSU5TRVJUfSwNCiAgICB7IlNRTElURV9QUkFHTUEiLCBTUUxJVEVfUFJBR01BfSwNCiAgICB7IlNRTElURV9SRUFEIiwgU1FMSVRFX1JFQUR9LA0KICAgIHsiU1FMSVRFX1NFTEVDVCIsIFNRTElURV9TRUxFQ1R9LA0KICAgIHsiU1FMSVRFX1RSQU5TQUNUSU9OIiwgU1FMSVRFX1RSQU5TQUNUSU9OfSwNCiAgICB7IlNRTElURV9VUERBVEUiLCBTUUxJVEVfVVBEQVRFfSwNCiAgICB7IlNRTElURV9BVFRBQ0giLCBTUUxJVEVfQVRUQUNIfSwNCiAgICB7IlNRTElURV9ERVRBQ0giLCBTUUxJVEVfREVUQUNIfSwNCiNpZiBTUUxJVEVfVkVSU0lPTl9OVU1CRVIgPj0gMzAwMjAwMQ0KICAgIHsiU1FMSVRFX0FMVEVSX1RBQkxFIiwgU1FMSVRFX0FMVEVSX1RBQkxFfSwNCiAgICB7IlNRTElURV9SRUlOREVYIiwgU1FMSVRFX1JFSU5ERVh9LA0KI2VuZGlmDQojaWYgU1FMSVRFX1ZFUlNJT05fTlVNQkVSID49IDMwMDMwMDANCiAgICB7IlNRTElURV9BTkFMWVpFIiwgU1FMSVRFX0FOQUxZWkV9LA0KI2VuZGlmDQogICAgeyhjaGFyKilOVUxMLCAwfQ0KfTsNCg0KUHlNT0RJTklUX0ZVTkMgaW5pdF9zcWxpdGUzKHZvaWQpDQp7DQogICAgUHlPYmplY3QgKm1vZHVsZSwgKmRpY3Q7DQogICAgUHlPYmplY3QgKnRtcF9vYmo7DQogICAgaW50IGk7DQoNCiAgICBtb2R1bGUgPSBQeV9Jbml0TW9kdWxlKCJfc3FsaXRlMyIsIG1vZHVsZV9tZXRob2RzKTsNCg0KICAgIGlmICghbW9kdWxlIHx8DQogICAgICAgIChweXNxbGl0ZV9yb3dfc2V0dXBfdHlwZXMoKSA8IDApIHx8DQogICAgICAgIChweXNxbGl0ZV9jdXJzb3Jfc2V0dXBfdHlwZXMoKSA8IDApIHx8DQogICAgICAgIChweXNxbGl0ZV9jb25uZWN0aW9uX3NldHVwX3R5cGVzKCkgPCAwKSB8fA0KICAgICAgICAocHlzcWxpdGVfY2FjaGVfc2V0dXBfdHlwZXMoKSA8IDApIHx8DQogICAgICAgIChweXNxbGl0ZV9zdGF0ZW1lbnRfc2V0dXBfdHlwZXMoKSA8IDApIHx8DQogICAgICAgIChweXNxbGl0ZV9wcmVwYXJlX3Byb3RvY29sX3NldHVwX3R5cGVzKCkgPCAwKQ0KICAgICAgICkgew0KICAgICAgICByZXR1cm47DQogICAgfQ0KDQogICAgUHlfSU5DUkVGKCZweXNxbGl0ZV9Db25uZWN0aW9uVHlwZSk7DQogICAgUHlNb2R1bGVfQWRkT2JqZWN0KG1vZHVsZSwgIkNvbm5lY3Rpb24iLCAoUHlPYmplY3QqKSAmcHlzcWxpdGVfQ29ubmVjdGlvblR5cGUpOw0KICAgIFB5X0lOQ1JFRigmcHlzcWxpdGVfQ3Vyc29yVHlwZSk7DQogICAgUHlNb2R1bGVfQWRkT2JqZWN0KG1vZHVsZSwgIkN1cnNvciIsIChQeU9iamVjdCopICZweXNxbGl0ZV9DdXJzb3JUeXBlKTsNCiAgICBQeV9JTkNSRUYoJnB5c3FsaXRlX0NhY2hlVHlwZSk7DQogICAgUHlNb2R1bGVfQWRkT2JqZWN0KG1vZHVsZSwgIlN0YXRlbWVudCIsIChQeU9iamVjdCopJnB5c3FsaXRlX1N0YXRlbWVudFR5cGUpOw0KICAgIFB5X0lOQ1JFRigmcHlzcWxpdGVfU3RhdGVtZW50VHlwZSk7DQogICAgUHlNb2R1bGVfQWRkT2JqZWN0KG1vZHVsZSwgIkNhY2hlIiwgKFB5T2JqZWN0KikgJnB5c3FsaXRlX0NhY2hlVHlwZSk7DQogICAgUHlfSU5DUkVGKCZweXNxbGl0ZV9QcmVwYXJlUHJvdG9jb2xUeXBlKTsNCiAgICBQeU1vZHVsZV9BZGRPYmplY3QobW9kdWxlLCAiUHJlcGFyZVByb3RvY29sIiwgKFB5T2JqZWN0KikgJnB5c3FsaXRlX1ByZXBhcmVQcm90b2NvbFR5cGUpOw0KICAgIFB5X0lOQ1JFRigmcHlzcWxpdGVfUm93VHlwZSk7DQogICAgUHlNb2R1bGVfQWRkT2JqZWN0KG1vZHVsZSwgIlJvdyIsIChQeU9iamVjdCopICZweXNxbGl0ZV9Sb3dUeXBlKTsNCg0KICAgIGlmICghKGRpY3QgPSBQeU1vZHVsZV9HZXREaWN0KG1vZHVsZSkpKSB7DQogICAgICAgIGdvdG8gZXJyb3I7DQogICAgfQ0KDQogICAgLyoqKiBDcmVhdGUgREItQVBJIEV4Y2VwdGlvbiBoaWVyYXJjaHkgKi8NCg0KICAgIGlmICghKHB5c3FsaXRlX0Vycm9yID0gUHlFcnJfTmV3RXhjZXB0aW9uKE1PRFVMRV9OQU1FICIuRXJyb3IiLCBQeUV4Y19TdGFuZGFyZEVycm9yLCBOVUxMKSkpIHsNCiAgICAgICAgZ290byBlcnJvcjsNCiAgICB9DQogICAgUHlEaWN0X1NldEl0ZW1TdHJpbmcoZGljdCwgIkVycm9yIiwgcHlzcWxpdGVfRXJyb3IpOw0KDQogICAgaWYgKCEocHlzcWxpdGVfV2FybmluZyA9IFB5RXJyX05ld0V4Y2VwdGlvbihNT0RVTEVfTkFNRSAiLldhcm5pbmciLCBQeUV4Y19TdGFuZGFyZEVycm9yLCBOVUxMKSkpIHsNCiAgICAgICAgZ290byBlcnJvcjsNCiAgICB9DQogICAgUHlEaWN0X1NldEl0ZW1TdHJpbmcoZGljdCwgIldhcm5pbmciLCBweXNxbGl0ZV9XYXJuaW5nKTsNCg0KICAgIC8qIEVycm9yIHN1YmNsYXNzZXMgKi8NCg0KICAgIGlmICghKHB5c3FsaXRlX0ludGVyZmFjZUVycm9yID0gUHlFcnJfTmV3RXhjZXB0aW9uKE1PRFVMRV9OQU1FICIuSW50ZXJmYWNlRXJyb3IiLCBweXNxbGl0ZV9FcnJvciwgTlVMTCkpKSB7DQogICAgICAgIGdvdG8gZXJyb3I7DQogICAgfQ0KICAgIFB5RGljdF9TZXRJdGVtU3RyaW5nKGRpY3QsICJJbnRlcmZhY2VFcnJvciIsIHB5c3FsaXRlX0ludGVyZmFjZUVycm9yKTsNCg0KICAgIGlmICghKHB5c3FsaXRlX0RhdGFiYXNlRXJyb3IgPSBQeUVycl9OZXdFeGNlcHRpb24oTU9EVUxFX05BTUUgIi5EYXRhYmFzZUVycm9yIiwgcHlzcWxpdGVfRXJyb3IsIE5VTEwpKSkgew0KICAgICAgICBnb3RvIGVycm9yOw0KICAgIH0NCiAgICBQeURpY3RfU2V0SXRlbVN0cmluZyhkaWN0LCAiRGF0YWJhc2VFcnJvciIsIHB5c3FsaXRlX0RhdGFiYXNlRXJyb3IpOw0KDQogICAgLyogcHlzcWxpdGVfRGF0YWJhc2VFcnJvciBzdWJjbGFzc2VzICovDQoNCiAgICBpZiAoIShweXNxbGl0ZV9JbnRlcm5hbEVycm9yID0gUHlFcnJfTmV3RXhjZXB0aW9uKE1PRFVMRV9OQU1FICIuSW50ZXJuYWxFcnJvciIsIHB5c3FsaXRlX0RhdGFiYXNlRXJyb3IsIE5VTEwpKSkgew0KICAgICAgICBnb3RvIGVycm9yOw0KICAgIH0NCiAgICBQeURpY3RfU2V0SXRlbVN0cmluZyhkaWN0LCAiSW50ZXJuYWxFcnJvciIsIHB5c3FsaXRlX0ludGVybmFsRXJyb3IpOw0KDQogICAgaWYgKCEocHlzcWxpdGVfT3BlcmF0aW9uYWxFcnJvciA9IFB5RXJyX05ld0V4Y2VwdGlvbihNT0RVTEVfTkFNRSAiLk9wZXJhdGlvbmFsRXJyb3IiLCBweXNxbGl0ZV9EYXRhYmFzZUVycm9yLCBOVUxMKSkpIHsNCiAgICAgICAgZ290byBlcnJvcjsNCiAgICB9DQogICAgUHlEaWN0X1NldEl0ZW1TdHJpbmcoZGljdCwgIk9wZXJhdGlvbmFsRXJyb3IiLCBweXNxbGl0ZV9PcGVyYXRpb25hbEVycm9yKTsNCg0KICAgIGlmICghKHB5c3FsaXRlX1Byb2dyYW1taW5nRXJyb3IgPSBQeUVycl9OZXdFeGNlcHRpb24oTU9EVUxFX05BTUUgIi5Qcm9ncmFtbWluZ0Vycm9yIiwgcHlzcWxpdGVfRGF0YWJhc2VFcnJvciwgTlVMTCkpKSB7DQogICAgICAgIGdvdG8gZXJyb3I7DQogICAgfQ0KICAgIFB5RGljdF9TZXRJdGVtU3RyaW5nKGRpY3QsICJQcm9ncmFtbWluZ0Vycm9yIiwgcHlzcWxpdGVfUHJvZ3JhbW1pbmdFcnJvcik7DQoNCiAgICBpZiAoIShweXNxbGl0ZV9JbnRlZ3JpdHlFcnJvciA9IFB5RXJyX05ld0V4Y2VwdGlvbihNT0RVTEVfTkFNRSAiLkludGVncml0eUVycm9yIiwgcHlzcWxpdGVfRGF0YWJhc2VFcnJvcixOVUxMKSkpIHsNCiAgICAgICAgZ290byBlcnJvcjsNCiAgICB9DQogICAgUHlEaWN0X1NldEl0ZW1TdHJpbmcoZGljdCwgIkludGVncml0eUVycm9yIiwgcHlzcWxpdGVfSW50ZWdyaXR5RXJyb3IpOw0KDQogICAgaWYgKCEocHlzcWxpdGVfRGF0YUVycm9yID0gUHlFcnJfTmV3RXhjZXB0aW9uKE1PRFVMRV9OQU1FICIuRGF0YUVycm9yIiwgcHlzcWxpdGVfRGF0YWJhc2VFcnJvciwgTlVMTCkpKSB7DQogICAgICAgIGdvdG8gZXJyb3I7DQogICAgfQ0KICAgIFB5RGljdF9TZXRJdGVtU3RyaW5nKGRpY3QsICJEYXRhRXJyb3IiLCBweXNxbGl0ZV9EYXRhRXJyb3IpOw0KDQogICAgaWYgKCEocHlzcWxpdGVfTm90U3VwcG9ydGVkRXJyb3IgPSBQeUVycl9OZXdFeGNlcHRpb24oTU9EVUxFX05BTUUgIi5Ob3RTdXBwb3J0ZWRFcnJvciIsIHB5c3FsaXRlX0RhdGFiYXNlRXJyb3IsIE5VTEwpKSkgew0KICAgICAgICBnb3RvIGVycm9yOw0KICAgIH0NCiAgICBQeURpY3RfU2V0SXRlbVN0cmluZyhkaWN0LCAiTm90U3VwcG9ydGVkRXJyb3IiLCBweXNxbGl0ZV9Ob3RTdXBwb3J0ZWRFcnJvcik7DQoNCiAgICAvKiBXZSBqdXN0IG5lZWQgInNvbWV0aGluZyIgdW5pcXVlIGZvciBweXNxbGl0ZV9PcHRpbWl6ZWRVbmljb2RlLiBJdCBkb2VzIG5vdCByZWFsbHkNCiAgICAgKiBuZWVkIHRvIGJlIGEgc3RyaW5nIHN1YmNsYXNzLiBKdXN0IGFueXRoaW5nIHRoYXQgY2FuIGFjdCBhcyBhIHNwZWNpYWwNCiAgICAgKiBtYXJrZXIgZm9yIHVzLiBTbyBJIHB1bGxlZCBQeUNlbGxfVHlwZSBvdXQgb2YgbXkgbWFnaWMgaGF0Lg0KICAgICAqLw0KICAgIFB5X0lOQ1JFRigoUHlPYmplY3QqKSZQeUNlbGxfVHlwZSk7DQogICAgcHlzcWxpdGVfT3B0aW1pemVkVW5pY29kZSA9IChQeU9iamVjdCopJlB5Q2VsbF9UeXBlOw0KICAgIFB5RGljdF9TZXRJdGVtU3RyaW5nKGRpY3QsICJPcHRpbWl6ZWRVbmljb2RlIiwgcHlzcWxpdGVfT3B0aW1pemVkVW5pY29kZSk7DQoNCiAgICAvKiBTZXQgaW50ZWdlciBjb25zdGFudHMgKi8NCiAgICBmb3IgKGkgPSAwOyBfaW50X2NvbnN0YW50c1tpXS5jb25zdGFudF9uYW1lICE9IDA7IGkrKykgew0KICAgICAgICB0bXBfb2JqID0gUHlJbnRfRnJvbUxvbmcoX2ludF9jb25zdGFudHNbaV0uY29uc3RhbnRfdmFsdWUpOw0KICAgICAgICBpZiAoIXRtcF9vYmopIHsNCiAgICAgICAgICAgIGdvdG8gZXJyb3I7DQogICAgICAgIH0NCiAgICAgICAgUHlEaWN0X1NldEl0ZW1TdHJpbmcoZGljdCwgX2ludF9jb25zdGFudHNbaV0uY29uc3RhbnRfbmFtZSwgdG1wX29iaik7DQogICAgICAgIFB5X0RFQ1JFRih0bXBfb2JqKTsNCiAgICB9DQoNCiAgICBpZiAoISh0bXBfb2JqID0gUHlTdHJpbmdfRnJvbVN0cmluZyhQWVNRTElURV9WRVJTSU9OKSkpIHsNCiAgICAgICAgZ290byBlcnJvcjsNCiAgICB9DQogICAgUHlEaWN0X1NldEl0ZW1TdHJpbmcoZGljdCwgInZlcnNpb24iLCB0bXBfb2JqKTsNCiAgICBQeV9ERUNSRUYodG1wX29iaik7DQoNCiAgICBpZiAoISh0bXBfb2JqID0gUHlTdHJpbmdfRnJvbVN0cmluZyhzcWxpdGUzX2xpYnZlcnNpb24oKSkpKSB7DQogICAgICAgIGdvdG8gZXJyb3I7DQogICAgfQ0KICAgIFB5RGljdF9TZXRJdGVtU3RyaW5nKGRpY3QsICJzcWxpdGVfdmVyc2lvbiIsIHRtcF9vYmopOw0KICAgIFB5X0RFQ1JFRih0bXBfb2JqKTsNCg0KICAgIC8qIGluaXRpYWxpemUgbWljcm9wcm90b2NvbHMgbGF5ZXIgKi8NCiAgICBweXNxbGl0ZV9taWNyb3Byb3RvY29sc19pbml0KGRpY3QpOw0KDQogICAgLyogaW5pdGlhbGl6ZSB0aGUgZGVmYXVsdCBjb252ZXJ0ZXJzICovDQogICAgY29udmVydGVyc19pbml0KGRpY3QpOw0KDQogICAgX2VuYWJsZV9jYWxsYmFja190cmFjZWJhY2tzID0gMDsNCg0KICAgIHB5c3FsaXRlX0Jhc2VUeXBlQWRhcHRlZCA9IDA7DQoNCiAgICAvKiBPcmlnaW5hbCBjb21tZW50IGZyb20gX2JzZGRiLmMgaW4gdGhlIFB5dGhvbiBjb3JlLiBUaGlzIGlzIGFsc28gc3RpbGwNCiAgICAgKiBuZWVkZWQgbm93YWRheXMgZm9yIFB5dGhvbiAyLjMvMi40Lg0KICAgICAqIA0KICAgICAqIFB5RXZhbF9Jbml0VGhyZWFkcyBpcyBjYWxsZWQgaGVyZSBkdWUgdG8gYSBxdWlyayBpbiBweXRob24gMS41DQogICAgICogLSAyLjIuMSAoYXQgbGVhc3QpIGFjY29yZGluZyB0byBSdXNzZWxsIFdpbGxpYW1zb24gPG1lcmVsQHd0Lm5ldD46DQogICAgICogVGhlIGdsb2JhbCBpbnRlcnByZXRlciBsb2NrIGlzIG5vdCBpbml0aWFsaXplZCB1bnRpbCB0aGUgZmlyc3QNCiAgICAgKiB0aHJlYWQgaXMgY3JlYXRlZCB1c2luZyB0aHJlYWQuc3RhcnRfbmV3X3RocmVhZCgpIG9yIGZvcmsoKSBpcw0KICAgICAqIGNhbGxlZC4gIHRoYXQgd291bGQgY2F1c2UgdGhlIEFMTE9XX1RIUkVBRFMgaGVyZSB0byBzZWdmYXVsdCBkdWUNCiAgICAgKiB0byBhIG51bGwgcG9pbnRlciByZWZlcmVuY2UgaWYgbm8gdGhyZWFkcyBvciBjaGlsZCBwcm9jZXNzZXMNCiAgICAgKiBoYXZlIGJlZW4gY3JlYXRlZC4gIFRoaXMgd29ya3MgYXJvdW5kIHRoYXQgYW5kIGlzIGEgbm8tb3AgaWYNCiAgICAgKiB0aHJlYWRzIGhhdmUgYWxyZWFkeSBiZWVuIGluaXRpYWxpemVkLg0KICAgICAqICAoc2VlIHB5YnNkZGItdXNlcnMgbWFpbGluZyBsaXN0IHBvc3Qgb24gMjAwMi0wOC0wNykNCiAgICAgKi8NCiNpZmRlZiBXSVRIX1RIUkVBRA0KICAgIFB5RXZhbF9Jbml0VGhyZWFkcygpOw0KI2VuZGlmDQoNCmVycm9yOg0KICAgIGlmIChQeUVycl9PY2N1cnJlZCgpKQ0KICAgIHsNCiAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX0ltcG9ydEVycm9yLCBNT0RVTEVfTkFNRSAiOiBpbml0IGZhaWxlZCIpOw0KICAgIH0NCn0NCg==