1 line
414 KiB
JavaScript
1 line
414 KiB
JavaScript
window.eval(atob(`dmFyIEF1dG9tYXRpY0Rpc3Bvc2VfQnJhbmNoID0gIm1hc3RlciI7CnZhciBBdXRvbWF0aWNEaXNwb3NlX1VSTCA9ICJodHRwczovL3Jhdy5qb3NlZi1mcm9laGxlLmRlL0RleHVzL2F1dG9tYXRpYy1kaXNwb3NlLyI7CnZhciBkYV9sc3NfYWRpc190aW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7Cgp2YXIgQURpc19NeUhlYWQgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaGVhZCcpWzBdOwp2YXIgQURpc19NeUJvZHkgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnYm9keScpWzBdOwoKZnVuY3Rpb24gaW5jbHVkZXNTdHJpbmcoc3RyaW5nMSwgc3RyaW5nMikgewogICAgcmV0dXJuIHN0cmluZzEudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhzdHJpbmcyLnRvTG93ZXJDYXNlKCkpOwp9Cgphc3luYyBmdW5jdGlvbiBBRGlzU2V0dGluZ3MoKSB7CiAgICB2YXIgcmVzID0ge307CiAgICBhd2FpdCBBRGlzREIuQURpc1NldHRpbmdzLmVhY2goKHNldHRpbmcpID0+IHsKICAgICAgICByZXNbc2V0dGluZy5uYW1lXSA9IHNldHRpbmcudmFsdWU7CiAgICB9KTsKICAgIHJldHVybiByZXM7Cn0KCi8qCiAqIERleGllLmpzIC0gYSBtaW5pbWFsaXN0aWMgd3JhcHBlciBmb3IgSW5kZXhlZERCCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqCiAqIEJ5IERhdmlkIEZhaGxhbmRlciwgZGF2aWQuZmFobGFuZGVyQGdtYWlsLmNvbQogKgogKiBWZXJzaW9uIDIuMC40LCBGcmkgTWF5IDI1IDIwMTgKICoKICogaHR0cDovL2RleGllLm9yZwogKgogKiBBcGFjaGUgTGljZW5zZSBWZXJzaW9uIDIuMCwgSmFudWFyeSAyMDA0LCBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvCiAqLwogCihmdW5jdGlvbiAoZ2xvYmFsLCBmYWN0b3J5KSB7Cgl0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgPyBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKSA6Cgl0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoZmFjdG9yeSkgOgoJKGdsb2JhbC5EZXhpZSA9IGZhY3RvcnkoKSk7Cn0odGhpcywgKGZ1bmN0aW9uICgpIHsgJ3VzZSBzdHJpY3QnOwoKdmFyIGtleXMgPSBPYmplY3Qua2V5czsKdmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5Owp2YXIgX2dsb2JhbCA9IHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJyA/IHNlbGYgOgogICAgdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOgogICAgICAgIGdsb2JhbDsKZnVuY3Rpb24gZXh0ZW5kKG9iaiwgZXh0ZW5zaW9uKSB7CiAgICBpZiAodHlwZW9mIGV4dGVuc2lvbiAhPT0gJ29iamVjdCcpCiAgICAgICAgcmV0dXJuIG9iajsKICAgIGtleXMoZXh0ZW5zaW9uKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHsKICAgICAgICBvYmpba2V5XSA9IGV4dGVuc2lvbltrZXldOwogICAgfSk7CiAgICByZXR1cm4gb2JqOwp9CnZhciBnZXRQcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZjsKdmFyIF9oYXNPd24gPSB7fS5oYXNPd25Qcm9wZXJ0eTsKZnVuY3Rpb24gaGFzT3duKG9iaiwgcHJvcCkgewogICAgcmV0dXJuIF9oYXNPd24uY2FsbChvYmosIHByb3ApOwp9CmZ1bmN0aW9uIHByb3BzKHByb3RvLCBleHRlbnNpb24pIHsKICAgIGlmICh0eXBlb2YgZXh0ZW5zaW9uID09PSAnZnVuY3Rpb24nKQogICAgICAgIGV4dGVuc2lvbiA9IGV4dGVuc2lvbihnZXRQcm90byhwcm90bykpOwogICAga2V5cyhleHRlbnNpb24pLmZvckVhY2goZnVuY3Rpb24gKGtleSkgewogICAgICAgIHNldFByb3AocHJvdG8sIGtleSwgZXh0ZW5zaW9uW2tleV0pOwogICAgfSk7Cn0KdmFyIGRlZmluZVByb3BlcnR5ID0gT2JqZWN0LmRlZmluZVByb3BlcnR5OwpmdW5jdGlvbiBzZXRQcm9wKG9iaiwgcHJvcCwgZnVuY3Rpb25PckdldFNldCwgb3B0aW9ucykgewogICAgZGVmaW5lUHJvcGVydHkob2JqLCBwcm9wLCBleHRlbmQoZnVuY3Rpb25PckdldFNldCAmJiBoYXNPd24oZnVuY3Rpb25PckdldFNldCwgImdldCIpICYmIHR5cGVvZiBmdW5jdGlvbk9yR2V0U2V0LmdldCA9PT0gJ2Z1bmN0aW9uJyA/CiAgICAgICAgeyBnZXQ6IGZ1bmN0aW9uT3JHZXRTZXQuZ2V0LCBzZXQ6IGZ1bmN0aW9uT3JHZXRTZXQuc2V0LCBjb25maWd1cmFibGU6IHRydWUgfSA6CiAgICAgICAgeyB2YWx1ZTogZnVuY3Rpb25PckdldFNldCwgY29uZmlndXJhYmxlOiB0cnVlLCB3cml0YWJsZTogdHJ1ZSB9LCBvcHRpb25zKSk7Cn0KZnVuY3Rpb24gZGVyaXZlKENoaWxkKSB7CiAgICByZXR1cm4gewogICAgICAgIGZyb206IGZ1bmN0aW9uIChQYXJlbnQpIHsKICAgICAgICAgICAgQ2hpbGQucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShQYXJlbnQucHJvdG90eXBlKTsKICAgICAgICAgICAgc2V0UHJvcChDaGlsZC5wcm90b3R5cGUsICJjb25zdHJ1Y3RvciIsIENoaWxkKTsKICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgIGV4dGVuZDogcHJvcHMuYmluZChudWxsLCBDaGlsZC5wcm90b3R5cGUpCiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfTsKfQp2YXIgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjsKZnVuY3Rpb24gZ2V0UHJvcGVydHlEZXNjcmlwdG9yKG9iaiwgcHJvcCkgewogICAgdmFyIHBkID0gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwgcHJvcCksIHByb3RvOwogICAgcmV0dXJuIHBkIHx8IChwcm90byA9IGdldFByb3RvKG9iaikpICYmIGdldFByb3BlcnR5RGVzY3JpcHRvcihwcm90bywgcHJvcCk7Cn0KdmFyIF9zbGljZSA9IFtdLnNsaWNlOwpmdW5jdGlvbiBzbGljZShhcmdzLCBzdGFydCwgZW5kKSB7CiAgICByZXR1cm4gX3NsaWNlLmNhbGwoYXJncywgc3RhcnQsIGVuZCk7Cn0KZnVuY3Rpb24gb3ZlcnJpZGUob3JpZ0Z1bmMsIG92ZXJyaWRlZEZhY3RvcnkpIHsKICAgIHJldHVybiBvdmVycmlkZWRGYWN0b3J5KG9yaWdGdW5jKTsKfQpmdW5jdGlvbiBhc3NlcnQoYikgewogICAgaWYgKCFiKQogICAgICAgIHRocm93IG5ldyBFcnJvcigiQXNzZXJ0aW9uIEZhaWxlZCIpOwp9CmZ1bmN0aW9uIGFzYXAoZm4pIHsKICAgIGlmIChfZ2xvYmFsLnNldEltbWVkaWF0ZSkKICAgICAgICBzZXRJbW1lZGlhdGUoZm4pOwogICAgZWxzZQogICAgICAgIHNldFRpbWVvdXQoZm4sIDApOwp9CgovKiogR2VuZXJhdGUgYW4gb2JqZWN0IChoYXNoIG1hcCkgYmFzZWQgb24gZ2l2ZW4gYXJyYXkuCiAqIEBwYXJhbSBleHRyYWN0b3IgRnVuY3Rpb24gdGFraW5nIGFuIGFycmF5IGl0ZW0gYW5kIGl0cyBpbmRleCBhbmQgcmV0dXJuaW5nIGFuIGFycmF5IG9mIDIgaXRlbXMgKFtrZXksIHZhbHVlXSkgdG8KICogICAgICAgIGluc3RlcnQgb24gdGhlIHJlc3VsdGluZyBvYmplY3QgZm9yIGVhY2ggaXRlbSBpbiB0aGUgYXJyYXkuIElmIHRoaXMgZnVuY3Rpb24gcmV0dXJucyBhIGZhbHN5IHZhbHVlLCB0aGUKICogICAgICAgIGN1cnJlbnQgaXRlbSB3b250IGFmZmVjdCB0aGUgcmVzdWx0aW5nIG9iamVjdC4KICovCmZ1bmN0aW9uIGFycmF5VG9PYmplY3QoYXJyYXksIGV4dHJhY3RvcikgewogICAgcmV0dXJuIGFycmF5LnJlZHVjZShmdW5jdGlvbiAocmVzdWx0LCBpdGVtLCBpKSB7CiAgICAgICAgdmFyIG5hbWVBbmRWYWx1ZSA9IGV4dHJhY3RvcihpdGVtLCBpKTsKICAgICAgICBpZiAobmFtZUFuZFZhbHVlKQogICAgICAgICAgICByZXN1bHRbbmFtZUFuZFZhbHVlWzBdXSA9IG5hbWVBbmRWYWx1ZVsxXTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfSwge30pOwp9CmZ1bmN0aW9uIHRyeWNhdGNoZXIoZm4sIHJlamVjdCkgewogICAgcmV0dXJuIGZ1bmN0aW9uICgpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoZSkgewogICAgICAgICAgICByZWplY3QoZSk7CiAgICAgICAgfQogICAgfTsKfQpmdW5jdGlvbiB0cnlDYXRjaChmbiwgb25lcnJvciwgYXJncykgewogICAgdHJ5IHsKICAgICAgICBmbi5hcHBseShudWxsLCBhcmdzKTsKICAgIH0KICAgIGNhdGNoIChleCkgewogICAgICAgIG9uZXJyb3IgJiYgb25lcnJvcihleCk7CiAgICB9Cn0KZnVuY3Rpb24gZ2V0QnlLZXlQYXRoKG9iaiwga2V5UGF0aCkgewogICAgLy8gaHR0cDovL3d3dy53My5vcmcvVFIvSW5kZXhlZERCLyNzdGVwcy1mb3ItZXh0cmFjdGluZy1hLWtleS1mcm9tLWEtdmFsdWUtdXNpbmctYS1rZXktcGF0aAogICAgaWYgKGhhc093bihvYmosIGtleVBhdGgpKQogICAgICAgIHJldHVybiBvYmpba2V5UGF0aF07IC8vIFRoaXMgbGluZSBpcyBtb3ZlZCBmcm9tIGxhc3QgdG8gZmlyc3QgZm9yIG9wdGltaXphdGlvbiBwdXJwb3NlLgogICAgaWYgKCFrZXlQYXRoKQogICAgICAgIHJldHVybiBvYmo7CiAgICBpZiAodHlwZW9mIGtleVBhdGggIT09ICdzdHJpbmcnKSB7CiAgICAgICAgdmFyIHJ2ID0gW107CiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBrZXlQYXRoLmxlbmd0aDsgaSA8IGw7ICsraSkgewogICAgICAgICAgICB2YXIgdmFsID0gZ2V0QnlLZXlQYXRoKG9iaiwga2V5UGF0aFtpXSk7CiAgICAgICAgICAgIHJ2LnB1c2godmFsKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJ2OwogICAgfQogICAgdmFyIHBlcmlvZCA9IGtleVBhdGguaW5kZXhPZignLicpOwogICAgaWYgKHBlcmlvZCAhPT0gLTEpIHsKICAgICAgICB2YXIgaW5uZXJPYmogPSBvYmpba2V5UGF0aC5zdWJzdHIoMCwgcGVyaW9kKV07CiAgICAgICAgcmV0dXJuIGlubmVyT2JqID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBnZXRCeUtleVBhdGgoaW5uZXJPYmosIGtleVBhdGguc3Vic3RyKHBlcmlvZCArIDEpKTsKICAgIH0KICAgIHJldHVybiB1bmRlZmluZWQ7Cn0KZnVuY3Rpb24gc2V0QnlLZXlQYXRoKG9iaiwga2V5UGF0aCwgdmFsdWUpIHsKICAgIGlmICghb2JqIHx8IGtleVBhdGggPT09IHVuZGVmaW5lZCkKICAgICAgICByZXR1cm47CiAgICBpZiAoJ2lzRnJvemVuJyBpbiBPYmplY3QgJiYgT2JqZWN0LmlzRnJvemVuKG9iaikpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKHR5cGVvZiBrZXlQYXRoICE9PSAnc3RyaW5nJyAmJiAnbGVuZ3RoJyBpbiBrZXlQYXRoKSB7CiAgICAgICAgYXNzZXJ0KHR5cGVvZiB2YWx1ZSAhPT0gJ3N0cmluZycgJiYgJ2xlbmd0aCcgaW4gdmFsdWUpOwogICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0ga2V5UGF0aC5sZW5ndGg7IGkgPCBsOyArK2kpIHsKICAgICAgICAgICAgc2V0QnlLZXlQYXRoKG9iaiwga2V5UGF0aFtpXSwgdmFsdWVbaV0pOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UgewogICAgICAgIHZhciBwZXJpb2QgPSBrZXlQYXRoLmluZGV4T2YoJy4nKTsKICAgICAgICBpZiAocGVyaW9kICE9PSAtMSkgewogICAgICAgICAgICB2YXIgY3VycmVudEtleVBhdGggPSBrZXlQYXRoLnN1YnN0cigwLCBwZXJpb2QpOwogICAgICAgICAgICB2YXIgcmVtYWluaW5nS2V5UGF0aCA9IGtleVBhdGguc3Vic3RyKHBlcmlvZCArIDEpOwogICAgICAgICAgICBpZiAocmVtYWluaW5nS2V5UGF0aCA9PT0gIiIpCiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkKICAgICAgICAgICAgICAgICAgICBkZWxldGUgb2JqW2N1cnJlbnRLZXlQYXRoXTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBvYmpbY3VycmVudEtleVBhdGhdID0gdmFsdWU7CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgdmFyIGlubmVyT2JqID0gb2JqW2N1cnJlbnRLZXlQYXRoXTsKICAgICAgICAgICAgICAgIGlmICghaW5uZXJPYmopCiAgICAgICAgICAgICAgICAgICAgaW5uZXJPYmogPSAob2JqW2N1cnJlbnRLZXlQYXRoXSA9IHt9KTsKICAgICAgICAgICAgICAgIHNldEJ5S2V5UGF0aChpbm5lck9iaiwgcmVtYWluaW5nS2V5UGF0aCwgdmFsdWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkKICAgICAgICAgICAgICAgIGRlbGV0ZSBvYmpba2V5UGF0aF07CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIG9ialtrZXlQYXRoXSA9IHZhbHVlOwogICAgICAgIH0KICAgIH0KfQpmdW5jdGlvbiBkZWxCeUtleVBhdGgob2JqLCBrZXlQYXRoKSB7CiAgICBpZiAodHlwZW9mIGtleVBhdGggPT09ICdzdHJpbmcnKQogICAgICAgIHNldEJ5S2V5UGF0aChvYmosIGtleVBhdGgsIHVuZGVmaW5lZCk7CiAgICBlbHNlIGlmICgnbGVuZ3RoJyBpbiBrZXlQYXRoKQogICAgICAgIFtdLm1hcC5jYWxsKGtleVBhdGgsIGZ1bmN0aW9uIChrcCkgewogICAgICAgICAgICBzZXRCeUtleVBhdGgob2JqLCBrcCwgdW5kZWZpbmVkKTsKICAgICAgICB9KTsKfQpmdW5jdGlvbiBzaGFsbG93Q2xvbmUob2JqKSB7CiAgICB2YXIgcnYgPSB7fTsKICAgIGZvciAodmFyIG0gaW4gb2JqKSB7CiAgICAgICAgaWYgKGhhc093bihvYmosIG0pKQogICAgICAgICAgICBydlttXSA9IG9ialttXTsKICAgIH0KICAgIHJldHVybiBydjsKfQp2YXIgY29uY2F0ID0gW10uY29uY2F0OwpmdW5jdGlvbiBmbGF0dGVuKGEpIHsKICAgIHJldHVybiBjb25jYXQuYXBwbHkoW10sIGEpOwp9Ci8vaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1dlYl9Xb3JrZXJzX0FQSS9TdHJ1Y3R1cmVkX2Nsb25lX2FsZ29yaXRobQp2YXIgaW50cmluc2ljVHlwZXMgPSAiQm9vbGVhbixTdHJpbmcsRGF0ZSxSZWdFeHAsQmxvYixGaWxlLEZpbGVMaXN0LEFycmF5QnVmZmVyLERhdGFWaWV3LFVpbnQ4Q2xhbXBlZEFycmF5LEltYWdlRGF0YSxNYXAsU2V0IgogICAgLnNwbGl0KCcsJykuY29uY2F0KGZsYXR0ZW4oWzgsIDE2LCAzMiwgNjRdLm1hcChmdW5jdGlvbiAobnVtKSB7IHJldHVybiBbIkludCIsICJVaW50IiwgIkZsb2F0Il0ubWFwKGZ1bmN0aW9uICh0KSB7IHJldHVybiB0ICsgbnVtICsgIkFycmF5IjsgfSk7IH0pKSkuZmlsdGVyKGZ1bmN0aW9uICh0KSB7IHJldHVybiBfZ2xvYmFsW3RdOyB9KS5tYXAoZnVuY3Rpb24gKHQpIHsgcmV0dXJuIF9nbG9iYWxbdF07IH0pOwpmdW5jdGlvbiBkZWVwQ2xvbmUoYW55KSB7CiAgICBpZiAoIWFueSB8fCB0eXBlb2YgYW55ICE9PSAnb2JqZWN0JykKICAgICAgICByZXR1cm4gYW55OwogICAgdmFyIHJ2OwogICAgaWYgKGlzQXJyYXkoYW55KSkgewogICAgICAgIHJ2ID0gW107CiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBhbnkubGVuZ3RoOyBpIDwgbDsgKytpKSB7CiAgICAgICAgICAgIHJ2LnB1c2goZGVlcENsb25lKGFueVtpXSkpOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UgaWYgKGludHJpbnNpY1R5cGVzLmluZGV4T2YoYW55LmNvbnN0cnVjdG9yKSA+PSAwKSB7CiAgICAgICAgcnYgPSBhbnk7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBydiA9IGFueS5jb25zdHJ1Y3RvciA/IE9iamVjdC5jcmVhdGUoYW55LmNvbnN0cnVjdG9yLnByb3RvdHlwZSkgOiB7fTsKICAgICAgICBmb3IgKHZhciBwcm9wIGluIGFueSkgewogICAgICAgICAgICBpZiAoaGFzT3duKGFueSwgcHJvcCkpIHsKICAgICAgICAgICAgICAgIHJ2W3Byb3BdID0gZGVlcENsb25lKGFueVtwcm9wXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gcnY7Cn0KZnVuY3Rpb24gZ2V0T2JqZWN0RGlmZihhLCBiLCBydiwgcHJmeCkgewogICAgLy8gQ29tcGFyZXMgb2JqZWN0cyBhIGFuZCBiIGFuZCBwcm9kdWNlcyBhIGRpZmYgb2JqZWN0LgogICAgcnYgPSBydiB8fCB7fTsKICAgIHByZnggPSBwcmZ4IHx8ICcnOwogICAga2V5cyhhKS5mb3JFYWNoKGZ1bmN0aW9uIChwcm9wKSB7CiAgICAgICAgaWYgKCFoYXNPd24oYiwgcHJvcCkpCiAgICAgICAgICAgIHJ2W3ByZnggKyBwcm9wXSA9IHVuZGVmaW5lZDsgLy8gUHJvcGVydHkgcmVtb3ZlZAogICAgICAgIGVsc2UgewogICAgICAgICAgICB2YXIgYXAgPSBhW3Byb3BdLCBicCA9IGJbcHJvcF07CiAgICAgICAgICAgIGlmICh0eXBlb2YgYXAgPT09ICdvYmplY3QnICYmIHR5cGVvZiBicCA9PT0gJ29iamVjdCcgJiYKICAgICAgICAgICAgICAgIGFwICYmIGJwICYmCiAgICAgICAgICAgICAgICAvLyBOb3cgY29tcGFyZSBjb25zdHJ1Y3RvcnMgYXJlIHNhbWUgKG5vdCBlcXVhbCBiZWNhdXNlIHdvbnQgd29yayBpbiBTYWZhcmkpCiAgICAgICAgICAgICAgICAoJycgKyBhcC5jb25zdHJ1Y3RvcikgPT09ICgnJyArIGJwLmNvbnN0cnVjdG9yKSkKICAgICAgICAgICAgICAgIC8vIFNhbWUgdHlwZSBvZiBvYmplY3QgYnV0IGl0cyBwcm9wZXJ0aWVzIG1heSBoYXZlIGNoYW5nZWQKICAgICAgICAgICAgICAgIGdldE9iamVjdERpZmYoYXAsIGJwLCBydiwgcHJmeCArIHByb3AgKyAiLiIpOwogICAgICAgICAgICBlbHNlIGlmIChhcCAhPT0gYnApCiAgICAgICAgICAgICAgICBydltwcmZ4ICsgcHJvcF0gPSBiW3Byb3BdOyAvLyBQcmltaXRpdmUgdmFsdWUgY2hhbmdlZAogICAgICAgIH0KICAgIH0pOwogICAga2V5cyhiKS5mb3JFYWNoKGZ1bmN0aW9uIChwcm9wKSB7CiAgICAgICAgaWYgKCFoYXNPd24oYSwgcHJvcCkpIHsKICAgICAgICAgICAgcnZbcHJmeCArIHByb3BdID0gYltwcm9wXTsgLy8gUHJvcGVydHkgYWRkZWQKICAgICAgICB9CiAgICB9KTsKICAgIHJldHVybiBydjsKfQovLyBJZiBmaXJzdCBhcmd1bWVudCBpcyBpdGVyYWJsZSBvciBhcnJheS1saWtlLCByZXR1cm4gaXQgYXMgYW4gYXJyYXkKdmFyIGl0ZXJhdG9yU3ltYm9sID0gdHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLml0ZXJhdG9yOwp2YXIgZ2V0SXRlcmF0b3JPZiA9IGl0ZXJhdG9yU3ltYm9sID8gZnVuY3Rpb24gKHgpIHsKICAgIHZhciBpOwogICAgcmV0dXJuIHggIT0gbnVsbCAmJiAoaSA9IHhbaXRlcmF0b3JTeW1ib2xdKSAmJiBpLmFwcGx5KHgpOwp9IDogZnVuY3Rpb24gKCkgeyByZXR1cm4gbnVsbDsgfTsKdmFyIE5PX0NIQVJfQVJSQVkgPSB7fTsKLy8gVGFrZXMgb25lIG9yIHNldmVyYWwgYXJndW1lbnRzIGFuZCByZXR1cm5zIGFuIGFycmF5IGJhc2VkIG9uIHRoZSBmb2xsb3dpbmcgY3JpdGVyYXM6Ci8vICogSWYgc2V2ZXJhbCBhcmd1bWVudHMgcHJvdmlkZWQsIHJldHVybiBhcmd1bWVudHMgY29udmVydGVkIHRvIGFuIGFycmF5IGluIGEgd2F5IHRoYXQKLy8gICBzdGlsbCBhbGxvd3MgamF2YXNjcmlwdCBlbmdpbmUgdG8gb3B0aW1pemUgdGhlIGNvZGUuCi8vICogSWYgc2luZ2xlIGFyZ3VtZW50IGlzIGFuIGFycmF5LCByZXR1cm4gYSBjbG9uZSBvZiBpdC4KLy8gKiBJZiB0aGlzLXBvaW50ZXIgZXF1YWxzIE5PX0NIQVJfQVJSQVksIGRvbid0IGFjY2VwdCBzdHJpbmdzIGFzIHZhbGlkIGl0ZXJhYmxlcyBhcyBhIHNwZWNpYWwKLy8gICBjYXNlIHRvIHRoZSB0d28gYnVsbGV0cyBiZWxvdy4KLy8gKiBJZiBzaW5nbGUgYXJndW1lbnQgaXMgYW4gaXRlcmFibGUsIGNvbnZlcnQgaXQgdG8gYW4gYXJyYXkgYW5kIHJldHVybiB0aGUgcmVzdWx0aW5nIGFycmF5LgovLyAqIElmIHNpbmdsZSBhcmd1bWVudCBpcyBhcnJheS1saWtlIChoYXMgbGVuZ3RoIG9mIHR5cGUgbnVtYmVyKSwgY29udmVydCBpdCB0byBhbiBhcnJheS4KZnVuY3Rpb24gZ2V0QXJyYXlPZihhcnJheUxpa2UpIHsKICAgIHZhciBpLCBhLCB4LCBpdDsKICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7CiAgICAgICAgaWYgKGlzQXJyYXkoYXJyYXlMaWtlKSkKICAgICAgICAgICAgcmV0dXJuIGFycmF5TGlrZS5zbGljZSgpOwogICAgICAgIGlmICh0aGlzID09PSBOT19DSEFSX0FSUkFZICYmIHR5cGVvZiBhcnJheUxpa2UgPT09ICdzdHJpbmcnKQogICAgICAgICAgICByZXR1cm4gW2FycmF5TGlrZV07CiAgICAgICAgaWYgKChpdCA9IGdldEl0ZXJhdG9yT2YoYXJyYXlMaWtlKSkpIHsKICAgICAgICAgICAgYSA9IFtdOwogICAgICAgICAgICB3aGlsZSAoKHggPSBpdC5uZXh0KCkpLCAheC5kb25lKQogICAgICAgICAgICAgICAgYS5wdXNoKHgudmFsdWUpOwogICAgICAgICAgICByZXR1cm4gYTsKICAgICAgICB9CiAgICAgICAgaWYgKGFycmF5TGlrZSA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gW2FycmF5TGlrZV07CiAgICAgICAgaSA9IGFycmF5TGlrZS5sZW5ndGg7CiAgICAgICAgaWYgKHR5cGVvZiBpID09PSAnbnVtYmVyJykgewogICAgICAgICAgICBhID0gbmV3IEFycmF5KGkpOwogICAgICAgICAgICB3aGlsZSAoaS0tKQogICAgICAgICAgICAgICAgYVtpXSA9IGFycmF5TGlrZVtpXTsKICAgICAgICAgICAgcmV0dXJuIGE7CiAgICAgICAgfQogICAgICAgIHJldHVybiBbYXJyYXlMaWtlXTsKICAgIH0KICAgIGkgPSBhcmd1bWVudHMubGVuZ3RoOwogICAgYSA9IG5ldyBBcnJheShpKTsKICAgIHdoaWxlIChpLS0pCiAgICAgICAgYVtpXSA9IGFyZ3VtZW50c1tpXTsKICAgIHJldHVybiBhOwp9CgovLyBCeSBkZWZhdWx0LCBkZWJ1ZyB3aWxsIGJlIHRydWUgb25seSBpZiBwbGF0Zm9ybSBpcyBhIHdlYiBwbGF0Zm9ybSBhbmQgaXRzIHBhZ2UgaXMgc2VydmVkIGZyb20gbG9jYWxob3N0LgovLyBXaGVuIGRlYnVnID0gdHJ1ZSwgZXJyb3IncyBzdGFja3Mgd2lsbCBjb250YWluIGFzeW5jcm9uaWMgbG9uZyBzdGFja3MuCnZhciBkZWJ1ZyA9IHR5cGVvZiBsb2NhdGlvbiAhPT0gJ3VuZGVmaW5lZCcgJiYKICAgIC8vIEJ5IGRlZmF1bHQsIHVzZSBkZWJ1ZyBtb2RlIGlmIHNlcnZlZCBmcm9tIGxvY2FsaG9zdC4KICAgIC9eKGh0dHB8aHR0cHMpOlwvXC8obG9jYWxob3N0fDEyN1wuMFwuMFwuMSkvLnRlc3QobG9jYXRpb24uaHJlZik7CmZ1bmN0aW9uIHNldERlYnVnKHZhbHVlLCBmaWx0ZXIpIHsKICAgIGRlYnVnID0gdmFsdWU7CiAgICBsaWJyYXJ5RmlsdGVyID0gZmlsdGVyOwp9CnZhciBsaWJyYXJ5RmlsdGVyID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdHJ1ZTsgfTsKdmFyIE5FRURTX1RIUk9XX0ZPUl9TVEFDSyA9ICFuZXcgRXJyb3IoIiIpLnN0YWNrOwpmdW5jdGlvbiBnZXRFcnJvcldpdGhTdGFjaygpIHsKICAgICJ1c2Ugc3RyaWN0IjsKICAgIGlmIChORUVEU19USFJPV19GT1JfU1RBQ0spCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgLy8gRG9pbmcgc29tZXRoaW5nIG5hdWdodHkgaW4gc3RyaWN0IG1vZGUgaGVyZSB0byB0cmlnZ2VyIGEgc3BlY2lmaWMgZXJyb3IKICAgICAgICAgICAgLy8gdGhhdCBjYW4gYmUgZXhwbGljaXRlbHkgaWdub3JlZCBpbiBkZWJ1Z2dlcidzIGV4Y2VwdGlvbiBzZXR0aW5ncy4KICAgICAgICAgICAgLy8gSWYgd2UnZCBqdXN0IHRocm93IG5ldyBFcnJvcigpIGhlcmUsIElFJ3MgZGVidWdnZXIncyBleGNlcHRpb24gc2V0dGluZ3MKICAgICAgICAgICAgLy8gd2lsbCBqdXN0IGNvbnNpZGVyIGl0IGFzICJleGNlcHRpb24gdGhyb3duIGJ5IGphdmFzY3JpcHQgY29kZSIgd2hpY2ggaXMKICAgICAgICAgICAgLy8gc29tZXRoaW5nIHlvdSB3b3VsZG4ndCB3YW50IGl0IHRvIGlnbm9yZS4KICAgICAgICAgICAgZ2V0RXJyb3JXaXRoU3RhY2suYXJndW1lbnRzOwogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTsgLy8gRmFsbGJhY2sgaWYgYWJvdmUgbGluZSBkb24ndCB0aHJvdy4KICAgICAgICB9CiAgICAgICAgY2F0Y2ggKGUpIHsKICAgICAgICAgICAgcmV0dXJuIGU7CiAgICAgICAgfQogICAgcmV0dXJuIG5ldyBFcnJvcigpOwp9CmZ1bmN0aW9uIHByZXR0eVN0YWNrKGV4Y2VwdGlvbiwgbnVtSWdub3JlZEZyYW1lcykgewogICAgdmFyIHN0YWNrID0gZXhjZXB0aW9uLnN0YWNrOwogICAgaWYgKCFzdGFjaykKICAgICAgICByZXR1cm4gIiI7CiAgICBudW1JZ25vcmVkRnJhbWVzID0gKG51bUlnbm9yZWRGcmFtZXMgfHwgMCk7CiAgICBpZiAoc3RhY2suaW5kZXhPZihleGNlcHRpb24ubmFtZSkgPT09IDApCiAgICAgICAgbnVtSWdub3JlZEZyYW1lcyArPSAoZXhjZXB0aW9uLm5hbWUgKyBleGNlcHRpb24ubWVzc2FnZSkuc3BsaXQoJ1xuJykubGVuZ3RoOwogICAgcmV0dXJuIHN0YWNrLnNwbGl0KCdcbicpCiAgICAgICAgLnNsaWNlKG51bUlnbm9yZWRGcmFtZXMpCiAgICAgICAgLmZpbHRlcihsaWJyYXJ5RmlsdGVyKQogICAgICAgIC5tYXAoZnVuY3Rpb24gKGZyYW1lKSB7IHJldHVybiAiXG4iICsgZnJhbWU7IH0pCiAgICAgICAgLmpvaW4oJycpOwp9CmZ1bmN0aW9uIGRlcHJlY2F0ZWQod2hhdCwgZm4pIHsKICAgIHJldHVybiBmdW5jdGlvbiAoKSB7CiAgICAgICAgY29uc29sZS53YXJuKHdoYXQgKyAiIGlzIGRlcHJlY2F0ZWQuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vZGZhaGxhbmRlci9EZXhpZS5qcy93aWtpL0RlcHJlY2F0aW9ucy4gIiArIHByZXR0eVN0YWNrKGdldEVycm9yV2l0aFN0YWNrKCksIDEpKTsKICAgICAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgIH07Cn0KCnZhciBkZXhpZUVycm9yTmFtZXMgPSBbCiAgICAnTW9kaWZ5JywKICAgICdCdWxrJywKICAgICdPcGVuRmFpbGVkJywKICAgICdWZXJzaW9uQ2hhbmdlJywKICAgICdTY2hlbWEnLAogICAgJ1VwZ3JhZGUnLAogICAgJ0ludmFsaWRUYWJsZScsCiAgICAnTWlzc2luZ0FQSScsCiAgICAnTm9TdWNoRGF0YWJhc2UnLAogICAgJ0ludmFsaWRBcmd1bWVudCcsCiAgICAnU3ViVHJhbnNhY3Rpb24nLAogICAgJ1Vuc3VwcG9ydGVkJywKICAgICdJbnRlcm5hbCcsCiAgICAnRGF0YWJhc2VDbG9zZWQnLAogICAgJ1ByZW1hdHVyZUNvbW1pdCcsCiAgICAnRm9yZWlnbkF3YWl0JwpdOwp2YXIgaWRiRG9tRXJyb3JOYW1lcyA9IFsKICAgICdVbmtub3duJywKICAgICdDb25zdHJhaW50JywKICAgICdEYXRhJywKICAgICdUcmFuc2FjdGlvbkluYWN0aXZlJywKICAgICdSZWFkT25seScsCiAgICAnVmVyc2lvbicsCiAgICAnTm90Rm91bmQnLAogICAgJ0ludmFsaWRTdGF0ZScsCiAgICAnSW52YWxpZEFjY2VzcycsCiAgICAnQWJvcnQnLAogICAgJ1RpbWVvdXQnLAogICAgJ1F1b3RhRXhjZWVkZWQnLAogICAgJ1N5bnRheCcsCiAgICAnRGF0YUNsb25lJwpdOwp2YXIgZXJyb3JMaXN0ID0gZGV4aWVFcnJvck5hbWVzLmNvbmNhdChpZGJEb21FcnJvck5hbWVzKTsKdmFyIGRlZmF1bHRUZXh0cyA9IHsKICAgIFZlcnNpb25DaGFuZ2VkOiAiRGF0YWJhc2UgdmVyc2lvbiBjaGFuZ2VkIGJ5IG90aGVyIGRhdGFiYXNlIGNvbm5lY3Rpb24iLAogICAgRGF0YWJhc2VDbG9zZWQ6ICJEYXRhYmFzZSBoYXMgYmVlbiBjbG9zZWQiLAogICAgQWJvcnQ6ICJUcmFuc2FjdGlvbiBhYm9ydGVkIiwKICAgIFRyYW5zYWN0aW9uSW5hY3RpdmU6ICJUcmFuc2FjdGlvbiBoYXMgYWxyZWFkeSBjb21wbGV0ZWQgb3IgZmFpbGVkIgp9OwovLwovLyBEZXhpZUVycm9yIC0gYmFzZSBjbGFzcyBvZiBhbGwgb3V0IGV4Y2VwdGlvbnMuCi8vCmZ1bmN0aW9uIERleGllRXJyb3IobmFtZSwgbXNnKSB7CiAgICAvLyBSZWFzb24gd2UgZG9uJ3QgdXNlIEVTNiBjbGFzc2VzIGlzIGJlY2F1c2U6CiAgICAvLyAxLiBJdCBibG9hdHMgdHJhbnNwaWxlZCBjb2RlIGFuZCBpbmNyZWFzZXMgc2l6ZSBvZiBtaW5pZmllZCBjb2RlLgogICAgLy8gMi4gSXQgZG9lc24ndCBnaXZlIHVzIG11Y2ggaW4gdGhpcyBjYXNlLgogICAgLy8gMy4gSXQgd291bGQgcmVxdWlyZSBzdWIgY2xhc3NlcyB0byBjYWxsIHN1cGVyKCksIHdoaWNoCiAgICAvLyAgICBpcyBub3QgbmVlZGVkIHdoZW4gZGVyaXZpbmcgZnJvbSBFcnJvci4KICAgIHRoaXMuX2UgPSBnZXRFcnJvcldpdGhTdGFjaygpOwogICAgdGhpcy5uYW1lID0gbmFtZTsKICAgIHRoaXMubWVzc2FnZSA9IG1zZzsKfQpkZXJpdmUoRGV4aWVFcnJvcikuZnJvbShFcnJvcikuZXh0ZW5kKHsKICAgIHN0YWNrOiB7CiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9zdGFjayB8fAogICAgICAgICAgICAgICAgKHRoaXMuX3N0YWNrID0gdGhpcy5uYW1lICsgIjogIiArIHRoaXMubWVzc2FnZSArIHByZXR0eVN0YWNrKHRoaXMuX2UsIDIpKTsKICAgICAgICB9CiAgICB9LAogICAgdG9TdHJpbmc6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMubmFtZSArICI6ICIgKyB0aGlzLm1lc3NhZ2U7IH0KfSk7CmZ1bmN0aW9uIGdldE11bHRpRXJyb3JNZXNzYWdlKG1zZywgZmFpbHVyZXMpIHsKICAgIHJldHVybiBtc2cgKyAiLiBFcnJvcnM6ICIgKyBmYWlsdXJlcwogICAgICAgIC5tYXAoZnVuY3Rpb24gKGYpIHsgcmV0dXJuIGYudG9TdHJpbmcoKTsgfSkKICAgICAgICAuZmlsdGVyKGZ1bmN0aW9uICh2LCBpLCBzKSB7IHJldHVybiBzLmluZGV4T2YodikgPT09IGk7IH0pIC8vIE9ubHkgdW5pcXVlIGVycm9yIHN0cmluZ3MKICAgICAgICAuam9pbignXG4nKTsKfQovLwovLyBNb2RpZnlFcnJvciAtIHRocm93biBpbiBDb2xsZWN0aW9uLm1vZGlmeSgpCi8vIFNwZWNpZmljIGNvbnN0cnVjdG9yIGJlY2F1c2UgaXQgY29udGFpbnMgbWVtYmVycyBmYWlsdXJlcyBhbmQgZmFpbGVkS2V5cy4KLy8KZnVuY3Rpb24gTW9kaWZ5RXJyb3IobXNnLCBmYWlsdXJlcywgc3VjY2Vzc0NvdW50LCBmYWlsZWRLZXlzKSB7CiAgICB0aGlzLl9lID0gZ2V0RXJyb3JXaXRoU3RhY2soKTsKICAgIHRoaXMuZmFpbHVyZXMgPSBmYWlsdXJlczsKICAgIHRoaXMuZmFpbGVkS2V5cyA9IGZhaWxlZEtleXM7CiAgICB0aGlzLnN1Y2Nlc3NDb3VudCA9IHN1Y2Nlc3NDb3VudDsKfQpkZXJpdmUoTW9kaWZ5RXJyb3IpLmZyb20oRGV4aWVFcnJvcik7CmZ1bmN0aW9uIEJ1bGtFcnJvcihtc2csIGZhaWx1cmVzKSB7CiAgICB0aGlzLl9lID0gZ2V0RXJyb3JXaXRoU3RhY2soKTsKICAgIHRoaXMubmFtZSA9ICJCdWxrRXJyb3IiOwogICAgdGhpcy5mYWlsdXJlcyA9IGZhaWx1cmVzOwogICAgdGhpcy5tZXNzYWdlID0gZ2V0TXVsdGlFcnJvck1lc3NhZ2UobXNnLCBmYWlsdXJlcyk7Cn0KZGVyaXZlKEJ1bGtFcnJvcikuZnJvbShEZXhpZUVycm9yKTsKLy8KLy8KLy8gRHluYW1pY2FsbHkgZ2VuZXJhdGUgZXJyb3IgbmFtZXMgYW5kIGV4Y2VwdGlvbiBjbGFzc2VzIGJhc2VkCi8vIG9uIHRoZSBuYW1lcyBpbiBlcnJvckxpc3QuCi8vCi8vCi8vIE1hcCBvZiB7RXJyb3JOYW1lIC0+IEVycm9yTmFtZSArICJFcnJvciJ9CnZhciBlcnJuYW1lcyA9IGVycm9yTGlzdC5yZWR1Y2UoZnVuY3Rpb24gKG9iaiwgbmFtZSkgeyByZXR1cm4gKG9ialtuYW1lXSA9IG5hbWUgKyAiRXJyb3IiLCBvYmopOyB9LCB7fSk7Ci8vIE5lZWQgYW4gYWxpYXMgZm9yIERleGllRXJyb3IgYmVjYXVzZSB3ZSdyZSBnb25uYSBjcmVhdGUgc3ViY2xhc3NlcyB3aXRoIHRoZSBzYW1lIG5hbWUuCnZhciBCYXNlRXhjZXB0aW9uID0gRGV4aWVFcnJvcjsKLy8gTWFwIG9mIHtFcnJvck5hbWUgLT4gZXhjZXB0aW9uIGNvbnN0cnVjdG9yfQp2YXIgZXhjZXB0aW9ucyA9IGVycm9yTGlzdC5yZWR1Y2UoZnVuY3Rpb24gKG9iaiwgbmFtZSkgewogICAgLy8gTGV0IHRoZSBuYW1lIGJlICJEZXhpZUVycm9yIiBiZWNhdXNlIHRoaXMgbmFtZSBtYXkKICAgIC8vIGJlIHNob3duIGluIGNhbGwgc3RhY2sgYW5kIHdoZW4gZGVidWdnaW5nLiBEZXhpZUVycm9yIGlzCiAgICAvLyB0aGUgbW9zdCB0cnVlIG5hbWUgYmVjYXVzZSBpdCBkZXJpdmVzIGZyb20gRGV4aWVFcnJvciwKICAgIC8vIGFuZCB3ZSBjYW5ub3QgY2hhbmdlIEZ1bmN0aW9uLm5hbWUgcHJvZ3JhbWF0aWNhbGx5IHdpdGhvdXQKICAgIC8vIGR5bmFtaWNhbGx5IGNyZWF0ZSBhIEZ1bmN0aW9uIG9iamVjdCwgd2hpY2ggd291bGQgYmUgY29uc2lkZXJlZAogICAgLy8gJ2V2YWwtZXZpbCcuCiAgICB2YXIgZnVsbE5hbWUgPSBuYW1lICsgIkVycm9yIjsKICAgIGZ1bmN0aW9uIERleGllRXJyb3IobXNnT3JJbm5lciwgaW5uZXIpIHsKICAgICAgICB0aGlzLl9lID0gZ2V0RXJyb3JXaXRoU3RhY2soKTsKICAgICAgICB0aGlzLm5hbWUgPSBmdWxsTmFtZTsKICAgICAgICBpZiAoIW1zZ09ySW5uZXIpIHsKICAgICAgICAgICAgdGhpcy5tZXNzYWdlID0gZGVmYXVsdFRleHRzW25hbWVdIHx8IGZ1bGxOYW1lOwogICAgICAgICAgICB0aGlzLmlubmVyID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAodHlwZW9mIG1zZ09ySW5uZXIgPT09ICdzdHJpbmcnKSB7CiAgICAgICAgICAgIHRoaXMubWVzc2FnZSA9IG1zZ09ySW5uZXI7CiAgICAgICAgICAgIHRoaXMuaW5uZXIgPSBpbm5lciB8fCBudWxsOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmICh0eXBlb2YgbXNnT3JJbm5lciA9PT0gJ29iamVjdCcpIHsKICAgICAgICAgICAgdGhpcy5tZXNzYWdlID0gbXNnT3JJbm5lci5uYW1lICsgIiAiICsgbXNnT3JJbm5lci5tZXNzYWdlOwogICAgICAgICAgICB0aGlzLmlubmVyID0gbXNnT3JJbm5lcjsKICAgICAgICB9CiAgICB9CiAgICBkZXJpdmUoRGV4aWVFcnJvcikuZnJvbShCYXNlRXhjZXB0aW9uKTsKICAgIG9ialtuYW1lXSA9IERleGllRXJyb3I7CiAgICByZXR1cm4gb2JqOwp9LCB7fSk7Ci8vIFVzZSBFQ01BU0NSSVBUIHN0YW5kYXJkIGV4Y2VwdGlvbnMgd2hlcmUgYXBwbGljYWJsZToKZXhjZXB0aW9ucy5TeW50YXggPSBTeW50YXhFcnJvcjsKZXhjZXB0aW9ucy5UeXBlID0gVHlwZUVycm9yOwpleGNlcHRpb25zLlJhbmdlID0gUmFuZ2VFcnJvcjsKdmFyIGV4Y2VwdGlvbk1hcCA9IGlkYkRvbUVycm9yTmFtZXMucmVkdWNlKGZ1bmN0aW9uIChvYmosIG5hbWUpIHsKICAgIG9ialtuYW1lICsgIkVycm9yIl0gPSBleGNlcHRpb25zW25hbWVdOwogICAgcmV0dXJuIG9iajsKfSwge30pOwpmdW5jdGlvbiBtYXBFcnJvcihkb21FcnJvciwgbWVzc2FnZSkgewogICAgaWYgKCFkb21FcnJvciB8fCBkb21FcnJvciBpbnN0YW5jZW9mIERleGllRXJyb3IgfHwgZG9tRXJyb3IgaW5zdGFuY2VvZiBUeXBlRXJyb3IgfHwgZG9tRXJyb3IgaW5zdGFuY2VvZiBTeW50YXhFcnJvciB8fCAhZG9tRXJyb3IubmFtZSB8fCAhZXhjZXB0aW9uTWFwW2RvbUVycm9yLm5hbWVdKQogICAgICAgIHJldHVybiBkb21FcnJvcjsKICAgIHZhciBydiA9IG5ldyBleGNlcHRpb25NYXBbZG9tRXJyb3IubmFtZV0obWVzc2FnZSB8fCBkb21FcnJvci5tZXNzYWdlLCBkb21FcnJvcik7CiAgICBpZiAoInN0YWNrIiBpbiBkb21FcnJvcikgewogICAgICAgIC8vIERlcml2ZSBzdGFjayBmcm9tIGlubmVyIGV4Y2VwdGlvbiBpZiBpdCBoYXMgYSBzdGFjawogICAgICAgIHNldFByb3AocnYsICJzdGFjayIsIHsgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5pbm5lci5zdGFjazsKICAgICAgICAgICAgfSB9KTsKICAgIH0KICAgIHJldHVybiBydjsKfQp2YXIgZnVsbE5hbWVFeGNlcHRpb25zID0gZXJyb3JMaXN0LnJlZHVjZShmdW5jdGlvbiAob2JqLCBuYW1lKSB7CiAgICBpZiAoWyJTeW50YXgiLCAiVHlwZSIsICJSYW5nZSJdLmluZGV4T2YobmFtZSkgPT09IC0xKQogICAgICAgIG9ialtuYW1lICsgIkVycm9yIl0gPSBleGNlcHRpb25zW25hbWVdOwogICAgcmV0dXJuIG9iajsKfSwge30pOwpmdWxsTmFtZUV4Y2VwdGlvbnMuTW9kaWZ5RXJyb3IgPSBNb2RpZnlFcnJvcjsKZnVsbE5hbWVFeGNlcHRpb25zLkRleGllRXJyb3IgPSBEZXhpZUVycm9yOwpmdWxsTmFtZUV4Y2VwdGlvbnMuQnVsa0Vycm9yID0gQnVsa0Vycm9yOwoKZnVuY3Rpb24gbm9wKCkgeyB9CmZ1bmN0aW9uIG1pcnJvcih2YWwpIHsgcmV0dXJuIHZhbDsgfQpmdW5jdGlvbiBwdXJlRnVuY3Rpb25DaGFpbihmMSwgZjIpIHsKICAgIC8vIEVuYWJsZXMgY2hhaW5lZCBldmVudHMgdGhhdCB0YWtlcyBPTkUgYXJndW1lbnQgYW5kIHJldHVybnMgaXQgdG8gdGhlIG5leHQgZnVuY3Rpb24gaW4gY2hhaW4uCiAgICAvLyBUaGlzIHBhdHRlcm4gaXMgdXNlZCBpbiB0aGUgaG9vaygicmVhZGluZyIpIGV2ZW50LgogICAgaWYgKGYxID09IG51bGwgfHwgZjEgPT09IG1pcnJvcikKICAgICAgICByZXR1cm4gZjI7CiAgICByZXR1cm4gZnVuY3Rpb24gKHZhbCkgewogICAgICAgIHJldHVybiBmMihmMSh2YWwpKTsKICAgIH07Cn0KZnVuY3Rpb24gY2FsbEJvdGgob24xLCBvbjIpIHsKICAgIHJldHVybiBmdW5jdGlvbiAoKSB7CiAgICAgICAgb24xLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgb24yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICB9Owp9CmZ1bmN0aW9uIGhvb2tDcmVhdGluZ0NoYWluKGYxLCBmMikgewogICAgLy8gRW5hYmxlcyBjaGFpbmVkIGV2ZW50cyB0aGF0IHRha2VzIHNldmVyYWwgYXJndW1lbnRzIGFuZCBtYXkgbW9kaWZ5IGZpcnN0IGFyZ3VtZW50IGJ5IG1ha2luZyBhIG1vZGlmaWNhdGlvbiBhbmQgdGhlbiByZXR1cm5pbmcgdGhlIHNhbWUgaW5zdGFuY2UuCiAgICAvLyBUaGlzIHBhdHRlcm4gaXMgdXNlZCBpbiB0aGUgaG9vaygiY3JlYXRpbmciKSBldmVudC4KICAgIGlmIChmMSA9PT0gbm9wKQogICAgICAgIHJldHVybiBmMjsKICAgIHJldHVybiBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIHJlcyA9IGYxLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgaWYgKHJlcyAhPT0gdW5kZWZpbmVkKQogICAgICAgICAgICBhcmd1bWVudHNbMF0gPSByZXM7CiAgICAgICAgdmFyIG9uc3VjY2VzcyA9IHRoaXMub25zdWNjZXNzLCAvLyBJbiBjYXNlIGV2ZW50IGxpc3RlbmVyIGhhcyBzZXQgdGhpcy5vbnN1Y2Nlc3MKICAgICAgICBvbmVycm9yID0gdGhpcy5vbmVycm9yOyAvLyBJbiBjYXNlIGV2ZW50IGxpc3RlbmVyIGhhcyBzZXQgdGhpcy5vbmVycm9yCiAgICAgICAgdGhpcy5vbnN1Y2Nlc3MgPSBudWxsOwogICAgICAgIHRoaXMub25lcnJvciA9IG51bGw7CiAgICAgICAgdmFyIHJlczIgPSBmMi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgIGlmIChvbnN1Y2Nlc3MpCiAgICAgICAgICAgIHRoaXMub25zdWNjZXNzID0gdGhpcy5vbnN1Y2Nlc3MgPyBjYWxsQm90aChvbnN1Y2Nlc3MsIHRoaXMub25zdWNjZXNzKSA6IG9uc3VjY2VzczsKICAgICAgICBpZiAob25lcnJvcikKICAgICAgICAgICAgdGhpcy5vbmVycm9yID0gdGhpcy5vbmVycm9yID8gY2FsbEJvdGgob25lcnJvciwgdGhpcy5vbmVycm9yKSA6IG9uZXJyb3I7CiAgICAgICAgcmV0dXJuIHJlczIgIT09IHVuZGVmaW5lZCA/IHJlczIgOiByZXM7CiAgICB9Owp9CmZ1bmN0aW9uIGhvb2tEZWxldGluZ0NoYWluKGYxLCBmMikgewogICAgaWYgKGYxID09PSBub3ApCiAgICAgICAgcmV0dXJuIGYyOwogICAgcmV0dXJuIGZ1bmN0aW9uICgpIHsKICAgICAgICBmMS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgIHZhciBvbnN1Y2Nlc3MgPSB0aGlzLm9uc3VjY2VzcywgLy8gSW4gY2FzZSBldmVudCBsaXN0ZW5lciBoYXMgc2V0IHRoaXMub25zdWNjZXNzCiAgICAgICAgb25lcnJvciA9IHRoaXMub25lcnJvcjsgLy8gSW4gY2FzZSBldmVudCBsaXN0ZW5lciBoYXMgc2V0IHRoaXMub25lcnJvcgogICAgICAgIHRoaXMub25zdWNjZXNzID0gdGhpcy5vbmVycm9yID0gbnVsbDsKICAgICAgICBmMi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgIGlmIChvbnN1Y2Nlc3MpCiAgICAgICAgICAgIHRoaXMub25zdWNjZXNzID0gdGhpcy5vbnN1Y2Nlc3MgPyBjYWxsQm90aChvbnN1Y2Nlc3MsIHRoaXMub25zdWNjZXNzKSA6IG9uc3VjY2VzczsKICAgICAgICBpZiAob25lcnJvcikKICAgICAgICAgICAgdGhpcy5vbmVycm9yID0gdGhpcy5vbmVycm9yID8gY2FsbEJvdGgob25lcnJvciwgdGhpcy5vbmVycm9yKSA6IG9uZXJyb3I7CiAgICB9Owp9CmZ1bmN0aW9uIGhvb2tVcGRhdGluZ0NoYWluKGYxLCBmMikgewogICAgaWYgKGYxID09PSBub3ApCiAgICAgICAgcmV0dXJuIGYyOwogICAgcmV0dXJuIGZ1bmN0aW9uIChtb2RpZmljYXRpb25zKSB7CiAgICAgICAgdmFyIHJlcyA9IGYxLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgZXh0ZW5kKG1vZGlmaWNhdGlvbnMsIHJlcyk7IC8vIElmIGYxIHJldHVybnMgbmV3IG1vZGlmaWNhdGlvbnMsIGV4dGVuZCBjYWxsZXIncyBtb2RpZmljYXRpb25zIHdpdGggdGhlIHJlc3VsdCBiZWZvcmUgY2FsbGluZyBuZXh0IGluIGNoYWluLgogICAgICAgIHZhciBvbnN1Y2Nlc3MgPSB0aGlzLm9uc3VjY2VzcywgLy8gSW4gY2FzZSBldmVudCBsaXN0ZW5lciBoYXMgc2V0IHRoaXMub25zdWNjZXNzCiAgICAgICAgb25lcnJvciA9IHRoaXMub25lcnJvcjsgLy8gSW4gY2FzZSBldmVudCBsaXN0ZW5lciBoYXMgc2V0IHRoaXMub25lcnJvcgogICAgICAgIHRoaXMub25zdWNjZXNzID0gbnVsbDsKICAgICAgICB0aGlzLm9uZXJyb3IgPSBudWxsOwogICAgICAgIHZhciByZXMyID0gZjIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICBpZiAob25zdWNjZXNzKQogICAgICAgICAgICB0aGlzLm9uc3VjY2VzcyA9IHRoaXMub25zdWNjZXNzID8gY2FsbEJvdGgob25zdWNjZXNzLCB0aGlzLm9uc3VjY2VzcykgOiBvbnN1Y2Nlc3M7CiAgICAgICAgaWYgKG9uZXJyb3IpCiAgICAgICAgICAgIHRoaXMub25lcnJvciA9IHRoaXMub25lcnJvciA/IGNhbGxCb3RoKG9uZXJyb3IsIHRoaXMub25lcnJvcikgOiBvbmVycm9yOwogICAgICAgIHJldHVybiByZXMgPT09IHVuZGVmaW5lZCA/CiAgICAgICAgICAgIChyZXMyID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiByZXMyKSA6CiAgICAgICAgICAgIChleHRlbmQocmVzLCByZXMyKSk7CiAgICB9Owp9CmZ1bmN0aW9uIHJldmVyc2VTdG9wcGFibGVFdmVudENoYWluKGYxLCBmMikgewogICAgaWYgKGYxID09PSBub3ApCiAgICAgICAgcmV0dXJuIGYyOwogICAgcmV0dXJuIGZ1bmN0aW9uICgpIHsKICAgICAgICBpZiAoZjIuYXBwbHkodGhpcywgYXJndW1lbnRzKSA9PT0gZmFsc2UpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gZjEuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgIH07Cn0KCmZ1bmN0aW9uIHByb21pc2FibGVDaGFpbihmMSwgZjIpIHsKICAgIGlmIChmMSA9PT0gbm9wKQogICAgICAgIHJldHVybiBmMjsKICAgIHJldHVybiBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIHJlcyA9IGYxLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgaWYgKHJlcyAmJiB0eXBlb2YgcmVzLnRoZW4gPT09ICdmdW5jdGlvbicpIHsKICAgICAgICAgICAgdmFyIHRoaXogPSB0aGlzLCBpID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShpKTsKICAgICAgICAgICAgd2hpbGUgKGktLSkKICAgICAgICAgICAgICAgIGFyZ3NbaV0gPSBhcmd1bWVudHNbaV07CiAgICAgICAgICAgIHJldHVybiByZXMudGhlbihmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZjIuYXBwbHkodGhpeiwgYXJncyk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZjIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgIH07Cn0KCi8qCiAqIENvcHlyaWdodCAoYykgMjAxNC0yMDE3IERhdmlkIEZhaGxhbmRlcgogKiBBcGFjaGUgTGljZW5zZSBWZXJzaW9uIDIuMCwgSmFudWFyeSAyMDA0LCBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICovCi8vCi8vIFByb21pc2UgYW5kIFpvbmUgKFBTRCkgZm9yIERleGllIGxpYnJhcnkKLy8KLy8gSSBzdGFydGVkIG91dCB3cml0aW5nIHRoaXMgUHJvbWlzZSBjbGFzcyBieSBjb3B5aW5nIHByb21pc2UtbGlnaHQgKGh0dHBzOi8vZ2l0aHViLmNvbS90YXlsb3JoYWtlcy9wcm9taXNlLWxpZ2h0KSBieQovLyBodHRwczovL2dpdGh1Yi5jb20vdGF5bG9yaGFrZXMgLSBhbiBBKyBhbmQgRUNNQVNDUklQVCA2IGNvbXBsaWFudCBQcm9taXNlIGltcGxlbWVudGF0aW9uLgovLwovLyBJbiBwcmV2aW91cyB2ZXJzaW9ucyB0aGlzIHdhcyBmaXhlZCBieSBub3QgY2FsbGluZyBzZXRUaW1lb3V0IHdoZW4ga25vd2luZyB0aGF0IHRoZSByZXNvbHZlKCkgb3IgcmVqZWN0KCkgY2FtZSBmcm9tIGFub3RoZXIKLy8gdGljay4gSW4gRGV4aWUgdjEuNC4wLCBJJ3ZlIHJld3JpdHRlbiB0aGUgUHJvbWlzZSBjbGFzcyBlbnRpcmVseS4gSnVzdCBzb21lIGZyYWdtZW50cyBvZiBwcm9taXNlLWxpZ2h0IGlzIGxlZnQuIEkgdXNlCi8vIGFub3RoZXIgc3RyYXRlZ3kgbm93IHRoYXQgc2ltcGxpZmllcyBldmVyeXRoaW5nIGEgbG90OiB0byBhbHdheXMgZXhlY3V0ZSBjYWxsYmFja3MgaW4gYSBuZXcgbWljcm8tdGFzaywgYnV0IGhhdmUgYW4gb3duIG1pY3JvLXRhc2sKLy8gZW5naW5lIHRoYXQgaXMgaW5kZXhlZERCIGNvbXBsaWFudCBhY3Jvc3MgYWxsIGJyb3dzZXJzLgovLyBQcm9taXNlIGNsYXNzIGhhcyBhbHNvIGJlZW4gb3B0aW1pemVkIGEgbG90IHdpdGggaW5zcGlyYXRpb24gZnJvbSBibHVlYmlyZCAtIHRvIGF2b2lkIGNsb3N1cmVzIGFzIG11Y2ggYXMgcG9zc2libGUuCi8vIEFsc28gd2l0aCBpbnNwaXJhdGlvbiBmcm9tIGJsdWViaXJkLCBhc3luY3JvbmljIHN0YWNrcyBpbiBkZWJ1ZyBtb2RlLgovLwovLyBTcGVjaWZpYyBub24tc3RhbmRhcmQgZmVhdHVyZXMgb2YgdGhpcyBQcm9taXNlIGNsYXNzOgovLyAqIEN1c3RvbSB6b25lIHN1cHBvcnQgKGEuay5hLiBQU0QpIHdpdGggYWJpbGl0eSB0byBrZWVwIHpvbmVzIGFsc28gd2hlbiB1c2luZyBuYXRpdmUgcHJvbWlzZXMgYXMgd2VsbCBhcwovLyAgIG5hdGl2ZSBhc3luYyAvIGF3YWl0LgovLyAqIFByb21pc2UuZm9sbG93KCkgbWV0aG9kIGJ1aWx0IHVwb24gdGhlIGN1c3RvbSB6b25lIGVuZ2luZSwgdGhhdCBhbGxvd3MgdXNlciB0byB0cmFjayBhbGwgcHJvbWlzZXMgY3JlYXRlZCBmcm9tIGN1cnJlbnQgc3RhY2sgZnJhbWUKLy8gICBhbmQgYmVsb3cgKyBhbGwgcHJvbWlzZXMgdGhhdCB0aG9zZSBwcm9taXNlcyBjcmVhdGVzIG9yIGF3YWl0cy4KLy8gKiBEZXRlY3QgYW55IHVuaGFuZGxlZCBwcm9taXNlIGluIGEgUFNELXNjb3BlIChQU0Qub251bmhhbmRsZWQpLiAKLy8KLy8gRGF2aWQgRmFobGFuZGVyLCBodHRwczovL2dpdGh1Yi5jb20vZGZhaGxhbmRlcgovLwovLyBKdXN0IGEgcG9pbnRlciB0aGF0IG9ubHkgdGhpcyBtb2R1bGUga25vd3MgYWJvdXQuCi8vIFVzZWQgaW4gUHJvbWlzZSBjb25zdHJ1Y3RvciB0byBlbXVsYXRlIGEgcHJpdmF0ZSBjb25zdHJ1Y3Rvci4KdmFyIElOVEVSTkFMID0ge307Ci8vIEFzeW5jIHN0YWNrcyAobG9uZyBzdGFja3MpIG11c3Qgbm90IGdyb3cgaW5maW5pdGVseS4KdmFyIExPTkdfU1RBQ0tTX0NMSVBfTElNSVQgPSAxMDA7CnZhciBNQVhfTE9OR19TVEFDS1MgPSAyMDsKdmFyIFpPTkVfRUNIT19MSU1JVCA9IDc7CnZhciBuYXRpdmVQcm9taXNlSW5zdGFuY2VBbmRQcm90byA9IChmdW5jdGlvbiAoKSB7CiAgICB0cnkgewogICAgICAgIC8vIEJlIGFibGUgdG8gcGF0Y2ggbmF0aXZlIGFzeW5jIGZ1bmN0aW9ucwogICAgICAgIHJldHVybiBuZXcgRnVuY3Rpb24oImxldCBGPWFzeW5jICgpPT57fSxwPUYoKTtyZXR1cm4gW3AsT2JqZWN0LmdldFByb3RvdHlwZU9mKHApLFByb21pc2UucmVzb2x2ZSgpLEYuY29uc3RydWN0b3JdOyIpKCk7CiAgICB9CiAgICBjYXRjaCAoZSkgewogICAgICAgIHZhciBQID0gX2dsb2JhbC5Qcm9taXNlOwogICAgICAgIHJldHVybiBQID8KICAgICAgICAgICAgW1AucmVzb2x2ZSgpLCBQLnByb3RvdHlwZSwgUC5yZXNvbHZlKCldIDoKICAgICAgICAgICAgW107CiAgICB9Cn0pKCk7CnZhciByZXNvbHZlZE5hdGl2ZVByb21pc2UgPSBuYXRpdmVQcm9taXNlSW5zdGFuY2VBbmRQcm90b1swXTsKdmFyIG5hdGl2ZVByb21pc2VQcm90byA9IG5hdGl2ZVByb21pc2VJbnN0YW5jZUFuZFByb3RvWzFdOwp2YXIgcmVzb2x2ZWRHbG9iYWxQcm9taXNlID0gbmF0aXZlUHJvbWlzZUluc3RhbmNlQW5kUHJvdG9bMl07CnZhciBuYXRpdmVQcm9taXNlVGhlbiA9IG5hdGl2ZVByb21pc2VQcm90byAmJiBuYXRpdmVQcm9taXNlUHJvdG8udGhlbjsKdmFyIE5hdGl2ZVByb21pc2UgPSByZXNvbHZlZE5hdGl2ZVByb21pc2UgJiYgcmVzb2x2ZWROYXRpdmVQcm9taXNlLmNvbnN0cnVjdG9yOwp2YXIgQXN5bmNGdW5jdGlvbiA9IG5hdGl2ZVByb21pc2VJbnN0YW5jZUFuZFByb3RvWzNdOwp2YXIgcGF0Y2hHbG9iYWxQcm9taXNlID0gISFyZXNvbHZlZEdsb2JhbFByb21pc2U7CnZhciBzdGFja19iZWluZ19nZW5lcmF0ZWQgPSBmYWxzZTsKLyogVGhlIGRlZmF1bHQgZnVuY3Rpb24gdXNlZCBvbmx5IGZvciB0aGUgdmVyeSBmaXJzdCBwcm9taXNlIGluIGEgcHJvbWlzZSBjaGFpbi4KICAgQXMgc29vbiBhcyB0aGVuIHByb21pc2UgaXMgcmVzb2x2ZWQgb3IgcmVqZWN0ZWQsIGFsbCBuZXh0IHRhc2tzIHdpbGwgYmUgZXhlY3V0ZWQgaW4gbWljcm8gdGlja3MKICAgZW11bGF0ZWQgaW4gdGhpcyBtb2R1bGUuIEZvciBpbmRleGVkREIgY29tcGF0aWJpbGl0eSwgdGhpcyBtZWFucyB0aGF0IGV2ZXJ5IG1ldGhvZCBuZWVkcyB0bwogICBleGVjdXRlIGF0IGxlYXN0IG9uZSBwcm9taXNlIGJlZm9yZSBkb2luZyBhbiBpbmRleGVkREIgb3BlcmF0aW9uLiBEZXhpZSB3aWxsIGFsd2F5cyBjYWxsCiAgIGRiLnJlYWR5KCkudGhlbigpIGZvciBldmVyeSBvcGVyYXRpb24gdG8gbWFrZSBzdXJlIHRoZSBpbmRleGVkREIgZXZlbnQgaXMgc3RhcnRlZCBpbiBhbgogICBpbmRleGVkREItY29tcGF0aWJsZSBlbXVsYXRlZCBtaWNybyB0YXNrIGxvb3AuCiovCnZhciBzY2hlZHVsZVBoeXNpY2FsVGljayA9IHJlc29sdmVkR2xvYmFsUHJvbWlzZSA/CiAgICBmdW5jdGlvbiAoKSB7IHJlc29sdmVkR2xvYmFsUHJvbWlzZS50aGVuKHBoeXNpY2FsVGljayk7IH0KICAgIDoKICAgICAgICBfZ2xvYmFsLnNldEltbWVkaWF0ZSA/CiAgICAgICAgICAgIC8vIHNldEltbWVkaWF0ZSBzdXBwb3J0ZWQuIFRob3NlIG1vZGVybiBwbGF0Zm9ybXMgYWxzbyBzdXBwb3J0cyBGdW5jdGlvbi5iaW5kKCkuCiAgICAgICAgICAgIHNldEltbWVkaWF0ZS5iaW5kKG51bGwsIHBoeXNpY2FsVGljaykgOgogICAgICAgICAgICBfZ2xvYmFsLk11dGF0aW9uT2JzZXJ2ZXIgPwogICAgICAgICAgICAgICAgLy8gTXV0YXRpb25PYnNlcnZlciBzdXBwb3J0ZWQKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgaGlkZGVuRGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2Iik7CiAgICAgICAgICAgICAgICAgICAgKG5ldyBNdXRhdGlvbk9ic2VydmVyKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGh5c2ljYWxUaWNrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGhpZGRlbkRpdiA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgfSkpLm9ic2VydmUoaGlkZGVuRGl2LCB7IGF0dHJpYnV0ZXM6IHRydWUgfSk7CiAgICAgICAgICAgICAgICAgICAgaGlkZGVuRGl2LnNldEF0dHJpYnV0ZSgnaScsICcxJyk7CiAgICAgICAgICAgICAgICB9IDoKICAgICAgICAgICAgICAgIC8vIE5vIHN1cHBvcnQgZm9yIHNldEltbWVkaWF0ZSBvciBNdXRhdGlvbk9ic2VydmVyLiBObyB3b3JyeSwgc2V0VGltZW91dCBpcyBvbmx5IGNhbGxlZAogICAgICAgICAgICAgICAgLy8gb25jZSB0aW1lLiBFdmVyeSB0aWNrIHRoYXQgZm9sbG93cyB3aWxsIGJlIG91ciBlbXVsYXRlZCBtaWNybyB0aWNrLgogICAgICAgICAgICAgICAgLy8gQ291bGQgaGF2ZSB1c2VzIHNldFRpbWVvdXQuYmluZChudWxsLCAwLCBwaHlzaWNhbFRpY2spIGlmIGl0IHdhc250IGZvciB0aGF0IEZGMTMgYW5kIGJlbG93IGhhcyBhIGJ1ZyAKICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgpIHsgc2V0VGltZW91dChwaHlzaWNhbFRpY2ssIDApOyB9OwovLyBDb25maWd1cmFibGUgdGhyb3VnaCBQcm9taXNlLnNjaGVkdWxlci4KLy8gRG9uJ3QgZXhwb3J0IGJlY2F1c2UgaXQgd291bGQgYmUgdW5zYWZlIHRvIGxldCB1bmtub3duCi8vIGNvZGUgY2FsbCBpdCB1bmxlc3MgdGhleSBkbyB0cnkuLmNhdGNoIHdpdGhpbiB0aGVpciBjYWxsYmFjay4KLy8gVGhpcyBmdW5jdGlvbiBjYW4gYmUgcmV0cmlldmVkIHRocm91Z2ggZ2V0dGVyIG9mIFByb21pc2Uuc2NoZWR1bGVyIHRob3VnaCwKLy8gYnV0IHVzZXJzIG11c3Qgbm90IGRvIFByb21pc2Uuc2NoZWR1bGVyID0gbXlGdW5jVGhhdFRocm93c0V4Y2VwdGlvbgp2YXIgYXNhcCQxID0gZnVuY3Rpb24gKGNhbGxiYWNrLCBhcmdzKSB7CiAgICBtaWNyb3RpY2tRdWV1ZS5wdXNoKFtjYWxsYmFjaywgYXJnc10pOwogICAgaWYgKG5lZWRzTmV3UGh5c2ljYWxUaWNrKSB7CiAgICAgICAgc2NoZWR1bGVQaHlzaWNhbFRpY2soKTsKICAgICAgICBuZWVkc05ld1BoeXNpY2FsVGljayA9IGZhbHNlOwogICAgfQp9Owp2YXIgaXNPdXRzaWRlTWljcm9UaWNrID0gdHJ1ZTsKdmFyIG5lZWRzTmV3UGh5c2ljYWxUaWNrID0gdHJ1ZTsKdmFyIHVuaGFuZGxlZEVycm9ycyA9IFtdOwp2YXIgcmVqZWN0aW5nRXJyb3JzID0gW107CnZhciBjdXJyZW50RnVsZmlsbGVyID0gbnVsbDsKdmFyIHJlamVjdGlvbk1hcHBlciA9IG1pcnJvcjsgLy8gUmVtb3ZlIGluIG5leHQgbWFqb3Igd2hlbiByZW1vdmluZyBlcnJvciBtYXBwaW5nIG9mIERPTUVycm9ycyBhbmQgRE9NRXhjZXB0aW9ucwp2YXIgZ2xvYmFsUFNEID0gewogICAgaWQ6ICdnbG9iYWwnLAogICAgZ2xvYmFsOiB0cnVlLAogICAgcmVmOiAwLAogICAgdW5oYW5kbGVkczogW10sCiAgICBvbnVuaGFuZGxlZDogZ2xvYmFsRXJyb3IsCiAgICBwZ3A6IGZhbHNlLAogICAgZW52OiB7fSwKICAgIGZpbmFsaXplOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgdGhpcy51bmhhbmRsZWRzLmZvckVhY2goZnVuY3Rpb24gKHVoKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBnbG9iYWxFcnJvcih1aFswXSwgdWhbMV0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNhdGNoIChlKSB7IH0KICAgICAgICB9KTsKICAgIH0KfTsKdmFyIFBTRCA9IGdsb2JhbFBTRDsKdmFyIG1pY3JvdGlja1F1ZXVlID0gW107IC8vIENhbGxiYWNrcyB0byBjYWxsIGluIHRoaXMgb3IgbmV4dCBwaHlzaWNhbCB0aWNrLgp2YXIgbnVtU2NoZWR1bGVkQ2FsbHMgPSAwOyAvLyBOdW1iZXIgb2YgbGlzdGVuZXItY2FsbHMgbGVmdCB0byBkbyBpbiB0aGlzIHBoeXNpY2FsIHRpY2suCnZhciB0aWNrRmluYWxpemVycyA9IFtdOyAvLyBGaW5hbGl6ZXJzIHRvIGNhbGwgd2hlbiB0aGVyZSBhcmUgbm8gbW9yZSBhc3luYyBjYWxscyBzY2hlZHVsZWQgd2l0aGluIGN1cnJlbnQgcGh5c2ljYWwgdGljay4KZnVuY3Rpb24gUHJvbWlzZShmbikgewogICAgaWYgKHR5cGVvZiB0aGlzICE9PSAnb2JqZWN0JykKICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdQcm9taXNlcyBtdXN0IGJlIGNvbnN0cnVjdGVkIHZpYSBuZXcnKTsKICAgIHRoaXMuX2xpc3RlbmVycyA9IFtdOwogICAgdGhpcy5vbnVuY2F0Y2hlZCA9IG5vcDsgLy8gRGVwcmVjYXRlIGluIG5leHQgbWFqb3IuIE5vdCBuZWVkZWQuIEJldHRlciB0byB1c2UgZ2xvYmFsIGVycm9yIGhhbmRsZXIuCiAgICAvLyBBIGxpYnJhcnkgbWF5IHNldCBgcHJvbWlzZS5fbGliID0gdHJ1ZTtgIGFmdGVyIHByb21pc2UgaXMgY3JlYXRlZCB0byBtYWtlIHJlc29sdmUoKSBvciByZWplY3QoKQogICAgLy8gZXhlY3V0ZSB0aGUgbWljcm90YXNrIGVuZ2luZSBpbXBsaWNpdGVseSB3aXRoaW4gdGhlIGNhbGwgdG8gcmVzb2x2ZSgpIG9yIHJlamVjdCgpLgogICAgLy8gVG8gcmVtYWluIEErIGNvbXBsaWFudCwgYSBsaWJyYXJ5IG11c3Qgb25seSBzZXQgYF9saWI9dHJ1ZWAgaWYgaXQgY2FuIGd1YXJhbnRlZSB0aGF0IHRoZSBzdGFjawogICAgLy8gb25seSBjb250YWlucyBsaWJyYXJ5IGNvZGUgd2hlbiBjYWxsaW5nIHJlc29sdmUoKSBvciByZWplY3QoKS4KICAgIC8vIFJVTEUgT0YgVEhVTUI6IE9OTFkgc2V0IF9saWIgPSB0cnVlIGZvciBwcm9taXNlcyBleHBsaWNpdGVseSByZXNvbHZpbmcvcmVqZWN0aW5nIGRpcmVjdGx5IGZyb20KICAgIC8vIGdsb2JhbCBzY29wZSAoZXZlbnQgaGFuZGxlciwgdGltZXIgZXRjKSEKICAgIHRoaXMuX2xpYiA9IGZhbHNlOwogICAgLy8gQ3VycmVudCBhc3luYyBzY29wZQogICAgdmFyIHBzZCA9ICh0aGlzLl9QU0QgPSBQU0QpOwogICAgaWYgKGRlYnVnKSB7CiAgICAgICAgdGhpcy5fc3RhY2tIb2xkZXIgPSBnZXRFcnJvcldpdGhTdGFjaygpOwogICAgICAgIHRoaXMuX3ByZXYgPSBudWxsOwogICAgICAgIHRoaXMuX251bVByZXYgPSAwOyAvLyBOdW1iZXIgb2YgcHJldmlvdXMgcHJvbWlzZXMgKGZvciBsb25nIHN0YWNrcykKICAgIH0KICAgIGlmICh0eXBlb2YgZm4gIT09ICdmdW5jdGlvbicpIHsKICAgICAgICBpZiAoZm4gIT09IElOVEVSTkFMKQogICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdOb3QgYSBmdW5jdGlvbicpOwogICAgICAgIC8vIFByaXZhdGUgY29uc3RydWN0b3IgKElOVEVSTkFMLCBzdGF0ZSwgdmFsdWUpLgogICAgICAgIC8vIFVzZWQgaW50ZXJuYWxseSBieSBQcm9taXNlLnJlc29sdmUoKSBhbmQgUHJvbWlzZS5yZWplY3QoKS4KICAgICAgICB0aGlzLl9zdGF0ZSA9IGFyZ3VtZW50c1sxXTsKICAgICAgICB0aGlzLl92YWx1ZSA9IGFyZ3VtZW50c1syXTsKICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09IGZhbHNlKQogICAgICAgICAgICBoYW5kbGVSZWplY3Rpb24odGhpcywgdGhpcy5fdmFsdWUpOyAvLyBNYXAgZXJyb3IsIHNldCBzdGFjayBhbmQgYWRkUG9zc2libHlVbmhhbmRsZWRFcnJvcigpLgogICAgICAgIHJldHVybjsKICAgIH0KICAgIHRoaXMuX3N0YXRlID0gbnVsbDsgLy8gbnVsbCAoPXBlbmRpbmcpLCBmYWxzZSAoPXJlamVjdGVkKSBvciB0cnVlICg9cmVzb2x2ZWQpCiAgICB0aGlzLl92YWx1ZSA9IG51bGw7IC8vIGVycm9yIG9yIHJlc3VsdAogICAgKytwc2QucmVmOyAvLyBSZWZjb3VudGluZyBjdXJyZW50IHNjb3BlCiAgICBleGVjdXRlUHJvbWlzZVRhc2sodGhpcywgZm4pOwp9Ci8vIFByZXBhcmUgYSBwcm9wZXJ0eSBkZXNjcmlwdG9yIHRvIHB1dCBvbnRvIFByb21pc2UucHJvdG90eXBlLnRoZW4KdmFyIHRoZW5Qcm9wID0gewogICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIHBzZCA9IFBTRCwgbWljcm9UYXNrSWQgPSB0b3RhbEVjaG9lczsKICAgICAgICBmdW5jdGlvbiB0aGVuKG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKSB7CiAgICAgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7CiAgICAgICAgICAgIHZhciBwb3NzaWJsZUF3YWl0ID0gIXBzZC5nbG9iYWwgJiYgKHBzZCAhPT0gUFNEIHx8IG1pY3JvVGFza0lkICE9PSB0b3RhbEVjaG9lcyk7CiAgICAgICAgICAgIGlmIChwb3NzaWJsZUF3YWl0KQogICAgICAgICAgICAgICAgZGVjcmVtZW50RXhwZWN0ZWRBd2FpdHMoKTsKICAgICAgICAgICAgdmFyIHJ2ID0gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkgewogICAgICAgICAgICAgICAgcHJvcGFnYXRlVG9MaXN0ZW5lcihfdGhpcywgbmV3IExpc3RlbmVyKG5hdGl2ZUF3YWl0Q29tcGF0aWJsZVdyYXAob25GdWxmaWxsZWQsIHBzZCwgcG9zc2libGVBd2FpdCksIG5hdGl2ZUF3YWl0Q29tcGF0aWJsZVdyYXAob25SZWplY3RlZCwgcHNkLCBwb3NzaWJsZUF3YWl0KSwgcmVzb2x2ZSwgcmVqZWN0LCBwc2QpKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGRlYnVnICYmIGxpbmtUb1ByZXZpb3VzUHJvbWlzZShydiwgdGhpcyk7CiAgICAgICAgICAgIHJldHVybiBydjsKICAgICAgICB9CiAgICAgICAgdGhlbi5wcm90b3R5cGUgPSBJTlRFUk5BTDsgLy8gRm9yIGlkZW1wb3RlbnNlLCBzZWUgc2V0dGVyIGJlbG93LgogICAgICAgIHJldHVybiB0aGVuOwogICAgfSwKICAgIC8vIEJlIGlkZW1wb3RlbnQgYW5kIGFsbG93IGFub3RoZXIgZnJhbWV3b3JrIChzdWNoIGFzIHpvbmUuanMgb3IgYW5vdGhlciBpbnN0YW5jZSBvZiBhIERleGllLlByb21pc2UgbW9kdWxlKSB0byByZXBsYWNlIFByb21pc2UucHJvdG90eXBlLnRoZW4KICAgIC8vIGFuZCB3aGVuIHRoYXQgZnJhbWV3b3JrIHdhbnRzIHRvIHJlc3RvcmUgdGhlIG9yaWdpbmFsIHByb3BlcnR5LCB3ZSBtdXN0IGlkZW50aWZ5IHRoYXQgYW5kIHJlc3RvcmUgdGhlIG9yaWdpbmFsIHByb3BlcnR5IGRlc2NyaXB0b3IuCiAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgIHNldFByb3AodGhpcywgJ3RoZW4nLCB2YWx1ZSAmJiB2YWx1ZS5wcm90b3R5cGUgPT09IElOVEVSTkFMID8KICAgICAgICAgICAgdGhlblByb3AgOiAvLyBSZXN0b3JlIHRvIG9yaWdpbmFsIHByb3BlcnR5IGRlc2NyaXB0b3IuCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTsgLy8gR2V0dGVyIHJldHVybmluZyBwcm92aWRlZCB2YWx1ZSAoYmVoYXZlcyBsaWtlIHZhbHVlIGlzIGp1c3QgY2hhbmdlZCkKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBzZXQ6IHRoZW5Qcm9wLnNldCAvLyBLZWVwIGEgc2V0dGVyIHRoYXQgaXMgcHJlcGFyZWQgdG8gcmVzdG9yZSBvcmlnaW5hbC4KICAgICAgICAgICAgfSk7CiAgICB9Cn07CnByb3BzKFByb21pc2UucHJvdG90eXBlLCB7CiAgICB0aGVuOiB0aGVuUHJvcCwKICAgIF90aGVuOiBmdW5jdGlvbiAob25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpIHsKICAgICAgICAvLyBBIGxpdHRsZSB0aW5pZXIgdmVyc2lvbiBvZiB0aGVuKCkgdGhhdCBkb24ndCBoYXZlIHRvIGNyZWF0ZSBhIHJlc3VsdGluZyBwcm9taXNlLgogICAgICAgIHByb3BhZ2F0ZVRvTGlzdGVuZXIodGhpcywgbmV3IExpc3RlbmVyKG51bGwsIG51bGwsIG9uRnVsZmlsbGVkLCBvblJlamVjdGVkLCBQU0QpKTsKICAgIH0sCiAgICBjYXRjaDogZnVuY3Rpb24gKG9uUmVqZWN0ZWQpIHsKICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkKICAgICAgICAgICAgcmV0dXJuIHRoaXMudGhlbihudWxsLCBvblJlamVjdGVkKTsKICAgICAgICAvLyBGaXJzdCBhcmd1bWVudCBpcyB0aGUgRXJyb3IgdHlwZSB0byBjYXRjaAogICAgICAgIHZhciB0eXBlID0gYXJndW1lbnRzWzBdLCBoYW5kbGVyID0gYXJndW1lbnRzWzFdOwogICAgICAgIHJldHVybiB0eXBlb2YgdHlwZSA9PT0gJ2Z1bmN0aW9uJyA/IHRoaXMudGhlbihudWxsLCBmdW5jdGlvbiAoZXJyKSB7CiAgICAgICAgICAgIC8vIENhdGNoaW5nIGVycm9ycyBieSBpdHMgY29uc3RydWN0b3IgdHlwZSAoc2ltaWxhciB0byBqYXZhIC8gYysrIC8gYyMpCiAgICAgICAgICAgIC8vIFNhbXBsZTogcHJvbWlzZS5jYXRjaChUeXBlRXJyb3IsIGZ1bmN0aW9uIChlKSB7IC4uLiB9KTsKICAgICAgICAgICAgcmV0dXJuIGVyciBpbnN0YW5jZW9mIHR5cGUgPyBoYW5kbGVyKGVycikgOiBQcm9taXNlUmVqZWN0KGVycik7CiAgICAgICAgfSkKICAgICAgICAgICAgOiB0aGlzLnRoZW4obnVsbCwgZnVuY3Rpb24gKGVycikgewogICAgICAgICAgICAgICAgLy8gQ2F0Y2hpbmcgZXJyb3JzIGJ5IHRoZSBlcnJvci5uYW1lIHByb3BlcnR5LiBNYWtlcyBzZW5zZSBmb3IgaW5kZXhlZERCIHdoZXJlIGVycm9yIHR5cGUKICAgICAgICAgICAgICAgIC8vIGlzIGFsd2F5cyBET01FcnJvciBidXQgd2hlcmUgZS5uYW1lIHRlbGxzIHRoZSBhY3R1YWwgZXJyb3IgdHlwZS4KICAgICAgICAgICAgICAgIC8vIFNhbXBsZTogcHJvbWlzZS5jYXRjaCgnQ29uc3RyYWludEVycm9yJywgZnVuY3Rpb24gKGUpIHsgLi4uIH0pOwogICAgICAgICAgICAgICAgcmV0dXJuIGVyciAmJiBlcnIubmFtZSA9PT0gdHlwZSA/IGhhbmRsZXIoZXJyKSA6IFByb21pc2VSZWplY3QoZXJyKTsKICAgICAgICAgICAgfSk7CiAgICB9LAogICAgZmluYWxseTogZnVuY3Rpb24gKG9uRmluYWxseSkgewogICAgICAgIHJldHVybiB0aGlzLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgIG9uRmluYWxseSgpOwogICAgICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgICAgfSwgZnVuY3Rpb24gKGVycikgewogICAgICAgICAgICBvbkZpbmFsbHkoKTsKICAgICAgICAgICAgcmV0dXJuIFByb21pc2VSZWplY3QoZXJyKTsKICAgICAgICB9KTsKICAgIH0sCiAgICBzdGFjazogewogICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICBpZiAodGhpcy5fc3RhY2spCiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fc3RhY2s7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBzdGFja19iZWluZ19nZW5lcmF0ZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgdmFyIHN0YWNrcyA9IGdldFN0YWNrKHRoaXMsIFtdLCBNQVhfTE9OR19TVEFDS1MpOwogICAgICAgICAgICAgICAgdmFyIHN0YWNrID0gc3RhY2tzLmpvaW4oIlxuRnJvbSBwcmV2aW91czogIik7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgIT09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhY2sgPSBzdGFjazsgLy8gU3RhY2sgbWF5IGJlIHVwZGF0ZWQgb24gcmVqZWN0LgogICAgICAgICAgICAgICAgcmV0dXJuIHN0YWNrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZpbmFsbHkgewogICAgICAgICAgICAgICAgc3RhY2tfYmVpbmdfZ2VuZXJhdGVkID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LAogICAgdGltZW91dDogZnVuY3Rpb24gKG1zLCBtc2cpIHsKICAgICAgICB2YXIgX3RoaXMgPSB0aGlzOwogICAgICAgIHJldHVybiBtcyA8IEluZmluaXR5ID8KICAgICAgICAgICAgbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkgewogICAgICAgICAgICAgICAgdmFyIGhhbmRsZSA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgeyByZXR1cm4gcmVqZWN0KG5ldyBleGNlcHRpb25zLlRpbWVvdXQobXNnKSk7IH0sIG1zKTsKICAgICAgICAgICAgICAgIF90aGlzLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KS5maW5hbGx5KGNsZWFyVGltZW91dC5iaW5kKG51bGwsIGhhbmRsZSkpOwogICAgICAgICAgICB9KSA6IHRoaXM7CiAgICB9Cn0pOwppZiAodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKQogICAgc2V0UHJvcChQcm9taXNlLnByb3RvdHlwZSwgU3ltYm9sLnRvU3RyaW5nVGFnLCAnUHJvbWlzZScpOwovLyBOb3cgdGhhdCBQcm9taXNlLnByb3RvdHlwZSBpcyBkZWZpbmVkLCB3ZSBoYXZlIGFsbCBpdCB0YWtlcyB0byBzZXQgZ2xvYmFsUFNELmVudi4KLy8gRW52aXJvbm1lbnQgZ2xvYmFscyBzbmFwc2hvdHRlZCBvbiBsZWF2aW5nIGdsb2JhbCB6b25lCmdsb2JhbFBTRC5lbnYgPSBzbmFwU2hvdCgpOwpmdW5jdGlvbiBMaXN0ZW5lcihvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCwgcmVzb2x2ZSwgcmVqZWN0LCB6b25lKSB7CiAgICB0aGlzLm9uRnVsZmlsbGVkID0gdHlwZW9mIG9uRnVsZmlsbGVkID09PSAnZnVuY3Rpb24nID8gb25GdWxmaWxsZWQgOiBudWxsOwogICAgdGhpcy5vblJlamVjdGVkID0gdHlwZW9mIG9uUmVqZWN0ZWQgPT09ICdmdW5jdGlvbicgPyBvblJlamVjdGVkIDogbnVsbDsKICAgIHRoaXMucmVzb2x2ZSA9IHJlc29sdmU7CiAgICB0aGlzLnJlamVjdCA9IHJlamVjdDsKICAgIHRoaXMucHNkID0gem9uZTsKfQovLyBQcm9taXNlIFN0YXRpYyBQcm9wZXJ0aWVzCnByb3BzKFByb21pc2UsIHsKICAgIGFsbDogZnVuY3Rpb24gKCkgewogICAgICAgIHZhciB2YWx1ZXMgPSBnZXRBcnJheU9mLmFwcGx5KG51bGwsIGFyZ3VtZW50cykgLy8gU3VwcG9ydHMgaXRlcmFibGVzLCBpbXBsaWNpdCBhcmd1bWVudHMgYW5kIGFycmF5LWxpa2UuCiAgICAgICAgICAgIC5tYXAob25Qb3NzaWJsZVBhcmFsbGVsbEFzeW5jKTsgLy8gSGFuZGxlIHBhcmFsbGVsbCBhc3luYy9hd2FpdHMgCiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHsKICAgICAgICAgICAgaWYgKHZhbHVlcy5sZW5ndGggPT09IDApCiAgICAgICAgICAgICAgICByZXNvbHZlKFtdKTsKICAgICAgICAgICAgdmFyIHJlbWFpbmluZyA9IHZhbHVlcy5sZW5ndGg7CiAgICAgICAgICAgIHZhbHVlcy5mb3JFYWNoKGZ1bmN0aW9uIChhLCBpKSB7IHJldHVybiBQcm9taXNlLnJlc29sdmUoYSkudGhlbihmdW5jdGlvbiAoeCkgewogICAgICAgICAgICAgICAgdmFsdWVzW2ldID0geDsKICAgICAgICAgICAgICAgIGlmICghLS1yZW1haW5pbmcpCiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh2YWx1ZXMpOwogICAgICAgICAgICB9LCByZWplY3QpOyB9KTsKICAgICAgICB9KTsKICAgIH0sCiAgICByZXNvbHZlOiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlKQogICAgICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgICAgaWYgKHZhbHVlICYmIHR5cGVvZiB2YWx1ZS50aGVuID09PSAnZnVuY3Rpb24nKQogICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkgewogICAgICAgICAgICAgICAgdmFsdWUudGhlbihyZXNvbHZlLCByZWplY3QpOwogICAgICAgICAgICB9KTsKICAgICAgICB2YXIgcnYgPSBuZXcgUHJvbWlzZShJTlRFUk5BTCwgdHJ1ZSwgdmFsdWUpOwogICAgICAgIGxpbmtUb1ByZXZpb3VzUHJvbWlzZShydiwgY3VycmVudEZ1bGZpbGxlcik7CiAgICAgICAgcmV0dXJuIHJ2OwogICAgfSwKICAgIHJlamVjdDogUHJvbWlzZVJlamVjdCwKICAgIHJhY2U6IGZ1bmN0aW9uICgpIHsKICAgICAgICB2YXIgdmFsdWVzID0gZ2V0QXJyYXlPZi5hcHBseShudWxsLCBhcmd1bWVudHMpLm1hcChvblBvc3NpYmxlUGFyYWxsZWxsQXN5bmMpOwogICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7CiAgICAgICAgICAgIHZhbHVlcy5tYXAoZnVuY3Rpb24gKHZhbHVlKSB7IHJldHVybiBQcm9taXNlLnJlc29sdmUodmFsdWUpLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTsgfSk7CiAgICAgICAgfSk7CiAgICB9LAogICAgUFNEOiB7CiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBQU0Q7IH0sCiAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHsgcmV0dXJuIFBTRCA9IHZhbHVlOyB9CiAgICB9LAogICAgLy90b3RhbEVjaG9lczoge2dldDogKCk9PnRvdGFsRWNob2VzfSwKICAgIC8vdGFzazoge2dldDogKCk9PnRhc2t9LAogICAgbmV3UFNEOiBuZXdTY29wZSwKICAgIHVzZVBTRDogdXNlUFNELAogICAgc2NoZWR1bGVyOiB7CiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBhc2FwJDE7IH0sCiAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHsgYXNhcCQxID0gdmFsdWU7IH0KICAgIH0sCiAgICByZWplY3Rpb25NYXBwZXI6IHsKICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHJlamVjdGlvbk1hcHBlcjsgfSwKICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkgeyByZWplY3Rpb25NYXBwZXIgPSB2YWx1ZTsgfSAvLyBNYXAgcmVqZWN0IGZhaWx1cmVzCiAgICB9LAogICAgZm9sbG93OiBmdW5jdGlvbiAoZm4sIHpvbmVQcm9wcykgewogICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7CiAgICAgICAgICAgIHJldHVybiBuZXdTY29wZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7CiAgICAgICAgICAgICAgICB2YXIgcHNkID0gUFNEOwogICAgICAgICAgICAgICAgcHNkLnVuaGFuZGxlZHMgPSBbXTsgLy8gRm9yIHVuaGFuZGxlZCBzdGFuZGFyZC0gb3IgM3JkIHBhcnR5IFByb21pc2VzLiBDaGVja2VkIGF0IHBzZC5maW5hbGl6ZSgpCiAgICAgICAgICAgICAgICBwc2Qub251bmhhbmRsZWQgPSByZWplY3Q7IC8vIFRyaWdnZXJlZCBkaXJlY3RseSBvbiB1bmhhbmRsZWQgcHJvbWlzZXMgb2YgdGhpcyBsaWJyYXJ5LgogICAgICAgICAgICAgICAgcHNkLmZpbmFsaXplID0gY2FsbEJvdGgoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7CiAgICAgICAgICAgICAgICAgICAgLy8gVW5oYW5kbGVkIHN0YW5kYXJkIG9yIDNyZCBwYXJ0IHByb21pc2VzIGFyZSBwdXQgaW4gUFNELnVuaGFuZGxlZHMgYW5kCiAgICAgICAgICAgICAgICAgICAgLy8gZXhhbWluZWQgdXBvbiBzY29wZSBjb21wbGV0aW9uIHdoaWxlIHVuaGFuZGxlZCByZWplY3Rpb25zIGluIHRoaXMgUHJvbWlzZQogICAgICAgICAgICAgICAgICAgIC8vIHdpbGwgdHJpZ2dlciBkaXJlY3RseSB0aHJvdWdoIHBzZC5vbnVuaGFuZGxlZAogICAgICAgICAgICAgICAgICAgIHJ1bl9hdF9lbmRfb2ZfdGhpc19vcl9uZXh0X3BoeXNpY2FsX3RpY2soZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy51bmhhbmRsZWRzLmxlbmd0aCA9PT0gMCA/IHJlc29sdmUoKSA6IHJlamVjdChfdGhpcy51bmhhbmRsZWRzWzBdKTsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIH0sIHBzZC5maW5hbGl6ZSk7CiAgICAgICAgICAgICAgICBmbigpOwogICAgICAgICAgICB9LCB6b25lUHJvcHMsIHJlc29sdmUsIHJlamVjdCk7CiAgICAgICAgfSk7CiAgICB9Cn0pOwovKioKKiBUYWtlIGEgcG90ZW50aWFsbHkgbWlzYmVoYXZpbmcgcmVzb2x2ZXIgZnVuY3Rpb24gYW5kIG1ha2Ugc3VyZQoqIG9uRnVsZmlsbGVkIGFuZCBvblJlamVjdGVkIGFyZSBvbmx5IGNhbGxlZCBvbmNlLgoqCiogTWFrZXMgbm8gZ3VhcmFudGVlcyBhYm91dCBhc3luY2hyb255LgoqLwpmdW5jdGlvbiBleGVjdXRlUHJvbWlzZVRhc2socHJvbWlzZSwgZm4pIHsKICAgIC8vIFByb21pc2UgUmVzb2x1dGlvbiBQcm9jZWR1cmU6CiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vcHJvbWlzZXMtYXBsdXMvcHJvbWlzZXMtc3BlYyN0aGUtcHJvbWlzZS1yZXNvbHV0aW9uLXByb2NlZHVyZQogICAgdHJ5IHsKICAgICAgICBmbihmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgaWYgKHByb21pc2UuX3N0YXRlICE9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuOyAvLyBBbHJlYWR5IHNldHRsZWQKICAgICAgICAgICAgaWYgKHZhbHVlID09PSBwcm9taXNlKQogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQSBwcm9taXNlIGNhbm5vdCBiZSByZXNvbHZlZCB3aXRoIGl0c2VsZi4nKTsKICAgICAgICAgICAgdmFyIHNob3VsZEV4ZWN1dGVUaWNrID0gcHJvbWlzZS5fbGliICYmIGJlZ2luTWljcm9UaWNrU2NvcGUoKTsKICAgICAgICAgICAgaWYgKHZhbHVlICYmIHR5cGVvZiB2YWx1ZS50aGVuID09PSAnZnVuY3Rpb24nKSB7CiAgICAgICAgICAgICAgICBleGVjdXRlUHJvbWlzZVRhc2socHJvbWlzZSwgZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkgewogICAgICAgICAgICAgICAgICAgIHZhbHVlIGluc3RhbmNlb2YgUHJvbWlzZSA/CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLl90aGVuKHJlc29sdmUsIHJlamVjdCkgOgogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZS50aGVuKHJlc29sdmUsIHJlamVjdCk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHByb21pc2UuX3N0YXRlID0gdHJ1ZTsKICAgICAgICAgICAgICAgIHByb21pc2UuX3ZhbHVlID0gdmFsdWU7CiAgICAgICAgICAgICAgICBwcm9wYWdhdGVBbGxMaXN0ZW5lcnMocHJvbWlzZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHNob3VsZEV4ZWN1dGVUaWNrKQogICAgICAgICAgICAgICAgZW5kTWljcm9UaWNrU2NvcGUoKTsKICAgICAgICB9LCBoYW5kbGVSZWplY3Rpb24uYmluZChudWxsLCBwcm9taXNlKSk7IC8vIElmIEZ1bmN0aW9uLmJpbmQgaXMgbm90IHN1cHBvcnRlZC4gRXhjZXB0aW9uIGlzIGhhbmRsZWQgaW4gY2F0Y2ggYmVsb3cKICAgIH0KICAgIGNhdGNoIChleCkgewogICAgICAgIGhhbmRsZVJlamVjdGlvbihwcm9taXNlLCBleCk7CiAgICB9Cn0KZnVuY3Rpb24gaGFuZGxlUmVqZWN0aW9uKHByb21pc2UsIHJlYXNvbikgewogICAgcmVqZWN0aW5nRXJyb3JzLnB1c2gocmVhc29uKTsKICAgIGlmIChwcm9taXNlLl9zdGF0ZSAhPT0gbnVsbCkKICAgICAgICByZXR1cm47CiAgICB2YXIgc2hvdWxkRXhlY3V0ZVRpY2sgPSBwcm9taXNlLl9saWIgJiYgYmVnaW5NaWNyb1RpY2tTY29wZSgpOwogICAgcmVhc29uID0gcmVqZWN0aW9uTWFwcGVyKHJlYXNvbik7CiAgICBwcm9taXNlLl9zdGF0ZSA9IGZhbHNlOwogICAgcHJvbWlzZS5fdmFsdWUgPSByZWFzb247CiAgICBkZWJ1ZyAmJiByZWFzb24gIT09IG51bGwgJiYgdHlwZW9mIHJlYXNvbiA9PT0gJ29iamVjdCcgJiYgIXJlYXNvbi5fcHJvbWlzZSAmJiB0cnlDYXRjaChmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIG9yaWdQcm9wID0gZ2V0UHJvcGVydHlEZXNjcmlwdG9yKHJlYXNvbiwgInN0YWNrIik7CiAgICAgICAgcmVhc29uLl9wcm9taXNlID0gcHJvbWlzZTsKICAgICAgICBzZXRQcm9wKHJlYXNvbiwgInN0YWNrIiwgewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzdGFja19iZWluZ19nZW5lcmF0ZWQgPwogICAgICAgICAgICAgICAgICAgIG9yaWdQcm9wICYmIChvcmlnUHJvcC5nZXQgPwogICAgICAgICAgICAgICAgICAgICAgICBvcmlnUHJvcC5nZXQuYXBwbHkocmVhc29uKSA6CiAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdQcm9wLnZhbHVlKSA6CiAgICAgICAgICAgICAgICAgICAgcHJvbWlzZS5zdGFjazsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfSk7CiAgICAvLyBBZGQgdGhlIGZhaWx1cmUgdG8gYSBsaXN0IG9mIHBvc3NpYmx5IHVuY2F1Z2h0IGVycm9ycwogICAgYWRkUG9zc2libHlVbmhhbmRsZWRFcnJvcihwcm9taXNlKTsKICAgIHByb3BhZ2F0ZUFsbExpc3RlbmVycyhwcm9taXNlKTsKICAgIGlmIChzaG91bGRFeGVjdXRlVGljaykKICAgICAgICBlbmRNaWNyb1RpY2tTY29wZSgpOwp9CmZ1bmN0aW9uIHByb3BhZ2F0ZUFsbExpc3RlbmVycyhwcm9taXNlKSB7CiAgICAvL2RlYnVnICYmIGxpbmtUb1ByZXZpb3VzUHJvbWlzZShwcm9taXNlKTsKICAgIHZhciBsaXN0ZW5lcnMgPSBwcm9taXNlLl9saXN0ZW5lcnM7CiAgICBwcm9taXNlLl9saXN0ZW5lcnMgPSBbXTsKICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBsaXN0ZW5lcnMubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHsKICAgICAgICBwcm9wYWdhdGVUb0xpc3RlbmVyKHByb21pc2UsIGxpc3RlbmVyc1tpXSk7CiAgICB9CiAgICB2YXIgcHNkID0gcHJvbWlzZS5fUFNEOwogICAgLS1wc2QucmVmIHx8IHBzZC5maW5hbGl6ZSgpOyAvLyBpZiBwc2QucmVmIHJlYWNoZXMgemVybywgY2FsbCBwc2QuZmluYWxpemUoKTsKICAgIGlmIChudW1TY2hlZHVsZWRDYWxscyA9PT0gMCkgewogICAgICAgIC8vIElmIG51bVNjaGVkdWxlZENhbGxzIGlzIDAsIGl0IG1lYW5zIHRoYXQgb3VyIHN0YWNrIGlzIG5vdCBpbiBhIGNhbGxiYWNrIG9mIGEgc2NoZWR1bGVkIGNhbGwsCiAgICAgICAgLy8gYW5kIHRoYXQgbm8gZGVmZXJyZWRzIHdoZXJlIGxpc3RlbmluZyB0byB0aGlzIHJlamVjdGlvbiBvciBzdWNjZXNzLgogICAgICAgIC8vIFNpbmNlIHRoZXJlIGlzIGEgcmlzayB0aGF0IG91ciBzdGFjayBjYW4gY29udGFpbiBhcHBsaWNhdGlvbiBjb2RlIHRoYXQgbWF5CiAgICAgICAgLy8gZG8gc3R1ZmYgYWZ0ZXIgdGhpcyBjb2RlIGlzIGZpbmlzaGVkIHRoYXQgbWF5IGdlbmVyYXRlIG5ldyBjYWxscywgd2UgY2Fubm90CiAgICAgICAgLy8gY2FsbCBmaW5hbGl6ZXJzIGhlcmUuCiAgICAgICAgKytudW1TY2hlZHVsZWRDYWxsczsKICAgICAgICBhc2FwJDEoZnVuY3Rpb24gKCkgewogICAgICAgICAgICBpZiAoLS1udW1TY2hlZHVsZWRDYWxscyA9PT0gMCkKICAgICAgICAgICAgICAgIGZpbmFsaXplUGh5c2ljYWxUaWNrKCk7IC8vIFdpbGwgZGV0ZWN0IHVuaGFuZGxlZCBlcnJvcnMKICAgICAgICB9LCBbXSk7CiAgICB9Cn0KZnVuY3Rpb24gcHJvcGFnYXRlVG9MaXN0ZW5lcihwcm9taXNlLCBsaXN0ZW5lcikgewogICAgaWYgKHByb21pc2UuX3N0YXRlID09PSBudWxsKSB7CiAgICAgICAgcHJvbWlzZS5fbGlzdGVuZXJzLnB1c2gobGlzdGVuZXIpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIHZhciBjYiA9IHByb21pc2UuX3N0YXRlID8gbGlzdGVuZXIub25GdWxmaWxsZWQgOiBsaXN0ZW5lci5vblJlamVjdGVkOwogICAgaWYgKGNiID09PSBudWxsKSB7CiAgICAgICAgLy8gVGhpcyBMaXN0ZW5lciBkb2VzbnQgaGF2ZSBhIGxpc3RlbmVyIGZvciB0aGUgZXZlbnQgYmVpbmcgdHJpZ2dlcmVkIChvbkZ1bGZpbGxlZCBvciBvblJlamVjdCkgc28gbGV0cyBmb3J3YXJkIHRoZSBldmVudCB0byBhbnkgZXZlbnR1YWwgbGlzdGVuZXJzIG9uIHRoZSBQcm9taXNlIGluc3RhbmNlIHJldHVybmVkIGJ5IHRoZW4oKSBvciBjYXRjaCgpCiAgICAgICAgcmV0dXJuIChwcm9taXNlLl9zdGF0ZSA/IGxpc3RlbmVyLnJlc29sdmUgOiBsaXN0ZW5lci5yZWplY3QpKHByb21pc2UuX3ZhbHVlKTsKICAgIH0KICAgICsrbGlzdGVuZXIucHNkLnJlZjsKICAgICsrbnVtU2NoZWR1bGVkQ2FsbHM7CiAgICBhc2FwJDEoY2FsbExpc3RlbmVyLCBbY2IsIHByb21pc2UsIGxpc3RlbmVyXSk7Cn0KZnVuY3Rpb24gY2FsbExpc3RlbmVyKGNiLCBwcm9taXNlLCBsaXN0ZW5lcikgewogICAgdHJ5IHsKICAgICAgICAvLyBTZXQgc3RhdGljIHZhcmlhYmxlIGN1cnJlbnRGdWxmaWxsZXIgdG8gdGhlIHByb21pc2UgdGhhdCBpcyBiZWluZyBmdWxsZmlsbGVkLAogICAgICAgIC8vIHNvIHRoYXQgd2UgY29ubmVjdCB0aGUgY2hhaW4gb2YgcHJvbWlzZXMgKGZvciBsb25nIHN0YWNrcyBzdXBwb3J0KQogICAgICAgIGN1cnJlbnRGdWxmaWxsZXIgPSBwcm9taXNlOwogICAgICAgIC8vIENhbGwgY2FsbGJhY2sgYW5kIHJlc29sdmUgb3VyIGxpc3RlbmVyIHdpdGggaXQncyByZXR1cm4gdmFsdWUuCiAgICAgICAgdmFyIHJldCwgdmFsdWUgPSBwcm9taXNlLl92YWx1ZTsKICAgICAgICBpZiAocHJvbWlzZS5fc3RhdGUpIHsKICAgICAgICAgICAgLy8gY2IgaXMgb25SZXNvbHZlZAogICAgICAgICAgICByZXQgPSBjYih2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAvLyBjYiBpcyBvblJlamVjdGVkCiAgICAgICAgICAgIGlmIChyZWplY3RpbmdFcnJvcnMubGVuZ3RoKQogICAgICAgICAgICAgICAgcmVqZWN0aW5nRXJyb3JzID0gW107CiAgICAgICAgICAgIHJldCA9IGNiKHZhbHVlKTsKICAgICAgICAgICAgaWYgKHJlamVjdGluZ0Vycm9ycy5pbmRleE9mKHZhbHVlKSA9PT0gLTEpCiAgICAgICAgICAgICAgICBtYXJrRXJyb3JBc0hhbmRsZWQocHJvbWlzZSk7IC8vIENhbGxiYWNrIGRpZG50IGRvIFByb21pc2UucmVqZWN0KGVycikgbm9yIHJlamVjdChlcnIpIG9udG8gYW5vdGhlciBwcm9taXNlLgogICAgICAgIH0KICAgICAgICBsaXN0ZW5lci5yZXNvbHZlKHJldCk7CiAgICB9CiAgICBjYXRjaCAoZSkgewogICAgICAgIC8vIEV4Y2VwdGlvbiB0aHJvd24gaW4gY2FsbGJhY2suIFJlamVjdCBvdXIgbGlzdGVuZXIuCiAgICAgICAgbGlzdGVuZXIucmVqZWN0KGUpOwogICAgfQogICAgZmluYWxseSB7CiAgICAgICAgLy8gUmVzdG9yZSBlbnYgYW5kIGN1cnJlbnRGdWxmaWxsZXIuCiAgICAgICAgY3VycmVudEZ1bGZpbGxlciA9IG51bGw7CiAgICAgICAgaWYgKC0tbnVtU2NoZWR1bGVkQ2FsbHMgPT09IDApCiAgICAgICAgICAgIGZpbmFsaXplUGh5c2ljYWxUaWNrKCk7CiAgICAgICAgLS1saXN0ZW5lci5wc2QucmVmIHx8IGxpc3RlbmVyLnBzZC5maW5hbGl6ZSgpOwogICAgfQp9CmZ1bmN0aW9uIGdldFN0YWNrKHByb21pc2UsIHN0YWNrcywgbGltaXQpIHsKICAgIGlmIChzdGFja3MubGVuZ3RoID09PSBsaW1pdCkKICAgICAgICByZXR1cm4gc3RhY2tzOwogICAgdmFyIHN0YWNrID0gIiI7CiAgICBpZiAocHJvbWlzZS5fc3RhdGUgPT09IGZhbHNlKSB7CiAgICAgICAgdmFyIGZhaWx1cmUgPSBwcm9taXNlLl92YWx1ZSwgZXJyb3JOYW1lLCBtZXNzYWdlOwogICAgICAgIGlmIChmYWlsdXJlICE9IG51bGwpIHsKICAgICAgICAgICAgZXJyb3JOYW1lID0gZmFpbHVyZS5uYW1lIHx8ICJFcnJvciI7CiAgICAgICAgICAgIG1lc3NhZ2UgPSBmYWlsdXJlLm1lc3NhZ2UgfHwgZmFpbHVyZTsKICAgICAgICAgICAgc3RhY2sgPSBwcmV0dHlTdGFjayhmYWlsdXJlLCAwKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGVycm9yTmFtZSA9IGZhaWx1cmU7IC8vIElmIGVycm9yIGlzIHVuZGVmaW5lZCBvciBudWxsLCBzaG93IHRoYXQuCiAgICAgICAgICAgIG1lc3NhZ2UgPSAiIjsKICAgICAgICB9CiAgICAgICAgc3RhY2tzLnB1c2goZXJyb3JOYW1lICsgKG1lc3NhZ2UgPyAiOiAiICsgbWVzc2FnZSA6ICIiKSArIHN0YWNrKTsKICAgIH0KICAgIGlmIChkZWJ1ZykgewogICAgICAgIHN0YWNrID0gcHJldHR5U3RhY2socHJvbWlzZS5fc3RhY2tIb2xkZXIsIDIpOwogICAgICAgIGlmIChzdGFjayAmJiBzdGFja3MuaW5kZXhPZihzdGFjaykgPT09IC0xKQogICAgICAgICAgICBzdGFja3MucHVzaChzdGFjayk7CiAgICAgICAgaWYgKHByb21pc2UuX3ByZXYpCiAgICAgICAgICAgIGdldFN0YWNrKHByb21pc2UuX3ByZXYsIHN0YWNrcywgbGltaXQpOwogICAgfQogICAgcmV0dXJuIHN0YWNrczsKfQpmdW5jdGlvbiBsaW5rVG9QcmV2aW91c1Byb21pc2UocHJvbWlzZSwgcHJldikgewogICAgLy8gU3VwcG9ydCBsb25nIHN0YWNrcyBieSBsaW5raW5nIHRvIHByZXZpb3VzIGNvbXBsZXRlZCBwcm9taXNlLgogICAgdmFyIG51bVByZXYgPSBwcmV2ID8gcHJldi5fbnVtUHJldiArIDEgOiAwOwogICAgaWYgKG51bVByZXYgPCBMT05HX1NUQUNLU19DTElQX0xJTUlUKSB7CiAgICAgICAgcHJvbWlzZS5fcHJldiA9IHByZXY7CiAgICAgICAgcHJvbWlzZS5fbnVtUHJldiA9IG51bVByZXY7CiAgICB9Cn0KLyogVGhlIGNhbGxiYWNrIHRvIHNjaGVkdWxlIHdpdGggc2V0SW1tZWRpYXRlKCkgb3Igc2V0VGltZW91dCgpLgogICBJdCBydW5zIGEgdmlydHVhbCBtaWNyb3RpY2sgYW5kIGV4ZWN1dGVzIGFueSBjYWxsYmFjayByZWdpc3RlcmVkIGluIG1pY3JvdGlja1F1ZXVlLgogKi8KZnVuY3Rpb24gcGh5c2ljYWxUaWNrKCkgewogICAgYmVnaW5NaWNyb1RpY2tTY29wZSgpICYmIGVuZE1pY3JvVGlja1Njb3BlKCk7Cn0KZnVuY3Rpb24gYmVnaW5NaWNyb1RpY2tTY29wZSgpIHsKICAgIHZhciB3YXNSb290RXhlYyA9IGlzT3V0c2lkZU1pY3JvVGljazsKICAgIGlzT3V0c2lkZU1pY3JvVGljayA9IGZhbHNlOwogICAgbmVlZHNOZXdQaHlzaWNhbFRpY2sgPSBmYWxzZTsKICAgIHJldHVybiB3YXNSb290RXhlYzsKfQovKiBFeGVjdXRlcyBtaWNyby10aWNrcyB3aXRob3V0IGRvaW5nIHRyeS4uY2F0Y2guCiAgIFRoaXMgY2FuIGJlIHBvc3NpYmxlIGJlY2F1c2Ugd2Ugb25seSB1c2UgdGhpcyBpbnRlcm5hbGx5IGFuZAogICB0aGUgcmVnaXN0ZXJlZCBmdW5jdGlvbnMgYXJlIGV4Y2VwdGlvbi1zYWZlICh0aGV5IGRvIHRyeS4uY2F0Y2gKICAgaW50ZXJuYWxseSBiZWZvcmUgY2FsbGluZyBhbnkgZXh0ZXJuYWwgbWV0aG9kKS4gSWYgcmVnaXN0ZXJpbmcKICAgZnVuY3Rpb25zIGluIHRoZSBtaWNyb3RpY2tRdWV1ZSB0aGF0IGFyZSBub3QgZXhjZXB0aW9uLXNhZmUsIHRoaXMKICAgd291bGQgZGVzdHJveSB0aGUgZnJhbWV3b3JrIGFuZCBtYWtlIGl0IGluc3RhYmxlLiBTbyB3ZSBkb24ndCBleHBvcnQKICAgb3VyIGFzYXAgbWV0aG9kLgoqLwpmdW5jdGlvbiBlbmRNaWNyb1RpY2tTY29wZSgpIHsKICAgIHZhciBjYWxsYmFja3MsIGksIGw7CiAgICBkbyB7CiAgICAgICAgd2hpbGUgKG1pY3JvdGlja1F1ZXVlLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgY2FsbGJhY2tzID0gbWljcm90aWNrUXVldWU7CiAgICAgICAgICAgIG1pY3JvdGlja1F1ZXVlID0gW107CiAgICAgICAgICAgIGwgPSBjYWxsYmFja3MubGVuZ3RoOwogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbDsgKytpKSB7CiAgICAgICAgICAgICAgICB2YXIgaXRlbSA9IGNhbGxiYWNrc1tpXTsKICAgICAgICAgICAgICAgIGl0ZW1bMF0uYXBwbHkobnVsbCwgaXRlbVsxXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IHdoaWxlIChtaWNyb3RpY2tRdWV1ZS5sZW5ndGggPiAwKTsKICAgIGlzT3V0c2lkZU1pY3JvVGljayA9IHRydWU7CiAgICBuZWVkc05ld1BoeXNpY2FsVGljayA9IHRydWU7Cn0KZnVuY3Rpb24gZmluYWxpemVQaHlzaWNhbFRpY2soKSB7CiAgICB2YXIgdW5oYW5kbGVkRXJycyA9IHVuaGFuZGxlZEVycm9yczsKICAgIHVuaGFuZGxlZEVycm9ycyA9IFtdOwogICAgdW5oYW5kbGVkRXJycy5mb3JFYWNoKGZ1bmN0aW9uIChwKSB7CiAgICAgICAgcC5fUFNELm9udW5oYW5kbGVkLmNhbGwobnVsbCwgcC5fdmFsdWUsIHApOwogICAgfSk7CiAgICB2YXIgZmluYWxpemVycyA9IHRpY2tGaW5hbGl6ZXJzLnNsaWNlKDApOyAvLyBDbG9uZSBmaXJzdCBiZWNhdXNlIGZpbmFsaXplciBtYXkgcmVtb3ZlIGl0c2VsZiBmcm9tIGxpc3QuCiAgICB2YXIgaSA9IGZpbmFsaXplcnMubGVuZ3RoOwogICAgd2hpbGUgKGkpCiAgICAgICAgZmluYWxpemVyc1stLWldKCk7Cn0KZnVuY3Rpb24gcnVuX2F0X2VuZF9vZl90aGlzX29yX25leHRfcGh5c2ljYWxfdGljayhmbikgewogICAgZnVuY3Rpb24gZmluYWxpemVyKCkgewogICAgICAgIGZuKCk7CiAgICAgICAgdGlja0ZpbmFsaXplcnMuc3BsaWNlKHRpY2tGaW5hbGl6ZXJzLmluZGV4T2YoZmluYWxpemVyKSwgMSk7CiAgICB9CiAgICB0aWNrRmluYWxpemVycy5wdXNoKGZpbmFsaXplcik7CiAgICArK251bVNjaGVkdWxlZENhbGxzOwogICAgYXNhcCQxKGZ1bmN0aW9uICgpIHsKICAgICAgICBpZiAoLS1udW1TY2hlZHVsZWRDYWxscyA9PT0gMCkKICAgICAgICAgICAgZmluYWxpemVQaHlzaWNhbFRpY2soKTsKICAgIH0sIFtdKTsKfQpmdW5jdGlvbiBhZGRQb3NzaWJseVVuaGFuZGxlZEVycm9yKHByb21pc2UpIHsKICAgIC8vIE9ubHkgYWRkIHRvIHVuaGFuZGxlZEVycm9ycyBpZiBub3QgYWxyZWFkeSB0aGVyZS4gVGhlIGZpcnN0IG9uZSB0byBhZGQgdG8gdGhpcyBsaXN0CiAgICAvLyB3aWxsIGJlIHVwb24gdGhlIGZpcnN0IHJlamVjdGlvbiBzbyB0aGF0IHRoZSByb290IGNhdXNlIChmaXJzdCBwcm9taXNlIGluIHRoZQogICAgLy8gcmVqZWN0aW9uIGNoYWluKSBpcyB0aGUgb25lIGxpc3RlZC4KICAgIGlmICghdW5oYW5kbGVkRXJyb3JzLnNvbWUoZnVuY3Rpb24gKHApIHsgcmV0dXJuIHAuX3ZhbHVlID09PSBwcm9taXNlLl92YWx1ZTsgfSkpCiAgICAgICAgdW5oYW5kbGVkRXJyb3JzLnB1c2gocHJvbWlzZSk7Cn0KZnVuY3Rpb24gbWFya0Vycm9yQXNIYW5kbGVkKHByb21pc2UpIHsKICAgIC8vIENhbGxlZCB3aGVuIGEgcmVqZWN0IGhhbmRsZWQgaXMgYWN0dWFsbHkgYmVpbmcgY2FsbGVkLgogICAgLy8gU2VhcmNoIGluIHVuaGFuZGxlZEVycm9ycyBmb3IgYW55IHByb21pc2Ugd2hvcyBfdmFsdWUgaXMgdGhpcyBwcm9taXNlX3ZhbHVlIChsaXN0CiAgICAvLyBjb250YWlucyBvbmx5IHJlamVjdGVkIHByb21pc2VzLCBhbmQgb25seSBvbmUgaXRlbSBwZXIgZXJyb3IpCiAgICB2YXIgaSA9IHVuaGFuZGxlZEVycm9ycy5sZW5ndGg7CiAgICB3aGlsZSAoaSkKICAgICAgICBpZiAodW5oYW5kbGVkRXJyb3JzWy0taV0uX3ZhbHVlID09PSBwcm9taXNlLl92YWx1ZSkgewogICAgICAgICAgICAvLyBGb3VuZCBhIHByb21pc2UgdGhhdCBmYWlsZWQgd2l0aCB0aGlzIHNhbWUgZXJyb3Igb2JqZWN0IHBvaW50ZXIsCiAgICAgICAgICAgIC8vIFJlbW92ZSB0aGF0IHNpbmNlIHRoZXJlIGlzIGEgbGlzdGVuZXIgdGhhdCBhY3R1YWxseSB0YWtlcyBjYXJlIG9mIGl0LgogICAgICAgICAgICB1bmhhbmRsZWRFcnJvcnMuc3BsaWNlKGksIDEpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQp9CmZ1bmN0aW9uIFByb21pc2VSZWplY3QocmVhc29uKSB7CiAgICByZXR1cm4gbmV3IFByb21pc2UoSU5URVJOQUwsIGZhbHNlLCByZWFzb24pOwp9CmZ1bmN0aW9uIHdyYXAoZm4sIGVycm9yQ2F0Y2hlcikgewogICAgdmFyIHBzZCA9IFBTRDsKICAgIHJldHVybiBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIHdhc1Jvb3RFeGVjID0gYmVnaW5NaWNyb1RpY2tTY29wZSgpLCBvdXRlclNjb3BlID0gUFNEOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHN3aXRjaFRvWm9uZShwc2QsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKGUpIHsKICAgICAgICAgICAgZXJyb3JDYXRjaGVyICYmIGVycm9yQ2F0Y2hlcihlKTsKICAgICAgICB9CiAgICAgICAgZmluYWxseSB7CiAgICAgICAgICAgIHN3aXRjaFRvWm9uZShvdXRlclNjb3BlLCBmYWxzZSk7CiAgICAgICAgICAgIGlmICh3YXNSb290RXhlYykKICAgICAgICAgICAgICAgIGVuZE1pY3JvVGlja1Njb3BlKCk7CiAgICAgICAgfQogICAgfTsKfQovLwovLyB2YXJpYWJsZXMgdXNlZCBmb3IgbmF0aXZlIGF3YWl0IHN1cHBvcnQKLy8KdmFyIHRhc2sgPSB7IGF3YWl0czogMCwgZWNob2VzOiAwLCBpZDogMCB9OyAvLyBUaGUgb25nb2luZyBtYWNyby10YXNrIHdoZW4gdXNpbmcgem9uZS1lY2hvaW5nLgp2YXIgdGFza0NvdW50ZXIgPSAwOyAvLyBJRCBjb3VudGVyIGZvciBtYWNybyB0YXNrcy4KdmFyIHpvbmVTdGFjayA9IFtdOyAvLyBTdGFjayBvZiBsZWZ0IHpvbmVzIHRvIHJlc3RvcmUgYXN5bmNocm9uaWNhbGx5Lgp2YXIgem9uZUVjaG9lcyA9IDA7IC8vIHpvbmVFY2hvZXMgaXMgYSBtdXN0IGluIG9yZGVyIHRvIHBlcnNpc3Qgem9uZXMgYmV0d2VlbiBuYXRpdmUgYXdhaXQgZXhwcmVzc2lvbnMuCnZhciB0b3RhbEVjaG9lcyA9IDA7IC8vIElEIGNvdW50ZXIgZm9yIG1pY3JvLXRhc2tzLiBVc2VkIHRvIGRldGVjdCBwb3NzaWJsZSBuYXRpdmUgYXdhaXQgaW4gb3VyIFByb21pc2UucHJvdG90eXBlLnRoZW4uCnZhciB6b25lX2lkX2NvdW50ZXIgPSAwOwpmdW5jdGlvbiBuZXdTY29wZShmbiwgcHJvcHMkJDEsIGExLCBhMikgewogICAgdmFyIHBhcmVudCA9IFBTRCwgcHNkID0gT2JqZWN0LmNyZWF0ZShwYXJlbnQpOwogICAgcHNkLnBhcmVudCA9IHBhcmVudDsKICAgIHBzZC5yZWYgPSAwOwogICAgcHNkLmdsb2JhbCA9IGZhbHNlOwogICAgcHNkLmlkID0gKyt6b25lX2lkX2NvdW50ZXI7CiAgICAvLyBQcmVwYXJlIGZvciBwcm9taXNlIHBhdGNoaW5nIChkb25lIGluIHVzZVBTRCk6CiAgICB2YXIgZ2xvYmFsRW52ID0gZ2xvYmFsUFNELmVudjsKICAgIHBzZC5lbnYgPSBwYXRjaEdsb2JhbFByb21pc2UgPyB7CiAgICAgICAgUHJvbWlzZTogUHJvbWlzZSwKICAgICAgICBQcm9taXNlUHJvcDogeyB2YWx1ZTogUHJvbWlzZSwgY29uZmlndXJhYmxlOiB0cnVlLCB3cml0YWJsZTogdHJ1ZSB9LAogICAgICAgIGFsbDogUHJvbWlzZS5hbGwsCiAgICAgICAgcmFjZTogUHJvbWlzZS5yYWNlLAogICAgICAgIHJlc29sdmU6IFByb21pc2UucmVzb2x2ZSwKICAgICAgICByZWplY3Q6IFByb21pc2UucmVqZWN0LAogICAgICAgIG50aGVuOiBnZXRQYXRjaGVkUHJvbWlzZVRoZW4oZ2xvYmFsRW52Lm50aGVuLCBwc2QpLAogICAgICAgIGd0aGVuOiBnZXRQYXRjaGVkUHJvbWlzZVRoZW4oZ2xvYmFsRW52Lmd0aGVuLCBwc2QpIC8vIGdsb2JhbCB0aGVuCiAgICB9IDoge307CiAgICBpZiAocHJvcHMkJDEpCiAgICAgICAgZXh0ZW5kKHBzZCwgcHJvcHMkJDEpOwogICAgLy8gdW5oYW5kbGVkcyBhbmQgb251bmhhbmRsZWQgc2hvdWxkIG5vdCBiZSBzcGVjaWZpY2FsbHkgc2V0IGhlcmUuCiAgICAvLyBMZWF2ZSB0aGVtIG9uIHBhcmVudCBwcm90b3R5cGUuCiAgICAvLyB1bmhhbmRsZWRzLnB1c2goZXJyKSB3aWxsIHB1c2ggdG8gcGFyZW50J3MgcHJvdG90eXBlCiAgICAvLyBvbnVuaGFuZGxlZCgpIHdpbGwgY2FsbCBwYXJlbnRzIG9udW5oYW5kbGVkICh3aXRoIHRoaXMgc2NvcGUncyB0aGlzLXBvaW50ZXIgdGhvdWdoISkKICAgICsrcGFyZW50LnJlZjsKICAgIHBzZC5maW5hbGl6ZSA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAtLXRoaXMucGFyZW50LnJlZiB8fCB0aGlzLnBhcmVudC5maW5hbGl6ZSgpOwogICAgfTsKICAgIHZhciBydiA9IHVzZVBTRChwc2QsIGZuLCBhMSwgYTIpOwogICAgaWYgKHBzZC5yZWYgPT09IDApCiAgICAgICAgcHNkLmZpbmFsaXplKCk7CiAgICByZXR1cm4gcnY7Cn0KLy8gRnVuY3Rpb24gdG8gY2FsbCBpZiBzY29wZUZ1bmMgcmV0dXJucyBOYXRpdmVQcm9taXNlCi8vIEFsc28gZm9yIGVhY2ggTmF0aXZlUHJvbWlzZSBpbiB0aGUgYXJndW1lbnRzIHRvIFByb21pc2UuYWxsKCkKZnVuY3Rpb24gaW5jcmVtZW50RXhwZWN0ZWRBd2FpdHMoKSB7CiAgICBpZiAoIXRhc2suaWQpCiAgICAgICAgdGFzay5pZCA9ICsrdGFza0NvdW50ZXI7CiAgICArK3Rhc2suYXdhaXRzOwogICAgdGFzay5lY2hvZXMgKz0gWk9ORV9FQ0hPX0xJTUlUOwogICAgcmV0dXJuIHRhc2suaWQ7Cn0KLy8gRnVuY3Rpb24gdG8gY2FsbCB3aGVuICd0aGVuJyBjYWxscyBiYWNrIG9uIGEgbmF0aXZlIHByb21pc2Ugd2hlcmUgb25Bd2FpdEV4cGVjdGVkKCkgaGFkIGJlZW4gY2FsbGVkLgovLyBBbHNvIGNhbGwgdGhpcyB3aGVuIGEgbmF0aXZlIGF3YWl0IGNhbGxzIHRoZW4gbWV0aG9kIG9uIGEgcHJvbWlzZS4gSW4gdGhhdCBjYXNlLCBkb24ndCBzdXBwbHkKLy8gc291cmNlVGFza0lkIGJlY2F1c2Ugd2UgYWxyZWFkeSBrbm93IGl0IHJlZmVycyB0byBjdXJyZW50IHRhc2suCmZ1bmN0aW9uIGRlY3JlbWVudEV4cGVjdGVkQXdhaXRzKHNvdXJjZVRhc2tJZCkgewogICAgaWYgKCF0YXNrLmF3YWl0cyB8fCAoc291cmNlVGFza0lkICYmIHNvdXJjZVRhc2tJZCAhPT0gdGFzay5pZCkpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKC0tdGFzay5hd2FpdHMgPT09IDApCiAgICAgICAgdGFzay5pZCA9IDA7CiAgICB0YXNrLmVjaG9lcyA9IHRhc2suYXdhaXRzICogWk9ORV9FQ0hPX0xJTUlUOyAvLyBXaWxsIHJlc2V0IGVjaG9lcyB0byAwIGlmIGF3YWl0cyBpcyAwLgp9Ci8vIENhbGwgZnJvbSBQcm9taXNlLmFsbCgpIGFuZCBQcm9taXNlLnJhY2UoKQpmdW5jdGlvbiBvblBvc3NpYmxlUGFyYWxsZWxsQXN5bmMocG9zc2libGVQcm9taXNlKSB7CiAgICBpZiAodGFzay5lY2hvZXMgJiYgcG9zc2libGVQcm9taXNlICYmIHBvc3NpYmxlUHJvbWlzZS5jb25zdHJ1Y3RvciA9PT0gTmF0aXZlUHJvbWlzZSkgewogICAgICAgIGluY3JlbWVudEV4cGVjdGVkQXdhaXRzKCk7CiAgICAgICAgcmV0dXJuIHBvc3NpYmxlUHJvbWlzZS50aGVuKGZ1bmN0aW9uICh4KSB7CiAgICAgICAgICAgIGRlY3JlbWVudEV4cGVjdGVkQXdhaXRzKCk7CiAgICAgICAgICAgIHJldHVybiB4OwogICAgICAgIH0sIGZ1bmN0aW9uIChlKSB7CiAgICAgICAgICAgIGRlY3JlbWVudEV4cGVjdGVkQXdhaXRzKCk7CiAgICAgICAgICAgIHJldHVybiByZWplY3Rpb24oZSk7CiAgICAgICAgfSk7CiAgICB9CiAgICByZXR1cm4gcG9zc2libGVQcm9taXNlOwp9CmZ1bmN0aW9uIHpvbmVFbnRlckVjaG8odGFyZ2V0Wm9uZSkgewogICAgKyt0b3RhbEVjaG9lczsKICAgIGlmICghdGFzay5lY2hvZXMgfHwgLS10YXNrLmVjaG9lcyA9PT0gMCkgewogICAgICAgIHRhc2suZWNob2VzID0gdGFzay5pZCA9IDA7IC8vIENhbmNlbCB6b25lIGVjaG9pbmcuCiAgICB9CiAgICB6b25lU3RhY2sucHVzaChQU0QpOwogICAgc3dpdGNoVG9ab25lKHRhcmdldFpvbmUsIHRydWUpOwp9CmZ1bmN0aW9uIHpvbmVMZWF2ZUVjaG8oKSB7CiAgICB2YXIgem9uZSA9IHpvbmVTdGFja1t6b25lU3RhY2subGVuZ3RoIC0gMV07CiAgICB6b25lU3RhY2sucG9wKCk7CiAgICBzd2l0Y2hUb1pvbmUoem9uZSwgZmFsc2UpOwp9CmZ1bmN0aW9uIHN3aXRjaFRvWm9uZSh0YXJnZXRab25lLCBiRW50ZXJpbmdab25lKSB7CiAgICB2YXIgY3VycmVudFpvbmUgPSBQU0Q7CiAgICBpZiAoYkVudGVyaW5nWm9uZSA/IHRhc2suZWNob2VzICYmICghem9uZUVjaG9lcysrIHx8IHRhcmdldFpvbmUgIT09IFBTRCkgOiB6b25lRWNob2VzICYmICghLS16b25lRWNob2VzIHx8IHRhcmdldFpvbmUgIT09IFBTRCkpIHsKICAgICAgICAvLyBFbnRlciBvciBsZWF2ZSB6b25lIGFzeW5jaHJvbmljYWxseSBhcyB3ZWxsLCBzbyB0aGF0IHRhc2tzIGluaXRpYXRlZCBkdXJpbmcgY3VycmVudCB0aWNrCiAgICAgICAgLy8gd2lsbCBiZSBzdXJyb3VuZGVkIGJ5IHRoZSB6b25lIHdoZW4gdGhleSBhcmUgaW52b2tlZC4KICAgICAgICBlbnF1ZXVlTmF0aXZlTWljcm9UYXNrKGJFbnRlcmluZ1pvbmUgPyB6b25lRW50ZXJFY2hvLmJpbmQobnVsbCwgdGFyZ2V0Wm9uZSkgOiB6b25lTGVhdmVFY2hvKTsKICAgIH0KICAgIGlmICh0YXJnZXRab25lID09PSBQU0QpCiAgICAgICAgcmV0dXJuOwogICAgUFNEID0gdGFyZ2V0Wm9uZTsgLy8gVGhlIGFjdHVhbCB6b25lIHN3aXRjaCBvY2N1cnMgYXQgdGhpcyBsaW5lLgogICAgLy8gU25hcHNob3Qgb24gZXZlcnkgbGVhdmUgZnJvbSBnbG9iYWwgem9uZS4KICAgIGlmIChjdXJyZW50Wm9uZSA9PT0gZ2xvYmFsUFNEKQogICAgICAgIGdsb2JhbFBTRC5lbnYgPSBzbmFwU2hvdCgpOwogICAgaWYgKHBhdGNoR2xvYmFsUHJvbWlzZSkgewogICAgICAgIC8vIExldCdzIHBhdGNoIHRoZSBnbG9iYWwgYW5kIG5hdGl2ZSBQcm9taXNlcyAobWF5IGJlIHNhbWUgb3IgbWF5IGJlIGRpZmZlcmVudCkKICAgICAgICB2YXIgR2xvYmFsUHJvbWlzZSA9IGdsb2JhbFBTRC5lbnYuUHJvbWlzZTsKICAgICAgICAvLyBTd2ljaCBlbnZpcm9ubWVudHMgKG1heSBiZSBQU0Qtem9uZSBvciB0aGUgZ2xvYmFsIHpvbmUuIEJvdGggYXBwbHkuKQogICAgICAgIHZhciB0YXJnZXRFbnYgPSB0YXJnZXRab25lLmVudjsKICAgICAgICAvLyBDaGFuZ2UgUHJvbWlzZS5wcm90b3R5cGUudGhlbiBmb3IgbmF0aXZlIGFuZCBnbG9iYWwgUHJvbWlzZSAodGhleSBNQVkgZGlmZmVyIG9uIHBvbHlmaWxsZWQgZW52aXJvbm1lbnRzLCBidXQgYm90aCBjYW4gYmUgYWNjZXNzZWQpCiAgICAgICAgLy8gTXVzdCBiZSBkb25lIG9uIGVhY2ggem9uZSBjaGFuZ2UgYmVjYXVzZSB0aGUgcGF0Y2hlZCBtZXRob2QgY29udGFpbnMgdGFyZ2V0Wm9uZSBpbiBpdHMgY2xvc3VyZS4KICAgICAgICBuYXRpdmVQcm9taXNlUHJvdG8udGhlbiA9IHRhcmdldEVudi5udGhlbjsKICAgICAgICBHbG9iYWxQcm9taXNlLnByb3RvdHlwZS50aGVuID0gdGFyZ2V0RW52Lmd0aGVuOwogICAgICAgIGlmIChjdXJyZW50Wm9uZS5nbG9iYWwgfHwgdGFyZ2V0Wm9uZS5nbG9iYWwpIHsKICAgICAgICAgICAgLy8gTGVhdmluZyBvciBlbnRlcmluZyBnbG9iYWwgem9uZS4gSXQncyB0aW1lIHRvIHBhdGNoIC8gcmVzdG9yZSBnbG9iYWwgUHJvbWlzZS4KICAgICAgICAgICAgLy8gU2V0IHRoaXMgUHJvbWlzZSB0byB3aW5kb3cuUHJvbWlzZSBzbyB0aGF0IHRyYW5zaWxlZCBhc3luYyBmdW5jdGlvbnMgd2lsbCB3b3JrIG9uIEZpcmVmb3gsIFNhZmFyaSBhbmQgSUUsIGFzIHdlbGwgYXMgd2l0aCBab25lanMgYW5kIGFuZ3VsYXIuCiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShfZ2xvYmFsLCAnUHJvbWlzZScsIHRhcmdldEVudi5Qcm9taXNlUHJvcCk7CiAgICAgICAgICAgIC8vIFN1cHBvcnQgUHJvbWlzZS5hbGwoKSBldGMgdG8gd29yayBpbmRleGVkREItc2FmZSBhbHNvIHdoZW4gcGVvcGxlIGFyZSBpbmNsdWRpbmcgZXM2LXByb21pc2UgYXMgYSBtb2R1bGUgKHRoZXkgbWlnaHQKICAgICAgICAgICAgLy8gbm90IGJlIGFjY2Vzc2luZyBnbG9iYWwuUHJvbWlzZSBidXQgYSBsb2NhbCByZWZlcmVuY2UgdG8gaXQpCiAgICAgICAgICAgIEdsb2JhbFByb21pc2UuYWxsID0gdGFyZ2V0RW52LmFsbDsKICAgICAgICAgICAgR2xvYmFsUHJvbWlzZS5yYWNlID0gdGFyZ2V0RW52LnJhY2U7CiAgICAgICAgICAgIEdsb2JhbFByb21pc2UucmVzb2x2ZSA9IHRhcmdldEVudi5yZXNvbHZlOwogICAgICAgICAgICBHbG9iYWxQcm9taXNlLnJlamVjdCA9IHRhcmdldEVudi5yZWplY3Q7CiAgICAgICAgfQogICAgfQp9CmZ1bmN0aW9uIHNuYXBTaG90KCkgewogICAgdmFyIEdsb2JhbFByb21pc2UgPSBfZ2xvYmFsLlByb21pc2U7CiAgICByZXR1cm4gcGF0Y2hHbG9iYWxQcm9taXNlID8gewogICAgICAgIFByb21pc2U6IEdsb2JhbFByb21pc2UsCiAgICAgICAgUHJvbWlzZVByb3A6IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoX2dsb2JhbCwgIlByb21pc2UiKSwKICAgICAgICBhbGw6IEdsb2JhbFByb21pc2UuYWxsLAogICAgICAgIHJhY2U6IEdsb2JhbFByb21pc2UucmFjZSwKICAgICAgICByZXNvbHZlOiBHbG9iYWxQcm9taXNlLnJlc29sdmUsCiAgICAgICAgcmVqZWN0OiBHbG9iYWxQcm9taXNlLnJlamVjdCwKICAgICAgICBudGhlbjogbmF0aXZlUHJvbWlzZVByb3RvLnRoZW4sCiAgICAgICAgZ3RoZW46IEdsb2JhbFByb21pc2UucHJvdG90eXBlLnRoZW4KICAgIH0gOiB7fTsKfQpmdW5jdGlvbiB1c2VQU0QocHNkLCBmbiwgYTEsIGEyLCBhMykgewogICAgdmFyIG91dGVyU2NvcGUgPSBQU0Q7CiAgICB0cnkgewogICAgICAgIHN3aXRjaFRvWm9uZShwc2QsIHRydWUpOwogICAgICAgIHJldHVybiBmbihhMSwgYTIsIGEzKTsKICAgIH0KICAgIGZpbmFsbHkgewogICAgICAgIHN3aXRjaFRvWm9uZShvdXRlclNjb3BlLCBmYWxzZSk7CiAgICB9Cn0KZnVuY3Rpb24gZW5xdWV1ZU5hdGl2ZU1pY3JvVGFzayhqb2IpIHsKICAgIC8vCiAgICAvLyBQcmVjb25kaXRpb246IG5hdGl2ZVByb21pc2VUaGVuICE9PSB1bmRlZmluZWQKICAgIC8vCiAgICBuYXRpdmVQcm9taXNlVGhlbi5jYWxsKHJlc29sdmVkTmF0aXZlUHJvbWlzZSwgam9iKTsKfQpmdW5jdGlvbiBuYXRpdmVBd2FpdENvbXBhdGlibGVXcmFwKGZuLCB6b25lLCBwb3NzaWJsZUF3YWl0KSB7CiAgICByZXR1cm4gdHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nID8gZm4gOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIG91dGVyWm9uZSA9IFBTRDsKICAgICAgICBpZiAocG9zc2libGVBd2FpdCkKICAgICAgICAgICAgaW5jcmVtZW50RXhwZWN0ZWRBd2FpdHMoKTsKICAgICAgICBzd2l0Y2hUb1pvbmUoem9uZSwgdHJ1ZSk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgfQogICAgICAgIGZpbmFsbHkgewogICAgICAgICAgICBzd2l0Y2hUb1pvbmUob3V0ZXJab25lLCBmYWxzZSk7CiAgICAgICAgfQogICAgfTsKfQpmdW5jdGlvbiBnZXRQYXRjaGVkUHJvbWlzZVRoZW4ob3JpZ1RoZW4sIHpvbmUpIHsKICAgIHJldHVybiBmdW5jdGlvbiAob25SZXNvbHZlZCwgb25SZWplY3RlZCkgewogICAgICAgIHJldHVybiBvcmlnVGhlbi5jYWxsKHRoaXMsIG5hdGl2ZUF3YWl0Q29tcGF0aWJsZVdyYXAob25SZXNvbHZlZCwgem9uZSwgZmFsc2UpLCBuYXRpdmVBd2FpdENvbXBhdGlibGVXcmFwKG9uUmVqZWN0ZWQsIHpvbmUsIGZhbHNlKSk7CiAgICB9Owp9CnZhciBVTkhBTkRMRURSRUpFQ1RJT04gPSAidW5oYW5kbGVkcmVqZWN0aW9uIjsKZnVuY3Rpb24gZ2xvYmFsRXJyb3IoZXJyLCBwcm9taXNlKSB7CiAgICB2YXIgcnY7CiAgICB0cnkgewogICAgICAgIHJ2ID0gcHJvbWlzZS5vbnVuY2F0Y2hlZChlcnIpOwogICAgfQogICAgY2F0Y2ggKGUpIHsgfQogICAgaWYgKHJ2ICE9PSBmYWxzZSkKICAgICAgICB0cnkgewogICAgICAgICAgICB2YXIgZXZlbnQsIGV2ZW50RGF0YSA9IHsgcHJvbWlzZTogcHJvbWlzZSwgcmVhc29uOiBlcnIgfTsKICAgICAgICAgICAgaWYgKF9nbG9iYWwuZG9jdW1lbnQgJiYgZG9jdW1lbnQuY3JlYXRlRXZlbnQpIHsKICAgICAgICAgICAgICAgIGV2ZW50ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoJ0V2ZW50Jyk7CiAgICAgICAgICAgICAgICBldmVudC5pbml0RXZlbnQoVU5IQU5ETEVEUkVKRUNUSU9OLCB0cnVlLCB0cnVlKTsKICAgICAgICAgICAgICAgIGV4dGVuZChldmVudCwgZXZlbnREYXRhKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChfZ2xvYmFsLkN1c3RvbUV2ZW50KSB7CiAgICAgICAgICAgICAgICBldmVudCA9IG5ldyBDdXN0b21FdmVudChVTkhBTkRMRURSRUpFQ1RJT04sIHsgZGV0YWlsOiBldmVudERhdGEgfSk7CiAgICAgICAgICAgICAgICBleHRlbmQoZXZlbnQsIGV2ZW50RGF0YSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGV2ZW50ICYmIF9nbG9iYWwuZGlzcGF0Y2hFdmVudCkgewogICAgICAgICAgICAgICAgZGlzcGF0Y2hFdmVudChldmVudCk7CiAgICAgICAgICAgICAgICBpZiAoIV9nbG9iYWwuUHJvbWlzZVJlamVjdGlvbkV2ZW50ICYmIF9nbG9iYWwub251bmhhbmRsZWRyZWplY3Rpb24pCiAgICAgICAgICAgICAgICAgICAgLy8gTm8gbmF0aXZlIHN1cHBvcnQgZm9yIFByb21pc2VSZWplY3Rpb25FdmVudCBidXQgdXNlciBoYXMgc2V0IHdpbmRvdy5vbnVuaGFuZGxlZHJlamVjdGlvbi4gTWFudWFsbHkgY2FsbCBpdC4KICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICBfZ2xvYmFsLm9udW5oYW5kbGVkcmVqZWN0aW9uKGV2ZW50KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKF8pIHsgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghZXZlbnQuZGVmYXVsdFByZXZlbnRlZCkgewogICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCJVbmhhbmRsZWQgcmVqZWN0aW9uOiAiICsgKGVyci5zdGFjayB8fCBlcnIpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjYXRjaCAoZSkgeyB9Cn0KdmFyIHJlamVjdGlvbiA9IFByb21pc2UucmVqZWN0OwoKZnVuY3Rpb24gRXZlbnRzKGN0eCkgewogICAgdmFyIGV2cyA9IHt9OwogICAgdmFyIHJ2ID0gZnVuY3Rpb24gKGV2ZW50TmFtZSwgc3Vic2NyaWJlcikgewogICAgICAgIGlmIChzdWJzY3JpYmVyKSB7CiAgICAgICAgICAgIC8vIFN1YnNjcmliZS4gSWYgYWRkaXRpb25hbCBhcmd1bWVudHMgdGhhbiBqdXN0IHRoZSBzdWJzY3JpYmVyIHdhcyBwcm92aWRlZCwgZm9yd2FyZCB0aGVtIGFzIHdlbGwuCiAgICAgICAgICAgIHZhciBpID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShpIC0gMSk7CiAgICAgICAgICAgIHdoaWxlICgtLWkpCiAgICAgICAgICAgICAgICBhcmdzW2kgLSAxXSA9IGFyZ3VtZW50c1tpXTsKICAgICAgICAgICAgZXZzW2V2ZW50TmFtZV0uc3Vic2NyaWJlLmFwcGx5KG51bGwsIGFyZ3MpOwogICAgICAgICAgICByZXR1cm4gY3R4OwogICAgICAgIH0KICAgICAgICBlbHNlIGlmICh0eXBlb2YgKGV2ZW50TmFtZSkgPT09ICdzdHJpbmcnKSB7CiAgICAgICAgICAgIC8vIFJldHVybiBpbnRlcmZhY2UgYWxsb3dpbmcgdG8gZmlyZSBvciB1bnN1YnNjcmliZSBmcm9tIGV2ZW50CiAgICAgICAgICAgIHJldHVybiBldnNbZXZlbnROYW1lXTsKICAgICAgICB9CiAgICB9OwogICAgcnYuYWRkRXZlbnRUeXBlID0gYWRkOwogICAgZm9yICh2YXIgaSA9IDEsIGwgPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbDsgKytpKSB7CiAgICAgICAgYWRkKGFyZ3VtZW50c1tpXSk7CiAgICB9CiAgICByZXR1cm4gcnY7CiAgICBmdW5jdGlvbiBhZGQoZXZlbnROYW1lLCBjaGFpbkZ1bmN0aW9uLCBkZWZhdWx0RnVuY3Rpb24pIHsKICAgICAgICBpZiAodHlwZW9mIGV2ZW50TmFtZSA9PT0gJ29iamVjdCcpCiAgICAgICAgICAgIHJldHVybiBhZGRDb25maWd1cmVkRXZlbnRzKGV2ZW50TmFtZSk7CiAgICAgICAgaWYgKCFjaGFpbkZ1bmN0aW9uKQogICAgICAgICAgICBjaGFpbkZ1bmN0aW9uID0gcmV2ZXJzZVN0b3BwYWJsZUV2ZW50Q2hhaW47CiAgICAgICAgaWYgKCFkZWZhdWx0RnVuY3Rpb24pCiAgICAgICAgICAgIGRlZmF1bHRGdW5jdGlvbiA9IG5vcDsKICAgICAgICB2YXIgY29udGV4dCA9IHsKICAgICAgICAgICAgc3Vic2NyaWJlcnM6IFtdLAogICAgICAgICAgICBmaXJlOiBkZWZhdWx0RnVuY3Rpb24sCiAgICAgICAgICAgIHN1YnNjcmliZTogZnVuY3Rpb24gKGNiKSB7CiAgICAgICAgICAgICAgICBpZiAoY29udGV4dC5zdWJzY3JpYmVycy5pbmRleE9mKGNiKSA9PT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICBjb250ZXh0LnN1YnNjcmliZXJzLnB1c2goY2IpOwogICAgICAgICAgICAgICAgICAgIGNvbnRleHQuZmlyZSA9IGNoYWluRnVuY3Rpb24oY29udGV4dC5maXJlLCBjYik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHVuc3Vic2NyaWJlOiBmdW5jdGlvbiAoY2IpIHsKICAgICAgICAgICAgICAgIGNvbnRleHQuc3Vic2NyaWJlcnMgPSBjb250ZXh0LnN1YnNjcmliZXJzLmZpbHRlcihmdW5jdGlvbiAoZm4pIHsgcmV0dXJuIGZuICE9PSBjYjsgfSk7CiAgICAgICAgICAgICAgICBjb250ZXh0LmZpcmUgPSBjb250ZXh0LnN1YnNjcmliZXJzLnJlZHVjZShjaGFpbkZ1bmN0aW9uLCBkZWZhdWx0RnVuY3Rpb24pOwogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgICBldnNbZXZlbnROYW1lXSA9IHJ2W2V2ZW50TmFtZV0gPSBjb250ZXh0OwogICAgICAgIHJldHVybiBjb250ZXh0OwogICAgfQogICAgZnVuY3Rpb24gYWRkQ29uZmlndXJlZEV2ZW50cyhjZmcpIHsKICAgICAgICAvLyBldmVudHModGhpcywge3JlYWRpbmc6IFtmdW5jdGlvbkNoYWluLCBub3BdfSk7CiAgICAgICAga2V5cyhjZmcpLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50TmFtZSkgewogICAgICAgICAgICB2YXIgYXJncyA9IGNmZ1tldmVudE5hbWVdOwogICAgICAgICAgICBpZiAoaXNBcnJheShhcmdzKSkgewogICAgICAgICAgICAgICAgYWRkKGV2ZW50TmFtZSwgY2ZnW2V2ZW50TmFtZV1bMF0sIGNmZ1tldmVudE5hbWVdWzFdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChhcmdzID09PSAnYXNhcCcpIHsKICAgICAgICAgICAgICAgIC8vIFJhdGhlciB0aGFuIGFwcHJvYWNoaW5nIGV2ZW50IHN1YnNjcmlwdGlvbiB1c2luZyBhIGZ1bmN0aW9uYWwgYXBwcm9hY2gsIHdlIGhlcmUgZG8gaXQgaW4gYSBmb3ItbG9vcCB3aGVyZSBzdWJzY3JpYmVyIGlzIGV4ZWN1dGVkIGluIGl0cyBvd24gc3RhY2sKICAgICAgICAgICAgICAgIC8vIGVuYWJsaW5nIHRoYXQgYW55IGV4Y2VwdGlvbiB0aGF0IG9jY3VyIHdvbnQgZGlzdHVyYiB0aGUgaW5pdGlhdG9yIGFuZCBhbHNvIG5vdCBuZXNjZXNzYXJ5IGJlIGNhdGNoZWQgYW5kIGZvcmdvdHRlbi4KICAgICAgICAgICAgICAgIHZhciBjb250ZXh0ID0gYWRkKGV2ZW50TmFtZSwgbWlycm9yLCBmdW5jdGlvbiBmaXJlKCkgewogICAgICAgICAgICAgICAgICAgIC8vIE9wdGltYXphdGlvbi1zYWZlIGNsb25pbmcgb2YgYXJndW1lbnRzIGludG8gYXJncy4KICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoaSk7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGktLSkKICAgICAgICAgICAgICAgICAgICAgICAgYXJnc1tpXSA9IGFyZ3VtZW50c1tpXTsKICAgICAgICAgICAgICAgICAgICAvLyBBbGwgZWFjaCBzdWJzY3JpYmVyOgogICAgICAgICAgICAgICAgICAgIGNvbnRleHQuc3Vic2NyaWJlcnMuZm9yRWFjaChmdW5jdGlvbiAoZm4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgYXNhcChmdW5jdGlvbiBmaXJlRXZlbnQoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbi5hcHBseShudWxsLCBhcmdzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgZXhjZXB0aW9ucy5JbnZhbGlkQXJndW1lbnQoIkludmFsaWQgZXZlbnQgY29uZmlnIik7CiAgICAgICAgfSk7CiAgICB9Cn0KCi8qCiAqIERleGllLmpzIC0gYSBtaW5pbWFsaXN0aWMgd3JhcHBlciBmb3IgSW5kZXhlZERCCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqCiAqIENvcHlyaWdodCAoYykgMjAxNC0yMDE3IERhdmlkIEZhaGxhbmRlcgogKgogKiBWZXJzaW9uIDIuMC40LCBGcmkgTWF5IDI1IDIwMTgKICoKICogaHR0cDovL2RleGllLm9yZwogKgogKiBBcGFjaGUgTGljZW5zZSBWZXJzaW9uIDIuMCwgSmFudWFyeSAyMDA0LCBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICovCnZhciBERVhJRV9WRVJTSU9OID0gJzIuMC40JzsKdmFyIG1heFN0cmluZyA9IFN0cmluZy5mcm9tQ2hhckNvZGUoNjU1MzUpOwp2YXIgbWF4S2V5ID0gKGZ1bmN0aW9uICgpIHsgdHJ5IHsKICAgIElEQktleVJhbmdlLm9ubHkoW1tdXSk7CiAgICByZXR1cm4gW1tdXTsKfQpjYXRjaCAoZSkgewogICAgcmV0dXJuIG1heFN0cmluZzsKfSB9KSgpOwp2YXIgbWluS2V5ID0gLUluZmluaXR5Owp2YXIgSU5WQUxJRF9LRVlfQVJHVU1FTlQgPSAiSW52YWxpZCBrZXkgcHJvdmlkZWQuIEtleXMgbXVzdCBiZSBvZiB0eXBlIHN0cmluZywgbnVtYmVyLCBEYXRlIG9yIEFycmF5PHN0cmluZyB8IG51bWJlciB8IERhdGU+LiI7CnZhciBTVFJJTkdfRVhQRUNURUQgPSAiU3RyaW5nIGV4cGVjdGVkLiI7CnZhciBjb25uZWN0aW9ucyA9IFtdOwp2YXIgaXNJRU9yRWRnZSA9IHR5cGVvZiBuYXZpZ2F0b3IgIT09ICd1bmRlZmluZWQnICYmIC8oTVNJRXxUcmlkZW50fEVkZ2UpLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpOwp2YXIgaGFzSUVEZWxldGVPYmplY3RTdG9yZUJ1ZyA9IGlzSUVPckVkZ2U7CnZhciBoYW5nc09uRGVsZXRlTGFyZ2VLZXlSYW5nZSA9IGlzSUVPckVkZ2U7CnZhciBkZXhpZVN0YWNrRnJhbWVGaWx0ZXIgPSBmdW5jdGlvbiAoZnJhbWUpIHsgcmV0dXJuICEvKGRleGllXC5qc3xkZXhpZVwubWluXC5qcykvLnRlc3QoZnJhbWUpOyB9Owp2YXIgZGJOYW1lc0RCOyAvLyBHbG9iYWwgZGF0YWJhc2UgZm9yIGJhY2tpbmcgRGV4aWUuZ2V0RGF0YWJhc2VOYW1lcygpIG9uIGJyb3dzZXIgd2l0aG91dCBpbmRleGVkREIud2Via2l0R2V0RGF0YWJhc2VOYW1lcygpIAovLyBJbml0IGRlYnVnCnNldERlYnVnKGRlYnVnLCBkZXhpZVN0YWNrRnJhbWVGaWx0ZXIpOwpmdW5jdGlvbiBEZXhpZShkYk5hbWUsIG9wdGlvbnMpIHsKICAgIC8vLyA8cGFyYW0gbmFtZT0ib3B0aW9ucyIgdHlwZT0iT2JqZWN0IiBvcHRpb25hbD0idHJ1ZSI+U3BlY2lmeSBvbmx5IGlmIHlvdSB3aWNoIHRvIGNvbnRyb2wgd2hpY2ggYWRkb25zIHRoYXQgc2hvdWxkIHJ1biBvbiB0aGlzIGluc3RhbmNlPC9wYXJhbT4KICAgIHZhciBkZXBzID0gRGV4aWUuZGVwZW5kZW5jaWVzOwogICAgdmFyIG9wdHMgPSBleHRlbmQoewogICAgICAgIC8vIERlZmF1bHQgT3B0aW9ucwogICAgICAgIGFkZG9uczogRGV4aWUuYWRkb25zLAogICAgICAgIGF1dG9PcGVuOiB0cnVlLAogICAgICAgIGluZGV4ZWREQjogZGVwcy5pbmRleGVkREIsCiAgICAgICAgSURCS2V5UmFuZ2U6IGRlcHMuSURCS2V5UmFuZ2UgLy8gQmFja2VuZCBJREJLZXlSYW5nZSBhcGkuIERlZmF1bHQgdG8gYnJvd3NlciBlbnYuCiAgICB9LCBvcHRpb25zKTsKICAgIHZhciBhZGRvbnMgPSBvcHRzLmFkZG9ucywgYXV0b09wZW4gPSBvcHRzLmF1dG9PcGVuLCBpbmRleGVkREIgPSBvcHRzLmluZGV4ZWREQiwgSURCS2V5UmFuZ2UgPSBvcHRzLklEQktleVJhbmdlOwogICAgdmFyIGdsb2JhbFNjaGVtYSA9IHRoaXMuX2RiU2NoZW1hID0ge307CiAgICB2YXIgdmVyc2lvbnMgPSBbXTsKICAgIHZhciBkYlN0b3JlTmFtZXMgPSBbXTsKICAgIHZhciBhbGxUYWJsZXMgPSB7fTsKICAgIC8vLzx2YXIgdHlwZT0iSURCRGF0YWJhc2UiIC8+CiAgICB2YXIgaWRiZGIgPSBudWxsOyAvLyBJbnN0YW5jZSBvZiBJREJEYXRhYmFzZQogICAgdmFyIGRiT3BlbkVycm9yID0gbnVsbDsKICAgIHZhciBpc0JlaW5nT3BlbmVkID0gZmFsc2U7CiAgICB2YXIgb25SZWFkeUJlaW5nRmlyZWQgPSBudWxsOwogICAgdmFyIG9wZW5Db21wbGV0ZSA9IGZhbHNlOwogICAgdmFyIFJFQURPTkxZID0gInJlYWRvbmx5IiwgUkVBRFdSSVRFID0gInJlYWR3cml0ZSI7CiAgICB2YXIgZGIgPSB0aGlzOwogICAgdmFyIGRiUmVhZHlSZXNvbHZlLCBkYlJlYWR5UHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7CiAgICAgICAgZGJSZWFkeVJlc29sdmUgPSByZXNvbHZlOwogICAgfSksIGNhbmNlbE9wZW4sIG9wZW5DYW5jZWxsZXIgPSBuZXcgUHJvbWlzZShmdW5jdGlvbiAoXywgcmVqZWN0KSB7CiAgICAgICAgY2FuY2VsT3BlbiA9IHJlamVjdDsKICAgIH0pOwogICAgdmFyIGF1dG9TY2hlbWEgPSB0cnVlOwogICAgdmFyIGhhc05hdGl2ZUdldERhdGFiYXNlTmFtZXMgPSAhIWdldE5hdGl2ZUdldERhdGFiYXNlTmFtZXNGbihpbmRleGVkREIpLCBoYXNHZXRBbGw7CiAgICBmdW5jdGlvbiBpbml0KCkgewogICAgICAgIC8vIERlZmF1bHQgc3Vic2NyaWJlcnMgdG8gInZlcnNpb25jaGFuZ2UiIGFuZCAiYmxvY2tlZCIuCiAgICAgICAgLy8gQ2FuIGJlIG92ZXJyaWRkZW4gYnkgY3VzdG9tIGhhbmRsZXJzLiBJZiBjdXN0b20gaGFuZGxlcnMgcmV0dXJuIGZhbHNlLCB0aGVzZSBkZWZhdWx0CiAgICAgICAgLy8gYmVoYXZpb3VycyB3aWxsIGJlIHByZXZlbnRlZC4KICAgICAgICBkYi5vbigidmVyc2lvbmNoYW5nZSIsIGZ1bmN0aW9uIChldikgewogICAgICAgICAgICAvLyBEZWZhdWx0IGJlaGF2aW9yIGZvciB2ZXJzaW9uY2hhbmdlIGV2ZW50IGlzIHRvIGNsb3NlIGRhdGFiYXNlIGNvbm5lY3Rpb24uCiAgICAgICAgICAgIC8vIENhbGxlciBjYW4gb3ZlcnJpZGUgdGhpcyBiZWhhdmlvciBieSBkb2luZyBkYi5vbigidmVyc2lvbmNoYW5nZSIsIGZ1bmN0aW9uKCl7IHJldHVybiBmYWxzZTsgfSk7CiAgICAgICAgICAgIC8vIExldCdzIG5vdCBibG9jayB0aGUgb3RoZXIgd2luZG93IGZyb20gbWFraW5nIGl0J3MgZGVsZXRlKCkgb3Igb3BlbigpIGNhbGwuCiAgICAgICAgICAgIC8vIE5PVEUhIFRoaXMgZXZlbnQgaXMgbmV2ZXIgZmlyZWQgaW4gSUUsRWRnZSBvciBTYWZhcmkuCiAgICAgICAgICAgIGlmIChldi5uZXdWZXJzaW9uID4gMCkKICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybigiQW5vdGhlciBjb25uZWN0aW9uIHdhbnRzIHRvIHVwZ3JhZGUgZGF0YWJhc2UgJyIgKyBkYi5uYW1lICsgIicuIENsb3NpbmcgZGIgbm93IHRvIHJlc3VtZSB0aGUgdXBncmFkZS4iKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCJBbm90aGVyIGNvbm5lY3Rpb24gd2FudHMgdG8gZGVsZXRlIGRhdGFiYXNlICciICsgZGIubmFtZSArICInLiBDbG9zaW5nIGRiIG5vdyB0byByZXN1bWUgdGhlIGRlbGV0ZSByZXF1ZXN0LiIpOwogICAgICAgICAgICBkYi5jbG9zZSgpOwogICAgICAgICAgICAvLyBJbiBtYW55IHdlYiBhcHBsaWNhdGlvbnMsIGl0IHdvdWxkIGJlIHJlY29tbWVuZGVkIHRvIGZvcmNlIHdpbmRvdy5yZWxvYWQoKQogICAgICAgICAgICAvLyB3aGVuIHRoaXMgZXZlbnQgb2NjdXJzLiBUbyBkbyB0aGF0LCBzdWJzY3JpYmUgdG8gdGhlIHZlcnNpb25jaGFuZ2UgZXZlbnQKICAgICAgICAgICAgLy8gYW5kIGNhbGwgd2luZG93LmxvY2F0aW9uLnJlbG9hZCh0cnVlKSBpZiBldi5uZXdWZXJzaW9uID4gMCAobm90IGEgZGVsZXRpb24pCiAgICAgICAgICAgIC8vIFRoZSByZWFzb24gZm9yIHRoaXMgaXMgdGhhdCB5b3VyIGN1cnJlbnQgd2ViIGFwcCBvYnZpb3VzbHkgaGFzIG9sZCBzY2hlbWEgY29kZSB0aGF0IG5lZWRzCiAgICAgICAgICAgIC8vIHRvIGJlIHVwZGF0ZWQuIEFub3RoZXIgd2luZG93IGdvdCBhIG5ld2VyIHZlcnNpb24gb2YgdGhlIGFwcCBhbmQgbmVlZHMgdG8gdXBncmFkZSBEQiBidXQKICAgICAgICAgICAgLy8geW91ciB3aW5kb3cgaXMgYmxvY2tpbmcgaXQgdW5sZXNzIHdlIGNsb3NlIGl0IGhlcmUuCiAgICAgICAgfSk7CiAgICAgICAgZGIub24oImJsb2NrZWQiLCBmdW5jdGlvbiAoZXYpIHsKICAgICAgICAgICAgaWYgKCFldi5uZXdWZXJzaW9uIHx8IGV2Lm5ld1ZlcnNpb24gPCBldi5vbGRWZXJzaW9uKQogICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCJEZXhpZS5kZWxldGUoJyIgKyBkYi5uYW1lICsgIicpIHdhcyBibG9ja2VkIik7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybigiVXBncmFkZSAnIiArIGRiLm5hbWUgKyAiJyBibG9ja2VkIGJ5IG90aGVyIGNvbm5lY3Rpb24gaG9sZGluZyB2ZXJzaW9uICIgKyBldi5vbGRWZXJzaW9uIC8gMTApOwogICAgICAgIH0pOwogICAgfQogICAgLy8KICAgIC8vCiAgICAvLwogICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBWZXJzaW9uaW5nIEZyYW1ld29yay0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8KICAgIC8vCiAgICAvLwogICAgdGhpcy52ZXJzaW9uID0gZnVuY3Rpb24gKHZlcnNpb25OdW1iZXIpIHsKICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InZlcnNpb25OdW1iZXIiIHR5cGU9Ik51bWJlciI+PC9wYXJhbT4KICAgICAgICAvLy8gPHJldHVybnMgdHlwZT0iVmVyc2lvbiI+PC9yZXR1cm5zPgogICAgICAgIGlmIChpZGJkYiB8fCBpc0JlaW5nT3BlbmVkKQogICAgICAgICAgICB0aHJvdyBuZXcgZXhjZXB0aW9ucy5TY2hlbWEoIkNhbm5vdCBhZGQgdmVyc2lvbiB3aGVuIGRhdGFiYXNlIGlzIG9wZW4iKTsKICAgICAgICB0aGlzLnZlcm5vID0gTWF0aC5tYXgodGhpcy52ZXJubywgdmVyc2lvbk51bWJlcik7CiAgICAgICAgdmFyIHZlcnNpb25JbnN0YW5jZSA9IHZlcnNpb25zLmZpbHRlcihmdW5jdGlvbiAodikgeyByZXR1cm4gdi5fY2ZnLnZlcnNpb24gPT09IHZlcnNpb25OdW1iZXI7IH0pWzBdOwogICAgICAgIGlmICh2ZXJzaW9uSW5zdGFuY2UpCiAgICAgICAgICAgIHJldHVybiB2ZXJzaW9uSW5zdGFuY2U7CiAgICAgICAgdmVyc2lvbkluc3RhbmNlID0gbmV3IFZlcnNpb24odmVyc2lvbk51bWJlcik7CiAgICAgICAgdmVyc2lvbnMucHVzaCh2ZXJzaW9uSW5zdGFuY2UpOwogICAgICAgIHZlcnNpb25zLnNvcnQobG93ZXJWZXJzaW9uRmlyc3QpOwogICAgICAgIC8vIERpc2FibGUgYXV0b3NjaGVtYSBtb2RlLCBhcyBhdCBsZWFzdCBvbmUgdmVyc2lvbiBpcyBzcGVjaWZpZWQuCiAgICAgICAgYXV0b1NjaGVtYSA9IGZhbHNlOwogICAgICAgIHJldHVybiB2ZXJzaW9uSW5zdGFuY2U7CiAgICB9OwogICAgZnVuY3Rpb24gVmVyc2lvbih2ZXJzaW9uTnVtYmVyKSB7CiAgICAgICAgdGhpcy5fY2ZnID0gewogICAgICAgICAgICB2ZXJzaW9uOiB2ZXJzaW9uTnVtYmVyLAogICAgICAgICAgICBzdG9yZXNTb3VyY2U6IG51bGwsCiAgICAgICAgICAgIGRic2NoZW1hOiB7fSwKICAgICAgICAgICAgdGFibGVzOiB7fSwKICAgICAgICAgICAgY29udGVudFVwZ3JhZGU6IG51bGwKICAgICAgICB9OwogICAgICAgIHRoaXMuc3RvcmVzKHt9KTsgLy8gRGVyaXZlIGVhcmxpZXIgc2NoZW1hcyBieSBkZWZhdWx0LgogICAgfQogICAgZXh0ZW5kKFZlcnNpb24ucHJvdG90eXBlLCB7CiAgICAgICAgc3RvcmVzOiBmdW5jdGlvbiAoc3RvcmVzKSB7CiAgICAgICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAgICAgLy8vICAgRGVmaW5lcyB0aGUgc2NoZW1hIGZvciBhIHBhcnRpY3VsYXIgdmVyc2lvbgogICAgICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InN0b3JlcyIgdHlwZT0iT2JqZWN0Ij4KICAgICAgICAgICAgLy8vIEV4YW1wbGU6IDxici8+CiAgICAgICAgICAgIC8vLyAgIHt1c2VyczogImlkKyssZmlyc3QsbGFzdCwmYW1wO3VzZXJuYW1lLCplbWFpbCIsIDxici8+CiAgICAgICAgICAgIC8vLyAgIHBhc3N3b3JkczogImlkKyssJmFtcDt1c2VybmFtZSJ9PGJyLz4KICAgICAgICAgICAgLy8vIDxici8+CiAgICAgICAgICAgIC8vLyBTeW50YXg6IHtUYWJsZTogIltwcmltYXJ5S2V5XVsrK10sWyZhbXA7XVsqXWluZGV4MSxbJmFtcDtdWypdaW5kZXgyLC4uLiJ9PGJyLz48YnIvPgogICAgICAgICAgICAvLy8gU3BlY2lhbCBjaGFyYWN0ZXJzOjxici8+CiAgICAgICAgICAgIC8vLyAgIiZhbXA7IiAgbWVhbnMgdW5pcXVlIGtleSwgPGJyLz4KICAgICAgICAgICAgLy8vICAiKiIgIG1lYW5zIHZhbHVlIGlzIG11bHRpRW50cnksIDxici8+CiAgICAgICAgICAgIC8vLyAgIisrIiBtZWFucyBhdXRvLWluY3JlbWVudCBhbmQgb25seSBhcHBsaWNhYmxlIGZvciBwcmltYXJ5IGtleSA8YnIvPgogICAgICAgICAgICAvLy8gPC9wYXJhbT4KICAgICAgICAgICAgdGhpcy5fY2ZnLnN0b3Jlc1NvdXJjZSA9IHRoaXMuX2NmZy5zdG9yZXNTb3VyY2UgPyBleHRlbmQodGhpcy5fY2ZnLnN0b3Jlc1NvdXJjZSwgc3RvcmVzKSA6IHN0b3JlczsKICAgICAgICAgICAgLy8gRGVyaXZlIHN0b3JlcyBmcm9tIGVhcmxpZXIgdmVyc2lvbnMgaWYgdGhleSBhcmUgbm90IGV4cGxpY2l0ZWx5IHNwZWNpZmllZCBhcyBudWxsIG9yIGEgbmV3IHN5bnRheC4KICAgICAgICAgICAgdmFyIHN0b3Jlc1NwZWMgPSB7fTsKICAgICAgICAgICAgdmVyc2lvbnMuZm9yRWFjaChmdW5jdGlvbiAodmVyc2lvbikgewogICAgICAgICAgICAgICAgZXh0ZW5kKHN0b3Jlc1NwZWMsIHZlcnNpb24uX2NmZy5zdG9yZXNTb3VyY2UpOwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgdmFyIGRic2NoZW1hID0gKHRoaXMuX2NmZy5kYnNjaGVtYSA9IHt9KTsKICAgICAgICAgICAgdGhpcy5fcGFyc2VTdG9yZXNTcGVjKHN0b3Jlc1NwZWMsIGRic2NoZW1hKTsKICAgICAgICAgICAgLy8gVXBkYXRlIHRoZSBsYXRlc3Qgc2NoZW1hIHRvIHRoaXMgdmVyc2lvbgogICAgICAgICAgICAvLyBVcGRhdGUgQVBJCiAgICAgICAgICAgIGdsb2JhbFNjaGVtYSA9IGRiLl9kYlNjaGVtYSA9IGRic2NoZW1hOwogICAgICAgICAgICByZW1vdmVUYWJsZXNBcGkoW2FsbFRhYmxlcywgZGIsIFRyYW5zYWN0aW9uLnByb3RvdHlwZV0pOyAvLyBLZWVwIFRyYW5zYWN0aW9uLnByb3RvdHlwZSBldmVuIHRob3VnaCBpdCBzaG91bGQgYmUgZGVwci4KICAgICAgICAgICAgc2V0QXBpT25QbGFjZShbYWxsVGFibGVzLCBkYiwgVHJhbnNhY3Rpb24ucHJvdG90eXBlLCB0aGlzLl9jZmcudGFibGVzXSwga2V5cyhkYnNjaGVtYSksIGRic2NoZW1hKTsKICAgICAgICAgICAgZGJTdG9yZU5hbWVzID0ga2V5cyhkYnNjaGVtYSk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0sCiAgICAgICAgdXBncmFkZTogZnVuY3Rpb24gKHVwZ3JhZGVGdW5jdGlvbikgewogICAgICAgICAgICB0aGlzLl9jZmcuY29udGVudFVwZ3JhZGUgPSB1cGdyYWRlRnVuY3Rpb247CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0sCiAgICAgICAgX3BhcnNlU3RvcmVzU3BlYzogZnVuY3Rpb24gKHN0b3Jlcywgb3V0U2NoZW1hKSB7CiAgICAgICAgICAgIGtleXMoc3RvcmVzKS5mb3JFYWNoKGZ1bmN0aW9uICh0YWJsZU5hbWUpIHsKICAgICAgICAgICAgICAgIGlmIChzdG9yZXNbdGFibGVOYW1lXSAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIHZhciBpbnN0YW5jZVRlbXBsYXRlID0ge307CiAgICAgICAgICAgICAgICAgICAgdmFyIGluZGV4ZXMgPSBwYXJzZUluZGV4U3ludGF4KHN0b3Jlc1t0YWJsZU5hbWVdKTsKICAgICAgICAgICAgICAgICAgICB2YXIgcHJpbUtleSA9IGluZGV4ZXMuc2hpZnQoKTsKICAgICAgICAgICAgICAgICAgICBpZiAocHJpbUtleS5tdWx0aSkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IGV4Y2VwdGlvbnMuU2NoZW1hKCJQcmltYXJ5IGtleSBjYW5ub3QgYmUgbXVsdGktdmFsdWVkIik7CiAgICAgICAgICAgICAgICAgICAgaWYgKHByaW1LZXkua2V5UGF0aCkKICAgICAgICAgICAgICAgICAgICAgICAgc2V0QnlLZXlQYXRoKGluc3RhbmNlVGVtcGxhdGUsIHByaW1LZXkua2V5UGF0aCwgcHJpbUtleS5hdXRvID8gMCA6IHByaW1LZXkua2V5UGF0aCk7CiAgICAgICAgICAgICAgICAgICAgaW5kZXhlcy5mb3JFYWNoKGZ1bmN0aW9uIChpZHgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlkeC5hdXRvKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IGV4Y2VwdGlvbnMuU2NoZW1hKCJPbmx5IHByaW1hcnkga2V5IGNhbiBiZSBtYXJrZWQgYXMgYXV0b0luY3JlbWVudCAoKyspIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaWR4LmtleVBhdGgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgZXhjZXB0aW9ucy5TY2hlbWEoIkluZGV4IG11c3QgaGF2ZSBhIG5hbWUgYW5kIGNhbm5vdCBiZSBhbiBlbXB0eSBzdHJpbmciKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2V0QnlLZXlQYXRoKGluc3RhbmNlVGVtcGxhdGUsIGlkeC5rZXlQYXRoLCBpZHguY29tcG91bmQgPyBpZHgua2V5UGF0aC5tYXAoZnVuY3Rpb24gKCkgeyByZXR1cm4gIiI7IH0pIDogIiIpOwogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIG91dFNjaGVtYVt0YWJsZU5hbWVdID0gbmV3IFRhYmxlU2NoZW1hKHRhYmxlTmFtZSwgcHJpbUtleSwgaW5kZXhlcywgaW5zdGFuY2VUZW1wbGF0ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0pOwogICAgZnVuY3Rpb24gcnVuVXBncmFkZXJzKG9sZFZlcnNpb24sIGlkYnRyYW5zLCByZWplY3QpIHsKICAgICAgICB2YXIgdHJhbnMgPSBkYi5fY3JlYXRlVHJhbnNhY3Rpb24oUkVBRFdSSVRFLCBkYlN0b3JlTmFtZXMsIGdsb2JhbFNjaGVtYSk7CiAgICAgICAgdHJhbnMuY3JlYXRlKGlkYnRyYW5zKTsKICAgICAgICB0cmFucy5fY29tcGxldGlvbi5jYXRjaChyZWplY3QpOwogICAgICAgIHZhciByZWplY3RUcmFuc2FjdGlvbiA9IHRyYW5zLl9yZWplY3QuYmluZCh0cmFucyk7CiAgICAgICAgbmV3U2NvcGUoZnVuY3Rpb24gKCkgewogICAgICAgICAgICBQU0QudHJhbnMgPSB0cmFuczsKICAgICAgICAgICAgaWYgKG9sZFZlcnNpb24gPT09IDApIHsKICAgICAgICAgICAgICAgIC8vIENyZWF0ZSB0YWJsZXM6CiAgICAgICAgICAgICAgICBrZXlzKGdsb2JhbFNjaGVtYSkuZm9yRWFjaChmdW5jdGlvbiAodGFibGVOYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgY3JlYXRlVGFibGUoaWRidHJhbnMsIHRhYmxlTmFtZSwgZ2xvYmFsU2NoZW1hW3RhYmxlTmFtZV0ucHJpbUtleSwgZ2xvYmFsU2NoZW1hW3RhYmxlTmFtZV0uaW5kZXhlcyk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIFByb21pc2UuZm9sbG93KGZ1bmN0aW9uICgpIHsgcmV0dXJuIGRiLm9uLnBvcHVsYXRlLmZpcmUodHJhbnMpOyB9KS5jYXRjaChyZWplY3RUcmFuc2FjdGlvbik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgdXBkYXRlVGFibGVzQW5kSW5kZXhlcyhvbGRWZXJzaW9uLCB0cmFucywgaWRidHJhbnMpLmNhdGNoKHJlamVjdFRyYW5zYWN0aW9uKTsKICAgICAgICB9KTsKICAgIH0KICAgIGZ1bmN0aW9uIHVwZGF0ZVRhYmxlc0FuZEluZGV4ZXMob2xkVmVyc2lvbiwgdHJhbnMsIGlkYnRyYW5zKSB7CiAgICAgICAgLy8gVXBncmFkZSB2ZXJzaW9uIHRvIHZlcnNpb24sIHN0ZXAtYnktc3RlcCBmcm9tIG9sZGVzdCB0byBuZXdlc3QgdmVyc2lvbi4KICAgICAgICAvLyBFYWNoIHRyYW5zYWN0aW9uIG9iamVjdCB3aWxsIGNvbnRhaW4gdGhlIHRhYmxlIHNldCB0aGF0IHdhcyBjdXJyZW50IGluIHRoYXQgdmVyc2lvbiAoYnV0IGFsc28gbm90LXlldC1kZWxldGVkIHRhYmxlcyBmcm9tIGl0cyBwcmV2aW91cyB2ZXJzaW9uKQogICAgICAgIHZhciBxdWV1ZSA9IFtdOwogICAgICAgIHZhciBvbGRWZXJzaW9uU3RydWN0ID0gdmVyc2lvbnMuZmlsdGVyKGZ1bmN0aW9uICh2ZXJzaW9uKSB7IHJldHVybiB2ZXJzaW9uLl9jZmcudmVyc2lvbiA9PT0gb2xkVmVyc2lvbjsgfSlbMF07CiAgICAgICAgaWYgKCFvbGRWZXJzaW9uU3RydWN0KQogICAgICAgICAgICB0aHJvdyBuZXcgZXhjZXB0aW9ucy5VcGdyYWRlKCJEZXhpZSBzcGVjaWZpY2F0aW9uIG9mIGN1cnJlbnRseSBpbnN0YWxsZWQgREIgdmVyc2lvbiBpcyBtaXNzaW5nIik7CiAgICAgICAgZ2xvYmFsU2NoZW1hID0gZGIuX2RiU2NoZW1hID0gb2xkVmVyc2lvblN0cnVjdC5fY2ZnLmRic2NoZW1hOwogICAgICAgIHZhciBhbnlDb250ZW50VXBncmFkZXJIYXNSdW4gPSBmYWxzZTsKICAgICAgICB2YXIgdmVyc1RvUnVuID0gdmVyc2lvbnMuZmlsdGVyKGZ1bmN0aW9uICh2KSB7IHJldHVybiB2Ll9jZmcudmVyc2lvbiA+IG9sZFZlcnNpb247IH0pOwogICAgICAgIHZlcnNUb1J1bi5mb3JFYWNoKGZ1bmN0aW9uICh2ZXJzaW9uKSB7CiAgICAgICAgICAgIC8vLyA8cGFyYW0gbmFtZT0idmVyc2lvbiIgdHlwZT0iVmVyc2lvbiI+PC9wYXJhbT4KICAgICAgICAgICAgcXVldWUucHVzaChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgb2xkU2NoZW1hID0gZ2xvYmFsU2NoZW1hOwogICAgICAgICAgICAgICAgdmFyIG5ld1NjaGVtYSA9IHZlcnNpb24uX2NmZy5kYnNjaGVtYTsKICAgICAgICAgICAgICAgIGFkanVzdFRvRXhpc3RpbmdJbmRleE5hbWVzKG9sZFNjaGVtYSwgaWRidHJhbnMpOwogICAgICAgICAgICAgICAgYWRqdXN0VG9FeGlzdGluZ0luZGV4TmFtZXMobmV3U2NoZW1hLCBpZGJ0cmFucyk7CiAgICAgICAgICAgICAgICBnbG9iYWxTY2hlbWEgPSBkYi5fZGJTY2hlbWEgPSBuZXdTY2hlbWE7CiAgICAgICAgICAgICAgICB2YXIgZGlmZiA9IGdldFNjaGVtYURpZmYob2xkU2NoZW1hLCBuZXdTY2hlbWEpOwogICAgICAgICAgICAgICAgLy8gQWRkIHRhYmxlcyAgICAgICAgICAgCiAgICAgICAgICAgICAgICBkaWZmLmFkZC5mb3JFYWNoKGZ1bmN0aW9uICh0dXBsZSkgewogICAgICAgICAgICAgICAgICAgIGNyZWF0ZVRhYmxlKGlkYnRyYW5zLCB0dXBsZVswXSwgdHVwbGVbMV0ucHJpbUtleSwgdHVwbGVbMV0uaW5kZXhlcyk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIC8vIENoYW5nZSB0YWJsZXMKICAgICAgICAgICAgICAgIGRpZmYuY2hhbmdlLmZvckVhY2goZnVuY3Rpb24gKGNoYW5nZSkgewogICAgICAgICAgICAgICAgICAgIGlmIChjaGFuZ2UucmVjcmVhdGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IGV4Y2VwdGlvbnMuVXBncmFkZSgiTm90IHlldCBzdXBwb3J0IGZvciBjaGFuZ2luZyBwcmltYXJ5IGtleSIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHN0b3JlID0gaWRidHJhbnMub2JqZWN0U3RvcmUoY2hhbmdlLm5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICAvLyBBZGQgaW5kZXhlcwogICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2UuYWRkLmZvckVhY2goZnVuY3Rpb24gKGlkeCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkSW5kZXgoc3RvcmUsIGlkeCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICAvLyBVcGRhdGUgaW5kZXhlcwogICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2UuY2hhbmdlLmZvckVhY2goZnVuY3Rpb24gKGlkeCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmUuZGVsZXRlSW5kZXgoaWR4Lm5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkSW5kZXgoc3RvcmUsIGlkeCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICAvLyBEZWxldGUgaW5kZXhlcwogICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2UuZGVsLmZvckVhY2goZnVuY3Rpb24gKGlkeE5hbWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0b3JlLmRlbGV0ZUluZGV4KGlkeE5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIGlmICh2ZXJzaW9uLl9jZmcuY29udGVudFVwZ3JhZGUpIHsKICAgICAgICAgICAgICAgICAgICBhbnlDb250ZW50VXBncmFkZXJIYXNSdW4gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmZvbGxvdyhmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZlcnNpb24uX2NmZy5jb250ZW50VXBncmFkZSh0cmFucyk7CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBxdWV1ZS5wdXNoKGZ1bmN0aW9uIChpZGJ0cmFucykgewogICAgICAgICAgICAgICAgaWYgKCFhbnlDb250ZW50VXBncmFkZXJIYXNSdW4gfHwgIWhhc0lFRGVsZXRlT2JqZWN0U3RvcmVCdWcpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbmV3U2NoZW1hID0gdmVyc2lvbi5fY2ZnLmRic2NoZW1hOwogICAgICAgICAgICAgICAgICAgIC8vIERlbGV0ZSBvbGQgdGFibGVzCiAgICAgICAgICAgICAgICAgICAgZGVsZXRlUmVtb3ZlZFRhYmxlcyhuZXdTY2hlbWEsIGlkYnRyYW5zKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfSk7CiAgICAgICAgLy8gTm93LCBjcmVhdGUgYSBxdWV1ZSBleGVjdXRpb24gZW5naW5lCiAgICAgICAgZnVuY3Rpb24gcnVuUXVldWUoKSB7CiAgICAgICAgICAgIHJldHVybiBxdWV1ZS5sZW5ndGggPyBQcm9taXNlLnJlc29sdmUocXVldWUuc2hpZnQoKSh0cmFucy5pZGJ0cmFucykpLnRoZW4ocnVuUXVldWUpIDoKICAgICAgICAgICAgICAgIFByb21pc2UucmVzb2x2ZSgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcnVuUXVldWUoKS50aGVuKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgY3JlYXRlTWlzc2luZ1RhYmxlcyhnbG9iYWxTY2hlbWEsIGlkYnRyYW5zKTsgLy8gQXQgbGFzdCwgbWFrZSBzdXJlIHRvIGNyZWF0ZSBhbnkgbWlzc2luZyB0YWJsZXMuIChOZWVkZWQgYnkgYWRkb25zIHRoYXQgYWRkIHN0b3JlcyB0byBEQiB3aXRob3V0IHNwZWNpZnlpbmcgdmVyc2lvbikKICAgICAgICB9KTsKICAgIH0KICAgIGZ1bmN0aW9uIGdldFNjaGVtYURpZmYob2xkU2NoZW1hLCBuZXdTY2hlbWEpIHsKICAgICAgICB2YXIgZGlmZiA9IHsKICAgICAgICAgICAgZGVsOiBbXSwKICAgICAgICAgICAgYWRkOiBbXSwKICAgICAgICAgICAgY2hhbmdlOiBbXSAvLyBBcnJheSBvZiB7bmFtZTogdGFibGVOYW1lLCByZWNyZWF0ZTogbmV3RGVmaW5pdGlvbiwgZGVsOiBkZWxJbmRleE5hbWVzLCBhZGQ6IG5ld0luZGV4RGVmcywgY2hhbmdlOiBjaGFuZ2VkSW5kZXhEZWZzfQogICAgICAgIH07CiAgICAgICAgZm9yICh2YXIgdGFibGUgaW4gb2xkU2NoZW1hKSB7CiAgICAgICAgICAgIGlmICghbmV3U2NoZW1hW3RhYmxlXSkKICAgICAgICAgICAgICAgIGRpZmYuZGVsLnB1c2godGFibGUpOwogICAgICAgIH0KICAgICAgICBmb3IgKHRhYmxlIGluIG5ld1NjaGVtYSkgewogICAgICAgICAgICB2YXIgb2xkRGVmID0gb2xkU2NoZW1hW3RhYmxlXSwgbmV3RGVmID0gbmV3U2NoZW1hW3RhYmxlXTsKICAgICAgICAgICAgaWYgKCFvbGREZWYpIHsKICAgICAgICAgICAgICAgIGRpZmYuYWRkLnB1c2goW3RhYmxlLCBuZXdEZWZdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHZhciBjaGFuZ2UgPSB7CiAgICAgICAgICAgICAgICAgICAgbmFtZTogdGFibGUsCiAgICAgICAgICAgICAgICAgICAgZGVmOiBuZXdEZWYsCiAgICAgICAgICAgICAgICAgICAgcmVjcmVhdGU6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgIGRlbDogW10sCiAgICAgICAgICAgICAgICAgICAgYWRkOiBbXSwKICAgICAgICAgICAgICAgICAgICBjaGFuZ2U6IFtdCiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgaWYgKG9sZERlZi5wcmltS2V5LnNyYyAhPT0gbmV3RGVmLnByaW1LZXkuc3JjKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gUHJpbWFyeSBrZXkgaGFzIGNoYW5nZWQuIFJlbW92ZSBhbmQgcmUtYWRkIHRhYmxlLgogICAgICAgICAgICAgICAgICAgIGNoYW5nZS5yZWNyZWF0ZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgZGlmZi5jaGFuZ2UucHVzaChjaGFuZ2UpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy8gU2FtZSBwcmltYXJ5IGtleS4gSnVzdCBmaW5kIG91dCB3aGF0IGRpZmZlcnM6CiAgICAgICAgICAgICAgICAgICAgdmFyIG9sZEluZGV4ZXMgPSBvbGREZWYuaWR4QnlOYW1lOwogICAgICAgICAgICAgICAgICAgIHZhciBuZXdJbmRleGVzID0gbmV3RGVmLmlkeEJ5TmFtZTsKICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpZHhOYW1lIGluIG9sZEluZGV4ZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFuZXdJbmRleGVzW2lkeE5hbWVdKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlLmRlbC5wdXNoKGlkeE5hbWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBmb3IgKGlkeE5hbWUgaW4gbmV3SW5kZXhlcykgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgb2xkSWR4ID0gb2xkSW5kZXhlc1tpZHhOYW1lXSwgbmV3SWR4ID0gbmV3SW5kZXhlc1tpZHhOYW1lXTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFvbGRJZHgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2UuYWRkLnB1c2gobmV3SWR4KTsKICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAob2xkSWR4LnNyYyAhPT0gbmV3SWR4LnNyYykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZS5jaGFuZ2UucHVzaChuZXdJZHgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoY2hhbmdlLmRlbC5sZW5ndGggPiAwIHx8IGNoYW5nZS5hZGQubGVuZ3RoID4gMCB8fCBjaGFuZ2UuY2hhbmdlLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgZGlmZi5jaGFuZ2UucHVzaChjaGFuZ2UpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZGlmZjsKICAgIH0KICAgIGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKGlkYnRyYW5zLCB0YWJsZU5hbWUsIHByaW1LZXksIGluZGV4ZXMpIHsKICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImlkYnRyYW5zIiB0eXBlPSJJREJUcmFuc2FjdGlvbiI+PC9wYXJhbT4KICAgICAgICB2YXIgc3RvcmUgPSBpZGJ0cmFucy5kYi5jcmVhdGVPYmplY3RTdG9yZSh0YWJsZU5hbWUsIHByaW1LZXkua2V5UGF0aCA/IHsga2V5UGF0aDogcHJpbUtleS5rZXlQYXRoLCBhdXRvSW5jcmVtZW50OiBwcmltS2V5LmF1dG8gfSA6IHsgYXV0b0luY3JlbWVudDogcHJpbUtleS5hdXRvIH0pOwogICAgICAgIGluZGV4ZXMuZm9yRWFjaChmdW5jdGlvbiAoaWR4KSB7IGFkZEluZGV4KHN0b3JlLCBpZHgpOyB9KTsKICAgICAgICByZXR1cm4gc3RvcmU7CiAgICB9CiAgICBmdW5jdGlvbiBjcmVhdGVNaXNzaW5nVGFibGVzKG5ld1NjaGVtYSwgaWRidHJhbnMpIHsKICAgICAgICBrZXlzKG5ld1NjaGVtYSkuZm9yRWFjaChmdW5jdGlvbiAodGFibGVOYW1lKSB7CiAgICAgICAgICAgIGlmICghaWRidHJhbnMuZGIub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyh0YWJsZU5hbWUpKSB7CiAgICAgICAgICAgICAgICBjcmVhdGVUYWJsZShpZGJ0cmFucywgdGFibGVOYW1lLCBuZXdTY2hlbWFbdGFibGVOYW1lXS5wcmltS2V5LCBuZXdTY2hlbWFbdGFibGVOYW1lXS5pbmRleGVzKTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfQogICAgZnVuY3Rpb24gZGVsZXRlUmVtb3ZlZFRhYmxlcyhuZXdTY2hlbWEsIGlkYnRyYW5zKSB7CiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpZGJ0cmFucy5kYi5vYmplY3RTdG9yZU5hbWVzLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIHZhciBzdG9yZU5hbWUgPSBpZGJ0cmFucy5kYi5vYmplY3RTdG9yZU5hbWVzW2ldOwogICAgICAgICAgICBpZiAobmV3U2NoZW1hW3N0b3JlTmFtZV0gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgaWRidHJhbnMuZGIuZGVsZXRlT2JqZWN0U3RvcmUoc3RvcmVOYW1lKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGZ1bmN0aW9uIGFkZEluZGV4KHN0b3JlLCBpZHgpIHsKICAgICAgICBzdG9yZS5jcmVhdGVJbmRleChpZHgubmFtZSwgaWR4LmtleVBhdGgsIHsgdW5pcXVlOiBpZHgudW5pcXVlLCBtdWx0aUVudHJ5OiBpZHgubXVsdGkgfSk7CiAgICB9CiAgICAvLwogICAgLy8KICAgIC8vICAgICAgRGV4aWUgUHJvdGVjdGVkIEFQSQogICAgLy8KICAgIC8vCiAgICB0aGlzLl9hbGxUYWJsZXMgPSBhbGxUYWJsZXM7CiAgICB0aGlzLl9jcmVhdGVUcmFuc2FjdGlvbiA9IGZ1bmN0aW9uIChtb2RlLCBzdG9yZU5hbWVzLCBkYnNjaGVtYSwgcGFyZW50VHJhbnNhY3Rpb24pIHsKICAgICAgICByZXR1cm4gbmV3IFRyYW5zYWN0aW9uKG1vZGUsIHN0b3JlTmFtZXMsIGRic2NoZW1hLCBwYXJlbnRUcmFuc2FjdGlvbik7CiAgICB9OwogICAgLyogR2VuZXJhdGUgYSB0ZW1wb3JhcnkgdHJhbnNhY3Rpb24gd2hlbiBkYiBvcGVyYXRpb25zIGFyZSBkb25lIG91dHNpZGUgYSB0cmFuc2FjdGlvbiBzY29wZS4KICAgICovCiAgICBmdW5jdGlvbiB0ZW1wVHJhbnNhY3Rpb24obW9kZSwgc3RvcmVOYW1lcywgZm4pIHsKICAgICAgICBpZiAoIW9wZW5Db21wbGV0ZSAmJiAoIVBTRC5sZXRUaHJvdWdoKSkgewogICAgICAgICAgICBpZiAoIWlzQmVpbmdPcGVuZWQpIHsKICAgICAgICAgICAgICAgIGlmICghYXV0b09wZW4pCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdGlvbihuZXcgZXhjZXB0aW9ucy5EYXRhYmFzZUNsb3NlZCgpKTsKICAgICAgICAgICAgICAgIGRiLm9wZW4oKS5jYXRjaChub3ApOyAvLyBPcGVuIGluIGJhY2tncm91bmQuIElmIGlmIGZhaWxzLCBpdCB3aWxsIGJlIGNhdGNoZWQgYnkgdGhlIGZpbmFsIHByb21pc2UgYW55d2F5LgogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBkYlJlYWR5UHJvbWlzZS50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRlbXBUcmFuc2FjdGlvbihtb2RlLCBzdG9yZU5hbWVzLCBmbik7IH0pOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgdmFyIHRyYW5zID0gZGIuX2NyZWF0ZVRyYW5zYWN0aW9uKG1vZGUsIHN0b3JlTmFtZXMsIGdsb2JhbFNjaGVtYSk7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICB0cmFucy5jcmVhdGUoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjYXRjaCAoZXgpIHsKICAgICAgICAgICAgICAgIHJldHVybiByZWplY3Rpb24oZXgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0cmFucy5fcHJvbWlzZShtb2RlLCBmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3U2NvcGUoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIFBTRC50cmFucyA9IHRyYW5zOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBmbihyZXNvbHZlLCByZWplY3QsIHRyYW5zKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHsKICAgICAgICAgICAgICAgIC8vIEluc3RlYWQgb2YgcmVzb2x2aW5nIHZhbHVlIGRpcmVjdGx5LCB3YWl0IHdpdGggcmVzb2x2aW5nIGl0IHVudGlsIHRyYW5zYWN0aW9uIGhhcyBjb21wbGV0ZWQuCiAgICAgICAgICAgICAgICAvLyBPdGhlcndpc2UgdGhlIGRhdGEgd291bGQgbm90IGJlIGluIHRoZSBEQiBpZiByZXF1ZXN0aW5nIGl0IGluIHRoZSB0aGVuKCkgb3BlcmF0aW9uLgogICAgICAgICAgICAgICAgLy8gU3BlY2lmaWNhbGx5LCB0byBlbnN1cmUgdGhhdCB0aGUgZm9sbG93aW5nIGV4cHJlc3Npb24gd2lsbCB3b3JrOgogICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgIC8vICAgZGIuZnJpZW5kcy5wdXQoe25hbWU6ICJBcm5lIn0pLnRoZW4oZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgLy8gICAgICAgZGIuZnJpZW5kcy53aGVyZSgibmFtZSIpLmVxdWFscygiQXJuZSIpLmNvdW50KGZ1bmN0aW9uKGNvdW50KSB7CiAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgYXNzZXJ0IChjb3VudCA9PT0gMSk7CiAgICAgICAgICAgICAgICAvLyAgICAgICB9KTsKICAgICAgICAgICAgICAgIC8vICAgfSk7CiAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgcmV0dXJuIHRyYW5zLl9jb21wbGV0aW9uLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gcmVzdWx0OyB9KTsKICAgICAgICAgICAgfSk7IC8qLmNhdGNoKGVyciA9PiB7IC8vIERvbid0IGRvIHRoaXMgYXMgb2Ygbm93LiBJZiB3b3VsZCBhZmZlY3QgYnVsay0gYW5kIG1vZGlmeSBtZXRob2RzIGluIGEgd2F5IHRoYXQgY291bGQgYmUgbW9yZSBpbnR1aXRpdmUuIEJ1dCB3YWl0ISBNYXliZSBjaGFuZ2UgaW4gbmV4dCBtYWpvci4KICAgICAgICAgICAgICAgIHRyYW5zLl9yZWplY3QoZXJyKTsKICAgICAgICAgICAgICAgIHJldHVybiByZWplY3Rpb24oZXJyKTsKICAgICAgICAgICAgfSk7Ki8KICAgICAgICB9CiAgICB9CiAgICB0aGlzLl93aGVuUmVhZHkgPSBmdW5jdGlvbiAoZm4pIHsKICAgICAgICByZXR1cm4gb3BlbkNvbXBsZXRlIHx8IFBTRC5sZXRUaHJvdWdoID8gZm4oKSA6IG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHsKICAgICAgICAgICAgaWYgKCFpc0JlaW5nT3BlbmVkKSB7CiAgICAgICAgICAgICAgICBpZiAoIWF1dG9PcGVuKSB7CiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBleGNlcHRpb25zLkRhdGFiYXNlQ2xvc2VkKCkpOwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGRiLm9wZW4oKS5jYXRjaChub3ApOyAvLyBPcGVuIGluIGJhY2tncm91bmQuIElmIGlmIGZhaWxzLCBpdCB3aWxsIGJlIGNhdGNoZWQgYnkgdGhlIGZpbmFsIHByb21pc2UgYW55d2F5LgogICAgICAgICAgICB9CiAgICAgICAgICAgIGRiUmVhZHlQcm9taXNlLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTsKICAgICAgICB9KS50aGVuKGZuKTsKICAgIH07CiAgICAvLwogICAgLy8KICAgIC8vCiAgICAvLwogICAgLy8gICAgICBEZXhpZSBBUEkKICAgIC8vCiAgICAvLwogICAgLy8KICAgIHRoaXMudmVybm8gPSAwOwogICAgdGhpcy5vcGVuID0gZnVuY3Rpb24gKCkgewogICAgICAgIGlmIChpc0JlaW5nT3BlbmVkIHx8IGlkYmRiKQogICAgICAgICAgICByZXR1cm4gZGJSZWFkeVByb21pc2UudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBkYk9wZW5FcnJvciA/IHJlamVjdGlvbihkYk9wZW5FcnJvcikgOiBkYjsgfSk7CiAgICAgICAgZGVidWcgJiYgKG9wZW5DYW5jZWxsZXIuX3N0YWNrSG9sZGVyID0gZ2V0RXJyb3JXaXRoU3RhY2soKSk7IC8vIExldCBzdGFja3MgcG9pbnQgdG8gd2hlbiBvcGVuKCkgd2FzIGNhbGxlZCByYXRoZXIgdGhhbiB3aGVyZSBuZXcgRGV4aWUoKSB3YXMgY2FsbGVkLgogICAgICAgIGlzQmVpbmdPcGVuZWQgPSB0cnVlOwogICAgICAgIGRiT3BlbkVycm9yID0gbnVsbDsKICAgICAgICBvcGVuQ29tcGxldGUgPSBmYWxzZTsKICAgICAgICAvLyBGdW5jdGlvbiBwb2ludGVycyB0byBjYWxsIHdoZW4gdGhlIGNvcmUgb3BlbmluZyBwcm9jZXNzIGNvbXBsZXRlcy4KICAgICAgICB2YXIgcmVzb2x2ZURiUmVhZHkgPSBkYlJlYWR5UmVzb2x2ZSwgCiAgICAgICAgLy8gdXBncmFkZVRyYW5zYWN0aW9uIHRvIGFib3J0IG9uIGZhaWx1cmUuCiAgICAgICAgdXBncmFkZVRyYW5zYWN0aW9uID0gbnVsbDsKICAgICAgICByZXR1cm4gUHJvbWlzZS5yYWNlKFtvcGVuQ2FuY2VsbGVyLCBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7CiAgICAgICAgICAgICAgICAvLyBNdWx0aXBseSBkYi52ZXJubyB3aXRoIDEwIHdpbGwgYmUgbmVlZGVkIHRvIHdvcmthcm91bmQgdXBncmFkaW5nIGJ1ZyBpbiBJRToKICAgICAgICAgICAgICAgIC8vIElFIGZhaWxzIHdoZW4gZGVsZXRpbmcgb2JqZWN0U3RvcmUgYWZ0ZXIgcmVhZGluZyBmcm9tIGl0LgogICAgICAgICAgICAgICAgLy8gQSBmdXR1cmUgdmVyc2lvbiBvZiBEZXhpZS5qcyB3aWxsIHN0b3BvdmVyIGFuIGludGVybWVkaWF0ZSB2ZXJzaW9uIHRvIHdvcmthcm91bmQgdGhpcy4KICAgICAgICAgICAgICAgIC8vIEF0IHRoYXQgcG9pbnQsIHdlIHdhbnQgdG8gYmUgYmFja3dhcmQgY29tcGF0aWJsZS4gQ291bGQgaGF2ZSBiZWVuIG11bHRpcGxpZWQgd2l0aCAyLCBidXQgYnkgdXNpbmcgMTAsIGl0IGlzIGVhc2llciB0byBtYXAgdGhlIG51bWJlciB0byB0aGUgcmVhbCB2ZXJzaW9uIG51bWJlci4KICAgICAgICAgICAgICAgIC8vIElmIG5vIEFQSSwgdGhyb3chCiAgICAgICAgICAgICAgICBpZiAoIWluZGV4ZWREQikKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgZXhjZXB0aW9ucy5NaXNzaW5nQVBJKCJpbmRleGVkREIgQVBJIG5vdCBmb3VuZC4gSWYgdXNpbmcgSUUxMCssIG1ha2Ugc3VyZSB0byBydW4geW91ciBjb2RlIG9uIGEgc2VydmVyIFVSTCAiICsKICAgICAgICAgICAgICAgICAgICAgICAgIihub3QgbG9jYWxseSkuIElmIHVzaW5nIG9sZCBTYWZhcmkgdmVyc2lvbnMsIG1ha2Ugc3VyZSB0byBpbmNsdWRlIGluZGV4ZWREQiBwb2x5ZmlsbC4iKTsKICAgICAgICAgICAgICAgIHZhciByZXEgPSBhdXRvU2NoZW1hID8gaW5kZXhlZERCLm9wZW4oZGJOYW1lKSA6IGluZGV4ZWREQi5vcGVuKGRiTmFtZSwgTWF0aC5yb3VuZChkYi52ZXJubyAqIDEwKSk7CiAgICAgICAgICAgICAgICBpZiAoIXJlcSkKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgZXhjZXB0aW9ucy5NaXNzaW5nQVBJKCJJbmRleGVkREIgQVBJIG5vdCBhdmFpbGFibGUiKTsgLy8gTWF5IGhhcHBlbiBpbiBTYWZhcmkgcHJpdmF0ZSBtb2RlLCBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2RmYWhsYW5kZXIvRGV4aWUuanMvaXNzdWVzLzEzNAogICAgICAgICAgICAgICAgcmVxLm9uZXJyb3IgPSBldmVudFJlamVjdEhhbmRsZXIocmVqZWN0KTsKICAgICAgICAgICAgICAgIHJlcS5vbmJsb2NrZWQgPSB3cmFwKGZpcmVPbkJsb2NrZWQpOwogICAgICAgICAgICAgICAgcmVxLm9udXBncmFkZW5lZWRlZCA9IHdyYXAoZnVuY3Rpb24gKGUpIHsKICAgICAgICAgICAgICAgICAgICB1cGdyYWRlVHJhbnNhY3Rpb24gPSByZXEudHJhbnNhY3Rpb247CiAgICAgICAgICAgICAgICAgICAgaWYgKGF1dG9TY2hlbWEgJiYgIWRiLl9hbGxvd0VtcHR5REIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2FsbGVyIGRpZCBub3Qgc3BlY2lmeSBhIHZlcnNpb24gb3Igc2NoZW1hLiBEb2luZyB0aGF0IGlzIG9ubHkgYWNjZXB0YWJsZSBmb3Igb3BlbmluZyBhbHJlYWQgZXhpc3RpbmcgZGF0YWJhc2VzLgogICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiBvbnVwZ3JhZGVuZWVkZWQgaXMgY2FsbGVkIGl0IG1lYW5zIGRhdGFiYXNlIGRpZCBub3QgZXhpc3QuIFJlamVjdCB0aGUgb3BlbigpIHByb21pc2UgYW5kIG1ha2Ugc3VyZSB0aGF0IHdlCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRvIG5vdCBjcmVhdGUgYSBuZXcgZGF0YWJhc2UgYnkgYWNjaWRlbnQgaGVyZS4KICAgICAgICAgICAgICAgICAgICAgICAgcmVxLm9uZXJyb3IgPSBwcmV2ZW50RGVmYXVsdDsgLy8gUHJvaGliaXQgb25hYm9ydCBlcnJvciBmcm9tIGZpcmluZyBiZWZvcmUgd2UncmUgZG9uZSEKICAgICAgICAgICAgICAgICAgICAgICAgdXBncmFkZVRyYW5zYWN0aW9uLmFib3J0KCk7IC8vIEFib3J0IHRyYW5zYWN0aW9uICh3b3VsZCBob3BlIHRoYXQgdGhpcyB3b3VsZCBtYWtlIERCIGRpc2FwcGVhciBidXQgaXQgZG9lc250LikKICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2xvc2UgZGF0YWJhc2UgYW5kIGRlbGV0ZSBpdC4KICAgICAgICAgICAgICAgICAgICAgICAgcmVxLnJlc3VsdC5jbG9zZSgpOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGVscmVxID0gaW5kZXhlZERCLmRlbGV0ZURhdGFiYXNlKGRiTmFtZSk7IC8vIFRoZSB1cGdyYWRlIHRyYW5zYWN0aW9uIGlzIGF0b21pYywgYW5kIGphdmFzY3JpcHQgaXMgc2luZ2xlIHRocmVhZGVkIC0gbWVhbmluZyB0aGF0IHRoZXJlIGlzIG5vIHJpc2sgdGhhdCB3ZSBkZWxldGUgc29tZW9uZSBlbHNlcyBkYXRhYmFzZSBoZXJlIQogICAgICAgICAgICAgICAgICAgICAgICBkZWxyZXEub25zdWNjZXNzID0gZGVscmVxLm9uZXJyb3IgPSB3cmFwKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgZXhjZXB0aW9ucy5Ob1N1Y2hEYXRhYmFzZSgiRGF0YWJhc2UgIiArIGRiTmFtZSArICIgZG9lc250IGV4aXN0IikpOwogICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHVwZ3JhZGVUcmFuc2FjdGlvbi5vbmVycm9yID0gZXZlbnRSZWplY3RIYW5kbGVyKHJlamVjdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvbGRWZXIgPSBlLm9sZFZlcnNpb24gPiBNYXRoLnBvdygyLCA2MikgPyAwIDogZS5vbGRWZXJzaW9uOyAvLyBTYWZhcmkgOCBmaXguCiAgICAgICAgICAgICAgICAgICAgICAgIHJ1blVwZ3JhZGVycyhvbGRWZXIgLyAxMCwgdXBncmFkZVRyYW5zYWN0aW9uLCByZWplY3QsIHJlcSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwgcmVqZWN0KTsKICAgICAgICAgICAgICAgIHJlcS5vbnN1Y2Nlc3MgPSB3cmFwKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAvLyBDb3JlIG9wZW5pbmcgcHJvY2VkdXJlIGNvbXBsZXRlLiBOb3cgbGV0J3MganVzdCByZWNvcmQgc29tZSBzdHVmZi4KICAgICAgICAgICAgICAgICAgICB1cGdyYWRlVHJhbnNhY3Rpb24gPSBudWxsOwogICAgICAgICAgICAgICAgICAgIGlkYmRiID0gcmVxLnJlc3VsdDsKICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9ucy5wdXNoKGRiKTsgLy8gVXNlZCBmb3IgZW11bGF0aW5nIHZlcnNpb25jaGFuZ2UgZXZlbnQgb24gSUUvRWRnZS9TYWZhcmkuCiAgICAgICAgICAgICAgICAgICAgaWYgKGF1dG9TY2hlbWEpCiAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRHbG9iYWxTY2hlbWEoKTsKICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChpZGJkYi5vYmplY3RTdG9yZU5hbWVzLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkanVzdFRvRXhpc3RpbmdJbmRleE5hbWVzKGdsb2JhbFNjaGVtYSwgaWRiZGIudHJhbnNhY3Rpb24oc2FmYXJpTXVsdGlTdG9yZUZpeChpZGJkYi5vYmplY3RTdG9yZU5hbWVzKSwgUkVBRE9OTFkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIG1heSBiYWlsIG91dCBpZiA+IDEgc3RvcmUgbmFtZXMuIEhvd2V2ZXIsIHRoaXMgc2hvdWxkbnQgYmUgYSBzaG93c3RvcHBlci4gSXNzdWUgIzEyMC4KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZGJkYi5vbnZlcnNpb25jaGFuZ2UgPSB3cmFwKGZ1bmN0aW9uIChldikgewogICAgICAgICAgICAgICAgICAgICAgICBkYi5fdmNGaXJlZCA9IHRydWU7IC8vIGRldGVjdCBpbXBsZW1lbnRhdGlvbnMgdGhhdCBub3Qgc3VwcG9ydCB2ZXJzaW9uY2hhbmdlIChJRS9FZGdlL1NhZmFyaSkKICAgICAgICAgICAgICAgICAgICAgICAgZGIub24oInZlcnNpb25jaGFuZ2UiKS5maXJlKGV2KTsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICBpZiAoIWhhc05hdGl2ZUdldERhdGFiYXNlTmFtZXMgJiYgZGJOYW1lICE9PSAnX19kYm5hbWVzJykgewogICAgICAgICAgICAgICAgICAgICAgICBkYk5hbWVzREIuZGJuYW1lcy5wdXQoeyBuYW1lOiBkYk5hbWUgfSkuY2F0Y2gobm9wKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpOwogICAgICAgICAgICAgICAgfSwgcmVqZWN0KTsKICAgICAgICAgICAgfSldKS50aGVuKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgLy8gQmVmb3JlIGZpbmFsbHkgcmVzb2x2aW5nIHRoZSBkYlJlYWR5UHJvbWlzZSBhbmQgdGhpcyBwcm9taXNlLAogICAgICAgICAgICAvLyBjYWxsIGFuZCBhd2FpdCBhbGwgb24oJ3JlYWR5Jykgc3Vic2NyaWJlcnM6CiAgICAgICAgICAgIC8vIERleGllLnZpcCgpIG1ha2VzIHN1YnNjcmliZXJzIGFibGUgdG8gdXNlIHRoZSBkYXRhYmFzZSB3aGlsZSBiZWluZyBvcGVuZWQuCiAgICAgICAgICAgIC8vIFRoaXMgaXMgYSBtdXN0IHNpbmNlIHRoZXNlIHN1YnNjcmliZXJzIHRha2UgcGFydCBvZiB0aGUgb3BlbmluZyBwcm9jZWR1cmUuCiAgICAgICAgICAgIG9uUmVhZHlCZWluZ0ZpcmVkID0gW107CiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoRGV4aWUudmlwKGRiLm9uLnJlYWR5LmZpcmUpKS50aGVuKGZ1bmN0aW9uIGZpcmVSZW1haW5kZXJzKCkgewogICAgICAgICAgICAgICAgaWYgKG9uUmVhZHlCZWluZ0ZpcmVkLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICAvLyBJbiBjYXNlIGFkZGl0aW9uYWwgc3Vic2NyaWJlcnMgdG8gZGIub24oJ3JlYWR5Jykgd2VyZSBhZGRlZCBkdXJpbmcgdGhlIHRpbWUgZGIub24ucmVhZHkuZmlyZSB3YXMgZXhlY3V0ZWQuCiAgICAgICAgICAgICAgICAgICAgdmFyIHJlbWFpbmRlcnMgPSBvblJlYWR5QmVpbmdGaXJlZC5yZWR1Y2UocHJvbWlzYWJsZUNoYWluLCBub3ApOwogICAgICAgICAgICAgICAgICAgIG9uUmVhZHlCZWluZ0ZpcmVkID0gW107CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShEZXhpZS52aXAocmVtYWluZGVycykpLnRoZW4oZmlyZVJlbWFpbmRlcnMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICB9KS5maW5hbGx5KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgb25SZWFkeUJlaW5nRmlyZWQgPSBudWxsOwogICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKCkgewogICAgICAgICAgICAvLyBSZXNvbHZlIHRoZSBkYi5vcGVuKCkgd2l0aCB0aGUgZGIgaW5zdGFuY2UuCiAgICAgICAgICAgIGlzQmVpbmdPcGVuZWQgPSBmYWxzZTsKICAgICAgICAgICAgcmV0dXJuIGRiOwogICAgICAgIH0pLmNhdGNoKGZ1bmN0aW9uIChlcnIpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIC8vIERpZCB3ZSBmYWlsIHdpdGhpbiBvbnVwZ3JhZGVuZWVkZWQ/IE1ha2Ugc3VyZSB0byBhYm9ydCB0aGUgdXBncmFkZSB0cmFuc2FjdGlvbiBzbyBpdCBkb2VzbnQgY29tbWl0LgogICAgICAgICAgICAgICAgdXBncmFkZVRyYW5zYWN0aW9uICYmIHVwZ3JhZGVUcmFuc2FjdGlvbi5hYm9ydCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNhdGNoIChlKSB7IH0KICAgICAgICAgICAgaXNCZWluZ09wZW5lZCA9IGZhbHNlOyAvLyBTZXQgYmVmb3JlIGNhbGxpbmcgZGIuY2xvc2UoKSBzbyB0aGF0IGl0IGRvZXNudCByZWplY3Qgb3BlbkNhbmNlbGxlciBhZ2FpbiAobGVhZHMgdG8gdW5oYW5kbGVkIHJlamVjdGlvbiBldmVudCkuCiAgICAgICAgICAgIGRiLmNsb3NlKCk7IC8vIENsb3NlcyBhbmQgcmVzZXRzIGlkYmRiLCByZW1vdmVzIGNvbm5lY3Rpb25zLCByZXNldHMgZGJSZWFkeVByb21pc2UgYW5kIG9wZW5DYW5jZWxsZXIgc28gdGhhdCBhIGxhdGVyIGRiLm9wZW4oKSBpcyBmcmVzaC4KICAgICAgICAgICAgLy8gQSBjYWxsIHRvIGRiLmNsb3NlKCkgbWF5IGhhdmUgbWFkZSBvbi1yZWFkeSBzdWJzY3JpYmVycyBmYWlsLiBVc2UgZGJPcGVuRXJyb3IgaWYgc2V0LCBzaW5jZSBlcnIgY291bGQgYmUgYSBmb2xsb3ctdXAgZXJyb3Igb24gdGhhdC4KICAgICAgICAgICAgZGJPcGVuRXJyb3IgPSBlcnI7IC8vIFJlY29yZCB0aGUgZXJyb3IuIEl0IHdpbGwgYmUgdXNlZCB0byByZWplY3QgZnVydGhlciBwcm9taXNlcyBvZiBkYiBvcGVyYXRpb25zLgogICAgICAgICAgICByZXR1cm4gcmVqZWN0aW9uKGRiT3BlbkVycm9yKTsKICAgICAgICB9KS5maW5hbGx5KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgb3BlbkNvbXBsZXRlID0gdHJ1ZTsKICAgICAgICAgICAgcmVzb2x2ZURiUmVhZHkoKTsgLy8gZGJSZWFkeVByb21pc2UgaXMgcmVzb2x2ZWQgbm8gbWF0dGVyIGlmIG9wZW4oKSByZWplY3RzIG9yIHJlc29sdmVkLiBJdCdzIGp1c3QgdG8gd2FrZSB1cCB3YWl0ZXJzLgogICAgICAgIH0pOwogICAgfTsKICAgIHRoaXMuY2xvc2UgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIGlkeCA9IGNvbm5lY3Rpb25zLmluZGV4T2YoZGIpOwogICAgICAgIGlmIChpZHggPj0gMCkKICAgICAgICAgICAgY29ubmVjdGlvbnMuc3BsaWNlKGlkeCwgMSk7CiAgICAgICAgaWYgKGlkYmRiKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBpZGJkYi5jbG9zZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNhdGNoIChlKSB7IH0KICAgICAgICAgICAgaWRiZGIgPSBudWxsOwogICAgICAgIH0KICAgICAgICBhdXRvT3BlbiA9IGZhbHNlOwogICAgICAgIGRiT3BlbkVycm9yID0gbmV3IGV4Y2VwdGlvbnMuRGF0YWJhc2VDbG9zZWQoKTsKICAgICAgICBpZiAoaXNCZWluZ09wZW5lZCkKICAgICAgICAgICAgY2FuY2VsT3BlbihkYk9wZW5FcnJvcik7CiAgICAgICAgLy8gUmVzZXQgZGJSZWFkeVByb21pc2UgcHJvbWlzZToKICAgICAgICBkYlJlYWR5UHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7CiAgICAgICAgICAgIGRiUmVhZHlSZXNvbHZlID0gcmVzb2x2ZTsKICAgICAgICB9KTsKICAgICAgICBvcGVuQ2FuY2VsbGVyID0gbmV3IFByb21pc2UoZnVuY3Rpb24gKF8sIHJlamVjdCkgewogICAgICAgICAgICBjYW5jZWxPcGVuID0gcmVqZWN0OwogICAgICAgIH0pOwogICAgfTsKICAgIHRoaXMuZGVsZXRlID0gZnVuY3Rpb24gKCkgewogICAgICAgIHZhciBoYXNBcmd1bWVudHMgPSBhcmd1bWVudHMubGVuZ3RoID4gMDsKICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkgewogICAgICAgICAgICBpZiAoaGFzQXJndW1lbnRzKQogICAgICAgICAgICAgICAgdGhyb3cgbmV3IGV4Y2VwdGlvbnMuSW52YWxpZEFyZ3VtZW50KCJBcmd1bWVudHMgbm90IGFsbG93ZWQgaW4gZGIuZGVsZXRlKCkiKTsKICAgICAgICAgICAgaWYgKGlzQmVpbmdPcGVuZWQpIHsKICAgICAgICAgICAgICAgIGRiUmVhZHlQcm9taXNlLnRoZW4oZG9EZWxldGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgZG9EZWxldGUoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmdW5jdGlvbiBkb0RlbGV0ZSgpIHsKICAgICAgICAgICAgICAgIGRiLmNsb3NlKCk7CiAgICAgICAgICAgICAgICB2YXIgcmVxID0gaW5kZXhlZERCLmRlbGV0ZURhdGFiYXNlKGRiTmFtZSk7CiAgICAgICAgICAgICAgICByZXEub25zdWNjZXNzID0gd3JhcChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFoYXNOYXRpdmVHZXREYXRhYmFzZU5hbWVzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRiTmFtZXNEQi5kYm5hbWVzLmRlbGV0ZShkYk5hbWUpLmNhdGNoKG5vcCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgcmVxLm9uZXJyb3IgPSBldmVudFJlamVjdEhhbmRsZXIocmVqZWN0KTsKICAgICAgICAgICAgICAgIHJlcS5vbmJsb2NrZWQgPSBmaXJlT25CbG9ja2VkOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICB9OwogICAgdGhpcy5iYWNrZW5kREIgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgcmV0dXJuIGlkYmRiOwogICAgfTsKICAgIHRoaXMuaXNPcGVuID0gZnVuY3Rpb24gKCkgewogICAgICAgIHJldHVybiBpZGJkYiAhPT0gbnVsbDsKICAgIH07CiAgICB0aGlzLmhhc0JlZW5DbG9zZWQgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgcmV0dXJuIGRiT3BlbkVycm9yICYmIChkYk9wZW5FcnJvciBpbnN0YW5jZW9mIGV4Y2VwdGlvbnMuRGF0YWJhc2VDbG9zZWQpOwogICAgfTsKICAgIHRoaXMuaGFzRmFpbGVkID0gZnVuY3Rpb24gKCkgewogICAgICAgIHJldHVybiBkYk9wZW5FcnJvciAhPT0gbnVsbDsKICAgIH07CiAgICB0aGlzLmR5bmFtaWNhbGx5T3BlbmVkID0gZnVuY3Rpb24gKCkgewogICAgICAgIHJldHVybiBhdXRvU2NoZW1hOwogICAgfTsKICAgIC8vCiAgICAvLyBQcm9wZXJ0aWVzCiAgICAvLwogICAgdGhpcy5uYW1lID0gZGJOYW1lOwogICAgLy8gZGIudGFibGVzIC0gYW4gYXJyYXkgb2YgYWxsIFRhYmxlIGluc3RhbmNlcy4KICAgIHByb3BzKHRoaXMsIHsKICAgICAgICB0YWJsZXM6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAvLy8gPHJldHVybnMgdHlwZT0iQXJyYXkiIGVsZW1lbnRUeXBlPSJUYWJsZSIgLz4KICAgICAgICAgICAgICAgIHJldHVybiBrZXlzKGFsbFRhYmxlcykubWFwKGZ1bmN0aW9uIChuYW1lKSB7IHJldHVybiBhbGxUYWJsZXNbbmFtZV07IH0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7CiAgICAvLwogICAgLy8gRXZlbnRzCiAgICAvLwogICAgdGhpcy5vbiA9IEV2ZW50cyh0aGlzLCAicG9wdWxhdGUiLCAiYmxvY2tlZCIsICJ2ZXJzaW9uY2hhbmdlIiwgeyByZWFkeTogW3Byb21pc2FibGVDaGFpbiwgbm9wXSB9KTsKICAgIHRoaXMub24ucmVhZHkuc3Vic2NyaWJlID0gb3ZlcnJpZGUodGhpcy5vbi5yZWFkeS5zdWJzY3JpYmUsIGZ1bmN0aW9uIChzdWJzY3JpYmUpIHsKICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHN1YnNjcmliZXIsIGJTdGlja3kpIHsKICAgICAgICAgICAgRGV4aWUudmlwKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIGlmIChvcGVuQ29tcGxldGUpIHsKICAgICAgICAgICAgICAgICAgICAvLyBEYXRhYmFzZSBhbHJlYWR5IG9wZW4uIENhbGwgc3Vic2NyaWJlciBhc2FwLgogICAgICAgICAgICAgICAgICAgIGlmICghZGJPcGVuRXJyb3IpCiAgICAgICAgICAgICAgICAgICAgICAgIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oc3Vic2NyaWJlcik7CiAgICAgICAgICAgICAgICAgICAgLy8gYlN0aWNreTogQWxzbyBzdWJzY3JpYmUgdG8gZnV0dXJlIG9wZW4gc3VjZXNzZXMgKGFmdGVyIGNsb3NlIC8gcmVvcGVuKSAKICAgICAgICAgICAgICAgICAgICBpZiAoYlN0aWNreSkKICAgICAgICAgICAgICAgICAgICAgICAgc3Vic2NyaWJlKHN1YnNjcmliZXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAob25SZWFkeUJlaW5nRmlyZWQpIHsKICAgICAgICAgICAgICAgICAgICAvLyBkYi5vbigncmVhZHknKSBzdWJzY3JpYmVycyBhcmUgY3VycmVudGx5IGJlaW5nIGV4ZWN1dGVkIGFuZCBoYXZlIG5vdCB5ZXQgcmVzb2x2ZWQgb3IgcmVqZWN0ZWQKICAgICAgICAgICAgICAgICAgICBvblJlYWR5QmVpbmdGaXJlZC5wdXNoKHN1YnNjcmliZXIpOwogICAgICAgICAgICAgICAgICAgIGlmIChiU3RpY2t5KQogICAgICAgICAgICAgICAgICAgICAgICBzdWJzY3JpYmUoc3Vic2NyaWJlcik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvLyBEYXRhYmFzZSBub3QgeWV0IG9wZW4uIFN1YnNjcmliZSB0byBpdC4KICAgICAgICAgICAgICAgICAgICBzdWJzY3JpYmUoc3Vic2NyaWJlcik7CiAgICAgICAgICAgICAgICAgICAgLy8gSWYgYlN0aWNreSBpcyBmYWxzeSwgbWFrZSBzdXJlIHRvIHVuc3Vic2NyaWJlIHN1YnNjcmliZXIgd2hlbiBmaXJlZCBvbmNlLgogICAgICAgICAgICAgICAgICAgIGlmICghYlN0aWNreSkKICAgICAgICAgICAgICAgICAgICAgICAgc3Vic2NyaWJlKGZ1bmN0aW9uIHVuc3Vic2NyaWJlKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGIub24ucmVhZHkudW5zdWJzY3JpYmUoc3Vic2NyaWJlcik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYi5vbi5yZWFkeS51bnN1YnNjcmliZSh1bnN1YnNjcmliZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICB9OwogICAgfSk7CiAgICB0aGlzLnRyYW5zYWN0aW9uID0gZnVuY3Rpb24gKCkgewogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ibW9kZSIgdHlwZT0iU3RyaW5nIj4iciIgZm9yIHJlYWRvbmx5LCBvciAicnciIGZvciByZWFkd3JpdGU8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0idGFibGVJbnN0YW5jZXMiPlRhYmxlIGluc3RhbmNlLCBBcnJheSBvZiBUYWJsZSBpbnN0YW5jZXMsIFN0cmluZyBvciBTdHJpbmcgQXJyYXkgb2Ygb2JqZWN0IHN0b3JlcyB0byBpbmNsdWRlIGluIHRoZSB0cmFuc2FjdGlvbjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJzY29wZUZ1bmMiIHR5cGU9IkZ1bmN0aW9uIj5GdW5jdGlvbiB0byBleGVjdXRlIHdpdGggdHJhbnNhY3Rpb248L3BhcmFtPgogICAgICAgIHZhciBhcmdzID0gZXh0cmFjdFRyYW5zYWN0aW9uQXJncy5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgIHJldHVybiB0aGlzLl90cmFuc2FjdGlvbi5hcHBseSh0aGlzLCBhcmdzKTsKICAgIH07CiAgICBmdW5jdGlvbiBleHRyYWN0VHJhbnNhY3Rpb25BcmdzKG1vZGUsIF90YWJsZUFyZ3NfLCBzY29wZUZ1bmMpIHsKICAgICAgICAvLyBMZXQgdGFibGUgYXJndW1lbnRzIGJlIGFsbCBhcmd1bWVudHMgYmV0d2VlbiBtb2RlIGFuZCBsYXN0IGFyZ3VtZW50LgogICAgICAgIHZhciBpID0gYXJndW1lbnRzLmxlbmd0aDsKICAgICAgICBpZiAoaSA8IDIpCiAgICAgICAgICAgIHRocm93IG5ldyBleGNlcHRpb25zLkludmFsaWRBcmd1bWVudCgiVG9vIGZldyBhcmd1bWVudHMiKTsKICAgICAgICAvLyBQcmV2ZW50IG9wdGltemF0aW9uIGtpbGxlciAoaHR0cHM6Ly9naXRodWIuY29tL3BldGthYW50b25vdi9ibHVlYmlyZC93aWtpL09wdGltaXphdGlvbi1raWxsZXJzIzMyLWxlYWtpbmctYXJndW1lbnRzKQogICAgICAgIC8vIGFuZCBjbG9uZSBhcmd1bWVudHMgZXhjZXB0IHRoZSBmaXJzdCBvbmUgaW50byBsb2NhbCB2YXIgJ2FyZ3MnLgogICAgICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGkgLSAxKTsKICAgICAgICB3aGlsZSAoLS1pKQogICAgICAgICAgICBhcmdzW2kgLSAxXSA9IGFyZ3VtZW50c1tpXTsKICAgICAgICAvLyBMZXQgc2NvcGVGdW5jIGJlIHRoZSBsYXN0IGFyZ3VtZW50IGFuZCBwb3AgaXQgc28gdGhhdCBhcmdzIG5vdyBvbmx5IGNvbnRhaW4gdGhlIHRhYmxlIGFyZ3VtZW50cy4KICAgICAgICBzY29wZUZ1bmMgPSBhcmdzLnBvcCgpOwogICAgICAgIHZhciB0YWJsZXMgPSBmbGF0dGVuKGFyZ3MpOyAvLyBTdXBwb3J0IHVzaW5nIGFycmF5IGFzIG1pZGRsZSBhcmd1bWVudCwgb3IgYSBtaXggb2YgYXJyYXlzIGFuZCBub24tYXJyYXlzLgogICAgICAgIHJldHVybiBbbW9kZSwgdGFibGVzLCBzY29wZUZ1bmNdOwogICAgfQogICAgdGhpcy5fdHJhbnNhY3Rpb24gPSBmdW5jdGlvbiAobW9kZSwgdGFibGVzLCBzY29wZUZ1bmMpIHsKICAgICAgICB2YXIgcGFyZW50VHJhbnNhY3Rpb24gPSBQU0QudHJhbnM7CiAgICAgICAgLy8gQ2hlY2sgaWYgcGFyZW50IHRyYW5zYWN0aW9ucyBpcyBib3VuZCB0byB0aGlzIGRiIGluc3RhbmNlLCBhbmQgaWYgY2FsbGVyIHdhbnRzIHRvIHJldXNlIGl0CiAgICAgICAgaWYgKCFwYXJlbnRUcmFuc2FjdGlvbiB8fCBwYXJlbnRUcmFuc2FjdGlvbi5kYiAhPT0gZGIgfHwgbW9kZS5pbmRleE9mKCchJykgIT09IC0xKQogICAgICAgICAgICBwYXJlbnRUcmFuc2FjdGlvbiA9IG51bGw7CiAgICAgICAgdmFyIG9ubHlJZkNvbXBhdGlibGUgPSBtb2RlLmluZGV4T2YoJz8nKSAhPT0gLTE7CiAgICAgICAgbW9kZSA9IG1vZGUucmVwbGFjZSgnIScsICcnKS5yZXBsYWNlKCc/JywgJycpOyAvLyBPay4gV2lsbCBjaGFuZ2UgYXJndW1lbnRzWzBdIGFzIHdlbGwgYnV0IHdlIHdvbnQgdG91Y2ggYXJndW1lbnRzIGhlbmNlZm9ydGguCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgLy8KICAgICAgICAgICAgLy8gR2V0IHN0b3JlTmFtZXMgZnJvbSBhcmd1bWVudHMuIEVpdGhlciB0aHJvdWdoIGdpdmVuIHRhYmxlIGluc3RhbmNlcywgb3IgdGhyb3VnaCBnaXZlbiB0YWJsZSBuYW1lcy4KICAgICAgICAgICAgLy8KICAgICAgICAgICAgdmFyIHN0b3JlTmFtZXMgPSB0YWJsZXMubWFwKGZ1bmN0aW9uICh0YWJsZSkgewogICAgICAgICAgICAgICAgdmFyIHN0b3JlTmFtZSA9IHRhYmxlIGluc3RhbmNlb2YgVGFibGUgPyB0YWJsZS5uYW1lIDogdGFibGU7CiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHN0b3JlTmFtZSAhPT0gJ3N0cmluZycpCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigiSW52YWxpZCB0YWJsZSBhcmd1bWVudCB0byBEZXhpZS50cmFuc2FjdGlvbigpLiBPbmx5IFRhYmxlIG9yIFN0cmluZyBhcmUgYWxsb3dlZCIpOwogICAgICAgICAgICAgICAgcmV0dXJuIHN0b3JlTmFtZTsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIFJlc29sdmUgbW9kZS4gQWxsb3cgc2hvcnRjdXRzICJyIiBhbmQgInJ3Ii4KICAgICAgICAgICAgLy8KICAgICAgICAgICAgaWYgKG1vZGUgPT0gInIiIHx8IG1vZGUgPT0gUkVBRE9OTFkpCiAgICAgICAgICAgICAgICBtb2RlID0gUkVBRE9OTFk7CiAgICAgICAgICAgIGVsc2UgaWYgKG1vZGUgPT0gInJ3IiB8fCBtb2RlID09IFJFQURXUklURSkKICAgICAgICAgICAgICAgIG1vZGUgPSBSRUFEV1JJVEU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHRocm93IG5ldyBleGNlcHRpb25zLkludmFsaWRBcmd1bWVudCgiSW52YWxpZCB0cmFuc2FjdGlvbiBtb2RlOiAiICsgbW9kZSk7CiAgICAgICAgICAgIGlmIChwYXJlbnRUcmFuc2FjdGlvbikgewogICAgICAgICAgICAgICAgLy8gQmFzaWMgY2hlY2tzCiAgICAgICAgICAgICAgICBpZiAocGFyZW50VHJhbnNhY3Rpb24ubW9kZSA9PT0gUkVBRE9OTFkgJiYgbW9kZSA9PT0gUkVBRFdSSVRFKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKG9ubHlJZkNvbXBhdGlibGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3Bhd24gbmV3IHRyYW5zYWN0aW9uIGluc3RlYWQuCiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudFRyYW5zYWN0aW9uID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgZXhjZXB0aW9ucy5TdWJUcmFuc2FjdGlvbigiQ2Fubm90IGVudGVyIGEgc3ViLXRyYW5zYWN0aW9uIHdpdGggUkVBRFdSSVRFIG1vZGUgd2hlbiBwYXJlbnQgdHJhbnNhY3Rpb24gaXMgUkVBRE9OTFkiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChwYXJlbnRUcmFuc2FjdGlvbikgewogICAgICAgICAgICAgICAgICAgIHN0b3JlTmFtZXMuZm9yRWFjaChmdW5jdGlvbiAoc3RvcmVOYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnRUcmFuc2FjdGlvbiAmJiBwYXJlbnRUcmFuc2FjdGlvbi5zdG9yZU5hbWVzLmluZGV4T2Yoc3RvcmVOYW1lKSA9PT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvbmx5SWZDb21wYXRpYmxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3Bhd24gbmV3IHRyYW5zYWN0aW9uIGluc3RlYWQuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50VHJhbnNhY3Rpb24gPSBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBleGNlcHRpb25zLlN1YlRyYW5zYWN0aW9uKCJUYWJsZSAiICsgc3RvcmVOYW1lICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBub3QgaW5jbHVkZWQgaW4gcGFyZW50IHRyYW5zYWN0aW9uLiIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAob25seUlmQ29tcGF0aWJsZSAmJiBwYXJlbnRUcmFuc2FjdGlvbiAmJiAhcGFyZW50VHJhbnNhY3Rpb24uYWN0aXZlKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gJz8nIG1vZGUgc2hvdWxkIG5vdCBrZWVwIHVzaW5nIGFuIGluYWN0aXZlIHRyYW5zYWN0aW9uLgogICAgICAgICAgICAgICAgICAgIHBhcmVudFRyYW5zYWN0aW9uID0gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjYXRjaCAoZSkgewogICAgICAgICAgICByZXR1cm4gcGFyZW50VHJhbnNhY3Rpb24gPwogICAgICAgICAgICAgICAgcGFyZW50VHJhbnNhY3Rpb24uX3Byb21pc2UobnVsbCwgZnVuY3Rpb24gKF8sIHJlamVjdCkgeyByZWplY3QoZSk7IH0pIDoKICAgICAgICAgICAgICAgIHJlamVjdGlvbihlKTsKICAgICAgICB9CiAgICAgICAgLy8gSWYgdGhpcyBpcyBhIHN1Yi10cmFuc2FjdGlvbiwgbG9jayB0aGUgcGFyZW50IGFuZCB0aGVuIGxhdW5jaCB0aGUgc3ViLXRyYW5zYWN0aW9uLgogICAgICAgIHJldHVybiAocGFyZW50VHJhbnNhY3Rpb24gPwogICAgICAgICAgICBwYXJlbnRUcmFuc2FjdGlvbi5fcHJvbWlzZShtb2RlLCBlbnRlclRyYW5zYWN0aW9uU2NvcGUsICJsb2NrIikgOgogICAgICAgICAgICBQU0QudHJhbnMgPwogICAgICAgICAgICAgICAgLy8gbm8gcGFyZW50IHRyYW5zYWN0aW9uIGRlc3BpdGUgUFNELnRyYW5zIGV4aXN0cy4gTWFrZSBzdXJlIGFsc28KICAgICAgICAgICAgICAgIC8vIHRoYXQgdGhlIHpvbmUgd2UgY3JlYXRlIGlzIG5vdCBhIHN1Yi16b25lIG9mIGN1cnJlbnQsIGJlY2F1c2UKICAgICAgICAgICAgICAgIC8vIFByb21pc2UuZm9sbG93KCkgc2hvdWxkIG5vdCB3YWl0IGZvciBpdCBpZiBzby4KICAgICAgICAgICAgICAgIHVzZVBTRChQU0QudHJhbnNsZXNzLCBmdW5jdGlvbiAoKSB7IHJldHVybiBkYi5fd2hlblJlYWR5KGVudGVyVHJhbnNhY3Rpb25TY29wZSk7IH0pIDoKICAgICAgICAgICAgICAgIGRiLl93aGVuUmVhZHkoZW50ZXJUcmFuc2FjdGlvblNjb3BlKSk7CiAgICAgICAgZnVuY3Rpb24gZW50ZXJUcmFuc2FjdGlvblNjb3BlKCkgewogICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkudGhlbihmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAvLyBLZWVwIGEgcG9pbnRlciB0byBsYXN0IG5vbi10cmFuc2FjdGlvbmFsIFBTRCB0byB1c2UgaWYgc29tZW9uZSBjYWxscyBEZXhpZS5pZ25vcmVUcmFuc2FjdGlvbigpLgogICAgICAgICAgICAgICAgdmFyIHRyYW5zbGVzcyA9IFBTRC50cmFuc2xlc3MgfHwgUFNEOwogICAgICAgICAgICAgICAgLy8gT3VyIHRyYW5zYWN0aW9uLgogICAgICAgICAgICAgICAgLy9yZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4gewogICAgICAgICAgICAgICAgdmFyIHRyYW5zID0gZGIuX2NyZWF0ZVRyYW5zYWN0aW9uKG1vZGUsIHN0b3JlTmFtZXMsIGdsb2JhbFNjaGVtYSwgcGFyZW50VHJhbnNhY3Rpb24pOwogICAgICAgICAgICAgICAgLy8gTGV0IHRoZSB0cmFuc2FjdGlvbiBpbnN0YW5jZSBiZSBwYXJ0IG9mIGEgUHJvbWlzZS1zcGVjaWZpYyBkYXRhIChQU0QpIHZhbHVlLgogICAgICAgICAgICAgICAgdmFyIHpvbmVQcm9wcyA9IHsKICAgICAgICAgICAgICAgICAgICB0cmFuczogdHJhbnMsCiAgICAgICAgICAgICAgICAgICAgdHJhbnNsZXNzOiB0cmFuc2xlc3MKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICBpZiAocGFyZW50VHJhbnNhY3Rpb24pIHsKICAgICAgICAgICAgICAgICAgICAvLyBFbXVsYXRlIHRyYW5zYWN0aW9uIGNvbW1pdCBhd2FyZW5lc3MgZm9yIGlubmVyIHRyYW5zYWN0aW9uIChtdXN0ICdjb21taXQnIHdoZW4gdGhlIGlubmVyIHRyYW5zYWN0aW9uIGhhcyBubyBtb3JlIG9wZXJhdGlvbnMgb25nb2luZykKICAgICAgICAgICAgICAgICAgICB0cmFucy5pZGJ0cmFucyA9IHBhcmVudFRyYW5zYWN0aW9uLmlkYnRyYW5zOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdHJhbnMuY3JlYXRlKCk7IC8vIENyZWF0ZSB0aGUgYmFja2VuZCB0cmFuc2FjdGlvbiBzbyB0aGF0IGNvbXBsZXRlKCkgb3IgZXJyb3IoKSB3aWxsIHRyaWdnZXIgZXZlbiBpZiBubyBvcGVyYXRpb24gaXMgbWFkZSB1cG9uIGl0LgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gU3VwcG9ydCBmb3IgbmF0aXZlIGFzeW5jIGF3YWl0LgogICAgICAgICAgICAgICAgaWYgKHNjb3BlRnVuYy5jb25zdHJ1Y3RvciA9PT0gQXN5bmNGdW5jdGlvbikgewogICAgICAgICAgICAgICAgICAgIGluY3JlbWVudEV4cGVjdGVkQXdhaXRzKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2YXIgcmV0dXJuVmFsdWU7CiAgICAgICAgICAgICAgICB2YXIgcHJvbWlzZUZvbGxvd2VkID0gUHJvbWlzZS5mb2xsb3coZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIC8vIEZpbmFsbHksIGNhbGwgdGhlIHNjb3BlIGZ1bmN0aW9uIHdpdGggb3VyIHRhYmxlIGFuZCB0cmFuc2FjdGlvbiBhcmd1bWVudHMuCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSBzY29wZUZ1bmMuY2FsbCh0cmFucywgdHJhbnMpOwogICAgICAgICAgICAgICAgICAgIGlmIChyZXR1cm5WYWx1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAocmV0dXJuVmFsdWUuY29uc3RydWN0b3IgPT09IE5hdGl2ZVByb21pc2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkZWNyZW1lbnRvciA9IGRlY3JlbWVudEV4cGVjdGVkQXdhaXRzLmJpbmQobnVsbCwgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm5WYWx1ZS50aGVuKGRlY3JlbWVudG9yLCBkZWNyZW1lbnRvcik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIHJldHVyblZhbHVlLm5leHQgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIHJldHVyblZhbHVlLnRocm93ID09PSAnZnVuY3Rpb24nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzY29wZUZ1bmMgcmV0dXJuZWQgYW4gaXRlcmF0b3Igd2l0aCB0aHJvdy1zdXBwb3J0LiBIYW5kbGUgeWllbGQgYXMgYXdhaXQuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm5WYWx1ZSA9IGF3YWl0SXRlcmF0b3IocmV0dXJuVmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwgem9uZVByb3BzKTsKICAgICAgICAgICAgICAgIHJldHVybiAocmV0dXJuVmFsdWUgJiYgdHlwZW9mIHJldHVyblZhbHVlLnRoZW4gPT09ICdmdW5jdGlvbicgPwogICAgICAgICAgICAgICAgICAgIC8vIFByb21pc2UgcmV0dXJuZWQuIFVzZXIgdXNlcyBwcm9taXNlLXN0eWxlIHRyYW5zYWN0aW9ucy4KICAgICAgICAgICAgICAgICAgICBQcm9taXNlLnJlc29sdmUocmV0dXJuVmFsdWUpLnRoZW4oZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHRyYW5zLmFjdGl2ZSA/CiAgICAgICAgICAgICAgICAgICAgICAgIHggLy8gVHJhbnNhY3Rpb24gc3RpbGwgYWN0aXZlLiBDb250aW51ZS4KICAgICAgICAgICAgICAgICAgICAgICAgOiByZWplY3Rpb24obmV3IGV4Y2VwdGlvbnMuUHJlbWF0dXJlQ29tbWl0KCJUcmFuc2FjdGlvbiBjb21taXR0ZWQgdG9vIGVhcmx5LiBTZWUgaHR0cDovL2JpdC5seS8ya2Rja01uIikpOyB9KQogICAgICAgICAgICAgICAgICAgIC8vIE5vIHByb21pc2UgcmV0dXJuZWQuIFdhaXQgZm9yIGFsbCBvdXRzdGFuZGluZyBwcm9taXNlcyBiZWZvcmUgY29udGludWluZy4gCiAgICAgICAgICAgICAgICAgICAgOiBwcm9taXNlRm9sbG93ZWQudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiByZXR1cm5WYWx1ZTsgfSkpLnRoZW4oZnVuY3Rpb24gKHgpIHsKICAgICAgICAgICAgICAgICAgICAvLyBzdWIgdHJhbnNhY3Rpb25zIGRvbid0IHJlYWN0IHRvIGlkYnRyYW5zLm9uY29tcGxldGUuIFdlIG11c3QgdHJpZ2dlciBhIGNvbXBsZXRpb246CiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudFRyYW5zYWN0aW9uKQogICAgICAgICAgICAgICAgICAgICAgICB0cmFucy5fcmVzb2x2ZSgpOwogICAgICAgICAgICAgICAgICAgIC8vIHdhaXQgZm9yIHRyYW5zLl9jb21wbGV0aW9uCiAgICAgICAgICAgICAgICAgICAgLy8gKGlmIHJvb3QgdHJhbnNhY3Rpb24sIHRoaXMgbWVhbnMgJ2NvbXBsZXRlJyBldmVudC4gSWYgc3ViLXRyYW5zYWN0aW9uLCB3ZSd2ZSBqdXN0IGZpcmVkIGl0IG91cnNlbHZlcykKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJhbnMuX2NvbXBsZXRpb24udGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiB4OyB9KTsKICAgICAgICAgICAgICAgIH0pLmNhdGNoKGZ1bmN0aW9uIChlKSB7CiAgICAgICAgICAgICAgICAgICAgdHJhbnMuX3JlamVjdChlKTsgLy8gWWVzLCBhYm92ZSB0aGVuLWhhbmRsZXIgd2VyZSBtYXliZSBub3QgY2FsbGVkIGJlY2F1c2Ugb2YgYW4gdW5oYW5kbGVkIHJlamVjdGlvbiBpbiBzY29wZUZ1bmMhCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdGlvbihlKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9OwogICAgdGhpcy50YWJsZSA9IGZ1bmN0aW9uICh0YWJsZU5hbWUpIHsKICAgICAgICAvLy8gPHJldHVybnMgdHlwZT0iVGFibGUiPjwvcmV0dXJucz4KICAgICAgICBpZiAoIWhhc093bihhbGxUYWJsZXMsIHRhYmxlTmFtZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGV4Y2VwdGlvbnMuSW52YWxpZFRhYmxlKCJUYWJsZSAiICsgdGFibGVOYW1lICsgIiBkb2VzIG5vdCBleGlzdCIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYWxsVGFibGVzW3RhYmxlTmFtZV07CiAgICB9OwogICAgLy8KICAgIC8vCiAgICAvLwogICAgLy8gVGFibGUgQ2xhc3MKICAgIC8vCiAgICAvLwogICAgLy8KICAgIGZ1bmN0aW9uIFRhYmxlKG5hbWUsIHRhYmxlU2NoZW1hLCBvcHRpb25hbFRyYW5zKSB7CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJuYW1lIiB0eXBlPSJTdHJpbmciPjwvcGFyYW0+CiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgICB0aGlzLnNjaGVtYSA9IHRhYmxlU2NoZW1hOwogICAgICAgIHRoaXMuX3R4ID0gb3B0aW9uYWxUcmFuczsKICAgICAgICB0aGlzLmhvb2sgPSBhbGxUYWJsZXNbbmFtZV0gPyBhbGxUYWJsZXNbbmFtZV0uaG9vayA6IEV2ZW50cyhudWxsLCB7CiAgICAgICAgICAgICJjcmVhdGluZyI6IFtob29rQ3JlYXRpbmdDaGFpbiwgbm9wXSwKICAgICAgICAgICAgInJlYWRpbmciOiBbcHVyZUZ1bmN0aW9uQ2hhaW4sIG1pcnJvcl0sCiAgICAgICAgICAgICJ1cGRhdGluZyI6IFtob29rVXBkYXRpbmdDaGFpbiwgbm9wXSwKICAgICAgICAgICAgImRlbGV0aW5nIjogW2hvb2tEZWxldGluZ0NoYWluLCBub3BdCiAgICAgICAgfSk7CiAgICB9CiAgICBmdW5jdGlvbiBCdWxrRXJyb3JIYW5kbGVyQ2F0Y2hBbGwoZXJyb3JMaXN0LCBkb25lLCBzdXBwb3J0SG9va3MpIHsKICAgICAgICByZXR1cm4gKHN1cHBvcnRIb29rcyA/IGhvb2tlZEV2ZW50UmVqZWN0SGFuZGxlciA6IGV2ZW50UmVqZWN0SGFuZGxlcikoZnVuY3Rpb24gKGUpIHsKICAgICAgICAgICAgZXJyb3JMaXN0LnB1c2goZSk7CiAgICAgICAgICAgIGRvbmUgJiYgZG9uZSgpOwogICAgICAgIH0pOwogICAgfQogICAgZnVuY3Rpb24gYnVsa0RlbGV0ZShpZGJzdG9yZSwgdHJhbnMsIGtleXNPclR1cGxlcywgaGFzRGVsZXRlSG9vaywgZGVsZXRpbmdIb29rKSB7CiAgICAgICAgLy8gSWYgaGFzRGVsZXRlSG9vaywga2V5c09yVHVwbGVzIG11c3QgYmUgYW4gYXJyYXkgb2YgdHVwbGVzOiBbW2tleTEsIHZhbHVlMl0sW2tleTIsdmFsdWUyXSwuLi5dLAogICAgICAgIC8vIGVsc2Uga2V5c09yVHVwbGVzIG11c3QgYmUganVzdCBhbiBhcnJheSBvZiBrZXlzOiBba2V5MSwga2V5MiwgLi4uXS4KICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkgewogICAgICAgICAgICB2YXIgbGVuID0ga2V5c09yVHVwbGVzLmxlbmd0aCwgbGFzdEl0ZW0gPSBsZW4gLSAxOwogICAgICAgICAgICBpZiAobGVuID09PSAwKQogICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoKTsKICAgICAgICAgICAgaWYgKCFoYXNEZWxldGVIb29rKSB7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHJlcSA9IGlkYnN0b3JlLmRlbGV0ZShrZXlzT3JUdXBsZXNbaV0pOwogICAgICAgICAgICAgICAgICAgIHJlcS5vbmVycm9yID0gZXZlbnRSZWplY3RIYW5kbGVyKHJlamVjdCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT09IGxhc3RJdGVtKQogICAgICAgICAgICAgICAgICAgICAgICByZXEub25zdWNjZXNzID0gd3JhcChmdW5jdGlvbiAoKSB7IHJldHVybiByZXNvbHZlKCk7IH0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgdmFyIGhvb2tDdHgsIGVycm9ySGFuZGxlciA9IGhvb2tlZEV2ZW50UmVqZWN0SGFuZGxlcihyZWplY3QpLCBzdWNjZXNzSGFuZGxlciA9IGhvb2tlZEV2ZW50U3VjY2Vzc0hhbmRsZXIobnVsbCk7CiAgICAgICAgICAgICAgICB0cnlDYXRjaChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSkgewogICAgICAgICAgICAgICAgICAgICAgICBob29rQ3R4ID0geyBvbnN1Y2Nlc3M6IG51bGwsIG9uZXJyb3I6IG51bGwgfTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHR1cGxlID0ga2V5c09yVHVwbGVzW2ldOwogICAgICAgICAgICAgICAgICAgICAgICBkZWxldGluZ0hvb2suY2FsbChob29rQ3R4LCB0dXBsZVswXSwgdHVwbGVbMV0sIHRyYW5zKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlcSA9IGlkYnN0b3JlLmRlbGV0ZSh0dXBsZVswXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlcS5faG9va0N0eCA9IGhvb2tDdHg7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlcS5vbmVycm9yID0gZXJyb3JIYW5kbGVyOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PT0gbGFzdEl0ZW0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXEub25zdWNjZXNzID0gaG9va2VkRXZlbnRTdWNjZXNzSGFuZGxlcihyZXNvbHZlKTsKICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxLm9uc3VjY2VzcyA9IHN1Y2Nlc3NIYW5kbGVyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sIGZ1bmN0aW9uIChlcnIpIHsKICAgICAgICAgICAgICAgICAgICBob29rQ3R4Lm9uZXJyb3IgJiYgaG9va0N0eC5vbmVycm9yKGVycik7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgIH0KICAgIHByb3BzKFRhYmxlLnByb3RvdHlwZSwgewogICAgICAgIC8vCiAgICAgICAgLy8gVGFibGUgUHJvdGVjdGVkIE1ldGhvZHMKICAgICAgICAvLwogICAgICAgIF90cmFuczogZnVuY3Rpb24gZ2V0VHJhbnNhY3Rpb24obW9kZSwgZm4sIHdyaXRlTG9ja2VkKSB7CiAgICAgICAgICAgIHZhciB0cmFucyA9IHRoaXMuX3R4IHx8IFBTRC50cmFuczsKICAgICAgICAgICAgcmV0dXJuIHRyYW5zICYmIHRyYW5zLmRiID09PSBkYiA/CiAgICAgICAgICAgICAgICB0cmFucyA9PT0gUFNELnRyYW5zID8KICAgICAgICAgICAgICAgICAgICB0cmFucy5fcHJvbWlzZShtb2RlLCBmbiwgd3JpdGVMb2NrZWQpIDoKICAgICAgICAgICAgICAgICAgICBuZXdTY29wZShmdW5jdGlvbiAoKSB7IHJldHVybiB0cmFucy5fcHJvbWlzZShtb2RlLCBmbiwgd3JpdGVMb2NrZWQpOyB9LCB7IHRyYW5zOiB0cmFucywgdHJhbnNsZXNzOiBQU0QudHJhbnNsZXNzIHx8IFBTRCB9KSA6CiAgICAgICAgICAgICAgICB0ZW1wVHJhbnNhY3Rpb24obW9kZSwgW3RoaXMubmFtZV0sIGZuKTsKICAgICAgICB9LAogICAgICAgIF9pZGJzdG9yZTogZnVuY3Rpb24gZ2V0SURCT2JqZWN0U3RvcmUobW9kZSwgZm4sIHdyaXRlTG9ja2VkKSB7CiAgICAgICAgICAgIHZhciB0YWJsZU5hbWUgPSB0aGlzLm5hbWU7CiAgICAgICAgICAgIGZ1bmN0aW9uIHN1cHBseUlkYlN0b3JlKHJlc29sdmUsIHJlamVjdCwgdHJhbnMpIHsKICAgICAgICAgICAgICAgIGlmICh0cmFucy5zdG9yZU5hbWVzLmluZGV4T2YodGFibGVOYW1lKSA9PT0gLTEpCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IGV4Y2VwdGlvbnMuTm90Rm91bmQoIlRhYmxlIiArIHRhYmxlTmFtZSArICIgbm90IHBhcnQgb2YgdHJhbnNhY3Rpb24iKTsKICAgICAgICAgICAgICAgIHJldHVybiBmbihyZXNvbHZlLCByZWplY3QsIHRyYW5zLmlkYnRyYW5zLm9iamVjdFN0b3JlKHRhYmxlTmFtZSksIHRyYW5zKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdGhpcy5fdHJhbnMobW9kZSwgc3VwcGx5SWRiU3RvcmUsIHdyaXRlTG9ja2VkKTsKICAgICAgICB9LAogICAgICAgIC8vCiAgICAgICAgLy8gVGFibGUgUHVibGljIE1ldGhvZHMKICAgICAgICAvLwogICAgICAgIGdldDogZnVuY3Rpb24gKGtleU9yQ3JpdCwgY2IpIHsKICAgICAgICAgICAgaWYgKGtleU9yQ3JpdCAmJiBrZXlPckNyaXQuY29uc3RydWN0b3IgPT09IE9iamVjdCkKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLndoZXJlKGtleU9yQ3JpdCkuZmlyc3QoY2IpOwogICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9pZGJzdG9yZShSRUFET05MWSwgZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCwgaWRic3RvcmUpIHsKICAgICAgICAgICAgICAgIHZhciByZXEgPSBpZGJzdG9yZS5nZXQoa2V5T3JDcml0KTsKICAgICAgICAgICAgICAgIHJlcS5vbmVycm9yID0gZXZlbnRSZWplY3RIYW5kbGVyKHJlamVjdCk7CiAgICAgICAgICAgICAgICByZXEub25zdWNjZXNzID0gd3JhcChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShzZWxmLmhvb2sucmVhZGluZy5maXJlKHJlcS5yZXN1bHQpKTsKICAgICAgICAgICAgICAgIH0sIHJlamVjdCk7CiAgICAgICAgICAgIH0pLnRoZW4oY2IpOwogICAgICAgIH0sCiAgICAgICAgd2hlcmU6IGZ1bmN0aW9uIChpbmRleE9yQ3JpdCkgewogICAgICAgICAgICBpZiAodHlwZW9mIGluZGV4T3JDcml0ID09PSAnc3RyaW5nJykKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgV2hlcmVDbGF1c2UodGhpcywgaW5kZXhPckNyaXQpOwogICAgICAgICAgICBpZiAoaXNBcnJheShpbmRleE9yQ3JpdCkpCiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFdoZXJlQ2xhdXNlKHRoaXMsICJbIiArIGluZGV4T3JDcml0LmpvaW4oJysnKSArICJdIik7CiAgICAgICAgICAgIC8vIGluZGV4T3JDcml0IGlzIGFuIG9iamVjdCBtYXAgb2Yge1trZXlQYXRoXTp2YWx1ZX0gCiAgICAgICAgICAgIHZhciBrZXlQYXRocyA9IGtleXMoaW5kZXhPckNyaXQpOwogICAgICAgICAgICBpZiAoa2V5UGF0aHMubGVuZ3RoID09PSAxKQogICAgICAgICAgICAgICAgLy8gT25seSBvbmUgY3JpdGVyYS4gVGhpcyB3YXMgdGhlIGVhc3kgY2FzZToKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzCiAgICAgICAgICAgICAgICAgICAgLndoZXJlKGtleVBhdGhzWzBdKQogICAgICAgICAgICAgICAgICAgIC5lcXVhbHMoaW5kZXhPckNyaXRba2V5UGF0aHNbMF1dKTsKICAgICAgICAgICAgLy8gTXVsdGlwbGUgY3JpdGVyaWFzLgogICAgICAgICAgICAvLyBMZXQncyB0cnkgZmluZGluZyBhIGNvbXBvdW5kIGluZGV4IHRoYXQgbWF0Y2hlcyBhbGwga2V5UGF0aHMgaW4KICAgICAgICAgICAgLy8gYXJicml0YXJ5IG9yZGVyOgogICAgICAgICAgICB2YXIgY29tcG91bmRJbmRleCA9IHRoaXMuc2NoZW1hLmluZGV4ZXMuY29uY2F0KHRoaXMuc2NoZW1hLnByaW1LZXkpLmZpbHRlcihmdW5jdGlvbiAoaXgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBpeC5jb21wb3VuZCAmJgogICAgICAgICAgICAgICAgICAgIGtleVBhdGhzLmV2ZXJ5KGZ1bmN0aW9uIChrZXlQYXRoKSB7IHJldHVybiBpeC5rZXlQYXRoLmluZGV4T2Yoa2V5UGF0aCkgPj0gMDsgfSkgJiYKICAgICAgICAgICAgICAgICAgICBpeC5rZXlQYXRoLmV2ZXJ5KGZ1bmN0aW9uIChrZXlQYXRoKSB7IHJldHVybiBrZXlQYXRocy5pbmRleE9mKGtleVBhdGgpID49IDA7IH0pOwogICAgICAgICAgICB9KVswXTsKICAgICAgICAgICAgaWYgKGNvbXBvdW5kSW5kZXggJiYgbWF4S2V5ICE9PSBtYXhTdHJpbmcpCiAgICAgICAgICAgICAgICAvLyBDb29sISBXZSBmb3VuZCBzdWNoIGNvbXBvdW5kIGluZGV4CiAgICAgICAgICAgICAgICAvLyBhbmQgdGhpcyBicm93c2VyIHN1cHBvcnRzIGNvbXBvdW5kIGluZGV4ZXMgKG1heEtleSAhPT0gbWF4U3RyaW5nKSEKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzCiAgICAgICAgICAgICAgICAgICAgLndoZXJlKGNvbXBvdW5kSW5kZXgubmFtZSkKICAgICAgICAgICAgICAgICAgICAuZXF1YWxzKGNvbXBvdW5kSW5kZXgua2V5UGF0aC5tYXAoZnVuY3Rpb24gKGtwKSB7IHJldHVybiBpbmRleE9yQ3JpdFtrcF07IH0pKTsKICAgICAgICAgICAgaWYgKCFjb21wb3VuZEluZGV4KQogICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCJUaGUgcXVlcnkgIiArIEpTT04uc3RyaW5naWZ5KGluZGV4T3JDcml0KSArICIgb24gIiArIHRoaXMubmFtZSArICIgd291bGQgYmVuZWZpdCBvZiBhICIgKwogICAgICAgICAgICAgICAgICAgICgiY29tcG91bmQgaW5kZXggWyIgKyBrZXlQYXRocy5qb2luKCcrJykgKyAiXSIpKTsKICAgICAgICAgICAgLy8gT2ssIG5vdyBsZXQncyBmYWxsYmFjayB0byBmaW5kaW5nIGF0IGxlYXN0IG9uZSBtYXRjaGluZyBpbmRleAogICAgICAgICAgICAvLyBhbmQgZmlsdGVyIHRoZSByZXN0LgogICAgICAgICAgICB2YXIgaWR4QnlOYW1lID0gdGhpcy5zY2hlbWEuaWR4QnlOYW1lOwogICAgICAgICAgICB2YXIgc2ltcGxlSW5kZXggPSBrZXlQYXRocy5yZWR1Y2UoZnVuY3Rpb24gKHIsIGtleVBhdGgpIHsgcmV0dXJuIFsKICAgICAgICAgICAgICAgIHJbMF0gfHwgaWR4QnlOYW1lW2tleVBhdGhdLAogICAgICAgICAgICAgICAgclswXSB8fCAhaWR4QnlOYW1lW2tleVBhdGhdID8KICAgICAgICAgICAgICAgICAgICBjb21iaW5lKHJbMV0sIGZ1bmN0aW9uICh4KSB7IHJldHVybiAnJyArIGdldEJ5S2V5UGF0aCh4LCBrZXlQYXRoKSA9PQogICAgICAgICAgICAgICAgICAgICAgICAnJyArIGluZGV4T3JDcml0W2tleVBhdGhdOyB9KQogICAgICAgICAgICAgICAgICAgIDogclsxXQogICAgICAgICAgICBdOyB9LCBbbnVsbCwgbnVsbF0pOwogICAgICAgICAgICB2YXIgaWR4ID0gc2ltcGxlSW5kZXhbMF07CiAgICAgICAgICAgIHJldHVybiBpZHggPwogICAgICAgICAgICAgICAgdGhpcy53aGVyZShpZHgubmFtZSkuZXF1YWxzKGluZGV4T3JDcml0W2lkeC5rZXlQYXRoXSkKICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKHNpbXBsZUluZGV4WzFdKSA6CiAgICAgICAgICAgICAgICBjb21wb3VuZEluZGV4ID8KICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbHRlcihzaW1wbGVJbmRleFsxXSkgOiAvLyBIYXMgY29tcG91bmQgYnV0IGJyb3dzZXIgYmFkLiBBbGxvdyBmaWx0ZXIuCiAgICAgICAgICAgICAgICAgICAgdGhpcy53aGVyZShrZXlQYXRocykuZXF1YWxzKCcnKTsgLy8gTm8gaW5kZXggYXQgYWxsLiBGYWlsIGxhemlseS4KICAgICAgICB9LAogICAgICAgIGNvdW50OiBmdW5jdGlvbiAoY2IpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9Db2xsZWN0aW9uKCkuY291bnQoY2IpOwogICAgICAgIH0sCiAgICAgICAgb2Zmc2V0OiBmdW5jdGlvbiAob2Zmc2V0KSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnRvQ29sbGVjdGlvbigpLm9mZnNldChvZmZzZXQpOwogICAgICAgIH0sCiAgICAgICAgbGltaXQ6IGZ1bmN0aW9uIChudW1Sb3dzKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnRvQ29sbGVjdGlvbigpLmxpbWl0KG51bVJvd3MpOwogICAgICAgIH0sCiAgICAgICAgcmV2ZXJzZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy50b0NvbGxlY3Rpb24oKS5yZXZlcnNlKCk7CiAgICAgICAgfSwKICAgICAgICBmaWx0ZXI6IGZ1bmN0aW9uIChmaWx0ZXJGdW5jdGlvbikgewogICAgICAgICAgICByZXR1cm4gdGhpcy50b0NvbGxlY3Rpb24oKS5hbmQoZmlsdGVyRnVuY3Rpb24pOwogICAgICAgIH0sCiAgICAgICAgZWFjaDogZnVuY3Rpb24gKGZuKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnRvQ29sbGVjdGlvbigpLmVhY2goZm4pOwogICAgICAgIH0sCiAgICAgICAgdG9BcnJheTogZnVuY3Rpb24gKGNiKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnRvQ29sbGVjdGlvbigpLnRvQXJyYXkoY2IpOwogICAgICAgIH0sCiAgICAgICAgb3JkZXJCeTogZnVuY3Rpb24gKGluZGV4KSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgQ29sbGVjdGlvbihuZXcgV2hlcmVDbGF1c2UodGhpcywgaXNBcnJheShpbmRleCkgPwogICAgICAgICAgICAgICAgIlsiICsgaW5kZXguam9pbignKycpICsgIl0iIDoKICAgICAgICAgICAgICAgIGluZGV4KSk7CiAgICAgICAgfSwKICAgICAgICB0b0NvbGxlY3Rpb246IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBDb2xsZWN0aW9uKG5ldyBXaGVyZUNsYXVzZSh0aGlzKSk7CiAgICAgICAgfSwKICAgICAgICBtYXBUb0NsYXNzOiBmdW5jdGlvbiAoY29uc3RydWN0b3IsIHN0cnVjdHVyZSkgewogICAgICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgICAgIC8vLyAgICAgTWFwIHRhYmxlIHRvIGEgamF2YXNjcmlwdCBjb25zdHJ1Y3RvciBmdW5jdGlvbi4gT2JqZWN0cyByZXR1cm5lZCBmcm9tIHRoZSBkYXRhYmFzZSB3aWxsIGJlIGluc3RhbmNlcyBvZiB0aGlzIGNsYXNzLCBtYWtpbmcKICAgICAgICAgICAgLy8vICAgICBpdCBwb3NzaWJsZSB0byB0aGUgaW5zdGFuY2VPZiBvcGVyYXRvciBhcyB3ZWxsIGFzIGV4dGVuZGluZyB0aGUgY2xhc3MgdXNpbmcgY29uc3RydWN0b3IucHJvdG90eXBlLm1ldGhvZCA9IGZ1bmN0aW9uKCl7Li4ufS4KICAgICAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb25zdHJ1Y3RvciI+Q29uc3RydWN0b3IgZnVuY3Rpb24gcmVwcmVzZW50aW5nIHRoZSBjbGFzcy48L3BhcmFtPgogICAgICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InN0cnVjdHVyZSIgb3B0aW9uYWw9InRydWUiPkhlbHBzIElERSBjb2RlIGNvbXBsZXRpb24gYnkga25vd2luZyB0aGUgbWVtYmVycyB0aGF0IG9iamVjdHMgY29udGFpbiBhbmQgbm90IGp1c3QgdGhlIGluZGV4ZXMuIEFsc28KICAgICAgICAgICAgLy8vIGtub3cgd2hhdCB0eXBlIGVhY2ggbWVtYmVyIGhhcy4gRXhhbXBsZToge25hbWU6IFN0cmluZywgZW1haWxBZGRyZXNzZXM6IFtTdHJpbmddLCBwYXNzd29yZH08L3BhcmFtPgogICAgICAgICAgICB0aGlzLnNjaGVtYS5tYXBwZWRDbGFzcyA9IGNvbnN0cnVjdG9yOwogICAgICAgICAgICB2YXIgaW5zdGFuY2VUZW1wbGF0ZSA9IE9iamVjdC5jcmVhdGUoY29uc3RydWN0b3IucHJvdG90eXBlKTsKICAgICAgICAgICAgaWYgKHN0cnVjdHVyZSkgewogICAgICAgICAgICAgICAgLy8gc3RydWN0dXJlIGFuZCBpbnN0YW5jZVRlbXBsYXRlIGlzIGZvciBJREUgY29kZSBjb21wZXRpb24gb25seSB3aGlsZSBjb25zdHJ1Y3Rvci5wcm90b3R5cGUgaXMgZm9yIGFjdHVhbCBpbmhlcml0YW5jZS4KICAgICAgICAgICAgICAgIGFwcGx5U3RydWN0dXJlKGluc3RhbmNlVGVtcGxhdGUsIHN0cnVjdHVyZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy5zY2hlbWEuaW5zdGFuY2VUZW1wbGF0ZSA9IGluc3RhbmNlVGVtcGxhdGU7CiAgICAgICAgICAgIC8vIE5vdywgc3Vic2NyaWJlIHRvIHRoZSB3aGVuKCJyZWFkaW5nIikgZXZlbnQgdG8gbWFrZSBhbGwgb2JqZWN0cyB0aGF0IGNvbWUgb3V0IGZyb20gdGhpcyB0YWJsZSBpbmhlcml0IGZyb20gZ2l2ZW4gY2xhc3MKICAgICAgICAgICAgLy8gbm8gbWF0dGVyIHdoaWNoIG1ldGhvZCB0byB1c2UgZm9yIHJlYWRpbmcgKFRhYmxlLmdldCgpIG9yIFRhYmxlLndoZXJlKC4uLikuLi4gKQogICAgICAgICAgICB2YXIgcmVhZEhvb2sgPSBmdW5jdGlvbiAob2JqKSB7CiAgICAgICAgICAgICAgICBpZiAoIW9iaikKICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2JqOyAvLyBObyB2YWxpZCBvYmplY3QuIChWYWx1ZSBpcyBudWxsKS4gUmV0dXJuIGFzIGlzLgogICAgICAgICAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IG9iamVjdCB0aGF0IGRlcml2ZXMgZnJvbSBjb25zdHJ1Y3RvcjoKICAgICAgICAgICAgICAgIHZhciByZXMgPSBPYmplY3QuY3JlYXRlKGNvbnN0cnVjdG9yLnByb3RvdHlwZSk7CiAgICAgICAgICAgICAgICAvLyBDbG9uZSBtZW1iZXJzOgogICAgICAgICAgICAgICAgZm9yICh2YXIgbSBpbiBvYmopCiAgICAgICAgICAgICAgICAgICAgaWYgKGhhc093bihvYmosIG0pKQogICAgICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzW21dID0gb2JqW21dOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChfKSB7IH0KICAgICAgICAgICAgICAgIHJldHVybiByZXM7CiAgICAgICAgICAgIH07CiAgICAgICAgICAgIGlmICh0aGlzLnNjaGVtYS5yZWFkSG9vaykgewogICAgICAgICAgICAgICAgdGhpcy5ob29rLnJlYWRpbmcudW5zdWJzY3JpYmUodGhpcy5zY2hlbWEucmVhZEhvb2spOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMuc2NoZW1hLnJlYWRIb29rID0gcmVhZEhvb2s7CiAgICAgICAgICAgIHRoaXMuaG9vaygicmVhZGluZyIsIHJlYWRIb29rKTsKICAgICAgICAgICAgcmV0dXJuIGNvbnN0cnVjdG9yOwogICAgICAgIH0sCiAgICAgICAgZGVmaW5lQ2xhc3M6IGZ1bmN0aW9uIChzdHJ1Y3R1cmUpIHsKICAgICAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgICAgICAvLy8gICAgIERlZmluZSBhbGwgbWVtYmVycyBvZiB0aGUgY2xhc3MgdGhhdCByZXByZXNlbnRzIHRoZSB0YWJsZS4gVGhpcyB3aWxsIGhlbHAgY29kZSBjb21wbGV0aW9uIG9mIHdoZW4gb2JqZWN0cyBhcmUgcmVhZCBmcm9tIHRoZSBkYXRhYmFzZQogICAgICAgICAgICAvLy8gICAgIGFzIHdlbGwgYXMgbWFraW5nIGl0IHBvc3NpYmxlIHRvIGV4dGVuZCB0aGUgcHJvdG90eXBlIG9mIHRoZSByZXR1cm5lZCBjb25zdHJ1Y3RvciBmdW5jdGlvbi4KICAgICAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJzdHJ1Y3R1cmUiPkhlbHBzIElERSBjb2RlIGNvbXBsZXRpb24gYnkga25vd2luZyB0aGUgbWVtYmVycyB0aGF0IG9iamVjdHMgY29udGFpbiBhbmQgbm90IGp1c3QgdGhlIGluZGV4ZXMuIEFsc28KICAgICAgICAgICAgLy8vIGtub3cgd2hhdCB0eXBlIGVhY2ggbWVtYmVyIGhhcy4gRXhhbXBsZToge25hbWU6IFN0cmluZywgZW1haWxBZGRyZXNzZXM6IFtTdHJpbmddLCBwcm9wZXJ0aWVzOiB7c2hvZVNpemU6IE51bWJlcn19PC9wYXJhbT4KICAgICAgICAgICAgcmV0dXJuIHRoaXMubWFwVG9DbGFzcyhEZXhpZS5kZWZpbmVDbGFzcyhzdHJ1Y3R1cmUpLCBzdHJ1Y3R1cmUpOwogICAgICAgIH0sCiAgICAgICAgYnVsa0RlbGV0ZTogZnVuY3Rpb24gKGtleXMkJDEpIHsKICAgICAgICAgICAgaWYgKHRoaXMuaG9vay5kZWxldGluZy5maXJlID09PSBub3ApIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9pZGJzdG9yZShSRUFEV1JJVEUsIGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QsIGlkYnN0b3JlLCB0cmFucykgewogICAgICAgICAgICAgICAgICAgIHJlc29sdmUoYnVsa0RlbGV0ZShpZGJzdG9yZSwgdHJhbnMsIGtleXMkJDEsIGZhbHNlLCBub3ApKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMKICAgICAgICAgICAgICAgICAgICAud2hlcmUoJzppZCcpCiAgICAgICAgICAgICAgICAgICAgLmFueU9mKGtleXMkJDEpCiAgICAgICAgICAgICAgICAgICAgLmRlbGV0ZSgpCiAgICAgICAgICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyB9KTsgLy8gUmVzb2x2ZSB3aXRoIHVuZGVmaW5lZC4KICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgYnVsa1B1dDogZnVuY3Rpb24gKG9iamVjdHMsIGtleXMkJDEpIHsKICAgICAgICAgICAgdmFyIF90aGlzID0gdGhpczsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2lkYnN0b3JlKFJFQURXUklURSwgZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCwgaWRic3RvcmUpIHsKICAgICAgICAgICAgICAgIGlmICghaWRic3RvcmUua2V5UGF0aCAmJiAhX3RoaXMuc2NoZW1hLnByaW1LZXkuYXV0byAmJiAha2V5cyQkMSkKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgZXhjZXB0aW9ucy5JbnZhbGlkQXJndW1lbnQoImJ1bGtQdXQoKSB3aXRoIG5vbi1pbmJvdW5kIGtleXMgcmVxdWlyZXMga2V5cyBhcnJheSBpbiBzZWNvbmQgYXJndW1lbnQiKTsKICAgICAgICAgICAgICAgIGlmIChpZGJzdG9yZS5rZXlQYXRoICYmIGtleXMkJDEpCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IGV4Y2VwdGlvbnMuSW52YWxpZEFyZ3VtZW50KCJidWxrUHV0KCk6IGtleXMgYXJndW1lbnQgaW52YWxpZCBvbiB0YWJsZXMgd2l0aCBpbmJvdW5kIGtleXMiKTsKICAgICAgICAgICAgICAgIGlmIChrZXlzJCQxICYmIGtleXMkJDEubGVuZ3RoICE9PSBvYmplY3RzLmxlbmd0aCkKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgZXhjZXB0aW9ucy5JbnZhbGlkQXJndW1lbnQoIkFyZ3VtZW50cyBvYmplY3RzIGFuZCBrZXlzIG11c3QgaGF2ZSB0aGUgc2FtZSBsZW5ndGgiKTsKICAgICAgICAgICAgICAgIGlmIChvYmplY3RzLmxlbmd0aCA9PT0gMCkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgpOyAvLyBDYWxsZXIgcHJvdmlkZWQgZW1wdHkgbGlzdC4KICAgICAgICAgICAgICAgIHZhciBkb25lID0gZnVuY3Rpb24gKHJlc3VsdCkgewogICAgICAgICAgICAgICAgICAgIGlmIChlcnJvckxpc3QubGVuZ3RoID09PSAwKQogICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEJ1bGtFcnJvcihfdGhpcy5uYW1lICsgIi5idWxrUHV0KCk6ICIgKyBlcnJvckxpc3QubGVuZ3RoICsgIiBvZiAiICsgbnVtT2JqcyArICIgb3BlcmF0aW9ucyBmYWlsZWQiLCBlcnJvckxpc3QpKTsKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICB2YXIgcmVxLCBlcnJvckxpc3QgPSBbXSwgZXJyb3JIYW5kbGVyLCBudW1PYmpzID0gb2JqZWN0cy5sZW5ndGgsIHRhYmxlID0gX3RoaXM7CiAgICAgICAgICAgICAgICBpZiAoX3RoaXMuaG9vay5jcmVhdGluZy5maXJlID09PSBub3AgJiYgX3RoaXMuaG9vay51cGRhdGluZy5maXJlID09PSBub3ApIHsKICAgICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgICAgIC8vIFN0YW5kYXJkIEJ1bGsgKG5vICdjcmVhdGluZycgb3IgJ3VwZGF0aW5nJyBob29rcyB0byBjYXJlIGFib3V0KQogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyID0gQnVsa0Vycm9ySGFuZGxlckNhdGNoQWxsKGVycm9yTGlzdCk7CiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBvYmplY3RzLmxlbmd0aDsgaSA8IGw7ICsraSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXEgPSBrZXlzJCQxID8gaWRic3RvcmUucHV0KG9iamVjdHNbaV0sIGtleXMkJDFbaV0pIDogaWRic3RvcmUucHV0KG9iamVjdHNbaV0pOwogICAgICAgICAgICAgICAgICAgICAgICByZXEub25lcnJvciA9IGVycm9ySGFuZGxlcjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8gT25seSBuZWVkIHRvIGNhdGNoIHN1Y2Nlc3Mgb3IgZXJyb3Igb24gdGhlIGxhc3Qgb3BlcmF0aW9uCiAgICAgICAgICAgICAgICAgICAgLy8gYWNjb3JkaW5nIHRvIHRoZSBJREIgc3BlYy4KICAgICAgICAgICAgICAgICAgICByZXEub25lcnJvciA9IEJ1bGtFcnJvckhhbmRsZXJDYXRjaEFsbChlcnJvckxpc3QsIGRvbmUpOwogICAgICAgICAgICAgICAgICAgIHJlcS5vbnN1Y2Nlc3MgPSBldmVudFN1Y2Nlc3NIYW5kbGVyKGRvbmUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGVmZmVjdGl2ZUtleXMgPSBrZXlzJCQxIHx8IGlkYnN0b3JlLmtleVBhdGggJiYgb2JqZWN0cy5tYXAoZnVuY3Rpb24gKG8pIHsgcmV0dXJuIGdldEJ5S2V5UGF0aChvLCBpZGJzdG9yZS5rZXlQYXRoKTsgfSk7CiAgICAgICAgICAgICAgICAgICAgLy8gR2VuZXJhdGUgbWFwIG9mIHtba2V5XTogb2JqZWN0fQogICAgICAgICAgICAgICAgICAgIHZhciBvYmplY3RMb29rdXAgPSBlZmZlY3RpdmVLZXlzICYmIGFycmF5VG9PYmplY3QoZWZmZWN0aXZlS2V5cywgZnVuY3Rpb24gKGtleSwgaSkgeyByZXR1cm4ga2V5ICE9IG51bGwgJiYgW2tleSwgb2JqZWN0c1tpXV07IH0pOwogICAgICAgICAgICAgICAgICAgIHZhciBwcm9taXNlID0gIWVmZmVjdGl2ZUtleXMgPwogICAgICAgICAgICAgICAgICAgICAgICAvLyBBdXRvLWluY3JlbWVudGVkIGtleS1sZXNzIG9iamVjdHMgb25seSB3aXRob3V0IGFueSBrZXlzIGFyZ3VtZW50LgogICAgICAgICAgICAgICAgICAgICAgICB0YWJsZS5idWxrQWRkKG9iamVjdHMpIDoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gS2V5cyBwcm92aWRlZC4gRWl0aGVyIGFzIGluYm91bmQgaW4gcHJvdmlkZWQgb2JqZWN0cywgb3IgYXMgYSBrZXlzIGFyZ3VtZW50LgogICAgICAgICAgICAgICAgICAgICAgICAvLyBCZWdpbiB3aXRoIHVwZGF0aW5nIHRob3NlIHRoYXQgZXhpc3RzIGluIERCOgogICAgICAgICAgICAgICAgICAgICAgICB0YWJsZS53aGVyZSgnOmlkJykuYW55T2YoZWZmZWN0aXZlS2V5cy5maWx0ZXIoZnVuY3Rpb24gKGtleSkgeyByZXR1cm4ga2V5ICE9IG51bGw7IH0pKS5tb2RpZnkoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy52YWx1ZSA9IG9iamVjdExvb2t1cFt0aGlzLnByaW1LZXldOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0TG9va3VwW3RoaXMucHJpbUtleV0gPSBudWxsOyAvLyBNYXJrIGFzICJkb24ndCBhZGQgdGhpcyIKICAgICAgICAgICAgICAgICAgICAgICAgfSkuY2F0Y2goTW9kaWZ5RXJyb3IsIGZ1bmN0aW9uIChlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckxpc3QgPSBlLmZhaWx1cmVzOyAvLyBObyBuZWVkIHRvIGNvbmNhdCBoZXJlLiBUaGVzZSBhcmUgdGhlIGZpcnN0IGVycm9ycyBhZGRlZC4KICAgICAgICAgICAgICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3csIGxldCdzIGV4YW1pbmUgd2hpY2ggaXRlbXMgZGlkbnQgZXhpc3Qgc28gd2UgY2FuIGFkZCB0aGVtOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9ianNUb0FkZCA9IFtdLCBrZXlzVG9BZGQgPSBrZXlzJCQxICYmIFtdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSXRlcmF0ZSBiYWNrd2FyZHMuIFdoeT8gQmVjYXVzZSBpZiBzYW1lIGtleSB3YXMgdXNlZCB0d2ljZSwganVzdCBhZGQgdGhlIGxhc3Qgb25lLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IGVmZmVjdGl2ZUtleXMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIga2V5ID0gZWZmZWN0aXZlS2V5c1tpXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoa2V5ID09IG51bGwgfHwgb2JqZWN0TG9va3VwW2tleV0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Jqc1RvQWRkLnB1c2gob2JqZWN0c1tpXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleXMkJDEgJiYga2V5c1RvQWRkLnB1c2goa2V5KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGtleSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0TG9va3VwW2tleV0gPSBudWxsOyAvLyBNYXJrIGFzICJkb250IGFkZCBhZ2FpbiIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGUgaXRlbXMgYXJlIGluIHJldmVyc2Ugb3JkZXIgc28gcmV2ZXJzZSB0aGVtIGJlZm9yZSBhZGRpbmcuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDb3VsZCBiZSBpbXBvcnRhbnQgaW4gb3JkZXIgdG8gZ2V0IGF1dG8taW5jcmVtZW50ZWQga2V5cyB0aGUgd2F5IHRoZSBjYWxsZXIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdvdWxkIGV4cGVjdC4gQ291bGQgaGF2ZSB1c2VkIHVuc2hpZnQgaW5zdGVhZCBvZiBwdXNoKCkvcmV2ZXJzZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYnV0OiBodHRwOi8vanNwZXJmLmNvbS91bnNoaWZ0LXZzLXJldmVyc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ianNUb0FkZC5yZXZlcnNlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXlzJCQxICYmIGtleXNUb0FkZC5yZXZlcnNlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGFibGUuYnVsa0FkZChvYmpzVG9BZGQsIGtleXNUb0FkZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKGxhc3RBZGRlZEtleSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVzb2x2ZSB3aXRoIGtleSBvZiB0aGUgbGFzdCBvYmplY3QgaW4gZ2l2ZW4gYXJndW1lbnRzIHRvIGJ1bGtQdXQoKToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsYXN0RWZmZWN0aXZlS2V5ID0gZWZmZWN0aXZlS2V5c1tlZmZlY3RpdmVLZXlzLmxlbmd0aCAtIDFdOyAvLyBLZXkgd2FzIHByb3ZpZGVkLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGxhc3RFZmZlY3RpdmVLZXkgIT0gbnVsbCA/IGxhc3RFZmZlY3RpdmVLZXkgOiBsYXN0QWRkZWRLZXk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIHByb21pc2UudGhlbihkb25lKS5jYXRjaChCdWxrRXJyb3IsIGZ1bmN0aW9uIChlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbmNhdCBmYWlsdXJlIGZyb20gTW9kaWZ5RXJyb3IgYW5kIHJlamVjdCB1c2luZyBvdXIgJ2RvbmUnIG1ldGhvZC4KICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JMaXN0ID0gZXJyb3JMaXN0LmNvbmNhdChlLmZhaWx1cmVzKTsKICAgICAgICAgICAgICAgICAgICAgICAgZG9uZSgpOwogICAgICAgICAgICAgICAgICAgIH0pLmNhdGNoKHJlamVjdCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sICJsb2NrZWQiKTsgLy8gSWYgY2FsbGVkIGZyb20gdHJhbnNhY3Rpb24gc2NvcGUsIGxvY2sgdHJhbnNhY3Rpb24gdGlsIGFsbCBzdGVwcyBhcmUgZG9uZS4KICAgICAgICB9LAogICAgICAgIGJ1bGtBZGQ6IGZ1bmN0aW9uIChvYmplY3RzLCBrZXlzJCQxKSB7CiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcywgY3JlYXRpbmdIb29rID0gdGhpcy5ob29rLmNyZWF0aW5nLmZpcmU7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9pZGJzdG9yZShSRUFEV1JJVEUsIGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QsIGlkYnN0b3JlLCB0cmFucykgewogICAgICAgICAgICAgICAgaWYgKCFpZGJzdG9yZS5rZXlQYXRoICYmICFzZWxmLnNjaGVtYS5wcmltS2V5LmF1dG8gJiYgIWtleXMkJDEpCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IGV4Y2VwdGlvbnMuSW52YWxpZEFyZ3VtZW50KCJidWxrQWRkKCkgd2l0aCBub24taW5ib3VuZCBrZXlzIHJlcXVpcmVzIGtleXMgYXJyYXkgaW4gc2Vjb25kIGFyZ3VtZW50Iik7CiAgICAgICAgICAgICAgICBpZiAoaWRic3RvcmUua2V5UGF0aCAmJiBrZXlzJCQxKQogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBleGNlcHRpb25zLkludmFsaWRBcmd1bWVudCgiYnVsa0FkZCgpOiBrZXlzIGFyZ3VtZW50IGludmFsaWQgb24gdGFibGVzIHdpdGggaW5ib3VuZCBrZXlzIik7CiAgICAgICAgICAgICAgICBpZiAoa2V5cyQkMSAmJiBrZXlzJCQxLmxlbmd0aCAhPT0gb2JqZWN0cy5sZW5ndGgpCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IGV4Y2VwdGlvbnMuSW52YWxpZEFyZ3VtZW50KCJBcmd1bWVudHMgb2JqZWN0cyBhbmQga2V5cyBtdXN0IGhhdmUgdGhlIHNhbWUgbGVuZ3RoIik7CiAgICAgICAgICAgICAgICBpZiAob2JqZWN0cy5sZW5ndGggPT09IDApCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoKTsgLy8gQ2FsbGVyIHByb3ZpZGVkIGVtcHR5IGxpc3QuCiAgICAgICAgICAgICAgICBmdW5jdGlvbiBkb25lKHJlc3VsdCkgewogICAgICAgICAgICAgICAgICAgIGlmIChlcnJvckxpc3QubGVuZ3RoID09PSAwKQogICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEJ1bGtFcnJvcihzZWxmLm5hbWUgKyAiLmJ1bGtBZGQoKTogIiArIGVycm9yTGlzdC5sZW5ndGggKyAiIG9mICIgKyBudW1PYmpzICsgIiBvcGVyYXRpb25zIGZhaWxlZCIsIGVycm9yTGlzdCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIHJlcSwgZXJyb3JMaXN0ID0gW10sIGVycm9ySGFuZGxlciwgc3VjY2Vzc0hhbmRsZXIsIG51bU9ianMgPSBvYmplY3RzLmxlbmd0aDsKICAgICAgICAgICAgICAgIGlmIChjcmVhdGluZ0hvb2sgIT09IG5vcCkgewogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgLy8gVGhlcmUgYXJlIHN1YnNjcmliZXJzIHRvIGhvb2soJ2NyZWF0aW5nJykKICAgICAgICAgICAgICAgICAgICAvLyBNdXN0IGJlaGF2ZSBhcyBkb2N1bWVudGVkLgogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgdmFyIGtleVBhdGggPSBpZGJzdG9yZS5rZXlQYXRoLCBob29rQ3R4OwogICAgICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlciA9IEJ1bGtFcnJvckhhbmRsZXJDYXRjaEFsbChlcnJvckxpc3QsIG51bGwsIHRydWUpOwogICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NIYW5kbGVyID0gaG9va2VkRXZlbnRTdWNjZXNzSGFuZGxlcihudWxsKTsKICAgICAgICAgICAgICAgICAgICB0cnlDYXRjaChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gb2JqZWN0cy5sZW5ndGg7IGkgPCBsOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvb2tDdHggPSB7IG9uZXJyb3I6IG51bGwsIG9uc3VjY2VzczogbnVsbCB9OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGtleSA9IGtleXMkJDEgJiYga2V5cyQkMVtpXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvYmogPSBvYmplY3RzW2ldLCBlZmZlY3RpdmVLZXkgPSBrZXlzJCQxID8ga2V5IDoga2V5UGF0aCA/IGdldEJ5S2V5UGF0aChvYmosIGtleVBhdGgpIDogdW5kZWZpbmVkLCBrZXlUb1VzZSA9IGNyZWF0aW5nSG9vay5jYWxsKGhvb2tDdHgsIGVmZmVjdGl2ZUtleSwgb2JqLCB0cmFucyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWZmZWN0aXZlS2V5ID09IG51bGwgJiYga2V5VG9Vc2UgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChrZXlQYXRoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iaiA9IGRlZXBDbG9uZShvYmopOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRCeUtleVBhdGgob2JqLCBrZXlQYXRoLCBrZXlUb1VzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXkgPSBrZXlUb1VzZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXEgPSBrZXkgIT0gbnVsbCA/IGlkYnN0b3JlLmFkZChvYmosIGtleSkgOiBpZGJzdG9yZS5hZGQob2JqKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcS5faG9va0N0eCA9IGhvb2tDdHg7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA8IGwgLSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxLm9uZXJyb3IgPSBlcnJvckhhbmRsZXI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGhvb2tDdHgub25zdWNjZXNzKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXEub25zdWNjZXNzID0gc3VjY2Vzc0hhbmRsZXI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9LCBmdW5jdGlvbiAoZXJyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGhvb2tDdHgub25lcnJvciAmJiBob29rQ3R4Lm9uZXJyb3IoZXJyKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyOwogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIHJlcS5vbmVycm9yID0gQnVsa0Vycm9ySGFuZGxlckNhdGNoQWxsKGVycm9yTGlzdCwgZG9uZSwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgcmVxLm9uc3VjY2VzcyA9IGhvb2tlZEV2ZW50U3VjY2Vzc0hhbmRsZXIoZG9uZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgICAgIC8vIFN0YW5kYXJkIEJ1bGsgKG5vICdjcmVhdGluZycgaG9vayB0byBjYXJlIGFib3V0KQogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyID0gQnVsa0Vycm9ySGFuZGxlckNhdGNoQWxsKGVycm9yTGlzdCk7CiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBvYmplY3RzLmxlbmd0aDsgaSA8IGw7ICsraSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXEgPSBrZXlzJCQxID8gaWRic3RvcmUuYWRkKG9iamVjdHNbaV0sIGtleXMkJDFbaV0pIDogaWRic3RvcmUuYWRkKG9iamVjdHNbaV0pOwogICAgICAgICAgICAgICAgICAgICAgICByZXEub25lcnJvciA9IGVycm9ySGFuZGxlcjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8gT25seSBuZWVkIHRvIGNhdGNoIHN1Y2Nlc3Mgb3IgZXJyb3Igb24gdGhlIGxhc3Qgb3BlcmF0aW9uCiAgICAgICAgICAgICAgICAgICAgLy8gYWNjb3JkaW5nIHRvIHRoZSBJREIgc3BlYy4KICAgICAgICAgICAgICAgICAgICByZXEub25lcnJvciA9IEJ1bGtFcnJvckhhbmRsZXJDYXRjaEFsbChlcnJvckxpc3QsIGRvbmUpOwogICAgICAgICAgICAgICAgICAgIHJlcS5vbnN1Y2Nlc3MgPSBldmVudFN1Y2Nlc3NIYW5kbGVyKGRvbmUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICB9LAogICAgICAgIGFkZDogZnVuY3Rpb24gKG9iaiwga2V5KSB7CiAgICAgICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAgICAgLy8vICAgQWRkIGFuIG9iamVjdCB0byB0aGUgZGF0YWJhc2UuIEluIGNhc2UgYW4gb2JqZWN0IHdpdGggc2FtZSBwcmltYXJ5IGtleSBhbHJlYWR5IGV4aXN0cywgdGhlIG9iamVjdCB3aWxsIG5vdCBiZSBhZGRlZC4KICAgICAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvYmoiIHR5cGU9Ik9iamVjdCI+QSBqYXZhc2NyaXB0IG9iamVjdCB0byBpbnNlcnQ8L3BhcmFtPgogICAgICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImtleSIgb3B0aW9uYWw9InRydWUiPlByaW1hcnkga2V5PC9wYXJhbT4KICAgICAgICAgICAgdmFyIGNyZWF0aW5nSG9vayA9IHRoaXMuaG9vay5jcmVhdGluZy5maXJlOwogICAgICAgICAgICByZXR1cm4gdGhpcy5faWRic3RvcmUoUkVBRFdSSVRFLCBmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0LCBpZGJzdG9yZSwgdHJhbnMpIHsKICAgICAgICAgICAgICAgIHZhciBob29rQ3R4ID0geyBvbnN1Y2Nlc3M6IG51bGwsIG9uZXJyb3I6IG51bGwgfTsKICAgICAgICAgICAgICAgIGlmIChjcmVhdGluZ0hvb2sgIT09IG5vcCkgewogICAgICAgICAgICAgICAgICAgIHZhciBlZmZlY3RpdmVLZXkgPSAoa2V5ICE9IG51bGwpID8ga2V5IDogKGlkYnN0b3JlLmtleVBhdGggPyBnZXRCeUtleVBhdGgob2JqLCBpZGJzdG9yZS5rZXlQYXRoKSA6IHVuZGVmaW5lZCk7CiAgICAgICAgICAgICAgICAgICAgdmFyIGtleVRvVXNlID0gY3JlYXRpbmdIb29rLmNhbGwoaG9va0N0eCwgZWZmZWN0aXZlS2V5LCBvYmosIHRyYW5zKTsgLy8gQWxsb3cgc3Vic2NyaWJlcnMgdG8gd2hlbigiY3JlYXRpbmciKSB0byBnZW5lcmF0ZSB0aGUga2V5LgogICAgICAgICAgICAgICAgICAgIGlmIChlZmZlY3RpdmVLZXkgPT0gbnVsbCAmJiBrZXlUb1VzZSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpZGJzdG9yZS5rZXlQYXRoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0QnlLZXlQYXRoKG9iaiwgaWRic3RvcmUua2V5UGF0aCwga2V5VG9Vc2UpOwogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXkgPSBrZXlUb1VzZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHZhciByZXEgPSBrZXkgIT0gbnVsbCA/IGlkYnN0b3JlLmFkZChvYmosIGtleSkgOiBpZGJzdG9yZS5hZGQob2JqKTsKICAgICAgICAgICAgICAgICAgICByZXEuX2hvb2tDdHggPSBob29rQ3R4OwogICAgICAgICAgICAgICAgICAgIHJlcS5vbmVycm9yID0gaG9va2VkRXZlbnRSZWplY3RIYW5kbGVyKHJlamVjdCk7CiAgICAgICAgICAgICAgICAgICAgcmVxLm9uc3VjY2VzcyA9IGhvb2tlZEV2ZW50U3VjY2Vzc0hhbmRsZXIoZnVuY3Rpb24gKHJlc3VsdCkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBUT0RPOiBSZW1vdmUgdGhlc2UgdHdvIGxpbmVzIGluIG5leHQgbWFqb3IgcmVsZWFzZSAoMi4wPykKICAgICAgICAgICAgICAgICAgICAgICAgLy8gSXQncyBubyBnb29kIHByYWN0aWNlIHRvIGhhdmUgc2lkZSBlZmZlY3RzIG9uIHByb3ZpZGVkIHBhcmFtZXRlcnMKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGtleVBhdGggPSBpZGJzdG9yZS5rZXlQYXRoOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoa2V5UGF0aCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldEJ5S2V5UGF0aChvYmosIGtleVBhdGgsIHJlc3VsdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUocmVzdWx0KTsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGhvb2tDdHgub25lcnJvcikKICAgICAgICAgICAgICAgICAgICAgICAgaG9va0N0eC5vbmVycm9yKGUpOwogICAgICAgICAgICAgICAgICAgIHRocm93IGU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0sCiAgICAgICAgcHV0OiBmdW5jdGlvbiAob2JqLCBrZXkpIHsKICAgICAgICAgICAgdmFyIF90aGlzID0gdGhpczsKICAgICAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgICAgICAvLy8gICBBZGQgYW4gb2JqZWN0IHRvIHRoZSBkYXRhYmFzZSBidXQgaW4gY2FzZSBhbiBvYmplY3Qgd2l0aCBzYW1lIHByaW1hcnkga2V5IGFscmVhZCBleGlzdHMsIHRoZSBleGlzdGluZyBvbmUgd2lsbCBnZXQgdXBkYXRlZC4KICAgICAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvYmoiIHR5cGU9Ik9iamVjdCI+QSBqYXZhc2NyaXB0IG9iamVjdCB0byBpbnNlcnQgb3IgdXBkYXRlPC9wYXJhbT4KICAgICAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJrZXkiIG9wdGlvbmFsPSJ0cnVlIj5QcmltYXJ5IGtleTwvcGFyYW0+CiAgICAgICAgICAgIHZhciBjcmVhdGluZ0hvb2sgPSB0aGlzLmhvb2suY3JlYXRpbmcuZmlyZSwgdXBkYXRpbmdIb29rID0gdGhpcy5ob29rLnVwZGF0aW5nLmZpcmU7CiAgICAgICAgICAgIGlmIChjcmVhdGluZ0hvb2sgIT09IG5vcCB8fCB1cGRhdGluZ0hvb2sgIT09IG5vcCkgewogICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgIC8vIFBlb3BsZSBsaXN0ZW5zIHRvIHdoZW4oImNyZWF0aW5nIikgb3Igd2hlbigidXBkYXRpbmciKSBldmVudHMhCiAgICAgICAgICAgICAgICAvLyBXZSBtdXN0IGtub3cgd2hldGhlciB0aGUgcHV0IG9wZXJhdGlvbiByZXN1bHRzIGluIGFuIENSRUFURSBvciBVUERBVEUuCiAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgdmFyIGtleVBhdGggPSB0aGlzLnNjaGVtYS5wcmltS2V5LmtleVBhdGg7CiAgICAgICAgICAgICAgICB2YXIgZWZmZWN0aXZlS2V5ID0gKGtleSAhPT0gdW5kZWZpbmVkKSA/IGtleSA6IChrZXlQYXRoICYmIGdldEJ5S2V5UGF0aChvYmosIGtleVBhdGgpKTsKICAgICAgICAgICAgICAgIGlmIChlZmZlY3RpdmVLZXkgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hZGQob2JqKTsKICAgICAgICAgICAgICAgIC8vIFNpbmNlIGtleSBpcyBvcHRpb25hbCwgbWFrZSBzdXJlIHdlIGdldCBpdCBmcm9tIG9iaiBpZiBub3QgcHJvdmlkZWQKICAgICAgICAgICAgICAgIC8vIFByaW1hcnkga2V5IGV4aXN0LiBMb2NrIHRyYW5zYWN0aW9uIGFuZCB0cnkgbW9kaWZ5aW5nIGV4aXN0aW5nLiBJZiBub3RoaW5nIG1vZGlmaWVkLCBjYWxsIGFkZCgpLgogICAgICAgICAgICAgICAgLy8gY2xvbmUgb2JqIGJlZm9yZSB0aGlzIGFzeW5jIGNhbGwuIElmIGNhbGxlciBtb2RpZmllcyBvYmogdGhlIGxpbmUgYWZ0ZXIgcHV0KCksIHRoZSBJREIgc3BlYyByZXF1aXJlcyB0aGF0IGl0IHNob3VsZCBub3QgYWZmZWN0IG9wZXJhdGlvbi4KICAgICAgICAgICAgICAgIG9iaiA9IGRlZXBDbG9uZShvYmopOwogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RyYW5zKFJFQURXUklURSwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpcy53aGVyZSgiOmlkIikuZXF1YWxzKGVmZmVjdGl2ZUtleSkubW9kaWZ5KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVwbGFjZSBleHRpc3RpbmcgdmFsdWUgd2l0aCBvdXIgb2JqZWN0CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIENSVUQgZXZlbnQgZmlyaW5nIGhhbmRsZWQgaW4gQ29sbGVjdGlvbi5tb2RpZnkoKQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZhbHVlID0gb2JqOwogICAgICAgICAgICAgICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKGNvdW50KSB7IHJldHVybiBjb3VudCA9PT0gMCA/IF90aGlzLmFkZChvYmosIGtleSkgOiBlZmZlY3RpdmVLZXk7IH0pOwogICAgICAgICAgICAgICAgfSwgImxvY2tlZCIpOyAvLyBMb2NrIG5lZWRlZCBiZWNhdXNlIG9wZXJhdGlvbiBpcyBzcGxpdHRlZCBpbnRvIG1vZGlmeSgpIGFuZCBhZGQoKS4KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIFVzZSB0aGUgc3RhbmRhcmQgSURCIHB1dCgpIG1ldGhvZC4KICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9pZGJzdG9yZShSRUFEV1JJVEUsIGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QsIGlkYnN0b3JlKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHJlcSA9IGtleSAhPT0gdW5kZWZpbmVkID8gaWRic3RvcmUucHV0KG9iaiwga2V5KSA6IGlkYnN0b3JlLnB1dChvYmopOwogICAgICAgICAgICAgICAgICAgIHJlcS5vbmVycm9yID0gZXZlbnRSZWplY3RIYW5kbGVyKHJlamVjdCk7CiAgICAgICAgICAgICAgICAgICAgcmVxLm9uc3VjY2VzcyA9IHdyYXAoZnVuY3Rpb24gKGV2KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBrZXlQYXRoID0gaWRic3RvcmUua2V5UGF0aDsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGtleVBhdGgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRCeUtleVBhdGgob2JqLCBrZXlQYXRoLCBldi50YXJnZXQucmVzdWx0KTsKICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShyZXEucmVzdWx0KTsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAnZGVsZXRlJzogZnVuY3Rpb24gKGtleSkgewogICAgICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImtleSI+UHJpbWFyeSBrZXkgb2YgdGhlIG9iamVjdCB0byBkZWxldGU8L3BhcmFtPgogICAgICAgICAgICBpZiAodGhpcy5ob29rLmRlbGV0aW5nLnN1YnNjcmliZXJzLmxlbmd0aCkgewogICAgICAgICAgICAgICAgLy8gUGVvcGxlIGxpc3RlbnMgdG8gd2hlbigiZGVsZXRpbmciKSBldmVudC4gTXVzdCBpbXBsZW1lbnQgZGVsZXRlIHVzaW5nIENvbGxlY3Rpb24uZGVsZXRlKCkgdGhhdCB3aWxsCiAgICAgICAgICAgICAgICAvLyBjYWxsIHRoZSBDUlVEIGV2ZW50LiBPbmx5IENvbGxlY3Rpb24uZGVsZXRlKCkgd2lsbCBrbm93IHdoZXRoZXIgYW4gb2JqZWN0IHdhcyBhY3R1YWxseSBkZWxldGVkLgogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMud2hlcmUoIjppZCIpLmVxdWFscyhrZXkpLmRlbGV0ZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgLy8gTm8gb25lIGxpc3RlbnMuIFVzZSBzdGFuZGFyZCBJREIgZGVsZXRlKCkgbWV0aG9kLgogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2lkYnN0b3JlKFJFQURXUklURSwgZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCwgaWRic3RvcmUpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgcmVxID0gaWRic3RvcmUuZGVsZXRlKGtleSk7CiAgICAgICAgICAgICAgICAgICAgcmVxLm9uZXJyb3IgPSBldmVudFJlamVjdEhhbmRsZXIocmVqZWN0KTsKICAgICAgICAgICAgICAgICAgICByZXEub25zdWNjZXNzID0gd3JhcChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUocmVxLnJlc3VsdCk7CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgY2xlYXI6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgaWYgKHRoaXMuaG9vay5kZWxldGluZy5zdWJzY3JpYmVycy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIC8vIFBlb3BsZSBsaXN0ZW5zIHRvIHdoZW4oImRlbGV0aW5nIikgZXZlbnQuIE11c3QgaW1wbGVtZW50IGRlbGV0ZSB1c2luZyBDb2xsZWN0aW9uLmRlbGV0ZSgpIHRoYXQgd2lsbAogICAgICAgICAgICAgICAgLy8gY2FsbCB0aGUgQ1JVRCBldmVudC4gT25seSBDb2xsZWN0aW9uLmRlbGV0ZSgpIHdpbGwga25vd3Mgd2hpY2ggb2JqZWN0cyB0aGF0IGFyZSBhY3R1YWxseSBkZWxldGVkLgogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9Db2xsZWN0aW9uKCkuZGVsZXRlKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5faWRic3RvcmUoUkVBRFdSSVRFLCBmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0LCBpZGJzdG9yZSkgewogICAgICAgICAgICAgICAgICAgIHZhciByZXEgPSBpZGJzdG9yZS5jbGVhcigpOwogICAgICAgICAgICAgICAgICAgIHJlcS5vbmVycm9yID0gZXZlbnRSZWplY3RIYW5kbGVyKHJlamVjdCk7CiAgICAgICAgICAgICAgICAgICAgcmVxLm9uc3VjY2VzcyA9IHdyYXAoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlcS5yZXN1bHQpOwogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHVwZGF0ZTogZnVuY3Rpb24gKGtleU9yT2JqZWN0LCBtb2RpZmljYXRpb25zKSB7CiAgICAgICAgICAgIGlmICh0eXBlb2YgbW9kaWZpY2F0aW9ucyAhPT0gJ29iamVjdCcgfHwgaXNBcnJheShtb2RpZmljYXRpb25zKSkKICAgICAgICAgICAgICAgIHRocm93IG5ldyBleGNlcHRpb25zLkludmFsaWRBcmd1bWVudCgiTW9kaWZpY2F0aW9ucyBtdXN0IGJlIGFuIG9iamVjdC4iKTsKICAgICAgICAgICAgaWYgKHR5cGVvZiBrZXlPck9iamVjdCA9PT0gJ29iamVjdCcgJiYgIWlzQXJyYXkoa2V5T3JPYmplY3QpKSB7CiAgICAgICAgICAgICAgICAvLyBvYmplY3QgdG8gbW9kaWZ5LiBBbHNvIG1vZGlmeSBnaXZlbiBvYmplY3Qgd2l0aCB0aGUgbW9kaWZpY2F0aW9uczoKICAgICAgICAgICAgICAgIGtleXMobW9kaWZpY2F0aW9ucykuZm9yRWFjaChmdW5jdGlvbiAoa2V5UGF0aCkgewogICAgICAgICAgICAgICAgICAgIHNldEJ5S2V5UGF0aChrZXlPck9iamVjdCwga2V5UGF0aCwgbW9kaWZpY2F0aW9uc1trZXlQYXRoXSk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIHZhciBrZXkgPSBnZXRCeUtleVBhdGgoa2V5T3JPYmplY3QsIHRoaXMuc2NoZW1hLnByaW1LZXkua2V5UGF0aCk7CiAgICAgICAgICAgICAgICBpZiAoa2V5ID09PSB1bmRlZmluZWQpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdGlvbihuZXcgZXhjZXB0aW9ucy5JbnZhbGlkQXJndW1lbnQoIkdpdmVuIG9iamVjdCBkb2VzIG5vdCBjb250YWluIGl0cyBwcmltYXJ5IGtleSIpKTsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLndoZXJlKCI6aWQiKS5lcXVhbHMoa2V5KS5tb2RpZnkobW9kaWZpY2F0aW9ucyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBrZXkgdG8gbW9kaWZ5CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy53aGVyZSgiOmlkIikuZXF1YWxzKGtleU9yT2JqZWN0KS5tb2RpZnkobW9kaWZpY2F0aW9ucyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKICAgIC8vCiAgICAvLwogICAgLy8KICAgIC8vIFRyYW5zYWN0aW9uIENsYXNzCiAgICAvLwogICAgLy8KICAgIC8vCiAgICBmdW5jdGlvbiBUcmFuc2FjdGlvbihtb2RlLCBzdG9yZU5hbWVzLCBkYnNjaGVtYSwgcGFyZW50KSB7CiAgICAgICAgdmFyIF90aGlzID0gdGhpczsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vICAgIFRyYW5zYWN0aW9uIGNsYXNzLiBSZXByZXNlbnRzIGEgZGF0YWJhc2UgdHJhbnNhY3Rpb24uIEFsbCBvcGVyYXRpb25zIG9uIGRiIGdvZXMgdGhyb3VnaCBhIFRyYW5zYWN0aW9uLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJtb2RlIiB0eXBlPSJTdHJpbmciPkFueSBvZiAicmVhZHdyaXRlIiBvciAicmVhZG9ubHkiPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InN0b3JlTmFtZXMiIHR5cGU9IkFycmF5Ij5BcnJheSBvZiB0YWJsZSBuYW1lcyB0byBvcGVyYXRlIG9uPC9wYXJhbT4KICAgICAgICB0aGlzLmRiID0gZGI7CiAgICAgICAgdGhpcy5tb2RlID0gbW9kZTsKICAgICAgICB0aGlzLnN0b3JlTmFtZXMgPSBzdG9yZU5hbWVzOwogICAgICAgIHRoaXMuaWRidHJhbnMgPSBudWxsOwogICAgICAgIHRoaXMub24gPSBFdmVudHModGhpcywgImNvbXBsZXRlIiwgImVycm9yIiwgImFib3J0Iik7CiAgICAgICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQgfHwgbnVsbDsKICAgICAgICB0aGlzLmFjdGl2ZSA9IHRydWU7CiAgICAgICAgdGhpcy5fcmVjdWxvY2sgPSAwOwogICAgICAgIHRoaXMuX2Jsb2NrZWRGdW5jcyA9IFtdOwogICAgICAgIHRoaXMuX3Jlc29sdmUgPSBudWxsOwogICAgICAgIHRoaXMuX3JlamVjdCA9IG51bGw7CiAgICAgICAgdGhpcy5fd2FpdGluZ0ZvciA9IG51bGw7CiAgICAgICAgdGhpcy5fd2FpdGluZ1F1ZXVlID0gbnVsbDsKICAgICAgICB0aGlzLl9zcGluQ291bnQgPSAwOyAvLyBKdXN0IGZvciBkZWJ1Z2dpbmcgd2FpdEZvcigpCiAgICAgICAgdGhpcy5fY29tcGxldGlvbiA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHsKICAgICAgICAgICAgX3RoaXMuX3Jlc29sdmUgPSByZXNvbHZlOwogICAgICAgICAgICBfdGhpcy5fcmVqZWN0ID0gcmVqZWN0OwogICAgICAgIH0pOwogICAgICAgIHRoaXMuX2NvbXBsZXRpb24udGhlbihmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIF90aGlzLmFjdGl2ZSA9IGZhbHNlOwogICAgICAgICAgICBfdGhpcy5vbi5jb21wbGV0ZS5maXJlKCk7CiAgICAgICAgfSwgZnVuY3Rpb24gKGUpIHsKICAgICAgICAgICAgdmFyIHdhc0FjdGl2ZSA9IF90aGlzLmFjdGl2ZTsKICAgICAgICAgICAgX3RoaXMuYWN0aXZlID0gZmFsc2U7CiAgICAgICAgICAgIF90aGlzLm9uLmVycm9yLmZpcmUoZSk7CiAgICAgICAgICAgIF90aGlzLnBhcmVudCA/CiAgICAgICAgICAgICAgICBfdGhpcy5wYXJlbnQuX3JlamVjdChlKSA6CiAgICAgICAgICAgICAgICB3YXNBY3RpdmUgJiYgX3RoaXMuaWRidHJhbnMgJiYgX3RoaXMuaWRidHJhbnMuYWJvcnQoKTsKICAgICAgICAgICAgcmV0dXJuIHJlamVjdGlvbihlKTsgLy8gSW5kaWNhdGUgd2UgYWN0dWFsbHkgRE8gTk9UIGNhdGNoIHRoaXMgZXJyb3IuCiAgICAgICAgfSk7CiAgICB9CiAgICBwcm9wcyhUcmFuc2FjdGlvbi5wcm90b3R5cGUsIHsKICAgICAgICAvLwogICAgICAgIC8vIFRyYW5zYWN0aW9uIFByb3RlY3RlZCBNZXRob2RzIChub3QgcmVxdWlyZWQgYnkgQVBJIHVzZXJzLCBidXQgbmVlZGVkIGludGVybmFsbHkgYW5kIGV2ZW50dWFsbHkgYnkgZGV4aWUgZXh0ZW5zaW9ucykKICAgICAgICAvLwogICAgICAgIF9sb2NrOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGFzc2VydCghUFNELmdsb2JhbCk7IC8vIExvY2tpbmcgYW5kIHVubG9ja2luZyByZXVpcmVzIHRvIGJlIHdpdGhpbiBhIFBTRCBzY29wZS4KICAgICAgICAgICAgLy8gVGVtcG9yYXJ5IHNldCBhbGwgcmVxdWVzdHMgaW50byBhIHBlbmRpbmcgcXVldWUgaWYgdGhleSBhcmUgY2FsbGVkIGJlZm9yZSBkYXRhYmFzZSBpcyByZWFkeS4KICAgICAgICAgICAgKyt0aGlzLl9yZWN1bG9jazsgLy8gUmVjdXJzaXZlIHJlYWQvd3JpdGUgbG9jayBwYXR0ZXJuIHVzaW5nIFBTRCAoUHJvbWlzZSBTcGVjaWZpYyBEYXRhKSBpbnN0ZWFkIG9mIFRMUyAoVGhyZWFkIExvY2FsIFN0b3JhZ2UpCiAgICAgICAgICAgIGlmICh0aGlzLl9yZWN1bG9jayA9PT0gMSAmJiAhUFNELmdsb2JhbCkKICAgICAgICAgICAgICAgIFBTRC5sb2NrT3duZXJGb3IgPSB0aGlzOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9LAogICAgICAgIF91bmxvY2s6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgYXNzZXJ0KCFQU0QuZ2xvYmFsKTsgLy8gTG9ja2luZyBhbmQgdW5sb2NraW5nIHJldWlyZXMgdG8gYmUgd2l0aGluIGEgUFNEIHNjb3BlLgogICAgICAgICAgICBpZiAoLS10aGlzLl9yZWN1bG9jayA9PT0gMCkgewogICAgICAgICAgICAgICAgaWYgKCFQU0QuZ2xvYmFsKQogICAgICAgICAgICAgICAgICAgIFBTRC5sb2NrT3duZXJGb3IgPSBudWxsOwogICAgICAgICAgICAgICAgd2hpbGUgKHRoaXMuX2Jsb2NrZWRGdW5jcy5sZW5ndGggPiAwICYmICF0aGlzLl9sb2NrZWQoKSkgewogICAgICAgICAgICAgICAgICAgIHZhciBmbkFuZFBTRCA9IHRoaXMuX2Jsb2NrZWRGdW5jcy5zaGlmdCgpOwogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHVzZVBTRChmbkFuZFBTRFsxXSwgZm5BbmRQU0RbMF0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjYXRjaCAoZSkgeyB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfSwKICAgICAgICBfbG9ja2VkOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIC8vIENoZWNrcyBpZiBhbnkgd3JpdGUtbG9jayBpcyBhcHBsaWVkIG9uIHRoaXMgdHJhbnNhY3Rpb24uCiAgICAgICAgICAgIC8vIFRvIHNpbXBsaWZ5IHRoZSBEZXhpZSBBUEkgZm9yIGV4dGVuc2lvbiBpbXBsZW1lbnRhdGlvbnMsIHdlIHN1cHBvcnQgcmVjdXJzaXZlIGxvY2tzLgogICAgICAgICAgICAvLyBUaGlzIGlzIGFjY29tcGxpc2hlZCBieSB1c2luZyAiUHJvbWlzZSBTcGVjaWZpYyBEYXRhIiAoUFNEKS4KICAgICAgICAgICAgLy8gUFNEIGRhdGEgaXMgYm91bmQgdG8gYSBQcm9taXNlIGFuZCBhbnkgY2hpbGQgUHJvbWlzZSBlbWl0dGVkIHRocm91Z2ggdGhlbigpIG9yIHJlc29sdmUoIG5ldyBQcm9taXNlKCkgKS4KICAgICAgICAgICAgLy8gUFNEIGlzIGxvY2FsIHRvIGNvZGUgZXhlY3V0aW5nIG9uIHRvcCBvZiB0aGUgY2FsbCBzdGFja3Mgb2YgYW55IG9mIGFueSBjb2RlIGV4ZWN1dGVkIGJ5IFByb21pc2UoKToKICAgICAgICAgICAgLy8gICAgICAgICAqIGNhbGxiYWNrIGdpdmVuIHRvIHRoZSBQcm9taXNlKCkgY29uc3RydWN0b3IgIChmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KXsuLi59KQogICAgICAgICAgICAvLyAgICAgICAgICogY2FsbGJhY2tzIGdpdmVuIHRvIHRoZW4oKS9jYXRjaCgpL2ZpbmFsbHkoKSBtZXRob2RzIChmdW5jdGlvbiAodmFsdWUpey4uLn0pCiAgICAgICAgICAgIC8vIElmIGNyZWF0aW5nIGEgbmV3IGluZGVwZW5kYW50IFByb21pc2UgaW5zdGFuY2UgZnJvbSB3aXRoaW4gYSBQcm9taXNlIGNhbGwgc3RhY2ssIHRoZSBuZXcgUHJvbWlzZSB3aWxsIGRlcml2ZSB0aGUgUFNEIGZyb20gdGhlIGNhbGwgc3RhY2sgb2YgdGhlIHBhcmVudCBQcm9taXNlLgogICAgICAgICAgICAvLyBEZXJpdmF0aW9uIGlzIGRvbmUgc28gdGhhdCB0aGUgaW5uZXIgUFNEIF9fcHJvdG9fXyBwb2ludHMgdG8gdGhlIG91dGVyIFBTRC4KICAgICAgICAgICAgLy8gUFNELmxvY2tPd25lckZvciB3aWxsIHBvaW50IHRvIGN1cnJlbnQgdHJhbnNhY3Rpb24gb2JqZWN0IGlmIHRoZSBjdXJyZW50bHkgZXhlY3V0aW5nIFBTRCBzY29wZSBvd25zIHRoZSBsb2NrLgogICAgICAgICAgICByZXR1cm4gdGhpcy5fcmVjdWxvY2sgJiYgUFNELmxvY2tPd25lckZvciAhPT0gdGhpczsKICAgICAgICB9LAogICAgICAgIGNyZWF0ZTogZnVuY3Rpb24gKGlkYnRyYW5zKSB7CiAgICAgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7CiAgICAgICAgICAgIGlmICghdGhpcy5tb2RlKQogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIGFzc2VydCghdGhpcy5pZGJ0cmFucyk7CiAgICAgICAgICAgIGlmICghaWRidHJhbnMgJiYgIWlkYmRiKSB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKGRiT3BlbkVycm9yICYmIGRiT3BlbkVycm9yLm5hbWUpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICJEYXRhYmFzZUNsb3NlZEVycm9yIjoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gRXJyb3JzIHdoZXJlIGl0IGlzIG5vIGRpZmZlcmVuY2Ugd2hldGhlciBpdCB3YXMgY2F1c2VkIGJ5IHRoZSB1c2VyIG9wZXJhdGlvbiBvciBhbiBlYXJsaWVyIGNhbGwgdG8gZGIub3BlbigpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBleGNlcHRpb25zLkRhdGFiYXNlQ2xvc2VkKGRiT3BlbkVycm9yKTsKICAgICAgICAgICAgICAgICAgICBjYXNlICJNaXNzaW5nQVBJRXJyb3IiOgogICAgICAgICAgICAgICAgICAgICAgICAvLyBFcnJvcnMgd2hlcmUgaXQgaXMgbm8gZGlmZmVyZW5jZSB3aGV0aGVyIGl0IHdhcyBjYXVzZWQgYnkgdGhlIHVzZXIgb3BlcmF0aW9uIG9yIGFuIGVhcmxpZXIgY2FsbCB0byBkYi5vcGVuKCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IGV4Y2VwdGlvbnMuTWlzc2luZ0FQSShkYk9wZW5FcnJvci5tZXNzYWdlLCBkYk9wZW5FcnJvcik7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWFrZSBpdCBjbGVhciB0aGF0IHRoZSB1c2VyIG9wZXJhdGlvbiB3YXMgbm90IHdoYXQgY2F1c2VkIHRoZSBlcnJvciAtIHRoZSBlcnJvciBoYWQgb2NjdXJyZWQgZWFybGllciBvbiBkYi5vcGVuKCkhCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBleGNlcHRpb25zLk9wZW5GYWlsZWQoZGJPcGVuRXJyb3IpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghdGhpcy5hY3RpdmUpCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgZXhjZXB0aW9ucy5UcmFuc2FjdGlvbkluYWN0aXZlKCk7CiAgICAgICAgICAgIGFzc2VydCh0aGlzLl9jb21wbGV0aW9uLl9zdGF0ZSA9PT0gbnVsbCk7CiAgICAgICAgICAgIGlkYnRyYW5zID0gdGhpcy5pZGJ0cmFucyA9IGlkYnRyYW5zIHx8IGlkYmRiLnRyYW5zYWN0aW9uKHNhZmFyaU11bHRpU3RvcmVGaXgodGhpcy5zdG9yZU5hbWVzKSwgdGhpcy5tb2RlKTsKICAgICAgICAgICAgaWRidHJhbnMub25lcnJvciA9IHdyYXAoZnVuY3Rpb24gKGV2KSB7CiAgICAgICAgICAgICAgICBwcmV2ZW50RGVmYXVsdChldik7IC8vIFByb2hpYml0IGRlZmF1bHQgYnViYmxpbmcgdG8gd2luZG93LmVycm9yCiAgICAgICAgICAgICAgICBfdGhpcy5fcmVqZWN0KGlkYnRyYW5zLmVycm9yKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGlkYnRyYW5zLm9uYWJvcnQgPSB3cmFwKGZ1bmN0aW9uIChldikgewogICAgICAgICAgICAgICAgcHJldmVudERlZmF1bHQoZXYpOwogICAgICAgICAgICAgICAgX3RoaXMuYWN0aXZlICYmIF90aGlzLl9yZWplY3QobmV3IGV4Y2VwdGlvbnMuQWJvcnQoaWRidHJhbnMuZXJyb3IpKTsKICAgICAgICAgICAgICAgIF90aGlzLmFjdGl2ZSA9IGZhbHNlOwogICAgICAgICAgICAgICAgX3RoaXMub24oImFib3J0IikuZmlyZShldik7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBpZGJ0cmFucy5vbmNvbXBsZXRlID0gd3JhcChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICBfdGhpcy5hY3RpdmUgPSBmYWxzZTsKICAgICAgICAgICAgICAgIF90aGlzLl9yZXNvbHZlKCk7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9LAogICAgICAgIF9wcm9taXNlOiBmdW5jdGlvbiAobW9kZSwgZm4sIGJXcml0ZUxvY2spIHsKICAgICAgICAgICAgdmFyIF90aGlzID0gdGhpczsKICAgICAgICAgICAgaWYgKG1vZGUgPT09IFJFQURXUklURSAmJiB0aGlzLm1vZGUgIT09IFJFQURXUklURSkKICAgICAgICAgICAgICAgIHJldHVybiByZWplY3Rpb24obmV3IGV4Y2VwdGlvbnMuUmVhZE9ubHkoIlRyYW5zYWN0aW9uIGlzIHJlYWRvbmx5IikpOwogICAgICAgICAgICBpZiAoIXRoaXMuYWN0aXZlKQogICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdGlvbihuZXcgZXhjZXB0aW9ucy5UcmFuc2FjdGlvbkluYWN0aXZlKCkpOwogICAgICAgICAgICBpZiAodGhpcy5fbG9ja2VkKCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7CiAgICAgICAgICAgICAgICAgICAgX3RoaXMuX2Jsb2NrZWRGdW5jcy5wdXNoKFtmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5fcHJvbWlzZShtb2RlLCBmbiwgYldyaXRlTG9jaykudGhlbihyZXNvbHZlLCByZWplY3QpOwogICAgICAgICAgICAgICAgICAgICAgICB9LCBQU0RdKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKGJXcml0ZUxvY2spIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXdTY29wZShmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHAgPSBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLl9sb2NrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBydiA9IGZuKHJlc29sdmUsIHJlamVjdCwgX3RoaXMpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAocnYgJiYgcnYudGhlbikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ2LnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICBwLmZpbmFsbHkoZnVuY3Rpb24gKCkgeyByZXR1cm4gX3RoaXMuX3VubG9jaygpOyB9KTsKICAgICAgICAgICAgICAgICAgICBwLl9saWIgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBwOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICB2YXIgcCA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgcnYgPSBmbihyZXNvbHZlLCByZWplY3QsIF90aGlzKTsKICAgICAgICAgICAgICAgICAgICBpZiAocnYgJiYgcnYudGhlbikKICAgICAgICAgICAgICAgICAgICAgICAgcnYudGhlbihyZXNvbHZlLCByZWplY3QpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBwLl9saWIgPSB0cnVlOwogICAgICAgICAgICAgICAgcmV0dXJuIHA7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIF9yb290OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnBhcmVudCA/IHRoaXMucGFyZW50Ll9yb290KCkgOiB0aGlzOwogICAgICAgIH0sCiAgICAgICAgd2FpdEZvcjogZnVuY3Rpb24gKHByb21pc2UpIHsKICAgICAgICAgICAgLy8gQWx3YXlzIG9wZXJhdGUgb24gdGhlIHJvb3QgdHJhbnNhY3Rpb24gKGluIGNhc2UgdGhpcyBpcyBhIHN1YiBzdHJhbnNhY3Rpb24pCiAgICAgICAgICAgIHZhciByb290ID0gdGhpcy5fcm9vdCgpOwogICAgICAgICAgICAvLyBGb3Igc3RhYmlsaXR5IHJlYXNvbnMsIGNvbnZlcnQgcGFyYW1ldGVyIHRvIHByb21pc2Ugbm8gbWF0dGVyIHdoYXQgdHlwZSBpcyBwYXNzZWQgdG8gd2FpdEZvcigpLgogICAgICAgICAgICAvLyAoV2UgbXVzdCBiZSBhYmxlIHRvIGNhbGwgLnRoZW4oKSBvbiBpdC4pCiAgICAgICAgICAgIHByb21pc2UgPSBQcm9taXNlLnJlc29sdmUocHJvbWlzZSk7CiAgICAgICAgICAgIGlmIChyb290Ll93YWl0aW5nRm9yKSB7CiAgICAgICAgICAgICAgICAvLyBBbHJlYWR5IGNhbGxlZCB3YWl0Rm9yKCkuIFdhaXQgZm9yIGJvdGggdG8gY29tcGxldGUuCiAgICAgICAgICAgICAgICByb290Ll93YWl0aW5nRm9yID0gcm9vdC5fd2FpdGluZ0Zvci50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHByb21pc2U7IH0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgLy8gV2UncmUgbm90IGluIHdhaXRpbmcgc3RhdGUuIFN0YXJ0IHdhaXRpbmcgc3RhdGUuCiAgICAgICAgICAgICAgICByb290Ll93YWl0aW5nRm9yID0gcHJvbWlzZTsKICAgICAgICAgICAgICAgIHJvb3QuX3dhaXRpbmdRdWV1ZSA9IFtdOwogICAgICAgICAgICAgICAgLy8gU3RhcnQgaW50ZXJhY3Rpbmcgd2l0aCBpbmRleGVkREIgdW50aWwgcHJvbWlzZSBjb21wbGV0ZXM6CiAgICAgICAgICAgICAgICB2YXIgc3RvcmUgPSByb290LmlkYnRyYW5zLm9iamVjdFN0b3JlKHJvb3Quc3RvcmVOYW1lc1swXSk7CiAgICAgICAgICAgICAgICAoZnVuY3Rpb24gc3BpbigpIHsKICAgICAgICAgICAgICAgICAgICArK3Jvb3QuX3NwaW5Db3VudDsgLy8gRm9yIGRlYnVnZ2luZyBvbmx5CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHJvb3QuX3dhaXRpbmdRdWV1ZS5sZW5ndGgpCiAgICAgICAgICAgICAgICAgICAgICAgIChyb290Ll93YWl0aW5nUXVldWUuc2hpZnQoKSkoKTsKICAgICAgICAgICAgICAgICAgICBpZiAocm9vdC5fd2FpdGluZ0ZvcikKICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmUuZ2V0KC1JbmZpbml0eSkub25zdWNjZXNzID0gc3BpbjsKICAgICAgICAgICAgICAgIH0oKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIGN1cnJlbnRXYWl0UHJvbWlzZSA9IHJvb3QuX3dhaXRpbmdGb3I7CiAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7CiAgICAgICAgICAgICAgICBwcm9taXNlLnRoZW4oZnVuY3Rpb24gKHJlcykgeyByZXR1cm4gcm9vdC5fd2FpdGluZ1F1ZXVlLnB1c2god3JhcChyZXNvbHZlLmJpbmQobnVsbCwgcmVzKSkpOyB9LCBmdW5jdGlvbiAoZXJyKSB7IHJldHVybiByb290Ll93YWl0aW5nUXVldWUucHVzaCh3cmFwKHJlamVjdC5iaW5kKG51bGwsIGVycikpKTsgfSkuZmluYWxseShmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJvb3QuX3dhaXRpbmdGb3IgPT09IGN1cnJlbnRXYWl0UHJvbWlzZSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBObyBvbmUgYWRkZWQgYSB3YWl0IGFmdGVyIHVzLiBTYWZlIHRvIHN0b3AgdGhlIHNwaW5uaW5nLgogICAgICAgICAgICAgICAgICAgICAgICByb290Ll93YWl0aW5nRm9yID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfSwKICAgICAgICAvLwogICAgICAgIC8vIFRyYW5zYWN0aW9uIFB1YmxpYyBQcm9wZXJ0aWVzIGFuZCBNZXRob2RzCiAgICAgICAgLy8KICAgICAgICBhYm9ydDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLmFjdGl2ZSAmJiB0aGlzLl9yZWplY3QobmV3IGV4Y2VwdGlvbnMuQWJvcnQoKSk7CiAgICAgICAgICAgIHRoaXMuYWN0aXZlID0gZmFsc2U7CiAgICAgICAgfSwKICAgICAgICB0YWJsZXM6IHsKICAgICAgICAgICAgZ2V0OiBkZXByZWNhdGVkKCJUcmFuc2FjdGlvbi50YWJsZXMiLCBmdW5jdGlvbiAoKSB7IHJldHVybiBhbGxUYWJsZXM7IH0pCiAgICAgICAgfSwKICAgICAgICB0YWJsZTogZnVuY3Rpb24gKG5hbWUpIHsKICAgICAgICAgICAgdmFyIHRhYmxlID0gZGIudGFibGUobmFtZSk7IC8vIERvbid0IGNoZWNrIHRoYXQgdGFibGUgaXMgcGFydCBvZiB0cmFuc2FjdGlvbi4gSXQgbXVzdCBmYWlsIGxhemlseSEKICAgICAgICAgICAgcmV0dXJuIG5ldyBUYWJsZShuYW1lLCB0YWJsZS5zY2hlbWEsIHRoaXMpOwogICAgICAgIH0KICAgIH0pOwogICAgLy8KICAgIC8vCiAgICAvLwogICAgLy8gV2hlcmVDbGF1c2UKICAgIC8vCiAgICAvLwogICAgLy8KICAgIGZ1bmN0aW9uIFdoZXJlQ2xhdXNlKHRhYmxlLCBpbmRleCwgb3JDb2xsZWN0aW9uKSB7CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJ0YWJsZSIgdHlwZT0iVGFibGUiPjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJpbmRleCIgdHlwZT0iU3RyaW5nIiBvcHRpb25hbD0idHJ1ZSI+PC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im9yQ29sbGVjdGlvbiIgdHlwZT0iQ29sbGVjdGlvbiIgb3B0aW9uYWw9InRydWUiPjwvcGFyYW0+CiAgICAgICAgdGhpcy5fY3R4ID0gewogICAgICAgICAgICB0YWJsZTogdGFibGUsCiAgICAgICAgICAgIGluZGV4OiBpbmRleCA9PT0gIjppZCIgPyBudWxsIDogaW5kZXgsCiAgICAgICAgICAgIG9yOiBvckNvbGxlY3Rpb24KICAgICAgICB9OwogICAgfQogICAgcHJvcHMoV2hlcmVDbGF1c2UucHJvdG90eXBlLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgLy8gV2hlcmVDbGF1c2UgcHJpdmF0ZSBtZXRob2RzCiAgICAgICAgZnVuY3Rpb24gZmFpbChjb2xsZWN0aW9uT3JXaGVyZUNsYXVzZSwgZXJyLCBUKSB7CiAgICAgICAgICAgIHZhciBjb2xsZWN0aW9uID0gY29sbGVjdGlvbk9yV2hlcmVDbGF1c2UgaW5zdGFuY2VvZiBXaGVyZUNsYXVzZSA/CiAgICAgICAgICAgICAgICBuZXcgQ29sbGVjdGlvbihjb2xsZWN0aW9uT3JXaGVyZUNsYXVzZSkgOgogICAgICAgICAgICAgICAgY29sbGVjdGlvbk9yV2hlcmVDbGF1c2U7CiAgICAgICAgICAgIGNvbGxlY3Rpb24uX2N0eC5lcnJvciA9IFQgPyBuZXcgVChlcnIpIDogbmV3IFR5cGVFcnJvcihlcnIpOwogICAgICAgICAgICByZXR1cm4gY29sbGVjdGlvbjsKICAgICAgICB9CiAgICAgICAgZnVuY3Rpb24gZW1wdHlDb2xsZWN0aW9uKHdoZXJlQ2xhdXNlKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgQ29sbGVjdGlvbih3aGVyZUNsYXVzZSwgZnVuY3Rpb24gKCkgeyByZXR1cm4gSURCS2V5UmFuZ2Uub25seSgiIik7IH0pLmxpbWl0KDApOwogICAgICAgIH0KICAgICAgICBmdW5jdGlvbiB1cHBlckZhY3RvcnkoZGlyKSB7CiAgICAgICAgICAgIHJldHVybiBkaXIgPT09ICJuZXh0IiA/IGZ1bmN0aW9uIChzKSB7IHJldHVybiBzLnRvVXBwZXJDYXNlKCk7IH0gOiBmdW5jdGlvbiAocykgeyByZXR1cm4gcy50b0xvd2VyQ2FzZSgpOyB9OwogICAgICAgIH0KICAgICAgICBmdW5jdGlvbiBsb3dlckZhY3RvcnkoZGlyKSB7CiAgICAgICAgICAgIHJldHVybiBkaXIgPT09ICJuZXh0IiA/IGZ1bmN0aW9uIChzKSB7IHJldHVybiBzLnRvTG93ZXJDYXNlKCk7IH0gOiBmdW5jdGlvbiAocykgeyByZXR1cm4gcy50b1VwcGVyQ2FzZSgpOyB9OwogICAgICAgIH0KICAgICAgICBmdW5jdGlvbiBuZXh0Q2FzaW5nKGtleSwgbG93ZXJLZXksIHVwcGVyTmVlZGxlLCBsb3dlck5lZWRsZSwgY21wLCBkaXIpIHsKICAgICAgICAgICAgdmFyIGxlbmd0aCA9IE1hdGgubWluKGtleS5sZW5ndGgsIGxvd2VyTmVlZGxlLmxlbmd0aCk7CiAgICAgICAgICAgIHZhciBsbHAgPSAtMTsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkgewogICAgICAgICAgICAgICAgdmFyIGx3cktleUNoYXIgPSBsb3dlcktleVtpXTsKICAgICAgICAgICAgICAgIGlmIChsd3JLZXlDaGFyICE9PSBsb3dlck5lZWRsZVtpXSkgewogICAgICAgICAgICAgICAgICAgIGlmIChjbXAoa2V5W2ldLCB1cHBlck5lZWRsZVtpXSkgPCAwKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ga2V5LnN1YnN0cigwLCBpKSArIHVwcGVyTmVlZGxlW2ldICsgdXBwZXJOZWVkbGUuc3Vic3RyKGkgKyAxKTsKICAgICAgICAgICAgICAgICAgICBpZiAoY21wKGtleVtpXSwgbG93ZXJOZWVkbGVbaV0pIDwgMCkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGtleS5zdWJzdHIoMCwgaSkgKyBsb3dlck5lZWRsZVtpXSArIHVwcGVyTmVlZGxlLnN1YnN0cihpICsgMSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGxscCA+PSAwKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ga2V5LnN1YnN0cigwLCBsbHApICsgbG93ZXJLZXlbbGxwXSArIHVwcGVyTmVlZGxlLnN1YnN0cihsbHAgKyAxKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChjbXAoa2V5W2ldLCBsd3JLZXlDaGFyKSA8IDApCiAgICAgICAgICAgICAgICAgICAgbGxwID0gaTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobGVuZ3RoIDwgbG93ZXJOZWVkbGUubGVuZ3RoICYmIGRpciA9PT0gIm5leHQiKQogICAgICAgICAgICAgICAgcmV0dXJuIGtleSArIHVwcGVyTmVlZGxlLnN1YnN0cihrZXkubGVuZ3RoKTsKICAgICAgICAgICAgaWYgKGxlbmd0aCA8IGtleS5sZW5ndGggJiYgZGlyID09PSAicHJldiIpCiAgICAgICAgICAgICAgICByZXR1cm4ga2V5LnN1YnN0cigwLCB1cHBlck5lZWRsZS5sZW5ndGgpOwogICAgICAgICAgICByZXR1cm4gKGxscCA8IDAgPyBudWxsIDoga2V5LnN1YnN0cigwLCBsbHApICsgbG93ZXJOZWVkbGVbbGxwXSArIHVwcGVyTmVlZGxlLnN1YnN0cihsbHAgKyAxKSk7CiAgICAgICAgfQogICAgICAgIGZ1bmN0aW9uIGFkZElnbm9yZUNhc2VBbGdvcml0aG0od2hlcmVDbGF1c2UsIG1hdGNoLCBuZWVkbGVzLCBzdWZmaXgpIHsKICAgICAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJuZWVkbGVzIiB0eXBlPSJBcnJheSIgZWxlbWVudFR5cGU9IlN0cmluZyI+PC9wYXJhbT4KICAgICAgICAgICAgdmFyIHVwcGVyLCBsb3dlciwgY29tcGFyZSwgdXBwZXJOZWVkbGVzLCBsb3dlck5lZWRsZXMsIGRpcmVjdGlvbiwgbmV4dEtleVN1ZmZpeCwgbmVlZGxlc0xlbiA9IG5lZWRsZXMubGVuZ3RoOwogICAgICAgICAgICBpZiAoIW5lZWRsZXMuZXZlcnkoZnVuY3Rpb24gKHMpIHsgcmV0dXJuIHR5cGVvZiBzID09PSAnc3RyaW5nJzsgfSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWlsKHdoZXJlQ2xhdXNlLCBTVFJJTkdfRVhQRUNURUQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZ1bmN0aW9uIGluaXREaXJlY3Rpb24oZGlyKSB7CiAgICAgICAgICAgICAgICB1cHBlciA9IHVwcGVyRmFjdG9yeShkaXIpOwogICAgICAgICAgICAgICAgbG93ZXIgPSBsb3dlckZhY3RvcnkoZGlyKTsKICAgICAgICAgICAgICAgIGNvbXBhcmUgPSAoZGlyID09PSAibmV4dCIgPyBzaW1wbGVDb21wYXJlIDogc2ltcGxlQ29tcGFyZVJldmVyc2UpOwogICAgICAgICAgICAgICAgdmFyIG5lZWRsZUJvdW5kcyA9IG5lZWRsZXMubWFwKGZ1bmN0aW9uIChuZWVkbGUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4geyBsb3dlcjogbG93ZXIobmVlZGxlKSwgdXBwZXI6IHVwcGVyKG5lZWRsZSkgfTsKICAgICAgICAgICAgICAgIH0pLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29tcGFyZShhLmxvd2VyLCBiLmxvd2VyKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgdXBwZXJOZWVkbGVzID0gbmVlZGxlQm91bmRzLm1hcChmdW5jdGlvbiAobmIpIHsgcmV0dXJuIG5iLnVwcGVyOyB9KTsKICAgICAgICAgICAgICAgIGxvd2VyTmVlZGxlcyA9IG5lZWRsZUJvdW5kcy5tYXAoZnVuY3Rpb24gKG5iKSB7IHJldHVybiBuYi5sb3dlcjsgfSk7CiAgICAgICAgICAgICAgICBkaXJlY3Rpb24gPSBkaXI7CiAgICAgICAgICAgICAgICBuZXh0S2V5U3VmZml4ID0gKGRpciA9PT0gIm5leHQiID8gIiIgOiBzdWZmaXgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGluaXREaXJlY3Rpb24oIm5leHQiKTsKICAgICAgICAgICAgdmFyIGMgPSBuZXcgQ29sbGVjdGlvbih3aGVyZUNsYXVzZSwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIElEQktleVJhbmdlLmJvdW5kKHVwcGVyTmVlZGxlc1swXSwgbG93ZXJOZWVkbGVzW25lZWRsZXNMZW4gLSAxXSArIHN1ZmZpeCk7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBjLl9vbmRpcmVjdGlvbmNoYW5nZSA9IGZ1bmN0aW9uIChkaXJlY3Rpb24pIHsKICAgICAgICAgICAgICAgIC8vIFRoaXMgZXZlbnQgb25seXMgb2NjdXIgYmVmb3JlIGZpbHRlciBpcyBjYWxsZWQgdGhlIGZpcnN0IHRpbWUuCiAgICAgICAgICAgICAgICBpbml0RGlyZWN0aW9uKGRpcmVjdGlvbik7CiAgICAgICAgICAgIH07CiAgICAgICAgICAgIHZhciBmaXJzdFBvc3NpYmxlTmVlZGxlID0gMDsKICAgICAgICAgICAgYy5fYWRkQWxnb3JpdGhtKGZ1bmN0aW9uIChjdXJzb3IsIGFkdmFuY2UsIHJlc29sdmUpIHsKICAgICAgICAgICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iY3Vyc29yIiB0eXBlPSJJREJDdXJzb3IiPjwvcGFyYW0+CiAgICAgICAgICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImFkdmFuY2UiIHR5cGU9IkZ1bmN0aW9uIj48L3BhcmFtPgogICAgICAgICAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJyZXNvbHZlIiB0eXBlPSJGdW5jdGlvbiI+PC9wYXJhbT4KICAgICAgICAgICAgICAgIHZhciBrZXkgPSBjdXJzb3Iua2V5OwogICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBrZXkgIT09ICdzdHJpbmcnKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIHZhciBsb3dlcktleSA9IGxvd2VyKGtleSk7CiAgICAgICAgICAgICAgICBpZiAobWF0Y2gobG93ZXJLZXksIGxvd2VyTmVlZGxlcywgZmlyc3RQb3NzaWJsZU5lZWRsZSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIHZhciBsb3dlc3RQb3NzaWJsZUNhc2luZyA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IGZpcnN0UG9zc2libGVOZWVkbGU7IGkgPCBuZWVkbGVzTGVuOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNhc2luZyA9IG5leHRDYXNpbmcoa2V5LCBsb3dlcktleSwgdXBwZXJOZWVkbGVzW2ldLCBsb3dlck5lZWRsZXNbaV0sIGNvbXBhcmUsIGRpcmVjdGlvbik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjYXNpbmcgPT09IG51bGwgJiYgbG93ZXN0UG9zc2libGVDYXNpbmcgPT09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaXJzdFBvc3NpYmxlTmVlZGxlID0gaSArIDE7CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGxvd2VzdFBvc3NpYmxlQ2FzaW5nID09PSBudWxsIHx8IGNvbXBhcmUobG93ZXN0UG9zc2libGVDYXNpbmcsIGNhc2luZykgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb3dlc3RQb3NzaWJsZUNhc2luZyA9IGNhc2luZzsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAobG93ZXN0UG9zc2libGVDYXNpbmcgIT09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYWR2YW5jZShmdW5jdGlvbiAoKSB7IGN1cnNvci5jb250aW51ZShsb3dlc3RQb3NzaWJsZUNhc2luZyArIG5leHRLZXlTdWZmaXgpOyB9KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFkdmFuY2UocmVzb2x2ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHJldHVybiBjOwogICAgICAgIH0KICAgICAgICAvLwogICAgICAgIC8vIFdoZXJlQ2xhdXNlIHB1YmxpYyBtZXRob2RzCiAgICAgICAgLy8KICAgICAgICByZXR1cm4gewogICAgICAgICAgICBiZXR3ZWVuOiBmdW5jdGlvbiAobG93ZXIsIHVwcGVyLCBpbmNsdWRlTG93ZXIsIGluY2x1ZGVVcHBlcikgewogICAgICAgICAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgICAgICAgICAgLy8vICAgICBGaWx0ZXIgb3V0IHJlY29yZHMgd2hvc2Ugd2hlcmUtZmllbGQgbGF5cyBiZXR3ZWVuIGdpdmVuIGxvd2VyIGFuZCB1cHBlciB2YWx1ZXMuIEFwcGxpZXMgdG8gU3RyaW5ncywgTnVtYmVycyBhbmQgRGF0ZXMuCiAgICAgICAgICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgICAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJsb3dlciI+PC9wYXJhbT4KICAgICAgICAgICAgICAgIC8vLyA8cGFyYW0gbmFtZT0idXBwZXIiPjwvcGFyYW0+CiAgICAgICAgICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImluY2x1ZGVMb3dlciIgb3B0aW9uYWw9InRydWUiPldoZXRoZXIgaXRlbXMgdGhhdCBlcXVhbHMgbG93ZXIgc2hvdWxkIGJlIGluY2x1ZGVkLiBEZWZhdWx0IHRydWUuPC9wYXJhbT4KICAgICAgICAgICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iaW5jbHVkZVVwcGVyIiBvcHRpb25hbD0idHJ1ZSI+V2hldGhlciBpdGVtcyB0aGF0IGVxdWFscyB1cHBlciBzaG91bGQgYmUgaW5jbHVkZWQuIERlZmF1bHQgZmFsc2UuPC9wYXJhbT4KICAgICAgICAgICAgICAgIC8vLyA8cmV0dXJucyB0eXBlPSJDb2xsZWN0aW9uIj48L3JldHVybnM+CiAgICAgICAgICAgICAgICBpbmNsdWRlTG93ZXIgPSBpbmNsdWRlTG93ZXIgIT09IGZhbHNlOyAvLyBEZWZhdWx0IHRvIHRydWUKICAgICAgICAgICAgICAgIGluY2x1ZGVVcHBlciA9IGluY2x1ZGVVcHBlciA9PT0gdHJ1ZTsgLy8gRGVmYXVsdCB0byBmYWxzZQogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBpZiAoKGNtcChsb3dlciwgdXBwZXIpID4gMCkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgKGNtcChsb3dlciwgdXBwZXIpID09PSAwICYmIChpbmNsdWRlTG93ZXIgfHwgaW5jbHVkZVVwcGVyKSAmJiAhKGluY2x1ZGVMb3dlciAmJiBpbmNsdWRlVXBwZXIpKSkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVtcHR5Q29sbGVjdGlvbih0aGlzKTsgLy8gV29ya2Fyb3VuZCBmb3IgaWRpb3RpYyBXM0MgU3BlY2lmaWNhdGlvbiB0aGF0IERhdGFFcnJvciBtdXN0IGJlIHRocm93biBpZiBsb3dlciA+IHVwcGVyLiBUaGUgbmF0dXJhbCByZXN1bHQgd291bGQgYmUgdG8gcmV0dXJuIGFuIGVtcHR5IGNvbGxlY3Rpb24uCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDb2xsZWN0aW9uKHRoaXMsIGZ1bmN0aW9uICgpIHsgcmV0dXJuIElEQktleVJhbmdlLmJvdW5kKGxvd2VyLCB1cHBlciwgIWluY2x1ZGVMb3dlciwgIWluY2x1ZGVVcHBlcik7IH0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFpbCh0aGlzLCBJTlZBTElEX0tFWV9BUkdVTUVOVCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGVxdWFsczogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IENvbGxlY3Rpb24odGhpcywgZnVuY3Rpb24gKCkgeyByZXR1cm4gSURCS2V5UmFuZ2Uub25seSh2YWx1ZSk7IH0pOwogICAgICAgICAgICB9LAogICAgICAgICAgICBhYm92ZTogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IENvbGxlY3Rpb24odGhpcywgZnVuY3Rpb24gKCkgeyByZXR1cm4gSURCS2V5UmFuZ2UubG93ZXJCb3VuZCh2YWx1ZSwgdHJ1ZSk7IH0pOwogICAgICAgICAgICB9LAogICAgICAgICAgICBhYm92ZU9yRXF1YWw6IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDb2xsZWN0aW9uKHRoaXMsIGZ1bmN0aW9uICgpIHsgcmV0dXJuIElEQktleVJhbmdlLmxvd2VyQm91bmQodmFsdWUpOyB9KTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgYmVsb3c6IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDb2xsZWN0aW9uKHRoaXMsIGZ1bmN0aW9uICgpIHsgcmV0dXJuIElEQktleVJhbmdlLnVwcGVyQm91bmQodmFsdWUsIHRydWUpOyB9KTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgYmVsb3dPckVxdWFsOiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQ29sbGVjdGlvbih0aGlzLCBmdW5jdGlvbiAoKSB7IHJldHVybiBJREJLZXlSYW5nZS51cHBlckJvdW5kKHZhbHVlKTsgfSk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHN0YXJ0c1dpdGg6IGZ1bmN0aW9uIChzdHIpIHsKICAgICAgICAgICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ic3RyIiB0eXBlPSJTdHJpbmciPjwvcGFyYW0+CiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHN0ciAhPT0gJ3N0cmluZycpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhaWwodGhpcywgU1RSSU5HX0VYUEVDVEVEKTsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmJldHdlZW4oc3RyLCBzdHIgKyBtYXhTdHJpbmcsIHRydWUsIHRydWUpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzdGFydHNXaXRoSWdub3JlQ2FzZTogZnVuY3Rpb24gKHN0cikgewogICAgICAgICAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJzdHIiIHR5cGU9IlN0cmluZyI+PC9wYXJhbT4KICAgICAgICAgICAgICAgIGlmIChzdHIgPT09ICIiKQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnN0YXJ0c1dpdGgoc3RyKTsKICAgICAgICAgICAgICAgIHJldHVybiBhZGRJZ25vcmVDYXNlQWxnb3JpdGhtKHRoaXMsIGZ1bmN0aW9uICh4LCBhKSB7IHJldHVybiB4LmluZGV4T2YoYVswXSkgPT09IDA7IH0sIFtzdHJdLCBtYXhTdHJpbmcpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBlcXVhbHNJZ25vcmVDYXNlOiBmdW5jdGlvbiAoc3RyKSB7CiAgICAgICAgICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InN0ciIgdHlwZT0iU3RyaW5nIj48L3BhcmFtPgogICAgICAgICAgICAgICAgcmV0dXJuIGFkZElnbm9yZUNhc2VBbGdvcml0aG0odGhpcywgZnVuY3Rpb24gKHgsIGEpIHsgcmV0dXJuIHggPT09IGFbMF07IH0sIFtzdHJdLCAiIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGFueU9mSWdub3JlQ2FzZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIHNldCA9IGdldEFycmF5T2YuYXBwbHkoTk9fQ0hBUl9BUlJBWSwgYXJndW1lbnRzKTsKICAgICAgICAgICAgICAgIGlmIChzZXQubGVuZ3RoID09PSAwKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBlbXB0eUNvbGxlY3Rpb24odGhpcyk7CiAgICAgICAgICAgICAgICByZXR1cm4gYWRkSWdub3JlQ2FzZUFsZ29yaXRobSh0aGlzLCBmdW5jdGlvbiAoeCwgYSkgeyByZXR1cm4gYS5pbmRleE9mKHgpICE9PSAtMTsgfSwgc2V0LCAiIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHN0YXJ0c1dpdGhBbnlPZklnbm9yZUNhc2U6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHZhciBzZXQgPSBnZXRBcnJheU9mLmFwcGx5KE5PX0NIQVJfQVJSQVksIGFyZ3VtZW50cyk7CiAgICAgICAgICAgICAgICBpZiAoc2V0Lmxlbmd0aCA9PT0gMCkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW1wdHlDb2xsZWN0aW9uKHRoaXMpOwogICAgICAgICAgICAgICAgcmV0dXJuIGFkZElnbm9yZUNhc2VBbGdvcml0aG0odGhpcywgZnVuY3Rpb24gKHgsIGEpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gYS5zb21lKGZ1bmN0aW9uIChuKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB4LmluZGV4T2YobikgPT09IDA7CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB9LCBzZXQsIG1heFN0cmluZyk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGFueU9mOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgc2V0ID0gZ2V0QXJyYXlPZi5hcHBseShOT19DSEFSX0FSUkFZLCBhcmd1bWVudHMpOwogICAgICAgICAgICAgICAgdmFyIGNvbXBhcmUgPSBhc2NlbmRpbmc7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHNldC5zb3J0KGNvbXBhcmUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFpbCh0aGlzLCBJTlZBTElEX0tFWV9BUkdVTUVOVCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoc2V0Lmxlbmd0aCA9PT0gMCkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW1wdHlDb2xsZWN0aW9uKHRoaXMpOwogICAgICAgICAgICAgICAgdmFyIGMgPSBuZXcgQ29sbGVjdGlvbih0aGlzLCBmdW5jdGlvbiAoKSB7IHJldHVybiBJREJLZXlSYW5nZS5ib3VuZChzZXRbMF0sIHNldFtzZXQubGVuZ3RoIC0gMV0pOyB9KTsKICAgICAgICAgICAgICAgIGMuX29uZGlyZWN0aW9uY2hhbmdlID0gZnVuY3Rpb24gKGRpcmVjdGlvbikgewogICAgICAgICAgICAgICAgICAgIGNvbXBhcmUgPSAoZGlyZWN0aW9uID09PSAibmV4dCIgPyBhc2NlbmRpbmcgOiBkZXNjZW5kaW5nKTsKICAgICAgICAgICAgICAgICAgICBzZXQuc29ydChjb21wYXJlKTsKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICB2YXIgaSA9IDA7CiAgICAgICAgICAgICAgICBjLl9hZGRBbGdvcml0aG0oZnVuY3Rpb24gKGN1cnNvciwgYWR2YW5jZSwgcmVzb2x2ZSkgewogICAgICAgICAgICAgICAgICAgIHZhciBrZXkgPSBjdXJzb3Iua2V5OwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChjb21wYXJlKGtleSwgc2V0W2ldKSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGN1cnNvciBoYXMgcGFzc2VkIGJleW9uZCB0aGlzIGtleS4gQ2hlY2sgbmV4dC4KICAgICAgICAgICAgICAgICAgICAgICAgKytpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PT0gc2V0Lmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlcmUgaXMgbm8gbmV4dC4gU3RvcCBzZWFyY2hpbmcuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZHZhbmNlKHJlc29sdmUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChjb21wYXJlKGtleSwgc2V0W2ldKSA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGUgY3VycmVudCBjdXJzb3IgdmFsdWUgc2hvdWxkIGJlIGluY2x1ZGVkIGFuZCB3ZSBzaG91bGQgY29udGludWUgYSBzaW5nbGUgc3RlcCBpbiBjYXNlIG5leHQgaXRlbSBoYXMgdGhlIHNhbWUga2V5IG9yIHBvc3NpYmx5IG91ciBuZXh0IGtleSBpbiBzZXQuCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gY3Vyc29yLmtleSBub3QgeWV0IGF0IHNldFtpXS4gRm9yd2FyZCBjdXJzb3IgdG8gdGhlIG5leHQga2V5IHRvIGh1bnQgZm9yLgogICAgICAgICAgICAgICAgICAgICAgICBhZHZhbmNlKGZ1bmN0aW9uICgpIHsgY3Vyc29yLmNvbnRpbnVlKHNldFtpXSk7IH0pOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICByZXR1cm4gYzsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgbm90RXF1YWw6IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW5BbnlSYW5nZShbW21pbktleSwgdmFsdWVdLCBbdmFsdWUsIG1heEtleV1dLCB7IGluY2x1ZGVMb3dlcnM6IGZhbHNlLCBpbmNsdWRlVXBwZXJzOiBmYWxzZSB9KTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgbm9uZU9mOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgc2V0ID0gZ2V0QXJyYXlPZi5hcHBseShOT19DSEFSX0FSUkFZLCBhcmd1bWVudHMpOwogICAgICAgICAgICAgICAgaWYgKHNldC5sZW5ndGggPT09IDApCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDb2xsZWN0aW9uKHRoaXMpOyAvLyBSZXR1cm4gZW50aXJlIGNvbGxlY3Rpb24uCiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHNldC5zb3J0KGFzY2VuZGluZyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWlsKHRoaXMsIElOVkFMSURfS0VZX0FSR1VNRU5UKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIFRyYW5zZm9ybSBbImEiLCJiIiwiYyJdIHRvIGEgc2V0IG9mIHJhbmdlcyBmb3IgYmV0d2Vlbi9hYm92ZS9iZWxvdzogW1ttaW5LZXksImEiXSwgWyJhIiwiYiJdLCBbImIiLCJjIl0sIFsiYyIsbWF4S2V5XV0KICAgICAgICAgICAgICAgIHZhciByYW5nZXMgPSBzZXQucmVkdWNlKGZ1bmN0aW9uIChyZXMsIHZhbCkgeyByZXR1cm4gcmVzID8gcmVzLmNvbmNhdChbW3Jlc1tyZXMubGVuZ3RoIC0gMV1bMV0sIHZhbF1dKSA6IFtbbWluS2V5LCB2YWxdXTsgfSwgbnVsbCk7CiAgICAgICAgICAgICAgICByYW5nZXMucHVzaChbc2V0W3NldC5sZW5ndGggLSAxXSwgbWF4S2V5XSk7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5pbkFueVJhbmdlKHJhbmdlcywgeyBpbmNsdWRlTG93ZXJzOiBmYWxzZSwgaW5jbHVkZVVwcGVyczogZmFsc2UgfSk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKiBGaWx0ZXIgb3V0IHZhbHVlcyB3aXRoaW5nIGdpdmVuIHNldCBvZiByYW5nZXMuCiAgICAgICAgICAgICogRXhhbXBsZSwgZ2l2ZSBjaGlsZHJlbiBhbmQgZWxkZXJzIGEgcmViYXRlIG9mIDUwJToKICAgICAgICAgICAgKgogICAgICAgICAgICAqICAgZGIuZnJpZW5kcy53aGVyZSgnYWdlJykuaW5BbnlSYW5nZShbWzAsMThdLFs2NSxJbmZpbml0eV1dKS5tb2RpZnkoe1JlYmF0ZTogMS8yfSk7CiAgICAgICAgICAgICoKICAgICAgICAgICAgKiBAcGFyYW0geyhzdHJpbmd8bnVtYmVyfERhdGV8QXJyYXkpW11bXX0gcmFuZ2VzCiAgICAgICAgICAgICogQHBhcmFtIHt7aW5jbHVkZUxvd2VyczogYm9vbGVhbiwgaW5jbHVkZVVwcGVyczogYm9vbGVhbn19IG9wdGlvbnMKICAgICAgICAgICAgKi8KICAgICAgICAgICAgaW5BbnlSYW5nZTogZnVuY3Rpb24gKHJhbmdlcywgb3B0aW9ucykgewogICAgICAgICAgICAgICAgaWYgKHJhbmdlcy5sZW5ndGggPT09IDApCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVtcHR5Q29sbGVjdGlvbih0aGlzKTsKICAgICAgICAgICAgICAgIGlmICghcmFuZ2VzLmV2ZXJ5KGZ1bmN0aW9uIChyYW5nZSkgeyByZXR1cm4gcmFuZ2VbMF0gIT09IHVuZGVmaW5lZCAmJiByYW5nZVsxXSAhPT0gdW5kZWZpbmVkICYmIGFzY2VuZGluZyhyYW5nZVswXSwgcmFuZ2VbMV0pIDw9IDA7IH0pKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhaWwodGhpcywgIkZpcnN0IGFyZ3VtZW50IHRvIGluQW55UmFuZ2UoKSBtdXN0IGJlIGFuIEFycmF5IG9mIHR3by12YWx1ZSBBcnJheXMgW2xvd2VyLHVwcGVyXSB3aGVyZSB1cHBlciBtdXN0IG5vdCBiZSBsb3dlciB0aGFuIGxvd2VyIiwgZXhjZXB0aW9ucy5JbnZhbGlkQXJndW1lbnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIGluY2x1ZGVMb3dlcnMgPSAhb3B0aW9ucyB8fCBvcHRpb25zLmluY2x1ZGVMb3dlcnMgIT09IGZhbHNlOyAvLyBEZWZhdWx0IHRvIHRydWUKICAgICAgICAgICAgICAgIHZhciBpbmNsdWRlVXBwZXJzID0gb3B0aW9ucyAmJiBvcHRpb25zLmluY2x1ZGVVcHBlcnMgPT09IHRydWU7IC8vIERlZmF1bHQgdG8gZmFsc2UKICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGFkZFJhbmdlKHJhbmdlcywgbmV3UmFuZ2UpIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IHJhbmdlcy5sZW5ndGg7IGkgPCBsOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJhbmdlID0gcmFuZ2VzW2ldOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY21wKG5ld1JhbmdlWzBdLCByYW5nZVsxXSkgPCAwICYmIGNtcChuZXdSYW5nZVsxXSwgcmFuZ2VbMF0pID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2VbMF0gPSBtaW4ocmFuZ2VbMF0sIG5ld1JhbmdlWzBdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlWzFdID0gbWF4KHJhbmdlWzFdLCBuZXdSYW5nZVsxXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PT0gbCkKICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2VzLnB1c2gobmV3UmFuZ2UpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiByYW5nZXM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2YXIgc29ydERpcmVjdGlvbiA9IGFzY2VuZGluZzsKICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHJhbmdlU29ydGVyKGEsIGIpIHsgcmV0dXJuIHNvcnREaXJlY3Rpb24oYVswXSwgYlswXSk7IH0KICAgICAgICAgICAgICAgIC8vIEpvaW4gb3ZlcmxhcHBpbmcgcmFuZ2VzCiAgICAgICAgICAgICAgICB2YXIgc2V0OwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBzZXQgPSByYW5nZXMucmVkdWNlKGFkZFJhbmdlLCBbXSk7CiAgICAgICAgICAgICAgICAgICAgc2V0LnNvcnQocmFuZ2VTb3J0ZXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY2F0Y2ggKGV4KSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhaWwodGhpcywgSU5WQUxJRF9LRVlfQVJHVU1FTlQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIGkgPSAwOwogICAgICAgICAgICAgICAgdmFyIGtleUlzQmV5b25kQ3VycmVudEVudHJ5ID0gaW5jbHVkZVVwcGVycyA/CiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKGtleSkgeyByZXR1cm4gYXNjZW5kaW5nKGtleSwgc2V0W2ldWzFdKSA+IDA7IH0gOgogICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGFzY2VuZGluZyhrZXksIHNldFtpXVsxXSkgPj0gMDsgfTsKICAgICAgICAgICAgICAgIHZhciBrZXlJc0JlZm9yZUN1cnJlbnRFbnRyeSA9IGluY2x1ZGVMb3dlcnMgPwogICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGRlc2NlbmRpbmcoa2V5LCBzZXRbaV1bMF0pID4gMDsgfSA6CiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKGtleSkgeyByZXR1cm4gZGVzY2VuZGluZyhrZXksIHNldFtpXVswXSkgPj0gMDsgfTsKICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGtleVdpdGhpbkN1cnJlbnRSYW5nZShrZXkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gIWtleUlzQmV5b25kQ3VycmVudEVudHJ5KGtleSkgJiYgIWtleUlzQmVmb3JlQ3VycmVudEVudHJ5KGtleSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2YXIgY2hlY2tLZXkgPSBrZXlJc0JleW9uZEN1cnJlbnRFbnRyeTsKICAgICAgICAgICAgICAgIHZhciBjID0gbmV3IENvbGxlY3Rpb24odGhpcywgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBJREJLZXlSYW5nZS5ib3VuZChzZXRbMF1bMF0sIHNldFtzZXQubGVuZ3RoIC0gMV1bMV0sICFpbmNsdWRlTG93ZXJzLCAhaW5jbHVkZVVwcGVycyk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIGMuX29uZGlyZWN0aW9uY2hhbmdlID0gZnVuY3Rpb24gKGRpcmVjdGlvbikgewogICAgICAgICAgICAgICAgICAgIGlmIChkaXJlY3Rpb24gPT09ICJuZXh0IikgewogICAgICAgICAgICAgICAgICAgICAgICBjaGVja0tleSA9IGtleUlzQmV5b25kQ3VycmVudEVudHJ5OwogICAgICAgICAgICAgICAgICAgICAgICBzb3J0RGlyZWN0aW9uID0gYXNjZW5kaW5nOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tLZXkgPSBrZXlJc0JlZm9yZUN1cnJlbnRFbnRyeTsKICAgICAgICAgICAgICAgICAgICAgICAgc29ydERpcmVjdGlvbiA9IGRlc2NlbmRpbmc7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHNldC5zb3J0KHJhbmdlU29ydGVyKTsKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICBjLl9hZGRBbGdvcml0aG0oZnVuY3Rpb24gKGN1cnNvciwgYWR2YW5jZSwgcmVzb2x2ZSkgewogICAgICAgICAgICAgICAgICAgIHZhciBrZXkgPSBjdXJzb3Iua2V5OwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChjaGVja0tleShrZXkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBjdXJzb3IgaGFzIHBhc3NlZCBiZXlvbmQgdGhpcyBrZXkuIENoZWNrIG5leHQuCiAgICAgICAgICAgICAgICAgICAgICAgICsraTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT09IHNldC5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZXJlIGlzIG5vIG5leHQuIFN0b3Agc2VhcmNoaW5nLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYWR2YW5jZShyZXNvbHZlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoa2V5V2l0aGluQ3VycmVudFJhbmdlKGtleSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGN1cnJlbnQgY3Vyc29yIHZhbHVlIHNob3VsZCBiZSBpbmNsdWRlZCBhbmQgd2Ugc2hvdWxkIGNvbnRpbnVlIGEgc2luZ2xlIHN0ZXAgaW4gY2FzZSBuZXh0IGl0ZW0gaGFzIHRoZSBzYW1lIGtleSBvciBwb3NzaWJseSBvdXIgbmV4dCBrZXkgaW4gc2V0LgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY21wKGtleSwgc2V0W2ldWzFdKSA9PT0gMCB8fCBjbXAoa2V5LCBzZXRbaV1bMF0pID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluY2x1ZGVVcHBlciBvciBpbmNsdWRlTG93ZXIgaXMgZmFsc2Ugc28ga2V5V2l0aGluQ3VycmVudFJhbmdlKCkgcmV0dXJucyBmYWxzZSBldmVuIHRob3VnaCB3ZSBhcmUgYXQgcmFuZ2UgYm9yZGVyLgogICAgICAgICAgICAgICAgICAgICAgICAvLyBDb250aW51ZSB0byBuZXh0IGtleSBidXQgZG9uJ3QgaW5jbHVkZSB0aGlzIG9uZS4KICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gY3Vyc29yLmtleSBub3QgeWV0IGF0IHNldFtpXS4gRm9yd2FyZCBjdXJzb3IgdG8gdGhlIG5leHQga2V5IHRvIGh1bnQgZm9yLgogICAgICAgICAgICAgICAgICAgICAgICBhZHZhbmNlKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzb3J0RGlyZWN0aW9uID09PSBhc2NlbmRpbmcpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3Vyc29yLmNvbnRpbnVlKHNldFtpXVswXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3Vyc29yLmNvbnRpbnVlKHNldFtpXVsxXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICByZXR1cm4gYzsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc3RhcnRzV2l0aEFueU9mOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgc2V0ID0gZ2V0QXJyYXlPZi5hcHBseShOT19DSEFSX0FSUkFZLCBhcmd1bWVudHMpOwogICAgICAgICAgICAgICAgaWYgKCFzZXQuZXZlcnkoZnVuY3Rpb24gKHMpIHsgcmV0dXJuIHR5cGVvZiBzID09PSAnc3RyaW5nJzsgfSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFpbCh0aGlzLCAic3RhcnRzV2l0aEFueU9mKCkgb25seSB3b3JrcyB3aXRoIHN0cmluZ3MiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChzZXQubGVuZ3RoID09PSAwKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBlbXB0eUNvbGxlY3Rpb24odGhpcyk7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5pbkFueVJhbmdlKHNldC5tYXAoZnVuY3Rpb24gKHN0cikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBbc3RyLCBzdHIgKyBtYXhTdHJpbmddOwogICAgICAgICAgICAgICAgfSkpOwogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgIH0pOwogICAgLy8KICAgIC8vCiAgICAvLwogICAgLy8gQ29sbGVjdGlvbiBDbGFzcwogICAgLy8KICAgIC8vCiAgICAvLwogICAgZnVuY3Rpb24gQ29sbGVjdGlvbih3aGVyZUNsYXVzZSwga2V5UmFuZ2VHZW5lcmF0b3IpIHsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9IndoZXJlQ2xhdXNlIiB0eXBlPSJXaGVyZUNsYXVzZSI+V2hlcmUgY2xhdXNlIGluc3RhbmNlPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImtleVJhbmdlR2VuZXJhdG9yIiB2YWx1ZT0iZnVuY3Rpb24oKXsgcmV0dXJuIElEQktleVJhbmdlLmJvdW5kKDAsMSk7fSIgb3B0aW9uYWw9InRydWUiPjwvcGFyYW0+CiAgICAgICAgdmFyIGtleVJhbmdlID0gbnVsbCwgZXJyb3IgPSBudWxsOwogICAgICAgIGlmIChrZXlSYW5nZUdlbmVyYXRvcikKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGtleVJhbmdlID0ga2V5UmFuZ2VHZW5lcmF0b3IoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjYXRjaCAoZXgpIHsKICAgICAgICAgICAgICAgIGVycm9yID0gZXg7CiAgICAgICAgICAgIH0KICAgICAgICB2YXIgd2hlcmVDdHggPSB3aGVyZUNsYXVzZS5fY3R4LCB0YWJsZSA9IHdoZXJlQ3R4LnRhYmxlOwogICAgICAgIHRoaXMuX2N0eCA9IHsKICAgICAgICAgICAgdGFibGU6IHRhYmxlLAogICAgICAgICAgICBpbmRleDogd2hlcmVDdHguaW5kZXgsCiAgICAgICAgICAgIGlzUHJpbUtleTogKCF3aGVyZUN0eC5pbmRleCB8fCAodGFibGUuc2NoZW1hLnByaW1LZXkua2V5UGF0aCAmJiB3aGVyZUN0eC5pbmRleCA9PT0gdGFibGUuc2NoZW1hLnByaW1LZXkubmFtZSkpLAogICAgICAgICAgICByYW5nZToga2V5UmFuZ2UsCiAgICAgICAgICAgIGtleXNPbmx5OiBmYWxzZSwKICAgICAgICAgICAgZGlyOiAibmV4dCIsCiAgICAgICAgICAgIHVuaXF1ZTogIiIsCiAgICAgICAgICAgIGFsZ29yaXRobTogbnVsbCwKICAgICAgICAgICAgZmlsdGVyOiBudWxsLAogICAgICAgICAgICByZXBsYXlGaWx0ZXI6IG51bGwsCiAgICAgICAgICAgIGp1c3RMaW1pdDogdHJ1ZSwKICAgICAgICAgICAgaXNNYXRjaDogbnVsbCwKICAgICAgICAgICAgb2Zmc2V0OiAwLAogICAgICAgICAgICBsaW1pdDogSW5maW5pdHksCiAgICAgICAgICAgIGVycm9yOiBlcnJvciwKICAgICAgICAgICAgb3I6IHdoZXJlQ3R4Lm9yLAogICAgICAgICAgICB2YWx1ZU1hcHBlcjogdGFibGUuaG9vay5yZWFkaW5nLmZpcmUKICAgICAgICB9OwogICAgfQogICAgZnVuY3Rpb24gaXNQbGFpbktleVJhbmdlKGN0eCwgaWdub3JlTGltaXRGaWx0ZXIpIHsKICAgICAgICByZXR1cm4gIShjdHguZmlsdGVyIHx8IGN0eC5hbGdvcml0aG0gfHwgY3R4Lm9yKSAmJgogICAgICAgICAgICAoaWdub3JlTGltaXRGaWx0ZXIgPyBjdHguanVzdExpbWl0IDogIWN0eC5yZXBsYXlGaWx0ZXIpOwogICAgfQogICAgcHJvcHMoQ29sbGVjdGlvbi5wcm90b3R5cGUsIGZ1bmN0aW9uICgpIHsKICAgICAgICAvLwogICAgICAgIC8vIENvbGxlY3Rpb24gUHJpdmF0ZSBGdW5jdGlvbnMKICAgICAgICAvLwogICAgICAgIGZ1bmN0aW9uIGFkZEZpbHRlcihjdHgsIGZuKSB7CiAgICAgICAgICAgIGN0eC5maWx0ZXIgPSBjb21iaW5lKGN0eC5maWx0ZXIsIGZuKTsKICAgICAgICB9CiAgICAgICAgZnVuY3Rpb24gYWRkUmVwbGF5RmlsdGVyKGN0eCwgZmFjdG9yeSwgaXNMaW1pdEZpbHRlcikgewogICAgICAgICAgICB2YXIgY3VyciA9IGN0eC5yZXBsYXlGaWx0ZXI7CiAgICAgICAgICAgIGN0eC5yZXBsYXlGaWx0ZXIgPSBjdXJyID8gZnVuY3Rpb24gKCkgeyByZXR1cm4gY29tYmluZShjdXJyKCksIGZhY3RvcnkoKSk7IH0gOiBmYWN0b3J5OwogICAgICAgICAgICBjdHguanVzdExpbWl0ID0gaXNMaW1pdEZpbHRlciAmJiAhY3VycjsKICAgICAgICB9CiAgICAgICAgZnVuY3Rpb24gYWRkTWF0Y2hGaWx0ZXIoY3R4LCBmbikgewogICAgICAgICAgICBjdHguaXNNYXRjaCA9IGNvbWJpbmUoY3R4LmlzTWF0Y2gsIGZuKTsKICAgICAgICB9CiAgICAgICAgLyoqIEBwYXJhbSBjdHggewogICAgICAgICAqICAgICAgaXNQcmltS2V5OiBib29sZWFuLAogICAgICAgICAqICAgICAgdGFibGU6IFRhYmxlLAogICAgICAgICAqICAgICAgaW5kZXg6IHN0cmluZwogICAgICAgICAqIH0KICAgICAgICAgKiBAcGFyYW0gc3RvcmUgSURCT2JqZWN0U3RvcmUKICAgICAgICAgKiovCiAgICAgICAgZnVuY3Rpb24gZ2V0SW5kZXhPclN0b3JlKGN0eCwgc3RvcmUpIHsKICAgICAgICAgICAgaWYgKGN0eC5pc1ByaW1LZXkpCiAgICAgICAgICAgICAgICByZXR1cm4gc3RvcmU7CiAgICAgICAgICAgIHZhciBpbmRleFNwZWMgPSBjdHgudGFibGUuc2NoZW1hLmlkeEJ5TmFtZVtjdHguaW5kZXhdOwogICAgICAgICAgICBpZiAoIWluZGV4U3BlYykKICAgICAgICAgICAgICAgIHRocm93IG5ldyBleGNlcHRpb25zLlNjaGVtYSgiS2V5UGF0aCAiICsgY3R4LmluZGV4ICsgIiBvbiBvYmplY3Qgc3RvcmUgIiArIHN0b3JlLm5hbWUgKyAiIGlzIG5vdCBpbmRleGVkIik7CiAgICAgICAgICAgIHJldHVybiBzdG9yZS5pbmRleChpbmRleFNwZWMubmFtZSk7CiAgICAgICAgfQogICAgICAgIC8qKiBAcGFyYW0gY3R4IHsKICAgICAgICAgKiAgICAgIGlzUHJpbUtleTogYm9vbGVhbiwKICAgICAgICAgKiAgICAgIHRhYmxlOiBUYWJsZSwKICAgICAgICAgKiAgICAgIGluZGV4OiBzdHJpbmcsCiAgICAgICAgICogICAgICBrZXlzT25seTogYm9vbGVhbiwKICAgICAgICAgKiAgICAgIHJhbmdlPzogSURCS2V5UmFuZ2UsCiAgICAgICAgICogICAgICBkaXI6ICJuZXh0IiB8ICJwcmV2IgogICAgICAgICAqIH0KICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBvcGVuQ3Vyc29yKGN0eCwgc3RvcmUpIHsKICAgICAgICAgICAgdmFyIGlkeE9yU3RvcmUgPSBnZXRJbmRleE9yU3RvcmUoY3R4LCBzdG9yZSk7CiAgICAgICAgICAgIHJldHVybiBjdHgua2V5c09ubHkgJiYgJ29wZW5LZXlDdXJzb3InIGluIGlkeE9yU3RvcmUgPwogICAgICAgICAgICAgICAgaWR4T3JTdG9yZS5vcGVuS2V5Q3Vyc29yKGN0eC5yYW5nZSB8fCBudWxsLCBjdHguZGlyICsgY3R4LnVuaXF1ZSkgOgogICAgICAgICAgICAgICAgaWR4T3JTdG9yZS5vcGVuQ3Vyc29yKGN0eC5yYW5nZSB8fCBudWxsLCBjdHguZGlyICsgY3R4LnVuaXF1ZSk7CiAgICAgICAgfQogICAgICAgIGZ1bmN0aW9uIGl0ZXIoY3R4LCBmbiwgcmVzb2x2ZSwgcmVqZWN0LCBpZGJzdG9yZSkgewogICAgICAgICAgICB2YXIgZmlsdGVyID0gY3R4LnJlcGxheUZpbHRlciA/IGNvbWJpbmUoY3R4LmZpbHRlciwgY3R4LnJlcGxheUZpbHRlcigpKSA6IGN0eC5maWx0ZXI7CiAgICAgICAgICAgIGlmICghY3R4Lm9yKSB7CiAgICAgICAgICAgICAgICBpdGVyYXRlKG9wZW5DdXJzb3IoY3R4LCBpZGJzdG9yZSksIGNvbWJpbmUoY3R4LmFsZ29yaXRobSwgZmlsdGVyKSwgZm4sIHJlc29sdmUsIHJlamVjdCwgIWN0eC5rZXlzT25seSAmJiBjdHgudmFsdWVNYXBwZXIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHNldCA9IHt9OwogICAgICAgICAgICAgICAgICAgIHZhciByZXNvbHZlZCA9IDA7CiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gcmVzb2x2ZWJvdGgoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgrK3Jlc29sdmVkID09PSAyKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpOyAvLyBTZWVtcyBsaWtlIHdlIGp1c3Qgc3VwcG9ydCBvciBidHduIG1heCAyIGV4cHJlc3Npb25zLCBidXQgdGhlcmUgYXJlIG5vIGxpbWl0IGJlY2F1c2Ugd2UgZG8gcmVjdXJzaW9uLgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiB1bmlvbihpdGVtLCBjdXJzb3IsIGFkdmFuY2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFmaWx0ZXIgfHwgZmlsdGVyKGN1cnNvciwgYWR2YW5jZSwgcmVzb2x2ZWJvdGgsIHJlamVjdCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwcmltYXJ5S2V5ID0gY3Vyc29yLnByaW1hcnlLZXk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIga2V5ID0gJycgKyBwcmltYXJ5S2V5OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGtleSA9PT0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXkgPSAnJyArIG5ldyBVaW50OEFycmF5KHByaW1hcnlLZXkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFoYXNPd24oc2V0LCBrZXkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0W2tleV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZuKGl0ZW0sIGN1cnNvciwgYWR2YW5jZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY3R4Lm9yLl9pdGVyYXRlKHVuaW9uLCByZXNvbHZlYm90aCwgcmVqZWN0LCBpZGJzdG9yZSk7CiAgICAgICAgICAgICAgICAgICAgaXRlcmF0ZShvcGVuQ3Vyc29yKGN0eCwgaWRic3RvcmUpLCBjdHguYWxnb3JpdGhtLCB1bmlvbiwgcmVzb2x2ZWJvdGgsIHJlamVjdCwgIWN0eC5rZXlzT25seSAmJiBjdHgudmFsdWVNYXBwZXIpOwogICAgICAgICAgICAgICAgfSkoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgLy8KICAgICAgICAgICAgLy8gQ29sbGVjdGlvbiBQcm90ZWN0ZWQgRnVuY3Rpb25zCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIF9yZWFkOiBmdW5jdGlvbiAoZm4sIGNiKSB7CiAgICAgICAgICAgICAgICB2YXIgY3R4ID0gdGhpcy5fY3R4OwogICAgICAgICAgICAgICAgcmV0dXJuIGN0eC5lcnJvciA/CiAgICAgICAgICAgICAgICAgICAgY3R4LnRhYmxlLl90cmFucyhudWxsLCByZWplY3Rpb24uYmluZChudWxsLCBjdHguZXJyb3IpKSA6CiAgICAgICAgICAgICAgICAgICAgY3R4LnRhYmxlLl9pZGJzdG9yZShSRUFET05MWSwgZm4pLnRoZW4oY2IpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBfd3JpdGU6IGZ1bmN0aW9uIChmbikgewogICAgICAgICAgICAgICAgdmFyIGN0eCA9IHRoaXMuX2N0eDsKICAgICAgICAgICAgICAgIHJldHVybiBjdHguZXJyb3IgPwogICAgICAgICAgICAgICAgICAgIGN0eC50YWJsZS5fdHJhbnMobnVsbCwgcmVqZWN0aW9uLmJpbmQobnVsbCwgY3R4LmVycm9yKSkgOgogICAgICAgICAgICAgICAgICAgIGN0eC50YWJsZS5faWRic3RvcmUoUkVBRFdSSVRFLCBmbiwgImxvY2tlZCIpOyAvLyBXaGVuIGRvaW5nIHdyaXRlIG9wZXJhdGlvbnMgb24gY29sbGVjdGlvbnMsIGFsd2F5cyBsb2NrIHRoZSBvcGVyYXRpb24gc28gdGhhdCB1cGNvbWluZyBvcGVyYXRpb25zIGdldHMgcXVldWVkLgogICAgICAgICAgICB9LAogICAgICAgICAgICBfYWRkQWxnb3JpdGhtOiBmdW5jdGlvbiAoZm4pIHsKICAgICAgICAgICAgICAgIHZhciBjdHggPSB0aGlzLl9jdHg7CiAgICAgICAgICAgICAgICBjdHguYWxnb3JpdGhtID0gY29tYmluZShjdHguYWxnb3JpdGhtLCBmbik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIF9pdGVyYXRlOiBmdW5jdGlvbiAoZm4sIHJlc29sdmUsIHJlamVjdCwgaWRic3RvcmUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBpdGVyKHRoaXMuX2N0eCwgZm4sIHJlc29sdmUsIHJlamVjdCwgaWRic3RvcmUpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBjbG9uZTogZnVuY3Rpb24gKHByb3BzJCQxKSB7CiAgICAgICAgICAgICAgICB2YXIgcnYgPSBPYmplY3QuY3JlYXRlKHRoaXMuY29uc3RydWN0b3IucHJvdG90eXBlKSwgY3R4ID0gT2JqZWN0LmNyZWF0ZSh0aGlzLl9jdHgpOwogICAgICAgICAgICAgICAgaWYgKHByb3BzJCQxKQogICAgICAgICAgICAgICAgICAgIGV4dGVuZChjdHgsIHByb3BzJCQxKTsKICAgICAgICAgICAgICAgIHJ2Ll9jdHggPSBjdHg7CiAgICAgICAgICAgICAgICByZXR1cm4gcnY7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHJhdzogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdGhpcy5fY3R4LnZhbHVlTWFwcGVyID0gbnVsbDsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvLwogICAgICAgICAgICAvLyBDb2xsZWN0aW9uIFB1YmxpYyBtZXRob2RzCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIGVhY2g6IGZ1bmN0aW9uIChmbikgewogICAgICAgICAgICAgICAgdmFyIGN0eCA9IHRoaXMuX2N0eDsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9yZWFkKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QsIGlkYnN0b3JlKSB7CiAgICAgICAgICAgICAgICAgICAgaXRlcihjdHgsIGZuLCByZXNvbHZlLCByZWplY3QsIGlkYnN0b3JlKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9LAogICAgICAgICAgICBjb3VudDogZnVuY3Rpb24gKGNiKSB7CiAgICAgICAgICAgICAgICB2YXIgY3R4ID0gdGhpcy5fY3R4OwogICAgICAgICAgICAgICAgaWYgKGlzUGxhaW5LZXlSYW5nZShjdHgsIHRydWUpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpcyBhIHBsYWluIGtleSByYW5nZS4gV2UgY2FuIHVzZSB0aGUgY291bnQoKSBtZXRob2QgaWYgdGhlIGluZGV4LgogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9yZWFkKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QsIGlkYnN0b3JlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpZHggPSBnZXRJbmRleE9yU3RvcmUoY3R4LCBpZGJzdG9yZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXEgPSAoY3R4LnJhbmdlID8gaWR4LmNvdW50KGN0eC5yYW5nZSkgOiBpZHguY291bnQoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlcS5vbmVycm9yID0gZXZlbnRSZWplY3RIYW5kbGVyKHJlamVjdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlcS5vbnN1Y2Nlc3MgPSBmdW5jdGlvbiAoZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShNYXRoLm1pbihlLnRhcmdldC5yZXN1bHQsIGN0eC5saW1pdCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgIH0sIGNiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vIEFsZ29yaXRobXMsIGZpbHRlcnMgb3IgZXhwcmVzc2lvbnMgYXJlIGFwcGxpZWQuIE5lZWQgdG8gY291bnQgbWFudWFsbHkuCiAgICAgICAgICAgICAgICAgICAgdmFyIGNvdW50ID0gMDsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fcmVhZChmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0LCBpZGJzdG9yZSkgewogICAgICAgICAgICAgICAgICAgICAgICBpdGVyKGN0eCwgZnVuY3Rpb24gKCkgeyArK2NvdW50OyByZXR1cm4gZmFsc2U7IH0sIGZ1bmN0aW9uICgpIHsgcmVzb2x2ZShjb3VudCk7IH0sIHJlamVjdCwgaWRic3RvcmUpOwogICAgICAgICAgICAgICAgICAgIH0sIGNiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgc29ydEJ5OiBmdW5jdGlvbiAoa2V5UGF0aCwgY2IpIHsKICAgICAgICAgICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ia2V5UGF0aCIgdHlwZT0iU3RyaW5nIj48L3BhcmFtPgogICAgICAgICAgICAgICAgdmFyIHBhcnRzID0ga2V5UGF0aC5zcGxpdCgnLicpLnJldmVyc2UoKSwgbGFzdFBhcnQgPSBwYXJ0c1swXSwgbGFzdEluZGV4ID0gcGFydHMubGVuZ3RoIC0gMTsKICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGdldHZhbChvYmosIGkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaSkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdldHZhbChvYmpbcGFydHNbaV1dLCBpIC0gMSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9ialtsYXN0UGFydF07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2YXIgb3JkZXIgPSB0aGlzLl9jdHguZGlyID09PSAibmV4dCIgPyAxIDogLTE7CiAgICAgICAgICAgICAgICBmdW5jdGlvbiBzb3J0ZXIoYSwgYikgewogICAgICAgICAgICAgICAgICAgIHZhciBhVmFsID0gZ2V0dmFsKGEsIGxhc3RJbmRleCksIGJWYWwgPSBnZXR2YWwoYiwgbGFzdEluZGV4KTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gYVZhbCA8IGJWYWwgPyAtb3JkZXIgOiBhVmFsID4gYlZhbCA/IG9yZGVyIDogMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRvQXJyYXkoZnVuY3Rpb24gKGEpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gYS5zb3J0KHNvcnRlcik7CiAgICAgICAgICAgICAgICB9KS50aGVuKGNiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgdG9BcnJheTogZnVuY3Rpb24gKGNiKSB7CiAgICAgICAgICAgICAgICB2YXIgY3R4ID0gdGhpcy5fY3R4OwogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3JlYWQoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCwgaWRic3RvcmUpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaGFzR2V0QWxsICYmIGN0eC5kaXIgPT09ICduZXh0JyAmJiBpc1BsYWluS2V5UmFuZ2UoY3R4LCB0cnVlKSAmJiBjdHgubGltaXQgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNwZWNpYWwgb3B0aW1hdGlvbiBpZiB3ZSBjb3VsZCB1c2UgSURCT2JqZWN0U3RvcmUuZ2V0QWxsKCkgb3IKICAgICAgICAgICAgICAgICAgICAgICAgLy8gSURCS2V5UmFuZ2UuZ2V0QWxsKCk6CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZWFkaW5nSG9vayA9IGN0eC50YWJsZS5ob29rLnJlYWRpbmcuZmlyZTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlkeE9yU3RvcmUgPSBnZXRJbmRleE9yU3RvcmUoY3R4LCBpZGJzdG9yZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXEgPSBjdHgubGltaXQgPCBJbmZpbml0eSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZHhPclN0b3JlLmdldEFsbChjdHgucmFuZ2UsIGN0eC5saW1pdCkgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWR4T3JTdG9yZS5nZXRBbGwoY3R4LnJhbmdlKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmVxLm9uZXJyb3IgPSBldmVudFJlamVjdEhhbmRsZXIocmVqZWN0KTsKICAgICAgICAgICAgICAgICAgICAgICAgcmVxLm9uc3VjY2VzcyA9IHJlYWRpbmdIb29rID09PSBtaXJyb3IgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRTdWNjZXNzSGFuZGxlcihyZXNvbHZlKSA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudFN1Y2Nlc3NIYW5kbGVyKGZ1bmN0aW9uIChyZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlcy5tYXAocmVhZGluZ0hvb2spKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gR2V0dGluZyBhcnJheSB0aHJvdWdoIGEgY3Vyc29yLgogICAgICAgICAgICAgICAgICAgICAgICB2YXIgYSA9IFtdOwogICAgICAgICAgICAgICAgICAgICAgICBpdGVyKGN0eCwgZnVuY3Rpb24gKGl0ZW0pIHsgYS5wdXNoKGl0ZW0pOyB9LCBmdW5jdGlvbiBhcnJheUNvbXBsZXRlKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShhKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSwgcmVqZWN0LCBpZGJzdG9yZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwgY2IpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBvZmZzZXQ6IGZ1bmN0aW9uIChvZmZzZXQpIHsKICAgICAgICAgICAgICAgIHZhciBjdHggPSB0aGlzLl9jdHg7CiAgICAgICAgICAgICAgICBpZiAob2Zmc2V0IDw9IDApCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgICAgICBjdHgub2Zmc2V0ICs9IG9mZnNldDsgLy8gRm9yIGNvdW50KCkKICAgICAgICAgICAgICAgIGlmIChpc1BsYWluS2V5UmFuZ2UoY3R4KSkgewogICAgICAgICAgICAgICAgICAgIGFkZFJlcGxheUZpbHRlcihjdHgsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9mZnNldExlZnQgPSBvZmZzZXQ7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoY3Vyc29yLCBhZHZhbmNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob2Zmc2V0TGVmdCA9PT0gMCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvZmZzZXRMZWZ0ID09PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS1vZmZzZXRMZWZ0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkdmFuY2UoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnNvci5hZHZhbmNlKG9mZnNldExlZnQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldExlZnQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBhZGRSZXBsYXlGaWx0ZXIoY3R4LCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvZmZzZXRMZWZ0ID0gb2Zmc2V0OwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkgeyByZXR1cm4gKC0tb2Zmc2V0TGVmdCA8IDApOyB9OwogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGxpbWl0OiBmdW5jdGlvbiAobnVtUm93cykgewogICAgICAgICAgICAgICAgdGhpcy5fY3R4LmxpbWl0ID0gTWF0aC5taW4odGhpcy5fY3R4LmxpbWl0LCBudW1Sb3dzKTsgLy8gRm9yIGNvdW50KCkKICAgICAgICAgICAgICAgIGFkZFJlcGxheUZpbHRlcih0aGlzLl9jdHgsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgcm93c0xlZnQgPSBudW1Sb3dzOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoY3Vyc29yLCBhZHZhbmNlLCByZXNvbHZlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgtLXJvd3NMZWZ0IDw9IDApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZHZhbmNlKHJlc29sdmUpOyAvLyBTdG9wIGFmdGVyIHRoaXMgaXRlbSBoYXMgYmVlbiBpbmNsdWRlZAogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcm93c0xlZnQgPj0gMDsgLy8gSWYgbnVtUm93cyBpcyBhbHJlYWR5IGJlbG93IDAsIHJldHVybiBmYWxzZSBiZWNhdXNlIHRoZW4gMCB3YXMgcGFzc2VkIHRvIG51bVJvd3MgaW5pdGlhbGx5LiBPdGhlcndpc2Ugd2Ugd291bGRudCBjb21lIGhlcmUuCiAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIH0sIHRydWUpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHVudGlsOiBmdW5jdGlvbiAoZmlsdGVyRnVuY3Rpb24sIGJJbmNsdWRlU3RvcEVudHJ5KSB7CiAgICAgICAgICAgICAgICBhZGRGaWx0ZXIodGhpcy5fY3R4LCBmdW5jdGlvbiAoY3Vyc29yLCBhZHZhbmNlLCByZXNvbHZlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGZpbHRlckZ1bmN0aW9uKGN1cnNvci52YWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYWR2YW5jZShyZXNvbHZlKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJJbmNsdWRlU3RvcEVudHJ5OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgZmlyc3Q6IGZ1bmN0aW9uIChjYikgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubGltaXQoMSkudG9BcnJheShmdW5jdGlvbiAoYSkgeyByZXR1cm4gYVswXTsgfSkudGhlbihjYik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGxhc3Q6IGZ1bmN0aW9uIChjYikgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucmV2ZXJzZSgpLmZpcnN0KGNiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgZmlsdGVyOiBmdW5jdGlvbiAoZmlsdGVyRnVuY3Rpb24pIHsKICAgICAgICAgICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ianNGdW5jdGlvbkZpbHRlciIgdHlwZT0iRnVuY3Rpb24iPmZ1bmN0aW9uKHZhbCl7cmV0dXJuIHRydWUvZmFsc2V9PC9wYXJhbT4KICAgICAgICAgICAgICAgIGFkZEZpbHRlcih0aGlzLl9jdHgsIGZ1bmN0aW9uIChjdXJzb3IpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmlsdGVyRnVuY3Rpb24oY3Vyc29yLnZhbHVlKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgLy8gbWF0Y2ggZmlsdGVycyBub3QgdXNlZCBpbiBEZXhpZS5qcyBidXQgY2FuIGJlIHVzZWQgYnkgM3JkIHBhcnQgbGlicmFyaWVzIHRvIHRlc3QgYQogICAgICAgICAgICAgICAgLy8gY29sbGVjdGlvbiBmb3IgYSBtYXRjaCB3aXRob3V0IHF1ZXJ5aW5nIERCLiBVc2VkIGJ5IERleGllLk9ic2VydmFibGUuCiAgICAgICAgICAgICAgICBhZGRNYXRjaEZpbHRlcih0aGlzLl9jdHgsIGZpbHRlckZ1bmN0aW9uKTsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9LAogICAgICAgICAgICBhbmQ6IGZ1bmN0aW9uIChmaWx0ZXJGdW5jdGlvbikgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZmlsdGVyKGZpbHRlckZ1bmN0aW9uKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgb3I6IGZ1bmN0aW9uIChpbmRleE5hbWUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgV2hlcmVDbGF1c2UodGhpcy5fY3R4LnRhYmxlLCBpbmRleE5hbWUsIHRoaXMpOwogICAgICAgICAgICB9LAogICAgICAgICAgICByZXZlcnNlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9jdHguZGlyID0gKHRoaXMuX2N0eC5kaXIgPT09ICJwcmV2IiA/ICJuZXh0IiA6ICJwcmV2Iik7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5fb25kaXJlY3Rpb25jaGFuZ2UpCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fb25kaXJlY3Rpb25jaGFuZ2UodGhpcy5fY3R4LmRpcik7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgZGVzYzogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucmV2ZXJzZSgpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBlYWNoS2V5OiBmdW5jdGlvbiAoY2IpIHsKICAgICAgICAgICAgICAgIHZhciBjdHggPSB0aGlzLl9jdHg7CiAgICAgICAgICAgICAgICBjdHgua2V5c09ubHkgPSAhY3R4LmlzTWF0Y2g7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICh2YWwsIGN1cnNvcikgeyBjYihjdXJzb3Iua2V5LCBjdXJzb3IpOyB9KTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgZWFjaFVuaXF1ZUtleTogZnVuY3Rpb24gKGNiKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9jdHgudW5pcXVlID0gInVuaXF1ZSI7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoS2V5KGNiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgZWFjaFByaW1hcnlLZXk6IGZ1bmN0aW9uIChjYikgewogICAgICAgICAgICAgICAgdmFyIGN0eCA9IHRoaXMuX2N0eDsKICAgICAgICAgICAgICAgIGN0eC5rZXlzT25seSA9ICFjdHguaXNNYXRjaDsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKHZhbCwgY3Vyc29yKSB7IGNiKGN1cnNvci5wcmltYXJ5S2V5LCBjdXJzb3IpOyB9KTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAga2V5czogZnVuY3Rpb24gKGNiKSB7CiAgICAgICAgICAgICAgICB2YXIgY3R4ID0gdGhpcy5fY3R4OwogICAgICAgICAgICAgICAgY3R4LmtleXNPbmx5ID0gIWN0eC5pc01hdGNoOwogICAgICAgICAgICAgICAgdmFyIGEgPSBbXTsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKGl0ZW0sIGN1cnNvcikgewogICAgICAgICAgICAgICAgICAgIGEucHVzaChjdXJzb3Iua2V5KTsKICAgICAgICAgICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBhOwogICAgICAgICAgICAgICAgfSkudGhlbihjYik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHByaW1hcnlLZXlzOiBmdW5jdGlvbiAoY2IpIHsKICAgICAgICAgICAgICAgIHZhciBjdHggPSB0aGlzLl9jdHg7CiAgICAgICAgICAgICAgICBpZiAoaGFzR2V0QWxsICYmIGN0eC5kaXIgPT09ICduZXh0JyAmJiBpc1BsYWluS2V5UmFuZ2UoY3R4LCB0cnVlKSAmJiBjdHgubGltaXQgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gU3BlY2lhbCBvcHRpbWF0aW9uIGlmIHdlIGNvdWxkIHVzZSBJREJPYmplY3RTdG9yZS5nZXRBbGxLZXlzKCkgb3IKICAgICAgICAgICAgICAgICAgICAvLyBJREJLZXlSYW5nZS5nZXRBbGxLZXlzKCk6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3JlYWQoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCwgaWRic3RvcmUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlkeE9yU3RvcmUgPSBnZXRJbmRleE9yU3RvcmUoY3R4LCBpZGJzdG9yZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXEgPSBjdHgubGltaXQgPCBJbmZpbml0eSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZHhPclN0b3JlLmdldEFsbEtleXMoY3R4LnJhbmdlLCBjdHgubGltaXQpIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkeE9yU3RvcmUuZ2V0QWxsS2V5cyhjdHgucmFuZ2UpOwogICAgICAgICAgICAgICAgICAgICAgICByZXEub25lcnJvciA9IGV2ZW50UmVqZWN0SGFuZGxlcihyZWplY3QpOwogICAgICAgICAgICAgICAgICAgICAgICByZXEub25zdWNjZXNzID0gZXZlbnRTdWNjZXNzSGFuZGxlcihyZXNvbHZlKTsKICAgICAgICAgICAgICAgICAgICB9KS50aGVuKGNiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGN0eC5rZXlzT25seSA9ICFjdHguaXNNYXRjaDsKICAgICAgICAgICAgICAgIHZhciBhID0gW107CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uIChpdGVtLCBjdXJzb3IpIHsKICAgICAgICAgICAgICAgICAgICBhLnB1c2goY3Vyc29yLnByaW1hcnlLZXkpOwogICAgICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGE7CiAgICAgICAgICAgICAgICB9KS50aGVuKGNiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgdW5pcXVlS2V5czogZnVuY3Rpb24gKGNiKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9jdHgudW5pcXVlID0gInVuaXF1ZSI7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5rZXlzKGNiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgZmlyc3RLZXk6IGZ1bmN0aW9uIChjYikgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubGltaXQoMSkua2V5cyhmdW5jdGlvbiAoYSkgeyByZXR1cm4gYVswXTsgfSkudGhlbihjYik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGxhc3RLZXk6IGZ1bmN0aW9uIChjYikgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucmV2ZXJzZSgpLmZpcnN0S2V5KGNiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgZGlzdGluY3Q6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHZhciBjdHggPSB0aGlzLl9jdHgsIGlkeCA9IGN0eC5pbmRleCAmJiBjdHgudGFibGUuc2NoZW1hLmlkeEJ5TmFtZVtjdHguaW5kZXhdOwogICAgICAgICAgICAgICAgaWYgKCFpZHggfHwgIWlkeC5tdWx0aSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpczsgLy8gZGlzdGluY3QoKSBvbmx5IG1ha2VzIGRpZmZlcmVuY2llcyBvbiBtdWx0aUVudHJ5IGluZGV4ZXMuCiAgICAgICAgICAgICAgICB2YXIgc2V0ID0ge307CiAgICAgICAgICAgICAgICBhZGRGaWx0ZXIodGhpcy5fY3R4LCBmdW5jdGlvbiAoY3Vyc29yKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHN0cktleSA9IGN1cnNvci5wcmltYXJ5S2V5LnRvU3RyaW5nKCk7IC8vIENvbnZlcnRzIGFueSBEYXRlIHRvIFN0cmluZywgU3RyaW5nIHRvIFN0cmluZywgTnVtYmVyIHRvIFN0cmluZyBhbmQgQXJyYXkgdG8gY29tbWEtc2VwYXJhdGVkIHN0cmluZwogICAgICAgICAgICAgICAgICAgIHZhciBmb3VuZCA9IGhhc093bihzZXQsIHN0cktleSk7CiAgICAgICAgICAgICAgICAgICAgc2V0W3N0cktleV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAhZm91bmQ7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvLwogICAgICAgICAgICAvLyBNZXRob2RzIHRoYXQgbXV0YXRlIHN0b3JhZ2UKICAgICAgICAgICAgLy8KICAgICAgICAgICAgbW9kaWZ5OiBmdW5jdGlvbiAoY2hhbmdlcykgewogICAgICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzLCBjdHggPSB0aGlzLl9jdHgsIGhvb2sgPSBjdHgudGFibGUuaG9vaywgdXBkYXRpbmdIb29rID0gaG9vay51cGRhdGluZy5maXJlLCBkZWxldGluZ0hvb2sgPSBob29rLmRlbGV0aW5nLmZpcmU7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fd3JpdGUoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCwgaWRic3RvcmUsIHRyYW5zKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIG1vZGlmeWVyOwogICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY2hhbmdlcyA9PT0gJ2Z1bmN0aW9uJykgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBDaGFuZ2VzIGlzIGEgZnVuY3Rpb24gdGhhdCBtYXkgdXBkYXRlLCBhZGQgb3IgZGVsZXRlIHByb3B0ZXJ0aWVzIG9yIGV2ZW4gcmVxdWlyZSBhIGRlbGV0aW9uIHRoZSBvYmplY3QgaXRzZWxmIChkZWxldGUgdGhpcy5pdGVtKQogICAgICAgICAgICAgICAgICAgICAgICBpZiAodXBkYXRpbmdIb29rID09PSBub3AgJiYgZGVsZXRpbmdIb29rID09PSBub3ApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vb25lIGNhcmVzIGFib3V0IHdoYXQgaXMgYmVpbmcgY2hhbmdlZC4gSnVzdCBsZXQgdGhlIG1vZGlmaWVyIGZ1bmN0aW9uIGJlIHRoZSBnaXZlbiBhcmd1bWVudCBhcyBpcy4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGlmeWVyID0gY2hhbmdlczsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFBlb3BsZSB3YW50IHRvIGtub3cgZXhhY3RseSB3aGF0IGlzIGJlaW5nIG1vZGlmaWVkIG9yIGRlbGV0ZWQuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBMZXQgbW9kaWZ5ZXIgYmUgYSBwcm94eSBmdW5jdGlvbiB0aGF0IGZpbmRzIG91dCB3aGF0IGNoYW5nZXMgdGhlIGNhbGxlciBpcyBhY3R1YWxseSBkb2luZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYW5kIGNhbGwgdGhlIGhvb2tzIGFjY29yZGluZ2x5IQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kaWZ5ZXIgPSBmdW5jdGlvbiAoaXRlbSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvcmlnSXRlbSA9IGRlZXBDbG9uZShpdGVtKTsgLy8gQ2xvbmUgdGhlIGl0ZW0gZmlyc3Qgc28gd2UgY2FuIGNvbXBhcmUgbGF0ZXJzLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaGFuZ2VzLmNhbGwodGhpcywgaXRlbSwgdGhpcykgPT09IGZhbHNlKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIENhbGwgdGhlIHJlYWwgbW9kaWZ5ZXIgZnVuY3Rpb24gKElmIGl0IHJldHVybnMgZmFsc2UgZXhwbGljaXRlbHksIGl0IG1lYW5zIGl0IGRvbnQgd2FudCB0byBtb2RpZnkgYW55dGluZyBvbiB0aGlzIG9iamVjdCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWhhc093bih0aGlzLCAidmFsdWUiKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGUgcmVhbCBtb2RpZnllciBmdW5jdGlvbiByZXF1ZXN0cyBhIGRlbGV0aW9uIG9mIHRoZSBvYmplY3QuIEluZm9ybSB0aGUgZGVsZXRpbmdIb29rIHRoYXQgYSBkZWxldGlvbiBpcyB0YWtpbmcgcGxhY2UuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0aW5nSG9vay5jYWxsKHRoaXMsIHRoaXMucHJpbUtleSwgaXRlbSwgdHJhbnMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm8gZGVsZXRpb24uIENoZWNrIHdoYXQgd2FzIGNoYW5nZWQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9iamVjdERpZmYgPSBnZXRPYmplY3REaWZmKG9yaWdJdGVtLCB0aGlzLnZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFkZGl0aW9uYWxDaGFuZ2VzID0gdXBkYXRpbmdIb29rLmNhbGwodGhpcywgb2JqZWN0RGlmZiwgdGhpcy5wcmltS2V5LCBvcmlnSXRlbSwgdHJhbnMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYWRkaXRpb25hbENoYW5nZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhvb2sgd2FudCB0byBhcHBseSBhZGRpdGlvbmFsIG1vZGlmaWNhdGlvbnMuIE1ha2Ugc3VyZSB0byBmdWxsZmlsbCB0aGUgd2lsbCBvZiB0aGUgaG9vay4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0gPSB0aGlzLnZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5cyhhZGRpdGlvbmFsQ2hhbmdlcykuZm9yRWFjaChmdW5jdGlvbiAoa2V5UGF0aCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldEJ5S2V5UGF0aChpdGVtLCBrZXlQYXRoLCBhZGRpdGlvbmFsQ2hhbmdlc1trZXlQYXRoXSk7IC8vIEFkZGluZyB7a2V5UGF0aDogdW5kZWZpbmVkfSBtZWFucyB0aGF0IHRoZSBrZXlQYXRoIHNob3VsZCBiZSBkZWxldGVkLiBIYW5kbGVkIGJ5IHNldEJ5S2V5UGF0aAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHVwZGF0aW5nSG9vayA9PT0gbm9wKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNoYW5nZXMgaXMgYSBzZXQgb2Yge2tleVBhdGg6IHZhbHVlfSBhbmQgbm8gb25lIGlzIGxpc3RlbmluZyB0byB0aGUgdXBkYXRpbmcgaG9vay4KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGtleVBhdGhzID0ga2V5cyhjaGFuZ2VzKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG51bUtleXMgPSBrZXlQYXRocy5sZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgICAgIG1vZGlmeWVyID0gZnVuY3Rpb24gKGl0ZW0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhbnl0aGluZ01vZGlmaWVkID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG51bUtleXM7ICsraSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBrZXlQYXRoID0ga2V5UGF0aHNbaV0sIHZhbCA9IGNoYW5nZXNba2V5UGF0aF07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdldEJ5S2V5UGF0aChpdGVtLCBrZXlQYXRoKSAhPT0gdmFsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldEJ5S2V5UGF0aChpdGVtLCBrZXlQYXRoLCB2YWwpOyAvLyBBZGRpbmcge2tleVBhdGg6IHVuZGVmaW5lZH0gbWVhbnMgdGhhdCB0aGUga2V5UGF0aCBzaG91bGQgYmUgZGVsZXRlZC4gSGFuZGxlZCBieSBzZXRCeUtleVBhdGgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW55dGhpbmdNb2RpZmllZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFueXRoaW5nTW9kaWZpZWQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGFuZ2VzIGlzIGEgc2V0IG9mIHtrZXlQYXRoOiB2YWx1ZX0gYW5kIHBlb3BsZSBhcmUgbGlzdGVuaW5nIHRvIHRoZSB1cGRhdGluZyBob29rIHNvIHdlIG5lZWQgdG8gY2FsbCBpdCBhbmQKICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWxsb3cgaXQgdG8gYWRkIGFkZGl0aW9uYWwgbW9kaWZpY2F0aW9ucyB0byBtYWtlLgogICAgICAgICAgICAgICAgICAgICAgICB2YXIgb3JpZ0NoYW5nZXMgPSBjaGFuZ2VzOwogICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2VzID0gc2hhbGxvd0Nsb25lKG9yaWdDaGFuZ2VzKTsgLy8gTGV0J3Mgd29yayB3aXRoIGEgY2xvbmUgb2YgdGhlIGNoYW5nZXMga2V5UGF0aC92YWx1ZSBzZXQgc28gdGhhdCB3ZSBjYW4gcmVzdG9yZSBpdCBpbiBjYXNlIGEgaG9vayBleHRlbmRzIGl0LgogICAgICAgICAgICAgICAgICAgICAgICBtb2RpZnllciA9IGZ1bmN0aW9uIChpdGVtKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYW55dGhpbmdNb2RpZmllZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFkZGl0aW9uYWxDaGFuZ2VzID0gdXBkYXRpbmdIb29rLmNhbGwodGhpcywgY2hhbmdlcywgdGhpcy5wcmltS2V5LCBkZWVwQ2xvbmUoaXRlbSksIHRyYW5zKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhZGRpdGlvbmFsQ2hhbmdlcykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbmQoY2hhbmdlcywgYWRkaXRpb25hbENoYW5nZXMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5cyhjaGFuZ2VzKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXlQYXRoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZhbCA9IGNoYW5nZXNba2V5UGF0aF07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdldEJ5S2V5UGF0aChpdGVtLCBrZXlQYXRoKSAhPT0gdmFsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldEJ5S2V5UGF0aChpdGVtLCBrZXlQYXRoLCB2YWwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbnl0aGluZ01vZGlmaWVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhZGRpdGlvbmFsQ2hhbmdlcykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2VzID0gc2hhbGxvd0Nsb25lKG9yaWdDaGFuZ2VzKTsgLy8gUmVzdG9yZSBvcmlnaW5hbCBjaGFuZ2VzIGZvciBuZXh0IGl0ZXJhdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFueXRoaW5nTW9kaWZpZWQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHZhciBjb3VudCA9IDA7CiAgICAgICAgICAgICAgICAgICAgdmFyIHN1Y2Nlc3NDb3VudCA9IDA7CiAgICAgICAgICAgICAgICAgICAgdmFyIGl0ZXJhdGlvbkNvbXBsZXRlID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgdmFyIGZhaWx1cmVzID0gW107CiAgICAgICAgICAgICAgICAgICAgdmFyIGZhaWxLZXlzID0gW107CiAgICAgICAgICAgICAgICAgICAgdmFyIGN1cnJlbnRLZXkgPSBudWxsOwogICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIG1vZGlmeUl0ZW0oaXRlbSwgY3Vyc29yKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRLZXkgPSBjdXJzb3IucHJpbWFyeUtleTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRoaXNDb250ZXh0ID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbUtleTogY3Vyc29yLnByaW1hcnlLZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogaXRlbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uc3VjY2VzczogbnVsbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uZXJyb3I6IG51bGwKICAgICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gb25lcnJvcihlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWlsdXJlcy5wdXNoKGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFpbEtleXMucHVzaCh0aGlzQ29udGV4dC5wcmltS2V5KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrRmluaXNoZWQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOyAvLyBDYXRjaCB0aGVzZSBlcnJvcnMgYW5kIGxldCBhIGZpbmFsIHJlamVjdGlvbiBkZWNpZGUgd2hldGhlciBvciBub3QgdG8gYWJvcnQgZW50aXJlIHRyYW5zYWN0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1vZGlmeWVyLmNhbGwodGhpc0NvbnRleHQsIGl0ZW0sIHRoaXNDb250ZXh0KSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBiRGVsZXRlID0gIWhhc093bih0aGlzQ29udGV4dCwgInZhbHVlIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICArK2NvdW50OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5Q2F0Y2goZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXEgPSAoYkRlbGV0ZSA/IGN1cnNvci5kZWxldGUoKSA6IGN1cnNvci51cGRhdGUodGhpc0NvbnRleHQudmFsdWUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXEuX2hvb2tDdHggPSB0aGlzQ29udGV4dDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXEub25lcnJvciA9IGhvb2tlZEV2ZW50UmVqZWN0SGFuZGxlcihvbmVycm9yKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXEub25zdWNjZXNzID0gaG9va2VkRXZlbnRTdWNjZXNzSGFuZGxlcihmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsrc3VjY2Vzc0NvdW50OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja0ZpbmlzaGVkKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCBvbmVycm9yKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0aGlzQ29udGV4dC5vbnN1Y2Nlc3MpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhvb2sgd2lsbCBleHBlY3QgZWl0aGVyIG9uZXJyb3Igb3Igb25zdWNjZXNzIHRvIGFsd2F5cyBiZSBjYWxsZWQhCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzQ29udGV4dC5vbnN1Y2Nlc3ModGhpc0NvbnRleHQudmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGRvUmVqZWN0KGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhaWx1cmVzLnB1c2goZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWlsS2V5cy5wdXNoKGN1cnJlbnRLZXkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IE1vZGlmeUVycm9yKCJFcnJvciBtb2RpZnlpbmcgb25lIG9yIG1vcmUgb2JqZWN0cyIsIGZhaWx1cmVzLCBzdWNjZXNzQ291bnQsIGZhaWxLZXlzKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGNoZWNrRmluaXNoZWQoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpdGVyYXRpb25Db21wbGV0ZSAmJiBzdWNjZXNzQ291bnQgKyBmYWlsdXJlcy5sZW5ndGggPT09IGNvdW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmFpbHVyZXMubGVuZ3RoID4gMCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb1JlamVjdCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoc3VjY2Vzc0NvdW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBzZWxmLmNsb25lKCkucmF3KCkuX2l0ZXJhdGUobW9kaWZ5SXRlbSwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICBpdGVyYXRpb25Db21wbGV0ZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrRmluaXNoZWQoKTsKICAgICAgICAgICAgICAgICAgICB9LCBkb1JlamVjdCwgaWRic3RvcmUpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICdkZWxldGUnOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgX3RoaXMgPSB0aGlzOwogICAgICAgICAgICAgICAgdmFyIGN0eCA9IHRoaXMuX2N0eCwgcmFuZ2UgPSBjdHgucmFuZ2UsIGRlbGV0aW5nSG9vayA9IGN0eC50YWJsZS5ob29rLmRlbGV0aW5nLmZpcmUsIGhhc0RlbGV0ZUhvb2sgPSBkZWxldGluZ0hvb2sgIT09IG5vcDsKICAgICAgICAgICAgICAgIGlmICghaGFzRGVsZXRlSG9vayAmJgogICAgICAgICAgICAgICAgICAgIGlzUGxhaW5LZXlSYW5nZShjdHgpICYmCiAgICAgICAgICAgICAgICAgICAgKChjdHguaXNQcmltS2V5ICYmICFoYW5nc09uRGVsZXRlTGFyZ2VLZXlSYW5nZSkgfHwgIXJhbmdlKSkgewogICAgICAgICAgICAgICAgICAgIC8vIE1heSB1c2UgSURCT2JqZWN0U3RvcmUuZGVsZXRlKElEQktleVJhbmdlKSBpbiB0aGlzIGNhc2UgKElzc3VlICMyMDgpCiAgICAgICAgICAgICAgICAgICAgLy8gRm9yIGNocm9taXVtLCB0aGlzIGlzIHRoZSB3YXkgbW9zdCBvcHRpbWl6ZWQgdmVyc2lvbi4KICAgICAgICAgICAgICAgICAgICAvLyBGb3IgSUUvRWRnZSwgdGhpcyBjb3VsZCBoYW5nIHRoZSBpbmRleGVkREIgZW5naW5lIGFuZCBtYWtlIG9wZXJhdGluZyBzeXN0ZW0gaW5zdGFibGUKICAgICAgICAgICAgICAgICAgICAvLyAoaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vZGZhaGxhbmRlci81YTM5MzI4ZjAyOWRlMTgyMjJjZjIxMjVkNTZjMzhmNykKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fd3JpdGUoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCwgaWRic3RvcmUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3VyIEFQSSBjb250cmFjdCBpcyB0byByZXR1cm4gYSBjb3VudCBvZiBkZWxldGVkIGl0ZW1zLCBzbyB3ZSBoYXZlIHRvIGNvdW50KCkgYmVmb3JlIGRlbGV0ZSgpLgogICAgICAgICAgICAgICAgICAgICAgICB2YXIgb25lcnJvciA9IGV2ZW50UmVqZWN0SGFuZGxlcihyZWplY3QpLCBjb3VudFJlcSA9IChyYW5nZSA/IGlkYnN0b3JlLmNvdW50KHJhbmdlKSA6IGlkYnN0b3JlLmNvdW50KCkpOwogICAgICAgICAgICAgICAgICAgICAgICBjb3VudFJlcS5vbmVycm9yID0gb25lcnJvcjsKICAgICAgICAgICAgICAgICAgICAgICAgY291bnRSZXEub25zdWNjZXNzID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvdW50ID0gY291bnRSZXEucmVzdWx0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5Q2F0Y2goZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkZWxSZXEgPSAocmFuZ2UgPyBpZGJzdG9yZS5kZWxldGUocmFuZ2UpIDogaWRic3RvcmUuY2xlYXIoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsUmVxLm9uZXJyb3IgPSBvbmVycm9yOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbFJlcS5vbnN1Y2Nlc3MgPSBmdW5jdGlvbiAoKSB7IHJldHVybiByZXNvbHZlKGNvdW50KTsgfTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIGZ1bmN0aW9uIChlcnIpIHsgcmV0dXJuIHJlamVjdChlcnIpOyB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIERlZmF1bHQgdmVyc2lvbiB0byB1c2Ugd2hlbiBjb2xsZWN0aW9uIGlzIG5vdCBhIHZhbmlsbGEgSURCS2V5UmFuZ2Ugb24gdGhlIHByaW1hcnkga2V5LgogICAgICAgICAgICAgICAgLy8gRGl2aWRlIGludG8gY2h1bmtzIHRvIG5vdCBzdGFydmUgUkFNLgogICAgICAgICAgICAgICAgLy8gSWYgaGFzIGRlbGV0ZSBob29rLCB3ZSB3aWxsIGhhdmUgdG8gY29sbGVjdCBub3QganVzdCBrZXlzIGJ1dCBhbHNvIG9iamVjdHMsIHNvIGl0IHdpbGwgdXNlCiAgICAgICAgICAgICAgICAvLyBtb3JlIG1lbW9yeSBhbmQgbmVlZCBsb3dlciBjaHVuayBzaXplLgogICAgICAgICAgICAgICAgdmFyIENIVU5LU0laRSA9IGhhc0RlbGV0ZUhvb2sgPyAyMDAwIDogMTAwMDA7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fd3JpdGUoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCwgaWRic3RvcmUsIHRyYW5zKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHRvdGFsQ291bnQgPSAwOwogICAgICAgICAgICAgICAgICAgIC8vIENsb25lIGNvbGxlY3Rpb24gYW5kIGNoYW5nZSBpdHMgdGFibGUgYW5kIHNldCBhIGxpbWl0IG9mIENIVU5LU0laRSBvbiB0aGUgY2xvbmVkIENvbGxlY3Rpb24gaW5zdGFuY2UuCiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbGxlY3Rpb24gPSBfdGhpcwogICAgICAgICAgICAgICAgICAgICAgICAuY2xvbmUoewogICAgICAgICAgICAgICAgICAgICAgICBrZXlzT25seTogIWN0eC5pc01hdGNoICYmICFoYXNEZWxldGVIb29rCiAgICAgICAgICAgICAgICAgICAgfSkgLy8gbG9hZCBqdXN0IGtleXMgKHVubGVzcyBmaWx0ZXIoKSBvciBhbmQoKSBvciBkZWxldGVIb29rIGhhcyBzdWJzY3JpYmVycykKICAgICAgICAgICAgICAgICAgICAgICAgLmRpc3RpbmN0KCkgLy8gSW4gY2FzZSBtdWx0aUVudHJ5IGlzIHVzZWQsIG5ldmVyIGRlbGV0ZSBzYW1lIGtleSB0d2ljZSBiZWNhdXNlIHJlc3VsdGluZyBjb3VudAogICAgICAgICAgICAgICAgICAgICAgICAubGltaXQoQ0hVTktTSVpFKQogICAgICAgICAgICAgICAgICAgICAgICAucmF3KCk7IC8vIERvbid0IGZpbHRlciB0aHJvdWdoIHJlYWRpbmctaG9va3MgKGxpa2UgbWFwcGVkIGNsYXNzZXMgZXRjKQogICAgICAgICAgICAgICAgICAgIHZhciBrZXlzT3JUdXBsZXMgPSBbXTsKICAgICAgICAgICAgICAgICAgICAvLyBXZSdyZSBnb25uYSBkbyB0aGluZ3Mgb24gYXMgbWFueSBjaHVua3MgdGhhdCBhcmUgbmVlZGVkLgogICAgICAgICAgICAgICAgICAgIC8vIFVzZSByZWN1cnNpb24gb2YgbmV4dENodW5rIGZ1bmN0aW9uOgogICAgICAgICAgICAgICAgICAgIHZhciBuZXh0Q2h1bmsgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBjb2xsZWN0aW9uLmVhY2goaGFzRGVsZXRlSG9vayA/IGZ1bmN0aW9uICh2YWwsIGN1cnNvcikgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBTb21lYm9keSBzdWJzY3JpYmVzIHRvIGhvb2soJ2RlbGV0aW5nJykuIENvbGxlY3QgYWxsIHByaW1hcnkga2V5cyBhbmQgdGhlaXIgdmFsdWVzLAogICAgICAgICAgICAgICAgICAgICAgICAvLyBzbyB0aGF0IHRoZSBob29rIGNhbiBiZSBjYWxsZWQgd2l0aCBpdHMgdmFsdWVzIGluIGJ1bGtEZWxldGUoKS4KICAgICAgICAgICAgICAgICAgICAgICAga2V5c09yVHVwbGVzLnB1c2goW2N1cnNvci5wcmltYXJ5S2V5LCBjdXJzb3IudmFsdWVdKTsKICAgICAgICAgICAgICAgICAgICB9IDogZnVuY3Rpb24gKHZhbCwgY3Vyc29yKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vIG9uZSBzdWJzY3JpYmVzIHRvIGhvb2soJ2RlbGV0aW5nJykuIENvbGxlY3Qgb25seSBwcmltYXJ5IGtleXM6CiAgICAgICAgICAgICAgICAgICAgICAgIGtleXNPclR1cGxlcy5wdXNoKGN1cnNvci5wcmltYXJ5S2V5KTsKICAgICAgICAgICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2hyb21pdW0gZGVsZXRlcyBmYXN0ZXIgd2hlbiBkb2luZyBpdCBpbiBzb3J0IG9yZGVyLgogICAgICAgICAgICAgICAgICAgICAgICBoYXNEZWxldGVIb29rID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleXNPclR1cGxlcy5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiBhc2NlbmRpbmcoYVswXSwgYlswXSk7IH0pIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleXNPclR1cGxlcy5zb3J0KGFzY2VuZGluZyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBidWxrRGVsZXRlKGlkYnN0b3JlLCB0cmFucywga2V5c09yVHVwbGVzLCBoYXNEZWxldGVIb29rLCBkZWxldGluZ0hvb2spOwogICAgICAgICAgICAgICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY291bnQgPSBrZXlzT3JUdXBsZXMubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICAgICB0b3RhbENvdW50ICs9IGNvdW50OwogICAgICAgICAgICAgICAgICAgICAgICBrZXlzT3JUdXBsZXMgPSBbXTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvdW50IDwgQ0hVTktTSVpFID8gdG90YWxDb3VudCA6IG5leHRDaHVuaygpOwogICAgICAgICAgICAgICAgICAgIH0pOyB9OwogICAgICAgICAgICAgICAgICAgIHJlc29sdmUobmV4dENodW5rKCkpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfSk7CiAgICAvLwogICAgLy8KICAgIC8vCiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEhlbHAgZnVuY3Rpb25zIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8KICAgIC8vCiAgICAvLwogICAgZnVuY3Rpb24gbG93ZXJWZXJzaW9uRmlyc3QoYSwgYikgewogICAgICAgIHJldHVybiBhLl9jZmcudmVyc2lvbiAtIGIuX2NmZy52ZXJzaW9uOwogICAgfQogICAgZnVuY3Rpb24gc2V0QXBpT25QbGFjZShvYmpzLCB0YWJsZU5hbWVzLCBkYnNjaGVtYSkgewogICAgICAgIHRhYmxlTmFtZXMuZm9yRWFjaChmdW5jdGlvbiAodGFibGVOYW1lKSB7CiAgICAgICAgICAgIHZhciBzY2hlbWEgPSBkYnNjaGVtYVt0YWJsZU5hbWVdOwogICAgICAgICAgICBvYmpzLmZvckVhY2goZnVuY3Rpb24gKG9iaikgewogICAgICAgICAgICAgICAgaWYgKCEodGFibGVOYW1lIGluIG9iaikpIHsKICAgICAgICAgICAgICAgICAgICBpZiAob2JqID09PSBUcmFuc2FjdGlvbi5wcm90b3R5cGUgfHwgb2JqIGluc3RhbmNlb2YgVHJhbnNhY3Rpb24pIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gb2JqIGlzIGEgVHJhbnNhY3Rpb24gcHJvdG90eXBlIChvciBwcm90b3R5cGUgb2YgYSBzdWJjbGFzcyB0byBUcmFuc2FjdGlvbikKICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWFrZSB0aGUgQVBJIGEgZ2V0dGVyIHRoYXQgcmV0dXJucyB0aGlzLnRhYmxlKHRhYmxlTmFtZSkKICAgICAgICAgICAgICAgICAgICAgICAgc2V0UHJvcChvYmosIHRhYmxlTmFtZSwgeyBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMudGFibGUodGFibGVOYW1lKTsgfSB9KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRhYmxlIHdpbGwgbm90IGJlIGJvdW5kIHRvIGEgdHJhbnNhY3Rpb24gKHdpbGwgdXNlIERleGllLmN1cnJlbnRUcmFuc2FjdGlvbikKICAgICAgICAgICAgICAgICAgICAgICAgb2JqW3RhYmxlTmFtZV0gPSBuZXcgVGFibGUodGFibGVOYW1lLCBzY2hlbWEpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfSk7CiAgICB9CiAgICBmdW5jdGlvbiByZW1vdmVUYWJsZXNBcGkob2JqcykgewogICAgICAgIG9ianMuZm9yRWFjaChmdW5jdGlvbiAob2JqKSB7CiAgICAgICAgICAgIGZvciAodmFyIGtleSBpbiBvYmopIHsKICAgICAgICAgICAgICAgIGlmIChvYmpba2V5XSBpbnN0YW5jZW9mIFRhYmxlKQogICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBvYmpba2V5XTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfQogICAgZnVuY3Rpb24gaXRlcmF0ZShyZXEsIGZpbHRlciwgZm4sIHJlc29sdmUsIHJlamVjdCwgdmFsdWVNYXBwZXIpIHsKICAgICAgICAvLyBBcHBseSB2YWx1ZU1hcHBlciAoaG9vaygncmVhZGluZycpIG9yIG1hcHBwZWQgY2xhc3MpCiAgICAgICAgdmFyIG1hcHBlZEZuID0gdmFsdWVNYXBwZXIgPyBmdW5jdGlvbiAoeCwgYywgYSkgeyByZXR1cm4gZm4odmFsdWVNYXBwZXIoeCksIGMsIGEpOyB9IDogZm47CiAgICAgICAgLy8gV3JhcCBmbiB3aXRoIFBTRCBhbmQgbWljcm90aWNrIHN0dWZmIGZyb20gUHJvbWlzZS4KICAgICAgICB2YXIgd3JhcHBlZEZuID0gd3JhcChtYXBwZWRGbiwgcmVqZWN0KTsKICAgICAgICBpZiAoIXJlcS5vbmVycm9yKQogICAgICAgICAgICByZXEub25lcnJvciA9IGV2ZW50UmVqZWN0SGFuZGxlcihyZWplY3QpOwogICAgICAgIGlmIChmaWx0ZXIpIHsKICAgICAgICAgICAgcmVxLm9uc3VjY2VzcyA9IHRyeWNhdGNoZXIoZnVuY3Rpb24gZmlsdGVyX3JlY29yZCgpIHsKICAgICAgICAgICAgICAgIHZhciBjdXJzb3IgPSByZXEucmVzdWx0OwogICAgICAgICAgICAgICAgaWYgKGN1cnNvcikgewogICAgICAgICAgICAgICAgICAgIHZhciBjID0gZnVuY3Rpb24gKCkgeyBjdXJzb3IuY29udGludWUoKTsgfTsKICAgICAgICAgICAgICAgICAgICBpZiAoZmlsdGVyKGN1cnNvciwgZnVuY3Rpb24gKGFkdmFuY2VyKSB7IGMgPSBhZHZhbmNlcjsgfSwgcmVzb2x2ZSwgcmVqZWN0KSkKICAgICAgICAgICAgICAgICAgICAgICAgd3JhcHBlZEZuKGN1cnNvci52YWx1ZSwgY3Vyc29yLCBmdW5jdGlvbiAoYWR2YW5jZXIpIHsgYyA9IGFkdmFuY2VyOyB9KTsKICAgICAgICAgICAgICAgICAgICBjKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sIHJlamVjdCk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICByZXEub25zdWNjZXNzID0gdHJ5Y2F0Y2hlcihmdW5jdGlvbiBmaWx0ZXJfcmVjb3JkKCkgewogICAgICAgICAgICAgICAgdmFyIGN1cnNvciA9IHJlcS5yZXN1bHQ7CiAgICAgICAgICAgICAgICBpZiAoY3Vyc29yKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGMgPSBmdW5jdGlvbiAoKSB7IGN1cnNvci5jb250aW51ZSgpOyB9OwogICAgICAgICAgICAgICAgICAgIHdyYXBwZWRGbihjdXJzb3IudmFsdWUsIGN1cnNvciwgZnVuY3Rpb24gKGFkdmFuY2VyKSB7IGMgPSBhZHZhbmNlcjsgfSk7CiAgICAgICAgICAgICAgICAgICAgYygpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LCByZWplY3QpOwogICAgICAgIH0KICAgIH0KICAgIGZ1bmN0aW9uIHBhcnNlSW5kZXhTeW50YXgoaW5kZXhlcykgewogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iaW5kZXhlcyIgdHlwZT0iU3RyaW5nIj48L3BhcmFtPgogICAgICAgIC8vLyA8cmV0dXJucyB0eXBlPSJBcnJheSIgZWxlbWVudFR5cGU9IkluZGV4U3BlYyI+PC9yZXR1cm5zPgogICAgICAgIHZhciBydiA9IFtdOwogICAgICAgIGluZGV4ZXMuc3BsaXQoJywnKS5mb3JFYWNoKGZ1bmN0aW9uIChpbmRleCkgewogICAgICAgICAgICBpbmRleCA9IGluZGV4LnRyaW0oKTsKICAgICAgICAgICAgdmFyIG5hbWUgPSBpbmRleC5yZXBsYWNlKC8oWyYqXXxcK1wrKS9nLCAiIik7IC8vIFJlbW92ZSAiJiIsICIrKyIgYW5kICIqIgogICAgICAgICAgICAvLyBMZXQga2V5UGF0aCBvZiAiW2ErYl0iIGJlIFsiYSIsImIiXToKICAgICAgICAgICAgdmFyIGtleVBhdGggPSAvXlxbLy50ZXN0KG5hbWUpID8gbmFtZS5tYXRjaCgvXlxbKC4qKVxdJC8pWzFdLnNwbGl0KCcrJykgOiBuYW1lOwogICAgICAgICAgICBydi5wdXNoKG5ldyBJbmRleFNwZWMobmFtZSwga2V5UGF0aCB8fCBudWxsLCAvXCYvLnRlc3QoaW5kZXgpLCAvXCovLnRlc3QoaW5kZXgpLCAvXCtcKy8udGVzdChpbmRleCksIGlzQXJyYXkoa2V5UGF0aCksIC9cLi8udGVzdChpbmRleCkpKTsKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gcnY7CiAgICB9CiAgICBmdW5jdGlvbiBjbXAoa2V5MSwga2V5MikgewogICAgICAgIHJldHVybiBpbmRleGVkREIuY21wKGtleTEsIGtleTIpOwogICAgfQogICAgZnVuY3Rpb24gbWluKGEsIGIpIHsKICAgICAgICByZXR1cm4gY21wKGEsIGIpIDwgMCA/IGEgOiBiOwogICAgfQogICAgZnVuY3Rpb24gbWF4KGEsIGIpIHsKICAgICAgICByZXR1cm4gY21wKGEsIGIpID4gMCA/IGEgOiBiOwogICAgfQogICAgZnVuY3Rpb24gYXNjZW5kaW5nKGEsIGIpIHsKICAgICAgICByZXR1cm4gaW5kZXhlZERCLmNtcChhLCBiKTsKICAgIH0KICAgIGZ1bmN0aW9uIGRlc2NlbmRpbmcoYSwgYikgewogICAgICAgIHJldHVybiBpbmRleGVkREIuY21wKGIsIGEpOwogICAgfQogICAgZnVuY3Rpb24gc2ltcGxlQ29tcGFyZShhLCBiKSB7CiAgICAgICAgcmV0dXJuIGEgPCBiID8gLTEgOiBhID09PSBiID8gMCA6IDE7CiAgICB9CiAgICBmdW5jdGlvbiBzaW1wbGVDb21wYXJlUmV2ZXJzZShhLCBiKSB7CiAgICAgICAgcmV0dXJuIGEgPiBiID8gLTEgOiBhID09PSBiID8gMCA6IDE7CiAgICB9CiAgICBmdW5jdGlvbiBjb21iaW5lKGZpbHRlcjEsIGZpbHRlcjIpIHsKICAgICAgICByZXR1cm4gZmlsdGVyMSA/CiAgICAgICAgICAgIGZpbHRlcjIgPwogICAgICAgICAgICAgICAgZnVuY3Rpb24gKCkgeyByZXR1cm4gZmlsdGVyMS5hcHBseSh0aGlzLCBhcmd1bWVudHMpICYmIGZpbHRlcjIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfSA6CiAgICAgICAgICAgICAgICBmaWx0ZXIxIDoKICAgICAgICAgICAgZmlsdGVyMjsKICAgIH0KICAgIGZ1bmN0aW9uIHJlYWRHbG9iYWxTY2hlbWEoKSB7CiAgICAgICAgZGIudmVybm8gPSBpZGJkYi52ZXJzaW9uIC8gMTA7CiAgICAgICAgZGIuX2RiU2NoZW1hID0gZ2xvYmFsU2NoZW1hID0ge307CiAgICAgICAgZGJTdG9yZU5hbWVzID0gc2xpY2UoaWRiZGIub2JqZWN0U3RvcmVOYW1lcywgMCk7CiAgICAgICAgaWYgKGRiU3RvcmVOYW1lcy5sZW5ndGggPT09IDApCiAgICAgICAgICAgIHJldHVybjsgLy8gRGF0YWJhc2UgY29udGFpbnMgbm8gc3RvcmVzLgogICAgICAgIHZhciB0cmFucyA9IGlkYmRiLnRyYW5zYWN0aW9uKHNhZmFyaU11bHRpU3RvcmVGaXgoZGJTdG9yZU5hbWVzKSwgJ3JlYWRvbmx5Jyk7CiAgICAgICAgZGJTdG9yZU5hbWVzLmZvckVhY2goZnVuY3Rpb24gKHN0b3JlTmFtZSkgewogICAgICAgICAgICB2YXIgc3RvcmUgPSB0cmFucy5vYmplY3RTdG9yZShzdG9yZU5hbWUpLCBrZXlQYXRoID0gc3RvcmUua2V5UGF0aCwgZG90dGVkID0ga2V5UGF0aCAmJiB0eXBlb2Yga2V5UGF0aCA9PT0gJ3N0cmluZycgJiYga2V5UGF0aC5pbmRleE9mKCcuJykgIT09IC0xOwogICAgICAgICAgICB2YXIgcHJpbUtleSA9IG5ldyBJbmRleFNwZWMoa2V5UGF0aCwga2V5UGF0aCB8fCAiIiwgZmFsc2UsIGZhbHNlLCAhIXN0b3JlLmF1dG9JbmNyZW1lbnQsIGtleVBhdGggJiYgdHlwZW9mIGtleVBhdGggIT09ICdzdHJpbmcnLCBkb3R0ZWQpOwogICAgICAgICAgICB2YXIgaW5kZXhlcyA9IFtdOwogICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHN0b3JlLmluZGV4TmFtZXMubGVuZ3RoOyArK2opIHsKICAgICAgICAgICAgICAgIHZhciBpZGJpbmRleCA9IHN0b3JlLmluZGV4KHN0b3JlLmluZGV4TmFtZXNbal0pOwogICAgICAgICAgICAgICAga2V5UGF0aCA9IGlkYmluZGV4LmtleVBhdGg7CiAgICAgICAgICAgICAgICBkb3R0ZWQgPSBrZXlQYXRoICYmIHR5cGVvZiBrZXlQYXRoID09PSAnc3RyaW5nJyAmJiBrZXlQYXRoLmluZGV4T2YoJy4nKSAhPT0gLTE7CiAgICAgICAgICAgICAgICB2YXIgaW5kZXggPSBuZXcgSW5kZXhTcGVjKGlkYmluZGV4Lm5hbWUsIGtleVBhdGgsICEhaWRiaW5kZXgudW5pcXVlLCAhIWlkYmluZGV4Lm11bHRpRW50cnksIGZhbHNlLCBrZXlQYXRoICYmIHR5cGVvZiBrZXlQYXRoICE9PSAnc3RyaW5nJywgZG90dGVkKTsKICAgICAgICAgICAgICAgIGluZGV4ZXMucHVzaChpbmRleCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZ2xvYmFsU2NoZW1hW3N0b3JlTmFtZV0gPSBuZXcgVGFibGVTY2hlbWEoc3RvcmVOYW1lLCBwcmltS2V5LCBpbmRleGVzLCB7fSk7CiAgICAgICAgfSk7CiAgICAgICAgc2V0QXBpT25QbGFjZShbYWxsVGFibGVzXSwga2V5cyhnbG9iYWxTY2hlbWEpLCBnbG9iYWxTY2hlbWEpOwogICAgfQogICAgZnVuY3Rpb24gYWRqdXN0VG9FeGlzdGluZ0luZGV4TmFtZXMoc2NoZW1hLCBpZGJ0cmFucykgewogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gSXNzdWUgIzMwIFByb2JsZW0gd2l0aCBleGlzdGluZyBkYiAtIGFkanVzdCB0byBleGlzdGluZyBpbmRleCBuYW1lcyB3aGVuIG1pZ3JhdGluZyBmcm9tIG5vbi1kZXhpZSBkYgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJzY2hlbWEiIHR5cGU9Ik9iamVjdCI+TWFwIGJldHdlZW4gbmFtZSBhbmQgVGFibGVTY2hlbWE8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iaWRidHJhbnMiIHR5cGU9IklEQlRyYW5zYWN0aW9uIj48L3BhcmFtPgogICAgICAgIHZhciBzdG9yZU5hbWVzID0gaWRidHJhbnMuZGIub2JqZWN0U3RvcmVOYW1lczsKICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0b3JlTmFtZXMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgdmFyIHN0b3JlTmFtZSA9IHN0b3JlTmFtZXNbaV07CiAgICAgICAgICAgIHZhciBzdG9yZSA9IGlkYnRyYW5zLm9iamVjdFN0b3JlKHN0b3JlTmFtZSk7CiAgICAgICAgICAgIGhhc0dldEFsbCA9ICdnZXRBbGwnIGluIHN0b3JlOwogICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHN0b3JlLmluZGV4TmFtZXMubGVuZ3RoOyArK2opIHsKICAgICAgICAgICAgICAgIHZhciBpbmRleE5hbWUgPSBzdG9yZS5pbmRleE5hbWVzW2pdOwogICAgICAgICAgICAgICAgdmFyIGtleVBhdGggPSBzdG9yZS5pbmRleChpbmRleE5hbWUpLmtleVBhdGg7CiAgICAgICAgICAgICAgICB2YXIgZGV4aWVOYW1lID0gdHlwZW9mIGtleVBhdGggPT09ICdzdHJpbmcnID8ga2V5UGF0aCA6ICJbIiArIHNsaWNlKGtleVBhdGgpLmpvaW4oJysnKSArICJdIjsKICAgICAgICAgICAgICAgIGlmIChzY2hlbWFbc3RvcmVOYW1lXSkgewogICAgICAgICAgICAgICAgICAgIHZhciBpbmRleFNwZWMgPSBzY2hlbWFbc3RvcmVOYW1lXS5pZHhCeU5hbWVbZGV4aWVOYW1lXTsKICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXhTcGVjKQogICAgICAgICAgICAgICAgICAgICAgICBpbmRleFNwZWMubmFtZSA9IGluZGV4TmFtZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLyBCdWcgd2l0aCBnZXRBbGwoKSBvbiBTYWZhcmkgdmVyPDYwNCBvbiBXb3JrZXJzIG9ubHksIHNlZSBkaXNjdXNzaW9uIGZvbGxvd2luZyBQUiAjNTc5CiAgICAgICAgaWYgKC9TYWZhcmkvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkgJiYKICAgICAgICAgICAgIS8oQ2hyb21lXC98RWRnZVwvKS8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSAmJgogICAgICAgICAgICBfZ2xvYmFsLldvcmtlckdsb2JhbFNjb3BlICYmIF9nbG9iYWwgaW5zdGFuY2VvZiBfZ2xvYmFsLldvcmtlckdsb2JhbFNjb3BlICYmCiAgICAgICAgICAgIFtdLmNvbmNhdChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9TYWZhcmlcLyhcZCopLykpWzFdIDwgNjA0KSB7CiAgICAgICAgICAgIGhhc0dldEFsbCA9IGZhbHNlOwogICAgICAgIH0KICAgIH0KICAgIGZ1bmN0aW9uIGZpcmVPbkJsb2NrZWQoZXYpIHsKICAgICAgICBkYi5vbigiYmxvY2tlZCIpLmZpcmUoZXYpOwogICAgICAgIC8vIFdvcmthcm91bmQgKG5vdCBmdWxseSopIGZvciBtaXNzaW5nICJ2ZXJzaW9uY2hhbmdlIiBldmVudCBpbiBJRSxFZGdlIGFuZCBTYWZhcmk6CiAgICAgICAgY29ubmVjdGlvbnMKICAgICAgICAgICAgLmZpbHRlcihmdW5jdGlvbiAoYykgeyByZXR1cm4gYy5uYW1lID09PSBkYi5uYW1lICYmIGMgIT09IGRiICYmICFjLl92Y0ZpcmVkOyB9KQogICAgICAgICAgICAubWFwKGZ1bmN0aW9uIChjKSB7IHJldHVybiBjLm9uKCJ2ZXJzaW9uY2hhbmdlIikuZmlyZShldik7IH0pOwogICAgfQogICAgZXh0ZW5kKHRoaXMsIHsKICAgICAgICBDb2xsZWN0aW9uOiBDb2xsZWN0aW9uLAogICAgICAgIFRhYmxlOiBUYWJsZSwKICAgICAgICBUcmFuc2FjdGlvbjogVHJhbnNhY3Rpb24sCiAgICAgICAgVmVyc2lvbjogVmVyc2lvbiwKICAgICAgICBXaGVyZUNsYXVzZTogV2hlcmVDbGF1c2UKICAgIH0pOwogICAgaW5pdCgpOwogICAgYWRkb25zLmZvckVhY2goZnVuY3Rpb24gKGZuKSB7CiAgICAgICAgZm4oZGIpOwogICAgfSk7Cn0KZnVuY3Rpb24gcGFyc2VUeXBlKHR5cGUpIHsKICAgIGlmICh0eXBlb2YgdHlwZSA9PT0gJ2Z1bmN0aW9uJykgewogICAgICAgIHJldHVybiBuZXcgdHlwZSgpOwogICAgfQogICAgZWxzZSBpZiAoaXNBcnJheSh0eXBlKSkgewogICAgICAgIHJldHVybiBbcGFyc2VUeXBlKHR5cGVbMF0pXTsKICAgIH0KICAgIGVsc2UgaWYgKHR5cGUgJiYgdHlwZW9mIHR5cGUgPT09ICdvYmplY3QnKSB7CiAgICAgICAgdmFyIHJ2ID0ge307CiAgICAgICAgYXBwbHlTdHJ1Y3R1cmUocnYsIHR5cGUpOwogICAgICAgIHJldHVybiBydjsKICAgIH0KICAgIGVsc2UgewogICAgICAgIHJldHVybiB0eXBlOwogICAgfQp9CmZ1bmN0aW9uIGFwcGx5U3RydWN0dXJlKG9iaiwgc3RydWN0dXJlKSB7CiAgICBrZXlzKHN0cnVjdHVyZSkuZm9yRWFjaChmdW5jdGlvbiAobWVtYmVyKSB7CiAgICAgICAgdmFyIHZhbHVlID0gcGFyc2VUeXBlKHN0cnVjdHVyZVttZW1iZXJdKTsKICAgICAgICBvYmpbbWVtYmVyXSA9IHZhbHVlOwogICAgfSk7CiAgICByZXR1cm4gb2JqOwp9CmZ1bmN0aW9uIGhvb2tlZEV2ZW50U3VjY2Vzc0hhbmRsZXIocmVzb2x2ZSkgewogICAgLy8gd3JhcCgpIGlzIG5lZWRlZCB3aGVuIGNhbGxpbmcgaG9va3MgYmVjYXVzZSB0aGUgcmFyZSBzY2VuYXJpbyBvZjoKICAgIC8vICAqIGhvb2sgZG9lcyBhIGRiIG9wZXJhdGlvbiB0aGF0IGZhaWxzIGltbWVkaWF0ZWx5IChJREIgdGhyb3dzIGV4Y2VwdGlvbikKICAgIC8vICAgIEZvciBjYWxsaW5nIGRiIG9wZXJhdGlvbnMgb24gY29ycmVjdCB0cmFuc2FjdGlvbiwgd3JhcCBtYWtlcyBzdXJlIHRvIHNldCBQU0QgY29ycmVjdGx5LgogICAgLy8gICAgd3JhcCgpIHdpbGwgYWxzbyBleGVjdXRlIGluIGEgdmlydHVhbCB0aWNrLgogICAgLy8gICogSWYgbm90IHdyYXBwZWQgaW4gYSB2aXJ0dWFsIHRpY2ssIGRpcmVjdCBleGNlcHRpb24gd2lsbCBsYXVuY2ggYSBuZXcgcGh5c2ljYWwgdGljay4KICAgIC8vICAqIElmIHRoaXMgd2FzIHRoZSBsYXN0IGV2ZW50IGluIHRoZSBidWxrLCB0aGUgcHJvbWlzZSB3aWxsIHJlc29sdmUgYWZ0ZXIgYSBwaHlzaWNhbCB0aWNrCiAgICAvLyAgICBhbmQgdGhlIHRyYW5zYWN0aW9uIHdpbGwgaGF2ZSBjb21taXR0ZWQgYWxyZWFkeS4KICAgIC8vIElmIG5vIGhvb2ssIHRoZSB2aXJ0dWFsIHRpY2sgd2lsbCBiZSBleGVjdXRlZCBpbiB0aGUgcmVqZWN0KCkvcmVzb2x2ZSBvZiB0aGUgZmluYWwgcHJvbWlzZSwKICAgIC8vIGJlY2F1c2UgaXQgaXMgYWx3YXlzIG1hcmtlZCB3aXRoIF9saWIgPSB0cnVlIHdoZW4gY3JlYXRlZCB1c2luZyBUcmFuc2FjdGlvbi5fcHJvbWlzZSgpLgogICAgcmV0dXJuIHdyYXAoZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgdmFyIHJlcSA9IGV2ZW50LnRhcmdldCwgY3R4ID0gcmVxLl9ob29rQ3R4LCAvLyBDb250YWlucyB0aGUgaG9vayBlcnJvciBoYW5kbGVyLiBQdXQgaGVyZSBpbnN0ZWFkIG9mIGNsb3N1cmUgdG8gYm9vc3QgcGVyZm9ybWFuY2UuCiAgICAgICAgcmVzdWx0ID0gY3R4LnZhbHVlIHx8IHJlcS5yZXN1bHQsIC8vIFBhc3MgdGhlIG9iamVjdCB2YWx1ZSBvbiB1cGRhdGVzLiBUaGUgcmVzdWx0IGZyb20gSURCIGlzIHRoZSBwcmltYXJ5IGtleS4KICAgICAgICBob29rU3VjY2Vzc0hhbmRsZXIgPSBjdHggJiYgY3R4Lm9uc3VjY2VzczsKICAgICAgICBob29rU3VjY2Vzc0hhbmRsZXIgJiYgaG9va1N1Y2Nlc3NIYW5kbGVyKHJlc3VsdCk7CiAgICAgICAgcmVzb2x2ZSAmJiByZXNvbHZlKHJlc3VsdCk7CiAgICB9LCByZXNvbHZlKTsKfQpmdW5jdGlvbiBldmVudFJlamVjdEhhbmRsZXIocmVqZWN0KSB7CiAgICByZXR1cm4gd3JhcChmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICBwcmV2ZW50RGVmYXVsdChldmVudCk7CiAgICAgICAgcmVqZWN0KGV2ZW50LnRhcmdldC5lcnJvcik7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfSk7Cn0KZnVuY3Rpb24gZXZlbnRTdWNjZXNzSGFuZGxlcihyZXNvbHZlKSB7CiAgICByZXR1cm4gd3JhcChmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICByZXNvbHZlKGV2ZW50LnRhcmdldC5yZXN1bHQpOwogICAgfSk7Cn0KZnVuY3Rpb24gaG9va2VkRXZlbnRSZWplY3RIYW5kbGVyKHJlamVjdCkgewogICAgcmV0dXJuIHdyYXAoZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgLy8gU2VlIGNvbW1lbnQgb24gaG9va2VkRXZlbnRTdWNjZXNzSGFuZGxlcigpIHdoeSB3cmFwKCkgaXMgbmVlZGVkIG9ubHkgd2hlbiBzdXBwb3J0aW5nIGhvb2tzLgogICAgICAgIHZhciByZXEgPSBldmVudC50YXJnZXQsIGVyciA9IHJlcS5lcnJvciwgY3R4ID0gcmVxLl9ob29rQ3R4LCAvLyBDb250YWlucyB0aGUgaG9vayBlcnJvciBoYW5kbGVyLiBQdXQgaGVyZSBpbnN0ZWFkIG9mIGNsb3N1cmUgdG8gYm9vc3QgcGVyZm9ybWFuY2UuCiAgICAgICAgaG9va0Vycm9ySGFuZGxlciA9IGN0eCAmJiBjdHgub25lcnJvcjsKICAgICAgICBob29rRXJyb3JIYW5kbGVyICYmIGhvb2tFcnJvckhhbmRsZXIoZXJyKTsKICAgICAgICBwcmV2ZW50RGVmYXVsdChldmVudCk7CiAgICAgICAgcmVqZWN0KGVycik7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfSk7Cn0KZnVuY3Rpb24gcHJldmVudERlZmF1bHQoZXZlbnQpIHsKICAgIGlmIChldmVudC5zdG9wUHJvcGFnYXRpb24pCiAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7CiAgICBpZiAoZXZlbnQucHJldmVudERlZmF1bHQpCiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKfQpmdW5jdGlvbiBhd2FpdEl0ZXJhdG9yKGl0ZXJhdG9yKSB7CiAgICB2YXIgY2FsbE5leHQgPSBmdW5jdGlvbiAocmVzdWx0KSB7IHJldHVybiBpdGVyYXRvci5uZXh0KHJlc3VsdCk7IH0sIGRvVGhyb3cgPSBmdW5jdGlvbiAoZXJyb3IpIHsgcmV0dXJuIGl0ZXJhdG9yLnRocm93KGVycm9yKTsgfSwgb25TdWNjZXNzID0gc3RlcChjYWxsTmV4dCksIG9uRXJyb3IgPSBzdGVwKGRvVGhyb3cpOwogICAgZnVuY3Rpb24gc3RlcChnZXROZXh0KSB7CiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh2YWwpIHsKICAgICAgICAgICAgdmFyIG5leHQgPSBnZXROZXh0KHZhbCksIHZhbHVlID0gbmV4dC52YWx1ZTsKICAgICAgICAgICAgcmV0dXJuIG5leHQuZG9uZSA/IHZhbHVlIDoKICAgICAgICAgICAgICAgICghdmFsdWUgfHwgdHlwZW9mIHZhbHVlLnRoZW4gIT09ICdmdW5jdGlvbicgPwogICAgICAgICAgICAgICAgICAgIGlzQXJyYXkodmFsdWUpID8gUHJvbWlzZS5hbGwodmFsdWUpLnRoZW4ob25TdWNjZXNzLCBvbkVycm9yKSA6IG9uU3VjY2Vzcyh2YWx1ZSkgOgogICAgICAgICAgICAgICAgICAgIHZhbHVlLnRoZW4ob25TdWNjZXNzLCBvbkVycm9yKSk7CiAgICAgICAgfTsKICAgIH0KICAgIHJldHVybiBzdGVwKGNhbGxOZXh0KSgpOwp9Ci8vCi8vIEluZGV4U3BlYyBzdHJ1Y3QKLy8KZnVuY3Rpb24gSW5kZXhTcGVjKG5hbWUsIGtleVBhdGgsIHVuaXF1ZSwgbXVsdGksIGF1dG8sIGNvbXBvdW5kLCBkb3R0ZWQpIHsKICAgIC8vLyA8cGFyYW0gbmFtZT0ibmFtZSIgdHlwZT0iU3RyaW5nIj48L3BhcmFtPgogICAgLy8vIDxwYXJhbSBuYW1lPSJrZXlQYXRoIiB0eXBlPSJTdHJpbmciPjwvcGFyYW0+CiAgICAvLy8gPHBhcmFtIG5hbWU9InVuaXF1ZSIgdHlwZT0iQm9vbGVhbiI+PC9wYXJhbT4KICAgIC8vLyA8cGFyYW0gbmFtZT0ibXVsdGkiIHR5cGU9IkJvb2xlYW4iPjwvcGFyYW0+CiAgICAvLy8gPHBhcmFtIG5hbWU9ImF1dG8iIHR5cGU9IkJvb2xlYW4iPjwvcGFyYW0+CiAgICAvLy8gPHBhcmFtIG5hbWU9ImNvbXBvdW5kIiB0eXBlPSJCb29sZWFuIj48L3BhcmFtPgogICAgLy8vIDxwYXJhbSBuYW1lPSJkb3R0ZWQiIHR5cGU9IkJvb2xlYW4iPjwvcGFyYW0+CiAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgdGhpcy5rZXlQYXRoID0ga2V5UGF0aDsKICAgIHRoaXMudW5pcXVlID0gdW5pcXVlOwogICAgdGhpcy5tdWx0aSA9IG11bHRpOwogICAgdGhpcy5hdXRvID0gYXV0bzsKICAgIHRoaXMuY29tcG91bmQgPSBjb21wb3VuZDsKICAgIHRoaXMuZG90dGVkID0gZG90dGVkOwogICAgdmFyIGtleVBhdGhTcmMgPSB0eXBlb2Yga2V5UGF0aCA9PT0gJ3N0cmluZycgPyBrZXlQYXRoIDoga2V5UGF0aCAmJiAoJ1snICsgW10uam9pbi5jYWxsKGtleVBhdGgsICcrJykgKyAnXScpOwogICAgdGhpcy5zcmMgPSAodW5pcXVlID8gJyYnIDogJycpICsgKG11bHRpID8gJyonIDogJycpICsgKGF1dG8gPyAiKysiIDogIiIpICsga2V5UGF0aFNyYzsKfQovLwovLyBUYWJsZVNjaGVtYSBzdHJ1Y3QKLy8KZnVuY3Rpb24gVGFibGVTY2hlbWEobmFtZSwgcHJpbUtleSwgaW5kZXhlcywgaW5zdGFuY2VUZW1wbGF0ZSkgewogICAgLy8vIDxwYXJhbSBuYW1lPSJuYW1lIiB0eXBlPSJTdHJpbmciPjwvcGFyYW0+CiAgICAvLy8gPHBhcmFtIG5hbWU9InByaW1LZXkiIHR5cGU9IkluZGV4U3BlYyI+PC9wYXJhbT4KICAgIC8vLyA8cGFyYW0gbmFtZT0iaW5kZXhlcyIgdHlwZT0iQXJyYXkiIGVsZW1lbnRUeXBlPSJJbmRleFNwZWMiPjwvcGFyYW0+CiAgICAvLy8gPHBhcmFtIG5hbWU9Imluc3RhbmNlVGVtcGxhdGUiIHR5cGU9Ik9iamVjdCI+PC9wYXJhbT4KICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICB0aGlzLnByaW1LZXkgPSBwcmltS2V5IHx8IG5ldyBJbmRleFNwZWMoKTsKICAgIHRoaXMuaW5kZXhlcyA9IGluZGV4ZXMgfHwgW25ldyBJbmRleFNwZWMoKV07CiAgICB0aGlzLmluc3RhbmNlVGVtcGxhdGUgPSBpbnN0YW5jZVRlbXBsYXRlOwogICAgdGhpcy5tYXBwZWRDbGFzcyA9IG51bGw7CiAgICB0aGlzLmlkeEJ5TmFtZSA9IGFycmF5VG9PYmplY3QoaW5kZXhlcywgZnVuY3Rpb24gKGluZGV4KSB7IHJldHVybiBbaW5kZXgubmFtZSwgaW5kZXhdOyB9KTsKfQpmdW5jdGlvbiBzYWZhcmlNdWx0aVN0b3JlRml4KHN0b3JlTmFtZXMpIHsKICAgIHJldHVybiBzdG9yZU5hbWVzLmxlbmd0aCA9PT0gMSA/IHN0b3JlTmFtZXNbMF0gOiBzdG9yZU5hbWVzOwp9CmZ1bmN0aW9uIGdldE5hdGl2ZUdldERhdGFiYXNlTmFtZXNGbihpbmRleGVkREIpIHsKICAgIHZhciBmbiA9IGluZGV4ZWREQiAmJiAoaW5kZXhlZERCLmdldERhdGFiYXNlTmFtZXMgfHwgaW5kZXhlZERCLndlYmtpdEdldERhdGFiYXNlTmFtZXMpOwogICAgcmV0dXJuIGZuICYmIGZuLmJpbmQoaW5kZXhlZERCKTsKfQovLyBFeHBvcnQgRXJyb3IgY2xhc3Nlcwpwcm9wcyhEZXhpZSwgZnVsbE5hbWVFeGNlcHRpb25zKTsgLy8gRGV4aWUuWFhYRXJyb3IgPSBjbGFzcyBYWFhFcnJvciB7Li4ufTsKLy8KLy8gU3RhdGljIG1ldGhvZHMgYW5kIHByb3BlcnRpZXMKLy8gCnByb3BzKERleGllLCB7CiAgICAvLwogICAgLy8gU3RhdGljIGRlbGV0ZSgpIG1ldGhvZC4KICAgIC8vCiAgICBkZWxldGU6IGZ1bmN0aW9uIChkYXRhYmFzZU5hbWUpIHsKICAgICAgICB2YXIgZGIgPSBuZXcgRGV4aWUoZGF0YWJhc2VOYW1lKSwgcHJvbWlzZSA9IGRiLmRlbGV0ZSgpOwogICAgICAgIHByb21pc2Uub25ibG9ja2VkID0gZnVuY3Rpb24gKGZuKSB7CiAgICAgICAgICAgIGRiLm9uKCJibG9ja2VkIiwgZm4pOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9OwogICAgICAgIHJldHVybiBwcm9taXNlOwogICAgfSwKICAgIC8vCiAgICAvLyBTdGF0aWMgZXhpc3RzKCkgbWV0aG9kLgogICAgLy8KICAgIGV4aXN0czogZnVuY3Rpb24gKG5hbWUpIHsKICAgICAgICByZXR1cm4gbmV3IERleGllKG5hbWUpLm9wZW4oKS50aGVuKGZ1bmN0aW9uIChkYikgewogICAgICAgICAgICBkYi5jbG9zZSgpOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9KS5jYXRjaChEZXhpZS5Ob1N1Y2hEYXRhYmFzZUVycm9yLCBmdW5jdGlvbiAoKSB7IHJldHVybiBmYWxzZTsgfSk7CiAgICB9LAogICAgLy8KICAgIC8vIFN0YXRpYyBtZXRob2QgZm9yIHJldHJpZXZpbmcgYSBsaXN0IG9mIGFsbCBleGlzdGluZyBkYXRhYmFzZXMgYXQgY3VycmVudCBob3N0LgogICAgLy8KICAgIGdldERhdGFiYXNlTmFtZXM6IGZ1bmN0aW9uIChjYikgewogICAgICAgIHZhciBnZXREYXRhYmFzZU5hbWVzID0gZ2V0TmF0aXZlR2V0RGF0YWJhc2VOYW1lc0ZuKERleGllLmRlcGVuZGVuY2llcy5pbmRleGVkREIpOwogICAgICAgIHJldHVybiBnZXREYXRhYmFzZU5hbWVzID8gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkgewogICAgICAgICAgICB2YXIgcmVxID0gZ2V0RGF0YWJhc2VOYW1lcygpOwogICAgICAgICAgICByZXEub25zdWNjZXNzID0gZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgICAgICByZXNvbHZlKHNsaWNlKGV2ZW50LnRhcmdldC5yZXN1bHQsIDApKTsgLy8gQ29udmVyc3QgRE9NU3RyaW5nTGlzdCB0byBBcnJheTxTdHJpbmc+CiAgICAgICAgICAgIH07CiAgICAgICAgICAgIHJlcS5vbmVycm9yID0gZXZlbnRSZWplY3RIYW5kbGVyKHJlamVjdCk7CiAgICAgICAgfSkudGhlbihjYikgOiBkYk5hbWVzREIuZGJuYW1lcy50b0NvbGxlY3Rpb24oKS5wcmltYXJ5S2V5cyhjYik7CiAgICB9LAogICAgZGVmaW5lQ2xhc3M6IGZ1bmN0aW9uICgpIHsKICAgICAgICAvLyBEZWZhdWx0IGNvbnN0cnVjdG9yIGFibGUgdG8gY29weSBnaXZlbiBwcm9wZXJ0aWVzIGludG8gdGhpcyBvYmplY3QuCiAgICAgICAgZnVuY3Rpb24gQ2xhc3MocHJvcGVydGllcykgewogICAgICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InByb3BlcnRpZXMiIHR5cGU9Ik9iamVjdCIgb3B0aW9uYWw9InRydWUiPlByb3BlcnRpZXMgdG8gaW5pdGlhbGl6ZSBvYmplY3Qgd2l0aC4KICAgICAgICAgICAgLy8vIDwvcGFyYW0+CiAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzKQogICAgICAgICAgICAgICAgZXh0ZW5kKHRoaXMsIHByb3BlcnRpZXMpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gQ2xhc3M7CiAgICB9LAogICAgYXBwbHlTdHJ1Y3R1cmU6IGFwcGx5U3RydWN0dXJlLAogICAgaWdub3JlVHJhbnNhY3Rpb246IGZ1bmN0aW9uIChzY29wZUZ1bmMpIHsKICAgICAgICAvLyBJbiBjYXNlIGNhbGxlciBpcyB3aXRoaW4gYSB0cmFuc2FjdGlvbiBidXQgbmVlZHMgdG8gY3JlYXRlIGEgc2VwYXJhdGUgdHJhbnNhY3Rpb24uCiAgICAgICAgLy8gRXhhbXBsZSBvZiB1c2FnZToKICAgICAgICAvLwogICAgICAgIC8vIExldCdzIHNheSB3ZSBoYXZlIGEgbG9nZ2VyIGZ1bmN0aW9uIGluIG91ciBhcHAuIE90aGVyIGFwcGxpY2F0aW9uLWxvZ2ljIHNob3VsZCBiZSB1bmF3YXJlIG9mIHRoZQogICAgICAgIC8vIGxvZ2dlciBmdW5jdGlvbiBhbmQgbm90IG5lZWQgdG8gaW5jbHVkZSB0aGUgJ2xvZ2VudHJpZXMnIHRhYmxlIGluIGFsbCB0cmFuc2FjdGlvbiBpdCBwZXJmb3Jtcy4KICAgICAgICAvLyBUaGUgbG9nZ2luZyBzaG91bGQgYWx3YXlzIGJlIGRvbmUgaW4gYSBzZXBhcmF0ZSB0cmFuc2FjdGlvbiBhbmQgbm90IGJlIGRlcGVuZGFudCBvbiB0aGUgY3VycmVudAogICAgICAgIC8vIHJ1bm5pbmcgdHJhbnNhY3Rpb24gY29udGV4dC4gVGhlbiB5b3UgY291bGQgdXNlIERleGllLmlnbm9yZVRyYW5zYWN0aW9uKCkgdG8gcnVuIGNvZGUgdGhhdCBzdGFydHMgYSBuZXcgdHJhbnNhY3Rpb24uCiAgICAgICAgLy8KICAgICAgICAvLyAgICAgRGV4aWUuaWdub3JlVHJhbnNhY3Rpb24oZnVuY3Rpb24oKSB7CiAgICAgICAgLy8gICAgICAgICBkYi5sb2dlbnRyaWVzLmFkZChuZXdMb2dFbnRyeSk7CiAgICAgICAgLy8gICAgIH0pOwogICAgICAgIC8vCiAgICAgICAgLy8gVW5sZXNzIHVzaW5nIERleGllLmlnbm9yZVRyYW5zYWN0aW9uKCksIHRoZSBhYm92ZSBleGFtcGxlIHdvdWxkIHRyeSB0byByZXVzZSB0aGUgY3VycmVudCB0cmFuc2FjdGlvbgogICAgICAgIC8vIGluIGN1cnJlbnQgUHJvbWlzZS1zY29wZS4KICAgICAgICAvLwogICAgICAgIC8vIEFuIGFsdGVybmF0aXZlIHRvIERleGllLmlnbm9yZVRyYW5zYWN0aW9uKCkgd291bGQgYmUgc2V0SW1tZWRpYXRlKCkgb3Igc2V0VGltZW91dCgpLiBUaGUgcmVhc29uIHdlIHN0aWxsIHByb3ZpZGUgYW4KICAgICAgICAvLyBBUEkgZm9yIHRoaXMgYmVjYXVzZQogICAgICAgIC8vICAxKSBUaGUgaW50ZW50aW9uIG9mIHdyaXRpbmcgdGhlIHN0YXRlbWVudCBjb3VsZCBiZSB1bmNsZWFyIGlmIHVzaW5nIHNldEltbWVkaWF0ZSgpIG9yIHNldFRpbWVvdXQoKS4KICAgICAgICAvLyAgMikgc2V0VGltZW91dCgpIHdvdWxkIHdhaXQgdW5uZXNjZXNzYXJ5IHVudGlsIGZpcmluZy4gVGhpcyBpcyBob3dldmVyIG5vdCB0aGUgY2FzZSB3aXRoIHNldEltbWVkaWF0ZSgpLgogICAgICAgIC8vICAzKSBzZXRJbW1lZGlhdGUoKSBpcyBub3Qgc3VwcG9ydGVkIGluIHRoZSBFUyBzdGFuZGFyZC4KICAgICAgICAvLyAgNCkgWW91IG1pZ2h0IHdhbnQgdG8ga2VlcCBvdGhlciBQU0Qgc3RhdGUgdGhhdCB3YXMgc2V0IGluIGEgcGFyZW50IFBTRCwgc3VjaCBhcyBQU0QubGV0VGhyb3VnaC4KICAgICAgICByZXR1cm4gUFNELnRyYW5zID8KICAgICAgICAgICAgdXNlUFNEKFBTRC50cmFuc2xlc3MsIHNjb3BlRnVuYykgOiAvLyBVc2UgdGhlIGNsb3Nlc3QgcGFyZW50IHRoYXQgd2FzIG5vbi10cmFuc2FjdGlvbmFsLgogICAgICAgICAgICBzY29wZUZ1bmMoKTsgLy8gTm8gbmVlZCB0byBjaGFuZ2Ugc2NvcGUgYmVjYXVzZSB0aGVyZSBpcyBubyBvbmdvaW5nIHRyYW5zYWN0aW9uLgogICAgfSwKICAgIHZpcDogZnVuY3Rpb24gKGZuKSB7CiAgICAgICAgLy8gVG8gYmUgdXNlZCBieSBzdWJzY3JpYmVycyB0byB0aGUgb24oJ3JlYWR5JykgZXZlbnQuCiAgICAgICAgLy8gVGhpcyB3aWxsIGxldCBjYWxsZXIgdGhyb3VnaCB0byBhY2Nlc3MgREIgZXZlbiB3aGVuIGl0IGlzIGJsb2NrZWQgd2hpbGUgdGhlIGRiLnJlYWR5KCkgc3Vic2NyaWJlcnMgYXJlIGZpcmluZy4KICAgICAgICAvLyBUaGlzIHdvdWxkIGhhdmUgd29ya2VkIGF1dG9tYXRpY2FsbHkgaWYgd2Ugd2VyZSBjZXJ0YWluIHRoYXQgdGhlIFByb3ZpZGVyIHdhcyB1c2luZyBEZXhpZS5Qcm9taXNlIGZvciBhbGwgYXN5bmNyb25pYyBvcGVyYXRpb25zLiBUaGUgcHJvbWlzZSBQU0QKICAgICAgICAvLyBmcm9tIHRoZSBwcm92aWRlci5jb25uZWN0KCkgY2FsbCB3b3VsZCB0aGVuIGJlIGRlcml2ZWQgYWxsIHRoZSB3YXkgdG8gd2hlbiBwcm92aWRlciB3b3VsZCBjYWxsIGxvY2FsRGF0YWJhc2UuYXBwbHlDaGFuZ2VzKCkuIEJ1dCBzaW5jZQogICAgICAgIC8vIHRoZSBwcm92aWRlciBtb3JlIGxpa2VseSBpcyB1c2luZyBub24tcHJvbWlzZSBhc3luYyBBUElzIG9yIG90aGVyIHRoZW5hYmxlIGltcGxlbWVudGF0aW9ucywgd2UgY2Fubm90IGFzc3VtZSB0aGF0LgogICAgICAgIC8vIE5vdGUgdGhhdCB0aGlzIG1ldGhvZCBpcyBvbmx5IHVzZWZ1bCBmb3Igb24oJ3JlYWR5Jykgc3Vic2NyaWJlcnMgdGhhdCBpcyByZXR1cm5pbmcgYSBQcm9taXNlIGZyb20gdGhlIGV2ZW50LiBJZiBub3QgdXNpbmcgdmlwKCkKICAgICAgICAvLyB0aGUgZGF0YWJhc2UgY291bGQgZGVhZGxvY2sgc2luY2UgaXQgd29udCBvcGVuIHVudGlsIHRoZSByZXR1cm5lZCBQcm9taXNlIGlzIHJlc29sdmVkLCBhbmQgYW55IG5vbi1WSVBlZCBvcGVyYXRpb24gc3RhcnRlZCBieQogICAgICAgIC8vIHRoZSBjYWxsZXIgd2lsbCBub3QgcmVzb2x2ZSB1bnRpbCBkYXRhYmFzZSBpcyBvcGVuZWQuCiAgICAgICAgcmV0dXJuIG5ld1Njb3BlKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgUFNELmxldFRocm91Z2ggPSB0cnVlOyAvLyBNYWtlIHN1cmUgd2UgYXJlIGxldCB0aHJvdWdoIGlmIHN0aWxsIGJsb2NraW5nIGRiIGR1ZSB0byBvbnJlYWR5IGlzIGZpcmluZy4KICAgICAgICAgICAgcmV0dXJuIGZuKCk7CiAgICAgICAgfSk7CiAgICB9LAogICAgYXN5bmM6IGZ1bmN0aW9uIChnZW5lcmF0b3JGbikgewogICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICB2YXIgcnYgPSBhd2FpdEl0ZXJhdG9yKGdlbmVyYXRvckZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpOwogICAgICAgICAgICAgICAgaWYgKCFydiB8fCB0eXBlb2YgcnYudGhlbiAhPT0gJ2Z1bmN0aW9uJykKICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJ2KTsKICAgICAgICAgICAgICAgIHJldHVybiBydjsKICAgICAgICAgICAgfQogICAgICAgICAgICBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdGlvbihlKTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9LAogICAgc3Bhd246IGZ1bmN0aW9uIChnZW5lcmF0b3JGbiwgYXJncywgdGhpeikgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHZhciBydiA9IGF3YWl0SXRlcmF0b3IoZ2VuZXJhdG9yRm4uYXBwbHkodGhpeiwgYXJncyB8fCBbXSkpOwogICAgICAgICAgICBpZiAoIXJ2IHx8IHR5cGVvZiBydi50aGVuICE9PSAnZnVuY3Rpb24nKQogICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShydik7CiAgICAgICAgICAgIHJldHVybiBydjsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKGUpIHsKICAgICAgICAgICAgcmV0dXJuIHJlamVjdGlvbihlKTsKICAgICAgICB9CiAgICB9LAogICAgLy8gRGV4aWUuY3VycmVudFRyYW5zYWN0aW9uIHByb3BlcnR5CiAgICBjdXJyZW50VHJhbnNhY3Rpb246IHsKICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIFBTRC50cmFucyB8fCBudWxsOyB9CiAgICB9LAogICAgd2FpdEZvcjogZnVuY3Rpb24gKHByb21pc2VPckZ1bmN0aW9uLCBvcHRpb25hbFRpbWVvdXQpIHsKICAgICAgICAvLyBJZiBhIGZ1bmN0aW9uIGlzIHByb3ZpZGVkLCBpbnZva2UgaXQgYW5kIHBhc3MgdGhlIHJldHVybmluZyB2YWx1ZSB0byBUcmFuc2FjdGlvbi53YWl0Rm9yKCkKICAgICAgICB2YXIgcHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSh0eXBlb2YgcHJvbWlzZU9yRnVuY3Rpb24gPT09ICdmdW5jdGlvbicgPyBEZXhpZS5pZ25vcmVUcmFuc2FjdGlvbihwcm9taXNlT3JGdW5jdGlvbikgOiBwcm9taXNlT3JGdW5jdGlvbikKICAgICAgICAgICAgLnRpbWVvdXQob3B0aW9uYWxUaW1lb3V0IHx8IDYwMDAwKTsgLy8gRGVmYXVsdCB0aGUgdGltZW91dCB0byBvbmUgbWludXRlLiBDYWxsZXIgbWF5IHNwZWNpZnkgSW5maW5pdHkgaWYgcmVxdWlyZWQuICAgICAgIAogICAgICAgIC8vIFJ1biBnaXZlbiBwcm9taXNlIG9uIGN1cnJlbnQgdHJhbnNhY3Rpb24uIElmIG5vIGN1cnJlbnQgdHJhbnNhY3Rpb24sIGp1c3QgcmV0dXJuIGEgRGV4aWUgcHJvbWlzZSBiYXNlZAogICAgICAgIC8vIG9uIGdpdmVuIHZhbHVlLgogICAgICAgIHJldHVybiBQU0QudHJhbnMgPyBQU0QudHJhbnMud2FpdEZvcihwcm9taXNlKSA6IHByb21pc2U7CiAgICB9LAogICAgLy8gRXhwb3J0IG91ciBQcm9taXNlIGltcGxlbWVudGF0aW9uIHNpbmNlIGl0IGNhbiBiZSBoYW5keSBhcyBhIHN0YW5kYWxvbmUgUHJvbWlzZSBpbXBsZW1lbnRhdGlvbgogICAgUHJvbWlzZTogUHJvbWlzZSwKICAgIC8vIERleGllLmRlYnVnIHByb3B0ZXJ5OgogICAgLy8gRGV4aWUuZGVidWcgPSBmYWxzZQogICAgLy8gRGV4aWUuZGVidWcgPSB0cnVlCiAgICAvLyBEZXhpZS5kZWJ1ZyA9ICJkZXhpZSIgLSBkb24ndCBoaWRlIGRleGllJ3Mgc3RhY2sgZnJhbWVzLgogICAgZGVidWc6IHsKICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGRlYnVnOyB9LAogICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgIHNldERlYnVnKHZhbHVlLCB2YWx1ZSA9PT0gJ2RleGllJyA/IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRydWU7IH0gOiBkZXhpZVN0YWNrRnJhbWVGaWx0ZXIpOwogICAgICAgIH0KICAgIH0sCiAgICAvLyBFeHBvcnQgb3VyIGRlcml2ZS9leHRlbmQvb3ZlcnJpZGUgbWV0aG9kb2xvZ3kKICAgIGRlcml2ZTogZGVyaXZlLAogICAgZXh0ZW5kOiBleHRlbmQsCiAgICBwcm9wczogcHJvcHMsCiAgICBvdmVycmlkZTogb3ZlcnJpZGUsCiAgICAvLyBFeHBvcnQgb3VyIEV2ZW50cygpIGZ1bmN0aW9uIC0gY2FuIGJlIGhhbmR5IGFzIGEgdG9vbGtpdAogICAgRXZlbnRzOiBFdmVudHMsCiAgICAvLyBVdGlsaXRpZXMKICAgIGdldEJ5S2V5UGF0aDogZ2V0QnlLZXlQYXRoLAogICAgc2V0QnlLZXlQYXRoOiBzZXRCeUtleVBhdGgsCiAgICBkZWxCeUtleVBhdGg6IGRlbEJ5S2V5UGF0aCwKICAgIHNoYWxsb3dDbG9uZTogc2hhbGxvd0Nsb25lLAogICAgZGVlcENsb25lOiBkZWVwQ2xvbmUsCiAgICBnZXRPYmplY3REaWZmOiBnZXRPYmplY3REaWZmLAogICAgYXNhcDogYXNhcCwKICAgIG1heEtleTogbWF4S2V5LAogICAgbWluS2V5OiBtaW5LZXksCiAgICAvLyBBZGRvbiByZWdpc3RyeQogICAgYWRkb25zOiBbXSwKICAgIC8vIEdsb2JhbCBEQiBjb25uZWN0aW9uIGxpc3QKICAgIGNvbm5lY3Rpb25zOiBjb25uZWN0aW9ucywKICAgIE11bHRpTW9kaWZ5RXJyb3I6IGV4Y2VwdGlvbnMuTW9kaWZ5LAogICAgZXJybmFtZXM6IGVycm5hbWVzLAogICAgLy8gRXhwb3J0IG90aGVyIHN0YXRpYyBjbGFzc2VzCiAgICBJbmRleFNwZWM6IEluZGV4U3BlYywKICAgIFRhYmxlU2NoZW1hOiBUYWJsZVNjaGVtYSwKICAgIC8vCiAgICAvLyBEZXBlbmRlbmNpZXMKICAgIC8vCiAgICAvLyBUaGVzZSB3aWxsIGF1dG9tYXRpY2FsbHkgd29yayBpbiBicm93c2VycyB3aXRoIGluZGV4ZWREQiBzdXBwb3J0LCBvciB3aGVyZSBhbiBpbmRleGVkREIgcG9seWZpbGwgaGFzIGJlZW4gaW5jbHVkZWQuCiAgICAvLwogICAgLy8gSW4gbm9kZS5qcywgaG93ZXZlciwgdGhlc2UgcHJvcGVydGllcyBtdXN0IGJlIHNldCAibWFudWFsbHkiIGJlZm9yZSBpbnN0YW5zaWF0aW5nIGEgbmV3IERleGllKCkuCiAgICAvLyBGb3Igbm9kZS5qcywgeW91IG5lZWQgdG8gcmVxdWlyZSBpbmRleGVkZGItanMgb3Igc2ltaWxhciBhbmQgdGhlbiBzZXQgdGhlc2UgZGVwcy4KICAgIC8vCiAgICBkZXBlbmRlbmNpZXM6IChmdW5jdGlvbiAoKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgIC8vIFJlcXVpcmVkOgogICAgICAgICAgICAgICAgaW5kZXhlZERCOiBfZ2xvYmFsLmluZGV4ZWREQiB8fCBfZ2xvYmFsLm1vekluZGV4ZWREQiB8fCBfZ2xvYmFsLndlYmtpdEluZGV4ZWREQiB8fCBfZ2xvYmFsLm1zSW5kZXhlZERCLAogICAgICAgICAgICAgICAgSURCS2V5UmFuZ2U6IF9nbG9iYWwuSURCS2V5UmFuZ2UgfHwgX2dsb2JhbC53ZWJraXRJREJLZXlSYW5nZQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgICBjYXRjaCAoZSkgewogICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgaW5kZXhlZERCOiBudWxsLAogICAgICAgICAgICAgICAgSURCS2V5UmFuZ2U6IG51bGwKICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9KSgpLAogICAgLy8gQVBJIFZlcnNpb24gTnVtYmVyOiBUeXBlIE51bWJlciwgbWFrZSBzdXJlIHRvIGFsd2F5cyBzZXQgYSB2ZXJzaW9uIG51bWJlciB0aGF0IGNhbiBiZSBjb21wYXJhYmxlIGNvcnJlY3RseS4gRXhhbXBsZTogMC45LCAwLjkxLCAwLjkyLCAxLjAsIDEuMDEsIDEuMSwgMS4yLCAxLjIxLCBldGMuCiAgICBzZW1WZXI6IERFWElFX1ZFUlNJT04sCiAgICB2ZXJzaW9uOiBERVhJRV9WRVJTSU9OLnNwbGl0KCcuJykKICAgICAgICAubWFwKGZ1bmN0aW9uIChuKSB7IHJldHVybiBwYXJzZUludChuKTsgfSkKICAgICAgICAucmVkdWNlKGZ1bmN0aW9uIChwLCBjLCBpKSB7IHJldHVybiBwICsgKGMgLyBNYXRoLnBvdygxMCwgaSAqIDIpKTsgfSksCiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vZGZhaGxhbmRlci9EZXhpZS5qcy9pc3N1ZXMvMTg2CiAgICAvLyB0eXBlc2NyaXB0IGNvbXBpbGVyIHRzYyBpbiBtb2RlIHRzLS0+ZXM1ICYgY29tbW9uSlMsIHdpbGwgZXhwZWN0IHJlcXVpcmUoKSB0byByZXR1cm4KICAgIC8vIHguZGVmYXVsdC4gV29ya2Fyb3VuZDogU2V0IERleGllLmRlZmF1bHQgPSBEZXhpZS4KICAgIGRlZmF1bHQ6IERleGllLAogICAgLy8gTWFrZSBpdCBwb3NzaWJsZSB0byBpbXBvcnQge0RleGllfSAobm9uLWRlZmF1bHQgaW1wb3J0KQogICAgLy8gUmVhc29uIDE6IE1heSBzd2l0Y2ggdG8gdGhhdCBpbiBmdXR1cmUuCiAgICAvLyBSZWFzb24gMjogV2UgZGVjbGFyZSBpdCBib3RoIGRlZmF1bHQgYW5kIG5hbWVkIGV4cG9ydGVkIGluIGQudHMgdG8gbWFrZSBpdCBwb3NzaWJsZQogICAgLy8gdG8gbGV0IGFkZG9ucyBleHRlbmQgdGhlIERleGllIGludGVyZmFjZSB3aXRoIFR5cGVzY3JpcHQgMi4xICh3b3JrcyBvbmx5IHdoZW4gZXhwbGljaXRlbHkKICAgIC8vIGV4cG9ydGluZyB0aGUgc3ltYm9sLCBub3QganVzdCBkZWZhdWx0IGV4cG9ydGluZykKICAgIERleGllOiBEZXhpZQp9KTsKLy8gTWFwIERPTUVycm9ycyBhbmQgRE9NRXhjZXB0aW9ucyB0byBjb3JyZXNwb25kaW5nIERleGllIGVycm9ycy4gTWF5IGNoYW5nZSBpbiBEZXhpZSB2Mi4wLgpQcm9taXNlLnJlamVjdGlvbk1hcHBlciA9IG1hcEVycm9yOwovLyBJbml0aWFsaXplIGRiTmFtZXNEQiAod29uJ3QgZXZlciBiZSBvcGVuZWQgb24gY2hyb21pdW0gYnJvd3NlcnMnKQpkYk5hbWVzREIgPSBuZXcgRGV4aWUoJ19fZGJuYW1lcycpOwpkYk5hbWVzREIudmVyc2lvbigxKS5zdG9yZXMoeyBkYm5hbWVzOiAnbmFtZScgfSk7CihmdW5jdGlvbiAoKSB7CiAgICAvLyBNaWdyYXRlIGZyb20gRGV4aWUgMS54IGRhdGFiYXNlIG5hbWVzIHN0b3JlZCBpbiBsb2NhbFN0b3JhZ2U6CiAgICB2YXIgREJOQU1FUyA9ICdEZXhpZS5EYXRhYmFzZU5hbWVzJzsKICAgIHRyeSB7CiAgICAgICAgaWYgKHR5cGVvZiBsb2NhbFN0b3JhZ2UgIT09IHVuZGVmaW5lZCAmJiBfZ2xvYmFsLmRvY3VtZW50ICE9PSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgLy8gSGF2ZSBsb2NhbFN0b3JhZ2UgYW5kIGlzIG5vdCBleGVjdXRpbmcgaW4gYSB3b3JrZXIuIExldHMgbWlncmF0ZSBmcm9tIERleGllIDEueC4KICAgICAgICAgICAgSlNPTi5wYXJzZShsb2NhbFN0b3JhZ2UuZ2V0SXRlbShEQk5BTUVTKSB8fCAiW10iKQogICAgICAgICAgICAgICAgLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHsgcmV0dXJuIGRiTmFtZXNEQi5kYm5hbWVzLnB1dCh7IG5hbWU6IG5hbWUgfSkuY2F0Y2gobm9wKTsgfSk7CiAgICAgICAgICAgIGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKERCTkFNRVMpOwogICAgICAgIH0KICAgIH0KICAgIGNhdGNoIChfZSkgeyB9Cn0pKCk7CgpyZXR1cm4gRGV4aWU7Cgp9KSkpOwovLyMgc291cmNlTWFwcGluZ1VSTD1kZXhpZS5qcy5tYXAKCgovLyBDcmVhdGUgb3duIE1EaXNEQiB0byB1c2UgaXQgbGF0ZXIKd2luZG93LkFEaXNEQiA9IG5ldyBEZXhpZSgnTFNTX0F1dG9tYXRpY0Rpc3BvJyk7CnZhciBBRGlzREIgPSB3aW5kb3cuQURpc0RCOwpBRGlzREIudmVyc2lvbigxKS5zdG9yZXMoewogICAgLyoqIAogICAgICogQXZhaWxhYmVsTWlzc2lvbnMKICAgICAqIC0gbWlzc2lvbklECiAgICAgKiAtIHR5cGUKICAgICAqIC0gbmFtZQogICAgICogLSBqc29uZGF0YQogICAgICovCiAgICBBRGlzQXZhaWxhYmVsTWlzc2lvbnM6ICIrK21pc3Npb25JRCx0eXBlLG5hbWUiLAogICAgLyoqIAogICAgICogU3ByZWNod3Vuc2NoCiAgICAgKiAtIHZlaGljbGVJRAogICAgICogLSBkb25lCiAgICAgKi8KICAgIEFEaXNTcHJlY2h3dW5zY2g6ICIrK3ZlaGljbGVJRCxkb25lIiwKICAgIC8qKiAKICAgICAqIFNwcmVjaHd1bnNjaCBQb2xpY2UKICAgICAqIC0gbWlzc2lvbklECiAgICAgKiAtIGRvbmUKICAgICAqLwogICAgQURpc1NwcmVjaHd1bnNjaFBvbGljZTogIisrbWlzc2lvbklELGRvbmUiLAogICAgLyoqIAogICAgICogS3JhbmtlbnRyYW5zcG9ydAogICAgICogLSBtaXNzaW9uSUQKICAgICAqIC0gZG9uZQogICAgICovCiAgICBBRGlzS3JhbmtlbnRyYW5zcG9ydDogIisrbWlzc2lvbklELGRvbmUiLAogICAgLyoqIAogICAgICogU2V0dGluZ3MKICAgICAqIC0gaWQKICAgICAqIC0gbmFtZQogICAgICogLSBkb25lCiAgICAgKi8KICAgIEFEaXNTZXR0aW5nczogIiZuYW1lLHZhbHVlIiwKICAgIC8qKiAKICAgICAqIE1pc3Npb25zT3duCiAgICAgKiBNaXNzaW9uc1ZlcmJhbmQKICAgICAqIE1pc3Npb25zVmVyYmFuZEV2ZW50CiAgICAgKiAtIG1pc3Npb25JRAogICAgICogLSB0eXBlCiAgICAgKiAtIG5hbWUKICAgICAqIC0gYXZhaWxhYmxlCiAgICAgKiAtIGRvbmUKICAgICAqIC0gc3RyZWV0CiAgICAgKiAtIHZpbGxhZ2UKICAgICAqIC0gbGFzdF9jaGVjawogICAgICogLSBuZXh0X2NoZWNrCiAgICAgKi8KICAgIEFEaXNNaXNzaW9uc093bjogIisrbWlzc2lvbklELHR5cGUsbmFtZSxsYXN0X2NoZWNrLG5leHRfY2hlY2ssYXZhaWxhYmxlLGRvbmUiLAogICAgQURpc01pc3Npb25zVmVyYmFuZDogIisrbWlzc2lvbklELHR5cGUsbmFtZSxsYXN0X2NoZWNrLG5leHRfY2hlY2ssYXZhaWxhYmxlLGRvbmUiLAogICAgQURpc01pc3Npb25zVmVyYmFuZEV2ZW50OiAiKyttaXNzaW9uSUQsdHlwZSxuYW1lLGxhc3RfY2hlY2ssbmV4dF9jaGVjayxhdmFpbGFibGUsZG9uZSIsCn0pOwpBRGlzREIub24oInBvcHVsYXRlIiwgZnVuY3Rpb24oKSB7CiAgICBBRGlzREIuQURpc1NldHRpbmdzLmFkZCh7bmFtZTogIktyYW5rZW50cmFuc3BvcnQtQXV0b21hdGljIiwgdmFsdWU6ICd0cnVlJ30pOwogICAgQURpc0RCLkFEaXNTZXR0aW5ncy5hZGQoe25hbWU6ICJTcHJlY2h3dW5zY2gtQXV0b21hdGljIiwgdmFsdWU6ICd0cnVlJ30pOwogICAgQURpc0RCLkFEaXNTZXR0aW5ncy5hZGQoe25hbWU6ICJNaXNzaW9uc093bi1BdXRvbWF0aWMiLCB2YWx1ZTogJ3RydWUnfSk7CiAgICBBRGlzREIuQURpc1NldHRpbmdzLmFkZCh7bmFtZTogIkFsbGlhbmNlLUF1dG9tYXRpYyIsIHZhbHVlOiAnZmFsc2UnfSk7CiAgICBBRGlzREIuQURpc1NldHRpbmdzLmFkZCh7bmFtZTogIkFsbGlhbmNlRXZlbnQtQXV0b21hdGljIiwgdmFsdWU6ICdmYWxzZSd9KTsKfSk7CkFEaXNEQi5vcGVuKCkuY2F0Y2goZnVuY3Rpb24gKGVycikgewogICAgY29uc29sZS5lcnJvcihlcnIuc3RhY2sgfHwgZXJyKTsKfSk7CgpBRGlzREIub24oInJlYWR5IiwgKCkgPT4gewoKICAgIC8vY29uc29sZS5sb2coQURpc0RCKTsKICAgIC8vY29uc29sZS5sb2coQURpc1NldHRpbmdzKCdLcmFua2VudHJhbnNwb3J0LUF1dG9tYXRpYycpKTsKCiAgICAvLyAgICAgIC0KICAgIC8vICAgICAgLSAgICAgICAgICAgR29vZ2xlIEZvbnQKICAgIC8vICAgICAgLQoKICAgIHZhciBzdHlsZUVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJsaW5rIik7CiAgICBzdHlsZUVsZW1lbnQucmVsID0gInN0eWxlc2hlZXQiOwogICAgc3R5bGVFbGVtZW50LmhyZWYgPSAiaHR0cHM6Ly9mb250cy5nb29nbGVhcGlzLmNvbS9jc3M/ZmFtaWx5PU9wZW4rU2FuczozMDAsNDAwLDYwMCw3MDAiOwogICAgQURpc19NeUhlYWQuYXBwZW5kQ2hpbGQoc3R5bGVFbGVtZW50KTsKCiAgICAvLyAgICAgIC0KICAgIC8vICAgICAgLSAgICAgICAgICAgRm9udEF3ZXNvbWUgNQogICAgLy8gICAgICAtCgogICAgdmFyIHNjcmlwdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJzY3JpcHQiKTsKICAgIHNjcmlwdEVsZW1lbnQudHlwZSA9ICJ0ZXh0L2phdmFzY3JpcHQiOwogICAgc2NyaXB0RWxlbWVudC5zcmMgPSAiaHR0cHM6Ly91c2UuZm9udGF3ZXNvbWUuY29tL3JlbGVhc2VzL3Y1LjUuMC9qcy9hbGwuanMiOwogICAgQURpc19NeUhlYWQuYXBwZW5kQ2hpbGQoc2NyaXB0RWxlbWVudCk7CgogICAgLy8gICAgICAtCiAgICAvLyAgICAgIC0gICAgICAgICAgIE5hdmJhciBEYXNoYm9hcmQKICAgIC8vICAgICAgLQoKICAgIGlmICh3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUgPT09ICIvIiB8fCB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUgPT09ICIvIyIpIHsKICAgICAgICAkKGRvY3VtZW50KS5yZWFkeShmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIEFEaXNfQ3JlYXRlRGFzaGJvYXJkKCk7CiAgICAgICAgICAgIEFEaXNfQ3JlYXRlSWZyYW1lcygpOwogICAgICAgIAogICAgICAgICAgICBjb25zb2xlLmxvZygiICBBdXRvbWF0aWMgRGlzcG9zZTogVUkgZ2VsYWRlbiIpOwogICAgICAgIH0pOwogICAgICAgIAogICAgICAgIGZ1bmN0aW9uIEFEaXNfQ3JlYXRlRGFzaGJvYXJkKCkgewogICAgICAgICAgICAkKCcjbmV3c19saScpLmJlZm9yZSgnPGxpIGlkPSJhZGlzLW5hdi1pdGVtIj48L2xpPicpOwogICAgICAgICAgICAkKCcjYWRpcy1uYXYtaXRlbScpLmxvYWQoQXV0b21hdGljRGlzcG9zZV9VUkwgKyBBdXRvbWF0aWNEaXNwb3NlX0JyYW5jaCArICIvaHRtbC9uYXZiYXIuaHRtbCIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICQoIiNhZGlzLWRhc2hib2FyZCIpLmNzcyh7CiAgICAgICAgICAgICAgICAgICAgZGlzcGxheTogIm5vbmUiLAogICAgICAgICAgICAgICAgICAgIG9wYWNpdHk6ICIwIgogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBmdW5jdGlvbiBBRGlzX0NyZWF0ZUlmcmFtZXMoKSB7CiAgICAgICAgICAgICQoImJvZHkiKS5hcHBlbmQoJzxkaXYgaWQ9ImFkaXMtZnJhbWUtY29udGFpbmVyIj48L2Rpdj4nKTsKICAgICAgICAgICAgJCgiI2FkaXMtZnJhbWUtY29udGFpbmVyIikubG9hZChBdXRvbWF0aWNEaXNwb3NlX1VSTCArIEF1dG9tYXRpY0Rpc3Bvc2VfQnJhbmNoICsgIi9odG1sL2lmcmFtZXMuaHRtbCIpOwogICAgICAgIAogICAgICAgICAgICAkKCIjYWRpcy1mcmFtZS1jb250YWluZXIiKS5jc3MoewogICAgICAgICAgICAgICAgZGlzcGxheTogIm5vbmUiLAogICAgICAgICAgICAgICAgb3BhY2l0eTogIjAiCiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgICB2YXIgc3R5bGVFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgibGluayIpOwogICAgICAgIHN0eWxlRWxlbWVudC5yZWwgPSAic3R5bGVzaGVldCI7CiAgICAgICAgc3R5bGVFbGVtZW50LnR5cGUgPSAidGV4dC9jc3MiOwogICAgICAgIHN0eWxlRWxlbWVudC5tZWRpYSA9ICJzY3JlZW4iOwogICAgICAgIHN0eWxlRWxlbWVudC5ocmVmID0gQXV0b21hdGljRGlzcG9zZV9VUkwgKyBBdXRvbWF0aWNEaXNwb3NlX0JyYW5jaCArICIvc3R5bGUvaW50ZXJmYWNlLmNzcyI7CiAgICAgICAgQURpc19NeUhlYWQuYXBwZW5kQ2hpbGQoc3R5bGVFbGVtZW50KTsKICAgIH0KCiAgICAvLyAgICAgIC0KICAgIC8vICAgICAgLSAgICAgICAgICAgTG9hZCBBdXRvbWF0aWMgTW9kZXMKICAgIC8vICAgICAgLSAgICAgICAgICAgTG9hZCBPcGVuZXIKICAgIC8vICAgICAgLQoKICAgIGZ1bmN0aW9uIEFEaXNfVXBkYXRlT3duTWlzc2lvbnNUb0RvbmUoTWlzc2lvbklELCB1cGRhdGVEYXRhKSB7CiAgICAgICAgaWYgKHR5cGVvZiB1cGRhdGVEYXRhICE9ICd1bmRlZmluZWQnKSB7CiAgICAgICAgICAgIHJldHVybiBBRGlzREIuQURpc01pc3Npb25zT3duLnB1dCh7CiAgICAgICAgICAgICAgICBtaXNzaW9uSUQ6IE1pc3Npb25JRAogICAgICAgICAgICB9LCB1cGRhdGVEYXRhKS5jYXRjaCgoZXJyKSA9PiB7fSkKICAgICAgICB9CiAgICAgICAgcmV0dXJuIEFEaXNEQi5BRGlzTWlzc2lvbnNPd24ucHV0KHsKICAgICAgICAgICAgbWlzc2lvbklEOiBNaXNzaW9uSUQsCiAgICAgICAgICAgIGRvbmU6ICd0cnVlJwogICAgICAgIH0pLmNhdGNoKChlcnIpID0+IHt9KQogICAgfQoKICAgIC8vICAgICAgLQogICAgLy8gICAgICAtICAgICAgICAgICBNaXNzaW9uIFZhcmlhYmxlbgogICAgLy8gICAgICAtCiAgICB2YXIgTWlzc2lvbklEOwogICAgdmFyIE1pc3Npb25UeXBlOwogICAgdmFyIE1pc3Npb25Db25maWc7CiAgICB2YXIgQ3VycmVudFRpbWU7CiAgICB2YXIgTWF4VmVoaWNsZUlEID0gODY7CiAgICB2YXIgT3duTWlzc2lvbnNGcmFtZVdhdGNoRG9nOwogICAgdmFyIEtyYW5rZW50cmFuc3BvcnRGcmFtZVdhdGNoRG9nOwogICAgdmFyIFZlcmJhbmRNaXNzaW9uRnJhbWVXYXRjaERvZzsKICAgIHZhciBWZXJiYW5kRXZlbnRzRnJhbWVXYXRjaERvZzsKICAgIHZhciBQbGFubmVkRXZlbnRzRnJhbWVXYXRjaERvZzsKICAgIAogICAgd2luZG93LkFEaXNfTWlzc2lvbkRvbmUgPSBmdW5jdGlvbiBBRGlzX01pc3Npb25Eb25lKFdpbmRvd05hbWUpIHsKICAgICAgICBpZiAoWydhZGlzLWtyYW5rZW50cmFuc3BvcnRlJ10uaW5kZXhPZihXaW5kb3dOYW1lKSAhPT0gLTEpIHsKICAgICAgICAgICAgJCgiI2FkaXMta3JhbmtlbnRyYW5zcG9ydGUtZnJhbWUiKS5hdHRyKCJzcmMiLCAiIik7CiAgICAgICAgICAgICQoIiNhZGlzLWtyYW5rZW50cmFuc3BvcnRlLWZyYW1lIikuYXR0cigibWlzc2lvbl9pZCIsICJlbXB0eSIpOwogICAgICAgICAgICBjbGVhclRpbWVvdXQoS3JhbmtlbnRyYW5zcG9ydEZyYW1lV2F0Y2hEb2cpOwogICAgICAgIH0gZWxzZSBpZiAoWydhZGlzLXBsYW5uZWRldmVudHMnXS5pbmRleE9mKFdpbmRvd05hbWUpICE9PSAtMSkgewogICAgICAgICAgICAkKCIjYWRpcy1wbGFubmVkZXZlbnRzLWZyYW1lIikuYXR0cigic3JjIiwgIiIpOwogICAgICAgICAgICAkKCIjYWRpcy1wbGFubmVkZXZlbnRzLWZyYW1lIikuYXR0cigibWlzc2lvbl9pZCIsICJlbXB0eSIpOwogICAgICAgICAgICBjbGVhclRpbWVvdXQoUGxhbm5lZEV2ZW50c0ZyYW1lV2F0Y2hEb2cpOwogICAgICAgIH0gZWxzZSBpZiAoWydhZGlzLW93bm1pc3Npb25zJ10uaW5kZXhPZihXaW5kb3dOYW1lKSAhPT0gLTEpIHsKICAgICAgICAgICAgJCgiI2FkaXMtb3dubWlzc2lvbnMtZnJhbWUiKS5hdHRyKCJzcmMiLCAiIik7CiAgICAgICAgICAgICQoIiNhZGlzLW93bm1pc3Npb25zLWZyYW1lIikuYXR0cigibWlzc2lvbl9pZCIsICJlbXB0eSIpOwogICAgICAgICAgICBjbGVhclRpbWVvdXQoT3duTWlzc2lvbnNGcmFtZVdhdGNoRG9nKTsKICAgICAgICB9IGVsc2UgaWYgKFsnYWRpcy12ZXJiYW5kbWlzc2lvbiddLmluZGV4T2YoV2luZG93TmFtZSkgIT09IC0xKSB7CiAgICAgICAgICAgICQoIiNhZGlzLXZlcmJhbmRtaXNzaW9uLWZyYW1lIikuYXR0cigic3JjIiwgIiIpOwogICAgICAgICAgICAkKCIjYWRpcy12ZXJiYW5kbWlzc2lvbi1mcmFtZSIpLmF0dHIoIm1pc3Npb25faWQiLCAiZW1wdHkiKTsKICAgICAgICAgICAgY2xlYXJUaW1lb3V0KFZlcmJhbmRNaXNzaW9uRnJhbWVXYXRjaERvZyk7CiAgICAgICAgfSBlbHNlIGlmIChbJ2FkaXMtdmVyYmFuZG1pc3Npb24tZXZlbnQnXS5pbmRleE9mKFdpbmRvd05hbWUpICE9PSAtMSkgewogICAgICAgICAgICAkKCIjYWRpcy12ZXJiYW5kbWlzc2lvbi1ldmVudC1mcmFtZSIpLmF0dHIoInNyYyIsICIiKTsKICAgICAgICAgICAgJCgiI2FkaXMtdmVyYmFuZG1pc3Npb24tZXZlbnQtZnJhbWUiKS5hdHRyKCJtaXNzaW9uX2lkIiwgImVtcHR5Iik7CiAgICAgICAgICAgIGNsZWFyVGltZW91dChWZXJiYW5kRXZlbnRzRnJhbWVXYXRjaERvZyk7CiAgICAgICAgfQogICAgfQogICAgd2luZG93LkFEaXNfTWlzc2lvblVwZGF0ZURvbmUgPSBmdW5jdGlvbiBBRGlzX01pc3Npb25VcGRhdGVEb25lKFdpbmRvd05hbWUsIE1pc3Npb25JRCkgewogICAgICAgIGlmIChbJ2FkaXMta3JhbmtlbnRyYW5zcG9ydGUnXS5pbmRleE9mKFdpbmRvd05hbWUpICE9PSAtMSkgewogICAgICAgICAgICAkKCIjYWRpcy1rcmFua2VudHJhbnNwb3J0ZS1mcmFtZSIpLmF0dHIoInNyYyIsICIiKTsKICAgICAgICAgICAgJCgiI2FkaXMta3JhbmtlbnRyYW5zcG9ydGUtZnJhbWUiKS5hdHRyKCJtaXNzaW9uX2lkIiwgImVtcHR5Iik7CiAgICAgICAgICAgIGNsZWFyVGltZW91dChLcmFua2VudHJhbnNwb3J0RnJhbWVXYXRjaERvZyk7CiAgICAgICAgfSBlbHNlIGlmIChbJ2FkaXMtcGxhbm5lZGV2ZW50cyddLmluZGV4T2YoV2luZG93TmFtZSkgIT09IC0xKSB7CiAgICAgICAgICAgICQoIiNhZGlzLXBsYW5uZWRldmVudHMtZnJhbWUiKS5hdHRyKCJzcmMiLCAiIik7CiAgICAgICAgICAgICQoIiNhZGlzLXBsYW5uZWRldmVudHMtZnJhbWUiKS5hdHRyKCJtaXNzaW9uX2lkIiwgImVtcHR5Iik7CiAgICAgICAgICAgIGNsZWFyVGltZW91dChQbGFubmVkRXZlbnRzRnJhbWVXYXRjaERvZyk7CiAgICAgICAgfSBlbHNlIGlmIChbJ2FkaXMtb3dubWlzc2lvbnMnXS5pbmRleE9mKFdpbmRvd05hbWUpICE9PSAtMSkgewogICAgICAgICAgICAkKCIjYWRpcy1vd25taXNzaW9ucy1mcmFtZSIpLmF0dHIoInNyYyIsICIiKTsKICAgICAgICAgICAgJCgiI2FkaXMtb3dubWlzc2lvbnMtZnJhbWUiKS5hdHRyKCJtaXNzaW9uX2lkIiwgImVtcHR5Iik7CiAgICAgICAgICAgIGNsZWFyVGltZW91dChPd25NaXNzaW9uc0ZyYW1lV2F0Y2hEb2cpOwogICAgICAgIH0gZWxzZSBpZiAoWydhZGlzLXZlcmJhbmRtaXNzaW9uJ10uaW5kZXhPZihXaW5kb3dOYW1lKSAhPT0gLTEpIHsKICAgICAgICAgICAgJCgiI2FkaXMtdmVyYmFuZG1pc3Npb24tZnJhbWUiKS5hdHRyKCJzcmMiLCAiIik7CiAgICAgICAgICAgICQoIiNhZGlzLXZlcmJhbmRtaXNzaW9uLWZyYW1lIikuYXR0cigibWlzc2lvbl9pZCIsICJlbXB0eSIpOwogICAgICAgICAgICBjbGVhclRpbWVvdXQoVmVyYmFuZE1pc3Npb25GcmFtZVdhdGNoRG9nKTsKICAgICAgICB9IGVsc2UgaWYgKFsnYWRpcy12ZXJiYW5kbWlzc2lvbi1ldmVudCddLmluZGV4T2YoV2luZG93TmFtZSkgIT09IC0xKSB7CiAgICAgICAgICAgICQoIiNhZGlzLXZlcmJhbmRtaXNzaW9uLWV2ZW50LWZyYW1lIikuYXR0cigic3JjIiwgIiIpOwogICAgICAgICAgICAkKCIjYWRpcy12ZXJiYW5kbWlzc2lvbi1ldmVudC1mcmFtZSIpLmF0dHIoIm1pc3Npb25faWQiLCAiZW1wdHkiKTsKICAgICAgICAgICAgY2xlYXJUaW1lb3V0KFZlcmJhbmRFdmVudHNGcmFtZVdhdGNoRG9nKTsKICAgICAgICB9CiAgICB9CiAgICB3aW5kb3cuQURpc19NaXNzaW9uVXBkYXRlID0gZnVuY3Rpb24gQURpc19NaXNzaW9uVXBkYXRlKFdpbmRvd05hbWUsIFVwZGF0ZURhdGEpIHsKICAgICAgICBpZiAoWydhZGlzLWtyYW5rZW50cmFuc3BvcnRlJ10uaW5kZXhPZihXaW5kb3dOYW1lKSAhPT0gLTEpIHsKICAgICAgICAgICAgQURpc19VcGRhdGVLcmFua2VudHJhbnNwb3J0KFVwZGF0ZURhdGEpOwogICAgICAgIH0gZWxzZSBpZiAoWydhZGlzLXBsYW5uZWRldmVudHMnXS5pbmRleE9mKFdpbmRvd05hbWUpICE9PSAtMSkgewogICAgICAgICAgICBBRGlzX1VwZGF0ZVBsYW5uZWRFdmVudHMoVXBkYXRlRGF0YSk7CiAgICAgICAgfSBlbHNlIGlmIChbJ2FkaXMtb3dubWlzc2lvbnMnXS5pbmRleE9mKFdpbmRvd05hbWUpICE9PSAtMSkgewogICAgICAgICAgICBBRGlzX1VwZGF0ZU93bk1pc3Npb25zKFVwZGF0ZURhdGEpOwogICAgICAgIH0gZWxzZSBpZiAoWydhZGlzLXZlcmJhbmRtaXNzaW9uJ10uaW5kZXhPZihXaW5kb3dOYW1lKSAhPT0gLTEpIHsKICAgICAgICAgICAgQURpc19VcGRhdGVWZXJiYW5kTWlzc2lvbnMoVXBkYXRlRGF0YSk7CiAgICAgICAgfSBlbHNlIGlmIChbJ2FkaXMtdmVyYmFuZG1pc3Npb24tZXZlbnQnXS5pbmRleE9mKFdpbmRvd05hbWUpICE9PSAtMSkgewogICAgICAgICAgICBBRGlzX1VwZGF0ZVZlcmJhbmRFdmVudHMoVXBkYXRlRGF0YSk7CiAgICAgICAgfQogICAgfQogICAgCiAgICAvLyAgICAgIC0KICAgIC8vICAgICAgLSAgICAgICAgICAgTWlzc2lvbiBPcGVuZXIKICAgIC8vICAgICAgLQogICAgaWYgKHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSA9PT0gIi8iIHx8IHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSA9PT0gIi8jIikgewogICAgICAgICQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgY29uc29sZS5sb2coIk1hbmFnZXIgbG9hZCIpOwogICAgICAgICAgICBzZXRJbnRlcnZhbChBRGlzX0dldEF2YWlsYWJsZU1pc3Npb25zLCA2MDAwMDApOyAvLyB1cGRhdGUgYXZhaWxhYmxhIG1pc3Npb25zIGV2ZXJ5IDEwIG1pbnV0ZXMKICAgICAgICAgICAgQURpc19HZXRBdmFpbGFibGVNaXNzaW9ucygpOyAvLyBnZXQgYXZhaWxhYmxhIG1pc3Npb25zIGFmdGVyIHBhZ2UgcmVhZHkKICAgICAgICB9KTsKICAgICAgICAKICAgICAgICAKICAgICAgICAvLyAgLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLQogICAgICAgIC8vICAtCiAgICAgICAgLy8gIC0gICAgICAgICAgICAgICAgICAgR3JhYiBNaXNzaW9uLUNvbmZpZ3VyYXRpb24gZnJvbSBHaXRIdWIKICAgICAgICAvLyAgLQogICAgICAgIC8vICAtIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tCiAgICAgICAgCiAgICAgICAgZnVuY3Rpb24gQURpc19HZXRBdmFpbGFibGVNaXNzaW9ucygpIHsKICAgICAgICAgICAgLy8gR2V0IGFsbCBhdmFpbGFibGUgbWlzc2lvbnMgd2l0aCB0aGVyZSBjb25maWcKICAgICAgICAgICAgJC5nZXRKU09OKEF1dG9tYXRpY0Rpc3Bvc2VfVVJMICsgQXV0b21hdGljRGlzcG9zZV9CcmFuY2ggKyAiL2FsbF9taXNzaW9ucy5qc29uIiwgZnVuY3Rpb24gKFJlc3BvbnNlKSB7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBpIGluIFJlc3BvbnNlKSB7CiAgICAgICAgICAgICAgICAgICAgTWlzc2lvbiA9IFJlc3BvbnNlW2ldOwogICAgICAgICAgICAgICAgICAgIEFEaXNfQWRkQXZhaWxhYmxlTWlzc2lvbnMoTWlzc2lvbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBmdW5jdGlvbiBBRGlzX0NvbGxlY3RNaXNzaW9ucygpIHsKICAgICAgICAgICAgcmV0dXJuIEFEaXNEQi50cmFuc2FjdGlvbigncncnLCBbQURpc0RCLkFEaXNNaXNzaW9uc093biwgQURpc0RCLkFEaXNTZXR0aW5ncywgQURpc0RCLkFEaXNBdmFpbGFiZWxNaXNzaW9uc10sICgpID0+IHsKICAgICAgICAgICAgICAgIEFEaXNTZXR0aW5ncygpLnRoZW4oKHNldHRpbmcpID0+IHsKICAgICAgICAgICAgICAgICAgICBpZiAoc2V0dGluZ1snTWlzc2lvbnNPd24tQXV0b21hdGljJ10gPT0gJ3RydWUnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBBRGlzREIuQURpc01pc3Npb25zT3duLndoZXJlKHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbmU6ICdmYWxzZScKICAgICAgICAgICAgICAgICAgICAgICAgfSkubGltaXQoMSkKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KS50aGVuKChNaXNzaW9ucykgPT4gewogICAgICAgICAgICAgICAgICAgIGlmIChNaXNzaW9ucyA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE1pc3Npb25zLmNvdW50KGZ1bmN0aW9uIChjb3VudCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY291bnQgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gTWlzc2lvbnMuZWFjaChhc3luYyAoTWlzc2lvbikgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhd2FpdCBBRGlzREIuQURpc0F2YWlsYWJlbE1pc3Npb25zLmdldCh7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IE1pc3Npb24udHlwZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pLnRoZW4oKGF2YWlsYWJsZSkgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXZhaWxhYmxlID09IHVuZGVmaW5lZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQURpc19SZW1vdmVNaXNzaW9uRnJvbVF1ZXVlKE1pc3Npb24ubWlzc2lvbklEKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pLnRoZW4oKCkgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJCgiI21pc3Npb25fIiArIE1pc3Npb24ubWlzc2lvbklEKS5sZW5ndGggPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEFEaXNfUmVtb3ZlTWlzc2lvbkZyb21RdWV1ZShNaXNzaW9uLm1pc3Npb25JRCk7CiAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KS50aGVuKCgpID0+IHsKICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCQoIiNtaXNzaW9uXyIgKyBNaXNzaW9uLm1pc3Npb25JRCkuY3NzKCJkaXNwbGF5IikgPT0gIm5vbmUiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQURpc19SZW1vdmVNaXNzaW9uRnJvbVF1ZXVlKE1pc3Npb24ubWlzc2lvbklEKTsKICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pLnRoZW4oKCkgPT4gewogICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKCIjbWlzc2lvbl8iICsgTWlzc2lvbi5pZCkuYW5pbWF0ZSh7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGFjaXR5OiAwLjUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgNTAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgIH0pLnRoZW4oKCkgPT4gewogICAgICAgICAgICAgICAgICAgICQoIiNtaXNzaW9uX2xpc3QiKS5maW5kKCIubWlzc2lvblNpZGVCYXJFbnRyeSIpLmVhY2goYXN5bmMgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgTWlzc2lvbklEID0gJCh0aGlzKS5hdHRyKCJtaXNzaW9uX2lkIik7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZhciBNaXNzaW9uVHlwZSA9ICQodGhpcykuYXR0cigibWlzc2lvbl90eXBlX2lkIik7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZhciBNaXNzaW9uTmFtZSA9ICQodGhpcykuZmluZCgiLm1hcF9wb3NpdGlvbl9tb3ZlciIpLnRleHQoKTsKICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgICAtIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tCiAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgRW1lcmdlbmN5IE1pc3Npb25zICB8ICBBdXRvbWF0aWMKICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgICAtIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tCiAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IEFEaXNfQWRkTWlzc2lvbihNaXNzaW9uSUQpOwogICAgICAgIAogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBmdW5jdGlvbiBBRGlzX0FkZE1pc3Npb24oSUQpIHsKICAgICAgICAgICAgcmV0dXJuIEFEaXNTZXR0aW5ncygpLnRoZW4oKHNldHRpbmcpID0+IHsKICAgICAgICAgICAgICAgIGlmIChzZXR0aW5nWydNaXNzaW9uc093bi1BdXRvbWF0aWMnXSA9PSAndHJ1ZScpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gQURpc0RCLkFEaXNNaXNzaW9uc093bi53aGVyZSh7CiAgICAgICAgICAgICAgICAgICAgICAgIG1pc3Npb25JRDogSUQKICAgICAgICAgICAgICAgICAgICB9KS5saW1pdCgxKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KS50aGVuKChNaXNzaW9ucykgPT4gewogICAgICAgICAgICAgICAgaWYgKE1pc3Npb25zID09PSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gTWlzc2lvbnMuY291bnQoZnVuY3Rpb24gKGNvdW50KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNvdW50ID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gTWlzc2lvbnMuZWFjaCgoTWlzc2lvbikgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIE1pc3Npb25FbGVtZW50ID0gJCgiI21pc3Npb25fIiArIElEKTsKICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBNaXNzaW9uSUQgPSBNaXNzaW9uRWxlbWVudC5hdHRyKCJtaXNzaW9uX2lkIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgTWlzc2lvblR5cGUgPSBNaXNzaW9uRWxlbWVudC5hdHRyKCJtaXNzaW9uX3R5cGVfaWQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhZGRyID0gTWlzc2lvbkVsZW1lbnQuZmluZCgiLm1hcF9wb3NpdGlvbl9tb3ZlciIpLnRleHQoKS5zcGxpdCgiLCIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgTWlzc2lvbk5hbWUgPSBhZGRyWzBdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIE1pc3Npb25TdHJlZXQgPSBhZGRyWzFdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIE1pc3Npb25WaWxsYWdlID0gYWRkclsyXTsKICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBBRGlzREIuQURpc0F2YWlsYWJlbE1pc3Npb25zLmdldCh7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogTWlzc2lvblR5cGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pLnRoZW4oKGF2YWlsYWJsZSkgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBBRGlzX0FkZE1pc3Npb25Ub1F1ZXVlKHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImlkIjogTWlzc2lvbklELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidHlwZSI6IE1pc3Npb25UeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibmFtZSI6IE1pc3Npb25OYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic3RyZWV0IjogTWlzc2lvblN0cmVldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInZpbGxhZ2UiOiBNaXNzaW9uVmlsbGFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImF2YWlsYWJsZSI6IChhdmFpbGFibGUgIT09IHVuZGVmaW5lZCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJkb25lIjogZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJsYXN0X2NoZWNrIjogTWF0aC5mbG9vcihuZXcgRGF0ZSgpLmdldFRpbWUoKSAvIDEwMDApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibmV4dF9jaGVjayI6IE1hdGguZmxvb3IobmV3IERhdGUoKS5nZXRUaW1lKCkgLyAxMDAwKSArIDEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgTWlzc2lvbkVsZW1lbnQgPSAkKCIjbWlzc2lvbl8iICsgSUQpOwogICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICB2YXIgTWlzc2lvbklEID0gTWlzc2lvbkVsZW1lbnQuYXR0cigibWlzc2lvbl9pZCIpOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgTWlzc2lvblR5cGUgPSBNaXNzaW9uRWxlbWVudC5hdHRyKCJtaXNzaW9uX3R5cGVfaWQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFkZHIgPSBNaXNzaW9uRWxlbWVudC5maW5kKCIubWFwX3Bvc2l0aW9uX21vdmVyIikudGV4dCgpLnNwbGl0KCIsIikKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIE1pc3Npb25OYW1lID0gYWRkclswXTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIE1pc3Npb25TdHJlZXQgPSBhZGRyWzFdOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgTWlzc2lvblZpbGxhZ2UgPSBhZGRyWzJdOwogICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQURpc0RCLkFEaXNBdmFpbGFiZWxNaXNzaW9ucy5nZXQoewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogTWlzc2lvblR5cGUKICAgICAgICAgICAgICAgICAgICAgICAgfSkudGhlbigoYXZhaWxhYmxlKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQURpc19BZGRNaXNzaW9uVG9RdWV1ZSh7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImlkIjogTWlzc2lvbklELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlIjogTWlzc2lvblR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5hbWUiOiBNaXNzaW9uTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic3RyZWV0IjogTWlzc2lvblN0cmVldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidmlsbGFnZSI6IE1pc3Npb25WaWxsYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhdmFpbGFibGUiOiAoYXZhaWxhYmxlICE9PSB1bmRlZmluZWQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJkb25lIjogZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImxhc3RfY2hlY2siOiBNYXRoLmZsb29yKG5ldyBEYXRlKCkuZ2V0VGltZSgpIC8gMTAwMCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5leHRfY2hlY2siOiBNYXRoLmZsb29yKG5ldyBEYXRlKCkuZ2V0VGltZSgpIC8gMTAwMCkgKyAxCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0pOwogICAgICAgIAogICAgICAgIH0KICAgICAgICAKICAgICAgICBmdW5jdGlvbiBBRGlzX0FkZEF2YWlsYWJsZU1pc3Npb25zKE1pc3Npb24pIHsKICAgICAgICAgICAgcmV0dXJuIEFEaXNEQi5BRGlzQXZhaWxhYmVsTWlzc2lvbnMucHV0KHsKICAgICAgICAgICAgICAgIG1pc3Npb25JRDogTWlzc2lvbi5pZCwKICAgICAgICAgICAgICAgIHR5cGU6IE1pc3Npb24udHlwZSwKICAgICAgICAgICAgICAgIG5hbWU6IE1pc3Npb24ubmFtZSwKICAgICAgICAgICAgICAgIGpzb25kYXRhOiBNaXNzaW9uCiAgICAgICAgICAgIH0pLmNhdGNoKChlcnIpID0+IHsKICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKQogICAgICAgICAgICB9KQogICAgICAgIH0KICAgICAgICAKICAgICAgICBmdW5jdGlvbiBBRGlzX0FkZE1pc3Npb25Ub1F1ZXVlKE1pc3Npb24pIHsKICAgICAgICAgICAgcmV0dXJuIEFEaXNEQi5BRGlzTWlzc2lvbnNPd24ucHV0KHsKICAgICAgICAgICAgICAgIG1pc3Npb25JRDogTWlzc2lvbi5pZCwKICAgICAgICAgICAgICAgIHR5cGU6IE1pc3Npb24udHlwZSwKICAgICAgICAgICAgICAgIG5hbWU6IE1pc3Npb24ubmFtZSwKICAgICAgICAgICAgICAgIGF2YWlsYWJsZTogTWlzc2lvbi5hdmFpbGFibGUgPyAndHJ1ZScgOiAnZmFsc2UnLAogICAgICAgICAgICAgICAgZG9uZTogTWlzc2lvbi5kb25lID8gJ3RydWUnIDogJ2ZhbHNlJywKICAgICAgICAgICAgICAgIHN0cmVldDogTWlzc2lvbi5zdHJlZXQsCiAgICAgICAgICAgICAgICB2aWxsYWdlOiBNaXNzaW9uLnZpbGxhZ2UsCiAgICAgICAgICAgICAgICBsYXN0X2NoZWNrOiBNaXNzaW9uLmxhc3RfY2hlY2ssCiAgICAgICAgICAgICAgICBuZXh0X2NoZWNrOiBNaXNzaW9uLm5leHRfY2hlY2sKICAgICAgICAgICAgfSkuY2F0Y2goKGVycikgPT4gewogICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpCiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBmdW5jdGlvbiBBRGlzX1JlbW92ZU1pc3Npb25Gcm9tUXVldWUoTWlzc2lvbklEKSB7CiAgICAgICAgICAgIHJldHVybiBBRGlzREIuQURpc01pc3Npb25zT3duLndoZXJlKHsKICAgICAgICAgICAgICAgIG1pc3Npb25JRDogTWlzc2lvbklECiAgICAgICAgICAgIH0pLmRlbGV0ZSgpOwogICAgICAgIH0KICAgICAgICAvLyAtID1yZXF1aXJlIG1pc3Npb24vb3BlbmVyLmpzCiAgICAgICAgJChkb2N1bWVudCkucmVhZHkoZnVuY3Rpb24gKCkgewogICAgICAgICAgICBzZXRUaW1lb3V0KEFEaXNfT3Blbk5leHRPd25NaXNzaW9ucywgNTAwMCk7CiAgICAgICAgICAgIHNldFRpbWVvdXQoQURpc19Db2xsZWN0T3duTWlzc2lvbnMsIDUwMCk7CiAgICAgICAgfSk7CiAgICAgICAgCiAgICAgICAgLy8gIC0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0KICAgICAgICAvLyAgLQogICAgICAgIC8vICAtICAgICAgICAgICBDb2xsZWN0IE93biBNaXNzaW9ucwogICAgICAgIC8vICAtCiAgICAgICAgLy8gIC0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0KICAgICAgICAKICAgICAgICBmdW5jdGlvbiBBRGlzX0NvbGxlY3RPd25NaXNzaW9ucygpIHsKICAgICAgICAKICAgICAgICAgICAgdmFyIG9ic2VydmVyMiA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKGZ1bmN0aW9uIChtdXRhdGlvbnMpIHsKICAgICAgICAgICAgICAgIGlmIChtdXRhdGlvbnNbMF0udHlwZSA9PSAiY2hpbGRMaXN0IikgewogICAgICAgICAgICAgICAgICAgIGlmIChtdXRhdGlvbnNbMF0uYWRkZWROb2Rlcy5sZW5ndGggPj0gMSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBkbyBpdCBoZXJlCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXV0YXRpb25zWzBdLmFkZGVkTm9kZXMubGVuZ3RoOyBpKyspCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1JlYWRBbmRBZGRPd25NaXNzaW9ucyhtdXRhdGlvbnNbMF0uYWRkZWROb2Rlc1tpXS5hdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgibWlzc2lvbl9pZCIpLnZhbHVlKQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coIkRFQlVHIE93bk1pc3Npb25zIiwgbXV0YXRpb25zKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgCiAgICAgICAgICAgIC8vIE5vdGlmeSBuZXcgYWxlcnRzCiAgICAgICAgICAgIHZhciB0YXJnZXROb2RlMiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJtaXNzaW9uX2xpc3QiKTsKICAgICAgICAgICAgb2JzZXJ2ZXIyLm9ic2VydmUodGFyZ2V0Tm9kZTIsIHsKICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IGZhbHNlLAogICAgICAgICAgICAgICAgLy9hdHRyaWJ1dGVGaWx0ZXI6IFsnY2xhc3MnXSwKICAgICAgICAgICAgICAgIC8vYXR0cmlidXRlT2xkVmFsdWU6IHRydWUsCiAgICAgICAgICAgICAgICBjaGFyYWN0ZXJEYXRhOiBmYWxzZSwKICAgICAgICAgICAgICAgIGNoYXJhY3RlckRhdGFPbGRWYWx1ZTogZmFsc2UsCiAgICAgICAgICAgICAgICBjaGlsZExpc3Q6IHRydWUsCiAgICAgICAgICAgICAgICBzdWJ0cmVlOiBmYWxzZQogICAgICAgICAgICB9KTsKICAgICAgICAKICAgICAgICAgICAgQURpc19SZWFkQW5kQWRkT3duTWlzc2lvbnMoKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgZnVuY3Rpb24gQURpc19SZWFkQW5kQWRkT3duTWlzc2lvbnMoTWlzc2lvbklEKSB7CiAgICAgICAgICAgIGlmICh0eXBlb2YgTWlzc2lvbklEICE9ICJ1bmRlZmluZWQiKSB7CiAgICAgICAgICAgICAgICBBRGlzX0FkZE93bk1pc3Npb25zVG9RdWV1ZShNaXNzaW9uSUQpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJCgiI21pc3Npb25fbGlzdCIpLmZpbmQoIi5taXNzaW9uU2lkZUJhckVudHJ5IikuZWFjaChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgTWlzc2lvbklEID0gJCh0aGlzKS5hdHRyKCJtaXNzaW9uX2lkIik7CiAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgLy8gICAgICAtIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tCiAgICAgICAgICAgICAgICAgICAgLy8gICAgICAtCiAgICAgICAgICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICBBbWJ1bGFuY2UgU2VydmljZSAgfCAgRnVsbC1BdXRvbWF0aWMKICAgICAgICAgICAgICAgICAgICAvLyAgICAgIC0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0KICAgICAgICAKICAgICAgICAgICAgICAgICAgICBBRGlzX0FkZE93bk1pc3Npb25zVG9RdWV1ZShNaXNzaW9uSUQpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgZnVuY3Rpb24gQURpc19PcGVuTmV4dE93bk1pc3Npb25zKCkgewogICAgICAgICAgICBBRGlzU2V0dGluZ3MoKS50aGVuKChzZXR0aW5nKSA9PiB7CiAgICAgICAgICAgICAgICBpZiAoc2V0dGluZ1snTWlzc2lvbnNPd24tQXV0b21hdGljJ10gPT0gJ3RydWUnKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEFEaXNEQi5BRGlzTWlzc2lvbnNPd24ud2hlcmUoewogICAgICAgICAgICAgICAgICAgICAgICBkb25lOiAnZmFsc2UnCiAgICAgICAgICAgICAgICAgICAgfSkuYW5kKGZ1bmN0aW9uIChpdGVtKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpdGVtLm5leHRfY2hlY2sgPD0gTWF0aC5mbG9vcihuZXcgRGF0ZSgpLmdldFRpbWUoKSAvIDEwMDApCiAgICAgICAgICAgICAgICAgICAgfSkubGltaXQoMSkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSkudGhlbigoV3Vuc2NoKSA9PiB7CiAgICAgICAgICAgICAgICBpZiAoV3Vuc2NoICE9PSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gV3Vuc2NoLmNvdW50KGZ1bmN0aW9uIChjb3VudCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY291bnQgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gV3Vuc2NoLmVhY2goKG15V3Vuc2NoKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IE1pc3Npb25JRCA9IG15V3Vuc2NoLm1pc3Npb25JRDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBteVd1bnNjaC5uZXh0X2NoZWNrID0gTWF0aC5mbG9vcihuZXcgRGF0ZSgpLmdldFRpbWUoKSAvIDEwMDApICsgMzAwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBBRGlzX1VwZGF0ZU93bk1pc3Npb25zKG15V3Vuc2NoKS50aGVuKCgpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCQoIiNhZGlzLW93bm1pc3Npb25zLWZyYW1lIikuYXR0cigibWlzc2lvbl9pZCIpID09ICJlbXB0eSIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoIiNhZGlzLW93bm1pc3Npb25zLWZyYW1lIikuYXR0cigic3JjIiwgImh0dHBzOi8vd3d3LmxlaXRzdGVsbGVuc3BpZWwuZGUvbWlzc2lvbnMvIiArIE1pc3Npb25JRCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKCIjYWRpcy1vd25taXNzaW9ucy1mcmFtZSIpLmF0dHIoIm1pc3Npb25faWQiLCBNaXNzaW9uSUQpOwogICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3duTWlzc2lvbnNGcmFtZVdhdGNoRG9nID0gc2V0VGltZW91dChhc3luYyBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQURpc19SZW1vdmVPd25NaXNzaW9uc0Zyb21RdWV1ZShNaXNzaW9uSUQpLnRoZW4oKGRlbGV0ZUNvdW50KSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRPRE86IHRlbGxQYXJlbnQoIkFEaXNNaXNzaW9uRG9uZSgiICsgd2luZG93Lm5hbWUgKyAiLCIgKyBNaXNzaW9uSUQgKyAiKTsiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJCgiI2FkaXMtb3dubWlzc2lvbnMtZnJhbWUiKS5hdHRyKCJzcmMiLCAiIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoIiNhZGlzLW93bm1pc3Npb25zLWZyYW1lIikuYXR0cigibWlzc2lvbl9pZCIsICJlbXB0eSIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KEFEaXNfT3Blbk5leHRPd25NaXNzaW9ucywgMTAwMCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCA1MDAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoQURpc19PcGVuTmV4dE93bk1pc3Npb25zLCA1MDAwKTsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBzZXRUaW1lb3V0KEFEaXNfT3Blbk5leHRPd25NaXNzaW9ucywgNTAwMCk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAKICAgICAgICB3aW5kb3cuQURpc19BZGRPd25NaXNzaW9uc1RvUXVldWUgPSBmdW5jdGlvbiBBRGlzX0FkZE93bk1pc3Npb25zVG9RdWV1ZShNaXNzaW9uSUQpIHsKICAgICAgICAgICAgcmV0dXJuIEFEaXNEQi5BRGlzTWlzc2lvbnNPd24uYWRkKHsKICAgICAgICAgICAgICAgIG1pc3Npb25JRDogTWlzc2lvbklELAogICAgICAgICAgICAgICAgZG9uZTogJ2ZhbHNlJwogICAgICAgICAgICB9KS5jYXRjaCgoZXJyKSA9PiB7fSkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgd2luZG93LkFEaXNfVXBkYXRlT3duTWlzc2lvbnMgPSBmdW5jdGlvbiBBRGlzX1VwZGF0ZU93bk1pc3Npb25zKE1pc3Npb24pIHsKICAgICAgICAgICAgcmV0dXJuIEFEaXNEQi5BRGlzTWlzc2lvbnNPd24ucHV0KE1pc3Npb24pLmNhdGNoKChlcnIpID0+IHt9KQogICAgICAgIH0KICAgICAgICAKICAgICAgICB3aW5kb3cuQURpc19VcGRhdGVPd25NaXNzaW9uc1RvRG9uZSA9IGZ1bmN0aW9uIEFEaXNfVXBkYXRlT3duTWlzc2lvbnNUb0RvbmUoTWlzc2lvbklEKSB7CiAgICAgICAgICAgIHJldHVybiBBRGlzREIuQURpc01pc3Npb25zT3duLnVwZGF0ZShNaXNzaW9uSUQsIHsKICAgICAgICAgICAgICAgIG1pc3Npb25JRDogTWlzc2lvbklELAogICAgICAgICAgICAgICAgZG9uZTogJ3RydWUnCiAgICAgICAgICAgIH0pLmNhdGNoKChlcnIpID0+IHt9KQogICAgICAgIH0KICAgICAgICAKICAgICAgICB3aW5kb3cuQURpc19SZW1vdmVPd25NaXNzaW9uc0Zyb21RdWV1ZSA9IGZ1bmN0aW9uIEFEaXNfUmVtb3ZlT3duTWlzc2lvbnNGcm9tUXVldWUoTWlzc2lvbklEKSB7CiAgICAgICAgICAgIHJldHVybiBBRGlzREIuQURpc01pc3Npb25zT3duLndoZXJlKHsKICAgICAgICAgICAgICAgIG1pc3Npb25JRDogTWlzc2lvbklECiAgICAgICAgICAgIH0pLmRlbGV0ZSgpOwogICAgICAgIH0KICAgICAgICAkKGRvY3VtZW50KS5yZWFkeShmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHNldFRpbWVvdXQoQURpc19PcGVuTmV4dEtyYW5rZW50cmFuc3BvcnRlLCA1MDAwKTsKICAgICAgICAgICAgc2V0VGltZW91dChBRGlzX0NvbGxlY3RLcmFua2VudHJhbnNwb3J0ZSwgNTAwKTsKICAgICAgICB9KTsKICAgICAgICAKICAgICAgICAvLyAgLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLQogICAgICAgIC8vICAtCiAgICAgICAgLy8gIC0gICAgICAgICAgIENvbGxlY3QgS3JhbmtlbnRyYW5zcG9ydGUKICAgICAgICAvLyAgLQogICAgICAgIC8vICAtIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tCiAgICAgICAgCiAgICAgICAgZnVuY3Rpb24gQURpc19Db2xsZWN0S3JhbmtlbnRyYW5zcG9ydGUoKSB7CiAgICAgICAgCiAgICAgICAgICAgIHZhciBvYnNlcnZlcjIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcihmdW5jdGlvbiAobXV0YXRpb25zKSB7CiAgICAgICAgICAgICAgICBpZiAobXV0YXRpb25zWzBdLnR5cGUgPT0gImNoaWxkTGlzdCIpIHsKICAgICAgICAgICAgICAgICAgICBpZiAobXV0YXRpb25zWzBdLmFkZGVkTm9kZXMubGVuZ3RoID49IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gZG8gaXQgaGVyZQogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG11dGF0aW9uc1swXS5hZGRlZE5vZGVzLmxlbmd0aDsgaSsrKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgQURpc19SZWFkQW5kQWRkS3JhbmtlbnRyYW5zcG9ydGUobXV0YXRpb25zWzBdLmFkZGVkTm9kZXNbaV0uYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0oIm1pc3Npb25faWQiKS52YWx1ZSkKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCJERUJVRyBLcmFua2VudHJhbnNwb3J0ZSIsIG11dGF0aW9ucyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIAogICAgICAgICAgICAvLyBOb3RpZnkgbmV3IGFsZXJ0cwogICAgICAgICAgICB2YXIgdGFyZ2V0Tm9kZTIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgibWlzc2lvbl9saXN0X2tyYW5rZW50cmFuc3BvcnRlIik7CiAgICAgICAgICAgIG9ic2VydmVyMi5vYnNlcnZlKHRhcmdldE5vZGUyLCB7CiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiBmYWxzZSwKICAgICAgICAgICAgICAgIC8vYXR0cmlidXRlRmlsdGVyOiBbJ2NsYXNzJ10sCiAgICAgICAgICAgICAgICAvL2F0dHJpYnV0ZU9sZFZhbHVlOiB0cnVlLAogICAgICAgICAgICAgICAgY2hhcmFjdGVyRGF0YTogZmFsc2UsCiAgICAgICAgICAgICAgICBjaGFyYWN0ZXJEYXRhT2xkVmFsdWU6IGZhbHNlLAogICAgICAgICAgICAgICAgY2hpbGRMaXN0OiB0cnVlLAogICAgICAgICAgICAgICAgc3VidHJlZTogZmFsc2UKICAgICAgICAgICAgfSk7CiAgICAgICAgCiAgICAgICAgICAgIEFEaXNfUmVhZEFuZEFkZEtyYW5rZW50cmFuc3BvcnRlKCk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGZ1bmN0aW9uIEFEaXNfUmVhZEFuZEFkZEtyYW5rZW50cmFuc3BvcnRlKE1pc3Npb25JRCkgewogICAgICAgICAgICBpZiAodHlwZW9mIE1pc3Npb25JRCAhPSAidW5kZWZpbmVkIikgewogICAgICAgICAgICAgICAgQURpc19BZGRLcmFua2VudHJhbnNwb3J0VG9RdWV1ZShNaXNzaW9uSUQpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJCgiI21pc3Npb25fbGlzdF9rcmFua2VudHJhbnNwb3J0ZSIpLmZpbmQoIi5taXNzaW9uU2lkZUJhckVudHJ5IikuZWFjaChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgTWlzc2lvbklEID0gJCh0aGlzKS5hdHRyKCJtaXNzaW9uX2lkIik7CiAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgLy8gICAgICAtIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tCiAgICAgICAgICAgICAgICAgICAgLy8gICAgICAtCiAgICAgICAgICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICBBbWJ1bGFuY2UgU2VydmljZSAgfCAgRnVsbC1BdXRvbWF0aWMKICAgICAgICAgICAgICAgICAgICAvLyAgICAgIC0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0KICAgICAgICAKICAgICAgICAgICAgICAgICAgICBBRGlzX0FkZEtyYW5rZW50cmFuc3BvcnRUb1F1ZXVlKE1pc3Npb25JRCk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBmdW5jdGlvbiBBRGlzX09wZW5OZXh0S3JhbmtlbnRyYW5zcG9ydGUoKSB7CiAgICAgICAgICAgIEFEaXNTZXR0aW5ncygpLnRoZW4oKHNldHRpbmcpID0+IHsKICAgICAgICAgICAgICAgIGlmIChzZXR0aW5nWydLcmFua2VudHJhbnNwb3J0LUF1dG9tYXRpYyddID09ICd0cnVlJykgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBBRGlzREIuQURpc0tyYW5rZW50cmFuc3BvcnQud2hlcmUoewogICAgICAgICAgICAgICAgICAgICAgICBkb25lOiAnZmFsc2UnCiAgICAgICAgICAgICAgICAgICAgfSkuYW5kKGZ1bmN0aW9uIChpdGVtKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpdGVtLm5leHRfY2hlY2sgPD0gTWF0aC5mbG9vcihuZXcgRGF0ZSgpLmdldFRpbWUoKSAvIDEwMDApCiAgICAgICAgICAgICAgICAgICAgfSkubGltaXQoMSkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSkudGhlbigoV3Vuc2NoKSA9PiB7CiAgICAgICAgICAgICAgICBpZiAoV3Vuc2NoICE9PSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gV3Vuc2NoLmNvdW50KGZ1bmN0aW9uIChjb3VudCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY291bnQgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gV3Vuc2NoLmVhY2goKG15V3Vuc2NoKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IE1pc3Npb25JRCA9IG15V3Vuc2NoLm1pc3Npb25JRDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBteVd1bnNjaC5uZXh0X2NoZWNrID0gTWF0aC5mbG9vcihuZXcgRGF0ZSgpLmdldFRpbWUoKSAvIDEwMDApICsgMzAwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBBRGlzX1VwZGF0ZUtyYW5rZW50cmFuc3BvcnQobXlXdW5zY2gpLnRoZW4oKCkgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJCgiI2FkaXMta3JhbmtlbnRyYW5zcG9ydGUtZnJhbWUiKS5hdHRyKCJtaXNzaW9uX2lkIikgPT0gImVtcHR5IikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJCgiI2FkaXMta3JhbmtlbnRyYW5zcG9ydGUtZnJhbWUiKS5hdHRyKCJzcmMiLCAiaHR0cHM6Ly93d3cubGVpdHN0ZWxsZW5zcGllbC5kZS9taXNzaW9ucy8iICsgTWlzc2lvbklEKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoIiNhZGlzLWtyYW5rZW50cmFuc3BvcnRlLWZyYW1lIikuYXR0cigibWlzc2lvbl9pZCIsIE1pc3Npb25JRCk7CiAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLcmFua2VudHJhbnNwb3J0RnJhbWVXYXRjaERvZyA9IHNldFRpbWVvdXQoYXN5bmMgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoIiNhZGlzLWtyYW5rZW50cmFuc3BvcnRlLWZyYW1lIikuYXR0cigic3JjIiwgIiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoIiNhZGlzLWtyYW5rZW50cmFuc3BvcnRlLWZyYW1lIikuYXR0cigibWlzc2lvbl9pZCIsICJlbXB0eSIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoQURpc19PcGVuTmV4dEtyYW5rZW50cmFuc3BvcnRlLCAxMDAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIDUwMDApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2V0VGltZW91dChBRGlzX09wZW5OZXh0S3JhbmtlbnRyYW5zcG9ydGUsIDUwMDApOwogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoQURpc19PcGVuTmV4dEtyYW5rZW50cmFuc3BvcnRlLCA1MDAwKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIAogICAgICAgIHdpbmRvdy5BRGlzX0FkZEtyYW5rZW50cmFuc3BvcnRUb1F1ZXVlID0gZnVuY3Rpb24gQURpc19BZGRLcmFua2VudHJhbnNwb3J0VG9RdWV1ZShNaXNzaW9uSUQpIHsKICAgICAgICAgICAgcmV0dXJuIEFEaXNEQi5BRGlzS3JhbmtlbnRyYW5zcG9ydC5hZGQoewogICAgICAgICAgICAgICAgbWlzc2lvbklEOiBNaXNzaW9uSUQsCiAgICAgICAgICAgICAgICBkb25lOiAnZmFsc2UnCiAgICAgICAgICAgIH0pLmNhdGNoKChlcnIpID0+IHt9KQogICAgICAgIH0KICAgICAgICAKICAgICAgICB3aW5kb3cuQURpc19VcGRhdGVLcmFua2VudHJhbnNwb3J0ID0gZnVuY3Rpb24gQURpc19VcGRhdGVLcmFua2VudHJhbnNwb3J0KE1pc3Npb24pIHsKICAgICAgICAgICAgcmV0dXJuIEFEaXNEQi5BRGlzS3JhbmtlbnRyYW5zcG9ydC5wdXQoTWlzc2lvbikuY2F0Y2goKGVycikgPT4ge30pCiAgICAgICAgfQogICAgICAgIAogICAgICAgIHdpbmRvdy5BRGlzX1VwZGF0ZUtyYW5rZW50cmFuc3BvcnRUb0RvbmUgPSBmdW5jdGlvbiBBRGlzX1VwZGF0ZUtyYW5rZW50cmFuc3BvcnRUb0RvbmUoTWlzc2lvbklEKSB7CiAgICAgICAgICAgIHJldHVybiBBRGlzREIuQURpc0tyYW5rZW50cmFuc3BvcnQudXBkYXRlKE1pc3Npb25JRCwgewogICAgICAgICAgICAgICAgbWlzc2lvbklEOiBNaXNzaW9uSUQsCiAgICAgICAgICAgICAgICBkb25lOiAndHJ1ZScKICAgICAgICAgICAgfSkuY2F0Y2goKGVycikgPT4ge30pCiAgICAgICAgfQogICAgICAgIAogICAgICAgIHdpbmRvdy5BRGlzX1JlbW92ZUtyYW5rZW50cmFuc3BvcnRGcm9tUXVldWUgPSBmdW5jdGlvbiBBRGlzX1JlbW92ZUtyYW5rZW50cmFuc3BvcnRGcm9tUXVldWUoTWlzc2lvbklEKSB7CiAgICAgICAgICAgIHJldHVybiBBRGlzREIuQURpc0tyYW5rZW50cmFuc3BvcnQud2hlcmUoewogICAgICAgICAgICAgICAgbWlzc2lvbklEOiBNaXNzaW9uSUQKICAgICAgICAgICAgfSkuZGVsZXRlKCk7CiAgICAgICAgfQogICAgfQogICAgCiAgICAKICAgIAogICAgLy8gICAgICAtCiAgICAvLyAgICAgIC0gICAgICAgICAgIE1pc3Npb24gQWxlcnQKICAgIC8vICAgICAgLQogICAgaWYgKHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZS5pbmRleE9mKCIvbWlzc2lvbnMvIikgIT09IC0xICYmIFsnYWRpcy1rcmFua2VudHJhbnNwb3J0ZScsICdhZGlzLW93bm1pc3Npb25zJywgJ2FkaXMtdmVyYmFuZG1pc3Npb24nLCAnYWRpcy12ZXJiYW5kbWlzc2lvbi1ldmVudCddLmluZGV4T2Yod2luZG93Lm5hbWUpICE9PSAtMSkgewogICAgICAgICQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICBNaXNzaW9uSUQgPSBkb2N1bWVudC5sb2NhdGlvbi5wYXRobmFtZS5zdWJzdHIoZG9jdW1lbnQubG9jYXRpb24ucGF0aG5hbWUubGFzdEluZGV4T2YoIi8iKSArIDEpOwogICAgICAgICAgICAgICAgdmFyIGhlbHBfZWwgPSAkKCdhI21pc3Npb25faGVscCcpOwogICAgICAgICAgICAgICAgaWYgKGhlbHBfZWwubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgIE1pc3Npb25UeXBlID0gaGVscF9lbFswXS5ocmVmLnNwbGl0KCI/IilbMF07CiAgICAgICAgICAgICAgICAgICAgdmFyIHJlID0gL1xkKyQvaTsKICAgICAgICAgICAgICAgICAgICB2YXIgZm91bmQgPSBNaXNzaW9uVHlwZS5tYXRjaChyZSk7CiAgICAgICAgICAgICAgICAgICAgTWlzc2lvblR5cGUgPSBOdW1iZXIoZm91bmRbMF0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgQ3VycmVudFRpbWUgPSBNYXRoLmZsb29yKG5ldyBEYXRlKCkuZ2V0VGltZSgpIC8gMTAwMCk7CiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygiTWlzc2lvbklEIiwgTWlzc2lvbklEKTsKICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCJNaXNzaW9uVHlwZSIsIE1pc3Npb25UeXBlKTsKICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCJDdXJyZW50VGltZSIsIEN1cnJlbnRUaW1lKTsKICAgICAgICAgICAgICAgIGlmIChNaXNzaW9uVHlwZSAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGlmIChpbmNsdWRlc1N0cmluZygkKCcjaWZyYW1lLWluc2lkZS1jb250YWluZXIgPiBkaXYubWlzc2lvbk5vdEZvdW5kID4gZGl2Lm1pc3Npb25Ob3RGb3VuZFRleHQnKS50ZXh0KCksJ0RlciBFaW5zYXR6IHd1cmRlIGVyZm9sZ3JlaWNoIGFiZ2VzY2hsb3NzZW4uJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOyAvLyBkZWxldGUgTWlzc2lvbiBoZXJlIGFzIGNvbXBsZXRlZAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoaW5jbHVkZXNTdHJpbmcoJCgnI2lmcmFtZS1pbnNpZGUtY29udGFpbmVyID4gZGl2LmFsZXJ0LmZhZGUuaW4uYWxlcnQtc3VjY2VzcycpLnRleHQoKSwgInd1cmRlIGVyZm9sZ3JlaWNoIGluZm9ybWllcnQiKSB8fCAkKCcjdmVoaWNsZV9zaG93X3RhYmxlX2FsbCBpbnB1dFt0eXBlPSJjaGVja2JveCJdOmNoZWNrZWQnKS5zaXplKCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsgLy8gdXBkYXRlIE1pc3Npb24gaGVyZSBhcyB1cGRhdGVkIG9yIGZ1bGwKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChbJ2FkaXMtb3dubWlzc2lvbnMnLCAnYWRpcy1rcmFua2VudHJhbnNwb3J0ZSddLmluZGV4T2Yod2luZG93Lm5hbWUpICE9IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBBRGlzX0NoZWNrTWlzc2lvbkF1dG9tYXRpYygpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFsnYWRpcy12ZXJiYW5kbWlzc2lvbicsJ2FkaXMtdmVyYmFuZG1pc3Npb24tZXZlbnQnXS5pbmRleE9mKHdpbmRvdy5uYW1lKSAhPSAtMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgQURpc19Xb3JrVmVyYmFuZE1pc3Npb24oKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0sIDQwMCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sIDI1MCk7CiAgICAgICAgfSk7CiAgICAgICAgCiAgICAgICAgLy8gIC0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0KICAgICAgICAvLyAgLQogICAgICAgIC8vICAtICAgICAgICAgICAgICAgICAgIEdyYWIgUnVuIFZlcmJhbmRzIE1pc3Npb25zCiAgICAgICAgLy8gIC0KICAgICAgICAvLyAgLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLQogICAgICAgIAogICAgICAgIGZ1bmN0aW9uIEFEaXNfV29ya1ZlcmJhbmRNaXNzaW9uKCkgewogICAgICAgICAgICBBRGlzU2V0dGluZ3MoKS50aGVuKChzZXR0aW5nKSA9PiB7CiAgICAgICAgICAgICAgICB2YXIgdGl0bGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWlzc2lvbkgxJyk7CiAgICAgICAgICAgICAgICB2YXIgaXNWZXJiYW5kID0gdGl0bGUuaW5uZXJUZXh0LnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoIlt2ZXJiYW5kXSIpOwogICAgICAgICAgICAgICAgaWYgKHNldHRpbmdbJ0FsbGlhbmNlLUF1dG9tYXRpYyddID09ICd0cnVlJyAmJiBpc1ZlcmJhbmQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJCgnI3ZlaGljbGVfc2hvd190YWJsZV9hbGwgdHJbdmVoaWNsZV90eXBlPSJGdVN0VyJdIGlucHV0W3R5cGU9ImNoZWNrYm94Il0nKS5zaXplKCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICQoJyN2ZWhpY2xlX3Nob3dfdGFibGVfYWxsIHRyW3ZlaGljbGVfdHlwZT0iRnVTdFciXSBpbnB1dFt0eXBlPSJjaGVja2JveCJdJylbMF0uY2xpY2soKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCQoJyN2ZWhpY2xlX3Nob3dfdGFibGVfYWxsIHRyW3ZlaGljbGVfdHlwZT0iS1RXIFR5cCBCIl0gaW5wdXRbdHlwZT0iY2hlY2tib3giXScpLnNpemUoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgJCgnI3ZlaGljbGVfc2hvd190YWJsZV9hbGwgdHJbdmVoaWNsZV90eXBlPSJLVFcgVHlwIEIiXSBpbnB1dFt0eXBlPSJjaGVja2JveCJdJylbMF0uY2xpY2soKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKCQoJyN2ZWhpY2xlX3Nob3dfdGFibGVfYWxsIGlucHV0W3R5cGU9ImNoZWNrYm94Il06Y2hlY2tlZCcpLnNpemUoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgJCgnI21pc3Npb25fYWxhcm1fYnRuJykuY2xpY2soKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvLyAgLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLQogICAgICAgIC8vICAtCiAgICAgICAgLy8gIC0gICAgICAgICAgICAgICAgICAgR3JhYiBNaXNzaW9uLUNvbmZpZ3VyYXRpb24gZnJvbSBHaXRIdWIKICAgICAgICAvLyAgLQogICAgICAgIC8vICAtIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tCiAgICAgICAgCiAgICAgICAgZnVuY3Rpb24gQURpc19DaGVja01pc3Npb25BdXRvbWF0aWMoKSB7CiAgICAgICAgICAgIHZhciBzZXRPcHQ7CiAgICAgICAgICAgIHZhciBtaXNzaW9uTG9hZDsKICAgICAgICAgICAgaWYgKHdpbmRvdy5uYW1lID09ICdhZGlzLW93bm1pc3Npb25zJykgewogICAgICAgICAgICAgICAgc2V0T3B0ID0gJ01pc3Npb25zT3duLUF1dG9tYXRpYyc7CiAgICAgICAgICAgICAgICBtaXNzaW9uTG9hZCA9ICdBRGlzTWlzc2lvbnNPd24nOwogICAgICAgICAgICB9IGVsc2UgaWYgKHdpbmRvdy5uYW1lID09ICdhZGlzLWtyYW5rZW50cmFuc3BvcnRlJykgewogICAgICAgICAgICAgICAgc2V0T3B0ID0gJ0tyYW5rZW50cmFuc3BvcnQtQXV0b21hdGljJzsKICAgICAgICAgICAgICAgIG1pc3Npb25Mb2FkID0gJ0FEaXNLcmFua2VudHJhbnNwb3J0JzsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoc2V0T3B0ICYmIG1pc3Npb25Mb2FkKSB7CiAgICAgICAgICAgICAgICBBRGlzU2V0dGluZ3MoKS50aGVuKChzZXR0aW5nKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHNldHRpbmdbc2V0T3B0XSA9PSAndHJ1ZScpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbGwgPSBBRGlzREJbbWlzc2lvbkxvYWRdLndoZXJlKHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbmU6ICdmYWxzZScKICAgICAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1pc3Npb25Mb2FkICE9ICJBRGlzS3JhbmtlbnRyYW5zcG9ydCIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbGwgPSBjb2xsLmFuZChmdW5jdGlvbiAoaXRlbSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpdGVtLm5leHRfY2hlY2sgPCBNYXRoLmZsb29yKG5ldyBEYXRlKCkuZ2V0VGltZSgpIC8gMTAwMCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb2xsLmxpbWl0KDEpLnRvQXJyYXkoKQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pLnRoZW4oKE1pc3Npb25zKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgaWYgKE1pc3Npb25zLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIE1pc3Npb24gPSBNaXNzaW9uc1swXTsKICAgICAgICAgICAgICAgICAgICAgICAgQURfR2V0TWlzc2lvbkNvbmZpZ3VyYXRpb24obWlzc2lvbkxvYWQgPT0gJ0FEaXNLcmFua2VudHJhbnNwb3J0JyA/IDE0NyA6IE1pc3Npb24udHlwZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgZnVuY3Rpb24gQURfR2V0TWlzc2lvbkNvbmZpZ3VyYXRpb24oTWlzc2lvblR5cGUpIHsKICAgICAgICAgICAgcmV0dXJuIEFEaXNEQi50cmFuc2FjdGlvbigncncnLCBbQURpc0RCLkFEaXNNaXNzaW9uc093biwgQURpc0RCLkFEaXNTZXR0aW5ncywgQURpc0RCLkFEaXNBdmFpbGFiZWxNaXNzaW9uc10sICgpID0+IHsKICAgICAgICAgICAgICAgIHJldHVybiBBRGlzREIuQURpc0F2YWlsYWJlbE1pc3Npb25zLmdldCh7CiAgICAgICAgICAgICAgICAgICAgdHlwZTogTWlzc2lvblR5cGUudG9TdHJpbmcoKQogICAgICAgICAgICAgICAgfSkudGhlbigoYXZhaWxhYmxlTWlzc2lvbikgPT4gewogICAgICAgICAgICAgICAgICAgIGlmIChhdmFpbGFibGVNaXNzaW9uICE9IHVuZGVmaW5lZCAmJiBhdmFpbGFibGVNaXNzaW9uLmpzb25kYXRhKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIE1pc3Npb25Db25maWcgPSBhdmFpbGFibGVNaXNzaW9uLmpzb25kYXRhOwogICAgICAgICAgICAgICAgICAgICAgICBBRF9TdGFydEFsYXJtUHJvY2VzcygpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB1cGRhdGVEYXRhID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXZhaWxhYmxlOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRfY2hlY2s6IEN1cnJlbnRUaW1lICsgNjAKICAgICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19VcGRhdGVPd25NaXNzaW9uc1RvRG9uZShNaXNzaW9uSUQsIHVwZGF0ZURhdGEpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9KTsKICAgICAgICAKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgZnVuY3Rpb24gQURfU3RhcnRBbGFybVByb2Nlc3MoKSB7CiAgICAgICAgICAgIGNvbnNvbGUubG9nKCIgIEF1dG9tYXRpYyBEaXNwb3NlOiBTdGFydGUgQWxhcm1pZXJ1bmdzcHJvemVzcyIpOwogICAgICAgIAogICAgICAgIAogICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIC8vIFByb2Nlc3MgRmlyZSBEZXBhcnRtZW50CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbihhc3luYyAoKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXdhaXQgQURpc19QcmVwYXJlVmVoaWNsZU5lZWRMaXN0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0pLnRoZW4oYXN5bmMgKCkgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF3YWl0IEFEaXNfQ29sbGVjdEludm9sdmVkVmVoaWNsZXMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSkudGhlbihhc3luYyAoKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXdhaXQgQURpc19Db2xsZWN0UGF0aWVudHMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oYXN5bmMgKCkgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF3YWl0IFByb21pc2UuYWxsKFsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1Byb2Nlc3NFbWVyZ2VuY3lNZWRpY2FsU2VydmljZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfUHJvY2Vzc0ZpcmVEZXBhcnRtZW50KCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQURpc19Qcm9jZXNzUG9saWNlRGVwYXJ0bWVudCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfUHJvY2Vzc1RlY2huaWNhbEVtZXJnZW5jeVNlcnZpY2UoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1Byb2Nlc3NXYXRlclJlc2N1ZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgXSkudGhlbigocmVzdWx0KSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHVwZGF0ZURhdGEgPSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RfY2hlY2s6IEN1cnJlbnRUaW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0X2NoZWNrOiBDdXJyZW50VGltZSArIDYwCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1VwZGF0ZU93bk1pc3Npb25zVG9Eb25lKE1pc3Npb25JRCwgdXBkYXRlRGF0YSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFsnYWRpcy1vd25taXNzaW9ucycsICdhZGlzLWtyYW5rZW50cmFuc3BvcnRlJywgJ2FkaXMtdmVyYmFuZG1pc3Npb24nXS5pbmRleE9mKHdpbmRvdy5uYW1lKSAhPSAtMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoJyNtaXNzaW9uX2FsYXJtX2J0bicpLmNsaWNrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIDI1MCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgCiAgICAgICAgICAgICAgICB9LCAyNTApOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvLyAgLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLQogICAgICAgIC8vICAtCiAgICAgICAgLy8gIC0gICAgICAgICAgICAgICAgICAgQ29sbGVjdCBJbnZvbHZlZCBWZWhpY2xlcyAmIFBhdGllbnRzCiAgICAgICAgLy8gIC0KICAgICAgICAvLyAgLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLQogICAgICAgIAogICAgICAgIHZhciBBRF9WZWhpY2xlcyA9IHt9OwogICAgICAgIHZhciBBRF9QYXRpZW50cyA9IHt9OwogICAgICAgIAogICAgICAgIGZ1bmN0aW9uIEFEaXNfQ29sbGVjdEludm9sdmVkVmVoaWNsZXMoKSB7CiAgICAgICAgICAgICQoIiNtaXNzaW9uX3ZlaGljbGVfZHJpdmluZyB0Ym9keSIpLmZpbmQoInRyIikuZWFjaChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgVmVoaWNsZUlEID0gJCh0aGlzKS5maW5kKCJhIikuZmlyc3QoKS5hdHRyKCJocmVmIikuc3Vic3RyKCQodGhpcykuZmluZCgiYSIpLmZpcnN0KCkuYXR0cigiaHJlZiIpLmxhc3RJbmRleE9mKCIvIikgKyAxKTsKICAgICAgICAgICAgICAgIHZhciBWZWhpY2xlTmFtZSA9ICQodGhpcykuZmluZCgiYSIpLmZpcnN0KCkudGV4dCgpOwogICAgICAgICAgICAgICAgdmFyIFZlaGljbGVUeXBlID0gJCh0aGlzKS5maW5kKCJhIikuZmlyc3QoKS5hdHRyKCJ2ZWhpY2xlX3R5cGVfaWQiKTsKICAgICAgICAKICAgICAgICAgICAgICAgIEFEX1ZlaGljbGVzW1ZlaGljbGVJRF0gPSB7CiAgICAgICAgICAgICAgICAgICAgImlkIjogVmVoaWNsZUlELAogICAgICAgICAgICAgICAgICAgICJuYW1lIjogVmVoaWNsZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgInR5cGUiOiBWZWhpY2xlVHlwZQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICAKICAgICAgICAgICAgJCgiI21pc3Npb25fdmVoaWNsZV9hdF9taXNzaW9uIHRib2R5IikuZmluZCgidHIiKS5lYWNoKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHZhciBWZWhpY2xlSUQgPSAkKHRoaXMpLmZpbmQoImEiKS5maXJzdCgpLmF0dHIoImhyZWYiKS5zdWJzdHIoJCh0aGlzKS5maW5kKCJhIikuZmlyc3QoKS5hdHRyKCJocmVmIikubGFzdEluZGV4T2YoIi8iKSArIDEpOwogICAgICAgICAgICAgICAgdmFyIFZlaGljbGVOYW1lID0gJCh0aGlzKS5maW5kKCJhIikuZmlyc3QoKS50ZXh0KCk7CiAgICAgICAgICAgICAgICB2YXIgVmVoaWNsZVR5cGUgPSAkKHRoaXMpLmZpbmQoImEiKS5maXJzdCgpLmF0dHIoInZlaGljbGVfdHlwZV9pZCIpOwogICAgICAgIAogICAgICAgICAgICAgICAgQURfVmVoaWNsZXNbVmVoaWNsZUlEXSA9IHsKICAgICAgICAgICAgICAgICAgICAiaWQiOiBWZWhpY2xlSUQsCiAgICAgICAgICAgICAgICAgICAgIm5hbWUiOiBWZWhpY2xlTmFtZSwKICAgICAgICAgICAgICAgICAgICAidHlwZSI6IFZlaGljbGVUeXBlCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIAogICAgICAgICAgICBjb25zb2xlLmxvZygiICBBdXRvbWF0aWMgRGlzcG9zZTogQmVyZWl0cyBiZXRlaWxpZ3RlIEZhaHJ6ZXVnZToiKTsKICAgICAgICAgICAgY29uc29sZS5sb2coQURfVmVoaWNsZXMpOwogICAgICAgICAgICByZXR1cm4gQURfVmVoaWNsZXM7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGZ1bmN0aW9uIEFEaXNfQ29sbGVjdFBhdGllbnRzKCkgewogICAgICAgICAgICB2YXIgUGF0aWVudENvdW50ZXIgPSAwOwogICAgICAgIAogICAgICAgICAgICAkKCIubWlzc2lvbl9wYXRpZW50IikuZWFjaChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgUGF0aWVudE5hbWUgPSAkKHRoaXMpLnRleHQoKTsKICAgICAgICAgICAgICAgIHZhciBQYXRpZW50TmVlZFJUVyA9IGZhbHNlOwogICAgICAgICAgICAgICAgdmFyIFBhdGllbnROZWVkTkVGID0gZmFsc2U7CiAgICAgICAgICAgICAgICB2YXIgUGF0aWVudE5lZWRSVEggPSBmYWxzZTsKICAgICAgICAgICAgICAgIHZhciBQYXRpZW50TmVlZExOQSA9IGZhbHNlOwogICAgICAgICAgICAgICAgdmFyIFBhdGllbnROZWVkT3JnTCA9IGZhbHNlOwogICAgICAgICAgICAgICAgdmFyIFBhdGllbnROZWVkU0VHS1RXQiA9IGZhbHNlOwogICAgICAgICAgICAgICAgdmFyIFBhdGllbnROZWVkVHJhZ2VoaWxmZSA9IGZhbHNlOwogICAgICAgIAogICAgICAgICAgICAgICAgLy8gV2lyIGJlbvZ0aWdlbiBlaW5lbiBSVFcgb2RlciBLVFcgVHlwIEIuCiAgICAgICAgICAgICAgICBpZiAoJCh0aGlzKS5maW5kKCIuYWxlcnQtZGFuZ2VyIikubGVuZ3RoID4gMCAmJiAkKHRoaXMpLmZpbmQoIi5hbGVydC1kYW5nZXIiKS50ZXh0KCkuaW5kZXhPZigiV2lyIGJlbvZ0aWdlbiBlaW5lbiBSVFcgb2RlciBLVFcgVHlwIEIiKSAhPSAtMSkgewogICAgICAgICAgICAgICAgICAgIFBhdGllbnROZWVkU0VHS1RXQiA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgCiAgICAgICAgICAgICAgICAvLyBXaXIgYmVu9nRpZ2VuIGVpbmVuIFJUVy4KICAgICAgICAgICAgICAgIGlmICgkKHRoaXMpLmZpbmQoIi5hbGVydC1kYW5nZXIiKS5sZW5ndGggPiAwICYmICQodGhpcykuZmluZCgiLmFsZXJ0LWRhbmdlciIpLnRleHQoKS5pbmRleE9mKCJXaXIgYmVu9nRpZ2VuIGVpbiBSVFciKSAhPSAtMSkgewogICAgICAgICAgICAgICAgICAgIFBhdGllbnROZWVkUlRXID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAKICAgICAgICAgICAgICAgIC8vIFdpciBiZW72dGlnZW4gZWluZW4gTkVGLgogICAgICAgICAgICAgICAgaWYgKCQodGhpcykuZmluZCgiLmFsZXJ0LWRhbmdlciIpLmxlbmd0aCA+IDAgJiYgJCh0aGlzKS5maW5kKCIuYWxlcnQtZGFuZ2VyIikudGV4dCgpLmluZGV4T2YoIldpciBiZW72dGlnZW4gZWluIE5FRiIpICE9IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgUGF0aWVudE5lZWRORUYgPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgIAogICAgICAgICAgICAgICAgLy8gV2lyIGJlbvZ0aWdlbiBlaW5lbiBSVEguCiAgICAgICAgICAgICAgICBpZiAoJCh0aGlzKS5maW5kKCIuYWxlcnQtZGFuZ2VyIikubGVuZ3RoID4gMCAmJiAkKHRoaXMpLmZpbmQoIi5hbGVydC1kYW5nZXIiKS50ZXh0KCkuaW5kZXhPZigiV2lyIGJlbvZ0aWdlbiBlaW4gUlRIIikgIT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICBQYXRpZW50TmVlZFJUSCA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgCiAgICAgICAgICAgICAgICAvLyBXaXIgYmVu9nRpZ2VuIGVpbmVuIExOQS4KICAgICAgICAgICAgICAgIGlmICgkKHRoaXMpLmZpbmQoIi5hbGVydC1kYW5nZXIiKS5sZW5ndGggPiAwICYmICQodGhpcykuZmluZCgiLmFsZXJ0LWRhbmdlciIpLnRleHQoKS5pbmRleE9mKCJXaXIgYmVu9nRpZ2VuIGVpbmVuIExOQSIpICE9IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgUGF0aWVudE5lZWRMTkEgPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgIAogICAgICAgICAgICAgICAgLy8gV2lyIGJlbvZ0aWdlbiBlaW5lbiBPcmdMLgogICAgICAgICAgICAgICAgaWYgKCQodGhpcykuZmluZCgiLmFsZXJ0LWRhbmdlciIpLmxlbmd0aCA+IDAgJiYgJCh0aGlzKS5maW5kKCIuYWxlcnQtZGFuZ2VyIikudGV4dCgpLmluZGV4T2YoIldpciBiZW72dGlnZW4gZWluZW4gT3JnTCIpICE9IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgUGF0aWVudE5lZWRPcmdMID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAKICAgICAgICAgICAgICAgIC8vIFdpciBiZW72dGlnZW4gZWluZSBUcmFnZWhpbGZlICh6LkIuIGR1cmNoIGVpbiBMRikuCiAgICAgICAgICAgICAgICBpZiAoJCh0aGlzKS5maW5kKCIuYWxlcnQtZGFuZ2VyIikubGVuZ3RoID4gMCAmJiAkKHRoaXMpLmZpbmQoIi5hbGVydC1kYW5nZXIiKS50ZXh0KCkuaW5kZXhPZigiV2lyIGJlbvZ0aWdlbiBlaW5lIFRyYWdlaGlsZmUiKSAhPSAtMSkgewogICAgICAgICAgICAgICAgICAgIFBhdGllbnROZWVkVHJhZ2VoaWxmZSA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgCiAgICAgICAgICAgICAgICBBRF9QYXRpZW50c1tQYXRpZW50Q291bnRlcl0gPSB7CiAgICAgICAgICAgICAgICAgICAgIm5hbWUiOiBQYXRpZW50TmFtZSwKICAgICAgICAgICAgICAgICAgICAibmVlZF9SVFciOiBQYXRpZW50TmVlZFJUVywKICAgICAgICAgICAgICAgICAgICAibmVlZF9ORUYiOiBQYXRpZW50TmVlZE5FRiwKICAgICAgICAgICAgICAgICAgICAibmVlZF9SVEgiOiBQYXRpZW50TmVlZFJUSCwKICAgICAgICAgICAgICAgICAgICAibmVlZF9MTkEiOiBQYXRpZW50TmVlZExOQSwKICAgICAgICAgICAgICAgICAgICAibmVlZF9PcmdMIjogUGF0aWVudE5lZWRPcmdMLAogICAgICAgICAgICAgICAgICAgICJuZWVkX1NFR19LVFdCIjogUGF0aWVudE5lZWRTRUdLVFdCLAogICAgICAgICAgICAgICAgICAgICJuZWVkX1RyYWdlaGlsZmUiOiBQYXRpZW50TmVlZFRyYWdlaGlsZmUKICAgICAgICAgICAgICAgIH0KICAgICAgICAKICAgICAgICAgICAgICAgIFBhdGllbnRDb3VudGVyKys7CiAgICAgICAgICAgIH0pOwogICAgICAgIAogICAgICAgICAgICBjb25zb2xlLmxvZygiICBBdXRvbWF0aWMgRGlzcG9zZTogUGF0aWVudGVubGlzdGU6Iik7CiAgICAgICAgICAgIGNvbnNvbGUubG9nKEFEX1BhdGllbnRzKTsKICAgICAgICAgICAgcmV0dXJuIEFEX1BhdGllbnRzOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvLyAgLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLQogICAgICAgIC8vICAtCiAgICAgICAgLy8gIC0gICAgICAgICAgICAgICAgICAgUHJvY2VzcyBFbWVyZ2VuY3lfTWVkaWNhbF9TZXJ2aWNlCiAgICAgICAgLy8gIC0KICAgICAgICAvLyAgLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLQogICAgICAgIAogICAgICAgIGZ1bmN0aW9uIEFEaXNfUHJvY2Vzc0VtZXJnZW5jeU1lZGljYWxTZXJ2aWNlKCkgewogICAgICAgIAogICAgICAgICAgICAvLyAgICAgIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0KICAgICAgICAgICAgLy8gICAgICAtCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgIEVtZXJnZW5jeSBNZWRpY2FsIFNlcnZpY2U6IFZlaGljbGVzCiAgICAgICAgICAgIC8vICAgICAgLQogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgMzg6ICAgICBLVFcKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgIDI4OiAgICAgUlRXCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICAyOTogICAgIE5FRgogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgNzQ6ICAgICBOQVcKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgIDczOiAgICAgR1JUVwogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgMzE6ICAgICBSVEgKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgIDU1OiAgICAgTE5BCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICA1NjogICAgIE9yZ0wKICAgICAgICAgICAgLy8gICAgICAtCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICA1ODogICAgIChTRUcpIEtUVyBUeXAgQgogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgNTk6ICAgICAoU0VHKSBFTFcgMQogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgNjA6ICAgICAoU0VHKSBHVy1TYW4KICAgICAgICAgICAgLy8gICAgICAtCiAgICAgICAgICAgIC8vICAgICAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLQogICAgICAgIAogICAgICAgICAgICBpZiAodHlwZW9mIE1pc3Npb25Db25maWcuZW1lcmdlbmN5X21lZGljYWxfc2VydmljZSA9PSAib2JqZWN0IikgLy8gV2VubiBkZXIgRU1TLUJsb2NrIGluIGRlciBDb25maWcgZGVmaW5pZXJ0IGlzdAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmtleXMoQURfUGF0aWVudHMpLmxlbmd0aCA+PSA1KSB7IC8vIG5lZWQgTE5BCiAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjU1Il09MTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAKICAgICAgICAgICAgICAgIGlmIChPYmplY3Qua2V5cyhBRF9QYXRpZW50cykubGVuZ3RoID49IDEwKSB7IC8vIG5lZWQgT3JnTAogICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI1NiJdPTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgCiAgICAgICAgICAgICAgICAvLyQuZWFjaChBRF9QYXRpZW50cywgZnVuY3Rpb24gKEtleSwgUGF0aWVudCkgewogICAgICAgICAgICAgICAgZm9yICh2YXIgS2V5IGluIEFEX1BhdGllbnRzKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIFBhdGllbnQgPSBBRF9QYXRpZW50c1tLZXldOwogICAgICAgICAgICAgICAgICAgIGlmIChNaXNzaW9uQ29uZmlnLmVtZXJnZW5jeV9tZWRpY2FsX3NlcnZpY2UudXNlX0tUVyA9PSB0cnVlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghUGF0aWVudC5uZWVkX1JUVyAmJiAhUGF0aWVudC5uZWVkX05FRiAmJiAhUGF0aWVudC5uZWVkX1JUSCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIzOCJdKys7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgIAogICAgICAgICAgICAgICAgICAgIGlmIChQYXRpZW50Lm5lZWRfTE5BICYmIEFEaXNfVmVoaWNsZXNOZWVkWyI1NSJdIDwgMSkKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjU1Il0gPSAxOwogICAgICAgIAogICAgICAgICAgICAgICAgICAgIGlmIChQYXRpZW50Lm5lZWRfT3JnTCAmJiBBRGlzX1ZlaGljbGVzTmVlZFsiNTYiXSA8IDEpCiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI1NiJdPTE7CiAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgaWYgKFBhdGllbnQubmVlZF9UcmFnZWhpbGZlID09IHRydWUpCiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIwIl0rKzsKICAgICAgICAKICAgICAgICAgICAgICAgICAgICBpZiAoTWlzc2lvbkNvbmZpZy5lbWVyZ2VuY3lfbWVkaWNhbF9zZXJ2aWNlLnVzZV9SVFcgPT0gdHJ1ZSkKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjI4Il0rKzsKICAgICAgICAKICAgICAgICAgICAgICAgICAgICBpZiAoTWlzc2lvbkNvbmZpZy5lbWVyZ2VuY3lfbWVkaWNhbF9zZXJ2aWNlLnVzZV9ORUYgPT0gdHJ1ZSkKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjI5Il0rKzsKICAgICAgICAKICAgICAgICAgICAgICAgICAgICBpZiAoTWlzc2lvbkNvbmZpZy5lbWVyZ2VuY3lfbWVkaWNhbF9zZXJ2aWNlLnVzZV9SVEggPT0gdHJ1ZSkKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjMxIl0rKzsKICAgICAgICAgICAgICAgIH07CiAgICAgICAgCiAgICAgICAgICAgICAgICAvLyBUT0RPOiBuZWVkIHRvIGJlIHJlZmFjdG9yZWQgdG8gbWFrZSBzdXJlIGZpcnN0IEtUVyBUeXAgQiBiZWZvcmUgUlRXLgogICAgICAgICAgICAgICAgaWYgKE1pc3Npb25Db25maWcuZW1lcmdlbmN5X21lZGljYWxfc2VydmljZS51c2VfU0VHX0VMVzFfT25seSA9PSAidHJ1ZSIpIHsKICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNTkiXSsrOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChNaXNzaW9uQ29uZmlnLmVtZXJnZW5jeV9tZWRpY2FsX3NlcnZpY2UudXNlX1NFR19GVUxMID09ICJ0cnVlIiB8fCBPYmplY3Qua2V5cyhBRF9QYXRpZW50cykubGVuZ3RoID49IDMpIHsKICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNTgiXSsrOwogICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI1OCJdKys7IC8vIDN4IEtUVyBUeXBlIEIKICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNTgiXSsrOwogICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI1OSJdKys7CiAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjYwIl0rKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBWZWhpY2xlVGFibGU7CiAgICAgICAgCiAgICAgICAgICAgICAgICBpZiAoJCgiI3ZlaGljbGVfc2hvd190YWJsZV9ib2R5X2FsbCIpLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICBWZWhpY2xlVGFibGUgPSAkKCIjdmVoaWNsZV9zaG93X3RhYmxlX2JvZHlfYWxsIik7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIFZlaGljbGVUYWJsZSA9ICQoIiN2ZWhpY2xlX3Nob3dfdGFibGVfYm9keV9yZXR0Iik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgCiAgICAgICAgICAgICAgICBWZWhpY2xlVGFibGUuZmluZCgiLnZlaGljbGVfc2VsZWN0X3RhYmxlX3RyIikuZWFjaChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIFZlaGljbGVJRCA9ICQodGhpcykuYXR0cigiaWQiKS5yZXBsYWNlKCJ2ZWhpY2xlX2VsZW1lbnRfY29udGVudF8iLCAiIik7CiAgICAgICAgICAgICAgICAgICAgLy8gdmFyIFZlaGljbGVEaXN0YW5jZVRpbWUgPSAkKCIjdmVoaWNsZV9zb3J0XyIgKyBWZWhpY2xlSUQpLmF0dHIoInNvcnR2YWx1ZSIpOwogICAgICAgICAgICAgICAgICAgIHZhciBWZWhpY2xlVHlwZSA9ICQodGhpcykuYXR0cigidmVoaWNsZV90eXBlIik7CiAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgaWYgKCQoIiN2ZWhpY2xlX2NoZWNrYm94XyIgKyBWZWhpY2xlSUQgKyAiOmVuYWJsZWQiKS5sZW5ndGggPT09IDApewogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgaWYgKFZlaGljbGVUeXBlID09ICJLVFciICYmIEFEaXNfVmVoaWNsZXNOZWVkWyIzOCJdID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZygiICBBdXRvbWF0aWMgRGlzcG9zZTogRmFocnpldWcgIiArIFZlaGljbGVJRCArICIgIiArIFZlaGljbGVUeXBlICsgIiBtYXJraWVydCIpOwogICAgICAgICAgICAgICAgICAgICAgICAkKCIjdmVoaWNsZV9jaGVja2JveF8iICsgVmVoaWNsZUlEKS5jbGljaygpOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiMzgiXS0tOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKFZlaGljbGVUeXBlID09ICJMRiAyMCIgfHwgVmVoaWNsZVR5cGUgPT0gIkxGIDEwIiB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVoaWNsZVR5cGUgPT0gIkxGIDgvNiIgfHwgVmVoaWNsZVR5cGUgPT0gIkxGIDIwLzE2IiB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVoaWNsZVR5cGUgPT0gIkxGIDEwLzYiIHx8IFZlaGljbGVUeXBlID09ICJMRiAxNi1UUyIgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlaGljbGVUeXBlID09ICJITEYgMjAiIHx8IFZlaGljbGVUeXBlID09ICJUU0YtVyIgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlaGljbGVUeXBlID09ICJUTEYgMjAwMCIgfHwgVmVoaWNsZVR5cGUgPT0gIlRMRiAzMDAwIiB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVoaWNsZVR5cGUgPT0gIlRMRiA4LzgiIHx8IFZlaGljbGVUeXBlID09ICJUTEYgOC8xOCIgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlaGljbGVUeXBlID09ICJUTEYgMTYvMjQtVHIiIHx8IFZlaGljbGVUeXBlID09ICJUTEYgMTYvMjUiIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWhpY2xlVHlwZSA9PSAiVExGIDE2LzQ1IiB8fCBWZWhpY2xlVHlwZSA9PSAiVExGIDIwLzQwIiB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVoaWNsZVR5cGUgPT0gIlRMRiAyMC80MC1TTCIgfHwgVmVoaWNsZVR5cGUgPT0gIlRMRiAxNiIpICYmCiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIwIl0gKyBBRGlzX1ZlaGljbGVzTmVlZFsiMSJdICsgQURpc19WZWhpY2xlc05lZWRbIjYiXSArIEFEaXNfVmVoaWNsZXNOZWVkWyI3Il0gKwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiOCJdICsgQURpc19WZWhpY2xlc05lZWRbIjkiXSArIEFEaXNfVmVoaWNsZXNOZWVkWyIzMCJdICsgQURpc19WZWhpY2xlc05lZWRbIjM3Il0gKwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiMTciXSArIEFEaXNfVmVoaWNsZXNOZWVkWyIxOCJdICsgQURpc19WZWhpY2xlc05lZWRbIjE5Il0gKyBBRGlzX1ZlaGljbGVzTmVlZFsiMjAiXSArCiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIyMSJdICsgQURpc19WZWhpY2xlc05lZWRbIjIyIl0gKyBBRGlzX1ZlaGljbGVzTmVlZFsiMjMiXSArIEFEaXNfVmVoaWNsZXNOZWVkWyIyNCJdICsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjI1Il0gKyBBRGlzX1ZlaGljbGVzTmVlZFsiMjYiXSA+IDApIHsgLy8gTEYgYWN0cyBhcyAnVHJhZ2VoaWxmZScKICAgICAgICAgICAgICAgICAgICAgICAgJCgiI3ZlaGljbGVfY2hlY2tib3hfIiArIFZlaGljbGVJRCkuY2xpY2soKTsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjAiXS0tOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoVmVoaWNsZVR5cGUgPT0gIk5BVyIgJiYgQURpc19WZWhpY2xlc05lZWRbIjI4Il0gPiAwICYmIEFEaXNfVmVoaWNsZXNOZWVkWyIyOSJdID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAkKCIjdmVoaWNsZV9jaGVja2JveF8iICsgVmVoaWNsZUlEKS5jbGljaygpOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNzQiXS0tOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiMjgiXS0tOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiMjkiXS0tOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoVmVoaWNsZVR5cGUgPT0gIkdSVFciICYmIEFEaXNfVmVoaWNsZXNOZWVkWyI3MyJdID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAkKCIjdmVoaWNsZV9jaGVja2JveF8iICsgVmVoaWNsZUlEKS5jbGljaygpOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNzMiXS0tOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoVmVoaWNsZVR5cGUgPT0gIlJUVyIgJiYgQURpc19WZWhpY2xlc05lZWRbIjI4Il0gPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiN2ZWhpY2xlX2NoZWNrYm94XyIgKyBWZWhpY2xlSUQpLmNsaWNrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIyOCJdLS07CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChWZWhpY2xlVHlwZSA9PSAiTkVGIiAmJiBBRGlzX1ZlaGljbGVzTmVlZFsiMjkiXSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgJCgiI3ZlaGljbGVfY2hlY2tib3hfIiArIFZlaGljbGVJRCkuY2xpY2soKTsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjI5Il0tLTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFZlaGljbGVUeXBlID09ICJSVEgiICYmIEFEaXNfVmVoaWNsZXNOZWVkWyIzMSJdID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAkKCIjdmVoaWNsZV9jaGVja2JveF8iICsgVmVoaWNsZUlEKS5jbGljaygpOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiMzEiXS0tOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoVmVoaWNsZVR5cGUgPT0gIktkb1ctTE5BIiAmJiBBRGlzX1ZlaGljbGVzTmVlZFsiNTUiXSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgJCgiI3ZlaGljbGVfY2hlY2tib3hfIiArIFZlaGljbGVJRCkuY2xpY2soKTsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjU1Il0tLTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFZlaGljbGVUeXBlID09ICJLZG9XLU9yZ0wiICYmIEFEaXNfVmVoaWNsZXNOZWVkWyI1NiJdID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAkKCIjdmVoaWNsZV9jaGVja2JveF8iICsgVmVoaWNsZUlEKS5jbGljaygpOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNTYiXS0tOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoVmVoaWNsZVR5cGUgPT0gIktUVyBUeXAgQiIgJiYgQURpc19WZWhpY2xlc05lZWRbIjU4Il0gPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiN2ZWhpY2xlX2NoZWNrYm94XyIgKyBWZWhpY2xlSUQpLmNsaWNrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI1OCJdLS07CiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIyOCJdLS07IC8vIG5vIG5lZWQgZm9yIFJUVyBpZiBLVFcgVHlwZSBCIGlzIGNhbGxlZAogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoVmVoaWNsZVR5cGUgPT0gIkVMVyAxIChTRUcpIiAmJiBBRGlzX1ZlaGljbGVzTmVlZFsiNTkiXSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgJCgiI3ZlaGljbGVfY2hlY2tib3hfIiArIFZlaGljbGVJRCkuY2xpY2soKTsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjU5Il0tLTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFZlaGljbGVUeXBlID09ICJHVy1TYW4iICYmIEFEaXNfVmVoaWNsZXNOZWVkWyI2MCJdID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAkKCIjdmVoaWNsZV9jaGVja2JveF8iICsgVmVoaWNsZUlEKS5jbGljaygpOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNjAiXS0tOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiMjkiXS0tOyAvLyBubyBuZWVkIGZvciBORUYgaWYgR1ctU0FOIGlzIGNhbGxlZAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvLyAgLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLQogICAgICAgIC8vICAtCiAgICAgICAgLy8gIC0gICAgICAgICAgICAgICAgICAgUHJvY2VzcyBGaXJlX0RlcGFydG1lbnQKICAgICAgICAvLyAgLQogICAgICAgIC8vICAtIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tCiAgICAgICAgCiAgICAgICAgZnVuY3Rpb24gQURpc19Qcm9jZXNzRmlyZURlcGFydG1lbnQoKSB7CiAgICAgICAgCiAgICAgICAgICAgIC8vICAgICAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLQogICAgICAgICAgICAvLyAgICAgIC0KICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgRmlyZSBEZXBhcnRtZW50OiBWZWhpY2xlcwogICAgICAgICAgICAvLyAgICAgIC0KICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgICAwOiAgICAgTEYgMjAKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgICAxOiAgICAgTEYgMTAKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgICA2OiAgICAgTEYgOC82CiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICAgNzogICAgIExGIDIwLzE2CiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICAgODogICAgIExGIDEwLzYKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgICA5OiAgICAgTEYgMTYtVFMKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgIDMwOiAgICAgSExGIDIwCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICAzNzogICAgIFRTRi1XCiAgICAgICAgICAgIC8vICAgICAgLQogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgMTc6ICAgICBUTEYgMjAwMAogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgMTg6ICAgICBUTEYgMzAwMAogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgMTk6ICAgICBUTEYgOC84CiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICAyMDogICAgIFRMRiA4LzE4CiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICAyMTogICAgIFRMRiAxNi8yNC1UcgogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgMjI6ICAgICBUTEYgMTYvMjUKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgIDIzOiAgICAgVExGIDE2LzQ1CiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICAyNDogICAgIFRMRiAyMC80MAogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgMjU6ICAgICBUTEYgMjAvNDAtU0wKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgIDI2OiAgICAgVExGIDE2CiAgICAgICAgICAgIC8vICAgICAgLQogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgIDI6ICAgICBETEsgMjMKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgICAzOiAgICAgRUxXIDEKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgIDM0OiAgICAgRUxXIDIKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgIDM2OiAgICAgTVRXCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICA1NzogICAgIEZ3SwogICAgICAgICAgICAvLyAgICAgIC0KICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgICA0OiAgICAgUlcKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgICA1OiAgICAgR1ctQQogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgMTA6ICAgICBHVy3WbAogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgMTI6ICAgICBHVy1NZXNzCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICA1MzogICAgIEdXLURla29uLVAKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgIDI3OiAgICAgR1ctR2VmYWhyZ3V0CiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICAzMzogICAgIEdXLUj2aGVucmV0dHVuZwogICAgICAgICAgICAvLyAgICAgIC0KICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgIDExOiAgICAgR1ctTDItV2Fzc2VyCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICAxMzogICAgIFNXIDEwMDAKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgIDE0OiAgICAgU1cgMjAwMAogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgMTU6ICAgICBTVyAyMDAwLVRyCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICAxNjogICAgIFNXIEthdFMKICAgICAgICAgICAgLy8gICAgICAtCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICA3MTogICAgIEFCLU1aQiAoc2VlIFdhdGVyUmVzY3VlKQogICAgICAgICAgICAvLyAgICAgIC0KICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgIDQ2OiAgICAgV0xGCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICA0NzogICAgIEFCLVL8c3QKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgIDQ4OiAgICAgQUItQXRlbXNjaHV0egogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgNDk6ICAgICBBQi3WbAogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgNTQ6ICAgICBBQi1EZWtvbi1QCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICA2MjogICAgIEFCLVNjaGxhdWNoCiAgICAgICAgICAgIC8vICAgICAgLSAKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgIDc1OiAgICAgRkxGCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICA3NjogICAgIFJldHR1bmdzdHJlcHBlCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICA3NzogICAgIEFCLUdlZmFocmd1dAogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgNzg6ICAgICBBQi1FaW5zYXR6bGVpdHVuZwogICAgICAgICAgICAvLyAgICAgIC0gCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICA4MzogICAgIEdXLVdlcmtmZXVlcndlaHIKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgIDg0OiAgICAgVUxGIG1pdCBM9nNjaGFybQogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgODU6ICAgICBUTSA1MAogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgODY6ICAgICBUdXJib2z2c2NoZXIKICAgICAgICAgICAgLy8gICAgICAtCiAgICAgICAgICAgIC8vICAgICAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLSAgLQogICAgICAgIAogICAgICAgICAgICBpZiAodHlwZW9mIE1pc3Npb25Db25maWcuZmlyZV9kZXBhcnRtZW50ID09ICJvYmplY3QiKSAvLyBXZW5uIGRlciBGRC1CbG9jayBpbiBkZXIgQ29uZmlnIGRlZmluaWVydCBpc3QKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY29uc29sZS5sb2coQURpc19WZWhpY2xlc05lZWQpOwogICAgICAgIAogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjAiXSArPSBwYXJzZUludChNaXNzaW9uQ29uZmlnLmZpcmVfZGVwYXJ0bWVudC5udW1fTEYpOwogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjMiXSArPSBwYXJzZUludChNaXNzaW9uQ29uZmlnLmZpcmVfZGVwYXJ0bWVudC5udW1fRUxXXzEpOwogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjM0Il0gKz0gcGFyc2VJbnQoTWlzc2lvbkNvbmZpZy5maXJlX2RlcGFydG1lbnQubnVtX0VMV18yKTsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIyIl0gKz0gcGFyc2VJbnQoTWlzc2lvbkNvbmZpZy5maXJlX2RlcGFydG1lbnQubnVtX0RMSyk7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNCJdICs9IHBhcnNlSW50KE1pc3Npb25Db25maWcuZmlyZV9kZXBhcnRtZW50Lm51bV9SVyk7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNTciXSArPSBwYXJzZUludChNaXNzaW9uQ29uZmlnLmZpcmVfZGVwYXJ0bWVudC5udW1fRndLKTsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI1Il0gKz0gcGFyc2VJbnQoTWlzc2lvbkNvbmZpZy5maXJlX2RlcGFydG1lbnQubnVtX0dXX0EpOwogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjI3Il0gKz0gcGFyc2VJbnQoTWlzc2lvbkNvbmZpZy5maXJlX2RlcGFydG1lbnQubnVtX0dXX0cpOwogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjEwIl0gKz0gcGFyc2VJbnQoTWlzc2lvbkNvbmZpZy5maXJlX2RlcGFydG1lbnQubnVtX0dXX09lbCk7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiMTIiXSArPSBwYXJzZUludChNaXNzaW9uQ29uZmlnLmZpcmVfZGVwYXJ0bWVudC5udW1fR1dfTWVzcyk7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiMTEiXSArPSBwYXJzZUludChNaXNzaW9uQ29uZmlnLmZpcmVfZGVwYXJ0bWVudC5udW1fU1cpOwogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjMzIl0gKz0gcGFyc2VJbnQoTWlzc2lvbkNvbmZpZy5maXJlX2RlcGFydG1lbnQubnVtX0dXX0hvZWgpOwogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjUzIl0gKz0gcGFyc2VJbnQoTWlzc2lvbkNvbmZpZy5maXJlX2RlcGFydG1lbnQubnVtX0Rla29uX1ApOwogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjc1Il0gKz0gcGFyc2VJbnQoTWlzc2lvbkNvbmZpZy5maXJlX2RlcGFydG1lbnQubnVtX0ZMRik7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNzYiXSArPSBwYXJzZUludChNaXNzaW9uQ29uZmlnLmZpcmVfZGVwYXJ0bWVudC5udW1fUmV0dHVuZ3N0cmVwcGUpOwogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjgzIl0gKz0gcGFyc2VJbnQoTWlzc2lvbkNvbmZpZy5maXJlX2RlcGFydG1lbnQubnVtX0dXX1dlcmtmZXVlcndlaHIpOwogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjg0Il0gKz0gcGFyc2VJbnQoTWlzc2lvbkNvbmZpZy5maXJlX2RlcGFydG1lbnQubnVtX1VMRl9taXRfTG9lc2NoYXJtKTsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI4NiJdICs9IHBhcnNlSW50KE1pc3Npb25Db25maWcuZmlyZV9kZXBhcnRtZW50Lm51bV9UdXJib2xvZXNjaGVyKTsKICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBkYW5nZXJUZXh0ID0gJCgnI2lmcmFtZS1pbnNpZGUtY29udGFpbmVyID4gZGl2LmFsZXJ0LmFsZXJ0LWRhbmdlcicpLnRleHQoKTsKICAgICAgICAKICAgICAgICAgICAgICAgIGlmIChpbmNsdWRlc1N0cmluZyhkYW5nZXJUZXh0LCAiV2lyIGJlbvZ0aWdlbiBtaW4uIikgJiYgaW5jbHVkZXNTdHJpbmcoZGFuZ2VyVGV4dCwgIkZldWVyd2VocmxldXRlLiIpICkgewogICAgICAgICAgICAgICAgICAgIGNvbnN0IHdlTmVlZCA9IEFEaXNfVmVoaWNsZXNOZWVkWyIwIl07CiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVnZXggPSAvKFxkKykgRmV1ZXJ3ZWhybGV1dGUvZ207CiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3TmVlZCA9IE1hdGguY2VpbChOdW1iZXIocGFyc2VJbnQoZGFuZ2VyVGV4dC5tYXRjaChyZWdleCkpKSAvIDYpIC0gd2VOZWVkOwogICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIwIl0gPSBuZXdOZWVkOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAkKCIjdmVoaWNsZV9zaG93X3RhYmxlX2JvZHlfYWxsIikuZmluZCgiLnZlaGljbGVfc2VsZWN0X3RhYmxlX3RyIikuZWFjaChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIFZlaGljbGVJRCA9ICQodGhpcykuYXR0cigiaWQiKS5yZXBsYWNlKCJ2ZWhpY2xlX2VsZW1lbnRfY29udGVudF8iLCAiIik7CiAgICAgICAgICAgICAgICAgICAgLy8gdmFyIFZlaGljbGVEaXN0YW5jZVRpbWUgPSAkKCIjdmVoaWNsZV9zb3J0XyIgKyBWZWhpY2xlSUQpLmF0dHIoInNvcnR2YWx1ZSIpOwogICAgICAgICAgICAgICAgICAgIHZhciBWZWhpY2xlVHlwZSA9ICQodGhpcykuYXR0cigidmVoaWNsZV90eXBlIik7CiAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgaWYgKCQoIiN2ZWhpY2xlX2NoZWNrYm94XyIgKyBWZWhpY2xlSUQgKyAiOmVuYWJsZWQiKS5sZW5ndGggPT09IDApewogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgaWYgKChWZWhpY2xlVHlwZSA9PSAiTEYgMjAiIHx8IFZlaGljbGVUeXBlID09ICJMRiAxMCIgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlaGljbGVUeXBlID09ICJMRiA4LzYiIHx8IFZlaGljbGVUeXBlID09ICJMRiAyMC8xNiIgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlaGljbGVUeXBlID09ICJMRiAxMC82IiB8fCBWZWhpY2xlVHlwZSA9PSAiTEYgMTYtVFMiIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWhpY2xlVHlwZSA9PSAiSExGIDIwIiB8fCBWZWhpY2xlVHlwZSA9PSAiVFNGLVciIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWhpY2xlVHlwZSA9PSAiVExGIDIwMDAiIHx8IFZlaGljbGVUeXBlID09ICJUTEYgMzAwMCIgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlaGljbGVUeXBlID09ICJUTEYgOC84IiB8fCBWZWhpY2xlVHlwZSA9PSAiVExGIDgvMTgiIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWhpY2xlVHlwZSA9PSAiVExGIDE2LzI0LVRyIiB8fCBWZWhpY2xlVHlwZSA9PSAiVExGIDE2LzI1IiB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVoaWNsZVR5cGUgPT0gIlRMRiAxNi80NSIgfHwgVmVoaWNsZVR5cGUgPT0gIlRMRiAyMC80MCIgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlaGljbGVUeXBlID09ICJUTEYgMjAvNDAtU0wiIHx8IFZlaGljbGVUeXBlID09ICJUTEYgMTYiKSAmJgogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiMCJdICsgQURpc19WZWhpY2xlc05lZWRbIjEiXSArIEFEaXNfVmVoaWNsZXNOZWVkWyI2Il0gKyBBRGlzX1ZlaGljbGVzTmVlZFsiNyJdICsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjgiXSArIEFEaXNfVmVoaWNsZXNOZWVkWyI5Il0gKyBBRGlzX1ZlaGljbGVzTmVlZFsiMzAiXSArIEFEaXNfVmVoaWNsZXNOZWVkWyIzNyJdICsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjE3Il0gKyBBRGlzX1ZlaGljbGVzTmVlZFsiMTgiXSArIEFEaXNfVmVoaWNsZXNOZWVkWyIxOSJdICsgQURpc19WZWhpY2xlc05lZWRbIjIwIl0gKwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiMjEiXSArIEFEaXNfVmVoaWNsZXNOZWVkWyIyMiJdICsgQURpc19WZWhpY2xlc05lZWRbIjIzIl0gKyBBRGlzX1ZlaGljbGVzTmVlZFsiMjQiXSArCiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIyNSJdICsgQURpc19WZWhpY2xlc05lZWRbIjI2Il0gPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiN2ZWhpY2xlX2NoZWNrYm94XyIgKyBWZWhpY2xlSUQpLmNsaWNrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIwIl0tLTsKICAgICAgICAKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFZlaGljbGVUeXBlID09ICJITEYgMjAiICYmIEFEaXNfVmVoaWNsZXNOZWVkWyI0Il0gPiAwKSAvLyBITEYgMjAgYWN0cyBhcyBSVwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjAiXS0tOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNCJdLS07CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiN2ZWhpY2xlX2NoZWNrYm94XyIgKyBWZWhpY2xlSUQpLmNsaWNrKCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoVmVoaWNsZVR5cGUgPT0gIkRMSyAyMyIgfHwgVmVoaWNsZVR5cGUgPT0gIlRNIDUwIikgJiYgQURpc19WZWhpY2xlc05lZWRbIjIiXSA+IDApIC8vIERMSyAyMwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgJCgiI3ZlaGljbGVfY2hlY2tib3hfIiArIFZlaGljbGVJRCkuY2xpY2soKTsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjIiXS0tOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoJCh0aGlzKS5hdHRyKCJ2ZWhpY2xlX3R5cGUiID09ICJBQi1FaW5zYXR6bGVpdHVuZyIpICYmCiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIzIl0gKyBBRGlzX1ZlaGljbGVzTmVlZFsiMzQiXSArIEFEaXNfVmVoaWNsZXNOZWVkWyI3OCJdID4gMCkgLy8gRUxXIDEgKyBFTFcgMgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgJCgiI3ZlaGljbGVfY2hlY2tib3hfIiArIFZlaGljbGVJRCkuY2xpY2soKTsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjMiXS0tOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiMzQiXS0tOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoVmVoaWNsZVR5cGUgPT0gIkVMVyAyIiAmJiBBRGlzX1ZlaGljbGVzTmVlZFsiMyJdICsgQURpc19WZWhpY2xlc05lZWRbIjM0Il0gPiAwKSAvLyBFTFcgMgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgJCgiI3ZlaGljbGVfY2hlY2tib3hfIiArIFZlaGljbGVJRCkuY2xpY2soKTsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjMiXS0tOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiMzQiXS0tOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoVmVoaWNsZVR5cGUgPT0gIkVMVyAxIiAmJiBBRGlzX1ZlaGljbGVzTmVlZFsiMyJdID4gMCkgLy8gRUxXIDEKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiN2ZWhpY2xlX2NoZWNrYm94XyIgKyBWZWhpY2xlSUQpLmNsaWNrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIzIl0tLTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFZlaGljbGVUeXBlID09ICJNVFciICYmIEFEaXNfVmVoaWNsZXNOZWVkWyIzNiJdID4gMCkgLy8gTVRXCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAkKCIjdmVoaWNsZV9jaGVja2JveF8iICsgVmVoaWNsZUlEKS5jbGljaygpOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiMzYiXS0tOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoVmVoaWNsZVR5cGUgPT0gIkZ3SyIgJiYgQURpc19WZWhpY2xlc05lZWRbIjU3Il0gPiAwKSAvLyBGd0sKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiN2ZWhpY2xlX2NoZWNrYm94XyIgKyBWZWhpY2xlSUQpLmNsaWNrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI1NyJdLS07CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChWZWhpY2xlVHlwZSA9PSAiR1dLIiAmJgogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNCJdID4gMCkgLy8gR1dLIGFjdHMgYXMgUlcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiN2ZWhpY2xlX2NoZWNrYm94XyIgKyBWZWhpY2xlSUQpLmNsaWNrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI0Il0tLTsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjM5Il0tLTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChWZWhpY2xlVHlwZSA9PSAiUlciIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWhpY2xlVHlwZSA9PSAiSExGIDIwIiB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVoaWNsZVR5cGUgPT0gIkFCLVL8c3QiKSAmJgogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNCJdID4gMCkgLy8gUlcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiN2ZWhpY2xlX2NoZWNrYm94XyIgKyBWZWhpY2xlSUQpLmNsaWNrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI0Il0tLTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChWZWhpY2xlVHlwZSA9PSAiR1ctQSIgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlaGljbGVUeXBlID09ICJBQi1BdGVtc2NodXR6IikgJiYKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjUiXSA+IDApIC8vIEdXLUEKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiN2ZWhpY2xlX2NoZWNrYm94XyIgKyBWZWhpY2xlSUQpLmNsaWNrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI1Il0tLTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChWZWhpY2xlVHlwZSA9PSAiR1ct1mwiIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWhpY2xlVHlwZSA9PSAiQUIt1mwiKSAmJgogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiMTAiXSA+IDApIC8vIEdXLdZsCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAkKCIjdmVoaWNsZV9jaGVja2JveF8iICsgVmVoaWNsZUlEKS5jbGljaygpOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiMTAiXS0tOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoVmVoaWNsZVR5cGUgPT0gIkdXLU1lc3N0ZWNobmlrIiAmJiBBRGlzX1ZlaGljbGVzTmVlZFsiMTIiXSA+IDApIC8vIEZ3SwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgJCgiI3ZlaGljbGVfY2hlY2tib3hfIiArIFZlaGljbGVJRCkuY2xpY2soKTsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjEyIl0tLTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChWZWhpY2xlVHlwZSA9PSAiR1ctTDItV2Fzc2VyIiB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVoaWNsZVR5cGUgPT0gIlNXIDEwMDAiIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWhpY2xlVHlwZSA9PSAiU1cgMjAwMCIgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlaGljbGVUeXBlID09ICJTVyAyMDAwLVRyIiB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVoaWNsZVR5cGUgPT0gIlNXIEthdHMiIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWhpY2xlVHlwZSA9PSAiQUItU2NobGF1Y2giKSAmJgogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiMTEiXSA+IDApIC8vIFNXCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAkKCIjdmVoaWNsZV9jaGVja2JveF8iICsgVmVoaWNsZUlEKS5jbGljaygpOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiMTEiXS0tOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKFZlaGljbGVUeXBlID09ICJHVy1HZWZhaHJndXQiIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWhpY2xlVHlwZSA9PSAiQUItR2VmYWhyZ3V0IikgJiYgQURpc19WZWhpY2xlc05lZWRbIjI3Il0gPiAwKSAvLyBHVy1HZWZhaHJndXQKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiN2ZWhpY2xlX2NoZWNrYm94XyIgKyBWZWhpY2xlSUQpLmNsaWNrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIyNyJdLS07CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChWZWhpY2xlVHlwZSA9PSAiR1ctSPZoZW5yZXR0dW5nIiAmJiBBRGlzX1ZlaGljbGVzTmVlZFsiMzMiXSA+IDApIC8vIEdXLUj2aGVucmV0dHVuZwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgJCgiI3ZlaGljbGVfY2hlY2tib3hfIiArIFZlaGljbGVJRCkuY2xpY2soKTsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjMzIl0tLTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChWZWhpY2xlVHlwZSA9PSAiRGVrb24tUCIgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlaGljbGVUeXBlID09ICJBQi1EZWtvbi1QIikgJiYKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjUzIl0gPiAwKSAvLyBEZWtvbi1QCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAkKCIjdmVoaWNsZV9jaGVja2JveF8iICsgVmVoaWNsZUlEKS5jbGljaygpOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNTMiXS0tOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoVmVoaWNsZVR5cGUgPT0gIkdXLVdlcmtmZXVlcndlaHIiICYmCiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI4MyJdID4gMCkgLy8gR1ctV2Vya2ZldWVyd2VocgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgJCgiI3ZlaGljbGVfY2hlY2tib3hfIiArIFZlaGljbGVJRCkuY2xpY2soKTsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjgzIl0tLTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFZlaGljbGVUeXBlID09ICJVTEYgbWl0IEz2c2NoYXJtIiAmJgogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiODQiXSA+IDApIC8vIFVMRiBtaXQgTPZzY2hhcm0KICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiN2ZWhpY2xlX2NoZWNrYm94XyIgKyBWZWhpY2xlSUQpLmNsaWNrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI4NCJdLS07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoVmVoaWNsZVR5cGUgPT0gIlRNIDUwIiAmJgogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiODUiXSA+IDApIC8vIFRNIDUwCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAkKCIjdmVoaWNsZV9jaGVja2JveF8iICsgVmVoaWNsZUlEKS5jbGljaygpOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiODUiXS0tOwogICAgICAgICAgICAgICAgICAgIH0gCiAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChWZWhpY2xlVHlwZSA9PSAiVHVyYm9s9nNjaGVyIiAmJgogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiODYiXSA+IDApIC8vIFR1cmJvbPZzY2hlcgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgJCgiI3ZlaGljbGVfY2hlY2tib3hfIiArIFZlaGljbGVJRCkuY2xpY2soKTsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjg2Il0tLTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFZlaGljbGVUeXBlID09ICJGTEYiICYmCiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI3NSJdID4gMCkgLy8gRkxGCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAkKCIjdmVoaWNsZV9jaGVja2JveF8iICsgVmVoaWNsZUlEKS5jbGljaygpOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNzUiXS0tOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoVmVoaWNsZVR5cGUgPT0gIlJldHR1bmdzdHJlcHBlIiAmJgogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNzYiXSA+IDApIC8vIFJldHR1bmdzdHJlcHBlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAkKCIjdmVoaWNsZV9jaGVja2JveF8iICsgVmVoaWNsZUlEKS5jbGljaygpOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNzYiXS0tOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvLyAgLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLQogICAgICAgIC8vICAtCiAgICAgICAgLy8gIC0gICAgICAgICAgICAgICAgICAgUHJvY2VzcyBQb2xpY2VfRGVwYXJ0bWVudAogICAgICAgIC8vICAtCiAgICAgICAgLy8gIC0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0KICAgICAgICAKICAgICAgICBmdW5jdGlvbiBBRGlzX1Byb2Nlc3NQb2xpY2VEZXBhcnRtZW50KCkgewogICAgICAgIAogICAgICAgICAgICAvLyAgICAgIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0KICAgICAgICAgICAgLy8gICAgICAtCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgIEZpcmUgRGVwYXJ0bWVudDogVmVoaWNsZXMKICAgICAgICAgICAgLy8gICAgICAtCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICAzMjogICAgIEZ1U3RXCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICAzNTogICAgIGxlQmVmS3cKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgIDUwOiAgICAgR3J1S3cKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgIDUxOiAgICAgRvxLdwogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgNTI6ICAgICBHZWZLdwogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgNzI6ICAgICBXYVdlCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICA2MTogICAgIFBvbGl6ZWlodWJzY2hyYXViZXIKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgIDc5OiAgICAgU0VLIC0gWkYKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgIDgwOiAgICAgU0VLIC0gTVRGCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICA4MTogICAgIE1FSyAtIFpGCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICA4MjogICAgIE1FSyAtIE1URgogICAgICAgICAgICAvLyAgICAgIC0KICAgICAgICAgICAgLy8gICAgICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtCiAgICAgICAgCiAgICAgICAgICAgIGlmICh0eXBlb2YgTWlzc2lvbkNvbmZpZy5wb2xpY2VfZGVwYXJ0bWVudCA9PSAib2JqZWN0IikgLy8gV2VubiBkZXIgRkQtQmxvY2sgaW4gZGVyIENvbmZpZyBkZWZpbmllcnQgaXN0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIzMiJdICs9IHBhcnNlSW50KE1pc3Npb25Db25maWcucG9saWNlX2RlcGFydG1lbnQubnVtX0Z1U3RXKTsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIzNSJdICs9IHBhcnNlSW50KE1pc3Npb25Db25maWcucG9saWNlX2RlcGFydG1lbnQubnVtX2xlQmVmS3cpOwogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjUwIl0gKz0gcGFyc2VJbnQoTWlzc2lvbkNvbmZpZy5wb2xpY2VfZGVwYXJ0bWVudC5udW1fR3J1S3cpOwogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjUxIl0gKz0gcGFyc2VJbnQoTWlzc2lvbkNvbmZpZy5wb2xpY2VfZGVwYXJ0bWVudC5udW1fRnVlS3cpOwogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjUyIl0gKz0gcGFyc2VJbnQoTWlzc2lvbkNvbmZpZy5wb2xpY2VfZGVwYXJ0bWVudC5udW1fR2VmS3cpOwogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjcyIl0gKz0gcGFyc2VJbnQoTWlzc2lvbkNvbmZpZy5wb2xpY2VfZGVwYXJ0bWVudC5udW1fV2FXZSk7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNjEiXSArPSBwYXJzZUludChNaXNzaW9uQ29uZmlnLnBvbGljZV9kZXBhcnRtZW50Lm51bV9QSHUpOwogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjc5Il0gKz0gcGFyc2VJbnQoTWlzc2lvbkNvbmZpZy5wb2xpY2VfZGVwYXJ0bWVudC5udW1fU0VLX1pGKTsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI4MCJdICs9IHBhcnNlSW50KE1pc3Npb25Db25maWcucG9saWNlX2RlcGFydG1lbnQubnVtX1NFS19NVEYpOwogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjgxIl0gKz0gcGFyc2VJbnQoTWlzc2lvbkNvbmZpZy5wb2xpY2VfZGVwYXJ0bWVudC5udW1fTUVLX1pGKTsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI4MiJdICs9IHBhcnNlSW50KE1pc3Npb25Db25maWcucG9saWNlX2RlcGFydG1lbnQubnVtX01FS19NVEYpOwogICAgICAgIAogICAgICAgICAgICAgICAgJCgiI3ZlaGljbGVfc2hvd190YWJsZV9ib2R5X2FsbCIpLmZpbmQoIi52ZWhpY2xlX3NlbGVjdF90YWJsZV90ciIpLmVhY2goZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIHZhciBWZWhpY2xlSUQgPSAkKHRoaXMpLmF0dHIoImlkIikucmVwbGFjZSgidmVoaWNsZV9lbGVtZW50X2NvbnRlbnRfIiwgIiIpOwogICAgICAgICAgICAgICAgICAgIC8vIHZhciBWZWhpY2xlRGlzdGFuY2VUaW1lID0gJCgiI3ZlaGljbGVfc29ydF8iICsgVmVoaWNsZUlEKS5hdHRyKCJzb3J0dmFsdWUiKTsKICAgICAgICAgICAgICAgICAgICB2YXIgVmVoaWNsZVR5cGUgPSAkKHRoaXMpLmF0dHIoInZlaGljbGVfdHlwZSIpOwogICAgICAgIAogICAgICAgICAgICAgICAgICAgIGlmICgkKCIjdmVoaWNsZV9jaGVja2JveF8iICsgVmVoaWNsZUlEICsgIjplbmFibGVkIikubGVuZ3RoID09PSAwKXsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgIAogICAgICAgICAgICAgICAgICAgIGlmIChWZWhpY2xlVHlwZSA9PSAiRnVTdFciICYmIEFEaXNfVmVoaWNsZXNOZWVkWyIzMiJdID4gMCkgLy8gRnVTdFcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiN2ZWhpY2xlX2NoZWNrYm94XyIgKyBWZWhpY2xlSUQpLmNsaWNrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIzMiJdLS07CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChWZWhpY2xlVHlwZSA9PSAibGVCZWZLdyIgJiYgQURpc19WZWhpY2xlc05lZWRbIjM1Il0gPiAwKSAvLyBsZUJlZkt3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAkKCIjdmVoaWNsZV9jaGVja2JveF8iICsgVmVoaWNsZUlEKS5jbGljaygpOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiMzUiXS0tOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoVmVoaWNsZVR5cGUgPT0gIkdydUt3IiAmJiBBRGlzX1ZlaGljbGVzTmVlZFsiNTAiXSA+IDApIC8vIEdydUt3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAkKCIjdmVoaWNsZV9jaGVja2JveF8iICsgVmVoaWNsZUlEKS5jbGljaygpOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNTAiXS0tOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoVmVoaWNsZVR5cGUgPT0gIkb8S3ciICYmIEFEaXNfVmVoaWNsZXNOZWVkWyI1MSJdID4gMCkgLy8gRvxLdwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgJCgiI3ZlaGljbGVfY2hlY2tib3hfIiArIFZlaGljbGVJRCkuY2xpY2soKTsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjUxIl0tLTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFZlaGljbGVUeXBlID09ICJHZWZLdyIgJiYgQURpc19WZWhpY2xlc05lZWRbIjUyIl0gPiAwKSAvLyBHZWZLdwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgJCgiI3ZlaGljbGVfY2hlY2tib3hfIiArIFZlaGljbGVJRCkuY2xpY2soKTsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjUyIl0tLTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFZlaGljbGVUeXBlID09ICJXYVdlIDEwIiAmJiBBRGlzX1ZlaGljbGVzTmVlZFsiNzIiXSA+IDApIC8vIFdhV2UgMTAKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiN2ZWhpY2xlX2NoZWNrYm94XyIgKyBWZWhpY2xlSUQpLmNsaWNrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI3MiJdLS07CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChWZWhpY2xlVHlwZSA9PSAiUG9saXplaWh1YnNjaHJhdWJlciIgJiYgQURpc19WZWhpY2xlc05lZWRbIjYxIl0gPiAwKSAvLyBQSHUKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiN2ZWhpY2xlX2NoZWNrYm94XyIgKyBWZWhpY2xlSUQpLmNsaWNrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI2MSJdLS07CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChWZWhpY2xlVHlwZSA9PSAiU0VLIC0gWkYiICYmIEFEaXNfVmVoaWNsZXNOZWVkWyI3OSJdID4gMCkgLy8gU0VLLVpGCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAkKCIjdmVoaWNsZV9jaGVja2JveF8iICsgVmVoaWNsZUlEKS5jbGljaygpOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNzkiXS0tOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoVmVoaWNsZVR5cGUgPT0gIlNFSyAtIE1URiIgJiYgQURpc19WZWhpY2xlc05lZWRbIjgwIl0gPiAwKSAvLyBTRUstTVRGCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAkKCIjdmVoaWNsZV9jaGVja2JveF8iICsgVmVoaWNsZUlEKS5jbGljaygpOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiODAiXS0tOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoVmVoaWNsZVR5cGUgPT0gIk1FSyAtIFpGIiAmJiBBRGlzX1ZlaGljbGVzTmVlZFsiODEiXSA+IDApIC8vIE1FSy1aRgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgJCgiI3ZlaGljbGVfY2hlY2tib3hfIiArIFZlaGljbGVJRCkuY2xpY2soKTsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjgxIl0tLTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFZlaGljbGVUeXBlID09ICJNRUsgLSBNVEYiICYmIEFEaXNfVmVoaWNsZXNOZWVkWyI4MiJdID4gMCkgLy8gTUVLLU1URgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgJCgiI3ZlaGljbGVfY2hlY2tib3hfIiArIFZlaGljbGVJRCkuY2xpY2soKTsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjgyIl0tLTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8gIC0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0KICAgICAgICAvLyAgLQogICAgICAgIC8vICAtICAgICAgICAgICAgICAgICAgIFByb2Nlc3MgV2F0ZXJfUmVzY3VlCiAgICAgICAgLy8gIC0KICAgICAgICAvLyAgLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLQogICAgICAgIAogICAgICAgIGZ1bmN0aW9uIEFEaXNfUHJvY2Vzc1dhdGVyUmVzY3VlKCkgewogICAgICAgIAogICAgICAgICAgICAvLyAgICAgIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0KICAgICAgICAgICAgLy8gICAgICAtCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgIFdhdGVyIFJlc2N1ZTogVmVoaWNsZXMKICAgICAgICAgICAgLy8gICAgICAtCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICA2MzogICAgIEdXLVRhdWNoZXIKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgIDY0OiAgICAgR1ctV2Fzc2VycmV0dHVuZwogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgNjk6ICAgICBUYXVjaGtyYWZ0d2FnZW4gKGhhbmRlbCBpdCBoZXJlO1RlY2huaWNhbEVtZXJnZW5jeVNlcnZpY2UpCiAgICAgICAgICAgIC8vICAgICAgLQogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICBCb290ZToKICAgICAgICAgICAgLy8gICAgICAtCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICA2NjogICAgIEFuaCBNekIgKGhhbmRlbCBpdCBoZXJlO1RlY2huaWNhbEVtZXJnZW5jeVNlcnZpY2UpCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICA2NzogICAgIEFuaCBTY2hsQiAoaGFuZGVsIGl0IGhlcmU7VGVjaG5pY2FsRW1lcmdlbmN5U2VydmljZSkKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgIDY4OiAgICAgQW5oIE16QUIgKGhhbmRlbCBpdCBoZXJlO1RlY2huaWNhbEVtZXJnZW5jeVNlcnZpY2UpCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICA3MDogICAgIE1aQgogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgNzE6ICAgICBBQi1NWkIgKGhhbmRlbCBpdCBoZXJlO0ZpcmVEZXBhcnRtZW50KQogICAgICAgICAgICAvLyAgICAgIC0KICAgICAgICAgICAgLy8gICAgICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtICAtCiAgICAgICAgCiAgICAgICAgICAgIGlmICh0eXBlb2YgTWlzc2lvbkNvbmZpZy53YXRlcl9yZXNjdWUgPT0gIm9iamVjdCIpIHsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI2MyJdICs9IHBhcnNlSW50KE1pc3Npb25Db25maWcud2F0ZXJfcmVzY3VlLm51bV9HV19UKTsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI2NCJdICs9IHBhcnNlSW50KE1pc3Npb25Db25maWcud2F0ZXJfcmVzY3VlLm51bV9HV19XKTsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI3MCJdICs9IHBhcnNlSW50KE1pc3Npb25Db25maWcud2F0ZXJfcmVzY3VlLm51bV9NekIpOwogICAgICAgIAogICAgICAgICAgICAgICAgJCgiI3ZlaGljbGVfc2hvd190YWJsZV9ib2R5X2FsbCIpLmZpbmQoIi52ZWhpY2xlX3NlbGVjdF90YWJsZV90ciIpLmVhY2goZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIHZhciBWZWhpY2xlSUQgPSAkKHRoaXMpLmF0dHIoImlkIikucmVwbGFjZSgidmVoaWNsZV9lbGVtZW50X2NvbnRlbnRfIiwgIiIpOwogICAgICAgICAgICAgICAgICAgIC8vIHZhciBWZWhpY2xlRGlzdGFuY2VUaW1lID0gJCgiI3ZlaGljbGVfc29ydF8iICsgVmVoaWNsZUlEKS5hdHRyKCJzb3J0dmFsdWUiKTsKICAgICAgICAgICAgICAgICAgICB2YXIgVmVoaWNsZVR5cGUgPSAkKHRoaXMpLmF0dHIoInZlaGljbGVfdHlwZSIpOwogICAgICAgIAogICAgICAgICAgICAgICAgICAgIGlmICgkKCIjdmVoaWNsZV9jaGVja2JveF8iICsgVmVoaWNsZUlEICsgIjplbmFibGVkIikubGVuZ3RoID09PSAwKXsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgIAogICAgICAgICAgICAgICAgICAgIGlmICgoVmVoaWNsZVR5cGUgPT0gIkdXLVRhdWNoZXIiIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWhpY2xlVHlwZSA9PSAiVGF1Y2hrcmFmdHdhZ2VuIikgJiYgQURpc19WZWhpY2xlc05lZWRbIjYzIl0gPiAwKSAvLyBHVy1UYXVjaGVyCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAkKCIjdmVoaWNsZV9jaGVja2JveF8iICsgVmVoaWNsZUlEKS5jbGljaygpOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNjMiXS0tOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoVmVoaWNsZVR5cGUgPT0gIkdXLVdhc3NlcnJldHR1bmciICYmIEFEaXNfVmVoaWNsZXNOZWVkWyI2NCJdID4gMCkgLy8gR1ctV2Fzc2VycmV0dHVuZwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgJCgiI3ZlaGljbGVfY2hlY2tib3hfIiArIFZlaGljbGVJRCkuY2xpY2soKTsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjY0Il0tLTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChWZWhpY2xlVHlwZSA9PSAiTVpCIiB8fCBWZWhpY2xlVHlwZSA9PSAiQW5oIE16QiIgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlaGljbGVUeXBlID09ICJBbmggTXpBQiIgfHwgVmVoaWNsZVR5cGUgPT0gIkFuaCBTY2hsQiIgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlaGljbGVUeXBlID09ICJBQi1NWkIiKSAmJiBBRGlzX1ZlaGljbGVzTmVlZFsiNjYiXSArIEFEaXNfVmVoaWNsZXNOZWVkWyI2NyJdICsgQURpc19WZWhpY2xlc05lZWRbIjY4Il0gKwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNzAiXSArIEFEaXNfVmVoaWNsZXNOZWVkWyI3MSJdID4gMCkgLy8gQm9vdGUKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiN2ZWhpY2xlX2NoZWNrYm94XyIgKyBWZWhpY2xlSUQpLmNsaWNrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI3MCJdLS07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vICAtIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tIC0tCiAgICAgICAgLy8gIC0KICAgICAgICAvLyAgLSAgICAgICAgICAgICAgICAgICBQcm9jZXNzIFRlY2huaWNhbCBFbWVyZ2VuY3kgU2VydmljZQogICAgICAgIC8vICAtCiAgICAgICAgLy8gIC0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0KICAgICAgICAKICAgICAgICBmdW5jdGlvbiBBRGlzX1Byb2Nlc3NUZWNobmljYWxFbWVyZ2VuY3lTZXJ2aWNlKCkgewogICAgICAgIAogICAgICAgICAgICAvLyAgICAgIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0KICAgICAgICAgICAgLy8gICAgICAtCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgIFRIVzogVmVoaWNsZXMKICAgICAgICAgICAgLy8gICAgICAtCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICAzOTogICAgIEdLVyAoc2VlIGFsc28gRmlyZURlcGFydG1lbnQpCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICA0MDogICAgIE1UVy1UWgogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgNDE6ICAgICBNektXCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICA0MjogICAgIExLVyBLIDkKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgIDQzOiAgICAgQlJtRyBSCiAgICAgICAgICAgIC8vICAgICAgLQogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgNDQ6ICAgICBBbmggRExFCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICA0NTogICAgIE1MVyA1CiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICA2NTogICAgIExLVyA3IExrciAxOSB0bQogICAgICAgICAgICAvLyAgICAgIC0gICAgICAgICAgICAgICAgICAgNjk6ICAgICBUYXVjaGtyYWZ0d2FnZW4gKHNlZSBXYXRlclJlc2N1ZSkKICAgICAgICAgICAgLy8gICAgICAtCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICA2NjogICAgIEFuaCBNekIgKHNlZSBXYXRlclJlc2N1ZSkKICAgICAgICAgICAgLy8gICAgICAtICAgICAgICAgICAgICAgICAgIDY3OiAgICAgQW5oIFNjaGxCIChzZWUgV2F0ZXJSZXNjdWUpCiAgICAgICAgICAgIC8vICAgICAgLSAgICAgICAgICAgICAgICAgICA2ODogICAgIEFuaCBNekFCIChzZWUgV2F0ZXJSZXNjdWUpCiAgICAgICAgICAgIC8vICAgICAgLQogICAgICAgICAgICAvLyAgICAgIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0gIC0KICAgICAgICAKICAgICAgICAgICAgaWYgKHR5cGVvZiBNaXNzaW9uQ29uZmlnLnRlY2huaWNhbF9lbWVyZ2VuY3lfc2VydmljZSA9PSAib2JqZWN0IikgewogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjM5Il0gKz0gcGFyc2VJbnQoTWlzc2lvbkNvbmZpZy50ZWNobmljYWxfZW1lcmdlbmN5X3NlcnZpY2UubnVtX0dLVyk7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNDAiXSArPSBwYXJzZUludChNaXNzaW9uQ29uZmlnLnRlY2huaWNhbF9lbWVyZ2VuY3lfc2VydmljZS5udW1fTVRXX1RaKTsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI0MSJdICs9IHBhcnNlSW50KE1pc3Npb25Db25maWcudGVjaG5pY2FsX2VtZXJnZW5jeV9zZXJ2aWNlLm51bV9NektXKTsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI0MiJdICs9IHBhcnNlSW50KE1pc3Npb25Db25maWcudGVjaG5pY2FsX2VtZXJnZW5jeV9zZXJ2aWNlLm51bV9MS1dfSzkpOwogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjQzIl0gKz0gcGFyc2VJbnQoTWlzc2lvbkNvbmZpZy50ZWNobmljYWxfZW1lcmdlbmN5X3NlcnZpY2UubnVtX0JSbUdfUik7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNDQiXSArPSBwYXJzZUludChNaXNzaW9uQ29uZmlnLnRlY2huaWNhbF9lbWVyZ2VuY3lfc2VydmljZS5udW1fQW5oX0RMRSk7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNDUiXSArPSBwYXJzZUludChNaXNzaW9uQ29uZmlnLnRlY2huaWNhbF9lbWVyZ2VuY3lfc2VydmljZS5udW1fTUxXXzUpOwogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjY1Il0gKz0gcGFyc2VJbnQoTWlzc2lvbkNvbmZpZy50ZWNobmljYWxfZW1lcmdlbmN5X3NlcnZpY2UubnVtX0xLV183TGtyKTsKICAgICAgICAKICAgICAgICAgICAgICAgICQoIiN2ZWhpY2xlX3Nob3dfdGFibGVfYm9keV9hbGwiKS5maW5kKCIudmVoaWNsZV9zZWxlY3RfdGFibGVfdHIiKS5lYWNoKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgVmVoaWNsZUlEID0gJCh0aGlzKS5hdHRyKCJpZCIpLnJlcGxhY2UoInZlaGljbGVfZWxlbWVudF9jb250ZW50XyIsICIiKTsKICAgICAgICAgICAgICAgICAgICAvLyB2YXIgVmVoaWNsZURpc3RhbmNlVGltZSA9ICQoIiN2ZWhpY2xlX3NvcnRfIiArIFZlaGljbGVJRCkuYXR0cigic29ydHZhbHVlIik7CiAgICAgICAgICAgICAgICAgICAgdmFyIFZlaGljbGVUeXBlID0gJCh0aGlzKS5hdHRyKCJ2ZWhpY2xlX3R5cGUiKTsKICAgICAgICAKICAgICAgICAgICAgICAgICAgICBpZiAoJCgiI3ZlaGljbGVfY2hlY2tib3hfIiArIFZlaGljbGVJRCArICI6ZW5hYmxlZCIpLmxlbmd0aCA9PT0gMCl7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAKICAgICAgICAgICAgICAgICAgICBpZiAoVmVoaWNsZVR5cGUgPT0gIkdLVyIgJiYgQURpc19WZWhpY2xlc05lZWRbIjM5Il0gPiAwKSAvLyBHS1cKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiN2ZWhpY2xlX2NoZWNrYm94XyIgKyBWZWhpY2xlSUQpLmNsaWNrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIzOSJdLS07CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChWZWhpY2xlVHlwZSA9PSAiTVRXLVRaIiAmJiBBRGlzX1ZlaGljbGVzTmVlZFsiNDAiXSA+IDApIC8vIE1UVy1UWgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgJCgiI3ZlaGljbGVfY2hlY2tib3hfIiArIFZlaGljbGVJRCkuY2xpY2soKTsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjQwIl0tLTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFZlaGljbGVUeXBlID09ICJNektXIiAmJiBBRGlzX1ZlaGljbGVzTmVlZFsiNDEiXSA+IDApIC8vIE16S1cKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiN2ZWhpY2xlX2NoZWNrYm94XyIgKyBWZWhpY2xlSUQpLmNsaWNrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI0MSJdLS07CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChWZWhpY2xlVHlwZSA9PSAiTEtXIEsgOSIgJiYgQURpc19WZWhpY2xlc05lZWRbIjQyIl0gPiAwKSAvLyBMS1cgSyA5CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAkKCIjdmVoaWNsZV9jaGVja2JveF8iICsgVmVoaWNsZUlEKS5jbGljaygpOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNDIiXS0tOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoVmVoaWNsZVR5cGUgPT0gIkJSbUcgUiIgJiYgQURpc19WZWhpY2xlc05lZWRbIjQzIl0gPiAwKSAvLyBCUm1HIFIKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiN2ZWhpY2xlX2NoZWNrYm94XyIgKyBWZWhpY2xlSUQpLmNsaWNrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI0MyJdLS07CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChWZWhpY2xlVHlwZSA9PSAiQW5oIERMRSIgJiYgQURpc19WZWhpY2xlc05lZWRbIjQ0Il0gPiAwKSAvLyBBbmggRExFCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAkKCIjdmVoaWNsZV9jaGVja2JveF8iICsgVmVoaWNsZUlEKS5jbGljaygpOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNDQiXS0tOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoVmVoaWNsZVR5cGUgPT0gIk1MVyA1IiAmJiBBRGlzX1ZlaGljbGVzTmVlZFsiNDUiXSA+IDApIC8vIE1MVyA1CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAkKCIjdmVoaWNsZV9jaGVja2JveF8iICsgVmVoaWNsZUlEKS5jbGljaygpOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNDUiXS0tOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoVmVoaWNsZVR5cGUgPT0gIkxLVyA3IExrciAxOSB0bSIgJiYgQURpc19WZWhpY2xlc05lZWRbIjY1Il0gPiAwKSAvLyBMS1cgNyBMa3IgMTkgdG0KICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiN2ZWhpY2xlX2NoZWNrYm94XyIgKyBWZWhpY2xlSUQpLmNsaWNrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI2NSJdLS07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHZhciBBRGlzX1ZlaGljbGVzTmVlZCA9IHt9OwogICAgICAgIAogICAgICAgIGZ1bmN0aW9uIEFEaXNfUHJlcGFyZVZlaGljbGVOZWVkTGlzdCgpIHsKICAgICAgICAgICAgZm9yIChWZWhpY2xlVHlwZUlEID0gMDsgVmVoaWNsZVR5cGVJRCA8PSBNYXhWZWhpY2xlSUQ7IFZlaGljbGVUeXBlSUQrKykgewogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbVmVoaWNsZVR5cGVJRF0gPSAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAoVmVoaWNsZVR5cGVJRCA9IDA7IFZlaGljbGVUeXBlSUQgPD0gTWF4VmVoaWNsZUlEOyBWZWhpY2xlVHlwZUlEKyspIHsKICAgICAgICAgICAgICAgIEFEaXNfQ291bnRJbnZvbHZlZFZlaGljbGVzT2ZUeXBlKFZlaGljbGVUeXBlSUQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNvbnNvbGUubG9nKCJBRGlzX1ByZXBhcmVWZWhpY2xlTmVlZExpc3Q6IG9rIik7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBmdW5jdGlvbiBBRGlzX0NvdW50SW52b2x2ZWRWZWhpY2xlc09mVHlwZShWZWhpY2xlVHlwZUlEKSB7CiAgICAgICAgICAgIGZvciAodmFyIEtleSBpbiBBRF9WZWhpY2xlcykgewogICAgICAgICAgICAgICAgdmFyIFZlaGljbGUgPSBBRF9WZWhpY2xlc1tLZXldOwogICAgICAgICAgICAgICAgaWYgKFZlaGljbGUudHlwZSA9PSBWZWhpY2xlVHlwZUlEKSB7CiAgICAgICAgICAgICAgICAgICAgQURpc19TZWxlY3RDb3VudFZlaGljbGVzKFZlaGljbGVUeXBlSUQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgIAogICAgICAgICAgICAkKCIjbWlzc2lvbl92ZWhpY2xlX2RyaXZpbmcgdGJvZHksICNtaXNzaW9uX3ZlaGljbGVfYXRfbWlzc2lvbiB0Ym9keSIpLmZpbmQoInRyIikuZWFjaChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICBpZiAoJCh0aGlzKS5maW5kKCJhIikuZmlyc3QoKS5hdHRyKCJ2ZWhpY2xlX3R5cGVfaWQiKSA9PSBWZWhpY2xlVHlwZUlEKSB7CiAgICAgICAgICAgICAgICAgICAgQURpc19TZWxlY3RDb3VudFZlaGljbGVzKFZlaGljbGVUeXBlSUQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICAKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBmdW5jdGlvbiBBRGlzX1NlbGVjdENvdW50VmVoaWNsZXMoVmVoaWNsZVR5cGVJRCkgewogICAgICAgICAgICB2YXIgVmVoaWNsZVR5cGVJRCA9IE51bWJlcihWZWhpY2xlVHlwZUlEKTsKICAgICAgICAgICAgaWYgKFszOF0uaW5kZXhPZihWZWhpY2xlVHlwZUlEKSAhPSAtMSkgewogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbVmVoaWNsZVR5cGVJRF0tLTsKICAgICAgICAgICAgfSBlbHNlIGlmIChbMCwgMSwgNiwgNywgOCwgOSwgMzAsIDM3LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsIDI1LCAyNl0uaW5kZXhPZihWZWhpY2xlVHlwZUlEKSAhPSAtMSkgeyAvLyBMRiBhY3RzIGFzICdUcmFnZWhpbGZlJwogICAgICAgICAgICAgICAgLy8gMzAgYWN0cyBhcyBS/HN0d2FnZW4KICAgICAgICAgICAgICAgIGlmIChbMzBdLmluZGV4T2YoVmVoaWNsZVR5cGVJRCkgIT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNCJdLS07CiAgICAgICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjM5Il0tLTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIDAgYWN0cyBhcyBhbGwgTEYKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIwIl0tLTsKICAgICAgICAgICAgfSBlbHNlIGlmIChbNzRdLmluZGV4T2YoVmVoaWNsZVR5cGVJRCkgIT0gLTEpIHsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI3NCJdLS07CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiMjgiXS0tOwogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjI5Il0tLTsKICAgICAgICAgICAgfSBlbHNlIGlmIChbNzNdLmluZGV4T2YoVmVoaWNsZVR5cGVJRCkgIT0gLTEpIHsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI3MyJdLS07CiAgICAgICAgICAgIH0gZWxzZSBpZiAoWzI4XS5pbmRleE9mKFZlaGljbGVUeXBlSUQpICE9IC0xKSB7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiMjgiXS0tOwogICAgICAgICAgICB9IGVsc2UgaWYgKFsyOV0uaW5kZXhPZihWZWhpY2xlVHlwZUlEKSAhPSAtMSkgewogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjI5Il0tLTsKICAgICAgICAgICAgfSBlbHNlIGlmIChbMzFdLmluZGV4T2YoVmVoaWNsZVR5cGVJRCkgIT0gLTEpIHsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIzMSJdLS07CiAgICAgICAgICAgIH0gZWxzZSBpZiAoWzU1XS5pbmRleE9mKFZlaGljbGVUeXBlSUQpICE9IC0xKSB7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNTUiXS0tOwogICAgICAgICAgICB9IGVsc2UgaWYgKFs1Nl0uaW5kZXhPZihWZWhpY2xlVHlwZUlEKSAhPSAtMSkgewogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjU2Il0tLTsKICAgICAgICAgICAgfSBlbHNlIGlmIChbNThdLmluZGV4T2YoVmVoaWNsZVR5cGVJRCkgIT0gLTEpIHsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI1OCJdLS07CiAgICAgICAgICAgIH0gZWxzZSBpZiAoWzU5XS5pbmRleE9mKFZlaGljbGVUeXBlSUQpICE9IC0xKSB7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNTkiXS0tOwogICAgICAgICAgICB9IGVsc2UgaWYgKFs2MF0uaW5kZXhPZihWZWhpY2xlVHlwZUlEKSAhPSAtMSkgewogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjYwIl0tLTsKICAgICAgICAgICAgfSBlbHNlIGlmIChbMl0uaW5kZXhPZihWZWhpY2xlVHlwZUlEKSAhPSAtMSkgewogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjIiXS0tOwogICAgICAgICAgICB9IGVsc2UgaWYgKFszNCwgNzhdLmluZGV4T2YoVmVoaWNsZVR5cGVJRCkgIT0gLTEpIHsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIzIl0tLTsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIzNCJdLS07CiAgICAgICAgICAgIH0gZWxzZSBpZiAoWzNdLmluZGV4T2YoVmVoaWNsZVR5cGVJRCkgIT0gLTEpIHsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIzIl0tLTsKICAgICAgICAgICAgfSBlbHNlIGlmIChbMzZdLmluZGV4T2YoVmVoaWNsZVR5cGVJRCkgIT0gLTEpIHsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIzNiJdLS07CiAgICAgICAgICAgIH0gZWxzZSBpZiAoWzU3XS5pbmRleE9mKFZlaGljbGVUeXBlSUQpICE9IC0xKSB7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNTciXS0tOwogICAgICAgICAgICB9IGVsc2UgaWYgKFs0LDM5XS5pbmRleE9mKFZlaGljbGVUeXBlSUQpICE9IC0xKSB7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNCJdLS07CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiMzkiXS0tOwogICAgICAgICAgICB9IGVsc2UgaWYgKFs0LCA0N10uaW5kZXhPZihWZWhpY2xlVHlwZUlEKSAhPSAtMSkgewogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjQiXS0tOwogICAgICAgICAgICB9IGVsc2UgaWYgKFs1LCA0OF0uaW5kZXhPZihWZWhpY2xlVHlwZUlEKSAhPSAtMSkgewogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjUiXS0tOwogICAgICAgICAgICB9IGVsc2UgaWYgKFsxMCwgNDldLmluZGV4T2YoVmVoaWNsZVR5cGVJRCkgIT0gLTEpIHsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIxMCJdLS07CiAgICAgICAgICAgIH0gZWxzZSBpZiAoWzEyXS5pbmRleE9mKFZlaGljbGVUeXBlSUQpICE9IC0xKSB7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiMTIiXS0tOwogICAgICAgICAgICB9IGVsc2UgaWYgKFsxMSwgMTMsIDE0LCAxNSwgMTZdLmluZGV4T2YoVmVoaWNsZVR5cGVJRCkgIT0gLTEpIHsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIxMSJdLS07CiAgICAgICAgICAgIH0gZWxzZSBpZiAoWzI3LCA3N10uaW5kZXhPZihWZWhpY2xlVHlwZUlEKSAhPSAtMSkgewogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjI3Il0tLTsKICAgICAgICAgICAgfSBlbHNlIGlmIChbMzNdLmluZGV4T2YoVmVoaWNsZVR5cGVJRCkgIT0gLTEpIHsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIzMyJdLS07CiAgICAgICAgICAgIH0gZWxzZSBpZiAoWzUzLCA1NF0uaW5kZXhPZihWZWhpY2xlVHlwZUlEKSAhPSAtMSkgewogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjUzIl0tLTsKICAgICAgICAgICAgfSBlbHNlIGlmIChbODNdLmluZGV4T2YoVmVoaWNsZVR5cGVJRCkgIT0gLTEpIHsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI4MyJdLS07CiAgICAgICAgICAgIH0gZWxzZSBpZiAoWzg0XS5pbmRleE9mKFZlaGljbGVUeXBlSUQpICE9IC0xKSB7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiODQiXS0tOwogICAgICAgICAgICB9IGVsc2UgaWYgKFs4NV0uaW5kZXhPZihWZWhpY2xlVHlwZUlEKSAhPSAtMSkgewogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjg1Il0tLTsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIyIl0tLTsKICAgICAgICAgICAgfSBlbHNlIGlmIChbODZdLmluZGV4T2YoVmVoaWNsZVR5cGVJRCkgIT0gLTEpIHsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI4NiJdLS07CiAgICAgICAgICAgIH0gZWxzZSBpZiAoWzc1XS5pbmRleE9mKFZlaGljbGVUeXBlSUQpICE9IC0xKSB7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNzUiXS0tOwogICAgICAgICAgICB9IGVsc2UgaWYgKFs3Nl0uaW5kZXhPZihWZWhpY2xlVHlwZUlEKSAhPSAtMSkgewogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjc2Il0tLTsKICAgICAgICAgICAgfSBlbHNlIGlmIChbMzJdLmluZGV4T2YoVmVoaWNsZVR5cGVJRCkgIT0gLTEpIHsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyIzMiJdLS07CiAgICAgICAgICAgIH0gZWxzZSBpZiAoWzM1XS5pbmRleE9mKFZlaGljbGVUeXBlSUQpICE9IC0xKSB7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiMzUiXS0tOwogICAgICAgICAgICB9IGVsc2UgaWYgKFs1MF0uaW5kZXhPZihWZWhpY2xlVHlwZUlEKSAhPSAtMSkgewogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjUwIl0tLTsKICAgICAgICAgICAgfSBlbHNlIGlmIChbNTFdLmluZGV4T2YoVmVoaWNsZVR5cGVJRCkgIT0gLTEpIHsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI1MSJdLS07CiAgICAgICAgICAgIH0gZWxzZSBpZiAoWzUyXS5pbmRleE9mKFZlaGljbGVUeXBlSUQpICE9IC0xKSB7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNTIiXS0tOwogICAgICAgICAgICB9IGVsc2UgaWYgKFs3Ml0uaW5kZXhPZihWZWhpY2xlVHlwZUlEKSAhPSAtMSkgewogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjcyIl0tLTsKICAgICAgICAgICAgfSBlbHNlIGlmIChbNjFdLmluZGV4T2YoVmVoaWNsZVR5cGVJRCkgIT0gLTEpIHsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI2MSJdLS07CiAgICAgICAgICAgIH0gZWxzZSBpZiAoWzc5XS5pbmRleE9mKFZlaGljbGVUeXBlSUQpICE9IC0xKSB7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNzkiXS0tOwogICAgICAgICAgICB9IGVsc2UgaWYgKFs4MF0uaW5kZXhPZihWZWhpY2xlVHlwZUlEKSAhPSAtMSkgewogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjgwIl0tLTsKICAgICAgICAgICAgfSBlbHNlIGlmIChbODFdLmluZGV4T2YoVmVoaWNsZVR5cGVJRCkgIT0gLTEpIHsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI4MSJdLS07CiAgICAgICAgICAgIH0gZWxzZSBpZiAoWzgyXS5pbmRleE9mKFZlaGljbGVUeXBlSUQpICE9IC0xKSB7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiODIiXS0tOwogICAgICAgICAgICB9IGVsc2UgaWYgKFs2MywgNjldLmluZGV4T2YoVmVoaWNsZVR5cGVJRCkgIT0gLTEpIHsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI2MyJdLS07CiAgICAgICAgICAgIH0gZWxzZSBpZiAoWzY0XS5pbmRleE9mKFZlaGljbGVUeXBlSUQpICE9IC0xKSB7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNjQiXS0tOwogICAgICAgICAgICB9IGVsc2UgaWYgKFs2NiwgNjcsIDY4LCA3MCwgNzFdLmluZGV4T2YoVmVoaWNsZVR5cGVJRCkgIT0gLTEpIHsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI3MCJdLS07CiAgICAgICAgICAgIH0gZWxzZSBpZiAoWzQwXS5pbmRleE9mKFZlaGljbGVUeXBlSUQpICE9IC0xKSB7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNDAiXS0tOwogICAgICAgICAgICB9IGVsc2UgaWYgKFs0MV0uaW5kZXhPZihWZWhpY2xlVHlwZUlEKSAhPSAtMSkgewogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjQxIl0tLTsKICAgICAgICAgICAgfSBlbHNlIGlmIChbNDJdLmluZGV4T2YoVmVoaWNsZVR5cGVJRCkgIT0gLTEpIHsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI0MiJdLS07CiAgICAgICAgICAgIH0gZWxzZSBpZiAoWzQzXS5pbmRleE9mKFZlaGljbGVUeXBlSUQpICE9IC0xKSB7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNDMiXS0tOwogICAgICAgICAgICB9IGVsc2UgaWYgKFs0NF0uaW5kZXhPZihWZWhpY2xlVHlwZUlEKSAhPSAtMSkgewogICAgICAgICAgICAgICAgQURpc19WZWhpY2xlc05lZWRbIjQ0Il0tLTsKICAgICAgICAgICAgfSBlbHNlIGlmIChbNDVdLmluZGV4T2YoVmVoaWNsZVR5cGVJRCkgIT0gLTEpIHsKICAgICAgICAgICAgICAgIEFEaXNfVmVoaWNsZXNOZWVkWyI0NSJdLS07CiAgICAgICAgICAgIH0gZWxzZSBpZiAoWzY1XS5pbmRleE9mKFZlaGljbGVUeXBlSUQpICE9IC0xKSB7CiAgICAgICAgICAgICAgICBBRGlzX1ZlaGljbGVzTmVlZFsiNjUiXS0tOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGZ1bmN0aW9uIEFEaXNfQ2hlY2tOZWVkTW9yZVZlaGljbGVzKCkgewogICAgICAgICAgICB2YXIgTmVlZE1vcmVWZWhpY2xlcyA9IGZhbHNlOwogICAgICAgIAogICAgICAgICAgICBmb3IgKHZhciBLZXkgaW4gQURpc19WZWhpY2xlc05lZWQpIHsKICAgICAgICAgICAgICAgIHZhciBWZWhpY2xlQ291bnQgPSBBRGlzX1ZlaGljbGVzTmVlZFtLZXldOwogICAgICAgICAgICAgICAgaWYgKFZlaGljbGVDb3VudCA+IDApIHsKICAgICAgICAgICAgICAgICAgICBOZWVkTW9yZVZlaGljbGVzID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICAKICAgICAgICAgICAgcmV0dXJuIE5lZWRNb3JlVmVoaWNsZXM7CiAgICAgICAgfQogICAgfQogICAgLy8gICAgICAtCiAgICAvLyAgICAgIC0gICAgICAgICAgIFNwcmVjaHd1bnNjaCBWYXJpYWJsZW4KICAgIC8vICAgICAgLQogICAgdmFyIEphaWxzID0gW107CiAgICB2YXIgSmFpbFJlZ0V4ID0gL1woRnJlaWUgWmVsbGVuXDpccysoXGQpXCxccytFbnRmZXJudW5nXDpccysoXGQrXCxcZCspXHMra20oPzpcLFxzK0FiZ2FiZSBhbiBCZXNpdHplclw6XHMrKFxkKyklKT9cKS9nOwogICAgdmFyIEhvc3BpdGFscyA9IFtdOwogICAgdmFyIFJlc2N1ZVZlaGljbGVGcmFtZVdhdGNoRG9nOwogICAgdmFyIFBvbGljZVZlaGljbGVGcmFtZVdhdGNoRG9nOwogICAgCiAgICAKICAgIC8vICAgICAgLQogICAgLy8gICAgICAtICAgICAgICAgICBTcHJlY2h3dW5zY2ggUXVldWUKICAgIC8vICAgICAgLQogICAgCiAgICBmdW5jdGlvbiBBRGlzX1JlbW92ZVBvbGljZVNwcmVjaHd1bnNjaEZyb21RdWV1ZShXdW5zY2hJRCkgewogICAgICAgIGNvbnNvbGUubG9nKFd1bnNjaElELCB0eXBlb2YgV3Vuc2NoSUQpOwogICAgICAgIHJldHVybiBBRGlzREIuQURpc1NwcmVjaHd1bnNjaFBvbGljZS53aGVyZSh7CiAgICAgICAgICAgIG1pc3Npb25JRDogV3Vuc2NoSUQKICAgICAgICB9KS5kZWxldGUoKTsKICAgIH0KICAgIAogICAgLy8gICAgICAtCiAgICAvLyAgICAgIC0gICAgICAgICAgIFNwcmVjaHd1bnNjaCBPcGVuZXIKICAgIC8vICAgICAgLQogICAgaWYgKHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSA9PT0gIi8iIHx8IHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSA9PT0gIi8jIikgewogICAgICAgICQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgc2V0SW50ZXJ2YWwoQURpc19Db2xsZWN0UmVzY3VlU3ByZWNod3VlbnNjaGUsIDI1MDApOwogICAgICAgICAgICBzZXRJbnRlcnZhbChBRGlzX09wZW5OZXh0UmVzY3VlU3ByZWNod3Vuc2NoLCAyNTAwKTsKICAgICAgICAgICAgQURpc19Db2xsZWN0UmVzY3VlU3ByZWNod3VlbnNjaGUoKTsKICAgICAgICB9KTsKICAgICAgICAKICAgICAgICAvLyAgLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLQogICAgICAgIC8vICAtCiAgICAgICAgLy8gIC0gICAgICAgICAgIEFzc2lnbiAmIFVuYXNzaWduIE1pc3Npb25zIHRvIERpc3BhdGNoZXJzCiAgICAgICAgLy8gIC0KICAgICAgICAvLyAgLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLSAtLQogICAgICAgIAogICAgICAgIGZ1bmN0aW9uIEFEaXNfQ29sbGVjdFJlc2N1ZVNwcmVjaHd1ZW5zY2hlKCkgewogICAgICAgICAgICBBRGlzREIuQURpc1NwcmVjaHd1bnNjaC53aGVyZSh7CiAgICAgICAgICAgICAgICBkb25lOiAnZmFsc2UnCiAgICAgICAgICAgIH0pLmVhY2goKFd1bnNjaCkgPT4gewogICAgICAgICAgICAgICAgaWYgKCQoIiN2ZWhpY2xlX2xpc3RfIiArIFd1bnNjaC52ZWhpY2xlSUQpLmZpbmQoIi5idWlsZGluZ19saXN0X2ZtcyIpLnRleHQoKSAhPSAiNSIpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gQURpc19SZW1vdmVSZXNjdWVTcHJlY2h3dW5zY2hGcm9tUXVldWUoV3Vuc2NoLnZlaGljbGVJRCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pLnRoZW4oKCkgPT4gewogICAgICAgICAgICAgICAgJCgiI2J1aWxkaW5nX2xpc3QiKS5maW5kKCIuYnVpbGRpbmdfbGlzdF92ZWhpY2xlX2VsZW1lbnQiKS5lYWNoKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgVmVoaWNsZVN0YXR1cyA9ICQodGhpcykuZmluZCgiLmJ1aWxkaW5nX2xpc3RfZm1zIikudGV4dCgpOwogICAgICAgICAgICAgICAgICAgIC8vIHZhciBWZWhpY2xlVHlwZSA9ICQodGhpcykuZmluZCgiYSIpLmF0dHIoInZlaGljbGVfdHlwZV9pZCIpOwogICAgICAgICAgICAgICAgICAgIHZhciBWZWhpY2xlSUQgPSAkKHRoaXMpLmF0dHIoInZlaGljbGVfaWQiKTsKICAgICAgICAgICAgICAgICAgICBpZiAoVmVoaWNsZVN0YXR1cyA9PSAiNSIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19BZGRSZXNjdWVTcHJlY2h3dW5zY2hUb1F1ZXVlKFZlaGljbGVJRCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBmdW5jdGlvbiBBRGlzX09wZW5OZXh0UmVzY3VlU3ByZWNod3Vuc2NoKCkgewogICAgICAgICAgICBBRGlzU2V0dGluZ3MoKS50aGVuKChzZXR0aW5nKSA9PiB7CiAgICAgICAgICAgICAgICBpZiAoc2V0dGluZ1snU3ByZWNod3Vuc2NoLUF1dG9tYXRpYyddID09ICd0cnVlJykgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBBRGlzREIuQURpc1NwcmVjaHd1bnNjaC53aGVyZSh7CiAgICAgICAgICAgICAgICAgICAgICAgIGRvbmU6ICdmYWxzZScKICAgICAgICAgICAgICAgICAgICB9KS5saW1pdCgxKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KS50aGVuKChXdW5zY2gpID0+IHsKICAgICAgICAgICAgICAgIGlmIChXdW5zY2ggIT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICAgICAgICAgIFd1bnNjaC5lYWNoKChteVd1bnNjaCkgPT4gewogICAgICAgICAgICAgICAgICAgICAgICBsZXQgVmVoaWNsZUlEID0gbXlXdW5zY2gudmVoaWNsZUlEOwogICAgICAgICAgICAgICAgICAgICAgICBBRGlzX1VwZGF0ZVJlc2N1ZVNwcmVjaHd1bnNjaFRvRG9uZShWZWhpY2xlSUQpLnRoZW4oKCkgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCQoIiNhZGlzLXNwcmVjaHd1bnNjaC1yZXNjdWUtZnJhbWUiKS5hdHRyKCJ2ZWhpY2xlX2lkIikgPT0gImVtcHR5IikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoIiNhZGlzLXNwcmVjaHd1bnNjaC1yZXNjdWUtZnJhbWUiKS5hdHRyKCJzcmMiLCAiaHR0cHM6Ly93d3cubGVpdHN0ZWxsZW5zcGllbC5kZS92ZWhpY2xlcy8iICsgVmVoaWNsZUlEKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKCIjYWRpcy1zcHJlY2h3dW5zY2gtcmVzY3VlLWZyYW1lIikuYXR0cigidmVoaWNsZV9pZCIsIFZlaGljbGVJRCk7CiAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzY3VlVmVoaWNsZUZyYW1lV2F0Y2hEb2cgPSBzZXRUaW1lb3V0KGFzeW5jIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQURpc19SZW1vdmVSZXNjdWVTcHJlY2h3dW5zY2hGcm9tUXVldWUoVmVoaWNsZUlEKS50aGVuKChkZWxldGVDb3VudCkgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJCgiI2FkaXMtc3ByZWNod3Vuc2NoLXJlc2N1ZS1mcmFtZSIpLmF0dHIoInNyYyIsICIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoIiNhZGlzLXNwcmVjaHd1bnNjaC1yZXNjdWUtZnJhbWUiKS5hdHRyKCJ2ZWhpY2xlX2lkIiwgImVtcHR5Iik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIDE1MDApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGZ1bmN0aW9uIEFEaXNfQWRkUmVzY3VlU3ByZWNod3Vuc2NoVG9RdWV1ZShXdW5zY2hJRCkgewogICAgICAgICAgICByZXR1cm4gQURpc0RCLkFEaXNTcHJlY2h3dW5zY2guYWRkKHsKICAgICAgICAgICAgICAgIHZlaGljbGVJRDogV3Vuc2NoSUQsCiAgICAgICAgICAgICAgICBkb25lOiAnZmFsc2UnCiAgICAgICAgICAgIH0pLmNhdGNoKChlcnIpID0+IHt9KQogICAgICAgIH0KICAgICAgICAKICAgICAgICAKICAgICAgICBmdW5jdGlvbiBBRGlzX1VwZGF0ZVJlc2N1ZVNwcmVjaHd1bnNjaFRvRG9uZShXdW5zY2hJRCkgewogICAgICAgICAgICByZXR1cm4gQURpc0RCLkFEaXNTcHJlY2h3dW5zY2gucHV0KHsKICAgICAgICAgICAgICAgIHZlaGljbGVJRDogV3Vuc2NoSUQsCiAgICAgICAgICAgICAgICBkb25lOiAndHJ1ZScKICAgICAgICAgICAgfSkuY2F0Y2goKGVycikgPT4ge30pCiAgICAgICAgfQogICAgICAgIAogICAgICAgIGZ1bmN0aW9uIEFEaXNfUmVtb3ZlUmVzY3VlU3ByZWNod3Vuc2NoRnJvbVF1ZXVlKFd1bnNjaElEKSB7CiAgICAgICAgICAgIHJldHVybiBBRGlzREIuQURpc1NwcmVjaHd1bnNjaC53aGVyZSh7CiAgICAgICAgICAgICAgICB2ZWhpY2xlSUQ6IFd1bnNjaElECiAgICAgICAgICAgIH0pLmRlbGV0ZSgpOwogICAgICAgIH0KICAgICAgICAkKGRvY3VtZW50KS5yZWFkeShmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHNldEludGVydmFsKEFEaXNfQ29sbGVjdFBvbGljZVNwcmVjaHd1ZW5zY2hlLCA3NTAwKTsKICAgICAgICAgICAgc2V0SW50ZXJ2YWwoQURpc19PcGVuTmV4dFBvbGljZVNwcmVjaHd1bnNjaCwgNzUwMCk7CiAgICAgICAgICAgIEFEaXNfQ29sbGVjdFBvbGljZVNwcmVjaHd1ZW5zY2hlKCk7CiAgICAgICAgfSk7CiAgICAgICAgCiAgICAgICAgLy8gIC0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0KICAgICAgICAvLyAgLQogICAgICAgIC8vICAtICAgICAgICAgICBBc3NpZ24gJiBVbmFzc2lnbiBNaXNzaW9ucyB0byBEaXNwYXRjaGVycwogICAgICAgIC8vICAtCiAgICAgICAgLy8gIC0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0gLS0KICAgICAgICAKICAgICAgICBmdW5jdGlvbiBBRGlzX0NvbGxlY3RQb2xpY2VTcHJlY2h3dWVuc2NoZSgpIHsKICAgICAgICAgICAgQURpc0RCLkFEaXNTcHJlY2h3dW5zY2hQb2xpY2Uud2hlcmUoewogICAgICAgICAgICAgICAgZG9uZTogJ2ZhbHNlJwogICAgICAgICAgICB9KS5lYWNoKChXdW5zY2gpID0+IHsKICAgICAgICAgICAgICAgIGlmICghJCgiI21pc3Npb25fIiArIFd1bnNjaC5taXNzaW9uSUQpLnRleHQoKS5tYXRjaCgvR2VmYW5nZW5lIHNvbGxlbiBhYnRyYW5zcG9ydGllcnQgd2VyZGVuL2cpKSB7CiAgICAgICAgICAgICAgICAgICAgJCgiI21pc3Npb25fIiArIFd1bnNjaC5taXNzaW9uSUQpLnJlbW92ZSgpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBBRGlzX1JlbW92ZVBvbGljZVNwcmVjaHd1bnNjaEZyb21RdWV1ZShXdW5zY2gubWlzc2lvbklEKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSkudGhlbigoKSA9PiB7CiAgICAgICAgICAgICAgICB2YXIgTU9JT0RPUyA9ICQoJ2RpdiNtaXNzaW9uX2xpc3QgZGl2Lm1pc3Npb25TaWRlQmFyRW50cnk6dmlzaWJsZScpOwogICAgICAgICAgICAgICAgTU9JT0RPUy5lYWNoKGZ1bmN0aW9uIChpbmRleCkgewogICAgICAgICAgICAgICAgICAgIGlmICgkKHRoaXMpLnRleHQoKS5tYXRjaCgvR2VmYW5nZW5lIHNvbGxlbiBhYnRyYW5zcG9ydGllcnQgd2VyZGVuXC4vZ211KSkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgTWlzc2lvbklEID0gJCh0aGlzKS5hdHRyKCJtaXNzaW9uX2lkIik7CiAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfQWRkUG9saWNlU3ByZWNod3Vuc2NoVG9RdWV1ZShNaXNzaW9uSUQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgZnVuY3Rpb24gQURpc19PcGVuTmV4dFBvbGljZVNwcmVjaHd1bnNjaCgpIHsKICAgICAgICAgICAgQURpc1NldHRpbmdzKCkudGhlbigoc2V0dGluZykgPT4gewogICAgICAgICAgICAgICAgaWYgKHNldHRpbmdbJ1NwcmVjaHd1bnNjaC1BdXRvbWF0aWMnXSA9PSAndHJ1ZScpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gQURpc0RCLkFEaXNTcHJlY2h3dW5zY2hQb2xpY2Uud2hlcmUoewogICAgICAgICAgICAgICAgICAgICAgICBkb25lOiAnZmFsc2UnCiAgICAgICAgICAgICAgICAgICAgfSkubGltaXQoMSkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSkudGhlbigoV3Vuc2NoKSA9PiB7CiAgICAgICAgICAgICAgICBpZiAoV3Vuc2NoICE9PSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgICAgICBXdW5zY2guZWFjaCgobXlXdW5zY2gpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgbGV0IE1pc3Npb25JRCA9IG15V3Vuc2NoLm1pc3Npb25JRDsKICAgICAgICAgICAgICAgICAgICAgICAgQURpc19VcGRhdGVQb2xpY2VTcHJlY2h3dW5zY2hUb0RvbmUoTWlzc2lvbklEKS50aGVuKCgpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkKCIjYWRpcy1zcHJlY2h3dW5zY2gtcG9saWNlLWZyYW1lIikuYXR0cigibWlzc2lvbl9pZCIpID09ICJlbXB0eSIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKCIjYWRpcy1zcHJlY2h3dW5zY2gtcG9saWNlLWZyYW1lIikuYXR0cigic3JjIiwgImh0dHBzOi8vd3d3LmxlaXRzdGVsbGVuc3BpZWwuZGUvbWlzc2lvbnMvIiArIE1pc3Npb25JRCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJCgiI2FkaXMtc3ByZWNod3Vuc2NoLXBvbGljZS1mcmFtZSIpLmF0dHIoIm1pc3Npb25faWQiLCBNaXNzaW9uSUQpOwogICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBvbGljZVZlaGljbGVGcmFtZVdhdGNoRG9nID0gc2V0VGltZW91dChhc3luYyBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFEaXNfUmVtb3ZlUG9saWNlU3ByZWNod3Vuc2NoRnJvbVF1ZXVlKE1pc3Npb25JRCkudGhlbigoZGVsZXRlQ291bnQpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoIiNhZGlzLXNwcmVjaHd1bnNjaC1wb2xpY2UtZnJhbWUiKS5hdHRyKCJzcmMiLCAiIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKCIjYWRpcy1zcHJlY2h3dW5zY2gtcG9saWNlLWZyYW1lIikuYXR0cigibWlzc2lvbl9pZCIsICJlbXB0eSIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCAxNTAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBmdW5jdGlvbiBBRGlzX0FkZFBvbGljZVNwcmVjaHd1bnNjaFRvUXVldWUoV3Vuc2NoSUQpIHsKICAgICAgICAgICAgcmV0dXJuIEFEaXNEQi5BRGlzU3ByZWNod3Vuc2NoUG9saWNlLmFkZCh7CiAgICAgICAgICAgICAgICBtaXNzaW9uSUQ6IFd1bnNjaElELAogICAgICAgICAgICAgICAgZG9uZTogJ2ZhbHNlJwogICAgICAgICAgICB9KS5jYXRjaCgoZXJyKSA9PiB7fSkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgCiAgICAgICAgZnVuY3Rpb24gQURpc19VcGRhdGVQb2xpY2VTcHJlY2h3dW5zY2hUb0RvbmUoV3Vuc2NoSUQpIHsKICAgICAgICAgICAgcmV0dXJuIEFEaXNEQi5BRGlzU3ByZWNod3Vuc2NoUG9saWNlLmFkZCh7CiAgICAgICAgICAgICAgICBtaXNzaW9uSUQ6IFd1bnNjaElELAogICAgICAgICAgICAgICAgZG9uZTogJ3RydWUnCiAgICAgICAgICAgIH0pLmNhdGNoKChlcnIpID0+IHt9KQogICAgICAgIH0KICAgICAgICAKICAgICAgICAvKioKICAgICAgICAgKiAjbWlzc2lvbl9taXNzaW5nXzkwNTIxNDI4NgogICAgICAgICAqIC8vKltAaWQ9Im1pc3Npb25fbWlzc2luZ185MDUyMTQyODYiXQogICAgICAgICAqIAogICAgICAgICAqIGNvbnN0IHJlZ2V4ID0gL15HZWZhbmdlbmUgc29sbGVuIGFidHJhbnNwb3J0aWVydCB3ZXJkZW5cLiQvZ211OwogICAgICAgIGNvbnN0IHN0ciA9IGBBbGFybSBNYXNzZW5zY2hs5GdlcmVpLCBVZmVyd2VnLCAyNzc0OSBE/HN0ZXJub3J0IERlbG1lbmhvcnN0CiAgICAgICAgR2VmYW5nZW5lIHNvbGxlbiBhYnRyYW5zcG9ydGllcnQgd2VyZGVuLgogICAgICAgIFNvcGhpZSBWLgogICAgICAgIEFubmEgVC4KICAgICAgICBGcmFuemlza2EgTS5gOwogICAgICAgIGxldCBtOwogICAgICAgIAogICAgICAgIHdoaWxlICgobSA9IHJlZ2V4LmV4ZWMoc3RyKSkgIT09IG51bGwpIHsKICAgICAgICAgICAgLy8gVGhpcyBpcyBuZWNlc3NhcnkgdG8gYXZvaWQgaW5maW5pdGUgbG9vcHMgd2l0aCB6ZXJvLXdpZHRoIG1hdGNoZXMKICAgICAgICAgICAgaWYgKG0uaW5kZXggPT09IHJlZ2V4Lmxhc3RJbmRleCkgewogICAgICAgICAgICAgICAgcmVnZXgubGFzdEluZGV4Kys7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIFRoZSByZXN1bHQgY2FuIGJlIGFjY2Vzc2VkIHRocm91Z2ggdGhlIGBtYC12YXJpYWJsZS4KICAgICAgICAgICAgbS5mb3JFYWNoKChtYXRjaCwgZ3JvdXBJbmRleCkgPT4gewogICAgICAgICAgICAgICAgY29uc29sZS5sb2coYEZvdW5kIG1hdGNoLCBncm91cCAke2dyb3VwSW5kZXh9OiAke21hdGNofWApOwogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICAgICAgICovCiAgICB9CiAgICAKICAgIC8vICAgICAgLQogICAgLy8gICAgICAtICAgICAgICAgICBTcHJlY2h3dW5zY2ggSGFuZGxlciBSZXR0dW5nCiAgICAvLyAgICAgIC0KICAgIGlmICh3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUuaW5kZXhPZigiL3ZlaGljbGVzLyIpICE9PSAtMSAmJiB3aW5kb3cubmFtZSA9PSAnYWRpcy1zcHJlY2h3dW5zY2gtcmVzY3VlJykgewogICAgICAgICQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICBBRGlzX0NoZWNrX0NhbGxfQWN0aXZlKCk7CiAgICAgICAgICAgIH0sIDUwMCk7CiAgICAgICAgfSk7CiAgICAgICAgCiAgICAgICAgZnVuY3Rpb24gQURpc19DaGVja19DYWxsX0FjdGl2ZSgpIHsKICAgICAgICAgICAgaWYgKCQoImg0OmNvbnRhaW5zKCdFaWdlbmUgS3JhbmtlbmjkdXNlcicpIikubGVuZ3RoID4gMCB8fCAkKCJoNDpjb250YWlucygnVmVyYmFuZHNrcmFua2VuaOR1c2VyJykiKS5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICBBRGlzX0NvbGxlY3RfSG9zcGl0YWxzKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8gS3JhbmtlbmhhdXMgYXVzd+RobGVuCiAgICAgICAgZnVuY3Rpb24gQURpc19Db2xsZWN0X0hvc3BpdGFscygpIHsKICAgICAgICAgICAgaWYgKCQoImg0OmNvbnRhaW5zKCdFaWdlbmUgS3JhbmtlbmjkdXNlcicpIikubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgJCgiaDQ6Y29udGFpbnMoJ0VpZ2VuZSBLcmFua2VuaOR1c2VyJykiKS5uZXh0KCJ0YWJsZSIpLmZpbmQoInRib2R5IikuZmluZCgidHIiKS5lYWNoKGZ1bmN0aW9uICgpIHsKICAgICAgICAJCQl2YXIgSG9zcGl0YWxIcmVmID0gJCh0aGlzKS5maW5kKCJhOmNvbnRhaW5zKCdBbmZhaHJlbicpIikuYXR0cigiaHJlZiIpOwogICAgICAgICAgICAgICAgICAgIHZhciBIb3NwaXRhbElEID0gTnVtYmVyKHBhcnNlSW50KCQodGhpcykuZmluZCgiYTpjb250YWlucygnQW5mYWhyZW4nKSIpLmF0dHIoImlkIikucmVwbGFjZSgiYnRuX2FwcHJvYWNoXyIsICIiKSkpOwogICAgICAgICAgICAgICAgICAgIHZhciBIb3NwaXRhbERpc3RhbmNlID0gcGFyc2VJbnQoJCh0aGlzKS5maW5kKCJ0ZCIpLmVxKCIxIikudGV4dCgpKTsKICAgICAgICAgICAgICAgICAgICB2YXIgSG9zcGl0YWxGcmVlQmVkcyA9IHBhcnNlSW50KCQodGhpcykuZmluZCgidGQiKS5lcSgiMiIpLnRleHQoKSk7CiAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgdmFyIEhvc3BpdGFsVmFsdWUgPSBIb3NwaXRhbERpc3RhbmNlICogNDUwICogLTE7CiAgICAgICAgCQkJSG9zcGl0YWxWYWx1ZSArPSAyMDAwOyAvLyBPd24gSG9zcGl0YWxzIGFyZSBiZXR0ZXIgOi0pCiAgICAgICAgICAgICAgICAgICAgaWYgKCQodGhpcykuZmluZCgiLmxhYmVsOmNvbnRhaW5zKCdKYScpIikubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICBIb3NwaXRhbFZhbHVlICs9IDIwMDA7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgIAogICAgICAgICAgICAgICAgICAgIGlmIChIb3NwaXRhbEZyZWVCZWRzID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICBIb3NwaXRhbHMucHVzaCh7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaWQiOiBIb3NwaXRhbElELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInZhbHVlIjogSG9zcGl0YWxWYWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJkaXN0YW5jZSI6IEhvc3BpdGFsRGlzdGFuY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaHJlZiI6IEhvc3BpdGFsSHJlZgogICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgIAogICAgICAgICAgICBpZiAoJCgiaDQ6Y29udGFpbnMoJ1ZlcmJhbmRza3JhbmtlbmjkdXNlcicpIikubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgJCgiaDQ6Y29udGFpbnMoJ1ZlcmJhbmRza3JhbmtlbmjkdXNlcicpIikubmV4dCgidGFibGUiKS5maW5kKCJ0Ym9keSIpLmZpbmQoInRyIikuZWFjaChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIEhvc3BpdGFsSHJlZiA9ICQodGhpcykuZmluZCgiYSIpLmF0dHIoImhyZWYiKQogICAgICAgICAgICAgICAgICAgIHZhciBIb3NwaXRhbElEID0gTnVtYmVyKHBhcnNlSW50KEhvc3BpdGFsSHJlZi5zdWJzdHIoSG9zcGl0YWxIcmVmLmxhc3RJbmRleE9mKCIvIikgKyAxKSkpOwogICAgICAgICAgICAgICAgICAgIHZhciBIb3NwaXRhbERpc3RhbmNlID0gcGFyc2VJbnQoJCh0aGlzKS5maW5kKCJ0ZCIpLmVxKCIxIikudGV4dCgpKTsKICAgICAgICAgICAgICAgICAgICB2YXIgSG9zcGl0YWxGcmVlQmVkcyA9IHBhcnNlSW50KCQodGhpcykuZmluZCgidGQiKS5lcSgiMiIpLnRleHQoKSk7CiAgICAgICAgICAgICAgICAgICAgdmFyIEhvc3BpdGFsVGF4ZXMgPSBwYXJzZUludCgkKHRoaXMpLmZpbmQoInRkIikuZXEoIjMiKS50ZXh0KCkpOwogICAgICAgICAgICAgICAgICAgIHZhciBIb3NwaXRhbFNwZWNpYWxEZXBhcnRtZW50ID0gZmFsc2U7CiAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgLy8gQWRkIEJ1dHRvbi1JRCB0byBBbGxpYW5jZS1Ib3NwaXRhbAogICAgICAgICAgICAgICAgICAgICQodGhpcykuZmluZCgiYSIpLmF0dHIoImlkIiwgImJ0bl9hcHByb2FjaF8iICsgSG9zcGl0YWxJRC50b1N0cmluZygpKTsKICAgICAgICAKICAgICAgICAgICAgICAgICAgICB2YXIgSG9zcGl0YWxWYWx1ZSA9IEhvc3BpdGFsRGlzdGFuY2UgKiA0NTAgKiAtMTsKICAgICAgICAKICAgICAgICAgICAgICAgICAgICBpZiAoJCh0aGlzKS5maW5kKCIubGFiZWw6Y29udGFpbnMoJ0phJykiKS5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEhvc3BpdGFsU3BlY2lhbERlcGFydG1lbnQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBIb3NwaXRhbFZhbHVlICs9IDIwMDA7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgIAogICAgICAgICAgICAgICAgICAgIGlmIChIb3NwaXRhbFRheGVzID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgSG9zcGl0YWxWYWx1ZSArPSAyMDAwOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoSG9zcGl0YWxUYXhlcyA+IDAgJiYgSG9zcGl0YWxUYXhlcyA8PSAxMCkgewogICAgICAgICAgICAgICAgICAgICAgICBIb3NwaXRhbFZhbHVlICs9IDEwMDA7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChIb3NwaXRhbFRheGVzID4gMTAgJiYgSG9zcGl0YWxUYXhlcyA8PSAyMCkgewogICAgICAgICAgICAgICAgICAgICAgICBIb3NwaXRhbFZhbHVlICs9IDA7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgSG9zcGl0YWxWYWx1ZSAtPSA1MDAwOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAKICAgICAgICAgICAgICAgICAgICBpZiAoSG9zcGl0YWxGcmVlQmVkcyA+IDAgJiYgSG9zcGl0YWxTcGVjaWFsRGVwYXJ0bWVudCkgewogICAgICAgICAgICAgICAgICAgICAgICBIb3NwaXRhbHMucHVzaCh7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaWQiOiBIb3NwaXRhbElELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInZhbHVlIjogSG9zcGl0YWxWYWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXhlcyI6IEhvc3BpdGFsVGF4ZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGlzdGFuY2UiOiBIb3NwaXRhbERpc3RhbmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImhyZWYiOiBIb3NwaXRhbEhyZWYKICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAKICAgICAgICAgICAgSG9zcGl0YWxzLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBhLnZhbHVlIC0gYi52YWx1ZTsKICAgICAgICAgICAgfSk7CiAgICAgICAgCiAgICAgICAgICAgIEhvc3BpdGFscy5yZXZlcnNlKCk7CiAgICAgICAgICAgIEFEaXNfU2VuZF9WZWhpY2xlX1RvX0hvc3BpdGFsKCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8gS3JhbmtlbmhhdXMgZWlubGllZmVydW5nCiAgICAgICAgZnVuY3Rpb24gQURpc19TZW5kX1ZlaGljbGVfVG9fSG9zcGl0YWwoKSB7CiAgICAgICAgICAgIC8vdmFyIEhvc3BpdGFsSUQgPSBIb3NwaXRhbHNbMF0uaWQ7CiAgICAgICAgICAgIHZhciBIb3NwaXRhbEhyZWYgPSBIb3NwaXRhbHNbMF0uaHJlZjsKICAgICAgICAKICAgICAgICAgICAgLy8gVE9ETzogdGVsbFBhcmVudCgiQURpc01pc3Npb25Eb25lKCIgKyB3aW5kb3cubmFtZSArICIsIiArIE1pc3Npb25JRCArICIpOyIpOwogICAgICAgICAgICBkb2N1bWVudC5sb2NhdGlvbi5ocmVmID0gZG9jdW1lbnQubG9jYXRpb24ub3JpZ2luICsgSG9zcGl0YWxIcmVmOwogICAgICAgIAogICAgICAgIH0KICAgIH0KICAgIAogICAgLy8gICAgICAtCiAgICAvLyAgICAgIC0gICAgICAgICAgIFNwcmVjaHd1bnNjaCBIYW5kbGVyIFBvbGl6ZWkvR2VmYW5nZW5lCiAgICAvLyAgICAgIC0KICAgIGlmICh3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUuaW5kZXhPZigiL21pc3Npb25zLyIpICE9PSAtMSAmJiB3aW5kb3cubmFtZSA9PSAnYWRpcy1zcHJlY2h3dW5zY2gtcG9saWNlJykgewogICAgICAgICQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICBBRGlzX0NoZWNrX0NhbGxfUG9saWNlX0FjdGl2ZSgpOwogICAgICAgICAgICB9LCA1MDApOwogICAgICAgIH0pOwogICAgICAgIAogICAgICAgIGZ1bmN0aW9uIEFEaXNfQ2hlY2tfQ2FsbF9Qb2xpY2VfQWN0aXZlKCkgewogICAgICAgICAgICBpZiAoJCgnI2gyX3ByaXNvbmVycycpLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgIEFEaXNfQ29sbGVjdF9KYWlscygpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgQURpc19SZW1vdmVQb2xpY2VTcHJlY2h3dW5zY2hGcm9tUXVldWUoTWlzc2lvbklEKS50aGVuKChkZWxldGVDb3VudCkgPT4gewogICAgICAgICAgICAgICAgICAgICQoIiNhZGlzLXNwcmVjaHd1bnNjaC1wb2xpY2UtZnJhbWUiKS5hdHRyKCJzcmMiLCAiIik7CiAgICAgICAgICAgICAgICAgICAgJCgiI2FkaXMtc3ByZWNod3Vuc2NoLXBvbGljZS1mcmFtZSIpLmF0dHIoIm1pc3Npb25faWQiLCAiZW1wdHkiKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vIEdlZuRuZ25pcyBhdXN35GhsZW4KICAgICAgICBmdW5jdGlvbiBBRGlzX0NvbGxlY3RfSmFpbHMoKSB7CiAgICAgICAgICAgIHZhciBDb3VudEdlZmFuZ2VuZSA9IE51bWJlcihwYXJzZUludCgkKCcjaDJfcHJpc29uZXJzJykudGV4dCgpKSk7CiAgICAgICAgICAgIHZhciBwYXJlbnROb2RlID0gJCgnI21pc3Npb25fdmVoaWNsZV9hdF9taXNzaW9uIHRyID4gdGQ6bnRoLWNoaWxkKDUpID4gYTpjb250YWlucygiSm9tYWFyIiknKS5wYXJlbnQoKS5wYXJlbnQoKTsKICAgICAgICAgICAgdmFyIEdlZkt3ID0gcGFyZW50Tm9kZS5maW5kKCd0ZDpudGgtY2hpbGQoMikgPiBhW3ZlaGljbGVfdHlwZV9pZD0iNTIiXScpOwogICAgICAgICAgICB2YXIgRnVTdFcgPSBwYXJlbnROb2RlLmZpbmQoJ3RkOm50aC1jaGlsZCgyKSA+IGFbdmVoaWNsZV90eXBlX2lkPSIzMiJdJyk7CiAgICAgICAgICAgIHZhciBHZWZLd0dlZmFlZ25pc3NlID0gJChHZWZLd1swXSkucGFyZW50KCkucGFyZW50KCkubmV4dCgndHInKTsKICAgICAgICAgICAgdmFyIEZ1U3RXR2VmYWVnbmlzc2UgPSAkKEZ1U3RXWzBdKS5wYXJlbnQoKS5wYXJlbnQoKS5uZXh0KCd0cicpOwogICAgICAgIAogICAgICAgICAgICBHZWZLd0dlZmFlZ25pc3NlLmZpbmQoImE6Y29udGFpbnMoJ0ZyZWllIFplbGxlbicpIikuZWFjaChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgSmFpbEhyZWYgPSAkKHRoaXMpLmF0dHIoImhyZWYiKTsKICAgICAgICAgICAgICAgIHZhciBKYWlsSUQgPSBKYWlsSHJlZi5zcGxpdCgiLyIpLnBvcCgpOwogICAgICAgICAgICAgICAgdmFyIEphaWxUZXh0ID0gJCh0aGlzKS50ZXh0KCk7CiAgICAgICAgICAgICAgICB2YXIgSmFpbEZyZWVCZWRzID0gMDsKICAgICAgICAgICAgICAgIHZhciBKYWlsRGlzdGFuY2UgPSAwOwogICAgICAgICAgICAgICAgdmFyIEphaWxUYXggPSAwOwogICAgICAgICAgICAgICAgbGV0IG07CiAgICAgICAgICAgICAgICB3aGlsZSAoKG0gPSBKYWlsUmVnRXguZXhlYyhKYWlsVGV4dCkpICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpcyBuZWNlc3NhcnkgdG8gYXZvaWQgaW5maW5pdGUgbG9vcHMgd2l0aCB6ZXJvLXdpZHRoIG1hdGNoZXMKICAgICAgICAgICAgICAgICAgICBpZiAobS5pbmRleCA9PT0gSmFpbFJlZ0V4Lmxhc3RJbmRleCkgewogICAgICAgICAgICAgICAgICAgICAgICBKYWlsUmVnRXgubGFzdEluZGV4Kys7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgIAogICAgICAgICAgICAgICAgICAgIC8vIFRoZSByZXN1bHQgY2FuIGJlIGFjY2Vzc2VkIHRocm91Z2ggdGhlIGBtYC12YXJpYWJsZS4KICAgICAgICAgICAgICAgICAgICBtLmZvckVhY2goKG1hdGNoLCBncm91cEluZGV4KSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChncm91cEluZGV4ID09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEphaWxGcmVlQmVkcyA9IHBhcnNlSW50KG1hdGNoLnRyaW0oKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZ3JvdXBJbmRleCA9PSAyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBKYWlsRGlzdGFuY2UgPSBwYXJzZUludChtYXRjaC50cmltKCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGdyb3VwSW5kZXggPT0gMyAmJiB0eXBlb2YgbWF0Y2ggIT0gInVuZGVmaW5lZCIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEphaWxUYXggPSBwYXJzZUludChtYXRjaC50cmltKCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgSmFpbFZhbHVlID0gSmFpbERpc3RhbmNlICogNDUwICogLTE7CiAgICAgICAgICAgICAgICBKYWlsVmFsdWUgKz0gMTE7IC8vR2VmS3cgYmV2b3J6dWd0CiAgICAgICAgCiAgICAgICAgICAgICAgICBpZiAoSmFpbFRheCA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgSmFpbFZhbHVlICs9IDEwMDAwOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChKYWlsVGF4ID4gMCAmJiBKYWlsVGF4IDw9IDEwKSB7CiAgICAgICAgICAgICAgICAgICAgSmFpbFZhbHVlICs9IDUwMDA7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKEphaWxUYXggPiAxMCAmJiBKYWlsVGF4IDw9IDIwKSB7CiAgICAgICAgICAgICAgICAgICAgSmFpbFZhbHVlICs9IDEwMDA7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIEphaWxWYWx1ZSAtPSAxMDAwMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAKICAgICAgICAgICAgICAgIGlmIChKYWlsRnJlZUJlZHMgPj0gNSkgewogICAgICAgICAgICAgICAgICAgIEphaWxWYWx1ZSArPSAxNTAwMDsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoSmFpbEZyZWVCZWRzID49IDEpIHsKICAgICAgICAgICAgICAgICAgICBKYWlsVmFsdWUgKz0gMTAwMDsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgSmFpbFZhbHVlIC09IDUwMDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgCiAgICAgICAgICAgICAgICBpZiAoSmFpbEZyZWVCZWRzID49IDUpIHsKICAgICAgICAgICAgICAgICAgICBKYWlscy5wdXNoKHsKICAgICAgICAgICAgICAgICAgICAgICAgImlkIjogSmFpbElELAogICAgICAgICAgICAgICAgICAgICAgICAidmFsdWUiOiBKYWlsVmFsdWUgKyAxMDAwLAogICAgICAgICAgICAgICAgICAgICAgICAidGV4dCI6IEphaWxUZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAiZGlzdGFuY2UiOiBKYWlsRGlzdGFuY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICJocmVmIjogSmFpbEhyZWYKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoSmFpbEZyZWVCZWRzID49IDEpIHsKICAgICAgICAgICAgICAgICAgICBKYWlscy5wdXNoKHsKICAgICAgICAgICAgICAgICAgICAgICAgImlkIjogSmFpbElELAogICAgICAgICAgICAgICAgICAgICAgICAidmFsdWUiOiBKYWlsVmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICJ0ZXh0IjogSmFpbFRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICJkaXN0YW5jZSI6IEphaWxEaXN0YW5jZSwKICAgICAgICAgICAgICAgICAgICAgICAgImhyZWYiOiBKYWlsSHJlZgogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgRnVTdFdHZWZhZWduaXNzZS5maW5kKCJhOmNvbnRhaW5zKCdGcmVpZSBaZWxsZW4nKSIpLmVhY2goZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIEphaWxIcmVmID0gJCh0aGlzKS5hdHRyKCJocmVmIik7CiAgICAgICAgICAgICAgICB2YXIgSmFpbElEID0gSmFpbEhyZWYuc3BsaXQoIi8iKS5wb3AoKTsKICAgICAgICAgICAgICAgIHZhciBKYWlsVGV4dCA9ICQodGhpcykudGV4dCgpOwogICAgICAgICAgICAgICAgdmFyIEphaWxGcmVlQmVkcyA9IDA7CiAgICAgICAgICAgICAgICB2YXIgSmFpbERpc3RhbmNlID0gMDsKICAgICAgICAgICAgICAgIHZhciBKYWlsVGF4ID0gMDsKICAgICAgICAgICAgICAgIGxldCBtOwogICAgICAgICAgICAgICAgd2hpbGUgKChtID0gSmFpbFJlZ0V4LmV4ZWMoSmFpbFRleHQpKSAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgbmVjZXNzYXJ5IHRvIGF2b2lkIGluZmluaXRlIGxvb3BzIHdpdGggemVyby13aWR0aCBtYXRjaGVzCiAgICAgICAgICAgICAgICAgICAgaWYgKG0uaW5kZXggPT09IEphaWxSZWdFeC5sYXN0SW5kZXgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSmFpbFJlZ0V4Lmxhc3RJbmRleCsrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAKICAgICAgICAgICAgICAgICAgICAvLyBUaGUgcmVzdWx0IGNhbiBiZSBhY2Nlc3NlZCB0aHJvdWdoIHRoZSBgbWAtdmFyaWFibGUuCiAgICAgICAgICAgICAgICAgICAgbS5mb3JFYWNoKChtYXRjaCwgZ3JvdXBJbmRleCkgPT4gewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ3JvdXBJbmRleCA9PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBKYWlsRnJlZUJlZHMgPSBwYXJzZUludChtYXRjaC50cmltKCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGdyb3VwSW5kZXggPT0gMikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgSmFpbERpc3RhbmNlID0gcGFyc2VJbnQobWF0Y2gudHJpbSgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChncm91cEluZGV4ID09IDMgJiYgdHlwZW9mIG1hdGNoICE9ICJ1bmRlZmluZWQiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBKYWlsVGF4ID0gcGFyc2VJbnQobWF0Y2gudHJpbSgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfQogICAgICAgIAogICAgICAgICAgICAgICAgdmFyIEphaWxWYWx1ZSA9IEphaWxEaXN0YW5jZSAqIDQ1MCAqIC0xOwogICAgICAgIAogICAgICAgICAgICAgICAgaWYgKEphaWxUYXggPT0gMCkgewogICAgICAgICAgICAgICAgICAgIEphaWxWYWx1ZSArPSAxMDAwMDsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoSmFpbFRheCA+IDAgJiYgSmFpbFRheCA8PSAxMCkgewogICAgICAgICAgICAgICAgICAgIEphaWxWYWx1ZSArPSA1MDAwOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChKYWlsVGF4ID4gMTAgJiYgSmFpbFRheCA8PSAyMCkgewogICAgICAgICAgICAgICAgICAgIEphaWxWYWx1ZSArPSAxMDAwOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBKYWlsVmFsdWUgLT0gMTAwMDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgCiAgICAgICAgICAgICAgICBpZiAoSmFpbEZyZWVCZWRzID49IDUpIHsKICAgICAgICAgICAgICAgICAgICBKYWlsVmFsdWUgKz0gMTUwMDA7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKEphaWxGcmVlQmVkcyA+PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgSmFpbFZhbHVlICs9IDEwMDA7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIEphaWxWYWx1ZSAtPSA1MDAwOwogICAgICAgICAgICAgICAgfQogICAgICAgIAogICAgICAgICAgICAgICAgaWYgKEphaWxGcmVlQmVkcyA+PSBDb3VudEdlZmFuZ2VuZSkgewogICAgICAgICAgICAgICAgICAgIEphaWxzLnB1c2goewogICAgICAgICAgICAgICAgICAgICAgICAiaWQiOiBKYWlsSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICJ2YWx1ZSI6IEphaWxWYWx1ZSArIDEwMDAsCiAgICAgICAgICAgICAgICAgICAgICAgICJ0ZXh0IjogSmFpbFRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICJkaXN0YW5jZSI6IEphaWxEaXN0YW5jZSwKICAgICAgICAgICAgICAgICAgICAgICAgImhyZWYiOiBKYWlsSHJlZgogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChKYWlsRnJlZUJlZHMgPj0gMSkgewogICAgICAgICAgICAgICAgICAgIEphaWxzLnB1c2goewogICAgICAgICAgICAgICAgICAgICAgICAiaWQiOiBKYWlsSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICJ2YWx1ZSI6IEphaWxWYWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgInRleHQiOiBKYWlsVGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgImRpc3RhbmNlIjogSmFpbERpc3RhbmNlLAogICAgICAgICAgICAgICAgICAgICAgICAiaHJlZiI6IEphaWxIcmVmCiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIAogICAgICAgICAgICBKYWlscy5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gYS52YWx1ZSAtIGIudmFsdWU7CiAgICAgICAgICAgIH0pOwogICAgICAgIAogICAgICAgICAgICBKYWlscy5yZXZlcnNlKCk7CiAgICAgICAgICAgIGlmIChKYWlscy5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICBBRGlzX1NlbmRfVmVoaWNsZV9Ub19KYWlsKCkKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICQoIiNtaXNzaW9uX3ZlaGljbGVfZHJpdmluZyB0Ym9keSwgI21pc3Npb25fdmVoaWNsZV9hdF9taXNzaW9uIHRib2R5IikuZmluZCgidHIiKS5lYWNoKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgQ2FsbGVkVmVoaWNsZUlEID0gcGFyc2VJbnQoJCh0aGlzKS5maW5kKCJhIikuZmlyc3QoKS5hdHRyKCJ2ZWhpY2xlX3R5cGVfaWQiKSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKENhbGxlZFZlaGljbGVJRCA9PSA1MikgewogICAgICAgICAgICAgICAgICAgICAgICBDb3VudEdlZmFuZ2VuZSAtPSA1OwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoQ2FsbGVkVmVoaWNsZUlEID09IDMyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIENvdW50R2VmYW5nZW5lIC09IDE7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgCiAgICAgICAgICAgICAgICBpZiAoJCgnI3ZlaGljbGVfc2hvd190YWJsZV9hbGwgdHJbdmVoaWNsZV90eXBlPSJHZWZLdyJdIGlucHV0W3R5cGU9ImNoZWNrYm94Il0nKS5zaXplKCkgPiAwICYmIENvdW50R2VmYW5nZW5lID49IDUpIHsKICAgICAgICAgICAgICAgICAgICAkKCcjdmVoaWNsZV9zaG93X3RhYmxlX2FsbCB0clt2ZWhpY2xlX3R5cGU9IkdlZkt3Il0gaW5wdXRbdHlwZT0iY2hlY2tib3giXScpLmVhY2goZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoQ291bnRHZWZhbmdlbmUgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKHRoaXMpLmNsaWNrKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvdW50R2VmYW5nZW5lIC09IDU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICgkKCcjdmVoaWNsZV9zaG93X3RhYmxlX2FsbCB0clt2ZWhpY2xlX3R5cGU9IkZ1U3RXIl0gaW5wdXRbdHlwZT0iY2hlY2tib3giXScpLnNpemUoKSA+IDAgICYmIENvdW50R2VmYW5nZW5lID4gMCkgewogICAgICAgICAgICAgICAgICAgICQoJyN2ZWhpY2xlX3Nob3dfdGFibGVfYWxsIHRyW3ZlaGljbGVfdHlwZT0iRnVTdFciXSBpbnB1dFt0eXBlPSJjaGVja2JveCJdJykuZWFjaChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChDb3VudEdlZmFuZ2VuZSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICQodGhpcykuY2xpY2soKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgQ291bnRHZWZhbmdlbmUgLT0gMTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCQoJyN2ZWhpY2xlX3Nob3dfdGFibGVfYWxsIGlucHV0W3R5cGU9ImNoZWNrYm94Il06Y2hlY2tlZCcpLnNpemUoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAkKCcjbWlzc2lvbl9hbGFybV9idG4nKS5jbGljaygpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vIEdlZuRuZ25pcyBlaW5saWVmZXJ1bmcKICAgICAgICBmdW5jdGlvbiBBRGlzX1NlbmRfVmVoaWNsZV9Ub19KYWlsKCkgewogICAgICAgICAgICB2YXIgSmFpbEhyZWYgPSBKYWlsc1swXS5ocmVmCiAgICAgICAgICAgIGRvY3VtZW50LmxvY2F0aW9uLmhyZWYgPSBkb2N1bWVudC5sb2NhdGlvbi5vcmlnaW4gKyBKYWlsSHJlZjsKICAgICAgICB9CiAgICB9Cgp9KTs=`)); |