Ly8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KCi8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCgojaW5jbHVkZSAiZnBkZnNkay9pbmNsdWRlL2ZzZGtfZGVmaW5lLmgiCiNpbmNsdWRlICJmcGRmc2RrL2luY2x1ZGUvZnBkZnhmYS9mcGRmeGZhX2RvYy5oIgojaW5jbHVkZSAiZnBkZnNkay9pbmNsdWRlL2ZzZGtfbWdyLmgiCiNpbmNsdWRlICJmcGRmc2RrL2luY2x1ZGUvZnBkZnhmYS9mcGRmeGZhX2FwcC5oIgojaW5jbHVkZSAiZnBkZnNkay9pbmNsdWRlL2ZwZGZ4ZmEvZnBkZnhmYV91dGlsLmgiCiNpbmNsdWRlICJmcGRmc2RrL2luY2x1ZGUvZnBkZnhmYS9mcGRmeGZhX3BhZ2UuaCIKI2luY2x1ZGUgImZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L0lKYXZhU2NyaXB0LmgiCiNpbmNsdWRlICJwdWJsaWMvZnBkZl9mb3JtZmlsbC5oIgoKI2RlZmluZSBJRFNfWEZBX1ZhbGlkYXRlX0lucHV0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICJBdCBsZWFzdCBvbmUgcmVxdWlyZWQgZmllbGQgd2FzIGVtcHR5LiBQbGVhc2UgZmlsbCBpbiB0aGUgcmVxdWlyZWQgIiBcCiAgImZpZWxkc1xyXG4oaGlnaGxpZ2h0ZWQpIGJlZm9yZSBjb250aW51aW5nLiIKCi8vIHN1Ym1pdAojZGVmaW5lIEZYRkFfQ09ORklHIDB4MDAwMDAwMDEKI2RlZmluZSBGWEZBX1RFTVBMQVRFIDB4MDAwMDAwMTAKI2RlZmluZSBGWEZBX0xPQ0FMRVNFVCAweDAwMDAwMTAwCiNkZWZpbmUgRlhGQV9EQVRBU0VUUyAweDAwMDAxMDAwCiNkZWZpbmUgRlhGQV9YTVBNRVRBIDB4MDAwMTAwMDAKI2RlZmluZSBGWEZBX1hGREYgMHgwMDEwMDAwMAojZGVmaW5lIEZYRkFfRk9STSAweDAxMDAwMDAwCiNkZWZpbmUgRlhGQV9QREYgMHgxMDAwMDAwMAoKI2lmbmRlZiBfV0lOMzIKZXh0ZXJuIHZvaWQgU2V0TGFzdEVycm9yKGludCBlcnIpOwoKZXh0ZXJuIGludCBHZXRMYXN0RXJyb3IoKTsKI2VuZGlmCgpDUERGWEZBX0RvY3VtZW50OjpDUERGWEZBX0RvY3VtZW50KENQREZfRG9jdW1lbnQqIHBQREZEb2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1BERlhGQV9BcHAqIHBQcm92aWRlcikKICAgIDogbV9pRG9jVHlwZShET0NUWVBFX1BERiksCiAgICAgIG1fcFBERkRvYyhwUERGRG9jKSwKICAgICAgbV9wU0RLRG9jKG51bGxwdHIpLAogICAgICBtX3BYRkFEb2MobnVsbHB0ciksCiAgICAgIG1fcFhGQURvY1ZpZXcobnVsbHB0ciksCiAgICAgIG1fcEFwcChwUHJvdmlkZXIpLAogICAgICBtX3BKU0NvbnRleHQobnVsbHB0cikgewp9CgpDUERGWEZBX0RvY3VtZW50Ojp+Q1BERlhGQV9Eb2N1bWVudCgpIHsKICBpZiAobV9wWEZBRG9jKSB7CiAgICBJWEZBX0FwcCogcEFwcCA9IG1fcEFwcC0+R2V0WEZBQXBwKCk7CiAgICBpZiAocEFwcCkgewogICAgICBJWEZBX0RvY0hhbmRsZXIqIHBEb2NIYW5kbGVyID0gcEFwcC0+R2V0RG9jSGFuZGxlcigpOwogICAgICBpZiAocERvY0hhbmRsZXIpIHsKICAgICAgICBDbG9zZVhGQURvYyhwRG9jSGFuZGxlcik7CiAgICAgIH0KICAgIH0KICAgIGRlbGV0ZSBtX3BYRkFEb2M7CiAgfQogIGlmIChtX3BKU0NvbnRleHQgJiYgbV9wU0RLRG9jICYmIG1fcFNES0RvYy0+R2V0RW52KCkpCiAgICBtX3BTREtEb2MtPkdldEVudigpLT5HZXRKU1J1bnRpbWUoKS0+UmVsZWFzZUNvbnRleHQobV9wSlNDb250ZXh0KTsKICBkZWxldGUgbV9wU0RLRG9jOwogIGlmIChtX3BQREZEb2MpIHsKICAgIENQREZfUGFyc2VyKiBwUGFyc2VyID0gbV9wUERGRG9jLT5HZXRQYXJzZXIoKTsKICAgIGlmIChwUGFyc2VyKQogICAgICBkZWxldGUgcFBhcnNlcjsKICAgIGVsc2UKICAgICAgZGVsZXRlIG1fcFBERkRvYzsKICB9Cn0KCkZYX0JPT0wgQ1BERlhGQV9Eb2N1bWVudDo6TG9hZFhGQURvYygpIHsKICBpZiAoIW1fcFBERkRvYykKICAgIHJldHVybiBGQUxTRTsKCiAgbV9YRkFQYWdlTGlzdC5SZW1vdmVBbGwoKTsKCiAgSVhGQV9BcHAqIHBBcHAgPSBtX3BBcHAtPkdldFhGQUFwcCgpOwogIGlmICghcEFwcCkKICAgIHJldHVybiBGQUxTRTsKCiAgbV9wWEZBRG9jID0gcEFwcC0+Q3JlYXRlRG9jKHRoaXMsIG1fcFBERkRvYyk7CiAgaWYgKCFtX3BYRkFEb2MpIHsKICAgIFNldExhc3RFcnJvcihGUERGX0VSUl9YRkFMT0FEKTsKICAgIHJldHVybiBGQUxTRTsKICB9CgogIElYRkFfRG9jSGFuZGxlciogcERvY0hhbmRsZXIgPSBwQXBwLT5HZXREb2NIYW5kbGVyKCk7CiAgaWYgKCFwRG9jSGFuZGxlcikgewogICAgU2V0TGFzdEVycm9yKEZQREZfRVJSX1hGQUxPQUQpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KCiAgcERvY0hhbmRsZXItPlN0YXJ0TG9hZChtX3BYRkFEb2MpOwogIGludCBpU3RhdHVzID0gcERvY0hhbmRsZXItPkRvTG9hZChtX3BYRkFEb2MsIE5VTEwpOwogIGlmIChpU3RhdHVzICE9IFhGQV9QQVJTRVNUQVRVU19Eb25lKSB7CiAgICBDbG9zZVhGQURvYyhwRG9jSGFuZGxlcik7CiAgICBTZXRMYXN0RXJyb3IoRlBERl9FUlJfWEZBTE9BRCk7CiAgICByZXR1cm4gRkFMU0U7CiAgfQogIHBEb2NIYW5kbGVyLT5TdG9wTG9hZChtX3BYRkFEb2MpOwogIHBEb2NIYW5kbGVyLT5TZXRKU0VSdW50aW1lKG1fcFhGQURvYywgbV9wQXBwLT5HZXRKU0VSdW50aW1lKCkpOwoKICBpZiAocERvY0hhbmRsZXItPkdldERvY1R5cGUobV9wWEZBRG9jKSA9PSBYRkFfRE9DVFlQRV9EeW5hbWljKQogICAgbV9pRG9jVHlwZSA9IERPQ1RZUEVfRFlOQU1JQ19YRkE7CiAgZWxzZQogICAgbV9pRG9jVHlwZSA9IERPQ1RZUEVfU1RBVElDX1hGQTsKCiAgbV9wWEZBRG9jVmlldyA9IHBEb2NIYW5kbGVyLT5DcmVhdGVEb2NWaWV3KG1fcFhGQURvYywgWEZBX0RPQ1ZJRVdfVmlldyk7CiAgaWYgKG1fcFhGQURvY1ZpZXctPlN0YXJ0TGF5b3V0KCkgPCAwKSB7CiAgICBDbG9zZVhGQURvYyhwRG9jSGFuZGxlcik7CiAgICBTZXRMYXN0RXJyb3IoRlBERl9FUlJfWEZBTEFZT1VUKTsKICAgIHJldHVybiBGQUxTRTsKICB9CgogIG1fcFhGQURvY1ZpZXctPkRvTGF5b3V0KE5VTEwpOwogIG1fcFhGQURvY1ZpZXctPlN0b3BMYXlvdXQoKTsKICByZXR1cm4gVFJVRTsKfQoKaW50IENQREZYRkFfRG9jdW1lbnQ6OkdldFBhZ2VDb3VudCgpIHsKICBpZiAoIW1fcFBERkRvYyAmJiAhbV9wWEZBRG9jKQogICAgcmV0dXJuIDA7CgogIHN3aXRjaCAobV9pRG9jVHlwZSkgewogICAgY2FzZSBET0NUWVBFX1BERjoKICAgIGNhc2UgRE9DVFlQRV9TVEFUSUNfWEZBOgogICAgICBpZiAobV9wUERGRG9jKQogICAgICAgIHJldHVybiBtX3BQREZEb2MtPkdldFBhZ2VDb3VudCgpOwogICAgY2FzZSBET0NUWVBFX0RZTkFNSUNfWEZBOgogICAgICBpZiAobV9wWEZBRG9jKQogICAgICAgIHJldHVybiBtX3BYRkFEb2NWaWV3LT5Db3VudFBhZ2VWaWV3cygpOwogICAgZGVmYXVsdDoKICAgICAgcmV0dXJuIDA7CiAgfQoKICByZXR1cm4gMDsKfQoKQ1BERlhGQV9QYWdlKiBDUERGWEZBX0RvY3VtZW50OjpHZXRQYWdlKGludCBwYWdlX2luZGV4KSB7CiAgaWYgKHBhZ2VfaW5kZXggPCAwKQogICAgcmV0dXJuIG51bGxwdHI7CiAgQ1BERlhGQV9QYWdlKiBwUGFnZSA9IG51bGxwdHI7CiAgaW50IG5Db3VudCA9IG1fWEZBUGFnZUxpc3QuR2V0U2l6ZSgpOwogIGlmIChuQ291bnQgPiAwICYmIHBhZ2VfaW5kZXggPCBuQ291bnQpIHsKICAgIHBQYWdlID0gbV9YRkFQYWdlTGlzdC5HZXRBdChwYWdlX2luZGV4KTsKICAgIGlmIChwUGFnZSkKICAgICAgcFBhZ2UtPkFkZFJlZigpOwogIH0gZWxzZSB7CiAgICBtX1hGQVBhZ2VMaXN0LlNldFNpemUoR2V0UGFnZUNvdW50KCkpOwogIH0KICBpZiAocFBhZ2UpCiAgICByZXR1cm4gcFBhZ2U7CiAgcFBhZ2UgPSBuZXcgQ1BERlhGQV9QYWdlKHRoaXMsIHBhZ2VfaW5kZXgpOwogIGlmICghcFBhZ2UtPkxvYWRQYWdlKCkpIHsKICAgIGRlbGV0ZSBwUGFnZTsKICAgIHJldHVybiBudWxscHRyOwogIH0KICBtX1hGQVBhZ2VMaXN0LlNldEF0KHBhZ2VfaW5kZXgsIHBQYWdlKTsKICByZXR1cm4gcFBhZ2U7Cn0KCkNQREZYRkFfUGFnZSogQ1BERlhGQV9Eb2N1bWVudDo6R2V0UGFnZShJWEZBX1BhZ2VWaWV3KiBwUGFnZSkgewogIGlmICghcFBhZ2UpCiAgICByZXR1cm4gTlVMTDsKCiAgaWYgKCFtX3BYRkFEb2MpCiAgICByZXR1cm4gTlVMTDsKCiAgaWYgKG1faURvY1R5cGUgIT0gRE9DVFlQRV9EWU5BTUlDX1hGQSkKICAgIHJldHVybiBOVUxMOwoKICBpbnQgblNpemUgPSBtX1hGQVBhZ2VMaXN0LkdldFNpemUoKTsKICBmb3IgKGludCBpID0gMDsgaSA8IG5TaXplOyBpKyspIHsKICAgIENQREZYRkFfUGFnZSogcFRlbXBQYWdlID0gbV9YRkFQYWdlTGlzdC5HZXRBdChpKTsKICAgIGlmICghcFRlbXBQYWdlKQogICAgICBjb250aW51ZTsKICAgIGlmIChwVGVtcFBhZ2UtPkdldFhGQVBhZ2VWaWV3KCkgJiYgcFRlbXBQYWdlLT5HZXRYRkFQYWdlVmlldygpID09IHBQYWdlKQogICAgICByZXR1cm4gcFRlbXBQYWdlOwogIH0KCiAgcmV0dXJuIE5VTEw7Cn0KCnZvaWQgQ1BERlhGQV9Eb2N1bWVudDo6UmVtb3ZlUGFnZShDUERGWEZBX1BhZ2UqIHBhZ2UpIHsKICBtX1hGQVBhZ2VMaXN0LlNldEF0KHBhZ2UtPkdldFBhZ2VJbmRleCgpLCBOVUxMKTsKfQoKQ1BERlNES19Eb2N1bWVudCogQ1BERlhGQV9Eb2N1bWVudDo6R2V0U0RLRG9jdW1lbnQoCiAgICBDUERGRG9jX0Vudmlyb25tZW50KiBwRm9ybUZpbGxFbnYpIHsKICBpZiAoIW1fcFNES0RvYyAmJiBwRm9ybUZpbGxFbnYpCiAgICBtX3BTREtEb2MgPSBuZXcgQ1BERlNES19Eb2N1bWVudCh0aGlzLCBwRm9ybUZpbGxFbnYpOwogIHJldHVybiBtX3BTREtEb2M7Cn0KCnZvaWQgQ1BERlhGQV9Eb2N1bWVudDo6RlhSZWN0MlBERlJlY3QoY29uc3QgQ0ZYX1JlY3RGJiBmeFJlY3RGLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENQREZfUmVjdCYgcGRmUmVjdCkgewogIHBkZlJlY3QubGVmdCA9IGZ4UmVjdEYubGVmdDsKICBwZGZSZWN0LnRvcCA9IGZ4UmVjdEYuYm90dG9tKCk7CiAgcGRmUmVjdC5yaWdodCA9IGZ4UmVjdEYucmlnaHQoKTsKICBwZGZSZWN0LmJvdHRvbSA9IGZ4UmVjdEYudG9wOwp9Cgp2b2lkIENQREZYRkFfRG9jdW1lbnQ6OlNldENoYW5nZU1hcmsoSVhGQV9Eb2MqIGhEb2MpIHsKICBpZiAoaERvYyA9PSBtX3BYRkFEb2MgJiYgbV9wU0RLRG9jKSB7CiAgICBtX3BTREtEb2MtPlNldENoYW5nZU1hcmsoKTsKICB9Cn0KCkZYX0JPT0wgQ1BERlhGQV9Eb2N1bWVudDo6R2V0Q2hhbmdlTWFyayhJWEZBX0RvYyogaERvYykgewogIGlmIChoRG9jID09IG1fcFhGQURvYyAmJiBtX3BTREtEb2MpCiAgICByZXR1cm4gbV9wU0RLRG9jLT5HZXRDaGFuZ2VNYXJrKCk7CiAgcmV0dXJuIEZBTFNFOwp9Cgp2b2lkIENQREZYRkFfRG9jdW1lbnQ6OkludmFsaWRhdGVSZWN0KElYRkFfUGFnZVZpZXcqIHBQYWdlVmlldywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDRlhfUmVjdEYmIHJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZYX0RXT1JEIGR3RmxhZ3MgLyogPSAwICovKSB7CiAgaWYgKCFtX3BYRkFEb2MgfHwgIW1fcFNES0RvYykKICAgIHJldHVybjsKCiAgaWYgKG1faURvY1R5cGUgIT0gRE9DVFlQRV9EWU5BTUlDX1hGQSkKICAgIHJldHVybjsKCiAgQ1BERl9SZWN0IHJjUGFnZTsKICBGWFJlY3QyUERGUmVjdChydCwgcmNQYWdlKTsKCiAgQ1BERlhGQV9QYWdlKiBwUGFnZSA9IEdldFBhZ2UocFBhZ2VWaWV3KTsKCiAgaWYgKHBQYWdlID09IE5VTEwpCiAgICByZXR1cm47CgogIENQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BTREtEb2MtPkdldEVudigpOwogIGlmICghcEVudikKICAgIHJldHVybjsKCiAgcEVudi0+RkZJX0ludmFsaWRhdGUoKEZQREZfUEFHRSlwUGFnZSwgcmNQYWdlLmxlZnQsIHJjUGFnZS5ib3R0b20sCiAgICAgICAgICAgICAgICAgICAgICAgcmNQYWdlLnJpZ2h0LCByY1BhZ2UudG9wKTsKfQoKdm9pZCBDUERGWEZBX0RvY3VtZW50OjpJbnZhbGlkYXRlUmVjdChJWEZBX1dpZGdldCogaFdpZGdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGWF9EV09SRCBkd0ZsYWdzIC8qID0gMCAqLykgewogIGlmICghaFdpZGdldCkKICAgIHJldHVybjsKCiAgaWYgKCFtX3BYRkFEb2MgfHwgIW1fcFNES0RvYyB8fCAhbV9wWEZBRG9jVmlldykKICAgIHJldHVybjsKCiAgaWYgKG1faURvY1R5cGUgIT0gRE9DVFlQRV9EWU5BTUlDX1hGQSkKICAgIHJldHVybjsKCiAgSVhGQV9XaWRnZXRIYW5kbGVyKiBwV2lkZ2V0SGFuZGxlciA9IG1fcFhGQURvY1ZpZXctPkdldFdpZGdldEhhbmRsZXIoKTsKICBpZiAoIXBXaWRnZXRIYW5kbGVyKQogICAgcmV0dXJuOwoKICBJWEZBX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSBwV2lkZ2V0SGFuZGxlci0+R2V0UGFnZVZpZXcoaFdpZGdldCk7CiAgaWYgKCFwUGFnZVZpZXcpCiAgICByZXR1cm47CgogIENGWF9SZWN0RiByZWN0OwogIHBXaWRnZXRIYW5kbGVyLT5HZXRSZWN0KGhXaWRnZXQsIHJlY3QpOwogIEludmFsaWRhdGVSZWN0KHBQYWdlVmlldywgcmVjdCwgZHdGbGFncyk7Cn0KCnZvaWQgQ1BERlhGQV9Eb2N1bWVudDo6RGlzcGxheUNhcmV0KElYRkFfV2lkZ2V0KiBoV2lkZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGWF9CT09MIGJWaXNpYmxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDRlhfUmVjdEYqIHBSdEFuY2hvcikgewogIGlmICghaFdpZGdldCB8fCBwUnRBbmNob3IgPT0gTlVMTCkKICAgIHJldHVybjsKCiAgaWYgKCFtX3BYRkFEb2MgfHwgIW1fcFNES0RvYyB8fCAhbV9wWEZBRG9jVmlldykKICAgIHJldHVybjsKCiAgaWYgKG1faURvY1R5cGUgIT0gRE9DVFlQRV9EWU5BTUlDX1hGQSkKICAgIHJldHVybjsKCiAgSVhGQV9XaWRnZXRIYW5kbGVyKiBwV2lkZ2V0SGFuZGxlciA9IG1fcFhGQURvY1ZpZXctPkdldFdpZGdldEhhbmRsZXIoKTsKICBpZiAoIXBXaWRnZXRIYW5kbGVyKQogICAgcmV0dXJuOwoKICBJWEZBX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSBwV2lkZ2V0SGFuZGxlci0+R2V0UGFnZVZpZXcoaFdpZGdldCk7CiAgaWYgKCFwUGFnZVZpZXcpCiAgICByZXR1cm47CgogIENQREZYRkFfUGFnZSogcFBhZ2UgPSBHZXRQYWdlKHBQYWdlVmlldyk7CgogIGlmIChwUGFnZSA9PSBOVUxMKQogICAgcmV0dXJuOwoKICBDUERGX1JlY3QgcmNDYXJldDsKICBGWFJlY3QyUERGUmVjdCgqcFJ0QW5jaG9yLCByY0NhcmV0KTsKCiAgQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IG1fcFNES0RvYy0+R2V0RW52KCk7CiAgaWYgKCFwRW52KQogICAgcmV0dXJuOwoKICBwRW52LT5GRklfRGlzcGxheUNhcmV0KChGUERGX1BBR0UpcFBhZ2UsIGJWaXNpYmxlLCByY0NhcmV0LmxlZnQsIHJjQ2FyZXQudG9wLAogICAgICAgICAgICAgICAgICAgICAgICAgcmNDYXJldC5yaWdodCwgcmNDYXJldC5ib3R0b20pOwp9CgpGWF9CT09MIENQREZYRkFfRG9jdW1lbnQ6OkdldFBvcHVwUG9zKElYRkFfV2lkZ2V0KiBoV2lkZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZYX0ZMT0FUIGZNaW5Qb3B1cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGWF9GTE9BVCBmTWF4UG9wdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ0ZYX1JlY3RGJiBydEFuY2hvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDRlhfUmVjdEYmIHJ0UG9wdXApIHsKICBpZiAoTlVMTCA9PSBoV2lkZ2V0KSB7CiAgICByZXR1cm4gRkFMU0U7CiAgfQogIElYRkFfUGFnZVZpZXcqIHBYRkFQYWdlVmlldyA9CiAgICAgIG1fcFhGQURvY1ZpZXctPkdldFdpZGdldEhhbmRsZXIoKS0+R2V0UGFnZVZpZXcoaFdpZGdldCk7CiAgaWYgKE5VTEwgPT0gcFhGQVBhZ2VWaWV3KSB7CiAgICByZXR1cm4gRkFMU0U7CiAgfQogIENQREZYRkFfUGFnZSogcFBhZ2UgPSBHZXRQYWdlKHBYRkFQYWdlVmlldyk7CiAgaWYgKHBQYWdlID09IE5VTEwpCiAgICByZXR1cm4gRkFMU0U7CgogIENYRkFfV2lkZ2V0QWNjKiBwV2lkZ2V0QWNjID0KICAgICAgbV9wWEZBRG9jVmlldy0+R2V0V2lkZ2V0SGFuZGxlcigpLT5HZXREYXRhQWNjKGhXaWRnZXQpOwoKICBpbnQgblJvdGF0ZSA9IDA7CiNpZmRlZiBQREZfRU5BQkxFX1hGQQogIG5Sb3RhdGUgPSBwV2lkZ2V0QWNjLT5HZXRSb3RhdGUoKTsKI2VuZGlmCgogIENQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BTREtEb2MtPkdldEVudigpOwogIGlmIChwRW52ID09IE5VTEwpCiAgICByZXR1cm4gRkFMU0U7CiAgRlNfUkVDVEYgcGFnZVZpZXdSZWN0OwogIHBFbnYtPkZGSV9HZXRQYWdlVmlld1JlY3QocFBhZ2UsIHBhZ2VWaWV3UmVjdCk7CgogIENQREZfUmVjdCByY0FuY2hvcjsKCiAgcmNBbmNob3IubGVmdCA9IHJ0QW5jaG9yLmxlZnQ7CiAgcmNBbmNob3IudG9wID0gcnRBbmNob3IuYm90dG9tKCk7CiAgcmNBbmNob3IucmlnaHQgPSBydEFuY2hvci5yaWdodCgpOwogIHJjQW5jaG9yLmJvdHRvbSA9IHJ0QW5jaG9yLnRvcDsKCiAgaW50IHQxLCB0MiwgdDsKICBGWF9EV09SRCBkd1BvczsKICBGWF9GTE9BVCBmUG91cEhlaWdodDsKICBzd2l0Y2ggKG5Sb3RhdGUpIHsKICAgIGNhc2UgOTA6IHsKICAgICAgdDEgPSAoaW50KShwYWdlVmlld1JlY3QucmlnaHQgLSByY0FuY2hvci5yaWdodCk7CiAgICAgIHQyID0gKGludCkocmNBbmNob3IubGVmdCAtIHBhZ2VWaWV3UmVjdC5sZWZ0KTsKICAgICAgaWYgKHJjQW5jaG9yLmJvdHRvbSA8IHBhZ2VWaWV3UmVjdC5ib3R0b20pIHsKICAgICAgICBydFBvcHVwLmxlZnQgKz0gcmNBbmNob3IuYm90dG9tIC0gcGFnZVZpZXdSZWN0LmJvdHRvbTsKICAgICAgfQoKICAgICAgYnJlYWs7CiAgICB9CgogICAgY2FzZSAxODA6IHsKICAgICAgdDIgPSAoaW50KShwYWdlVmlld1JlY3QudG9wIC0gcmNBbmNob3IudG9wKTsKICAgICAgdDEgPSAoaW50KShyY0FuY2hvci5ib3R0b20gLSBwYWdlVmlld1JlY3QuYm90dG9tKTsKICAgICAgaWYgKHJjQW5jaG9yLmxlZnQgPCBwYWdlVmlld1JlY3QubGVmdCkgewogICAgICAgIHJ0UG9wdXAubGVmdCArPSByY0FuY2hvci5sZWZ0IC0gcGFnZVZpZXdSZWN0LmxlZnQ7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICB9CiAgICBjYXNlIDI3MDogewogICAgICB0MSA9IChpbnQpKHJjQW5jaG9yLmxlZnQgLSBwYWdlVmlld1JlY3QubGVmdCk7CiAgICAgIHQyID0gKGludCkocGFnZVZpZXdSZWN0LnJpZ2h0IC0gcmNBbmNob3IucmlnaHQpOwoKICAgICAgaWYgKHJjQW5jaG9yLnRvcCA+IHBhZ2VWaWV3UmVjdC50b3ApIHsKICAgICAgICBydFBvcHVwLmxlZnQgLT0gcmNBbmNob3IudG9wIC0gcGFnZVZpZXdSZWN0LnRvcDsKICAgICAgfQogICAgICBicmVhazsKICAgIH0KICAgIGNhc2UgMDoKICAgIGRlZmF1bHQ6IHsKICAgICAgdDEgPSAoaW50KShwYWdlVmlld1JlY3QudG9wIC0gcmNBbmNob3IudG9wKTsKICAgICAgdDIgPSAoaW50KShyY0FuY2hvci5ib3R0b20gLSBwYWdlVmlld1JlY3QuYm90dG9tKTsKICAgICAgaWYgKHJjQW5jaG9yLnJpZ2h0ID4gcGFnZVZpZXdSZWN0LnJpZ2h0KSB7CiAgICAgICAgcnRQb3B1cC5sZWZ0IC09IHJjQW5jaG9yLnJpZ2h0IC0gcGFnZVZpZXdSZWN0LnJpZ2h0OwogICAgICB9CiAgICAgIGJyZWFrOwogICAgfQogIH0KCiAgaWYgKHQxIDw9IDAgJiYgdDIgPD0gMCkgewogICAgcmV0dXJuIEZBTFNFOwogIH0KICBpZiAodDEgPD0gMCkgewogICAgdCA9IHQyOwogICAgZHdQb3MgPSAxOwogIH0gZWxzZSBpZiAodDIgPD0gMCkgewogICAgdCA9IHQxOwogICAgZHdQb3MgPSAwOwogIH0gZWxzZSBpZiAodDEgPiB0MikgewogICAgdCA9IHQxOwogICAgZHdQb3MgPSAwOwogIH0gZWxzZSB7CiAgICB0ID0gdDI7CiAgICBkd1BvcyA9IDE7CiAgfQogIGlmICh0IDwgZk1pblBvcHVwKSB7CiAgICBmUG91cEhlaWdodCA9IGZNaW5Qb3B1cDsKICB9IGVsc2UgaWYgKHQgPiBmTWF4UG9wdXApIHsKICAgIGZQb3VwSGVpZ2h0ID0gZk1heFBvcHVwOwogIH0gZWxzZSB7CiAgICBmUG91cEhlaWdodCA9IChGWF9GTE9BVCl0OwogIH0KCiAgc3dpdGNoIChuUm90YXRlKSB7CiAgICBjYXNlIDA6CiAgICBjYXNlIDE4MDogewogICAgICBpZiAoZHdQb3MgPT0gMCkgewogICAgICAgIHJ0UG9wdXAudG9wID0gcnRBbmNob3IuaGVpZ2h0OwogICAgICAgIHJ0UG9wdXAuaGVpZ2h0ID0gZlBvdXBIZWlnaHQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcnRQb3B1cC50b3AgPSAtZlBvdXBIZWlnaHQ7CiAgICAgICAgcnRQb3B1cC5oZWlnaHQgPSBmUG91cEhlaWdodDsKICAgICAgfQogICAgICBicmVhazsKICAgIH0KICAgIGNhc2UgOTA6CiAgICBjYXNlIDI3MDogewogICAgICBpZiAoZHdQb3MgPT0gMCkgewogICAgICAgIHJ0UG9wdXAudG9wID0gcnRBbmNob3Iud2lkdGg7CiAgICAgICAgcnRQb3B1cC5oZWlnaHQgPSBmUG91cEhlaWdodDsKICAgICAgfSBlbHNlIHsKICAgICAgICBydFBvcHVwLnRvcCA9IC1mUG91cEhlaWdodDsKICAgICAgICBydFBvcHVwLmhlaWdodCA9IGZQb3VwSGVpZ2h0OwogICAgICB9CiAgICAgIGJyZWFrOwogICAgfQogICAgZGVmYXVsdDoKICAgICAgYnJlYWs7CiAgfQoKICByZXR1cm4gVFJVRTsKfQoKRlhfQk9PTCBDUERGWEZBX0RvY3VtZW50OjpQb3B1cE1lbnUoSVhGQV9XaWRnZXQqIGhXaWRnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENGWF9Qb2ludEYgcHRQb3B1cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ0ZYX1JlY3RGKiBwUmVjdEV4Y2x1ZGUpIHsKICBpZiAoTlVMTCA9PSBoV2lkZ2V0KSB7CiAgICByZXR1cm4gRkFMU0U7CiAgfQogIElYRkFfUGFnZVZpZXcqIHBYRkFQYWdlVmlldyA9CiAgICAgIG1fcFhGQURvY1ZpZXctPkdldFdpZGdldEhhbmRsZXIoKS0+R2V0UGFnZVZpZXcoaFdpZGdldCk7CiAgaWYgKHBYRkFQYWdlVmlldyA9PSBOVUxMKQogICAgcmV0dXJuIEZBTFNFOwogIENQREZYRkFfUGFnZSogcFBhZ2UgPSBHZXRQYWdlKHBYRkFQYWdlVmlldyk7CgogIGlmIChwUGFnZSA9PSBOVUxMKQogICAgcmV0dXJuIEZBTFNFOwoKICBpbnQgbWVudUZsYWcgPSAwOwoKICBJWEZBX01lbnVIYW5kbGVyKiBwWEZBTWVudUhhbmRlciA9IG1fcEFwcC0+R2V0WEZBQXBwKCktPkdldE1lbnVIYW5kbGVyKCk7CiAgaWYgKHBYRkFNZW51SGFuZGVyLT5DYW5VbmRvKGhXaWRnZXQpKQogICAgbWVudUZsYWcgfD0gRlhGQV9NRU1VX1VORE87CiAgaWYgKHBYRkFNZW51SGFuZGVyLT5DYW5SZWRvKGhXaWRnZXQpKQogICAgbWVudUZsYWcgfD0gRlhGQV9NRU1VX1JFRE87CiAgaWYgKHBYRkFNZW51SGFuZGVyLT5DYW5QYXN0ZShoV2lkZ2V0KSkKICAgIG1lbnVGbGFnIHw9IEZYRkFfTUVNVV9QQVNURTsKICBpZiAocFhGQU1lbnVIYW5kZXItPkNhbkNvcHkoaFdpZGdldCkpCiAgICBtZW51RmxhZyB8PSBGWEZBX01FTVVfQ09QWTsKICBpZiAocFhGQU1lbnVIYW5kZXItPkNhbkN1dChoV2lkZ2V0KSkKICAgIG1lbnVGbGFnIHw9IEZYRkFfTUVNVV9DVVQ7CiAgaWYgKHBYRkFNZW51SGFuZGVyLT5DYW5TZWxlY3RBbGwoaFdpZGdldCkpCiAgICBtZW51RmxhZyB8PSBGWEZBX01FTVVfU0VMRUNUQUxMOwoKICBDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wU0RLRG9jLT5HZXRFbnYoKTsKICBpZiAocEVudiA9PSBOVUxMKQogICAgcmV0dXJuIEZBTFNFOwoKICByZXR1cm4gcEVudi0+RkZJX1BvcHVwTWVudShwUGFnZSwgaFdpZGdldCwgbWVudUZsYWcsIHB0UG9wdXAsIE5VTEwpOwp9Cgp2b2lkIENQREZYRkFfRG9jdW1lbnQ6OlBhZ2VWaWV3RXZlbnQoSVhGQV9QYWdlVmlldyogcFBhZ2VWaWV3LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlhfRFdPUkQgZHdGbGFncykgewogIGlmICghcFBhZ2VWaWV3IHx8IChkd0ZsYWdzICE9IFhGQV9QQUdFVklFV0VWRU5UX1Bvc3RBZGRlZCAmJgogICAgICAgICAgICAgICAgICAgICBkd0ZsYWdzICE9IFhGQV9QQUdFVklFV0VWRU5UX1Bvc3RSZW1vdmVkKSkgewogICAgcmV0dXJuOwogIH0KICBDUERGWEZBX1BhZ2UqIHBQYWdlID0gbnVsbHB0cjsKICBDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wU0RLRG9jLT5HZXRFbnYoKTsKICBpZiAoZHdGbGFncyA9PSBYRkFfUEFHRVZJRVdFVkVOVF9Qb3N0QWRkZWQpIHsKICAgIGludCBuUGFnZUluZGV4ID0gcFBhZ2VWaWV3LT5HZXRQYWdlVmlld0luZGV4KCk7CiAgICBwUGFnZSA9IEdldFBhZ2UoblBhZ2VJbmRleCk7CiAgICBpZiAocFBhZ2UpCiAgICAgIHBQYWdlLT5TZXRYRkFQYWdlVmlldyhwUGFnZVZpZXcpOwogICAgcEVudi0+RkZJX1BhZ2VFdmVudChuUGFnZUluZGV4LCBkd0ZsYWdzKTsKICAgIHJldHVybjsKICB9CiAgcFBhZ2UgPSBHZXRQYWdlKHBQYWdlVmlldyk7CiAgaWYgKCFwUGFnZSkKICAgIHJldHVybjsKICBwRW52LT5GRklfUGFnZUV2ZW50KHBQYWdlLT5HZXRQYWdlSW5kZXgoKSwgZHdGbGFncyk7CiAgcFBhZ2UtPlJlbGVhc2UoKTsKfQoKdm9pZCBDUERGWEZBX0RvY3VtZW50OjpXaWRnZXRFdmVudChJWEZBX1dpZGdldCogaFdpZGdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDWEZBX1dpZGdldEFjYyogcFdpZGdldERhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlhfRFdPUkQgZHdFdmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkKiBwUGFyYW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCogcEFkZGl0aW9uYWwpIHsKICBpZiAobV9pRG9jVHlwZSAhPSBET0NUWVBFX0RZTkFNSUNfWEZBIHx8ICFoV2lkZ2V0KQogICAgcmV0dXJuOwoKICBDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wU0RLRG9jLT5HZXRFbnYoKTsKICBpZiAoIXBFbnYpCiAgICByZXR1cm47CgogIElYRkFfUGFnZVZpZXcqIHBQYWdlVmlldyA9CiAgICAgIG1fcFhGQURvY1ZpZXctPkdldFdpZGdldEhhbmRsZXIoKS0+R2V0UGFnZVZpZXcoaFdpZGdldCk7CiAgaWYgKHBQYWdlVmlldyA9PSBOVUxMKQogICAgcmV0dXJuOwoKICBDUERGWEZBX1BhZ2UqIHBYRkFQYWdlID0gR2V0UGFnZShwUGFnZVZpZXcpOwogIGlmIChwWEZBUGFnZSA9PSBOVUxMKQogICAgcmV0dXJuOwoKICBDUERGU0RLX1BhZ2VWaWV3KiBwU2RrUGFnZVZpZXcgPSBtX3BTREtEb2MtPkdldFBhZ2VWaWV3KHBYRkFQYWdlKTsKICBpZiAoZHdFdmVudCA9PSBYRkFfV0lER0VURVZFTlRfUG9zdEFkZGVkKSB7CiAgICBwU2RrUGFnZVZpZXctPkFkZEFubm90KGhXaWRnZXQpOwoKICB9IGVsc2UgaWYgKGR3RXZlbnQgPT0gWEZBX1dJREdFVEVWRU5UX1ByZVJlbW92ZWQpIHsKICAgIENQREZTREtfQW5ub3QqIHBBbm5vdCA9IHBTZGtQYWdlVmlldy0+R2V0QW5ub3RCeVhGQVdpZGdldChoV2lkZ2V0KTsKICAgIGlmIChwQW5ub3QpIHsKICAgICAgcFNka1BhZ2VWaWV3LT5EZWxldGVBbm5vdChwQW5ub3QpOwogICAgfQogIH0KfQoKaW50MzJfdCBDUERGWEZBX0RvY3VtZW50OjpDb3VudFBhZ2VzKElYRkFfRG9jKiBoRG9jKSB7CiAgaWYgKGhEb2MgPT0gbV9wWEZBRG9jICYmIG1fcFNES0RvYykgewogICAgcmV0dXJuIEdldFBhZ2VDb3VudCgpOwogIH0KICByZXR1cm4gMDsKfQppbnQzMl90IENQREZYRkFfRG9jdW1lbnQ6OkdldEN1cnJlbnRQYWdlKElYRkFfRG9jKiBoRG9jKSB7CiAgaWYgKGhEb2MgIT0gbV9wWEZBRG9jIHx8ICFtX3BTREtEb2MpCiAgICByZXR1cm4gLTE7CiAgaWYgKG1faURvY1R5cGUgIT0gRE9DVFlQRV9EWU5BTUlDX1hGQSkKICAgIHJldHVybiAtMTsKCiAgQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IG1fcFNES0RvYy0+R2V0RW52KCk7CiAgaWYgKHBFbnYgPT0gTlVMTCkKICAgIHJldHVybiAtMTsKCiAgcmV0dXJuIHBFbnYtPkZGSV9HZXRDdXJyZW50UGFnZUluZGV4KHRoaXMpOwp9CnZvaWQgQ1BERlhGQV9Eb2N1bWVudDo6U2V0Q3VycmVudFBhZ2UoSVhGQV9Eb2MqIGhEb2MsIGludDMyX3QgaUN1clBhZ2UpIHsKICBpZiAoaERvYyAhPSBtX3BYRkFEb2MgfHwgIW1fcFNES0RvYyB8fCBtX2lEb2NUeXBlICE9IERPQ1RZUEVfRFlOQU1JQ19YRkEgfHwKICAgICAgaUN1clBhZ2UgPCAwIHx8IGlDdXJQYWdlID49IG1fcFNES0RvYy0+R2V0UGFnZUNvdW50KCkpIHsKICAgIHJldHVybjsKICB9CiAgQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IG1fcFNES0RvYy0+R2V0RW52KCk7CiAgaWYgKCFwRW52KQogICAgcmV0dXJuOwogIHBFbnYtPkZGSV9TZXRDdXJyZW50UGFnZSh0aGlzLCBpQ3VyUGFnZSk7Cn0KRlhfQk9PTCBDUERGWEZBX0RvY3VtZW50OjpJc0NhbGN1bGF0aW9uc0VuYWJsZWQoSVhGQV9Eb2MqIGhEb2MpIHsKICBpZiAoaERvYyAhPSBtX3BYRkFEb2MgfHwgIW1fcFNES0RvYykKICAgIHJldHVybiBGQUxTRTsKICBpZiAobV9wU0RLRG9jLT5HZXRJbnRlckZvcm0oKSkKICAgIHJldHVybiBtX3BTREtEb2MtPkdldEludGVyRm9ybSgpLT5Jc1hmYUNhbGN1bGF0ZUVuYWJsZWQoKTsKCiAgcmV0dXJuIEZBTFNFOwp9CnZvaWQgQ1BERlhGQV9Eb2N1bWVudDo6U2V0Q2FsY3VsYXRpb25zRW5hYmxlZChJWEZBX0RvYyogaERvYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZYX0JPT0wgYkVuYWJsZWQpIHsKICBpZiAoaERvYyAhPSBtX3BYRkFEb2MgfHwgIW1fcFNES0RvYykKICAgIHJldHVybjsKICBpZiAobV9wU0RLRG9jLT5HZXRJbnRlckZvcm0oKSkKICAgIG1fcFNES0RvYy0+R2V0SW50ZXJGb3JtKCktPlhmYUVuYWJsZUNhbGN1bGF0ZShiRW5hYmxlZCk7Cn0KCnZvaWQgQ1BERlhGQV9Eb2N1bWVudDo6R2V0VGl0bGUoSVhGQV9Eb2MqIGhEb2MsIENGWF9XaWRlU3RyaW5nJiB3c1RpdGxlKSB7CiAgaWYgKGhEb2MgIT0gbV9wWEZBRG9jKQogICAgcmV0dXJuOwogIGlmIChtX3BQREZEb2MgPT0gTlVMTCkKICAgIHJldHVybjsKICBDUERGX0RpY3Rpb25hcnkqIHBJbmZvRGljdCA9IG1fcFBERkRvYy0+R2V0SW5mbygpOwoKICBpZiAocEluZm9EaWN0ID09IE5VTEwpCiAgICByZXR1cm47CgogIENGWF9CeXRlU3RyaW5nIGNzVGl0bGUgPSBwSW5mb0RpY3QtPkdldFN0cmluZ0J5KCJUaXRsZSIpOwogIHdzVGl0bGUgPSB3c1RpdGxlLkZyb21Mb2NhbChjc1RpdGxlLkdldEJ1ZmZlcihjc1RpdGxlLkdldExlbmd0aCgpKSk7CiAgY3NUaXRsZS5SZWxlYXNlQnVmZmVyKGNzVGl0bGUuR2V0TGVuZ3RoKCkpOwp9CnZvaWQgQ1BERlhGQV9Eb2N1bWVudDo6U2V0VGl0bGUoSVhGQV9Eb2MqIGhEb2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ0ZYX1dpZGVTdHJpbmdDJiB3c1RpdGxlKSB7CiAgaWYgKGhEb2MgIT0gbV9wWEZBRG9jKQogICAgcmV0dXJuOwogIGlmIChtX3BQREZEb2MgPT0gTlVMTCkKICAgIHJldHVybjsKICBDUERGX0RpY3Rpb25hcnkqIHBJbmZvRGljdCA9IG1fcFBERkRvYy0+R2V0SW5mbygpOwoKICBpZiAocEluZm9EaWN0ID09IE5VTEwpCiAgICByZXR1cm47CiAgcEluZm9EaWN0LT5TZXRBdCgiVGl0bGUiLCBuZXcgQ1BERl9TdHJpbmcod3NUaXRsZSkpOwp9CnZvaWQgQ1BERlhGQV9Eb2N1bWVudDo6RXhwb3J0RGF0YShJWEZBX0RvYyogaERvYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENGWF9XaWRlU3RyaW5nQyYgd3NGaWxlUGF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZYX0JPT0wgYlhEUCkgewogIGlmIChoRG9jICE9IG1fcFhGQURvYykKICAgIHJldHVybjsKICBpZiAobV9pRG9jVHlwZSAhPSBET0NUWVBFX0RZTkFNSUNfWEZBICYmIG1faURvY1R5cGUgIT0gRE9DVFlQRV9TVEFUSUNfWEZBKQogICAgcmV0dXJuOwogIENQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BTREtEb2MtPkdldEVudigpOwogIGlmIChwRW52ID09IE5VTEwpCiAgICByZXR1cm47CiAgaW50IGZpbGVUeXBlID0gYlhEUCA/IEZYRkFfU0FWRUFTX1hEUCA6IEZYRkFfU0FWRUFTX1hNTDsKICBDRlhfQnl0ZVN0cmluZyBicyA9IENGWF9XaWRlU3RyaW5nKHdzRmlsZVBhdGgpLlVURjE2TEVfRW5jb2RlKCk7CgogIGlmICh3c0ZpbGVQYXRoLklzRW1wdHkoKSkgewogICAgaWYgKCFwRW52LT5HZXRGb3JtRmlsbEluZm8oKSB8fAogICAgICAgIHBFbnYtPkdldEZvcm1GaWxsSW5mbygpLT5tX3BKc1BsYXRmb3JtID09IE5VTEwpCiAgICAgIHJldHVybjsKICAgIENGWF9XaWRlU3RyaW5nIGZpbGVwYXRoID0gcEVudi0+SlNfZmllbGRCcm93c2UoKTsKICAgIGJzID0gZmlsZXBhdGguVVRGMTZMRV9FbmNvZGUoKTsKICB9CiAgaW50IGxlbiA9IGJzLkdldExlbmd0aCgpIC8gc2l6ZW9mKHVuc2lnbmVkIHNob3J0KTsKICBGUERGX0ZJTEVIQU5ETEVSKiBwRmlsZUhhbmRsZXIgPSBwRW52LT5GRklfT3BlbkZpbGUoCiAgICAgIGJYRFAgPyBGWEZBX1NBVkVBU19YRFAgOiBGWEZBX1NBVkVBU19YTUwsCiAgICAgIChGUERGX1dJREVTVFJJTkcpYnMuR2V0QnVmZmVyKGxlbiAqIHNpemVvZih1bnNpZ25lZCBzaG9ydCkpLCAid2IiKTsKICBicy5SZWxlYXNlQnVmZmVyKGxlbiAqIHNpemVvZih1bnNpZ25lZCBzaG9ydCkpOwoKICBpZiAocEZpbGVIYW5kbGVyID09IE5VTEwpCiAgICByZXR1cm47CgogIENGUERGX0ZpbGVTdHJlYW0gZmlsZVdyaXRlKHBGaWxlSGFuZGxlcik7CgogIElYRkFfRG9jSGFuZGxlciogcFhGQURvY0hhbmRlciA9IG1fcEFwcC0+R2V0WEZBQXBwKCktPkdldERvY0hhbmRsZXIoKTsKICBDRlhfQnl0ZVN0cmluZyBjb250ZW50OwogIGlmIChmaWxlVHlwZSA9PSBGWEZBX1NBVkVBU19YTUwpIHsKICAgIGNvbnRlbnQgPSAiPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiVVRGLThcIj8+XHJcbiI7CiAgICBmaWxlV3JpdGUuV3JpdGVCbG9jaygoY29uc3QgRlhfQ0hBUiopY29udGVudCwgZmlsZVdyaXRlLkdldFNpemUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQuR2V0TGVuZ3RoKCkpOwogICAgQ0ZYX1dpZGVTdHJpbmdDIGRhdGEoTCJkYXRhIik7CiAgICBpZiAocFhGQURvY0hhbmRlci0+U2F2ZVBhY2thZ2UobV9wWEZBRG9jVmlldy0+R2V0RG9jKCksIGRhdGEsICZmaWxlV3JpdGUpKSB7CiAgICAgIC8vIFRPRE86IE1heWJlIHJlcG9ydCBlcnJvci4KICAgIH0KICB9IGVsc2UgaWYgKGZpbGVUeXBlID09IEZYRkFfU0FWRUFTX1hEUCkgewogICAgaWYgKG1fcFBERkRvYyA9PSBOVUxMKQogICAgICByZXR1cm47CiAgICBDUERGX0RpY3Rpb25hcnkqIHBSb290ID0gbV9wUERGRG9jLT5HZXRSb290KCk7CiAgICBpZiAocFJvb3QgPT0gTlVMTCkKICAgICAgcmV0dXJuOwogICAgQ1BERl9EaWN0aW9uYXJ5KiBwQWNyb0Zvcm0gPSBwUm9vdC0+R2V0RGljdEJ5KCJBY3JvRm9ybSIpOwogICAgaWYgKE5VTEwgPT0gcEFjcm9Gb3JtKQogICAgICByZXR1cm47CiAgICBDUERGX09iamVjdCogcFhGQSA9IHBBY3JvRm9ybS0+R2V0RWxlbWVudCgiWEZBIik7CiAgICBpZiAocFhGQSA9PSBOVUxMKQogICAgICByZXR1cm47CiAgICBpZiAoIXBYRkEtPklzQXJyYXkoKSkKICAgICAgcmV0dXJuOwogICAgQ1BERl9BcnJheSogcEFycmF5ID0gcFhGQS0+R2V0QXJyYXkoKTsKICAgIGlmIChOVUxMID09IHBBcnJheSkKICAgICAgcmV0dXJuOwogICAgaW50IHNpemUgPSBwQXJyYXktPkdldENvdW50KCk7CiAgICBmb3IgKGludCBpID0gMTsgaSA8IHNpemU7IGkgKz0gMikgewogICAgICBDUERGX09iamVjdCogcFBERk9iaiA9IHBBcnJheS0+R2V0RWxlbWVudChpKTsKICAgICAgQ1BERl9PYmplY3QqIHBQcmVQREZPYmogPSBwQXJyYXktPkdldEVsZW1lbnQoaSAtIDEpOwogICAgICBpZiAoIXBQcmVQREZPYmotPklzU3RyaW5nKCkpCiAgICAgICAgY29udGludWU7CiAgICAgIGlmICghcFBERk9iai0+SXNSZWZlcmVuY2UoKSkKICAgICAgICBjb250aW51ZTsKICAgICAgQ1BERl9PYmplY3QqIHBEaXJlY3RPYmogPSBwUERGT2JqLT5HZXREaXJlY3QoKTsKICAgICAgaWYgKCFwRGlyZWN0T2JqLT5Jc1N0cmVhbSgpKQogICAgICAgIGNvbnRpbnVlOwogICAgICBpZiAocFByZVBERk9iai0+R2V0U3RyaW5nKCkgPT0gImZvcm0iKSB7CiAgICAgICAgQ0ZYX1dpZGVTdHJpbmdDIGZvcm0oTCJmb3JtIik7CiAgICAgICAgcFhGQURvY0hhbmRlci0+U2F2ZVBhY2thZ2UobV9wWEZBRG9jVmlldy0+R2V0RG9jKCksIGZvcm0sICZmaWxlV3JpdGUpOwogICAgICB9IGVsc2UgaWYgKHBQcmVQREZPYmotPkdldFN0cmluZygpID09ICJkYXRhc2V0cyIpIHsKICAgICAgICBDRlhfV2lkZVN0cmluZ0MgZGF0YXNldHMoTCJkYXRhc2V0cyIpOwogICAgICAgIHBYRkFEb2NIYW5kZXItPlNhdmVQYWNrYWdlKG1fcFhGQURvY1ZpZXctPkdldERvYygpLCBkYXRhc2V0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZmlsZVdyaXRlKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAoaSA9PSBzaXplIC0gMSkgewogICAgICAgICAgQ0ZYX1dpZGVTdHJpbmcgd1BhdGggPSBDRlhfV2lkZVN0cmluZzo6RnJvbVVURjE2TEUoCiAgICAgICAgICAgICAgKHVuc2lnbmVkIHNob3J0KikoY29uc3QgRlhfQ0hBUiopYnMsCiAgICAgICAgICAgICAgYnMuR2V0TGVuZ3RoKCkgLyBzaXplb2YodW5zaWduZWQgc2hvcnQpKTsKICAgICAgICAgIENGWF9CeXRlU3RyaW5nIGJQYXRoID0gd1BhdGguVVRGOEVuY29kZSgpOwogICAgICAgICAgQ0ZYX0J5dGVTdHJpbmcgc3pGb3JtYXQgPQogICAgICAgICAgICAgICJcbjxwZGYgaHJlZj1cIiVzXCIgeG1sbnM9XCJodHRwOi8vbnMuYWRvYmUuY29tL3hkcC9wZGYvXCIvPiI7CiAgICAgICAgICBjb250ZW50LkZvcm1hdChzekZvcm1hdCwgKGNoYXIqKShjb25zdCBGWF9DSEFSKiliUGF0aCk7CiAgICAgICAgICBmaWxlV3JpdGUuV3JpdGVCbG9jaygoY29uc3QgRlhfQ0hBUiopY29udGVudCwgZmlsZVdyaXRlLkdldFNpemUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQuR2V0TGVuZ3RoKCkpOwogICAgICAgIH0KCiAgICAgICAgQ1BERl9TdHJlYW0qIHBTdHJlYW0gPSAoQ1BERl9TdHJlYW0qKXBEaXJlY3RPYmo7CiAgICAgICAgQ1BERl9TdHJlYW1BY2MqIHBBY2MgPSBuZXcgQ1BERl9TdHJlYW1BY2M7CiAgICAgICAgcEFjYy0+TG9hZEFsbERhdGEocFN0cmVhbSk7CiAgICAgICAgZmlsZVdyaXRlLldyaXRlQmxvY2socEFjYy0+R2V0RGF0YSgpLCBmaWxlV3JpdGUuR2V0U2l6ZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBBY2MtPkdldFNpemUoKSk7CiAgICAgICAgZGVsZXRlIHBBY2M7CiAgICAgIH0KICAgIH0KICB9CiAgaWYgKCFmaWxlV3JpdGUuRmx1c2goKSkgewogICAgLy8gVE9ETzogUmVwb3J0IGVycm9yLgogIH0KfQp2b2lkIENQREZYRkFfRG9jdW1lbnQ6OkltcG9ydERhdGEoSVhGQV9Eb2MqIGhEb2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDRlhfV2lkZVN0cmluZ0MmIHdzRmlsZVBhdGgpIHsKICAvLyBUT0RPLi4uCn0KCnZvaWQgQ1BERlhGQV9Eb2N1bWVudDo6R290b1VSTChJWEZBX0RvYyogaERvYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENGWF9XaWRlU3RyaW5nQyYgYnNVUkwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGWF9CT09MIGJBcHBlbmQpIHsKICBpZiAoaERvYyAhPSBtX3BYRkFEb2MpCiAgICByZXR1cm47CgogIGlmIChtX2lEb2NUeXBlICE9IERPQ1RZUEVfRFlOQU1JQ19YRkEpCiAgICByZXR1cm47CgogIENQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BTREtEb2MtPkdldEVudigpOwogIGlmIChwRW52ID09IE5VTEwpCiAgICByZXR1cm47CgogIENGWF9XaWRlU3RyaW5nQyBzdHIoYnNVUkwuR2V0UHRyKCkpOwoKICBwRW52LT5GRklfR290b1VSTCh0aGlzLCBzdHIsIGJBcHBlbmQpOwp9CgpGWF9CT09MIENQREZYRkFfRG9jdW1lbnQ6OklzVmFsaWRhdGlvbnNFbmFibGVkKElYRkFfRG9jKiBoRG9jKSB7CiAgaWYgKGhEb2MgIT0gbV9wWEZBRG9jIHx8ICFtX3BTREtEb2MpCiAgICByZXR1cm4gRkFMU0U7CiAgaWYgKG1fcFNES0RvYy0+R2V0SW50ZXJGb3JtKCkpCiAgICByZXR1cm4gbV9wU0RLRG9jLT5HZXRJbnRlckZvcm0oKS0+SXNYZmFWYWxpZGF0aW9uc0VuYWJsZWQoKTsKCiAgcmV0dXJuIFRSVUU7Cn0Kdm9pZCBDUERGWEZBX0RvY3VtZW50OjpTZXRWYWxpZGF0aW9uc0VuYWJsZWQoSVhGQV9Eb2MqIGhEb2MsIEZYX0JPT0wgYkVuYWJsZWQpIHsKICBpZiAoaERvYyAhPSBtX3BYRkFEb2MgfHwgIW1fcFNES0RvYykKICAgIHJldHVybjsKICBpZiAobV9wU0RLRG9jLT5HZXRJbnRlckZvcm0oKSkKICAgIG1fcFNES0RvYy0+R2V0SW50ZXJGb3JtKCktPlhmYVNldFZhbGlkYXRpb25zRW5hYmxlZChiRW5hYmxlZCk7Cn0Kdm9pZCBDUERGWEZBX0RvY3VtZW50OjpTZXRGb2N1c1dpZGdldChJWEZBX0RvYyogaERvYywgSVhGQV9XaWRnZXQqIGhXaWRnZXQpIHsKICBpZiAoaERvYyAhPSBtX3BYRkFEb2MpCiAgICByZXR1cm47CgogIGlmIChOVUxMID09IGhXaWRnZXQpIHsKICAgIG1fcFNES0RvYy0+U2V0Rm9jdXNBbm5vdChOVUxMKTsKICAgIHJldHVybjsKICB9CgogIGludCBwYWdlVmlld0NvdW50ID0gbV9wU0RLRG9jLT5HZXRQYWdlVmlld0NvdW50KCk7CiAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWdlVmlld0NvdW50OyBpKyspIHsKICAgIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyA9IG1fcFNES0RvYy0+R2V0UGFnZVZpZXcoaSk7CiAgICBpZiAocFBhZ2VWaWV3ID09IE5VTEwpCiAgICAgIGNvbnRpbnVlOwogICAgQ1BERlNES19Bbm5vdCogcEFubm90ID0gcFBhZ2VWaWV3LT5HZXRBbm5vdEJ5WEZBV2lkZ2V0KGhXaWRnZXQpOwogICAgaWYgKHBBbm5vdCkgewogICAgICBtX3BTREtEb2MtPlNldEZvY3VzQW5ub3QocEFubm90KTsKICAgICAgYnJlYWs7CiAgICB9CiAgfQp9CnZvaWQgQ1BERlhGQV9Eb2N1bWVudDo6UHJpbnQoSVhGQV9Eb2MqIGhEb2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBuU3RhcnRQYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgbkVuZFBhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlhfRFdPUkQgZHdPcHRpb25zKSB7CiAgaWYgKGhEb2MgIT0gbV9wWEZBRG9jKQogICAgcmV0dXJuOwoKICBDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wU0RLRG9jLT5HZXRFbnYoKTsKICBpZiAocEVudiA9PSBOVUxMKQogICAgcmV0dXJuOwoKICBpZiAoIXBFbnYtPkdldEZvcm1GaWxsSW5mbygpIHx8CiAgICAgIHBFbnYtPkdldEZvcm1GaWxsSW5mbygpLT5tX3BKc1BsYXRmb3JtID09IE5VTEwpCiAgICByZXR1cm47CiAgaWYgKHBFbnYtPkdldEZvcm1GaWxsSW5mbygpLT5tX3BKc1BsYXRmb3JtLT5Eb2NfcHJpbnQgPT0gTlVMTCkKICAgIHJldHVybjsKICBwRW52LT5HZXRGb3JtRmlsbEluZm8oKS0+bV9wSnNQbGF0Zm9ybS0+RG9jX3ByaW50KAogICAgICBwRW52LT5HZXRGb3JtRmlsbEluZm8oKS0+bV9wSnNQbGF0Zm9ybSwKICAgICAgZHdPcHRpb25zICYgWEZBX1BSSU5UT1BUX1Nob3dEaWFsb2csIG5TdGFydFBhZ2UsIG5FbmRQYWdlLAogICAgICBkd09wdGlvbnMgJiBYRkFfUFJJTlRPUFRfQ2FuQ2FuY2VsLCBkd09wdGlvbnMgJiBYRkFfUFJJTlRPUFRfU2hyaW5rUGFnZSwKICAgICAgZHdPcHRpb25zICYgWEZBX1BSSU5UT1BUX0FzSW1hZ2UsIGR3T3B0aW9ucyAmIFhGQV9QUklOVE9QVF9SZXZlcnNlT3JkZXIsCiAgICAgIGR3T3B0aW9ucyAmIFhGQV9QUklOVE9QVF9QcmludEFubm90KTsKfQoKdm9pZCBDUERGWEZBX0RvY3VtZW50OjpHZXRVUkwoSVhGQV9Eb2MqIGhEb2MsIENGWF9XaWRlU3RyaW5nJiB3c0RvY1VSTCkgewogIGlmIChoRG9jICE9IG1fcFhGQURvYykKICAgIHJldHVybjsKCiAgQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IG1fcFNES0RvYy0+R2V0RW52KCk7CiAgaWYgKHBFbnYgPT0gTlVMTCkKICAgIHJldHVybjsKCiAgcEVudi0+RkZJX0dldFVSTCh0aGlzLCB3c0RvY1VSTCk7Cn0KCkZYX0FSR0IgQ1BERlhGQV9Eb2N1bWVudDo6R2V0SGlnaGxpZ2h0Q29sb3IoSVhGQV9Eb2MqIGhEb2MpIHsKICBpZiAoaERvYyAhPSBtX3BYRkFEb2MpCiAgICByZXR1cm4gMDsKICBpZiAobV9wU0RLRG9jKSB7CiAgICBpZiAoQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0gPSBtX3BTREtEb2MtPkdldEludGVyRm9ybSgpKSB7CiAgICAgIEZYX0NPTE9SUkVGIGNvbG9yID0gcEludGVyRm9ybS0+R2V0SGlnaGxpZ2h0Q29sb3IoRlBERl9GT1JNRklFTERfWEZBKTsKICAgICAgdWludDhfdCBhbHBoYSA9IHBJbnRlckZvcm0tPkdldEhpZ2hsaWdodEFscGhhKCk7CiAgICAgIEZYX0FSR0IgYXJnYiA9IEFyZ2JFbmNvZGUoKGludClhbHBoYSwgY29sb3IpOwogICAgICByZXR1cm4gYXJnYjsKICAgIH0KICB9CiAgcmV0dXJuIDA7Cn0KCkZYX0JPT0wgQ1BERlhGQV9Eb2N1bWVudDo6X05vdGlmeVN1Ym1pdChGWF9CT09MIGJQcmV2T3JQb3N0KSB7CiAgaWYgKGJQcmV2T3JQb3N0KQogICAgcmV0dXJuIF9PbkJlZm9yZU5vdGlmeVN1bWJpdCgpOwoKICBfT25BZnRlck5vdGlmeVN1bWJpdCgpOwogIHJldHVybiBUUlVFOwp9CgpGWF9CT09MIENQREZYRkFfRG9jdW1lbnQ6Ol9PbkJlZm9yZU5vdGlmeVN1bWJpdCgpIHsKI2lmZGVmIFBERl9FTkFCTEVfWEZBCiAgaWYgKG1faURvY1R5cGUgIT0gRE9DVFlQRV9EWU5BTUlDX1hGQSAmJiBtX2lEb2NUeXBlICE9IERPQ1RZUEVfU1RBVElDX1hGQSkKICAgIHJldHVybiBUUlVFOwogIGlmIChtX3BYRkFEb2NWaWV3ID09IE5VTEwpCiAgICByZXR1cm4gVFJVRTsKICBJWEZBX1dpZGdldEhhbmRsZXIqIHBXaWRnZXRIYW5kbGVyID0gbV9wWEZBRG9jVmlldy0+R2V0V2lkZ2V0SGFuZGxlcigpOwogIGlmIChwV2lkZ2V0SGFuZGxlciA9PSBOVUxMKQogICAgcmV0dXJuIFRSVUU7CiAgSVhGQV9XaWRnZXRBY2NJdGVyYXRvciogcFdpZGdldEFjY0l0ZXJhdG9yID0KICAgICAgbV9wWEZBRG9jVmlldy0+Q3JlYXRlV2lkZ2V0QWNjSXRlcmF0b3IoKTsKICBpZiAocFdpZGdldEFjY0l0ZXJhdG9yKSB7CiAgICBDWEZBX0V2ZW50UGFyYW0gUGFyYW07CiAgICBQYXJhbS5tX2VUeXBlID0gWEZBX0VWRU5UX1ByZVN1Ym1pdDsKICAgIENYRkFfV2lkZ2V0QWNjKiBwV2lkZ2V0QWNjID0gcFdpZGdldEFjY0l0ZXJhdG9yLT5Nb3ZlVG9OZXh0KCk7CiAgICB3aGlsZSAocFdpZGdldEFjYykgewogICAgICBwV2lkZ2V0SGFuZGxlci0+UHJvY2Vzc0V2ZW50KHBXaWRnZXRBY2MsICZQYXJhbSk7CiAgICAgIHBXaWRnZXRBY2MgPSBwV2lkZ2V0QWNjSXRlcmF0b3ItPk1vdmVUb05leHQoKTsKICAgIH0KICAgIHBXaWRnZXRBY2NJdGVyYXRvci0+UmVsZWFzZSgpOwogIH0KICBwV2lkZ2V0QWNjSXRlcmF0b3IgPSBtX3BYRkFEb2NWaWV3LT5DcmVhdGVXaWRnZXRBY2NJdGVyYXRvcigpOwogIGlmIChwV2lkZ2V0QWNjSXRlcmF0b3IpIHsKICAgIENYRkFfV2lkZ2V0QWNjKiBwV2lkZ2V0QWNjID0gcFdpZGdldEFjY0l0ZXJhdG9yLT5Nb3ZlVG9OZXh0KCk7CiAgICBwV2lkZ2V0QWNjID0gcFdpZGdldEFjY0l0ZXJhdG9yLT5Nb3ZlVG9OZXh0KCk7CiAgICB3aGlsZSAocFdpZGdldEFjYykgewogICAgICBpbnQgZlJldCA9IHBXaWRnZXRBY2MtPlByb2Nlc3NWYWxpZGF0ZSgtMSk7CiAgICAgIGlmIChmUmV0ID09IFhGQV9FVkVOVEVSUk9SX0Vycm9yKSB7CiAgICAgICAgQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IG1fcFNES0RvYy0+R2V0RW52KCk7CiAgICAgICAgaWYgKHBFbnYgPT0gTlVMTCkKICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICBDRlhfV2lkZVN0cmluZyB3czsKICAgICAgICB3cy5Gcm9tTG9jYWwoSURTX1hGQV9WYWxpZGF0ZV9JbnB1dCk7CiAgICAgICAgQ0ZYX0J5dGVTdHJpbmcgYnMgPSB3cy5VVEYxNkxFX0VuY29kZSgpOwogICAgICAgIGludCBsZW4gPSBicy5HZXRMZW5ndGgoKSAvIHNpemVvZih1bnNpZ25lZCBzaG9ydCk7CiAgICAgICAgcEVudi0+RkZJX0FsZXJ0KAogICAgICAgICAgICAoRlBERl9XSURFU1RSSU5HKWJzLkdldEJ1ZmZlcihsZW4gKiBzaXplb2YodW5zaWduZWQgc2hvcnQpKSwKICAgICAgICAgICAgKEZQREZfV0lERVNUUklORylMIiIsIDAsIDEpOwogICAgICAgIGJzLlJlbGVhc2VCdWZmZXIobGVuICogc2l6ZW9mKHVuc2lnbmVkIHNob3J0KSk7CiAgICAgICAgcFdpZGdldEFjY0l0ZXJhdG9yLT5SZWxlYXNlKCk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICB9CiAgICAgIHBXaWRnZXRBY2MgPSBwV2lkZ2V0QWNjSXRlcmF0b3ItPk1vdmVUb05leHQoKTsKICAgIH0KICAgIHBXaWRnZXRBY2NJdGVyYXRvci0+UmVsZWFzZSgpOwogICAgbV9wWEZBRG9jVmlldy0+VXBkYXRlRG9jVmlldygpOwogIH0KI2VuZGlmCiAgcmV0dXJuIFRSVUU7Cn0Kdm9pZCBDUERGWEZBX0RvY3VtZW50OjpfT25BZnRlck5vdGlmeVN1bWJpdCgpIHsKICBpZiAobV9pRG9jVHlwZSAhPSBET0NUWVBFX0RZTkFNSUNfWEZBICYmIG1faURvY1R5cGUgIT0gRE9DVFlQRV9TVEFUSUNfWEZBKQogICAgcmV0dXJuOwogIGlmIChtX3BYRkFEb2NWaWV3ID09IE5VTEwpCiAgICByZXR1cm47CiAgSVhGQV9XaWRnZXRIYW5kbGVyKiBwV2lkZ2V0SGFuZGxlciA9IG1fcFhGQURvY1ZpZXctPkdldFdpZGdldEhhbmRsZXIoKTsKICBpZiAocFdpZGdldEhhbmRsZXIgPT0gTlVMTCkKICAgIHJldHVybjsKICBJWEZBX1dpZGdldEFjY0l0ZXJhdG9yKiBwV2lkZ2V0QWNjSXRlcmF0b3IgPQogICAgICBtX3BYRkFEb2NWaWV3LT5DcmVhdGVXaWRnZXRBY2NJdGVyYXRvcigpOwogIGlmIChwV2lkZ2V0QWNjSXRlcmF0b3IgPT0gTlVMTCkKICAgIHJldHVybjsKICBDWEZBX0V2ZW50UGFyYW0gUGFyYW07CiAgUGFyYW0ubV9lVHlwZSA9IFhGQV9FVkVOVF9Qb3N0U3VibWl0OwoKICBDWEZBX1dpZGdldEFjYyogcFdpZGdldEFjYyA9IHBXaWRnZXRBY2NJdGVyYXRvci0+TW92ZVRvTmV4dCgpOwogIHdoaWxlIChwV2lkZ2V0QWNjKSB7CiAgICBwV2lkZ2V0SGFuZGxlci0+UHJvY2Vzc0V2ZW50KHBXaWRnZXRBY2MsICZQYXJhbSk7CiAgICBwV2lkZ2V0QWNjID0gcFdpZGdldEFjY0l0ZXJhdG9yLT5Nb3ZlVG9OZXh0KCk7CiAgfQogIHBXaWRnZXRBY2NJdGVyYXRvci0+UmVsZWFzZSgpOwogIG1fcFhGQURvY1ZpZXctPlVwZGF0ZURvY1ZpZXcoKTsKfQoKRlhfQk9PTCBDUERGWEZBX0RvY3VtZW50OjpTdWJtaXREYXRhKElYRkFfRG9jKiBoRG9jLCBDWEZBX1N1Ym1pdCBzdWJtaXQpIHsKICBpZiAoIV9Ob3RpZnlTdWJtaXQoVFJVRSkpCiAgICByZXR1cm4gRkFMU0U7CiAgaWYgKE5VTEwgPT0gbV9wWEZBRG9jVmlldykKICAgIHJldHVybiBGQUxTRTsKICBtX3BYRkFEb2NWaWV3LT5VcGRhdGVEb2NWaWV3KCk7CgogIEZYX0JPT0wgcmV0ID0gX1N1Ym1pdERhdGEoaERvYywgc3VibWl0KTsKICBfTm90aWZ5U3VibWl0KEZBTFNFKTsKICByZXR1cm4gcmV0Owp9CgpJRlhfRmlsZVJlYWQqIENQREZYRkFfRG9jdW1lbnQ6Ok9wZW5MaW5rZWRGaWxlKElYRkFfRG9jKiBoRG9jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENGWF9XaWRlU3RyaW5nJiB3c0xpbmspIHsKICBDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wU0RLRG9jLT5HZXRFbnYoKTsKICBpZiAocEVudiA9PSBOVUxMKQogICAgcmV0dXJuIEZBTFNFOwogIENGWF9CeXRlU3RyaW5nIGJzID0gd3NMaW5rLlVURjE2TEVfRW5jb2RlKCk7CiAgaW50IGxlbiA9IGJzLkdldExlbmd0aCgpIC8gc2l6ZW9mKHVuc2lnbmVkIHNob3J0KTsKICBGUERGX0ZJTEVIQU5ETEVSKiBwRmlsZUhhbmRsZXIgPSBwRW52LT5GRklfT3BlbkZpbGUoCiAgICAgIDAsIChGUERGX1dJREVTVFJJTkcpYnMuR2V0QnVmZmVyKGxlbiAqIHNpemVvZih1bnNpZ25lZCBzaG9ydCkpLCAicmIiKTsKICBicy5SZWxlYXNlQnVmZmVyKGxlbiAqIHNpemVvZih1bnNpZ25lZCBzaG9ydCkpOwoKICBpZiAocEZpbGVIYW5kbGVyID09IE5VTEwpCiAgICByZXR1cm4gTlVMTDsKICByZXR1cm4gbmV3IENGUERGX0ZpbGVTdHJlYW0ocEZpbGVIYW5kbGVyKTsKfQpGWF9CT09MIENQREZYRkFfRG9jdW1lbnQ6Ol9FeHBvcnRTdWJtaXRGaWxlKEZQREZfRklMRUhBTkRMRVIqIHBGaWxlSGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZmlsZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlBERl9EV09SRCBlbmNvZGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZQREZfRFdPUkQgZmxhZykgewogIGlmIChOVUxMID09IG1fcFhGQURvY1ZpZXcpCiAgICByZXR1cm4gRkFMU0U7CiAgSVhGQV9Eb2NIYW5kbGVyKiBwRG9jSGFuZGxlciA9IG1fcEFwcC0+R2V0WEZBQXBwKCktPkdldERvY0hhbmRsZXIoKTsKICBDRlhfQnl0ZVN0cmluZyBjb250ZW50OwoKICBDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wU0RLRG9jLT5HZXRFbnYoKTsKICBpZiAocEVudiA9PSBOVUxMKQogICAgcmV0dXJuIEZBTFNFOwoKICBDRlBERl9GaWxlU3RyZWFtIGZpbGVTdHJlYW0ocEZpbGVIYW5kbGVyKTsKCiAgaWYgKGZpbGVUeXBlID09IEZYRkFfU0FWRUFTX1hNTCkgewogICAgQ0ZYX1dpZGVTdHJpbmcgd3M7CiAgICB3cy5Gcm9tTG9jYWwoImRhdGEiKTsKICAgIENGWF9CeXRlU3RyaW5nIGNvbnRlbnQgPSAiPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiVVRGLThcIj8+XHJcbiI7CiAgICBmaWxlU3RyZWFtLldyaXRlQmxvY2soKGNvbnN0IEZYX0NIQVIqKWNvbnRlbnQsIDAsIGNvbnRlbnQuR2V0TGVuZ3RoKCkpOwogICAgcERvY0hhbmRsZXItPlNhdmVQYWNrYWdlKG1fcFhGQURvYywgd3MsICZmaWxlU3RyZWFtKTsKICB9IGVsc2UgaWYgKGZpbGVUeXBlID09IEZYRkFfU0FWRUFTX1hEUCkgewogICAgaWYgKGZsYWcgPT0gMCkKICAgICAgZmxhZyA9IEZYRkFfQ09ORklHIHwgRlhGQV9URU1QTEFURSB8IEZYRkFfTE9DQUxFU0VUIHwgRlhGQV9EQVRBU0VUUyB8CiAgICAgICAgICAgICBGWEZBX1hNUE1FVEEgfCBGWEZBX1hGREYgfCBGWEZBX0ZPUk07CiAgICBpZiAobV9wUERGRG9jID09IE5VTEwpIHsKICAgICAgZmlsZVN0cmVhbS5GbHVzaCgpOwogICAgICByZXR1cm4gRkFMU0U7CiAgICB9CiAgICBDUERGX0RpY3Rpb25hcnkqIHBSb290ID0gbV9wUERGRG9jLT5HZXRSb290KCk7CiAgICBpZiAocFJvb3QgPT0gTlVMTCkgewogICAgICBmaWxlU3RyZWFtLkZsdXNoKCk7CiAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KICAgIENQREZfRGljdGlvbmFyeSogcEFjcm9Gb3JtID0gcFJvb3QtPkdldERpY3RCeSgiQWNyb0Zvcm0iKTsKICAgIGlmIChOVUxMID09IHBBY3JvRm9ybSkgewogICAgICBmaWxlU3RyZWFtLkZsdXNoKCk7CiAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KICAgIENQREZfT2JqZWN0KiBwWEZBID0gcEFjcm9Gb3JtLT5HZXRFbGVtZW50KCJYRkEiKTsKICAgIGlmIChwWEZBID09IE5VTEwpIHsKICAgICAgZmlsZVN0cmVhbS5GbHVzaCgpOwogICAgICByZXR1cm4gRkFMU0U7CiAgICB9CiAgICBpZiAoIXBYRkEtPklzQXJyYXkoKSkgewogICAgICBmaWxlU3RyZWFtLkZsdXNoKCk7CiAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KICAgIENQREZfQXJyYXkqIHBBcnJheSA9IHBYRkEtPkdldEFycmF5KCk7CiAgICBpZiAoTlVMTCA9PSBwQXJyYXkpIHsKICAgICAgZmlsZVN0cmVhbS5GbHVzaCgpOwogICAgICByZXR1cm4gRkFMU0U7CiAgICB9CiAgICBpbnQgc2l6ZSA9IHBBcnJheS0+R2V0Q291bnQoKTsKICAgIGZvciAoaW50IGkgPSAxOyBpIDwgc2l6ZTsgaSArPSAyKSB7CiAgICAgIENQREZfT2JqZWN0KiBwUERGT2JqID0gcEFycmF5LT5HZXRFbGVtZW50KGkpOwogICAgICBDUERGX09iamVjdCogcFByZVBERk9iaiA9IHBBcnJheS0+R2V0RWxlbWVudChpIC0gMSk7CiAgICAgIGlmICghcFByZVBERk9iai0+SXNTdHJpbmcoKSkKICAgICAgICBjb250aW51ZTsKICAgICAgaWYgKCFwUERGT2JqLT5Jc1JlZmVyZW5jZSgpKQogICAgICAgIGNvbnRpbnVlOwogICAgICBDUERGX09iamVjdCogcERpcmVjdE9iaiA9IHBQREZPYmotPkdldERpcmVjdCgpOwogICAgICBpZiAoIXBEaXJlY3RPYmotPklzU3RyZWFtKCkpCiAgICAgICAgY29udGludWU7CiAgICAgIGlmIChwUHJlUERGT2JqLT5HZXRTdHJpbmcoKSA9PSAiY29uZmlnIiAmJiAhKGZsYWcgJiBGWEZBX0NPTkZJRykpCiAgICAgICAgY29udGludWU7CiAgICAgIGlmIChwUHJlUERGT2JqLT5HZXRTdHJpbmcoKSA9PSAidGVtcGxhdGUiICYmICEoZmxhZyAmIEZYRkFfVEVNUExBVEUpKQogICAgICAgIGNvbnRpbnVlOwogICAgICBpZiAocFByZVBERk9iai0+R2V0U3RyaW5nKCkgPT0gImxvY2FsZVNldCIgJiYgIShmbGFnICYgRlhGQV9MT0NBTEVTRVQpKQogICAgICAgIGNvbnRpbnVlOwogICAgICBpZiAocFByZVBERk9iai0+R2V0U3RyaW5nKCkgPT0gImRhdGFzZXRzIiAmJiAhKGZsYWcgJiBGWEZBX0RBVEFTRVRTKSkKICAgICAgICBjb250aW51ZTsKICAgICAgaWYgKHBQcmVQREZPYmotPkdldFN0cmluZygpID09ICJ4bXBtZXRhIiAmJiAhKGZsYWcgJiBGWEZBX1hNUE1FVEEpKQogICAgICAgIGNvbnRpbnVlOwogICAgICBpZiAocFByZVBERk9iai0+R2V0U3RyaW5nKCkgPT0gInhmZGYiICYmICEoZmxhZyAmIEZYRkFfWEZERikpCiAgICAgICAgY29udGludWU7CiAgICAgIGlmIChwUHJlUERGT2JqLT5HZXRTdHJpbmcoKSA9PSAiZm9ybSIgJiYgIShmbGFnICYgRlhGQV9GT1JNKSkKICAgICAgICBjb250aW51ZTsKICAgICAgaWYgKHBQcmVQREZPYmotPkdldFN0cmluZygpID09ICJmb3JtIikgewogICAgICAgIENGWF9XaWRlU3RyaW5nIHdzOwogICAgICAgIHdzLkZyb21Mb2NhbCgiZm9ybSIpOwogICAgICAgIHBEb2NIYW5kbGVyLT5TYXZlUGFja2FnZShtX3BYRkFEb2MsIHdzLCAmZmlsZVN0cmVhbSk7CiAgICAgIH0gZWxzZSBpZiAocFByZVBERk9iai0+R2V0U3RyaW5nKCkgPT0gImRhdGFzZXRzIikgewogICAgICAgIENGWF9XaWRlU3RyaW5nIHdzOwogICAgICAgIHdzLkZyb21Mb2NhbCgiZGF0YXNldHMiKTsKICAgICAgICBwRG9jSGFuZGxlci0+U2F2ZVBhY2thZ2UobV9wWEZBRG9jLCB3cywgJmZpbGVTdHJlYW0pOwogICAgICB9IGVsc2UgewogICAgICAgIC8vIFBERixjcmVhdG9yLgogICAgICAgIC8vIFRPRE86CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIFRSVUU7Cn0KCnZvaWQgQ1BERlhGQV9Eb2N1bWVudDo6X0NsZWFyQ2hhbmdlTWFyaygpIHsKICBpZiAobV9wU0RLRG9jKQogICAgbV9wU0RLRG9jLT5DbGVhckNoYW5nZU1hcmsoKTsKfQoKdm9pZCBDUERGWEZBX0RvY3VtZW50OjpfVG9YRkFDb250ZW50RmxhZ3MoQ0ZYX1dpZGVTdHJpbmcgY3NTcmNDb250ZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGUERGX0RXT1JEJiBmbGFnKSB7CiAgaWYgKGNzU3JjQ29udGVudC5GaW5kKEwiIGNvbmZpZyAiLCAwKSAhPSAtMSkKICAgIGZsYWcgfD0gRlhGQV9DT05GSUc7CiAgaWYgKGNzU3JjQ29udGVudC5GaW5kKEwiIHRlbXBsYXRlICIsIDApICE9IC0xKQogICAgZmxhZyB8PSBGWEZBX1RFTVBMQVRFOwogIGlmIChjc1NyY0NvbnRlbnQuRmluZChMIiBsb2NhbGVTZXQgIiwgMCkgIT0gLTEpCiAgICBmbGFnIHw9IEZYRkFfTE9DQUxFU0VUOwogIGlmIChjc1NyY0NvbnRlbnQuRmluZChMIiBkYXRhc2V0cyAiLCAwKSAhPSAtMSkKICAgIGZsYWcgfD0gRlhGQV9EQVRBU0VUUzsKICBpZiAoY3NTcmNDb250ZW50LkZpbmQoTCIgeG1wbWV0YSAiLCAwKSAhPSAtMSkKICAgIGZsYWcgfD0gRlhGQV9YTVBNRVRBOwogIGlmIChjc1NyY0NvbnRlbnQuRmluZChMIiB4ZmRmICIsIDApICE9IC0xKQogICAgZmxhZyB8PSBGWEZBX1hGREY7CiAgaWYgKGNzU3JjQ29udGVudC5GaW5kKEwiIGZvcm0gIiwgMCkgIT0gLTEpCiAgICBmbGFnIHw9IEZYRkFfRk9STTsKICBpZiAoZmxhZyA9PSAwKQogICAgZmxhZyA9IEZYRkFfQ09ORklHIHwgRlhGQV9URU1QTEFURSB8IEZYRkFfTE9DQUxFU0VUIHwgRlhGQV9EQVRBU0VUUyB8CiAgICAgICAgICAgRlhGQV9YTVBNRVRBIHwgRlhGQV9YRkRGIHwgRlhGQV9GT1JNOwp9CkZYX0JPT0wgQ1BERlhGQV9Eb2N1bWVudDo6X01haWxUb0luZm8oQ0ZYX1dpZGVTdHJpbmcmIGNzVVJMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENGWF9XaWRlU3RyaW5nJiBjc1RvQWRkcmVzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDRlhfV2lkZVN0cmluZyYgY3NDQ0FkZHJlc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0ZYX1dpZGVTdHJpbmcmIGNzQkNDQWRkcmVzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDRlhfV2lkZVN0cmluZyYgY3NTdWJqZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENGWF9XaWRlU3RyaW5nJiBjc01zZykgewogIENGWF9XaWRlU3RyaW5nIHNyY1VSTCA9IGNzVVJMOwogIHNyY1VSTC5UcmltTGVmdCgpOwogIGlmICgwICE9IHNyY1VSTC5MZWZ0KDcpLkNvbXBhcmVOb0Nhc2UoTCJtYWlsdG86IikpCiAgICByZXR1cm4gRkFMU0U7CiAgaW50IHBvcyA9IHNyY1VSTC5GaW5kKEwnPycsIDApOwogIENGWF9XaWRlU3RyaW5nIHRtcDsKICBpZiAocG9zID09IC0xKSB7CiAgICBwb3MgPSBzcmNVUkwuRmluZChMJ0AnLCAwKTsKICAgIGlmIChwb3MgPT0gLTEpCiAgICAgIHJldHVybiBGQUxTRTsKICAgIGVsc2UgewogICAgICB0bXAgPSBzcmNVUkwuUmlnaHQoY3NVUkwuR2V0TGVuZ3RoKCkgLSA3KTsKICAgICAgdG1wLlRyaW1MZWZ0KCk7CiAgICAgIHRtcC5UcmltUmlnaHQoKTsKICAgIH0KICB9IGVsc2UgewogICAgdG1wID0gc3JjVVJMLkxlZnQocG9zKTsKICAgIHRtcCA9IHRtcC5SaWdodCh0bXAuR2V0TGVuZ3RoKCkgLSA3KTsKICAgIHRtcC5UcmltTGVmdCgpOwogICAgdG1wLlRyaW1SaWdodCgpOwogIH0KCiAgY3NUb0FkZHJlc3MgPSB0bXA7CgogIHNyY1VSTCA9IHNyY1VSTC5SaWdodChzcmNVUkwuR2V0TGVuZ3RoKCkgLSAocG9zICsgMSkpOwogIHdoaWxlICghc3JjVVJMLklzRW1wdHkoKSkgewogICAgc3JjVVJMLlRyaW1MZWZ0KCk7CiAgICBzcmNVUkwuVHJpbVJpZ2h0KCk7CiAgICBwb3MgPSBzcmNVUkwuRmluZChMJyYnLCAwKTsKICAgIGlmIChwb3MgPT0gLTEpCiAgICAgIHRtcCA9IHNyY1VSTDsKICAgIGVsc2UKICAgICAgdG1wID0gc3JjVVJMLkxlZnQocG9zKTsKCiAgICB0bXAuVHJpbUxlZnQoKTsKICAgIHRtcC5UcmltUmlnaHQoKTsKICAgIGlmICh0bXAuR2V0TGVuZ3RoKCkgPj0gMyAmJiAwID09IHRtcC5MZWZ0KDMpLkNvbXBhcmVOb0Nhc2UoTCJjYz0iKSkgewogICAgICB0bXAgPSB0bXAuUmlnaHQodG1wLkdldExlbmd0aCgpIC0gMyk7CiAgICAgIGlmICghY3NDQ0FkZHJlc3MuSXNFbXB0eSgpKQogICAgICAgIGNzQ0NBZGRyZXNzICs9IEwnOyc7CiAgICAgIGNzQ0NBZGRyZXNzICs9IHRtcDsKCiAgICB9IGVsc2UgaWYgKHRtcC5HZXRMZW5ndGgoKSA+PSA0ICYmCiAgICAgICAgICAgICAgIDAgPT0gdG1wLkxlZnQoNCkuQ29tcGFyZU5vQ2FzZShMImJjYz0iKSkgewogICAgICB0bXAgPSB0bXAuUmlnaHQodG1wLkdldExlbmd0aCgpIC0gNCk7CiAgICAgIGlmICghY3NCQ0NBZGRyZXNzLklzRW1wdHkoKSkKICAgICAgICBjc0JDQ0FkZHJlc3MgKz0gTCc7JzsKICAgICAgY3NCQ0NBZGRyZXNzICs9IHRtcDsKICAgIH0gZWxzZSBpZiAodG1wLkdldExlbmd0aCgpID49IDggJiYKICAgICAgICAgICAgICAgMCA9PSB0bXAuTGVmdCg4KS5Db21wYXJlTm9DYXNlKEwic3ViamVjdD0iKSkgewogICAgICB0bXAgPSB0bXAuUmlnaHQodG1wLkdldExlbmd0aCgpIC0gOCk7CiAgICAgIGNzU3ViamVjdCArPSB0bXA7CiAgICB9IGVsc2UgaWYgKHRtcC5HZXRMZW5ndGgoKSA+PSA1ICYmCiAgICAgICAgICAgICAgIDAgPT0gdG1wLkxlZnQoNSkuQ29tcGFyZU5vQ2FzZShMImJvZHk9IikpIHsKICAgICAgdG1wID0gdG1wLlJpZ2h0KHRtcC5HZXRMZW5ndGgoKSAtIDUpOwogICAgICBjc01zZyArPSB0bXA7CiAgICB9CiAgICBpZiAocG9zID09IC0xKQogICAgICBzcmNVUkwgPSBMIiI7CiAgICBlbHNlCiAgICAgIHNyY1VSTCA9IHNyY1VSTC5SaWdodChjc1VSTC5HZXRMZW5ndGgoKSAtIChwb3MgKyAxKSk7CiAgfQogIGNzVG9BZGRyZXNzLlJlcGxhY2UoTCIsIiwgTCI7Iik7CiAgY3NDQ0FkZHJlc3MuUmVwbGFjZShMIiwiLCBMIjsiKTsKICBjc0JDQ0FkZHJlc3MuUmVwbGFjZShMIiwiLCBMIjsiKTsKICByZXR1cm4gVFJVRTsKfQoKRlhfQk9PTCBDUERGWEZBX0RvY3VtZW50OjpfU3VibWl0RGF0YShJWEZBX0RvYyogaERvYywgQ1hGQV9TdWJtaXQgc3VibWl0KSB7CiNpZmRlZiBQREZfRU5BQkxFX1hGQQogIENQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BTREtEb2MtPkdldEVudigpOwogIGlmICghcEVudikKICAgIHJldHVybiBGQUxTRTsKICBDRlhfV2lkZVN0cmluZ0MgY3NVUkxDOwogIHN1Ym1pdC5HZXRTdWJtaXRUYXJnZXQoY3NVUkxDKTsKICBDRlhfV2lkZVN0cmluZyBjc1VSTCA9IGNzVVJMQzsKICBpZiAoY3NVUkwuSXNFbXB0eSgpKSB7CiAgICBDRlhfV2lkZVN0cmluZyB3czsKICAgIHdzLkZyb21Mb2NhbCgiU3VibWl0IGNhbmNlbGxlZC4iKTsKICAgIENGWF9CeXRlU3RyaW5nIGJzID0gd3MuVVRGMTZMRV9FbmNvZGUoKTsKICAgIGludCBsZW4gPSBicy5HZXRMZW5ndGgoKSAvIHNpemVvZih1bnNpZ25lZCBzaG9ydCk7CiAgICBwRW52LT5GRklfQWxlcnQoKEZQREZfV0lERVNUUklORylicy5HZXRCdWZmZXIobGVuICogc2l6ZW9mKHVuc2lnbmVkIHNob3J0KSksCiAgICAgICAgICAgICAgICAgICAgKEZQREZfV0lERVNUUklORylMIiIsIDAsIDQpOwogICAgYnMuUmVsZWFzZUJ1ZmZlcihsZW4gKiBzaXplb2YodW5zaWduZWQgc2hvcnQpKTsKICAgIHJldHVybiBGQUxTRTsKICB9CiAgRlBERl9CT09MIGJSZXQgPSBUUlVFOwogIEZQREZfRklMRUhBTkRMRVIqIHBGaWxlSGFuZGxlciA9IG51bGxwdHI7CiAgaW50IGZpbGVGbGFnID0gLTE7CiAgc3dpdGNoIChzdWJtaXQuR2V0U3VibWl0Rm9ybWF0KCkpIHsKICAgIGNhc2UgWEZBX0FUVFJJQlVURUVOVU1fWGRwOiB7CiAgICAgIENGWF9XaWRlU3RyaW5nQyBjc0NvbnRlbnRDOwogICAgICBzdWJtaXQuR2V0U3VibWl0WERQQ29udGVudChjc0NvbnRlbnRDKTsKICAgICAgQ0ZYX1dpZGVTdHJpbmcgY3NDb250ZW50OwogICAgICBjc0NvbnRlbnQgPSBjc0NvbnRlbnRDOwogICAgICBjc0NvbnRlbnQuVHJpbUxlZnQoKTsKICAgICAgY3NDb250ZW50LlRyaW1SaWdodCgpOwogICAgICBDRlhfV2lkZVN0cmluZyBzcGFjZTsKICAgICAgc3BhY2UuRnJvbUxvY2FsKCIgIik7CiAgICAgIGNzQ29udGVudCA9IHNwYWNlICsgY3NDb250ZW50ICsgc3BhY2U7CiAgICAgIEZQREZfRFdPUkQgZmxhZyA9IDA7CiAgICAgIGlmIChzdWJtaXQuSXNTdWJtaXRFbWJlZFBERigpKQogICAgICAgIGZsYWcgfD0gRlhGQV9QREY7CiAgICAgIF9Ub1hGQUNvbnRlbnRGbGFncyhjc0NvbnRlbnQsIGZsYWcpOwogICAgICBwRmlsZUhhbmRsZXIgPSBwRW52LT5GRklfT3BlbkZpbGUoRlhGQV9TQVZFQVNfWERQLCBudWxscHRyLCAid2IiKTsKICAgICAgZmlsZUZsYWcgPSBGWEZBX1NBVkVBU19YRFA7CiAgICAgIF9FeHBvcnRTdWJtaXRGaWxlKHBGaWxlSGFuZGxlciwgRlhGQV9TQVZFQVNfWERQLCAwLCBmbGFnKTsKICAgICAgYnJlYWs7CiAgICB9CiAgICBjYXNlIFhGQV9BVFRSSUJVVEVFTlVNX1htbDoKICAgICAgcEZpbGVIYW5kbGVyID0gcEVudi0+RkZJX09wZW5GaWxlKEZYRkFfU0FWRUFTX1hNTCwgbnVsbHB0ciwgIndiIik7CiAgICAgIGZpbGVGbGFnID0gRlhGQV9TQVZFQVNfWE1MOwogICAgICBfRXhwb3J0U3VibWl0RmlsZShwRmlsZUhhbmRsZXIsIEZYRkFfU0FWRUFTX1hNTCwgMCk7CiAgICAgIGJyZWFrOwogICAgY2FzZSBYRkFfQVRUUklCVVRFRU5VTV9QZGY6CiAgICAgIGJyZWFrOwogICAgY2FzZSBYRkFfQVRUUklCVVRFRU5VTV9VcmxlbmNvZGVkOgogICAgICBwRmlsZUhhbmRsZXIgPSBwRW52LT5GRklfT3BlbkZpbGUoRlhGQV9TQVZFQVNfWE1MLCBudWxscHRyLCAid2IiKTsKICAgICAgZmlsZUZsYWcgPSBGWEZBX1NBVkVBU19YTUw7CiAgICAgIF9FeHBvcnRTdWJtaXRGaWxlKHBGaWxlSGFuZGxlciwgRlhGQV9TQVZFQVNfWE1MLCAwKTsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICByZXR1cm4gZmFsc2U7CiAgfQogIGlmICghcEZpbGVIYW5kbGVyKQogICAgcmV0dXJuIEZBTFNFOwogIGlmICgwID09IGNzVVJMLkxlZnQoNykuQ29tcGFyZU5vQ2FzZShMIm1haWx0bzoiKSkgewogICAgQ0ZYX1dpZGVTdHJpbmcgY3NUb0FkZHJlc3M7CiAgICBDRlhfV2lkZVN0cmluZyBjc0NDQWRkcmVzczsKICAgIENGWF9XaWRlU3RyaW5nIGNzQkNDQWRkcmVzczsKICAgIENGWF9XaWRlU3RyaW5nIGNzU3ViamVjdDsKICAgIENGWF9XaWRlU3RyaW5nIGNzTXNnOwogICAgYlJldCA9IF9NYWlsVG9JbmZvKGNzVVJMLCBjc1RvQWRkcmVzcywgY3NDQ0FkZHJlc3MsIGNzQkNDQWRkcmVzcywgY3NTdWJqZWN0LAogICAgICAgICAgICAgICAgICAgICAgIGNzTXNnKTsKICAgIGlmICghYlJldCkKICAgICAgcmV0dXJuIEZBTFNFOwogICAgQ0ZYX0J5dGVTdHJpbmcgYnNUbyA9IENGWF9XaWRlU3RyaW5nKGNzVG9BZGRyZXNzKS5VVEYxNkxFX0VuY29kZSgpOwogICAgQ0ZYX0J5dGVTdHJpbmcgYnNDQyA9IENGWF9XaWRlU3RyaW5nKGNzQ0NBZGRyZXNzKS5VVEYxNkxFX0VuY29kZSgpOwogICAgQ0ZYX0J5dGVTdHJpbmcgYnNCY2MgPSBDRlhfV2lkZVN0cmluZyhjc0JDQ0FkZHJlc3MpLlVURjE2TEVfRW5jb2RlKCk7CiAgICBDRlhfQnl0ZVN0cmluZyBic1N1YmplY3QgPSBDRlhfV2lkZVN0cmluZyhjc1N1YmplY3QpLlVURjE2TEVfRW5jb2RlKCk7CiAgICBDRlhfQnl0ZVN0cmluZyBic01zZyA9IENGWF9XaWRlU3RyaW5nKGNzTXNnKS5VVEYxNkxFX0VuY29kZSgpOwogICAgRlBERl9XSURFU1RSSU5HIHBUbyA9IChGUERGX1dJREVTVFJJTkcpYnNUby5HZXRCdWZmZXIoYnNUby5HZXRMZW5ndGgoKSk7CiAgICBGUERGX1dJREVTVFJJTkcgcENDID0gKEZQREZfV0lERVNUUklORylic0NDLkdldEJ1ZmZlcihic0NDLkdldExlbmd0aCgpKTsKICAgIEZQREZfV0lERVNUUklORyBwQmNjID0gKEZQREZfV0lERVNUUklORylic0JjYy5HZXRCdWZmZXIoYnNCY2MuR2V0TGVuZ3RoKCkpOwogICAgRlBERl9XSURFU1RSSU5HIHBTdWJqZWN0ID0KICAgICAgICAoRlBERl9XSURFU1RSSU5HKWJzU3ViamVjdC5HZXRCdWZmZXIoYnNTdWJqZWN0LkdldExlbmd0aCgpKTsKICAgIEZQREZfV0lERVNUUklORyBwTXNnID0gKEZQREZfV0lERVNUUklORylic01zZy5HZXRCdWZmZXIoYnNNc2cuR2V0TGVuZ3RoKCkpOwogICAgcEVudi0+RkZJX0VtYWlsVG8ocEZpbGVIYW5kbGVyLCBwVG8sIHBTdWJqZWN0LCBwQ0MsIHBCY2MsIHBNc2cpOwogICAgYnNUby5SZWxlYXNlQnVmZmVyKCk7CiAgICBic0NDLlJlbGVhc2VCdWZmZXIoKTsKICAgIGJzQmNjLlJlbGVhc2VCdWZmZXIoKTsKICAgIGJzU3ViamVjdC5SZWxlYXNlQnVmZmVyKCk7CiAgICBic01zZy5SZWxlYXNlQnVmZmVyKCk7CiAgfSBlbHNlIHsKICAgIC8vIGh0dHChomZ0cAogICAgQ0ZYX1dpZGVTdHJpbmcgd3M7CiAgICBDRlhfQnl0ZVN0cmluZyBicyA9IGNzVVJMLlVURjE2TEVfRW5jb2RlKCk7CiAgICBpbnQgbGVuID0gYnMuR2V0TGVuZ3RoKCkgLyBzaXplb2YodW5zaWduZWQgc2hvcnQpOwogICAgcEVudi0+RkZJX1VwbG9hZFRvKAogICAgICAgIHBGaWxlSGFuZGxlciwgZmlsZUZsYWcsCiAgICAgICAgKEZQREZfV0lERVNUUklORylicy5HZXRCdWZmZXIobGVuICogc2l6ZW9mKHVuc2lnbmVkIHNob3J0KSkpOwogICAgYnMuUmVsZWFzZUJ1ZmZlcihsZW4gKiBzaXplb2YodW5zaWduZWQgc2hvcnQpKTsKICB9CiAgcmV0dXJuIGJSZXQ7CiNlbHNlCiAgcmV0dXJuIFRSVUU7CiNlbmRpZgp9CgpGWF9CT09MIENQREZYRkFfRG9jdW1lbnQ6OlNldEdsb2JhbFByb3BlcnR5KElYRkFfRG9jKiBoRG9jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENGWF9CeXRlU3RyaW5nQyYgc3pQcm9wTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGWEpTRV9IVkFMVUUgaFZhbHVlKSB7CiAgaWYgKGhEb2MgIT0gbV9wWEZBRG9jKQogICAgcmV0dXJuIEZBTFNFOwoKICBpZiAobV9wU0RLRG9jICYmIG1fcFNES0RvYy0+R2V0RW52KCktPkdldEpTUnVudGltZSgpKQogICAgcmV0dXJuIG1fcFNES0RvYy0+R2V0RW52KCktPkdldEpTUnVudGltZSgpLT5TZXRIVmFsdWVCeU5hbWUoc3pQcm9wTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhWYWx1ZSk7CiAgcmV0dXJuIEZBTFNFOwp9CkZYX0JPT0wgQ1BERlhGQV9Eb2N1bWVudDo6R2V0UERGU2NyaXB0T2JqZWN0KElYRkFfRG9jKiBoRG9jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDRlhfQnl0ZVN0cmluZ0MmIHV0ZjhOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGWEpTRV9IVkFMVUUgaFZhbHVlKSB7CiAgaWYgKGhEb2MgIT0gbV9wWEZBRG9jKQogICAgcmV0dXJuIEZBTFNFOwoKICBpZiAoIW1fcFNES0RvYyB8fCAhbV9wU0RLRG9jLT5HZXRFbnYoKS0+R2V0SlNSdW50aW1lKCkpCiAgICByZXR1cm4gRkFMU0U7CgogIGlmICghbV9wSlNDb250ZXh0KSB7CiAgICBtX3BTREtEb2MtPkdldEVudigpLT5HZXRKU1J1bnRpbWUoKS0+U2V0UmVhZGVyRG9jdW1lbnQobV9wU0RLRG9jKTsKICAgIG1fcEpTQ29udGV4dCA9IG1fcFNES0RvYy0+R2V0RW52KCktPkdldEpTUnVudGltZSgpLT5OZXdDb250ZXh0KCk7CiAgfQoKICByZXR1cm4gX0dldEhWYWx1ZUJ5TmFtZSh1dGY4TmFtZSwgaFZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICAgIG1fcFNES0RvYy0+R2V0RW52KCktPkdldEpTUnVudGltZSgpKTsKfQpGWF9CT09MIENQREZYRkFfRG9jdW1lbnQ6OkdldEdsb2JhbFByb3BlcnR5KElYRkFfRG9jKiBoRG9jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENGWF9CeXRlU3RyaW5nQyYgc3pQcm9wTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGWEpTRV9IVkFMVUUgaFZhbHVlKSB7CiAgaWYgKGhEb2MgIT0gbV9wWEZBRG9jKQogICAgcmV0dXJuIEZBTFNFOwogIGlmICghbV9wU0RLRG9jIHx8ICFtX3BTREtEb2MtPkdldEVudigpLT5HZXRKU1J1bnRpbWUoKSkKICAgIHJldHVybiBGQUxTRTsKCiAgaWYgKCFtX3BKU0NvbnRleHQpIHsKICAgIG1fcFNES0RvYy0+R2V0RW52KCktPkdldEpTUnVudGltZSgpLT5TZXRSZWFkZXJEb2N1bWVudChtX3BTREtEb2MpOwogICAgbV9wSlNDb250ZXh0ID0gbV9wU0RLRG9jLT5HZXRFbnYoKS0+R2V0SlNSdW50aW1lKCktPk5ld0NvbnRleHQoKTsKICB9CgogIHJldHVybiBfR2V0SFZhbHVlQnlOYW1lKHN6UHJvcE5hbWUsIGhWYWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBtX3BTREtEb2MtPkdldEVudigpLT5HZXRKU1J1bnRpbWUoKSk7Cn0KRlhfQk9PTCBDUERGWEZBX0RvY3VtZW50OjpfR2V0SFZhbHVlQnlOYW1lKGNvbnN0IENGWF9CeXRlU3RyaW5nQyYgdXRmOE5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGWEpTRV9IVkFMVUUgaFZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSUpTX1J1bnRpbWUqIHJ1blRpbWUpIHsKICByZXR1cm4gcnVuVGltZS0+R2V0SFZhbHVlQnlOYW1lKHV0ZjhOYW1lLCBoVmFsdWUpOwp9Cg==