PD9waHAKLyo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBGaWxlOiAJSlBHUkFQSF9QT0xBUi5QSFAKLy8gRGVzY3JpcHRpb246CVBvbGFyIHBsb3QgZXh0ZW5zaW9uIGZvciBKcEdyYXBoCi8vIENyZWF0ZWQ6IAkyMDAzLTAyLTAyCi8vIEF1dGhvcjoJSm9oYW4gUGVyc3NvbiAoam9oYW5wQGFkaXR1cy5udSkKLy8gVmVyOgkJJElkJAovLwovLyBDb3B5cmlnaHQgKGMpIEFkaXR1cyBDb25zdWx0aW5nLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoqLwoKcmVxdWlyZV9vbmNlICgnanBncmFwaF9wbG90bWFyay5pbmMnKTsKCgpyZXF1aXJlX29uY2UgImpwZ3JhcGhfbG9nLnBocCI7CgoKREVGSU5FKCdQT0xBUl8zNjAnLDEpOwpERUZJTkUoJ1BPTEFSXzE4MCcsMik7CgovLwovLyBOb3RlLiBEb24ndCBhdHRlbXB0IHRvIG1ha2Ugc2Vuc2Ugb2YgdGhpcyBjb2RlLgovLyBJbiBvcmRlciBub3QgdG8gaGF2ZSB0byBiZSBhYmxlIHRvIGluaGVyaXQgdGhlIHNjYWxpbmcgY29kZQovLyBmcm9tIHRoZSBtYWluIGdyYXBoIHBhY2thZ2Ugd2UgaGF2ZSBoYWQgdG8gbWFrZSBzb21lICJ0cmlja3MiIHNpbmNlCi8vIHRoZSBvcmlnaW5hbCBzY2FsaW5nIGFuZCBheGlzIHdhcyBub3QgZGVzaWduZWQgdG8gZG8gd2hhdCBpcwovLyByZXF1aXJlZCBoZXJlLgovLyBUaGVyZSB3ZXJlIHR3byBvcHRpb24uIDE6IFJlLWltcGxlbWVudCBldmVyeXRoaW5nIGFuZCBnZXQgYSBjbGVhbiBkZXNpZ24KLy8gYW5kIDI6IGRvIHNvbWUgInNtYWxsIiB0cmlja2VyeSBhbmQgYmUgYWJsZSB0byBpbmhlcml0IG1vc3Qgb2YKLy8gdGhlIGZ1bmN0aW9ubGl0eSBmcm9tIHRoZSBtYWluIGdyYXBoIHBhY2thZ2UuIAovLyBXZSBjaG9vc2UgMjogaGVyZSBpbiBvcmRlciB0byBzYXZlIHNvbWUgdGltZS4KLy8gCgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIGNsYXNzIFBvbGFyUGxvdAovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmNsYXNzIFBvbGFyUGxvdCB7CiAgICB2YXIgJG51bXBvaW50cz0wOwogICAgdmFyICRpQ29sb3I9J25hdnknLCRpRmlsbENvbG9yPScnOwogICAgdmFyICRpTGluZVdlaWdodD0xOwogICAgdmFyICRjb29yZD1udWxsOwogICAgdmFyICRsZWdlbmRjc2ltdGFyZ2V0PScnOwogICAgdmFyICRsZWdlbmRjc2ltYWx0PScnOwogICAgdmFyICRsZWdlbmQ9IiI7CiAgICB2YXIgJGNzaW10YXJnZXRzPWFycmF5KCk7CS8vIEFycmF5IG9mIHRhcmdldHMgZm9yIENTSU0KICAgIHZhciAkY3NpbWFyZWFzPSIiOwkJCS8vIFJlc3VsdGFudCBDU0lNIGFyZWEgdGFncwkKICAgIHZhciAkY3NpbWFsdHM9bnVsbDsJCQkvLyBBTFQ6cyBmb3IgY29ycmVzcG9uZGluZyB0YXJnZXQKICAgIHZhciAkbGluZV9zdHlsZT0nc29saWQnLCRtYXJrOwoKICAgIGZ1bmN0aW9uIFBvbGFyUGxvdCgkYURhdGEpIHsKCSRuID0gY291bnQoJGFEYXRhKTsKCWlmKCAkbiAmIDEgKSB7CgkgICAgSnBHcmFwaEVycm9yOjpSYWlzZUwoMTcwMDEpOwovLygnUG9sYXIgcGxvdHMgbXVzdCBoYXZlIGFuIGV2ZW4gbnVtYmVyIG9mIGRhdGEgcG9pbnQuIEVhY2ggZGF0YSBwb2ludCBpcyBhIHR1cGxlIChhbmdsZSxyYWRpdXMpLicpOwoJfQoJJHRoaXMtPm51bXBvaW50cyA9ICRuLzI7CgkkdGhpcy0+Y29vcmQgPSAkYURhdGE7CgkkdGhpcy0+bWFyayA9IG5ldyBQbG90TWFyaygpOwogICAgfQoKICAgIGZ1bmN0aW9uIFNldFdlaWdodCgkYVdlaWdodCkgewoJJHRoaXMtPmlMaW5lV2VpZ2h0ID0gJGFXZWlnaHQ7CiAgICB9CgogICAgZnVuY3Rpb24gU2V0Q29sb3IoJGFDb2xvcil7CgkkdGhpcy0+aUNvbG9yID0gJGFDb2xvcjsKICAgIH0KCiAgICBmdW5jdGlvbiBTZXRGaWxsQ29sb3IoJGFDb2xvcil7CgkkdGhpcy0+aUZpbGxDb2xvciA9ICRhQ29sb3I7CiAgICB9CgogICAgZnVuY3Rpb24gTWF4KCkgewoJJG0gPSAkdGhpcy0+Y29vcmRbMV07CgkkaT0xOwoJd2hpbGUoICRpIDwgJHRoaXMtPm51bXBvaW50cyApIHsKCSAgICAkbSA9IG1heCgkbSwkdGhpcy0+Y29vcmRbMiokaSsxXSk7ICAKCSAgICArKyRpOwoJfSAKCXJldHVybiAkbTsKICAgIH0KICAgIC8vIFNldCBocmVmIHRhcmdldHMgZm9yIENTSU0JCiAgICBmdW5jdGlvbiBTZXRDU0lNVGFyZ2V0cygkYVRhcmdldHMsJGFBbHRzPW51bGwpIHsKCSR0aGlzLT5jc2ltdGFyZ2V0cz0kYVRhcmdldHM7CgkkdGhpcy0+Y3NpbWFsdHM9JGFBbHRzOwkJCiAgICB9CiAJCiAgICAvLyBHZXQgYWxsIGNyZWF0ZWQgYXJlYXMKICAgIGZ1bmN0aW9uIEdldENTSU1hcmVhcygpIHsKCXJldHVybiAkdGhpcy0+Y3NpbWFyZWFzOwogICAgfQkKCQogICAgZnVuY3Rpb24gU2V0TGVnZW5kKCRhTGVnZW5kLCRhQ1NJTT0iIiwkYUNTSU1BbHQ9IiIpIHsKCSR0aGlzLT5sZWdlbmQgPSAkYUxlZ2VuZDsKCSR0aGlzLT5sZWdlbmRjc2ltdGFyZ2V0ID0gJGFDU0lNOwoJJHRoaXMtPmxlZ2VuZGNzaW1hbHQgPSAkYUNTSU1BbHQ7CiAgICB9CgogICAgLy8gUHJpdmF0ZSBtZXRob2RzCgogICAgZnVuY3Rpb24gTGVnZW5kKCYkYUdyYXBoKSB7CgkkY29sb3IgPSAkdGhpcy0+aUNvbG9yIDsKCWlmKCAkdGhpcy0+bGVnZW5kICE9ICIiICkgewoJICAgIGlmKCAkdGhpcy0+aUZpbGxDb2xvciE9JycgKSB7CgkJJGNvbG9yID0gJHRoaXMtPmlGaWxsQ29sb3I7CgkJJGFHcmFwaC0+bGVnZW5kLT5BZGQoJHRoaXMtPmxlZ2VuZCwkY29sb3IsJHRoaXMtPm1hcmssMCwKCQkJCSAgICAgJHRoaXMtPmxlZ2VuZGNzaW10YXJnZXQsJHRoaXMtPmxlZ2VuZGNzaW1hbHQpOyAgICAKCSAgICB9CgkgICAgZWxzZSB7CgkJJGFHcmFwaC0+bGVnZW5kLT5BZGQoJHRoaXMtPmxlZ2VuZCwkY29sb3IsJHRoaXMtPm1hcmssJHRoaXMtPmxpbmVfc3R5bGUsCgkJCQkgICAgICR0aGlzLT5sZWdlbmRjc2ltdGFyZ2V0LCR0aGlzLT5sZWdlbmRjc2ltYWx0KTsgICAgCgkgICAgfQoJfQogICAgfQoKICAgIGZ1bmN0aW9uIFN0cm9rZSgmJGltZywkc2NhbGUpIHsKCgkkaT0wOwoJJHA9YXJyYXkoKTsKCSR0aGlzLT5jc2ltYXJlYXM9Jyc7Cgl3aGlsZSgkaSA8ICR0aGlzLT5udW1wb2ludHMpIHsKCSAgICBsaXN0KCR4MSwkeTEpID0gJHNjYWxlLT5QVHJhbnNsYXRlKCR0aGlzLT5jb29yZFsyKiRpXSwkdGhpcy0+Y29vcmRbMiokaSsxXSk7CgkgICAgJHBbMiokaV0gPSAkeDE7CgkgICAgJHBbMiokaSsxXSA9ICR5MTsKCQoJICAgIGlmKCBpc3NldCgkdGhpcy0+Y3NpbXRhcmdldHNbJGldKSApIHsKCSAgICAgICAgJHRoaXMtPm1hcmstPlNldENTSU1UYXJnZXQoJHRoaXMtPmNzaW10YXJnZXRzWyRpXSk7CgkgICAgICAgICR0aGlzLT5tYXJrLT5TZXRDU0lNQWx0KCR0aGlzLT5jc2ltYWx0c1skaV0pOwoJCSR0aGlzLT5tYXJrLT5TZXRDU0lNQWx0VmFsKCR0aGlzLT5jb29yZFsyKiRpXSwgJHRoaXMtPmNvb3JkWzIqJGkrMV0pOwoJCSR0aGlzLT5tYXJrLT5TdHJva2UoJGltZywkeDEsJHkxKTsKCQkkdGhpcy0+Y3NpbWFyZWFzIC49ICR0aGlzLT5tYXJrLT5HZXRDU0lNQXJlYXMoKTsKCSAgICB9CgkgICAgZWxzZQoJCSR0aGlzLT5tYXJrLT5TdHJva2UoJGltZywkeDEsJHkxKTsKCgkgICAgKyskaTsKCX0KCglpZiggJHRoaXMtPmlGaWxsQ29sb3IgIT0gJycgKSB7CgkgICAgJGltZy0+U2V0Q29sb3IoJHRoaXMtPmlGaWxsQ29sb3IpOwoJICAgICRpbWctPkZpbGxlZFBvbHlnb24oJHApOwoJfQoJJGltZy0+U2V0TGluZVdlaWdodCgkdGhpcy0+aUxpbmVXZWlnaHQpOwoJJGltZy0+U2V0Q29sb3IoJHRoaXMtPmlDb2xvcik7CgkkaW1nLT5Qb2x5Z29uKCRwLCR0aGlzLT5pRmlsbENvbG9yIT0nJyk7CiAgICB9Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gY2xhc3MgUG9sYXJBeGlzCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KY2xhc3MgUG9sYXJBeGlzIGV4dGVuZHMgQXhpcyB7CiAgICB2YXIgJGFuZ2xlX3N0ZXA9MTUsJGFuZ2xlX2NvbG9yPSdsaWdodGdyYXknLCRhbmdsZV9sYWJlbF9jb2xvcj0nYmxhY2snOwogICAgdmFyICRhbmdsZV9mb250ZmFtPUZGX0ZPTlQxLCRhbmdsZV9mb250c3R5bGU9RlNfTk9STUFMLCRhbmdsZV9mb250c2l6ZT0xMDsKICAgIHZhciAkYW5nbGVfZm9udGNvbG9yID0gJ25hdnknOwogICAgdmFyICRncmlkbWlub3JfY29sb3I9J2xpZ2h0Z3JheScsJGdyaWRtYWpvcl9jb2xvcj0nbGlnaHRncmF5JzsKICAgIHZhciAkc2hvd19taW5vcl9ncmlkID0gZmFsc2UsICRzaG93X21ham9yX2dyaWQgPSB0cnVlIDsKICAgIHZhciAkc2hvd19hbmdsZV9tYXJrPXRydWUsICRzaG93X2FuZ2xlX2dyaWQ9dHJ1ZSwgJHNob3dfYW5nbGVfbGFiZWw9dHJ1ZTsKICAgIHZhciAkYW5nbGVfdGlja19sZW49MywgJGFuZ2xlX3RpY2tfbGVuMj0zLCAkYW5nbGVfdGlja19jb2xvcj0nYmxhY2snOwogICAgdmFyICRzaG93X2FuZ2xlX3RpY2s9dHJ1ZTsKICAgIHZhciAkcmFkaXVzX3RpY2tfY29sb3I9J2JsYWNrJzsKCiAgICBmdW5jdGlvbiBQb2xhckF4aXMoJiRpbWcsJiRhU2NhbGUpIHsKCXBhcmVudDo6QXhpcygkaW1nLCRhU2NhbGUpOwogICAgfQoKICAgIGZ1bmN0aW9uIFNob3dBbmdsZURlZ3JlZU1hcmsoJGFGbGc9dHJ1ZSkgewoJJHRoaXMtPnNob3dfYW5nbGVfbWFyayA9ICRhRmxnOwogICAgfQoKICAgIGZ1bmN0aW9uIFNldEFuZ2xlU3RlcCgkYVN0ZXApIHsKCSR0aGlzLT5hbmdsZV9zdGVwPSRhU3RlcDsKICAgIH0KCiAgICBmdW5jdGlvbiBIaWRlVGlja3MoJGFGbGc9dHJ1ZSwkYUFuZ2xlRmxnPXRydWUpIHsKCXBhcmVudDo6SGlkZVRpY2tzKCRhRmxnLCRhRmxnKTsKCSR0aGlzLT5zaG93X2FuZ2xlX3RpY2sgPSAhJGFBbmdsZUZsZzsKICAgIH0KCiAgICBmdW5jdGlvbiBTaG93QW5nbGVMYWJlbCgkYUZsZz10cnVlKSB7CgkkdGhpcy0+c2hvd19hbmdsZV9sYWJlbCA9ICRhRmxnOwogICAgfQoKICAgIGZ1bmN0aW9uIFNob3dHcmlkKCRhTWFqb3I9dHJ1ZSwkYU1pbm9yPWZhbHNlLCRhQW5nbGU9dHJ1ZSkgewoJJHRoaXMtPnNob3dfbWlub3JfZ3JpZCA9ICRhTWlub3I7CgkkdGhpcy0+c2hvd19tYWpvcl9ncmlkID0gJGFNYWpvcjsKCSR0aGlzLT5zaG93X2FuZ2xlX2dyaWQgPSAkYUFuZ2xlIDsKICAgIH0KCiAgICBmdW5jdGlvbiBTZXRBbmdsZUZvbnQoJGFGb250RmFtLCRhRm9udFN0eWxlPUZTX05PUk1BTCwkYUZvbnRTaXplPTEwKSB7CgkkdGhpcy0+YW5nbGVfZm9udGZhbSA9ICRhRm9udEZhbTsKCSR0aGlzLT5hbmdsZV9mb250c3R5bGUgPSAkYUZvbnRTdHlsZTsKCSR0aGlzLT5hbmdsZV9mb250c2l6ZSA9ICRhRm9udFNpemU7CiAgICB9CgogICAgZnVuY3Rpb24gU2V0Q29sb3IoJGFDb2xvciwkYVJhZENvbG9yPScnLCRhQW5nbGVDb2xvcj0nJykgewoJaWYoICRhQW5nbGVDb2xvciA9PSAnJyApCgkgICAgJGFBbmdsZUNvbG9yPSRhQ29sb3I7CglwYXJlbnQ6OlNldENvbG9yKCRhQ29sb3IsJGFSYWRDb2xvcik7CgkkdGhpcy0+YW5nbGVfZm9udGNvbG9yID0gJGFBbmdsZUNvbG9yOwogICAgfQoKICAgIGZ1bmN0aW9uIFNldEdyaWRDb2xvcigkYU1ham9yQ29sb3IsJGFNaW5vckNvbG9yPScnLCRhQW5nbGVDb2xvcj0nJykgewoJaWYoICRhTWlub3JDb2xvciA9PSAnJyApIAoJICAgICRhTWlub3JDb2xvciA9ICRhTWFqb3JDb2xvcjsKCWlmKCAkYUFuZ2xlQ29sb3IgPT0gJycgKSAKCSAgICAkYUFuZ2xlQ29sb3IgPSAkYU1ham9yQ29sb3I7CgoJJHRoaXMtPmdyaWRtaW5vcl9jb2xvciA9ICRhTWlub3JDb2xvcjsKCSR0aGlzLT5ncmlkbWFqb3JfY29sb3IgPSAkYU1ham9yQ29sb3I7CgkkdGhpcy0+YW5nbGVfY29sb3IgPSAkYUFuZ2xlQ29sb3I7CiAgICB9CgogICAgZnVuY3Rpb24gU2V0VGlja0NvbG9ycygkYVJhZENvbG9yLCRhQW5nbGVDb2xvcj0nJykgewoJJHRoaXMtPnJhZGl1c190aWNrX2NvbG9yID0gJGFSYWRDb2xvcjsKCSR0aGlzLT5hbmdsZV90aWNrX2NvbG9yID0gJGFBbmdsZUNvbG9yOwogICAgfQogICAgCiAgICAvLyBQcml2YXRlIG1ldGhvZHMKICAgIGZ1bmN0aW9uIFN0cm9rZUdyaWQoJHBvcykgewoJJHggPSByb3VuZCgkdGhpcy0+aW1nLT5sZWZ0X21hcmdpbiArICR0aGlzLT5pbWctPnBsb3R3aWR0aC8yKTsKCSR0aGlzLT5zY2FsZS0+dGlja3MtPlN0cm9rZSgkdGhpcy0+aW1nLCR0aGlzLT5zY2FsZSwkcG9zKTsKCgkvLyBTdHJva2UgdGhlIG1pbm9yIGFyY3MgCgkkcG1pbiA9IGFycmF5KCk7CgkkcCA9ICR0aGlzLT5zY2FsZS0+dGlja3MtPnRpY2tzX3BvczsKCSRuID0gY291bnQoJHApOwoJJGkgPSAwOwoJJHRoaXMtPmltZy0+U2V0Q29sb3IoJHRoaXMtPmdyaWRtaW5vcl9jb2xvcik7Cgl3aGlsZSggJGkgPCAkbiApIHsKCSAgICAkciA9ICRwWyRpXS0keCsxOwoJICAgICRwbWluW109JHI7CgkgICAgaWYoICR0aGlzLT5zaG93X21pbm9yX2dyaWQgKSB7CgkJJHRoaXMtPmltZy0+Q2lyY2xlKCR4LCRwb3MsJHIpOwoJICAgIH0KCSAgICAkaSsrOwoJfQoJCgkkbGltaXQgPSBtYXgoJHRoaXMtPmltZy0+cGxvdHdpZHRoLCR0aGlzLT5pbWctPnBsb3RoZWlnaHQpKjEuNCA7Cgl3aGlsZSggJHIgPCAkbGltaXQgKSB7CgkgICAgJG9mZiA9ICRyOwoJICAgICRpPTE7CgkgICAgJHIgPSAkb2ZmICsgcm91bmQoJHBbJGldLSR4KzEpOwoJICAgIHdoaWxlKCAkciA8ICRsaW1pdCAmJiAkaSA8ICRuICkgewoJCSRyID0gJG9mZiskcFskaV0tJHg7CgkJJHBtaW5bXT0kcjsKCQlpZiggJHRoaXMtPnNob3dfbWlub3JfZ3JpZCApIHsKCQkgICAgJHRoaXMtPmltZy0+Q2lyY2xlKCR4LCRwb3MsJHIpOwoJCX0KCQkkaSsrOwoJICAgIH0KCX0KCgkvLyBTdHJva2UgdGhlIG1ham9yIGFyY3MgCglpZiggJHRoaXMtPnNob3dfbWFqb3JfZ3JpZCApIHsKCSAgICAvLyBGaXJzdCBkZXRlcm1pbmUgaG93IG1hbnkgbWlub3Igc3RlcCBvbgoJICAgIC8vIGV2ZXJ5IG1ham9yIHN0ZXAuIFdlIGhhdmUgcmVjb3JkZWQgdGhlIG1pbm9yIHJhZGl1cwoJICAgIC8vIGluIHBtaW4gYW5kIHVzZSB0aGVzZSB2YWx1ZXMuIFRoaXMgaXMgZG9uZSBpbiBvcmRlcgoJICAgIC8vIHRvIGF2b2lkIHJvdW5kaW5nIGVycm9ycyBpZiB3ZSB3ZXJlIHRvIHJlY2FsY3VsYXRlIHRoZQoJICAgIC8vIGRpZmZlcmVudCBtYWpvciByYWRpdXMuCgkgICAgJHBtYWogPSAkdGhpcy0+c2NhbGUtPnRpY2tzLT5tYWpfdGlja3NfcG9zOwoJICAgICRwID0gJHRoaXMtPnNjYWxlLT50aWNrcy0+dGlja3NfcG9zOwoJICAgIGlmKCAkdGhpcy0+c2NhbGUtPm5hbWUgPT0gJ2xpbicgKSB7CgkJJHN0ZXA9cm91bmQoKCRwbWFqWzFdIC0gJHBtYWpbMF0pLygkcFsxXSAtICRwWzBdKSk7CgkgICAgfQoJICAgIGVsc2UgewoJCSRzdGVwPTk7CgkgICAgfQoJICAgICRuID0gcm91bmQoY291bnQoJHBtaW4pLyRzdGVwKTsKCSAgICAkaSA9IDA7CgkgICAgJHRoaXMtPmltZy0+U2V0Q29sb3IoJHRoaXMtPmdyaWRtYWpvcl9jb2xvcik7CgkgICAgJGxpbWl0ID0gbWF4KCR0aGlzLT5pbWctPnBsb3R3aWR0aCwkdGhpcy0+aW1nLT5wbG90aGVpZ2h0KSoxLjQgOwoJICAgICRvZmYgPSAkcjsKCSAgICAkaT0wOwoJICAgICRyID0gJHBtaW5bJGkqJHN0ZXBdOwoJICAgIHdoaWxlKCAkciA8ICRsaW1pdCAmJiAkaSA8ICRuICkgewoJCSRyID0gJHBtaW5bJGkqJHN0ZXBdOwoJCSR0aGlzLT5pbWctPkNpcmNsZSgkeCwkcG9zLCRyKTsKCQkkaSsrOwoJICAgIH0KCX0KCgkvLyBEcmF3IGFuZ2xlcwoJaWYoICR0aGlzLT5zaG93X2FuZ2xlX2dyaWQgKSB7CgkgICAgJHRoaXMtPmltZy0+U2V0Q29sb3IoJHRoaXMtPmFuZ2xlX2NvbG9yKTsKCSAgICAkZCA9IG1heCgkdGhpcy0+aW1nLT5wbG90aGVpZ2h0LCR0aGlzLT5pbWctPnBsb3R3aWR0aCkqMS40IDsKCSAgICAkYSA9IDA7CgkgICAgJHAgPSAkdGhpcy0+c2NhbGUtPnRpY2tzLT50aWNrc19wb3M7CgkgICAgJHN0YXJ0X3JhZGl1cyA9ICRwWzFdLSR4OwoJICAgIHdoaWxlKCAkYSA8IDM2MCApIHsKCQlpZiggJGEgPT0gOTAgfHwgJGEgPT0gMjcwICkgewoJCSAgICAvLyBNYWtlIHN1cmUgdGhlcmUgYXJlIG5vIHJvdW5kaW5nIHByb2JsZW0gd2l0aAoJCSAgICAvLyBleGFjdGx5IHZlcnRpY2FsIGxpbmVzCgkJICAgICR0aGlzLT5pbWctPkxpbmUoJHgrJHN0YXJ0X3JhZGl1cypjb3MoJGEvMTgwKk1fUEkpKzEsCgkJCQkgICAgICRwb3MtJHN0YXJ0X3JhZGl1cypzaW4oJGEvMTgwKk1fUEkpLAoJCQkJICAgICAkeCskc3RhcnRfcmFkaXVzKmNvcygkYS8xODAqTV9QSSkrMSwKCQkJCSAgICAgJHBvcy0kZCpzaW4oJGEvMTgwKk1fUEkpKTsKCQkgICAgCgkJfQoJCWVsc2UgewoJCSAgICAkdGhpcy0+aW1nLT5MaW5lKCR4KyRzdGFydF9yYWRpdXMqY29zKCRhLzE4MCpNX1BJKSsxLAoJCQkJICAgICAkcG9zLSRzdGFydF9yYWRpdXMqc2luKCRhLzE4MCpNX1BJKSwKCQkJCSAgICAgJHgrJGQqY29zKCRhLzE4MCpNX1BJKSwKCQkJCSAgICAgJHBvcy0kZCpzaW4oJGEvMTgwKk1fUEkpKTsKCQl9CgkJJGEgKz0gJHRoaXMtPmFuZ2xlX3N0ZXA7CgkgICAgfQoJfQogICAgfQoKICAgIGZ1bmN0aW9uIFN0cm9rZUFuZ2xlTGFiZWxzKCRwb3MsJHR5cGUpIHsKCglpZiggISR0aGlzLT5zaG93X2FuZ2xlX2xhYmVsICkgCgkgICAgcmV0dXJuOwoJCgkkeDAgPSByb3VuZCgkdGhpcy0+aW1nLT5sZWZ0X21hcmdpbiskdGhpcy0+aW1nLT5wbG90d2lkdGgvMikrMTsKCgkkZCA9IG1heCgkdGhpcy0+aW1nLT5wbG90d2lkdGgsJHRoaXMtPmltZy0+cGxvdGhlaWdodCkqMS40MjsKCSRhID0gJHRoaXMtPmFuZ2xlX3N0ZXA7CgkkdCA9IG5ldyBUZXh0KCk7CgkkdC0+U2V0Q29sb3IoJHRoaXMtPmFuZ2xlX2ZvbnRjb2xvcik7CgkkdC0+U2V0Rm9udCgkdGhpcy0+YW5nbGVfZm9udGZhbSwkdGhpcy0+YW5nbGVfZm9udHN0eWxlLCR0aGlzLT5hbmdsZV9mb250c2l6ZSk7CgkkeHJpZ2h0ID0gJHRoaXMtPmltZy0+d2lkdGggLSAkdGhpcy0+aW1nLT5yaWdodF9tYXJnaW47CgkkeXRvcCA9ICR0aGlzLT5pbWctPnRvcF9tYXJnaW47CgkkeGxlZnQgPSAkdGhpcy0+aW1nLT5sZWZ0X21hcmdpbjsKCSR5Ym90dG9tID0gJHRoaXMtPmltZy0+aGVpZ2h0IC0gJHRoaXMtPmltZy0+Ym90dG9tX21hcmdpbjsKCSRoYSA9ICdsZWZ0JzsKCSR2YSA9ICdjZW50ZXInOwoJJHcgPSAkdGhpcy0+aW1nLT5wbG90d2lkdGgvMjsKCSRoID0gJHRoaXMtPmltZy0+cGxvdGhlaWdodC8yOwoJJHh0ID0gJHgwOyAkeXQgPSAkcG9zOwoJJG1hcmdpbj01OwoKCSR0bCAgPSAkdGhpcy0+YW5nbGVfdGlja19sZW4gOyAvLyBPdXRlciBsZW4KCSR0bDIgPSAkdGhpcy0+YW5nbGVfdGlja19sZW4yIDsgLy8gSW50ZXJpb3IgbGVuCgoJJHRoaXMtPmltZy0+U2V0Q29sb3IoJHRoaXMtPmFuZ2xlX3RpY2tfY29sb3IpOwoJJHJvdDkwID0gJHRoaXMtPmltZy0+YSA9PSA5MCA7CgoJaWYoICR0eXBlID09IFBPTEFSXzM2MCApIHsKCSAgICAkY2ExID0gYXRhbigkaC8kdykvTV9QSSoxODA7CgkgICAgJGNhMiA9IDE4MC0kY2ExOwoJICAgICRjYTMgPSAkY2ExKzE4MDsKCSAgICAkY2E0ID0gMzYwLSRjYTE7CgkgICAgJGVuZCA9IDM2MDsKCSAgICB3aGlsZSggJGEgPCAkZW5kICkgewoJCSRjYSA9IGNvcygkYS8xODAqTV9QSSk7CgkJJHNhID0gc2luKCRhLzE4MCpNX1BJKTsKCQkkeCA9ICRkKiRjYTsKCQkkeSA9ICRkKiRzYTsKCQkkeHQ9MTAwMDskeXQ9MTAwMDsKCQlpZiggJGEgPD0gJGNhMSB8fCAkYSA+PSAkY2E0ICkgewoJCSAgICAkeXQgPSAkcG9zIC0gJHcgKiAkeS8keDsKCQkgICAgJHh0ID0gJHhyaWdodCArICRtYXJnaW47CiAJCSAgICBpZiggJHJvdDkwICkgewoJCQkkaGEgPSAnY2VudGVyJzsKCQkJJHZhID0gJ3RvcCc7CgkJICAgIH0KCQkgICAgZWxzZSB7CgkJCSRoYSA9ICdsZWZ0JzsKCQkJJHZhID0gJ2NlbnRlcic7CgkJICAgIH0KCQkgICAgJHgxPSR4cmlnaHQtJHRsMjsgJHgyPSR4cmlnaHQrJHRsOwoJCSAgICAkeTE9JHkyPSR5dDsKCQl9CgkJZWxzZWlmKCAkYSA+ICRjYTEgJiYgJGEgPCAkY2EyICkgeyAKCQkgICAgJHh0ID0gJHgwICsgJGggKiAkeC8keTsKCQkgICAgJHl0ID0gJHl0b3AgLSAkbWFyZ2luOwogCQkgICAgaWYoICRyb3Q5MCApIHsKCQkJJGhhID0gJ2xlZnQnOwoJCQkkdmEgPSAnY2VudGVyJzsKCQkgICAgfQoJCSAgICBlbHNlIHsKCQkJJGhhID0gJ2NlbnRlcic7CgkJCSR2YSA9ICdib3R0b20nOwoJCSAgICB9CgkJICAgICR5MT0keXRvcCskdGwyOyR5Mj0keXRvcC0kdGw7CgkJICAgICR4MT0keDI9JHh0OwoJCX0KCQllbHNlaWYoICRhID49ICRjYTIgJiYgJGEgPD0gJGNhMyApIHsgCgkJICAgICR5dCA9ICRwb3MgKyAkdyAqICR5LyR4OwoJCSAgICAkeHQgPSAkeGxlZnQgLSAkbWFyZ2luOwogCQkgICAgaWYoICRyb3Q5MCApIHsKCQkJJGhhID0gJ2NlbnRlcic7CgkJCSR2YSA9ICdib3R0b20nOwoJCSAgICB9CgkJICAgIGVsc2UgewoJCQkkaGEgPSAncmlnaHQnOwoJCQkkdmEgPSAnY2VudGVyJzsKCQkgICAgfQoJCSAgICAkeDE9JHhsZWZ0KyR0bDI7JHgyPSR4bGVmdC0kdGw7CgkJICAgICR5MT0keTI9JHl0OwoJCX0KCQllbHNlIHsgCgkJICAgICR4dCA9ICR4MCAtICRoICogJHgvJHk7CgkJICAgICR5dCA9ICR5Ym90dG9tICsgJG1hcmdpbjsKIAkJICAgIGlmKCAkcm90OTAgKSB7CgkJCSRoYSA9ICdyaWdodCc7CgkJCSR2YSA9ICdjZW50ZXInOwoJCSAgICB9CgkJICAgIGVsc2UgewoJCQkkaGEgPSAnY2VudGVyJzsKCQkJJHZhID0gJ3RvcCc7CgkJICAgIH0KCQkgICAgJHkxPSR5Ym90dG9tLSR0bDI7JHkyPSR5Ym90dG9tKyR0bDsKCQkgICAgJHgxPSR4Mj0keHQ7CgkJfQoJCWlmKCAkYSAhPSAwICYmICRhICE9IDE4MCApIHsKCQkgICAgJHQtPkFsaWduKCRoYSwkdmEpOwoJCSAgICBpZiggJHRoaXMtPnNob3dfYW5nbGVfbWFyayApCgkJCSRhIC49ICewJzsKCQkgICAgJHQtPlNldCgkYSk7CgkJICAgICR0LT5TdHJva2UoJHRoaXMtPmltZywkeHQsJHl0KTsgICAKCQkgICAgaWYoICR0aGlzLT5zaG93X2FuZ2xlX3RpY2sgKQoJCQkkdGhpcy0+aW1nLT5MaW5lKCR4MSwkeTEsJHgyLCR5Mik7CgkJfQoJCSRhICs9ICR0aGlzLT5hbmdsZV9zdGVwOwoJICAgIH0KCX0KCWVsc2UgewoJICAgIC8vIFBPTEFSX0hBTEYKCSAgICAkY2ExID0gYXRhbigkaC8kdyoyKS9NX1BJKjE4MDsKCSAgICAkY2EyID0gMTgwLSRjYTE7CgkgICAgJGVuZCA9IDE4MDsJICAgIAoJICAgIHdoaWxlKCAkYSA8ICRlbmQgKSB7CgkJJGNhID0gY29zKCRhLzE4MCpNX1BJKTsKCQkkc2EgPSBzaW4oJGEvMTgwKk1fUEkpOwoJCSR4ID0gJGQqJGNhOwoJCSR5ID0gJGQqJHNhOwoJCWlmKCAkYSA8PSAkY2ExICkgewoJCSAgICAkeXQgPSAkcG9zIC0gJHcgKiAkeS8keDsKCQkgICAgJHh0ID0gJHhyaWdodCArICRtYXJnaW47CiAJCSAgICBpZiggJHJvdDkwICkgewoJCQkkaGEgPSAnY2VudGVyJzsKCQkJJHZhID0gJ3RvcCc7CgkJICAgIH0KCQkgICAgZWxzZSB7CgkJCSRoYSA9ICdsZWZ0JzsKCQkJJHZhID0gJ2NlbnRlcic7CgkJICAgIH0KCQkgICAgJHgxPSR4cmlnaHQtJHRsMjsgJHgyPSR4cmlnaHQrJHRsOwoJCSAgICAkeTE9JHkyPSR5dDsKCQl9CgkJZWxzZWlmKCAkYSA+ICRjYTEgJiYgJGEgPCAkY2EyICkgeyAKCQkgICAgJHh0ID0gJHgwICsgMiokaCAqICR4LyR5OwoJCSAgICAkeXQgPSAkeXRvcCAtICRtYXJnaW47CiAJCSAgICBpZiggJHJvdDkwICkgewoJCQkkaGEgPSAnbGVmdCc7CgkJCSR2YSA9ICdjZW50ZXInOwoJCSAgICB9CgkJICAgIGVsc2UgewoJCQkkaGEgPSAnY2VudGVyJzsKCQkJJHZhID0gJ2JvdHRvbSc7CgkJICAgIH0KCQkgICAgJHkxPSR5dG9wKyR0bDI7JHkyPSR5dG9wLSR0bDsKCQkgICAgJHgxPSR4Mj0keHQ7CgkJfQoJCWVsc2VpZiggJGEgPj0gJGNhMiApIHsgCgkJICAgICR5dCA9ICRwb3MgKyAkdyAqICR5LyR4OwoJCSAgICAkeHQgPSAkeGxlZnQgLSAkbWFyZ2luOwogCQkgICAgaWYoICRyb3Q5MCApIHsKCQkJJGhhID0gJ2NlbnRlcic7CgkJCSR2YSA9ICdib3R0b20nOwoJCSAgICB9CgkJICAgIGVsc2UgewoJCQkkaGEgPSAncmlnaHQnOwoJCQkkdmEgPSAnY2VudGVyJzsKCQkgICAgfQoJCSAgICAkeDE9JHhsZWZ0KyR0bDI7JHgyPSR4bGVmdC0kdGw7CgkJICAgICR5MT0keTI9JHl0OwoJCX0KCQkkdC0+QWxpZ24oJGhhLCR2YSk7CgkJaWYoICR0aGlzLT5zaG93X2FuZ2xlX21hcmsgKQoJCSAgICAkYSAuPSAnsCc7CgkJJHQtPlNldCgkYSk7CgkJJHQtPlN0cm9rZSgkdGhpcy0+aW1nLCR4dCwkeXQpOyAgCgkJaWYoICR0aGlzLT5zaG93X2FuZ2xlX3RpY2sgKQoJCSAgICAkdGhpcy0+aW1nLT5MaW5lKCR4MSwkeTEsJHgyLCR5Mik7ICAKCQkkYSArPSAkdGhpcy0+YW5nbGVfc3RlcDsKCSAgICB9Cgl9CiAgICB9CgogICAgZnVuY3Rpb24gU3Ryb2tlKCRwb3MpIHsKCgkkdGhpcy0+aW1nLT5TZXRMaW5lV2VpZ2h0KCR0aGlzLT53ZWlnaHQpOwoJJHRoaXMtPmltZy0+U2V0Q29sb3IoJHRoaXMtPmNvbG9yKTsJCQoJJHRoaXMtPmltZy0+U2V0Rm9udCgkdGhpcy0+Zm9udF9mYW1pbHksJHRoaXMtPmZvbnRfc3R5bGUsJHRoaXMtPmZvbnRfc2l6ZSk7CglpZiggISR0aGlzLT5oaWRlX2xpbmUgKSAKCSAgICAkdGhpcy0+aW1nLT5GaWxsZWRSZWN0YW5nbGUoJHRoaXMtPmltZy0+bGVmdF9tYXJnaW4sJHBvcywKCQkgICAgICR0aGlzLT5pbWctPndpZHRoLSR0aGlzLT5pbWctPnJpZ2h0X21hcmdpbiwkcG9zKyR0aGlzLT53ZWlnaHQtMSk7CgkkeT0kcG9zKyR0aGlzLT5pbWctPkdldEZvbnRIZWlnaHQoKSskdGhpcy0+dGl0bGVfbWFyZ2luKyR0aGlzLT50aXRsZS0+bWFyZ2luOwoJaWYoICR0aGlzLT50aXRsZV9hZGp1c3Q9PSJoaWdoIiApCgkgICAgJHRoaXMtPnRpdGxlLT5Qb3MoJHRoaXMtPmltZy0+d2lkdGgtJHRoaXMtPmltZy0+cmlnaHRfbWFyZ2luLCR5LCJyaWdodCIsInRvcCIpOwoJZWxzZWlmKCAkdGhpcy0+dGl0bGVfYWRqdXN0PT0ibWlkZGxlIiB8fCAkdGhpcy0+dGl0bGVfYWRqdXN0PT0iY2VudGVyIiApIAoJICAgICR0aGlzLT50aXRsZS0+UG9zKCgkdGhpcy0+aW1nLT53aWR0aC0kdGhpcy0+aW1nLT5sZWZ0X21hcmdpbi0KCQkJICAgICAgICR0aGlzLT5pbWctPnJpZ2h0X21hcmdpbikvMiskdGhpcy0+aW1nLT5sZWZ0X21hcmdpbiwKCQkJICAgICAgJHksImNlbnRlciIsInRvcCIpOwoJZWxzZWlmKCR0aGlzLT50aXRsZV9hZGp1c3Q9PSJsb3ciKQoJICAgICR0aGlzLT50aXRsZS0+UG9zKCR0aGlzLT5pbWctPmxlZnRfbWFyZ2luLCR5LCJsZWZ0IiwidG9wIik7CgllbHNlIHsJCgkgICAgSnBHcmFwaEVycm9yOjpSYWlzZUwoMTcwMDIsJHRoaXMtPnRpdGxlX2FkanVzdCk7Ci8vKCdVbmtub3duIGFsaWdubWVudCBzcGVjaWZpZWQgZm9yIFgtYXhpcyB0aXRsZS4gKCcuJHRoaXMtPnRpdGxlX2FkanVzdC4nKScpOwoJfQoKCQoJaWYgKCEkdGhpcy0+aGlkZV9sYWJlbHMpIHsKCSAgICAkdGhpcy0+U3Ryb2tlTGFiZWxzKCRwb3MsZmFsc2UpOwoJfQoJJHRoaXMtPmltZy0+U2V0Q29sb3IoJHRoaXMtPnJhZGl1c190aWNrX2NvbG9yKTsKCSR0aGlzLT5zY2FsZS0+dGlja3MtPlN0cm9rZSgkdGhpcy0+aW1nLCR0aGlzLT5zY2FsZSwkcG9zKTsKCgkvLwoJLy8gTWlycm9yIHRoZSBwb3NpdGlvbnMgZm9yIHRoZSBsZWZ0IHNpZGUgb2YgdGhlIHNjYWxlCiAgICAgICAgLy8KCSRtaWQgPSAyKigkdGhpcy0+aW1nLT5sZWZ0X21hcmdpbiskdGhpcy0+aW1nLT5wbG90d2lkdGgvMik7CgkkbiA9IGNvdW50KCR0aGlzLT5zY2FsZS0+dGlja3MtPnRpY2tzX3Bvcyk7CgkkaT0wOwoJd2hpbGUoICRpIDwgJG4gKSB7CgkgICAgJHRoaXMtPnNjYWxlLT50aWNrcy0+dGlja3NfcG9zWyRpXSA9IAoJCSRtaWQtJHRoaXMtPnNjYWxlLT50aWNrcy0+dGlja3NfcG9zWyRpXSA7CgkgICAgKyskaTsKCX0KCgkkbiA9IGNvdW50KCR0aGlzLT5zY2FsZS0+dGlja3MtPm1hal90aWNrc19wb3MpOwoJJGk9MDsKCXdoaWxlKCAkaSA8ICRuICkgewoJICAgICR0aGlzLT5zY2FsZS0+dGlja3MtPm1hal90aWNrc19wb3NbJGldID0gCgkJJG1pZC0kdGhpcy0+c2NhbGUtPnRpY2tzLT5tYWpfdGlja3NfcG9zWyRpXSA7CgkgICAgKyskaTsKCX0KCQoJJG4gPSBjb3VudCgkdGhpcy0+c2NhbGUtPnRpY2tzLT5tYWpfdGlja2xhYmVsc19wb3MpOwoJJGk9MTsKCXdoaWxlKCAkaSA8ICRuICkgewoJICAgICR0aGlzLT5zY2FsZS0+dGlja3MtPm1hal90aWNrbGFiZWxzX3Bvc1skaV0gPQoJCSRtaWQtJHRoaXMtPnNjYWxlLT50aWNrcy0+bWFqX3RpY2tsYWJlbHNfcG9zWyRpXSA7CgkgICAgKyskaTsKCX0KCgkvLyBEcmF3IHRoZSBsZWZ0IHNpZGUgb2YgdGhlIHNjYWxlCgkkbiA9IGNvdW50KCR0aGlzLT5zY2FsZS0+dGlja3MtPnRpY2tzX3Bvcyk7CgkkeXUgPSAkcG9zIC0gJHRoaXMtPnNjYWxlLT50aWNrcy0+ZGlyZWN0aW9uKiR0aGlzLT5zY2FsZS0+dGlja3MtPkdldE1pblRpY2tBYnNTaXplKCk7CgoKCS8vIE1pbm9yIHRpY2tzCglpZiggISAkdGhpcy0+c2NhbGUtPnRpY2tzLT5zdXByZXNzX21pbm9yX3RpY2ttYXJrcyApIHsKCSAgICAkaT0xOwoJICAgIHdoaWxlKCAkaSA8ICRuLzIgKSB7CgkJJHggPSByb3VuZCgkdGhpcy0+c2NhbGUtPnRpY2tzLT50aWNrc19wb3NbJGldKSA7CgkJJHRoaXMtPmltZy0+TGluZSgkeCwkcG9zLCR4LCR5dSk7CgkJKyskaTsKCSAgICB9Cgl9CgoJJG4gPSBjb3VudCgkdGhpcy0+c2NhbGUtPnRpY2tzLT5tYWpfdGlja3NfcG9zKTsKCSR5dSA9ICRwb3MgLSAkdGhpcy0+c2NhbGUtPnRpY2tzLT5kaXJlY3Rpb24qJHRoaXMtPnNjYWxlLT50aWNrcy0+R2V0TWFqVGlja0Fic1NpemUoKTsKCgoJLy8gTWFqb3IgdGlja3MKCWlmKCAhICR0aGlzLT5zY2FsZS0+dGlja3MtPnN1cHJlc3NfdGlja21hcmtzICkgewoJICAgICRpPTE7CgkgICAgd2hpbGUoICRpIDwgJG4vMiApIHsKCQkkeCA9IHJvdW5kKCR0aGlzLT5zY2FsZS0+dGlja3MtPm1hal90aWNrc19wb3NbJGldKSA7CgkJJHRoaXMtPmltZy0+TGluZSgkeCwkcG9zLCR4LCR5dSk7CgkJKyskaTsKCSAgICB9Cgl9CglpZiAoISR0aGlzLT5oaWRlX2xhYmVscykgewoJICAgICR0aGlzLT5TdHJva2VMYWJlbHMoJHBvcyxmYWxzZSk7Cgl9CgkkdGhpcy0+dGl0bGUtPlN0cm9rZSgkdGhpcy0+aW1nKTsJCiAgICB9Cn0KCmNsYXNzIFBvbGFyU2NhbGUgZXh0ZW5kcyBMaW5lYXJTY2FsZSB7CiAgICB2YXIgJGdyYXBoOwogICAgZnVuY3Rpb24gUG9sYXJTY2FsZSgkYU1heD0wLCYkZ3JhcGgpIHsKCXBhcmVudDo6TGluZWFyU2NhbGUoMCwkYU1heCwneCcpOwoJJHRoaXMtPmdyYXBoID0gJiRncmFwaDsKICAgIH0KCiAgICBmdW5jdGlvbiBfVHJhbnNsYXRlKCR2KSB7CglyZXR1cm4gcGFyZW50OjpUcmFuc2xhdGUoJHYpOwogICAgfQoKICAgIGZ1bmN0aW9uIFBUcmFuc2xhdGUoJGFBbmdsZSwkYVJhZCkgewoJCgkkbSA9ICR0aGlzLT5zY2FsZVsxXTsKCSR3ID0gJHRoaXMtPmdyYXBoLT5pbWctPnBsb3R3aWR0aC8yOwoJJGFSYWQgPSAkYVJhZC8kbSokdzsKCgkkeCA9IGNvcyggJGFBbmdsZS8xODAgKiBNX1BJICkgKiAkYVJhZDsKCSR5ID0gc2luKCAkYUFuZ2xlLzE4MCAqIE1fUEkgKSAqICRhUmFkOwoKCSR4ICs9ICR0aGlzLT5fVHJhbnNsYXRlKDApOwoKCWlmKCAkdGhpcy0+Z3JhcGgtPmlUeXBlID09IFBPTEFSXzM2MCApIHsKCSAgICAkeSA9ICgkdGhpcy0+Z3JhcGgtPmltZy0+dG9wX21hcmdpbiArICR0aGlzLT5ncmFwaC0+aW1nLT5wbG90aGVpZ2h0LzIpIC0gJHk7Cgl9CgllbHNlIHsKCSAgICAkeSA9ICgkdGhpcy0+Z3JhcGgtPmltZy0+dG9wX21hcmdpbiArICR0aGlzLT5ncmFwaC0+aW1nLT5wbG90aGVpZ2h0KSAtICR5OwoJfQoJcmV0dXJuIGFycmF5KCR4LCR5KTsKICAgIH0KfQoKY2xhc3MgUG9sYXJMb2dTY2FsZSBleHRlbmRzIExvZ1NjYWxlIHsKICAgIHZhciAkZ3JhcGg7CiAgICBmdW5jdGlvbiBQb2xhckxvZ1NjYWxlKCRhTWF4PTEsJiRncmFwaCkgewoJcGFyZW50OjpMb2dTY2FsZSgwLCRhTWF4LCd4Jyk7CgkkdGhpcy0+Z3JhcGggPSAmJGdyYXBoOwoJJHRoaXMtPnRpY2tzLT5TZXRMYWJlbExvZ1R5cGUoTE9HTEFCRUxTX01BR05JVFVERSk7CgogICAgfQoKICAgIGZ1bmN0aW9uIFBUcmFuc2xhdGUoJGFBbmdsZSwkYVJhZCkgewoKCWlmKCAkYVJhZCA9PSAwICkgCgkgICAgJGFSYWQgPSAxOwoJJGFSYWQgPSBsb2cxMCgkYVJhZCk7CgkkbSA9ICR0aGlzLT5zY2FsZVsxXTsKCSR3ID0gJHRoaXMtPmdyYXBoLT5pbWctPnBsb3R3aWR0aC8yOwoJJGFSYWQgPSAkYVJhZC8kbSokdzsKCgkkeCA9IGNvcyggJGFBbmdsZS8xODAgKiBNX1BJICkgKiAkYVJhZDsKCSR5ID0gc2luKCAkYUFuZ2xlLzE4MCAqIE1fUEkgKSAqICRhUmFkOwoKCSR4ICs9ICR3KyR0aGlzLT5ncmFwaC0+aW1nLT5sZWZ0X21hcmdpbjsvLyR0aGlzLT5fVHJhbnNsYXRlKDApOwoJaWYoICR0aGlzLT5ncmFwaC0+aVR5cGUgPT0gUE9MQVJfMzYwICkgewoJICAgICR5ID0gKCR0aGlzLT5ncmFwaC0+aW1nLT50b3BfbWFyZ2luICsgJHRoaXMtPmdyYXBoLT5pbWctPnBsb3RoZWlnaHQvMikgLSAkeTsKCX0KCWVsc2UgewoJICAgICR5ID0gKCR0aGlzLT5ncmFwaC0+aW1nLT50b3BfbWFyZ2luICsgJHRoaXMtPmdyYXBoLT5pbWctPnBsb3RoZWlnaHQpIC0gJHk7Cgl9CglyZXR1cm4gYXJyYXkoJHgsJHkpOwogICAgfQp9CgpjbGFzcyBQb2xhckdyYXBoIGV4dGVuZHMgR3JhcGggewogICAgdmFyICRzY2FsZTsKICAgIHZhciAkaVR5cGU9UE9MQVJfMzYwOwogICAgdmFyICRheGlzOwogICAgCiAgICBmdW5jdGlvbiBQb2xhckdyYXBoKCRhV2lkdGg9MzAwLCRhSGVpZ2h0PTIwMCwkYUNhY2hlZE5hbWU9IiIsJGFUaW1lT3V0PTAsJGFJbmxpbmU9dHJ1ZSkgewoJcGFyZW50OjpHcmFwaCgkYVdpZHRoLCRhSGVpZ2h0LCRhQ2FjaGVkTmFtZSwkYVRpbWVPdXQsJGFJbmxpbmUpIDsKCSR0aGlzLT5TZXREZW5zaXR5KFRJQ0tEX0RFTlNFKTsKCSR0aGlzLT5TZXRCb3goKTsKCSR0aGlzLT5TZXRNYXJnaW5Db2xvcignd2hpdGUnKTsKICAgIH0KCiAgICBmdW5jdGlvbiBTZXREZW5zaXR5KCRhRGVuc2UpIHsKCSR0aGlzLT5TZXRUaWNrRGVuc2l0eShUSUNLRF9OT1JNQUwsJGFEZW5zZSk7CiAgICB9CgogICAgZnVuY3Rpb24gU2V0OTBBbmRNYXJnaW4oJGxtPTAsJHJtPTAsJHRtPTAsJGJtPTApIHsKCSRhZGogPSAoJHRoaXMtPmltZy0+aGVpZ2h0IC0gJHRoaXMtPmltZy0+d2lkdGgpLzI7CgkkdGhpcy0+U2V0QW5nbGUoOTApOwoJJHRoaXMtPmltZy0+U2V0TWFyZ2luKCRsbS0kYWRqLCRybS0kYWRqLCR0bSskYWRqLCRibSskYWRqKTsKCSR0aGlzLT5pbWctPlNldENlbnRlcihmbG9vcigkdGhpcy0+aW1nLT53aWR0aC8yKSxmbG9vcigkdGhpcy0+aW1nLT5oZWlnaHQvMikpOwoJJHRoaXMtPmF4aXMtPlNldExhYmVsQWxpZ24oJ3JpZ2h0JywnY2VudGVyJyk7CgkvL0pwR3JhcGhFcnJvcjo6UmFpc2UoJ1NldDkwQW5kTWFyZ2luKCkgaXMgbm90IHN1cHBvcnRlZCBmb3IgcG9sYXIgZ3JhcGhzLicpOwogICAgfQoKICAgIGZ1bmN0aW9uIFNldFNjYWxlKCRhU2NhbGUsJHJtYXg9MCkgewoJaWYoICRhU2NhbGUgPT0gJ2xpbicgKSAKCSAgICAkdGhpcy0+c2NhbGUgPSBuZXcgUG9sYXJTY2FsZSgkcm1heCwkdGhpcyk7CgllbHNlaWYoICRhU2NhbGUgPT0gJ2xvZycgKSB7CgkgICAgJHRoaXMtPnNjYWxlID0gbmV3IFBvbGFyTG9nU2NhbGUoJHJtYXgsJHRoaXMpOwoJfQoJZWxzZSB7CgkgICAgSnBHcmFwaEVycm9yOjpSYWlzZUwoMTcwMDQpOy8vKCdVbmtub3duIHNjYWxlIHR5cGUgZm9yIHBvbGFyIGdyYXBoLiBNdXN0IGJlICJsaW4iIG9yICJsb2ciJyk7Cgl9CgoJJHRoaXMtPmF4aXMgPSBuZXcgUG9sYXJBeGlzKCR0aGlzLT5pbWcsJHRoaXMtPnNjYWxlKTsKCSR0aGlzLT5TZXRNYXJnaW4oNDAsNDAsNTAsNDApOwogICAgfQoKICAgIGZ1bmN0aW9uIFNldFR5cGUoJGFUeXBlKSB7CgkkdGhpcy0+aVR5cGUgPSAkYVR5cGU7CiAgICB9CgogICAgZnVuY3Rpb24gU2V0UGxvdFNpemUoJHcsJGgpIHsKCSR0aGlzLT5TZXRNYXJnaW4oKCR0aGlzLT5pbWctPndpZHRoLSR3KS8yLCgkdGhpcy0+aW1nLT53aWR0aC0kdykvMiwKCQkJICgkdGhpcy0+aW1nLT5oZWlnaHQtJGgpLzIsKCR0aGlzLT5pbWctPmhlaWdodC0kaCkvMik7CiAgICB9CgogICAgLy8gUHJpdmF0ZSBtZXRob2RzCiAgICBmdW5jdGlvbiBHZXRQbG90c01heCgpIHsKCSRuID0gY291bnQoJHRoaXMtPnBsb3RzKTsKCSRtID0gJHRoaXMtPnBsb3RzWzBdLT5NYXgoKTsKCSRpPTE7Cgl3aGlsZSgkaSA8ICRuKSB7CgkgICAgJG0gPSBtYXgoJHRoaXMtPnBsb3RzWyRpXS0+TWF4KCksJG0pOwoJICAgICsrJGk7Cgl9CglyZXR1cm4gJG07CiAgICB9CgogICAgZnVuY3Rpb24gU3Ryb2tlKCRhU3Ryb2tlRmlsZU5hbWU9IiIpIHsKCgkvLyBTdGFydCBieSBhZGp1c3RpbmcgdGhlIG1hcmdpbiBzbyB0aGF0IHBvdGVudGlhbCB0aXRsZXMgd2lsbCBmaXQuCgkkdGhpcy0+QWRqdXN0TWFyZ2luc0ZvclRpdGxlcygpOwoJICAgIAoJLy8gSWYgdGhlIGZpbGVuYW1lIGlzIHRoZSBwcmVkZWZpbmVkIHZhbHVlID0gJ19jc2ltX3NwZWNpYWxfJwoJLy8gd2UgYXNzdW1lIHRoYXQgdGhlIGNhbGwgdG8gc3Ryb2tlIG9ubHkgbmVlZHMgdG8gZG8gZW5vdWdoCgkvLyB0byBjb3JyZWN0bHkgZ2VuZXJhdGUgdGhlIENTSU0gbWFwcy4KCS8vIFdlIHVzZSB0aGlzIHZhcmlhYmxlIHRvIHNraXAgdGhpbmdzIHdlIGRvbid0IHN0cmljdGx5IG5lZWQKCS8vIHRvIGRvIHRvIGdlbmVyYXRlIHRoZSBpbWFnZSBtYXAgdG8gaW1wcm92ZSBwZXJmb3JtYW5jZQoJLy8gYSBiZXN0IHdlIGNhbi4gVGhlcmVmb3IgeW91IHdpbGwgc2VlIGEgbG90IG9mIHRlc3RzICEkX2NzaW0gaW4gdGhlCgkvLyBjb2RlIGJlbG93LgoJJF9jc2ltID0gKCRhU3Ryb2tlRmlsZU5hbWU9PT1fQ1NJTV9TUEVDSUFMRklMRSk7CgoJLy8gV2UgbmVlZCB0byBrbm93IGlmIHdlIGhhdmUgc3Ryb2tlZCB0aGUgcGxvdCBpbiB0aGUKCS8vIEdldENTSU1hcmVhcy4gT3RoZXJ3aXNlIHRoZSBDU0lNIGhhc24ndCBiZWVuIGdlbmVyYXRlZAoJLy8gYW5kIGluIHRoZSBjYXNlIG9mIEdldENTSU0gY2FsbGVkIGJlZm9yZSBzdHJva2UgdG8gZ2VuZXJhdGUKCS8vIENTSU0gd2l0aG91dCBzdG9yaW5nIGFuIGltYWdlIHRvIGRpc2sgR2V0Q1NJTSBtdXN0IGNhbGwgU3Ryb2tlLgoJJHRoaXMtPmlIYXNTdHJva2VkID0gdHJ1ZTsKCgkvL0NoZWNrIGlmIHdlIHNob3VsZCBhdXRvc2NhbGUgYXhpcwoJaWYoICEkdGhpcy0+c2NhbGUtPklzU3BlY2lmaWVkKCkgJiYgY291bnQoJHRoaXMtPnBsb3RzKT4wICkgewoJICAgICRtYXggPSAkdGhpcy0+R2V0UGxvdHNNYXgoKTsKCSAgICAkdDEgPSAkdGhpcy0+aW1nLT5wbG90d2lkdGg7CgkgICAgJHRoaXMtPmltZy0+cGxvdHdpZHRoIC89IDI7CgkgICAgJHQyID0gJHRoaXMtPmltZy0+bGVmdF9tYXJnaW47CgkgICAgJHRoaXMtPmltZy0+bGVmdF9tYXJnaW4gKz0gJHRoaXMtPmltZy0+cGxvdHdpZHRoKzE7CgkgICAgJHRoaXMtPnNjYWxlLT5BdXRvU2NhbGUoJHRoaXMtPmltZywwLCRtYXgsCgkJCQkgICAgICR0aGlzLT5pbWctPnBsb3R3aWR0aC8kdGhpcy0+eHRpY2tfZmFjdG9yLzIpOwoJICAgICR0aGlzLT5pbWctPnBsb3R3aWR0aCA9ICR0MTsKCSAgICAkdGhpcy0+aW1nLT5sZWZ0X21hcmdpbiA9ICR0MjsKCX0KCWVsc2UgewoJICAgIC8vIFRoZSB0aWNrIGNhbGN1bGF0aW9uIHdpbGwgdXNlIHRoZSB1c2VyIHN1cGxpZWQgbWluL21heCB2YWx1ZXMgdG8gZGV0ZXJtaW5lCgkgICAgLy8gdGhlIHRpY2tzLiBJZiBhdXRvX3RpY2tzIGlzIGZhbHNlIHRoZSBleGFjdCB1c2VyIHNwZWNpZmVkIG1pbiBhbmQgbWF4CgkgICAgLy8gdmFsdWVzIHdpbGwgYmUgdXNlZCBmb3IgdGhlIHNjYWxlLiAKCSAgICAvLyBJZiBhdXRvX3RpY2tzIGlzIHRydWUgdGhlbiB0aGUgc2NhbGUgbWlnaHQgYmUgc2xpZ2h0bHkgYWRqdXN0ZWQKCSAgICAvLyBzbyB0aGF0IHRoZSBtaW4gYW5kIG1heCB2YWx1ZXMgZmFsbHMgb24gYW4gZXZlbiBtYWpvciBzdGVwLgoJICAgIC8vJG1pbiA9IDA7CgkgICAgJG1heCA9ICR0aGlzLT5zY2FsZS0+c2NhbGVbMV07CgkgICAgJHQxID0gJHRoaXMtPmltZy0+cGxvdHdpZHRoOwoJICAgICR0aGlzLT5pbWctPnBsb3R3aWR0aCAvPSAyOwoJICAgICR0MiA9ICR0aGlzLT5pbWctPmxlZnRfbWFyZ2luOwoJICAgICR0aGlzLT5pbWctPmxlZnRfbWFyZ2luICs9ICR0aGlzLT5pbWctPnBsb3R3aWR0aCsxOwoJICAgICR0aGlzLT5zY2FsZS0+QXV0b1NjYWxlKCR0aGlzLT5pbWcsMCwkbWF4LAoJCQkJICAgICAkdGhpcy0+aW1nLT5wbG90d2lkdGgvJHRoaXMtPnh0aWNrX2ZhY3Rvci8yKTsKCSAgICAkdGhpcy0+aW1nLT5wbG90d2lkdGggPSAkdDE7CgkgICAgJHRoaXMtPmltZy0+bGVmdF9tYXJnaW4gPSAkdDI7Cgl9CgoJaWYoICR0aGlzLT5pVHlwZSA9PSAgUE9MQVJfMTgwICkgCgkgICAgJHBvcyA9ICR0aGlzLT5pbWctPmhlaWdodCAtICR0aGlzLT5pbWctPmJvdHRvbV9tYXJnaW47CgllbHNlCgkgICAgJHBvcyA9ICR0aGlzLT5pbWctPnBsb3RoZWlnaHQvMiArICR0aGlzLT5pbWctPnRvcF9tYXJnaW47CgoKCWlmKCAhJF9jc2ltICkgewoJICAgICR0aGlzLT5TdHJva2VQbG90QXJlYSgpOwoJfQoKCSR0aGlzLT5pRG9DbGlwcGluZyA9IHRydWU7CgoJaWYoICR0aGlzLT5pRG9DbGlwcGluZyApIHsKCSAgICAkb2xkaW1hZ2UgPSAkdGhpcy0+aW1nLT5DbG9uZUNhbnZhc0goKTsKCX0KCglpZiggISRfY3NpbSApIHsKCSAgICAkdGhpcy0+YXhpcy0+U3Ryb2tlR3JpZCgkcG9zKTsKCX0KCgkvLyBTdHJva2UgYWxsIHBsb3RzIGZvciBZMSBheGlzCglmb3IoJGk9MDsgJGkgPCBjb3VudCgkdGhpcy0+cGxvdHMpOyArKyRpKSB7CgkgICAgJHRoaXMtPnBsb3RzWyRpXS0+U3Ryb2tlKCR0aGlzLT5pbWcsJHRoaXMtPnNjYWxlKTsKCX0JCQkJCQkKCgoJaWYoICR0aGlzLT5pRG9DbGlwcGluZyApIHsKCSAgICAvLyBDbGlwcGluZyBvbmx5IHN1cHBvcnRzIGdyYXBocyBhdCAwIGFuZCA5MCBkZWdyZWVzCgkgICAgaWYoICR0aGlzLT5pbWctPmEgPT0gMCAgKSB7CgkJJHRoaXMtPmltZy0+Q29weUNhbnZhc0goJG9sZGltYWdlLCR0aGlzLT5pbWctPmltZywKCQkJCQkkdGhpcy0+aW1nLT5sZWZ0X21hcmdpbiwkdGhpcy0+aW1nLT50b3BfbWFyZ2luLAoJCQkJCSR0aGlzLT5pbWctPmxlZnRfbWFyZ2luLCR0aGlzLT5pbWctPnRvcF9tYXJnaW4sCgkJCQkJJHRoaXMtPmltZy0+cGxvdHdpZHRoKzEsJHRoaXMtPmltZy0+cGxvdGhlaWdodCsxKTsKCSAgICB9CgkgICAgZWxzZWlmKCAkdGhpcy0+aW1nLT5hID09IDkwICkgewoJCSRhZGogPSByb3VuZCgoJHRoaXMtPmltZy0+aGVpZ2h0IC0gJHRoaXMtPmltZy0+d2lkdGgpLzIpOwoJCSR0aGlzLT5pbWctPkNvcHlDYW52YXNIKCRvbGRpbWFnZSwkdGhpcy0+aW1nLT5pbWcsCgkJCQkJJHRoaXMtPmltZy0+Ym90dG9tX21hcmdpbi0kYWRqLCR0aGlzLT5pbWctPmxlZnRfbWFyZ2luKyRhZGosCgkJCQkJJHRoaXMtPmltZy0+Ym90dG9tX21hcmdpbi0kYWRqLCR0aGlzLT5pbWctPmxlZnRfbWFyZ2luKyRhZGosCgkJCQkJJHRoaXMtPmltZy0+cGxvdGhlaWdodCwkdGhpcy0+aW1nLT5wbG90d2lkdGgpOwoJICAgIH0KCSAgICAkdGhpcy0+aW1nLT5EZXN0cm95KCk7CgkgICAgJHRoaXMtPmltZy0+U2V0Q2FudmFzSCgkb2xkaW1hZ2UpOwoJfQoKCWlmKCAhJF9jc2ltICkgewoJICAgICR0aGlzLT5heGlzLT5TdHJva2UoJHBvcyk7CgkgICAgJHRoaXMtPmF4aXMtPlN0cm9rZUFuZ2xlTGFiZWxzKCRwb3MsJHRoaXMtPmlUeXBlKTsKCX0KCglpZiggISRfY3NpbSApIHsKCSAgICAkdGhpcy0+U3Ryb2tlUGxvdEJveCgpOwoJICAgICR0aGlzLT5mb290ZXItPlN0cm9rZSgkdGhpcy0+aW1nKTsKCgkgICAgLy8gVGhlIHRpdGxlcyBhbmQgbGVnZW5kcyBuZXZlciBnZXRzIHJvdGF0ZWQgc28gbWFrZSBzdXJlCgkgICAgLy8gdGhhdCB0aGUgYW5nbGUgaXMgMCBiZWZvcmUgc3Ryb2tpbmcgdGhlbQkJCQkKCSAgICAkYWEgPSAkdGhpcy0+aW1nLT5TZXRBbmdsZSgwKTsKCSAgICAkdGhpcy0+U3Ryb2tlVGl0bGVzKCk7Cgl9CgoJZm9yKCRpPTA7ICRpIDwgY291bnQoJHRoaXMtPnBsb3RzKSA7ICsrJGkgKSB7CgkgICAgJHRoaXMtPnBsb3RzWyRpXS0+TGVnZW5kKCR0aGlzKTsKCX0KCgkkdGhpcy0+bGVnZW5kLT5TdHJva2UoJHRoaXMtPmltZyk7CQkKCglpZiggISRfY3NpbSApIHsKCgkgICAgJHRoaXMtPlN0cm9rZVRleHRzKCk7CQoJICAgICR0aGlzLT5pbWctPlNldEFuZ2xlKCRhYSk7CQoJCQkKCSAgICAvLyBEcmF3IGFuIG91dGxpbmUgYXJvdW5kIHRoZSBpbWFnZSBtYXAJCgkgICAgaWYoX0pQR19ERUJVRykKCQkkdGhpcy0+RGlzcGxheUNsaWVudFNpZGVhSW1hZ2VNYXBBcmVhcygpOwkJCgkgICAgCgkgICAgLy8gQWRqdXN0IHRoZSBhcHBlYXJhbmNlIG9mIHRoZSBpbWFnZQoJICAgICR0aGlzLT5BZGp1c3RTYXR1cmF0aW9uQnJpZ2h0bmVzc0NvbnRyYXN0KCk7CgoJICAgIC8vIElmIHRoZSBmaWxlbmFtZSBpcyBnaXZlbiBhcyB0aGUgc3BlY2lhbCAiX19oYW5kbGUiCgkgICAgLy8gdGhlbiB0aGUgaW1hZ2UgaGFuZGxlciBpcyByZXR1cm5lZCBhbmQgdGhlIGltYWdlIGlzIE5PVAoJICAgIC8vIHN0cmVhbWVkIGJhY2sKCSAgICBpZiggJGFTdHJva2VGaWxlTmFtZSA9PSBfSU1HX0hBTkRMRVIgKSB7CgkJcmV0dXJuICR0aGlzLT5pbWctPmltZzsKCSAgICB9CgkgICAgZWxzZSB7CgkJLy8gRmluYWxseSBzdHJlYW0gdGhlIGdlbmVyYXRlZCBwaWN0dXJlCQkJCQkKCQkkdGhpcy0+Y2FjaGUtPlB1dEFuZFN0cmVhbSgkdGhpcy0+aW1nLCR0aGlzLT5jYWNoZV9uYW1lLCR0aGlzLT5pbmxpbmUsCgkJCQkJICAgJGFTdHJva2VGaWxlTmFtZSk7CQkKCSAgICB9Cgl9CiAgICB9Cn0KCgoKPz4K