Ly8gQ29weXJpZ2h0IDIwMDggQ2hyaXN0b3BoZSBIZW5yeQovLyBoZW5yeSBVTkRFUlNDT1JFIGNocmlzdG9waGUgQVQgaG90bWFpbCBET1QgY29tCi8vIFRoaXMgaXMgYW4gZXh0ZW5kZWQgdmVyc2lvbiBvZiB0aGUgc3RhdGUgbWFjaGluZSBhdmFpbGFibGUgaW4gdGhlIGJvb3N0OjptcGwgbGlicmFyeQovLyBEaXN0cmlidXRlZCB1bmRlciB0aGUgc2FtZSBsaWNlbnNlIGFzIHRoZSBvcmlnaW5hbC4KLy8gQ29weXJpZ2h0IGZvciB0aGUgb3JpZ2luYWwgdmVyc2lvbjoKLy8gQ29weXJpZ2h0IDIwMDUgRGF2aWQgQWJyYWhhbXMgYW5kIEFsZWtzZXkgR3VydG92b3kuIERpc3RyaWJ1dGVkCi8vIHVuZGVyIHRoZSBCb29zdCBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMC4gKFNlZSBhY2NvbXBhbnlpbmcKLy8gZmlsZSBMSUNFTlNFXzFfMC50eHQgb3IgY29weSBhdAovLyBodHRwOi8vd3d3LmJvb3N0Lm9yZy9MSUNFTlNFXzFfMC50eHQpCgojaWZuZGVmIEJPT1NUX01TTV9CQUNLX1NUQVRFTUFDSElORV9ICiNkZWZpbmUgQk9PU1RfTVNNX0JBQ0tfU1RBVEVNQUNISU5FX0gKCiNpbmNsdWRlIDxleGNlcHRpb24+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDxxdWV1ZT4KI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDxudW1lcmljPgojaW5jbHVkZSA8dXRpbGl0eT4KCiNkZWZpbmUgQk9PU1RfTVBMX0NGR19OT19QUkVQUk9DRVNTRURfSEVBREVSUwoKI2luY2x1ZGUgPGJvb3N0L21wbC9jb250YWlucy5ocHA+CiNpbmNsdWRlIDxib29zdC9tcGwvZGVyZWYuaHBwPgoKI2luY2x1ZGUgPGJvb3N0L2Z1c2lvbi9jb250YWluZXIvdmVjdG9yL2NvbnZlcnQuaHBwPgojaW5jbHVkZSA8Ym9vc3QvZnVzaW9uL2luY2x1ZGUvYXNfdmVjdG9yLmhwcD4KI2luY2x1ZGUgPGJvb3N0L2Z1c2lvbi9pbmNsdWRlL2FzX3NldC5ocHA+CiNpbmNsdWRlIDxib29zdC9mdXNpb24vY29udGFpbmVyL3NldC5ocHA+CiNpbmNsdWRlIDxib29zdC9mdXNpb24vaW5jbHVkZS9zZXQuaHBwPgojaW5jbHVkZSA8Ym9vc3QvZnVzaW9uL2luY2x1ZGUvc2V0X2Z3ZC5ocHA+CiNpbmNsdWRlIDxib29zdC9mdXNpb24vaW5jbHVkZS9tcGwuaHBwPgojaW5jbHVkZSA8Ym9vc3QvZnVzaW9uL3NlcXVlbmNlL2ludHJpbnNpYy9hdF9rZXkuaHBwPgojaW5jbHVkZSA8Ym9vc3QvZnVzaW9uL2luY2x1ZGUvYXRfa2V5LmhwcD4KI2luY2x1ZGUgPGJvb3N0L2Z1c2lvbi9hbGdvcml0aG0vaXRlcmF0aW9uL2Zvcl9lYWNoLmhwcD4KI2luY2x1ZGUgPGJvb3N0L2Z1c2lvbi9pbmNsdWRlL2Zvcl9lYWNoLmhwcD4KCiNpbmNsdWRlIDxib29zdC9hc3NlcnQuaHBwPgojaW5jbHVkZSA8Ym9vc3QvcmVmLmhwcD4KI2luY2x1ZGUgPGJvb3N0L3R5cGVfdHJhaXRzLmhwcD4KI2luY2x1ZGUgPGJvb3N0L3V0aWxpdHkvZW5hYmxlX2lmLmhwcD4KI2luY2x1ZGUgPGJvb3N0L3R5cGVfdHJhaXRzL2lzX2NvbnZlcnRpYmxlLmhwcD4KCiNpbmNsdWRlIDxib29zdC9iaW5kLmhwcD4KI2luY2x1ZGUgPGJvb3N0L2JpbmQvYXBwbHkuaHBwPgojaW5jbHVkZSA8Ym9vc3QvZnVuY3Rpb24uaHBwPgojaWZuZGVmIEJPT1NUX05PX1JUVEkKI2luY2x1ZGUgPGJvb3N0L2FueS5ocHA+CiNlbmRpZgoKI2luY2x1ZGUgPGJvb3N0L3NlcmlhbGl6YXRpb24vYmFzZV9vYmplY3QuaHBwPiAKCiNpbmNsdWRlIDxib29zdC9tc20vcm93X3RhZ3MuaHBwPgojaW5jbHVkZSA8Ym9vc3QvbXNtL2JhY2svZm9sZF90b19saXN0LmhwcD4KI2luY2x1ZGUgPGJvb3N0L21zbS9iYWNrL21ldGFmdW5jdGlvbnMuaHBwPgojaW5jbHVkZSA8Ym9vc3QvbXNtL2JhY2svaGlzdG9yeV9wb2xpY2llcy5ocHA+CiNpbmNsdWRlIDxib29zdC9tc20vYmFjay9iaW5kX2hlbHBlcnMuaHBwPgojaW5jbHVkZSA8Ym9vc3QvbXNtL2JhY2svY29tbW9uX3R5cGVzLmhwcD4KI2luY2x1ZGUgPGJvb3N0L21zbS9iYWNrL2FyZ3MuaHBwPgojaW5jbHVkZSA8Ym9vc3QvbXNtL2JhY2svZGVmYXVsdF9jb21waWxlX3BvbGljeS5ocHA+CiNpbmNsdWRlIDxib29zdC9tc20vYmFjay9kaXNwYXRjaF90YWJsZS5ocHA+CgpCT09TVF9NUExfSEFTX1hYWF9UUkFJVF9ERUYoYWNjZXB0X3NpZykKQk9PU1RfTVBMX0hBU19YWFhfVFJBSVRfREVGKG5vX2F1dG9tYXRpY19jcmVhdGUpCkJPT1NUX01QTF9IQVNfWFhYX1RSQUlUX0RFRihub25fZm9yd2FyZGluZ19mbGFnKQpCT09TVF9NUExfSEFTX1hYWF9UUkFJVF9ERUYoZGlyZWN0X2VudHJ5KQpCT09TVF9NUExfSEFTX1hYWF9UUkFJVF9ERUYoaW5pdGlhbF9ldmVudCkKQk9PU1RfTVBMX0hBU19YWFhfVFJBSVRfREVGKGRvX3NlcmlhbGl6ZSkKCiNpZm5kZWYgQk9PU1RfTVNNX0NPTlNUUlVDVE9SX0FSR19TSVpFCiNkZWZpbmUgQk9PU1RfTVNNX0NPTlNUUlVDVE9SX0FSR19TSVpFIDUgLy8gZGVmYXVsdCBtYXggbnVtYmVyIG9mIGFyZ3VtZW50cyBmb3IgY29uc3RydWN0b3JzCiNlbmRpZgoKbmFtZXNwYWNlIGJvb3N0IHsgbmFtZXNwYWNlIG1zbSB7IG5hbWVzcGFjZSBiYWNrCnsKLy8gZXZlbnQgdXNlZCBpbnRlcm5hbGx5IGZvciB3cmFwcGluZyBhIGRpcmVjdCBlbnRyeQp0ZW1wbGF0ZSA8Y2xhc3MgU3RhdGVUeXBlLGNsYXNzIEV2ZW50PgpzdHJ1Y3QgZGlyZWN0X2VudHJ5X2V2ZW50IAp7CiAgICB0eXBlZGVmIGludCBkaXJlY3RfZW50cnk7CiAgICB0eXBlZGVmIFN0YXRlVHlwZSBhY3RpdmVfc3RhdGU7CgogICAgZGlyZWN0X2VudHJ5X2V2ZW50KEV2ZW50IGNvbnN0JiBldnQpOm1fZXZlbnQoZXZ0KXt9CiAgICBFdmVudCBjb25zdCYgbV9ldmVudDsKfTsKCi8vIFRoaXMgZGVjbGFyZXMgdGhlIHN0YXRpY2FsbHktaW5pdGlhbGl6ZWQgZGlzcGF0Y2hfdGFibGUgaW5zdGFuY2UuCnRlbXBsYXRlIDxjbGFzcyBGc20sY2xhc3MgU3R0LCBjbGFzcyBFdmVudCxjbGFzcyBDb21waWxlUG9saWN5Pgpjb25zdCBib29zdDo6bXNtOjpiYWNrOjpkaXNwYXRjaF90YWJsZTxGc20sU3R0LCBFdmVudCxDb21waWxlUG9saWN5PgpkaXNwYXRjaF90YWJsZTxGc20sU3R0LCBFdmVudCxDb21waWxlUG9saWN5Pjo6aW5zdGFuY2U7CgoKLy8gbGlicmFyeS1jb250YWluaW5nIGNsYXNzIGZvciBzdGF0ZSBtYWNoaW5lcy4gIFBhc3MgdGhlIGFjdHVhbCBGU00gY2xhc3MgYXMKLy8gdGhlIENvbmNyZXRlIHBhcmFtZXRlci4KdGVtcGxhdGU8Y2xhc3MgRGVyaXZlZCxjbGFzcyBIaXN0b3J5UG9saWN5PU5vSGlzdG9yeSxjbGFzcyBDb21waWxlUG9saWN5PWZhdm9yX3J1bnRpbWVfc3BlZWQ+CmNsYXNzIHN0YXRlX21hY2hpbmUgOiBwdWJsaWMgRGVyaXZlZAp7CnByaXZhdGU6IAogICAgdHlwZWRlZiBib29zdDo6bXNtOjpiYWNrOjpzdGF0ZV9tYWNoaW5lPERlcml2ZWQsCiAgICAgICAgSGlzdG9yeVBvbGljeSxDb21waWxlUG9saWN5PiAgICAgICAgICAgICAgICBsaWJyYXJ5X3NtOwoKICAgIHR5cGVkZWYgOjpib29zdDo6ZnVuY3Rpb248CiAgICAgICAgZXhlY3V0ZV9yZXR1cm4gKCk+ICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2l0aW9uX2ZjdDsKICAgIHR5cGVkZWYgOjpib29zdDo6ZnVuY3Rpb248CiAgICAgICAgZXhlY3V0ZV9yZXR1cm4gKCkgPiAgICAgICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZF9mY3Q7CiAgICB0eXBlZGVmIHN0ZDo6ZGVxdWU8ZGVmZXJyZWRfZmN0ID4gICAgICAgICAgICAgICBkZWZlcnJlZF9ldmVudHNfcXVldWVfdDsKICAgIHR5cGVkZWYgc3RkOjpxdWV1ZTx0cmFuc2l0aW9uX2ZjdCA+ICAgICAgICAgICAgIGV2ZW50c19xdWV1ZV90OwogICAgdHlwZWRlZiBib29sICgqZmxhZ19oYW5kbGVyKShsaWJyYXJ5X3NtJik7CgogICAgLy8gYWxsIHN0YXRlIG1hY2hpbmVzIGFyZSBmcmllbmQgd2l0aCBlYWNoIG90aGVyIHRvIGFsbG93IGVtYmVkZGluZyBhbnkgb2YgdGhlbSBpbiBhbm90aGVyIGZzbQogICAgdGVtcGxhdGUgPGNsYXNzICxjbGFzcyAsIGNsYXNzCiAgICA+IGZyaWVuZCBjbGFzcyBib29zdDo6bXNtOjpiYWNrOjpzdGF0ZV9tYWNoaW5lOwoKICAgIC8vIGhlbHBlciB0byBhZGQsIGlmIG5lZWRlZCwgdmlzaXRvcnMgdG8gYWxsIHN0YXRlcwogICAgLy8gdmVyc2lvbiB3aXRob3V0IHZpc2l0b3JzCiAgICB0ZW1wbGF0ZSA8Y2xhc3MgU3RhdGVUeXBlLGNsYXNzIEVuYWJsZT12b2lkPgogICAgc3RydWN0IHZpc2l0b3JfZmN0X2hlbHBlciAKICAgIHsKICAgIHB1YmxpYzoKICAgICAgICB2aXNpdG9yX2ZjdF9oZWxwZXIoKXt9CiAgICAgICAgdm9pZCBmaWxsX3Zpc2l0b3JzKGludCkKICAgICAgICB7CiAgICAgICAgfQogICAgICAgIHRlbXBsYXRlIDxjbGFzcyBGQ1Q+CiAgICAgICAgdm9pZCBpbnNlcnQoaW50LEZDVCkKICAgICAgICB7CiAgICAgICAgfQogICAgICAgIHRlbXBsYXRlIDxjbGFzcyBWSVNJVE9SPgogICAgICAgIHZvaWQgZXhlY3V0ZShpbnQsVklTSVRPUikKICAgICAgICB7CiAgICAgICAgfQogICAgfTsKICAgIC8vIHZlcnNpb24gd2l0aCB2aXNpdG9ycwogICAgdGVtcGxhdGUgPGNsYXNzIFN0YXRlVHlwZT4KICAgIHN0cnVjdCB2aXNpdG9yX2ZjdF9oZWxwZXI8U3RhdGVUeXBlLHR5cGVuYW1lIDo6Ym9vc3Q6OmVuYWJsZV9pZjxoYXNfYWNjZXB0X3NpZzxTdGF0ZVR5cGU+ID46OnR5cGU+IAogICAgewogICAgcHVibGljOgogICAgICAgIHZpc2l0b3JfZmN0X2hlbHBlcigpOm1fc3RhdGVfdmlzaXRvcnMoKXt9CiAgICAgICAgdm9pZCBmaWxsX3Zpc2l0b3JzKGludCBudW1iZXJfb2Zfc3RhdGVzKQogICAgICAgIHsKICAgICAgICAgICAgbV9zdGF0ZV92aXNpdG9ycy5yZXNpemUobnVtYmVyX29mX3N0YXRlcyk7CiAgICAgICAgfQogICAgICAgIHRlbXBsYXRlIDxjbGFzcyBGQ1Q+CiAgICAgICAgdm9pZCBpbnNlcnQoaW50IGluZGV4LEZDVCBmY3QpCiAgICAgICAgewogICAgICAgICAgICBtX3N0YXRlX3Zpc2l0b3JzW2luZGV4XT1mY3Q7CiAgICAgICAgfQogICAgICAgIHZvaWQgZXhlY3V0ZShpbnQgaW5kZXgpCiAgICAgICAgewogICAgICAgICAgICBtX3N0YXRlX3Zpc2l0b3JzW2luZGV4XSgpOwogICAgICAgIH0KCiNkZWZpbmUgTVNNX1ZJU0lUT1JfSEVMUEVSX0VYRUNVVEVfU1VCKHosIG4sIHVudXNlZCkgQVJHICMjIG4gdmlzICMjIG4KI2RlZmluZSBNU01fVklTSVRPUl9IRUxQRVJfRVhFQ1VURSh6LCBuLCB1bnVzZWQpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgIHRlbXBsYXRlIDxCT09TVF9QUF9FTlVNX1BBUkFNUyhuLCBjbGFzcyBBUkcpPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgdm9pZCBleGVjdXRlKGludCBpbmRleCBCT09TVF9QUF9DT01NQV9JRihuKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICAgICAgICAgICAgICAgQk9PU1RfUFBfRU5VTShuLCBNU01fVklTSVRPUl9IRUxQRVJfRVhFQ1VURV9TVUIsIH4gKSApICAgICAgICAgXAogICAgICAgIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgICAgIG1fc3RhdGVfdmlzaXRvcnNbaW5kZXhdKEJPT1NUX1BQX0VOVU1fUEFSQU1TKG4sdmlzKSk7ICAgICAgICAgICAgICAgICAgIFwKICAgICAgICB9CiAgICAgICAgQk9PU1RfUFBfUkVQRUFUX0ZST01fVE8oMSxCT09TVF9QUF9BREQoQk9PU1RfTVNNX1ZJU0lUT1JfQVJHX1NJWkUsMSksIE1TTV9WSVNJVE9SX0hFTFBFUl9FWEVDVVRFLCB+KQojdW5kZWYgTVNNX1ZJU0lUT1JfSEVMUEVSX0VYRUNVVEUKI3VuZGVmIE1TTV9WSVNJVE9SX0hFTFBFUl9FWEVDVVRFX1NVQgogICAgcHJpdmF0ZToKICAgICAgICB0eXBlZGVmIHR5cGVuYW1lIFN0YXRlVHlwZTo6YWNjZXB0X3NpZzo6dHlwZSAgICAgICAgICAgICAgICAgIHZpc2l0b3JfZmN0OwogICAgICAgIHR5cGVkZWYgc3RkOjp2ZWN0b3I8dmlzaXRvcl9mY3Q+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlzaXRvcnM7CgogICAgICAgIHZpc2l0b3JzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9zdGF0ZV92aXNpdG9yczsKICAgIH07CgogICAgdGVtcGxhdGUgPGNsYXNzIFN0YXRlVHlwZSxjbGFzcyBFbmFibGU9dm9pZD4KICAgIHN0cnVjdCBkZWZlcnJlZF9tc2dfcXVldWVfaGVscGVyIAogICAgewogICAgfTsKICAgIHRlbXBsYXRlIDxjbGFzcyBTdGF0ZVR5cGU+CiAgICBzdHJ1Y3QgZGVmZXJyZWRfbXNnX3F1ZXVlX2hlbHBlcjxTdGF0ZVR5cGUsCiAgICAgICAgdHlwZW5hbWUgOjpib29zdDo6ZW5hYmxlX2lmPCAKICAgICAgICAgICAgdHlwZW5hbWUgOjpib29zdDo6bXNtOjpiYWNrOjpoYXNfZnNtX2RlZmVycmVkX2V2ZW50czxTdGF0ZVR5cGU+Ojp0eXBlID46OnR5cGU+IAogICAgewogICAgcHVibGljOgogICAgICAgIGRlZmVycmVkX21zZ19xdWV1ZV9oZWxwZXIoKTptX2RlZmVycmVkX2V2ZW50c19xdWV1ZSgpe30KICAgICAgICBkZWZlcnJlZF9ldmVudHNfcXVldWVfdCAgICAgbV9kZWZlcnJlZF9ldmVudHNfcXVldWU7CiAgICB9OwoKIHB1YmxpYzogCiAgICAvLyB0YWdzCiAgICB0eXBlZGVmIGludCBjb21wb3NpdGVfdGFnOwoKICAgIC8vIGluIGNhc2Ugc29tZW9uZSBuZWVkcyB0byBrbm93CiAgICB0eXBlZGVmIEhpc3RvcnlQb2xpY3kgICAgICAgICAgICAgICBoaXN0b3J5X3BvbGljeTsKCiAgICBzdHJ1Y3QgSW5pdEV2ZW50IHsgfTsKICAgIC8vIGZsYWcgaGFuZGxpbmcKICAgIHN0cnVjdCBGbGFnX0FORAogICAgewogICAgICAgIHR5cGVkZWYgc3RkOjpsb2dpY2FsX2FuZDxib29sPiB0eXBlOwogICAgfTsKICAgIHN0cnVjdCBGbGFnX09SCiAgICB7CiAgICAgdHlwZWRlZiBzdGQ6OmxvZ2ljYWxfb3I8Ym9vbD4gdHlwZTsKICAgIH07CiAgICB0eXBlZGVmIHR5cGVuYW1lIERlcml2ZWQ6OkJhc2VBbGxTdGF0ZXMgICAgIEJhc2VTdGF0ZTsKICAgIHR5cGVkZWYgRGVyaXZlZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uY3JldGVTTTsKCiAgICAvLyBpZiB0aGUgZnJvbnQtZW5kIGZzbSBwcm92aWRlcyBhbiBpbml0aWFsX2V2ZW50IHR5cGVkZWYsIHJlcGxhY2UgSW5pdEV2ZW50IGJ5IHRoaXMgb25lCiAgICB0eXBlZGVmIHR5cGVuYW1lIDo6Ym9vc3Q6Om1wbDo6ZXZhbF9pZjwgCiAgICAgICAgdHlwZW5hbWUgaGFzX2luaXRpYWxfZXZlbnQ8RGVyaXZlZD46OnR5cGUsCiAgICAgICAgZ2V0X2luaXRpYWxfZXZlbnQ8RGVyaXZlZD4sCiAgICAgICAgOjpib29zdDo6bXBsOjppZGVudGl0eTxJbml0RXZlbnQ+CiAgICA+Ojp0eXBlIGZzbV9pbml0aWFsX2V2ZW50OwoKCiAgICB0ZW1wbGF0ZSA8Y2xhc3MgRXhpdFBvaW50PgogICAgc3RydWN0IGV4aXRfcHQgOiBwdWJsaWMgRXhpdFBvaW50CiAgICB7CiAgICAgICAgLy8gdGFncwogICAgICAgIHR5cGVkZWYgRXhpdFBvaW50ICAgICAgICAgICB3cmFwcGVkX2V4aXQ7CiAgICAgICAgdHlwZWRlZiBpbnQgICAgICAgICAgICAgICAgIHBzZXVkb19leGl0OwogICAgICAgIHR5cGVkZWYgbGlicmFyeV9zbSAgICAgICAgICBvd25lcjsKICAgICAgICB0eXBlZGVmIGludCAgICAgICAgICAgICAgICAgbm9fYXV0b21hdGljX2NyZWF0ZTsKICAgICAgICB0eXBlZGVmIHR5cGVuYW1lIAogICAgICAgICAgICBFeGl0UG9pbnQ6OmV2ZW50ICAgICAgICBFdmVudDsKICAgICAgICB0eXBlZGVmIDo6Ym9vc3Q6OmZ1bmN0aW9uPGV4ZWN1dGVfcmV0dXJuIChFdmVudCBjb25zdCYpPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3J3YXJkaW5nX2Z1bmN0aW9uOwoKICAgICAgICAvLyBmb3J3YXJkIGV2ZW50IHRvIHRoZSBoaWdoZXItbGV2ZWwgRlNNCiAgICAgICAgdGVtcGxhdGUgPGNsYXNzIEZvcndhcmRFdmVudD4KICAgICAgICB2b2lkIGZvcndhcmRfZXZlbnQoRm9yd2FyZEV2ZW50IGNvbnN0JiBpbmNvbWluZ0V2ZW50KQogICAgICAgIHsKICAgICAgICAgICAgLy8gdXNlIGhlbHBlciB0byBmb3J3YXJkIG9yIG5vdAogICAgICAgICAgICBGb3J3YXJkSGVscGVyPCA6OmJvb3N0Ojppc19jb252ZXJ0aWJsZTxGb3J3YXJkRXZlbnQsRXZlbnQ+Ojp2YWx1ZT46OmhlbHBlcihpbmNvbWluZ0V2ZW50LG1fZm9yd2FyZCk7CiAgICAgICAgfQogICAgICAgIHZvaWQgc2V0X2ZvcndhcmRfZmN0KDo6Ym9vc3Q6OmZ1bmN0aW9uPGV4ZWN1dGVfcmV0dXJuIChFdmVudCBjb25zdCYpPiBmY3QpCiAgICAgICAgewogICAgICAgICAgICBtX2ZvcndhcmQgPSBmY3Q7CiAgICAgICAgfSAgICAKICAgICAgICBleGl0X3B0KCk6bV9mb3J3YXJkKCl7fQogICAgICAgIC8vIGJ5IGFzc2lnbm1lbnRzLCB3ZSBrZWVwIG91ciBmb3J3YXJkaW5nIGZ1bmN0b3IgdW5jaGFuZ2VkIGFzIG91ciBjb250YWluaW5nIFNNIGRpZCBub3QgY2hhbmdlCiAgICB0ZW1wbGF0ZSA8Y2xhc3MgUkhTPgogICAgICAgIGV4aXRfcHQoUkhTJiByaHMpOm1fZm9yd2FyZCgpe30KICAgICAgICBleGl0X3B0PEV4aXRQb2ludD4mIG9wZXJhdG9yPSAoY29uc3QgZXhpdF9wdDxFeGl0UG9pbnQ+JiApIAogICAgICAgIHsgCiAgICAgICAgICAgIHJldHVybiAqdGhpczsgCiAgICAgICAgfSAKICAgIHByaXZhdGU6CiAgICAgICAgIGZvcndhcmRpbmdfZnVuY3Rpb24gICAgICAgICAgbV9mb3J3YXJkOwoKICAgICAgICAgLy8gdXNpbmcgcGFydGlhbCBzcGVjaWFsaXphdGlvbiBpbnN0ZWFkIG9mIGVuYWJsZV9pZiBiZWNhdXNlIG9mIFZDOCBidWcKICAgICAgICB0ZW1wbGF0ZSA8Ym9vbCBPd25FdmVudCwgaW50IER1bW15PTA+CiAgICAgICAgc3RydWN0IEZvcndhcmRIZWxwZXIKICAgICAgICB7CiAgICAgICAgICAgIHRlbXBsYXRlIDxjbGFzcyBGb3J3YXJkRXZlbnQ+CiAgICAgICAgICAgIHN0YXRpYyB2b2lkIGhlbHBlcihGb3J3YXJkRXZlbnQgY29uc3QmICxmb3J3YXJkaW5nX2Z1bmN0aW9uJiApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIE5vdCBvdXIgZXZlbnQsIGlnbm9yZQogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgICB0ZW1wbGF0ZSA8aW50IER1bW15PgogICAgICAgIHN0cnVjdCBGb3J3YXJkSGVscGVyPHRydWUsRHVtbXk+CiAgICAgICAgewogICAgICAgICAgICB0ZW1wbGF0ZSA8Y2xhc3MgRm9yd2FyZEV2ZW50PgogICAgICAgICAgICBzdGF0aWMgdm9pZCBoZWxwZXIoRm9yd2FyZEV2ZW50IGNvbnN0JiBpbmNvbWluZ0V2ZW50LGZvcndhcmRpbmdfZnVuY3Rpb24mIGZvcndhcmRfZmN0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBjYWxsIGlmIGhhbmRsZXIgc2V0LCBpZiBub3QsIHRoaXMgc3RhdGUgaXMgc2ltcGx5IGEgdGVybWluYXRlIHN0YXRlCiAgICAgICAgICAgICAgICBpZiAoZm9yd2FyZF9mY3QpCiAgICAgICAgICAgICAgICAgICAgZm9yd2FyZF9mY3QoaW5jb21pbmdFdmVudCk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgIH07CiAgICB0ZW1wbGF0ZSA8Y2xhc3MgRW50cnlQb2ludD4KICAgIHN0cnVjdCBlbnRyeV9wdCA6IHB1YmxpYyBFbnRyeVBvaW50CiAgICB7CiAgICAgICAgLy8gdGFncwogICAgICAgIHR5cGVkZWYgRW50cnlQb2ludCAgICAgICAgICB3cmFwcGVkX2VudHJ5OwogICAgICAgIHR5cGVkZWYgaW50ICAgICAgICAgICAgICAgICBwc2V1ZG9fZW50cnk7CiAgICAgICAgdHlwZWRlZiBsaWJyYXJ5X3NtICAgICAgICAgIG93bmVyOwogICAgICAgIHR5cGVkZWYgaW50ICAgICAgICAgICAgICAgICBub19hdXRvbWF0aWNfY3JlYXRlOwogICAgfTsKICAgIHRlbXBsYXRlIDxjbGFzcyBFbnRyeVBvaW50PgogICAgc3RydWN0IGRpcmVjdCA6IHB1YmxpYyBFbnRyeVBvaW50CiAgICB7CiAgICAgICAgLy8gdGFncwogICAgICAgIHR5cGVkZWYgRW50cnlQb2ludCAgICAgICAgICB3cmFwcGVkX2VudHJ5OwogICAgICAgIHR5cGVkZWYgaW50ICAgICAgICAgICAgICAgICBleHBsaWNpdF9lbnRyeV9zdGF0ZTsKICAgICAgICB0eXBlZGVmIGxpYnJhcnlfc20gICAgICAgICAgb3duZXI7CiAgICAgICAgdHlwZWRlZiBpbnQgICAgICAgICAgICAgICAgIG5vX2F1dG9tYXRpY19jcmVhdGU7CiAgICB9OwogICAgdHlwZWRlZiB0eXBlbmFtZSBnZXRfbnVtYmVyX29mX3JlZ2lvbnM8dHlwZW5hbWUgRGVyaXZlZDo6aW5pdGlhbF9zdGF0ZT46OnR5cGUgbnJfcmVnaW9uczsKICAgIC8vIFRlbXBsYXRlIHVzZWQgdG8gZm9ybSByb3dzIGluIHRoZSB0cmFuc2l0aW9uIHRhYmxlCiAgICB0ZW1wbGF0ZTwKICAgICAgICB0eXBlbmFtZSBST1cKICAgID4KICAgIHN0cnVjdCByb3dfCiAgICB7CiAgICAgICAgLy90eXBlZGVmIHR5cGVuYW1lIFJPVzo6U291cmNlIFQxOwogICAgICAgIHR5cGVkZWYgdHlwZW5hbWUgbWFrZV9lbnRyeTx0eXBlbmFtZSBST1c6OlNvdXJjZSxsaWJyYXJ5X3NtPjo6dHlwZSBUMTsKICAgICAgICB0eXBlZGVmIHR5cGVuYW1lIG1ha2VfZXhpdDx0eXBlbmFtZSBST1c6OlRhcmdldCxsaWJyYXJ5X3NtPjo6dHlwZSBUMjsKICAgICAgICB0eXBlZGVmIHR5cGVuYW1lIFJPVzo6RXZ0IHRyYW5zaXRpb25fZXZlbnQ7CiAgICAgICAgLy8gaWYgdGhlIHNvdXJjZSBpcyBhbiBleGl0IHBzZXVkbyBzdGF0ZSwgdGhlbgogICAgICAgIC8vIGN1cnJlbnRfc3RhdGVfdHlwZSBiZWNvbWVzIHRoZSByZXN1bHQgb2YgZ2V0X293bmVyCiAgICAgICAgLy8gbWVhbmluZyB0aGUgY29udGFpbmluZyBTTSBmcm9tIHdoaWNoIHRoZSBleGl0IG9jY3VycwogICAgICAgIHR5cGVkZWYgdHlwZW5hbWUgOjpib29zdDo6bXBsOjpldmFsX2lmPAogICAgICAgICAgICAgICAgdHlwZW5hbWUgaGFzX3BzZXVkb19leGl0PFQxPjo6dHlwZSwKICAgICAgICAgICAgICAgIGdldF9vd25lcjxUMSxsaWJyYXJ5X3NtPiwKICAgICAgICAgICAgICAgIDo6Ym9vc3Q6Om1wbDo6aWRlbnRpdHk8dHlwZW5hbWUgUk9XOjpTb3VyY2U+ID46OnR5cGUgY3VycmVudF9zdGF0ZV90eXBlOwoKICAgICAgICAvLyBpZiBUYXJnZXQgaXMgYSBzZXF1ZW5jZSwgdGhlbiB3ZSBoYXZlIGEgZm9yayBhbmQgZXhwZWN0IGEgc2VxdWVuY2Ugb2YgZXhwbGljaXRfZW50cnkKICAgICAgICAvLyBlbHNlIGlmIFRhcmdldCBpcyBhbiBleHBsaWNpdF9lbnRyeSwgbmV4dF9zdGF0ZV90eXBlIGJlY29tZXMgdGhlIHJlc3VsdCBvZiBnZXRfb3duZXIKICAgICAgICAvLyBtZWFuaW5nIHRoZSBjb250YWluaW5nIFNNIGlmIHRoZSByb3cgaXMgIm91dHNpZGUiIHRoZSBjb250YWluaW5nIFNNIG9yIGVsc2UgdGhlIGV4cGxpY2l0X2VudHJ5IHN0YXRlIGl0c2VsZgogICAgICAgIHR5cGVkZWYgdHlwZW5hbWUgOjpib29zdDo6bXBsOjpldmFsX2lmPAogICAgICAgICAgICB0eXBlbmFtZSA6OmJvb3N0OjptcGw6OmlzX3NlcXVlbmNlPFQyPjo6dHlwZSwKICAgICAgICAgICAgZ2V0X2Zvcmtfb3duZXI8VDIsbGlicmFyeV9zbT4sCiAgICAgICAgICAgIDo6Ym9vc3Q6Om1wbDo6ZXZhbF9pZjwKICAgICAgICAgICAgICAgICAgICB0eXBlbmFtZSBoYXNfbm9fYXV0b21hdGljX2NyZWF0ZTxUMj46OnR5cGUsCiAgICAgICAgICAgICAgICAgICAgZ2V0X293bmVyPFQyLGxpYnJhcnlfc20+LAogICAgICAgICAgICAgICAgICAgIDo6Ym9vc3Q6Om1wbDo6aWRlbnRpdHk8VDI+ID4KICAgICAgICA+Ojp0eXBlIG5leHRfc3RhdGVfdHlwZTsKCiAgICAgICAgLy8gaWYgYSBndWFyZCBjb25kaXRpb24gaXMgaGVyZSwgY2FsbCBpdCB0byBjaGVjayB0aGF0IHRoZSBldmVudCBpcyBhY2NlcHRlZAogICAgICAgIHN0YXRpYyBib29sIGNoZWNrX2d1YXJkKGxpYnJhcnlfc20mIGZzbSx0cmFuc2l0aW9uX2V2ZW50IGNvbnN0JiBldnQpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIFJPVzo6Z3VhcmRfY2FsbChmc20sZXZ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6OmJvb3N0OjpmdXNpb246OmF0X2tleTxjdXJyZW50X3N0YXRlX3R5cGU+KGZzbS5tX3N1YnN0YXRlX2xpc3QpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6OmJvb3N0OjpmdXNpb246OmF0X2tleTxuZXh0X3N0YXRlX3R5cGU+KGZzbS5tX3N1YnN0YXRlX2xpc3QpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmc20ubV9zdWJzdGF0ZV9saXN0ICkgKQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgLy8gVGFrZSB0aGUgdHJhbnNpdGlvbiBhY3Rpb24gYW5kIHJldHVybiB0aGUgbmV4dCBzdGF0ZS4KICAgICAgICBzdGF0aWMgSGFuZGxlZEVudW0gZXhlY3V0ZShsaWJyYXJ5X3NtJiBmc20sIGludCByZWdpb25faW5kZXgsIGludCBzdGF0ZSwgdHJhbnNpdGlvbl9ldmVudCBjb25zdCYgZXZ0KQogICAgICAgIHsKCiAgICAgICAgICAgIEJPT1NUX1NUQVRJQ19DT05TVEFOVChpbnQsIGN1cnJlbnRfc3RhdGUgPSAoZ2V0X3N0YXRlX2lkPHN0dCxjdXJyZW50X3N0YXRlX3R5cGU+Ojp0eXBlOjp2YWx1ZSkpOwogICAgICAgICAgICBCT09TVF9TVEFUSUNfQ09OU1RBTlQoaW50LCBuZXh0X3N0YXRlID0gKGdldF9zdGF0ZV9pZDxzdHQsbmV4dF9zdGF0ZV90eXBlPjo6dHlwZTo6dmFsdWUpKTsKICAgICAgICAgICAgQk9PU1RfQVNTRVJUKHN0YXRlID09IChjdXJyZW50X3N0YXRlKSk7CiAgICAgICAgICAgIC8vIGlmIFQxIGlzIGFuIGV4aXQgcHNldWRvIHN0YXRlLCB0aGVuIHRha2UgdGhlIHRyYW5zaXRpb24gb25seSBpZiB0aGUgcHNldWRvIGV4aXQgc3RhdGUgaXMgYWN0aXZlCiAgICAgICAgICAgIGlmIChoYXNfcHNldWRvX2V4aXQ8VDE+Ojp0eXBlOjp2YWx1ZSAmJiAKICAgICAgICAgICAgICAgICFpc19leGl0X3N0YXRlX2FjdGl2ZTxUMSxnZXRfb3duZXI8VDEsbGlicmFyeV9zbT4gPihmc20pKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gSEFORExFRF9GQUxTRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIWNoZWNrX2d1YXJkKGZzbSxldnQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBndWFyZCByZWplY3RlZCB0aGUgZXZlbnQsIHdlIHN0YXkgaW4gdGhlIGN1cnJlbnQgb25lCiAgICAgICAgICAgICAgICByZXR1cm4gSEFORExFRF9HVUFSRF9SRUpFQ1Q7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHRoZSBndWFyZCBjb25kaXRpb24gaGFzIGFscmVhZHkgYmVlbiBjaGVja2VkCiAgICAgICAgICAgIGV4ZWN1dGVfZXhpdDxjdXJyZW50X3N0YXRlX3R5cGU+CiAgICAgICAgICAgICAgICAoOjpib29zdDo6ZnVzaW9uOjphdF9rZXk8Y3VycmVudF9zdGF0ZV90eXBlPihmc20ubV9zdWJzdGF0ZV9saXN0KSxldnQsZnNtKTsKCiAgICAgICAgICAgIC8vIHRoZW4gY2FsbCB0aGUgYWN0aW9uIG1ldGhvZAogICAgICAgICAgICBST1c6OmFjdGlvbl9jYWxsKGZzbSxldnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpib29zdDo6ZnVzaW9uOjphdF9rZXk8Y3VycmVudF9zdGF0ZV90eXBlPihmc20ubV9zdWJzdGF0ZV9saXN0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6OmJvb3N0OjpmdXNpb246OmF0X2tleTxuZXh0X3N0YXRlX3R5cGU+KGZzbS5tX3N1YnN0YXRlX2xpc3QpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZzbS5tX3N1YnN0YXRlX2xpc3QpOwoKICAgICAgICAgICAgLy8gYW5kIGZpbmFsbHkgdGhlIGVudHJ5IG1ldGhvZCBvZiB0aGUgbmV3IGN1cnJlbnQgc3RhdGUKICAgICAgICAgICAgY29udmVydF9ldmVudF9hbmRfZXhlY3V0ZV9lbnRyeTxuZXh0X3N0YXRlX3R5cGUsVDI+CiAgICAgICAgICAgICAgICAoOjpib29zdDo6ZnVzaW9uOjphdF9rZXk8bmV4dF9zdGF0ZV90eXBlPihmc20ubV9zdWJzdGF0ZV9saXN0KSxldnQsZnNtKTsKICAgICAgICAgICAgZnNtLm1fc3RhdGVzW3JlZ2lvbl9pbmRleF09bmV4dF9zdGF0ZTsKICAgICAgICAgICAgcmV0dXJuIEhBTkRMRURfVFJVRTsKICAgICAgICB9CiAgICB9OwoKICAgIC8vIHJvdyBoYXZpbmcgb25seSBhIGd1YXJkIGNvbmRpdGlvbgogICAgdGVtcGxhdGU8CiAgICAgICAgdHlwZW5hbWUgUk9XCiAgICA+CiAgICBzdHJ1Y3QgZ19yb3dfCiAgICB7CiAgICAgICAgLy90eXBlZGVmIHR5cGVuYW1lIFJPVzo6U291cmNlIFQxOwogICAgICAgIHR5cGVkZWYgdHlwZW5hbWUgbWFrZV9lbnRyeTx0eXBlbmFtZSBST1c6OlNvdXJjZSxsaWJyYXJ5X3NtPjo6dHlwZSBUMTsKICAgICAgICB0eXBlZGVmIHR5cGVuYW1lIG1ha2VfZXhpdDx0eXBlbmFtZSBST1c6OlRhcmdldCxsaWJyYXJ5X3NtPjo6dHlwZSBUMjsKICAgICAgICB0eXBlZGVmIHR5cGVuYW1lIFJPVzo6RXZ0IHRyYW5zaXRpb25fZXZlbnQ7CiAgICAgICAgLy8gaWYgdGhlIHNvdXJjZSBpcyBhbiBleGl0IHBzZXVkbyBzdGF0ZSwgdGhlbgogICAgICAgIC8vIGN1cnJlbnRfc3RhdGVfdHlwZSBiZWNvbWVzIHRoZSByZXN1bHQgb2YgZ2V0X293bmVyCiAgICAgICAgLy8gbWVhbmluZyB0aGUgY29udGFpbmluZyBTTSBmcm9tIHdoaWNoIHRoZSBleGl0IG9jY3VycwogICAgICAgIHR5cGVkZWYgdHlwZW5hbWUgOjpib29zdDo6bXBsOjpldmFsX2lmPAogICAgICAgICAgICAgICAgdHlwZW5hbWUgaGFzX3BzZXVkb19leGl0PFQxPjo6dHlwZSwKICAgICAgICAgICAgICAgIGdldF9vd25lcjxUMSxsaWJyYXJ5X3NtPiwKICAgICAgICAgICAgICAgIDo6Ym9vc3Q6Om1wbDo6aWRlbnRpdHk8dHlwZW5hbWUgUk9XOjpTb3VyY2U+ID46OnR5cGUgY3VycmVudF9zdGF0ZV90eXBlOwoKICAgICAgICAvLyBpZiBUYXJnZXQgaXMgYSBzZXF1ZW5jZSwgdGhlbiB3ZSBoYXZlIGEgZm9yayBhbmQgZXhwZWN0IGEgc2VxdWVuY2Ugb2YgZXhwbGljaXRfZW50cnkKICAgICAgICAvLyBlbHNlIGlmIFRhcmdldCBpcyBhbiBleHBsaWNpdF9lbnRyeSwgbmV4dF9zdGF0ZV90eXBlIGJlY29tZXMgdGhlIHJlc3VsdCBvZiBnZXRfb3duZXIKICAgICAgICAvLyBtZWFuaW5nIHRoZSBjb250YWluaW5nIFNNIGlmIHRoZSByb3cgaXMgIm91dHNpZGUiIHRoZSBjb250YWluaW5nIFNNIG9yIGVsc2UgdGhlIGV4cGxpY2l0X2VudHJ5IHN0YXRlIGl0c2VsZgogICAgICAgIHR5cGVkZWYgdHlwZW5hbWUgOjpib29zdDo6bXBsOjpldmFsX2lmPAogICAgICAgICAgICB0eXBlbmFtZSA6OmJvb3N0OjptcGw6OmlzX3NlcXVlbmNlPFQyPjo6dHlwZSwKICAgICAgICAgICAgZ2V0X2Zvcmtfb3duZXI8VDIsbGlicmFyeV9zbT4sCiAgICAgICAgICAgIDo6Ym9vc3Q6Om1wbDo6ZXZhbF9pZjwKICAgICAgICAgICAgICAgICAgICB0eXBlbmFtZSBoYXNfbm9fYXV0b21hdGljX2NyZWF0ZTxUMj46OnR5cGUsCiAgICAgICAgICAgICAgICAgICAgZ2V0X293bmVyPFQyLGxpYnJhcnlfc20+LAogICAgICAgICAgICAgICAgICAgIDo6Ym9vc3Q6Om1wbDo6aWRlbnRpdHk8VDI+ID4KICAgICAgICA+Ojp0eXBlIG5leHRfc3RhdGVfdHlwZTsKCiAgICAgICAgLy8gaWYgYSBndWFyZCBjb25kaXRpb24gaXMgZGVmaW5lZCwgY2FsbCBpdCB0byBjaGVjayB0aGF0IHRoZSBldmVudCBpcyBhY2NlcHRlZAogICAgICAgIHN0YXRpYyBib29sIGNoZWNrX2d1YXJkKGxpYnJhcnlfc20mIGZzbSx0cmFuc2l0aW9uX2V2ZW50IGNvbnN0JiBldnQpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIFJPVzo6Z3VhcmRfY2FsbChmc20sZXZ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6OmJvb3N0OjpmdXNpb246OmF0X2tleTxjdXJyZW50X3N0YXRlX3R5cGU+KGZzbS5tX3N1YnN0YXRlX2xpc3QpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6OmJvb3N0OjpmdXNpb246OmF0X2tleTxuZXh0X3N0YXRlX3R5cGU+KGZzbS5tX3N1YnN0YXRlX2xpc3QpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmc20ubV9zdWJzdGF0ZV9saXN0ICkpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICAvLyBUYWtlIHRoZSB0cmFuc2l0aW9uIGFjdGlvbiBhbmQgcmV0dXJuIHRoZSBuZXh0IHN0YXRlLgogICAgICAgIHN0YXRpYyBIYW5kbGVkRW51bSBleGVjdXRlKGxpYnJhcnlfc20mIGZzbSwgaW50IHJlZ2lvbl9pbmRleCwgaW50IHN0YXRlLCB0cmFuc2l0aW9uX2V2ZW50IGNvbnN0JiBldnQpCiAgICAgICAgewogICAgICAgICAgICBCT09TVF9TVEFUSUNfQ09OU1RBTlQoaW50LCBjdXJyZW50X3N0YXRlID0gKGdldF9zdGF0ZV9pZDxzdHQsY3VycmVudF9zdGF0ZV90eXBlPjo6dHlwZTo6dmFsdWUpKTsKICAgICAgICAgICAgQk9PU1RfU1RBVElDX0NPTlNUQU5UKGludCwgbmV4dF9zdGF0ZSA9IChnZXRfc3RhdGVfaWQ8c3R0LG5leHRfc3RhdGVfdHlwZT46OnR5cGU6OnZhbHVlKSk7CiAgICAgICAgICAgIEJPT1NUX0FTU0VSVChzdGF0ZSA9PSAoY3VycmVudF9zdGF0ZSkpOwogICAgICAgICAgICAvLyBpZiBUMSBpcyBhbiBleGl0IHBzZXVkbyBzdGF0ZSwgdGhlbiB0YWtlIHRoZSB0cmFuc2l0aW9uIG9ubHkgaWYgdGhlIHBzZXVkbyBleGl0IHN0YXRlIGlzIGFjdGl2ZQogICAgICAgICAgICBpZiAoaGFzX3BzZXVkb19leGl0PFQxPjo6dHlwZTo6dmFsdWUgJiYgCiAgICAgICAgICAgICAgICAhaXNfZXhpdF9zdGF0ZV9hY3RpdmU8VDEsZ2V0X293bmVyPFQxLGxpYnJhcnlfc20+ID4oZnNtKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIEhBTkRMRURfRkFMU0U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFjaGVja19ndWFyZChmc20sZXZ0KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gZ3VhcmQgcmVqZWN0ZWQgdGhlIGV2ZW50LCB3ZSBzdGF5IGluIHRoZSBjdXJyZW50IG9uZQogICAgICAgICAgICAgICAgcmV0dXJuIEhBTkRMRURfR1VBUkRfUkVKRUNUOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIHRoZSBndWFyZCBjb25kaXRpb24gaGFzIGFscmVhZHkgYmVlbiBjaGVja2VkCiAgICAgICAgICAgIGV4ZWN1dGVfZXhpdDxjdXJyZW50X3N0YXRlX3R5cGU+CiAgICAgICAgICAgICAgICAoOjpib29zdDo6ZnVzaW9uOjphdF9rZXk8Y3VycmVudF9zdGF0ZV90eXBlPihmc20ubV9zdWJzdGF0ZV9saXN0KSxldnQsZnNtKTsKCiAgICAgICAgICAgIC8vIGFuZCBmaW5hbGx5IHRoZSBlbnRyeSBtZXRob2Qgb2YgdGhlIG5ldyBjdXJyZW50IHN0YXRlCiAgICAgICAgICAgIGNvbnZlcnRfZXZlbnRfYW5kX2V4ZWN1dGVfZW50cnk8bmV4dF9zdGF0ZV90eXBlLFQyPgogICAgICAgICAgICAgICAgKDo6Ym9vc3Q6OmZ1c2lvbjo6YXRfa2V5PG5leHRfc3RhdGVfdHlwZT4oZnNtLm1fc3Vic3RhdGVfbGlzdCksZXZ0LGZzbSk7CgogICAgICAgICAgICBmc20ubV9zdGF0ZXNbcmVnaW9uX2luZGV4XT1uZXh0X3N0YXRlOwogICAgICAgICAgICByZXR1cm4gSEFORExFRF9UUlVFOwogICAgICAgIH0KICAgIH07CgogICAgLy8gcm93IGhhdmluZyBvbmx5IGFuIGFjdGlvbiBtZXRob2QKICAgIHRlbXBsYXRlPAogICAgICAgIHR5cGVuYW1lIFJPVwogICAgPgogICAgc3RydWN0IGFfcm93XyAKICAgIHsKICAgICAgICAvL3R5cGVkZWYgdHlwZW5hbWUgUk9XOjpTb3VyY2UgVDE7CiAgICAgICAgdHlwZWRlZiB0eXBlbmFtZSBtYWtlX2VudHJ5PHR5cGVuYW1lIFJPVzo6U291cmNlLGxpYnJhcnlfc20+Ojp0eXBlIFQxOwogICAgICAgIHR5cGVkZWYgdHlwZW5hbWUgbWFrZV9leGl0PHR5cGVuYW1lIFJPVzo6VGFyZ2V0LGxpYnJhcnlfc20+Ojp0eXBlIFQyOwogICAgICAgIHR5cGVkZWYgdHlwZW5hbWUgUk9XOjpFdnQgdHJhbnNpdGlvbl9ldmVudDsKICAgICAgICAvLyBpZiB0aGUgc291cmNlIGlzIGFuIGV4aXQgcHNldWRvIHN0YXRlLCB0aGVuCiAgICAgICAgLy8gY3VycmVudF9zdGF0ZV90eXBlIGJlY29tZXMgdGhlIHJlc3VsdCBvZiBnZXRfb3duZXIKICAgICAgICAvLyBtZWFuaW5nIHRoZSBjb250YWluaW5nIFNNIGZyb20gd2hpY2ggdGhlIGV4aXQgb2NjdXJzCiAgICAgICAgdHlwZWRlZiB0eXBlbmFtZSA6OmJvb3N0OjptcGw6OmV2YWxfaWY8CiAgICAgICAgICAgICAgICB0eXBlbmFtZSBoYXNfcHNldWRvX2V4aXQ8VDE+Ojp0eXBlLAogICAgICAgICAgICAgICAgZ2V0X293bmVyPFQxLGxpYnJhcnlfc20+LAogICAgICAgICAgICAgICAgOjpib29zdDo6bXBsOjppZGVudGl0eTx0eXBlbmFtZSBST1c6OlNvdXJjZT4gPjo6dHlwZSBjdXJyZW50X3N0YXRlX3R5cGU7CgogICAgICAgIC8vIGlmIFRhcmdldCBpcyBhIHNlcXVlbmNlLCB0aGVuIHdlIGhhdmUgYSBmb3JrIGFuZCBleHBlY3QgYSBzZXF1ZW5jZSBvZiBleHBsaWNpdF9lbnRyeQogICAgICAgIC8vIGVsc2UgaWYgVGFyZ2V0IGlzIGFuIGV4cGxpY2l0X2VudHJ5LCBuZXh0X3N0YXRlX3R5cGUgYmVjb21lcyB0aGUgcmVzdWx0IG9mIGdldF9vd25lcgogICAgICAgIC8vIG1lYW5pbmcgdGhlIGNvbnRhaW5pbmcgU00gaWYgdGhlIHJvdyBpcyAib3V0c2lkZSIgdGhlIGNvbnRhaW5pbmcgU00gb3IgZWxzZSB0aGUgZXhwbGljaXRfZW50cnkgc3RhdGUgaXRzZWxmCiAgICAgICAgdHlwZWRlZiB0eXBlbmFtZSA6OmJvb3N0OjptcGw6OmV2YWxfaWY8CiAgICAgICAgICAgIHR5cGVuYW1lIDo6Ym9vc3Q6Om1wbDo6aXNfc2VxdWVuY2U8VDI+Ojp0eXBlLAogICAgICAgICAgICBnZXRfZm9ya19vd25lcjxUMixsaWJyYXJ5X3NtPiwKICAgICAgICAgICAgOjpib29zdDo6bXBsOjpldmFsX2lmPAogICAgICAgICAgICAgICAgICAgIHR5cGVuYW1lIGhhc19ub19hdXRvbWF0aWNfY3JlYXRlPFQyPjo6dHlwZSwKICAgICAgICAgICAgICAgICAgICBnZXRfb3duZXI8VDIsbGlicmFyeV9zbT4sCiAgICAgICAgICAgICAgICAgICAgOjpib29zdDo6bXBsOjppZGVudGl0eTxUMj4gPgogICAgICAgID46OnR5cGUgbmV4dF9zdGF0ZV90eXBlOwoKICAgICAgICAvLyBUYWtlIHRoZSB0cmFuc2l0aW9uIGFjdGlvbiBhbmQgcmV0dXJuIHRoZSBuZXh0IHN0YXRlLgogICAgICAgIHN0YXRpYyBIYW5kbGVkRW51bSBleGVjdXRlKGxpYnJhcnlfc20mIGZzbSwgaW50IHJlZ2lvbl9pbmRleCwgaW50IHN0YXRlLCB0cmFuc2l0aW9uX2V2ZW50IGNvbnN0JiBldnQpCiAgICAgICAgewogICAgICAgICAgICBCT09TVF9TVEFUSUNfQ09OU1RBTlQoaW50LCBjdXJyZW50X3N0YXRlID0gKGdldF9zdGF0ZV9pZDxzdHQsY3VycmVudF9zdGF0ZV90eXBlPjo6dHlwZTo6dmFsdWUpKTsKICAgICAgICAgICAgQk9PU1RfU1RBVElDX0NPTlNUQU5UKGludCwgbmV4dF9zdGF0ZSA9IChnZXRfc3RhdGVfaWQ8c3R0LG5leHRfc3RhdGVfdHlwZT46OnR5cGU6OnZhbHVlKSk7CiAgICAgICAgICAgIEJPT1NUX0FTU0VSVChzdGF0ZSA9PSAoY3VycmVudF9zdGF0ZSkpOwoKICAgICAgICAgICAgLy8gaWYgVDEgaXMgYW4gZXhpdCBwc2V1ZG8gc3RhdGUsIHRoZW4gdGFrZSB0aGUgdHJhbnNpdGlvbiBvbmx5IGlmIHRoZSBwc2V1ZG8gZXhpdCBzdGF0ZSBpcyBhY3RpdmUKICAgICAgICAgICAgaWYgKGhhc19wc2V1ZG9fZXhpdDxUMT46OnR5cGU6OnZhbHVlICYmIAogICAgICAgICAgICAgICAgIWlzX2V4aXRfc3RhdGVfYWN0aXZlPFQxLGdldF9vd25lcjxUMSxsaWJyYXJ5X3NtPiA+KGZzbSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBIQU5ETEVEX0ZBTFNFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIG5vIG5lZWQgdG8gY2hlY2sgdGhlIGd1YXJkIGNvbmRpdGlvbgogICAgICAgICAgICAvLyBmaXJzdCBjYWxsIHRoZSBleGl0IG1ldGhvZCBvZiB0aGUgY3VycmVudCBzdGF0ZQogICAgICAgICAgICBleGVjdXRlX2V4aXQ8Y3VycmVudF9zdGF0ZV90eXBlPgogICAgICAgICAgICAgICAgKDo6Ym9vc3Q6OmZ1c2lvbjo6YXRfa2V5PGN1cnJlbnRfc3RhdGVfdHlwZT4oZnNtLm1fc3Vic3RhdGVfbGlzdCksZXZ0LGZzbSk7CgogICAgICAgICAgICAvLyB0aGVuIGNhbGwgdGhlIGFjdGlvbiBtZXRob2QKICAgICAgICAgICAgUk9XOjphY3Rpb25fY2FsbChmc20sZXZ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpib29zdDo6ZnVzaW9uOjphdF9rZXk8Y3VycmVudF9zdGF0ZV90eXBlPihmc20ubV9zdWJzdGF0ZV9saXN0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDo6Ym9vc3Q6OmZ1c2lvbjo6YXRfa2V5PG5leHRfc3RhdGVfdHlwZT4oZnNtLm1fc3Vic3RhdGVfbGlzdCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmc20ubV9zdWJzdGF0ZV9saXN0KTsKCiAgICAgICAgICAgIC8vIGFuZCBmaW5hbGx5IHRoZSBlbnRyeSBtZXRob2Qgb2YgdGhlIG5ldyBjdXJyZW50IHN0YXRlCiAgICAgICAgICAgIGNvbnZlcnRfZXZlbnRfYW5kX2V4ZWN1dGVfZW50cnk8bmV4dF9zdGF0ZV90eXBlLFQyPgogICAgICAgICAgICAgICAgKDo6Ym9vc3Q6OmZ1c2lvbjo6YXRfa2V5PG5leHRfc3RhdGVfdHlwZT4oZnNtLm1fc3Vic3RhdGVfbGlzdCksZXZ0LGZzbSk7CgogICAgICAgICAgICBmc20ubV9zdGF0ZXNbcmVnaW9uX2luZGV4XT1uZXh0X3N0YXRlOwogICAgICAgICAgICByZXR1cm4gSEFORExFRF9UUlVFOwogICAgICAgIH0KICAgIH07CgogICAgLy8gcm93IGhhdmluZyBubyBndWFyZCBjb25kaXRpb24gb3IgYWN0aW9uLCBzaW1wbHkgdHJhbnNpdGlvbnMKICAgIHRlbXBsYXRlPAogICAgICAgIHR5cGVuYW1lIFJPVwogICAgPgogICAgc3RydWN0IF9yb3dfCiAgICB7CiAgICAgICAgLy90eXBlZGVmIHR5cGVuYW1lIFJPVzo6U291cmNlIFQxOwogICAgICAgIHR5cGVkZWYgdHlwZW5hbWUgbWFrZV9lbnRyeTx0eXBlbmFtZSBST1c6OlNvdXJjZSxsaWJyYXJ5X3NtPjo6dHlwZSBUMTsKICAgICAgICB0eXBlZGVmIHR5cGVuYW1lIG1ha2VfZXhpdDx0eXBlbmFtZSBST1c6OlRhcmdldCxsaWJyYXJ5X3NtPjo6dHlwZSBUMjsKICAgICAgICB0eXBlZGVmIHR5cGVuYW1lIFJPVzo6RXZ0IHRyYW5zaXRpb25fZXZlbnQ7CiAgICAgICAgLy8gaWYgdGhlIHNvdXJjZSBpcyBhbiBleGl0IHBzZXVkbyBzdGF0ZSwgdGhlbgogICAgICAgIC8vIGN1cnJlbnRfc3RhdGVfdHlwZSBiZWNvbWVzIHRoZSByZXN1bHQgb2YgZ2V0X293bmVyCiAgICAgICAgLy8gbWVhbmluZyB0aGUgY29udGFpbmluZyBTTSBmcm9tIHdoaWNoIHRoZSBleGl0IG9jY3VycwogICAgICAgIHR5cGVkZWYgdHlwZW5hbWUgOjpib29zdDo6bXBsOjpldmFsX2lmPAogICAgICAgICAgICAgICAgdHlwZW5hbWUgaGFzX3BzZXVkb19leGl0PFQxPjo6dHlwZSwKICAgICAgICAgICAgICAgIGdldF9vd25lcjxUMSxsaWJyYXJ5X3NtPiwKICAgICAgICAgICAgICAgIDo6Ym9vc3Q6Om1wbDo6aWRlbnRpdHk8dHlwZW5hbWUgUk9XOjpTb3VyY2U+ID46OnR5cGUgY3VycmVudF9zdGF0ZV90eXBlOwoKICAgICAgICAvLyBpZiBUYXJnZXQgaXMgYSBzZXF1ZW5jZSwgdGhlbiB3ZSBoYXZlIGEgZm9yayBhbmQgZXhwZWN0IGEgc2VxdWVuY2Ugb2YgZXhwbGljaXRfZW50cnkKICAgICAgICAvLyBlbHNlIGlmIFRhcmdldCBpcyBhbiBleHBsaWNpdF9lbnRyeSwgbmV4dF9zdGF0ZV90eXBlIGJlY29tZXMgdGhlIHJlc3VsdCBvZiBnZXRfb3duZXIKICAgICAgICAvLyBtZWFuaW5nIHRoZSBjb250YWluaW5nIFNNIGlmIHRoZSByb3cgaXMgIm91dHNpZGUiIHRoZSBjb250YWluaW5nIFNNIG9yIGVsc2UgdGhlIGV4cGxpY2l0X2VudHJ5IHN0YXRlIGl0c2VsZgogICAgICAgIHR5cGVkZWYgdHlwZW5hbWUgOjpib29zdDo6bXBsOjpldmFsX2lmPAogICAgICAgICAgICB0eXBlbmFtZSA6OmJvb3N0OjptcGw6OmlzX3NlcXVlbmNlPFQyPjo6dHlwZSwKICAgICAgICAgICAgZ2V0X2Zvcmtfb3duZXI8VDIsbGlicmFyeV9zbT4sCiAgICAgICAgICAgIDo6Ym9vc3Q6Om1wbDo6ZXZhbF9pZjwKICAgICAgICAgICAgICAgICAgICB0eXBlbmFtZSBoYXNfbm9fYXV0b21hdGljX2NyZWF0ZTxUMj46OnR5cGUsCiAgICAgICAgICAgICAgICAgICAgZ2V0X293bmVyPFQyLGxpYnJhcnlfc20+LAogICAgICAgICAgICAgICAgICAgIDo6Ym9vc3Q6Om1wbDo6aWRlbnRpdHk8VDI+ID4KICAgICAgICA+Ojp0eXBlIG5leHRfc3RhdGVfdHlwZTsKCiAgICAgICAgLy8gVGFrZSB0aGUgdHJhbnNpdGlvbiBhY3Rpb24gYW5kIHJldHVybiB0aGUgbmV4dCBzdGF0ZS4KICAgICAgICBzdGF0aWMgSGFuZGxlZEVudW0gZXhlY3V0ZShsaWJyYXJ5X3NtJiBmc20sIGludCByZWdpb25faW5kZXgsIGludCBzdGF0ZSwgdHJhbnNpdGlvbl9ldmVudCBjb25zdCYgZXZ0KQogICAgICAgIHsKICAgICAgICAgICAgQk9PU1RfU1RBVElDX0NPTlNUQU5UKGludCwgY3VycmVudF9zdGF0ZSA9IChnZXRfc3RhdGVfaWQ8c3R0LGN1cnJlbnRfc3RhdGVfdHlwZT46OnR5cGU6OnZhbHVlKSk7CiAgICAgICAgICAgIEJPT1NUX1NUQVRJQ19DT05TVEFOVChpbnQsIG5leHRfc3RhdGUgPSAoZ2V0X3N0YXRlX2lkPHN0dCxuZXh0X3N0YXRlX3R5cGU+Ojp0eXBlOjp2YWx1ZSkpOwogICAgICAgICAgICBCT09TVF9BU1NFUlQoc3RhdGUgPT0gKGN1cnJlbnRfc3RhdGUpKTsKCiAgICAgICAgICAgIC8vIGlmIFQxIGlzIGFuIGV4aXQgcHNldWRvIHN0YXRlLCB0aGVuIHRha2UgdGhlIHRyYW5zaXRpb24gb25seSBpZiB0aGUgcHNldWRvIGV4aXQgc3RhdGUgaXMgYWN0aXZlCiAgICAgICAgICAgIGlmIChoYXNfcHNldWRvX2V4aXQ8VDE+Ojp0eXBlOjp2YWx1ZSAmJiAKICAgICAgICAgICAgICAgICFpc19leGl0X3N0YXRlX2FjdGl2ZTxUMSxnZXRfb3duZXI8VDEsbGlicmFyeV9zbT4gPihmc20pKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gSEFORExFRF9GQUxTRTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBmaXJzdCBjYWxsIHRoZSBleGl0IG1ldGhvZCBvZiB0aGUgY3VycmVudCBzdGF0ZQogICAgICAgICAgICBleGVjdXRlX2V4aXQ8Y3VycmVudF9zdGF0ZV90eXBlPgogICAgICAgICAgICAgICAgKDo6Ym9vc3Q6OmZ1c2lvbjo6YXRfa2V5PGN1cnJlbnRfc3RhdGVfdHlwZT4oZnNtLm1fc3Vic3RhdGVfbGlzdCksZXZ0LGZzbSk7CgogICAgICAgICAgICAvLyBhbmQgZmluYWxseSB0aGUgZW50cnkgbWV0aG9kIG9mIHRoZSBuZXcgY3VycmVudCBzdGF0ZQogICAgICAgICAgICBjb252ZXJ0X2V2ZW50X2FuZF9leGVjdXRlX2VudHJ5PG5leHRfc3RhdGVfdHlwZSxUMj4KICAgICAgICAgICAgICAgICg6OmJvb3N0OjpmdXNpb246OmF0X2tleTxuZXh0X3N0YXRlX3R5cGU+KGZzbS5tX3N1YnN0YXRlX2xpc3QpLGV2dCxmc20pOwoKICAgICAgICAgICAgZnNtLm1fc3RhdGVzW3JlZ2lvbl9pbmRleF09bmV4dF9zdGF0ZTsKICAgICAgICAgICAgcmV0dXJuIEhBTkRMRURfVFJVRTsKICAgICAgICB9CiAgICB9OwogICAgLy8gImkiIHJvd3MgYXJlIHJvd3MgZm9yIGludGVybmFsIHRyYW5zaXRpb25zCiAgICB0ZW1wbGF0ZTwKICAgICAgICB0eXBlbmFtZSBST1cKICAgID4KICAgIHN0cnVjdCBpcm93XwogICAgewogICAgICAgIHR5cGVkZWYgdHlwZW5hbWUgbWFrZV9lbnRyeTx0eXBlbmFtZSBST1c6OlNvdXJjZSxsaWJyYXJ5X3NtPjo6dHlwZSBUMTsKICAgICAgICB0eXBlZGVmIHR5cGVuYW1lIG1ha2VfZXhpdDx0eXBlbmFtZSBST1c6OlRhcmdldCxsaWJyYXJ5X3NtPjo6dHlwZSBUMjsKICAgICAgICB0eXBlZGVmIHR5cGVuYW1lIFJPVzo6RXZ0IHRyYW5zaXRpb25fZXZlbnQ7CiAgICAgICAgdHlwZWRlZiB0eXBlbmFtZSBST1c6OlNvdXJjZSBjdXJyZW50X3N0YXRlX3R5cGU7CiAgICAgICAgdHlwZWRlZiBUMiBuZXh0X3N0YXRlX3R5cGU7CgogICAgICAgIC8vIGlmIGEgZ3VhcmQgY29uZGl0aW9uIGlzIGhlcmUsIGNhbGwgaXQgdG8gY2hlY2sgdGhhdCB0aGUgZXZlbnQgaXMgYWNjZXB0ZWQKICAgICAgICBzdGF0aWMgYm9vbCBjaGVja19ndWFyZChsaWJyYXJ5X3NtJiBmc20sdHJhbnNpdGlvbl9ldmVudCBjb25zdCYgZXZ0KQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCBST1c6Omd1YXJkX2NhbGwoZnNtLGV2dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpib29zdDo6ZnVzaW9uOjphdF9rZXk8Y3VycmVudF9zdGF0ZV90eXBlPihmc20ubV9zdWJzdGF0ZV9saXN0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpib29zdDo6ZnVzaW9uOjphdF9rZXk8bmV4dF9zdGF0ZV90eXBlPihmc20ubV9zdWJzdGF0ZV9saXN0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnNtLm1fc3Vic3RhdGVfbGlzdCkpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICAvLyBUYWtlIHRoZSB0cmFuc2l0aW9uIGFjdGlvbiBhbmQgcmV0dXJuIHRoZSBuZXh0IHN0YXRlLgogICAgICAgIHN0YXRpYyBIYW5kbGVkRW51bSBleGVjdXRlKGxpYnJhcnlfc20mIGZzbSwgaW50ICwgaW50IHN0YXRlLCB0cmFuc2l0aW9uX2V2ZW50IGNvbnN0JiBldnQpCiAgICAgICAgewoKICAgICAgICAgICAgQk9PU1RfU1RBVElDX0NPTlNUQU5UKGludCwgY3VycmVudF9zdGF0ZSA9IChnZXRfc3RhdGVfaWQ8c3R0LGN1cnJlbnRfc3RhdGVfdHlwZT46OnR5cGU6OnZhbHVlKSk7CiAgICAgICAgICAgIEJPT1NUX0FTU0VSVChzdGF0ZSA9PSAoY3VycmVudF9zdGF0ZSkpOwogICAgICAgICAgICBpZiAoIWNoZWNrX2d1YXJkKGZzbSxldnQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBndWFyZCByZWplY3RlZCB0aGUgZXZlbnQsIHdlIHN0YXkgaW4gdGhlIGN1cnJlbnQgb25lCiAgICAgICAgICAgICAgICByZXR1cm4gSEFORExFRF9HVUFSRF9SRUpFQ1Q7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGNhbGwgdGhlIGFjdGlvbiBtZXRob2QKICAgICAgICAgICAgUk9XOjphY3Rpb25fY2FsbChmc20sZXZ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIDo6Ym9vc3Q6OmZ1c2lvbjo6YXRfa2V5PGN1cnJlbnRfc3RhdGVfdHlwZT4oZnNtLm1fc3Vic3RhdGVfbGlzdCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpib29zdDo6ZnVzaW9uOjphdF9rZXk8bmV4dF9zdGF0ZV90eXBlPihmc20ubV9zdWJzdGF0ZV9saXN0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmc20ubV9zdWJzdGF0ZV9saXN0KTsKICAgICAgICAgICAgcmV0dXJuIEhBTkRMRURfVFJVRTsKICAgICAgICB9CiAgICB9OwoKICAgIC8vIHJvdyBoYXZpbmcgb25seSBhIGd1YXJkIGNvbmRpdGlvbgogICAgdGVtcGxhdGU8CiAgICAgICAgdHlwZW5hbWUgUk9XCiAgICA+CiAgICBzdHJ1Y3QgZ19pcm93XwogICAgewogICAgICAgIHR5cGVkZWYgdHlwZW5hbWUgbWFrZV9lbnRyeTx0eXBlbmFtZSBST1c6OlNvdXJjZSxsaWJyYXJ5X3NtPjo6dHlwZSBUMTsKICAgICAgICB0eXBlZGVmIHR5cGVuYW1lIG1ha2VfZXhpdDx0eXBlbmFtZSBST1c6OlRhcmdldCxsaWJyYXJ5X3NtPjo6dHlwZSBUMjsKICAgICAgICB0eXBlZGVmIHR5cGVuYW1lIFJPVzo6RXZ0IHRyYW5zaXRpb25fZXZlbnQ7CiAgICAgICAgdHlwZWRlZiB0eXBlbmFtZSBST1c6OlNvdXJjZSBjdXJyZW50X3N0YXRlX3R5cGU7CiAgICAgICAgdHlwZWRlZiBUMiBuZXh0X3N0YXRlX3R5cGU7CgogICAgICAgIC8vIGlmIGEgZ3VhcmQgY29uZGl0aW9uIGlzIGRlZmluZWQsIGNhbGwgaXQgdG8gY2hlY2sgdGhhdCB0aGUgZXZlbnQgaXMgYWNjZXB0ZWQKICAgICAgICBzdGF0aWMgYm9vbCBjaGVja19ndWFyZChsaWJyYXJ5X3NtJiBmc20sdHJhbnNpdGlvbl9ldmVudCBjb25zdCYgZXZ0KQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCBST1c6Omd1YXJkX2NhbGwoZnNtLGV2dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpib29zdDo6ZnVzaW9uOjphdF9rZXk8Y3VycmVudF9zdGF0ZV90eXBlPihmc20ubV9zdWJzdGF0ZV9saXN0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpib29zdDo6ZnVzaW9uOjphdF9rZXk8bmV4dF9zdGF0ZV90eXBlPihmc20ubV9zdWJzdGF0ZV9saXN0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnNtLm1fc3Vic3RhdGVfbGlzdCkgKQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgLy8gVGFrZSB0aGUgdHJhbnNpdGlvbiBhY3Rpb24gYW5kIHJldHVybiB0aGUgbmV4dCBzdGF0ZS4KICAgICAgICBzdGF0aWMgSGFuZGxlZEVudW0gZXhlY3V0ZShsaWJyYXJ5X3NtJiBmc20sIGludCAsIGludCBzdGF0ZSwgdHJhbnNpdGlvbl9ldmVudCBjb25zdCYgZXZ0KQogICAgICAgIHsKICAgICAgICAgICAgQk9PU1RfU1RBVElDX0NPTlNUQU5UKGludCwgY3VycmVudF9zdGF0ZSA9IChnZXRfc3RhdGVfaWQ8c3R0LGN1cnJlbnRfc3RhdGVfdHlwZT46OnR5cGU6OnZhbHVlKSk7CiAgICAgICAgICAgIEJPT1NUX0FTU0VSVChzdGF0ZSA9PSAoY3VycmVudF9zdGF0ZSkpOwogICAgICAgICAgICBpZiAoIWNoZWNrX2d1YXJkKGZzbSxldnQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBndWFyZCByZWplY3RlZCB0aGUgZXZlbnQsIHdlIHN0YXkgaW4gdGhlIGN1cnJlbnQgb25lCiAgICAgICAgICAgICAgICByZXR1cm4gSEFORExFRF9HVUFSRF9SRUpFQ1Q7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIEhBTkRMRURfVFJVRTsKICAgICAgICB9CiAgICB9OwoKICAgIC8vIHJvdyBoYXZpbmcgb25seSBhbiBhY3Rpb24gbWV0aG9kCiAgICB0ZW1wbGF0ZTwKICAgICAgICB0eXBlbmFtZSBST1cKICAgID4KICAgIHN0cnVjdCBhX2lyb3dfIAogICAgewogICAgICAgIHR5cGVkZWYgdHlwZW5hbWUgbWFrZV9lbnRyeTx0eXBlbmFtZSBST1c6OlNvdXJjZSxsaWJyYXJ5X3NtPjo6dHlwZSBUMTsKICAgICAgICB0eXBlZGVmIHR5cGVuYW1lIG1ha2VfZXhpdDx0eXBlbmFtZSBST1c6OlRhcmdldCxsaWJyYXJ5X3NtPjo6dHlwZSBUMjsKCiAgICAgICAgdHlwZWRlZiB0eXBlbmFtZSBST1c6OkV2dCB0cmFuc2l0aW9uX2V2ZW50OwogICAgICAgIHR5cGVkZWYgdHlwZW5hbWUgUk9XOjpTb3VyY2UgY3VycmVudF9zdGF0ZV90eXBlOwogICAgICAgIHR5cGVkZWYgVDIgbmV4dF9zdGF0ZV90eXBlOwoKICAgICAgICAvLyBUYWtlIHRoZSB0cmFuc2l0aW9uIGFjdGlvbiBhbmQgcmV0dXJuIHRoZSBuZXh0IHN0YXRlLgogICAgICAgIHN0YXRpYyBIYW5kbGVkRW51bSBleGVjdXRlKGxpYnJhcnlfc20mIGZzbSwgaW50IHJlZ2lvbl9pbmRleCwgaW50IHN0YXRlLCB0cmFuc2l0aW9uX2V2ZW50IGNvbnN0JiBldnQpCiAgICAgICAgewogICAgICAgICAgICBCT09TVF9TVEFUSUNfQ09OU1RBTlQoaW50LCBjdXJyZW50X3N0YXRlID0gKGdldF9zdGF0ZV9pZDxzdHQsY3VycmVudF9zdGF0ZV90eXBlPjo6dHlwZTo6dmFsdWUpKTsKICAgICAgICAgICAgQk9PU1RfQVNTRVJUKHN0YXRlID09IChjdXJyZW50X3N0YXRlKSk7CgogICAgICAgICAgICAvLyBjYWxsIHRoZSBhY3Rpb24gbWV0aG9kCiAgICAgICAgICAgIFJPVzo6YWN0aW9uX2NhbGwoZnNtLGV2dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDo6Ym9vc3Q6OmZ1c2lvbjo6YXRfa2V5PGN1cnJlbnRfc3RhdGVfdHlwZT4oZnNtLm1fc3Vic3RhdGVfbGlzdCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6OmJvb3N0OjpmdXNpb246OmF0X2tleTxuZXh0X3N0YXRlX3R5cGU+KGZzbS5tX3N1YnN0YXRlX2xpc3QpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZnNtLm1fc3Vic3RhdGVfbGlzdCk7CgogICAgICAgICAgICByZXR1cm4gSEFORExFRF9UUlVFOwogICAgICAgIH0KICAgIH07CiAgICAvLyByb3cgc2ltcGx5IGlnbm9yaW5nIHRoZSBldmVudAogICAgdGVtcGxhdGU8CiAgICAgICAgdHlwZW5hbWUgUk9XCiAgICA+CiAgICBzdHJ1Y3QgX2lyb3dfIAogICAgewogICAgICAgIHR5cGVkZWYgdHlwZW5hbWUgbWFrZV9lbnRyeTx0eXBlbmFtZSBST1c6OlNvdXJjZSxsaWJyYXJ5X3NtPjo6dHlwZSBUMTsKICAgICAgICB0eXBlZGVmIHR5cGVuYW1lIG1ha2VfZXhpdDx0eXBlbmFtZSBST1c6OlRhcmdldCxsaWJyYXJ5X3NtPjo6dHlwZSBUMjsKICAgICAgICB0eXBlZGVmIHR5cGVuYW1lIFJPVzo6RXZ0IHRyYW5zaXRpb25fZXZlbnQ7CiAgICAgICAgdHlwZWRlZiB0eXBlbmFtZSBST1c6OlNvdXJjZSBjdXJyZW50X3N0YXRlX3R5cGU7CiAgICAgICAgdHlwZWRlZiBUMiBuZXh0X3N0YXRlX3R5cGU7CgogICAgICAgIC8vIFRha2UgdGhlIHRyYW5zaXRpb24gYWN0aW9uIGFuZCByZXR1cm4gdGhlIG5leHQgc3RhdGUuCiAgICAgICAgc3RhdGljIEhhbmRsZWRFbnVtIGV4ZWN1dGUobGlicmFyeV9zbSYgLCBpbnQgLCBpbnQgc3RhdGUsIHRyYW5zaXRpb25fZXZlbnQgY29uc3QmICkKICAgICAgICB7CiAgICAgICAgICAgIEJPT1NUX1NUQVRJQ19DT05TVEFOVChpbnQsIGN1cnJlbnRfc3RhdGUgPSAoZ2V0X3N0YXRlX2lkPHN0dCxjdXJyZW50X3N0YXRlX3R5cGU+Ojp0eXBlOjp2YWx1ZSkpOwogICAgICAgICAgICBCT09TVF9BU1NFUlQoc3RhdGUgPT0gKGN1cnJlbnRfc3RhdGUpKTsKICAgICAgICAgICAgcmV0dXJuIEhBTkRMRURfVFJVRTsKICAgICAgICB9CiAgICB9OwogICAgLy8gdHJhbnNpdGlvbnMgaW50ZXJuYWwgdG8gdGhpcyBzdGF0ZSBtYWNoaW5lIChubyBzdWJzdGF0ZSBpbnZvbHZlZCkKICAgIHRlbXBsYXRlPAogICAgICAgIHR5cGVuYW1lIFJPVywKICAgICAgICB0eXBlbmFtZSBTdGF0ZVR5cGUKICAgID4KICAgIHN0cnVjdCBpbnRlcm5hbF8KICAgIHsKICAgICAgICB0eXBlZGVmIFN0YXRlVHlwZSBjdXJyZW50X3N0YXRlX3R5cGU7CiAgICAgICAgdHlwZWRlZiBTdGF0ZVR5cGUgbmV4dF9zdGF0ZV90eXBlOwogICAgICAgIHR5cGVkZWYgdHlwZW5hbWUgUk9XOjpFdnQgdHJhbnNpdGlvbl9ldmVudDsKCiAgICAgICAgLy8gaWYgYSBndWFyZCBjb25kaXRpb24gaXMgaGVyZSwgY2FsbCBpdCB0byBjaGVjayB0aGF0IHRoZSBldmVudCBpcyBhY2NlcHRlZAogICAgICAgIHN0YXRpYyBib29sIGNoZWNrX2d1YXJkKGxpYnJhcnlfc20mIGZzbSx0cmFuc2l0aW9uX2V2ZW50IGNvbnN0JiBldnQpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIFJPVzo6Z3VhcmRfY2FsbChmc20sZXZ0LAogICAgICAgICAgICAgICAgOjpib29zdDo6ZnVzaW9uOjphdF9rZXk8U3RhdGVUeXBlPihmc20ubV9zdWJzdGF0ZV9saXN0KSwKICAgICAgICAgICAgICAgIDo6Ym9vc3Q6OmZ1c2lvbjo6YXRfa2V5PFN0YXRlVHlwZT4oZnNtLm1fc3Vic3RhdGVfbGlzdCksCiAgICAgICAgICAgICAgICBmc20ubV9zdWJzdGF0ZV9saXN0KSApCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICAvLyBUYWtlIHRoZSB0cmFuc2l0aW9uIGFjdGlvbiBhbmQgcmV0dXJuIHRoZSBuZXh0IHN0YXRlLgogICAgICAgIHN0YXRpYyBIYW5kbGVkRW51bSBleGVjdXRlKGxpYnJhcnlfc20mIGZzbSwgaW50IHJlZ2lvbl9pbmRleCwgaW50IHN0YXRlLCB0cmFuc2l0aW9uX2V2ZW50IGNvbnN0JiBldnQpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIWNoZWNrX2d1YXJkKGZzbSxldnQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBndWFyZCByZWplY3RlZCB0aGUgZXZlbnQsIHdlIHN0YXkgaW4gdGhlIGN1cnJlbnQgb25lCiAgICAgICAgICAgICAgICByZXR1cm4gSEFORExFRF9HVUFSRF9SRUpFQ1Q7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHRoZW4gY2FsbCB0aGUgYWN0aW9uIG1ldGhvZAogICAgICAgICAgICBST1c6OmFjdGlvbl9jYWxsKGZzbSxldnQsCiAgICAgICAgICAgICAgICA6OmJvb3N0OjpmdXNpb246OmF0X2tleTxTdGF0ZVR5cGU+KGZzbS5tX3N1YnN0YXRlX2xpc3QpLAogICAgICAgICAgICAgICAgOjpib29zdDo6ZnVzaW9uOjphdF9rZXk8U3RhdGVUeXBlPihmc20ubV9zdWJzdGF0ZV9saXN0KSwKICAgICAgICAgICAgICAgIGZzbS5tX3N1YnN0YXRlX2xpc3QpOwogICAgICAgICAgICByZXR1cm4gSEFORExFRF9UUlVFOwogICAgICAgIH0KICAgIH07CiAgICB0ZW1wbGF0ZTwKICAgICAgICB0eXBlbmFtZSBST1csCiAgICAgICAgdHlwZW5hbWUgU3RhdGVUeXBlCiAgICA+CiAgICBzdHJ1Y3QgYV9pbnRlcm5hbF8KICAgIHsKICAgICAgICB0eXBlZGVmIFN0YXRlVHlwZSBjdXJyZW50X3N0YXRlX3R5cGU7CiAgICAgICAgdHlwZWRlZiBTdGF0ZVR5cGUgbmV4dF9zdGF0ZV90eXBlOwogICAgICAgIHR5cGVkZWYgdHlwZW5hbWUgUk9XOjpFdnQgdHJhbnNpdGlvbl9ldmVudDsKCiAgICAgICAgLy8gVGFrZSB0aGUgdHJhbnNpdGlvbiBhY3Rpb24gYW5kIHJldHVybiB0aGUgbmV4dCBzdGF0ZS4KICAgICAgICBzdGF0aWMgSGFuZGxlZEVudW0gZXhlY3V0ZShsaWJyYXJ5X3NtJiBmc20sIGludCByZWdpb25faW5kZXgsIGludCBzdGF0ZSwgdHJhbnNpdGlvbl9ldmVudCBjb25zdCYgZXZ0KQogICAgICAgIHsKICAgICAgICAgICAgLy8gdGhlbiBjYWxsIHRoZSBhY3Rpb24gbWV0aG9kCiAgICAgICAgICAgIFJPVzo6YWN0aW9uX2NhbGwoZnNtLGV2dCwKICAgICAgICAgICAgICAgIDo6Ym9vc3Q6OmZ1c2lvbjo6YXRfa2V5PFN0YXRlVHlwZT4oZnNtLm1fc3Vic3RhdGVfbGlzdCksCiAgICAgICAgICAgICAgICA6OmJvb3N0OjpmdXNpb246OmF0X2tleTxTdGF0ZVR5cGU+KGZzbS5tX3N1YnN0YXRlX2xpc3QpLAogICAgICAgICAgICAgICAgZnNtLm1fc3Vic3RhdGVfbGlzdCk7CiAgICAgICAgICAgIHJldHVybiBIQU5ETEVEX1RSVUU7CiAgICAgICAgfQogICAgfTsKICAgIHRlbXBsYXRlPAogICAgICAgIHR5cGVuYW1lIFJPVywKICAgICAgICB0eXBlbmFtZSBTdGF0ZVR5cGUKICAgID4KICAgIHN0cnVjdCBnX2ludGVybmFsXwogICAgewogICAgICAgIHR5cGVkZWYgU3RhdGVUeXBlIGN1cnJlbnRfc3RhdGVfdHlwZTsKICAgICAgICB0eXBlZGVmIFN0YXRlVHlwZSBuZXh0X3N0YXRlX3R5cGU7CiAgICAgICAgdHlwZWRlZiB0eXBlbmFtZSBST1c6OkV2dCB0cmFuc2l0aW9uX2V2ZW50OwoKICAgICAgICAvLyBpZiBhIGd1YXJkIGNvbmRpdGlvbiBpcyBoZXJlLCBjYWxsIGl0IHRvIGNoZWNrIHRoYXQgdGhlIGV2ZW50IGlzIGFjY2VwdGVkCiAgICAgICAgc3RhdGljIGJvb2wgY2hlY2tfZ3VhcmQobGlicmFyeV9zbSYgZnNtLHRyYW5zaXRpb25fZXZlbnQgY29uc3QmIGV2dCkKICAgICAgICB7CiAgICAgICAgICAgIGlmICggUk9XOjpndWFyZF9jYWxsKGZzbSxldnQsCiAgICAgICAgICAgICAgICA6OmJvb3N0OjpmdXNpb246OmF0X2tleTxTdGF0ZVR5cGU+KGZzbS5tX3N1YnN0YXRlX2xpc3QpLAogICAgICAgICAgICAgICAgOjpib29zdDo6ZnVzaW9uOjphdF9rZXk8U3RhdGVUeXBlPihmc20ubV9zdWJzdGF0ZV9saXN0KSwKICAgICAgICAgICAgICAgIGZzbS5tX3N1YnN0YXRlX2xpc3QpICkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIC8vIFRha2UgdGhlIHRyYW5zaXRpb24gYWN0aW9uIGFuZCByZXR1cm4gdGhlIG5leHQgc3RhdGUuCiAgICAgICAgc3RhdGljIEhhbmRsZWRFbnVtIGV4ZWN1dGUobGlicmFyeV9zbSYgZnNtLCBpbnQgcmVnaW9uX2luZGV4LCBpbnQgc3RhdGUsIHRyYW5zaXRpb25fZXZlbnQgY29uc3QmIGV2dCkKICAgICAgICB7CiAgICAgICAgICAgIGlmICghY2hlY2tfZ3VhcmQoZnNtLGV2dCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIGd1YXJkIHJlamVjdGVkIHRoZSBldmVudCwgd2Ugc3RheSBpbiB0aGUgY3VycmVudCBvbmUKICAgICAgICAgICAgICAgIHJldHVybiBIQU5ETEVEX0dVQVJEX1JFSkVDVDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gSEFORExFRF9UUlVFOwogICAgICAgIH0KICAgIH07CiAgICB0ZW1wbGF0ZTwKICAgICAgICB0eXBlbmFtZSBST1csCiAgICAgICAgdHlwZW5hbWUgU3RhdGVUeXBlCiAgICA+CiAgICBzdHJ1Y3QgX2ludGVybmFsXwogICAgewogICAgICAgIHR5cGVkZWYgU3RhdGVUeXBlIGN1cnJlbnRfc3RhdGVfdHlwZTsKICAgICAgICB0eXBlZGVmIFN0YXRlVHlwZSBuZXh0X3N0YXRlX3R5cGU7CiAgICAgICAgdHlwZWRlZiB0eXBlbmFtZSBST1c6OkV2dCB0cmFuc2l0aW9uX2V2ZW50OwogICAgICAgIHN0YXRpYyBIYW5kbGVkRW51bSBleGVjdXRlKGxpYnJhcnlfc20mICwgaW50ICwgaW50ICwgdHJhbnNpdGlvbl9ldmVudCBjb25zdCYgKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIEhBTkRMRURfVFJVRTsKICAgICAgICB9CiAgICB9OwogICAgLy8gVGVtcGxhdGUgdXNlZCB0byBmb3JtIGZvcndhcmRpbmcgcm93cyBpbiB0aGUgdHJhbnNpdGlvbiB0YWJsZSBmb3IgZXZlcnkgcm93IG9mIGEgY29tcG9zaXRlIFNNCiAgICB0ZW1wbGF0ZTwKICAgICAgICB0eXBlbmFtZSBUMQogICAgICAgICwgY2xhc3MgRXZ0CiAgICA+CiAgICBzdHJ1Y3QgZnJvdwogICAgewogICAgICAgIHR5cGVkZWYgVDEgICAgICAgICAgICAgICAgICBjdXJyZW50X3N0YXRlX3R5cGU7CiAgICAgICAgdHlwZWRlZiBUMSAgICAgICAgICAgICAgICAgIG5leHRfc3RhdGVfdHlwZTsKICAgICAgICB0eXBlZGVmIEV2dCAgICAgICAgICAgICAgICAgdHJhbnNpdGlvbl9ldmVudDsKCiAgICAgICAgLy8gVGFrZSB0aGUgdHJhbnNpdGlvbiBhY3Rpb24gYW5kIHJldHVybiB0aGUgbmV4dCBzdGF0ZS4KICAgICAgICBzdGF0aWMgSGFuZGxlZEVudW0gZXhlY3V0ZShsaWJyYXJ5X3NtJiBmc20sIGludCByZWdpb25faW5kZXgsIGludCAsIHRyYW5zaXRpb25fZXZlbnQgY29uc3QmIGV2dCkKICAgICAgICB7CiAgICAgICAgICAgICBleGVjdXRlX3JldHVybiByZXMgPSAKICAgICAgICAgICAgICAgICg6OmJvb3N0OjpmdXNpb246OmF0X2tleTxjdXJyZW50X3N0YXRlX3R5cGU+KGZzbS5tX3N1YnN0YXRlX2xpc3QpKS5wcm9jZXNzX2V2ZW50KGV2dCk7IAogICAgICAgICAgICAgZnNtLm1fc3RhdGVzW3JlZ2lvbl9pbmRleF09Z2V0X3N0YXRlX2lkPHN0dCxUMT46OnR5cGU6OnZhbHVlOwogICAgICAgICAgICAgcmV0dXJuIHJlczsKICAgICAgICB9CiAgICB9OwoKICAgIHRlbXBsYXRlIDxjbGFzcyBUYWcsIGNsYXNzIFRyYW5zaXRpb24sY2xhc3MgU3RhdGVUeXBlPgogICAgc3RydWN0IGNyZWF0ZV9iYWNrZW5kX3N0dAogICAgewogICAgfTsKICAgIHRlbXBsYXRlIDxjbGFzcyBUcmFuc2l0aW9uLGNsYXNzIFN0YXRlVHlwZT4KICAgIHN0cnVjdCBjcmVhdGVfYmFja2VuZF9zdHQ8Z19yb3dfdGFnLFRyYW5zaXRpb24sU3RhdGVUeXBlPgogICAgewogICAgICAgIHR5cGVkZWYgZ19yb3dfPFRyYW5zaXRpb24+IHR5cGU7CiAgICB9OwogICAgdGVtcGxhdGUgPGNsYXNzIFRyYW5zaXRpb24sY2xhc3MgU3RhdGVUeXBlPgogICAgc3RydWN0IGNyZWF0ZV9iYWNrZW5kX3N0dDxhX3Jvd190YWcsVHJhbnNpdGlvbixTdGF0ZVR5cGU+CiAgICB7CiAgICAgICAgdHlwZWRlZiBhX3Jvd188VHJhbnNpdGlvbj4gdHlwZTsKICAgIH07CiAgICB0ZW1wbGF0ZSA8Y2xhc3MgVHJhbnNpdGlvbixjbGFzcyBTdGF0ZVR5cGU+CiAgICBzdHJ1Y3QgY3JlYXRlX2JhY2tlbmRfc3R0PF9yb3dfdGFnLFRyYW5zaXRpb24sU3RhdGVUeXBlPgogICAgewogICAgICAgIHR5cGVkZWYgX3Jvd188VHJhbnNpdGlvbj4gdHlwZTsKICAgIH07CiAgICB0ZW1wbGF0ZSA8Y2xhc3MgVHJhbnNpdGlvbixjbGFzcyBTdGF0ZVR5cGU+CiAgICBzdHJ1Y3QgY3JlYXRlX2JhY2tlbmRfc3R0PHJvd190YWcsVHJhbnNpdGlvbixTdGF0ZVR5cGU+CiAgICB7CiAgICAgICAgdHlwZWRlZiByb3dfPFRyYW5zaXRpb24+IHR5cGU7CiAgICB9OwogICAgLy8gaW50ZXJuYWwgdHJhbnNpdGlvbnMKICAgIHRlbXBsYXRlIDxjbGFzcyBUcmFuc2l0aW9uLGNsYXNzIFN0YXRlVHlwZT4KICAgIHN0cnVjdCBjcmVhdGVfYmFja2VuZF9zdHQ8Z19pcm93X3RhZyxUcmFuc2l0aW9uLFN0YXRlVHlwZT4KICAgIHsKICAgICAgICB0eXBlZGVmIGdfaXJvd188VHJhbnNpdGlvbj4gdHlwZTsKICAgIH07CiAgICB0ZW1wbGF0ZSA8Y2xhc3MgVHJhbnNpdGlvbixjbGFzcyBTdGF0ZVR5cGU+CiAgICBzdHJ1Y3QgY3JlYXRlX2JhY2tlbmRfc3R0PGFfaXJvd190YWcsVHJhbnNpdGlvbixTdGF0ZVR5cGU+CiAgICB7CiAgICAgICAgdHlwZWRlZiBhX2lyb3dfPFRyYW5zaXRpb24+IHR5cGU7CiAgICB9OwogICAgdGVtcGxhdGUgPGNsYXNzIFRyYW5zaXRpb24sY2xhc3MgU3RhdGVUeXBlPgogICAgc3RydWN0IGNyZWF0ZV9iYWNrZW5kX3N0dDxpcm93X3RhZyxUcmFuc2l0aW9uLFN0YXRlVHlwZT4KICAgIHsKICAgICAgICB0eXBlZGVmIGlyb3dfPFRyYW5zaXRpb24+IHR5cGU7CiAgICB9OwogICAgdGVtcGxhdGUgPGNsYXNzIFRyYW5zaXRpb24sY2xhc3MgU3RhdGVUeXBlPgogICAgc3RydWN0IGNyZWF0ZV9iYWNrZW5kX3N0dDxfaXJvd190YWcsVHJhbnNpdGlvbixTdGF0ZVR5cGU+CiAgICB7CiAgICAgICAgdHlwZWRlZiBfaXJvd188VHJhbnNpdGlvbj4gdHlwZTsKICAgIH07CiAgICB0ZW1wbGF0ZSA8Y2xhc3MgVHJhbnNpdGlvbixjbGFzcyBTdGF0ZVR5cGU+CiAgICBzdHJ1Y3QgY3JlYXRlX2JhY2tlbmRfc3R0PHNtX2FfaV9yb3dfdGFnLFRyYW5zaXRpb24sU3RhdGVUeXBlPgogICAgewogICAgICAgIHR5cGVkZWYgYV9pbnRlcm5hbF88VHJhbnNpdGlvbixTdGF0ZVR5cGU+IHR5cGU7CiAgICB9OwogICAgdGVtcGxhdGUgPGNsYXNzIFRyYW5zaXRpb24sY2xhc3MgU3RhdGVUeXBlPgogICAgc3RydWN0IGNyZWF0ZV9iYWNrZW5kX3N0dDxzbV9nX2lfcm93X3RhZyxUcmFuc2l0aW9uLFN0YXRlVHlwZT4KICAgIHsKICAgICAgICB0eXBlZGVmIGdfaW50ZXJuYWxfPFRyYW5zaXRpb24sU3RhdGVUeXBlPiB0eXBlOwogICAgfTsKICAgIHRlbXBsYXRlIDxjbGFzcyBUcmFuc2l0aW9uLGNsYXNzIFN0YXRlVHlwZT4KICAgIHN0cnVjdCBjcmVhdGVfYmFja2VuZF9zdHQ8c21faV9yb3dfdGFnLFRyYW5zaXRpb24sU3RhdGVUeXBlPgogICAgewogICAgICAgIHR5cGVkZWYgaW50ZXJuYWxfPFRyYW5zaXRpb24sU3RhdGVUeXBlPiB0eXBlOwogICAgfTsKICAgIHRlbXBsYXRlIDxjbGFzcyBUcmFuc2l0aW9uLGNsYXNzIFN0YXRlVHlwZT4KICAgIHN0cnVjdCBjcmVhdGVfYmFja2VuZF9zdHQ8c21fX2lfcm93X3RhZyxUcmFuc2l0aW9uLFN0YXRlVHlwZT4KICAgIHsKICAgICAgICB0eXBlZGVmIF9pbnRlcm5hbF88VHJhbnNpdGlvbixTdGF0ZVR5cGU+IHR5cGU7CiAgICB9OwogICAgdGVtcGxhdGUgPGNsYXNzIFRyYW5zaXRpb24sY2xhc3MgU3RhdGVUeXBlPXZvaWQ+CiAgICBzdHJ1Y3QgbWFrZV9yb3dfdGFnCiAgICB7CiAgICAgICAgdHlwZWRlZiB0eXBlbmFtZSBjcmVhdGVfYmFja2VuZF9zdHQ8dHlwZW5hbWUgVHJhbnNpdGlvbjo6cm93X3R5cGVfdGFnLFRyYW5zaXRpb24sU3RhdGVUeXBlPjo6dHlwZSB0eXBlOwogICAgfTsKCiAgICAvLyBhZGQgdG8gdGhlIHN0dCB0aGUgaW5pdGlhbCBzdGF0ZXMgd2hpY2ggY291bGQgYmUgbWlzc2luZyAoaWYgbm90IGJlaW5nIGludm9sdmVkIGluIGEgdHJhbnNpdGlvbikKICAgIHRlbXBsYXRlIDxjbGFzcyBCYXNlVHlwZSwgY2xhc3Mgc3R0X3NpbXVsYXRlZCA9IHR5cGVuYW1lIEJhc2VUeXBlOjp0cmFuc2l0aW9uX3RhYmxlPgogICAgc3RydWN0IGNyZWF0ZV9yZWFsX3N0dCAKICAgIHsKICAgICAgICAvL3R5cGVkZWYgdHlwZW5hbWUgQmFzZVR5cGU6OnRyYW5zaXRpb25fdGFibGUgc3R0X3NpbXVsYXRlZDsKICAgICAgICB0eXBlZGVmIHR5cGVuYW1lIDo6Ym9vc3Q6Om1wbDo6Zm9sZDwKICAgICAgICAgICAgc3R0X3NpbXVsYXRlZCxtcGw6OnZlY3RvcjA8PiwKICAgICAgICAgICAgOjpib29zdDo6bXBsOjpwdXNoX2JhY2s8IDo6Ym9vc3Q6Om1wbDo6cGxhY2Vob2xkZXJzOjpfMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ha2Vfcm93X3RhZzwgOjpib29zdDo6bXBsOjpwbGFjZWhvbGRlcnM6Ol8yICwgQmFzZVR5cGUgPiA+CiAgICAgICAgPjo6dHlwZSB0eXBlOwogICAgfTsKCiAgICB0ZW1wbGF0ZSA8Y2xhc3MgVGFibGUsY2xhc3MgSW50ZXJtZWRpYXRlLGNsYXNzIFN0YXRlVHlwZT4KICAgIHN0cnVjdCBhZGRfZm9yd2FyZGluZ19yb3dfaGVscGVyCiAgICB7CiAgICAgICAgdHlwZWRlZiB0eXBlbmFtZSBnZW5lcmF0ZV9ldmVudF9zZXQ8VGFibGU+Ojp0eXBlIGFsbF9ldmVudHM7CiAgICAgICAgdHlwZWRlZiB0eXBlbmFtZSA6OmJvb3N0OjptcGw6OmZvbGQ8CiAgICAgICAgICAgIGFsbF9ldmVudHMsIEludGVybWVkaWF0ZSwKICAgICAgICAgICAgOjpib29zdDo6bXBsOjpwdXNoX2JhY2s8IDo6Ym9vc3Q6Om1wbDo6cGxhY2Vob2xkZXJzOjpfMSwKICAgICAgICAgICAgZnJvdzxTdGF0ZVR5cGUsIDo6Ym9vc3Q6Om1wbDo6cGxhY2Vob2xkZXJzOjpfMj4gPiA+Ojp0eXBlIHR5cGU7CiAgICB9OwogICAgLy8gZ2V0cyB0aGUgdHJhbnNpdGlvbiB0YWJsZSBmcm9tIGEgY29tcG9zaXRlIGFuZCBtYWtlIGZyb20gaXQgYSBmb3J3YXJkaW5nIHJvdwogICAgdGVtcGxhdGUgPGNsYXNzIFN0YXRlVHlwZSxjbGFzcyBJc0NvbXBvc2l0ZT4KICAgIHN0cnVjdCBnZXRfaW50ZXJuYWxfdHJhbnNpdGlvbl90YWJsZQogICAgewogICAgICAgIC8vIGZpcnN0IGdldCB0aGUgdGFibGUgb2YgYSBjb21wb3NpdGUKICAgICAgICB0eXBlZGVmIHR5cGVuYW1lIHJlY3Vyc2l2ZV9nZXRfdHJhbnNpdGlvbl90YWJsZTxTdGF0ZVR5cGU+Ojp0eXBlIG9yaWdpbmFsX3RhYmxlOwoKICAgICAgICAvLyBhZGQgdGhlIGludGVybmFsIGV2ZW50cyBkZWZpbmVkIGluIHRoZSBpbnRlcm5hbF90cmFuc2l0aW9uX3RhYmxlCiAgICAgICAgLy8gTm90ZTogdGhlc2UgYXJlIGFkZGVkIGZpcnN0IGJlY2F1c2UgdGhleSBtdXN0IGhhdmUgYSBsZXNzZXIgcHJpbwogICAgICAgIC8vIHRoYW4gdGhlIGRlZXBlciB0cmFuc2l0aW9ucyBpbiB0aGUgc3ViIHJlZ2lvbnMKICAgICAgICB0eXBlZGVmIHR5cGVuYW1lIFN0YXRlVHlwZTo6aW50ZXJuYWxfdHJhbnNpdGlvbl90YWJsZSBpc3R0X3NpbXVsYXRlZDsKICAgICAgICB0eXBlZGVmIHR5cGVuYW1lIDo6Ym9vc3Q6Om1wbDo6Zm9sZDwKICAgICAgICAgICAgaXN0dF9zaW11bGF0ZWQsOjpib29zdDo6bXBsOjp2ZWN0b3IwPD4sCiAgICAgICAgICAgIDo6Ym9vc3Q6Om1wbDo6cHVzaF9iYWNrPCA6OmJvb3N0OjptcGw6OnBsYWNlaG9sZGVyczo6XzEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYWtlX3Jvd190YWc8IDo6Ym9vc3Q6Om1wbDo6cGxhY2Vob2xkZXJzOjpfMiAsIFN0YXRlVHlwZT4gPgogICAgICAgID46OnR5cGUgaW50ZXJtZWRpYXRlOwoKICAgICAgICAvLyBhbmQgYWRkIGZvciBldmVyeSBldmVudCBhIGZvcndhcmRpbmcgcm93CiAgICAgICAgdHlwZWRlZiB0eXBlbmFtZSA6OmJvb3N0OjptcGw6OmV2YWxfaWY8CiAgICAgICAgICAgICAgICB0eXBlbmFtZSBDb21waWxlUG9saWN5OjphZGRfZm9yd2FyZGluZ19yb3dzLAogICAgICAgICAgICAgICAgYWRkX2ZvcndhcmRpbmdfcm93X2hlbHBlcjxvcmlnaW5hbF90YWJsZSxpbnRlcm1lZGlhdGUsU3RhdGVUeXBlPiwKICAgICAgICAgICAgICAgIDo6Ym9vc3Q6Om1wbDo6aWRlbnRpdHk8aW50ZXJtZWRpYXRlPgogICAgICAgID46OnR5cGUgdHlwZTsKICAgIH07CiAgICB0ZW1wbGF0ZSA8Y2xhc3MgU3RhdGVUeXBlPgogICAgc3RydWN0IGdldF9pbnRlcm5hbF90cmFuc2l0aW9uX3RhYmxlPFN0YXRlVHlwZSwgOjpib29zdDo6bXBsOjpmYWxzZV8gPgogICAgewogICAgICAgIHR5cGVkZWYgdHlwZW5hbWUgY3JlYXRlX3JlYWxfc3R0PFN0YXRlVHlwZSwgdHlwZW5hbWUgU3RhdGVUeXBlOjppbnRlcm5hbF90cmFuc2l0aW9uX3RhYmxlID46OnR5cGUgdHlwZTsKICAgIH07CiAgICB0eXBlZGVmIHR5cGVuYW1lIGNyZWF0ZV9yZWFsX3N0dDxEZXJpdmVkPjo6dHlwZSByZWFsX3RyYW5zaXRpb25fdGFibGU7CiAgICB0eXBlZGVmIHR5cGVuYW1lIGNyZWF0ZV9zdHQ8bGlicmFyeV9zbT46OnR5cGUgc3R0OwogICAgdHlwZWRlZiB0eXBlbmFtZSBnZXRfaW5pdGlhbF9zdGF0ZXM8dHlwZW5hbWUgRGVyaXZlZDo6aW5pdGlhbF9zdGF0ZT46OnR5cGUgaW5pdGlhbF9zdGF0ZXM7CiAgICB0eXBlZGVmIHR5cGVuYW1lIGdlbmVyYXRlX3N0YXRlX3NldDxzdHQ+Ojp0eXBlIHN0YXRlX2xpc3Q7CiAgICB0eXBlZGVmIHR5cGVuYW1lIEhpc3RvcnlQb2xpY3k6OnRlbXBsYXRlIGFwcGx5PG5yX3JlZ2lvbnM6OnZhbHVlPjo6dHlwZSBjb25jcmV0ZV9oaXN0b3J5OwoKICAgIHR5cGVkZWYgdHlwZW5hbWUgOjpib29zdDo6ZnVzaW9uOjpyZXN1bHRfb2Y6OmFzX3NldDxzdGF0ZV9saXN0Pjo6dHlwZSBzdWJzdGF0ZV9saXN0OwoKICAgIC8vIGV4dGVuZHMgdGhlIHRyYW5zaXRpb24gdGFibGUgd2l0aCByb3dzIGZyb20gY29tcG9zaXRlIHN0YXRlcwogICAgdGVtcGxhdGUgPGNsYXNzIENvbXBvc2l0ZT4KICAgIHN0cnVjdCBleHRlbmRfdGFibGUKICAgIHsKICAgICAgICAvLyBhZGQgdGhlIGluaXQgc3RhdGVzCiAgICAgICAgLy90eXBlZGVmIHR5cGVuYW1lIGNyZWF0ZV9zdHQ8Q29tcG9zaXRlPjo6dHlwZSBzdHQ7CiAgICAgICAgdHlwZWRlZiB0eXBlbmFtZSBDb21wb3NpdGU6OnN0dCBTdHQ7CiAgICAgICAgLy8gZm9yIGV2ZXJ5IHN0YXRlLCBhZGQgaXRzIHRyYW5zaXRpb24gdGFibGUgKGlmIGFueSkKICAgICAgICAvLyB0cmFuc2Zvcm1lZCBhcyBmcm93CiAgICAgICAgdHlwZWRlZiB0eXBlbmFtZSA6OmJvb3N0OjptcGw6OmZvbGQ8c3RhdGVfbGlzdCxTdHQsCiAgICAgICAgICAgICAgICA6OmJvb3N0OjptcGw6Omluc2VydF9yYW5nZTwgCiAgICAgICAgICAgICAgICAgICAgICAgIDo6Ym9vc3Q6Om1wbDo6cGxhY2Vob2xkZXJzOjpfMSwgCiAgICAgICAgICAgICAgICAgICAgICAgIDo6Ym9vc3Q6Om1wbDo6ZW5kPCA6OmJvb3N0OjptcGw6OnBsYWNlaG9sZGVyczo6XzE+LAogICAgICAgICAgICAgICAgICAgICAgICBnZXRfaW50ZXJuYWxfdHJhbnNpdGlvbl90YWJsZTwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpib29zdDo6bXBsOjpwbGFjZWhvbGRlcnM6Ol8yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2NvbXBvc2l0ZV9zdGF0ZTwgOjpib29zdDo6bXBsOjpwbGFjZWhvbGRlcnM6Ol8yPiA+ID4gCiAgICAgICAgPjo6dHlwZSB0eXBlOwogICAgfTsKICAgIC8vIGV4dGVuZCB0aGUgdGFibGUgd2l0aCB0YWJsZXMgZnJvbSBjb21wb3NpdGUgc3RhdGVzCiAgICB0eXBlZGVmIHR5cGVuYW1lIGV4dGVuZF90YWJsZTxsaWJyYXJ5X3NtPjo6dHlwZSBjb21wbGV0ZV90YWJsZTsKICAgICAvLyBidWlsZCBhIHNlcXVlbmNlIG9mIHJlZ2lvbnMKICAgICB0eXBlZGVmIHR5cGVuYW1lIGdldF9yZWdpb25zX2FzX3NlcXVlbmNlPHR5cGVuYW1lIERlcml2ZWQ6OmluaXRpYWxfc3RhdGU+Ojp0eXBlIHNlcV9pbml0aWFsX3N0YXRlczsKICAgIC8vIE1lbWJlciBmdW5jdGlvbnMKCiAgICAvLyBzdGFydCB0aGUgc3RhdGUgbWFjaGluZSAoY2FsbHMgZW50cnkgb2YgdGhlIGluaXRpYWwgc3RhdGUpCiAgICB2b2lkIHN0YXJ0KCkKICAgIHsKICAgICAgICAvLyBjYWxsIG9uX2VudHJ5IG9uIHRoaXMgU00KICAgICAgICAoc3RhdGljX2Nhc3Q8RGVyaXZlZCo+KHRoaXMpKS0+b25fZW50cnkoZnNtX2luaXRpYWxfZXZlbnQoKSwqdGhpcyk7CiAgICAgICAgOjpib29zdDo6bXBsOjpmb3JfZWFjaDxpbml0aWFsX3N0YXRlcywgYm9vc3Q6Om1zbTo6d3JhcDxtcGw6OnBsYWNlaG9sZGVyczo6XzE+ID4KICAgICAgICAgICAgKGNhbGxfaW5pdDxmc21faW5pdGlhbF9ldmVudD4oZnNtX2luaXRpYWxfZXZlbnQoKSx0aGlzKSk7CiAgICAgICAgLy8gZ2l2ZSBhIGNoYW5jZSB0byBoYW5kbGUgYW4gYW5vbnltb3VzIChldmVudGxlc3MpIHRyYW5zaXRpb24KICAgICAgICBoYW5kbGVfZXZlbnRsZXNzX3RyYW5zaXRpb25zX2hlbHBlcjxsaWJyYXJ5X3NtPiBldmVudGxlc3NfaGVscGVyKHRoaXMsdHJ1ZSk7CiAgICAgICAgZXZlbnRsZXNzX2hlbHBlci5wcm9jZXNzX2NvbXBsZXRpb25fZXZlbnQoKTsKCiAgICB9CgogICAgLy8gTWFpbiBmdW5jdGlvbiB1c2VkIGJ5IGNsaWVudHMgb2YgdGhlIGRlcml2ZWQgRlNNIHRvIG1ha2UKICAgIC8vIHRyYW5zaXRpb25zLiBDYW4gYWxzbyBiZSBjYWxsZWQgZm9yIGludGVybmFsbHkgKGZvciBleGFtcGxlIGluIGFuIGFjdGlvbiBtZXRob2QpIGdlbmVyYXRlZCBldmVudHMuCiAgICB0ZW1wbGF0ZTxjbGFzcyBFdmVudD4KICAgIGV4ZWN1dGVfcmV0dXJuIHByb2Nlc3NfZXZlbnQoRXZlbnQgY29uc3QmIGV2dCkKICAgIHsKICAgICAgICBIYW5kbGVkRW51bSByZXRfaGFuZGxlZD1IQU5ETEVEX0ZBTFNFOwogICAgICAgIC8vIGlmIHRoZSBzdGF0ZSBtYWNoaW5lIGhhcyB0ZXJtaW5hdGUgb3IgaW50ZXJydXB0IGZsYWdzLCBjaGVjayB0aGVtLCBvdGhlcndpc2Ugc2tpcAogICAgICAgIGlmIChpc19ldmVudF9oYW5kbGluZ19ibG9ja2VkX2hlbHBlcjxFdmVudD4KICAgICAgICAgICAgICAgICggOjpib29zdDo6bXBsOjpib29sXzxoYXNfZnNtX2Jsb2NraW5nX3N0YXRlczxsaWJyYXJ5X3NtPjo6dHlwZTo6dmFsdWU+KCkgKSApCiAgICAgICAgICAgIHJldHVybiBIQU5ETEVEX1RSVUU7CiAgICAgICAgLy8gaWYgYSBtZXNzYWdlIHF1ZXVlIGlzIG5lZWRlZCBhbmQgcHJvY2Vzc2luZyBpcyBvbiB0aGUgd2F5CiAgICAgICAgaWYgKCFkb19wcmVfbXNnX3F1ZXVlX2hlbHBlcjxFdmVudD4KICAgICAgICAgICAgICAgIChldnQsOjpib29zdDo6bXBsOjpib29sXzxpc19ub19tZXNzYWdlX3F1ZXVlPGxpYnJhcnlfc20+Ojp0eXBlOjp2YWx1ZT4oKSkgKQogICAgICAgIHsKICAgICAgICAgICAgLy8gd2FpdCBmb3IgdGhlIGVuZCBvZiBjdXJyZW50IHByb2Nlc3NpbmcKICAgICAgICAgICAgcmV0dXJuIEhBTkRMRURfVFJVRTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgLy8gcHJlcGFyZSB0aGUgbmV4dCBkZWZlcnJlZCBldmVudCBmb3IgaGFuZGxpbmcKICAgICAgICAgICAgLy8gaWYgb25lIGRlZmVyIGlzIGZvdW5kIGluIHRoZSBTTSwgb3RoZXJ3aXNlIHNraXAKICAgICAgICAgICAgaGFuZGxlX2RlZmVyX2hlbHBlcjxsaWJyYXJ5X3NtPiBkZWZlcl9oZWxwZXIobV9kZWZlcnJlZF9ldmVudHNfcXVldWUpOwogICAgICAgICAgICBkZWZlcl9oZWxwZXIuZG9fcHJlX2hhbmRsZV9kZWZlcnJlZCgpOwogICAgICAgICAgICAvLyBwcm9jZXNzIGV2ZW50CiAgICAgICAgICAgIEhhbmRsZWRFbnVtIGhhbmRsZWQgPSB0aGlzLT5kb19wcm9jZXNzX2hlbHBlcjxFdmVudD4KICAgICAgICAgICAgICAgIChldnQsOjpib29zdDo6bXBsOjpib29sXzxpc19ub19leGNlcHRpb25fdGhyb3duPGxpYnJhcnlfc20+Ojp0eXBlOjp2YWx1ZT4oKSk7CiAgICAgICAgICAgIGlmIChoYW5kbGVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXRfaGFuZGxlZCA9IEhBTkRMRURfVFJVRTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gcHJvY2VzcyBjb21wbGV0aW9uIHRyYW5zaXRpb25zIEJFRk9SRSBhbnkgb3RoZXIgZXZlbnQgaW4gdGhlIHBvb2wgKFVNTCBTdGFuZGFyZCAyLjMgpzE1LjMuMTQpCiAgICAgICAgICAgIGhhbmRsZV9ldmVudGxlc3NfdHJhbnNpdGlvbnNfaGVscGVyPGxpYnJhcnlfc20+IGV2ZW50bGVzc19oZWxwZXIodGhpcywoaGFuZGxlZCA9PSBIQU5ETEVEX1RSVUUpKTsKICAgICAgICAgICAgZXZlbnRsZXNzX2hlbHBlci5wcm9jZXNzX2NvbXBsZXRpb25fZXZlbnQoKTsKCiAgICAgICAgICAgIC8vIGFmdGVyIGhhbmRsaW5nLCB0YWtlIGNhcmUgb2YgdGhlIGRlZmVycmVkIGV2ZW50cwogICAgICAgICAgICBkZWZlcl9oZWxwZXIuZG9fcG9zdF9oYW5kbGVfZGVmZXJyZWQoaGFuZGxlZCk7CgogICAgICAgICAgICAvLyBub3cgY2hlY2sgaWYgc29tZSBldmVudHMgd2VyZSBnZW5lcmF0ZWQgaW4gYSB0cmFuc2l0aW9uIGFuZCB3YXMgbm90IGhhbmRsZWQKICAgICAgICAgICAgLy8gYmVjYXVzZSBvZiBhbm90aGVyIHByb2Nlc3NpbmcsIGFuZCBpZiB5ZXMsIHN0YXJ0IGhhbmRsaW5nIHRoZW0KICAgICAgICAgICAgZG9fcG9zdF9tc2dfcXVldWVfaGVscGVyKDo6Ym9vc3Q6Om1wbDo6Ym9vbF88aXNfbm9fbWVzc2FnZV9xdWV1ZTxsaWJyYXJ5X3NtPjo6dHlwZTo6dmFsdWU+KCkpOwoKICAgICAgICAgICAgcmV0dXJuIHJldF9oYW5kbGVkOwogICAgICAgIH0gICAgICAgCiAgICB9CgogICAgLy8gR2V0dGVyIHRoYXQgcmV0dXJucyB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgRlNNCiAgICBjb25zdCBpbnQqIGN1cnJlbnRfc3RhdGUoKSBjb25zdAogICAgewogICAgICAgIHJldHVybiB0aGlzLT5tX3N0YXRlczsKICAgIH0KCiAgICB0ZW1wbGF0ZSA8Y2xhc3MgQXJjaGl2ZT4KICAgIHN0cnVjdCBzZXJpYWxpemVfc3RhdGUKICAgIHsKICAgICAgICBzZXJpYWxpemVfc3RhdGUoQXJjaGl2ZSYgYXIpOmFyXyhhcil7fQoKICAgICAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPgogICAgICAgIHR5cGVuYW1lIDo6Ym9vc3Q6OmVuYWJsZV9pZjwgCiAgICAgICAgICAgIHR5cGVuYW1lIDo6Ym9vc3Q6Om1wbDo6b3JfPAogICAgICAgICAgICAgICAgdHlwZW5hbWUgaGFzX2RvX3NlcmlhbGl6ZTxUPjo6dHlwZSwKICAgICAgICAgICAgICAgIHR5cGVuYW1lIGlzX2NvbXBvc2l0ZV9zdGF0ZTxUPjo6dHlwZQogICAgICAgICAgICA+Ojp0eXBlCiAgICAgICAgICAgICx2b2lkIAogICAgICAgID46OnR5cGUKICAgICAgICBvcGVyYXRvcigpKFQmIHQpIGNvbnN0CiAgICAgICAgewogICAgICAgICAgICBhcl8gJiB0OwogICAgICAgIH0KICAgICAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPgogICAgICAgIHR5cGVuYW1lIDo6Ym9vc3Q6OmRpc2FibGVfaWY8IAogICAgICAgICAgICB0eXBlbmFtZSA6OmJvb3N0OjptcGw6Om9yXzwKICAgICAgICAgICAgICAgIHR5cGVuYW1lIGhhc19kb19zZXJpYWxpemU8VD46OnR5cGUsCiAgICAgICAgICAgICAgICB0eXBlbmFtZSBpc19jb21wb3NpdGVfc3RhdGU8VD46OnR5cGUKICAgICAgICAgICAgPjo6dHlwZQogICAgICAgICAgICAsdm9pZCAKICAgICAgICA+Ojp0eXBlCiAgICAgICAgb3BlcmF0b3IoKShUJiB0KSBjb25zdAogICAgICAgIHsKICAgICAgICAgICAgLy8gbm8gc3RhdGUgdG8gc2VyaWFsaXplCiAgICAgICAgfQogICAgICAgIEFyY2hpdmUmIGFyXzsKICAgIH07CiAgICAKICAgIHRlbXBsYXRlPGNsYXNzIEFyY2hpdmU+CiAgICB2b2lkIHNlcmlhbGl6ZShBcmNoaXZlICYgYXIsIGNvbnN0IHVuc2lnbmVkIGludCkKICAgIHsKICAgICAgICAvLyBpbnZva2Ugc2VyaWFsaXphdGlvbiBvZiB0aGUgYmFzZSBjbGFzcyAKICAgICAgICAoc2VyaWFsaXplX3N0YXRlPEFyY2hpdmU+KGFyKSkoYm9vc3Q6OnNlcmlhbGl6YXRpb246OmJhc2Vfb2JqZWN0PERlcml2ZWQ+KCp0aGlzKSk7CiAgICAgICAgLy8gbm93IG91ciBhdHRyaWJ1dGVzCiAgICAgICAgYXIgJiBtX3N0YXRlczsKICAgICAgICAvLyBxdWV1ZXMgY2Fubm90IGJlIHNlcmlhbGl6ZWQgPT4gc2tpcAogICAgICAgIGFyICYgbV9oaXN0b3J5OwogICAgICAgIGFyICYgbV9ldmVudF9wcm9jZXNzaW5nOwogICAgICAgIGFyICYgbV9pc19pbmNsdWRlZDsKICAgICAgICAvLyB2aXNpdG9ycyBjYW5ub3QgYmUgc2VyaWFsaXplZCA9PiBza2lwCiAgICAgICAgOjpib29zdDo6ZnVzaW9uOjpmb3JfZWFjaChtX3N1YnN0YXRlX2xpc3QsIHNlcmlhbGl6ZV9zdGF0ZTxBcmNoaXZlPihhcikpOwogICAgfQoKICAgIC8vIGxpbmVhcmx5IHNlYXJjaCBmb3IgdGhlIHN0YXRlIHdpdGggdGhlIGdpdmVuIGlkCiAgICBzdHJ1Y3QgZ2V0X3N0YXRlX2lkX2hlbHBlciAKICAgIHsKICAgICAgICBnZXRfc3RhdGVfaWRfaGVscGVyKGludCBpZCxjb25zdCBCYXNlU3RhdGUqKiByZXMsY29uc3QgbGlicmFyeV9zbSogc2VsZl8pOgogICAgICAgIHJlc3VsdF9zdGF0ZShyZXMpLHNlYXJjaGVkX2lkKGlkKSxzZWxmKHNlbGZfKSB7fQoKICAgICAgICB0ZW1wbGF0ZSA8Y2xhc3MgU3RhdGVUeXBlPgogICAgICAgIHZvaWQgb3BlcmF0b3IoKShib29zdDo6bXNtOjp3cmFwPFN0YXRlVHlwZT4gY29uc3QmKQogICAgICAgIHsKICAgICAgICAgICAgLy8gbG9vayBmb3IgdGhlIHN0YXRlIGlkIHVudGlsIGZvdW5kCiAgICAgICAgICAgIEJPT1NUX1NUQVRJQ19DT05TVEFOVChpbnQsIGlkID0gKGdldF9zdGF0ZV9pZDxzdHQsU3RhdGVUeXBlPjo6dmFsdWUpKTsKICAgICAgICAgICAgaWYgKCEqcmVzdWx0X3N0YXRlICYmIChpZCA9PSBzZWFyY2hlZF9pZCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICpyZXN1bHRfc3RhdGUgPSAmOjpib29zdDo6ZnVzaW9uOjphdF9rZXk8U3RhdGVUeXBlPihzZWxmLT5tX3N1YnN0YXRlX2xpc3QpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNvbnN0IEJhc2VTdGF0ZSoqICByZXN1bHRfc3RhdGU7CiAgICAgICAgaW50ICAgICAgICAgICAgICAgIHNlYXJjaGVkX2lkOwogICAgICAgIGNvbnN0IGxpYnJhcnlfc20qIHNlbGY7CiAgICB9OwogICAgLy8gcmV0dXJuIHRoZSBzdGF0ZSB3aG9zZSBpZCBpcyBwYXNzZWQgb3IgMCBpZiBub3QgZm91bmQKICAgIC8vIGNhdXRpb24gaWYgeW91IG5lZWQgdGhpcywgeW91IHByb2JhYmx5IG5lZWQgcG9seW1vcnBoaWMgc3RhdGVzCiAgICAvLyBjb21wbGV4aXR5OiBPKG51bWJlciBvZiBzdGF0ZXMpCiAgICBjb25zdCBCYXNlU3RhdGUqIGdldF9zdGF0ZV9ieV9pZChpbnQgaWQpIGNvbnN0CiAgICB7CiAgICAgICAgY29uc3QgQmFzZVN0YXRlKiAgcmVzdWx0X3N0YXRlPTA7CiAgICAgICAgOjpib29zdDo6bXBsOjpmb3JfZWFjaDxzdGF0ZV9saXN0LCAKICAgICAgICAgICAgOjpib29zdDo6bXNtOjp3cmFwPCA6OmJvb3N0OjptcGw6OnBsYWNlaG9sZGVyczo6XzE+ID4gKGdldF9zdGF0ZV9pZF9oZWxwZXIoaWQsJnJlc3VsdF9zdGF0ZSx0aGlzKSk7CiAgICAgICAgcmV0dXJuIHJlc3VsdF9zdGF0ZTsKICAgIH0KICAgIC8vIHRydWUgaWYgdGhlIHNtIGlzIHVzZWQgaW4gYW5vdGhlciBzbQogICAgYm9vbCBpc19jb250YWluZWQoKSBjb25zdAogICAgewogICAgICAgIHJldHVybiBtX2lzX2luY2x1ZGVkOwogICAgfQogICAgLy8gZ2V0IGEgc3RhdGUKICAgIC8vIGFzIGEgcG9pbnRlcgogICAgdGVtcGxhdGUgPGNsYXNzIFN0YXRlPgogICAgdHlwZW5hbWUgOjpib29zdDo6ZW5hYmxlX2lmPHR5cGVuYW1lIDo6Ym9vc3Q6OmlzX3BvaW50ZXI8U3RhdGU+Ojp0eXBlLFN0YXRlID46OnR5cGUKICAgIGdldF9zdGF0ZSg6OmJvb3N0Ojptc206OmJhY2s6OmR1bW15PDA+ID0gMCkKICAgIHsKICAgICAgICByZXR1cm4gJihzdGF0aWNfY2FzdDx0eXBlbmFtZSBib29zdDo6YWRkX3JlZmVyZW5jZTx0eXBlbmFtZSA6OmJvb3N0OjpyZW1vdmVfcG9pbnRlcjxTdGF0ZT46OnR5cGU+Ojp0eXBlID4gCiAgICAgICAgKDo6Ym9vc3Q6OmZ1c2lvbjo6YXRfa2V5PHR5cGVuYW1lIDo6Ym9vc3Q6OnJlbW92ZV9wb2ludGVyPFN0YXRlPjo6dHlwZT4obV9zdWJzdGF0ZV9saXN0KSkpOwogICAgfQogICAgLy8gYXMgYSByZWZlcmVuY2UKICAgIHRlbXBsYXRlIDxjbGFzcyBTdGF0ZT4KICAgIHR5cGVuYW1lIDo6Ym9vc3Q6OmVuYWJsZV9pZjx0eXBlbmFtZSA6OmJvb3N0Ojppc19yZWZlcmVuY2U8U3RhdGU+Ojp0eXBlLFN0YXRlID46OnR5cGUKICAgIGdldF9zdGF0ZSg6OmJvb3N0Ojptc206OmJhY2s6OmR1bW15PDE+ID0gMCkKICAgIHsKICAgICAgICByZXR1cm4gOjpib29zdDo6ZnVzaW9uOjphdF9rZXk8dHlwZW5hbWUgOjpib29zdDo6cmVtb3ZlX3JlZmVyZW5jZTxTdGF0ZT46OnR5cGU+KG1fc3Vic3RhdGVfbGlzdCk7CiAgICB9CgogICAgLy8gY2hlY2tzIGlmIGEgZmxhZyBpcyBhY3RpdmUgdXNpbmcgdGhlIEJpbmFyeU9wIGFzIGZvbGRpbmcgZnVuY3Rpb24KICAgIHRlbXBsYXRlIDxjbGFzcyBGbGFnLGNsYXNzIEJpbmFyeU9wPgogICAgYm9vbCBpc19mbGFnX2FjdGl2ZSgpCiAgICB7CiAgICAgICAgZmxhZ19oYW5kbGVyKiBmbGFnc19lbnRyaWVzID0gZ2V0X2VudHJpZXNfZm9yX2ZsYWc8RmxhZz4oKTsKCiAgICAgICAgcmV0dXJuIHN0ZDo6YWNjdW11bGF0ZShtX3N0YXRlcywKICAgICAgICAgICAgbV9zdGF0ZXMrbnJfcmVnaW9uczo6dmFsdWUsZmFsc2UsCiAgICAgICAgICAgIDo6Ym9vc3Q6OmJpbmQodHlwZW5hbWUgQmluYXJ5T3A6OnR5cGUoKSwKICAgICAgICAgICAgICAgICAgICA6OmJvb3N0OjpiaW5kKDo6Ym9vc3Q6OmFwcGx5PGJvb2w+KCksCiAgICAgICAgICAgICAgICAgICAgOjpib29zdDo6YmluZCg6OmJvb3N0Ojptc206OmJhY2s6OmRlcmVmPGZsYWdfaGFuZGxlcj4oKSwKICAgICAgICAgICAgICAgICAgICAgICAgOjpib29zdDo6YmluZCg6OmJvb3N0Ojptc206OmJhY2s6OnBsdXMyPGZsYWdfaGFuZGxlciosaW50PigpLAogICAgICAgICAgICAgICAgICAgICAgICBmbGFnc19lbnRyaWVzLCBfMikpLAogICAgICAgICAgICAgICAgICAgICAgICA6OmJvb3N0OjpyZWYoKnRoaXMpKSwgXzEpKTsKICAgIH0KICAgIC8vIGNoZWNrcyBpZiBhIGZsYWcgaXMgYWN0aXZlIHVzaW5nIG5vIGJpbmFyeSBvcCBpZiAxIHJlZ2lvbiwgb3IgT1IgaWYgPiAxIHJlZ2lvbnMKICAgIHRlbXBsYXRlIDxjbGFzcyBGbGFnPgogICAgYm9vbCBpc19mbGFnX2FjdGl2ZSgpCiAgICB7CiAgICAgICAgcmV0dXJuIEZsYWdIZWxwZXI8RmxhZywobnJfcmVnaW9uczo6dmFsdWU+MSk+OjpoZWxwZXIoKnRoaXMsZ2V0X2VudHJpZXNfZm9yX2ZsYWc8RmxhZz4oKSk7CiAgICB9CiAgICAvLyB2aXNpdCB0aGUgY3VycmVudGx5IGFjdGl2ZSBzdGF0ZXMgKGlmIHRoZXNlIGFyZSBkZWZpbmVkIGFzIHZpc2l0YWJsZQogICAgLy8gYnkgaW1wbGVtZW50aW5nIGFjY2VwdCkKICAgIHZvaWQgdmlzaXRfY3VycmVudF9zdGF0ZXMoKQogICAgewogICAgICAgIGZvciAoaW50IGk9MDsgaTxucl9yZWdpb25zOjp2YWx1ZTsrK2kpCiAgICAgICAgewogICAgICAgICAgICBtX3Zpc2l0b3JzLmV4ZWN1dGUobV9zdGF0ZXNbaV0pOwogICAgICAgIH0KICAgIH0KI2RlZmluZSBNU01fVklTSVRfU1RBVEVfU1VCKHosIG4sIHVudXNlZCkgQVJHICMjIG4gdmlzICMjIG4KI2RlZmluZSBNU01fVklTSVRfU1RBVEVfRVhFQ1VURSh6LCBuLCB1bnVzZWQpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgIHRlbXBsYXRlIDxCT09TVF9QUF9FTlVNX1BBUkFNUyhuLCBjbGFzcyBBUkcpPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgdm9pZCB2aXNpdF9jdXJyZW50X3N0YXRlcyhCT09TVF9QUF9FTlVNKG4sIE1TTV9WSVNJVF9TVEFURV9TVUIsIH4gKSApICAgICAgICAgXAogICAgICAgIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxucl9yZWdpb25zOjp2YWx1ZTsrK2kpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgICAgICB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICAgICAgICAgIG1fdmlzaXRvcnMuZXhlY3V0ZShtX3N0YXRlc1tpXSxCT09TVF9QUF9FTlVNX1BBUkFNUyhuLHZpcykpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgIH0KICAgICAgICBCT09TVF9QUF9SRVBFQVRfRlJPTV9UTygxLEJPT1NUX1BQX0FERChCT09TVF9NU01fVklTSVRPUl9BUkdfU0laRSwxKSwgTVNNX1ZJU0lUX1NUQVRFX0VYRUNVVEUsIH4pCiN1bmRlZiBNU01fVklTSVRfU1RBVEVfRVhFQ1VURQojdW5kZWYgTVNNX1ZJU0lUX1NUQVRFX1NVQgoKICAgIC8vIHB1dHMgdGhlIGdpdmVuIGV2ZW50IGludG8gdGhlIGRlZmVycmVkIHF1ZXVlCiAgICB0ZW1wbGF0ZSA8Y2xhc3MgRXZlbnQ+CiAgICB2b2lkIGRlZmVyX2V2ZW50KEV2ZW50IGNvbnN0JiBlKQogICAgewogICAgICAgIC8vIHRvIGNhbGwgdGhpcyBmdW5jdGlvbiwgeW91IG5lZWQgZWl0aGVyIGEgc3RhdGUgd2l0aCBhIGRlZmVycmVkX2V2ZW50cyB0eXBlZGVmCiAgICAgICAgLy8gb3IgdGhhdCB0aGUgZnNtIHByb3ZpZGVzIHRoZSBhY3RpdmF0ZV9kZWZlcnJlZF9ldmVudHMgdHlwZWRlZgogICAgICAgIEJPT1NUX01QTF9BU1NFUlQoKCBoYXNfZnNtX2RlZmVycmVkX2V2ZW50czxsaWJyYXJ5X3NtPiApKTsKICAgICAgICBleGVjdXRlX3JldHVybiAobGlicmFyeV9zbTo6KnBmKSAoRXZlbnQgY29uc3QmIGV2dCk9ICZsaWJyYXJ5X3NtOjpwcm9jZXNzX2V2ZW50OwogICAgICAgIEV2ZW50IHRlbXAgKGUpOwogICAgICAgIDo6Ym9vc3Q6OmZ1bmN0aW9uPGV4ZWN1dGVfcmV0dXJuICgpID4gZj0gOjpib29zdDo6YmluZChwZiwgdGhpcyx0ZW1wKTsKICAgICAgICBwb3N0X2RlZmVycmVkX2V2ZW50KGYpOwogICAgfQoKIHByb3RlY3RlZDogICAgLy8gaW50ZXJmYWNlIGZvciB0aGUgZGVyaXZlZCBjbGFzcwoKICAgICAvLyBoZWxwZXIgdXNlZCB0byBmaWxsIHRoZSBpbml0aWFsIHN0YXRlcwogICAgIHN0cnVjdCBpbml0X3N0YXRlcwogICAgIHsKICAgICAgICAgaW5pdF9zdGF0ZXMoaW50KiBjb25zdCBpbml0KTptX2luaXRpYWxfc3RhdGVzKGluaXQpLG1faW5kZXgoLTEpe30KCiAgICAgICAgIC8vIEhpc3RvcnkgaW5pdGlhbGl6ZXIgZnVuY3Rpb24gb2JqZWN0LCB1c2VkIHdpdGggbXBsOjpmb3JfZWFjaAogICAgICAgICB0ZW1wbGF0ZSA8Y2xhc3MgU3RhdGU+CiAgICAgICAgIHZvaWQgb3BlcmF0b3IoKSg6OmJvb3N0Ojptc206OndyYXA8U3RhdGU+IGNvbnN0JikKICAgICAgICAgewogICAgICAgICAgICAgbV9pbml0aWFsX3N0YXRlc1srK21faW5kZXhdPWdldF9zdGF0ZV9pZDxzdHQsU3RhdGU+Ojp0eXBlOjp2YWx1ZTsKICAgICAgICAgfQogICAgICAgICBpbnQqIGNvbnN0IG1faW5pdGlhbF9zdGF0ZXM7CiAgICAgICAgIGludCBtX2luZGV4OwogICAgIH07CiBwdWJsaWM6CiAgICAgc3RydWN0IHVwZGF0ZV9zdGF0ZQogICAgIHsKICAgICAgICAgdXBkYXRlX3N0YXRlKHN1YnN0YXRlX2xpc3QmIHRvX292ZXJ3cml0ZV8pOnRvX292ZXJ3cml0ZSgmdG9fb3ZlcndyaXRlXyl7fQogICAgICAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBTdGF0ZVR5cGU+CiAgICAgICAgIHZvaWQgb3BlcmF0b3IoKShTdGF0ZVR5cGUgY29uc3QmIGFzdGF0ZSkgY29uc3QKICAgICAgICAgewogICAgICAgICAgICAgOjpib29zdDo6ZnVzaW9uOjphdF9rZXk8U3RhdGVUeXBlPigqdG9fb3ZlcndyaXRlKT1hc3RhdGU7CiAgICAgICAgIH0KICAgICAgICAgc3Vic3RhdGVfbGlzdCogdG9fb3ZlcndyaXRlOwogICAgIH07CiAgICAgdGVtcGxhdGUgPGNsYXNzIEV4cHI+CiAgICAgdm9pZCBzZXRfc3RhdGVzKEV4cHIgY29uc3QmIGV4cHIpCiAgICAgewogICAgICAgICA6OmJvb3N0OjpmdXNpb246OmZvcl9lYWNoKCAKICAgICAgICAgICAgIDo6Ym9vc3Q6OmZ1c2lvbjo6YXNfdmVjdG9yKEZvbGRUb0xpc3QoKShleHByLCBib29zdDo6ZnVzaW9uOjpuaWwoKSkpLHVwZGF0ZV9zdGF0ZSh0aGlzLT5tX3N1YnN0YXRlX2xpc3QpKTsKICAgICB9CgogICAgIC8vIENvbnN0cnVjdCB3aXRoIHRoZSBkZWZhdWx0IGluaXRpYWwgc3RhdGVzCiAgICAgc3RhdGVfbWFjaGluZTxEZXJpdmVkLEhpc3RvcnlQb2xpY3ksQ29tcGlsZVBvbGljeSAgID4oKQogICAgICAgICA6RGVyaXZlZCgpCiAgICAgICAgICxtX2V2ZW50c19xdWV1ZSgpIAogICAgICAgICAsbV9kZWZlcnJlZF9ldmVudHNfcXVldWUoKQogICAgICAgICAsbV9oaXN0b3J5KCkKICAgICAgICAgLG1fZXZlbnRfcHJvY2Vzc2luZyhmYWxzZSkKICAgICAgICAgLG1faXNfaW5jbHVkZWQoZmFsc2UpCiAgICAgICAgICxtX3Zpc2l0b3JzKCkKICAgICAgICAgLG1fc3Vic3RhdGVfbGlzdCgpCiAgICAgewogICAgICAgICAvLyBpbml0aWFsaXplIG91ciBsaXN0IG9mIHN0YXRlcyB3aXRoIHRoZSBvbmVzIGRlZmluZWQgaW4gRGVyaXZlZDo6aW5pdGlhbF9zdGF0ZQogICAgICAgICA6OmJvb3N0OjptcGw6OmZvcl9lYWNoPCBzZXFfaW5pdGlhbF9zdGF0ZXMsIDo6Ym9vc3Q6Om1zbTo6d3JhcDxtcGw6OnBsYWNlaG9sZGVyczo6XzE+ID4KICAgICAgICAgICAgICAgICAgICAgICAgKGluaXRfc3RhdGVzKG1fc3RhdGVzKSk7CiAgICAgICAgIG1faGlzdG9yeS5zZXRfaW5pdGlhbF9zdGF0ZXMobV9zdGF0ZXMpOwogICAgICAgICAvLyBjcmVhdGUgc3RhdGVzCiAgICAgICAgIGZpbGxfc3RhdGVzKHRoaXMpOwogICAgIH0KICAgICB0ZW1wbGF0ZSA8Y2xhc3MgRXhwcj4KICAgICBzdGF0ZV9tYWNoaW5lPERlcml2ZWQsSGlzdG9yeVBvbGljeSxDb21waWxlUG9saWN5ICAgPgogICAgICAgICAoRXhwciBjb25zdCYgZXhwcix0eXBlbmFtZSA6OmJvb3N0OjplbmFibGVfaWY8dHlwZW5hbWUgOjpib29zdDo6cHJvdG86OmlzX2V4cHI8RXhwcj46OnR5cGUgPjo6dHlwZSogZHVtbXk9MCkKICAgICAgICAgOkRlcml2ZWQoKQogICAgICAgICAsbV9ldmVudHNfcXVldWUoKSAKICAgICAgICAgLG1fZGVmZXJyZWRfZXZlbnRzX3F1ZXVlKCkKICAgICAgICAgLG1faGlzdG9yeSgpCiAgICAgICAgICxtX2V2ZW50X3Byb2Nlc3NpbmcoZmFsc2UpCiAgICAgICAgICxtX2lzX2luY2x1ZGVkKGZhbHNlKQogICAgICAgICAsbV92aXNpdG9ycygpCiAgICAgICAgICxtX3N1YnN0YXRlX2xpc3QoKQogICAgIHsKICAgICAgICAgQk9PU1RfTVBMX0FTU0VSVF9NU0coCiAgICAgICAgICAgICAoIDo6Ym9vc3Q6OnByb3RvOjptYXRjaGVzPEV4cHIsIEZvbGRUb0xpc3Q+Ojp2YWx1ZSksCiAgICAgICAgICAgICBUSEVfU1RBVEVTX0VYUFJFU1NJT05fUEFTU0VEX0RPRVNfTk9UX01BVENIX0dSQU1NQVIsCiAgICAgICAgICAgICAoRm9sZFRvTGlzdCkpOwoKICAgICAgICAgLy8gaW5pdGlhbGl6ZSBvdXIgbGlzdCBvZiBzdGF0ZXMgd2l0aCB0aGUgb25lcyBkZWZpbmVkIGluIERlcml2ZWQ6OmluaXRpYWxfc3RhdGUKICAgICAgICAgOjpib29zdDo6bXBsOjpmb3JfZWFjaDwgc2VxX2luaXRpYWxfc3RhdGVzLCA6OmJvb3N0Ojptc206OndyYXA8bXBsOjpwbGFjZWhvbGRlcnM6Ol8xPiA+CiAgICAgICAgICAgICAgICAgICAgICAgIChpbml0X3N0YXRlcyhtX3N0YXRlcykpOwogICAgICAgICBtX2hpc3Rvcnkuc2V0X2luaXRpYWxfc3RhdGVzKG1fc3RhdGVzKTsKICAgICAgICAgLy8gY3JlYXRlIHN0YXRlcwogICAgICAgICBmaWxsX3N0YXRlcyh0aGlzKTsKICAgICAgICAgc2V0X3N0YXRlcyhleHByKTsKICAgICB9CiAgICAgLy8gQ29uc3RydWN0IHdpdGggdGhlIGRlZmF1bHQgaW5pdGlhbCBzdGF0ZXMgYW5kIHNvbWUgZGVmYXVsdCBhcmd1bWVudChzKQojZGVmaW5lIE1TTV9DT05TVFJVQ1RPUl9IRUxQRVJfRVhFQ1VURV9TVUIoeiwgbiwgdW51c2VkKSBBUkcgIyMgbiB0ICMjIG4KI2RlZmluZSBNU01fQ09OU1RSVUNUT1JfSEVMUEVSX0VYRUNVVEUoeiwgbiwgdW51c2VkKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgIHRlbXBsYXRlIDxCT09TVF9QUF9FTlVNX1BBUkFNUyhuLCBjbGFzcyBBUkcpPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgc3RhdGVfbWFjaGluZTxEZXJpdmVkLEhpc3RvcnlQb2xpY3ksQ29tcGlsZVBvbGljeSAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICA+KEJPT1NUX1BQX0VOVU0obiwgTVNNX0NPTlNUUlVDVE9SX0hFTFBFUl9FWEVDVVRFX1NVQiwgfiApLCAgICAgICAgICAgICAgICAgXAogICAgICAgIHR5cGVuYW1lIDo6Ym9vc3Q6OmRpc2FibGVfaWY8dHlwZW5hbWUgOjpib29zdDo6cHJvdG86OmlzX2V4cHI8QVJHMD46OnR5cGUgPjo6dHlwZSogZHVtbXk9MCApICAgICAgICAgICAgICAgIFwKICAgICAgICA6RGVyaXZlZChCT09TVF9QUF9FTlVNX1BBUkFNUyhuLHQpKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgICAsbV9ldmVudHNfcXVldWUoKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgICxtX2RlZmVycmVkX2V2ZW50c19xdWV1ZSgpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICAgLG1faGlzdG9yeSgpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgICAsbV9ldmVudF9wcm9jZXNzaW5nKGZhbHNlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgICxtX2lzX2luY2x1ZGVkKGZhbHNlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICAgLG1fdmlzaXRvcnMoKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgICAsbV9zdWJzdGF0ZV9saXN0KCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICAgOjpib29zdDo6bXBsOjpmb3JfZWFjaDwgc2VxX2luaXRpYWxfc3RhdGVzLCA6OmJvb3N0Ojptc206OndyYXA8bXBsOjpwbGFjZWhvbGRlcnM6Ol8xPiA+IFwKICAgICAgICAgICAgICAgICAgICAgICAgKGluaXRfc3RhdGVzKG1fc3RhdGVzKSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgICBtX2hpc3Rvcnkuc2V0X2luaXRpYWxfc3RhdGVzKG1fc3RhdGVzKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgIGZpbGxfc3RhdGVzKHRoaXMpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgIHRlbXBsYXRlIDxjbGFzcyBFeHByLEJPT1NUX1BQX0VOVU1fUEFSQU1TKG4sIGNsYXNzIEFSRyk+ICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgc3RhdGVfbWFjaGluZTxEZXJpdmVkLEhpc3RvcnlQb2xpY3ksQ29tcGlsZVBvbGljeSAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICA+KEV4cHIgY29uc3QmIGV4cHIsQk9PU1RfUFBfRU5VTShuLCBNU01fQ09OU1RSVUNUT1JfSEVMUEVSX0VYRUNVVEVfU1VCLCB+ICksIFwKICAgICAgICB0eXBlbmFtZSA6OmJvb3N0OjplbmFibGVfaWY8dHlwZW5hbWUgOjpib29zdDo6cHJvdG86OmlzX2V4cHI8RXhwcj46OnR5cGUgPjo6dHlwZSogZHVtbXk9MCApIFwKICAgICAgICA6RGVyaXZlZChCT09TVF9QUF9FTlVNX1BBUkFNUyhuLHQpKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgICAsbV9ldmVudHNfcXVldWUoKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgICxtX2RlZmVycmVkX2V2ZW50c19xdWV1ZSgpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICAgLG1faGlzdG9yeSgpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgICAsbV9ldmVudF9wcm9jZXNzaW5nKGZhbHNlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgICxtX2lzX2luY2x1ZGVkKGZhbHNlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICAgLG1fdmlzaXRvcnMoKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgICAsbV9zdWJzdGF0ZV9saXN0KCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICAgQk9PU1RfTVBMX0FTU0VSVF9NU0coICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgICAoIDo6Ym9vc3Q6OnByb3RvOjptYXRjaGVzPEV4cHIsIEZvbGRUb0xpc3Q+Ojp2YWx1ZSksICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgICAgICBUSEVfU1RBVEVTX0VYUFJFU1NJT05fUEFTU0VEX0RPRVNfTk9UX01BVENIX0dSQU1NQVIsICAgICAgICAgICAgICAgICAgIFwKICAgICAgICAgICAgIChGb2xkVG9MaXN0KSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgICA6OmJvb3N0OjptcGw6OmZvcl9lYWNoPCBzZXFfaW5pdGlhbF9zdGF0ZXMsIDo6Ym9vc3Q6Om1zbTo6d3JhcDxtcGw6OnBsYWNlaG9sZGVyczo6XzE+ID4gXAogICAgICAgICAgICAgICAgICAgICAgICAoaW5pdF9zdGF0ZXMobV9zdGF0ZXMpKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgIG1faGlzdG9yeS5zZXRfaW5pdGlhbF9zdGF0ZXMobV9zdGF0ZXMpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICAgZmlsbF9zdGF0ZXModGhpcyk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgICBzZXRfc3RhdGVzKGV4cHIpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgfQoKICAgICBCT09TVF9QUF9SRVBFQVRfRlJPTV9UTygxLEJPT1NUX1BQX0FERChCT09TVF9NU01fQ09OU1RSVUNUT1JfQVJHX1NJWkUsMSksIE1TTV9DT05TVFJVQ1RPUl9IRUxQRVJfRVhFQ1VURSwgfikKI3VuZGVmIE1TTV9DT05TVFJVQ1RPUl9IRUxQRVJfRVhFQ1VURQojdW5kZWYgTVNNX0NPTlNUUlVDVE9SX0hFTFBFUl9FWEVDVVRFX1NVQgoKCgogICAgIC8vIGFzc2lnbm1lbnQgb3BlcmF0b3IgdXNpbmcgdGhlIGNvcHkgcG9saWN5IHRvIGRlY2lkZSBpZiBub25fY29weWFibGUsIHNoYWxsb3cgb3IgZGVlcCBjb3B5aW5nIGlzIG5lY2Vzc2FyeQogICAgIGxpYnJhcnlfc20mIG9wZXJhdG9yPSAobGlicmFyeV9zbSBjb25zdCYgcmhzKQogICAgIHsKICAgICAgICAgaWYgKHRoaXMgIT0gJnJocykgCiAgICAgICAgIHsKICAgICAgICAgICAgRGVyaXZlZDo6b3BlcmF0b3I9KHJocyk7CiAgICAgICAgICAgIC8vIGluaXRpYWxpemUgb3VyIGxpc3Qgb2Ygc3RhdGVzIHdpdGggdGhlIG9uZXMgZGVmaW5lZCBpbiBEZXJpdmVkOjppbml0aWFsX3N0YXRlCiAgICAgICAgICAgIGZpbGxfc3RhdGVzKHRoaXMpOwogICAgICAgICAgICBkb19jb3B5KHJocyk7CiAgICAgICAgIH0KICAgICAgICByZXR1cm4gKnRoaXM7CiAgICAgfQogICAgIHN0YXRlX21hY2hpbmU8RGVyaXZlZCxIaXN0b3J5UG9saWN5LENvbXBpbGVQb2xpY3k+IAogICAgICAgICAobGlicmFyeV9zbSBjb25zdCYgcmhzKQogICAgICAgICA6IERlcml2ZWQocmhzKQogICAgIHsKICAgICAgICBpZiAodGhpcyAhPSAmcmhzKSAKICAgICAgICB7CiAgICAgICAgICAgIC8vIGluaXRpYWxpemUgb3VyIGxpc3Qgb2Ygc3RhdGVzIHdpdGggdGhlIG9uZXMgZGVmaW5lZCBpbiBEZXJpdmVkOjppbml0aWFsX3N0YXRlCiAgICAgICAgICAgIGZpbGxfc3RhdGVzKHRoaXMpOwogICAgICAgICAgICBkb19jb3B5KHJocyk7CiAgICAgICAgfQogICAgIH0KCiAgICAvLyB0aGUgZm9sbG93aW5nIDIgZnVuY3Rpb25zIGhhbmRsZSB0aGUgdGVybWluYXRlL2ludGVycnVwdCBzdGF0ZXMgaGFuZGxpbmcKICAgIC8vIGlmIG9uZSBvZiB0aGVzZSBzdGF0ZXMgaXMgZm91bmQsIHRoZSBmaXJzdCBvbmUgaXMgdXNlZAogICAgdGVtcGxhdGUgPGNsYXNzIEV2ZW50PgogICAgYm9vbCBpc19ldmVudF9oYW5kbGluZ19ibG9ja2VkX2hlbHBlciggOjpib29zdDo6bXBsOjp0cnVlXyBjb25zdCAmKQogICAgewogICAgICAgIC8vIGlmIHRoZSBzdGF0ZSBtYWNoaW5lIGlzIHRlcm1pbmF0ZWQsIGRvIG5vdCBoYW5kbGUgYW55IGV2ZW50CiAgICAgICAgaWYgKGlzX2ZsYWdfYWN0aXZlPCA6OmJvb3N0Ojptc206OlRlcm1pbmF0ZUZsYWc+KCkpCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIC8vIGlmIHRoZSBzdGF0ZSBtYWNoaW5lIGlzIGludGVycnVwdGVkLCBkbyBub3QgaGFuZGxlIGFueSBldmVudAogICAgICAgIC8vIHVubGVzcyB0aGUgZXZlbnQgaXMgdGhlIGVuZCBpbnRlcnJ1cHQgZXZlbnQKICAgICAgICBpZiAoIGlzX2ZsYWdfYWN0aXZlPCA6OmJvb3N0Ojptc206OkludGVycnVwdGVkRmxhZz4oKSAmJiAKICAgICAgICAgICAgIWlzX2ZsYWdfYWN0aXZlPCA6OmJvb3N0Ojptc206OkVuZEludGVycnVwdEZsYWc8RXZlbnQ+ID4oKSkKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgLy8gb3RoZXJ3aXNlIHNpbXBsZSBoYW5kbGluZywgbm8gZmxhZyA9PiBjb250aW51ZQogICAgdGVtcGxhdGUgPGNsYXNzIEV2ZW50PgogICAgYm9vbCBpc19ldmVudF9oYW5kbGluZ19ibG9ja2VkX2hlbHBlciggOjpib29zdDo6bXBsOjpmYWxzZV8gY29uc3QgJikKICAgIHsKICAgICAgICAvLyBubyB0ZXJtaW5hdGUvaW50ZXJydXB0IHN0YXRlcyBkZXRlY3RlZAogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIC8vIHRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zIGhhbmRsZSBwcmUvcG9zdC1wcm9jZXNzIGhhbmRsaW5nICBvZiBhIG1lc3NhZ2UgcXVldWUKICAgIHRlbXBsYXRlIDxjbGFzcyBTdGF0ZVR5cGUsY2xhc3MgRXZlbnRUeXBlPgogICAgYm9vbCBkb19wcmVfbXNnX3F1ZXVlX2hlbHBlcihFdmVudFR5cGUgY29uc3QmIGV2dCwgOjpib29zdDo6bXBsOjp0cnVlXyBjb25zdCAmKQogICAgewogICAgICAgIC8vIG5vIG1lc3NhZ2UgcXVldWUgbmVlZGVkCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICB0ZW1wbGF0ZSA8Y2xhc3MgU3RhdGVUeXBlLGNsYXNzIEV2ZW50VHlwZT4KICAgIGJvb2wgZG9fcHJlX21zZ19xdWV1ZV9oZWxwZXIoRXZlbnRUeXBlIGNvbnN0JiBldnQsIDo6Ym9vc3Q6Om1wbDo6ZmFsc2VfIGNvbnN0ICYpCiAgICB7CiAgICAgICAgZXhlY3V0ZV9yZXR1cm4gKGxpYnJhcnlfc206OipwZikgKEV2ZW50VHlwZSBjb25zdCYgZXZ0KSA9IAogICAgICAgICAgICAmbGlicmFyeV9zbTo6cHJvY2Vzc19ldmVudDsgCiAgICAgICAgLy8gaWYgd2UgYXJlIGFscmVhZHkgcHJvY2Vzc2luZyBhbiBldmVudAogICAgICAgIGlmIChtX2V2ZW50X3Byb2Nlc3NpbmcpCiAgICAgICAgewogICAgICAgICAgICAvLyBldmVudCBoYXMgdG8gYmUgcHV0IGludG8gdGhlIHF1ZXVlCiAgICAgICAgICAgIHRyYW5zaXRpb25fZmN0IGYgPSA6OmJvb3N0OjpiaW5kKHBmLHRoaXMsZXZ0KTsKICAgICAgICAgICAgbV9ldmVudHNfcXVldWUubV9ldmVudHNfcXVldWUucHVzaChmKTsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICAvLyBldmVudCBjYW4gYmUgaGFuZGxlZCwgcHJvY2Vzc2luZwogICAgICAgIG1fZXZlbnRfcHJvY2Vzc2luZyA9IHRydWU7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICB2b2lkIGRvX3Bvc3RfbXNnX3F1ZXVlX2hlbHBlciggOjpib29zdDo6bXBsOjp0cnVlXyBjb25zdCAmKQogICAgewogICAgICAgIC8vIG5vIG1lc3NhZ2UgcXVldWUgbmVlZGVkCiAgICB9CiAgICB2b2lkIGRvX3Bvc3RfbXNnX3F1ZXVlX2hlbHBlciggOjpib29zdDo6bXBsOjpmYWxzZV8gY29uc3QgJikKICAgIHsKICAgICAgICBtX2V2ZW50X3Byb2Nlc3NpbmcgPSBmYWxzZTsKICAgICAgICBwcm9jZXNzX21lc3NhZ2VfcXVldWUodGhpcyk7CiAgICB9CiAgICAvLyB0aGUgZm9sbG93aW5nIDIgZnVuY3Rpb25zIGhhbmRsZSB0aGUgcHJvY2Vzc2luZyBlaXRoZXIgd2l0aCBhIHRyeS9jYXRjaCBwcm90ZWN0aW9uIG9yIHdpdGhvdXQKICAgIHRlbXBsYXRlIDxjbGFzcyBTdGF0ZVR5cGUsY2xhc3MgRXZlbnRUeXBlPgogICAgSGFuZGxlZEVudW0gZG9fcHJvY2Vzc19oZWxwZXIoRXZlbnRUeXBlIGNvbnN0JiBldnQsIDo6Ym9vc3Q6Om1wbDo6dHJ1ZV8gY29uc3QgJikKICAgIHsKICAgICAgICByZXR1cm4gdGhpcy0+ZG9fcHJvY2Vzc19ldmVudChldnQpOwogICAgfQogICAgdGVtcGxhdGUgPGNsYXNzIFN0YXRlVHlwZSxjbGFzcyBFdmVudFR5cGU+CiAgICBIYW5kbGVkRW51bSBkb19wcm9jZXNzX2hlbHBlcihFdmVudFR5cGUgY29uc3QmIGV2dCwgOjpib29zdDo6bXBsOjpmYWxzZV8gY29uc3QgJikKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLT5kb19wcm9jZXNzX2V2ZW50KGV2dCk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChzdGQ6OmV4Y2VwdGlvbiYgZSkKICAgICAgICB7CiAgICAgICAgICAgIC8vIGdpdmUgYSBjaGFuY2UgdG8gdGhlIGNvbmNyZXRlIHN0YXRlIG1hY2hpbmUgdG8gaGFuZGxlCiAgICAgICAgICAgIHRoaXMtPmV4Y2VwdGlvbl9jYXVnaHQoZXZ0LCp0aGlzLGUpOwogICAgICAgIH0gCiAgICAgICAgcmV0dXJuIEhBTkRMRURfRkFMU0U7CiAgICB9CiAgICAvLyBoYW5kbGluZyBvZiBkZWZlcnJlZCBldmVudHMKICAgIC8vIGlmIG5vbmUgaXMgZm91bmQgaW4gdGhlIFNNLCB0YWtlIHRoZSBmb2xsb3dpbmcgZW1wdHkgbWFpbiB2ZXJzaW9uCiAgICB0ZW1wbGF0ZSA8Y2xhc3MgU3RhdGVUeXBlLCBjbGFzcyBFbmFibGUgPSB2b2lkPiAKICAgIHN0cnVjdCBoYW5kbGVfZGVmZXJfaGVscGVyCiAgICB7CiAgICAgICAgaGFuZGxlX2RlZmVyX2hlbHBlcihkZWZlcnJlZF9tc2dfcXVldWVfaGVscGVyPGxpYnJhcnlfc20+JiApe30KICAgICAgICB2b2lkIGRvX3ByZV9oYW5kbGVfZGVmZXJyZWQoKQogICAgICAgIHsKICAgICAgICB9CgogICAgICAgIHZvaWQgZG9fcG9zdF9oYW5kbGVfZGVmZXJyZWQoSGFuZGxlZEVudW0pCiAgICAgICAgewogICAgICAgIH0KICAgIH07CiAgICAvLyBvdGhlcndpc2UgdGhlIHN0YW5kYXJkIHZlcnNpb24gaGFuZGxpbmcgdGhlIGRlZmVycmVkIGV2ZW50cwogICAgdGVtcGxhdGUgPGNsYXNzIFN0YXRlVHlwZT4KICAgIHN0cnVjdCBoYW5kbGVfZGVmZXJfaGVscGVyCiAgICAgICAgPFN0YXRlVHlwZSwgdHlwZW5hbWUgZW5hYmxlX2lmPCB0eXBlbmFtZSA6OmJvb3N0Ojptc206OmJhY2s6Omhhc19mc21fZGVmZXJyZWRfZXZlbnRzPFN0YXRlVHlwZT46OnR5cGUgPjo6dHlwZT4KICAgIHsKICAgICAgICBoYW5kbGVfZGVmZXJfaGVscGVyKGRlZmVycmVkX21zZ19xdWV1ZV9oZWxwZXI8bGlicmFyeV9zbT4mIGFfcXVldWUpOgogICAgICAgICAgICBldmVudHNfcXVldWUoYV9xdWV1ZSksbmV4dF9kZWZlcnJlZF9ldmVudCgpe30KICAgICAgICB2b2lkIGRvX3ByZV9oYW5kbGVfZGVmZXJyZWQoKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCFldmVudHNfcXVldWUubV9kZWZlcnJlZF9ldmVudHNfcXVldWUuZW1wdHkoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbmV4dF9kZWZlcnJlZF9ldmVudCA9IGV2ZW50c19xdWV1ZS5tX2RlZmVycmVkX2V2ZW50c19xdWV1ZS5iYWNrKCk7CiAgICAgICAgICAgICAgICBldmVudHNfcXVldWUubV9kZWZlcnJlZF9ldmVudHNfcXVldWUucG9wX2JhY2soKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdm9pZCBkb19wb3N0X2hhbmRsZV9kZWZlcnJlZChIYW5kbGVkRW51bSBoYW5kbGVkKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCgoaGFuZGxlZCAmIEhBTkRMRURfREVGRVJSRUQpID09IEhBTkRMRURfREVGRVJSRUQpICYmIG5leHRfZGVmZXJyZWRfZXZlbnQgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyB0aGUgZXZlbnQgd2FzIGFscmVhZHkgZGVmZXJyZWQsIG5vIHJlYXNvbiB0byBwcm9jZXNzIGFub3RoZXIgZGVmZXJyZWQgZXZlbnQKICAgICAgICAgICAgICAgIGV2ZW50c19xdWV1ZS5tX2RlZmVycmVkX2V2ZW50c19xdWV1ZS5wdXNoX2JhY2sobmV4dF9kZWZlcnJlZF9ldmVudCk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAobmV4dF9kZWZlcnJlZF9ldmVudCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbmV4dF9kZWZlcnJlZF9ldmVudCgpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIHByaXZhdGU6CiAgICAgICAgZGVmZXJyZWRfbXNnX3F1ZXVlX2hlbHBlcjxsaWJyYXJ5X3NtPiYgIGV2ZW50c19xdWV1ZTsKICAgICAgICBkZWZlcnJlZF9mY3QgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV4dF9kZWZlcnJlZF9ldmVudDsKICAgIH07CgogICAgLy8gaGFuZGxpbmcgb2YgZXZlbnRsZXNzIHRyYW5zaXRpb25zCiAgICAvLyBpZiBub25lIGlzIGZvdW5kIGluIHRoZSBTTSwgbm90aGluZyB0byBkbwogICAgdGVtcGxhdGUgPGNsYXNzIFN0YXRlVHlwZSwgY2xhc3MgRW5hYmxlID0gdm9pZD4gCiAgICBzdHJ1Y3QgaGFuZGxlX2V2ZW50bGVzc190cmFuc2l0aW9uc19oZWxwZXIKICAgIHsKICAgICAgICBoYW5kbGVfZXZlbnRsZXNzX3RyYW5zaXRpb25zX2hlbHBlcihsaWJyYXJ5X3NtKiAsIGJvb2wgKXt9CiAgICAgICAgdm9pZCBwcm9jZXNzX2NvbXBsZXRpb25fZXZlbnQoKXt9CiAgICB9OwogICAgLy8gb3RoZXJ3aXNlIAogICAgdGVtcGxhdGUgPGNsYXNzIFN0YXRlVHlwZT4KICAgIHN0cnVjdCBoYW5kbGVfZXZlbnRsZXNzX3RyYW5zaXRpb25zX2hlbHBlcgogICAgICAgIDxTdGF0ZVR5cGUsIHR5cGVuYW1lIGVuYWJsZV9pZjwgdHlwZW5hbWUgOjpib29zdDo6bXNtOjpiYWNrOjpoYXNfZnNtX2V2ZW50bGVzc190cmFuc2l0aW9uPFN0YXRlVHlwZT46OnR5cGUgPjo6dHlwZT4KICAgIHsKICAgICAgICBoYW5kbGVfZXZlbnRsZXNzX3RyYW5zaXRpb25zX2hlbHBlcihsaWJyYXJ5X3NtKiBzZWxmXywgYm9vbCBoYW5kbGVkXyk6c2VsZihzZWxmXyksaGFuZGxlZChoYW5kbGVkXyl7fQogICAgICAgIHZvaWQgcHJvY2Vzc19jb21wbGV0aW9uX2V2ZW50KCkKICAgICAgICB7CiAgICAgICAgICAgIHR5cGVkZWYgdHlwZW5hbWUgOjpib29zdDo6bXBsOjpkZXJlZjwKICAgICAgICAgICAgICAgIHR5cGVuYW1lIDo6Ym9vc3Q6Om1wbDo6YmVnaW48CiAgICAgICAgICAgICAgICAgICAgdHlwZW5hbWUgZmluZF9jb21wbGV0aW9uX2V2ZW50czxTdGF0ZVR5cGU+Ojp0eXBlCiAgICAgICAgICAgICAgICAgICAgICAgID46OnR5cGUKICAgICAgICAgICAgPjo6dHlwZSBmaXJzdF9jb21wbGV0aW9uX2V2ZW50OwogICAgICAgICAgICBpZiAoaGFuZGxlZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc2VsZi0+cHJvY2Vzc19ldmVudChmaXJzdF9jb21wbGV0aW9uX2V2ZW50KCkgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KIAogICAgcHJpdmF0ZToKICAgICAgICBsaWJyYXJ5X3NtKiBzZWxmOwogICAgICAgIGJvb2wgICAgICAgIGhhbmRsZWQ7CiAgICB9OwoKICAgIHRlbXBsYXRlIDxjbGFzcyBTdGF0ZVR5cGUsY2xhc3MgRW5hYmxlPXZvaWQ+CiAgICBzdHJ1Y3QgcmVnaW9uX3Byb2Nlc3NpbmdfaGVscGVyIAogICAgewogICAgcHVibGljOgogICAgICAgIHJlZ2lvbl9wcm9jZXNzaW5nX2hlbHBlcihsaWJyYXJ5X3NtKiBzZWxmXyxIYW5kbGVkRW51bSYgcmVzdWx0XykKICAgICAgICAgICAgOnNlbGYoc2VsZl8pLHJlc3VsdChyZXN1bHRfKXt9CiAgICAgICAgdGVtcGxhdGU8Y2xhc3MgRXZlbnQ+CiAgICAgICAgdm9pZCBwcm9jZXNzKEV2ZW50IGNvbnN0JiBldnQpCiAgICAgICAgewogICAgICAgICAgICAvLyB1c2UgdGhpcyB0YWJsZSBhcyBpZiBpdCBjYW1lIGRpcmVjdGx5IGZyb20gdGhlIHVzZXIKICAgICAgICAgICAgdHlwZWRlZiBkaXNwYXRjaF90YWJsZTxsaWJyYXJ5X3NtLGNvbXBsZXRlX3RhYmxlLEV2ZW50LENvbXBpbGVQb2xpY3k+IHRhYmxlOwogICAgICAgICAgICBIYW5kbGVkRW51bSByZXMgPQogICAgICAgICAgICAgICAgdGFibGU6Omluc3RhbmNlLmVudHJpZXNbc2VsZi0+bV9zdGF0ZXNbMF1dKAogICAgICAgICAgICAgICAgKnNlbGYsIDAsIHNlbGYtPm1fc3RhdGVzWzBdLCBldnQpOwogICAgICAgICAgICByZXN1bHQgPSAoSGFuZGxlZEVudW0pKChpbnQpcmVzdWx0IHwgKGludClyZXMpOwogICAgICAgIH0KICAgICAgICBsaWJyYXJ5X3NtKiAgICAgc2VsZjsKICAgICAgICBIYW5kbGVkRW51bSYgICAgcmVzdWx0OwogICAgfTsKICAgIC8vIHZlcnNpb24gd2l0aCB2aXNpdG9ycwogICAgdGVtcGxhdGUgPGNsYXNzIFN0YXRlVHlwZT4KICAgIHN0cnVjdCByZWdpb25fcHJvY2Vzc2luZ19oZWxwZXI8U3RhdGVUeXBlLHR5cGVuYW1lIDo6Ym9vc3Q6OmVuYWJsZV9pZjwgCiAgICAgICAgICAgICAgICAgICAgICAgIDo6Ym9vc3Q6Om1wbDo6aXNfc2VxdWVuY2U8dHlwZW5hbWUgU3RhdGVUeXBlOjppbml0aWFsX3N0YXRlPiA+Ojp0eXBlPiAKICAgIHsKICAgICAgICBwcml2YXRlOgogICAgICAgIC8vIHByb2Nlc3MgZXZlbnQgaW4gb25lIHJlZ2lvbgogICAgICAgIHRlbXBsYXRlIDxjbGFzcyByZWdpb25faWQsaW50IER1bW15PTA+CiAgICAgICAgc3RydWN0IEluCiAgICAgICAgewogICAgICAgICAgICB0ZW1wbGF0ZTxjbGFzcyBFdmVudD4KICAgICAgICAgICAgc3RhdGljIHZvaWQgcHJvY2VzcyhFdmVudCBjb25zdCYgZXZ0LGxpYnJhcnlfc20qIHNlbGZfLEhhbmRsZWRFbnVtJiByZXN1bHRfKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyB1c2UgdGhpcyB0YWJsZSBhcyBpZiBpdCBjYW1lIGRpcmVjdGx5IGZyb20gdGhlIHVzZXIKICAgICAgICAgICAgICAgIHR5cGVkZWYgZGlzcGF0Y2hfdGFibGU8bGlicmFyeV9zbSxjb21wbGV0ZV90YWJsZSxFdmVudCxDb21waWxlUG9saWN5PiB0YWJsZTsKICAgICAgICAgICAgICAgIEhhbmRsZWRFbnVtIHJlcyA9CiAgICAgICAgICAgICAgICAgICAgdGFibGU6Omluc3RhbmNlLmVudHJpZXNbc2VsZl8tPm1fc3RhdGVzW3JlZ2lvbl9pZDo6dmFsdWVdXSgKICAgICAgICAgICAgICAgICAgICAqc2VsZl8sIHJlZ2lvbl9pZDo6dmFsdWUgLCBzZWxmXy0+bV9zdGF0ZXNbcmVnaW9uX2lkOjp2YWx1ZV0sIGV2dCk7CiAgICAgICAgICAgICAgICByZXN1bHRfID0gKEhhbmRsZWRFbnVtKSgoaW50KXJlc3VsdF8gfCAoaW50KXJlcyk7CiAgICAgICAgICAgICAgICBJbjwgOjpib29zdDo6bXBsOjppbnRfPHJlZ2lvbl9pZDo6dmFsdWUrMT4gPjo6cHJvY2VzcyhldnQsc2VsZl8scmVzdWx0Xyk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgICAgIHRlbXBsYXRlIDxpbnQgRHVtbXk+CiAgICAgICAgc3RydWN0IEluPCA6OmJvb3N0OjptcGw6OmludF88bnJfcmVnaW9uczo6dmFsdWU+LER1bW15PgogICAgICAgIHsKICAgICAgICAgICAgLy8gZW5kIG9mIHByb2Nlc3NpbmcKICAgICAgICAgICAgdGVtcGxhdGU8Y2xhc3MgRXZlbnQ+CiAgICAgICAgICAgIHN0YXRpYyB2b2lkIHByb2Nlc3MoRXZlbnQgY29uc3QmIGV2dCxsaWJyYXJ5X3NtKixIYW5kbGVkRW51bSYpe30KICAgICAgICB9OwogICAgICAgIHB1YmxpYzoKICAgICAgICByZWdpb25fcHJvY2Vzc2luZ19oZWxwZXIobGlicmFyeV9zbSogc2VsZl8sSGFuZGxlZEVudW0mIHJlc3VsdF8pCiAgICAgICAgICAgIDpzZWxmKHNlbGZfKSxyZXN1bHQocmVzdWx0Xyl7fQogICAgICAgIHRlbXBsYXRlPGNsYXNzIEV2ZW50PgogICAgICAgIHZvaWQgcHJvY2VzcyhFdmVudCBjb25zdCYgZXZ0KQogICAgICAgIHsKICAgICAgICAgICAgLy8gdXNlIHRoaXMgdGFibGUgYXMgaWYgaXQgY2FtZSBkaXJlY3RseSBmcm9tIHRoZSB1c2VyCiAgICAgICAgICAgIHR5cGVkZWYgZGlzcGF0Y2hfdGFibGU8bGlicmFyeV9zbSxjb21wbGV0ZV90YWJsZSxFdmVudCxDb21waWxlUG9saWN5PiB0YWJsZTsKICAgICAgICAgICAgSW48IDo6Ym9vc3Q6Om1wbDo6aW50XzwwPiA+Ojpwcm9jZXNzKGV2dCxzZWxmLHJlc3VsdCk7CiAgICAgICAgfQoKICAgICAgICBsaWJyYXJ5X3NtKiAgICAgc2VsZjsKICAgICAgICBIYW5kbGVkRW51bSYgICAgcmVzdWx0OwogICAgfTsKCiAgICAvLyBtaW5pbXVtIGV2ZW50IHByb2Nlc3Npbmcgd2l0aG91dCBleGNlcHRpb25zLCBxdWV1ZXMsIGV0Yy4KICAgIHRlbXBsYXRlPGNsYXNzIEV2ZW50PgogICAgSGFuZGxlZEVudW0gZG9fcHJvY2Vzc19ldmVudChFdmVudCBjb25zdCYgZXZ0KQogICAgewogICAgICAgIEhhbmRsZWRFbnVtIGhhbmRsZWQgPSBIQU5ETEVEX0ZBTFNFOwogICAgICAgIC8vIGRpc3BhdGNoIHRoZSBldmVudCB0byBldmVyeSByZWdpb24KICAgICAgICByZWdpb25fcHJvY2Vzc2luZ19oZWxwZXI8RGVyaXZlZD4gaGVscGVyKHRoaXMsaGFuZGxlZCk7CiAgICAgICAgaGVscGVyLnByb2Nlc3MoZXZ0KTsKCiAgICAgICAgLy8gaWYgdGhlIGV2ZW50IGhhcyBub3QgYmVlbiBoYW5kbGVkIGFuZCB3ZSBoYXZlIG9ydGhvZ29uYWwgem9uZXMsIHRoZW4KICAgICAgICAvLyBnZW5lcmF0ZSBhbiBlcnJvciBvbiBldmVyeSBhY3RpdmUgc3RhdGUgCiAgICAgICAgLy8gZm9yIHN0YXRlIG1hY2hpbmUgc3RhdGVzIGNvbnRhaW5lZCBpbiBvdGhlciBzdGF0ZSBtYWNoaW5lcywgZG8gbm90IGhhbmRsZQogICAgICAgIC8vIGJ1dCBsZXQgdGhlIGNvbnRhaW5pbmcgc20gaGFuZGxlIHRoZSBlcnJvcgogICAgICAgIC8vIGNvbXBsZXRpb24gZXZlbnRzIGRvIG5vdCBwcm9kdWNlIGFuIGVycm9yCiAgICAgICAgaWYgKCFoYW5kbGVkICYmICFpc19jb250YWluZWQoKSAmJiAhaXNfY29tcGxldGlvbl9ldmVudDxFdmVudD46OnR5cGU6OnZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPG5yX3JlZ2lvbnM6OnZhbHVlOysraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhpcy0+bm9fdHJhbnNpdGlvbihldnQsKnRoaXMsdGhpcy0+bV9zdGF0ZXNbaV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBoYW5kbGVkOwogICAgfQoKICAgIC8vIGRlZmF1bHQgcm93IGFyZ3VtZW50cyBmb3IgdGhlIGNvbXBpbGVycyB3aGljaCBhY2NlcHQgdGhpcwogICAgdGVtcGxhdGUgPGNsYXNzIEV2ZW50PgogICAgYm9vbCBub19ndWFyZChFdmVudCBjb25zdCYpe3JldHVybiB0cnVlO30KICAgIHRlbXBsYXRlIDxjbGFzcyBFdmVudD4KICAgIHZvaWQgbm9fYWN0aW9uKEV2ZW50IGNvbnN0Jil7fQoKI2lmbmRlZiBCT09TVF9OT19SVFRJCiAgICBIYW5kbGVkRW51bSBwcm9jZXNzX2FueV9ldmVudCggOjpib29zdDo6YW55IGNvbnN0JiBldnQpOwojZW5kaWYKCnByaXZhdGU6CiAgICAvLyBjb21wb3NpdGUgYWNjZXB0IGltcGxlbWVudGF0aW9uLiBGaXJzdCBjYWxscyBhY2NlcHQgb24gdGhlIGNvbXBvc2l0ZSwgdGhlbiBhY2NlcHQgb24gYWxsIGl0cyBhY3RpdmUgc3RhdGVzLgogICAgdm9pZCBjb21wb3NpdGVfYWNjZXB0KCkKICAgIHsKICAgICAgICB0aGlzLT5hY2NlcHQoKTsKICAgICAgICB0aGlzLT52aXNpdF9jdXJyZW50X3N0YXRlcygpOwogICAgfQoKI2RlZmluZSBNU01fQ09NUE9TSVRFX0FDQ0VQVF9TVUIoeiwgbiwgdW51c2VkKSBBUkcgIyMgbiB2aXMgIyMgbgojZGVmaW5lIE1TTV9DT01QT1NJVEVfQUNDRVBUX0VYRUNVVEUoeiwgbiwgdW51c2VkKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgIHRlbXBsYXRlIDxCT09TVF9QUF9FTlVNX1BBUkFNUyhuLCBjbGFzcyBBUkcpPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgIHZvaWQgY29tcG9zaXRlX2FjY2VwdChCT09TVF9QUF9FTlVNKG4sIE1TTV9DT01QT1NJVEVfQUNDRVBUX1NVQiwgfiApICkgICAgICAgICAgICAgICBcCiAgICAgICAgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgICAgIHRoaXMtPmFjY2VwdChCT09TVF9QUF9FTlVNX1BBUkFNUyhuLHZpcykpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgICAgIHRoaXMtPnZpc2l0X2N1cnJlbnRfc3RhdGVzKEJPT1NUX1BQX0VOVU1fUEFSQU1TKG4sdmlzKSk7ICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgfQogICAgICAgIEJPT1NUX1BQX1JFUEVBVF9GUk9NX1RPKDEsQk9PU1RfUFBfQUREKEJPT1NUX01TTV9WSVNJVE9SX0FSR19TSVpFLDEpLCBNU01fQ09NUE9TSVRFX0FDQ0VQVF9FWEVDVVRFLCB+KQojdW5kZWYgTVNNX0NPTVBPU0lURV9BQ0NFUFRfRVhFQ1VURQojdW5kZWYgTVNNX0NPTVBPU0lURV9BQ0NFUFRfU1VCCgogICAgLy8gaGVscGVyIHVzZWQgdG8gY2FsbCB0aGUgaW5pdCBzdGF0ZXMgYXQgdGhlIHN0YXJ0IG9mIHRoZSBzdGF0ZSBtYWNoaW5lCiAgICB0ZW1wbGF0ZSA8Y2xhc3MgRXZlbnQ+CiAgICBzdHJ1Y3QgY2FsbF9pbml0CiAgICB7CiAgICAgICAgY2FsbF9pbml0KEV2ZW50IGNvbnN0JiBhbl9ldmVudCxsaWJyYXJ5X3NtKiBzZWxmXyk6CiAgICAgICAgICAgICAgICBldnQoYW5fZXZlbnQpLHNlbGYoc2VsZl8pe30KICAgICAgICB0ZW1wbGF0ZSA8Y2xhc3MgU3RhdGU+CiAgICAgICAgdm9pZCBvcGVyYXRvcigpKGJvb3N0Ojptc206OndyYXA8U3RhdGU+IGNvbnN0JikKICAgICAgICB7CiAgICAgICAgICAgIGV4ZWN1dGVfZW50cnkoOjpib29zdDo6ZnVzaW9uOjphdF9rZXk8U3RhdGU+KHNlbGYtPm1fc3Vic3RhdGVfbGlzdCksZXZ0LCpzZWxmKTsKICAgICAgICB9CiAgICBwcml2YXRlOgogICAgICAgIEV2ZW50IGNvbnN0JiBldnQ7CiAgICAgICAgbGlicmFyeV9zbSogc2VsZjsKICAgIH07CiAgICAvLyBoZWxwZXIgZm9yIGZsYWcgaGFuZGxpbmcuIFVzZXMgT1IgYnkgZGVmYXVsdCBvbiBvcnRob2dvbmFsIHpvbmVzLgogICAgdGVtcGxhdGUgPGNsYXNzIEZsYWcsYm9vbCBvcnRob2dvbmFsU3RhdGVzPgogICAgc3RydWN0IEZsYWdIZWxwZXIgCiAgICB7CiAgICAgICAgc3RhdGljIGJvb2wgaGVscGVyKGxpYnJhcnlfc20mIHNtLGZsYWdfaGFuZGxlciogKQogICAgICAgIHsKICAgICAgICAgICAgLy8gYnkgZGVmYXVsdCB3ZSB1c2UgT1IgdG8gYWNjdW11bGF0ZSB0aGUgZmxhZ3MKICAgICAgICAgICAgcmV0dXJuIHNtLmlzX2ZsYWdfYWN0aXZlPEZsYWcsRmxhZ19PUj4oKTsKICAgICAgICB9CiAgICB9OwogICAgdGVtcGxhdGUgPGNsYXNzIEZsYWc+CiAgICBzdHJ1Y3QgRmxhZ0hlbHBlcjxGbGFnLGZhbHNlPgogICAgewogICAgICAgIHN0YXRpYyBib29sIGhlbHBlcihsaWJyYXJ5X3NtJiBzbSxmbGFnX2hhbmRsZXIqIGZsYWdzX2VudHJpZXMpCiAgICAgICAgewogICAgICAgICAgICAvLyBqdXN0IG9uZSBhY3RpdmUgc3RhdGUsIHNvIHdlIGNhbiBjYWxsIG9wZXJhdG9yW10gd2l0aCAwCiAgICAgICAgICAgIHJldHVybiBmbGFnc19lbnRyaWVzW3NtLmN1cnJlbnRfc3RhdGUoKVswXV0oc20pOwogICAgICAgIH0KICAgIH07CiAgICAvLyBoYW5kbGluZyBvZiBmbGFnCiAgICAvLyBkZWZpbmVzIGEgdHJ1ZSBhbmQgZmFsc2UgZnVuY3Rpb25zIHBsdXMgYSBmb3J3YXJkaW5nIG9uZSBmb3IgY29tcG9zaXRlIHN0YXRlcwogICAgdGVtcGxhdGUgPGNsYXNzIFN0YXRlVHlwZSxjbGFzcyBGbGFnPgogICAgc3RydWN0IEZsYWdIYW5kbGVyCiAgICB7CiAgICAgICAgc3RhdGljIGJvb2wgZmxhZ190cnVlKGxpYnJhcnlfc20mICkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBzdGF0aWMgYm9vbCBmbGFnX2ZhbHNlKGxpYnJhcnlfc20mICkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgc3RhdGljIGJvb2wgZm9yd2FyZChsaWJyYXJ5X3NtJiBmc20pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gOjpib29zdDo6ZnVzaW9uOjphdF9rZXk8U3RhdGVUeXBlPihmc20ubV9zdWJzdGF0ZV9saXN0KS50ZW1wbGF0ZSBpc19mbGFnX2FjdGl2ZTxGbGFnPigpOwogICAgICAgIH0KICAgIH07CiAgICB0ZW1wbGF0ZSA8Y2xhc3MgRmxhZz4KICAgIHN0cnVjdCBpbml0X2ZsYWdzCiAgICB7CiAgICBwcml2YXRlOgogICAgICAgIC8vIGhlbHBlciBmdW5jdGlvbiwgaGVscHMgaGlkaW5nIHRoZSBmb3J3YXJkIGZ1bmN0aW9uIGZvciBub24tc3RhdGUgbWFjaGluZXMgc3RhdGVzLgogICAgICAgIHRlbXBsYXRlIDxjbGFzcyBUPgogICAgICAgIHZvaWQgaGVscGVyIChmbGFnX2hhbmRsZXIqIGFuX2VudHJ5LGludCBvZmZzZXQsIDo6Ym9vc3Q6Om1wbDo6dHJ1ZV8gY29uc3QgJiAgKQogICAgICAgIHsKICAgICAgICAgICAgLy8gY29tcG9zaXRlID0+IGZvcndhcmQKICAgICAgICAgICAgYW5fZW50cnlbb2Zmc2V0XSA9ICZGbGFnSGFuZGxlcjxULEZsYWc+Ojpmb3J3YXJkOwogICAgICAgIH0KICAgICAgICB0ZW1wbGF0ZSA8Y2xhc3MgVD4KICAgICAgICB2b2lkIGhlbHBlciAoZmxhZ19oYW5kbGVyKiBhbl9lbnRyeSxpbnQgb2Zmc2V0LCA6OmJvb3N0OjptcGw6OmZhbHNlXyBjb25zdCAmICApCiAgICAgICAgewogICAgICAgICAgICAvLyBkZWZhdWx0IG5vIGZsYWcKICAgICAgICAgICAgYW5fZW50cnlbb2Zmc2V0XSA9ICZGbGFnSGFuZGxlcjxULEZsYWc+OjpmbGFnX2ZhbHNlOwogICAgICAgIH0KICAgICAgICAvLyBhdHRyaWJ1dGVzCiAgICAgICAgZmxhZ19oYW5kbGVyKiBlbnRyaWVzOwoKICAgIHB1YmxpYzoKICAgICAgICBpbml0X2ZsYWdzKGZsYWdfaGFuZGxlciogZW50cmllc18pCiAgICAgICAgICAgIDogZW50cmllcyhlbnRyaWVzXykKICAgICAgICB7fQoKICAgICAgICAvLyBGbGFncyBpbml0aWFsaXplciBmdW5jdGlvbiBvYmplY3QsIHVzZWQgd2l0aCBtcGw6OmZvcl9lYWNoCiAgICAgICAgdGVtcGxhdGUgPGNsYXNzIFN0YXRlVHlwZT4KICAgICAgICB2b2lkIG9wZXJhdG9yKCkoIDo6Ym9vc3Q6Om1zbTo6d3JhcDxTdGF0ZVR5cGU+IGNvbnN0JiApCiAgICAgICAgewogICAgICAgICAgICB0eXBlZGVmIHR5cGVuYW1lIFN0YXRlVHlwZTo6ZmxhZ19saXN0IGZsYWdzOwogICAgICAgICAgICB0eXBlZGVmIHR5cGVuYW1lIDo6Ym9vc3Q6Om1wbDo6Y29udGFpbnM8ZmxhZ3MsRmxhZyA+Ojp0eXBlIGZvdW5kOwogICAgICAgICAgICB0eXBlZGVmIHR5cGVuYW1lIGlzX2NvbXBvc2l0ZV9zdGF0ZTxTdGF0ZVR5cGU+Ojp0eXBlIGNvbXBvc2l0ZTsKCiAgICAgICAgICAgIEJPT1NUX1NUQVRJQ19DT05TVEFOVChpbnQsIHN0YXRlX2lkID0gKGdldF9zdGF0ZV9pZDxzdHQsU3RhdGVUeXBlPjo6dHlwZTo6dmFsdWUpKTsKICAgICAgICAgICAgaWYgKGZvdW5kOjp0eXBlOjp2YWx1ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gdGhlIHR5cGUgZGVmaW5lZCB0aGUgZmxhZyA9PiB0cnVlCiAgICAgICAgICAgICAgICBlbnRyaWVzW3N0YXRlX2lkXSA9ICZGbGFnSGFuZGxlcjxTdGF0ZVR5cGUsRmxhZz46OmZsYWdfdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIGZhbHNlIG9yIGZvcndhcmQKICAgICAgICAgICAgICAgIHR5cGVkZWYgdHlwZW5hbWUgOjpib29zdDo6bXBsOjphbmRfPAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZW5hbWUgaXNfY29tcG9zaXRlX3N0YXRlPFN0YXRlVHlwZT46OnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlbmFtZSA6OmJvb3N0OjptcGw6Om5vdF88CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVuYW1lIGhhc19ub25fZm9yd2FyZGluZ19mbGFnPEZsYWc+Ojp0eXBlPjo6dHlwZSA+Ojp0eXBlIGNvbXBvc2l0ZV9ub19mb3J3YXJkOwoKICAgICAgICAgICAgICAgIGhlbHBlcjxTdGF0ZVR5cGU+KGVudHJpZXMsc3RhdGVfaWQsOjpib29zdDo6bXBsOjpib29sXzxjb21wb3NpdGVfbm9fZm9yd2FyZDo6dHlwZTo6dmFsdWU+KCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfTsKICAgIC8vIG1haW50YWlucyBmb3IgZXZlcnkgZmxhZyBhIHN0YXRpYyBhcnJheSBjb250YWluaW5nIHRoZSBmbGFnIHZhbHVlIGZvciBldmVyeSBzdGF0ZQogICAgdGVtcGxhdGUgPGNsYXNzIEZsYWc+CiAgICBmbGFnX2hhbmRsZXIqIGdldF9lbnRyaWVzX2Zvcl9mbGFnKCkKICAgIHsKICAgICAgICBCT09TVF9TVEFUSUNfQ09OU1RBTlQoaW50LCBtYXhfc3RhdGUgPSAobXBsOjpzaXplPHN0YXRlX2xpc3Q+Ojp2YWx1ZSkpOwoKICAgICAgICBzdGF0aWMgZmxhZ19oYW5kbGVyIGZsYWdzX2VudHJpZXNbbWF4X3N0YXRlXTsKICAgICAgICAvLyBidWlsZCBhIHN0YXRlIGxpc3QKICAgICAgICA6OmJvb3N0OjptcGw6OmZvcl9lYWNoPHN0YXRlX2xpc3QsIGJvb3N0Ojptc206OndyYXA8IDo6Ym9vc3Q6Om1wbDo6cGxhY2Vob2xkZXJzOjpfMT4gPgogICAgICAgICAgICAgICAgICAgICAgICAoaW5pdF9mbGFnczxGbGFnPihmbGFnc19lbnRyaWVzKSk7CiAgICAgICAgcmV0dXJuIGZsYWdzX2VudHJpZXM7CiAgICB9CgogICAgLy8gaGVscGVyIHVzZWQgdG8gY3JlYXRlIGEgc3RhdGUgdXNpbmcgdGhlIGNvcnJlY3QgY29uc3RydWN0b3IKICAgIHRlbXBsYXRlIDxjbGFzcyBTdGF0ZSwgY2xhc3MgRW5hYmxlPXZvaWQ+CiAgICBzdHJ1Y3QgY3JlYXRlX3N0YXRlX2hlbHBlcgogICAgewogICAgICAgIHN0YXRpYyB2b2lkIHNldF9zbShsaWJyYXJ5X3NtKiApCiAgICAgICAgewogICAgICAgICAgICAvLyBzdGF0ZSBkb2Vzbid0IG5lZWQgaXRzIHNtCiAgICAgICAgfQogICAgfTsKICAgIC8vIGNyZWF0ZSBhIHN0YXRlIHJlcXVpcmluZyBhIHBvaW50ZXIgdG8gdGhlIHN0YXRlIG1hY2hpbmUKICAgIHRlbXBsYXRlIDxjbGFzcyBTdGF0ZT4KICAgIHN0cnVjdCBjcmVhdGVfc3RhdGVfaGVscGVyPFN0YXRlLHR5cGVuYW1lIGJvb3N0OjplbmFibGVfaWY8dHlwZW5hbWUgU3RhdGU6Om5lZWRzX3NtID46OnR5cGU+CiAgICB7CiAgICAgICAgc3RhdGljIHZvaWQgc2V0X3NtKGxpYnJhcnlfc20qIHNtKQogICAgICAgIHsKICAgICAgICAgICAgLy8gY3JlYXRlIGFuZCBzZXQgdGhlIGZzbQogICAgICAgICAgICA6OmJvb3N0OjpmdXNpb246OmF0X2tleTxTdGF0ZT4oc20tPm1fc3Vic3RhdGVfbGlzdCkuc2V0X3NtX3B0cihzbSk7CiAgICAgICAgfQogICAgfTsKICAgICAgICAvLyBtYWluIHVuc3BlY2lhbGl6ZWQgaGVscGVyIGNsYXNzCiAgICAgICAgdGVtcGxhdGUgPGNsYXNzIFN0YXRlVHlwZSxpbnQgQVJHUz4KICAgICAgICBzdHJ1Y3QgdmlzaXRvcl9hcmdzOwoKI2RlZmluZSBNU01fVklTSVRPUl9BUkdTX1NVQih6LCBuLCB1bnVzZWQpIEJPT1NUX1BQX0NBVChfLEJPT1NUX1BQX0FERChuLDEpKQojZGVmaW5lIE1TTV9WSVNJVE9SX0FSR1NfVFlQRURFRl9TVUIoeiwgbiwgdW51c2VkKSB0eXBlbmFtZSBTdGF0ZVR5cGU6OmFjY2VwdF9zaWc6OmFyZ3VtZW50ICMjIG4KCiNkZWZpbmUgTVNNX1ZJU0lUT1JfQVJHU19FWEVDVVRFKHosIG4sIHVudXNlZCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgdGVtcGxhdGUgPGNsYXNzIFN0YXRlVHlwZT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgIHN0cnVjdCB2aXNpdG9yX2FyZ3M8U3RhdGVUeXBlLG4+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgIHRlbXBsYXRlIDxjbGFzcyBTdGF0ZT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICBzdGF0aWMgdHlwZW5hbWUgZW5hYmxlX2lmX2M8IWlzX2NvbXBvc2l0ZV9zdGF0ZTxTdGF0ZT46OnZhbHVlLHZvaWQgPjo6dHlwZSAgICAgICAgICBcCiAgICAgICAgaGVscGVyIChsaWJyYXJ5X3NtKiBzbSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgIGludCBpZCxTdGF0ZVR5cGUmIGFzdGF0ZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgICAgIHNtLT5tX3Zpc2l0b3JzLmluc2VydChpZCwgYm9vc3Q6OmJpbmQoJlN0YXRlVHlwZTo6YWNjZXB0LCAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgICAgICAgICAgOjpib29zdDo6cmVmKGFzdGF0ZSkgQk9PU1RfUFBfQ09NTUFfSUYobikgQk9PU1RfUFBfRU5VTShuLCBNU01fVklTSVRPUl9BUkdTX1NVQiwgfikgKSk7ICAgXAogICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICB0ZW1wbGF0ZSA8Y2xhc3MgU3RhdGU+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgc3RhdGljIHR5cGVuYW1lIGVuYWJsZV9pZl9jPGlzX2NvbXBvc2l0ZV9zdGF0ZTxTdGF0ZT46OnZhbHVlLHZvaWQgPjo6dHlwZSAgICAgICAgICAgXAogICAgICAgIGhlbHBlciAobGlicmFyeV9zbSogc20sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICBpbnQgaWQsU3RhdGVUeXBlJiBhc3RhdGUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgICAgICB2b2lkIChTdGF0ZVR5cGU6OipjYWNjZXB0KShCT09TVF9QUF9FTlVNKG4sIE1TTV9WSVNJVE9SX0FSR1NfVFlQRURFRl9TVUIsIH4gKSApICAgICAgICAgICBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9ICZTdGF0ZVR5cGU6OmNvbXBvc2l0ZV9hY2NlcHQ7ICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgICAgICBzbS0+bV92aXNpdG9ycy5pbnNlcnQoaWQsIGJvb3N0OjpiaW5kKGNhY2NlcHQsICAgICAgICAgICAgIFwKICAgICAgICAgICAgOjpib29zdDo6cmVmKGFzdGF0ZSkgQk9PU1RfUFBfQ09NTUFfSUYobikgQk9PU1RfUFBfRU5VTShuLCBNU01fVklTSVRPUl9BUkdTX1NVQiwgfikgKSk7ICAgICAgICAgICAgICAgICBcCiAgICAgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAp9OwpCT09TVF9QUF9SRVBFQVQoQk9PU1RfUFBfQUREKEJPT1NUX01TTV9WSVNJVE9SX0FSR19TSVpFLDEpLCBNU01fVklTSVRPUl9BUkdTX0VYRUNVVEUsIH4pCiN1bmRlZiBNU01fVklTSVRPUl9BUkdTX0VYRUNVVEUKI3VuZGVmIE1TTV9WSVNJVE9SX0FSR1NfU1VCCgovLyB0aGUgSUJNIGNvbXBpbGVyIHNlZW1zIHRvIGhhdmUgcHJvYmxlbXMgd2l0aCBuZXN0ZWQgY2xhc3NlcwovLyB0aGUgc2FtZSBzZWVtcyB0byBhcHBseSB0byB0aGUgQXBwbGUgdmVyc2lvbiBvZiBnY2MgNC4wLjEgKGp1c3QgaW4gY2FzZSB3ZSBkbyBmb3IgPCA0LjEpCi8vIGFuZCBhbHNvIHRvIE1TIFZDIDwgOAojaWYgZGVmaW5lZCAoX19JQk1DUFBfXykgfHwgKGRlZmluZWQgKF9fQVBQTEVfQ0NfXykgJiYgKF9fR05VQ19fID09IDQgJiYgX19HTlVDX01JTk9SX18gPCAxKSkgfHwgKGRlZmluZWQoX01TQ19WRVIpICYmIChfTVNDX1ZFUiA8IDE0MDApKQogICAgIHB1YmxpYzoKI2VuZGlmCiAgICB0ZW1wbGF0ZTxjbGFzcyBDb250YWluaW5nU00+CiAgICB2b2lkIHNldF9jb250YWluaW5nX3NtKENvbnRhaW5pbmdTTSogc20pCiAgICB7CiAgICAgICAgbV9pc19pbmNsdWRlZD10cnVlOwogICAgICAgIDo6Ym9vc3Q6OmZ1c2lvbjo6Zm9yX2VhY2gobV9zdWJzdGF0ZV9saXN0LGFkZF9zdGF0ZTxDb250YWluaW5nU00+KHRoaXMsc20pKTsKICAgIH0KI2lmIGRlZmluZWQgKF9fSUJNQ1BQX18pIHx8IChkZWZpbmVkIChfX0FQUExFX0NDX18pICYmIChfX0dOVUNfXyA9PSA0ICYmIF9fR05VQ19NSU5PUl9fIDwgMSkpIHx8IChkZWZpbmVkKF9NU0NfVkVSKSAmJiAoX01TQ19WRVIgPCAxNDAwKSkKICAgICBwcml2YXRlOgojZW5kaWYKICAgIC8vIEEgZnVuY3Rpb24gb2JqZWN0IGZvciB1c2Ugd2l0aCBtcGw6OmZvcl9lYWNoIHRoYXQgc3R1ZmZzCiAgICAvLyBzdGF0ZXMgaW50byB0aGUgc3RhdGUgbGlzdC4KICAgIHRlbXBsYXRlPGNsYXNzIENvbnRhaW5pbmdTTT4KICAgIHN0cnVjdCBhZGRfc3RhdGUKICAgIHsKICAgICAgICBhZGRfc3RhdGUobGlicmFyeV9zbSogc2VsZl8sQ29udGFpbmluZ1NNKiBzbSkKICAgICAgICAgICAgOiBzZWxmKHNlbGZfKSxjb250YWluaW5nX3NtKHNtKXt9CgogICAgICAgIC8vIFN0YXRlIGlzIGEgc3ViIGZzbSB3aXRoIGV4aXQgcHNldWRvIHN0YXRlcyBhbmQgZ2V0cyBhIHBvaW50ZXIgdG8gdGhpcyBmc20sIHNvIGl0IGNhbiBidWlsZCBhIGNhbGxiYWNrCiAgICAgICAgdGVtcGxhdGUgPGNsYXNzIFN0YXRlVHlwZT4KICAgICAgICB0eXBlbmFtZSA6OmJvb3N0OjplbmFibGVfaWY8CiAgICAgICAgICAgIHR5cGVuYW1lIGlzX2NvbXBvc2l0ZV9zdGF0ZTxTdGF0ZVR5cGU+Ojp0eXBlLHZvaWQgPjo6dHlwZQogICAgICAgIG5ld19zdGF0ZV9oZWxwZXIoYm9vc3Q6Om1zbTo6YmFjazo6ZHVtbXk8MD4gPSAwKSBjb25zdAogICAgICAgIHsKICAgICAgICAgICAgOjpib29zdDo6ZnVzaW9uOjphdF9rZXk8U3RhdGVUeXBlPihzZWxmLT5tX3N1YnN0YXRlX2xpc3QpLnNldF9jb250YWluaW5nX3NtKGNvbnRhaW5pbmdfc20pOwogICAgICAgIH0KICAgICAgICAvLyBTdGF0ZSBpcyBhIHN1YiBmc20gd2l0aG91dCBleGl0IHBzZXVkbyBzdGF0ZXMgYW5kIGRvZXMgbm90IGdldCBhIGNhbGxiYWNrIHRvIHRoaXMgZnNtCiAgICAgICAgLy8gb3Igc3RhdGUgaXMgYSBub3JtYWwgc3RhdGUgYW5kIG5lZWRzIG5vdGhpbmcgZXhjZXB0IGNyZWF0aW9uCiAgICAgICAgdGVtcGxhdGUgPGNsYXNzIFN0YXRlVHlwZT4KICAgICAgICB0eXBlbmFtZSA6OmJvb3N0OjplbmFibGVfaWY8CiAgICAgICAgICAgIHR5cGVuYW1lIGJvb3N0OjptcGw6OmFuZF88dHlwZW5hbWUgYm9vc3Q6Om1wbDo6bm90XwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHR5cGVuYW1lIGlzX2NvbXBvc2l0ZV9zdGF0ZTxTdGF0ZVR5cGU+Ojp0eXBlPjo6dHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlbmFtZSBib29zdDo6bXBsOjpub3RfCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHlwZW5hbWUgaXNfcHNldWRvX2V4aXQ8U3RhdGVUeXBlPjo6dHlwZT46OnR5cGUKICAgICAgICAgICAgICAgICAgID46OnR5cGUsdm9pZD46OnR5cGUKICAgICAgICBuZXdfc3RhdGVfaGVscGVyKCA6OmJvb3N0Ojptc206OmJhY2s6OmR1bW15PDE+ID0gMCkgY29uc3QKICAgICAgICB7CiAgICAgICAgICAgIC8vbm90aGluZyB0byBkbwogICAgICAgIH0KICAgICAgICAvLyBzdGF0ZSBpcyBleGl0IHBzZXVkbyBzdGF0ZSBhbmQgZ2V0cyBjYWxsYmFjayB0byB0YXJnZXQgZnNtCiAgICAgICAgdGVtcGxhdGUgPGNsYXNzIFN0YXRlVHlwZT4KICAgICAgICB0eXBlbmFtZSA6OmJvb3N0OjplbmFibGVfaWY8dHlwZW5hbWUgaXNfcHNldWRvX2V4aXQ8U3RhdGVUeXBlPjo6dHlwZSx2b2lkID46OnR5cGUKICAgICAgICBuZXdfc3RhdGVfaGVscGVyKCA6OmJvb3N0Ojptc206OmJhY2s6OmR1bW15PDI+ID0gMCkgY29uc3QKICAgICAgICB7CiAgICAgICAgICAgIGV4ZWN1dGVfcmV0dXJuIChDb250YWluaW5nU006OipwZikgKHR5cGVuYW1lIFN0YXRlVHlwZTo6ZXZlbnQgY29uc3QmIGV2dCk9IAogICAgICAgICAgICAgICAgJkNvbnRhaW5pbmdTTTo6cHJvY2Vzc19ldmVudDsKICAgICAgICAgICAgOjpib29zdDo6ZnVuY3Rpb248ZXhlY3V0ZV9yZXR1cm4gKHR5cGVuYW1lIFN0YXRlVHlwZTo6ZXZlbnQgY29uc3QmKT4gZmN0ID0gCiAgICAgICAgICAgICAgICA6OmJvb3N0OjpiaW5kKHBmLGNvbnRhaW5pbmdfc20sXzEpOwogICAgICAgICAgICA6OmJvb3N0OjpmdXNpb246OmF0X2tleTxTdGF0ZVR5cGU+KHNlbGYtPm1fc3Vic3RhdGVfbGlzdCkuc2V0X2ZvcndhcmRfZmN0KGZjdCk7CiAgICAgICAgfQogICAgICAgIC8vIGZvciBldmVyeSBkZWZpbmVkIHN0YXRlIGluIHRoZSBzbQogICAgICAgIHRlbXBsYXRlIDxjbGFzcyBTdGF0ZT4KICAgICAgICB2b2lkIG9wZXJhdG9yKCkoIFN0YXRlIGNvbnN0JikgY29uc3QKICAgICAgICB7CiAgICAgICAgICAgIC8vY3JlYXRlIGEgbmV3IHN0YXRlIHdpdGggdGhlIGRlZmluZWQgaWQgYW5kIHR5cGUKICAgICAgICAgICAgQk9PU1RfU1RBVElDX0NPTlNUQU5UKGludCwgc3RhdGVfaWQgPSAoZ2V0X3N0YXRlX2lkPHN0dCxTdGF0ZT46OnZhbHVlKSk7CgogICAgICAgICAgICB0aGlzLT5uZXdfc3RhdGVfaGVscGVyPFN0YXRlPigpLAogICAgICAgICAgICBjcmVhdGVfc3RhdGVfaGVscGVyPFN0YXRlPjo6c2V0X3NtKHNlbGYpOwogICAgICAgICAgICAvLyBjcmVhdGUgYSB2aXNpdG9yIGNhbGxiYWNrCiAgICAgICAgICAgIHZpc2l0b3JfaGVscGVyKHN0YXRlX2lkLDo6Ym9vc3Q6OmZ1c2lvbjo6YXRfa2V5PFN0YXRlPihzZWxmLT5tX3N1YnN0YXRlX2xpc3QpLAogICAgICAgICAgICAgICAgICAgICAgICAgICA6OmJvb3N0OjptcGw6OmJvb2xfPGhhc19hY2NlcHRfc2lnPFN0YXRlPjo6dHlwZTo6dmFsdWU+KCkpOwogICAgICAgIH0KICAgIHByaXZhdGU6CiAgICAgICAgLy8gc3VwcG9ydCBwb3NzaWJsZSB1c2Ugb2YgYSB2aXNpdG9yIGlmIGFjY2VwdF9zaWcgaXMgZGVmaW5lZAogICAgICAgIHRlbXBsYXRlIDxjbGFzcyBTdGF0ZVR5cGU+CiAgICAgICAgdm9pZCB2aXNpdG9yX2hlbHBlcihpbnQgaWQsU3RhdGVUeXBlJiBhc3RhdGUsIDo6Ym9vc3Q6Om1wbDo6dHJ1ZV8gY29uc3QgJiApIGNvbnN0CiAgICAgICAgewogICAgICAgICAgICB2aXNpdG9yX2FyZ3M8U3RhdGVUeXBlLFN0YXRlVHlwZTo6YWNjZXB0X3NpZzo6YXJnc19udW1iZXI+OjoKICAgICAgICAgICAgICAgIHRlbXBsYXRlIGhlbHBlcjxTdGF0ZVR5cGU+KHNlbGYsaWQsYXN0YXRlKTsKICAgICAgICB9CiAgICAgICAgdGVtcGxhdGUgPGNsYXNzIFN0YXRlVHlwZT4KICAgICAgICB2b2lkIHZpc2l0b3JfaGVscGVyKGludCAsU3RhdGVUeXBlJiAsIDo6Ym9vc3Q6Om1wbDo6ZmFsc2VfIGNvbnN0ICYpIGNvbnN0CiAgICAgICAgewogICAgICAgICAgICAvLyBub3RoaW5nIHRvIGRvCiAgICAgICAgfQoKICAgICAgICBsaWJyYXJ5X3NtKiAgICAgIHNlbGY7CiAgICAgICAgQ29udGFpbmluZ1NNKiAgICBjb250YWluaW5nX3NtOwogICAgfTsKCiAgICAgLy8gaGVscGVyIHVzZWQgdG8gY29weSBldmVyeSBzdGF0ZSBpZiBuZWVkZWQKICAgICBzdHJ1Y3QgY29weV9oZWxwZXIKICAgICB7CiAgICAgICAgIGNvcHlfaGVscGVyKGxpYnJhcnlfc20qIHNtKToKICAgICAgICAgICBtX3NtKHNtKXt9CiAgICAgICAgIHRlbXBsYXRlIDxjbGFzcyBTdGF0ZVR5cGU+CiAgICAgICAgIHZvaWQgb3BlcmF0b3IoKSggOjpib29zdDo6bXNtOjp3cmFwPFN0YXRlVHlwZT4gY29uc3QmICkKICAgICAgICAgewogICAgICAgICAgICBCT09TVF9TVEFUSUNfQ09OU1RBTlQoaW50LCBzdGF0ZV9pZCA9IChnZXRfc3RhdGVfaWQ8c3R0LFN0YXRlVHlwZT46OnR5cGU6OnZhbHVlKSk7CiAgICAgICAgICAgIC8vIHBvc3NpYmx5IGFsc28gc2V0IHRoZSB2aXNpdG9yCiAgICAgICAgICAgIHZpc2l0b3JfaGVscGVyPFN0YXRlVHlwZT4oc3RhdGVfaWQpOwoKICAgICAgICAgICAgLy8gYW5kIGZvciBzdGF0ZXMgdGhhdCBrZWVwIGEgcG9pbnRlciB0byB0aGUgZnNtLCByZXNldCB0aGUgcG9pbnRlcgogICAgICAgICAgICBjcmVhdGVfc3RhdGVfaGVscGVyPFN0YXRlVHlwZT46OnNldF9zbShtX3NtKTsKICAgICAgICAgfQogICAgICAgICB0ZW1wbGF0ZSA8Y2xhc3MgU3RhdGVUeXBlPgogICAgICAgICB0eXBlbmFtZSA6OmJvb3N0OjplbmFibGVfaWY8dHlwZW5hbWUgaGFzX2FjY2VwdF9zaWc8U3RhdGVUeXBlPjo6dHlwZSx2b2lkID46OnR5cGUKICAgICAgICAgICAgIHZpc2l0b3JfaGVscGVyKGludCBpZCkgY29uc3QKICAgICAgICAgewogICAgICAgICAgICAgdmlzaXRvcl9hcmdzPFN0YXRlVHlwZSxTdGF0ZVR5cGU6OmFjY2VwdF9zaWc6OmFyZ3NfbnVtYmVyPjo6dGVtcGxhdGUgaGVscGVyPFN0YXRlVHlwZT4KICAgICAgICAgICAgICAgICAobV9zbSxpZCw6OmJvb3N0OjpmdXNpb246OmF0X2tleTxTdGF0ZVR5cGU+KG1fc20tPm1fc3Vic3RhdGVfbGlzdCkpOwogICAgICAgICB9CiAgICAgICAgIHRlbXBsYXRlIDxjbGFzcyBTdGF0ZVR5cGU+CiAgICAgICAgIHR5cGVuYW1lIDo6Ym9vc3Q6OmRpc2FibGVfaWY8dHlwZW5hbWUgaGFzX2FjY2VwdF9zaWc8U3RhdGVUeXBlPjo6dHlwZSx2b2lkID46OnR5cGUKICAgICAgICAgICAgIHZpc2l0b3JfaGVscGVyKGludCBpZCkgY29uc3QKICAgICAgICAgewogICAgICAgICAgICAgLy8gbm90aGluZyB0byBkbwogICAgICAgICB9CgogICAgICAgICBsaWJyYXJ5X3NtKiAgICAgbV9zbTsKICAgICB9OwogICAgIC8vIGhlbHBlciB0byBjb3B5IHRoZSBhY3RpdmUgc3RhdGVzIGF0dHJpYnV0ZQogICAgIHRlbXBsYXRlIDxjbGFzcyByZWdpb25faWQsaW50IER1bW15PTA+CiAgICAgc3RydWN0IHJlZ2lvbl9jb3B5X2hlbHBlcgogICAgIHsKICAgICAgICAgc3RhdGljIHZvaWQgZG9fY29weShsaWJyYXJ5X3NtKiBzZWxmXyxsaWJyYXJ5X3NtIGNvbnN0JiByaHMpCiAgICAgICAgIHsKICAgICAgICAgICAgIHNlbGZfLT5tX3N0YXRlc1tyZWdpb25faWQ6OnZhbHVlXSA9IHJocy5tX3N0YXRlc1tyZWdpb25faWQ6OnZhbHVlXTsKICAgICAgICAgICAgIHJlZ2lvbl9jb3B5X2hlbHBlcjwgOjpib29zdDo6bXBsOjppbnRfPHJlZ2lvbl9pZDo6dmFsdWUrMT4gPjo6ZG9fY29weShzZWxmXyxyaHMpOwogICAgICAgICB9CiAgICAgfTsKICAgICB0ZW1wbGF0ZSA8aW50IER1bW15PgogICAgIHN0cnVjdCByZWdpb25fY29weV9oZWxwZXI8IDo6Ym9vc3Q6Om1wbDo6aW50Xzxucl9yZWdpb25zOjp2YWx1ZT4sRHVtbXk+CiAgICAgewogICAgICAgICAvLyBlbmQgb2YgcHJvY2Vzc2luZwogICAgICAgICBzdGF0aWMgdm9pZCBkb19jb3B5KGxpYnJhcnlfc20qLGxpYnJhcnlfc20gY29uc3QmICl7fQogICAgIH07CiAgICAgLy8gY29weSBmdW5jdGlvbnMgZm9yIGRlZXAgY29weSAobm8gbmVlZCBvZiBhIDJuZCB2ZXJzaW9uIGZvciBOb0NvcHkgYXMgbm9uY29weWFibGUgaGFuZGxlcyBpdCkKICAgICB2b2lkIGRvX2NvcHkgKGxpYnJhcnlfc20gY29uc3QmIHJocywKICAgICAgICAgICAgICA6OmJvb3N0Ojptc206OmJhY2s6OmR1bW15PDA+ID0gMCkKICAgICB7CiAgICAgICAgIC8vIGRlZXAgY29weSBzaW1wbHkgYXNzaWducyB0aGUgZGF0YQogICAgICAgICByZWdpb25fY29weV9oZWxwZXI8IDo6Ym9vc3Q6Om1wbDo6aW50XzwwPiA+Ojpkb19jb3B5KHRoaXMscmhzKTsKICAgICAgICAgbV9ldmVudHNfcXVldWUgPSByaHMubV9ldmVudHNfcXVldWU7CiAgICAgICAgIG1fZGVmZXJyZWRfZXZlbnRzX3F1ZXVlID0gcmhzLm1fZGVmZXJyZWRfZXZlbnRzX3F1ZXVlOwogICAgICAgICBtX2hpc3RvcnkgPSByaHMubV9oaXN0b3J5OwogICAgICAgICBtX2V2ZW50X3Byb2Nlc3NpbmcgPSByaHMubV9ldmVudF9wcm9jZXNzaW5nOwogICAgICAgICBtX2lzX2luY2x1ZGVkID0gcmhzLm1faXNfaW5jbHVkZWQ7CiAgICAgICAgIG1fc3Vic3RhdGVfbGlzdCA9IHJocy5tX3N1YnN0YXRlX2xpc3Q7CiAgICAgICAgIC8vIGV4Y2VwdCBmb3IgdGhlIHN0YXRlcyB0aGVtc2VsdmVzLCB3aGljaCBnZXQgZHVwbGljYXRlZAoKICAgICAgICAgOjpib29zdDo6bXBsOjpmb3JfZWFjaDxzdGF0ZV9saXN0LCA6OmJvb3N0Ojptc206OndyYXA8IDo6Ym9vc3Q6Om1wbDo6cGxhY2Vob2xkZXJzOjpfMT4gPgogICAgICAgICAgICAgICAgICAgICAgICAoY29weV9oZWxwZXIodGhpcykpOwogICAgIH0KCiAgICAgLy8gaGVscGVyIHVzZWQgdG8gY2FsbCB0aGUgY29ycmVjdCBlbnRyeS9leGl0IG1ldGhvZAogICAgIC8vIHVuZm9ydHVuYXRlbHkgaW4gTyhudW1iZXIgb2Ygc3RhdGVzIGluIHRoZSBzdWItc20pIGJ1dCBzaG91bGQgYmUgYmV0dGVyIHRoYW4gYSB2aXJ0dWFsIGNhbGwKICAgICB0ZW1wbGF0ZTxjbGFzcyBFdmVudCxib29sIGlzX2VudHJ5PiAKICAgICBzdHJ1Y3QgZW50cnlfZXhpdF9oZWxwZXIKICAgICB7CiAgICAgICAgIGVudHJ5X2V4aXRfaGVscGVyKGludCBpZCxFdmVudCBjb25zdCYgZSxsaWJyYXJ5X3NtKiBzZWxmXyk6CiAgICAgICAgICAgIHN0YXRlX2lkKGlkKSxldnQoZSksc2VsZihzZWxmXyl7fQogICAgICAgICAvLyBoZWxwZXIgZm9yIGVudHJ5IGFjdGlvbnMKICAgICAgICAgdGVtcGxhdGUgPGNsYXNzIElzRW50cnksY2xhc3MgU3RhdGU+CiAgICAgICAgIHR5cGVuYW1lIDo6Ym9vc3Q6OmVuYWJsZV9pZjx0eXBlbmFtZSBJc0VudHJ5Ojp0eXBlLHZvaWQgPjo6dHlwZQogICAgICAgICBoZWxwZXIoIDo6Ym9vc3Q6Om1zbTo6YmFjazo6ZHVtbXk8MD4gPSAwKQogICAgICAgICB7CiAgICAgICAgICAgICBCT09TVF9TVEFUSUNfQ09OU1RBTlQoaW50LCBpZCA9IChnZXRfc3RhdGVfaWQ8c3R0LFN0YXRlPjo6dmFsdWUpKTsKICAgICAgICAgICAgIGlmIChpZCA9PSBzdGF0ZV9pZCkKICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICBleGVjdXRlX2VudHJ5PFN0YXRlPig6OmJvb3N0OjpmdXNpb246OmF0X2tleTxTdGF0ZT4oc2VsZi0+bV9zdWJzdGF0ZV9saXN0KSxldnQsKnNlbGYpOwogICAgICAgICAgICAgfQogICAgICAgICB9CiAgICAgICAgIC8vIGhlbHBlciBmb3IgZXhpdCBhY3Rpb25zCiAgICAgICAgIHRlbXBsYXRlIDxjbGFzcyBJc0VudHJ5LGNsYXNzIFN0YXRlPgogICAgICAgICB0eXBlbmFtZSBib29zdDo6ZGlzYWJsZV9pZjx0eXBlbmFtZSBJc0VudHJ5Ojp0eXBlLHZvaWQgPjo6dHlwZQogICAgICAgICBoZWxwZXIoIDo6Ym9vc3Q6Om1zbTo6YmFjazo6ZHVtbXk8MT4gPSAwKQogICAgICAgICB7CiAgICAgICAgICAgICBCT09TVF9TVEFUSUNfQ09OU1RBTlQoaW50LCBpZCA9IChnZXRfc3RhdGVfaWQ8c3R0LFN0YXRlPjo6dmFsdWUpKTsKICAgICAgICAgICAgIGlmIChpZCA9PSBzdGF0ZV9pZCkKICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICBleGVjdXRlX2V4aXQ8U3RhdGU+KDo6Ym9vc3Q6OmZ1c2lvbjo6YXRfa2V5PFN0YXRlPihzZWxmLT5tX3N1YnN0YXRlX2xpc3QpLGV2dCwqc2VsZik7CiAgICAgICAgICAgICB9CiAgICAgICAgIH0KICAgICAgICAgLy8gaXRlcmF0ZXMgdGhyb3VnaCBhbGwgc3RhdGVzIHRvIGZpbmQgdGhlIG9uZSB0byBiZSBhY3RpdmF0ZWQKICAgICAgICAgdGVtcGxhdGUgPGNsYXNzIFN0YXRlPgogICAgICAgICB2b2lkIG9wZXJhdG9yKCkoIDo6Ym9vc3Q6Om1zbTo6d3JhcDxTdGF0ZT4gY29uc3QmKQogICAgICAgICB7CiAgICAgICAgICAgICBlbnRyeV9leGl0X2hlbHBlcjxFdmVudCxpc19lbnRyeT46OnRlbXBsYXRlIGhlbHBlcjwgOjpib29zdDo6bXBsOjpib29sXzxpc19lbnRyeT4sU3RhdGUgPigpOwogICAgICAgICB9CiAgICAgcHJpdmF0ZToKICAgICAgICAgaW50ICAgICAgICAgICAgc3RhdGVfaWQ7CiAgICAgICAgIEV2ZW50IGNvbnN0JiAgIGV2dDsKICAgICAgICAgbGlicmFyeV9zbSogICAgc2VsZjsKICAgICB9OwoKICAgICAvLyBoZWxwZXIgdG8gc3RhcnQgdGhlIGZzbQogICAgIHRlbXBsYXRlIDxjbGFzcyByZWdpb25faWQsaW50IER1bW15PTA+CiAgICAgc3RydWN0IHJlZ2lvbl9zdGFydF9oZWxwZXIKICAgICB7CiAgICAgICAgIHRlbXBsYXRlPGNsYXNzIEV2ZW50PgogICAgICAgICBzdGF0aWMgdm9pZCBkb19zdGFydChsaWJyYXJ5X3NtKiBzZWxmXyxFdmVudCBjb25zdCYgaW5jb21pbmdFdmVudCkKICAgICAgICAgewogICAgICAgICAgICAgLy9mb3J3YXJkIHRoZSBldmVudCBmb3IgaGFuZGxpbmcgYnkgc3ViIHN0YXRlIG1hY2hpbmVzCiAgICAgICAgICAgICA6OmJvb3N0OjptcGw6OmZvcl9lYWNoPHN0YXRlX2xpc3QsIDo6Ym9vc3Q6Om1zbTo6d3JhcDwgOjpib29zdDo6bXBsOjpwbGFjZWhvbGRlcnM6Ol8xPiA+CiAgICAgICAgICAgICAgICAgKGVudHJ5X2V4aXRfaGVscGVyPEV2ZW50LHRydWU+KHNlbGZfLT5tX3N0YXRlc1tyZWdpb25faWQ6OnZhbHVlXSxpbmNvbWluZ0V2ZW50LHNlbGZfKSk7CiAgICAgICAgICAgICByZWdpb25fc3RhcnRfaGVscGVyCiAgICAgICAgICAgICAgICAgPCA6OmJvb3N0OjptcGw6OmludF88cmVnaW9uX2lkOjp2YWx1ZSsxPiA+Ojpkb19zdGFydChzZWxmXyxpbmNvbWluZ0V2ZW50KTsKICAgICAgICAgfQogICAgIH07CiAgICAgdGVtcGxhdGUgPGludCBEdW1teT4KICAgICBzdHJ1Y3QgcmVnaW9uX3N0YXJ0X2hlbHBlcjwgOjpib29zdDo6bXBsOjppbnRfPG5yX3JlZ2lvbnM6OnZhbHVlPixEdW1teT4KICAgICB7CiAgICAgICAgIC8vIGVuZCBvZiBwcm9jZXNzaW5nCiAgICAgICAgIHRlbXBsYXRlPGNsYXNzIEV2ZW50PgogICAgICAgICBzdGF0aWMgdm9pZCBkb19zdGFydChsaWJyYXJ5X3NtKixFdmVudCBjb25zdCYgKXt9CiAgICAgfTsKICAgICAvLyBzdGFydCBmb3Igc3RhdGVzIG1hY2hpbmVzIHdoaWNoIGFyZSB0aGVtc2VsdmVzIGVtYmVkZGVkIGluIG90aGVyIHN0YXRlIG1hY2hpbmVzIChjb21wb3NpdGVzKQogICAgIHRlbXBsYXRlIDxjbGFzcyBFdmVudD4KICAgICB2b2lkIHN0YXJ0KEV2ZW50IGNvbnN0JiBpbmNvbWluZ0V2ZW50KQogICAgIHsKICAgICAgICAgcmVnaW9uX3N0YXJ0X2hlbHBlcjwgOjpib29zdDo6bXBsOjppbnRfPDA+ID46OmRvX3N0YXJ0KHRoaXMsaW5jb21pbmdFdmVudCk7CiAgICAgfQoKICAgICAvLyBoZWxwZXIgdXNlZCB0byBzZXQgdGhlIGNvcnJlY3Qgc3RhdGUgYXMgYWN0aXZlIHN0YXRlIHVwb24gZW50cnkgaW50byBhIGZzbQogICAgIHN0cnVjdCBkaXJlY3RfZXZlbnRfc3RhcnRfaGVscGVyIAogICAgIHsKICAgICAgICAgZGlyZWN0X2V2ZW50X3N0YXJ0X2hlbHBlcihsaWJyYXJ5X3NtKiBzZWxmXyk6c2VsZihzZWxmXyl7fQogICAgICAgICAvLyB0aGlzIHZhcmlhbnQgaXMgZm9yIHRoZSBzdGFuZGFyZCBjYXNlLCBlbnRyeSBkdWUgdG8gYWN0aXZhdGlvbiBvZiB0aGUgY29udGFpbmluZyBGU00KICAgICAgICAgdGVtcGxhdGUgPGNsYXNzIEV2ZW50VHlwZSxjbGFzcyBGc21UeXBlPgogICAgICAgICB0eXBlbmFtZSA6OmJvb3N0OjpkaXNhYmxlX2lmPHR5cGVuYW1lIGhhc19kaXJlY3RfZW50cnk8RXZlbnRUeXBlPjo6dHlwZSx2b2lkPjo6dHlwZQogICAgICAgICAgICAgb3BlcmF0b3IoKShFdmVudFR5cGUgY29uc3QmIGV2dCxGc21UeXBlJiBmc20sIDo6Ym9vc3Q6Om1zbTo6YmFjazo6ZHVtbXk8MD4gPSAwKQogICAgICAgICB7CiAgICAgICAgICAgICAoc3RhdGljX2Nhc3Q8RGVyaXZlZCo+KHNlbGYpKS0+b25fZW50cnkoZXZ0LGZzbSk7CiAgICAgICAgICAgICBzZWxmLT5zdGFydChldnQpOwogICAgICAgICB9CgogICAgICAgICAvLyB0aGlzIHZhcmlhbnQgaXMgZm9yIHRoZSBkaXJlY3QgZW50cnkgY2FzZSAoanVzdCBvbmUgZW50cnksIG5vdCBhIHNlcXVlbmNlIG9mIGVudHJpZXMpCiAgICAgICAgIHRlbXBsYXRlIDxjbGFzcyBFdmVudFR5cGUsY2xhc3MgRnNtVHlwZT4KICAgICAgICAgdHlwZW5hbWUgOjpib29zdDo6ZW5hYmxlX2lmPAogICAgICAgICAgICAgdHlwZW5hbWUgOjpib29zdDo6bXBsOjphbmRfPAogICAgICAgICAgICAgICAgICAgICAgICB0eXBlbmFtZSA6OmJvb3N0OjptcGw6Om5vdF88IHR5cGVuYW1lIGlzX3BzZXVkb19lbnRyeTwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZW5hbWUgRXZlbnRUeXBlOjphY3RpdmVfc3RhdGU+Ojp0eXBlID46OnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVuYW1lIDo6Ym9vc3Q6Om1wbDo6YW5kXzx0eXBlbmFtZSBoYXNfZGlyZWN0X2VudHJ5PEV2ZW50VHlwZT46OnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlbmFtZSA6OmJvb3N0OjptcGw6Om5vdF88dHlwZW5hbWUgOjpib29zdDo6bXBsOjppc19zZXF1ZW5jZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHlwZW5hbWUgRXZlbnRUeXBlOjphY3RpdmVfc3RhdGU+Ojp0eXBlID46OnR5cGUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ojp0eXBlPjo6dHlwZSx2b2lkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ojp0eXBlCiAgICAgICAgIG9wZXJhdG9yKCkoRXZlbnRUeXBlIGNvbnN0JiBldnQsRnNtVHlwZSYgZnNtLCA6OmJvb3N0Ojptc206OmJhY2s6OmR1bW15PDE+ID0gMCkKICAgICAgICAgewogICAgICAgICAgICAgKHN0YXRpY19jYXN0PERlcml2ZWQqPihzZWxmKSktPm9uX2VudHJ5KGV2dCxmc20pOwogICAgICAgICAgICAgaW50IHN0YXRlX2lkID0gZ2V0X3N0YXRlX2lkPHN0dCx0eXBlbmFtZSBFdmVudFR5cGU6OmFjdGl2ZV9zdGF0ZTo6d3JhcHBlZF9lbnRyeT46OnZhbHVlOwogICAgICAgICAgICAgQk9PU1RfU1RBVElDX0FTU0VSVChFdmVudFR5cGU6OmFjdGl2ZV9zdGF0ZTo6em9uZV9pbmRleCA+PSAwKTsKICAgICAgICAgICAgIEJPT1NUX1NUQVRJQ19BU1NFUlQoRXZlbnRUeXBlOjphY3RpdmVfc3RhdGU6OnpvbmVfaW5kZXggPD0gbnJfcmVnaW9uczo6dmFsdWUpOwogICAgICAgICAgICAgLy8ganVzdCBzZXQgdGhlIGNvcnJlY3Qgem9uZSwgdGhlIG90aGVycyB3aWxsIGJlIGRlZmF1bHQvaGlzdG9yeSBpbml0aWFsaXplZAogICAgICAgICAgICAgc2VsZi0+bV9zdGF0ZXNbRXZlbnRUeXBlOjphY3RpdmVfc3RhdGU6OnpvbmVfaW5kZXhdID0gc3RhdGVfaWQ7CiAgICAgICAgICAgICBzZWxmLT5zdGFydChldnQubV9ldmVudCk7CiAgICAgICAgIH0KCiAgICAgICAgIC8vIHRoaXMgdmFyaWFudCBpcyBmb3IgdGhlIGZvcmsgZW50cnkgY2FzZSAoYSBzZXF1ZW5jZSBvbiBlbnRyaWVzKQogICAgICAgICB0ZW1wbGF0ZSA8Y2xhc3MgRXZlbnRUeXBlLGNsYXNzIEZzbVR5cGU+CiAgICAgICAgIHR5cGVuYW1lIDo6Ym9vc3Q6OmVuYWJsZV9pZjwKICAgICAgICAgICAgIHR5cGVuYW1lIDo6Ym9vc3Q6Om1wbDo6YW5kXzwKICAgICAgICAgICAgICAgICAgICB0eXBlbmFtZSA6OmJvb3N0OjptcGw6Om5vdF88CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVuYW1lIGlzX3BzZXVkb19lbnRyeTx0eXBlbmFtZSBFdmVudFR5cGU6OmFjdGl2ZV9zdGF0ZT46OnR5cGUgPjo6dHlwZSwKICAgICAgICAgICAgICAgICAgICB0eXBlbmFtZSA6OmJvb3N0OjptcGw6OmFuZF88dHlwZW5hbWUgaGFzX2RpcmVjdF9lbnRyeTxFdmVudFR5cGU+Ojp0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlbmFtZSA6OmJvb3N0OjptcGw6OmlzX3NlcXVlbmNlPAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZW5hbWUgRXZlbnRUeXBlOjphY3RpdmVfc3RhdGU+Ojp0eXBlIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ojp0eXBlPjo6dHlwZSx2b2lkIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID46OnR5cGUKICAgICAgICAgb3BlcmF0b3IoKShFdmVudFR5cGUgY29uc3QmIGV2dCxGc21UeXBlJiBmc20sIDo6Ym9vc3Q6Om1zbTo6YmFjazo6ZHVtbXk8Mj4gPSAwKQogICAgICAgICB7CiAgICAgICAgICAgICAoc3RhdGljX2Nhc3Q8RGVyaXZlZCo+KHNlbGYpKS0+b25fZW50cnkoZXZ0LGZzbSk7CiAgICAgICAgICAgICA6OmJvb3N0OjptcGw6OmZvcl9lYWNoPHR5cGVuYW1lIEV2ZW50VHlwZTo6YWN0aXZlX3N0YXRlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpib29zdDo6bXNtOjp3cmFwPCA6OmJvb3N0OjptcGw6OnBsYWNlaG9sZGVyczo6XzE+ID4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZm9ya19oZWxwZXI8RXZlbnRUeXBlPihzZWxmLGV2dCkpOwogICAgICAgICAgICAgLy8gc2V0IHRoZSBjb3JyZWN0IHpvbmVzLCB0aGUgb3RoZXJzIChpZiBhbnkpIHdpbGwgYmUgZGVmYXVsdC9oaXN0b3J5IGluaXRpYWxpemVkCiAgICAgICAgICAgICBzZWxmLT5zdGFydChldnQubV9ldmVudCk7CiAgICAgICAgIH0KCiAgICAgICAgIC8vIHRoaXMgdmFyaWFudCBpcyBmb3IgdGhlIHBzZXVkbyBzdGF0ZSBlbnRyeSBjYXNlCiAgICAgICAgIHRlbXBsYXRlIDxjbGFzcyBFdmVudFR5cGUsY2xhc3MgRnNtVHlwZT4KICAgICAgICAgdHlwZW5hbWUgOjpib29zdDo6ZW5hYmxlX2lmPAogICAgICAgICAgICAgdHlwZW5hbWUgaXNfcHNldWRvX2VudHJ5PHR5cGVuYW1lIEV2ZW50VHlwZTo6YWN0aXZlX3N0YXRlID46OnR5cGUsdm9pZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+Ojp0eXBlCiAgICAgICAgIG9wZXJhdG9yKCkoRXZlbnRUeXBlIGNvbnN0JiBldnQsRnNtVHlwZSYgZnNtLCA6OmJvb3N0Ojptc206OmJhY2s6OmR1bW15PDM+ID0gMCkKICAgICAgICAgewogICAgICAgICAgICAgLy8gZW50cnkgb24gdGhlIEZTTQogICAgICAgICAgICAgKHN0YXRpY19jYXN0PERlcml2ZWQqPihzZWxmKSktPm9uX2VudHJ5KGV2dCxmc20pOwogICAgICAgICAgICAgaW50IHN0YXRlX2lkID0gZ2V0X3N0YXRlX2lkPHN0dCx0eXBlbmFtZSBFdmVudFR5cGU6OmFjdGl2ZV9zdGF0ZTo6d3JhcHBlZF9lbnRyeT46OnZhbHVlOwogICAgICAgICAgICAgLy8gZ2l2ZW4gcmVnaW9uIHN0YXJ0cyB3aXRoIHRoZSBlbnRyeSBwc2V1ZG8gc3RhdGUgYXMgYWN0aXZlIHN0YXRlCiAgICAgICAgICAgICBzZWxmLT5tX3N0YXRlc1tFdmVudFR5cGU6OmFjdGl2ZV9zdGF0ZTo6em9uZV9pbmRleF0gPSBzdGF0ZV9pZDsKICAgICAgICAgICAgIHNlbGYtPnN0YXJ0KGV2dC5tX2V2ZW50KTsKICAgICAgICAgICAgIC8vIGFuZCB3ZSBwcm9jZXNzIHRoZSB0cmFuc2l0aW9uIGluIHRoZSB6b25lIG9mIHRoZSBuZXdseSBhY3RpdmUgc3RhdGUKICAgICAgICAgICAgIC8vIChlbnRyeSBwc2V1ZG8gc3RhdGVzIGFyZSwgYWNjb3JkaW5nIHRvIFVNTCwgYSBzdGF0ZSBjb25uZWN0aW5nIDEgdHJhbnNpdGlvbiBvdXRzaWRlIHRvIDEgaW5zaWRlCiAgICAgICAgICAgICBzZWxmLT5wcm9jZXNzX2V2ZW50KGV2dC5tX2V2ZW50KTsKICAgICAgICAgfQogICAgIHByaXZhdGU6CiAgICAgICAgIC8vIGhlbHBlciBmb3IgdGhlIGZvcmsgY2FzZSwgZG9lcyBhbG1vc3QgbGlrZSB0aGUgZGlyZWN0IGVudHJ5CiAgICAgICAgIGxpYnJhcnlfc20qIHNlbGY7CiAgICAgICAgIHRlbXBsYXRlIDxjbGFzcyBFdmVudFR5cGU+CiAgICAgICAgIHN0cnVjdCBmb3JrX2hlbHBlcgogICAgICAgICB7CiAgICAgICAgICAgICBmb3JrX2hlbHBlcihsaWJyYXJ5X3NtKiBzZWxmXyxFdmVudFR5cGUgY29uc3QmIGV2dF8pOgogICAgICAgICAgICAgICAgaGVscGVyX3NlbGYoc2VsZl8pLGhlbHBlcl9ldnQoZXZ0Xyl7fQogICAgICAgICAgICAgdGVtcGxhdGUgPGNsYXNzIFN0YXRlVHlwZT4KICAgICAgICAgICAgIHZvaWQgb3BlcmF0b3IoKSggOjpib29zdDo6bXNtOjp3cmFwPFN0YXRlVHlwZT4gY29uc3QmICkKICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICBpbnQgc3RhdGVfaWQgPSBnZXRfc3RhdGVfaWQ8c3R0LHR5cGVuYW1lIFN0YXRlVHlwZTo6d3JhcHBlZF9lbnRyeT46OnZhbHVlOwogICAgICAgICAgICAgICAgIEJPT1NUX1NUQVRJQ19BU1NFUlQoU3RhdGVUeXBlOjp6b25lX2luZGV4ID49IDApOwogICAgICAgICAgICAgICAgIEJPT1NUX1NUQVRJQ19BU1NFUlQoU3RhdGVUeXBlOjp6b25lX2luZGV4IDw9IG5yX3JlZ2lvbnM6OnZhbHVlKTsKICAgICAgICAgICAgICAgICBoZWxwZXJfc2VsZi0+bV9zdGF0ZXNbU3RhdGVUeXBlOjp6b25lX2luZGV4XSA9IHN0YXRlX2lkOwogICAgICAgICAgICAgfQogICAgICAgICBwcml2YXRlOgogICAgICAgICAgICAgbGlicmFyeV9zbSogICAgICAgIGhlbHBlcl9zZWxmOwogICAgICAgICAgICAgRXZlbnRUeXBlIGNvbnN0JiAgIGhlbHBlcl9ldnQ7CiAgICAgICAgIH07CiAgICAgfTsKCiAgICAgLy8gaGVscGVyIGZvciBlbnRyeQogICAgIHRlbXBsYXRlIDxjbGFzcyByZWdpb25faWQsaW50IER1bW15PTA+CiAgICAgc3RydWN0IHJlZ2lvbl9lbnRyeV9leGl0X2hlbHBlcgogICAgIHsKICAgICAgICAgdGVtcGxhdGU8Y2xhc3MgRXZlbnQ+CiAgICAgICAgIHN0YXRpYyB2b2lkIGRvX2VudHJ5KGxpYnJhcnlfc20qIHNlbGZfLEV2ZW50IGNvbnN0JiBpbmNvbWluZ0V2ZW50KQogICAgICAgICB7CiAgICAgICAgICAgICBzZWxmXy0+bV9zdGF0ZXNbcmVnaW9uX2lkOjp2YWx1ZV0gPSAKICAgICAgICAgICAgICAgICBzZWxmXy0+bV9oaXN0b3J5Lmhpc3RvcnlfZW50cnkoaW5jb21pbmdFdmVudClbcmVnaW9uX2lkOjp2YWx1ZV07CiAgICAgICAgICAgICByZWdpb25fZW50cnlfZXhpdF9oZWxwZXIKICAgICAgICAgICAgICAgICA8IDo6Ym9vc3Q6Om1wbDo6aW50XzxyZWdpb25faWQ6OnZhbHVlKzE+ID46OmRvX2VudHJ5KHNlbGZfLGluY29taW5nRXZlbnQpOwogICAgICAgICB9CiAgICAgICAgIHRlbXBsYXRlPGNsYXNzIEV2ZW50PgogICAgICAgICBzdGF0aWMgdm9pZCBkb19leGl0KGxpYnJhcnlfc20qIHNlbGZfLEV2ZW50IGNvbnN0JiBpbmNvbWluZ0V2ZW50KQogICAgICAgICB7CiAgICAgICAgICAgICA6OmJvb3N0OjptcGw6OmZvcl9lYWNoPHN0YXRlX2xpc3QsIDo6Ym9vc3Q6Om1zbTo6d3JhcDwgOjpib29zdDo6bXBsOjpwbGFjZWhvbGRlcnM6Ol8xPiA+CiAgICAgICAgICAgICAgICAgKGVudHJ5X2V4aXRfaGVscGVyPEV2ZW50LGZhbHNlPihzZWxmXy0+bV9zdGF0ZXNbcmVnaW9uX2lkOjp2YWx1ZV0saW5jb21pbmdFdmVudCxzZWxmXykpOwogICAgICAgICAgICAgcmVnaW9uX2VudHJ5X2V4aXRfaGVscGVyCiAgICAgICAgICAgICAgICAgPCA6OmJvb3N0OjptcGw6OmludF88cmVnaW9uX2lkOjp2YWx1ZSsxPiA+Ojpkb19leGl0KHNlbGZfLGluY29taW5nRXZlbnQpOwogICAgICAgICB9CiAgICAgfTsKICAgICB0ZW1wbGF0ZSA8aW50IER1bW15PgogICAgIHN0cnVjdCByZWdpb25fZW50cnlfZXhpdF9oZWxwZXI8IDo6Ym9vc3Q6Om1wbDo6aW50Xzxucl9yZWdpb25zOjp2YWx1ZT4sRHVtbXk+CiAgICAgewogICAgICAgICAvLyBlbmQgb2YgcHJvY2Vzc2luZwogICAgICAgICB0ZW1wbGF0ZTxjbGFzcyBFdmVudD4KICAgICAgICAgc3RhdGljIHZvaWQgZG9fZW50cnkobGlicmFyeV9zbSosRXZlbnQgY29uc3QmICl7fQogICAgICAgICB0ZW1wbGF0ZTxjbGFzcyBFdmVudD4KICAgICAgICAgc3RhdGljIHZvaWQgZG9fZXhpdChsaWJyYXJ5X3NtKixFdmVudCBjb25zdCYgKXt9CiAgICAgfTsKICAgICAvLyBlbnRyeS9leGl0IGZvciBzdGF0ZXMgbWFjaGluZXMgd2hpY2ggYXJlIHRoZW1zZWx2ZXMgZW1iZWRkZWQgaW4gb3RoZXIgc3RhdGUgbWFjaGluZXMgKGNvbXBvc2l0ZXMpCiAgICAgdGVtcGxhdGUgPGNsYXNzIEV2ZW50LGNsYXNzIEZzbVR5cGU+CiAgICAgdm9pZCBkb19lbnRyeShFdmVudCBjb25zdCYgaW5jb21pbmdFdmVudCxGc21UeXBlJiBmc20pCiAgICAgewogICAgICAgIC8vIGJ5IGRlZmF1bHQgd2UgYWN0aXZhdGUgdGhlIGhpc3RvcnkvaW5pdCBzdGF0ZXMsIGNhbiBiZSBvdmVyd3JpdHRlbiBieSBkaXJlY3RfZXZlbnRfc3RhcnRfaGVscGVyCiAgICAgICAgcmVnaW9uX2VudHJ5X2V4aXRfaGVscGVyPCA6OmJvb3N0OjptcGw6OmludF88MD4gPjo6ZG9fZW50cnkodGhpcyxpbmNvbWluZ0V2ZW50KTsKICAgICAgICAvLyBibG9jayBpbW1lZGlhdGUgaGFuZGxpbmcgb2YgZXZlbnRzCiAgICAgICAgbV9ldmVudF9wcm9jZXNzaW5nID0gdHJ1ZTsKICAgICAgICAvLyBpZiB0aGUgZXZlbnQgaXMgZ2VuZXJhdGluZyBhIGRpcmVjdCBlbnRyeS9mb3JrLCBzZXQgdGhlIGN1cnJlbnQgc3RhdGUocykgdG8gdGhlIGRpcmVjdCBzdGF0ZShzKQogICAgICAgIGRpcmVjdF9ldmVudF9zdGFydF9oZWxwZXIodGhpcykoaW5jb21pbmdFdmVudCxmc20pOwogICAgICAgIC8vIGhhbmRsZSBtZXNzYWdlcyB3aGljaCB3ZXJlIGdlbmVyYXRlZCBhbmQgYmxvY2tlZCBpbiB0aGUgaW5pdCBjYWxscwogICAgICAgIG1fZXZlbnRfcHJvY2Vzc2luZyA9IGZhbHNlOwogICAgICAgIHByb2Nlc3NfbWVzc2FnZV9xdWV1ZSh0aGlzKTsKICAgICB9CiAgICAgdGVtcGxhdGUgPGNsYXNzIEV2ZW50LGNsYXNzIEZzbVR5cGU+CiAgICAgdm9pZCBkb19leGl0KEV2ZW50IGNvbnN0JiBpbmNvbWluZ0V2ZW50LEZzbVR5cGUmIGZzbSkKICAgICB7CiAgICAgICAgLy8gZmlyc3QgcmVjdXJzaXZlbHkgZXhpdCB0aGUgc3ViIG1hY2hpbmVzCiAgICAgICAgLy8gZm9yd2FyZCB0aGUgZXZlbnQgZm9yIGhhbmRsaW5nIGJ5IHN1YiBzdGF0ZSBtYWNoaW5lcwogICAgICAgIHJlZ2lvbl9lbnRyeV9leGl0X2hlbHBlcjwgOjpib29zdDo6bXBsOjppbnRfPDA+ID46OmRvX2V4aXQodGhpcyxpbmNvbWluZ0V2ZW50KTsKICAgICAgICAvLyB0aGVuIGNhbGwgb3VyIG93biBleGl0CiAgICAgICAgKHN0YXRpY19jYXN0PERlcml2ZWQqPih0aGlzKSktPm9uX2V4aXQoaW5jb21pbmdFdmVudCxmc20pOwogICAgICAgIC8vIGdpdmUgdGhlIGhpc3RvcnkgYSBjaGFuY2UgdG8gaGFuZGxlIHRoaXMgKG9yIG5vdCkuCiAgICAgICAgbV9oaXN0b3J5Lmhpc3RvcnlfZXhpdCh0aGlzLT5tX3N0YXRlcyk7CiAgICAgfQoKICAgIC8vIHRoZSBJQk0gYW5kIFZDPDggY29tcGlsZXJzIHNlZW0gdG8gaGF2ZSBwcm9ibGVtcyB3aXRoIHRoZSBmcmllbmQgZGVjbGFyYXRpb24gb2YgZGlzcGF0Y2hfdGFibGUKI2lmIGRlZmluZWQgKF9fSUJNQ1BQX18pIHx8IChkZWZpbmVkKF9NU0NfVkVSKSAmJiAoX01TQ19WRVIgPCAxNDAwKSkKICAgICBwdWJsaWM6CiNlbmRpZgogICAgLy8gbm8gdHJhbnNpdGlvbiBmb3IgZXZlbnQuCiAgICB0ZW1wbGF0ZSA8Y2xhc3MgRXZlbnQ+CiAgICBzdGF0aWMgSGFuZGxlZEVudW0gY2FsbF9ub190cmFuc2l0aW9uKGxpYnJhcnlfc20mICwgaW50ICwgaW50ICwgRXZlbnQgY29uc3QmICkKICAgIHsKICAgICAgICByZXR1cm4gSEFORExFRF9GQUxTRTsKICAgIH0KICAgIC8vIGNhbGxlZCBmb3IgZGVmZXJyZWQgZXZlbnRzLiBBZGRyZXNzIHNldCBpbiB0aGUgZGlzcGF0Y2hfdGFibGUgYXQgaW5pdAogICAgdGVtcGxhdGUgPGNsYXNzIEV2ZW50PgogICAgc3RhdGljIEhhbmRsZWRFbnVtIGRlZmVyX3RyYW5zaXRpb24obGlicmFyeV9zbSYgZnNtLCBpbnQgLCBpbnQgLCBFdmVudCBjb25zdCYgZSkKICAgIHsKICAgICAgICBmc20uZGVmZXJfZXZlbnQoZSk7CiAgICAgICAgcmV0dXJuIEhBTkRMRURfREVGRVJSRUQ7CiAgICB9CiAgICAvLyBjYWxsZWQgZm9yIGNvbXBsZXRpb24gZXZlbnRzLiBEZWZhdWx0IGFkZHJlc3Mgc2V0IGluIHRoZSBkaXNwYXRjaF90YWJsZSBhdCBpbml0CiAgICAvLyBwcmV2ZW50cyBuby10cmFuc2l0aW9uIGRldGVjdGlvbiBmb3IgY29tcGxldGlvbiBldmVudHMKICAgIHRlbXBsYXRlIDxjbGFzcyBFdmVudD4KICAgIHN0YXRpYyBIYW5kbGVkRW51bSBkZWZhdWx0X2V2ZW50bGVzc190cmFuc2l0aW9uKGxpYnJhcnlfc20mIGZzbSwgaW50LCBpbnQgLCBFdmVudCBjb25zdCYgZSkKICAgIHsKICAgICAgICByZXR1cm4gSEFORExFRF9GQUxTRTsKICAgIH0KI2lmIGRlZmluZWQgKF9fSUJNQ1BQX18pIHx8IChkZWZpbmVkKF9NU0NfVkVSKSAmJiAoX01TQ19WRVIgPCAxNDAwKSkKICAgICBwcml2YXRlOgojZW5kaWYKICAgIC8vIHB1dHMgYSBkZWZlcnJlZCBldmVudCBpbiB0aGUgcXVldWUKICAgIHZvaWQgcG9zdF9kZWZlcnJlZF9ldmVudChkZWZlcnJlZF9mY3QmIGRlZmVycmVkKQogICAgewogICAgICAgIG1fZGVmZXJyZWRfZXZlbnRzX3F1ZXVlLm1fZGVmZXJyZWRfZXZlbnRzX3F1ZXVlLnB1c2hfZnJvbnQoZGVmZXJyZWQpOwogICAgfQogICAgLy8gcmVtb3ZlcyBvbmUgZXZlbnQgZnJvbSB0aGUgbWVzc2FnZSBxdWV1ZSBhbmQgcHJvY2Vzc2VzIGl0CiAgICB0ZW1wbGF0ZSA8Y2xhc3MgU3RhdGVUeXBlPgogICAgdHlwZW5hbWUgOjpib29zdDo6ZGlzYWJsZV9pZjx0eXBlbmFtZSBpc19ub19tZXNzYWdlX3F1ZXVlPFN0YXRlVHlwZT46OnR5cGUsdm9pZCA+Ojp0eXBlCiAgICBwcm9jZXNzX21lc3NhZ2VfcXVldWUoU3RhdGVUeXBlKikKICAgIHsKICAgICAgICBpZiAoIW1fZXZlbnRzX3F1ZXVlLm1fZXZlbnRzX3F1ZXVlLmVtcHR5KCkpCiAgICAgICAgewogICAgICAgICAgICB0cmFuc2l0aW9uX2ZjdCB0b19jYWxsID0gbV9ldmVudHNfcXVldWUubV9ldmVudHNfcXVldWUuZnJvbnQoKTsKICAgICAgICAgICAgbV9ldmVudHNfcXVldWUubV9ldmVudHNfcXVldWUucG9wKCk7CiAgICAgICAgICAgIHRvX2NhbGwoKTsKICAgICAgICB9CiAgICB9CiAgICB0ZW1wbGF0ZSA8Y2xhc3MgU3RhdGVUeXBlPgogICAgdHlwZW5hbWUgOjpib29zdDo6ZW5hYmxlX2lmPHR5cGVuYW1lIGlzX25vX21lc3NhZ2VfcXVldWU8U3RhdGVUeXBlPjo6dHlwZSx2b2lkID46OnR5cGUKICAgICAgICBwcm9jZXNzX21lc3NhZ2VfcXVldWUoU3RhdGVUeXBlKikKICAgIHsKICAgICAgICAvLyBub3RoaW5nIHRvIHByb2Nlc3MKICAgIH0KICAgIC8vIGNhbGxzIHRoZSBlbnRyeS9leGl0IG9yIG9uX2VudHJ5L29uX2V4aXQgZGVwZW5kaW5nIG9uIHRoZSBzdGF0ZSB0eXBlCiAgICAvLyAoYXZvaWRzIGNhbGxpbmcgdmlydHVhbGx5KQogICAgLy8gdmFyaWFudCBmb3IgRlNNcwogICAgdGVtcGxhdGUgPGNsYXNzIFN0YXRlVHlwZSxjbGFzcyBFdmVudFR5cGUsY2xhc3MgRnNtVHlwZT4KICAgIHN0YXRpYwogICAgICAgIHR5cGVuYW1lIGJvb3N0OjplbmFibGVfaWY8dHlwZW5hbWUgaXNfY29tcG9zaXRlX3N0YXRlPFN0YXRlVHlwZT46OnR5cGUsdm9pZCA+Ojp0eXBlCiAgICAgICAgZXhlY3V0ZV9lbnRyeShTdGF0ZVR5cGUmIGFzdGF0ZSxFdmVudFR5cGUgY29uc3QmIGV2dCxGc21UeXBlJiBmc20sYm9vc3Q6Om1zbTo6YmFjazo6ZHVtbXk8MD4gPSAwKQogICAgewogICAgICAgIC8vIGNhbGxzIG9uX2VudHJ5IG9uIHRoZSBmc20gdGhlbiBoYW5kbGVzIGRpcmVjdCBlbnRyaWVzLCBmb3JrLCBlbnRyeSBwc2V1ZG8gc3RhdGUKICAgICAgICBhc3RhdGUuZG9fZW50cnkoZXZ0LGZzbSk7CiAgICB9CiAgICAvLyB2YXJpYW50IGZvciBzdGF0ZXMKICAgIHRlbXBsYXRlIDxjbGFzcyBTdGF0ZVR5cGUsY2xhc3MgRXZlbnRUeXBlLGNsYXNzIEZzbVR5cGU+CiAgICBzdGF0aWMKICAgICAgICB0eXBlbmFtZSA6OmJvb3N0OjpkaXNhYmxlX2lmPAogICAgICAgICAgICB0eXBlbmFtZSA6OmJvb3N0OjptcGw6Om9yXzx0eXBlbmFtZSBpc19jb21wb3NpdGVfc3RhdGU8U3RhdGVUeXBlPjo6dHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZW5hbWUgaXNfcHNldWRvX2V4aXQ8U3RhdGVUeXBlPjo6dHlwZSA+Ojp0eXBlLHZvaWQgPjo6dHlwZQogICAgZXhlY3V0ZV9lbnRyeShTdGF0ZVR5cGUmIGFzdGF0ZSxFdmVudFR5cGUgY29uc3QmIGV2dCxGc21UeXBlJiBmc20sIDo6Ym9vc3Q6Om1zbTo6YmFjazo6ZHVtbXk8MT4gPSAwKQogICAgewogICAgICAgIC8vIHNpbXBsZSBjYWxsIHRvIG9uX2VudHJ5CiAgICAgICAgYXN0YXRlLm9uX2VudHJ5KGV2dCxmc20pOwogICAgfQogICAgLy8gdmFyaWFudCBmb3IgZXhpdCBwc2V1ZG8gc3RhdGVzCiAgICB0ZW1wbGF0ZSA8Y2xhc3MgU3RhdGVUeXBlLGNsYXNzIEV2ZW50VHlwZSxjbGFzcyBGc21UeXBlPgogICAgc3RhdGljCiAgICAgICAgdHlwZW5hbWUgOjpib29zdDo6ZW5hYmxlX2lmPHR5cGVuYW1lIGlzX3BzZXVkb19leGl0PFN0YXRlVHlwZT46OnR5cGUsdm9pZCA+Ojp0eXBlCiAgICBleGVjdXRlX2VudHJ5KFN0YXRlVHlwZSYgYXN0YXRlLEV2ZW50VHlwZSBjb25zdCYgZXZ0LEZzbVR5cGUmIGZzbSwgOjpib29zdDo6bXNtOjpiYWNrOjpkdW1teTwyPiA9IDApCiAgICB7CiAgICAgICAgLy8gY2FsbHMgb25fZW50cnkgb24gdGhlIHN0YXRlIHRoZW4gZm9yd2FyZCB0aGUgZXZlbnQgdG8gdGhlIHRyYW5zaXRpb24gd2hpY2ggc2hvdWxkIGJlIGRlZmluZWQgaW5zaWRlIHRoZSAKICAgICAgICAvLyBjb250YWluZWQgZnNtCiAgICAgICAgYXN0YXRlLm9uX2VudHJ5KGV2dCxmc20pOwogICAgICAgIGFzdGF0ZS5mb3J3YXJkX2V2ZW50KGV2dCk7CiAgICB9CiAgICB0ZW1wbGF0ZSA8Y2xhc3MgU3RhdGVUeXBlLGNsYXNzIEV2ZW50VHlwZSxjbGFzcyBGc21UeXBlPgogICAgc3RhdGljCiAgICAgICAgdHlwZW5hbWUgOjpib29zdDo6ZW5hYmxlX2lmPHR5cGVuYW1lIGlzX2NvbXBvc2l0ZV9zdGF0ZTxTdGF0ZVR5cGU+Ojp0eXBlLHZvaWQgPjo6dHlwZQogICAgZXhlY3V0ZV9leGl0KFN0YXRlVHlwZSYgYXN0YXRlLEV2ZW50VHlwZSBjb25zdCYgZXZ0LEZzbVR5cGUmIGZzbSwgOjpib29zdDo6bXNtOjpiYWNrOjpkdW1teTwwPiA9IDApCiAgICB7CiAgICAgICAgYXN0YXRlLmRvX2V4aXQoZXZ0LGZzbSk7CiAgICB9CiAgICB0ZW1wbGF0ZSA8Y2xhc3MgU3RhdGVUeXBlLGNsYXNzIEV2ZW50VHlwZSxjbGFzcyBGc21UeXBlPgogICAgc3RhdGljCiAgICAgICAgdHlwZW5hbWUgOjpib29zdDo6ZGlzYWJsZV9pZjx0eXBlbmFtZSBpc19jb21wb3NpdGVfc3RhdGU8U3RhdGVUeXBlPjo6dHlwZSx2b2lkID46OnR5cGUKICAgIGV4ZWN1dGVfZXhpdChTdGF0ZVR5cGUmIGFzdGF0ZSxFdmVudFR5cGUgY29uc3QmIGV2dCxGc21UeXBlJiBmc20sIDo6Ym9vc3Q6Om1zbTo6YmFjazo6ZHVtbXk8MT4gPSAwKQogICAgewogICAgICAgIC8vIHNpbXBsZSBjYWxsIHRvIG9uX2V4aXQKICAgICAgICBhc3RhdGUub25fZXhpdChldnQsZnNtKTsKICAgIH0KCiAgICAvLyBoZWxwZXIgYWxsb3dpbmcgc3BlY2lhbCBoYW5kbGluZyBvZiBkaXJlY3QgZW50cmllcyAvIGZvcmsKICAgIHRlbXBsYXRlIDxjbGFzcyBTdGF0ZVR5cGUsY2xhc3MgVGFyZ2V0VHlwZSxjbGFzcyBFdmVudFR5cGUsY2xhc3MgRnNtVHlwZT4KICAgIHN0YXRpYwogICAgICAgIHR5cGVuYW1lIDo6Ym9vc3Q6OmRpc2FibGVfaWY8CiAgICAgICAgICAgIHR5cGVuYW1lIDo6Ym9vc3Q6Om1wbDo6b3JfPHR5cGVuYW1lIGhhc19leHBsaWNpdF9lbnRyeV9zdGF0ZTxUYXJnZXRUeXBlPjo6dHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpib29zdDo6bXBsOjppc19zZXF1ZW5jZTxUYXJnZXRUeXBlPiA+Ojp0eXBlLHZvaWQ+Ojp0eXBlCiAgICBjb252ZXJ0X2V2ZW50X2FuZF9leGVjdXRlX2VudHJ5KFN0YXRlVHlwZSYgYXN0YXRlLEV2ZW50VHlwZSBjb25zdCYgZXZ0LCBGc21UeXBlJiBmc20sIDo6Ym9vc3Q6Om1zbTo6YmFjazo6ZHVtbXk8MT4gPSAwKQogICAgewogICAgICAgIC8vIGlmIHRoZSB0YXJnZXQgaXMgYSBub3JtYWwgc3RhdGUsIGRvIHRoZSBzdGFuZGFyZCBlbnRyeSBoYW5kbGluZwogICAgICAgIGV4ZWN1dGVfZW50cnk8U3RhdGVUeXBlPihhc3RhdGUsZXZ0LGZzbSk7CiAgICB9CiAgICB0ZW1wbGF0ZSA8Y2xhc3MgU3RhdGVUeXBlLGNsYXNzIFRhcmdldFR5cGUsY2xhc3MgRXZlbnRUeXBlLGNsYXNzIEZzbVR5cGU+CiAgICBzdGF0aWMKICAgICAgICB0eXBlbmFtZSA6OmJvb3N0OjplbmFibGVfaWY8CiAgICAgICAgICAgIHR5cGVuYW1lIDo6Ym9vc3Q6Om1wbDo6b3JfPHR5cGVuYW1lIGhhc19leHBsaWNpdF9lbnRyeV9zdGF0ZTxUYXJnZXRUeXBlPjo6dHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpib29zdDo6bXBsOjppc19zZXF1ZW5jZTxUYXJnZXRUeXBlPiA+Ojp0eXBlLHZvaWQgPjo6dHlwZQogICAgY29udmVydF9ldmVudF9hbmRfZXhlY3V0ZV9lbnRyeShTdGF0ZVR5cGUmIGFzdGF0ZSxFdmVudFR5cGUgY29uc3QmIGV2dCwgRnNtVHlwZSYgZnNtLCA6OmJvb3N0Ojptc206OmJhY2s6OmR1bW15PDA+ID0gMCkKICAgIHsKICAgICAgICAvLyBmb3IgdGhlIGRpcmVjdCBlbnRyeSwgcGFjayB0aGUgZXZlbnQgaW4gYSB3cmFwcGVyIHNvIHRoYXQgd2UgaGFuZGxlIGl0IGRpZmZlcmVudGx5IGR1cmluZyBmc20gZW50cnkKICAgICAgICBleGVjdXRlX2VudHJ5KGFzdGF0ZSxtc206OmJhY2s6OmRpcmVjdF9lbnRyeV9ldmVudDxUYXJnZXRUeXBlLEV2ZW50VHlwZT4oZXZ0KSxmc20pOwogICAgfQoKICAgIC8vIGNyZWF0ZXMgYWxsIHRoZSBzdGF0ZXMKICAgIHRlbXBsYXRlIDxjbGFzcyBDb250YWluaW5nU00+CiAgICB2b2lkIGZpbGxfc3RhdGVzKENvbnRhaW5pbmdTTSogY29udGFpbmluZ19zbT0wKQogICAgewogICAgICAgIEJPT1NUX1NUQVRJQ19DT05TVEFOVChpbnQsIG1heF9zdGF0ZSA9IChtcGw6OnNpemU8c3RhdGVfbGlzdD46OnZhbHVlKSk7CiAgICAgICAgLy8gYWxsb2NhdGUgdGhlIHBsYWNlIHdpdGhvdXQgcmVhbGxvY2F0aW9uCiAgICAgICAgbV92aXNpdG9ycy5maWxsX3Zpc2l0b3JzKG1heF9zdGF0ZSk7CiAgICAgICAgOjpib29zdDo6ZnVzaW9uOjpmb3JfZWFjaChtX3N1YnN0YXRlX2xpc3QsYWRkX3N0YXRlPENvbnRhaW5pbmdTTT4odGhpcyxjb250YWluaW5nX3NtKSk7CgogICAgfQoKcHJpdmF0ZToKICAgIHRlbXBsYXRlIDxjbGFzcyBTdGF0ZVR5cGUsY2xhc3MgRW5hYmxlPXZvaWQ+CiAgICBzdHJ1Y3QgbXNnX3F1ZXVlX2hlbHBlciAKICAgIHsKICAgIHB1YmxpYzoKICAgICAgICBtc2dfcXVldWVfaGVscGVyKCk6bV9ldmVudHNfcXVldWUoKXt9CiAgICAgICAgZXZlbnRzX3F1ZXVlX3QgICAgICAgICAgICAgIG1fZXZlbnRzX3F1ZXVlOwogICAgfTsKICAgIHRlbXBsYXRlIDxjbGFzcyBTdGF0ZVR5cGU+CiAgICBzdHJ1Y3QgbXNnX3F1ZXVlX2hlbHBlcjxTdGF0ZVR5cGUsCiAgICAgICAgdHlwZW5hbWUgOjpib29zdDo6ZW5hYmxlX2lmPHR5cGVuYW1lIGlzX25vX21lc3NhZ2VfcXVldWU8U3RhdGVUeXBlPjo6dHlwZSA+Ojp0eXBlPiAKICAgIHsKICAgIH07CgogICAgdGVtcGxhdGUgPGNsYXNzIEZzbSxjbGFzcyBTdHQsIGNsYXNzIEV2ZW50LCBjbGFzcyBDb21waWxlPgogICAgZnJpZW5kIHN0cnVjdCBkaXNwYXRjaF90YWJsZTsKCiAgICAvLyBkYXRhIG1lbWJlcnMKICAgIGludCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9zdGF0ZXNbbnJfcmVnaW9uczo6dmFsdWVdOwogICAgbXNnX3F1ZXVlX2hlbHBlcjxsaWJyYXJ5X3NtPiAgICBtX2V2ZW50c19xdWV1ZTsKICAgIGRlZmVycmVkX21zZ19xdWV1ZV9oZWxwZXIKICAgICAgICA8bGlicmFyeV9zbT4gICAgICAgICAgICAgICAgbV9kZWZlcnJlZF9ldmVudHNfcXVldWU7CiAgICBjb25jcmV0ZV9oaXN0b3J5ICAgICAgICAgICAgICAgIG1faGlzdG9yeTsKICAgIGJvb2wgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9ldmVudF9wcm9jZXNzaW5nOwogICAgYm9vbCAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2lzX2luY2x1ZGVkOwogICAgdmlzaXRvcl9mY3RfaGVscGVyPEJhc2VTdGF0ZT4gICBtX3Zpc2l0b3JzOwogICAgc3Vic3RhdGVfbGlzdCAgICAgICAgICAgICAgICAgICBtX3N1YnN0YXRlX2xpc3Q7CgoKfTsKCn0gfSB9Ly8gYm9vc3Q6Om1zbTo6YmFjawojZW5kaWYgLy9CT09TVF9NU01fQkFDS19TVEFURU1BQ0hJTkVfSAoK