LyoKICogICBDb3B5cmlnaHQgMjAwMy0yMDA0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4KLy8gKGMpIENvcHlyaWdodCBJQk0gQ29ycC4gMjAwNCwgMjAwNSBBbGwgUmlnaHRzIFJlc2VydmVkCiAqCiAqICAgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqICAgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqCiAqCiAqLwoKI2lmICFkZWZpbmVkKEFYSVNfQ09NUExFWEVMRU1FTlRfSF9fT0ZfQVhJU19JTkNMVURFRF8pCiNkZWZpbmUgQVhJU19DT01QTEVYRUxFTUVOVF9IX19PRl9BWElTX0lOQ0xVREVEXwoKI2luY2x1ZGUgPGxpc3Q+CiNpbmNsdWRlIDxheGlzL0Jhc2ljTm9kZS5ocHA+CiNpbmNsdWRlICJBdHRyaWJ1dGUuaCIKCkFYSVNfQ1BQX05BTUVTUEFDRV9TVEFSVAoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCi8qKgogKiBAY2xhc3MgQ29tcGxleEVsZW1lbnQKICogQGJyaWVmIGludGVyZmFjZSBmb3IgdGhlIENvbXBsZXhFbGVtZW50IGNsYXNzLgogKgogKi8KCmNsYXNzIENvbXBsZXhFbGVtZW50IDogcHVibGljIEJhc2ljTm9kZQp7CnB1YmxpYzoKICAgIENvbXBsZXhFbGVtZW50KEF4aXNDaGFyKiBwYWNoTG9jYWxOYW1lLCBBeGlzQ2hhciogcGFjaFByZWZpeCwgQXhpc0NoYXIqIHBhY2hVcmkpOwoKICAgIC8qKgogICAgICAqIFJldHVybnMgdGhlIEF0dHJpYnV0ZSBvZiB0aGlzIG5vZGUsIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuCiAgICAgICogcHJlZml4L2xvY2FsbmFtZSBwYWlyIG9yIHRoZSBnaXZlbiBuYW1lc3BhY2UgVVJJL2xvY2FsbmFtZSBwYWlyLgogICAgICAqIFRoZSB1c2VycyBjb3VsZCBnZXQgdGhlIGF0dHJpYnV0ZXMgd2l0aCB0aGUKICAgICAgKiBmb2xsb3dpbmcgY29tYmluYXRpb25zIG9mIHBhaXJzLgogICAgICAqICAxLiBieSBwcmVmaXggYW5kIGxvY2FsbmFtZSBwYWlyIChoZXJlIHRoZSBuYW1lc3BhY2UgVVJJKGkuZSBwYWNoVVJJCiAgICAgICogICAgICBoYXMgdG8gYmUgYSBlbXB0eSBzdHJpbmcpKSBvcgogICAgICAqICAyLiBieSBuYW1lc3BhY2UgVVJJIGFuZCBsb2NhbG5hbWUgcGFpciAoaGVyZSB0aGUgcHJlZml4CiAgICAgICogICAgICAoaS5lIHBhY2hQcmVmaXggaGFzIHRvIGJlIGEgZW1wdHkgc3RyaW5nKSkuCiAgICAgICogCiAgICAgICogSWYgbm90IGZvdW5kIHJldHVybnMgTlVMTC4KICAgICAgKi8KICAgIElBdHRyaWJ1dGUqIGdldEF0dHJpYnV0ZShBeGlzQ2hhciogcGFjaFByZWZpeCwgQXhpc0NoYXIqIHBhY2hVUkksICBBeGlzQ2hhciogcGFjaExvY2FsbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgIC8qKgogICAgICAqIFJldHVybnMgdGhlIGZpcnN0IEF0dHJpYnV0ZSBvZiB0aGlzIG5vZGUuIE5PVEU6IFdoZW4gdHJhdmVyc2luZyB0aGUgCiAgICAgICogIGF0dHJpYnV0ZXMgdGhpcyBoYXMgdG8gYmUgY2FsbGVkIGZpcnN0LCBiZWZvcmUgY2FsbGluZyB0aGUgCiAgICAgICogIGdldE5leHRBdHRyaWJ1dGUoKSBtdGhvZC4KICAgICAgKi8KICAgIElBdHRyaWJ1dGUqIGdldEZpcnN0QXR0cmlidXRlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgIC8qKgogICAgICAqIFJldHVybnMgdGhlIGxhc3QgQXR0cmlidXRlIG9mIHRoaXMgbm9kZS4KICAgICAgKi8KICAgIElBdHRyaWJ1dGUqIGdldExhc3RBdHRyaWJ1dGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgLyoqCiAgICAgICogUmV0dXJucyB0aGUgbmV4dCBBdHRyaWJ1dGUgb2YgdGhpcyBub2RlLiBOT1RFOiBXaGVuIHRyYXZlcnNpbmcgdGhlCiAgICAgICogIGF0dHJpYnV0ZXMgZ2V0Rmlyc3RBdHRyaWJ1dGUoKSBoYXMgdG8gYmUgY2FsbGVkIGZpcnN0LCBiZWZvcmUgY2FsbGluZyB0aGlzCiAgICAgICogIG10aG9kLCBvdGhlcndpc2UgdGhlIGJlaGF2aW9yIGlzIHVuZGVmaW5lZC4KICAgICAgKi8KICAgIElBdHRyaWJ1dGUqIGdldE5leHRBdHRyaWJ1dGUoKTsKCiAgICAvKioKICAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IEF0dHJpYnV0ZSBvZiB0aGlzIG5vZGUuIE5PVEU6IFdoZW4gdHJhdmVyc2luZyB0aGUKICAgICAgKiAgYXR0cmlidXRlcyBnZXRGaXJzdEF0dHJpYnV0ZSgpIGhhcyB0byBiZSBjYWxsZWQgZmlyc3QsIGJlZm9yZSBjYWxsaW5nIHRoaXMKICAgICAgKiAgbXRob2QsIG90aGVyd2lzZSB0aGUgYmVoYXZpb3IgaXMgdW5kZWZpbmVkLgogICAgICAqLwogICAgSUF0dHJpYnV0ZSogZ2V0Q3VycmVudEF0dHJpYnV0ZSgpOwoKICAgIC8qKiAKICAgoCAqIENyZWF0ZXMgYW4gQXR0cmlidXRlIGFuZCBhZGRzIGl0IHRvIHRoaXMgQ29tcGxleCBFbGVtZW50LgogICAgoCoKICAgICAqIEBwYXJhbSBsb2NhbG5hbWUgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KICAgoCAqIEBwYXJhbSBwcmVmaXggVGhlIHByZWZpeCBvZiB0aGUgYXR0cmlidXRlLgogICCgICogQHBhcmFtIHVyaSBUaGUgbmFtZXNwYWNlIHVyaSBvZiB0aGUgYXR0cmlidXRlLgogICCgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlLgogICCgICoKICAgoCAqIEByZXR1cm4gQSBwb2ludGVyIHRvIHRoZSBjcmVhdGVkIEF0dHJpYnV0ZSB3aWxsIGJlIHJldHVybmVkLgogICCgICovCiAgICBJQXR0cmlidXRlKiBjcmVhdGVBdHRyaWJ1dGUoY29uc3QgQXhpc0NoYXIqIGxvY2FsbmFtZSwKICAgICAgICBjb25zdCBBeGlzQ2hhciogcHJlZml4LCBjb25zdCBBeGlzQ2hhciogdXJpLCBjb25zdCBBeGlzQ2hhciogdmFsdWUpOwoKICAgIC8qKiAKICAgoCAqIENyZWF0ZXMgYW4gQXR0cmlidXRlIGFuZCBhZGRzIGl0IHRvIHRoaXMgQ29tcGxleCBFbGVtZW50LgogICCgICoKICAgoCAqIEBwYXJhbSBsb2NhbG5hbWUgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KICAgoCAqIEBwYXJhbSBwcmVmaXggVGhlIHByZWZpeCBvZiB0aGUgYXR0cmlidXRlLgogICCgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlLgogICCgICoKICAgoCAqIEByZXR1cm4gQSBwb2ludGVyIHRvIHRoZSBjcmVhdGVkIEF0dHJpYnV0ZSB3aWxsIGJlIHJldHVybmVkLgogICCgICovCiAgICBJQXR0cmlidXRlKiBjcmVhdGVBdHRyaWJ1dGUoY29uc3QgQXhpc0NoYXIqIGxvY2FsbmFtZSwKICAgICAgICAgICAgY29uc3QgQXhpc0NoYXIqIHByZWZpeCwgY29uc3QgQXhpc0NoYXIqIHZhbHVlKTsKCiAgICAvKioKICAgoCAqIENyZWF0ZXMgYW4gQXR0cmlidXRlIGFuZCBhZGRzIGl0IHRvIHRoaXMgQ29tcGxleCBFbGVtZW50LgogICCgICoKICAgoCAqIEBwYXJhbSBsb2NhbG5hbWUgVGhlIGxvY2FsIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KICAgoCAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KICAgoCAqCiAgIKAgKiBAcmV0dXJuIEEgcG9pbnRlciB0byB0aGUgY3JlYXRlZCBBdHRyaWJ1dGUgd2lsbCBiZSByZXR1cm5lZC4KICAgoCAqLwogICAgSUF0dHJpYnV0ZSogY3JlYXRlQXR0cmlidXRlKGNvbnN0IEF4aXNDaGFyKiBsb2NhbG5hbWUsCiAgICAgICAgICAgIGNvbnN0IEF4aXNDaGFyKiB2YWx1ZSk7CgogICAgLyoqCiAgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGNoaWxkIGVsZW1lbnRzIG9mIHRoaXMgQ29tcGxleEVsZW1lbnQuCiAgICAgICoKICAgICAgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2YgY2hpbGQgZWxlbWVudHMgb2YgdGhpcyBDb21wbGV4RWxlbWVudC4KICAgICAgKi8KICAgIGludCBnZXROb09mQ2hpbGRyZW4oKTsKCiAgICAvKioKICAgICAgKiBHZXQgdGhlIENoaWxkIE5vZGUgb2YgdGhlIGdpdmVuIHBvc2l0aW9uLgogICAgICAqCiAgICAgICogQHBhcmFtIGlDaGlsZFBvc2l0aW9uIFRoZSBjaGlsZCBwb3NpdGlvbi4KICAgICAgKiBAcmV0dXJuIFRoZSBDaGlsZCBOb2RlIG9mIHRoZSBnaXZlbiBwb3NpdGlvbi4KICAgICAgKi8KICAgIEJhc2ljTm9kZSogZ2V0Q2hpbGQoaW50IGlDaGlsZFBvc2l0aW9uKTsKCiAgICAvKioKICAgICAgKiBHZXRzIHRoZSBsYXN0IENoaWxkIE5vZGUgb2YgdGhpcyBDb21wbGV4IEVsZW1lbnQuCiAgICAgICoKICAgICAgKiBAcmV0dXJuIFRoZSBsYXN0IENoaWxkIE5vZGUgb2YgdGhpcyBDb21wbGV4IEVsZW1lbnQuCiAgICAgICovCiAgICBCYXNpY05vZGUqIGdldExhc3RDaGlsZCgpOwoKICAgIC8qKgogICAgICAqIEdldHMgdGhlIGZpcnN0IENoaWxkIE5vZGUgb2YgdGhpcyBDb21wbGV4IEVsZW1lbnQuCiAgICAgICoKICAgICAgKiBAcmV0dXJuIFRoZSBmaXJzdCBDaGlsZCBOb2RlIG9mIHRoaXMgQ29tcGxleCBFbGVtZW50LgogICAgICAqLwogICAgQmFzaWNOb2RlKiBnZXRGaXJzdENoaWxkKCk7CgogICAgLyoqCiAgICAgICogQWRkcyB0aGUgZ2l2ZW4gY2hpbGQgbm9kZSB0byB0aGlzIENvbXBsZXggRWxlbWVudC4KICAgICAgKgogICAgICAqIEBwYXJhbSBwQmFzaWNOb2RlIHRoZSBjaGlsZCBub2RlIHRvIGJlIGFkZGVkIHRvIHRoaXMgQ29tcGxleCBFbGVtZW50LgogICAgICAqIEByZXR1cm4gQVhJU19TVUNDRVNTIHRvIGluZGljYXRlIHN1Y2Nlc3NmdWxsIG9wZXJhdGlvbi4KICAgICAgKi8KICAgIGludCBhZGRDaGlsZChCYXNpY05vZGUqIHBCYXNpY05vZGUpOwoKICAgIC8qKgogICAgICAqIEdldHMgdGhlIE5vZGUgVHlwZSBvZiB0aGUgQ29tcGxleCBFbGVtZW50IHdoaWNoIGlzIEVMRU1FTlRfTk9ERS4KICAgICAgKgogICAgICAqIEByZXR1cm4gVGhlIE5vZGUgVHlwZSBvZiB0aGUgQ29tcGxleCBFbGVtZW50IHdoaWNoIGlzIEVMRU1FTlRfTk9ERS4KICAgICAgKi8KICAgIE5PREVfVFlQRSBnZXROb2RlVHlwZSgpIGNvbnN0OwoKICAgIC8qKgogICAgICAqIFNldHMgdGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhpcyBDb21wbGV4IEVsZW1lbnQuCiAgICAgICoKICAgICAgKiBAcGFyYW0gcGFjaFVSSSB0aGUgbmFtZXNwYWNlIFVSSSBvZiB0aGlzIENvbXBsZXggRWxlbWVudC4KICAgICAgKiBAcmV0dXJuIEFYSVNfU1VDQ0VTUyB0byBpbmRpY2F0ZSBzdWNjZXNzZnVsbCBvcGVyYXRpb24uCiAgICAgICovCiAgICBpbnQgc2V0VVJJKGNvbnN0IEF4aXNDaGFyKiBwYWNoVVJJKTsKCiAgICAvKioKICAgICAgKiBTZXRzIHRoZSBsb2NhbCBuYW1lIG9mIHRoaXMgQ29tcGxleCBFbGVtZW50LgogICAgICAqCiAgICAgICogQHBhcmFtIHBhY2hMb2NhbE5hbWUgdGhlIGxvY2FsIG5hbWUgb2YgdGhpcyBDb21wbGV4IEVsZW1lbnQuCiAgICAgICogQHJldHVybiBBWElTX1NVQ0NFU1MgdG8gaW5kaWNhdGUgc3VjY2Vzc2Z1bGwgb3BlcmF0aW9uLgogICAgICAqLwogICAgaW50IHNldExvY2FsTmFtZShjb25zdCBBeGlzQ2hhciogcGFjaExvY2FsTmFtZSk7CgogICAgLyoqCiAgICAgICogU2V0cyB0aGUgcHJlZml4IG9mIHRoaXMgQ29tcGxleCBFbGVtZW50LgogICAgICAqCiAgICAgICogQHBhcmFtIHBhY2hQcmVmaXggdGhlIHByZWZpeCBvZiB0aGlzIENvbXBsZXggRWxlbWVudC4KICAgICAgKiBAcmV0dXJuIEFYSVNfU1VDQ0VTUyB0byBpbmRpY2F0ZSBzdWNjZXNzZnVsbCBvcGVyYXRpb24uCiAgICAgICovCiAgICBpbnQgc2V0UHJlZml4KGNvbnN0IEF4aXNDaGFyKiBwYWNoUHJlZml4KTsKCiAgICBpbnQgc2VyaWFsaXplKFNvYXBTZXJpYWxpemVyJiBwU1opOwoKICAgIGludCBzZXJpYWxpemUoU29hcFNlcmlhbGl6ZXImIHBTWiwgc3RkOjpsaXN0PEF4aXNDaGFyKj4mIGxzdFRtcE5hbWVTcGFjZVN0YWNrKTsKCiAgICAvKioKICAgICAgKiBUaGUgQ29uc3RydWN0b3IuCiAgICAgICovCiAgICBDb21wbGV4RWxlbWVudCgpOwogICAgQ29tcGxleEVsZW1lbnQoY29uc3QgQ29tcGxleEVsZW1lbnQmIHJDb3B5KTsKICAgIEJhc2ljTm9kZSogY2xvbmUoKTsKCiAgICAvKioKICAgICAgKiBUaGUgRGVzdHJ1Y3Rvci4KICAgICAgKi8KICAgIHZpcnR1YWwgfkNvbXBsZXhFbGVtZW50KCk7CgogICAgLyoKICAgICAqIFRoaXMgbWV0aG9kIGlzIG92ZXJyaWRkZW4gdG8gZG8gbm90aGluZyBhbHdheXMgYmVjYXVzZSB0aGlzIGlzIAogICAgICogIGEgQ29tcGxleCBFbGVtZW50LiBJbnN0ZWFkIG9mIHVzaW5nIHRoaXMgbWV0aG9kLCBhIHVzZXIgb2YgYSAKICAgICAqICBDb21wbGV4RWxlbWVudCBtdXN0IGdldCB0aGUgY2hpbGRlcmVuIG9mIHRoaXMgQ29tcGxleEVsZW1lbnQgYW5kCiAgICAgKiAgaGFzIHRvIHRyYXZlcnNlIHRocm91Z2ggdGhlIGNoaWxkcmVhbiBpbiBhIGFwcHJvcHJpYXRlIG1hbm5lcgogICAgICogIGluIG9yZGVyIHRvIHNldCB0aGVyZSB2YWx1ZXMuCiAgICAgKiAgQSB1c2VyIG9mIGEgQ29tcGxleEVsZW1lbnQgc2hvdWxkIG5vdCB1c2UgdGhpcyBtZXRob2QuCiAgICAgKiBAcGFyYW0KICAgICAqIEByZXR1cm4gQWx3YXlzIHJldHVybiBmYWlsIChBWElTX0ZBSUwpLgogICAgICovCiAgICBpbnQgc2V0VmFsdWUoY29uc3QgQXhpc0NoYXIqIHBhY2hWYWx1ZSkge3JldHVybiBBWElTX0ZBSUw7fQoKICAgIC8qCiAgICAgKiBUaGlzIG1ldGhvZCBpcyBvdmVycmlkZGVuIHRvIHJldHVybiBOVUxMIGFsd2F5cyBiZWNhdXNlIHRoaXMgaXMgCiAgICAgKiAgYSBDb21wbGV4IEVsZW1lbnQuIEluc3RlYWQgb2YgdXNpbmcgdGhpcyBtZXRob2QsIGEgdXNlciBvZiBhIAogICAgICogIENvbXBsZXhFbGVtZW50IG11c3QgZ2V0IHRoZSBjaGlsZGVyZW4gb2YgdGhpcyBDb21wbGV4RWxlbWVudCBhbmQKICAgICAqICBoYXMgdG8gdHJhdmVyc2UgdGhyb3VnaCB0aGUgY2hpbGRyZWFuIGluIGEgYXBwcm9wcmlhdGUgbWFubmVyCiAgICAgKiAgaW4gb3JkZXIgdG8gZ2V0IHRoZXJlIHZhbHVlcy4KICAgICAqICBBIHVzZXIgb2YgYSBDb21wbGV4RWxlbWVudCBzaG91bGQgbm90IHVzZSB0aGlzIG1ldGhvZC4KICAgICAqIEBwYXJhbQogICAgICogQHJldHVybiBBbHdheXMgcmV0dXJuIE5VTEwgdG8gaW5kaWNhdGUgdW5zdWNjZXNzZnVsLgogICAgICovCiAgICBjb25zdCBBeGlzQ2hhciogZ2V0VmFsdWUoKSBjb25zdCB7cmV0dXJuIE5VTEw7fQoKICAgIC8qKgogICAgICAqIFJldHVybnMgdGhlIGxvY2FsIG5hbWUgb2YgdGhpcyBub2RlLgogICAgICAqCiAgICAgICogQHJldHVybiBUaGUgbG9jYWxuYW1lIG9mIHRoaXMgZWxlbWVudC4KICAgICAgKi8KICAgIGNvbnN0IEF4aXNDaGFyKiBnZXRMb2NhbE5hbWUoKTsKCiAgICAvKioKICAgICAgKiBSZXR1cm5zIHRoZSBuYW1lc3BhY2UgVVJJIG9mIHRoaXMgbm9kZS4KICAgICAgKgogICAgICAqIEByZXR1cm4gVGhlIG5hbWVzcGFjZSBVUkkgb2YgdGhpcyBlbGVtZW50LgogICAgICAqLwogICAgY29uc3QgQXhpc0NoYXIqIGdldFVSSSgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAvKioKICAgICAgKiBSZXR1cm5zIHRoZSBwcmVmaXggIG9mIHRoaXMgbm9kZS4KICAgICAgKgogICAgICAqIEByZXR1cm4gVGhlIHByZWZpeCBvZiB0aGlzIGVsZW1lbnQuCiAgICAgICovCiAgICBjb25zdCBBeGlzQ2hhciogZ2V0UHJlZml4KCk7CgogICAgLyoqCiAgICAgKiBTZXQgYSBwb2ludGVyIHRvIHRoZSBwYXJlbnQgbm9kZS4KICAgICAqLwogICAgdm9pZCBzZXRQYXJlbnQoQ29tcGxleEVsZW1lbnQgKnBhcmVudCk7Cgpwcml2YXRlOgogICAgaW50IGlOb09mQ2hpbGRyZW47CiAgICBpbnQgc2VyaWFsaXplQ2hpbGRyZW4oU29hcFNlcmlhbGl6ZXImIHBTWik7CiAgICBpbnQgc2VyaWFsaXplQ2hpbGRyZW4oU29hcFNlcmlhbGl6ZXImIHBTWiwgc3RkOjpsaXN0PEF4aXNDaGFyKj4mIGxzdFRtcE5hbWVTcGFjZVN0YWNrKTsKICAgIGludCBzZXJpYWxpemVOYW1lc3BhY2VEZWNsKFNvYXBTZXJpYWxpemVyICZwU1opOyAKICAgIGludCBhdHRyU2VyaWFsaXplKFNvYXBTZXJpYWxpemVyJiBwU1osIHN0ZDo6bGlzdDxBeGlzQ2hhcio+JiBsc3RUbXBOYW1lU3BhY2VTdGFjayk7CiAgICBib29sIGlzU2VyaWFsaXphYmxlKCk7CiAgICBzdGQ6Omxpc3Q8QmFzaWNOb2RlKj4gbV9jaGlsZHJlbjsKICAgIHN0ZDo6bGlzdDxBdHRyaWJ1dGUqPiBtX25hbWVzcGFjZURlY2xzOwogICAgc3RkOjpsaXN0PEF0dHJpYnV0ZSo+IG1fYXR0cmlidXRlczsKICAgIEF4aXNDaGFyKiBtX3BhY2hQcmVmaXg7CiAgICBBeGlzQ2hhciogbV9wYWNoTG9jYWxOYW1lOwogICAgQXhpc0NoYXIqIG1fcGFjaFVSSTsKCiAgICAvKioKICAgICAgKiBBdHRyaWJ1dGVzIGl0ZXJhdG9yCiAgICAgICovCiAgICBzdGQ6Omxpc3QgPEF0dHJpYnV0ZSAqPjo6aXRlcmF0b3IgbV92aUN1cnJlbnRBdHRyaWJ1dGU7CgogICAgQ29tcGxleEVsZW1lbnQgKiBtX3BQYXJlbnQ7Cgp9OwoKQVhJU19DUFBfTkFNRVNQQUNFX0VORAoKI2VuZGlmCg==