Ly8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQovLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KDQovLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KDQojaW5jbHVkZSAiZnBkZnNkay9pbmNsdWRlL2ZzZGtfZGVmaW5lLmgiDQojaW5jbHVkZSAiZnBkZnNkay9pbmNsdWRlL2ZwZGZ4ZmEvZnBkZnhmYV9kb2MuaCINCiNpbmNsdWRlICJmcGRmc2RrL2luY2x1ZGUvZnNka19tZ3IuaCINCiNpbmNsdWRlICJmcGRmc2RrL2luY2x1ZGUvZnBkZnhmYS9mcGRmeGZhX2FwcC5oIg0KI2luY2x1ZGUgImZwZGZzZGsvaW5jbHVkZS9mcGRmeGZhL2ZwZGZ4ZmFfdXRpbC5oIg0KI2luY2x1ZGUgImZwZGZzZGsvaW5jbHVkZS9mcGRmeGZhL2ZwZGZ4ZmFfcGFnZS5oIg0KI2luY2x1ZGUgImZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L0lKYXZhU2NyaXB0LmgiDQojaW5jbHVkZSAicHVibGljL2ZwZGZfZm9ybWZpbGwuaCINCg0KI2RlZmluZSBJRFNfWEZBX1ZhbGlkYXRlX0lucHV0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXA0KICAiQXQgbGVhc3Qgb25lIHJlcXVpcmVkIGZpZWxkIHdhcyBlbXB0eS4gUGxlYXNlIGZpbGwgaW4gdGhlIHJlcXVpcmVkICIgXA0KICAiZmllbGRzXHJcbihoaWdobGlnaHRlZCkgYmVmb3JlIGNvbnRpbnVpbmcuIg0KDQovLyBzdWJtaXQNCiNkZWZpbmUgRlhGQV9DT05GSUcgMHgwMDAwMDAwMQ0KI2RlZmluZSBGWEZBX1RFTVBMQVRFIDB4MDAwMDAwMTANCiNkZWZpbmUgRlhGQV9MT0NBTEVTRVQgMHgwMDAwMDEwMA0KI2RlZmluZSBGWEZBX0RBVEFTRVRTIDB4MDAwMDEwMDANCiNkZWZpbmUgRlhGQV9YTVBNRVRBIDB4MDAwMTAwMDANCiNkZWZpbmUgRlhGQV9YRkRGIDB4MDAxMDAwMDANCiNkZWZpbmUgRlhGQV9GT1JNIDB4MDEwMDAwMDANCiNkZWZpbmUgRlhGQV9QREYgMHgxMDAwMDAwMA0KDQojaWZuZGVmIF9XSU4zMg0KZXh0ZXJuIHZvaWQgU2V0TGFzdEVycm9yKGludCBlcnIpOw0KDQpleHRlcm4gaW50IEdldExhc3RFcnJvcigpOw0KI2VuZGlmDQoNCkNQREZYRkFfRG9jdW1lbnQ6OkNQREZYRkFfRG9jdW1lbnQoQ1BERl9Eb2N1bWVudCogcFBERkRvYywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1BERlhGQV9BcHAqIHBQcm92aWRlcikNCiAgICA6IG1faURvY1R5cGUoRE9DVFlQRV9QREYpLA0KICAgICAgbV9wUERGRG9jKHBQREZEb2MpLA0KICAgICAgbV9wU0RLRG9jKG51bGxwdHIpLA0KICAgICAgbV9wWEZBRG9jKG51bGxwdHIpLA0KICAgICAgbV9wWEZBRG9jVmlldyhudWxscHRyKSwNCiAgICAgIG1fcEFwcChwUHJvdmlkZXIpLA0KICAgICAgbV9wSlNDb250ZXh0KG51bGxwdHIpIHsNCn0NCg0KQ1BERlhGQV9Eb2N1bWVudDo6fkNQREZYRkFfRG9jdW1lbnQoKSB7DQogIGlmIChtX3BKU0NvbnRleHQgJiYgbV9wU0RLRG9jICYmIG1fcFNES0RvYy0+R2V0RW52KCkpDQogICAgbV9wU0RLRG9jLT5HZXRFbnYoKS0+R2V0SlNSdW50aW1lKCktPlJlbGVhc2VDb250ZXh0KG1fcEpTQ29udGV4dCk7DQoNCiAgZGVsZXRlIG1fcFNES0RvYzsNCg0KICBpZiAobV9wUERGRG9jKSB7DQogICAgQ1BERl9QYXJzZXIqIHBQYXJzZXIgPSBtX3BQREZEb2MtPkdldFBhcnNlcigpOw0KICAgIGlmIChwUGFyc2VyKQ0KICAgICAgZGVsZXRlIHBQYXJzZXI7DQogICAgZWxzZQ0KICAgICAgZGVsZXRlIG1fcFBERkRvYzsNCiAgfQ0KICBpZiAobV9wWEZBRG9jKSB7DQogICAgSVhGQV9BcHAqIHBBcHAgPSBtX3BBcHAtPkdldFhGQUFwcCgpOw0KICAgIGlmIChwQXBwKSB7DQogICAgICBJWEZBX0RvY0hhbmRsZXIqIHBEb2NIYW5kbGVyID0gcEFwcC0+R2V0RG9jSGFuZGxlcigpOw0KICAgICAgaWYgKHBEb2NIYW5kbGVyKSB7DQogICAgICAgIENsb3NlWEZBRG9jKHBEb2NIYW5kbGVyKTsNCiAgICAgIH0NCiAgICB9DQogICAgZGVsZXRlIG1fcFhGQURvYzsNCiAgfQ0KfQ0KDQpGWF9CT09MIENQREZYRkFfRG9jdW1lbnQ6OkxvYWRYRkFEb2MoKSB7DQogIGlmICghbV9wUERGRG9jKQ0KICAgIHJldHVybiBGQUxTRTsNCg0KICBtX1hGQVBhZ2VMaXN0LlJlbW92ZUFsbCgpOw0KDQogIElYRkFfQXBwKiBwQXBwID0gbV9wQXBwLT5HZXRYRkFBcHAoKTsNCiAgaWYgKCFwQXBwKQ0KICAgIHJldHVybiBGQUxTRTsNCg0KICBtX3BYRkFEb2MgPSBwQXBwLT5DcmVhdGVEb2ModGhpcywgbV9wUERGRG9jKTsNCiAgaWYgKCFtX3BYRkFEb2MpIHsNCiAgICBTZXRMYXN0RXJyb3IoRlBERl9FUlJfWEZBTE9BRCk7DQogICAgcmV0dXJuIEZBTFNFOw0KICB9DQoNCiAgSVhGQV9Eb2NIYW5kbGVyKiBwRG9jSGFuZGxlciA9IHBBcHAtPkdldERvY0hhbmRsZXIoKTsNCiAgaWYgKCFwRG9jSGFuZGxlcikgew0KICAgIFNldExhc3RFcnJvcihGUERGX0VSUl9YRkFMT0FEKTsNCiAgICByZXR1cm4gRkFMU0U7DQogIH0NCg0KICBwRG9jSGFuZGxlci0+U3RhcnRMb2FkKG1fcFhGQURvYyk7DQogIGludCBpU3RhdHVzID0gcERvY0hhbmRsZXItPkRvTG9hZChtX3BYRkFEb2MsIE5VTEwpOw0KICBpZiAoaVN0YXR1cyAhPSBYRkFfUEFSU0VTVEFUVVNfRG9uZSkgew0KICAgIENsb3NlWEZBRG9jKHBEb2NIYW5kbGVyKTsNCiAgICBTZXRMYXN0RXJyb3IoRlBERl9FUlJfWEZBTE9BRCk7DQogICAgcmV0dXJuIEZBTFNFOw0KICB9DQogIHBEb2NIYW5kbGVyLT5TdG9wTG9hZChtX3BYRkFEb2MpOw0KICBwRG9jSGFuZGxlci0+U2V0SlNFUnVudGltZShtX3BYRkFEb2MsIG1fcEFwcC0+R2V0SlNFUnVudGltZSgpKTsNCg0KICBpZiAocERvY0hhbmRsZXItPkdldERvY1R5cGUobV9wWEZBRG9jKSA9PSBYRkFfRE9DVFlQRV9EeW5hbWljKQ0KICAgIG1faURvY1R5cGUgPSBET0NUWVBFX0RZTkFNSUNfWEZBOw0KICBlbHNlDQogICAgbV9pRG9jVHlwZSA9IERPQ1RZUEVfU1RBVElDX1hGQTsNCg0KICBtX3BYRkFEb2NWaWV3ID0gcERvY0hhbmRsZXItPkNyZWF0ZURvY1ZpZXcobV9wWEZBRG9jLCBYRkFfRE9DVklFV19WaWV3KTsNCiAgaWYgKG1fcFhGQURvY1ZpZXctPlN0YXJ0TGF5b3V0KCkgPCAwKSB7DQogICAgQ2xvc2VYRkFEb2MocERvY0hhbmRsZXIpOw0KICAgIFNldExhc3RFcnJvcihGUERGX0VSUl9YRkFMQVlPVVQpOw0KICAgIHJldHVybiBGQUxTRTsNCiAgfQ0KDQogIG1fcFhGQURvY1ZpZXctPkRvTGF5b3V0KE5VTEwpOw0KICBtX3BYRkFEb2NWaWV3LT5TdG9wTGF5b3V0KCk7DQogIHJldHVybiBUUlVFOw0KfQ0KDQppbnQgQ1BERlhGQV9Eb2N1bWVudDo6R2V0UGFnZUNvdW50KCkgew0KICBpZiAoIW1fcFBERkRvYyAmJiAhbV9wWEZBRG9jKQ0KICAgIHJldHVybiAwOw0KDQogIHN3aXRjaCAobV9pRG9jVHlwZSkgew0KICAgIGNhc2UgRE9DVFlQRV9QREY6DQogICAgY2FzZSBET0NUWVBFX1NUQVRJQ19YRkE6DQogICAgICBpZiAobV9wUERGRG9jKQ0KICAgICAgICByZXR1cm4gbV9wUERGRG9jLT5HZXRQYWdlQ291bnQoKTsNCiAgICBjYXNlIERPQ1RZUEVfRFlOQU1JQ19YRkE6DQogICAgICBpZiAobV9wWEZBRG9jKQ0KICAgICAgICByZXR1cm4gbV9wWEZBRG9jVmlldy0+Q291bnRQYWdlVmlld3MoKTsNCiAgICBkZWZhdWx0Og0KICAgICAgcmV0dXJuIDA7DQogIH0NCg0KICByZXR1cm4gMDsNCn0NCg0KQ1BERlhGQV9QYWdlKiBDUERGWEZBX0RvY3VtZW50OjpHZXRQYWdlKGludCBwYWdlX2luZGV4KSB7DQogIGlmIChwYWdlX2luZGV4IDwgMCkNCiAgICByZXR1cm4gbnVsbHB0cjsNCiAgQ1BERlhGQV9QYWdlKiBwUGFnZSA9IG51bGxwdHI7DQogIGludCBuQ291bnQgPSBtX1hGQVBhZ2VMaXN0LkdldFNpemUoKTsNCiAgaWYgKG5Db3VudCA+IDAgJiYgcGFnZV9pbmRleCA8IG5Db3VudCkgew0KICAgIHBQYWdlID0gbV9YRkFQYWdlTGlzdC5HZXRBdChwYWdlX2luZGV4KTsNCiAgICBpZiAocFBhZ2UpDQogICAgICBwUGFnZS0+QWRkUmVmKCk7DQogIH0gZWxzZSB7DQogICAgbV9YRkFQYWdlTGlzdC5TZXRTaXplKEdldFBhZ2VDb3VudCgpKTsNCiAgfQ0KICBpZiAocFBhZ2UpDQogICAgcmV0dXJuIHBQYWdlOw0KICBwUGFnZSA9IG5ldyBDUERGWEZBX1BhZ2UodGhpcywgcGFnZV9pbmRleCk7DQogIGlmICghcFBhZ2UtPkxvYWRQYWdlKCkpIHsNCiAgICBkZWxldGUgcFBhZ2U7DQogICAgcmV0dXJuIG51bGxwdHI7DQogIH0NCiAgbV9YRkFQYWdlTGlzdC5TZXRBdChwYWdlX2luZGV4LCBwUGFnZSk7DQogIHJldHVybiBwUGFnZTsNCn0NCg0KQ1BERlhGQV9QYWdlKiBDUERGWEZBX0RvY3VtZW50OjpHZXRQYWdlKElYRkFfUGFnZVZpZXcqIHBQYWdlKSB7DQogIGlmICghcFBhZ2UpDQogICAgcmV0dXJuIE5VTEw7DQoNCiAgaWYgKCFtX3BYRkFEb2MpDQogICAgcmV0dXJuIE5VTEw7DQoNCiAgaWYgKG1faURvY1R5cGUgIT0gRE9DVFlQRV9EWU5BTUlDX1hGQSkNCiAgICByZXR1cm4gTlVMTDsNCg0KICBpbnQgblNpemUgPSBtX1hGQVBhZ2VMaXN0LkdldFNpemUoKTsNCiAgZm9yIChpbnQgaSA9IDA7IGkgPCBuU2l6ZTsgaSsrKSB7DQogICAgQ1BERlhGQV9QYWdlKiBwVGVtcFBhZ2UgPSBtX1hGQVBhZ2VMaXN0LkdldEF0KGkpOw0KICAgIGlmICghcFRlbXBQYWdlKQ0KICAgICAgY29udGludWU7DQogICAgaWYgKHBUZW1wUGFnZS0+R2V0WEZBUGFnZVZpZXcoKSAmJiBwVGVtcFBhZ2UtPkdldFhGQVBhZ2VWaWV3KCkgPT0gcFBhZ2UpDQogICAgICByZXR1cm4gcFRlbXBQYWdlOw0KICB9DQoNCiAgcmV0dXJuIE5VTEw7DQp9DQoNCnZvaWQgQ1BERlhGQV9Eb2N1bWVudDo6UmVtb3ZlUGFnZShDUERGWEZBX1BhZ2UqIHBhZ2UpIHsNCiAgbV9YRkFQYWdlTGlzdC5TZXRBdChwYWdlLT5HZXRQYWdlSW5kZXgoKSwgTlVMTCk7DQp9DQoNCkNQREZTREtfRG9jdW1lbnQqIENQREZYRkFfRG9jdW1lbnQ6OkdldFNES0RvY3VtZW50KA0KICAgIENQREZEb2NfRW52aXJvbm1lbnQqIHBGb3JtRmlsbEVudikgew0KICBpZiAoIW1fcFNES0RvYyAmJiBwRm9ybUZpbGxFbnYpDQogICAgbV9wU0RLRG9jID0gbmV3IENQREZTREtfRG9jdW1lbnQodGhpcywgcEZvcm1GaWxsRW52KTsNCiAgcmV0dXJuIG1fcFNES0RvYzsNCn0NCg0Kdm9pZCBDUERGWEZBX0RvY3VtZW50OjpGWFJlY3QyUERGUmVjdChjb25zdCBDRlhfUmVjdEYmIGZ4UmVjdEYsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENQREZfUmVjdCYgcGRmUmVjdCkgew0KICBwZGZSZWN0LmxlZnQgPSBmeFJlY3RGLmxlZnQ7DQogIHBkZlJlY3QudG9wID0gZnhSZWN0Ri5ib3R0b20oKTsNCiAgcGRmUmVjdC5yaWdodCA9IGZ4UmVjdEYucmlnaHQoKTsNCiAgcGRmUmVjdC5ib3R0b20gPSBmeFJlY3RGLnRvcDsNCn0NCg0Kdm9pZCBDUERGWEZBX0RvY3VtZW50OjpTZXRDaGFuZ2VNYXJrKElYRkFfRG9jKiBoRG9jKSB7DQogIGlmIChoRG9jID09IG1fcFhGQURvYyAmJiBtX3BTREtEb2MpIHsNCiAgICBtX3BTREtEb2MtPlNldENoYW5nZU1hcmsoKTsNCiAgfQ0KfQ0KDQpGWF9CT09MIENQREZYRkFfRG9jdW1lbnQ6OkdldENoYW5nZU1hcmsoSVhGQV9Eb2MqIGhEb2MpIHsNCiAgaWYgKGhEb2MgPT0gbV9wWEZBRG9jICYmIG1fcFNES0RvYykNCiAgICByZXR1cm4gbV9wU0RLRG9jLT5HZXRDaGFuZ2VNYXJrKCk7DQogIHJldHVybiBGQUxTRTsNCn0NCg0Kdm9pZCBDUERGWEZBX0RvY3VtZW50OjpJbnZhbGlkYXRlUmVjdChJWEZBX1BhZ2VWaWV3KiBwUGFnZVZpZXcsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENGWF9SZWN0RiYgcnQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZYX0RXT1JEIGR3RmxhZ3MgLyogPSAwICovKSB7DQogIGlmICghbV9wWEZBRG9jIHx8ICFtX3BTREtEb2MpDQogICAgcmV0dXJuOw0KDQogIGlmIChtX2lEb2NUeXBlICE9IERPQ1RZUEVfRFlOQU1JQ19YRkEpDQogICAgcmV0dXJuOw0KDQogIENQREZfUmVjdCByY1BhZ2U7DQogIEZYUmVjdDJQREZSZWN0KHJ0LCByY1BhZ2UpOw0KDQogIENQREZYRkFfUGFnZSogcFBhZ2UgPSBHZXRQYWdlKHBQYWdlVmlldyk7DQoNCiAgaWYgKHBQYWdlID09IE5VTEwpDQogICAgcmV0dXJuOw0KDQogIENQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BTREtEb2MtPkdldEVudigpOw0KICBpZiAoIXBFbnYpDQogICAgcmV0dXJuOw0KDQogIHBFbnYtPkZGSV9JbnZhbGlkYXRlKChGUERGX1BBR0UpcFBhZ2UsIHJjUGFnZS5sZWZ0LCByY1BhZ2UuYm90dG9tLA0KICAgICAgICAgICAgICAgICAgICAgICByY1BhZ2UucmlnaHQsIHJjUGFnZS50b3ApOw0KfQ0KDQp2b2lkIENQREZYRkFfRG9jdW1lbnQ6OkludmFsaWRhdGVSZWN0KElYRkFfV2lkZ2V0KiBoV2lkZ2V0LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGWF9EV09SRCBkd0ZsYWdzIC8qID0gMCAqLykgew0KICBpZiAoIWhXaWRnZXQpDQogICAgcmV0dXJuOw0KDQogIGlmICghbV9wWEZBRG9jIHx8ICFtX3BTREtEb2MgfHwgIW1fcFhGQURvY1ZpZXcpDQogICAgcmV0dXJuOw0KDQogIGlmIChtX2lEb2NUeXBlICE9IERPQ1RZUEVfRFlOQU1JQ19YRkEpDQogICAgcmV0dXJuOw0KDQogIElYRkFfV2lkZ2V0SGFuZGxlciogcFdpZGdldEhhbmRsZXIgPSBtX3BYRkFEb2NWaWV3LT5HZXRXaWRnZXRIYW5kbGVyKCk7DQogIGlmICghcFdpZGdldEhhbmRsZXIpDQogICAgcmV0dXJuOw0KDQogIElYRkFfUGFnZVZpZXcqIHBQYWdlVmlldyA9IHBXaWRnZXRIYW5kbGVyLT5HZXRQYWdlVmlldyhoV2lkZ2V0KTsNCiAgaWYgKCFwUGFnZVZpZXcpDQogICAgcmV0dXJuOw0KDQogIENGWF9SZWN0RiByZWN0Ow0KICBwV2lkZ2V0SGFuZGxlci0+R2V0UmVjdChoV2lkZ2V0LCByZWN0KTsNCiAgSW52YWxpZGF0ZVJlY3QocFBhZ2VWaWV3LCByZWN0LCBkd0ZsYWdzKTsNCn0NCg0Kdm9pZCBDUERGWEZBX0RvY3VtZW50OjpEaXNwbGF5Q2FyZXQoSVhGQV9XaWRnZXQqIGhXaWRnZXQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGWF9CT09MIGJWaXNpYmxlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ0ZYX1JlY3RGKiBwUnRBbmNob3IpIHsNCiAgaWYgKCFoV2lkZ2V0IHx8IHBSdEFuY2hvciA9PSBOVUxMKQ0KICAgIHJldHVybjsNCg0KICBpZiAoIW1fcFhGQURvYyB8fCAhbV9wU0RLRG9jIHx8ICFtX3BYRkFEb2NWaWV3KQ0KICAgIHJldHVybjsNCg0KICBpZiAobV9pRG9jVHlwZSAhPSBET0NUWVBFX0RZTkFNSUNfWEZBKQ0KICAgIHJldHVybjsNCg0KICBJWEZBX1dpZGdldEhhbmRsZXIqIHBXaWRnZXRIYW5kbGVyID0gbV9wWEZBRG9jVmlldy0+R2V0V2lkZ2V0SGFuZGxlcigpOw0KICBpZiAoIXBXaWRnZXRIYW5kbGVyKQ0KICAgIHJldHVybjsNCg0KICBJWEZBX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSBwV2lkZ2V0SGFuZGxlci0+R2V0UGFnZVZpZXcoaFdpZGdldCk7DQogIGlmICghcFBhZ2VWaWV3KQ0KICAgIHJldHVybjsNCg0KICBDUERGWEZBX1BhZ2UqIHBQYWdlID0gR2V0UGFnZShwUGFnZVZpZXcpOw0KDQogIGlmIChwUGFnZSA9PSBOVUxMKQ0KICAgIHJldHVybjsNCg0KICBDUERGX1JlY3QgcmNDYXJldDsNCiAgRlhSZWN0MlBERlJlY3QoKnBSdEFuY2hvciwgcmNDYXJldCk7DQoNCiAgQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IG1fcFNES0RvYy0+R2V0RW52KCk7DQogIGlmICghcEVudikNCiAgICByZXR1cm47DQoNCiAgcEVudi0+RkZJX0Rpc3BsYXlDYXJldCgoRlBERl9QQUdFKXBQYWdlLCBiVmlzaWJsZSwgcmNDYXJldC5sZWZ0LCByY0NhcmV0LnRvcCwNCiAgICAgICAgICAgICAgICAgICAgICAgICByY0NhcmV0LnJpZ2h0LCByY0NhcmV0LmJvdHRvbSk7DQp9DQoNCkZYX0JPT0wgQ1BERlhGQV9Eb2N1bWVudDo6R2V0UG9wdXBQb3MoSVhGQV9XaWRnZXQqIGhXaWRnZXQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZYX0ZMT0FUIGZNaW5Qb3B1cCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlhfRkxPQVQgZk1heFBvcHVwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDRlhfUmVjdEYmIHJ0QW5jaG9yLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDRlhfUmVjdEYmIHJ0UG9wdXApIHsNCiAgaWYgKE5VTEwgPT0gaFdpZGdldCkgew0KICAgIHJldHVybiBGQUxTRTsNCiAgfQ0KICBJWEZBX1BhZ2VWaWV3KiBwWEZBUGFnZVZpZXcgPQ0KICAgICAgbV9wWEZBRG9jVmlldy0+R2V0V2lkZ2V0SGFuZGxlcigpLT5HZXRQYWdlVmlldyhoV2lkZ2V0KTsNCiAgaWYgKE5VTEwgPT0gcFhGQVBhZ2VWaWV3KSB7DQogICAgcmV0dXJuIEZBTFNFOw0KICB9DQogIENQREZYRkFfUGFnZSogcFBhZ2UgPSBHZXRQYWdlKHBYRkFQYWdlVmlldyk7DQogIGlmIChwUGFnZSA9PSBOVUxMKQ0KICAgIHJldHVybiBGQUxTRTsNCg0KICBDWEZBX1dpZGdldEFjYyogcFdpZGdldEFjYyA9DQogICAgICBtX3BYRkFEb2NWaWV3LT5HZXRXaWRnZXRIYW5kbGVyKCktPkdldERhdGFBY2MoaFdpZGdldCk7DQoNCiAgaW50IG5Sb3RhdGUgPSAwOw0KI2lmZGVmIFBERl9FTkFCTEVfWEZBDQogIG5Sb3RhdGUgPSBwV2lkZ2V0QWNjLT5HZXRSb3RhdGUoKTsNCiNlbmRpZg0KDQogIENQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BTREtEb2MtPkdldEVudigpOw0KICBpZiAocEVudiA9PSBOVUxMKQ0KICAgIHJldHVybiBGQUxTRTsNCiAgRlNfUkVDVEYgcGFnZVZpZXdSZWN0Ow0KICBwRW52LT5GRklfR2V0UGFnZVZpZXdSZWN0KHBQYWdlLCBwYWdlVmlld1JlY3QpOw0KDQogIENQREZfUmVjdCByY0FuY2hvcjsNCg0KICByY0FuY2hvci5sZWZ0ID0gcnRBbmNob3IubGVmdDsNCiAgcmNBbmNob3IudG9wID0gcnRBbmNob3IuYm90dG9tKCk7DQogIHJjQW5jaG9yLnJpZ2h0ID0gcnRBbmNob3IucmlnaHQoKTsNCiAgcmNBbmNob3IuYm90dG9tID0gcnRBbmNob3IudG9wOw0KDQogIGludCB0MSwgdDIsIHQ7DQogIEZYX0RXT1JEIGR3UG9zOw0KICBGWF9GTE9BVCBmUG91cEhlaWdodDsNCiAgc3dpdGNoIChuUm90YXRlKSB7DQogICAgY2FzZSA5MDogew0KICAgICAgdDEgPSAoaW50KShwYWdlVmlld1JlY3QucmlnaHQgLSByY0FuY2hvci5yaWdodCk7DQogICAgICB0MiA9IChpbnQpKHJjQW5jaG9yLmxlZnQgLSBwYWdlVmlld1JlY3QubGVmdCk7DQogICAgICBpZiAocmNBbmNob3IuYm90dG9tIDwgcGFnZVZpZXdSZWN0LmJvdHRvbSkgew0KICAgICAgICBydFBvcHVwLmxlZnQgKz0gcmNBbmNob3IuYm90dG9tIC0gcGFnZVZpZXdSZWN0LmJvdHRvbTsNCiAgICAgIH0NCg0KICAgICAgYnJlYWs7DQogICAgfQ0KDQogICAgY2FzZSAxODA6IHsNCiAgICAgIHQyID0gKGludCkocGFnZVZpZXdSZWN0LnRvcCAtIHJjQW5jaG9yLnRvcCk7DQogICAgICB0MSA9IChpbnQpKHJjQW5jaG9yLmJvdHRvbSAtIHBhZ2VWaWV3UmVjdC5ib3R0b20pOw0KICAgICAgaWYgKHJjQW5jaG9yLmxlZnQgPCBwYWdlVmlld1JlY3QubGVmdCkgew0KICAgICAgICBydFBvcHVwLmxlZnQgKz0gcmNBbmNob3IubGVmdCAtIHBhZ2VWaWV3UmVjdC5sZWZ0Ow0KICAgICAgfQ0KICAgICAgYnJlYWs7DQogICAgfQ0KICAgIGNhc2UgMjcwOiB7DQogICAgICB0MSA9IChpbnQpKHJjQW5jaG9yLmxlZnQgLSBwYWdlVmlld1JlY3QubGVmdCk7DQogICAgICB0MiA9IChpbnQpKHBhZ2VWaWV3UmVjdC5yaWdodCAtIHJjQW5jaG9yLnJpZ2h0KTsNCg0KICAgICAgaWYgKHJjQW5jaG9yLnRvcCA+IHBhZ2VWaWV3UmVjdC50b3ApIHsNCiAgICAgICAgcnRQb3B1cC5sZWZ0IC09IHJjQW5jaG9yLnRvcCAtIHBhZ2VWaWV3UmVjdC50b3A7DQogICAgICB9DQogICAgICBicmVhazsNCiAgICB9DQogICAgY2FzZSAwOg0KICAgIGRlZmF1bHQ6IHsNCiAgICAgIHQxID0gKGludCkocGFnZVZpZXdSZWN0LnRvcCAtIHJjQW5jaG9yLnRvcCk7DQogICAgICB0MiA9IChpbnQpKHJjQW5jaG9yLmJvdHRvbSAtIHBhZ2VWaWV3UmVjdC5ib3R0b20pOw0KICAgICAgaWYgKHJjQW5jaG9yLnJpZ2h0ID4gcGFnZVZpZXdSZWN0LnJpZ2h0KSB7DQogICAgICAgIHJ0UG9wdXAubGVmdCAtPSByY0FuY2hvci5yaWdodCAtIHBhZ2VWaWV3UmVjdC5yaWdodDsNCiAgICAgIH0NCiAgICAgIGJyZWFrOw0KICAgIH0NCiAgfQ0KDQogIGlmICh0MSA8PSAwICYmIHQyIDw9IDApIHsNCiAgICByZXR1cm4gRkFMU0U7DQogIH0NCiAgaWYgKHQxIDw9IDApIHsNCiAgICB0ID0gdDI7DQogICAgZHdQb3MgPSAxOw0KICB9IGVsc2UgaWYgKHQyIDw9IDApIHsNCiAgICB0ID0gdDE7DQogICAgZHdQb3MgPSAwOw0KICB9IGVsc2UgaWYgKHQxID4gdDIpIHsNCiAgICB0ID0gdDE7DQogICAgZHdQb3MgPSAwOw0KICB9IGVsc2Ugew0KICAgIHQgPSB0MjsNCiAgICBkd1BvcyA9IDE7DQogIH0NCiAgaWYgKHQgPCBmTWluUG9wdXApIHsNCiAgICBmUG91cEhlaWdodCA9IGZNaW5Qb3B1cDsNCiAgfSBlbHNlIGlmICh0ID4gZk1heFBvcHVwKSB7DQogICAgZlBvdXBIZWlnaHQgPSBmTWF4UG9wdXA7DQogIH0gZWxzZSB7DQogICAgZlBvdXBIZWlnaHQgPSAoRlhfRkxPQVQpdDsNCiAgfQ0KDQogIHN3aXRjaCAoblJvdGF0ZSkgew0KICAgIGNhc2UgMDoNCiAgICBjYXNlIDE4MDogew0KICAgICAgaWYgKGR3UG9zID09IDApIHsNCiAgICAgICAgcnRQb3B1cC50b3AgPSBydEFuY2hvci5oZWlnaHQ7DQogICAgICAgIHJ0UG9wdXAuaGVpZ2h0ID0gZlBvdXBIZWlnaHQ7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBydFBvcHVwLnRvcCA9IC1mUG91cEhlaWdodDsNCiAgICAgICAgcnRQb3B1cC5oZWlnaHQgPSBmUG91cEhlaWdodDsNCiAgICAgIH0NCiAgICAgIGJyZWFrOw0KICAgIH0NCiAgICBjYXNlIDkwOg0KICAgIGNhc2UgMjcwOiB7DQogICAgICBpZiAoZHdQb3MgPT0gMCkgew0KICAgICAgICBydFBvcHVwLnRvcCA9IHJ0QW5jaG9yLndpZHRoOw0KICAgICAgICBydFBvcHVwLmhlaWdodCA9IGZQb3VwSGVpZ2h0Ow0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgcnRQb3B1cC50b3AgPSAtZlBvdXBIZWlnaHQ7DQogICAgICAgIHJ0UG9wdXAuaGVpZ2h0ID0gZlBvdXBIZWlnaHQ7DQogICAgICB9DQogICAgICBicmVhazsNCiAgICB9DQogICAgZGVmYXVsdDoNCiAgICAgIGJyZWFrOw0KICB9DQoNCiAgcmV0dXJuIFRSVUU7DQp9DQoNCkZYX0JPT0wgQ1BERlhGQV9Eb2N1bWVudDo6UG9wdXBNZW51KElYRkFfV2lkZ2V0KiBoV2lkZ2V0LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0ZYX1BvaW50RiBwdFBvcHVwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ0ZYX1JlY3RGKiBwUmVjdEV4Y2x1ZGUpIHsNCiAgaWYgKE5VTEwgPT0gaFdpZGdldCkgew0KICAgIHJldHVybiBGQUxTRTsNCiAgfQ0KICBJWEZBX1BhZ2VWaWV3KiBwWEZBUGFnZVZpZXcgPQ0KICAgICAgbV9wWEZBRG9jVmlldy0+R2V0V2lkZ2V0SGFuZGxlcigpLT5HZXRQYWdlVmlldyhoV2lkZ2V0KTsNCiAgaWYgKHBYRkFQYWdlVmlldyA9PSBOVUxMKQ0KICAgIHJldHVybiBGQUxTRTsNCiAgQ1BERlhGQV9QYWdlKiBwUGFnZSA9IEdldFBhZ2UocFhGQVBhZ2VWaWV3KTsNCg0KICBpZiAocFBhZ2UgPT0gTlVMTCkNCiAgICByZXR1cm4gRkFMU0U7DQoNCiAgaW50IG1lbnVGbGFnID0gMDsNCg0KICBJWEZBX01lbnVIYW5kbGVyKiBwWEZBTWVudUhhbmRlciA9IG1fcEFwcC0+R2V0WEZBQXBwKCktPkdldE1lbnVIYW5kbGVyKCk7DQogIGlmIChwWEZBTWVudUhhbmRlci0+Q2FuVW5kbyhoV2lkZ2V0KSkNCiAgICBtZW51RmxhZyB8PSBGWEZBX01FTVVfVU5ETzsNCiAgaWYgKHBYRkFNZW51SGFuZGVyLT5DYW5SZWRvKGhXaWRnZXQpKQ0KICAgIG1lbnVGbGFnIHw9IEZYRkFfTUVNVV9SRURPOw0KICBpZiAocFhGQU1lbnVIYW5kZXItPkNhblBhc3RlKGhXaWRnZXQpKQ0KICAgIG1lbnVGbGFnIHw9IEZYRkFfTUVNVV9QQVNURTsNCiAgaWYgKHBYRkFNZW51SGFuZGVyLT5DYW5Db3B5KGhXaWRnZXQpKQ0KICAgIG1lbnVGbGFnIHw9IEZYRkFfTUVNVV9DT1BZOw0KICBpZiAocFhGQU1lbnVIYW5kZXItPkNhbkN1dChoV2lkZ2V0KSkNCiAgICBtZW51RmxhZyB8PSBGWEZBX01FTVVfQ1VUOw0KICBpZiAocFhGQU1lbnVIYW5kZXItPkNhblNlbGVjdEFsbChoV2lkZ2V0KSkNCiAgICBtZW51RmxhZyB8PSBGWEZBX01FTVVfU0VMRUNUQUxMOw0KDQogIENQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BTREtEb2MtPkdldEVudigpOw0KICBpZiAocEVudiA9PSBOVUxMKQ0KICAgIHJldHVybiBGQUxTRTsNCg0KICByZXR1cm4gcEVudi0+RkZJX1BvcHVwTWVudShwUGFnZSwgaFdpZGdldCwgbWVudUZsYWcsIHB0UG9wdXAsIE5VTEwpOw0KfQ0KDQp2b2lkIENQREZYRkFfRG9jdW1lbnQ6OlBhZ2VWaWV3RXZlbnQoSVhGQV9QYWdlVmlldyogcFBhZ2VWaWV3LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZYX0RXT1JEIGR3RmxhZ3MpIHsNCiAgaWYgKCFwUGFnZVZpZXcgfHwgKGR3RmxhZ3MgIT0gWEZBX1BBR0VWSUVXRVZFTlRfUG9zdEFkZGVkICYmDQogICAgICAgICAgICAgICAgICAgICBkd0ZsYWdzICE9IFhGQV9QQUdFVklFV0VWRU5UX1Bvc3RSZW1vdmVkKSkgew0KICAgIHJldHVybjsNCiAgfQ0KICBDUERGWEZBX1BhZ2UqIHBQYWdlID0gbnVsbHB0cjsNCiAgaWYgKGR3RmxhZ3MgPT0gWEZBX1BBR0VWSUVXRVZFTlRfUG9zdEFkZGVkKSB7DQogICAgcFBhZ2UgPSBHZXRQYWdlKHBQYWdlVmlldy0+R2V0UGFnZVZpZXdJbmRleCgpKTsNCiAgICBpZiAocFBhZ2UpDQogICAgICBwUGFnZS0+U2V0WEZBUGFnZVZpZXcocFBhZ2VWaWV3KTsNCiAgICByZXR1cm47DQogIH0NCiAgcFBhZ2UgPSBHZXRQYWdlKHBQYWdlVmlldyk7DQogIGlmICghcFBhZ2UpDQogICAgcmV0dXJuOw0KICBwUGFnZS0+U2V0WEZBUGFnZVZpZXcobnVsbHB0cik7DQogIG1fcFNES0RvYy0+R2V0UGFnZVZpZXcocFBhZ2UpLT5DbGVhckZYQW5ub3RzKCk7DQp9DQoNCnZvaWQgQ1BERlhGQV9Eb2N1bWVudDo6V2lkZ2V0RXZlbnQoSVhGQV9XaWRnZXQqIGhXaWRnZXQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENYRkFfV2lkZ2V0QWNjKiBwV2lkZ2V0RGF0YSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlhfRFdPUkQgZHdFdmVudCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCogcFBhcmFtLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkKiBwQWRkaXRpb25hbCkgew0KICBpZiAobV9pRG9jVHlwZSAhPSBET0NUWVBFX0RZTkFNSUNfWEZBIHx8ICFoV2lkZ2V0KQ0KICAgIHJldHVybjsNCg0KICBDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wU0RLRG9jLT5HZXRFbnYoKTsNCiAgaWYgKCFwRW52KQ0KICAgIHJldHVybjsNCg0KICBJWEZBX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPQ0KICAgICAgbV9wWEZBRG9jVmlldy0+R2V0V2lkZ2V0SGFuZGxlcigpLT5HZXRQYWdlVmlldyhoV2lkZ2V0KTsNCiAgaWYgKHBQYWdlVmlldyA9PSBOVUxMKQ0KICAgIHJldHVybjsNCg0KICBDUERGWEZBX1BhZ2UqIHBYRkFQYWdlID0gR2V0UGFnZShwUGFnZVZpZXcpOw0KICBpZiAocFhGQVBhZ2UgPT0gTlVMTCkNCiAgICByZXR1cm47DQoNCiAgQ1BERlNES19QYWdlVmlldyogcFNka1BhZ2VWaWV3ID0gbV9wU0RLRG9jLT5HZXRQYWdlVmlldyhwWEZBUGFnZSk7DQogIGlmIChkd0V2ZW50ID09IFhGQV9XSURHRVRFVkVOVF9Qb3N0QWRkZWQpIHsNCiAgICBwU2RrUGFnZVZpZXctPkFkZEFubm90KGhXaWRnZXQpOw0KDQogIH0gZWxzZSBpZiAoZHdFdmVudCA9PSBYRkFfV0lER0VURVZFTlRfUHJlUmVtb3ZlZCkgew0KICAgIENQREZTREtfQW5ub3QqIHBBbm5vdCA9IHBTZGtQYWdlVmlldy0+R2V0QW5ub3RCeVhGQVdpZGdldChoV2lkZ2V0KTsNCiAgICBpZiAocEFubm90KSB7DQogICAgICBwU2RrUGFnZVZpZXctPkRlbGV0ZUFubm90KHBBbm5vdCk7DQogICAgfQ0KICB9DQp9DQoNCmludDMyX3QgQ1BERlhGQV9Eb2N1bWVudDo6Q291bnRQYWdlcyhJWEZBX0RvYyogaERvYykgew0KICBpZiAoaERvYyA9PSBtX3BYRkFEb2MgJiYgbV9wU0RLRG9jKSB7DQogICAgcmV0dXJuIEdldFBhZ2VDb3VudCgpOw0KICB9DQogIHJldHVybiAwOw0KfQ0KaW50MzJfdCBDUERGWEZBX0RvY3VtZW50OjpHZXRDdXJyZW50UGFnZShJWEZBX0RvYyogaERvYykgew0KICBpZiAoaERvYyAhPSBtX3BYRkFEb2MgfHwgIW1fcFNES0RvYykNCiAgICByZXR1cm4gLTE7DQogIGlmIChtX2lEb2NUeXBlICE9IERPQ1RZUEVfRFlOQU1JQ19YRkEpDQogICAgcmV0dXJuIC0xOw0KDQogIENQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BTREtEb2MtPkdldEVudigpOw0KICBpZiAocEVudiA9PSBOVUxMKQ0KICAgIHJldHVybiAtMTsNCg0KICByZXR1cm4gcEVudi0+RkZJX0dldEN1cnJlbnRQYWdlSW5kZXgodGhpcyk7DQp9DQp2b2lkIENQREZYRkFfRG9jdW1lbnQ6OlNldEN1cnJlbnRQYWdlKElYRkFfRG9jKiBoRG9jLCBpbnQzMl90IGlDdXJQYWdlKSB7DQogIGlmIChoRG9jICE9IG1fcFhGQURvYyB8fCAhbV9wU0RLRG9jKQ0KICAgIHJldHVybjsNCiAgaWYgKG1faURvY1R5cGUgIT0gRE9DVFlQRV9EWU5BTUlDX1hGQSkNCiAgICByZXR1cm47DQoNCiAgQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IG1fcFNES0RvYy0+R2V0RW52KCk7DQogIGlmIChwRW52ID09IE5VTEwpDQogICAgcmV0dXJuOw0KDQogIHBFbnYtPkZGSV9TZXRDdXJyZW50UGFnZSh0aGlzLCBpQ3VyUGFnZSk7DQp9DQpGWF9CT09MIENQREZYRkFfRG9jdW1lbnQ6OklzQ2FsY3VsYXRpb25zRW5hYmxlZChJWEZBX0RvYyogaERvYykgew0KICBpZiAoaERvYyAhPSBtX3BYRkFEb2MgfHwgIW1fcFNES0RvYykNCiAgICByZXR1cm4gRkFMU0U7DQogIGlmIChtX3BTREtEb2MtPkdldEludGVyRm9ybSgpKQ0KICAgIHJldHVybiBtX3BTREtEb2MtPkdldEludGVyRm9ybSgpLT5Jc1hmYUNhbGN1bGF0ZUVuYWJsZWQoKTsNCg0KICByZXR1cm4gRkFMU0U7DQp9DQp2b2lkIENQREZYRkFfRG9jdW1lbnQ6OlNldENhbGN1bGF0aW9uc0VuYWJsZWQoSVhGQV9Eb2MqIGhEb2MsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlhfQk9PTCBiRW5hYmxlZCkgew0KICBpZiAoaERvYyAhPSBtX3BYRkFEb2MgfHwgIW1fcFNES0RvYykNCiAgICByZXR1cm47DQogIGlmIChtX3BTREtEb2MtPkdldEludGVyRm9ybSgpKQ0KICAgIG1fcFNES0RvYy0+R2V0SW50ZXJGb3JtKCktPlhmYUVuYWJsZUNhbGN1bGF0ZShiRW5hYmxlZCk7DQp9DQoNCnZvaWQgQ1BERlhGQV9Eb2N1bWVudDo6R2V0VGl0bGUoSVhGQV9Eb2MqIGhEb2MsIENGWF9XaWRlU3RyaW5nJiB3c1RpdGxlKSB7DQogIGlmIChoRG9jICE9IG1fcFhGQURvYykNCiAgICByZXR1cm47DQogIGlmIChtX3BQREZEb2MgPT0gTlVMTCkNCiAgICByZXR1cm47DQogIENQREZfRGljdGlvbmFyeSogcEluZm9EaWN0ID0gbV9wUERGRG9jLT5HZXRJbmZvKCk7DQoNCiAgaWYgKHBJbmZvRGljdCA9PSBOVUxMKQ0KICAgIHJldHVybjsNCg0KICBDRlhfQnl0ZVN0cmluZyBjc1RpdGxlID0gcEluZm9EaWN0LT5HZXRTdHJpbmcoIlRpdGxlIik7DQogIHdzVGl0bGUgPSB3c1RpdGxlLkZyb21Mb2NhbChjc1RpdGxlLkdldEJ1ZmZlcihjc1RpdGxlLkdldExlbmd0aCgpKSk7DQogIGNzVGl0bGUuUmVsZWFzZUJ1ZmZlcihjc1RpdGxlLkdldExlbmd0aCgpKTsNCn0NCnZvaWQgQ1BERlhGQV9Eb2N1bWVudDo6U2V0VGl0bGUoSVhGQV9Eb2MqIGhEb2MsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENGWF9XaWRlU3RyaW5nQyYgd3NUaXRsZSkgew0KICBpZiAoaERvYyAhPSBtX3BYRkFEb2MpDQogICAgcmV0dXJuOw0KICBpZiAobV9wUERGRG9jID09IE5VTEwpDQogICAgcmV0dXJuOw0KICBDUERGX0RpY3Rpb25hcnkqIHBJbmZvRGljdCA9IG1fcFBERkRvYy0+R2V0SW5mbygpOw0KDQogIGlmIChwSW5mb0RpY3QgPT0gTlVMTCkNCiAgICByZXR1cm47DQogIHBJbmZvRGljdC0+U2V0QXQoIlRpdGxlIiwgbmV3IENQREZfU3RyaW5nKHdzVGl0bGUpKTsNCn0NCnZvaWQgQ1BERlhGQV9Eb2N1bWVudDo6RXhwb3J0RGF0YShJWEZBX0RvYyogaERvYywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDRlhfV2lkZVN0cmluZ0MmIHdzRmlsZVBhdGgsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlhfQk9PTCBiWERQKSB7DQogIGlmIChoRG9jICE9IG1fcFhGQURvYykNCiAgICByZXR1cm47DQogIGlmIChtX2lEb2NUeXBlICE9IERPQ1RZUEVfRFlOQU1JQ19YRkEgJiYgbV9pRG9jVHlwZSAhPSBET0NUWVBFX1NUQVRJQ19YRkEpDQogICAgcmV0dXJuOw0KICBDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wU0RLRG9jLT5HZXRFbnYoKTsNCiAgaWYgKHBFbnYgPT0gTlVMTCkNCiAgICByZXR1cm47DQogIGludCBmaWxlVHlwZSA9IGJYRFAgPyBGWEZBX1NBVkVBU19YRFAgOiBGWEZBX1NBVkVBU19YTUw7DQogIENGWF9CeXRlU3RyaW5nIGJzID0gQ0ZYX1dpZGVTdHJpbmcod3NGaWxlUGF0aCkuVVRGMTZMRV9FbmNvZGUoKTsNCg0KICBpZiAod3NGaWxlUGF0aC5Jc0VtcHR5KCkpIHsNCiAgICBpZiAoIXBFbnYtPkdldEZvcm1GaWxsSW5mbygpIHx8DQogICAgICAgIHBFbnYtPkdldEZvcm1GaWxsSW5mbygpLT5tX3BKc1BsYXRmb3JtID09IE5VTEwpDQogICAgICByZXR1cm47DQogICAgQ0ZYX1dpZGVTdHJpbmcgZmlsZXBhdGggPSBwRW52LT5KU19maWVsZEJyb3dzZSgpOw0KICAgIGJzID0gZmlsZXBhdGguVVRGMTZMRV9FbmNvZGUoKTsNCiAgfQ0KICBpbnQgbGVuID0gYnMuR2V0TGVuZ3RoKCkgLyBzaXplb2YodW5zaWduZWQgc2hvcnQpOw0KICBGUERGX0ZJTEVIQU5ETEVSKiBwRmlsZUhhbmRsZXIgPSBwRW52LT5GRklfT3BlbkZpbGUoDQogICAgICBiWERQID8gRlhGQV9TQVZFQVNfWERQIDogRlhGQV9TQVZFQVNfWE1MLA0KICAgICAgKEZQREZfV0lERVNUUklORylicy5HZXRCdWZmZXIobGVuICogc2l6ZW9mKHVuc2lnbmVkIHNob3J0KSksICJ3YiIpOw0KICBicy5SZWxlYXNlQnVmZmVyKGxlbiAqIHNpemVvZih1bnNpZ25lZCBzaG9ydCkpOw0KDQogIGlmIChwRmlsZUhhbmRsZXIgPT0gTlVMTCkNCiAgICByZXR1cm47DQoNCiAgQ0ZQREZfRmlsZVN0cmVhbSBmaWxlV3JpdGUocEZpbGVIYW5kbGVyKTsNCg0KICBJWEZBX0RvY0hhbmRsZXIqIHBYRkFEb2NIYW5kZXIgPSBtX3BBcHAtPkdldFhGQUFwcCgpLT5HZXREb2NIYW5kbGVyKCk7DQogIENGWF9CeXRlU3RyaW5nIGNvbnRlbnQ7DQogIGlmIChmaWxlVHlwZSA9PSBGWEZBX1NBVkVBU19YTUwpIHsNCiAgICBjb250ZW50ID0gIjw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIlVURi04XCI/PlxyXG4iOw0KICAgIGZpbGVXcml0ZS5Xcml0ZUJsb2NrKChjb25zdCBGWF9DSEFSKiljb250ZW50LCBmaWxlV3JpdGUuR2V0U2l6ZSgpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQuR2V0TGVuZ3RoKCkpOw0KICAgIENGWF9XaWRlU3RyaW5nQyBkYXRhKEwiZGF0YSIpOw0KICAgIGlmIChwWEZBRG9jSGFuZGVyLT5TYXZlUGFja2FnZShtX3BYRkFEb2NWaWV3LT5HZXREb2MoKSwgZGF0YSwgJmZpbGVXcml0ZSkpIHsNCiAgICAgIC8vIFRPRE86IE1heWJlIHJlcG9ydCBlcnJvci4NCiAgICB9DQogIH0gZWxzZSBpZiAoZmlsZVR5cGUgPT0gRlhGQV9TQVZFQVNfWERQKSB7DQogICAgaWYgKG1fcFBERkRvYyA9PSBOVUxMKQ0KICAgICAgcmV0dXJuOw0KICAgIENQREZfRGljdGlvbmFyeSogcFJvb3QgPSBtX3BQREZEb2MtPkdldFJvb3QoKTsNCiAgICBpZiAocFJvb3QgPT0gTlVMTCkNCiAgICAgIHJldHVybjsNCiAgICBDUERGX0RpY3Rpb25hcnkqIHBBY3JvRm9ybSA9IHBSb290LT5HZXREaWN0KCJBY3JvRm9ybSIpOw0KICAgIGlmIChOVUxMID09IHBBY3JvRm9ybSkNCiAgICAgIHJldHVybjsNCiAgICBDUERGX09iamVjdCogcFhGQSA9IHBBY3JvRm9ybS0+R2V0RWxlbWVudCgiWEZBIik7DQogICAgaWYgKHBYRkEgPT0gTlVMTCkNCiAgICAgIHJldHVybjsNCiAgICBpZiAocFhGQS0+R2V0VHlwZSgpICE9IFBERk9CSl9BUlJBWSkNCiAgICAgIHJldHVybjsNCiAgICBDUERGX0FycmF5KiBwQXJyYXkgPSBwWEZBLT5HZXRBcnJheSgpOw0KICAgIGlmIChOVUxMID09IHBBcnJheSkNCiAgICAgIHJldHVybjsNCiAgICBpbnQgc2l6ZSA9IHBBcnJheS0+R2V0Q291bnQoKTsNCiAgICBmb3IgKGludCBpID0gMTsgaSA8IHNpemU7IGkgKz0gMikgew0KICAgICAgQ1BERl9PYmplY3QqIHBQREZPYmogPSBwQXJyYXktPkdldEVsZW1lbnQoaSk7DQogICAgICBDUERGX09iamVjdCogcFByZVBERk9iaiA9IHBBcnJheS0+R2V0RWxlbWVudChpIC0gMSk7DQogICAgICBpZiAocFByZVBERk9iai0+R2V0VHlwZSgpICE9IFBERk9CSl9TVFJJTkcpDQogICAgICAgIGNvbnRpbnVlOw0KICAgICAgaWYgKHBQREZPYmotPkdldFR5cGUoKSAhPSBQREZPQkpfUkVGRVJFTkNFKQ0KICAgICAgICBjb250aW51ZTsNCiAgICAgIENQREZfT2JqZWN0KiBwRGlyZWN0T2JqID0gcFBERk9iai0+R2V0RGlyZWN0KCk7DQogICAgICBpZiAocERpcmVjdE9iai0+R2V0VHlwZSgpICE9IFBERk9CSl9TVFJFQU0pDQogICAgICAgIGNvbnRpbnVlOw0KICAgICAgaWYgKHBQcmVQREZPYmotPkdldFN0cmluZygpID09ICJmb3JtIikgew0KICAgICAgICBDRlhfV2lkZVN0cmluZ0MgZm9ybShMImZvcm0iKTsNCiAgICAgICAgcFhGQURvY0hhbmRlci0+U2F2ZVBhY2thZ2UobV9wWEZBRG9jVmlldy0+R2V0RG9jKCksIGZvcm0sICZmaWxlV3JpdGUpOw0KICAgICAgfSBlbHNlIGlmIChwUHJlUERGT2JqLT5HZXRTdHJpbmcoKSA9PSAiZGF0YXNldHMiKSB7DQogICAgICAgIENGWF9XaWRlU3RyaW5nQyBkYXRhc2V0cyhMImRhdGFzZXRzIik7DQogICAgICAgIHBYRkFEb2NIYW5kZXItPlNhdmVQYWNrYWdlKG1fcFhGQURvY1ZpZXctPkdldERvYygpLCBkYXRhc2V0cywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmZpbGVXcml0ZSk7DQogICAgICB9IGVsc2Ugew0KICAgICAgICBpZiAoaSA9PSBzaXplIC0gMSkgew0KICAgICAgICAgIENGWF9XaWRlU3RyaW5nIHdQYXRoID0gQ0ZYX1dpZGVTdHJpbmc6OkZyb21VVEYxNkxFKA0KICAgICAgICAgICAgICAodW5zaWduZWQgc2hvcnQqKShjb25zdCBGWF9DSEFSKilicywNCiAgICAgICAgICAgICAgYnMuR2V0TGVuZ3RoKCkgLyBzaXplb2YodW5zaWduZWQgc2hvcnQpKTsNCiAgICAgICAgICBDRlhfQnl0ZVN0cmluZyBiUGF0aCA9IHdQYXRoLlVURjhFbmNvZGUoKTsNCiAgICAgICAgICBDRlhfQnl0ZVN0cmluZyBzekZvcm1hdCA9DQogICAgICAgICAgICAgICJcbjxwZGYgaHJlZj1cIiVzXCIgeG1sbnM9XCJodHRwOi8vbnMuYWRvYmUuY29tL3hkcC9wZGYvXCIvPiI7DQogICAgICAgICAgY29udGVudC5Gb3JtYXQoc3pGb3JtYXQsIChjaGFyKikoY29uc3QgRlhfQ0hBUiopYlBhdGgpOw0KICAgICAgICAgIGZpbGVXcml0ZS5Xcml0ZUJsb2NrKChjb25zdCBGWF9DSEFSKiljb250ZW50LCBmaWxlV3JpdGUuR2V0U2l6ZSgpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQuR2V0TGVuZ3RoKCkpOw0KICAgICAgICB9DQoNCiAgICAgICAgQ1BERl9TdHJlYW0qIHBTdHJlYW0gPSAoQ1BERl9TdHJlYW0qKXBEaXJlY3RPYmo7DQogICAgICAgIENQREZfU3RyZWFtQWNjKiBwQWNjID0gbmV3IENQREZfU3RyZWFtQWNjOw0KICAgICAgICBwQWNjLT5Mb2FkQWxsRGF0YShwU3RyZWFtKTsNCiAgICAgICAgZmlsZVdyaXRlLldyaXRlQmxvY2socEFjYy0+R2V0RGF0YSgpLCBmaWxlV3JpdGUuR2V0U2l6ZSgpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwQWNjLT5HZXRTaXplKCkpOw0KICAgICAgICBkZWxldGUgcEFjYzsNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgaWYgKCFmaWxlV3JpdGUuRmx1c2goKSkgew0KICAgIC8vIFRPRE86IFJlcG9ydCBlcnJvci4NCiAgfQ0KfQ0Kdm9pZCBDUERGWEZBX0RvY3VtZW50OjpJbXBvcnREYXRhKElYRkFfRG9jKiBoRG9jLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENGWF9XaWRlU3RyaW5nQyYgd3NGaWxlUGF0aCkgew0KICAvLyBUT0RPLi4uDQp9DQoNCnZvaWQgQ1BERlhGQV9Eb2N1bWVudDo6R290b1VSTChJWEZBX0RvYyogaERvYywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDRlhfV2lkZVN0cmluZ0MmIGJzVVJMLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZYX0JPT0wgYkFwcGVuZCkgew0KICBpZiAoaERvYyAhPSBtX3BYRkFEb2MpDQogICAgcmV0dXJuOw0KDQogIGlmIChtX2lEb2NUeXBlICE9IERPQ1RZUEVfRFlOQU1JQ19YRkEpDQogICAgcmV0dXJuOw0KDQogIENQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BTREtEb2MtPkdldEVudigpOw0KICBpZiAocEVudiA9PSBOVUxMKQ0KICAgIHJldHVybjsNCg0KICBDRlhfV2lkZVN0cmluZ0Mgc3RyKGJzVVJMLkdldFB0cigpKTsNCg0KICBwRW52LT5GRklfR290b1VSTCh0aGlzLCBzdHIsIGJBcHBlbmQpOw0KfQ0KDQpGWF9CT09MIENQREZYRkFfRG9jdW1lbnQ6OklzVmFsaWRhdGlvbnNFbmFibGVkKElYRkFfRG9jKiBoRG9jKSB7DQogIGlmIChoRG9jICE9IG1fcFhGQURvYyB8fCAhbV9wU0RLRG9jKQ0KICAgIHJldHVybiBGQUxTRTsNCiAgaWYgKG1fcFNES0RvYy0+R2V0SW50ZXJGb3JtKCkpDQogICAgcmV0dXJuIG1fcFNES0RvYy0+R2V0SW50ZXJGb3JtKCktPklzWGZhVmFsaWRhdGlvbnNFbmFibGVkKCk7DQoNCiAgcmV0dXJuIFRSVUU7DQp9DQp2b2lkIENQREZYRkFfRG9jdW1lbnQ6OlNldFZhbGlkYXRpb25zRW5hYmxlZChJWEZBX0RvYyogaERvYywgRlhfQk9PTCBiRW5hYmxlZCkgew0KICBpZiAoaERvYyAhPSBtX3BYRkFEb2MgfHwgIW1fcFNES0RvYykNCiAgICByZXR1cm47DQogIGlmIChtX3BTREtEb2MtPkdldEludGVyRm9ybSgpKQ0KICAgIG1fcFNES0RvYy0+R2V0SW50ZXJGb3JtKCktPlhmYVNldFZhbGlkYXRpb25zRW5hYmxlZChiRW5hYmxlZCk7DQp9DQp2b2lkIENQREZYRkFfRG9jdW1lbnQ6OlNldEZvY3VzV2lkZ2V0KElYRkFfRG9jKiBoRG9jLCBJWEZBX1dpZGdldCogaFdpZGdldCkgew0KICBpZiAoaERvYyAhPSBtX3BYRkFEb2MpDQogICAgcmV0dXJuOw0KDQogIGlmIChOVUxMID09IGhXaWRnZXQpIHsNCiAgICBtX3BTREtEb2MtPlNldEZvY3VzQW5ub3QoTlVMTCk7DQogICAgcmV0dXJuOw0KICB9DQoNCiAgaW50IHBhZ2VWaWV3Q291bnQgPSBtX3BTREtEb2MtPkdldFBhZ2VWaWV3Q291bnQoKTsNCiAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWdlVmlld0NvdW50OyBpKyspIHsNCiAgICBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSBtX3BTREtEb2MtPkdldFBhZ2VWaWV3KGkpOw0KICAgIGlmIChwUGFnZVZpZXcgPT0gTlVMTCkNCiAgICAgIGNvbnRpbnVlOw0KICAgIENQREZTREtfQW5ub3QqIHBBbm5vdCA9IHBQYWdlVmlldy0+R2V0QW5ub3RCeVhGQVdpZGdldChoV2lkZ2V0KTsNCiAgICBpZiAocEFubm90KSB7DQogICAgICBtX3BTREtEb2MtPlNldEZvY3VzQW5ub3QocEFubm90KTsNCiAgICAgIGJyZWFrOw0KICAgIH0NCiAgfQ0KfQ0Kdm9pZCBDUERGWEZBX0RvY3VtZW50OjpQcmludChJWEZBX0RvYyogaERvYywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBuU3RhcnRQYWdlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IG5FbmRQYWdlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGWF9EV09SRCBkd09wdGlvbnMpIHsNCiAgaWYgKGhEb2MgIT0gbV9wWEZBRG9jKQ0KICAgIHJldHVybjsNCg0KICBDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wU0RLRG9jLT5HZXRFbnYoKTsNCiAgaWYgKHBFbnYgPT0gTlVMTCkNCiAgICByZXR1cm47DQoNCiAgaWYgKCFwRW52LT5HZXRGb3JtRmlsbEluZm8oKSB8fA0KICAgICAgcEVudi0+R2V0Rm9ybUZpbGxJbmZvKCktPm1fcEpzUGxhdGZvcm0gPT0gTlVMTCkNCiAgICByZXR1cm47DQogIGlmIChwRW52LT5HZXRGb3JtRmlsbEluZm8oKS0+bV9wSnNQbGF0Zm9ybS0+RG9jX3ByaW50ID09IE5VTEwpDQogICAgcmV0dXJuOw0KICBwRW52LT5HZXRGb3JtRmlsbEluZm8oKS0+bV9wSnNQbGF0Zm9ybS0+RG9jX3ByaW50KA0KICAgICAgcEVudi0+R2V0Rm9ybUZpbGxJbmZvKCktPm1fcEpzUGxhdGZvcm0sDQogICAgICBkd09wdGlvbnMgJiBYRkFfUFJJTlRPUFRfU2hvd0RpYWxvZywgblN0YXJ0UGFnZSwgbkVuZFBhZ2UsDQogICAgICBkd09wdGlvbnMgJiBYRkFfUFJJTlRPUFRfQ2FuQ2FuY2VsLCBkd09wdGlvbnMgJiBYRkFfUFJJTlRPUFRfU2hyaW5rUGFnZSwNCiAgICAgIGR3T3B0aW9ucyAmIFhGQV9QUklOVE9QVF9Bc0ltYWdlLCBkd09wdGlvbnMgJiBYRkFfUFJJTlRPUFRfUmV2ZXJzZU9yZGVyLA0KICAgICAgZHdPcHRpb25zICYgWEZBX1BSSU5UT1BUX1ByaW50QW5ub3QpOw0KfQ0KDQp2b2lkIENQREZYRkFfRG9jdW1lbnQ6OkdldFVSTChJWEZBX0RvYyogaERvYywgQ0ZYX1dpZGVTdHJpbmcmIHdzRG9jVVJMKSB7DQogIGlmIChoRG9jICE9IG1fcFhGQURvYykNCiAgICByZXR1cm47DQoNCiAgQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IG1fcFNES0RvYy0+R2V0RW52KCk7DQogIGlmIChwRW52ID09IE5VTEwpDQogICAgcmV0dXJuOw0KDQogIHBFbnYtPkZGSV9HZXRVUkwodGhpcywgd3NEb2NVUkwpOw0KfQ0KDQpGWF9BUkdCIENQREZYRkFfRG9jdW1lbnQ6OkdldEhpZ2hsaWdodENvbG9yKElYRkFfRG9jKiBoRG9jKSB7DQogIGlmIChoRG9jICE9IG1fcFhGQURvYykNCiAgICByZXR1cm4gMDsNCiAgaWYgKG1fcFNES0RvYykgew0KICAgIGlmIChDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IG1fcFNES0RvYy0+R2V0SW50ZXJGb3JtKCkpIHsNCiAgICAgIEZYX0NPTE9SUkVGIGNvbG9yID0gcEludGVyRm9ybS0+R2V0SGlnaGxpZ2h0Q29sb3IoRlBERl9GT1JNRklFTERfWEZBKTsNCiAgICAgIHVpbnQ4X3QgYWxwaGEgPSBwSW50ZXJGb3JtLT5HZXRIaWdobGlnaHRBbHBoYSgpOw0KICAgICAgRlhfQVJHQiBhcmdiID0gQXJnYkVuY29kZSgoaW50KWFscGhhLCBjb2xvcik7DQogICAgICByZXR1cm4gYXJnYjsNCiAgICB9DQogIH0NCiAgcmV0dXJuIDA7DQp9DQoNCnZvaWQgQ1BERlhGQV9Eb2N1bWVudDo6QWRkRG9SZWNvcmQoSVhGQV9XaWRnZXQqIGhXaWRnZXQpIHsNCiAgQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IG1fcFNES0RvYy0+R2V0RW52KCk7DQogIGlmIChwRW52ID09IE5VTEwpDQogICAgcmV0dXJuOw0KICByZXR1cm47DQogIC8vIHBFbnYtPkZGSV9BZGREb1JlY29yZCh0aGlzLCBoV2lkZ2V0KTsNCn0NCg0KRlhfQk9PTCBDUERGWEZBX0RvY3VtZW50OjpfTm90aWZ5U3VibWl0KEZYX0JPT0wgYlByZXZPclBvc3QpIHsNCiAgaWYgKGJQcmV2T3JQb3N0KQ0KICAgIHJldHVybiBfT25CZWZvcmVOb3RpZnlTdW1iaXQoKTsNCiAgZWxzZQ0KICAgIF9PbkFmdGVyTm90aWZ5U3VtYml0KCk7DQogIHJldHVybiBUUlVFOw0KfQ0KDQpGWF9CT09MIENQREZYRkFfRG9jdW1lbnQ6Ol9PbkJlZm9yZU5vdGlmeVN1bWJpdCgpIHsNCiNpZmRlZiBQREZfRU5BQkxFX1hGQQ0KICBpZiAobV9pRG9jVHlwZSAhPSBET0NUWVBFX0RZTkFNSUNfWEZBICYmIG1faURvY1R5cGUgIT0gRE9DVFlQRV9TVEFUSUNfWEZBKQ0KICAgIHJldHVybiBUUlVFOw0KICBpZiAobV9wWEZBRG9jVmlldyA9PSBOVUxMKQ0KICAgIHJldHVybiBUUlVFOw0KICBJWEZBX1dpZGdldEhhbmRsZXIqIHBXaWRnZXRIYW5kbGVyID0gbV9wWEZBRG9jVmlldy0+R2V0V2lkZ2V0SGFuZGxlcigpOw0KICBpZiAocFdpZGdldEhhbmRsZXIgPT0gTlVMTCkNCiAgICByZXR1cm4gVFJVRTsNCiAgSVhGQV9XaWRnZXRBY2NJdGVyYXRvciogcFdpZGdldEFjY0l0ZXJhdG9yID0NCiAgICAgIG1fcFhGQURvY1ZpZXctPkNyZWF0ZVdpZGdldEFjY0l0ZXJhdG9yKCk7DQogIGlmIChwV2lkZ2V0QWNjSXRlcmF0b3IpIHsNCiAgICBDWEZBX0V2ZW50UGFyYW0gUGFyYW07DQogICAgUGFyYW0ubV9lVHlwZSA9IFhGQV9FVkVOVF9QcmVTdWJtaXQ7DQogICAgQ1hGQV9XaWRnZXRBY2MqIHBXaWRnZXRBY2MgPSBwV2lkZ2V0QWNjSXRlcmF0b3ItPk1vdmVUb05leHQoKTsNCiAgICB3aGlsZSAocFdpZGdldEFjYykgew0KICAgICAgcFdpZGdldEhhbmRsZXItPlByb2Nlc3NFdmVudChwV2lkZ2V0QWNjLCAmUGFyYW0pOw0KICAgICAgcFdpZGdldEFjYyA9IHBXaWRnZXRBY2NJdGVyYXRvci0+TW92ZVRvTmV4dCgpOw0KICAgIH0NCiAgICBwV2lkZ2V0QWNjSXRlcmF0b3ItPlJlbGVhc2UoKTsNCiAgfQ0KICBwV2lkZ2V0QWNjSXRlcmF0b3IgPSBtX3BYRkFEb2NWaWV3LT5DcmVhdGVXaWRnZXRBY2NJdGVyYXRvcigpOw0KICBpZiAocFdpZGdldEFjY0l0ZXJhdG9yKSB7DQogICAgQ1hGQV9XaWRnZXRBY2MqIHBXaWRnZXRBY2MgPSBwV2lkZ2V0QWNjSXRlcmF0b3ItPk1vdmVUb05leHQoKTsNCiAgICBwV2lkZ2V0QWNjID0gcFdpZGdldEFjY0l0ZXJhdG9yLT5Nb3ZlVG9OZXh0KCk7DQogICAgd2hpbGUgKHBXaWRnZXRBY2MpIHsNCiAgICAgIGludCBmUmV0ID0gcFdpZGdldEFjYy0+UHJvY2Vzc1ZhbGlkYXRlKC0xKTsNCiAgICAgIGlmIChmUmV0ID09IFhGQV9FVkVOVEVSUk9SX0Vycm9yKSB7DQogICAgICAgIENQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BTREtEb2MtPkdldEVudigpOw0KICAgICAgICBpZiAocEVudiA9PSBOVUxMKQ0KICAgICAgICAgIHJldHVybiBGQUxTRTsNCiAgICAgICAgQ0ZYX1dpZGVTdHJpbmcgd3M7DQogICAgICAgIHdzLkZyb21Mb2NhbChJRFNfWEZBX1ZhbGlkYXRlX0lucHV0KTsNCiAgICAgICAgQ0ZYX0J5dGVTdHJpbmcgYnMgPSB3cy5VVEYxNkxFX0VuY29kZSgpOw0KICAgICAgICBpbnQgbGVuID0gYnMuR2V0TGVuZ3RoKCkgLyBzaXplb2YodW5zaWduZWQgc2hvcnQpOw0KICAgICAgICBwRW52LT5GRklfQWxlcnQoDQogICAgICAgICAgICAoRlBERl9XSURFU1RSSU5HKWJzLkdldEJ1ZmZlcihsZW4gKiBzaXplb2YodW5zaWduZWQgc2hvcnQpKSwNCiAgICAgICAgICAgIChGUERGX1dJREVTVFJJTkcpTCIiLCAwLCAxKTsNCiAgICAgICAgYnMuUmVsZWFzZUJ1ZmZlcihsZW4gKiBzaXplb2YodW5zaWduZWQgc2hvcnQpKTsNCiAgICAgICAgcFdpZGdldEFjY0l0ZXJhdG9yLT5SZWxlYXNlKCk7DQogICAgICAgIHJldHVybiBGQUxTRTsNCiAgICAgIH0NCiAgICAgIHBXaWRnZXRBY2MgPSBwV2lkZ2V0QWNjSXRlcmF0b3ItPk1vdmVUb05leHQoKTsNCiAgICB9DQogICAgcFdpZGdldEFjY0l0ZXJhdG9yLT5SZWxlYXNlKCk7DQogICAgbV9wWEZBRG9jVmlldy0+VXBkYXRlRG9jVmlldygpOw0KICB9DQojZW5kaWYNCiAgcmV0dXJuIFRSVUU7DQp9DQp2b2lkIENQREZYRkFfRG9jdW1lbnQ6Ol9PbkFmdGVyTm90aWZ5U3VtYml0KCkgew0KICBpZiAobV9pRG9jVHlwZSAhPSBET0NUWVBFX0RZTkFNSUNfWEZBICYmIG1faURvY1R5cGUgIT0gRE9DVFlQRV9TVEFUSUNfWEZBKQ0KICAgIHJldHVybjsNCiAgaWYgKG1fcFhGQURvY1ZpZXcgPT0gTlVMTCkNCiAgICByZXR1cm47DQogIElYRkFfV2lkZ2V0SGFuZGxlciogcFdpZGdldEhhbmRsZXIgPSBtX3BYRkFEb2NWaWV3LT5HZXRXaWRnZXRIYW5kbGVyKCk7DQogIGlmIChwV2lkZ2V0SGFuZGxlciA9PSBOVUxMKQ0KICAgIHJldHVybjsNCiAgSVhGQV9XaWRnZXRBY2NJdGVyYXRvciogcFdpZGdldEFjY0l0ZXJhdG9yID0NCiAgICAgIG1fcFhGQURvY1ZpZXctPkNyZWF0ZVdpZGdldEFjY0l0ZXJhdG9yKCk7DQogIGlmIChwV2lkZ2V0QWNjSXRlcmF0b3IgPT0gTlVMTCkNCiAgICByZXR1cm47DQogIENYRkFfRXZlbnRQYXJhbSBQYXJhbTsNCiAgUGFyYW0ubV9lVHlwZSA9IFhGQV9FVkVOVF9Qb3N0U3VibWl0Ow0KDQogIENYRkFfV2lkZ2V0QWNjKiBwV2lkZ2V0QWNjID0gcFdpZGdldEFjY0l0ZXJhdG9yLT5Nb3ZlVG9OZXh0KCk7DQogIHdoaWxlIChwV2lkZ2V0QWNjKSB7DQogICAgcFdpZGdldEhhbmRsZXItPlByb2Nlc3NFdmVudChwV2lkZ2V0QWNjLCAmUGFyYW0pOw0KICAgIHBXaWRnZXRBY2MgPSBwV2lkZ2V0QWNjSXRlcmF0b3ItPk1vdmVUb05leHQoKTsNCiAgfQ0KICBwV2lkZ2V0QWNjSXRlcmF0b3ItPlJlbGVhc2UoKTsNCiAgbV9wWEZBRG9jVmlldy0+VXBkYXRlRG9jVmlldygpOw0KfQ0KDQpGWF9CT09MIENQREZYRkFfRG9jdW1lbnQ6OlN1Ym1pdERhdGEoSVhGQV9Eb2MqIGhEb2MsIENYRkFfU3VibWl0IHN1Ym1pdCkgew0KICBpZiAoIV9Ob3RpZnlTdWJtaXQoVFJVRSkpDQogICAgcmV0dXJuIEZBTFNFOw0KICBpZiAoTlVMTCA9PSBtX3BYRkFEb2NWaWV3KQ0KICAgIHJldHVybiBGQUxTRTsNCiAgbV9wWEZBRG9jVmlldy0+VXBkYXRlRG9jVmlldygpOw0KDQogIEZYX0JPT0wgcmV0ID0gX1N1Ym1pdERhdGEoaERvYywgc3VibWl0KTsNCiAgX05vdGlmeVN1Ym1pdChGQUxTRSk7DQogIHJldHVybiByZXQ7DQp9DQoNCklGWF9GaWxlUmVhZCogQ1BERlhGQV9Eb2N1bWVudDo6T3BlbkxpbmtlZEZpbGUoSVhGQV9Eb2MqIGhEb2MsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENGWF9XaWRlU3RyaW5nJiB3c0xpbmspIHsNCiAgQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IG1fcFNES0RvYy0+R2V0RW52KCk7DQogIGlmIChwRW52ID09IE5VTEwpDQogICAgcmV0dXJuIEZBTFNFOw0KICBDRlhfQnl0ZVN0cmluZyBicyA9IHdzTGluay5VVEYxNkxFX0VuY29kZSgpOw0KICBpbnQgbGVuID0gYnMuR2V0TGVuZ3RoKCkgLyBzaXplb2YodW5zaWduZWQgc2hvcnQpOw0KICBGUERGX0ZJTEVIQU5ETEVSKiBwRmlsZUhhbmRsZXIgPSBwRW52LT5GRklfT3BlbkZpbGUoDQogICAgICAwLCAoRlBERl9XSURFU1RSSU5HKWJzLkdldEJ1ZmZlcihsZW4gKiBzaXplb2YodW5zaWduZWQgc2hvcnQpKSwgInJiIik7DQogIGJzLlJlbGVhc2VCdWZmZXIobGVuICogc2l6ZW9mKHVuc2lnbmVkIHNob3J0KSk7DQoNCiAgaWYgKHBGaWxlSGFuZGxlciA9PSBOVUxMKQ0KICAgIHJldHVybiBOVUxMOw0KICByZXR1cm4gbmV3IENGUERGX0ZpbGVTdHJlYW0ocEZpbGVIYW5kbGVyKTsNCn0NCkZYX0JPT0wgQ1BERlhGQV9Eb2N1bWVudDo6X0V4cG9ydFN1Ym1pdEZpbGUoRlBERl9GSUxFSEFORExFUiogcEZpbGVIYW5kbGVyLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZmlsZVR5cGUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZQREZfRFdPUkQgZW5jb2RlVHlwZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlBERl9EV09SRCBmbGFnKSB7DQogIGlmIChOVUxMID09IG1fcFhGQURvY1ZpZXcpDQogICAgcmV0dXJuIEZBTFNFOw0KICBJWEZBX0RvY0hhbmRsZXIqIHBEb2NIYW5kbGVyID0gbV9wQXBwLT5HZXRYRkFBcHAoKS0+R2V0RG9jSGFuZGxlcigpOw0KICBDRlhfQnl0ZVN0cmluZyBjb250ZW50Ow0KDQogIENQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BTREtEb2MtPkdldEVudigpOw0KICBpZiAocEVudiA9PSBOVUxMKQ0KICAgIHJldHVybiBGQUxTRTsNCg0KICBDRlBERl9GaWxlU3RyZWFtIGZpbGVTdHJlYW0ocEZpbGVIYW5kbGVyKTsNCg0KICBpZiAoZmlsZVR5cGUgPT0gRlhGQV9TQVZFQVNfWE1MKSB7DQogICAgQ0ZYX1dpZGVTdHJpbmcgd3M7DQogICAgd3MuRnJvbUxvY2FsKCJkYXRhIik7DQogICAgQ0ZYX0J5dGVTdHJpbmcgY29udGVudCA9ICI8P3htbCB2ZXJzaW9uPVwiMS4wXCIgZW5jb2Rpbmc9XCJVVEYtOFwiPz5cclxuIjsNCiAgICBmaWxlU3RyZWFtLldyaXRlQmxvY2soKGNvbnN0IEZYX0NIQVIqKWNvbnRlbnQsIDAsIGNvbnRlbnQuR2V0TGVuZ3RoKCkpOw0KICAgIHBEb2NIYW5kbGVyLT5TYXZlUGFja2FnZShtX3BYRkFEb2MsIHdzLCAmZmlsZVN0cmVhbSk7DQogIH0gZWxzZSBpZiAoZmlsZVR5cGUgPT0gRlhGQV9TQVZFQVNfWERQKSB7DQogICAgaWYgKGZsYWcgPT0gMCkNCiAgICAgIGZsYWcgPSBGWEZBX0NPTkZJRyB8IEZYRkFfVEVNUExBVEUgfCBGWEZBX0xPQ0FMRVNFVCB8IEZYRkFfREFUQVNFVFMgfA0KICAgICAgICAgICAgIEZYRkFfWE1QTUVUQSB8IEZYRkFfWEZERiB8IEZYRkFfRk9STTsNCiAgICBpZiAobV9wUERGRG9jID09IE5VTEwpIHsNCiAgICAgIGZpbGVTdHJlYW0uRmx1c2goKTsNCiAgICAgIHJldHVybiBGQUxTRTsNCiAgICB9DQogICAgQ1BERl9EaWN0aW9uYXJ5KiBwUm9vdCA9IG1fcFBERkRvYy0+R2V0Um9vdCgpOw0KICAgIGlmIChwUm9vdCA9PSBOVUxMKSB7DQogICAgICBmaWxlU3RyZWFtLkZsdXNoKCk7DQogICAgICByZXR1cm4gRkFMU0U7DQogICAgfQ0KICAgIENQREZfRGljdGlvbmFyeSogcEFjcm9Gb3JtID0gcFJvb3QtPkdldERpY3QoIkFjcm9Gb3JtIik7DQogICAgaWYgKE5VTEwgPT0gcEFjcm9Gb3JtKSB7DQogICAgICBmaWxlU3RyZWFtLkZsdXNoKCk7DQogICAgICByZXR1cm4gRkFMU0U7DQogICAgfQ0KICAgIENQREZfT2JqZWN0KiBwWEZBID0gcEFjcm9Gb3JtLT5HZXRFbGVtZW50KCJYRkEiKTsNCiAgICBpZiAocFhGQSA9PSBOVUxMKSB7DQogICAgICBmaWxlU3RyZWFtLkZsdXNoKCk7DQogICAgICByZXR1cm4gRkFMU0U7DQogICAgfQ0KICAgIGlmIChwWEZBLT5HZXRUeXBlKCkgIT0gUERGT0JKX0FSUkFZKSB7DQogICAgICBmaWxlU3RyZWFtLkZsdXNoKCk7DQogICAgICByZXR1cm4gRkFMU0U7DQogICAgfQ0KICAgIENQREZfQXJyYXkqIHBBcnJheSA9IHBYRkEtPkdldEFycmF5KCk7DQogICAgaWYgKE5VTEwgPT0gcEFycmF5KSB7DQogICAgICBmaWxlU3RyZWFtLkZsdXNoKCk7DQogICAgICByZXR1cm4gRkFMU0U7DQogICAgfQ0KICAgIGludCBzaXplID0gcEFycmF5LT5HZXRDb3VudCgpOw0KICAgIGZvciAoaW50IGkgPSAxOyBpIDwgc2l6ZTsgaSArPSAyKSB7DQogICAgICBDUERGX09iamVjdCogcFBERk9iaiA9IHBBcnJheS0+R2V0RWxlbWVudChpKTsNCiAgICAgIENQREZfT2JqZWN0KiBwUHJlUERGT2JqID0gcEFycmF5LT5HZXRFbGVtZW50KGkgLSAxKTsNCiAgICAgIGlmIChwUHJlUERGT2JqLT5HZXRUeXBlKCkgIT0gUERGT0JKX1NUUklORykNCiAgICAgICAgY29udGludWU7DQogICAgICBpZiAocFBERk9iai0+R2V0VHlwZSgpICE9IFBERk9CSl9SRUZFUkVOQ0UpDQogICAgICAgIGNvbnRpbnVlOw0KICAgICAgQ1BERl9PYmplY3QqIHBEaXJlY3RPYmogPSBwUERGT2JqLT5HZXREaXJlY3QoKTsNCiAgICAgIGlmIChwRGlyZWN0T2JqLT5HZXRUeXBlKCkgIT0gUERGT0JKX1NUUkVBTSkNCiAgICAgICAgY29udGludWU7DQogICAgICBpZiAocFByZVBERk9iai0+R2V0U3RyaW5nKCkgPT0gImNvbmZpZyIgJiYgIShmbGFnICYgRlhGQV9DT05GSUcpKQ0KICAgICAgICBjb250aW51ZTsNCiAgICAgIGlmIChwUHJlUERGT2JqLT5HZXRTdHJpbmcoKSA9PSAidGVtcGxhdGUiICYmICEoZmxhZyAmIEZYRkFfVEVNUExBVEUpKQ0KICAgICAgICBjb250aW51ZTsNCiAgICAgIGlmIChwUHJlUERGT2JqLT5HZXRTdHJpbmcoKSA9PSAibG9jYWxlU2V0IiAmJiAhKGZsYWcgJiBGWEZBX0xPQ0FMRVNFVCkpDQogICAgICAgIGNvbnRpbnVlOw0KICAgICAgaWYgKHBQcmVQREZPYmotPkdldFN0cmluZygpID09ICJkYXRhc2V0cyIgJiYgIShmbGFnICYgRlhGQV9EQVRBU0VUUykpDQogICAgICAgIGNvbnRpbnVlOw0KICAgICAgaWYgKHBQcmVQREZPYmotPkdldFN0cmluZygpID09ICJ4bXBtZXRhIiAmJiAhKGZsYWcgJiBGWEZBX1hNUE1FVEEpKQ0KICAgICAgICBjb250aW51ZTsNCiAgICAgIGlmIChwUHJlUERGT2JqLT5HZXRTdHJpbmcoKSA9PSAieGZkZiIgJiYgIShmbGFnICYgRlhGQV9YRkRGKSkNCiAgICAgICAgY29udGludWU7DQogICAgICBpZiAocFByZVBERk9iai0+R2V0U3RyaW5nKCkgPT0gImZvcm0iICYmICEoZmxhZyAmIEZYRkFfRk9STSkpDQogICAgICAgIGNvbnRpbnVlOw0KICAgICAgaWYgKHBQcmVQREZPYmotPkdldFN0cmluZygpID09ICJmb3JtIikgew0KICAgICAgICBDRlhfV2lkZVN0cmluZyB3czsNCiAgICAgICAgd3MuRnJvbUxvY2FsKCJmb3JtIik7DQogICAgICAgIHBEb2NIYW5kbGVyLT5TYXZlUGFja2FnZShtX3BYRkFEb2MsIHdzLCAmZmlsZVN0cmVhbSk7DQogICAgICB9IGVsc2UgaWYgKHBQcmVQREZPYmotPkdldFN0cmluZygpID09ICJkYXRhc2V0cyIpIHsNCiAgICAgICAgQ0ZYX1dpZGVTdHJpbmcgd3M7DQogICAgICAgIHdzLkZyb21Mb2NhbCgiZGF0YXNldHMiKTsNCiAgICAgICAgcERvY0hhbmRsZXItPlNhdmVQYWNrYWdlKG1fcFhGQURvYywgd3MsICZmaWxlU3RyZWFtKTsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIC8vIFBERixjcmVhdG9yLg0KICAgICAgICAvLyBUT0RPOg0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICByZXR1cm4gVFJVRTsNCn0NCg0Kdm9pZCBDUERGWEZBX0RvY3VtZW50OjpfQ2xlYXJDaGFuZ2VNYXJrKCkgew0KICBpZiAobV9wU0RLRG9jKQ0KICAgIG1fcFNES0RvYy0+Q2xlYXJDaGFuZ2VNYXJrKCk7DQp9DQoNCnZvaWQgQ1BERlhGQV9Eb2N1bWVudDo6X1RvWEZBQ29udGVudEZsYWdzKENGWF9XaWRlU3RyaW5nIGNzU3JjQ29udGVudCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZQREZfRFdPUkQmIGZsYWcpIHsNCiAgaWYgKGNzU3JjQ29udGVudC5GaW5kKEwiIGNvbmZpZyAiLCAwKSAhPSAtMSkNCiAgICBmbGFnIHw9IEZYRkFfQ09ORklHOw0KICBpZiAoY3NTcmNDb250ZW50LkZpbmQoTCIgdGVtcGxhdGUgIiwgMCkgIT0gLTEpDQogICAgZmxhZyB8PSBGWEZBX1RFTVBMQVRFOw0KICBpZiAoY3NTcmNDb250ZW50LkZpbmQoTCIgbG9jYWxlU2V0ICIsIDApICE9IC0xKQ0KICAgIGZsYWcgfD0gRlhGQV9MT0NBTEVTRVQ7DQogIGlmIChjc1NyY0NvbnRlbnQuRmluZChMIiBkYXRhc2V0cyAiLCAwKSAhPSAtMSkNCiAgICBmbGFnIHw9IEZYRkFfREFUQVNFVFM7DQogIGlmIChjc1NyY0NvbnRlbnQuRmluZChMIiB4bXBtZXRhICIsIDApICE9IC0xKQ0KICAgIGZsYWcgfD0gRlhGQV9YTVBNRVRBOw0KICBpZiAoY3NTcmNDb250ZW50LkZpbmQoTCIgeGZkZiAiLCAwKSAhPSAtMSkNCiAgICBmbGFnIHw9IEZYRkFfWEZERjsNCiAgaWYgKGNzU3JjQ29udGVudC5GaW5kKEwiIGZvcm0gIiwgMCkgIT0gLTEpDQogICAgZmxhZyB8PSBGWEZBX0ZPUk07DQogIGlmIChmbGFnID09IDApDQogICAgZmxhZyA9IEZYRkFfQ09ORklHIHwgRlhGQV9URU1QTEFURSB8IEZYRkFfTE9DQUxFU0VUIHwgRlhGQV9EQVRBU0VUUyB8DQogICAgICAgICAgIEZYRkFfWE1QTUVUQSB8IEZYRkFfWEZERiB8IEZYRkFfRk9STTsNCn0NCkZYX0JPT0wgQ1BERlhGQV9Eb2N1bWVudDo6X01haWxUb0luZm8oQ0ZYX1dpZGVTdHJpbmcmIGNzVVJMLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDRlhfV2lkZVN0cmluZyYgY3NUb0FkZHJlc3MsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENGWF9XaWRlU3RyaW5nJiBjc0NDQWRkcmVzcywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0ZYX1dpZGVTdHJpbmcmIGNzQkNDQWRkcmVzcywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0ZYX1dpZGVTdHJpbmcmIGNzU3ViamVjdCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0ZYX1dpZGVTdHJpbmcmIGNzTXNnKSB7DQogIENGWF9XaWRlU3RyaW5nIHNyY1VSTCA9IGNzVVJMOw0KICBzcmNVUkwuVHJpbUxlZnQoKTsNCiAgaWYgKDAgIT0gc3JjVVJMLkxlZnQoNykuQ29tcGFyZU5vQ2FzZShMIm1haWx0bzoiKSkNCiAgICByZXR1cm4gRkFMU0U7DQogIGludCBwb3MgPSBzcmNVUkwuRmluZChMJz8nLCAwKTsNCiAgQ0ZYX1dpZGVTdHJpbmcgdG1wOw0KICBpZiAocG9zID09IC0xKSB7DQogICAgcG9zID0gc3JjVVJMLkZpbmQoTCdAJywgMCk7DQogICAgaWYgKHBvcyA9PSAtMSkNCiAgICAgIHJldHVybiBGQUxTRTsNCiAgICBlbHNlIHsNCiAgICAgIHRtcCA9IHNyY1VSTC5SaWdodChjc1VSTC5HZXRMZW5ndGgoKSAtIDcpOw0KICAgICAgdG1wLlRyaW1MZWZ0KCk7DQogICAgICB0bXAuVHJpbVJpZ2h0KCk7DQogICAgfQ0KICB9IGVsc2Ugew0KICAgIHRtcCA9IHNyY1VSTC5MZWZ0KHBvcyk7DQogICAgdG1wID0gdG1wLlJpZ2h0KHRtcC5HZXRMZW5ndGgoKSAtIDcpOw0KICAgIHRtcC5UcmltTGVmdCgpOw0KICAgIHRtcC5UcmltUmlnaHQoKTsNCiAgfQ0KDQogIGNzVG9BZGRyZXNzID0gdG1wOw0KDQogIHNyY1VSTCA9IHNyY1VSTC5SaWdodChzcmNVUkwuR2V0TGVuZ3RoKCkgLSAocG9zICsgMSkpOw0KICB3aGlsZSAoIXNyY1VSTC5Jc0VtcHR5KCkpIHsNCiAgICBzcmNVUkwuVHJpbUxlZnQoKTsNCiAgICBzcmNVUkwuVHJpbVJpZ2h0KCk7DQogICAgcG9zID0gc3JjVVJMLkZpbmQoTCcmJywgMCk7DQogICAgaWYgKHBvcyA9PSAtMSkNCiAgICAgIHRtcCA9IHNyY1VSTDsNCiAgICBlbHNlDQogICAgICB0bXAgPSBzcmNVUkwuTGVmdChwb3MpOw0KDQogICAgdG1wLlRyaW1MZWZ0KCk7DQogICAgdG1wLlRyaW1SaWdodCgpOw0KICAgIGlmICh0bXAuR2V0TGVuZ3RoKCkgPj0gMyAmJiAwID09IHRtcC5MZWZ0KDMpLkNvbXBhcmVOb0Nhc2UoTCJjYz0iKSkgew0KICAgICAgdG1wID0gdG1wLlJpZ2h0KHRtcC5HZXRMZW5ndGgoKSAtIDMpOw0KICAgICAgaWYgKCFjc0NDQWRkcmVzcy5Jc0VtcHR5KCkpDQogICAgICAgIGNzQ0NBZGRyZXNzICs9IEwnOyc7DQogICAgICBjc0NDQWRkcmVzcyArPSB0bXA7DQoNCiAgICB9IGVsc2UgaWYgKHRtcC5HZXRMZW5ndGgoKSA+PSA0ICYmDQogICAgICAgICAgICAgICAwID09IHRtcC5MZWZ0KDQpLkNvbXBhcmVOb0Nhc2UoTCJiY2M9IikpIHsNCiAgICAgIHRtcCA9IHRtcC5SaWdodCh0bXAuR2V0TGVuZ3RoKCkgLSA0KTsNCiAgICAgIGlmICghY3NCQ0NBZGRyZXNzLklzRW1wdHkoKSkNCiAgICAgICAgY3NCQ0NBZGRyZXNzICs9IEwnOyc7DQogICAgICBjc0JDQ0FkZHJlc3MgKz0gdG1wOw0KICAgIH0gZWxzZSBpZiAodG1wLkdldExlbmd0aCgpID49IDggJiYNCiAgICAgICAgICAgICAgIDAgPT0gdG1wLkxlZnQoOCkuQ29tcGFyZU5vQ2FzZShMInN1YmplY3Q9IikpIHsNCiAgICAgIHRtcCA9IHRtcC5SaWdodCh0bXAuR2V0TGVuZ3RoKCkgLSA4KTsNCiAgICAgIGNzU3ViamVjdCArPSB0bXA7DQogICAgfSBlbHNlIGlmICh0bXAuR2V0TGVuZ3RoKCkgPj0gNSAmJg0KICAgICAgICAgICAgICAgMCA9PSB0bXAuTGVmdCg1KS5Db21wYXJlTm9DYXNlKEwiYm9keT0iKSkgew0KICAgICAgdG1wID0gdG1wLlJpZ2h0KHRtcC5HZXRMZW5ndGgoKSAtIDUpOw0KICAgICAgY3NNc2cgKz0gdG1wOw0KICAgIH0NCiAgICBpZiAocG9zID09IC0xKQ0KICAgICAgc3JjVVJMID0gTCIiOw0KICAgIGVsc2UNCiAgICAgIHNyY1VSTCA9IHNyY1VSTC5SaWdodChjc1VSTC5HZXRMZW5ndGgoKSAtIChwb3MgKyAxKSk7DQogIH0NCiAgY3NUb0FkZHJlc3MuUmVwbGFjZShMIiwiLCBMIjsiKTsNCiAgY3NDQ0FkZHJlc3MuUmVwbGFjZShMIiwiLCBMIjsiKTsNCiAgY3NCQ0NBZGRyZXNzLlJlcGxhY2UoTCIsIiwgTCI7Iik7DQogIHJldHVybiBUUlVFOw0KfQ0KDQpGWF9CT09MIENQREZYRkFfRG9jdW1lbnQ6Ol9TdWJtaXREYXRhKElYRkFfRG9jKiBoRG9jLCBDWEZBX1N1Ym1pdCBzdWJtaXQpIHsNCiNpZmRlZiBQREZfRU5BQkxFX1hGQQ0KICBDRlhfV2lkZVN0cmluZ0MgY3NVUkxDOw0KICBzdWJtaXQuR2V0U3VibWl0VGFyZ2V0KGNzVVJMQyk7DQogIENGWF9XaWRlU3RyaW5nIGNzVVJMID0gY3NVUkxDOw0KICBDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wU0RLRG9jLT5HZXRFbnYoKTsNCiAgaWYgKHBFbnYgPT0gTlVMTCkNCiAgICByZXR1cm4gRkFMU0U7DQogIGlmIChjc1VSTC5Jc0VtcHR5KCkpIHsNCiAgICBDRlhfV2lkZVN0cmluZyB3czsNCiAgICB3cy5Gcm9tTG9jYWwoIlN1Ym1pdCBjYW5jZWxsZWQuIik7DQogICAgQ0ZYX0J5dGVTdHJpbmcgYnMgPSB3cy5VVEYxNkxFX0VuY29kZSgpOw0KICAgIGludCBsZW4gPSBicy5HZXRMZW5ndGgoKSAvIHNpemVvZih1bnNpZ25lZCBzaG9ydCk7DQogICAgcEVudi0+RkZJX0FsZXJ0KChGUERGX1dJREVTVFJJTkcpYnMuR2V0QnVmZmVyKGxlbiAqIHNpemVvZih1bnNpZ25lZCBzaG9ydCkpLA0KICAgICAgICAgICAgICAgICAgICAoRlBERl9XSURFU1RSSU5HKUwiIiwgMCwgNCk7DQogICAgYnMuUmVsZWFzZUJ1ZmZlcihsZW4gKiBzaXplb2YodW5zaWduZWQgc2hvcnQpKTsNCiAgICByZXR1cm4gRkFMU0U7DQogIH0NCg0KICBGUERGX0JPT0wgYlJldCA9IFRSVUU7DQogIEZQREZfRklMRUhBTkRMRVIqIHBGaWxlSGFuZGxlciA9IE5VTEw7DQogIGludCBmaWxlRmxhZyA9IC0xOw0KDQogIGlmIChzdWJtaXQuR2V0U3VibWl0Rm9ybWF0KCkgPT0gWEZBX0FUVFJJQlVURUVOVU1fWGRwKSB7DQogICAgQ0ZYX1dpZGVTdHJpbmdDIGNzQ29udGVudEM7DQogICAgc3VibWl0LkdldFN1Ym1pdFhEUENvbnRlbnQoY3NDb250ZW50Qyk7DQogICAgQ0ZYX1dpZGVTdHJpbmcgY3NDb250ZW50Ow0KICAgIGNzQ29udGVudCA9IGNzQ29udGVudEMuR2V0UHRyKCk7DQogICAgY3NDb250ZW50LlRyaW1MZWZ0KCk7DQogICAgY3NDb250ZW50LlRyaW1SaWdodCgpOw0KICAgIENGWF9XaWRlU3RyaW5nIHNwYWNlOw0KICAgIHNwYWNlLkZyb21Mb2NhbCgiICIpOw0KICAgIGNzQ29udGVudCA9IHNwYWNlICsgY3NDb250ZW50ICsgc3BhY2U7DQogICAgRlBERl9EV09SRCBmbGFnID0gMDsNCiAgICBpZiAoc3VibWl0LklzU3VibWl0RW1iZWRQREYoKSkNCiAgICAgIGZsYWcgfD0gRlhGQV9QREY7DQogICAgX1RvWEZBQ29udGVudEZsYWdzKGNzQ29udGVudCwgZmxhZyk7DQogICAgcEZpbGVIYW5kbGVyID0gcEVudi0+RkZJX09wZW5GaWxlKEZYRkFfU0FWRUFTX1hEUCwgTlVMTCwgIndiIik7DQogICAgZmlsZUZsYWcgPSBGWEZBX1NBVkVBU19YRFA7DQogICAgX0V4cG9ydFN1Ym1pdEZpbGUocEZpbGVIYW5kbGVyLCBGWEZBX1NBVkVBU19YRFAsIDAsIGZsYWcpOw0KICB9IGVsc2UgaWYgKHN1Ym1pdC5HZXRTdWJtaXRGb3JtYXQoKSA9PSBYRkFfQVRUUklCVVRFRU5VTV9YbWwpIHsNCiAgICBwRmlsZUhhbmRsZXIgPSBwRW52LT5GRklfT3BlbkZpbGUoRlhGQV9TQVZFQVNfWE1MLCBOVUxMLCAid2IiKTsNCiAgICBmaWxlRmxhZyA9IEZYRkFfU0FWRUFTX1hNTDsNCiAgICBfRXhwb3J0U3VibWl0RmlsZShwRmlsZUhhbmRsZXIsIEZYRkFfU0FWRUFTX1hNTCwgMCk7DQogIH0gZWxzZSBpZiAoc3VibWl0LkdldFN1Ym1pdEZvcm1hdCgpID09IFhGQV9BVFRSSUJVVEVFTlVNX1BkZikgew0KICAgIC8vIGNzZmlsZW5hbWUgPSBjc0RvY05hbWU7DQogIH0gZWxzZSBpZiAoc3VibWl0LkdldFN1Ym1pdEZvcm1hdCgpID09IFhGQV9BVFRSSUJVVEVFTlVNX0Zvcm1kYXRhKSB7DQogICAgcmV0dXJuIEZBTFNFOw0KICB9IGVsc2UgaWYgKHN1Ym1pdC5HZXRTdWJtaXRGb3JtYXQoKSA9PSBYRkFfQVRUUklCVVRFRU5VTV9VcmxlbmNvZGVkKSB7DQogICAgcEZpbGVIYW5kbGVyID0gcEVudi0+RkZJX09wZW5GaWxlKEZYRkFfU0FWRUFTX1hNTCwgTlVMTCwgIndiIik7DQogICAgZmlsZUZsYWcgPSBGWEZBX1NBVkVBU19YTUw7DQogICAgX0V4cG9ydFN1Ym1pdEZpbGUocEZpbGVIYW5kbGVyLCBGWEZBX1NBVkVBU19YTUwsIDApOw0KICB9IGVsc2UgaWYgKHN1Ym1pdC5HZXRTdWJtaXRGb3JtYXQoKSA9PSBYRkFfQVRUUklCVVRFRU5VTV9YZmQpIHsNCiAgICByZXR1cm4gRkFMU0U7DQogIH0gZWxzZSB7DQogICAgcmV0dXJuIEZBTFNFOw0KICB9DQogIGlmIChwRmlsZUhhbmRsZXIgPT0gTlVMTCkNCiAgICByZXR1cm4gRkFMU0U7DQogIGlmICgwID09IGNzVVJMLkxlZnQoNykuQ29tcGFyZU5vQ2FzZShMIm1haWx0bzoiKSkgew0KICAgIENGWF9XaWRlU3RyaW5nIGNzVG9BZGRyZXNzOw0KICAgIENGWF9XaWRlU3RyaW5nIGNzQ0NBZGRyZXNzOw0KICAgIENGWF9XaWRlU3RyaW5nIGNzQkNDQWRkcmVzczsNCiAgICBDRlhfV2lkZVN0cmluZyBjc1N1YmplY3Q7DQogICAgQ0ZYX1dpZGVTdHJpbmcgY3NNc2c7DQoNCiAgICBiUmV0ID0gX01haWxUb0luZm8oY3NVUkwsIGNzVG9BZGRyZXNzLCBjc0NDQWRkcmVzcywgY3NCQ0NBZGRyZXNzLCBjc1N1YmplY3QsDQogICAgICAgICAgICAgICAgICAgICAgIGNzTXNnKTsNCiAgICBpZiAoRkFMU0UgPT0gYlJldCkNCiAgICAgIHJldHVybiBGQUxTRTsNCg0KICAgIENGWF9CeXRlU3RyaW5nIGJzVG8gPSBDRlhfV2lkZVN0cmluZyhjc1RvQWRkcmVzcykuVVRGMTZMRV9FbmNvZGUoKTsNCiAgICBDRlhfQnl0ZVN0cmluZyBic0NDID0gQ0ZYX1dpZGVTdHJpbmcoY3NDQ0FkZHJlc3MpLlVURjE2TEVfRW5jb2RlKCk7DQogICAgQ0ZYX0J5dGVTdHJpbmcgYnNCY2MgPSBDRlhfV2lkZVN0cmluZyhjc0JDQ0FkZHJlc3MpLlVURjE2TEVfRW5jb2RlKCk7DQogICAgQ0ZYX0J5dGVTdHJpbmcgYnNTdWJqZWN0ID0gQ0ZYX1dpZGVTdHJpbmcoY3NTdWJqZWN0KS5VVEYxNkxFX0VuY29kZSgpOw0KICAgIENGWF9CeXRlU3RyaW5nIGJzTXNnID0gQ0ZYX1dpZGVTdHJpbmcoY3NNc2cpLlVURjE2TEVfRW5jb2RlKCk7DQoNCiAgICBGUERGX1dJREVTVFJJTkcgcFRvID0gKEZQREZfV0lERVNUUklORylic1RvLkdldEJ1ZmZlcihic1RvLkdldExlbmd0aCgpKTsNCiAgICBGUERGX1dJREVTVFJJTkcgcENDID0gKEZQREZfV0lERVNUUklORylic0NDLkdldEJ1ZmZlcihic0NDLkdldExlbmd0aCgpKTsNCiAgICBGUERGX1dJREVTVFJJTkcgcEJjYyA9IChGUERGX1dJREVTVFJJTkcpYnNCY2MuR2V0QnVmZmVyKGJzQmNjLkdldExlbmd0aCgpKTsNCiAgICBGUERGX1dJREVTVFJJTkcgcFN1YmplY3QgPQ0KICAgICAgICAoRlBERl9XSURFU1RSSU5HKWJzU3ViamVjdC5HZXRCdWZmZXIoYnNTdWJqZWN0LkdldExlbmd0aCgpKTsNCiAgICBGUERGX1dJREVTVFJJTkcgcE1zZyA9IChGUERGX1dJREVTVFJJTkcpYnNNc2cuR2V0QnVmZmVyKGJzTXNnLkdldExlbmd0aCgpKTsNCg0KICAgIHBFbnYtPkZGSV9FbWFpbFRvKHBGaWxlSGFuZGxlciwgcFRvLCBwU3ViamVjdCwgcENDLCBwQmNjLCBwTXNnKTsNCiAgICBic1RvLlJlbGVhc2VCdWZmZXIoKTsNCiAgICBic0NDLlJlbGVhc2VCdWZmZXIoKTsNCiAgICBic0JjYy5SZWxlYXNlQnVmZmVyKCk7DQogICAgYnNTdWJqZWN0LlJlbGVhc2VCdWZmZXIoKTsNCiAgICBic01zZy5SZWxlYXNlQnVmZmVyKCk7DQogIH0gZWxzZSB7DQogICAgLy8gaHR0cKGiZnRwDQogICAgQ0ZYX1dpZGVTdHJpbmcgd3M7DQogICAgQ0ZYX0J5dGVTdHJpbmcgYnMgPSBjc1VSTC5VVEYxNkxFX0VuY29kZSgpOw0KICAgIGludCBsZW4gPSBicy5HZXRMZW5ndGgoKSAvIHNpemVvZih1bnNpZ25lZCBzaG9ydCk7DQogICAgcEVudi0+RkZJX1VwbG9hZFRvKA0KICAgICAgICBwRmlsZUhhbmRsZXIsIGZpbGVGbGFnLA0KICAgICAgICAoRlBERl9XSURFU1RSSU5HKWJzLkdldEJ1ZmZlcihsZW4gKiBzaXplb2YodW5zaWduZWQgc2hvcnQpKSk7DQogICAgYnMuUmVsZWFzZUJ1ZmZlcihsZW4gKiBzaXplb2YodW5zaWduZWQgc2hvcnQpKTsNCiAgfQ0KDQogIHJldHVybiBiUmV0Ow0KI2Vsc2UNCiAgcmV0dXJuIFRSVUU7DQojZW5kaWYNCn0NCg0KRlhfQk9PTCBDUERGWEZBX0RvY3VtZW50OjpTZXRHbG9iYWxQcm9wZXJ0eShJWEZBX0RvYyogaERvYywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ0ZYX0J5dGVTdHJpbmdDJiBzelByb3BOYW1lLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGWEpTRV9IVkFMVUUgaFZhbHVlKSB7DQogIGlmIChoRG9jICE9IG1fcFhGQURvYykNCiAgICByZXR1cm4gRkFMU0U7DQoNCiAgaWYgKG1fcFNES0RvYyAmJiBtX3BTREtEb2MtPkdldEVudigpLT5HZXRKU1J1bnRpbWUoKSkNCiAgICByZXR1cm4gbV9wU0RLRG9jLT5HZXRFbnYoKS0+R2V0SlNSdW50aW1lKCktPlNldEhWYWx1ZUJ5TmFtZShzelByb3BOYW1lLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhWYWx1ZSk7DQogIHJldHVybiBGQUxTRTsNCn0NCkZYX0JPT0wgQ1BERlhGQV9Eb2N1bWVudDo6R2V0UERGU2NyaXB0T2JqZWN0KElYRkFfRG9jKiBoRG9jLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ0ZYX0J5dGVTdHJpbmdDJiB1dGY4TmFtZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZYSlNFX0hWQUxVRSBoVmFsdWUpIHsNCiAgaWYgKGhEb2MgIT0gbV9wWEZBRG9jKQ0KICAgIHJldHVybiBGQUxTRTsNCg0KICBpZiAoIW1fcFNES0RvYyB8fCAhbV9wU0RLRG9jLT5HZXRFbnYoKS0+R2V0SlNSdW50aW1lKCkpDQogICAgcmV0dXJuIEZBTFNFOw0KDQogIGlmICghbV9wSlNDb250ZXh0KSB7DQogICAgbV9wU0RLRG9jLT5HZXRFbnYoKS0+R2V0SlNSdW50aW1lKCktPlNldFJlYWRlckRvY3VtZW50KG1fcFNES0RvYyk7DQogICAgbV9wSlNDb250ZXh0ID0gbV9wU0RLRG9jLT5HZXRFbnYoKS0+R2V0SlNSdW50aW1lKCktPk5ld0NvbnRleHQoKTsNCiAgfQ0KDQogIHJldHVybiBfR2V0SFZhbHVlQnlOYW1lKHV0ZjhOYW1lLCBoVmFsdWUsDQogICAgICAgICAgICAgICAgICAgICAgICAgIG1fcFNES0RvYy0+R2V0RW52KCktPkdldEpTUnVudGltZSgpKTsNCn0NCkZYX0JPT0wgQ1BERlhGQV9Eb2N1bWVudDo6R2V0R2xvYmFsUHJvcGVydHkoSVhGQV9Eb2MqIGhEb2MsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENGWF9CeXRlU3RyaW5nQyYgc3pQcm9wTmFtZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlhKU0VfSFZBTFVFIGhWYWx1ZSkgew0KICBpZiAoaERvYyAhPSBtX3BYRkFEb2MpDQogICAgcmV0dXJuIEZBTFNFOw0KICBpZiAoIW1fcFNES0RvYyB8fCAhbV9wU0RLRG9jLT5HZXRFbnYoKS0+R2V0SlNSdW50aW1lKCkpDQogICAgcmV0dXJuIEZBTFNFOw0KDQogIGlmICghbV9wSlNDb250ZXh0KSB7DQogICAgbV9wU0RLRG9jLT5HZXRFbnYoKS0+R2V0SlNSdW50aW1lKCktPlNldFJlYWRlckRvY3VtZW50KG1fcFNES0RvYyk7DQogICAgbV9wSlNDb250ZXh0ID0gbV9wU0RLRG9jLT5HZXRFbnYoKS0+R2V0SlNSdW50aW1lKCktPk5ld0NvbnRleHQoKTsNCiAgfQ0KDQogIHJldHVybiBfR2V0SFZhbHVlQnlOYW1lKHN6UHJvcE5hbWUsIGhWYWx1ZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgbV9wU0RLRG9jLT5HZXRFbnYoKS0+R2V0SlNSdW50aW1lKCkpOw0KfQ0KRlhfQk9PTCBDUERGWEZBX0RvY3VtZW50OjpfR2V0SFZhbHVlQnlOYW1lKGNvbnN0IENGWF9CeXRlU3RyaW5nQyYgdXRmOE5hbWUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlhKU0VfSFZBTFVFIGhWYWx1ZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJSlNfUnVudGltZSogcnVuVGltZSkgew0KICByZXR1cm4gcnVuVGltZS0+R2V0SFZhbHVlQnlOYW1lKHV0ZjhOYW1lLCBoVmFsdWUpOw0KfQ0K