IyEvdXNyL2Jpbi9wZXJsIC13VAojIC0qLSBNb2RlOiBwZXJsOyBpbmRlbnQtdGFicy1tb2RlOiBuaWwgLSotCgojCiMgVGhpcyBpcyBhIHNjcmlwdCB0byBlZGl0IHRoZSB0YXJnZXQgbWlsZXN0b25lcy4gSXQgaXMgbGFyZ2VseSBhIGNvcHkgb2YKIyB0aGUgZWRpdHZlcnNpb25zLmNnaSBzY3JpcHQsIHNpbmNlIHRoZSB0d28gZmllbGRzIHdlcmUgc2V0IHVwIGluIGEKIyB2ZXJ5IHNpbWlsYXIgZmFzaGlvbi4KIwojIChiYXNpY2FsbHkgcmVwbGFjZSBlYWNoIG9jY3VyYW5jZSBvZiAnbWlsZXN0b25lJyB3aXRoICd2ZXJzaW9uJywgYW5kCiMgeW91J2xsIGhhdmUgdGhlIG9yaWdpbmFsIHNjcmlwdCkKIwojIE1hdHQgTWFzc29uIDxtYXR0aGV3QHplcm9rbm93bGVkZ2UuY29tPgojCiMgQ29udHJpYnV0b3JzIDogR2F2aW4gU2hlbGxleSA8YnVnemlsbGFAY2hpbXB5Y2hvbXB5Lm9yZz4KIyAgICAgICAgICAgICAgICBGculk6XJpYyBCdWNsaW4gPExwU29saXRAZ21haWwuY29tPgojCgoKdXNlIHN0cmljdDsKdXNlIGxpYiAiLiI7CgpyZXF1aXJlICJDR0kucGwiOwpyZXF1aXJlICJnbG9iYWxzLnBsIjsKCnVzZSBCdWd6aWxsYTo6Q29uc3RhbnRzOwp1c2UgQnVnemlsbGE6OkNvbmZpZyBxdyg6REVGQVVMVCAkZGF0YWRpcik7CnVzZSBCdWd6aWxsYTo6VXNlcjsKCnVzZSB2YXJzIHF3KCR0ZW1wbGF0ZSAkdmFycyk7CgpteSAkY2dpID0gQnVnemlsbGEtPmNnaTsKCiMgVGVzdFByb2R1Y3Q6ICBqdXN0IHJldHVybnMgaWYgdGhlIHNwZWNpZmllZCBwcm9kdWN0IGRvZXMgZXhpc3RzCiMgQ2hlY2tQcm9kdWN0OiBzYW1lIGNoZWNrLCBvcHRpb25hbGx5ICBlbWl0IGFuIGVycm9yIHRleHQKIyBUZXN0TWlsZXN0b25lOiAganVzdCByZXR1cm5zIGlmIHRoZSBzcGVjaWZpZWQgcHJvZHVjdC92ZXJzaW9uIGNvbWJpbmF0aW9uIGV4aXN0cwojIENoZWNrTWlsZXN0b25lOiBzYW1lIGNoZWNrLCBvcHRpb25hbGx5IGVtaXQgYW4gZXJyb3IgdGV4dAoKc3ViIFRlc3RQcm9kdWN0ICgkKQp7CiAgICBteSAkcHJvZHVjdCA9IHNoaWZ0OwoKICAgIHRyaWNrX3RhaW50KCRwcm9kdWN0KTsKCiAgICAjIGRvZXMgdGhlIHByb2R1Y3QgZXhpc3Q/CiAgICBteSAkZGJoID0gQnVnemlsbGEtPmRiaDsKICAgIG15ICRzdGggPSAkZGJoLT5wcmVwYXJlX2NhY2hlZCgiU0VMRUNUIG5hbWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlJPTSBwcm9kdWN0cwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSEVSRSBuYW1lID0gPyIpOwogICAgJHN0aC0+ZXhlY3V0ZSgkcHJvZHVjdCk7CgogICAgbXkgKCRyb3cpID0gJHN0aC0+ZmV0Y2hyb3dfYXJyYXk7CgogICAgJHN0aC0+ZmluaXNoOwoKICAgIHJldHVybiAkcm93Owp9CgpzdWIgQ2hlY2tQcm9kdWN0ICgkKQp7CiAgICBteSAkcHJvZHVjdCA9IHNoaWZ0OwoKICAgICMgZG8gd2UgaGF2ZSBhIHByb2R1Y3Q/CiAgICB1bmxlc3MgKCRwcm9kdWN0KSB7CiAgICAgICAgVGhyb3dVc2VyRXJyb3IoJ3Byb2R1Y3Rfbm90X3NwZWNpZmllZCcpOyAgICAKICAgIH0KCiAgICAjIERvZXMgaXQgZXhpc3QgaW4gdGhlIERCPwogICAgdW5sZXNzIChUZXN0UHJvZHVjdCAkcHJvZHVjdCkgewogICAgICAgIFRocm93VXNlckVycm9yKCdwcm9kdWN0X2RvZXNudF9leGlzdCcsCiAgICAgICAgICAgICAgICAgICAgICAgeydwcm9kdWN0JyA9PiAkcHJvZHVjdH0pOwogICAgfQp9CgpzdWIgVGVzdE1pbGVzdG9uZSAoJCQpCnsKICAgIG15ICgkcHJvZHVjdCwgJG1pbGVzdG9uZSkgPSBAXzsKCiAgICBteSAkZGJoID0gQnVnemlsbGEtPmRiaDsKCiAgICAjIGRvZXMgdGhlIHByb2R1Y3QgZXhpc3Q/CiAgICBteSAkc3RoID0gJGRiaC0+cHJlcGFyZV9jYWNoZWQoIgogICAgICAgICAgICAgU0VMRUNUIHByb2R1Y3RzLm5hbWUsIHZhbHVlCiAgICAgICAgICAgICBGUk9NIG1pbGVzdG9uZXMKICAgICAgICAgICAgIElOTkVSIEpPSU4gcHJvZHVjdHMKICAgICAgICAgICAgICAgIE9OIG1pbGVzdG9uZXMucHJvZHVjdF9pZCA9IHByb2R1Y3RzLmlkCiAgICAgICAgICAgICBXSEVSRSBwcm9kdWN0cy5uYW1lID0gPwogICAgICAgICAgICAgICBBTkQgdmFsdWUgPSA/Iik7CgogICAgdHJpY2tfdGFpbnQoJHByb2R1Y3QpOwogICAgdHJpY2tfdGFpbnQoJG1pbGVzdG9uZSk7CgogICAgJHN0aC0+ZXhlY3V0ZSgkcHJvZHVjdCwgJG1pbGVzdG9uZSk7CgogICAgbXkgKCRkYl9taWxlc3RvbmUpID0gJHN0aC0+ZmV0Y2hyb3dfYXJyYXkoKTsKCiAgICAkc3RoLT5maW5pc2goKTsKCiAgICByZXR1cm4gJGRiX21pbGVzdG9uZTsKfQoKc3ViIENoZWNrTWlsZXN0b25lICgkJCkKewogICAgbXkgKCRwcm9kdWN0LCAkbWlsZXN0b25lKSA9IEBfOwoKICAgICMgZG8gd2UgaGF2ZSB0aGUgbWlsZXN0b25lIGFuZCBwcm9kdWN0IGNvbWJpbmF0aW9uPwogICAgdW5sZXNzICgkbWlsZXN0b25lKSB7CiAgICAgICAgVGhyb3dVc2VyRXJyb3IoJ21pbGVzdG9uZV9ub3Rfc3BlY2lmaWVkJyk7CiAgICB9CgogICAgQ2hlY2tQcm9kdWN0KCRwcm9kdWN0KTsKCiAgICB1bmxlc3MgKFRlc3RNaWxlc3RvbmUgJHByb2R1Y3QsICRtaWxlc3RvbmUpIHsKICAgICAgICBUaHJvd1VzZXJFcnJvcignbWlsZXN0b25lX25vdF92YWxpZCcsCiAgICAgICAgICAgICAgICAgICAgICAgeydwcm9kdWN0JyA9PiAkcHJvZHVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgJ21pbGVzdG9uZScgPT4gJG1pbGVzdG9uZX0pOwogICAgfQp9CgpzdWIgQ2hlY2tTb3J0a2V5ICgkJCkKewogICAgbXkgKCRtaWxlc3RvbmUsICRzb3J0a2V5KSA9IEBfOwogICAgIyBLZWVwIGEgY29weSBpbiBjYXNlIGRldGFpbnRfc2lnbmVkKCkgY2xlYXJzIHRoZSBzb3J0a2V5CiAgICBteSAkc3RvcmVkX3NvcnRrZXkgPSAkc29ydGtleTsKCiAgICBpZiAoIWRldGFpbnRfc2lnbmVkKCRzb3J0a2V5KSB8fCAkc29ydGtleSA8IC0zMjc2OCB8fCAkc29ydGtleSA+IDMyNzY3KSB7CiAgICAgICAgVGhyb3dVc2VyRXJyb3IoJ21pbGVzdG9uZV9zb3J0a2V5X2ludmFsaWQnLAogICAgICAgICAgICAgICAgICAgICAgIHsnbmFtZScgPT4gJG1pbGVzdG9uZSwKICAgICAgICAgICAgICAgICAgICAgICAgJ3NvcnRrZXknID0+ICRzdG9yZWRfc29ydGtleX0pOwogICAgfQoKICAgIHJldHVybiAkc29ydGtleTsKfQoKIwojIFByZWxpbWluYXJ5IGNoZWNrczoKIwoKbXkgJHVzZXIgPSBCdWd6aWxsYS0+bG9naW4oTE9HSU5fUkVRVUlSRUQpOwpteSAkd2hvaWQgPSAkdXNlci0+aWQ7CgpwcmludCBCdWd6aWxsYS0+Y2dpLT5oZWFkZXIoKTsKClVzZXJJbkdyb3VwKCJlZGl0Y29tcG9uZW50cyIpCiAgfHwgVGhyb3dVc2VyRXJyb3IoImF1dGhfZmFpbHVyZSIsIHtncm91cCAgPT4gImVkaXRjb21wb25lbnRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbiA9PiAiZWRpdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QgPT4gIm1pbGVzdG9uZXMifSk7CgojCiMgb2Z0ZW4gdXNlZCB2YXJpYWJsZXMKIwpteSAkcHJvZHVjdCA9IHRyaW0oJGNnaS0+cGFyYW0oJ3Byb2R1Y3QnKSAgICAgfHwgJycpOwpteSAkbWlsZXN0b25lID0gdHJpbSgkY2dpLT5wYXJhbSgnbWlsZXN0b25lJykgfHwgJycpOwpteSAkc29ydGtleSA9IHRyaW0oJGNnaS0+cGFyYW0oJ3NvcnRrZXknKSAgICAgfHwgJzAnKTsKbXkgJGFjdGlvbiAgPSB0cmltKCRjZ2ktPnBhcmFtKCdhY3Rpb24nKSAgICAgIHx8ICcnKTsKCiMKIyBwcm9kdWN0ID0gJycgLT4gU2hvdyBuaWNlIGxpc3Qgb2YgbWlsZXN0b25lcwojCgp1bmxlc3MgKCRwcm9kdWN0KSB7CgogICAgbXkgQHByb2R1Y3RzID0gKCk7CgogICAgbXkgJGRiaCA9IEJ1Z3ppbGxhLT5kYmg7CgogICAgbXkgJHN0aCA9ICRkYmgtPnByZXBhcmVfY2FjaGVkKCdTRUxFQ1QgcHJvZHVjdHMubmFtZSwgcHJvZHVjdHMuZGVzY3JpcHRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlJPTSBwcm9kdWN0cyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT1JERVIgQlkgcHJvZHVjdHMubmFtZScpOwoKICAgIG15ICRkYXRhID0gJGRiaC0+c2VsZWN0YWxsX2FycmF5cmVmKCRzdGgpOwoKICAgIGZvcmVhY2ggbXkgJGFyZWYgKEAkZGF0YSkgewoKICAgICAgICBteSAkcHJvZCA9IHt9OwoKICAgICAgICBteSAoJG5hbWUsICRkZXNjcmlwdGlvbikgPSBAJGFyZWY7CgogICAgICAgICRwcm9kLT57J25hbWUnfSA9ICRuYW1lOwogICAgICAgICRwcm9kLT57J2Rlc2NyaXB0aW9uJ30gPSAkZGVzY3JpcHRpb247CgogICAgICAgIHB1c2goQHByb2R1Y3RzLCAkcHJvZCk7CiAgICB9CgogICAgJHZhcnMtPnsncHJvZHVjdHMnfSA9IFxAcHJvZHVjdHM7CiAgICAkdGVtcGxhdGUtPnByb2Nlc3MoImFkbWluL21pbGVzdG9uZXMvc2VsZWN0LXByb2R1Y3QuaHRtbC50bXBsIiwKICAgICAgICAgICAgICAgICAgICAgICAkdmFycykKICAgICAgfHwgVGhyb3dUZW1wbGF0ZUVycm9yKCR0ZW1wbGF0ZS0+ZXJyb3IoKSk7CgogICAgZXhpdDsKfQoKCgojCiMgYWN0aW9uPScnIC0+IFNob3cgbmljZSBsaXN0IG9mIG1pbGVzdG9uZXMKIwoKdW5sZXNzICgkYWN0aW9uKSB7CgogICAgQ2hlY2tQcm9kdWN0KCRwcm9kdWN0KTsKICAgIG15ICRwcm9kdWN0X2lkID0gZ2V0X3Byb2R1Y3RfaWQoJHByb2R1Y3QpOwogICAgbXkgQG1pbGVzdG9uZXMgPSAoKTsKCiAgICBteSAkZGJoID0gQnVnemlsbGEtPmRiaDsKCiAgICBteSAkc3RoID0gJGRiaC0+cHJlcGFyZV9jYWNoZWQoJ1NFTEVDVCB2YWx1ZSwgc29ydGtleQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGUk9NIG1pbGVzdG9uZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0hFUkUgcHJvZHVjdF9pZCA9ID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT1JERVIgQlkgc29ydGtleSwgdmFsdWUnKTsKCiAgICBteSAkZGF0YSA9ICRkYmgtPnNlbGVjdGFsbF9hcnJheXJlZigkc3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5kZWYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkcHJvZHVjdF9pZCk7CgogICAgZm9yZWFjaCBteSAkYXJlZiAoQCRkYXRhKSB7CgogICAgICAgIG15ICRtaWxlc3RvbmUgPSB7fTsKICAgICAgICBteSAoJG5hbWUsICRzb3J0a2V5KSA9IEAkYXJlZjsKCiAgICAgICAgJG1pbGVzdG9uZS0+eyduYW1lJ30gPSAkbmFtZTsKICAgICAgICAkbWlsZXN0b25lLT57J3NvcnRrZXknfSA9ICRzb3J0a2V5OwoKICAgICAgICBwdXNoKEBtaWxlc3RvbmVzLCAkbWlsZXN0b25lKTsKICAgIH0KCiAgICAkdmFycy0+eydwcm9kdWN0J30gPSAkcHJvZHVjdDsKICAgICR2YXJzLT57J21pbGVzdG9uZXMnfSA9IFxAbWlsZXN0b25lczsKICAgICR0ZW1wbGF0ZS0+cHJvY2VzcygiYWRtaW4vbWlsZXN0b25lcy9saXN0Lmh0bWwudG1wbCIsCiAgICAgICAgICAgICAgICAgICAgICAgJHZhcnMpCiAgICAgIHx8IFRocm93VGVtcGxhdGVFcnJvcigkdGVtcGxhdGUtPmVycm9yKCkpOwoKICAgIGV4aXQ7Cn0KCgoKCiMKIyBhY3Rpb249J2FkZCcgLT4gcHJlc2VudCBmb3JtIGZvciBwYXJhbWV0ZXJzIGZvciBuZXcgbWlsZXN0b25lCiMKIyAobmV4dCBhY3Rpb24gd2lsbCBiZSAnbmV3JykKIwoKaWYgKCRhY3Rpb24gZXEgJ2FkZCcpIHsKCiAgICBDaGVja1Byb2R1Y3QoJHByb2R1Y3QpOwogICAgbXkgJHByb2R1Y3RfaWQgPSBnZXRfcHJvZHVjdF9pZCgkcHJvZHVjdCk7CgogICAgJHZhcnMtPnsncHJvZHVjdCd9ID0gJHByb2R1Y3Q7CiAgICAkdGVtcGxhdGUtPnByb2Nlc3MoImFkbWluL21pbGVzdG9uZXMvY3JlYXRlLmh0bWwudG1wbCIsCiAgICAgICAgICAgICAgICAgICAgICAgJHZhcnMpCiAgICAgIHx8IFRocm93VGVtcGxhdGVFcnJvcigkdGVtcGxhdGUtPmVycm9yKCkpOwoKICAgIGV4aXQ7Cn0KCgoKIwojIGFjdGlvbj0nbmV3JyAtPiBhZGQgbWlsZXN0b25lIGVudGVyZWQgaW4gdGhlICdhY3Rpb249YWRkJyBzY3JlZW4KIwoKaWYgKCRhY3Rpb24gZXEgJ25ldycpIHsKCiAgICBDaGVja1Byb2R1Y3QoJHByb2R1Y3QpOwogICAgbXkgJHByb2R1Y3RfaWQgPSBnZXRfcHJvZHVjdF9pZCgkcHJvZHVjdCk7CgogICAgIyBDbGVhbnVwcyBhbmQgdmFsaWRpZHkgY2hlY2tzCiAgICB1bmxlc3MgKCRtaWxlc3RvbmUpIHsKICAgICAgICBUaHJvd1VzZXJFcnJvcignbWlsZXN0b25lX2JsYW5rX25hbWUnLAogICAgICAgICAgICAgICAgICAgICAgIHsnbmFtZScgPT4gJG1pbGVzdG9uZX0pOwogICAgfQoKICAgIGlmIChsZW5ndGgoJG1pbGVzdG9uZSkgPiAyMCkgewogICAgICAgIFRocm93VXNlckVycm9yKCdtaWxlc3RvbmVfbmFtZV90b29fbG9uZycsCiAgICAgICAgICAgICAgICAgICAgICAgeyduYW1lJyA9PiAkbWlsZXN0b25lfSk7CiAgICB9CgogICAgJHNvcnRrZXkgPSBDaGVja1NvcnRrZXkoJG1pbGVzdG9uZSwgJHNvcnRrZXkpOwoKICAgIGlmIChUZXN0TWlsZXN0b25lKCRwcm9kdWN0LCAkbWlsZXN0b25lKSkgewogICAgICAgIFRocm93VXNlckVycm9yKCdtaWxlc3RvbmVfYWxyZWFkeV9leGlzdHMnLAogICAgICAgICAgICAgICAgICAgICAgIHsnbmFtZScgPT4gJG1pbGVzdG9uZSwKICAgICAgICAgICAgICAgICAgICAgICAgJ3Byb2R1Y3QnID0+ICRwcm9kdWN0fSk7CiAgICB9CgogICAgIyBBZGQgdGhlIG5ldyBtaWxlc3RvbmUKICAgIG15ICRkYmggPSBCdWd6aWxsYS0+ZGJoOwogICAgdHJpY2tfdGFpbnQoJG1pbGVzdG9uZSk7CiAgICAkZGJoLT5kbygnSU5TRVJUIElOVE8gbWlsZXN0b25lcyAoIHZhbHVlLCBwcm9kdWN0X2lkLCBzb3J0a2V5ICkKICAgICAgICAgICAgICBWQUxVRVMgKCA/LCA/LCA/ICknLAogICAgICAgICAgICAgdW5kZWYsCiAgICAgICAgICAgICAkbWlsZXN0b25lLAogICAgICAgICAgICAgJHByb2R1Y3RfaWQsCiAgICAgICAgICAgICAkc29ydGtleSk7CgogICAgIyBNYWtlIHZlcnNpb25jYWNoZSBmbHVzaAogICAgdW5saW5rICIkZGF0YWRpci92ZXJzaW9uY2FjaGUiOwoKICAgICR2YXJzLT57J25hbWUnfSA9ICRtaWxlc3RvbmU7CiAgICAkdmFycy0+eydwcm9kdWN0J30gPSAkcHJvZHVjdDsKICAgICR0ZW1wbGF0ZS0+cHJvY2VzcygiYWRtaW4vbWlsZXN0b25lcy9jcmVhdGVkLmh0bWwudG1wbCIsCiAgICAgICAgICAgICAgICAgICAgICAgJHZhcnMpCiAgICAgIHx8IFRocm93VGVtcGxhdGVFcnJvcigkdGVtcGxhdGUtPmVycm9yKCkpOwoKICAgIGV4aXQ7Cn0KCgoKCiMKIyBhY3Rpb249J2RlbCcgLT4gYXNrIGlmIHVzZXIgcmVhbGx5IHdhbnRzIHRvIGRlbGV0ZQojCiMgKG5leHQgYWN0aW9uIHdvdWxkIGJlICdkZWxldGUnKQojCgppZiAoJGFjdGlvbiBlcSAnZGVsJykgewogICAgQ2hlY2tNaWxlc3RvbmUoJHByb2R1Y3QsICRtaWxlc3RvbmUpOwogICAgbXkgJHByb2R1Y3RfaWQgPSBnZXRfcHJvZHVjdF9pZCgkcHJvZHVjdCk7CiAgICBteSAkZGJoID0gQnVnemlsbGEtPmRiaDsKCiAgICAkdmFycy0+eydkZWZhdWx0X21pbGVzdG9uZSd9ID0KICAgICAgJGRiaC0+c2VsZWN0cm93X2FycmF5KCdTRUxFQ1QgZGVmYXVsdG1pbGVzdG9uZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZST00gcHJvZHVjdHMgV0hFUkUgaWQgPSA/JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmRlZiwgJHByb2R1Y3RfaWQpOwoKICAgIHRyaWNrX3RhaW50KCRtaWxlc3RvbmUpOwogICAgJHZhcnMtPnsnbmFtZSd9ID0gJG1pbGVzdG9uZTsKICAgICR2YXJzLT57J3Byb2R1Y3QnfSA9ICRwcm9kdWN0OwoKICAgICMgVGhlIGRlZmF1bHQgbWlsZXN0b25lIGNhbm5vdCBiZSBkZWxldGVkLgogICAgaWYgKCR2YXJzLT57J2RlZmF1bHRfbWlsZXN0b25lJ30gZXEgJG1pbGVzdG9uZSkgewogICAgICAgIFRocm93VXNlckVycm9yKCJtaWxlc3RvbmVfaXNfZGVmYXVsdCIsICR2YXJzKTsKICAgIH0KCiAgICAkdmFycy0+eydidWdfY291bnQnfSA9CiAgICAgICRkYmgtPnNlbGVjdHJvd19hcnJheSgiU0VMRUNUIENPVU5UKGJ1Z19pZCkgRlJPTSBidWdzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0hFUkUgcHJvZHVjdF9pZCA9ID8gQU5EIHRhcmdldF9taWxlc3RvbmUgPSA/IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmRlZiwgKCRwcm9kdWN0X2lkLCAkbWlsZXN0b25lKSkgfHwgMDsKCiAgICAkdGVtcGxhdGUtPnByb2Nlc3MoImFkbWluL21pbGVzdG9uZXMvY29uZmlybS1kZWxldGUuaHRtbC50bXBsIiwgJHZhcnMpCiAgICAgIHx8IFRocm93VGVtcGxhdGVFcnJvcigkdGVtcGxhdGUtPmVycm9yKCkpOwogICAgZXhpdDsKfQoKCgojCiMgYWN0aW9uPSdkZWxldGUnIC0+IHJlYWxseSBkZWxldGUgdGhlIG1pbGVzdG9uZQojCgppZiAoJGFjdGlvbiBlcSAnZGVsZXRlJykgewogICAgQ2hlY2tNaWxlc3RvbmUoJHByb2R1Y3QsICRtaWxlc3RvbmUpOwogICAgbXkgJHByb2R1Y3RfaWQgPSBnZXRfcHJvZHVjdF9pZCgkcHJvZHVjdCk7CiAgICBteSAkZGJoID0gQnVnemlsbGEtPmRiaDsKCiAgICBteSAkZGVmYXVsdF9taWxlc3RvbmUgPQogICAgICAkZGJoLT5zZWxlY3Ryb3dfYXJyYXkoIlNFTEVDVCBkZWZhdWx0bWlsZXN0b25lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlJPTSBwcm9kdWN0cyBXSEVSRSBpZCA9ID8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuZGVmLCAkcHJvZHVjdF9pZCk7CgogICAgdHJpY2tfdGFpbnQoJG1pbGVzdG9uZSk7CiAgICAkdmFycy0+eyduYW1lJ30gPSAkbWlsZXN0b25lOwogICAgJHZhcnMtPnsncHJvZHVjdCd9ID0gJHByb2R1Y3Q7CgogICAgIyBUaGUgZGVmYXVsdCBtaWxlc3RvbmUgY2Fubm90IGJlIGRlbGV0ZWQuCiAgICBpZiAoJG1pbGVzdG9uZSBlcSAkZGVmYXVsdF9taWxlc3RvbmUpIHsKICAgICAgICBUaHJvd1VzZXJFcnJvcigibWlsZXN0b25lX2lzX2RlZmF1bHQiLCAkdmFycyk7CiAgICB9CgogICAgIyBXZSBkb24ndCB3YW50IHRvIGRlbGV0ZSBidWdzIHdoZW4gZGVsZXRpbmcgYSBtaWxlc3RvbmUuCiAgICAjIEJ1Z3MgY29uY2VybmVkIGFyZSByZWFzc2lnbmVkIHRvIHRoZSBkZWZhdWx0IG1pbGVzdG9uZS4KICAgIG15ICRidWdfaWRzID0KICAgICAgJGRiaC0+c2VsZWN0Y29sX2FycmF5cmVmKCJTRUxFQ1QgYnVnX2lkIEZST00gYnVncwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdIRVJFIHByb2R1Y3RfaWQgPSA/IEFORCB0YXJnZXRfbWlsZXN0b25lID0gPyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5kZWYsICgkcHJvZHVjdF9pZCwgJG1pbGVzdG9uZSkpOwoKICAgIG15ICRuYl9idWdzID0gc2NhbGFyKEAkYnVnX2lkcyk7CiAgICBpZiAoJG5iX2J1Z3MpIHsKICAgICAgICBteSAkdGltZXN0YW1wID0gJGRiaC0+c2VsZWN0cm93X2FycmF5KCJTRUxFQ1QgTk9XKCkiKTsKICAgICAgICBmb3JlYWNoIG15ICRidWdfaWQgKEAkYnVnX2lkcykgewogICAgICAgICAgICAkZGJoLT5kbygiVVBEQVRFIGJ1Z3MgU0VUIHRhcmdldF9taWxlc3RvbmUgPSA/LAogICAgICAgICAgICAgICAgICAgICAgZGVsdGFfdHMgPSA/IFdIRVJFIGJ1Z19pZCA9ID8iLAogICAgICAgICAgICAgICAgICAgICAgdW5kZWYsICgkZGVmYXVsdF9taWxlc3RvbmUsICR0aW1lc3RhbXAsICRidWdfaWQpKTsKICAgICAgICAgICAgIyBXZSBoYXZlIHRvIHVwZGF0ZSB0aGUgJ2J1Z3NfYWN0aXZpdHknIHRhYmxlIHRvby4KICAgICAgICAgICAgTG9nQWN0aXZpdHlFbnRyeSgkYnVnX2lkLCAndGFyZ2V0X21pbGVzdG9uZScsICRtaWxlc3RvbmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGRlZmF1bHRfbWlsZXN0b25lLCAkd2hvaWQsICR0aW1lc3RhbXApOwogICAgICAgIH0KICAgIH0KCiAgICAkdmFycy0+eydidWdfY291bnQnfSA9ICRuYl9idWdzOwoKICAgICRkYmgtPmRvKCJERUxFVEUgRlJPTSBtaWxlc3RvbmVzIFdIRVJFIHByb2R1Y3RfaWQgPSA/IEFORCB2YWx1ZSA9ID8iLAogICAgICAgICAgICAgdW5kZWYsICgkcHJvZHVjdF9pZCwgJG1pbGVzdG9uZSkpOwoKICAgIHVubGluayAiJGRhdGFkaXIvdmVyc2lvbmNhY2hlIjsKCiAgICAkdGVtcGxhdGUtPnByb2Nlc3MoImFkbWluL21pbGVzdG9uZXMvZGVsZXRlZC5odG1sLnRtcGwiLCAkdmFycykKICAgICAgfHwgVGhyb3dUZW1wbGF0ZUVycm9yKCR0ZW1wbGF0ZS0+ZXJyb3IoKSk7CiAgICBleGl0Owp9CgoKCiMKIyBhY3Rpb249J2VkaXQnIC0+IHByZXNlbnQgdGhlIGVkaXQgbWlsZXN0b25lIGZvcm0KIwojIChuZXh0IGFjdGlvbiB3b3VsZCBiZSAndXBkYXRlJykKIwoKaWYgKCRhY3Rpb24gZXEgJ2VkaXQnKSB7CgogICAgQ2hlY2tNaWxlc3RvbmUoJHByb2R1Y3QsICRtaWxlc3RvbmUpOwogICAgbXkgJHByb2R1Y3RfaWQgPSBnZXRfcHJvZHVjdF9pZCgkcHJvZHVjdCk7CgogICAgbXkgJGRiaCA9IEJ1Z3ppbGxhLT5kYmg7CgogICAgbXkgJHN0aCA9ICRkYmgtPnByZXBhcmVfY2FjaGVkKCdTRUxFQ1Qgc29ydGtleQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGUk9NIG1pbGVzdG9uZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0hFUkUgcHJvZHVjdF9pZCA9ID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQU5EIHZhbHVlID0gPycpOwoKICAgIHRyaWNrX3RhaW50KCRtaWxlc3RvbmUpOwoKICAgICR2YXJzLT57J3NvcnRrZXknfSA9ICRkYmgtPnNlbGVjdHJvd19hcnJheSgkc3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuZGVmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwcm9kdWN0X2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRtaWxlc3RvbmUpIHx8IDA7CgogICAgJHZhcnMtPnsnbmFtZSd9ID0gJG1pbGVzdG9uZTsKICAgICR2YXJzLT57J3Byb2R1Y3QnfSA9ICRwcm9kdWN0OwoKICAgICR0ZW1wbGF0ZS0+cHJvY2VzcygiYWRtaW4vbWlsZXN0b25lcy9lZGl0Lmh0bWwudG1wbCIsCiAgICAgICAgICAgICAgICAgICAgICAgJHZhcnMpCiAgICAgIHx8IFRocm93VGVtcGxhdGVFcnJvcigkdGVtcGxhdGUtPmVycm9yKCkpOwoKICAgIGV4aXQ7Cn0KCgoKIwojIGFjdGlvbj0ndXBkYXRlJyAtPiB1cGRhdGUgdGhlIG1pbGVzdG9uZQojCgppZiAoJGFjdGlvbiBlcSAndXBkYXRlJykgewoKICAgIG15ICRtaWxlc3RvbmVvbGQgPSB0cmltKCRjZ2ktPnBhcmFtKCdtaWxlc3RvbmVvbGQnKSB8fCAnJyk7CiAgICBteSAkc29ydGtleW9sZCA9IHRyaW0oJGNnaS0+cGFyYW0oJ3NvcnRrZXlvbGQnKSAgICAgfHwgJzAnKTsKCiAgICBDaGVja01pbGVzdG9uZSgkcHJvZHVjdCwgJG1pbGVzdG9uZW9sZCk7CiAgICBteSAkcHJvZHVjdF9pZCA9IGdldF9wcm9kdWN0X2lkKCRwcm9kdWN0KTsKCiAgICBpZiAobGVuZ3RoKCRtaWxlc3RvbmUpID4gMjApIHsKICAgICAgICBUaHJvd1VzZXJFcnJvcignbWlsZXN0b25lX25hbWVfdG9vX2xvbmcnLAogICAgICAgICAgICAgICAgICAgICAgIHsnbmFtZScgPT4gJG1pbGVzdG9uZX0pOwogICAgfQoKICAgIG15ICRkYmggPSBCdWd6aWxsYS0+ZGJoOwoKICAgICRkYmgtPmJ6X2xvY2tfdGFibGVzKCdidWdzIFdSSVRFJywKICAgICAgICAgICAgICAgICAgICAgICAgICdtaWxlc3RvbmVzIFdSSVRFJywKICAgICAgICAgICAgICAgICAgICAgICAgICdwcm9kdWN0cyBXUklURScpOwoKICAgIGlmICgkc29ydGtleSBuZSAkc29ydGtleW9sZCkgewogICAgICAgICRzb3J0a2V5ID0gQ2hlY2tTb3J0a2V5KCRtaWxlc3RvbmUsICRzb3J0a2V5KTsKCiAgICAgICAgdHJpY2tfdGFpbnQoJG1pbGVzdG9uZW9sZCk7CgogICAgICAgICRkYmgtPmRvKCdVUERBVEUgbWlsZXN0b25lcyBTRVQgc29ydGtleSA9ID8KICAgICAgICAgICAgICAgICAgV0hFUkUgcHJvZHVjdF9pZCA9ID8KICAgICAgICAgICAgICAgICAgQU5EIHZhbHVlID0gPycsCiAgICAgICAgICAgICAgICAgdW5kZWYsCiAgICAgICAgICAgICAgICAgJHNvcnRrZXksCiAgICAgICAgICAgICAgICAgJHByb2R1Y3RfaWQsCiAgICAgICAgICAgICAgICAgJG1pbGVzdG9uZW9sZCk7CgogICAgICAgIHVubGluayAiJGRhdGFkaXIvdmVyc2lvbmNhY2hlIjsKICAgICAgICAkdmFycy0+eyd1cGRhdGVkX3NvcnRrZXknfSA9IDE7CiAgICAgICAgJHZhcnMtPnsnc29ydGtleSd9ID0gJHNvcnRrZXk7CiAgICB9CgogICAgaWYgKCRtaWxlc3RvbmUgbmUgJG1pbGVzdG9uZW9sZCkgewogICAgICAgIHVubGVzcyAoJG1pbGVzdG9uZSkgewogICAgICAgICAgICBUaHJvd1VzZXJFcnJvcignbWlsZXN0b25lX2JsYW5rX25hbWUnKTsKICAgICAgICB9CiAgICAgICAgaWYgKFRlc3RNaWxlc3RvbmUoJHByb2R1Y3QsICRtaWxlc3RvbmUpKSB7CiAgICAgICAgICAgIFRocm93VXNlckVycm9yKCdtaWxlc3RvbmVfYWxyZWFkeV9leGlzdHMnLAogICAgICAgICAgICAgICAgICAgICAgICAgICB7J25hbWUnID0+ICRtaWxlc3RvbmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAncHJvZHVjdCcgPT4gJHByb2R1Y3R9KTsKICAgICAgICB9CgogICAgICAgIHRyaWNrX3RhaW50KCRtaWxlc3RvbmUpOwogICAgICAgIHRyaWNrX3RhaW50KCRtaWxlc3RvbmVvbGQpOwoKICAgICAgICAkZGJoLT5kbygnVVBEQVRFIGJ1Z3MKICAgICAgICAgICAgICAgICAgU0VUIHRhcmdldF9taWxlc3RvbmUgPSA/CiAgICAgICAgICAgICAgICAgIFdIRVJFIHRhcmdldF9taWxlc3RvbmUgPSA/CiAgICAgICAgICAgICAgICAgIEFORCBwcm9kdWN0X2lkID0gPycsCiAgICAgICAgICAgICAgICAgdW5kZWYsCiAgICAgICAgICAgICAgICAgJG1pbGVzdG9uZSwKICAgICAgICAgICAgICAgICAkbWlsZXN0b25lb2xkLAogICAgICAgICAgICAgICAgICRwcm9kdWN0X2lkKTsKCiAgICAgICAgJGRiaC0+ZG8oIlVQREFURSBtaWxlc3RvbmVzCiAgICAgICAgICAgICAgICAgIFNFVCB2YWx1ZSA9ID8KICAgICAgICAgICAgICAgICAgV0hFUkUgcHJvZHVjdF9pZCA9ID8KICAgICAgICAgICAgICAgICAgQU5EIHZhbHVlID0gPyIsCiAgICAgICAgICAgICAgICAgdW5kZWYsCiAgICAgICAgICAgICAgICAgJG1pbGVzdG9uZSwKICAgICAgICAgICAgICAgICAkcHJvZHVjdF9pZCwKICAgICAgICAgICAgICAgICAkbWlsZXN0b25lb2xkKTsKCiAgICAgICAgJGRiaC0+ZG8oIlVQREFURSBwcm9kdWN0cwogICAgICAgICAgICAgICAgICBTRVQgZGVmYXVsdG1pbGVzdG9uZSA9ID8KICAgICAgICAgICAgICAgICAgV0hFUkUgaWQgPSA/CiAgICAgICAgICAgICAgICAgIEFORCBkZWZhdWx0bWlsZXN0b25lID0gPyIsCiAgICAgICAgICAgICAgICAgdW5kZWYsCiAgICAgICAgICAgICAgICAgJG1pbGVzdG9uZSwKICAgICAgICAgICAgICAgICAkcHJvZHVjdF9pZCwKICAgICAgICAgICAgICAgICAkbWlsZXN0b25lb2xkKTsKCiAgICAgICAgdW5saW5rICIkZGF0YWRpci92ZXJzaW9uY2FjaGUiOwoKICAgICAgICAkdmFycy0+eyd1cGRhdGVkX25hbWUnfSA9IDE7CiAgICB9CgogICAgJGRiaC0+YnpfdW5sb2NrX3RhYmxlcygpOwoKICAgICR2YXJzLT57J25hbWUnfSA9ICRtaWxlc3RvbmU7CiAgICAkdmFycy0+eydwcm9kdWN0J30gPSAkcHJvZHVjdDsKICAgICR0ZW1wbGF0ZS0+cHJvY2VzcygiYWRtaW4vbWlsZXN0b25lcy91cGRhdGVkLmh0bWwudG1wbCIsCiAgICAgICAgICAgICAgICAgICAgICAgJHZhcnMpCiAgICAgIHx8IFRocm93VGVtcGxhdGVFcnJvcigkdGVtcGxhdGUtPmVycm9yKCkpOwoKICAgIGV4aXQ7Cn0KCgojCiMgTm8gdmFsaWQgYWN0aW9uIGZvdW5kCiMKVGhyb3dVc2VyRXJyb3IoJ25vX3ZhbGlkX2FjdGlvbicsIHsnZmllbGQnID0+ICJ0YXJnZXRfbWlsZXN0b25lIn0pOwo=