# tru_tags v2.1 # Tagging support for Textpattern # Nathan Arthur # http://www.rainskit.com/ # ...................................................................... # This is a plugin for Textpattern - http://textpattern.com/ # To install: textpattern > admin > plugins # Paste the following text into the 'Install plugin' box: # ...................................................................... YToxMTp7czoxNToiYWxsb3dfaHRtbF9oZWxwIjtpOjA7czo3OiJ2ZXJzaW9uIjtzOjM6IjIu MSI7czo2OiJhdXRob3IiO3M6MTM6Ik5hdGhhbiBBcnRodXIiO3M6MTA6ImF1dGhvcl91cmki O3M6MjI6Imh0dHA6Ly93d3cudHJ1aXN0LmNvbS8iO3M6MTE6ImRlc2NyaXB0aW9uIjtzOjMx OiJUYWdnaW5nIHN1cHBvcnQgZm9yIFRleHRwYXR0ZXJuIjtzOjQ6InR5cGUiO2k6MTtzOjQ6 Im5hbWUiO3M6ODoidHJ1X3RhZ3MiO3M6NDoiaGVscCI7czo1Njg6Igk8cD5UbyBsZWFybiBt b3JlIGFib3V0IHRydV90YWdzLCBjaGVjayBvdXQgdGhlIDxhIGhyZWY9Ii9ibG9nLzQ5My90 cnV0YWdzLWEtdGFnZ2luZy1wbHVnaW4tZm9yLXRleHRwYXR0ZXJuIj5pbnRyb2R1Y3Rvcnkg YXJ0aWNsZTwvYT4sIDxhIGhyZWY9Imh0dHA6Ly93d3cudHJ1aXN0LmNvbS9yZWZlcmVuY2Uv NTM3L3RydV90YWdzLXJlbGVhc2VzIj5yZWxlYXNlcyBwYWdlPC9hPiwgPGEgaHJlZj0iaHR0 cDovL3d3dy50cnVpc3QuY29tL3JlZmVyZW5jZS80OTUvdHJ1dGFncy1mZWF0dXJlLWxpc3Qi PmZlYXR1cmUgbGlzdDwvYT4sIGFuZCA8YSBocmVmPSJodHRwOi8vd3d3LnRydWlzdC5jb20v cmVmZXJlbmNlLzQ5Ny90cnV0YWdzLXVzYWdlLWluc3RydWN0aW9ucyI+dXNhZ2UgaW5zdHJ1 Y3Rpb25zPC9hPi48L3A+CgoJPHA+SSYjODIxNzt2ZSB0YWtlbiB0aGUgZGV0YWlsZWQgaGVs cCBvdXQgb2YgdGhlIHBsdWdpbjsgbXkgYXBvbG9naWVzLiAgSXQgd2FzIHRvbyBiaWcgYW5k IHRvbyBkaWZmaWN1bHQgdG8ga2VlcCBtYWludGFpbmluZyBvbiBteSBzaXRlIGFuZCBpbiB0 aGUgcGx1Z2luLjwvcD4iO3M6NDoiY29kZSI7czoxOTY5NDoiCiNDb3B5cmlnaHQgMjAwNyBO YXRoYW4gQXJ0aHVyCiNSZWxlYXNlZCB1bmRlciB0aGUgR05VIFB1YmxpYyBMaWNlbnNlLCBz ZWUgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9ncGwtbGljZW5zZS5waHAg Zm9yIGRldGFpbHMKI1RoaXMgd29yayBpcyBpbnNwaXJlZCBieSByYW5fdGFncyBieSBSYW4g QXJvdXNzaSwgb3JpZ2luYWxseSBmb3VuZCBhdCBodHRwOi8vYXJvdXNzaS5jb20vYXJ0aWNs ZS80NS90YWdnaW5nLXRleHRwYXR0ZXJuCgoKIyMjIENPTkZJR1VSQVRJT04gIyMjCiMjIyMj IyMjIyMjIyMjIyMjIyMjIwoKI1NlZSBodHRwOi8vd3d3LnRydWlzdC5jb20vcmVmZXJlbmNl LzQ5Ny90cnV0YWdzLXVzYWdlLWluc3RydWN0aW9ucyBmb3IgaW5zdHJ1Y3Rpb25zCgojIFN3 aXRjaCB0aGlzIHRvICcxJyB0byBnZXQgY2xlYW4gdXJsIHN1cHBvcnQgb3IgJzAnIHRvIHR1 cm4gaXQgb2ZmLgojIEl0IHdpbGwgcHJvYmFibHkgZmlndXJlIGl0IG91dCwgdGhvdWdoLCBz byB5b3Ugc2hvdWxkbid0IGhhdmUgdG8gY2hhbmdlIGl0LgpnbG9iYWwgJHBlcm1saW5rX21v ZGU7CmRlZmluZSgnVFJVX1RBR1NfVVNFX0NMRUFOX1VSTFMnLCAkcGVybWxpbmtfbW9kZSAh PSAnbWVzc3knKTsKCiMgVGhpcyB0ZWxscyB0cnVfdGFncyB3aGljaCBzZWN0aW9uIHRvIHVz ZSBmb3IgdGFncy4KZGVmaW5lKCdUUlVfVEFHU19TRUNUSU9OJywgJ3RhZycpOwoKIyBUaGlz IHRlbGxzIHRydV90YWdzIHdoYXQgYXR0cmlidXRlIG5hbWUgdG8gdXNlIGZvciB0YWcgc2Vh cmNoZXMuCmRlZmluZSgnVFJVX1RBR1NfVEFHX1BBUkFNRVRFUl9OQU1FJywgJ3QnKTsKCiMg VGhpcyB0ZWxscyB0cnVfdGFncyB0byBwdXQgdGFncyBpbnRvIHRoZSBSU1MgYW5kIEF0b20g ZmVlZHMsIGluICdDYXRlZ29yeScgZWxlbWVudHMuCiMgWW91IHByb2JhYmx5IHdhbnQgdGhp cy4KZGVmaW5lKCdUUlVfVEFHU19BRERfVEFHU19UT19GRUVEX1hNTCcsIDEpOwoKIyBCeSBk ZWZhdWx0LCB0aGlzIHdpbGwgYXBwZW5kIGEgdGFnIGxpc3QgbGlrZSAidGFnczogdHJlZXMs IGZsb3dlcnMsIGFuaW1hbHMsIGV0YyIKIyAod2l0aCBsaW5rcywgYW5kIHdpdGggcmVsPSJ0 YWciKSB0byB0aGUgYm9keSBvZiBSU1MvQXRvbSBmZWVkcy4gSWYgeW91IGRlZmluZSBhCiMg J21pc2MnIGZvcm0gbmFtZWQgdHJ1X3RhZ3NfZmVlZF90YWdzLCB0cnVfdGFncyB3aWxsIHVz ZSB0aGF0IGZvcm0gdG8gcmVuZGVyIHRoZSB0YWdzCiMgZm9yIHRoZSBmZWVkLCBpbnN0ZWFk LgpkZWZpbmUoJ1RSVV9UQUdTX0FERF9UQUdTX1RPX0ZFRURfQk9EWScsIDApOwoKIyBUaGlz IHNob3dzIGEgbGlzdCBvZiBjbGlja2FibGUgdGFncyBpbiB0aGUgYWRtaW4gc2lkZSBvbiB0 aGUgJ1dyaXRlJyBwYWdlCmRlZmluZSgnVFJVX1RBR1NfU0hPV19UQUdTX0lOX0FETUlOJywg MSk7CgojIENoYW5naW5nIHRoaXMgd29uJ3QgZG8gYW55IGdvb2QuICBJdCdzIGp1c3QgaGVy ZSBhcyBhIGNvbnZlbmllbmNlIGZvciBkZXZlbG9wbWVudC4KZGVmaW5lKCdUUlVfVEFHU19G SUVMRCcsICdLZXl3b3JkcycpOwoKCiMjIyBQUklNQVJZIFRBRyBGVU5DVElPTlMgIyMjCiMj IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgpmdW5jdGlvbiB0cnVfdGFnc19oYW5kbGVy KCRhdHRzKSB7CgkkdGFnX3BhcmFtZXRlciA9IHRydV90YWdzX3RhZ19wYXJhbWV0ZXIoYXJy YXkoKSwgZmFsc2UpOwoJaWYgKCFlbXB0eSgkdGFnX3BhcmFtZXRlcikpIHsKCQkkYXR0cyA9 IHRydV90YWdzX2ZpeHVwX3F1ZXJ5X2F0dHMoJGF0dHMsICR0YWdfcGFyYW1ldGVyKTsKCQly ZXR1cm4gZG9BcnRpY2xlcygkYXR0cywgdHJ1ZSk7CQkjZnVuY3Rpb24gaW4gVFhQIGNvZGUK CX0gZWxzZSB7CgkJcmV0dXJuIHRydV90YWdzX2Nsb3VkKCRhdHRzKTsKCX0KfQoKCmZ1bmN0 aW9uIHRydV90YWdzX2Nsb3VkKCRhdHRzKSB7CglyZXR1cm4gdHJ1X3RhZ3NfbGlzdCh0cnVf dGFnc19nZXRfc3RhbmRhcmRfY2xvdWRfYXR0cygkYXR0cywgZmFsc2UsIGZhbHNlKSk7Cn0K CgpmdW5jdGlvbiB0cnVfdGFnc19saXN0KCRhdHRzKSB7CgkkYXR0cyA9IHRydV90YWdzX2dl dF9zdGFuZGFyZF9jbG91ZF9hdHRzKCRhdHRzLCB0cnVlLCBmYWxzZSk7CgkkYWxsX3RhZ3Mg PSB0cnVfdGFnc19jbG91ZF9xdWVyeSgkYXR0cyk7CgoJcmV0dXJuIHRydV90YWdzX3JlbmRl cl9jbG91ZCgkYXR0cywgJGFsbF90YWdzLCAkYWxsX3RhZ3MpOwp9CgoKZnVuY3Rpb24gdHJ1 X3RhZ3NfZnJvbV9hcnRpY2xlKCRhdHRzKSB7CgkkYWxsX3RhZ3MgPSB0cnVfdGFnc19nZXRf dGFnc19mb3JfYXJ0aWNsZSgpOwoKCSRhdHRzID0gdHJ1X3RhZ3NfZ2V0X3N0YW5kYXJkX2Ns b3VkX2F0dHMoJGF0dHMsIGZhbHNlLCB0cnVlKTsKCSRhbGxfdGFnc19mb3Jfd2VpZ2h0ID0g JGFsbF90YWdzOwoJaWYgKCRhdHRzWyd1c2VvdmVyYWxsY291bnRzJ10pIHsKCQkkYWxsX3Rh Z3NfZm9yX3dlaWdodCA9IHRydV90YWdzX2Nsb3VkX3F1ZXJ5KCRhdHRzKTsKCX0KCglyZXR1 cm4gdHJ1X3RhZ3NfcmVuZGVyX2Nsb3VkKCRhdHRzLCAkYWxsX3RhZ3MsICRhbGxfdGFnc19m b3Jfd2VpZ2h0KTsKfQoKCmZ1bmN0aW9uIHRydV90YWdzX2lmX2hhc190YWdzKCRhdHRzLCAk dGhpbmcpIHsKCWdsb2JhbCAkdGhpc2FydGljbGU7CglleHRyYWN0KCR0aGlzYXJ0aWNsZSk7 CgoJJHRhZ3NfZmllbGQgPSBUUlVfVEFHU19GSUVMRDsKCgkkcnMgPSBzYWZlX3JvdygkdGFn c19maWVsZCwgInRleHRwYXR0ZXJuIiwgIklEPSckdGhpc2lkJyBBTkQgJHRhZ3NfZmllbGQg PD4gJyciKTsKCXJldHVybiBwYXJzZShFdmFsRWxzZSgkdGhpbmcsICRycykpOwp9CgoKZnVu Y3Rpb24gdHJ1X3RhZ3NfaWZfdGFnX3NlYXJjaCgkYXR0cywgJHRoaW5nKQp7CgkkdGFnX3Bh cmFtZXRlciA9IHRydV90YWdzX3RhZ19wYXJhbWV0ZXIoYXJyYXkoKSwgZmFsc2UpOwoJJGNv bmRpdGlvbiA9ICghZW1wdHkoJHRhZ19wYXJhbWV0ZXIpKSA/IHRydWUgOiBmYWxzZTsKCXJl dHVybiBwYXJzZShFdmFsRWxzZSgkdGhpbmcsICRjb25kaXRpb24pKTsKfQoKCmZ1bmN0aW9u IHRydV90YWdzX3RhZ19wYXJhbWV0ZXIoJGF0dHMsICRzYWZlaHRtbCA9IHRydWUpCnsKCWV4 dHJhY3QobEF0dHMoYXJyYXkoJ3N0cmlwaHlwaGVucycgPT4gMCwgJ3VybGVuY29kZScgPT4g MCksICAkYXR0cywgMCkpOwoKCSRwYXJtID0gdXJsZGVjb2RlKHN0cmlwX3RhZ3MoZ3BzKFRS VV9UQUdTX1RBR19QQVJBTUVURVJfTkFNRSkpKTsKCSRwYXJtID0gKCRzdHJpcGh5cGhlbnMg PyBzdHJfcmVwbGFjZSgnLScsICcgJywgJHBhcm0pIDogJHBhcm0pOwoJaWYgKCR1cmxlbmNv ZGUpIHsKCQkkcGFybSA9IHVybGVuY29kZSgkcGFybSk7CgkgfSBlbHNlIGlmICgkc2FmZWh0 bWwpIHsKCQkkcGFybSA9IGh0bWxzcGVjaWFsY2hhcnMoJHBhcm0pOwoJfQoKCXJldHVybiAk cGFybTsKfQoKCmZ1bmN0aW9uIHRydV90YWdzX3NlYXJjaF9wYXJhbWV0ZXIoKQp7CglyZXR1 cm4gc3RyaXBfdGFncyhncHMoJ3EnKSk7Cn0KCgpmdW5jdGlvbiB0cnVfdGFnc19yZWxhdGVk X3RhZ3NfZnJvbV9zZWFyY2goJGF0dHMpIHsKCSR0YWdfcGFyYW1ldGVyID0gdHJ1X3RhZ3Nf dGFnX3BhcmFtZXRlcihhcnJheSgpLCBmYWxzZSk7CglpZiAoIWVtcHR5KCR0YWdfcGFyYW1l dGVyKSkgewoJICAgICAgICAkdGFnc19maWVsZCA9IFRSVV9UQUdTX0ZJRUxEOwoJCSRhbGxf dGFncyA9IGFycmF5KCk7CgoJCSRxdWVyeV9hdHRzID0gdHJ1X3RhZ3NfZml4dXBfcXVlcnlf YXR0cygkYXR0cywgJHRhZ19wYXJhbWV0ZXIpOwoJCSRycyA9IHRydV90YWdzX3JlZG9fYXJ0 aWNsZV9zZWFyY2goJHF1ZXJ5X2F0dHMpOwoJCWlmICgkcnMpIHsKCQkJd2hpbGUgKCRhID0g bmV4dFJvdygkcnMpKSB7CgkJCQkkYXJ0aWNsZV90YWdzID0gZXhwbG9kZSgiLCIsIHRyaW0o dHJ1X3RhZ3Nfc3RydG9sb3dlcigkYVskdGFnc19maWVsZF0pKSk7CgkJCQkkYWxsX3RhZ3Mg PSBhcnJheV9tZXJnZSgkYWxsX3RhZ3MsIHRydV90YWdzX3RyaW1fdGFncygkYXJ0aWNsZV90 YWdzKSk7CgkJCX0KCQl9CgoJCSRhbHRfdGFnX3BhcmFtZXRlciA9IHN0cl9yZXBsYWNlKCct JywgJyAnLCAkdGFnX3BhcmFtZXRlcik7CgkJZm9yZWFjaCAoJGFsbF90YWdzIGFzICRrZXkg PT4gJHRhZykgewoJCQlpZiAoJHRhZyA9PSAkdGFnX3BhcmFtZXRlciB8fCAkdGFnID09ICRh bHRfdGFnX3BhcmFtZXRlcikgewoJCQkJdW5zZXQoJGFsbF90YWdzWyRrZXldKTsKCQkJfQoJ CX0KCgkJJGNsb3VkX2F0dHMgPSB0cnVfdGFnc19nZXRfc3RhbmRhcmRfY2xvdWRfYXR0cygk YXR0cywgZmFsc2UsIGZhbHNlKTsKCQkkYWxsX3RhZ3NfZm9yX3dlaWdodCA9ICRhbGxfdGFn czsKCQlpZiAoJGNsb3VkX2F0dHNbJ3VzZW92ZXJhbGxjb3VudHMnXSkgewoJCQkkYWxsX3Rh Z3NfZm9yX3dlaWdodCA9IHRydV90YWdzX2Nsb3VkX3F1ZXJ5KCRjbG91ZF9hdHRzKTsKCQl9 CgoJCXJldHVybiB0cnVfdGFnc19yZW5kZXJfY2xvdWQoJGNsb3VkX2F0dHMsICRhbGxfdGFn cywgJGFsbF90YWdzX2Zvcl93ZWlnaHQpOwoJfSBlbHNlIHsKCQlyZXR1cm4gJyc7Cgl9Cn0K CgojIyMgQ0xPVUQgU1VQUE9SVCBGVU5DVElPTlMgIyMjCiMjIyMjIyMjIyMjIyMjIyMjIyMj IyMjIyMjIyMjIyMKCmZ1bmN0aW9uIHRydV90YWdzX2dldF9zdGFuZGFyZF9jbG91ZF9hdHRz KCRhdHRzLCAkaXNMaXN0LCAkaXNBcnRpY2xlKSB7CglyZXR1cm4gbEF0dHMoYXJyYXkoJ3dy YXB0YWcnCT0+ICgkaXNMaXN0ID8gJ3VsJyA6ICcnKSwKCQkJJ2JyZWFrJwkJPT4gKCRpc0xp c3QgPyAnbGknIDogJywgJyksCgkJCSdjbGFzcycJCT0+ICcnLAoJCQknYnJlYWtjbGFzcycJ PT4gJycsCgkJCSdzZWN0aW9uJwk9PiAnJywKCQkJJ21pbnBlcmNlbnQnCT0+ICcxMDAnLAoJ CQknbWF4cGVyY2VudCcJPT4gKCRpc0xpc3QgfHwgJGlzQXJ0aWNsZSA/ICcxMDAnIDogJzIw MCcpLAoJCQknc2hvd2NvdW50cycJPT4gJycsCgkJCSdjb3VudHdyYXBjaGFycycJPT4gJ1td JywKCQkJJ3VzZXJlbHRhZycJPT4gKCRpc0FydGljbGUgPyAnMScgOiAnJyksCgkJCSdnZW5l cmF0ZWxpbmtzJwk9PiAnMScsCgkJCSdtaW50YWdjb3VudCcJPT4gJzAnLAoJCQknbWF4dGFn Y291bnQnCT0+ICcxMDAwJywKCQkJJ3NldHNpemVzJwk9PiAoJGlzQXJ0aWNsZSA/ICcwJyA6 ICcxJyksCgkJCSd1c2Vub2ZvbGxvdycJPT4gJycsCgkJCSdzb3J0JwkJPT4gJ2FscGhhJywK CQkJJ3VzZW92ZXJhbGxjb3VudHMnCT0+ICcnLAoJCQknc2V0Y2xhc3NlcycJPT4gKCRpc0Fy dGljbGUgPyAnMCcgOiAnMScpLAoJCQkndGl0bGUnCQk9PiAnJywKCQkJJ2xpc3RsaW1pdCcJ PT4gJycsCgkJCSdrZWVwJwkJPT4gJ2xhcmdlc3QnLAoJCQknY3V0b2ZmJwk9PiAnY2h1bmsn LAoJCQkndGV4dHRyYW5zZm9ybScJPT4gJ25vbmUnLAoJCQknbGlua3BhdGgnCT0+ICcnLAoJ CQknbGlua3BhdGh0YWlsJwk9PiAnJywKCQkJJ2ZpbHRlcnNlYXJjaCcJPT4gJzEnLAoJCQkn ZXhjbHVkZXNlY3Rpb24nPT4gJycKCQkpLCRhdHRzLCAwKTsKfQoKCmZ1bmN0aW9uIHRydV90 YWdzX2Nsb3VkX3F1ZXJ5KCRhdHRzKSB7CglleHRyYWN0KCRhdHRzKTsKCgkkc2VjdGlvbl9j bGF1c2UgPSAnJzsKCWlmICgkc2VjdGlvbiA8PiAnJykgewoJCSRrZXlzID0gc3BsaXQoJywn LCAkc2VjdGlvbik7CgkJZm9yZWFjaCAoJGtleXMgYXMgJGtleSkgewoJCQkka2V5cGFydHNb XSA9ICIgU2VjdGlvbiA9ICciIC4gdHJpbSgka2V5KSAuICInIjsKCQl9CgkJJHNlY3Rpb25f Y2xhdXNlID0gIiBBTkQgKCIgLiBqb2luKCcgb3IgJywgJGtleXBhcnRzKSAuICIpIjsKCX0K CgkkdGFnc19maWVsZCA9IFRSVV9UQUdTX0ZJRUxEOwoJaW5jbHVkZV9vbmNlIHR4cGF0aC4n L3B1Ymxpc2gvc2VhcmNoLnBocCc7CgoJJGZpbHRlciA9IHRydV90YWdzX2ZpbHRlcl9zZWN0 aW9ucygkZXhjbHVkZXNlY3Rpb24pOwoJJGZpbHRlciAuPSAoJGZpbHRlcnNlYXJjaCA/IGZp bHRlclNlYXJjaCgpIDogJycpOwoKCSRhbGxfdGFncyA9IGFycmF5KCk7CgkkcnMgPSBzYWZl X3Jvd3MoIiR0YWdzX2ZpZWxkIiwgInRleHRwYXR0ZXJuIiwgIiR0YWdzX2ZpZWxkIDw+ICcn IiAuICRzZWN0aW9uX2NsYXVzZSAuICRmaWx0ZXIgLiAiIGFuZCBTdGF0dXMgPj0gJzQnIGFu ZCBQb3N0ZWQgPCBub3coKSIpOwoJZm9yZWFjaCAoJHJzIGFzICRyb3cpIHsKCQkkdGVtcF9h cnJheSA9IGV4cGxvZGUoIiwiLCB0cmltKHRydV90YWdzX3N0cnRvbG93ZXIoJHJvd1skdGFn c19maWVsZF0pKSk7CgkJJGFsbF90YWdzID0gYXJyYXlfbWVyZ2UoJGFsbF90YWdzLCB0cnVf dGFnc190cmltX3RhZ3MoJHRlbXBfYXJyYXkpKTsKCX0KCglyZXR1cm4gJGFsbF90YWdzOwp9 CgoKZnVuY3Rpb24gdHJ1X3RhZ3NfZmlsdGVyX3NlY3Rpb25zKCRleGNsdWRlc2VjdGlvbikg ewoJJHNlY3Rpb25zID0gZXhwbG9kZSgnLCcsICRleGNsdWRlc2VjdGlvbik7CgkkZmlsdGVy cyA9IGFycmF5KCk7Cglmb3JlYWNoICgkc2VjdGlvbnMgYXMgJHNlY3Rpb24pIHsKCQkkZmls dGVyc1tdID0gImFuZCBTZWN0aW9uICE9ICciLmRvU2xhc2goJHNlY3Rpb24pLiInIjsKCX0K CXJldHVybiBqb2luKCcgJywgJGZpbHRlcnMpOwp9CgoKZnVuY3Rpb24gdHJ1X3RhZ3NfcmVu ZGVyX2Nsb3VkKCRhdHRzLCAkYWxsX3RhZ3MsICRhbGxfdGFnc19mb3Jfd2VpZ2h0KSB7Cgll eHRyYWN0KCRhdHRzKTsKCgkkdGFnc193ZWlnaHQgPSBhcnJheV9jb3VudF92YWx1ZXMoJGFs bF90YWdzX2Zvcl93ZWlnaHQpOwoKCWZvcmVhY2ggKCR0YWdzX3dlaWdodCBhcyAkdGFnID0+ ICR3ZWlnaHQpIHsKCQlpZiAoIWluX2FycmF5KCR0YWcsICRhbGxfdGFncykKCQkgICB8fCAk dGFnc193ZWlnaHRbJHRhZ10gPCAkbWludGFnY291bnQKCQkgICB8fCAkdGFnc193ZWlnaHRb JHRhZ10gPiAkbWF4dGFnY291bnQpIHsKCQkJdW5zZXQoJHRhZ3Nfd2VpZ2h0WyR0YWddKTsK CQl9Cgl9CgoJJHNvcnRfYnlfY291bnQgPSAoc3RycG9zKCRzb3J0LCAnY291bnQnKSAhPT0g ZmFsc2UpOwoJJHNvcnRfYXNjZW5kaW5nID0gKHN0cnBvcygkc29ydCwgJ2FzYycpICE9PSBm YWxzZSk7CgkkdGFnc193ZWlnaHQgPSB0cnVfdGFnc19zb3J0X3RhZ3MoJHRhZ3Nfd2VpZ2h0 LCAkc29ydF9ieV9jb3VudCwgJHNvcnRfYXNjZW5kaW5nKTsKCglpZiAoJGxpc3RsaW1pdCA+ IDAgJiYgJGxpc3RsaW1pdCA8IGNvdW50KCR0YWdzX3dlaWdodCkpIHsKCQkkcmVzb3J0ZWRf dGFncyA9IGFycmF5KCk7CgkJaWYgKCRrZWVwID09ICdsYXJnZXN0JykgewoJCQkkcmVzb3J0 ZWRfdGFncyA9IGFycmF5X2tleXModHJ1X3RhZ3Nfc29ydF90YWdzKCR0YWdzX3dlaWdodCwg dHJ1ZSwgZmFsc2UpKTsKCQl9IGVsc2UgewoJCQlpZiAoJGtlZXAgPT0gJ3JhbmRvbScpIHsK CQkJCWZvcmVhY2ggKCR0YWdzX3dlaWdodCBhcyAkdGFnID0+ICR3ZWlnaHQpIHsKCQkJCQkk cmVzb3J0ZWRfdGFnc1skdGFnXSA9IHJhbmQoMCwgJHdlaWdodCk7CgkJCQl9CgkJCQkkcmVz b3J0ZWRfdGFncyA9IGFycmF5X2tleXModHJ1X3RhZ3Nfc29ydF90YWdzKCRyZXNvcnRlZF90 YWdzLCB0cnVlLCBmYWxzZSkpOwoJCQl9IGVsc2UgaWYgKCRrZWVwID09ICdhbHBoYScpIHsK CQkJCSRyZXNvcnRlZF90YWdzID0gYXJyYXlfa2V5cygkdGFnc193ZWlnaHQpOwoJCQkJbmF0 Y2FzZXNvcnQoJHJlc29ydGVkX3RhZ3MpOwoJCQl9CgkJCSRjdXRvZmYgPSAnZXhhY3QnOwoJ CX0KCgkJJGxhc3RfZ29vZF9pbmRleCA9ICRsaXN0bGltaXQgLSAxOwoJCWlmICgkY3V0b2Zm ID09ICdjaHVuaycpIHsgLy9hbHRlcm5hdGl2ZSBpcyAnZXhhY3QnCgkJCSRsYXN0X3dlaWdo dCA9IC0xOwoJCQlmb3IgKCRpID0gMDsgJGkgPCAkbGlzdGxpbWl0ICsgMTsgJGkrKykgewoJ CQkJJG5ld193ZWlnaHQgPSAkdGFnc193ZWlnaHRbJHJlc29ydGVkX3RhZ3NbJGldXTsKCQkJ CWlmICgkbmV3X3dlaWdodCAhPSAkbGFzdF93ZWlnaHQpIHsKCQkJCQkkbGFzdF9nb29kX2lu ZGV4ID0gJGkgLSAxOwoJCQkJCSRsYXN0X3dlaWdodCA9ICRuZXdfd2VpZ2h0OwoJCQkJfQoJ CQl9CgkJCWlmICgkbGFzdF9nb29kX2luZGV4IDwgMCkgewoJCQkJJGxhc3RfZ29vZF9pbmRl eCA9ICRsaXN0bGltaXQgLSAxOwoJCQl9CgkJfQoKCQkkcmVzb3J0ZWRfdGFncyA9IGFycmF5 X2NodW5rKCRyZXNvcnRlZF90YWdzLCAkbGFzdF9nb29kX2luZGV4ICsgMSk7CgkJJHJlc29y dGVkX3RhZ3MgPSAkcmVzb3J0ZWRfdGFnc1swXTsKCgkJZm9yZWFjaCAoJHRhZ3Nfd2VpZ2h0 IGFzICR0YWcgPT4gJHdlaWdodCkgewoJCQlpZiAoIWluX2FycmF5KCR0YWcsICRyZXNvcnRl ZF90YWdzKSkgewoJCQkJdW5zZXQoJHRhZ3Nfd2VpZ2h0WyR0YWddKTsKCQkJfQoJCX0KCX0K CglpZiAoJGdlbmVyYXRlbGlua3MpIHsKCQlpZiAoJGxpbmtwYXRoKSB7CgkJCSR1cmxwcmVm aXggPSAkbGlua3BhdGg7CgkJCSR1cmxzdWZmaXggPSAkbGlua3BhdGh0YWlsOwoJCX0gZWxz ZSB7CgkJCWlmIChUUlVfVEFHU19VU0VfQ0xFQU5fVVJMUykgewoJCQkJJHVybHByZWZpeCA9 IGh1IC4gVFJVX1RBR1NfU0VDVElPTiAuICcvJzsKCQkJfSBlbHNlIHsKCQkJCSR1cmxwcmVm aXggPSBodSAuICc/cz0nIC4gVFJVX1RBR1NfU0VDVElPTiAuICcmYW1wO3Q9JzsKCQkJfQoJ CQkkdXJsc3VmZml4ID0gKFRSVV9UQUdTX1VTRV9DTEVBTl9VUkxTID8gJy8nIDogJycpOwoJ CX0KCgkJaWYgKCR1c2VyZWx0YWcpIHsKCQkJaWYgKCR1c2Vub2ZvbGxvdykgewoJCQkJJHVy bHN1ZmZpeCAuPSAnIiByZWw9InRhZyBub2ZvbGxvdyc7CgkJCX0gZWxzZSB7CgkJCQkkdXJs c3VmZml4IC49ICciIHJlbD0idGFnJzsKCQkJfQoJCX0gZWxzZSBpZiAoJHVzZW5vZm9sbG93 KSB7CgkJCSR1cmxzdWZmaXggLj0gJyIgcmVsPSJub2ZvbGxvdyc7CgkJfQoJfQoKCWlmIChj b3VudCgkdGFnc193ZWlnaHQpID4gMCkgewoJCSRtYXggPSBtYXgoJHRhZ3Nfd2VpZ2h0KTsK CQkkbWluID0gbWluKCR0YWdzX3dlaWdodCk7Cgl9IGVsc2UgewoJCSRtYXggPSAkbWluID0g MDsKCX0KCSRzdGVwdmFsdWUgPSAoJG1heCA9PSAkbWluKSA/IDAgOiAoJG1heHBlcmNlbnQg LSAkbWlucGVyY2VudCkgLyAoJG1heCAtICRtaW4pOwoKCWZvcmVhY2ggKCR0YWdzX3dlaWdo dCBhcyAkdGFnID0+ICR3ZWlnaHQpIHsKCQkkdGFnX3dlaWdodCA9IGZsb29yKCRtaW5wZXJj ZW50ICsgKCR3ZWlnaHQgLSAkbWluKSAqICRzdGVwdmFsdWUpOwoKCQkkc3R5bGUgPSAnJzsK CQlpZiAoJHNldHNpemVzKQoJCQkkc3R5bGUgPSAnIHN0eWxlPSJmb250LXNpemU6ICcgLiAk dGFnX3dlaWdodCAuICclOyInOwoKCQkkdGFnX2NsYXNzID0gJyc7CgkJaWYgKCRzZXRjbGFz c2VzKSB7CgkJCSR0YWdfY2xhc3MgPSAnIGNsYXNzPSInOwoJCQlpZiAoJHdlaWdodCA9PSAk bWluKQoJCQkJJHRhZ19jbGFzcyAuPSAidGFnU2l6ZVNtYWxsZXN0IjsKCQkJZWxzZSBpZiAo JHdlaWdodCA9PSAkbWF4KQoJCQkJJHRhZ19jbGFzcyAuPSAidGFnU2l6ZUxhcmdlc3QiOwoJ CQllbHNlCgkJCQkkdGFnX2NsYXNzIC49ICJ0YWdTaXplTWVkaXVtIjsKCQkJJHRhZ19jbGFz cyAuPSAnIHRhZ1NpemUnIC4gKCR3ZWlnaHQgKyAxIC0gJG1pbik7CgkJCSR0YWdfY2xhc3Mg Lj0gJyInOwoJCX0KCgkJLy9hZGFwdGVkIGZyb20gY29kZSBieSBnZHRyb2lhbm8sIHNlZSBo dHRwOi8vZm9ydW0udGV4dHBhdHRlcm4uY29tL3ZpZXd0b3BpYy5waHA/cGlkPTEwMjg3NSNw MTAyODc1CgkJJHRpdGxlY291bnQgPSAnJzsKCQlpZiAoJHRpdGxlKQoJCQkkdGl0bGVjb3Vu dCA9ICcgdGl0bGU9IicgLiAkdGl0bGUgLiAnIic7CgkJJGRpc3BsYXljb3VudD0gJyc7CgkJ JGNvdW50ID0gJGNvdW50d3JhcGNoYXJzezB9IC4gJHdlaWdodCAuICRjb3VudHdyYXBjaGFy c3sxfTsKCQlpZiAoJHNob3djb3VudHMgPT0gJ3RpdGxlJyB8fCAkc2hvd2NvdW50cyA9PSAn Ym90aCcpCgkJCSR0aXRsZWNvdW50ID0gJyB0aXRsZT0iJyAuICR0aXRsZSAuICRjb3VudCAu ICciJzsKCQlpZiAoJHNob3djb3VudHMgJiYgJHNob3djb3VudHMgIT0gJ3RpdGxlJykKCQkJ JGRpc3BsYXljb3VudCA9ICcgJyAuICRjb3VudDsKCgkJaWYgKCR0ZXh0dHJhbnNmb3JtID09 ICdjYXBpdGFsaXplJykgewoJCQkkdGFnID0gdWN3b3JkcygkdGFnKTsKCQl9IGVsc2UgaWYg KCR0ZXh0dHJhbnNmb3JtID09ICd1cHBlcmNhc2UnKSB7CgkJCSR0YWcgPSBzdHJ0b3VwcGVy KCR0YWcpOwoJCX0gZWxzZSBpZiAoJHRleHR0cmFuc2Zvcm0gPT0gJ2xvd2VyY2FzZScpIHsK CQkJJHRhZyA9IHN0cnRvbG93ZXIoJHRhZyk7CgkJfSBlbHNlIGlmICgkdGV4dHRyYW5zZm9y bSA9PSAnY2FwZmlyc3QnKSB7CgkJCSR0YWcgPSB1Y2ZpcnN0KCR0YWcpOwoJCX0KCgkJaWYg KCRnZW5lcmF0ZWxpbmtzKSB7CgkJCSR3aG9sZXVybCA9ICciJyAuICR1cmxwcmVmaXggLiB1 cmxlbmNvZGUoc3RyX3JlcGxhY2UoJyAnLCAnLScsICR0YWcpKSAuICR1cmxzdWZmaXggLiAn Iic7CgkJCSR0YWdzX2h0bWxbXSA9ICc8YSBocmVmPScgLiAkd2hvbGV1cmwgLiAkdGFnX2Ns YXNzIC4gJHN0eWxlIC4gJHRpdGxlY291bnQgLiAnPicgLiBodG1sc3BlY2lhbGNoYXJzKCR0 YWcpIC4gJzwvYT4nIC4gJGRpc3BsYXljb3VudDsKCQl9IGVsc2UgaWYgKCR0YWdfY2xhc3Mg fHwgJHN0eWxlIHx8ICR0aXRsZWNvdW50KSB7CgkJCSR0YWdzX2h0bWxbXSA9ICc8c3Bhbicg LiAkdGFnX2NsYXNzIC4gJHN0eWxlIC4gJHRpdGxlY291bnQgLiAnPicgLiAkdGFnIC4gJzwv c3Bhbj4nIC4gJGRpc3BsYXljb3VudDsKCQl9IGVsc2UgewoJCQkkdGFnc19odG1sW10gPSAk dGFnIC4gJGRpc3BsYXljb3VudDsKCQl9Cgl9CglyZXR1cm4gdHJ1X3RhZ3NfZG9fd3JhcCgk dGFnc19odG1sLCAkd3JhcHRhZywgJGJyZWFrLCAkY2xhc3MsICRicmVha2NsYXNzKTsKfQoK CiMjIyBDTEVBTiBVUkwgRlVOQ1RJT05TICMjIwojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj IyMKCmlmIChUUlVfVEFHU19VU0VfQ0xFQU5fVVJMUykgewoJcmVnaXN0ZXJfY2FsbGJhY2so J3RydV90YWdzX2NsZWFuX3VybF9oYW5kbGVyJywgJ3ByZXRleHQnKTsKfQoKZnVuY3Rpb24g dHJ1X3RhZ3NfY2xlYW5fdXJsX2hhbmRsZXIoJGV2ZW50LCAkc3RlcCkgewoJJHN1YnBhdGgg PSBwcmVnX3F1b3RlKHByZWdfcmVwbGFjZSgiL2h0dHBzPzpcL1wvLiooXC8uKikvVWkiLCIk MSIsaHUpLCcvJyk7CgkkcmVxID0gcHJlZ19yZXBsYWNlKCIvXiRzdWJwYXRoL2kiLCcvJywk X1NFUlZFUlsnUkVRVUVTVF9VUkknXSk7CgoJJHFzID0gc3RycG9zKCRyZXEsICc/Jyk7Cgkk cWF0dHMgPSAoJHFzID8gJyYnLnN1YnN0cigkcmVxLCAkcXMgKyAxKSA6ICcnKTsKCWlmICgk cXMpICRyZXEgPSBzdWJzdHIoJHJlcSwgMCwgJHFzKTsKCgkkcGFydHMgPSBhcnJheV92YWx1 ZXMoYXJyYXlfZmlsdGVyKHNwbGl0KCcvJywgJHJlcSkpKTsKCWlmIChjb3VudCgkcGFydHMp ID09IDIgJiYgJHBhcnRzWzBdID09IFRSVV9UQUdTX1NFQ1RJT04pIHsKCQkkdGFnID0gJHBh cnRzWzFdOwoJCSRfU0VSVkVSWydRVUVSWV9TVFJJTkcnXSA9IFRSVV9UQUdTX1RBR19QQVJB TUVURVJfTkFNRSAuICc9JyAuICR0YWcgLiAkcWF0dHM7CgkJLy8kX1NFUlZFUlsnUkVRVUVT VF9VUkknXSA9ICRzdWJwYXRoIC4gVFJVX1RBR1NfU0VDVElPTiAuICcvPycgLiAkX1NFUlZF UlsnUVVFUllfU1RSSU5HJ107CgkJJF9TRVJWRVJbJ1JFUVVFU1RfVVJJJ10gPSAkc3VicGF0 aCAuIFRSVV9UQUdTX1NFQ1RJT04gLiAnLz8nIC4gJF9TRVJWRVJbJ1FVRVJZX1NUUklORydd OwoJCWlmIChjb3VudCgkX1BPU1QpID4gMCkgewoJCQkkX1BPU1RbJ3NlY3Rpb24nXSA9IFRS VV9UQUdTX1NFQ1RJT047CgkJCSRfUE9TVFtUUlVfVEFHU19UQUdfUEFSQU1FVEVSX05BTUVd ID0gJHRhZzsKCQl9IGVsc2UgewoJCQkkX0dFVFsnc2VjdGlvbiddID0gVFJVX1RBR1NfU0VD VElPTjsKCQkJJF9HRVRbVFJVX1RBR1NfVEFHX1BBUkFNRVRFUl9OQU1FXSA9ICR0YWc7CgkJ fQoJfQp9CgoKIyMjIEFETUlOIFNJREUgRlVOQ1RJT05TICMjIwojIyMjIyMjIyMjIyMjIyMj IyMjIyMjIyMjIyMjCgppZiAoVFJVX1RBR1NfU0hPV19UQUdTX0lOX0FETUlOKQoJcmVnaXN0 ZXJfY2FsbGJhY2soJ3RydV90YWdzX2FkbWluX2hhbmRsZXInLCAnYXJ0aWNsZScpOwoKZnVu Y3Rpb24gdHJ1X3RhZ3NfYWRtaW5faGFuZGxlcigkZXZlbnQsICRzdGVwKSB7CgkkY2xvdWQg PSBhcnJheV91bmlxdWUodHJ1X3RhZ3NfY2xvdWRfcXVlcnkodHJ1X3RhZ3NfZ2V0X3N0YW5k YXJkX2Nsb3VkX2F0dHMoYXJyYXkoKSwgdHJ1ZSwgdHJ1ZSkpKTsKCXNvcnQoJGNsb3VkKTsK CSRsaW5rcyA9IGFycmF5KCk7Cglmb3JlYWNoICgkY2xvdWQgYXMgJHRhZykgewoJCSRsaW5r c1tdID0gJzxhIGhyZWY9IiNhZHZhbmNlZCIgb25jbGljaz0iYWRkVGFnKFxcXCcnLiR0YWcu J1xcXCcpOyByZXR1cm4gZmFsc2U7Ij4nIC4gaHRtbHNwZWNpYWxjaGFycygkdGFnKSAuICc8 XC9hPic7Cgl9CgkkdG9faW5zZXJ0ID0gam9pbignLCAnLCAkbGlua3MpOwoKCSRqcyA9IDw8 PEVPRgp2YXIga2V5d29yZHNGaWVsZCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdrZXl3 b3JkcycpOwp2YXIgcGFyZW50ID0ga2V5d29yZHNGaWVsZC5wYXJlbnROb2RlOwpwYXJlbnQu YXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYnInKSk7CnZhciBjbG91ZCA9 IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTsKY2xvdWQuc2V0QXR0cmlidXRlKCdj bGFzcycsICd0cnVfdGFnc19hZG1pbl90YWdzJyk7CmNsb3VkLmlubmVySFRNTCA9ICd7JHRv X2luc2VydH0nOwpwYXJlbnQuYXBwZW5kQ2hpbGQoY2xvdWQpOwoKZnVuY3Rpb24gYWRkVGFn KHRhZ05hbWUpIHsKCXZhciB0ZXh0YXJlYSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdr ZXl3b3JkcycpOwoJdmFyIGN1cnZhbCA9IHRleHRhcmVhLnZhbHVlLnJlcGxhY2UoL1xzKyQv LCAnJyk7CglpZiAoJycgPT0gY3VydmFsKQoJCXRleHRhcmVhLnZhbHVlID0gdGFnTmFtZTsK CWVsc2UgaWYgKCcsJyA9PSBjdXJ2YWwuY2hhckF0KGN1cnZhbC5sZW5ndGggLSAxKSkKCQl0 ZXh0YXJlYS52YWx1ZSArPSAnICcgKyB0YWdOYW1lOwoJZWxzZQoJCXRleHRhcmVhLnZhbHVl ICs9ICcsICcgKyB0YWdOYW1lOwp9CkVPRjsKCgllY2hvIHNjcmlwdF9qcygkanMpOwp9CgoK IyMjIEFUT00vUlNTIEZFRUQgRlVOQ1RJT05TICMjIwojIyMjIyMjIyMjIyMjIyMjIyMjIyMj IyMjIyMjIyMjCgpyZWdpc3Rlcl9jYWxsYmFjaygndHJ1X3RhZ3NfYXRvbV9oYW5kbGVyJywg J2F0b21fZW50cnknKTsKZnVuY3Rpb24gdHJ1X3RhZ3NfYXRvbV9oYW5kbGVyKCRldmVudCwg JHN0ZXApIHsgcmV0dXJuIHRydV90YWdzX2ZlZWRfaGFuZGxlcih0cnVlKTsgfQpyZWdpc3Rl cl9jYWxsYmFjaygndHJ1X3RhZ3NfcnNzX2hhbmRsZXInLCAncnNzX2VudHJ5Jyk7CmZ1bmN0 aW9uIHRydV90YWdzX3Jzc19oYW5kbGVyKCRldmVudCwgJHN0ZXApIHsgcmV0dXJuIHRydV90 YWdzX2ZlZWRfaGFuZGxlcihmYWxzZSk7IH0KCmZ1bmN0aW9uIHRydV90YWdzX2ZlZWRfaGFu ZGxlcigkYXRvbSkgewoJJHRhZ3MgPSB0cnVfdGFnc19nZXRfdGFnc19mb3JfYXJ0aWNsZSgp OwoKCWlmIChUUlVfVEFHU19BRERfVEFHU19UT19GRUVEX0JPRFkpIHsKCQkkZXh0cmFib2R5 ID0gJyc7CgkJJEZPUk1fTkFNRSA9ICd0cnVfdGFnc19mZWVkX3RhZ3MnOwoJCWlmIChmZXRj aCgnZm9ybScsICd0eHBfZm9ybScsICduYW1lJywgJEZPUk1fTkFNRSkpIHsKCQkJJGZvcm0g PSBmZXRjaF9mb3JtKCRGT1JNX05BTUUpOwoJCQkkZXh0cmFib2R5ID0gdHJpbShwYXJzZSgk Zm9ybSkpOwoJCX0gZWxzZSB7CgkJCSRhdHRzID0gdHJ1X3RhZ3NfZ2V0X3N0YW5kYXJkX2Ns b3VkX2F0dHMoYXJyYXkoKSwgZmFsc2UsIHRydWUpOwoJCQkkZXh0cmFib2R5ID0gJzxwPnRh Z3M6ICcgLiB0cnVfdGFnc19yZW5kZXJfY2xvdWQoJGF0dHMsICR0YWdzLCAkdGFncykgLiAn PC9wPic7CgkJfQoJCWdsb2JhbCAkdGhpc2FydGljbGU7CgkJaWYgKHRyaW0oJHRoaXNhcnRp Y2xlWydleGNlcnB0J10pKSB7CgkJCSR0aGlzYXJ0aWNsZVsnZXhjZXJwdCddID0gdHJpbSgk dGhpc2FydGljbGVbJ2V4Y2VycHQnXSkubi4kZXh0cmFib2R5Lm47CgkJfQoJCSR0aGlzYXJ0 aWNsZVsnYm9keSddID0gdHJpbSgkdGhpc2FydGljbGVbJ2JvZHknXSkubi4kZXh0cmFib2R5 Lm47Cgl9CgoJaWYgKFRSVV9UQUdTX0FERF9UQUdTX1RPX0ZFRURfWE1MKSB7CgkJJG91dHB1 dCA9IGFycmF5KCk7CgkJZm9yZWFjaCAoJHRhZ3MgYXMgJHRhZykgewoJCQlpZiAoJGF0b20p IHsKCQkJCSRvdXRwdXRbXSA9ICc8Y2F0ZWdvcnkgdGVybT0iJyAuIGh0bWxzcGVjaWFsY2hh cnMoJHRhZykgLiAnIiAvPic7CgkJCX0gZWxzZSB7CgkJCQkkb3V0cHV0W10gPSAnPGNhdGVn b3J5PicgLiBodG1sc3BlY2lhbGNoYXJzKCR0YWcpIC4gJzwvY2F0ZWdvcnk+JzsKCQkJfQoJ CX0KCQlyZXR1cm4gbi5qb2luKG4sICRvdXRwdXQpLm47Cgl9Cn0KCgojIyMgT1RIRVIgU1VQ UE9SVCBGVU5DVElPTlMgIyMjCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCmZ1 bmN0aW9uIHRydV90YWdzX2dldF90YWdzX2Zvcl9hcnRpY2xlKCkgewoJZ2xvYmFsICR0aGlz YXJ0aWNsZTsKCWV4dHJhY3QoJHRoaXNhcnRpY2xlKTsKCgkkdGFnc19maWVsZCA9IFRSVV9U QUdTX0ZJRUxEOwoJJHJzID0gc2FmZV9yb3coJHRhZ3NfZmllbGQsICJ0ZXh0cGF0dGVybiIs ICJJRD0nJHRoaXNpZCcgQU5EICR0YWdzX2ZpZWxkIDw+ICcnIik7CgkkYWxsX3RhZ3MgPSBl eHBsb2RlKCIsIiwgdHJpbSh0cnVfdGFnc19zdHJ0b2xvd2VyKCRyc1skdGFnc19maWVsZF0p KSk7CgoJcmV0dXJuIHRydV90YWdzX3RyaW1fdGFncygkYWxsX3RhZ3MpOwp9CgoKIyBmaXhl cyBidWcgd2l0aCA0LjAuNCdzIHZlcnNpb24gb2YgZG9XcmFwIHRoYXQgY2F1c2VkIHNwYWNl cyB0byBzaG93IHVwIGJlZm9yZSB0aGUgY29tbWFzCmZ1bmN0aW9uIHRydV90YWdzX2RvX3dy YXAoJGxpc3QsICR3cmFwdGFnLCAkYnJlYWssICRjbGFzcywgJGJyZWFrY2xhc3MpIHsKCWlm ICghJHdyYXB0YWcgJiYgIXByZWdfbWF0Y2goJy9eXHcrJC8nLCAkYnJlYWspKSB7CgkJcmV0 dXJuIGpvaW4oJGJyZWFrLm4sICRsaXN0KTsKCX0gZWxzZSB7CgkJcmV0dXJuIGRvV3JhcCgk bGlzdCwgJHdyYXB0YWcsICRicmVhaywgJGNsYXNzLCAkYnJlYWtjbGFzcyk7Cgl9Cn0KCgpm dW5jdGlvbiB0cnVfdGFnc190cmltX3RhZ3MoJHRhZ19hcnJheSkgewoJJHRyaW1tZWQgPSBh cnJheSgpOwoJZm9yZWFjaCAoJHRhZ19hcnJheSBhcyAkdGFnKSB7CgkJaWYgKCIiICE9IHRy aW0oJHRhZykpIHsKCQkJJHRyaW1tZWRbXSA9IHRyaW0oJHRhZyk7CgkJfQoJfQoJcmV0dXJu ICR0cmltbWVkOwp9CgoKZnVuY3Rpb24gdHJ1X3RhZ3NfZml4dXBfcXVlcnlfYXR0cygkYXR0 cywgJHRhZ19wYXJhbWV0ZXIpIHsKCSRrZXl3b3JkcyA9IGV4cGxvZGUoJywnLCAkdGFnX3Bh cmFtZXRlcik7Cglmb3JlYWNoICgka2V5d29yZHMgYXMgJGtleXdvcmQpIHsKCQlpZiAoc3Ry cG9zKCRrZXl3b3JkLCAnLScpICE9PSBmYWxzZSkgewoJCQkka2V5d29yZHNbXSA9IHN0cl9y ZXBsYWNlKCctJywgJyAnLCAka2V5d29yZCk7CgkJfQoJfQoJJGF0dHNbJ2tleXdvcmRzJ10g PSBpbXBsb2RlKCcsJywgJGtleXdvcmRzKTsKCglpZiAoaXNzZXQoJGF0dHNbJ3NlY3Rpb24n XSkgJiYgc3RycG9zKCRhdHRzWydzZWN0aW9uJ10sICcsJykgIT09IGZhbHNlKQoJCSRhdHRz WydzZWN0aW9uJ10gPSAnJzsKCglpZiAoaXNzZXQoJGF0dHNbJ2V4Y2x1ZGVzZWN0aW9uJ10p KSB7CgkJdW5zZXQoJGF0dHNbJ2V4Y2x1ZGVzZWN0aW9uJ10pOwoJfQoKCWlmICghaXNzZXQo JGF0dHNbJ2xpbWl0J10pKQoJCSRhdHRzWydsaW1pdCddID0gJzEwMDAnOwoKCSRhdHRzWydh bGxvd292ZXJyaWRlJ10gPSB0cnVlOwoKCXJldHVybiAkYXR0czsKfQoKCmZ1bmN0aW9uIHRy dV90YWdzX3N0cnRvbG93ZXIoJHN0cikgewoJaWYgKGZ1bmN0aW9uX2V4aXN0cygibWJfc3Ry dG9sb3dlciIpKSB7CgkvL2lmICh2ZXJzaW9uX2NvbXBhcmUocGhwdmVyc2lvbigpLCAiNC4z LjAiLCAiPj0iKSkgewoJCXJldHVybiBtYl9zdHJ0b2xvd2VyKCRzdHIsICJVVEYtOCIpOwoJ fSBlbHNlIHsKCQlyZXR1cm4gc3RydG9sb3dlcigkc3RyKTsKCX0KfQoKCi8vdGhlc2UgbmV4 dCB0d28gZnVuY3Rpb25zIGFyZSBncm9zcywgYnV0IEkgY2FuJ3QgZmlndXJlIG91dCBhbm90 aGVyIHdheSB0byBkbyBpdApmdW5jdGlvbiB0cnVfdGFnc19zb3J0X3RhZ3MoJHRhZ3Nfd2Vp Z2h0LCAkc29ydF9ieV9jb3VudCwgJHNvcnRfYXNjZW5kaW5nKSB7CglnbG9iYWwgJHRydV90 YWdzX3RhZ3Nfd2VpZ2h0LCAkdHJ1X3RhZ3Nfc29ydF9ieV9jb3VudCwgJHRydV90YWdzX3Nv cnRfYXNjZW5kaW5nOwoKCSR0cnVfdGFnc190YWdzX3dlaWdodCA9ICR0YWdzX3dlaWdodDsK CSR0cnVfdGFnc19zb3J0X2J5X2NvdW50ID0gJHNvcnRfYnlfY291bnQ7CgkkdHJ1X3RhZ3Nf c29ydF9hc2NlbmRpbmcgPSAkc29ydF9hc2NlbmRpbmc7CgoJJHRlbXBfYXJyYXkgPSBhcnJh eV9rZXlzKCR0YWdzX3dlaWdodCk7Cgl1c29ydCgkdGVtcF9hcnJheSwgInRydV90YWdzX3Nv cnRfdGFnc19jb21wYXJhdG9yIik7CgoJJHNvcnRlZF9hcnJheSA9IGFycmF5KCk7Cglmb3Jl YWNoICgkdGVtcF9hcnJheSBhcyAkdGFnKSB7CgkJJHNvcnRlZF9hcnJheVskdGFnXSA9ICR0 YWdzX3dlaWdodFskdGFnXTsKCX0KCglyZXR1cm4gJHNvcnRlZF9hcnJheTsKfQoKCmZ1bmN0 aW9uIHRydV90YWdzX3NvcnRfdGFnc19jb21wYXJhdG9yKCRsZWZ0LCAkcmlnaHQpIHsKCWds b2JhbCAkdHJ1X3RhZ3NfdGFnc193ZWlnaHQsICR0cnVfdGFnc19zb3J0X2J5X2NvdW50LCAk dHJ1X3RhZ3Nfc29ydF9hc2NlbmRpbmc7CgoJaWYgKCR0cnVfdGFnc19zb3J0X2J5X2NvdW50 KSB7CgkJJGxlZnRfd2VpZ2h0ID0gJHRydV90YWdzX3RhZ3Nfd2VpZ2h0WyRsZWZ0XTsKCQkk cmlnaHRfd2VpZ2h0ID0gJHRydV90YWdzX3RhZ3Nfd2VpZ2h0WyRyaWdodF07CgkJaWYgKCRs ZWZ0X3dlaWdodCA9PSAkcmlnaHRfd2VpZ2h0KSB7CgkJCXJldHVybiBzdHJuYXRjYXNlY21w KCRsZWZ0LCAkcmlnaHQpOwoJCX0gZWxzZSBpZiAoJHRydV90YWdzX3NvcnRfYXNjZW5kaW5n KSB7CgkJCXJldHVybiAkbGVmdF93ZWlnaHQgLSAkcmlnaHRfd2VpZ2h0OwoJCX0gZWxzZSB7 CgkJCXJldHVybiAkcmlnaHRfd2VpZ2h0IC0gJGxlZnRfd2VpZ2h0OwoJCX0KCX0gZWxzZSB7 CgkJcmV0dXJuIHN0cm5hdGNhc2VjbXAoJGxlZnQsICRyaWdodCk7Cgl9Cn0KCgoKIyMjIEJB U1RBUkQgRlVOQ1RJT05TIFRIQVQgU0hPVUxETidUIEhBVkUgVE8gRVhJU1QgIyMjCiMjIyMj IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoKCmZ1 bmN0aW9uIHRydV90YWdzX3JlZG9fYXJ0aWNsZV9zZWFyY2goJGF0dHMpIHsKCSR0aGVBdHRz ID0gbEF0dHMoYXJyYXkoJ2xpbWl0JyAgICAgPT4gMTAwMCwKCQkJCSdjYXRlZ29yeScgID0+ ICcnLAoJCQkJJ3NlY3Rpb24nICAgPT4gJycsCgkJCQknZXhjZXJwdGVkJyA9PiAnJywKCQkJ CSdhdXRob3InICAgID0+ICcnLAoJCQkJJ3NvcnRieScgICAgPT4gJ1Bvc3RlZCcsCgkJCQkn c29ydGRpcicgICA9PiAnZGVzYycsCgkJCQknbW9udGgnICAgICA9PiAnJywKCQkJCSdrZXl3 b3JkcycgID0+ICcnLAoJCQkJJ2Zyb250cGFnZScgPT4gJycsCgkJCQknaWQnICAgICAgICA9 PiAnJywKCQkJCSd0aW1lJyAgICAgID0+ICdwYXN0JywKCQkJCSdzdGF0dXMnICAgID0+ICc0 JywKCQkJCSdvZmZzZXQnICAgID0+IDAKCQkJKSwkYXR0cywgMCk7CglleHRyYWN0KCR0aGVB dHRzKTsKCgkvL0J1aWxkaW5nIHF1ZXJ5IHBhcnRzCgkkZnJvbnRwYWdlID0gKCRmcm9udHBh Z2UpID8gZmlsdGVyRnJvbnRQYWdlKCkgOiAnJzsKCSRjYXRlZ29yeSAgPSAoISRjYXRlZ29y eSkgID8gJycgOiAiIGFuZCAoKENhdGVnb3J5MT0nIi5kb3NsYXNoKCRjYXRlZ29yeSkuIicp IG9yIChDYXRlZ29yeTI9JyIuZG9TbGFzaCgkY2F0ZWdvcnkpLiInKSkgIjsKCSRzZWN0aW9u ICAgPSAoISRzZWN0aW9uKSAgID8gJycgOiAiIGFuZCBTZWN0aW9uID0gJyIuZG9zbGFzaCgk c2VjdGlvbikuIiciOwoJJGV4Y2VycHRlZCA9ICgkZXhjZXJwdGVkPT0neScpICA/ICIgYW5k IEV4Y2VycHQgIT0nJyIgOiAnJzsKCSRhdXRob3IgICAgPSAoISRhdXRob3IpICAgID8gJycg OiAiIGFuZCBBdXRob3JJRCA9ICciLmRvc2xhc2goJGF1dGhvcikuIiciOwoJJG1vbnRoICAg ICA9ICghJG1vbnRoKSAgICAgPyAnJyA6ICIgYW5kIFBvc3RlZCBsaWtlICciLmRvU2xhc2go JG1vbnRoKS4iJSciOwoJJGlkICAgICAgICA9ICghJGlkKSAgICAgICAgPyAnJyA6ICIgYW5k IElEID0gJyIuaW50dmFsKCRpZCkuIiciOwoJc3dpdGNoICgkdGltZSkgewoJCWNhc2UgJ2Fu eSc6CgkJCSR0aW1lID0gIiI7IGJyZWFrOwoJCWNhc2UgJ2Z1dHVyZSc6CgkJCSR0aW1lID0g IiBhbmQgUG9zdGVkID4gbm93KCkiOyBicmVhazsKCQlkZWZhdWx0OgoJCQkkdGltZSA9ICIg YW5kIFBvc3RlZCA8IG5vdygpIjsKCX0KCWlmICghaXNfbnVtZXJpYygkc3RhdHVzKSkKCQkk c3RhdHVzID0gZ2V0U3RhdHVzTnVtKCRzdGF0dXMpOwoKCSRjdXN0b20gPSAnJzsKCS8vIHRy eWluZyBjdXN0b20gZmllbGRzIGhlcmUKCSRjdXN0b21GaWVsZHMgPSBnZXRDdXN0b21GaWVs ZHMoKTsKCWlmICgkY3VzdG9tRmllbGRzKSB7CgkJZm9yZWFjaCgkY3VzdG9tRmllbGRzIGFz ICRjRmllbGQpIHsKCQkJaWYgKGlzc2V0KCRhdHRzWyRjRmllbGRdKSkKCQkJCSRjdXN0b21Q YWlyc1skY0ZpZWxkXSA9ICRhdHRzWyRjRmllbGRdOwoJCX0KCQlpZighZW1wdHkoJGN1c3Rv bVBhaXJzKSkKCQkJJGN1c3RvbSA9ICBidWlsZEN1c3RvbVNxbCgkY3VzdG9tRmllbGRzLCRj dXN0b21QYWlycyk7CgkJZWxzZQoJCQkkY3VzdG9tID0gJyc7Cgl9CgoJLy9BbGxvdyBrZXl3 b3JkcyBmb3Igbm8tY3VzdG9tIGFydGljbGVzLiBUaGF0IHRhZ2dpbmcgbW9kZSwgeW91IGtu b3cKCWlmICgka2V5d29yZHMpIHsKCQkka2V5cyA9IHNwbGl0KCcsJywka2V5d29yZHMpOwoJ CWZvcmVhY2ggKCRrZXlzIGFzICRrZXkpIHsKCQkJJGtleXBhcnRzW10gPSAiIEtleXdvcmRz IGxpa2UgJyUiLmRvU2xhc2godHJpbSgka2V5KSkuIiUnIjsKCQl9CgkJJGtleXdvcmRzID0g IiBhbmQgKCIgLiBqb2luKCcgb3IgJywka2V5cGFydHMpIC4gIikiOwoJfQoKCWlmICgkaWQp CgkJJHN0YXR1c3EgPSAiIGFuZCBTdGF0dXMgPj0gJzQnIjsKCWVsc2UKCQkkc3RhdHVzcSA9 ICIgYW5kIFN0YXR1cz0nIi5kb1NsYXNoKCRzdGF0dXMpLiInIjsKCgkkd2hlcmUgPSAiMSIg LiAkc3RhdHVzcS4gJHRpbWUuCgkJJGlkIC4gJGNhdGVnb3J5IC4gJHNlY3Rpb24gLiAkZXhj ZXJwdGVkIC4gJG1vbnRoIC4gJGF1dGhvciAuICRrZXl3b3JkcyAuICRjdXN0b20gLiAkZnJv bnRwYWdlOwoKCQkkcGdvZmZzZXQgPSAkb2Zmc2V0IC4gJywgJzsKCgkkcnMgPSBzYWZlX3Jv d3Nfc3RhcnQoIiosIHVuaXhfdGltZXN0YW1wKFBvc3RlZCkgYXMgdVBvc3RlZCIsICd0ZXh0 cGF0dGVybicsCgkJJHdoZXJlLiAnIG9yZGVyIGJ5ICcgLiBkb3NsYXNoKCRzb3J0YnkpIC4g JyAnIC4gZG9TbGFzaCgkc29ydGRpcikgLiAnIGxpbWl0ICcgLiBkb1NsYXNoKCRsaW1pdCkp OwoKCXJldHVybiAkcnM7Cn0KCgoiO3M6ODoiaGVscF9yYXciO3M6NDk4OiJUbyBsZWFybiBt b3JlIGFib3V0IHRydV90YWdzLCBjaGVjayBvdXQgdGhlICJpbnRyb2R1Y3RvcnkgYXJ0aWNs ZSI6L2Jsb2cvNDkzL3RydXRhZ3MtYS10YWdnaW5nLXBsdWdpbi1mb3ItdGV4dHBhdHRlcm4s ICJyZWxlYXNlcyBwYWdlIjpodHRwOi8vd3d3LnRydWlzdC5jb20vcmVmZXJlbmNlLzUzNy90 cnVfdGFncy1yZWxlYXNlcywgImZlYXR1cmUgbGlzdCI6aHR0cDovL3d3dy50cnVpc3QuY29t L3JlZmVyZW5jZS80OTUvdHJ1dGFncy1mZWF0dXJlLWxpc3QsIGFuZCAidXNhZ2UgaW5zdHJ1 Y3Rpb25zIjpodHRwOi8vd3d3LnRydWlzdC5jb20vcmVmZXJlbmNlLzQ5Ny90cnV0YWdzLXVz YWdlLWluc3RydWN0aW9ucy4KCkkndmUgdGFrZW4gdGhlIGRldGFpbGVkIGhlbHAgb3V0IG9m IHRoZSBwbHVnaW47IG15IGFwb2xvZ2llcy4gIEl0IHdhcyB0b28gYmlnIGFuZCB0b28gZGlm ZmljdWx0IHRvIGtlZXAgbWFpbnRhaW5pbmcgb24gbXkgc2l0ZSBhbmQgaW4gdGhlIHBsdWdp bi4iO3M6MzoibWQ1IjtzOjMyOiI5YzY1NTZkNDk5NThmNjVlMTA1YmMzOWVhYjg4NTA5YSI7 fQ==