LyoKICogYSBHVUkgYXBwbGljYXRpb24gZm9yIGRpc3BsYXlpbmcgYSBjb25zb2xlCiAqCVVTRVIzMiBiYWNrIGVuZAogKiBDb3B5cmlnaHQgMjAwMSBFcmljIFBvdWVjaAogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSAid2luZWNvbl91c2VyLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwod2luZWNvbnNvbGUpOwpXSU5FX0RFQ0xBUkVfREVCVUdfQ0hBTk5FTCh3Y19mb250KTsKCi8qIG1hcHBpbmcgY29uc29sZSBjb2xvcnMgdG8gUkdCIHZhbHVlcyAqLwpDT0xPUlJFRglXQ1VTRVJfQ29sb3JNYXBbMTZdID0KewogICAgUkdCKDB4MDAsIDB4MDAsIDB4MDApLCBSR0IoMHgwMCwgMHgwMCwgMHg4MCksIFJHQigweDAwLCAweDgwLCAweDAwKSwgUkdCKDB4MDAsIDB4ODAsIDB4ODApLAogICAgUkdCKDB4ODAsIDB4MDAsIDB4MDApLCBSR0IoMHg4MCwgMHgwMCwgMHg4MCksIFJHQigweDgwLCAweDgwLCAweDAwKSwgUkdCKDB4ODAsIDB4ODAsIDB4ODApLAogICAgUkdCKDB4QzAsIDB4QzAsIDB4QzApLCBSR0IoMHgwMCwgMHgwMCwgMHhGRiksIFJHQigweDAwLCAweEZGLCAweDAwKSwgUkdCKDB4MDAsIDB4RkYsIDB4RkYpLAogICAgUkdCKDB4RkYsIDB4MDAsIDB4MDApLCBSR0IoMHhGRiwgMHgwMCwgMHhGRiksIFJHQigweEZGLCAweEZGLCAweDAwKSwgUkdCKDB4RkYsIDB4RkYsIDB4RkYpLAp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0ZpbGxNZW1EQwogKgogKiBGaWxscyB0aGUgTWVtIERDIHdpdGggY3VycmVudCBjZWxscyB2YWx1ZXMKICovCnN0YXRpYyB2b2lkIFdDVVNFUl9GaWxsTWVtREMoY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIGludCB1cGRfdHAsIGludCB1cGRfYm0pCnsKICAgIHVuc2lnbmVkCQlpLCBqLCBrOwogICAgQ0hBUl9JTkZPKgkJY2VsbDsKICAgIEhGT05UCQloT2xkRm9udDsKICAgIFdPUkQJCWF0dHI7CiAgICBXQ0hBUioJCWxpbmU7CgogICAgLyogbm8gZm9udCBoYXMgYmVlbiBzZXQgdXAgeWV0LCBkb24ndCB3b3JyeSBhYm91dCBmaWxsaW5nIHRoZSBiaXRtYXAsCiAgICAgKiB3ZSdsbCBkbyBpdCBvbmNlIGEgZm9udCBpcyBjaG9zZW4KICAgICAqLwogICAgaWYgKCFQUklWQVRFKGRhdGEpLT5oRm9udCkgcmV0dXJuOwoKICAgIGlmICghKGxpbmUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZGF0YS0+Y3VyY2ZnLnNiX3dpZHRoICogc2l6ZW9mKFdDSEFSKSkpKQogICAge1dJTkVfRVJSKCJPT01cbiIpOyByZXR1cm47fQoKICAgIGhPbGRGb250ID0gU2VsZWN0T2JqZWN0KFBSSVZBVEUoZGF0YSktPmhNZW1EQywgUFJJVkFURShkYXRhKS0+aEZvbnQpOwogICAgZm9yIChqID0gdXBkX3RwOyBqIDw9IHVwZF9ibTsgaisrKQogICAgewoJY2VsbCA9ICZkYXRhLT5jZWxsc1tqICogZGF0YS0+Y3VyY2ZnLnNiX3dpZHRoXTsKCWZvciAoaSA9IDA7IGkgPCBkYXRhLT5jdXJjZmcuc2Jfd2lkdGg7IGkrKykKCXsKCSAgICBhdHRyID0gY2VsbFtpXS5BdHRyaWJ1dGVzOwoJICAgIFNldEJrQ29sb3IoUFJJVkFURShkYXRhKS0+aE1lbURDLCBXQ1VTRVJfQ29sb3JNYXBbKGF0dHI+PjQpJjB4MEZdKTsKCSAgICBTZXRUZXh0Q29sb3IoUFJJVkFURShkYXRhKS0+aE1lbURDLCBXQ1VTRVJfQ29sb3JNYXBbYXR0ciYweDBGXSk7CgkgICAgZm9yIChrID0gaTsgayA8IGRhdGEtPmN1cmNmZy5zYl93aWR0aCAmJiBjZWxsW2tdLkF0dHJpYnV0ZXMgPT0gYXR0cjsgaysrKQoJICAgIHsKCQlsaW5lW2sgLSBpXSA9IGNlbGxba10uQ2hhci5Vbmljb2RlQ2hhcjsKCSAgICB9CgkgICAgVGV4dE91dChQUklWQVRFKGRhdGEpLT5oTWVtREMsIGkgKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwgaiAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCwKCQkgICAgbGluZSwgayAtIGkpOwoJICAgIGkgPSBrIC0gMTsKCX0KICAgIH0KICAgIFNlbGVjdE9iamVjdChQUklWQVRFKGRhdGEpLT5oTWVtREMsIGhPbGRGb250KTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGxpbmUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfTmV3Qml0bWFwCiAqCiAqIEVpdGhlciB0aGUgZm9udCBnZW9tZXRyeSBvciB0aGUgc2IgZ2VvbWV0cnkgaGFzIGNoYW5nZWQuIHdlIG5lZWQKICogdG8gcmVjcmVhdGUgdGhlIGJpdG1hcCBnZW9tZXRyeS4KICovCnN0YXRpYyB2b2lkIFdDVVNFUl9OZXdCaXRtYXAoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIEJPT0wgZmlsbCkKewogICAgSERDICAgICAgICAgaERDOwogICAgSEJJVE1BUAlobmV3LCBob2xkOwoKICAgIGlmICghZGF0YS0+Y3VyY2ZnLnNiX3dpZHRoIHx8ICFkYXRhLT5jdXJjZmcuc2JfaGVpZ2h0IHx8CiAgICAgICAgIVBSSVZBVEUoZGF0YSktPmhGb250IHx8ICEoaERDID0gR2V0REMoUFJJVkFURShkYXRhKS0+aFduZCkpKQogICAgICAgIHJldHVybjsKICAgIGhuZXcgPSBDcmVhdGVDb21wYXRpYmxlQml0bWFwKGhEQywKCQkJCSAgZGF0YS0+Y3VyY2ZnLnNiX3dpZHRoICAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoLAoJCQkJICBkYXRhLT5jdXJjZmcuc2JfaGVpZ2h0ICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0KTsKICAgIFJlbGVhc2VEQyhQUklWQVRFKGRhdGEpLT5oV25kLCBoREMpOwogICAgaG9sZCA9IFNlbGVjdE9iamVjdChQUklWQVRFKGRhdGEpLT5oTWVtREMsIGhuZXcpOwoKICAgIGlmIChQUklWQVRFKGRhdGEpLT5oQml0bWFwKQogICAgewoJaWYgKGhvbGQgPT0gUFJJVkFURShkYXRhKS0+aEJpdG1hcCkKCSAgICBEZWxldGVPYmplY3QoUFJJVkFURShkYXRhKS0+aEJpdG1hcCk7CgllbHNlCgkgICAgV0lORV9GSVhNRSgibGVha1xuIik7CiAgICB9CiAgICBQUklWQVRFKGRhdGEpLT5oQml0bWFwID0gaG5ldzsKICAgIGlmIChmaWxsKQoJV0NVU0VSX0ZpbGxNZW1EQyhkYXRhLCAwLCBkYXRhLT5jdXJjZmcuc2JfaGVpZ2h0IC0gMSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9SZXNpemVTY3JlZW5CdWZmZXIKICoKICoKICovCnN0YXRpYyB2b2lkIFdDVVNFUl9SZXNpemVTY3JlZW5CdWZmZXIoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIFdDVVNFUl9OZXdCaXRtYXAoZGF0YSwgRkFMU0UpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfUG9zQ3Vyc29yCiAqCiAqIFNldCBhIG5ldyBwb3NpdGlvbiBmb3IgdGhlIGN1cnNvcgogKi8Kc3RhdGljIHZvaWQJV0NVU0VSX1Bvc0N1cnNvcihjb25zdCBzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgaWYgKFBSSVZBVEUoZGF0YSktPmhXbmQgIT0gR2V0Rm9jdXMoKSB8fCAhZGF0YS0+Y3VyY2ZnLmN1cnNvcl92aXNpYmxlKSByZXR1cm47CgogICAgU2V0Q2FyZXRQb3MoKGRhdGEtPmN1cnNvci5YIC0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWCkgKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwKCQkoZGF0YS0+Y3Vyc29yLlkgLSBkYXRhLT5jdXJjZmcud2luX3Bvcy5ZKSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCk7CiAgICBTaG93Q2FyZXQoUFJJVkFURShkYXRhKS0+aFduZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9TaGFwZUN1cnNvcgogKgogKiBTZXRzIGEgbmV3IHNoYXBlIGZvciB0aGUgY3Vyc29yCiAqLwp2b2lkCVdDVVNFUl9TaGFwZUN1cnNvcihzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgaW50IHNpemUsIGludCB2aXMsIEJPT0wgZm9yY2UpCnsKICAgIGlmIChmb3JjZSB8fCBzaXplICE9IGRhdGEtPmN1cmNmZy5jdXJzb3Jfc2l6ZSkKICAgIHsKCWlmIChkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUgJiYgUFJJVkFURShkYXRhKS0+aFduZCA9PSBHZXRGb2N1cygpKSBEZXN0cm95Q2FyZXQoKTsKCWlmIChQUklWQVRFKGRhdGEpLT5jdXJzb3JfYml0bWFwKSBEZWxldGVPYmplY3QoUFJJVkFURShkYXRhKS0+Y3Vyc29yX2JpdG1hcCk7CglQUklWQVRFKGRhdGEpLT5jdXJzb3JfYml0bWFwID0gKEhCSVRNQVApMDsKCWlmIChzaXplICE9IDEwMCkKCXsKCSAgICBpbnQJCXcxNmI7IC8qIG51bWJlciBvZiBieXRlcyBwZXIgcm93LCBhbGlnbmVkIG9uIHdvcmQgc2l6ZSAqLwoJICAgIEJZVEUqCXB0cjsKCSAgICBpbnQJCWksIGosIG5ibDsKCgkgICAgdzE2YiA9ICgoZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGggKyAxNSkgJiB+MTUpIC8gODsKCSAgICBwdHIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgdzE2YiAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCk7CgkgICAgaWYgKCFwdHIpIHtXSU5FX0VSUigiT09NXG4iKTsgcmV0dXJuO30KCSAgICBuYmwgPSBtYXgoKGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCAqIHNpemUpIC8gMTAwLCAxKTsKCSAgICBmb3IgKGogPSBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQgLSBuYmw7IGogPCBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQ7IGorKykKCSAgICB7CgkJZm9yIChpID0gMDsgaSA8IGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoOyBpKyspCgkJewoJCSAgICBwdHJbdzE2YiAqIGogKyAoaSAvIDgpXSB8PSAweDgwID4+IChpICYgNyk7CgkJfQoJICAgIH0KCSAgICBQUklWQVRFKGRhdGEpLT5jdXJzb3JfYml0bWFwID0gQ3JlYXRlQml0bWFwKGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCwgMSwgMSwgcHRyKTsKCSAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwdHIpOwoJfQoJZGF0YS0+Y3VyY2ZnLmN1cnNvcl9zaXplID0gc2l6ZTsKCWRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSA9IC0xOwogICAgfQoKICAgIHZpcyA9ICh2aXMpID8gVFJVRSA6IEZBTFNFOwogICAgaWYgKGZvcmNlIHx8IHZpcyAhPSBkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUpCiAgICB7CglkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUgPSB2aXM7CglpZiAoUFJJVkFURShkYXRhKS0+aFduZCA9PSBHZXRGb2N1cygpKQoJewoJICAgIGlmICh2aXMpCgkgICAgewoJCUNyZWF0ZUNhcmV0KFBSSVZBVEUoZGF0YSktPmhXbmQsIFBSSVZBVEUoZGF0YSktPmN1cnNvcl9iaXRtYXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwgZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0KTsKCQlXQ1VTRVJfUG9zQ3Vyc29yKGRhdGEpOwoJICAgIH0KCSAgICBlbHNlCgkgICAgewoJCURlc3Ryb3lDYXJldCgpOwoJICAgIH0KCX0KICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0NvbXB1dGVQb3NpdGlvbnMKICoKICogUmVjb21wdXRlcyBhbGwgdGhlIGNvbXBvbmVudHMgKG1haW5seSBzY3JvbGwgYmFycykgcG9zaXRpb25zCiAqLwp2b2lkCVdDVVNFUl9Db21wdXRlUG9zaXRpb25zKHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBSRUNUCQlyOwogICAgaW50CQkJZHgsIGR5OwoKICAgIC8qIGNvbXB1dGUgd2luZG93IHNpemUgZnJvbSBkZXNpcmVkIGNsaWVudCBzaXplICovCiAgICByLmxlZnQgPSByLnRvcCA9IDA7CiAgICByLnJpZ2h0ID0gZGF0YS0+Y3VyY2ZnLndpbl93aWR0aCAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoOwogICAgci5ib3R0b20gPSBkYXRhLT5jdXJjZmcud2luX2hlaWdodCAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKCiAgICBpZiAoSXNSZWN0RW1wdHkoJnIpKQogICAgewoJU2hvd1dpbmRvdyhQUklWQVRFKGRhdGEpLT5oV25kLCBTV19ISURFKTsKCXJldHVybjsKICAgIH0KCiAgICBBZGp1c3RXaW5kb3dSZWN0KCZyLCBHZXRXaW5kb3dMb25nKFBSSVZBVEUoZGF0YSktPmhXbmQsIEdXTF9TVFlMRSksIEZBTFNFKTsKCiAgICBkeCA9IGR5ID0gMDsKICAgIGlmIChkYXRhLT5jdXJjZmcuc2Jfd2lkdGggPiBkYXRhLT5jdXJjZmcud2luX3dpZHRoKQogICAgewoJZHkgPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZSFNDUk9MTCk7CglTZXRTY3JvbGxSYW5nZShQUklWQVRFKGRhdGEpLT5oV25kLCBTQl9IT1JaLCAwLAogICAgICAgICAgICAgICAgICAgICAgIGRhdGEtPmN1cmNmZy5zYl93aWR0aCAtIGRhdGEtPmN1cmNmZy53aW5fd2lkdGgsIEZBTFNFKTsKCVNldFNjcm9sbFBvcyhQUklWQVRFKGRhdGEpLT5oV25kLCBTQl9IT1JaLCAwLCBGQUxTRSk7IC8qIEZJWE1FICovCglTaG93U2Nyb2xsQmFyKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX0hPUlosIFRSVUUpOwogICAgfQogICAgZWxzZQogICAgewoJU2hvd1Njcm9sbEJhcihQUklWQVRFKGRhdGEpLT5oV25kLCBTQl9IT1JaLCBGQUxTRSk7CiAgICB9CgogICAgaWYgKGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgPiBkYXRhLT5jdXJjZmcud2luX2hlaWdodCkKICAgIHsKCWR4ID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFZTQ1JPTEwpOwoJU2V0U2Nyb2xsUmFuZ2UoUFJJVkFURShkYXRhKS0+aFduZCwgU0JfVkVSVCwgMCwKICAgICAgICAgICAgICAgICAgICAgICBkYXRhLT5jdXJjZmcuc2JfaGVpZ2h0IC0gZGF0YS0+Y3VyY2ZnLndpbl9oZWlnaHQsIEZBTFNFKTsKCVNldFNjcm9sbFBvcyhQUklWQVRFKGRhdGEpLT5oV25kLCBTQl9WRVJULCAwLCBGQUxTRSk7IC8qIEZJWE1FICovCglTaG93U2Nyb2xsQmFyKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX1ZFUlQsIFRSVUUpOwogICAgfQogICAgZWxzZQogICAgewoJU2hvd1Njcm9sbEJhcihQUklWQVRFKGRhdGEpLT5oV25kLCBTQl9WRVJULCBGQUxTRSk7CiAgICB9CgogICAgU2V0V2luZG93UG9zKFBSSVZBVEUoZGF0YSktPmhXbmQsIDAsIDAsIDAsIHIucmlnaHQgLSByLmxlZnQgKyBkeCwgci5ib3R0b20gLSByLnRvcCArIGR5LAoJCSBTV1BfTk9NT1ZFfFNXUF9OT1pPUkRFUnxTV1BfU0hPV1dJTkRPVyk7CiAgICBXQ1VTRVJfU2hhcGVDdXJzb3IoZGF0YSwgZGF0YS0+Y3VyY2ZnLmN1cnNvcl9zaXplLCBkYXRhLT5jdXJjZmcuY3Vyc29yX3Zpc2libGUsIFRSVUUpOwogICAgV0NVU0VSX1Bvc0N1cnNvcihkYXRhKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1NldFRpdGxlCiAqCiAqIFNldHMgdGhlIHRpdGxlIHRvIHRoZSB3aW5lIGNvbnNvbGUKICovCnN0YXRpYyB2b2lkCVdDVVNFUl9TZXRUaXRsZShjb25zdCBzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgV0NIQVIJYnVmZmVyWzI1Nl07CgogICAgaWYgKFdJTkVDT05fR2V0Q29uc29sZVRpdGxlKGRhdGEtPmhDb25JbiwgYnVmZmVyLCBzaXplb2YoYnVmZmVyKSkpCglTZXRXaW5kb3dUZXh0KFBSSVZBVEUoZGF0YSktPmhXbmQsIGJ1ZmZlcik7Cn0KCnZvaWQgV0NVU0VSX0R1bXBMb2dGb250KGNvbnN0IGNoYXIqIHBmeCwgY29uc3QgTE9HRk9OVCogbGYsIERXT1JEIGZ0KQp7CiAgICBXSU5FX1RSQUNFXyh3Y19mb250KSgiJXMgJXMlcyVzJXNcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICJcdGxmLmxmSGVpZ2h0PSVsZCBsZi5sZldpZHRoPSVsZCBsZi5sZkVzY2FwZW1lbnQ9JWxkIGxmLmxmT3JpZW50YXRpb249JWxkXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAiXHRsZi5sZldlaWdodD0lbGQgbGYubGZJdGFsaWM9JXUgbGYubGZVbmRlcmxpbmU9JXUgbGYubGZTdHJpa2VPdXQ9JXVcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICJcdGxmLmxmQ2hhclNldD0ldSBsZi5sZk91dFByZWNpc2lvbj0ldSBsZi5sZkNsaXBQcmVjaXNpb249JXUgbGYubGZRdWFsaXR5PSV1XG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAiXHRsZi0+bGZQaXRjaEFuZEZhbWlseT0ldSBsZi5sZkZhY2VOYW1lPSVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgcGZ4LAogICAgICAgICAgICAgICAgICAgICAgICAgKGZ0ICYgUkFTVEVSX0ZPTlRUWVBFKSA/ICJyYXN0ZXIiIDogIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAoZnQgJiBUUlVFVFlQRV9GT05UVFlQRSkgPyAidHJ1ZXR5cGUiIDogIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAoKGZ0ICYgKFJBU1RFUl9GT05UVFlQRXxUUlVFVFlQRV9GT05UVFlQRSkpID09IDApID8gInZlY3RvciIgOiAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgIChmdCAmIERFVklDRV9GT05UVFlQRSkgPyAifGRldmljZSIgOiAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgIGxmLT5sZkhlaWdodCwgbGYtPmxmV2lkdGgsIGxmLT5sZkVzY2FwZW1lbnQsIGxmLT5sZk9yaWVudGF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgbGYtPmxmV2VpZ2h0LCBsZi0+bGZJdGFsaWMsIGxmLT5sZlVuZGVybGluZSwgbGYtPmxmU3RyaWtlT3V0LCBsZi0+bGZDaGFyU2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgbGYtPmxmT3V0UHJlY2lzaW9uLCBsZi0+bGZDbGlwUHJlY2lzaW9uLCBsZi0+bGZRdWFsaXR5LCBsZi0+bGZQaXRjaEFuZEZhbWlseSwKICAgICAgICAgICAgICAgICAgICAgICAgIHdpbmVfZGJnc3RyX3cobGYtPmxmRmFjZU5hbWUpKTsKfQoKdm9pZCBXQ1VTRVJfRHVtcFRleHRNZXRyaWMoY29uc3QgVEVYVE1FVFJJQyogdG0sIERXT1JEIGZ0KQp7CiAgICBXSU5FX1RSQUNFXyh3Y19mb250KSgiJXMlcyVzJXNcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICJcdHRtSGVpZ2h0PSVsZCB0bUFzY2VudD0lbGQgdG1EZXNjZW50PSVsZCB0bUludGVybmFsTGVhZGluZz0lbGQgdG1FeHRlcm5hbExlYWRpbmc9JWxkXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAiXHR0bUF2ZUNoYXJXaWR0aD0lbGQgdG1NYXhDaGFyV2lkdGg9JWxkIHRtV2VpZ2h0PSVsZCB0bU92ZXJoYW5nPSVsZFxuIgogICAgICAgICAgICAgICAgICAgICAgICAgIlx0dG1EaWdpdGl6ZWRBc3BlY3RYPSVsZCB0bURpZ2l0aXplZEFzcGVjdFk9JWxkXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICAiXHR0bUZpcnN0Q2hhcj0lZCB0bUxhc3RDaGFyPSVkIHRtRGVmYXVsdENoYXI9JWQgdG1CcmVha0NoYXI9JWRcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICJcdHRtSXRhbGljPSV1IHRtVW5kZXJsaW5lZD0ldSB0bVN0cnVja091dD0ldSB0bVBpdGNoQW5kRmFtaWx5PSV1IHRtQ2hhclNldD0ldVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgIChmdCAmIFJBU1RFUl9GT05UVFlQRSkgPyAicmFzdGVyIiA6ICIiLAogICAgICAgICAgICAgICAgICAgICAgICAgKGZ0ICYgVFJVRVRZUEVfRk9OVFRZUEUpID8gInRydWV0eXBlIiA6ICIiLAogICAgICAgICAgICAgICAgICAgICAgICAgKChmdCAmIChSQVNURVJfRk9OVFRZUEV8VFJVRVRZUEVfRk9OVFRZUEUpKSA9PSAwKSA/ICJ2ZWN0b3IiIDogIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAoZnQgJiBERVZJQ0VfRk9OVFRZUEUpID8gInxkZXZpY2UiIDogIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICB0bS0+dG1IZWlnaHQsIHRtLT50bUFzY2VudCwgdG0tPnRtRGVzY2VudCwgdG0tPnRtSW50ZXJuYWxMZWFkaW5nLCB0bS0+dG1FeHRlcm5hbExlYWRpbmcsIHRtLT50bUF2ZUNoYXJXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgIHRtLT50bU1heENoYXJXaWR0aCwgdG0tPnRtV2VpZ2h0LCB0bS0+dG1PdmVyaGFuZywgdG0tPnRtRGlnaXRpemVkQXNwZWN0WCwgdG0tPnRtRGlnaXRpemVkQXNwZWN0WSwKICAgICAgICAgICAgICAgICAgICAgICAgIHRtLT50bUZpcnN0Q2hhciwgdG0tPnRtTGFzdENoYXIsIHRtLT50bURlZmF1bHRDaGFyLCB0bS0+dG1CcmVha0NoYXIsIHRtLT50bUl0YWxpYywgdG0tPnRtVW5kZXJsaW5lZCwgdG0tPnRtU3RydWNrT3V0LAogICAgICAgICAgICAgICAgICAgICAgICAgdG0tPnRtUGl0Y2hBbmRGYW1pbHksIHRtLT50bUNoYXJTZXQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfQXJlRm9udHNFcXVhbAogKgogKgogKi8KQk9PTCBXQ1VTRVJfQXJlRm9udHNFcXVhbChjb25zdCBzdHJ1Y3QgY29uZmlnX2RhdGEqIGNvbmZpZywgY29uc3QgTE9HRk9OVCogbGYpCnsKICAgIHJldHVybiBsZi0+bGZIZWlnaHQgPT0gY29uZmlnLT5jZWxsX2hlaWdodCAmJgogICAgICAgIGxmLT5sZldlaWdodCA9PSBjb25maWctPmZvbnRfd2VpZ2h0ICYmCiAgICAgICAgIWxmLT5sZkl0YWxpYyAmJiAhbGYtPmxmVW5kZXJsaW5lICYmICFsZi0+bGZTdHJpa2VPdXQgJiYKICAgICAgICAhbHN0cmNtcChsZi0+bGZGYWNlTmFtZSwgY29uZmlnLT5mYWNlX25hbWUpOwp9CgpzdHJ1Y3QgZm9udF9jaG9vc2VyCnsKICAgIHN0cnVjdCBpbm5lcl9kYXRhKglkYXRhOwogICAgaW50CQkJZG9uZTsKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9WYWxpZGF0ZUZvbnRNZXRyaWMKICoKICogUmV0dXJucyB0cnVlIGlmIHRoZSBmb250IGRlc2NyaWJlZCBpbiB0bSBpcyB1c2FibGUgYXMgYSBmb250IGZvciB0aGUgcmVuZGVyZXIKICovCkJPT0wJV0NVU0VSX1ZhbGlkYXRlRm9udE1ldHJpYyhjb25zdCBzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgY29uc3QgVEVYVE1FVFJJQyogdG0sIERXT1JEIGZvbnRUeXBlKQp7CiAgICBCT09MICAgICAgICByZXQgPSBUUlVFOwoKICAgIGlmIChmb250VHlwZSAmIFJBU1RFUl9GT05UVFlQRSkKICAgICAgICByZXQgPSAodG0tPnRtTWF4Q2hhcldpZHRoICogZGF0YS0+Y3VyY2ZnLndpbl93aWR0aCA8IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTQ1JFRU4pICYmCiAgICAgICAgICAgICAgIHRtLT50bUhlaWdodCAqIGRhdGEtPmN1cmNmZy53aW5faGVpZ2h0IDwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNDUkVFTikpOwogICAgcmV0dXJuIHJldCAmJiAhdG0tPnRtSXRhbGljICYmICF0bS0+dG1VbmRlcmxpbmVkICYmICF0bS0+dG1TdHJ1Y2tPdXQgJiYKICAgICAgICAodG0tPnRtQ2hhclNldCA9PSBERUZBVUxUX0NIQVJTRVQgfHwgdG0tPnRtQ2hhclNldCA9PSBBTlNJX0NIQVJTRVQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfVmFsaWRhdGVGb250CiAqCiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZm9udCBmYW1pbHkgZGVzY3JpYmVkIGluIGxmIGlzIHVzYWJsZSBhcyBhIGZvbnQgZm9yIHRoZSByZW5kZXJlcgogKi8KQk9PTAlXQ1VTRVJfVmFsaWRhdGVGb250KGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBjb25zdCBMT0dGT05UKiBsZikKewogICAgcmV0dXJuIChsZi0+bGZQaXRjaEFuZEZhbWlseSAmIDMpID09IEZJWEVEX1BJVENIICYmCiAgICAgICAgLyogKGxmLT5sZlBpdGNoQW5kRmFtaWx5ICYgMHhGMCkgPT0gRkZfTU9ERVJOICYmICovCiAgICAgICAgKGxmLT5sZkNoYXJTZXQgPT0gREVGQVVMVF9DSEFSU0VUIHx8IGxmLT5sZkNoYXJTZXQgPT0gQU5TSV9DSEFSU0VUKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJZ2V0X2ZpcnN0X2ZvbnRfZW51bV8yCiAqCQlnZXRfZmlyc3RfZm9udF9lbnVtCiAqCiAqIEhlbHBlciBmdW5jdGlvbnMgdG8gZ2V0IGEgZGVjZW50IGZvbnQgZm9yIHRoZSByZW5kZXJlcgogKi8Kc3RhdGljIGludCBDQUxMQkFDSyBnZXRfZmlyc3RfZm9udF9lbnVtXzIoY29uc3QgTE9HRk9OVCogbGYsIGNvbnN0IFRFWFRNRVRSSUMqIHRtLAoJCQkJCSAgRFdPUkQgRm9udFR5cGUsIExQQVJBTSBsUGFyYW0pCnsKICAgIHN0cnVjdCBmb250X2Nob29zZXIqCWZjID0gKHN0cnVjdCBmb250X2Nob29zZXIqKWxQYXJhbTsKCiAgICBXQ1VTRVJfRHVtcFRleHRNZXRyaWModG0sIEZvbnRUeXBlKTsKICAgIGlmIChXQ1VTRVJfVmFsaWRhdGVGb250TWV0cmljKGZjLT5kYXRhLCB0bSwgRm9udFR5cGUpKQogICAgewogICAgICAgIExPR0ZPTlQgbWxmID0gKmxmOwoKICAgICAgICAvKiBVc2UgdGhlIGRlZmF1bHQgc2l6ZXMgZm9yIHRoZSBmb250ICh0aGlzIGlzIG5lZWRlZCwgZXNwZWNpYWxseSBmb3IKICAgICAgICAgKiBUcnVlVHlwZSBmb250cywgc28gdGhhdCB3ZSBnZXQgYSBkZWNlbnQgc2l6ZSwgbm90IHRoZSBtYXggc2l6ZSkKICAgICAgICAgKi8KICAgICAgICBtbGYubGZXaWR0aCAgPSBmYy0+ZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGg7CiAgICAgICAgbWxmLmxmSGVpZ2h0ID0gZmMtPmRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKICAgICAgICBpZiAoV0NVU0VSX1NldEZvbnQoZmMtPmRhdGEsICZtbGYpKQogICAgICAgIHsKICAgICAgICAgICAgV0NVU0VSX0R1bXBMb2dGb250KCJJbml0Q2hvb3Npbmc6ICIsICZtbGYsIEZvbnRUeXBlKTsKICAgICAgICAgICAgZmMtPmRvbmUgPSAxOwogICAgICAgICAgICAvKiBzaW5jZSB3ZSd2ZSBtb2RpZmllZCB0aGUgY3VycmVudCBjb25maWcgd2l0aCBuZXcgZm9udCBpbmZvcm1hdGlvbiwKICAgICAgICAgICAgICogc2V0IHRoaXMgaW5mb3JtYXRpb24gYXMgdGhlIG5ldyBkZWZhdWx0LgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZmMtPmRhdGEtPmRlZmNmZy5jZWxsX3dpZHRoID0gZmMtPmRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoOwogICAgICAgICAgICBmYy0+ZGF0YS0+ZGVmY2ZnLmNlbGxfaGVpZ2h0ID0gZmMtPmRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKICAgICAgICAgICAgbHN0cmNweVcoZmMtPmRhdGEtPmRlZmNmZy5mYWNlX25hbWUsIGZjLT5kYXRhLT5jdXJjZmcuZmFjZV9uYW1lKTsKICAgICAgICAgICAgLyogRm9yY2UgYWxzbyBpdHMgd3JpdGluZyBiYWNrIHRvIHRoZSByZWdpc3RyeSBzbyB0aGF0IHdlIGNhbiBnZXQgaXQKICAgICAgICAgICAgICogdGhlIG5leHQgdGltZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIFdJTkVDT05fUmVnU2F2ZSgmZmMtPmRhdGEtPmRlZmNmZyk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiAxOwp9CgpzdGF0aWMgaW50IENBTExCQUNLIGdldF9maXJzdF9mb250X2VudW0oY29uc3QgTE9HRk9OVCogbGYsIGNvbnN0IFRFWFRNRVRSSUMqIHRtLAoJCQkJCURXT1JEIEZvbnRUeXBlLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBzdHJ1Y3QgZm9udF9jaG9vc2VyKglmYyA9IChzdHJ1Y3QgZm9udF9jaG9vc2VyKilsUGFyYW07CgogICAgV0NVU0VSX0R1bXBMb2dGb250KCJJbml0RmFtaWx5OiAiLCBsZiwgRm9udFR5cGUpOwogICAgaWYgKFdDVVNFUl9WYWxpZGF0ZUZvbnQoZmMtPmRhdGEsIGxmKSkKICAgIHsKCUVudW1Gb250RmFtaWxpZXMoUFJJVkFURShmYy0+ZGF0YSktPmhNZW1EQywgbGYtPmxmRmFjZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICBnZXRfZmlyc3RfZm9udF9lbnVtXzIsIGxQYXJhbSk7CglyZXR1cm4gIWZjLT5kb25lOyAvKiB3ZSBqdXN0IG5lZWQgdGhlIGZpcnN0IG1hdGNoaW5nIG9uZS4uLiAqLwogICAgfQogICAgcmV0dXJuIDE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9Db3B5Rm9udAogKgogKiBnZXQgdGhlIHJlbGV2YW50IGluZm9ybWF0aW9uIGZyb20gdGhlIGZvbnQgZGVzY3JpYmVkIGluIGxmIGFuZCBzdG9yZSB0aGVtCiAqIGluIGNvbmZpZwogKi8KSEZPTlQgV0NVU0VSX0NvcHlGb250KHN0cnVjdCBjb25maWdfZGF0YSogY29uZmlnLCBIV05EIGhXbmQsIGNvbnN0IExPR0ZPTlQqIGxmKQp7CiAgICBURVhUTUVUUklDICB0bTsKICAgIEhEQyAgICAgICAgIGhEQzsKICAgIEhGT05UICAgICAgIGhGb250LCBoT2xkRm9udDsKICAgIGludCAgICAgICAgIHcsIGksIGJ1ZlsyNTZdOwoKICAgIGlmICghKGhEQyA9IEdldERDKGhXbmQpKSkgcmV0dXJuIChIRk9OVCkwOwogICAgaWYgKCEoaEZvbnQgPSBDcmVhdGVGb250SW5kaXJlY3QobGYpKSkgZ290byBlcnIxOwoKICAgIGhPbGRGb250ID0gU2VsZWN0T2JqZWN0KGhEQywgaEZvbnQpOwogICAgR2V0VGV4dE1ldHJpY3MoaERDLCAmdG0pOwoKICAgIC8qIEZJWE1FOgogICAgICogdGhlIGN1cnJlbnQgZnJlZXR5cGUgZW5naW5lIChhdCBsZWFzdCAyLjAueCB3aXRoIHggPD0gOCkgYW5kIGl0cyBpbXBsZW1lbnRhdGlvbgogICAgICogaW4gV2luZSBkb24ndCByZXR1cm4gYWRlcXVhdGUgdmFsdWVzIGZvciBmaXhlZCBmb250cwogICAgICogSW4gV2luZG93cywgdGhvc2UgZm9udHMgYXJlIGV4cGVjdGVkIHRvIHJldHVybiB0aGUgc2FtZSB2YWx1ZSBmb3IKICAgICAqICAtIHRoZSBhdmVyYWdlIHdpZHRoCiAgICAgKiAgLSB0aGUgbGFyZ2VzdCB3aWR0aAogICAgICogIC0gdGhlIHdpZHRoIG9mIGFsbCBjaGFyYWN0ZXJzIGluIHRoZSBmb250CiAgICAgKiBUaGlzIGlzbid0IHRydWUgaW4gV2luZS4gQXMgYSB0ZW1wb3Jhcnkgd29ya2Fyb3VuZCwgd2UgZ2V0IGFzIHRoZSB3aWR0aCBvZiB0aGUKICAgICAqIGNlbGwsIHRoZSB3aWR0aCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHRoZSBmb250LCBhZnRlciBjaGVja2luZyB0aGF0IGFsbAogICAgICogY2hhcmFjdGVycyBpbiB0aGUgZm9udCBoYXZlIHRoZSBzYW1lIHdpZHRoIChJIGhlYXIgcGFyYW5v72EgY29taW5nKQogICAgICogd2hlbiB0aGlzIGdldHMgZml4ZWQsIHRoZSBjb2RlIHNob3VsZCBiZSB1c2luZyB0bS50bUF2ZUNoYXJXaWR0aAogICAgICogb3IgdG0udG1NYXhDaGFyV2lkdGggYXMgdGhlIGNlbGwgd2lkdGguCiAgICAgKi8KICAgIEdldENoYXJXaWR0aDMyKGhEQywgdG0udG1GaXJzdENoYXIsIHRtLnRtRmlyc3RDaGFyLCAmdyk7CiAgICBmb3IgKGkgPSB0bS50bUZpcnN0Q2hhciArIDE7IGkgPD0gdG0udG1MYXN0Q2hhcjsgaSArPSBzaXplb2YoYnVmKSAvIHNpemVvZihidWZbMF0pKQogICAgewogICAgICAgIGludCBqLCBsOwoKICAgICAgICBsID0gbWluKHRtLnRtTGFzdENoYXIgLSBpLCBzaXplb2YoYnVmKSAvIHNpemVvZihidWZbMF0pIC0gMSk7CiAgICAgICAgR2V0Q2hhcldpZHRoMzIoaERDLCBpLCBpICsgbCwgYnVmKTsKICAgICAgICBmb3IgKGogPSAwOyBqIDw9IGw7IGorKykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChidWZbal0gIT0gdykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV0lORV9XQVJOKCJOb24gdW5pZm9ybSBjZWxsIHdpZHRoOiBbJWRdPSVkIFslZF09JWRcbiIKICAgICAgICAgICAgICAgICAgICAgICAgICAiVGhpcyBtYXkgYmUgY2F1c2VkIGJ5IG9sZCBmcmVldHlwZSBsaWJyYXJpZXMsID49IDIuMC44IGlzIHJlY29tbWVuZGVkXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgIGkgKyBqLCBidWZbal0sIHRtLnRtRmlyc3RDaGFyLCB3KTsKICAgICAgICAgICAgICAgIGdvdG8gZXJyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgU2VsZWN0T2JqZWN0KGhEQywgaE9sZEZvbnQpOwogICAgUmVsZWFzZURDKGhXbmQsIGhEQyk7CgogICAgY29uZmlnLT5jZWxsX3dpZHRoICA9IHc7CiAgICBjb25maWctPmNlbGxfaGVpZ2h0ID0gdG0udG1IZWlnaHQgKyB0bS50bUV4dGVybmFsTGVhZGluZzsKICAgIGNvbmZpZy0+Zm9udF93ZWlnaHQgPSB0bS50bVdlaWdodDsKICAgIGxzdHJjcHkoY29uZmlnLT5mYWNlX25hbWUsIGxmLT5sZkZhY2VOYW1lKTsKCiAgICByZXR1cm4gaEZvbnQ7CiBlcnI6CiAgICBpZiAoaERDICYmIGhPbGRGb250KSBTZWxlY3RPYmplY3QoaERDLCBoT2xkRm9udCk7CiAgICBpZiAoaEZvbnQpIERlbGV0ZU9iamVjdChoRm9udCk7CiBlcnIxOgogICAgaWYgKGhEQykgUmVsZWFzZURDKGhXbmQsIGhEQyk7CgogICAgcmV0dXJuIChIRk9OVCkwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfRmlsbExvZ0ZvbnQKICoKICoKICovCnZvaWQgICAgV0NVU0VSX0ZpbGxMb2dGb250KExPR0ZPTlQqIGxmLCBjb25zdCBXQ0hBUiogbmFtZSwgVUlOVCBoZWlnaHQsIFVJTlQgd2VpZ2h0KQp7CiAgICBsZi0+bGZIZWlnaHQgICAgICAgID0gaGVpZ2h0OwogICAgbGYtPmxmV2lkdGggICAgICAgICA9IDA7CiAgICBsZi0+bGZFc2NhcGVtZW50ICAgID0gMDsKICAgIGxmLT5sZk9yaWVudGF0aW9uICAgPSAwOwogICAgbGYtPmxmV2VpZ2h0ICAgICAgICA9IHdlaWdodDsKICAgIGxmLT5sZkl0YWxpYyAgICAgICAgPSBGQUxTRTsKICAgIGxmLT5sZlVuZGVybGluZSAgICAgPSBGQUxTRTsKICAgIGxmLT5sZlN0cmlrZU91dCAgICAgPSBGQUxTRTsKICAgIGxmLT5sZkNoYXJTZXQgICAgICAgPSBERUZBVUxUX0NIQVJTRVQ7CiAgICBsZi0+bGZPdXRQcmVjaXNpb24gID0gT1VUX0RFRkFVTFRfUFJFQ0lTOwogICAgbGYtPmxmQ2xpcFByZWNpc2lvbiA9IENMSVBfREVGQVVMVF9QUkVDSVM7CiAgICBsZi0+bGZRdWFsaXR5ICAgICAgID0gREVGQVVMVF9RVUFMSVRZOwogICAgbGYtPmxmUGl0Y2hBbmRGYW1pbHkgPSBGSVhFRF9QSVRDSCB8IEZGX0RPTlRDQVJFOwogICAgbHN0cmNweShsZi0+bGZGYWNlTmFtZSwgbmFtZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9TZXRGb250CiAqCiAqIHNldHMgbG9nZm9udCBhcyB0aGUgbmV3IGZvbnQgZm9yIHRoZSBjb25zb2xlCiAqLwpCT09MCVdDVVNFUl9TZXRGb250KHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBjb25zdCBMT0dGT05UKiBsb2dmb250KQp7CiAgICBIRk9OVCAgICAgICBoRm9udDsKCiAgICBpZiAoUFJJVkFURShkYXRhKS0+aEZvbnQgIT0gMCAmJiBXQ1VTRVJfQXJlRm9udHNFcXVhbCgmZGF0YS0+Y3VyY2ZnLCBsb2dmb250KSkKICAgICAgICByZXR1cm4gVFJVRTsKCiAgICBoRm9udCA9IFdDVVNFUl9Db3B5Rm9udCgmZGF0YS0+Y3VyY2ZnLCBQUklWQVRFKGRhdGEpLT5oV25kLCBsb2dmb250KTsKICAgIGlmICghaEZvbnQpIHtXSU5FX0VSUigid3JvbmcgZm9udFxuIik7IHJldHVybiBGQUxTRTt9CgogICAgaWYgKFBSSVZBVEUoZGF0YSktPmhGb250KSBEZWxldGVPYmplY3QoUFJJVkFURShkYXRhKS0+aEZvbnQpOwogICAgUFJJVkFURShkYXRhKS0+aEZvbnQgPSBoRm9udDsKCiAgICBXQ1VTRVJfQ29tcHV0ZVBvc2l0aW9ucyhkYXRhKTsKICAgIFdDVVNFUl9OZXdCaXRtYXAoZGF0YSwgVFJVRSk7CiAgICBJbnZhbGlkYXRlUmVjdChQUklWQVRFKGRhdGEpLT5oV25kLCBOVUxMLCBGQUxTRSk7CiAgICBVcGRhdGVXaW5kb3coUFJJVkFURShkYXRhKS0+aFduZCk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9Jbml0Rm9udAogKgogKiBjcmVhdGUgYSBoRm9udCBmcm9tIHRoZSBzZXR0aW5ncyBzYXZlZCBpbiByZWdpc3RyeS4uLgogKiAoY2FsbGVkIG9uIGluaXQsIGFzc3VtaW5nIG5vIGZvbnQgaGFzIGJlZW4gY3JlYXRlZCBiZWZvcmUpCiAqLwpzdGF0aWMgQk9PTAlXQ1VTRVJfSW5pdEZvbnQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIHN0cnVjdCBmb250X2Nob29zZXIgZmM7CgogICAgV0lORV9UUkFDRV8od2NfZm9udCkoIj0+ICVzXG4iLCB3aW5lX2RiZ3N0cl93bihkYXRhLT5jdXJjZmcuZmFjZV9uYW1lLCAtMSkpOwogICAgaWYgKGRhdGEtPmN1cmNmZy5mYWNlX25hbWVbMF0gIT0gJ1wwJyAmJgogICAgICAgIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCAhPSAwICYmCiAgICAgICAgZGF0YS0+Y3VyY2ZnLmZvbnRfd2VpZ2h0ICE9IDApCiAgICB7CiAgICAgICAgTE9HRk9OVCAgICAgICAgICAgICBsZjsKCiAgICAgICAgV0NVU0VSX0ZpbGxMb2dGb250KCZsZiwgZGF0YS0+Y3VyY2ZnLmZhY2VfbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0LCBkYXRhLT5jdXJjZmcuZm9udF93ZWlnaHQpOwogICAgICAgIGlmIChQUklWQVRFKGRhdGEpLT5oRm9udCAhPSAwKSBXSU5FX0ZJWE1FKCJPaCBzdHJhbmdlXG4iKTsKCiAgICAgICAgaWYgKFdDVVNFUl9TZXRGb250KGRhdGEsICZsZikpCiAgICAgICAgewogICAgICAgICAgICBXQ1VTRVJfRHVtcExvZ0ZvbnQoIkluaXRSZXVzZXM6ICIsICZsZiwgMCk7CiAgICAgICAgICAgIHJldHVybiBUUlVFOwogICAgICAgIH0KICAgIH0KCiAgICAvKiB0cnkgdG8gZmluZCBhbiBhY2NlcHRhYmxlIGZvbnQgKi8KICAgIFdJTkVfV0FSTigiQ291bGRuJ3QgbWF0Y2ggdGhlIGZvbnQgZnJvbSByZWdpc3RyeS4uLiB0cnlpbmcgdG8gZmluZCBvbmVcbiIpOwogICAgZmMuZGF0YSA9IGRhdGE7CiAgICBmYy5kb25lID0gMDsKICAgIEVudW1Gb250RmFtaWxpZXMoUFJJVkFURShkYXRhKS0+aE1lbURDLCBOVUxMLCBnZXRfZmlyc3RfZm9udF9lbnVtLCAoTFBBUkFNKSZmYyk7CiAgICBpZiAoIWZjLmRvbmUpIFdJTkVfV0FSTigiQ291bGRuJ3QgZmluZCBhIGRlY2VudCBmb250LCBhYm9ydGluZ1xuIik7CiAgICByZXR1cm4gZmMuZG9uZTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX0dldENlbGwKICoKICogR2V0IGEgY2VsbCBmcm9tIGEgcmVsYXRpdmUgY29vcmRpbmF0ZSBpbiB3aW5kb3cgKHRha2VzIGludG8KICogYWNjb3VudCB0aGUgc2Nyb2xsaW5nKQogKi8Kc3RhdGljIENPT1JECVdDVVNFUl9HZXRDZWxsKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBDT09SRAljOwoKICAgIGMuWCA9IGRhdGEtPmN1cmNmZy53aW5fcG9zLlggKyAoc2hvcnQpTE9XT1JEKGxQYXJhbSkgLyBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKICAgIGMuWSA9IGRhdGEtPmN1cmNmZy53aW5fcG9zLlkgKyAoc2hvcnQpSElXT1JEKGxQYXJhbSkgLyBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQ7CgogICAgcmV0dXJuIGM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9HZXRTZWxlY3Rpb25SZWN0CiAqCiAqIEdldCB0aGUgc2VsZWN0aW9uIHJlY3RhbmdsZQogKi8Kc3RhdGljIHZvaWQJV0NVU0VSX0dldFNlbGVjdGlvblJlY3QoY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIExQUkVDVCByKQp7CiAgICByLT5sZWZ0ICAgPSAobWluKFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MS5YLCBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDIuWCkgICAgIC0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWCkgKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aDsKICAgIHItPnRvcCAgICA9IChtaW4oUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlksIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5ZKSAgICAgLSBkYXRhLT5jdXJjZmcud2luX3Bvcy5ZKSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKICAgIHItPnJpZ2h0ICA9IChtYXgoUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlgsIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5YKSArIDEgLSBkYXRhLT5jdXJjZmcud2luX3Bvcy5YKSAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoOwogICAgci0+Ym90dG9tID0gKG1heChQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWSwgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlkpICsgMSAtIGRhdGEtPmN1cmNmZy53aW5fcG9zLlkpICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfU2V0U2VsZWN0aW9uCiAqCiAqCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfU2V0U2VsZWN0aW9uKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBIREMgaFJlZkRDKQp7CiAgICBIREMJCWhEQzsKICAgIFJFQ1QJcjsKCiAgICBXQ1VTRVJfR2V0U2VsZWN0aW9uUmVjdChkYXRhLCAmcik7CiAgICBoREMgPSBoUmVmREMgPyBoUmVmREMgOiBHZXREQyhQUklWQVRFKGRhdGEpLT5oV25kKTsKICAgIGlmIChoREMpCiAgICB7CglpZiAoUFJJVkFURShkYXRhKS0+aFduZCA9PSBHZXRGb2N1cygpICYmIGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKCSAgICBIaWRlQ2FyZXQoUFJJVkFURShkYXRhKS0+aFduZCk7CglJbnZlcnRSZWN0KGhEQywgJnIpOwoJaWYgKGhEQyAhPSBoUmVmREMpCgkgICAgUmVsZWFzZURDKFBSSVZBVEUoZGF0YSktPmhXbmQsIGhEQyk7CglpZiAoUFJJVkFURShkYXRhKS0+aFduZCA9PSBHZXRGb2N1cygpICYmIGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKCSAgICBTaG93Q2FyZXQoUFJJVkFURShkYXRhKS0+aFduZCk7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9Nb3ZlU2VsZWN0aW9uCiAqCiAqCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfTW92ZVNlbGVjdGlvbihzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgQ09PUkQgYzEsIENPT1JEIGMyLCBCT09MIGZpbmFsKQp7CiAgICBSRUNUCXI7CiAgICBIREMJCWhEQzsKCiAgICBXQ1VTRVJfR2V0U2VsZWN0aW9uUmVjdChkYXRhLCAmcik7CiAgICBoREMgPSBHZXREQyhQUklWQVRFKGRhdGEpLT5oV25kKTsKICAgIGlmIChoREMpCiAgICB7CglpZiAoUFJJVkFURShkYXRhKS0+aFduZCA9PSBHZXRGb2N1cygpICYmIGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKCSAgICBIaWRlQ2FyZXQoUFJJVkFURShkYXRhKS0+aFduZCk7CglJbnZlcnRSZWN0KGhEQywgJnIpOwogICAgfQogICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxID0gYzE7CiAgICBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDIgPSBjMjsKICAgIGlmIChoREMpCiAgICB7CglXQ1VTRVJfR2V0U2VsZWN0aW9uUmVjdChkYXRhLCAmcik7CglJbnZlcnRSZWN0KGhEQywgJnIpOwoJUmVsZWFzZURDKFBSSVZBVEUoZGF0YSktPmhXbmQsIGhEQyk7CglpZiAoUFJJVkFURShkYXRhKS0+aFduZCA9PSBHZXRGb2N1cygpICYmIGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKCSAgICBTaG93Q2FyZXQoUFJJVkFURShkYXRhKS0+aFduZCk7CiAgICB9CiAgICBpZiAoZmluYWwpCiAgICB7CglSZWxlYXNlQ2FwdHVyZSgpOwoJUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiA9IFRSVUU7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9Db3B5U2VsZWN0aW9uVG9DbGlwYm9hcmQKICoKICogQ29waWVzIHRoZSBjdXJyZW50IHNlbGVjdGlvbiBpbnRvIHRoZSBjbGlwYm9hcmQKICovCnN0YXRpYyB2b2lkCVdDVVNFUl9Db3B5U2VsZWN0aW9uVG9DbGlwYm9hcmQoY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIEhBTkRMRQloTWVtOwogICAgTFBXU1RSCXA7CiAgICB1bnNpZ25lZAl3LCBoOwoKICAgIHcgPSBhYnMoUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlggLSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDIuWCkgKyAyOwogICAgaCA9IGFicyhQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWSAtIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5ZKSArIDE7CgogICAgaWYgKCFPcGVuQ2xpcGJvYXJkKFBSSVZBVEUoZGF0YSktPmhXbmQpKSByZXR1cm47CiAgICBFbXB0eUNsaXBib2FyZCgpOwoKICAgIGhNZW0gPSBHbG9iYWxBbGxvYyhHTUVNX01PVkVBQkxFLCAodyAqIGgpICogc2l6ZW9mKFdDSEFSKSk7CiAgICBpZiAoaE1lbSAmJiAocCA9IEdsb2JhbExvY2soaE1lbSkpKQogICAgewoJQ09PUkQJYzsKCWludAl5OwoKCWMuWCA9IG1pbihQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWCwgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlgpOwoJYy5ZID0gbWluKFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MS5ZLCBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDIuWSk7CgoJZm9yICh5ID0gMDsgeSA8IGg7IHkrKywgYy5ZKyspCgl7CgkgICAgUmVhZENvbnNvbGVPdXRwdXRDaGFyYWN0ZXIoZGF0YS0+aENvbk91dCwgJnBbeSAqIHddLCB3IC0gMSwgYywgTlVMTCk7CgkgICAgcFt5ICogdyArIHcgLSAxXSA9ICh5IDwgaCAtIDEpID8gJ1xuJyA6ICdcMCc7Cgl9CglHbG9iYWxVbmxvY2soaE1lbSk7CglTZXRDbGlwYm9hcmREYXRhKENGX1VOSUNPREVURVhULCBoTWVtKTsKICAgIH0KICAgIENsb3NlQ2xpcGJvYXJkKCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9QYXN0ZUZyb21DbGlwYm9hcmQKICoKICoKICovCnN0YXRpYyB2b2lkCVdDVVNFUl9QYXN0ZUZyb21DbGlwYm9hcmQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIEhBTkRMRQloOwogICAgV0NIQVIqCXB0cjsKCiAgICBpZiAoIU9wZW5DbGlwYm9hcmQoUFJJVkFURShkYXRhKS0+aFduZCkpIHJldHVybjsKICAgIGggPSBHZXRDbGlwYm9hcmREYXRhKENGX1VOSUNPREVURVhUKTsKICAgIGlmIChoICYmIChwdHIgPSBHbG9iYWxMb2NrKGgpKSkKICAgIHsKCWludAkJaSwgbGVuID0gR2xvYmFsU2l6ZShoKSAvIHNpemVvZihXQ0hBUik7CglJTlBVVF9SRUNPUkQJaXJbMl07CglEV09SRAkJbjsKCVNIT1JUCQlzaDsKCglpclswXS5FdmVudFR5cGUgPSBLRVlfRVZFTlQ7CglpclswXS5FdmVudC5LZXlFdmVudC53UmVwZWF0Q291bnQgPSAwOwoJaXJbMF0uRXZlbnQuS2V5RXZlbnQuZHdDb250cm9sS2V5U3RhdGUgPSAwOwoJaXJbMF0uRXZlbnQuS2V5RXZlbnQuYktleURvd24gPSBUUlVFOwoKCS8qIGdlbmVyYXRlIHRoZSBjb3JyZXNwb25kaW5nIGlucHV0IHJlY29yZHMgKi8KCWZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykKCXsKCSAgICAvKiBGSVhNRTogdGhlIG1vZGlmeWluZyBrZXlzIGFyZSBub3QgZ2VuZXJhdGVkIChzaGlmdCwgY3RybC4uLikgKi8KCSAgICBzaCA9IFZrS2V5U2NhbihwdHJbaV0pOwoJICAgIGlyWzBdLkV2ZW50LktleUV2ZW50LndWaXJ0dWFsS2V5Q29kZSA9IExPQllURShzaCk7CgkgICAgaXJbMF0uRXZlbnQuS2V5RXZlbnQud1ZpcnR1YWxTY2FuQ29kZSA9IE1hcFZpcnR1YWxLZXkoTE9CWVRFKHNoKSwgMCk7CgkgICAgaXJbMF0uRXZlbnQuS2V5RXZlbnQudUNoYXIuVW5pY29kZUNoYXIgPSBwdHJbaV07CgoJICAgIGlyWzFdID0gaXJbMF07CgkgICAgaXJbMV0uRXZlbnQuS2V5RXZlbnQuYktleURvd24gPSBGQUxTRTsKCgkgICAgV3JpdGVDb25zb2xlSW5wdXQoZGF0YS0+aENvbkluLCBpciwgMiwgJm4pOwoJfQoJR2xvYmFsVW5sb2NrKGgpOwogICAgfQogICAgQ2xvc2VDbGlwYm9hcmQoKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1JlZnJlc2gKICoKICoKICovCnN0YXRpYyB2b2lkIFdDVVNFUl9SZWZyZXNoKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBpbnQgdHAsIGludCBibSkKewogICAgV0NVU0VSX0ZpbGxNZW1EQyhkYXRhLCB0cCwgYm0pOwogICAgaWYgKGRhdGEtPmN1cmNmZy53aW5fcG9zLlkgPD0gYm0gJiYgZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSArIGRhdGEtPmN1cmNmZy53aW5faGVpZ2h0ID49IHRwKQogICAgewoJUkVDVAlyOwoKCXIubGVmdCAgID0gMDsKCXIucmlnaHQgID0gZGF0YS0+Y3VyY2ZnLndpbl93aWR0aCAqIGRhdGEtPmN1cmNmZy5jZWxsX3dpZHRoOwoJci50b3AgICAgPSAodHAgLSBkYXRhLT5jdXJjZmcud2luX3Bvcy5ZKSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKCXIuYm90dG9tID0gKGJtIC0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSArIDEpICogZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0OwoJSW52YWxpZGF0ZVJlY3QoUFJJVkFURShkYXRhKS0+aFduZCwgJnIsIEZBTFNFKTsKCVVwZGF0ZVdpbmRvdyhQUklWQVRFKGRhdGEpLT5oV25kKTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV0NVU0VSX1BhaW50CiAqCiAqCiAqLwpzdGF0aWMgdm9pZAlXQ1VTRVJfUGFpbnQoY29uc3Qgc3RydWN0IGlubmVyX2RhdGEqIGRhdGEpCnsKICAgIFBBSU5UU1RSVUNUCQlwczsKCiAgICBCZWdpblBhaW50KFBSSVZBVEUoZGF0YSktPmhXbmQsICZwcyk7CiAgICBCaXRCbHQocHMuaGRjLCAwLCAwLAogICAgICAgICAgIGRhdGEtPmN1cmNmZy53aW5fd2lkdGggKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwKICAgICAgICAgICBkYXRhLT5jdXJjZmcud2luX2hlaWdodCAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCwKCSAgIFBSSVZBVEUoZGF0YSktPmhNZW1EQywKICAgICAgICAgICBkYXRhLT5jdXJjZmcud2luX3Bvcy5YICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGgsCiAgICAgICAgICAgZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodCwKCSAgIFNSQ0NPUFkpOwogICAgaWYgKFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24pCglXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIHBzLmhkYyk7CiAgICBFbmRQYWludChQUklWQVRFKGRhdGEpLT5oV25kLCAmcHMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfU2Nyb2xsCiAqCiAqCiAqLwpzdGF0aWMgdm9pZCBXQ1VTRVJfU2Nyb2xsKHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBpbnQgcG9zLCBCT09MIGhvcnopCnsKICAgIGlmIChob3J6KQogICAgewoJU2V0U2Nyb2xsUG9zKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX0hPUlosIHBvcywgVFJVRSk7CglkYXRhLT5jdXJjZmcud2luX3Bvcy5YID0gcG9zOwogICAgfQogICAgZWxzZQogICAgewoJU2V0U2Nyb2xsUG9zKFBSSVZBVEUoZGF0YSktPmhXbmQsIFNCX1ZFUlQsIHBvcywgVFJVRSk7CglkYXRhLT5jdXJjZmcud2luX3Bvcy5ZID0gcG9zOwogICAgfQogICAgSW52YWxpZGF0ZVJlY3QoUFJJVkFURShkYXRhKS0+aFduZCwgTlVMTCwgRkFMU0UpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfRmlsbE1lbnUKICoKICoKICovCnN0YXRpYyBCT09MIFdDVVNFUl9GaWxsTWVudShITUVOVSBoTWVudSwgQk9PTCBzZXApCnsKICAgIEhNRU5VCQloU3ViTWVudTsKICAgIEhJTlNUQU5DRQkJaEluc3RhbmNlID0gR2V0TW9kdWxlSGFuZGxlKE5VTEwpOwogICAgV0NIQVIJCWJ1ZmZbMjU2XTsKCiAgICBpZiAoIWhNZW51KSByZXR1cm4gRkFMU0U7CgogICAgLyogRklYTUU6IGVycm9yIGhhbmRsaW5nICYgbWVtb3J5IGNsZWFudXAgKi8KICAgIGhTdWJNZW51ID0gQ3JlYXRlTWVudSgpOwogICAgaWYgKCFoU3ViTWVudSkgcmV0dXJuIEZBTFNFOwoKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfTUFSSywgYnVmZiwgc2l6ZW9mKGJ1ZmYpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBJbnNlcnRNZW51KGhTdWJNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TVFJJTkcsIElEU19NQVJLLCBidWZmKTsKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfQ09QWSwgYnVmZiwgc2l6ZW9mKGJ1ZmYpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBJbnNlcnRNZW51KGhTdWJNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TVFJJTkcsIElEU19DT1BZLCBidWZmKTsKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfUEFTVEUsIGJ1ZmYsIHNpemVvZihidWZmKSAvIHNpemVvZihXQ0hBUikpOwogICAgSW5zZXJ0TWVudShoU3ViTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU1RSSU5HLCBJRFNfUEFTVEUsIGJ1ZmYpOwogICAgTG9hZFN0cmluZyhoSW5zdGFuY2UsIElEU19TRUxFQ1RBTEwsIGJ1ZmYsIHNpemVvZihidWZmKSAvIHNpemVvZihXQ0hBUikpOwogICAgSW5zZXJ0TWVudShoU3ViTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU1RSSU5HLCBJRFNfU0VMRUNUQUxMLCBidWZmKTsKICAgIExvYWRTdHJpbmcoaEluc3RhbmNlLCBJRFNfU0NST0xMLCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaFN1Yk1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklORywgSURTX1NDUk9MTCwgYnVmZik7CiAgICBMb2FkU3RyaW5nKGhJbnN0YW5jZSwgSURTX1NFQVJDSCwgYnVmZiwgc2l6ZW9mKGJ1ZmYpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBJbnNlcnRNZW51KGhTdWJNZW51LCAtMSwgTUZfQllQT1NJVElPTnxNRl9TVFJJTkcsIElEU19TRUFSQ0gsIGJ1ZmYpOwoKICAgIGlmIChzZXApIEluc2VydE1lbnUoaE1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NFUEFSQVRPUiwgMCwgTlVMTCk7CiAgICBMb2FkU3RyaW5nKGhJbnN0YW5jZSwgSURTX0VESVQsIGJ1ZmYsIHNpemVvZihidWZmKSAvIHNpemVvZihXQ0hBUikpOwogICAgSW5zZXJ0TWVudShoTWVudSwgLTEsIE1GX0JZUE9TSVRJT058TUZfU1RSSU5HfE1GX1BPUFVQLCAoVUlOVF9QVFIpaFN1Yk1lbnUsIGJ1ZmYpOwogICAgTG9hZFN0cmluZyhoSW5zdGFuY2UsIElEU19ERUZBVUxULCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaE1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklORywgSURTX0RFRkFVTFQsIGJ1ZmYpOwogICAgTG9hZFN0cmluZyhoSW5zdGFuY2UsIElEU19QUk9QRVJUSUVTLCBidWZmLCBzaXplb2YoYnVmZikgLyBzaXplb2YoV0NIQVIpKTsKICAgIEluc2VydE1lbnUoaE1lbnUsIC0xLCBNRl9CWVBPU0lUSU9OfE1GX1NUUklORywgSURTX1BST1BFUlRJRVMsIGJ1ZmYpOwoKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfU2V0TWVudURldGFpbHMKICoKICogR3JheXMgLyB1bmdyYXlzIHRoZSBtZW51IGl0ZW1zIGFjY29yZGluZyB0byB0aGVpciBzdGF0ZQogKi8Kc3RhdGljIHZvaWQJV0NVU0VSX1NldE1lbnVEZXRhaWxzKGNvbnN0IHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBITUVOVSBoTWVudSkKewogICAgaWYgKCFoTWVudSkge1dJTkVfRVJSKCJJc3N1ZSBpbiBnZXR0aW5nIG1lbnUgYml0c1xuIik7cmV0dXJuO30KCiAgICBFbmFibGVNZW51SXRlbShoTWVudSwgSURTX0NPUFksCiAgICAgICAgICAgICAgICAgICBNRl9CWUNPTU1BTkR8KFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24gPyBNRl9FTkFCTEVEIDogTUZfR1JBWUVEKSk7CiAgICBFbmFibGVNZW51SXRlbShoTWVudSwgSURTX1BBU1RFLAoJCSAgIE1GX0JZQ09NTUFORHwoSXNDbGlwYm9hcmRGb3JtYXRBdmFpbGFibGUoQ0ZfVU5JQ09ERVRFWFQpCgkJCQkgPyBNRl9FTkFCTEVEIDogTUZfR1JBWUVEKSk7CiAgICBFbmFibGVNZW51SXRlbShoTWVudSwgSURTX1NDUk9MTCwgTUZfQllDT01NQU5EfE1GX0dSQVlFRCk7CiAgICBFbmFibGVNZW51SXRlbShoTWVudSwgSURTX1NFQVJDSCwgTUZfQllDT01NQU5EfE1GX0dSQVlFRCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9DcmVhdGUKICoKICogQ3JlYXRlcyB0aGUgd2luZG93IGZvciB0aGUgcmVuZGVyaW5nCiAqLwpzdGF0aWMgTFJFU1VMVCBXQ1VTRVJfQ3JlYXRlKEhXTkQgaFduZCwgTFBDUkVBVEVTVFJVQ1QgbHBjcykKewogICAgc3RydWN0IGlubmVyX2RhdGEqCWRhdGE7CiAgICBITUVOVQkJaFN5c01lbnU7CgogICAgZGF0YSA9IGxwY3MtPmxwQ3JlYXRlUGFyYW1zOwogICAgU2V0V2luZG93TG9uZyhoV25kLCAwTCwgKERXT1JEKWRhdGEpOwogICAgUFJJVkFURShkYXRhKS0+aFduZCA9IGhXbmQ7CgogICAgZGF0YS0+Y3VyY2ZnLmN1cnNvcl9zaXplID0gMTAxOyAvKiBpbnZhbGlkIHZhbHVlLCB3aWxsIHRyaWdnZXIgYSBjb21wbGV0ZSBjbGVhbnVwICovCgogICAgaFN5c01lbnUgPSBHZXRTeXN0ZW1NZW51KGhXbmQsIEZBTFNFKTsKICAgIGlmICghaFN5c01lbnUpIHJldHVybiAwOwogICAgUFJJVkFURShkYXRhKS0+aFBvcE1lbnUgPSBDcmVhdGVQb3B1cE1lbnUoKTsKICAgIGlmICghUFJJVkFURShkYXRhKS0+aFBvcE1lbnUpIHJldHVybiAwOwoKICAgIFdDVVNFUl9GaWxsTWVudShoU3lzTWVudSwgVFJVRSk7CiAgICBXQ1VTRVJfRmlsbE1lbnUoUFJJVkFURShkYXRhKS0+aFBvcE1lbnUsIEZBTFNFKTsKCiAgICBQUklWQVRFKGRhdGEpLT5oTWVtREMgPSBDcmVhdGVDb21wYXRpYmxlREMoMCk7CiAgICBpZiAoIVBSSVZBVEUoZGF0YSktPmhNZW1EQykge1dJTkVfRVJSKCJubyBtZW0gZGNcbiIpO3JldHVybiAwO30KCiAgICBkYXRhLT5jdXJjZmcucXVpY2tfZWRpdCA9IEZBTFNFOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUNVU0VSX0dldEN0cmxLZXlTdGF0ZQogKgogKiBHZXQgdGhlIGNvbnNvbGUgYml0IG1hc2sgZXF1aXZhbGVudCB0byB0aGUgVktfIHN0YXR1cyBpbiBrZXlTdGF0ZQogKi8Kc3RhdGljIERXT1JEICAgIFdDVVNFUl9HZXRDdHJsS2V5U3RhdGUoQllURSoga2V5U3RhdGUpCnsKICAgIERXT1JEICAgICAgICAgICAgICAgcmV0ID0gMDsKCiAgICBHZXRLZXlib2FyZFN0YXRlKGtleVN0YXRlKTsKICAgIGlmIChrZXlTdGF0ZVtWS19TSElGVF0gICAgJiAweDgwKQlyZXQgfD0gU0hJRlRfUFJFU1NFRDsKICAgIGlmIChrZXlTdGF0ZVtWS19DT05UUk9MXSAgJiAweDgwKQlyZXQgfD0gTEVGVF9DVFJMX1BSRVNTRUQ7IC8qIEZJWE1FOiBnb3R0YSBjaG9vc2Ugb25lICovCiAgICBpZiAoa2V5U3RhdGVbVktfTENPTlRST0xdICYgMHg4MCkJcmV0IHw9IExFRlRfQ1RSTF9QUkVTU0VEOwogICAgaWYgKGtleVN0YXRlW1ZLX1JDT05UUk9MXSAmIDB4ODApCXJldCB8PSBSSUdIVF9DVFJMX1BSRVNTRUQ7CiAgICBpZiAoa2V5U3RhdGVbVktfTE1FTlVdICAgICYgMHg4MCkJcmV0IHw9IExFRlRfQUxUX1BSRVNTRUQ7CiAgICBpZiAoa2V5U3RhdGVbVktfUk1FTlVdICAgICYgMHg4MCkJcmV0IHw9IFJJR0hUX0FMVF9QUkVTU0VEOwogICAgaWYgKGtleVN0YXRlW1ZLX0NBUElUQUxdICAmIDB4MDEpCXJldCB8PSBDQVBTTE9DS19PTjsKICAgIGlmIChrZXlTdGF0ZVtWS19OVU1MT0NLXSAgJiAweDAxKQlyZXQgfD0gTlVNTE9DS19PTjsKICAgIGlmIChrZXlTdGF0ZVtWS19TQ1JPTExdICAgJiAweDAxKQlyZXQgfD0gU0NST0xMTE9DS19PTjsKCiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfSGFuZGxlU2VsZWN0aW9uS2V5CiAqCiAqIEhhbmRsZXMga2V5cyB3aGlsZSBzZWxlY3RpbmcgYW4gYXJlYQogKi8Kc3RhdGljIHZvaWQgV0NVU0VSX0hhbmRsZVNlbGVjdGlvbktleShzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSwgQk9PTCBkb3duLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0pCnsKICAgIEJZVEUJa2V5U3RhdGVbMjU2XTsKICAgIERXT1JEICAgICAgIHN0YXRlID0gV0NVU0VSX0dldEN0cmxLZXlTdGF0ZShrZXlTdGF0ZSkgJiB+KENBUFNMT0NLX09OfE5VTUxPQ0tfT058U0NST0xMTE9DS19PTik7CiAgICBDT09SRCAgICAgICBjMSwgYzI7CgogICAgaWYgKGRvd24pIHJldHVybjsKCiAgICBzd2l0Y2ggKHN0YXRlKQogICAgewogICAgY2FzZSAwOgogICAgICAgIHN3aXRjaCAod1BhcmFtKQogICAgICAgIHsKICAgICAgICBjYXNlIFZLX1JFVFVSTjoKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiA9IEZBTFNFOwogICAgICAgICAgICBXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIDApOwogICAgICAgICAgICBXQ1VTRVJfQ29weVNlbGVjdGlvblRvQ2xpcGJvYXJkKGRhdGEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFZLX1JJR0hUOgogICAgICAgICAgICBjMSA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MTsKICAgICAgICAgICAgYzIgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDI7CiAgICAgICAgICAgIGMxLlgrKzsgYzIuWCsrOwogICAgICAgICAgICBpZiAoYzEuWCA8IGRhdGEtPmN1cmNmZy5zYl93aWR0aCAmJiBjMi5YIDwgZGF0YS0+Y3VyY2ZnLnNiX3dpZHRoKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBjMSwgYzIsIEZBTFNFKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFZLX0xFRlQ6CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzEuWC0tOyBjMi5YLS07CiAgICAgICAgICAgIGlmIChjMS5YID49IDAgJiYgYzIuWCA+PSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBjMSwgYzIsIEZBTFNFKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFZLX1VQOgogICAgICAgICAgICBjMSA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MTsKICAgICAgICAgICAgYzIgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDI7CiAgICAgICAgICAgIGMxLlktLTsgYzIuWS0tOwogICAgICAgICAgICBpZiAoYzEuWSA+PSAwICYmIGMyLlkgPj0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV0NVU0VSX01vdmVTZWxlY3Rpb24oZGF0YSwgYzEsIGMyLCBGQUxTRSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBWS19ET1dOOgogICAgICAgICAgICBjMSA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MTsKICAgICAgICAgICAgYzIgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDI7CiAgICAgICAgICAgIGMxLlkrKzsgYzIuWSsrOwogICAgICAgICAgICBpZiAoYzEuWCA8IGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgJiYgYzIuWCA8IGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIGMxLCBjMiwgRkFMU0UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgU0hJRlRfUFJFU1NFRDoKICAgICAgICBzd2l0Y2ggKHdQYXJhbSkKICAgICAgICB7CiAgICAgICAgY2FzZSBWS19SSUdIVDoKICAgICAgICAgICAgYzEgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDE7CiAgICAgICAgICAgIGMyID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyOwogICAgICAgICAgICBjMi5YKys7CiAgICAgICAgICAgIGlmIChjMi5YIDwgZGF0YS0+Y3VyY2ZnLnNiX3dpZHRoKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBjMSwgYzIsIEZBTFNFKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFZLX0xFRlQ6CiAgICAgICAgICAgIGMxID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxOwogICAgICAgICAgICBjMiA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MjsKICAgICAgICAgICAgYzIuWC0tOwogICAgICAgICAgICBpZiAoYzIuWCA+PSBjMS5YKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBjMSwgYzIsIEZBTFNFKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFZLX1VQOgogICAgICAgICAgICBjMSA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MTsKICAgICAgICAgICAgYzIgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDI7CiAgICAgICAgICAgIGMyLlktLTsKICAgICAgICAgICAgaWYgKGMyLlkgPj0gYzEuWSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV0NVU0VSX01vdmVTZWxlY3Rpb24oZGF0YSwgYzEsIGMyLCBGQUxTRSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBWS19ET1dOOgogICAgICAgICAgICBjMSA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MTsKICAgICAgICAgICAgYzIgPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDI7CiAgICAgICAgICAgIGMyLlkrKzsKICAgICAgICAgICAgaWYgKGMyLlggPCBkYXRhLT5jdXJjZmcuc2JfaGVpZ2h0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXQ1VTRVJfTW92ZVNlbGVjdGlvbihkYXRhLCBjMSwgYzIsIEZBTFNFKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9HZW5lcmF0ZUtleUlucHV0UmVjb3JkCiAqCiAqIGdlbmVyYXRlcyBpbnB1dF9yZWNvcmQgZnJvbSB3aW5kb3dzIFdNX0tFWVVQL1dNX0tFWURPV04gbWVzc2FnZXMKICovCnN0YXRpYyB2b2lkICAgIFdDVVNFUl9HZW5lcmF0ZUtleUlucHV0UmVjb3JkKHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhLCBCT09MIGRvd24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0sIEJPT0wgc3lzKQp7CiAgICBJTlBVVF9SRUNPUkQJaXI7CiAgICBEV09SRAkJbjsKICAgIFdDSEFSCQlidWZbMl07CiAgICBzdGF0aWMJV0NIQVIJbGFzdDsgLyoga2VlcCBsYXN0IGNoYXIgc2VlbiBhcyBmZWVkIGZvciBrZXkgdXAgbWVzc2FnZSAqLwogICAgQllURQkJa2V5U3RhdGVbMjU2XTsKCiAgICBpci5FdmVudFR5cGUgPSBLRVlfRVZFTlQ7CiAgICBpci5FdmVudC5LZXlFdmVudC5iS2V5RG93biA9IGRvd247CiAgICBpci5FdmVudC5LZXlFdmVudC53UmVwZWF0Q291bnQgPSBMT1dPUkQobFBhcmFtKTsKICAgIGlyLkV2ZW50LktleUV2ZW50LndWaXJ0dWFsS2V5Q29kZSA9IHdQYXJhbTsKCiAgICBpci5FdmVudC5LZXlFdmVudC53VmlydHVhbFNjYW5Db2RlID0gSElXT1JEKGxQYXJhbSkgJiAweEZGOwoKICAgIGlyLkV2ZW50LktleUV2ZW50LnVDaGFyLlVuaWNvZGVDaGFyID0gMDsKICAgIGlyLkV2ZW50LktleUV2ZW50LmR3Q29udHJvbEtleVN0YXRlID0gV0NVU0VSX0dldEN0cmxLZXlTdGF0ZShrZXlTdGF0ZSk7CiAgICBpZiAobFBhcmFtICYgKDFMIDw8IDI0KSkJCWlyLkV2ZW50LktleUV2ZW50LmR3Q29udHJvbEtleVN0YXRlIHw9IEVOSEFOQ0VEX0tFWTsKICAgIGlmIChzeXMpCQkJCWlyLkV2ZW50LktleUV2ZW50LmR3Q29udHJvbEtleVN0YXRlIHw9IExFRlRfQUxUX1BSRVNTRUQ7IC8qIEZJWE1FOiBnb3R0YSBjaG9vc2Ugb25lICovCgogICAgaWYgKCEoaXIuRXZlbnQuS2V5RXZlbnQuZHdDb250cm9sS2V5U3RhdGUgJiBFTkhBTkNFRF9LRVkpKQogICAgewoJaWYgKGRvd24pCgl7CgkgICAgc3dpdGNoIChUb1VuaWNvZGUod1BhcmFtLCBISVdPUkQobFBhcmFtKSwga2V5U3RhdGUsIGJ1ZiwgMiwgMCkpCgkgICAgewoJICAgIGNhc2UgMjoKCQkvKiBGSVhNRS4uLiBzaG91bGQgZ2VuZXJhdGUgdHdvIGV2ZW50cy4uLiAqLwoJCS8qIGZhbGwgdGhydSAqLwoJICAgIGNhc2UgMToKCQlsYXN0ID0gYnVmWzBdOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJbGFzdCA9IDA7CgkJYnJlYWs7CgkgICAgfQoJfQoJaXIuRXZlbnQuS2V5RXZlbnQudUNoYXIuVW5pY29kZUNoYXIgPSBsYXN0OyAvKiBGSVhNRSBIQUNLWS4uLiBhbmQgYnVnZ3kgJ2NveiBpdCBzaG91bGQgYmUgYSBzdGFjaywgbm90IGEgc2luZ2xlIHZhbHVlICovCglpZiAoIWRvd24pIGxhc3QgPSAwOwogICAgfQoKICAgIFdyaXRlQ29uc29sZUlucHV0KGRhdGEtPmhDb25JbiwgJmlyLCAxLCAmbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9HZW5lcmF0ZU1vdXNlSW5wdXRSZWNvcmQKICoKICoKICovCnN0YXRpYyB2b2lkICAgIFdDVVNFUl9HZW5lcmF0ZU1vdXNlSW5wdXRSZWNvcmQoc3RydWN0IGlubmVyX2RhdGEqIGRhdGEsIENPT1JEIGMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1BBUkFNIHdQYXJhbSwgRFdPUkQgZXZlbnQpCnsKICAgIElOUFVUX1JFQ09SRAlpcjsKICAgIEJZVEUJCWtleVN0YXRlWzI1Nl07CiAgICBEV09SRCAgICAgICAgICAgICAgIG1vZGUsIG47CgogICAgLyogTU9VU0VfRVZFTlRzIHNob3VsZG4ndCBiZSBzZW50IHVubGVzcyBFTkFCTEVfTU9VU0VfSU5QVVQgaXMgYWN0aXZlICovCiAgICBpZiAoIUdldENvbnNvbGVNb2RlKGRhdGEtPmhDb25JbiwgJm1vZGUpIHx8ICEobW9kZSAmIEVOQUJMRV9NT1VTRV9JTlBVVCkpCiAgICAgICAgcmV0dXJuOwoKICAgIGlyLkV2ZW50VHlwZSA9IE1PVVNFX0VWRU5UOwogICAgaXIuRXZlbnQuTW91c2VFdmVudC5kd01vdXNlUG9zaXRpb24gPSBjOwogICAgaXIuRXZlbnQuTW91c2VFdmVudC5kd0J1dHRvblN0YXRlID0gMDsKICAgIGlmICh3UGFyYW0gJiBNS19MQlVUVE9OKSBpci5FdmVudC5Nb3VzZUV2ZW50LmR3QnV0dG9uU3RhdGUgfD0gRlJPTV9MRUZUXzFTVF9CVVRUT05fUFJFU1NFRDsKICAgIGlmICh3UGFyYW0gJiBNS19NQlVUVE9OKSBpci5FdmVudC5Nb3VzZUV2ZW50LmR3QnV0dG9uU3RhdGUgfD0gRlJPTV9MRUZUXzJORF9CVVRUT05fUFJFU1NFRDsKICAgIGlmICh3UGFyYW0gJiBNS19SQlVUVE9OKSBpci5FdmVudC5Nb3VzZUV2ZW50LmR3QnV0dG9uU3RhdGUgfD0gUklHSFRNT1NUX0JVVFRPTl9QUkVTU0VEOwogICAgaXIuRXZlbnQuTW91c2VFdmVudC5kd0NvbnRyb2xLZXlTdGF0ZSA9IFdDVVNFUl9HZXRDdHJsS2V5U3RhdGUoa2V5U3RhdGUpOwogICAgaXIuRXZlbnQuTW91c2VFdmVudC5kd0V2ZW50RmxhZ3MgPSBldmVudDsKCiAgICBXcml0ZUNvbnNvbGVJbnB1dChkYXRhLT5oQ29uSW4sICZpciwgMSwgJm4pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfUHJvYwogKgogKgogKi8Kc3RhdGljIExSRVNVTFQgQ0FMTEJBQ0sgV0NVU0VSX1Byb2MoSFdORCBoV25kLCBVSU5UIHVNc2csIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0pCnsKICAgIHN0cnVjdCBpbm5lcl9kYXRhKglkYXRhID0gKHN0cnVjdCBpbm5lcl9kYXRhKilHZXRXaW5kb3dMb25nKGhXbmQsIDApOwoKICAgIHN3aXRjaCAodU1zZykKICAgIHsKICAgIGNhc2UgV01fQ1JFQVRFOgogICAgICAgIHJldHVybiBXQ1VTRVJfQ3JlYXRlKGhXbmQsIChMUENSRUFURVNUUlVDVClsUGFyYW0pOwogICAgY2FzZSBXTV9ERVNUUk9ZOgoJUFJJVkFURShkYXRhKS0+aFduZCA9IDA7CglQb3N0UXVpdE1lc3NhZ2UoMCk7CglicmVhazsKICAgIGNhc2UgV01fUEFJTlQ6CglXQ1VTRVJfUGFpbnQoZGF0YSk7CglicmVhazsKICAgIGNhc2UgV01fS0VZRE9XTjoKICAgIGNhc2UgV01fS0VZVVA6CiAgICAgICAgaWYgKFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24pCiAgICAgICAgICAgIFdDVVNFUl9IYW5kbGVTZWxlY3Rpb25LZXkoZGF0YSwgdU1zZyA9PSBXTV9LRVlET1dOLCB3UGFyYW0sIGxQYXJhbSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBXQ1VTRVJfR2VuZXJhdGVLZXlJbnB1dFJlY29yZChkYXRhLCB1TXNnID09IFdNX0tFWURPV04sIHdQYXJhbSwgbFBhcmFtLCBGQUxTRSk7CglicmVhazsKICAgIGNhc2UgV01fU1lTS0VZRE9XTjoKICAgIGNhc2UgV01fU1lTS0VZVVA6CglXQ1VTRVJfR2VuZXJhdGVLZXlJbnB1dFJlY29yZChkYXRhLCB1TXNnID09IFdNX1NZU0tFWURPV04sIHdQYXJhbSwgbFBhcmFtLCBUUlVFKTsKCWJyZWFrOwogICAgY2FzZSBXTV9MQlVUVE9ORE9XTjoKICAgICAgICBpZiAoZGF0YS0+Y3VyY2ZnLnF1aWNrX2VkaXQpCiAgICAgICAgewogICAgICAgICAgICBpZiAoUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiA9IEZBTFNFOwogICAgICAgICAgICAgICAgV0NVU0VSX1NldFNlbGVjdGlvbihkYXRhLCAwKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MSA9IFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MiA9IFdDVVNFUl9HZXRDZWxsKGRhdGEsIGxQYXJhbSk7CiAgICAgICAgICAgICAgICBTZXRDYXB0dXJlKFBSSVZBVEUoZGF0YSktPmhXbmQpOwogICAgICAgICAgICAgICAgV0NVU0VSX1NldFNlbGVjdGlvbihkYXRhLCAwKTsKICAgICAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPmhhc19zZWxlY3Rpb24gPSBUUlVFOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIFdDVVNFUl9HZW5lcmF0ZU1vdXNlSW5wdXRSZWNvcmQoZGF0YSwgV0NVU0VSX0dldENlbGwoZGF0YSwgbFBhcmFtKSwgd1BhcmFtLCAwKTsKICAgICAgICB9CglicmVhazsKICAgIGNhc2UgV01fTU9VU0VNT1ZFOgogICAgICAgIGlmIChkYXRhLT5jdXJjZmcucXVpY2tfZWRpdCkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChHZXRDYXB0dXJlKCkgPT0gUFJJVkFURShkYXRhKS0+aFduZCAmJiBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uICYmCiAgICAgICAgICAgICAgICAod1BhcmFtICYgTUtfTEJVVFRPTikpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MSwgV0NVU0VSX0dldENlbGwoZGF0YSwgbFBhcmFtKSwgRkFMU0UpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIFdDVVNFUl9HZW5lcmF0ZU1vdXNlSW5wdXRSZWNvcmQoZGF0YSwgV0NVU0VSX0dldENlbGwoZGF0YSwgbFBhcmFtKSwgd1BhcmFtLCBNT1VTRV9NT1ZFRCk7CiAgICAgICAgfQoJYnJlYWs7CiAgICBjYXNlIFdNX0xCVVRUT05VUDoKICAgICAgICBpZiAoZGF0YS0+Y3VyY2ZnLnF1aWNrX2VkaXQpCiAgICAgICAgewogICAgICAgICAgICBpZiAoR2V0Q2FwdHVyZSgpID09IFBSSVZBVEUoZGF0YSktPmhXbmQgJiYgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiAmJgogICAgICAgICAgICAgICAgKHdQYXJhbSYgTUtfTEJVVFRPTikpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdDVVNFUl9Nb3ZlU2VsZWN0aW9uKGRhdGEsIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0MSwgV0NVU0VSX0dldENlbGwoZGF0YSwgbFBhcmFtKSwgVFJVRSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgV0NVU0VSX0dlbmVyYXRlTW91c2VJbnB1dFJlY29yZChkYXRhLCBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pLCB3UGFyYW0sIDApOwogICAgICAgIH0KCWJyZWFrOwogICAgY2FzZSBXTV9SQlVUVE9ORE9XTjoKICAgICAgICBpZiAoKHdQYXJhbSAmIChNS19DT05UUk9MfE1LX1NISUZUKSkgPT0gZGF0YS0+Y3VyY2ZnLm1lbnVfbWFzaykKICAgICAgICB7CiAgICAgICAgICAgIFJFQ1QgICAgICAgIHI7CgogICAgICAgICAgICBHZXRXaW5kb3dSZWN0KGhXbmQsICZyKTsKICAgICAgICAgICAgV0NVU0VSX1NldE1lbnVEZXRhaWxzKGRhdGEsIFBSSVZBVEUoZGF0YSktPmhQb3BNZW51KTsKICAgICAgICAgICAgVHJhY2tQb3B1cE1lbnUoUFJJVkFURShkYXRhKS0+aFBvcE1lbnUsIFRQTV9MRUZUQUxJR058VFBNX1RPUEFMSUdOLAogICAgICAgICAgICAgICAgICAgICAgICAgICByLmxlZnQgKyBMT1dPUkQobFBhcmFtKSwgci50b3AgKyBISVdPUkQobFBhcmFtKSwgMCwgaFduZCwgTlVMTCk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIFdDVVNFUl9HZW5lcmF0ZU1vdXNlSW5wdXRSZWNvcmQoZGF0YSwgV0NVU0VSX0dldENlbGwoZGF0YSwgbFBhcmFtKSwgd1BhcmFtLCAwKTsKICAgICAgICB9CglicmVhazsKICAgIGNhc2UgV01fUkJVVFRPTlVQOgogICAgICAgIC8qIG5vIG5lZWQgdG8gdHJhY2sgZm9yIHJidXR0b24gdXAgd2hlbiBvcGVuaW5nIHRoZSBwb3B1cC4uLiB0aGUgZXZlbnQgd2lsbCBiZQogICAgICAgICAqIHN3YWxsb3dlZCBieSBUcmFja1BvcHVwTWVudSAqLwogICAgICAgIFdDVVNFUl9HZW5lcmF0ZU1vdXNlSW5wdXRSZWNvcmQoZGF0YSwgV0NVU0VSX0dldENlbGwoZGF0YSwgbFBhcmFtKSwgd1BhcmFtLCAwKTsKCWJyZWFrOwogICAgY2FzZSBXTV9NT1VTRVdIRUVMOgogICAgICAgIC8qIEZJWE1FOiBzaG91bGQgd2Ugc2Nyb2xsIHRvbyA/ICovCiAgICAgICAgV0NVU0VSX0dlbmVyYXRlTW91c2VJbnB1dFJlY29yZChkYXRhLCBXQ1VTRVJfR2V0Q2VsbChkYXRhLCBsUGFyYW0pLCB3UGFyYW0sIE1PVVNFX1dIRUVMRUQpOwoJYnJlYWs7CiAgICBjYXNlIFdNX1NFVEZPQ1VTOgoJaWYgKGRhdGEtPmN1cmNmZy5jdXJzb3JfdmlzaWJsZSkKCXsKCSAgICBDcmVhdGVDYXJldChQUklWQVRFKGRhdGEpLT5oV25kLCBQUklWQVRFKGRhdGEpLT5jdXJzb3JfYml0bWFwLAogICAgICAgICAgICAgICAgICAgICAgICBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwgZGF0YS0+Y3VyY2ZnLmNlbGxfaGVpZ2h0KTsKCSAgICBXQ1VTRVJfUG9zQ3Vyc29yKGRhdGEpOwoJfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBXTV9LSUxMRk9DVVM6CglpZiAoZGF0YS0+Y3VyY2ZnLmN1cnNvcl92aXNpYmxlKQoJICAgIERlc3Ryb3lDYXJldCgpOwoJYnJlYWs7CiAgICBjYXNlIFdNX0hTQ1JPTEw6CiAgICAgICAgewogICAgICAgICAgICBpbnQJcG9zID0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWDsKCiAgICAgICAgICAgIHN3aXRjaCAoTE9XT1JEKHdQYXJhbSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgY2FzZSBTQl9QQUdFVVA6IAlwb3MgLT0gODsgCQlicmVhazsKICAgICAgICAgICAgY2FzZSBTQl9QQUdFRE9XTjogCXBvcyArPSA4OyAJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX0xJTkVVUDogCXBvcy0tOwkJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX0xJTkVET1dOOiAJcG9zKys7CSAJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX1RIVU1CVFJBQ0s6IHBvcyA9IEhJV09SRCh3UGFyYW0pOwlicmVhazsKICAgICAgICAgICAgZGVmYXVsdDogCQkJCQlicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAocG9zIDwgMCkgcG9zID0gMDsKICAgICAgICAgICAgaWYgKHBvcyA+IGRhdGEtPmN1cmNmZy5zYl93aWR0aCAtIGRhdGEtPmN1cmNmZy53aW5fd2lkdGgpCiAgICAgICAgICAgICAgICBwb3MgPSBkYXRhLT5jdXJjZmcuc2Jfd2lkdGggLSBkYXRhLT5jdXJjZmcud2luX3dpZHRoOwogICAgICAgICAgICBpZiAocG9zICE9IGRhdGEtPmN1cmNmZy53aW5fcG9zLlgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFNjcm9sbFdpbmRvdyhoV25kLCAoZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWCAtIHBvcykgKiBkYXRhLT5jdXJjZmcuY2VsbF93aWR0aCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMKTsKICAgICAgICAgICAgICAgIGRhdGEtPmN1cmNmZy53aW5fcG9zLlggPSBwb3M7CiAgICAgICAgICAgICAgICBTZXRTY3JvbGxQb3MoaFduZCwgU0JfSE9SWiwgcG9zLCBUUlVFKTsKICAgICAgICAgICAgICAgIFVwZGF0ZVdpbmRvdyhoV25kKTsKICAgICAgICAgICAgICAgIFdDVVNFUl9Qb3NDdXJzb3IoZGF0YSk7CiAgICAgICAgICAgICAgICBXSU5FQ09OX05vdGlmeVdpbmRvd0NoYW5nZShkYXRhKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCWJyZWFrOwogICAgY2FzZSBXTV9WU0NST0xMOgogICAgICAgIHsKCSAgICBpbnQJcG9zID0gZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWTsKCgkgICAgc3dpdGNoIChMT1dPUkQod1BhcmFtKSkKCSAgICB7CiAgICAgICAgICAgIGNhc2UgU0JfUEFHRVVQOiAJcG9zIC09IDg7IAkJYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU0JfUEFHRURPV046IAlwb3MgKz0gODsgCQlicmVhazsKICAgICAgICAgICAgY2FzZSBTQl9MSU5FVVA6IAlwb3MtLTsJCQlicmVhazsKCSAgICBjYXNlIFNCX0xJTkVET1dOOiAJcG9zKys7CSAJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFNCX1RIVU1CVFJBQ0s6IHBvcyA9IEhJV09SRCh3UGFyYW0pOwlicmVhazsKICAgICAgICAgICAgZGVmYXVsdDogCQkJCQlicmVhazsKCSAgICB9CgkgICAgaWYgKHBvcyA8IDApIHBvcyA9IDA7CgkgICAgaWYgKHBvcyA+IGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgLSBkYXRhLT5jdXJjZmcud2luX2hlaWdodCkKICAgICAgICAgICAgICAgIHBvcyA9IGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgLSBkYXRhLT5jdXJjZmcud2luX2hlaWdodDsKCSAgICBpZiAocG9zICE9IGRhdGEtPmN1cmNmZy53aW5fcG9zLlkpCgkgICAgewoJCVNjcm9sbFdpbmRvdyhoV25kLCAwLCAoZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSAtIHBvcykgKiBkYXRhLT5jdXJjZmcuY2VsbF9oZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCk7CgkJZGF0YS0+Y3VyY2ZnLndpbl9wb3MuWSA9IHBvczsKCQlTZXRTY3JvbGxQb3MoaFduZCwgU0JfVkVSVCwgcG9zLCBUUlVFKTsKCQlVcGRhdGVXaW5kb3coaFduZCk7CgkJV0NVU0VSX1Bvc0N1cnNvcihkYXRhKTsKCQlXSU5FQ09OX05vdGlmeVdpbmRvd0NoYW5nZShkYXRhKTsKCSAgICB9CgogICAgICAgIH0KICAgIGNhc2UgV01fU1lTQ09NTUFORDoKCXN3aXRjaCAod1BhcmFtKQoJewoJY2FzZSBJRFNfREVGQVVMVDoKCSAgICBXQ1VTRVJfR2V0UHJvcGVydGllcyhkYXRhLCBGQUxTRSk7CgkgICAgYnJlYWs7CgljYXNlIElEU19QUk9QRVJUSUVTOgoJICAgIFdDVVNFUl9HZXRQcm9wZXJ0aWVzKGRhdGEsIFRSVUUpOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICByZXR1cm4gRGVmV2luZG93UHJvYyhoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7Cgl9CglicmVhazsKICAgIGNhc2UgV01fQ09NTUFORDoKCXN3aXRjaCAod1BhcmFtKQoJewoJY2FzZSBJRFNfREVGQVVMVDoKCSAgICBXQ1VTRVJfR2V0UHJvcGVydGllcyhkYXRhLCBGQUxTRSk7CgkgICAgYnJlYWs7CgljYXNlIElEU19QUk9QRVJUSUVTOgoJICAgIFdDVVNFUl9HZXRQcm9wZXJ0aWVzKGRhdGEsIFRSVUUpOwoJICAgIGJyZWFrOwoJY2FzZSBJRFNfTUFSSzoKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlggPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWSA9IDA7CiAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5YID0gUFJJVkFURShkYXRhKS0+c2VsZWN0UHQyLlkgPSAwOwogICAgICAgICAgICBXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIDApOwogICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID0gVFJVRTsKCSAgICBicmVhazsKCWNhc2UgSURTX0NPUFk6CiAgICAgICAgICAgIGlmIChQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBQUklWQVRFKGRhdGEpLT5oYXNfc2VsZWN0aW9uID0gRkFMU0U7CiAgICAgICAgICAgICAgICBXQ1VTRVJfU2V0U2VsZWN0aW9uKGRhdGEsIDApOwogICAgICAgICAgICAgICAgV0NVU0VSX0NvcHlTZWxlY3Rpb25Ub0NsaXBib2FyZChkYXRhKTsKICAgICAgICAgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBJRFNfUEFTVEU6CgkgICAgV0NVU0VSX1Bhc3RlRnJvbUNsaXBib2FyZChkYXRhKTsKCSAgICBicmVhazsKCWNhc2UgSURTX1NFTEVDVEFMTDoKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+c2VsZWN0UHQxLlggPSBQUklWQVRFKGRhdGEpLT5zZWxlY3RQdDEuWSA9IDA7CiAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5YID0gKGRhdGEtPmN1cmNmZy5zYl93aWR0aCAtIDEpICogZGF0YS0+Y3VyY2ZnLmNlbGxfd2lkdGg7CiAgICAgICAgICAgIFBSSVZBVEUoZGF0YSktPnNlbGVjdFB0Mi5ZID0gKGRhdGEtPmN1cmNmZy5zYl9oZWlnaHQgLSAxKSAqIGRhdGEtPmN1cmNmZy5jZWxsX2hlaWdodDsKICAgICAgICAgICAgV0NVU0VSX1NldFNlbGVjdGlvbihkYXRhLCAwKTsKICAgICAgICAgICAgUFJJVkFURShkYXRhKS0+aGFzX3NlbGVjdGlvbiA9IFRSVUU7CgkgICAgYnJlYWs7CgljYXNlIElEU19TQ1JPTEw6CgljYXNlIElEU19TRUFSQ0g6CgkgICAgV0lORV9GSVhNRSgiVW5oYW5kbGVkIHlldCBjb21tYW5kOiAleFxuIiwgd1BhcmFtKTsKCSAgICBicmVhazsKCWRlZmF1bHQ6CgkgICAgcmV0dXJuIERlZldpbmRvd1Byb2MoaFduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwoJfQoJYnJlYWs7CiAgICBjYXNlIFdNX0lOSVRNRU5VUE9QVVA6CglpZiAoIUhJV09SRChsUGFyYW0pKQlyZXR1cm4gRGVmV2luZG93UHJvYyhoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7CglXQ1VTRVJfU2V0TWVudURldGFpbHMoZGF0YSwgR2V0U3lzdGVtTWVudShQUklWQVRFKGRhdGEpLT5oV25kLCBGQUxTRSkpOwoJYnJlYWs7CiAgICBkZWZhdWx0OgoJcmV0dXJuIERlZldpbmRvd1Byb2MoaFduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9EZWxldGVCYWNrZW5kCiAqCiAqCiAqLwp2b2lkIFdDVVNFUl9EZWxldGVCYWNrZW5kKHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBpZiAoIVBSSVZBVEUoZGF0YSkpIHJldHVybjsKICAgIGlmIChQUklWQVRFKGRhdGEpLT5oTWVtREMpCQlEZWxldGVEQyhQUklWQVRFKGRhdGEpLT5oTWVtREMpOwogICAgaWYgKFBSSVZBVEUoZGF0YSktPmhXbmQpCQlEZXN0cm95V2luZG93KFBSSVZBVEUoZGF0YSktPmhXbmQpOwogICAgaWYgKFBSSVZBVEUoZGF0YSktPmhGb250KQkJRGVsZXRlT2JqZWN0KFBSSVZBVEUoZGF0YSktPmhGb250KTsKICAgIGlmIChQUklWQVRFKGRhdGEpLT5jdXJzb3JfYml0bWFwKQlEZWxldGVPYmplY3QoUFJJVkFURShkYXRhKS0+Y3Vyc29yX2JpdG1hcCk7CiAgICBpZiAoUFJJVkFURShkYXRhKS0+aEJpdG1hcCkJCURlbGV0ZU9iamVjdChQUklWQVRFKGRhdGEpLT5oQml0bWFwKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFBSSVZBVEUoZGF0YSkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXQ1VTRVJfTWFpbkxvb3AKICoKICoKICovCnN0YXRpYyBpbnQgV0NVU0VSX01haW5Mb29wKHN0cnVjdCBpbm5lcl9kYXRhKiBkYXRhKQp7CiAgICBNU0cJCW1zZzsKCiAgICBmb3IgKDs7KQogICAgewoJc3dpdGNoKE1zZ1dhaXRGb3JNdWx0aXBsZU9iamVjdHMoMSwgJmRhdGEtPmhTeW5jaHJvLCBGQUxTRSwgSU5GSU5JVEUsIFFTX0FMTElOUFVUKSkKCXsKCWNhc2UgV0FJVF9PQkpFQ1RfMDoKCSAgICBpZiAoIVdJTkVDT05fR3JhYkNoYW5nZXMoZGF0YSkgJiYgZGF0YS0+Y3VyY2ZnLmV4aXRfb25fZGllKQogICAgICAgICAgICAgICAgUG9zdFF1aXRNZXNzYWdlKDApOwoJICAgIGJyZWFrOwoJY2FzZSBXQUlUX09CSkVDVF8wKzE6CgkgICAgLyogbmVlZCB0byB1c2UgUGVla01lc3NhZ2UgbG9vcCBpbnN0ZWFkIG9mIHNpbXBsZSBHZXRNZXNzYWdlOgoJICAgICAqIG11bHRpcGxlIG1lc3NhZ2VzIG1pZ2h0IGhhdmUgYXJyaXZlZCBpbiBiZXR3ZWVuLAoJICAgICAqIHNvIEdldE1lc3NhZ2Ugd291bGQgbGVhZCB0byBkZWxheWVkIHByb2Nlc3NpbmcgKi8KCSAgICB3aGlsZSAoUGVla01lc3NhZ2UoJm1zZywgMCwgMCwgMCwgUE1fUkVNT1ZFKSkKCSAgICB7CiAgICAgICAgICAgICAgICBpZiAobXNnLm1lc3NhZ2UgPT0gV01fUVVJVCkgcmV0dXJuIDA7CiAgICAgICAgICAgICAgICBXSU5FX1RSQUNFKCJkaXNwYXRjaGluZyBtc2cgJTA0eFxuIiwgbXNnLm1lc3NhZ2UpOwogICAgICAgICAgICAgICAgRGlzcGF0Y2hNZXNzYWdlKCZtc2cpOwoJICAgIH0KCSAgICBicmVhazsKCWRlZmF1bHQ6CgkgICAgV0lORV9FUlIoImdvdCBwYlxuIik7CgkgICAgLyogZXJyICovCgkgICAgYnJlYWs7Cgl9CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdDVVNFUl9Jbml0QmFja2VuZAogKgogKiBJbml0aWFsaXNhdGlvbiBwYXJ0IElJOiBjcmVhdGlvbiBvZiB3aW5kb3cuCiAqCiAqLwpCT09MIFdDVVNFUl9Jbml0QmFja2VuZChzdHJ1Y3QgaW5uZXJfZGF0YSogZGF0YSkKewogICAgc3RhdGljIFdDSEFSIHdDbGFzc05hbWVbXSA9IHsnVycsJ2knLCduJywnZScsJ0MnLCdvJywnbicsJ3MnLCdvJywnbCcsJ2UnLCdDJywnbCcsJ2EnLCdzJywncycsMH07CgogICAgV05EQ0xBU1MJCXduZGNsYXNzOwoKICAgIGRhdGEtPnByaXZhdGUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKHN0cnVjdCBpbm5lcl9kYXRhX3VzZXIpKTsKICAgIGlmICghZGF0YS0+cHJpdmF0ZSkgcmV0dXJuIEZBTFNFOwoKICAgIGRhdGEtPmZuTWFpbkxvb3AgPSBXQ1VTRVJfTWFpbkxvb3A7CiAgICBkYXRhLT5mblBvc0N1cnNvciA9IFdDVVNFUl9Qb3NDdXJzb3I7CiAgICBkYXRhLT5mblNoYXBlQ3Vyc29yID0gV0NVU0VSX1NoYXBlQ3Vyc29yOwogICAgZGF0YS0+Zm5Db21wdXRlUG9zaXRpb25zID0gV0NVU0VSX0NvbXB1dGVQb3NpdGlvbnM7CiAgICBkYXRhLT5mblJlZnJlc2ggPSBXQ1VTRVJfUmVmcmVzaDsKICAgIGRhdGEtPmZuUmVzaXplU2NyZWVuQnVmZmVyID0gV0NVU0VSX1Jlc2l6ZVNjcmVlbkJ1ZmZlcjsKICAgIGRhdGEtPmZuU2V0VGl0bGUgPSBXQ1VTRVJfU2V0VGl0bGU7CiAgICBkYXRhLT5mblNjcm9sbCA9IFdDVVNFUl9TY3JvbGw7CiAgICBkYXRhLT5mbkRlbGV0ZUJhY2tlbmQgPSBXQ1VTRVJfRGVsZXRlQmFja2VuZDsKCiAgICB3bmRjbGFzcy5zdHlsZSAgICAgICAgID0gMDsKICAgIHduZGNsYXNzLmxwZm5XbmRQcm9jICAgPSBXQ1VTRVJfUHJvYzsKICAgIHduZGNsYXNzLmNiQ2xzRXh0cmEgICAgPSAwOwogICAgd25kY2xhc3MuY2JXbmRFeHRyYSAgICA9IHNpemVvZihEV09SRCk7CiAgICB3bmRjbGFzcy5oSW5zdGFuY2UgICAgID0gR2V0TW9kdWxlSGFuZGxlKE5VTEwpOwogICAgd25kY2xhc3MuaEljb24gICAgICAgICA9IExvYWRJY29uKDAsIElESV9XSU5MT0dPKTsKICAgIHduZGNsYXNzLmhDdXJzb3IgICAgICAgPSBMb2FkQ3Vyc29yKDAsIElEQ19BUlJPVyk7CiAgICB3bmRjbGFzcy5oYnJCYWNrZ3JvdW5kID0gR2V0U3RvY2tPYmplY3QoQkxBQ0tfQlJVU0gpOwogICAgd25kY2xhc3MubHBzek1lbnVOYW1lICA9IE5VTEw7CiAgICB3bmRjbGFzcy5scHN6Q2xhc3NOYW1lID0gd0NsYXNzTmFtZTsKCiAgICBSZWdpc3RlckNsYXNzKCZ3bmRjbGFzcyk7CgogICAgQ3JlYXRlV2luZG93KHduZGNsYXNzLmxwc3pDbGFzc05hbWUsIE5VTEwsCgkJIFdTX09WRVJMQVBQRUR8V1NfQ0FQVElPTnxXU19TWVNNRU5VfFdTX1RISUNLRlJBTUV8V1NfTUlOSU1JWkVCT1h8V1NfSFNDUk9MTHxXU19WU0NST0xMLAoJCSBDV19VU0VERUZBVUxULCBDV19VU0VERUZBVUxULCAwLCAwLCAwLCAwLCB3bmRjbGFzcy5oSW5zdGFuY2UsIGRhdGEpOwogICAgaWYgKCFQUklWQVRFKGRhdGEpLT5oV25kKSByZXR1cm4gRkFMU0U7CgogICAgLyogZm9yY2UgdXBkYXRlIG9mIGN1cnJlbnQgZGF0YSAqLwogICAgaWYgKCFXSU5FQ09OX0dyYWJDaGFuZ2VzKGRhdGEpKSByZXR1cm4gRkFMU0U7CgogICAgaWYgKCFXQ1VTRVJfSW5pdEZvbnQoZGF0YSkpIHJldHVybiBGQUxTRTsKCiAgICByZXR1cm4gVFJVRTsKfQo=