own-rag-cli 0.0.7-snapshot → 0.0.9-snapshot
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/bin/indexer_full.py +46 -1
- package/bin/mcp_server.py +43 -1
- package/bin/postinstall.sh +17 -1
- package/package.json +1 -1
- package/rag-setup-macos.run +8 -3
- package/rag-setup.run +8 -3
package/rag-setup-macos.run
CHANGED
|
@@ -724,8 +724,8 @@ log_info "$(t extracting)"
|
|
|
724
724
|
|
|
725
725
|
B64_COMPOSE="c2VydmljZXM6CiAgY2hyb21hZGI6CiAgICBpbWFnZTogY2hyb21hZGIvY2hyb21hOmxhdGVzdAogICAgY29udGFpbmVyX25hbWU6IGNocm9tYWRiLXJhZwogICAgcG9ydHM6CiAgICAgIC0gIjgwMDA6ODAwMCIKICAgIHZvbHVtZXM6CiAgICAgICMgUGVyc2lzdGUgbyBiYW5jbyBkaXJldGFtZW50ZSBuYSBwYXN0YSBkbyB1c3XDoXJpbyBubyBob3N0CiAgICAgIC0gJHtIT01FfS8ucmFnX2RiOi9jaHJvbWEvY2hyb21hCiAgICBlbnZpcm9ubWVudDoKICAgICAgIyBIYWJpbGl0YSBhdXRlbnRpY2HDp8OjbyBhbsO0bmltYSAoc2VtIHRva2VuKSBwYXJhIHVzbyBsb2NhbAogICAgICAtIEFOT05ZTUlaRURfVEVMRU1FVFJZPWZhbHNlCiAgICAgIC0gQ0hST01BX1NFUlZFUl9BVVRITl9DUkVERU5USUFMU19GSUxFPSIiCiAgICAgIC0gQ0hST01BX1NFUlZFUl9BVVRITl9QUk9WSURFUj0iIgogICAgcmVzdGFydDogYWx3YXlzCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDogWyJDTUQiLCAiY3VybCIsICItZiIsICJodHRwOi8vbG9jYWxob3N0OjgwMDAvYXBpL3YxL2hlYXJ0YmVhdCJdCiAgICAgIGludGVydmFsOiAzMHMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDMKICAgICAgc3RhcnRfcGVyaW9kOiAxMHMK"
|
|
726
726
|
B64_REQUIREMENTS="IyBDbGllbnRlIEhUVFAgZG8gQ2hyb21hREIgKGNvbmVjdGEgYW8gc2Vydmlkb3IgRG9ja2VyKQpjaHJvbWFkYj49MC41LjAKCiMgTW9kZWxvIGRlIGVtYmVkZGluZ3MgbG9jYWwgcm9kYW5kbyBuYSBDUFUKc2VudGVuY2UtdHJhbnNmb3JtZXJzPj0zLjAuMAojIERlcGVuZMOqbmNpYSB1c2FkYSBwb3IgbW9kZWxvcyBKaW5hIHYzIGNvbSBjw7NkaWdvIHJlbW90bwplaW5vcHM+PTAuNy4wCiMgRXZpdGEgaW5jb21wYXRpYmlsaWRhZGVzIGNvbmhlY2lkYXMgZG8gSmluYSB2MyBjb20gQVBJcyBub3ZhcyBkbyB0cmFuc2Zvcm1lcnMgNS54CnRyYW5zZm9ybWVyczw1CgojIFNwbGl0dGVyIGRlIHRleHRvIHBhcmEgY2h1bmtpbmcgaW50ZWxpZ2VudGUKbGFuZ2NoYWluLXRleHQtc3BsaXR0ZXJzPj0wLjIuMAoKIyBCYXJyYSBkZSBwcm9ncmVzc28gdmlzdWFsIG5vIHRlcm1pbmFsCnRxZG0+PTQuNjYuMAoKIyBNb25pdG9yIGRlIG1lbcOzcmlhIGVtIHRlbXBvIHJlYWwgZHVyYW50ZSBpbmRleGHDp8Ojbwpwc3V0aWw+PTUuOS4wCgojIFNESyBvZmljaWFsIGRvIE1DUCAoTW9kZWwgQ29udGV4dCBQcm90b2NvbCkgZGEgQW50aHJvcGljCm1jcD49MS4wLjAK"
|
|
727
|
-
B64_INDEXER="IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwoiIiIKaW5kZXhlcl9mdWxsLnB5IOKAlCBTY3JpcHQgc3RhbmRhbG9uZSBkZSBpbmRleGHDp8OjbyBkbyBSQUcgbG9jYWwuCgpVc286CiAgICBweXRob24gaW5kZXhlcl9mdWxsLnB5IFtjYW1pbmhvX2RvX3Byb2pldG9dCgpTZSBuZW5odW0gY2FtaW5obyBmb3IgcGFzc2FkbywgdXNhIG8gZGlyZXTDs3JpbyBhdHVhbC4KTyBDaHJvbWFEQiBkZXZlIGVzdGFyIHJvZGFuZG8gdmlhIERvY2tlciBlbSBsb2NhbGhvc3Q6ODAwMC4KIiIiCgppbXBvcnQgb3MKaW1wb3J0IHN5cwppbXBvcnQgaGFzaGxpYgppbXBvcnQgYXJncGFyc2UKaW1wb3J0IHNodXRpbAppbXBvcnQgbG9nZ2luZwppbXBvcnQgZ2MKaW1wb3J0IGpzb24KZnJvbSB0aW1lIGltcG9ydCBwZXJmX2NvdW50ZXIsIHRpbWUKZnJvbSBjb2xsZWN0aW9ucy5hYmMgaW1wb3J0IEl0ZXJhdG9yCmZyb20gcGF0aGxpYiBpbXBvcnQgUGF0aApmcm9tIGRhdGFjbGFzc2VzIGltcG9ydCBkYXRhY2xhc3MKZnJvbSBkYXRldGltZSBpbXBvcnQgZGF0ZXRpbWUKZnJvbSB1cmxsaWIucGFyc2UgaW1wb3J0IHVybHBhcnNlCgojIEV2aXRhIGF2aXNvcyAiYWR2aXNvcnkiIHJ1aWRvc29zIGRvIHRyYW5zZm9ybWVycyBubyBmbHV4byBpbnRlcmF0aXZvLgpvcy5lbnZpcm9uLnNldGRlZmF1bHQoIlRSQU5TRk9STUVSU19OT19BRFZJU09SWV9XQVJOSU5HUyIsICIxIikKCgpjbGFzcyBfVG9yY2hEdHlwZVdhcm5pbmdGaWx0ZXIobG9nZ2luZy5GaWx0ZXIpOgogICAgZGVmIGZpbHRlcihzZWxmLCByZWNvcmQ6IGxvZ2dpbmcuTG9nUmVjb3JkKSAtPiBib29sOgogICAgICAgIHJldHVybiAiYHRvcmNoX2R0eXBlYCBpcyBkZXByZWNhdGVkISBVc2UgYGR0eXBlYCBpbnN0ZWFkISIgbm90IGluIHJlY29yZC5nZXRNZXNzYWdlKCkKCgpmb3IgX2xvZ2dlcl9uYW1lIGluICgidHJhbnNmb3JtZXJzLmNvbmZpZ3VyYXRpb25fdXRpbHMiLCAidHJhbnNmb3JtZXJzLm1vZGVsaW5nX3V0aWxzIik6CiAgICBsb2dnaW5nLmdldExvZ2dlcihfbG9nZ2VyX25hbWUpLmFkZEZpbHRlcihfVG9yY2hEdHlwZVdhcm5pbmdGaWx0ZXIoKSkKCmltcG9ydCBjaHJvbWFkYgpmcm9tIHNlbnRlbmNlX3RyYW5zZm9ybWVycyBpbXBvcnQgU2VudGVuY2VUcmFuc2Zvcm1lcgpmcm9tIGxhbmdjaGFpbl90ZXh0X3NwbGl0dGVycyBpbXBvcnQgUmVjdXJzaXZlQ2hhcmFjdGVyVGV4dFNwbGl0dGVyCmZyb20gdHFkbSBpbXBvcnQgdHFkbQpmcm9tIGRvd25sb2FkX21vZGVsX2Zyb21faHVnZ2luZmFjZSBpbXBvcnQgZG93bmxvYWRfbW9kZWxfd2l0aF9mYWxsYmFjawoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBDb25maWd1cmHDp8O1ZXMgZ2xvYmFpcwojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCmRlZiBfZW52X2ludChuYW1lOiBzdHIsIGRlZmF1bHQ6IGludCwgKiwgbWluX3ZhbHVlOiBpbnQgPSAxKSAtPiBpbnQ6CiAgICByYXcgPSBvcy5lbnZpcm9uLmdldChuYW1lKQogICAgaWYgcmF3IGlzIE5vbmU6CiAgICAgICAgcmV0dXJuIG1heChtaW5fdmFsdWUsIGRlZmF1bHQpCiAgICB0cnk6CiAgICAgICAgcmV0dXJuIG1heChtaW5fdmFsdWUsIGludChyYXcpKQogICAgZXhjZXB0IFZhbHVlRXJyb3I6CiAgICAgICAgcmV0dXJuIG1heChtaW5fdmFsdWUsIGRlZmF1bHQpCgoKZGVmIF9lbnZfc3RyKG5hbWU6IHN0ciwgZGVmYXVsdDogc3RyKSAtPiBzdHI6CiAgICByYXcgPSBvcy5lbnZpcm9uLmdldChuYW1lKQogICAgaWYgcmF3IGlzIE5vbmU6CiAgICAgICAgcmV0dXJuIGRlZmF1bHQKICAgIHN0cmlwcGVkID0gcmF3LnN0cmlwKCkKICAgIHJldHVybiBzdHJpcHBlZCBpZiBzdHJpcHBlZCBlbHNlIGRlZmF1bHQKCgpkZWYgX3BhcnNlX3Bvc2l0aXZlX2ludChyYXc6IG9iamVjdCwgKiwgbWluX3ZhbHVlOiBpbnQgPSAxKSAtPiBpbnQgfCBOb25lOgogICAgdHJ5OgogICAgICAgIHBhcnNlZCA9IGludChzdHIocmF3KS5zdHJpcCgpKQogICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICByZXR1cm4gTm9uZQogICAgaWYgcGFyc2VkIDwgbWluX3ZhbHVlOgogICAgICAgIHJldHVybiBOb25lCiAgICByZXR1cm4gcGFyc2VkCgoKT1dOX1JBR19DTElfQ09ORklHX1BBVEggPSBQYXRoKAogICAgb3MuZW52aXJvbi5nZXQoIk9XTl9SQUdfQ0xJX0NPTkZJR19GSUxFIiwgc3RyKFBhdGguaG9tZSgpIC8gIi5vd24tcmFnLWNsaS5qc29uIikpCikuZXhwYW5kdXNlcigpCgoKZGVmIF9sb2FkX293bl9yYWdfY2xpX2NvbmZpZ19wYXlsb2FkKCkgLT4gZGljdFtzdHIsIG9iamVjdF06CiAgICB0cnk6CiAgICAgICAgaWYgbm90IE9XTl9SQUdfQ0xJX0NPTkZJR19QQVRILmV4aXN0cygpOgogICAgICAgICAgICByZXR1cm4ge30KICAgICAgICBwYXlsb2FkID0ganNvbi5sb2FkcyhPV05fUkFHX0NMSV9DT05GSUdfUEFUSC5yZWFkX3RleHQoZW5jb2Rpbmc9InV0Zi04IikpCiAgICAgICAgcmV0dXJuIHBheWxvYWQgaWYgaXNpbnN0YW5jZShwYXlsb2FkLCBkaWN0KSBlbHNlIHt9CiAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgIHJldHVybiB7fQoKCmRlZiBfZXh0cmFjdF9jaHJvbWFfZW5kcG9pbnRfZnJvbV9jb25maWcoY29uZmlnX3BheWxvYWQ6IG9iamVjdCkgLT4gdHVwbGVbc3RyLCBzdHIsIGludF06CiAgICBzY2hlbWUgPSAiaHR0cCIKICAgIGhvc3QgPSAibG9jYWxob3N0IgogICAgcG9ydCA9IDgwMDAKCiAgICBkZWYgX3JlYWRfc2NoZW1lKHJhdzogb2JqZWN0KSAtPiBOb25lOgogICAgICAgIG5vbmxvY2FsIHNjaGVtZQogICAgICAgIGlmIG5vdCBpc2luc3RhbmNlKHJhdywgc3RyKToKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgbG93ZXJlZCA9IHJhdy5zdHJpcCgpLmxvd2VyKCkKICAgICAgICBpZiBsb3dlcmVkIGluIHsiaHR0cCIsICJodHRwcyJ9OgogICAgICAgICAgICBzY2hlbWUgPSBsb3dlcmVkCgogICAgZGVmIF9yZWFkX2hvc3QocmF3OiBvYmplY3QpIC0+IE5vbmU6CiAgICAgICAgbm9ubG9jYWwgc2NoZW1lLCBob3N0LCBwb3J0CiAgICAgICAgaWYgbm90IGlzaW5zdGFuY2UocmF3LCBzdHIpOgogICAgICAgICAgICByZXR1cm4KICAgICAgICBjYW5kaWRhdGUgPSByYXcuc3RyaXAoKQogICAgICAgIGlmIG5vdCBjYW5kaWRhdGU6CiAgICAgICAgICAgIHJldHVybgogICAgICAgIHBhcnNlZCA9IHVybHBhcnNlKGNhbmRpZGF0ZSBpZiAiOi8vIiBpbiBjYW5kaWRhdGUgZWxzZSBmIi8ve2NhbmRpZGF0ZX0iKQogICAgICAgIGlmIHBhcnNlZC5zY2hlbWUgaW4geyJodHRwIiwgImh0dHBzIn06CiAgICAgICAgICAgIHNjaGVtZSA9IHBhcnNlZC5zY2hlbWUKICAgICAgICBpZiBwYXJzZWQuaG9zdG5hbWU6CiAgICAgICAgICAgIGhvc3QgPSBwYXJzZWQuaG9zdG5hbWUKICAgICAgICBlbGlmICI6Ly8iIG5vdCBpbiBjYW5kaWRhdGU6CiAgICAgICAgICAgIGhvc3QgPSBjYW5kaWRhdGUuc3RyaXAoKS5zdHJpcCgiLyIpCiAgICAgICAgaWYgcGFyc2VkLnBvcnQgYW5kIDEgPD0gcGFyc2VkLnBvcnQgPD0gNjU1MzU6CiAgICAgICAgICAgIHBvcnQgPSBwYXJzZWQucG9ydAoKICAgIGRlZiBfcmVhZF9wb3J0KHJhdzogb2JqZWN0KSAtPiBOb25lOgogICAgICAgIG5vbmxvY2FsIHBvcnQKICAgICAgICB0cnk6CiAgICAgICAgICAgIHBhcnNlZCA9IGludChzdHIocmF3KS5zdHJpcCgpKQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgICAgIHJldHVybgogICAgICAgIGlmIDEgPD0gcGFyc2VkIDw9IDY1NTM1OgogICAgICAgICAgICBwb3J0ID0gcGFyc2VkCgogICAgaWYgaXNpbnN0YW5jZShjb25maWdfcGF5bG9hZCwgZGljdCk6CiAgICAgICAgY2hyb21hX29iaiA9IGNvbmZpZ19wYXlsb2FkLmdldCgiY2hyb21hIikKICAgICAgICBpZiBpc2luc3RhbmNlKGNocm9tYV9vYmosIGRpY3QpOgogICAgICAgICAgICBfcmVhZF9zY2hlbWUoY2hyb21hX29iai5nZXQoInNjaGVtZSIpKQogICAgICAgICAgICBfcmVhZF9ob3N0KGNocm9tYV9vYmouZ2V0KCJob3N0IikpCiAgICAgICAgICAgIF9yZWFkX3BvcnQoY2hyb21hX29iai5nZXQoInBvcnQiKSkKCiAgICAgICAgIyBDb21wYXRpYmlsaWRhZGUgY29tIGZvcm1hdG9zIGZsYXQgYW50aWdvcy4KICAgICAgICBfcmVhZF9zY2hlbWUoY29uZmlnX3BheWxvYWQuZ2V0KCJDSFJPTUFfU0NIRU1FIikpCiAgICAgICAgX3JlYWRfaG9zdChjb25maWdfcGF5bG9hZC5nZXQoIkNIUk9NQV9IT1NUIikpCiAgICAgICAgX3JlYWRfcG9ydChjb25maWdfcGF5bG9hZC5nZXQoIkNIUk9NQV9QT1JUIikpCgogICAgcmV0dXJuIHNjaGVtZSwgaG9zdCwgcG9ydAoKCmRlZiBfZXh0cmFjdF9lbWJlZGRpbmdfYmF0Y2hfZnJvbV9jb25maWcoY29uZmlnX3BheWxvYWQ6IG9iamVjdCkgLT4gaW50IHwgTm9uZToKICAgIGlmIG5vdCBpc2luc3RhbmNlKGNvbmZpZ19wYXlsb2FkLCBkaWN0KToKICAgICAgICByZXR1cm4gTm9uZQoKICAgIGluZGV4aW5nID0gY29uZmlnX3BheWxvYWQuZ2V0KCJpbmRleGluZyIpCiAgICBpZiBpc2luc3RhbmNlKGluZGV4aW5nLCBkaWN0KToKICAgICAgICBmb3Iga2V5IGluICgiZW1iZWRkaW5nX2JhdGNoX3NpemUiLCAiYmF0Y2hfY291bnQiKToKICAgICAgICAgICAgcGFyc2VkID0gX3BhcnNlX3Bvc2l0aXZlX2ludChpbmRleGluZy5nZXQoa2V5KSwgbWluX3ZhbHVlPTEpCiAgICAgICAgICAgIGlmIHBhcnNlZCBpcyBub3QgTm9uZToKICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZWQKCiAgICBmb3Iga2V5IGluICgiTUNQX0VNQkVERElOR19CQVRDSF9TSVpFIiwgImVtYmVkZGluZ19iYXRjaF9zaXplIiwgImJhdGNoX2NvdW50Iik6CiAgICAgICAgcGFyc2VkID0gX3BhcnNlX3Bvc2l0aXZlX2ludChjb25maWdfcGF5bG9hZC5nZXQoa2V5KSwgbWluX3ZhbHVlPTEpCiAgICAgICAgaWYgcGFyc2VkIGlzIG5vdCBOb25lOgogICAgICAgICAgICByZXR1cm4gcGFyc2VkCiAgICByZXR1cm4gTm9uZQoKCmRlZiBfbG9hZF9jbGlfY2hyb21hX2RlZmF1bHRzKCkgLT4gdHVwbGVbc3RyLCBzdHIsIGludF06CiAgICBwYXlsb2FkID0gX2xvYWRfb3duX3JhZ19jbGlfY29uZmlnX3BheWxvYWQoKQogICAgaWYgbm90IHBheWxvYWQ6CiAgICAgICAgcmV0dXJuICgiaHR0cCIsICJsb2NhbGhvc3QiLCA4MDAwKQogICAgcmV0dXJuIF9leHRyYWN0X2Nocm9tYV9lbmRwb2ludF9mcm9tX2NvbmZpZyhwYXlsb2FkKQoKX0RFRkFVTFRfQ0hST01BX1NDSEVNRSwgX0RFRkFVTFRfQ0hST01BX0hPU1QsIF9ERUZBVUxUX0NIUk9NQV9QT1JUID0gX2xvYWRfY2xpX2Nocm9tYV9kZWZhdWx0cygpCl9ERUZBVUxUX0VNQkVERElOR19CQVRDSF9TSVpFID0gX2V4dHJhY3RfZW1iZWRkaW5nX2JhdGNoX2Zyb21fY29uZmlnKF9sb2FkX293bl9yYWdfY2xpX2NvbmZpZ19wYXlsb2FkKCkpIG9yIDQKQ0hST01BX1NDSEVNRSA9IF9lbnZfc3RyKCJNQ1BfQ0hST01BX1NDSEVNRSIsIF9ERUZBVUxUX0NIUk9NQV9TQ0hFTUUpLmxvd2VyKCkKaWYgQ0hST01BX1NDSEVNRSBub3QgaW4geyJodHRwIiwgImh0dHBzIn06CiAgICBDSFJPTUFfU0NIRU1FID0gX0RFRkFVTFRfQ0hST01BX1NDSEVNRQpDSFJPTUFfSE9TVCA9IF9lbnZfc3RyKCJNQ1BfQ0hST01BX0hPU1QiLCBfREVGQVVMVF9DSFJPTUFfSE9TVCkKQ0hST01BX1BPUlQgPSBfZW52X2ludCgiTUNQX0NIUk9NQV9QT1JUIiwgX0RFRkFVTFRfQ0hST01BX1BPUlQsIG1pbl92YWx1ZT0xKQpDSFJPTUFfU1NMID0gQ0hST01BX1NDSEVNRSA9PSAiaHR0cHMiCkNPTExFQ1RJT05fQ09ERV9KSU5BID0gImNvZGVfdmVjdG9yc19qaW5hIgpDT0xMRUNUSU9OX0RPQ19CR0UgPSAiZG9jX3ZlY3RvcnNfYmdlIgoKIyBQYXN0YXMgZSBleHRlbnPDtWVzIGlnbm9yYWRhcyBkdXJhbnRlIGEgdmFycmVkdXJhCklHTk9SRURfRElSUyA9IHsKICAgICIuZ2l0IiwgIm5vZGVfbW9kdWxlcyIsICJfX3B5Y2FjaGVfXyIsICIudmVudiIsICJ2ZW52IiwgImVudiIsCiAgICAiZGlzdCIsICJidWlsZCIsICJvdXQiLCAiLm5leHQiLCAiLm51eHQiLCAiLmNhY2hlIiwgImNvdmVyYWdlIiwKICAgICIucHl0ZXN0X2NhY2hlIiwgIi5teXB5X2NhY2hlIiwgIi5ydWZmX2NhY2hlIiwgInRhcmdldCIsICJiaW4iLCAib2JqIiwKICAgICIuaWRlYSIsICIudnNjb2RlIiwgIi5EU19TdG9yZSIsICJ2ZW5kb3IiLCAidG1wIiwgInRlbXAiLCAibG9ncyIsCiAgICAiLnJhZ19kYiIsCn0KCklHTk9SRURfRVhURU5TSU9OUyA9IHsKICAgICMgQmluw6FyaW9zIGUgaW1hZ2VucwogICAgIi5wbmciLCAiLmpwZyIsICIuanBlZyIsICIuZ2lmIiwgIi5zdmciLCAiLmljbyIsICIud2VicCIsICIuYm1wIiwKICAgICIubXA0IiwgIi5tcDMiLCAiLndhdiIsICIub2dnIiwgIi5hdmkiLCAiLm1vdiIsCiAgICAjIFBhY290ZXMgZSBjb21waWxhZG9zCiAgICAiLnppcCIsICIudGFyIiwgIi5neiIsICIucmFyIiwgIi43eiIsICIuamFyIiwgIi53YXIiLCAiLmVhciIsCiAgICAiLnB5YyIsICIucHlvIiwgIi5zbyIsICIuZGxsIiwgIi5leGUiLCAiLmJpbiIsICIucnVuIiwKICAgICMgTG9ja2ZpbGVzIGUgZ2VyYWRvcwogICAgIi5sb2NrIiwgIi5zdW0iLAogICAgIyBCYW5jbyBkZSBkYWRvcwogICAgIi5zcWxpdGUiLCAiLmRiIiwgIi5zcWxpdGUzIiwKICAgICMgRm9udGVzCiAgICAiLnR0ZiIsICIud29mZiIsICIud29mZjIiLCAiLmVvdCIsCiAgICAjIFBERi9Eb2N1bWVudG9zIGJpbsOhcmlvcwogICAgIi5wZGYiLCAiLmRvY3giLCAiLnhsc3giLCAiLnBwdHgiLAp9CgpDT0RFX0VYVEVOU0lPTlMgPSB7CiAgICAiLnB5IiwgIi5qcyIsICIudHMiLCAiLnRzeCIsICIuanN4IiwgIi5qYXZhIiwgIi5jIiwgIi5oIiwgIi5jcHAiLCAiLmhwcCIsCiAgICAiLmdvIiwgIi5ycyIsICIucmIiLCAiLnBocCIsICIuY3MiLCAiLnN3aWZ0IiwgIi5rdCIsICIua3RzIiwgIi5zY2FsYSIsICIuc3FsIiwKICAgICIuc2giLCAiLmJhc2giLCAiLnpzaCIsICIucHMxIiwgIi55YW1sIiwgIi55bWwiLCAiLnRvbWwiLCAiLmluaSIsICIuY29uZiIsCiAgICAiLmpzb24iLCAiLnhtbCIsICIuaHRtbCIsICIuY3NzIiwgIi5zY3NzIiwgIi5zYXNzIiwgIi52dWUiLCAiLnN2ZWx0ZSIsICIuZGFydCIsCiAgICAiLmx1YSIsICIuciIsICIubSIsICIubW0iLAp9CgpET0NfRVhURU5TSU9OUyA9IHsKICAgICIubWQiLCAiLm1keCIsICIucnN0IiwgIi50eHQiLCAiLmFkb2MiLCAiLm9yZyIsICIudGV4IiwgIi5jc3YiLAp9CgojIFRhbWFuaG8gbcOheGltbyBkZSBhcnF1aXZvIChldml0YSBpbmRleGFyIGFycXVpdm9zIGVub3JtZXMgZ2VyYWRvcykKTUFYX0ZJTEVfU0laRV9CWVRFUyA9IDUwMCAqIDEwMjQgICMgNTAwIEtCCgojIFBhcsOibWV0cm9zIGRvIHNwbGl0dGVyIGUgYmF0Y2ggKHBlcmZpbCBsb3ctbWVtb3J5IHBvciBwYWRyw6NvKS4KQ0hVTktfU0laRSA9IF9lbnZfaW50KCJNQ1BfQ0hVTktfU0laRSIsIDMwMDAsIG1pbl92YWx1ZT0yNTYpCkNIVU5LX09WRVJMQVAgPSBtaW4oQ0hVTktfU0laRSAtIDEsIF9lbnZfaW50KCJNQ1BfQ0hVTktfT1ZFUkxBUCIsIDQwMCwgbWluX3ZhbHVlPTApKQpFTUJFRERJTkdfQkFUQ0hfU0laRSA9IF9lbnZfaW50KAogICAgIk1DUF9FTUJFRERJTkdfQkFUQ0hfU0laRSIsCiAgICBfREVGQVVMVF9FTUJFRERJTkdfQkFUQ0hfU0laRSwKICAgIG1pbl92YWx1ZT0xLAopCkRFRkFVTFRfUEVSRl9QUk9GSUxFID0gImF1dG90dW5lIgpJTkRFWEVSX0NPTkZJR19QQVRIID0gUGF0aCgKICAgIG9zLmVudmlyb24uZ2V0KAogICAgICAgICJNQ1BfSU5ERVhFUl9DT05GSUdfRklMRSIsCiAgICAgICAgc3RyKFBhdGguaG9tZSgpIC8gIi5jYWNoZSIgLyAib3duLXJhZy1jbGkiIC8gImluZGV4ZXJfdHVuaW5nLmpzb24iKSwKICAgICkKKS5leHBhbmR1c2VyKCkKCiMgTW9kZWxvIGRlIGVtYmVkZGluZ3MgKHJvZGEgbmEgQ1BVKQpKSU5BX1YzX0VNQkVERElOR19NT0RFTCA9ICJqaW5hYWkvamluYS1lbWJlZGRpbmdzLXYzIgpKSU5BX1YyX0VNQkVERElOR19NT0RFTCA9ICJqaW5hYWkvamluYS1lbWJlZGRpbmdzLXYyLWJhc2UtY29kZSIKQkdFX0VNQkVERElOR19NT0RFTCA9ICJCQUFJL2JnZS1tMyIKREVGQVVMVF9FTUJFRERJTkdfTU9ERUxfQ0hPSUNFID0gImppbmEiCkRFRkFVTFRfSklOQV9RVUFOVElaQVRJT04gPSAiZHluYW1pYy1pbnQ4IgpNT0RFTF9DQUNIRV9CQVNFX0RJUiA9IFBhdGgoCiAgICBvcy5lbnZpcm9uLmdldCgiTUNQX01PREVMX0RJUiIsIHN0cihQYXRoLmhvbWUoKSAvICIuY2FjaGUiIC8gIm93bi1yYWctY2xpIiAvICJtb2RlbHMiKSkKKS5leHBhbmR1c2VyKCkKSklOQV9SRUNPTU1FTkRFRF9SQU1fR0JfREVGQVVMVCA9IDY0CkpJTkFfUkVDT01NRU5ERURfUkFNX0dCX0RZTkFNSUNfSU5UOCA9IDQ4CkpJTkFfUkVDT01NRU5ERURfU1dBUF9HQiA9IDE2CkpJTkFfTUlOX0FWQUlMQUJMRV9SQU1fR0JfSElOVCA9IDEyCgoKZGVmIF9lbnZfYm9vbChuYW1lOiBzdHIsIGRlZmF1bHQ6IGJvb2wgPSBGYWxzZSkgLT4gYm9vbDoKICAgIHJhdyA9IG9zLmVudmlyb24uZ2V0KG5hbWUpCiAgICBpZiByYXcgaXMgTm9uZToKICAgICAgICByZXR1cm4gZGVmYXVsdAogICAgcmV0dXJuIHJhdy5zdHJpcCgpLmxvd2VyKCkgaW4geyIxIiwgInRydWUiLCAieWVzIiwgIm9uIn0KCgpkZWYgX2NsYW1wKHZhbHVlOiBmbG9hdCwgbG93OiBmbG9hdCwgaGlnaDogZmxvYXQpIC0+IGZsb2F0OgogICAgcmV0dXJuIG1heChsb3csIG1pbihoaWdoLCB2YWx1ZSkpCgoKZGVmIF9pc19tZW1vcnlfcmVsYXRlZF9lcnJvcihleGM6IEV4Y2VwdGlvbikgLT4gYm9vbDoKICAgIGlmIGlzaW5zdGFuY2UoZXhjLCBNZW1vcnlFcnJvcik6CiAgICAgICAgcmV0dXJuIFRydWUKICAgIG1zZyA9IHN0cihleGMpLmxvd2VyKCkKICAgIG1lbW9yeV9tYXJrZXJzID0gKAogICAgICAgICJvdXQgb2YgbWVtb3J5IiwKICAgICAgICAib29tIiwKICAgICAgICAiY2Fubm90IGFsbG9jYXRlIG1lbW9yeSIsCiAgICAgICAgInN0ZDo6YmFkX2FsbG9jIiwKICAgICAgICAiYmFkIGFsbG9jIiwKICAgICAgICAiaW5zdWZmaWNpZW50IG1lbW9yeSIsCiAgICApCiAgICByZXR1cm4gYW55KG1hcmtlciBpbiBtc2cgZm9yIG1hcmtlciBpbiBtZW1vcnlfbWFya2VycykKCgpkZWYgX2lzX2RpbWVuc2lvbl9taXNtYXRjaF9lcnJvcihleGM6IEV4Y2VwdGlvbikgLT4gYm9vbDoKICAgIG1zZyA9IHN0cihleGMpLmxvd2VyKCkKICAgIHJldHVybiAoCiAgICAgICAgImV4cGVjdGluZyBlbWJlZGRpbmcgd2l0aCBkaW1lbnNpb24iIGluIG1zZwogICAgICAgIG9yICgiZW1iZWRkaW5nIiBpbiBtc2cgYW5kICJkaW1lbnNpb24iIGluIG1zZyBhbmQgImdvdCIgaW4gbXNnKQogICAgKQoKCmRlZiBfZm9ybWF0X2V4Y2VwdGlvbihleGM6IEV4Y2VwdGlvbikgLT4gc3RyOgogICAgbWVzc2FnZSA9IHN0cihleGMpLnN0cmlwKCkKICAgIGlmIG1lc3NhZ2U6CiAgICAgICAgcmV0dXJuIG1lc3NhZ2UKICAgIHJldHVybiByZXByKGV4YykKCgpAZGF0YWNsYXNzKGZyb3plbj1UcnVlKQpjbGFzcyBJbmRleFRhcmdldDoKICAgIG1vZGVsX2Nob2ljZTogc3RyCiAgICBjb2xsZWN0aW9uX25hbWU6IHN0cgogICAgbGFiZWw6IHN0cgoKCmRlZiBfcmVzb2x2ZV9tb2RlbF9pZChtb2RlbF9jaG9pY2U6IHN0cikgLT4gc3RyOgogICAgaWYgbW9kZWxfY2hvaWNlID09ICJqaW5hIjoKICAgICAgICByZXR1cm4gSklOQV9WM19FTUJFRERJTkdfTU9ERUwKICAgIGlmIG1vZGVsX2Nob2ljZSA9PSAiamluYS12MiI6CiAgICAgICAgcmV0dXJuIEpJTkFfVjJfRU1CRURESU5HX01PREVMCiAgICBpZiBtb2RlbF9jaG9pY2UgPT0gImJnZSI6CiAgICAgICAgcmV0dXJuIEJHRV9FTUJFRERJTkdfTU9ERUwKICAgIHJhaXNlIFZhbHVlRXJyb3IoZiJNb2RlbG8gbsOjbyBzdXBvcnRhZG86IHttb2RlbF9jaG9pY2V9IikKCgpkZWYgX3Jlc29sdmVfZmFsbGJhY2tfbW9kZWxfaWQobW9kZWxfY2hvaWNlOiBzdHIpIC0+IHN0cjoKICAgIHJldHVybiBCR0VfRU1CRURESU5HX01PREVMCgoKZGVmIF9kZXNjcmliZV9lbWJlZGRpbmdfY2hvaWNlKG1vZGVsX2Nob2ljZTogc3RyKSAtPiBzdHI6CiAgICBpZiBtb2RlbF9jaG9pY2UgPT0gImppbmEiOgogICAgICAgIHJldHVybiBmImppbmEgKHtKSU5BX1YzX0VNQkVERElOR19NT0RFTH0pIgogICAgaWYgbW9kZWxfY2hvaWNlID09ICJiZ2UiOgogICAgICAgIHJldHVybiBmImJnZSAoe0JHRV9FTUJFRERJTkdfTU9ERUx9KSIKICAgIGlmIG1vZGVsX2Nob2ljZSA9PSAiaHlicmlkIjoKICAgICAgICByZXR1cm4gZiJoeWJyaWQgKHtKSU5BX1YyX0VNQkVERElOR19NT0RFTH0gKyB7QkdFX0VNQkVERElOR19NT0RFTH0pIgogICAgcmV0dXJuIG1vZGVsX2Nob2ljZQoKCmRlZiBfcmVzb2x2ZV9pbmRleF90YXJnZXRzKG1vZGVsX2Nob2ljZTogc3RyKSAtPiBsaXN0W0luZGV4VGFyZ2V0XToKICAgIGlmIG1vZGVsX2Nob2ljZSA9PSAiamluYSI6CiAgICAgICAgcmV0dXJuIFsKICAgICAgICAgICAgSW5kZXhUYXJnZXQoCiAgICAgICAgICAgICAgICBtb2RlbF9jaG9pY2U9ImppbmEiLAogICAgICAgICAgICAgICAgY29sbGVjdGlvbl9uYW1lPUNPTExFQ1RJT05fQ09ERV9KSU5BLAogICAgICAgICAgICAgICAgbGFiZWw9IkNvZGUvSmluYSIsCiAgICAgICAgICAgICkKICAgICAgICBdCiAgICBpZiBtb2RlbF9jaG9pY2UgPT0gImJnZSI6CiAgICAgICAgcmV0dXJuIFsKICAgICAgICAgICAgSW5kZXhUYXJnZXQoCiAgICAgICAgICAgICAgICBtb2RlbF9jaG9pY2U9ImJnZSIsCiAgICAgICAgICAgICAgICBjb2xsZWN0aW9uX25hbWU9Q09MTEVDVElPTl9ET0NfQkdFLAogICAgICAgICAgICAgICAgbGFiZWw9IkRvYy9CR0UiLAogICAgICAgICAgICApCiAgICAgICAgXQogICAgaWYgbW9kZWxfY2hvaWNlID09ICJoeWJyaWQiOgogICAgICAgIHJldHVybiBbCiAgICAgICAgICAgIEluZGV4VGFyZ2V0KAogICAgICAgICAgICAgICAgbW9kZWxfY2hvaWNlPSJqaW5hLXYyIiwKICAgICAgICAgICAgICAgIGNvbGxlY3Rpb25fbmFtZT1DT0xMRUNUSU9OX0NPREVfSklOQSwKICAgICAgICAgICAgICAgIGxhYmVsPSJDb2RlL0ppbmEgdjIiLAogICAgICAgICAgICApLAogICAgICAgICAgICBJbmRleFRhcmdldCgKICAgICAgICAgICAgICAgIG1vZGVsX2Nob2ljZT0iYmdlIiwKICAgICAgICAgICAgICAgIGNvbGxlY3Rpb25fbmFtZT1DT0xMRUNUSU9OX0RPQ19CR0UsCiAgICAgICAgICAgICAgICBsYWJlbD0iRG9jL0JHRSIsCiAgICAgICAgICAgICksCiAgICAgICAgXQogICAgcmFpc2UgVmFsdWVFcnJvcihmIk1vZGVsbyBuw6NvIHN1cG9ydGFkbzoge21vZGVsX2Nob2ljZX0iKQoKCmRlZiBfY2xhc3NpZnlfZmlsZV90YXJnZXRzKGZpbGVwYXRoOiBQYXRoLCBtb2RlbF9jaG9pY2U6IHN0cikgLT4gc2V0W3N0cl06CiAgICBpZiBtb2RlbF9jaG9pY2UgIT0gImh5YnJpZCI6CiAgICAgICAgcmV0dXJuIHttb2RlbF9jaG9pY2V9CgogICAgc3VmZml4ID0gZmlsZXBhdGguc3VmZml4Lmxvd2VyKCkKICAgIGlzX2NvZGUgPSBzdWZmaXggaW4gQ09ERV9FWFRFTlNJT05TCiAgICBpc19kb2MgPSBzdWZmaXggaW4gRE9DX0VYVEVOU0lPTlMKCiAgICBpZiBpc19jb2RlIGFuZCBub3QgaXNfZG9jOgogICAgICAgIHJldHVybiB7ImppbmEtdjIifQogICAgaWYgaXNfZG9jIGFuZCBub3QgaXNfY29kZToKICAgICAgICByZXR1cm4geyJiZ2UifQoKICAgICMgRXh0ZW5zw6NvIGRlc2NvbmhlY2lkYS9hbWLDrWd1YTogaW5kZXhhIG5vcyBkb2lzIHJhbW9zIHBhcmEgbWFudGVyIHJlY2FsbC4KICAgIHJldHVybiB7ImppbmEtdjIiLCAiYmdlIn0KCgpkZWYgX21vZGVsX2NhY2hlX2RpcihiYXNlX2RpcjogUGF0aCwgbW9kZWxfaWQ6IHN0cikgLT4gUGF0aDoKICAgIHNhZmVfbmFtZSA9IG1vZGVsX2lkLnJlcGxhY2UoIi8iLCAiX18iKS5yZXBsYWNlKCI6IiwgIl8iKQogICAgcmV0dXJuIGJhc2VfZGlyIC8gc2FmZV9uYW1lCgoKZGVmIF9waWNrX3dpdGhfcHJvbXB0KAogICAgKiwKICAgIGN1cnJlbnRfdmFsdWU6IHN0ciB8IE5vbmUsCiAgICBkZWZhdWx0X3ZhbHVlOiBzdHIsCiAgICB0aXRsZTogc3RyLAogICAgb3B0aW9uczogbGlzdFt0dXBsZVtzdHIsIHN0cl1dLAopIC0+IHN0cjoKICAgIGlmIGN1cnJlbnRfdmFsdWU6CiAgICAgICAgcmV0dXJuIGN1cnJlbnRfdmFsdWUKICAgIGlmIG5vdCBzeXMuc3RkaW4uaXNhdHR5KCk6CiAgICAgICAgcmV0dXJuIGRlZmF1bHRfdmFsdWUKCiAgICBwcmludChmIlxuW0NPTkZJR10ge3RpdGxlfSIpCiAgICBmb3IgaW5kZXgsIChfLCBkZXNjcmlwdGlvbikgaW4gZW51bWVyYXRlKG9wdGlvbnMsIHN0YXJ0PTEpOgogICAgICAgIHByaW50KGYiICB7aW5kZXh9KSB7ZGVzY3JpcHRpb259IikKICAgIHByaW50KGYiICBFbnRlciA9IHBhZHLDo28gKHtkZWZhdWx0X3ZhbHVlfSkiKQoKICAgIGFuc3dlciA9IGlucHV0KCI+IEVzY29saGE6ICIpLnN0cmlwKCkKICAgIGlmIG5vdCBhbnN3ZXI6CiAgICAgICAgcmV0dXJuIGRlZmF1bHRfdmFsdWUKICAgIGlmIGFuc3dlci5pc2RpZ2l0KCk6CiAgICAgICAgaWR4ID0gaW50KGFuc3dlcikgLSAxCiAgICAgICAgaWYgMCA8PSBpZHggPCBsZW4ob3B0aW9ucyk6CiAgICAgICAgICAgIHJldHVybiBvcHRpb25zW2lkeF1bMF0KICAgIGxvd2VyZWQgPSBhbnN3ZXIubG93ZXIoKQogICAgdmFsaWRfa2V5cyA9IHtrIGZvciBrLCBfIGluIG9wdGlvbnN9CiAgICBpZiBsb3dlcmVkIGluIHZhbGlkX2tleXM6CiAgICAgICAgcmV0dXJuIGxvd2VyZWQKICAgIHByaW50KGYiW0FWSVNPXSBPcMOnw6NvIGludsOhbGlkYSAne2Fuc3dlcn0nLiBVc2FuZG8gcGFkcsOjbzoge2RlZmF1bHRfdmFsdWV9IikKICAgIHJldHVybiBkZWZhdWx0X3ZhbHVlCgoKZGVmIHJlc29sdmVfZW1iZWRkaW5nX2NvbmZpZygKICAgIG1vZGVsX2Nob2ljZV9hcmc6IHN0ciB8IE5vbmUsCiAgICBqaW5hX3F1YW50aXphdGlvbl9hcmc6IHN0ciB8IE5vbmUsCiAgICBwZXJzaXN0ZWRfY29uZmlnOiBkaWN0W3N0ciwgb2JqZWN0XSB8IE5vbmUgPSBOb25lLAopIC0+IHR1cGxlW3N0ciwgc3RyXToKICAgIHBlcnNpc3RlZF9jb25maWcgPSBwZXJzaXN0ZWRfY29uZmlnIG9yIHt9CiAgICBtb2RlbF9jaG9pY2VfZnJvbV9jb25maWcgPSBwZXJzaXN0ZWRfY29uZmlnLmdldCgiZW1iZWRkaW5nX21vZGVsIikKICAgIG1vZGVsX2Nob2ljZSA9IG1vZGVsX2Nob2ljZV9hcmcgb3Igb3MuZW52aXJvbi5nZXQoIk1DUF9FTUJFRERJTkdfTU9ERUwiKQogICAgaWYgbm90IG1vZGVsX2Nob2ljZSBhbmQgaXNpbnN0YW5jZShtb2RlbF9jaG9pY2VfZnJvbV9jb25maWcsIHN0cik6CiAgICAgICAgbW9kZWxfY2hvaWNlID0gbW9kZWxfY2hvaWNlX2Zyb21fY29uZmlnCiAgICBpZiBtb2RlbF9jaG9pY2U6CiAgICAgICAgbW9kZWxfY2hvaWNlID0gbW9kZWxfY2hvaWNlLnN0cmlwKCkubG93ZXIoKQogICAgbW9kZWxfY2hvaWNlID0gX3BpY2tfd2l0aF9wcm9tcHQoCiAgICAgICAgY3VycmVudF92YWx1ZT1tb2RlbF9jaG9pY2UsCiAgICAgICAgZGVmYXVsdF92YWx1ZT1ERUZBVUxUX0VNQkVERElOR19NT0RFTF9DSE9JQ0UsCiAgICAgICAgdGl0bGU9IkVzY29saGEgZG8gbW9kZWxvIGRlIGVtYmVkZGluZ3MiLAogICAgICAgIG9wdGlvbnM9WwogICAgICAgICAgICAoCiAgICAgICAgICAgICAgICAiamluYSIsCiAgICAgICAgICAgICAgICBmImppbmEgKHtKSU5BX1YzX0VNQkVERElOR19NT0RFTH0pIC0gZm9jbyBlbSBjw7NkaWdvLiIsCiAgICAgICAgICAgICksCiAgICAgICAgICAgICgKICAgICAgICAgICAgICAgICJiZ2UiLAogICAgICAgICAgICAgICAgZiJiZ2UgKHtCR0VfRU1CRURESU5HX01PREVMfSkgLSBjb250ZcO6ZG8gbWlzdG8uIiwKICAgICAgICAgICAgKSwKICAgICAgICAgICAgKAogICAgICAgICAgICAgICAgImh5YnJpZCIsCiAgICAgICAgICAgICAgICBmImh5YnJpZCAoSmluYSB2MiB7SklOQV9WMl9FTUJFRERJTkdfTU9ERUx9ICsgQkdFKSAtIGR1YXMgY29sZcOnw7Vlcy4iLAogICAgICAgICAgICApLAogICAgICAgIF0sCiAgICApCiAgICBpZiBtb2RlbF9jaG9pY2Ugbm90IGluIHsiamluYSIsICJiZ2UiLCAiaHlicmlkIn06CiAgICAgICAgcHJpbnQoZiJbQVZJU09dIE1DUF9FTUJFRERJTkdfTU9ERUwgaW52w6FsaWRvICd7bW9kZWxfY2hvaWNlfScuIFVzYW5kbyAne0RFRkFVTFRfRU1CRURESU5HX01PREVMX0NIT0lDRX0nLiIpCiAgICAgICAgbW9kZWxfY2hvaWNlID0gREVGQVVMVF9FTUJFRERJTkdfTU9ERUxfQ0hPSUNFCgogICAgcXVhbnRpemF0aW9uX2Zyb21fY29uZmlnID0gcGVyc2lzdGVkX2NvbmZpZy5nZXQoImppbmFfcXVhbnRpemF0aW9uIikKICAgIGppbmFfcXVhbnRpemF0aW9uID0gamluYV9xdWFudGl6YXRpb25fYXJnIG9yIG9zLmVudmlyb24uZ2V0KCJNQ1BfSklOQV9RVUFOVElaQVRJT04iKQogICAgaWYgbm90IGppbmFfcXVhbnRpemF0aW9uIGFuZCBpc2luc3RhbmNlKHF1YW50aXphdGlvbl9mcm9tX2NvbmZpZywgc3RyKToKICAgICAgICBqaW5hX3F1YW50aXphdGlvbiA9IHF1YW50aXphdGlvbl9mcm9tX2NvbmZpZwogICAgaWYgamluYV9xdWFudGl6YXRpb246CiAgICAgICAgamluYV9xdWFudGl6YXRpb24gPSBqaW5hX3F1YW50aXphdGlvbi5zdHJpcCgpLmxvd2VyKCkucmVwbGFjZSgiXyIsICItIikKCiAgICBpZiBtb2RlbF9jaG9pY2UgPT0gImppbmEiOgogICAgICAgIGppbmFfcXVhbnRpemF0aW9uID0gX3BpY2tfd2l0aF9wcm9tcHQoCiAgICAgICAgICAgIGN1cnJlbnRfdmFsdWU9amluYV9xdWFudGl6YXRpb24sCiAgICAgICAgICAgIGRlZmF1bHRfdmFsdWU9REVGQVVMVF9KSU5BX1FVQU5USVpBVElPTiwKICAgICAgICAgICAgdGl0bGU9IlF1YW50aXphY2FvIGRvIEppbmEgKGFwZW5hcyBwYXJhIENQVSkiLAogICAgICAgICAgICBvcHRpb25zPVsKICAgICAgICAgICAgICAgICgiZGVmYXVsdCIsICJkZWZhdWx0IChzZW0gcXVhbnRpemFjYW8pIC0gbWFpb3IgcXVhbGlkYWRlLCBpbmRleGFjYW8gbWFpcyBsZW50YS4iKSwKICAgICAgICAgICAgICAgICgiZHluYW1pYy1pbnQ4IiwgImR5bmFtaWMtaW50OCAtIGluZGV4YWNhbyBtYWlzIHJhcGlkYSBlIG1lbm9yIHVzbyBkZSBSQU0sIGNvbSBwZXF1ZW5hIHBlcmRhIGRlIHF1YWxpZGFkZS4iKSwKICAgICAgICAgICAgXSwKICAgICAgICApCiAgICAgICAgaWYgamluYV9xdWFudGl6YXRpb24gbm90IGluIHsiZGVmYXVsdCIsICJkeW5hbWljLWludDgifToKICAgICAgICAgICAgcHJpbnQoCiAgICAgICAgICAgICAgICBmIltBVklTT10gTUNQX0pJTkFfUVVBTlRJWkFUSU9OIGludsOhbGlkbyAne2ppbmFfcXVhbnRpemF0aW9ufScuICIKICAgICAgICAgICAgICAgIGYiVXNhbmRvICd7REVGQVVMVF9KSU5BX1FVQU5USVpBVElPTn0nLiIKICAgICAgICAgICAgKQogICAgICAgICAgICBqaW5hX3F1YW50aXphdGlvbiA9IERFRkFVTFRfSklOQV9RVUFOVElaQVRJT04KICAgIGVsc2U6CiAgICAgICAgamluYV9xdWFudGl6YXRpb24gPSAiZGVmYXVsdCIKCiAgICByZXR1cm4gbW9kZWxfY2hvaWNlLCBqaW5hX3F1YW50aXphdGlvbgoKCmRlZiBsb2FkX2luZGV4ZXJfdHVuaW5nX2NvbmZpZyhmb3JjZV9yZWNvbmZpZ3VyZTogYm9vbCkgLT4gZGljdFtzdHIsIG9iamVjdF06CiAgICBpZiBmb3JjZV9yZWNvbmZpZ3VyZToKICAgICAgICByZXR1cm4ge30KICAgIHRyeToKICAgICAgICBpZiBub3QgSU5ERVhFUl9DT05GSUdfUEFUSC5leGlzdHMoKToKICAgICAgICAgICAgcmV0dXJuIHt9CiAgICAgICAgZGF0YSA9IGpzb24ubG9hZHMoSU5ERVhFUl9DT05GSUdfUEFUSC5yZWFkX3RleHQoZW5jb2Rpbmc9InV0Zi04IikpCiAgICAgICAgaWYgaXNpbnN0YW5jZShkYXRhLCBkaWN0KToKICAgICAgICAgICAgcmV0dXJuIGRhdGEKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcmV0dXJuIHt9CiAgICByZXR1cm4ge30KCgpkZWYgX3BlcnNpc3RfYmF0Y2hfdG9fY2xpX2NvbmZpZyhiYXRjaF9zaXplOiBpbnQpIC0+IE5vbmU6CiAgICBwYXlsb2FkID0gX2xvYWRfb3duX3JhZ19jbGlfY29uZmlnX3BheWxvYWQoKQogICAgY2hyb21hID0gcGF5bG9hZC5nZXQoImNocm9tYSIpCiAgICBpZiBub3QgaXNpbnN0YW5jZShjaHJvbWEsIGRpY3QpOgogICAgICAgIGNocm9tYSA9IHsKICAgICAgICAgICAgInNjaGVtZSI6IENIUk9NQV9TQ0hFTUUsCiAgICAgICAgICAgICJob3N0IjogQ0hST01BX0hPU1QsCiAgICAgICAgICAgICJwb3J0IjogQ0hST01BX1BPUlQsCiAgICAgICAgfQogICAgICAgIHBheWxvYWRbImNocm9tYSJdID0gY2hyb21hCgogICAgaW5kZXhpbmcgPSBwYXlsb2FkLmdldCgiaW5kZXhpbmciKQogICAgaWYgbm90IGlzaW5zdGFuY2UoaW5kZXhpbmcsIGRpY3QpOgogICAgICAgIGluZGV4aW5nID0ge30KICAgIGluZGV4aW5nWyJlbWJlZGRpbmdfYmF0Y2hfc2l6ZSJdID0gYmF0Y2hfc2l6ZQogICAgaW5kZXhpbmdbImJhdGNoX2NvdW50Il0gPSBiYXRjaF9zaXplCiAgICBwYXlsb2FkWyJpbmRleGluZyJdID0gaW5kZXhpbmcKCiAgICB0cnk6CiAgICAgICAgT1dOX1JBR19DTElfQ09ORklHX1BBVEgucGFyZW50Lm1rZGlyKHBhcmVudHM9VHJ1ZSwgZXhpc3Rfb2s9VHJ1ZSkKICAgICAgICBPV05fUkFHX0NMSV9DT05GSUdfUEFUSC53cml0ZV90ZXh0KAogICAgICAgICAgICBqc29uLmR1bXBzKHBheWxvYWQsIGVuc3VyZV9hc2NpaT1GYWxzZSwgaW5kZW50PTIpICsgIlxuIiwKICAgICAgICAgICAgZW5jb2Rpbmc9InV0Zi04IiwKICAgICAgICApCiAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgcHJpbnQoCiAgICAgICAgICAgIGYiW0FWSVNPXSBOw6NvIGZvaSBwb3Nzw612ZWwgYXR1YWxpemFyIGJhdGNoIGVtICIKICAgICAgICAgICAgZiJ7T1dOX1JBR19DTElfQ09ORklHX1BBVEh9OiB7X2Zvcm1hdF9leGNlcHRpb24oZSl9IgogICAgICAgICkKCgpkZWYgc2F2ZV9pbmRleGVyX3R1bmluZ19jb25maWcoY29uZmlnOiBkaWN0W3N0ciwgb2JqZWN0XSkgLT4gTm9uZToKICAgIGJhdGNoX3NpemUgPSBfcGFyc2VfcG9zaXRpdmVfaW50KGNvbmZpZy5nZXQoImVtYmVkZGluZ19iYXRjaF9zaXplIiksIG1pbl92YWx1ZT0xKQogICAgcGF5bG9hZCA9IHsKICAgICAgICAqKmNvbmZpZywKICAgICAgICAidXBkYXRlZF9hdCI6IGludCh0aW1lKCkpLAogICAgfQogICAgaWYgYmF0Y2hfc2l6ZSBpcyBub3QgTm9uZToKICAgICAgICBwYXlsb2FkWyJiYXRjaF9jb3VudCJdID0gYmF0Y2hfc2l6ZQoKICAgIHRyeToKICAgICAgICBJTkRFWEVSX0NPTkZJR19QQVRILnBhcmVudC5ta2RpcihwYXJlbnRzPVRydWUsIGV4aXN0X29rPVRydWUpCiAgICAgICAgSU5ERVhFUl9DT05GSUdfUEFUSC53cml0ZV90ZXh0KAogICAgICAgICAgICBqc29uLmR1bXBzKHBheWxvYWQsIGVuc3VyZV9hc2NpaT1GYWxzZSwgaW5kZW50PTIpICsgIlxuIiwKICAgICAgICAgICAgZW5jb2Rpbmc9InV0Zi04IiwKICAgICAgICApCiAgICAgICAgcHJpbnQoZiJbQ09ORklHXSBDb25maWd1cmHDp8OjbyBwZXJzaXN0aWRhIGVtOiB7SU5ERVhFUl9DT05GSUdfUEFUSH0iKQogICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgIHByaW50KGYiW0FWSVNPXSBOw6NvIGZvaSBwb3Nzw612ZWwgcGVyc2lzdGlyIGNvbmZpZ3VyYcOnw6NvIGVtIHtJTkRFWEVSX0NPTkZJR19QQVRIfToge19mb3JtYXRfZXhjZXB0aW9uKGUpfSIpCgogICAgaWYgYmF0Y2hfc2l6ZSBpcyBub3QgTm9uZToKICAgICAgICBfcGVyc2lzdF9iYXRjaF90b19jbGlfY29uZmlnKGJhdGNoX3NpemUpCgoKZGVmIHJlc29sdmVfcGVyZl9wcm9maWxlKHBlcmZfcHJvZmlsZV9hcmc6IHN0ciB8IE5vbmUsIHBlcnNpc3RlZF9jb25maWc6IGRpY3Rbc3RyLCBvYmplY3RdKSAtPiBzdHI6CiAgICBwcm9maWxlX2Zyb21fY29uZmlnID0gcGVyc2lzdGVkX2NvbmZpZy5nZXQoInBlcmZfcHJvZmlsZSIpCiAgICBwcm9maWxlID0gcGVyZl9wcm9maWxlX2FyZyBvciBvcy5lbnZpcm9uLmdldCgiTUNQX1BFUkZfUFJPRklMRSIpCiAgICBpZiBub3QgcHJvZmlsZSBhbmQgaXNpbnN0YW5jZShwcm9maWxlX2Zyb21fY29uZmlnLCBzdHIpOgogICAgICAgIHByb2ZpbGUgPSBwcm9maWxlX2Zyb21fY29uZmlnCiAgICBpZiBwcm9maWxlOgogICAgICAgIHByb2ZpbGUgPSBwcm9maWxlLnN0cmlwKCkubG93ZXIoKQoKICAgIHByb2ZpbGUgPSBfcGlja193aXRoX3Byb21wdCgKICAgICAgICBjdXJyZW50X3ZhbHVlPXByb2ZpbGUsCiAgICAgICAgZGVmYXVsdF92YWx1ZT1ERUZBVUxUX1BFUkZfUFJPRklMRSwKICAgICAgICB0aXRsZT0iUGVyZmlsIGRlIHBlcmZvcm1hbmNlIGRhIGluZGV4YcOnw6NvIiwKICAgICAgICBvcHRpb25zPVsKICAgICAgICAgICAgKAogICAgICAgICAgICAgICAgImF1dG90dW5lIiwKICAgICAgICAgICAgICAgICJhdXRvdHVuZSAtIGVxdWlsw61icmlvIChyZWNvbWVuZGFkbykuIiwKICAgICAgICAgICAgKSwKICAgICAgICAgICAgKAogICAgICAgICAgICAgICAgIm1heC1wZXJmb3JtYW5jZSIsCiAgICAgICAgICAgICAgICAibWF4LXBlcmZvcm1hbmNlIC0gbcOheGltbyB0aHJvdWdocHV0IChtYWlzIFJBTSkuIiwKICAgICAgICAgICAgKSwKICAgICAgICBdLAogICAgKQogICAgaWYgcHJvZmlsZSBub3QgaW4geyJhdXRvdHVuZSIsICJtYXgtcGVyZm9ybWFuY2UifToKICAgICAgICBwcmludChmIltBVklTT10gUGVyZmlsIGludsOhbGlkbyAne3Byb2ZpbGV9Jy4gVXNhbmRvICd7REVGQVVMVF9QRVJGX1BST0ZJTEV9Jy4iKQogICAgICAgIHByb2ZpbGUgPSBERUZBVUxUX1BFUkZfUFJPRklMRQogICAgcmV0dXJuIHByb2ZpbGUKCgpkZWYgX3BhcnNlX2NvbmZpZ19pbnQoY29uZmlnOiBkaWN0W3N0ciwgb2JqZWN0XSwga2V5OiBzdHIpIC0+IGludCB8IE5vbmU6CiAgICByYXcgPSBjb25maWcuZ2V0KGtleSkKICAgIGlmIGlzaW5zdGFuY2UocmF3LCBpbnQpOgogICAgICAgIHJldHVybiByYXcKICAgIGlmIGlzaW5zdGFuY2UocmF3LCBzdHIpIGFuZCByYXcuaXNkaWdpdCgpOgogICAgICAgIHJldHVybiBpbnQocmF3KQogICAgcmV0dXJuIE5vbmUKCgpkZWYgX3JlYWRfbWVtaW5mb19naWIoKSAtPiB0dXBsZVtmbG9hdCB8IE5vbmUsIGZsb2F0IHwgTm9uZSwgZmxvYXQgfCBOb25lXToKICAgICIiIlJldG9ybmEgKG1lbV90b3RhbCwgbWVtX2F2YWlsYWJsZSwgc3dhcF90b3RhbCkgZW0gR2lCLCBxdWFuZG8gZGlzcG9uw612ZWwuIiIiCiAgICBtZW1fdG90YWxfa2liOiBpbnQgfCBOb25lID0gTm9uZQogICAgbWVtX2F2YWlsYWJsZV9raWI6IGludCB8IE5vbmUgPSBOb25lCiAgICBzd2FwX3RvdGFsX2tpYjogaW50IHwgTm9uZSA9IE5vbmUKCiAgICB0cnk6CiAgICAgICAgZm9yIGxpbmUgaW4gUGF0aCgiL3Byb2MvbWVtaW5mbyIpLnJlYWRfdGV4dChlbmNvZGluZz0idXRmLTgiKS5zcGxpdGxpbmVzKCk6CiAgICAgICAgICAgIGlmIGxpbmUuc3RhcnRzd2l0aCgiTWVtVG90YWw6Iik6CiAgICAgICAgICAgICAgICBtZW1fdG90YWxfa2liID0gaW50KGxpbmUuc3BsaXQoKVsxXSkKICAgICAgICAgICAgZWxpZiBsaW5lLnN0YXJ0c3dpdGgoIk1lbUF2YWlsYWJsZToiKToKICAgICAgICAgICAgICAgIG1lbV9hdmFpbGFibGVfa2liID0gaW50KGxpbmUuc3BsaXQoKVsxXSkKICAgICAgICAgICAgZWxpZiBsaW5lLnN0YXJ0c3dpdGgoIlN3YXBUb3RhbDoiKToKICAgICAgICAgICAgICAgIHN3YXBfdG90YWxfa2liID0gaW50KGxpbmUuc3BsaXQoKVsxXSkKICAgIGV4Y2VwdCAoT1NFcnJvciwgVmFsdWVFcnJvciwgSW5kZXhFcnJvcik6CiAgICAgICAgcmV0dXJuIE5vbmUsIE5vbmUsIE5vbmUKCiAgICB0b19naWIgPSBsYW1iZGEga2liOiAoa2liIC8gKDEwMjQgKiAxMDI0KSkgaWYga2liIGlzIG5vdCBOb25lIGVsc2UgTm9uZQogICAgcmV0dXJuIHRvX2dpYihtZW1fdG90YWxfa2liKSwgdG9fZ2liKG1lbV9hdmFpbGFibGVfa2liKSwgdG9fZ2liKHN3YXBfdG90YWxfa2liKQoKCmRlZiB3YXJuX2lmX2ppbmFfbWVtb3J5X3Jpc2sobW9kZWxfY2hvaWNlOiBzdHIsIGppbmFfcXVhbnRpemF0aW9uOiBzdHIpIC0+IE5vbmU6CiAgICAiIiJNb3N0cmEgYXZpc28gZGUgcmlzY28gZGUgT09NIHBhcmEgbyBtb2RlbG8gSmluYSBlbSBtw6FxdWluYXMgY29tIHBvdWNhIG1lbcOzcmlhLiIiIgogICAgaWYgbW9kZWxfY2hvaWNlIG5vdCBpbiB7ImppbmEiLCAiaHlicmlkIn06CiAgICAgICAgcmV0dXJuCgogICAgbWVtX3RvdGFsX2dpYiwgbWVtX2F2YWlsYWJsZV9naWIsIHN3YXBfdG90YWxfZ2liID0gX3JlYWRfbWVtaW5mb19naWIoKQogICAgaWYgbWVtX3RvdGFsX2dpYiBpcyBOb25lOgogICAgICAgIHJldHVybgoKICAgIHJlY29tbWVuZGVkX3JhbV9naWIgPSAoCiAgICAgICAgSklOQV9SRUNPTU1FTkRFRF9SQU1fR0JfREVGQVVMVAogICAgICAgIGlmIGppbmFfcXVhbnRpemF0aW9uID09ICJkZWZhdWx0IgogICAgICAgIGVsc2UgSklOQV9SRUNPTU1FTkRFRF9SQU1fR0JfRFlOQU1JQ19JTlQ4CiAgICApCgogICAgcmVhc29uczogbGlzdFtzdHJdID0gW10KICAgIGlmIG1lbV90b3RhbF9naWIgPCByZWNvbW1lbmRlZF9yYW1fZ2liOgogICAgICAgIHJlYXNvbnMuYXBwZW5kKAogICAgICAgICAgICBmIlJBTSB0b3RhbCBkZXRlY3RhZGE6IHttZW1fdG90YWxfZ2liOi4xZn0gR2lCIChyZWNvbWVuZGFkbyA+PSB7cmVjb21tZW5kZWRfcmFtX2dpYn0gR2lCIHBhcmEgSmluYS97amluYV9xdWFudGl6YXRpb259KS4iCiAgICAgICAgKQogICAgaWYgc3dhcF90b3RhbF9naWIgaXMgbm90IE5vbmUgYW5kIHN3YXBfdG90YWxfZ2liIDwgSklOQV9SRUNPTU1FTkRFRF9TV0FQX0dCOgogICAgICAgIHJlYXNvbnMuYXBwZW5kKAogICAgICAgICAgICBmIlN3YXAgZGV0ZWN0YWRhOiB7c3dhcF90b3RhbF9naWI6LjFmfSBHaUIgKHJlY29tZW5kYWRvID49IHtKSU5BX1JFQ09NTUVOREVEX1NXQVBfR0J9IEdpQikuIgogICAgICAgICkKICAgIGlmIG1lbV9hdmFpbGFibGVfZ2liIGlzIG5vdCBOb25lIGFuZCBtZW1fYXZhaWxhYmxlX2dpYiA8IEpJTkFfTUlOX0FWQUlMQUJMRV9SQU1fR0JfSElOVDoKICAgICAgICByZWFzb25zLmFwcGVuZCgKICAgICAgICAgICAgZiJSQU0gbGl2cmUgYXR1YWw6IHttZW1fYXZhaWxhYmxlX2dpYjouMWZ9IEdpQiAoYmFpeG8gcGFyYSBhIGNhcmdhIGluaWNpYWwgZG8gSmluYSkuIgogICAgICAgICkKCiAgICBpZiBub3QgcmVhc29uczoKICAgICAgICByZXR1cm4KCiAgICBwcmludCgiW0FWSVNPXSBBbHRvIHJpc2NvIGRlIE9PTSBjb20gSmluYSBuZXN0YSBtw6FxdWluYS9jYXJnYS4iKQogICAgZm9yIHJlYXNvbiBpbiByZWFzb25zOgogICAgICAgIHByaW50KGYiICAgICAgICAtIHtyZWFzb259IikKICAgIHByaW50KCIgICAgICAgIC0gU2Ugb2NvcnJlciAnS2lsbGVkJyAoZXhpdCAxMzcpLCB1c2UgQkdFOiAtLWVtYmVkZGluZy1tb2RlbCBiZ2UiKQogICAgcHJpbnQoIiAgICAgICAgLSBPdSByb2RlIG8gSmluYSBlbSBtw6FxdWluYSBjb20gbWFpcyBSQU0vc3dhcCBlIG1lbm9zIHByb2Nlc3NvcyBjb25jb3JyZW50ZXMuIikKCgpAZGF0YWNsYXNzKGZyb3plbj1UcnVlKQpjbGFzcyBSdW50aW1lSW5kZXhpbmdQYXJhbXM6CiAgICBjaHVua19zaXplOiBpbnQKICAgIGNodW5rX292ZXJsYXA6IGludAogICAgZW1iZWRkaW5nX2JhdGNoX3NpemU6IGludAogICAgcmVhc29uczogbGlzdFtzdHJdCgoKZGVmIF9yZXNvbHZlX21heF9wZXJmb3JtYW5jZV9wYXJhbXMoCiAgICAqLAogICAgY2h1bmtfc2l6ZV9sb2NrZWQ6IGJvb2wsCiAgICBjaHVua19vdmVybGFwX2xvY2tlZDogYm9vbCwKICAgIGJhdGNoX3NpemVfbG9ja2VkOiBib29sLAogICAgY2h1bmtfc2l6ZTogaW50LAogICAgY2h1bmtfb3ZlcmxhcDogaW50LAogICAgZW1iZWRkaW5nX2JhdGNoX3NpemU6IGludCwKKSAtPiBSdW50aW1lSW5kZXhpbmdQYXJhbXM6CiAgICBtZW1fdG90YWxfZ2liLCBtZW1fYXZhaWxhYmxlX2dpYiwgXyA9IF9yZWFkX21lbWluZm9fZ2liKCkKICAgIHJlYXNvbnMgPSBbCiAgICAgICAgIlBlcmZpbCBzZWxlY2lvbmFkbzogbWF4LXBlcmZvcm1hbmNlLiIsCiAgICAgICAgIk1vZG8gcG9kZSBlbGV2YXIgY29uc2lkZXJhdmVsbWVudGUgbyBjb25zdW1vIGRlIG1lbcOzcmlhIGUgY2F1c2FyIGVuY2VycmFtZW50byBwb3IgT09NIChleGl0IDEzNykuIiwKICAgIF0KCiAgICB0dW5lZF9jaHVua19zaXplID0gY2h1bmtfc2l6ZQogICAgdHVuZWRfY2h1bmtfb3ZlcmxhcCA9IGNodW5rX292ZXJsYXAKICAgIHR1bmVkX2JhdGNoID0gZW1iZWRkaW5nX2JhdGNoX3NpemUKCiAgICBpZiBub3QgY2h1bmtfc2l6ZV9sb2NrZWQ6CiAgICAgICAgaWYgbWVtX3RvdGFsX2dpYiBpcyBub3QgTm9uZSBhbmQgbWVtX3RvdGFsX2dpYiA+PSA2NCBhbmQgKG1lbV9hdmFpbGFibGVfZ2liIG9yIDApID49IDE2OgogICAgICAgICAgICB0dW5lZF9jaHVua19zaXplID0gNzAwMAogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHR1bmVkX2NodW5rX3NpemUgPSA2MDAwCiAgICAgICAgcmVhc29ucy5hcHBlbmQoZiJjaHVua19zaXplIGFqdXN0YWRvIHBhcmEge3R1bmVkX2NodW5rX3NpemV9IG5vIHBlcmZpbCBtYXgtcGVyZm9ybWFuY2UuIikKCiAgICBpZiBub3QgY2h1bmtfb3ZlcmxhcF9sb2NrZWQ6CiAgICAgICAgdHVuZWRfY2h1bmtfb3ZlcmxhcCA9IG1pbih0dW5lZF9jaHVua19zaXplIC0gMSwgbWF4KDMwMCwgaW50KHR1bmVkX2NodW5rX3NpemUgKiAwLjE1KSkpCiAgICAgICAgcmVhc29ucy5hcHBlbmQoZiJjaHVua19vdmVybGFwIGFqdXN0YWRvIHBhcmEge3R1bmVkX2NodW5rX292ZXJsYXB9LiIpCgogICAgaWYgbm90IGJhdGNoX3NpemVfbG9ja2VkOgogICAgICAgIGlmIG1lbV90b3RhbF9naWIgaXMgbm90IE5vbmUgYW5kIG1lbV90b3RhbF9naWIgPj0gNjQgYW5kIChtZW1fYXZhaWxhYmxlX2dpYiBvciAwKSA+PSAxNjoKICAgICAgICAgICAgdHVuZWRfYmF0Y2ggPSAyNAogICAgICAgIGVsaWYgbWVtX3RvdGFsX2dpYiBpcyBub3QgTm9uZSBhbmQgbWVtX3RvdGFsX2dpYiA+PSAzMjoKICAgICAgICAgICAgdHVuZWRfYmF0Y2ggPSAxNgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHR1bmVkX2JhdGNoID0gMTIKICAgICAgICByZWFzb25zLmFwcGVuZChmImVtYmVkZGluZ19iYXRjaF9zaXplIGFqdXN0YWRvIHBhcmEge3R1bmVkX2JhdGNofS4iKQoKICAgIHJldHVybiBSdW50aW1lSW5kZXhpbmdQYXJhbXMoCiAgICAgICAgY2h1bmtfc2l6ZT10dW5lZF9jaHVua19zaXplLAogICAgICAgIGNodW5rX292ZXJsYXA9dHVuZWRfY2h1bmtfb3ZlcmxhcCwKICAgICAgICBlbWJlZGRpbmdfYmF0Y2hfc2l6ZT1tYXgoMSwgdHVuZWRfYmF0Y2gpLAogICAgICAgIHJlYXNvbnM9cmVhc29ucywKICAgICkKCgpkZWYgX3Jlc29sdmVfYXV0b3R1bmVkX3BhcmFtcygKICAgICosCiAgICBtb2RlbDogU2VudGVuY2VUcmFuc2Zvcm1lciwKICAgIGNodW5rX3NpemVfbG9ja2VkOiBib29sLAogICAgY2h1bmtfb3ZlcmxhcF9sb2NrZWQ6IGJvb2wsCiAgICBiYXRjaF9zaXplX2xvY2tlZDogYm9vbCwKICAgIGNodW5rX3NpemU6IGludCwKICAgIGNodW5rX292ZXJsYXA6IGludCwKICAgIGVtYmVkZGluZ19iYXRjaF9zaXplOiBpbnQsCikgLT4gUnVudGltZUluZGV4aW5nUGFyYW1zOgogICAgcmVhc29uczogbGlzdFtzdHJdID0gWyJQZXJmaWwgc2VsZWNpb25hZG86IGF1dG90dW5lIChjdXN0by1iZW5lZsOtY2lvKS4iXQogICAgdmVyYm9zZV9hdXRvdHVuZSA9IF9lbnZfYm9vbCgiTUNQX0FVVE9UVU5FX1ZFUkJPU0UiLCBkZWZhdWx0PUZhbHNlKQoKICAgIHRyeToKICAgICAgICBpbXBvcnQgcHN1dGlsICAjIHR5cGU6IGlnbm9yZQogICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICByZWFzb25zLmFwcGVuZCgicHN1dGlsIGluZGlzcG9uw612ZWw7IG1hbnRlbmRvIHBhcsOibWV0cm9zIGF0dWFpcyBzZW0gYmVuY2htYXJrLiIpCiAgICAgICAgcmV0dXJuIFJ1bnRpbWVJbmRleGluZ1BhcmFtcygKICAgICAgICAgICAgY2h1bmtfc2l6ZT1jaHVua19zaXplLAogICAgICAgICAgICBjaHVua19vdmVybGFwPWNodW5rX292ZXJsYXAsCiAgICAgICAgICAgIGVtYmVkZGluZ19iYXRjaF9zaXplPWVtYmVkZGluZ19iYXRjaF9zaXplLAogICAgICAgICAgICByZWFzb25zPXJlYXNvbnMsCiAgICAgICAgKQoKICAgIHZtID0gcHN1dGlsLnZpcnR1YWxfbWVtb3J5KCkKICAgIHN3YXAgPSBwc3V0aWwuc3dhcF9tZW1vcnkoKQogICAgbWVtX3RvdGFsX2dpYiA9IHZtLnRvdGFsIC8gKDEwMjQqKjMpCiAgICBtZW1fYXZhaWxhYmxlX2dpYiA9IHZtLmF2YWlsYWJsZSAvICgxMDI0KiozKQogICAgc3dhcF90b3RhbF9naWIgPSBzd2FwLnRvdGFsIC8gKDEwMjQqKjMpCgogICAgdGFyZ2V0X3JhbV9wZXJjZW50ID0gX2NsYW1wKAogICAgICAgIGZsb2F0KG9zLmVudmlyb24uZ2V0KCJNQ1BfQVVUT1RVTkVfVEFSR0VUX1JBTV9QRVJDRU5UIiwgIjY4IikpLAogICAgICAgIDYwLjAsCiAgICAgICAgNzUuMCwKICAgICkKICAgIGlmIG1lbV9hdmFpbGFibGVfZ2liIDwgNiBvciBzd2FwX3RvdGFsX2dpYiA8IDQ6CiAgICAgICAgdGFyZ2V0X3JhbV9wZXJjZW50ID0gbWluKHRhcmdldF9yYW1fcGVyY2VudCwgNjMuMCkKICAgIHJlYXNvbnMuYXBwZW5kKAogICAgICAgIGYiTWVtw7NyaWEgZGV0ZWN0YWRhOiB0b3RhbD17bWVtX3RvdGFsX2dpYjouMWZ9IEdpQiwgbGl2cmU9e21lbV9hdmFpbGFibGVfZ2liOi4xZn0gR2lCLCAiCiAgICAgICAgZiJzd2FwPXtzd2FwX3RvdGFsX2dpYjouMWZ9IEdpQiwgYWx2bz17dGFyZ2V0X3JhbV9wZXJjZW50Oi4xZn0lLiIKICAgICkKCiAgICB0dW5lZF9jaHVua19zaXplID0gY2h1bmtfc2l6ZQogICAgdHVuZWRfY2h1bmtfb3ZlcmxhcCA9IGNodW5rX292ZXJsYXAKICAgIHR1bmVkX2JhdGNoID0gZW1iZWRkaW5nX2JhdGNoX3NpemUKCiAgICBpZiBub3QgY2h1bmtfc2l6ZV9sb2NrZWQ6CiAgICAgICAgaWYgbWVtX3RvdGFsX2dpYiA8IDggb3IgbWVtX2F2YWlsYWJsZV9naWIgPCAzOgogICAgICAgICAgICB0dW5lZF9jaHVua19zaXplID0gMTgwMAogICAgICAgIGVsaWYgbWVtX3RvdGFsX2dpYiA8IDE2IG9yIG1lbV9hdmFpbGFibGVfZ2liIDwgNjoKICAgICAgICAgICAgdHVuZWRfY2h1bmtfc2l6ZSA9IDI0MDAKICAgICAgICBlbGlmIG1lbV90b3RhbF9naWIgPCAzMiBvciBtZW1fYXZhaWxhYmxlX2dpYiA8IDEyOgogICAgICAgICAgICB0dW5lZF9jaHVua19zaXplID0gMzIwMAogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHR1bmVkX2NodW5rX3NpemUgPSA0MjAwCiAgICAgICAgcmVhc29ucy5hcHBlbmQoZiJjaHVua19zaXplIGF1dG90dW5hZG8gcGFyYSB7dHVuZWRfY2h1bmtfc2l6ZX0uIikKCiAgICBpZiBub3QgY2h1bmtfb3ZlcmxhcF9sb2NrZWQ6CiAgICAgICAgdHVuZWRfY2h1bmtfb3ZlcmxhcCA9IG1pbih0dW5lZF9jaHVua19zaXplIC0gMSwgbWF4KDEyMCwgaW50KHR1bmVkX2NodW5rX3NpemUgKiAwLjE1KSkpCiAgICAgICAgcmVhc29ucy5hcHBlbmQoZiJjaHVua19vdmVybGFwIGF1dG90dW5hZG8gcGFyYSB7dHVuZWRfY2h1bmtfb3ZlcmxhcH0uIikKCiAgICBpZiBub3QgYmF0Y2hfc2l6ZV9sb2NrZWQ6CiAgICAgICAgbWF4X2NhbmRpZGF0ZSA9IDE2CiAgICAgICAgaWYgbWVtX3RvdGFsX2dpYiA8IDggb3IgbWVtX2F2YWlsYWJsZV9naWIgPCAzIG9yIHN3YXBfdG90YWxfZ2liIDwgMjoKICAgICAgICAgICAgbWF4X2NhbmRpZGF0ZSA9IDIKICAgICAgICBlbGlmIG1lbV90b3RhbF9naWIgPCAxNiBvciBtZW1fYXZhaWxhYmxlX2dpYiA8IDY6CiAgICAgICAgICAgIG1heF9jYW5kaWRhdGUgPSA0CiAgICAgICAgZWxpZiBtZW1fdG90YWxfZ2liIDwgMzIgb3IgbWVtX2F2YWlsYWJsZV9naWIgPCAxMDoKICAgICAgICAgICAgbWF4X2NhbmRpZGF0ZSA9IDgKCiAgICAgICAgY2FuZGlkYXRlcyA9IFsyLCA0LCA2LCA4LCAxMiwgMTZdCiAgICAgICAgY2FuZGlkYXRlcyA9IFtjIGZvciBjIGluIGNhbmRpZGF0ZXMgaWYgYyA8PSBtYXhfY2FuZGlkYXRlXQogICAgICAgIGlmIG5vdCBjYW5kaWRhdGVzOgogICAgICAgICAgICBjYW5kaWRhdGVzID0gWzJdCgogICAgICAgIHByb2Nlc3MgPSBwc3V0aWwuUHJvY2VzcygpCiAgICAgICAgc2FtcGxlX3NpemUgPSBtaW4obWF4KDUxMiwgdHVuZWRfY2h1bmtfc2l6ZSksIDMwMDApCiAgICAgICAgc2FtcGxlX3RleHQgPSAoIiMgYXV0b3R1bmUtc2FtcGxlXG4iICsgKCJ4IiAqIHNhbXBsZV9zaXplKSkKCiAgICAgICAgYmVzdF9iYXRjaCA9IGNhbmRpZGF0ZXNbMF0KICAgICAgICBiZXN0X3Njb3JlID0gLTEuMAogICAgICAgIGJlc3RfbWVtb3J5X3BjdCA9IDEwMC4wCiAgICAgICAgc2VsZWN0ZWRfYmVuY2htYXJrX2xpbmU6IHN0ciB8IE5vbmUgPSBOb25lCiAgICAgICAgYmVuY2htYXJrX2xpbmVzOiBsaXN0W3N0cl0gPSBbXQoKICAgICAgICAjIFdhcm11cCBjdXJ0byBwYXJhIGVzdGFiaWxpemFyIGNhY2hlIGludGVybm8uCiAgICAgICAgdHJ5OgogICAgICAgICAgICBfID0gbW9kZWwuZW5jb2RlKFtzYW1wbGVfdGV4dF0sIHNob3dfcHJvZ3Jlc3NfYmFyPUZhbHNlLCBiYXRjaF9zaXplPTEpCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICAgICAgcGFzcwoKICAgICAgICBmb3IgY2FuZGlkYXRlIGluIGNhbmRpZGF0ZXM6CiAgICAgICAgICAgIGRvY3MgPSBbc2FtcGxlX3RleHRdICogY2FuZGlkYXRlCiAgICAgICAgICAgIGdjLmNvbGxlY3QoKQogICAgICAgICAgICBiZWZvcmVfdm0gPSBwc3V0aWwudmlydHVhbF9tZW1vcnkoKS5wZXJjZW50CiAgICAgICAgICAgIGJlZm9yZV9yc3MgPSBwcm9jZXNzLm1lbW9yeV9pbmZvKCkucnNzIC8gKDEwMjQqKjIpCiAgICAgICAgICAgIHN0YXJ0ZWQgPSBwZXJmX2NvdW50ZXIoKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBlbWJlZGRpbmdzID0gbW9kZWwuZW5jb2RlKAogICAgICAgICAgICAgICAgICAgIGRvY3MsCiAgICAgICAgICAgICAgICAgICAgc2hvd19wcm9ncmVzc19iYXI9RmFsc2UsCiAgICAgICAgICAgICAgICAgICAgYmF0Y2hfc2l6ZT1jYW5kaWRhdGUsCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICAgICAgICAgIGJlbmNobWFya19saW5lcy5hcHBlbmQoZiJiYXRjaD17Y2FuZGlkYXRlfTogZXJybyAoe2V9KSIpCiAgICAgICAgICAgICAgICBjb250aW51ZQoKICAgICAgICAgICAgZWxhcHNlZCA9IG1heChwZXJmX2NvdW50ZXIoKSAtIHN0YXJ0ZWQsIDFlLTYpCiAgICAgICAgICAgIGFmdGVyX3ZtID0gcHN1dGlsLnZpcnR1YWxfbWVtb3J5KCkucGVyY2VudAogICAgICAgICAgICBhZnRlcl9yc3MgPSBwcm9jZXNzLm1lbW9yeV9pbmZvKCkucnNzIC8gKDEwMjQqKjIpCiAgICAgICAgICAgIGRlbCBlbWJlZGRpbmdzCiAgICAgICAgICAgIGdjLmNvbGxlY3QoKQoKICAgICAgICAgICAgdGhyb3VnaHB1dCA9IGNhbmRpZGF0ZSAvIGVsYXBzZWQKICAgICAgICAgICAgc2FmZSA9IGFmdGVyX3ZtIDw9ICh0YXJnZXRfcmFtX3BlcmNlbnQgKyAzLjApCiAgICAgICAgICAgIGJlbmNobWFya19saW5lcy5hcHBlbmQoCiAgICAgICAgICAgICAgICBmImJhdGNoPXtjYW5kaWRhdGV9OiB7dGhyb3VnaHB1dDouMmZ9IGl0ZW5zL3MsIHZtPXthZnRlcl92bTouMWZ9JSwgcnNzX2RlbHRhPXthZnRlcl9yc3MgLSBiZWZvcmVfcnNzOisuMWZ9IE1pQiIKICAgICAgICAgICAgKQoKICAgICAgICAgICAgaWYgc2FmZSBhbmQgdGhyb3VnaHB1dCA+IGJlc3Rfc2NvcmU6CiAgICAgICAgICAgICAgICBiZXN0X3Njb3JlID0gdGhyb3VnaHB1dAogICAgICAgICAgICAgICAgYmVzdF9iYXRjaCA9IGNhbmRpZGF0ZQogICAgICAgICAgICAgICAgYmVzdF9tZW1vcnlfcGN0ID0gYWZ0ZXJfdm0KICAgICAgICAgICAgICAgIHNlbGVjdGVkX2JlbmNobWFya19saW5lID0gYmVuY2htYXJrX2xpbmVzWy0xXQogICAgICAgICAgICBlbGlmIGJlc3Rfc2NvcmUgPCAwIGFuZCBhZnRlcl92bSA8IGJlc3RfbWVtb3J5X3BjdDoKICAgICAgICAgICAgICAgICMgU2UgbmVuaHVtIGNhbmRpZGF0byBmaWNvdSAic2FmZSIsIGVzY29saGUgbyBtZW5vcyBhZ3Jlc3Npdm8gZW0gbWVtw7NyaWEuCiAgICAgICAgICAgICAgICBiZXN0X2JhdGNoID0gY2FuZGlkYXRlCiAgICAgICAgICAgICAgICBiZXN0X21lbW9yeV9wY3QgPSBhZnRlcl92bQogICAgICAgICAgICAgICAgc2VsZWN0ZWRfYmVuY2htYXJrX2xpbmUgPSBiZW5jaG1hcmtfbGluZXNbLTFdCgogICAgICAgICAgICAjIFNlIGrDoSBwYXNzb3UgbXVpdG8gZG8gbGltaXRlLCBldml0YSB0ZW50YXIgYmF0Y2hlcyBtYWlvcmVzLgogICAgICAgICAgICBpZiBhZnRlcl92bSA+IHRhcmdldF9yYW1fcGVyY2VudCArIDguMDoKICAgICAgICAgICAgICAgIGJyZWFrCgogICAgICAgICAgICAjIEV2aXRhIGVzY29saGVyIGNhbmRpZGF0byBxdWUgasOhIGNvbWXDp291IGFjaW1hIGRvIGxpbWl0ZS4KICAgICAgICAgICAgaWYgYmVmb3JlX3ZtID4gdGFyZ2V0X3JhbV9wZXJjZW50ICsgNS4wOgogICAgICAgICAgICAgICAgYnJlYWsKCiAgICAgICAgdHVuZWRfYmF0Y2ggPSBtYXgoMSwgYmVzdF9iYXRjaCkKICAgICAgICBpZiB2ZXJib3NlX2F1dG90dW5lOgogICAgICAgICAgICByZWFzb25zLmV4dGVuZChiZW5jaG1hcmtfbGluZXMpCiAgICAgICAgZWxpZiBzZWxlY3RlZF9iZW5jaG1hcmtfbGluZToKICAgICAgICAgICAgcmVhc29ucy5hcHBlbmQoZiJNaWNyby1iZW5jaG1hcms6IHtzZWxlY3RlZF9iZW5jaG1hcmtfbGluZX0iKQogICAgICAgIHJlYXNvbnMuYXBwZW5kKAogICAgICAgICAgICBmImVtYmVkZGluZ19iYXRjaF9zaXplIGF1dG90dW5hZG8gcGFyYSB7dHVuZWRfYmF0Y2h9IChhbHZvIGRlIG1lbcOzcmlhOiB7dGFyZ2V0X3JhbV9wZXJjZW50Oi4xZn0lKS4iCiAgICAgICAgKQoKICAgIHJldHVybiBSdW50aW1lSW5kZXhpbmdQYXJhbXMoCiAgICAgICAgY2h1bmtfc2l6ZT10dW5lZF9jaHVua19zaXplLAogICAgICAgIGNodW5rX292ZXJsYXA9dHVuZWRfY2h1bmtfb3ZlcmxhcCwKICAgICAgICBlbWJlZGRpbmdfYmF0Y2hfc2l6ZT1tYXgoMSwgdHVuZWRfYmF0Y2gpLAogICAgICAgIHJlYXNvbnM9cmVhc29ucywKICAgICkKCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIEZ1bsOnw7VlcyBhdXhpbGlhcmVzCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpkZWYgZ2V0X3RleHRfc3BsaXR0ZXIoY2h1bmtfc2l6ZTogaW50LCBjaHVua19vdmVybGFwOiBpbnQpIC0+IFJlY3Vyc2l2ZUNoYXJhY3RlclRleHRTcGxpdHRlcjoKICAgICIiIlJldG9ybmEgbyBzcGxpdHRlciBjb21wYXJ0aWxoYWRvIGNvbSBhcyBjb25maWd1cmHDp8O1ZXMgcGFkcsOjbyBkbyBwcm9qZXRvLiIiIgogICAgcmV0dXJuIFJlY3Vyc2l2ZUNoYXJhY3RlclRleHRTcGxpdHRlcigKICAgICAgICBjaHVua19zaXplPWNodW5rX3NpemUsCiAgICAgICAgY2h1bmtfb3ZlcmxhcD1jaHVua19vdmVybGFwLAogICAgICAgIGxlbmd0aF9mdW5jdGlvbj1sZW4sCiAgICAgICAgc2VwYXJhdG9ycz1bIlxuXG4iLCAiXG4iLCAiICIsICIiXSwKICAgICkKCgpkZWYgbG9hZF9lbWJlZGRpbmdfbW9kZWwobW9kZWxfY2hvaWNlOiBzdHIsIGppbmFfcXVhbnRpemF0aW9uOiBzdHIpIC0+IFNlbnRlbmNlVHJhbnNmb3JtZXI6CiAgICAiIiJDYXJyZWdhIG8gbW9kZWxvIGRlIGVtYmVkZGluZ3MgZm9yw6dhbmRvIHVzbyBkZSBDUFUuIiIiCiAgICBlbWJlZGRpbmdfbW9kZWxfaWQgPSBfcmVzb2x2ZV9tb2RlbF9pZChtb2RlbF9jaG9pY2UpCiAgICBmYWxsYmFja19tb2RlbF9pZCA9IF9yZXNvbHZlX2ZhbGxiYWNrX21vZGVsX2lkKG1vZGVsX2Nob2ljZSkKCiAgICBtb2RlbF9iYXNlX2RpciA9IE1PREVMX0NBQ0hFX0JBU0VfRElSCiAgICBtb2RlbF9iYXNlX2Rpci5ta2RpcihwYXJlbnRzPVRydWUsIGV4aXN0X29rPVRydWUpCiAgICBwcmVmZXJyZWRfbW9kZWxfY2FjaGVfZGlyID0gX21vZGVsX2NhY2hlX2Rpcihtb2RlbF9iYXNlX2RpciwgZW1iZWRkaW5nX21vZGVsX2lkKQoKICAgIHByaW50KGYiWytdIEJhaXhhbmRvIG1vZGVsbyBwcmVmZXJpZG86IHtlbWJlZGRpbmdfbW9kZWxfaWR9IikKICAgIHByaW50KGYiWytdIERpcmV0w7NyaW8gZGUgZG93bmxvYWQvY2FjaGUgZG8gbW9kZWxvOiB7cHJlZmVycmVkX21vZGVsX2NhY2hlX2Rpcn0iKQogICAgc2VsZWN0aW9uID0gZG93bmxvYWRfbW9kZWxfd2l0aF9mYWxsYmFjaygKICAgICAgICBwcmVmZXJyZWRfbW9kZWxfaWQ9ZW1iZWRkaW5nX21vZGVsX2lkLAogICAgICAgIGZhbGxiYWNrX21vZGVsX2lkPWZhbGxiYWNrX21vZGVsX2lkLAogICAgICAgIGxvY2FsX2Rpcj1tb2RlbF9iYXNlX2RpciwKICAgICkKICAgIHNlbGVjdGVkX21vZGVsX2RpciA9IHNlbGVjdGlvbi5sb2NhbF9kaXIKICAgIHByaW50KAogICAgICAgIGYiWytdIE1vZGVsbyBzZWxlY2lvbmFkbzoge3NlbGVjdGlvbi5tb2RlbF9pZH0gIgogICAgICAgIGYiKHByb3ZpZGVyPXtzZWxlY3Rpb24ucHJvdmlkZXJ9LCBwYXRoPXtzZWxlY3RlZF9tb2RlbF9kaXJ9KSIKICAgICkKCiAgICBkZWYgX2NsZWFyX2hmX2R5bmFtaWNfbW9kdWxlc19jYWNoZSgpIC0+IE5vbmU6CiAgICAgICAgY2FjaGVfZGlyID0gUGF0aC5ob21lKCkgLyAiLmNhY2hlIiAvICJodWdnaW5nZmFjZSIgLyAibW9kdWxlcyIgLyAidHJhbnNmb3JtZXJzX21vZHVsZXMiCiAgICAgICAgaWYgY2FjaGVfZGlyLmV4aXN0cygpOgogICAgICAgICAgICBwcmludChmIlshXSBMaW1wYW5kbyBjYWNoZSBkZSBtw7NkdWxvcyBkaW7Dom1pY29zIGRvIEh1Z2dpbmcgRmFjZToge2NhY2hlX2Rpcn0iKQogICAgICAgICAgICBzaHV0aWwucm10cmVlKGNhY2hlX2RpciwgaWdub3JlX2Vycm9ycz1UcnVlKQoKICAgIGRlZiBfbG9hZF9mcm9tX2xvY2FsX2Rpcihtb2RlbF9pZDogc3RyKSAtPiBTZW50ZW5jZVRyYW5zZm9ybWVyOgogICAgICAgICMgTyBtb2RlbG8gZGEgSmluYSBkZXBlbmRlIGRlIGPDs2RpZ28gcmVtb3RvOyBmYWxsYmFjayBub3JtYWxtZW50ZSBuw6NvLgogICAgICAgIHRydXN0X3JlbW90ZV9jb2RlID0gbW9kZWxfaWQuc3RhcnRzd2l0aCgiamluYWFpLyIpCiAgICAgICAgdG9rZW5pemVyX2t3YXJncyA9IHsiZml4X21pc3RyYWxfcmVnZXgiOiBUcnVlfQoKICAgICAgICBkZWYgX2luc3RhbnRpYXRlX21vZGVsKCkgLT4gU2VudGVuY2VUcmFuc2Zvcm1lcjoKICAgICAgICAgICAgcmV0dXJuIFNlbnRlbmNlVHJhbnNmb3JtZXIoCiAgICAgICAgICAgICAgICBzdHIoc2VsZWN0ZWRfbW9kZWxfZGlyKSwKICAgICAgICAgICAgICAgIGRldmljZT0iY3B1IiwKICAgICAgICAgICAgICAgIHRydXN0X3JlbW90ZV9jb2RlPXRydXN0X3JlbW90ZV9jb2RlLAogICAgICAgICAgICAgICAgdG9rZW5pemVyX2t3YXJncz10b2tlbml6ZXJfa3dhcmdzLAogICAgICAgICAgICApCgogICAgICAgIGRlZiBfbG9hZF93aXRoX21pc3RyYWxfcmVnZXhfcGF0Y2goKSAtPiBTZW50ZW5jZVRyYW5zZm9ybWVyOgogICAgICAgICAgICAjIE8gY8OzZGlnbyByZW1vdG8gZGEgSmluYSBpbnN0YW5jaWEgdW0gdG9rZW5pemVyIGludGVybm8gc2VtIHJlcGFzc2FyIHRva2VuaXplcl9rd2FyZ3MuCiAgICAgICAgICAgIGlmIG5vdCB0cnVzdF9yZW1vdGVfY29kZToKICAgICAgICAgICAgICAgIHJldHVybiBfaW5zdGFudGlhdGVfbW9kZWwoKQoKICAgICAgICAgICAgZnJvbSB0cmFuc2Zvcm1lcnMgaW1wb3J0IEF1dG9Nb2RlbCwgQXV0b1Rva2VuaXplcgogICAgICAgICAgICBmcm9tIHRyYW5zZm9ybWVycy5tb2RlbGluZ191dGlscyBpbXBvcnQgUHJlVHJhaW5lZE1vZGVsCgogICAgICAgICAgICBvcmlnaW5hbF9mcm9tX3ByZXRyYWluZWQgPSBBdXRvVG9rZW5pemVyLmZyb21fcHJldHJhaW5lZAogICAgICAgICAgICBvcmlnaW5hbF9tb2RlbF9mcm9tX3ByZXRyYWluZWQgPSBBdXRvTW9kZWwuZnJvbV9wcmV0cmFpbmVkCiAgICAgICAgICAgIG9yaWdpbmFsX3ByZXRyYWluZWRfbW9kZWxfZnJvbV9wcmV0cmFpbmVkID0gUHJlVHJhaW5lZE1vZGVsLmZyb21fcHJldHJhaW5lZAogICAgICAgICAgICBvcmlnaW5hbF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fY29uZmlnID0gUHJlVHJhaW5lZE1vZGVsLl9mcm9tX2NvbmZpZwogICAgICAgICAgICBtb2RlbF9yZWZzID0ge3N0cihzZWxlY3RlZF9tb2RlbF9kaXIpLCBzdHIoc2VsZWN0ZWRfbW9kZWxfZGlyLnJlc29sdmUoKSl9CgogICAgICAgICAgICBkZWYgX3BhdGNoZWRfZnJvbV9wcmV0cmFpbmVkKCphcmdzLCAqKmt3YXJncyk6CiAgICAgICAgICAgICAgICBtb2RlbF9yZWYgPSBhcmdzWzBdIGlmIGFyZ3MgZWxzZSBrd2FyZ3MuZ2V0KCJwcmV0cmFpbmVkX21vZGVsX25hbWVfb3JfcGF0aCIpCiAgICAgICAgICAgICAgICBpZiBtb2RlbF9yZWYgaXMgbm90IE5vbmUgYW5kIHN0cihtb2RlbF9yZWYpIGluIG1vZGVsX3JlZnM6CiAgICAgICAgICAgICAgICAgICAga3dhcmdzLnNldGRlZmF1bHQoImZpeF9taXN0cmFsX3JlZ2V4IiwgVHJ1ZSkKICAgICAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbF9mcm9tX3ByZXRyYWluZWQoKmFyZ3MsICoqa3dhcmdzKQoKICAgICAgICAgICAgZGVmIF9wYXRjaGVkX21vZGVsX2Zyb21fcHJldHJhaW5lZCgqYXJncywgKiprd2FyZ3MpOgogICAgICAgICAgICAgICAgbW9kZWxfcmVmID0gYXJnc1swXSBpZiBhcmdzIGVsc2Uga3dhcmdzLmdldCgicHJldHJhaW5lZF9tb2RlbF9uYW1lX29yX3BhdGgiKQogICAgICAgICAgICAgICAgaWYgbW9kZWxfcmVmIGlzIG5vdCBOb25lIGFuZCBzdHIobW9kZWxfcmVmKSBpbiBtb2RlbF9yZWZzIGFuZCAidG9yY2hfZHR5cGUiIGluIGt3YXJnczoKICAgICAgICAgICAgICAgICAgICBrd2FyZ3MgPSBkaWN0KGt3YXJncykKICAgICAgICAgICAgICAgICAgICBpZiAiZHR5cGUiIG5vdCBpbiBrd2FyZ3M6CiAgICAgICAgICAgICAgICAgICAgICAgIGt3YXJnc1siZHR5cGUiXSA9IGt3YXJnc1sidG9yY2hfZHR5cGUiXQogICAgICAgICAgICAgICAgICAgIGt3YXJncy5wb3AoInRvcmNoX2R0eXBlIiwgTm9uZSkKICAgICAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbF9tb2RlbF9mcm9tX3ByZXRyYWluZWQoKmFyZ3MsICoqa3dhcmdzKQoKICAgICAgICAgICAgb3JpZ2luYWxfcHJldHJhaW5lZF9tb2RlbF9mcm9tX3ByZXRyYWluZWRfZm4gPSBvcmlnaW5hbF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fcHJldHJhaW5lZC5fX2Z1bmNfXwoKICAgICAgICAgICAgQGNsYXNzbWV0aG9kCiAgICAgICAgICAgIGRlZiBfcGF0Y2hlZF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fcHJldHJhaW5lZChjbHMsICphcmdzLCAqKmt3YXJncyk6CiAgICAgICAgICAgICAgICBpZiAidG9yY2hfZHR5cGUiIGluIGt3YXJnczoKICAgICAgICAgICAgICAgICAgICBrd2FyZ3MgPSBkaWN0KGt3YXJncykKICAgICAgICAgICAgICAgICAgICBpZiAiZHR5cGUiIG5vdCBpbiBrd2FyZ3M6CiAgICAgICAgICAgICAgICAgICAgICAgIGt3YXJnc1siZHR5cGUiXSA9IGt3YXJnc1sidG9yY2hfZHR5cGUiXQogICAgICAgICAgICAgICAgICAgIGt3YXJncy5wb3AoInRvcmNoX2R0eXBlIiwgTm9uZSkKICAgICAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fcHJldHJhaW5lZF9mbihjbHMsICphcmdzLCAqKmt3YXJncykKCiAgICAgICAgICAgIG9yaWdpbmFsX3ByZXRyYWluZWRfbW9kZWxfZnJvbV9jb25maWdfZm4gPSBvcmlnaW5hbF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fY29uZmlnLl9fZnVuY19fCgogICAgICAgICAgICBAY2xhc3NtZXRob2QKICAgICAgICAgICAgZGVmIF9wYXRjaGVkX3ByZXRyYWluZWRfbW9kZWxfZnJvbV9jb25maWcoY2xzLCAqYXJncywgKiprd2FyZ3MpOgogICAgICAgICAgICAgICAgaWYgInRvcmNoX2R0eXBlIiBpbiBrd2FyZ3M6CiAgICAgICAgICAgICAgICAgICAga3dhcmdzID0gZGljdChrd2FyZ3MpCiAgICAgICAgICAgICAgICAgICAgaWYgImR0eXBlIiBub3QgaW4ga3dhcmdzOgogICAgICAgICAgICAgICAgICAgICAgICBrd2FyZ3NbImR0eXBlIl0gPSBrd2FyZ3NbInRvcmNoX2R0eXBlIl0KICAgICAgICAgICAgICAgICAgICBrd2FyZ3MucG9wKCJ0b3JjaF9kdHlwZSIsIE5vbmUpCiAgICAgICAgICAgICAgICByZXR1cm4gb3JpZ2luYWxfcHJldHJhaW5lZF9tb2RlbF9mcm9tX2NvbmZpZ19mbihjbHMsICphcmdzLCAqKmt3YXJncykKCiAgICAgICAgICAgIEF1dG9Ub2tlbml6ZXIuZnJvbV9wcmV0cmFpbmVkID0gX3BhdGNoZWRfZnJvbV9wcmV0cmFpbmVkCiAgICAgICAgICAgIEF1dG9Nb2RlbC5mcm9tX3ByZXRyYWluZWQgPSBfcGF0Y2hlZF9tb2RlbF9mcm9tX3ByZXRyYWluZWQKICAgICAgICAgICAgUHJlVHJhaW5lZE1vZGVsLmZyb21fcHJldHJhaW5lZCA9IF9wYXRjaGVkX3ByZXRyYWluZWRfbW9kZWxfZnJvbV9wcmV0cmFpbmVkCiAgICAgICAgICAgIFByZVRyYWluZWRNb2RlbC5fZnJvbV9jb25maWcgPSBfcGF0Y2hlZF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fY29uZmlnCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHJldHVybiBfaW5zdGFudGlhdGVfbW9kZWwoKQogICAgICAgICAgICBmaW5hbGx5OgogICAgICAgICAgICAgICAgQXV0b1Rva2VuaXplci5mcm9tX3ByZXRyYWluZWQgPSBvcmlnaW5hbF9mcm9tX3ByZXRyYWluZWQKICAgICAgICAgICAgICAgIEF1dG9Nb2RlbC5mcm9tX3ByZXRyYWluZWQgPSBvcmlnaW5hbF9tb2RlbF9mcm9tX3ByZXRyYWluZWQKICAgICAgICAgICAgICAgIFByZVRyYWluZWRNb2RlbC5mcm9tX3ByZXRyYWluZWQgPSBvcmlnaW5hbF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fcHJldHJhaW5lZAogICAgICAgICAgICAgICAgUHJlVHJhaW5lZE1vZGVsLl9mcm9tX2NvbmZpZyA9IG9yaWdpbmFsX3ByZXRyYWluZWRfbW9kZWxfZnJvbV9jb25maWcKCiAgICAgICAgcHJpbnQoZiJbK10gQ2FycmVnYW5kbyBtb2RlbG8gZGUgZW1iZWRkaW5ncyBhIHBhcnRpciBkZToge3NlbGVjdGVkX21vZGVsX2Rpcn0gKENQVSkuLi4iKQogICAgICAgIHRyeToKICAgICAgICAgICAgcmV0dXJuIF9sb2FkX3dpdGhfbWlzdHJhbF9yZWdleF9wYXRjaCgpCiAgICAgICAgZXhjZXB0IEZpbGVOb3RGb3VuZEVycm9yIGFzIGU6CiAgICAgICAgICAgICMgQ29ycmlnZSBjb3JydXDDp8Ojby9pbmNvbXBsZXR1ZGUgbm8gY2FjaGUgZGluw6JtaWNvIGRvIHRyYW5zZm9ybWVycy4KICAgICAgICAgICAgaWYgdHJ1c3RfcmVtb3RlX2NvZGUgYW5kICJ0cmFuc2Zvcm1lcnNfbW9kdWxlcyIgaW4gc3RyKGUpOgogICAgICAgICAgICAgICAgcHJpbnQoZiJbIV0gQ2FjaGUgZGluw6JtaWNvIGluY29uc2lzdGVudGUgZGV0ZWN0YWRvOiB7ZX0iKQogICAgICAgICAgICAgICAgX2NsZWFyX2hmX2R5bmFtaWNfbW9kdWxlc19jYWNoZSgpCiAgICAgICAgICAgICAgICByZXR1cm4gX2xvYWRfd2l0aF9taXN0cmFsX3JlZ2V4X3BhdGNoKCkKICAgICAgICAgICAgcmFpc2UKCiAgICBkZWYgX2FwcGx5X2ppbmFfcXVhbnRpemF0aW9uX2lmX25lZWRlZChtb2RlbDogU2VudGVuY2VUcmFuc2Zvcm1lciwgbW9kZWxfaWQ6IHN0cikgLT4gU2VudGVuY2VUcmFuc2Zvcm1lcjoKICAgICAgICBpZiBtb2RlbF9pZCAhPSBKSU5BX1YzX0VNQkVERElOR19NT0RFTCBvciBqaW5hX3F1YW50aXphdGlvbiA9PSAiZGVmYXVsdCI6CiAgICAgICAgICAgIHJldHVybiBtb2RlbAogICAgICAgIHRyeToKICAgICAgICAgICAgaW1wb3J0IHRvcmNoCiAgICAgICAgICAgIGltcG9ydCB3YXJuaW5ncwoKICAgICAgICAgICAgcXVhbnRpemVkX2xheWVycyA9IDAKICAgICAgICAgICAgZm9yIG1vZHVsZSBpbiBtb2RlbC5tb2R1bGVzKCk6CiAgICAgICAgICAgICAgICBpZiB0eXBlKG1vZHVsZSkuX19uYW1lX18gIT0gIlBhcmFtZXRyaXplZExpbmVhciI6CiAgICAgICAgICAgICAgICAgICAgY29udGludWUKCiAgICAgICAgICAgICAgICBmbG9hdF9saW5lYXIgPSB0b3JjaC5ubi5MaW5lYXIoCiAgICAgICAgICAgICAgICAgICAgbW9kdWxlLmluX2ZlYXR1cmVzLAogICAgICAgICAgICAgICAgICAgIG1vZHVsZS5vdXRfZmVhdHVyZXMsCiAgICAgICAgICAgICAgICAgICAgYmlhcz1tb2R1bGUuYmlhcyBpcyBub3QgTm9uZSwKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIHdpdGggdG9yY2gubm9fZ3JhZCgpOgogICAgICAgICAgICAgICAgICAgIGZsb2F0X2xpbmVhci53ZWlnaHQuY29weV8obW9kdWxlLndlaWdodC5kZXRhY2goKS50byh0b3JjaC5mbG9hdDMyKSkKICAgICAgICAgICAgICAgICAgICBpZiBtb2R1bGUuYmlhcyBpcyBub3QgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXRfbGluZWFyLmJpYXMuY29weV8obW9kdWxlLmJpYXMuZGV0YWNoKCkudG8odG9yY2guZmxvYXQzMikpCgogICAgICAgICAgICAgICAgd2l0aCB3YXJuaW5ncy5jYXRjaF93YXJuaW5ncygpOgogICAgICAgICAgICAgICAgICAgIHdhcm5pbmdzLmZpbHRlcndhcm5pbmdzKCJpZ25vcmUiLCBjYXRlZ29yeT1EZXByZWNhdGlvbldhcm5pbmcpCiAgICAgICAgICAgICAgICAgICAgcXVhbnRpemVkX2xpbmVhciA9IHRvcmNoLnF1YW50aXphdGlvbi5xdWFudGl6ZV9keW5hbWljKAogICAgICAgICAgICAgICAgICAgICAgICB0b3JjaC5ubi5TZXF1ZW50aWFsKGZsb2F0X2xpbmVhciksCiAgICAgICAgICAgICAgICAgICAgICAgIHt0b3JjaC5ubi5MaW5lYXJ9LAogICAgICAgICAgICAgICAgICAgICAgICBkdHlwZT10b3JjaC5xaW50OCwKICAgICAgICAgICAgICAgICAgICApWzBdCgogICAgICAgICAgICAgICAgbW9kdWxlLl9keW5hbWljX2ludDhfbGluZWFyID0gcXVhbnRpemVkX2xpbmVhcgoKICAgICAgICAgICAgICAgIGRlZiBfZm9yd2FyZF9keW5hbWljX2ludDgoc2VsZiwgaW5wdXQsIHRhc2tfaWQ9Tm9uZSwgcmVzaWR1YWw9RmFsc2UpOgogICAgICAgICAgICAgICAgICAgIG91dCA9IHNlbGYuX2R5bmFtaWNfaW50OF9saW5lYXIoaW5wdXQpCiAgICAgICAgICAgICAgICAgICAgaWYgcmVzaWR1YWw6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvdXQsIGlucHV0CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG91dAoKICAgICAgICAgICAgICAgIG1vZHVsZS5mb3J3YXJkID0gX2ZvcndhcmRfZHluYW1pY19pbnQ4Ll9fZ2V0X18obW9kdWxlLCBtb2R1bGUuX19jbGFzc19fKQogICAgICAgICAgICAgICAgcXVhbnRpemVkX2xheWVycyArPSAxCgogICAgICAgICAgICBpZiBxdWFudGl6ZWRfbGF5ZXJzID09IDA6CiAgICAgICAgICAgICAgICBwcmludCgKICAgICAgICAgICAgICAgICAgICAiW0FWSVNPXSBOZW5odW1hIGNhbWFkYSBQYXJhbWV0cml6ZWRMaW5lYXIgZW5jb250cmFkYSBwYXJhIGR5bmFtaWMtaW50ODsgdXNhbmRvIG1vZGVsbyBwYWRyYW8uIgogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgcmV0dXJuIG1vZGVsCgogICAgICAgICAgICBwcmludChmIlsrXSBRdWFudGl6YWNhbyBKaW5hIGFwbGljYWRhOiBkeW5hbWljLWludDggKENQVSwge3F1YW50aXplZF9sYXllcnN9IGNhbWFkYXMpLiIpCiAgICAgICAgICAgIHJldHVybiBtb2RlbAogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgcXVhbnRfZXJyb3I6CiAgICAgICAgICAgIHByaW50KGYiW0FWSVNPXSBGYWxoYSBhbyBhcGxpY2FyIGR5bmFtaWMtaW50OCAoe3F1YW50X2Vycm9yfSk7IHVzYW5kbyBtb2RlbG8gcGFkcmFvLiIpCiAgICAgICAgICAgIHJldHVybiBtb2RlbAoKICAgIHRyeToKICAgICAgICBtb2RlbCA9IF9sb2FkX2Zyb21fbG9jYWxfZGlyKHNlbGVjdGlvbi5tb2RlbF9pZCkKICAgICAgICBtb2RlbCA9IF9hcHBseV9qaW5hX3F1YW50aXphdGlvbl9pZl9uZWVkZWQobW9kZWwsIHNlbGVjdGlvbi5tb2RlbF9pZCkKICAgICAgICBwcmludCgiWytdIE1vZGVsbyBjYXJyZWdhZG8gY29tIHN1Y2Vzc28uIikKICAgICAgICByZXR1cm4gbW9kZWwKICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZmlyc3RfZXJyb3I6CiAgICAgICAgaWYgc2VsZWN0aW9uLm1vZGVsX2lkID09IGZhbGxiYWNrX21vZGVsX2lkOgogICAgICAgICAgICByYWlzZSBSdW50aW1lRXJyb3IoCiAgICAgICAgICAgICAgICBmIkZhbGhhIGFvIGNhcnJlZ2FyIG8gbW9kZWxvIGZhbGxiYWNrICd7ZmFsbGJhY2tfbW9kZWxfaWR9Jzoge2ZpcnN0X2Vycm9yfSIKICAgICAgICAgICAgKSBmcm9tIGZpcnN0X2Vycm9yCgogICAgICAgIHByaW50KAogICAgICAgICAgICBmIlshXSBGYWxoYSBhbyBjYXJyZWdhciAne3NlbGVjdGlvbi5tb2RlbF9pZH0nOiB7X2Zvcm1hdF9leGNlcHRpb24oZmlyc3RfZXJyb3IpfVxuIgogICAgICAgICAgICBmIiAgICBUZW50YW5kbyBmYWxsYmFjayBkZSBjYXJyZWdhbWVudG86IHtmYWxsYmFja19tb2RlbF9pZH0iCiAgICAgICAgKQogICAgICAgIGZhbGxiYWNrX3NlbGVjdGlvbiA9IGRvd25sb2FkX21vZGVsX3dpdGhfZmFsbGJhY2soCiAgICAgICAgICAgIHByZWZlcnJlZF9tb2RlbF9pZD1mYWxsYmFja19tb2RlbF9pZCwKICAgICAgICAgICAgZmFsbGJhY2tfbW9kZWxfaWQ9ZmFsbGJhY2tfbW9kZWxfaWQsCiAgICAgICAgICAgIGxvY2FsX2Rpcj1tb2RlbF9iYXNlX2RpciwKICAgICAgICApCiAgICAgICAgc2VsZWN0ZWRfbW9kZWxfZGlyID0gZmFsbGJhY2tfc2VsZWN0aW9uLmxvY2FsX2RpcgogICAgICAgIHByaW50KAogICAgICAgICAgICBmIlsrXSBNb2RlbG8gc2VsZWNpb25hZG86IHtmYWxsYmFja19zZWxlY3Rpb24ubW9kZWxfaWR9ICIKICAgICAgICAgICAgZiIocHJvdmlkZXI9e2ZhbGxiYWNrX3NlbGVjdGlvbi5wcm92aWRlcn0sIHBhdGg9e3NlbGVjdGVkX21vZGVsX2Rpcn0pIgogICAgICAgICkKICAgICAgICBtb2RlbCA9IF9sb2FkX2Zyb21fbG9jYWxfZGlyKGZhbGxiYWNrX3NlbGVjdGlvbi5tb2RlbF9pZCkKICAgICAgICBtb2RlbCA9IF9hcHBseV9qaW5hX3F1YW50aXphdGlvbl9pZl9uZWVkZWQobW9kZWwsIGZhbGxiYWNrX3NlbGVjdGlvbi5tb2RlbF9pZCkKICAgICAgICBwcmludCgiWytdIE1vZGVsbyBmYWxsYmFjayBjYXJyZWdhZG8gY29tIHN1Y2Vzc28uIikKICAgICAgICByZXR1cm4gbW9kZWwKCgpkZWYgY29ubmVjdF90b19jaHJvbWEoKSAtPiBjaHJvbWFkYi5IdHRwQ2xpZW50OgogICAgIiIiQ29uZWN0YSBhbyBDaHJvbWFEQiB2aWEgSFRUUCBlIHZhbGlkYSBhIGNvbmV4w6NvLiIiIgogICAgdHJ5OgogICAgICAgIGNsaWVudCA9IGNocm9tYWRiLkh0dHBDbGllbnQoaG9zdD1DSFJPTUFfSE9TVCwgcG9ydD1DSFJPTUFfUE9SVCwgc3NsPUNIUk9NQV9TU0wpCiAgICAgICAgIyBGYXogdW0gaGVhcnRiZWF0IHBhcmEgY29uZmlybWFyIHF1ZSBvIHNlcnZpZG9yIGVzdMOhIG5vIGFyCiAgICAgICAgY2xpZW50LmhlYXJ0YmVhdCgpCiAgICAgICAgcHJpbnQoZiJbK10gQ29uZWN0YWRvIGFvIENocm9tYURCIGVtIHtDSFJPTUFfU0NIRU1FfTovL3tDSFJPTUFfSE9TVH06e0NIUk9NQV9QT1JUfSIpCiAgICAgICAgcmV0dXJuIGNsaWVudAogICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgIHByaW50KGYiW0VSUk9dIE7Do28gZm9pIHBvc3PDrXZlbCBjb25lY3RhciBhbyBDaHJvbWFEQjoge2V9IikKICAgICAgICBwcmludChmIiAgICAgICBFbmRwb2ludCBjb25maWd1cmFkbzoge0NIUk9NQV9TQ0hFTUV9Oi8ve0NIUk9NQV9IT1NUfTp7Q0hST01BX1BPUlR9IikKICAgICAgICBzeXMuZXhpdCgxKQoKCmRlZiBzY2FuX2ZpbGVzKHJvb3RfcGF0aDogUGF0aCkgLT4gSXRlcmF0b3JbUGF0aF06CiAgICAiIiIKICAgIFZhcnJlIHJlY3Vyc2l2YW1lbnRlIG8gZGlyZXTDs3JpbyByYWl6LCByZXRvcm5hbmRvIGVtIHN0cmVhbWluZwogICAgb3MgYXJxdWl2b3MgZGUgdGV4dG8gcmVsZXZhbnRlcyBwYXJhIGluZGV4YcOnw6NvLgogICAgIiIiCiAgICBmb3IgZGlycGF0aCwgZGlybmFtZXMsIGZpbGVuYW1lcyBpbiBvcy53YWxrKHJvb3RfcGF0aCk6CiAgICAgICAgIyBSZW1vdmUgZGlycyBpZ25vcmFkb3MgaW4tcGxhY2UgcGFyYSBxdWUgb3Mud2FsayBuw6NvIGRlc8OnYSBuZWxlcwogICAgICAgIGRpcm5hbWVzWzpdID0gWwogICAgICAgICAgICBkIGZvciBkIGluIGRpcm5hbWVzCiAgICAgICAgICAgIGlmIGQgbm90IGluIElHTk9SRURfRElSUyBhbmQgbm90IGQuc3RhcnRzd2l0aCgiLiIpCiAgICAgICAgXQogICAgICAgIGRpcm5hbWVzLnNvcnQoKQoKICAgICAgICBmb3IgZmlsZW5hbWUgaW4gc29ydGVkKGZpbGVuYW1lcyk6CiAgICAgICAgICAgIGZpbGVwYXRoID0gUGF0aChkaXJwYXRoKSAvIGZpbGVuYW1lCgogICAgICAgICAgICAjIElnbm9yYSBwb3IgZXh0ZW5zw6NvCiAgICAgICAgICAgIGlmIGZpbGVwYXRoLnN1ZmZpeC5sb3dlcigpIGluIElHTk9SRURfRVhURU5TSU9OUzoKICAgICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICAgICAjIElnbm9yYSBhcnF1aXZvcyBtdWl0byBncmFuZGVzCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGlmIGZpbGVwYXRoLnN0YXQoKS5zdF9zaXplID4gTUFYX0ZJTEVfU0laRV9CWVRFUzoKICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICBleGNlcHQgT1NFcnJvcjoKICAgICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICAgICB5aWVsZCBmaWxlcGF0aAoKCmRlZiBtYWtlX2NodW5rX2lkKGZpbGVfcGF0aDogc3RyLCBjaHVua19pbmRleDogaW50KSAtPiBzdHI6CiAgICAiIiJHZXJhIHVtIElEIGRldGVybWluw61zdGljbyBwYXJhIGNhZGEgY2h1bmsgYmFzZWFkbyBubyBjYW1pbmhvICsgw61uZGljZS4iIiIKICAgIHJhdyA9IGYie2ZpbGVfcGF0aH06OmNodW5rOjp7Y2h1bmtfaW5kZXh9IgogICAgcmV0dXJuIGhhc2hsaWIubWQ1KHJhdy5lbmNvZGUoKSkuaGV4ZGlnZXN0KCkKCgpkZWYgX2xvb2tzX2JpbmFyeV9jb250ZW50KHJhdzogYnl0ZXMpIC0+IGJvb2w6CiAgICAiIiJEZXRlY3RhIGNvbnRlw7pkbyBiaW7DoXJpbyBwb3IgaGV1csOtc3RpY2EgZW0gYW1vc3RyYSBkZSBieXRlcy4iIiIKICAgIGlmIG5vdCByYXc6CiAgICAgICAgcmV0dXJuIEZhbHNlCgogICAgc2FtcGxlID0gcmF3Wzo0MDk2XQogICAgaWYgYiJceDAwIiBpbiBzYW1wbGU6CiAgICAgICAgcmV0dXJuIFRydWUKCiAgICBub25fdGV4dF9ieXRlcyA9IDAKICAgIGZvciBieXRlIGluIHNhbXBsZToKICAgICAgICBpZiBieXRlIGluICg5LCAxMCwgMTMpOiAgIyBcdCBcbiBccgogICAgICAgICAgICBjb250aW51ZQogICAgICAgIGlmIDMyIDw9IGJ5dGUgPD0gMTI2OiAgIyBBU0NJSSBpbXByaW3DrXZlbAogICAgICAgICAgICBjb250aW51ZQogICAgICAgIGlmIDE2MCA8PSBieXRlIDw9IDI1NTogICMgTGF0aW4tMSBlc3RlbmRpZG8gY29tdW0gZW0gdGV4dG8KICAgICAgICAgICAgY29udGludWUKICAgICAgICBub25fdGV4dF9ieXRlcyArPSAxCgogICAgcmV0dXJuIChub25fdGV4dF9ieXRlcyAvIGxlbihzYW1wbGUpKSA+IDAuMzAKCgpkZWYgcmVhZF9maWxlX3NhZmUoZmlsZXBhdGg6IFBhdGgpIC0+IHN0ciB8IE5vbmU6CiAgICAiIiJMw6ogdW0gYXJxdWl2byBkZSB0ZXh0bywgZXZpdGFuZG8gYmluw6FyaW9zIGUgdGVudGFuZG8gbcO6bHRpcGxvcyBlbmNvZGluZ3MuIiIiCiAgICB0cnk6CiAgICAgICAgcmF3ID0gZmlsZXBhdGgucmVhZF9ieXRlcygpCiAgICBleGNlcHQgT1NFcnJvciBhcyBlOgogICAgICAgIHByaW50KGYiICBbQVZJU09dIE7Do28gZm9pIHBvc3PDrXZlbCBsZXIge2ZpbGVwYXRofToge2V9IikKICAgICAgICByZXR1cm4gTm9uZQoKICAgIGlmIF9sb29rc19iaW5hcnlfY29udGVudChyYXcpOgogICAgICAgIHJldHVybiBOb25lCgogICAgZm9yIGVuY29kaW5nIGluICgidXRmLTgiLCAibGF0aW4tMSIsICJjcDEyNTIiKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIHJldHVybiByYXcuZGVjb2RlKGVuY29kaW5nKQogICAgICAgIGV4Y2VwdCBVbmljb2RlRGVjb2RlRXJyb3I6CiAgICAgICAgICAgIGNvbnRpbnVlCiAgICByZXR1cm4gTm9uZQoKCmRlZiBkZWxldGVfZmlsZV9jaHVua3MoY29sbGVjdGlvbjogY2hyb21hZGIuQ29sbGVjdGlvbiwgZmlsZV9wYXRoOiBzdHIpIC0+IE5vbmU6CiAgICAiIiJSZW1vdmUgdG9kb3Mgb3MgY2h1bmtzIGRlIHVtIGFycXVpdm8gZXNwZWPDrWZpY28gZGEgY29sZcOnw6NvLiIiIgogICAgdHJ5OgogICAgICAgICMgUGVkZSBzb21lbnRlIElEcyBwYXJhIGV2aXRhciBtYXRlcmlhbGl6YXIgZG9jcy9tZXRhZGF0YSBuYSBtZW3Ds3JpYS4KICAgICAgICByZXN1bHRzID0gY29sbGVjdGlvbi5nZXQod2hlcmU9eyJmaWxlX3BhdGgiOiBmaWxlX3BhdGh9LCBpbmNsdWRlPVtdKQogICAgICAgIGlmIHJlc3VsdHMgYW5kIHJlc3VsdHNbImlkcyJdOgogICAgICAgICAgICBjb2xsZWN0aW9uLmRlbGV0ZShpZHM9cmVzdWx0c1siaWRzIl0pCiAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgcHJpbnQoZiIgIFtBVklTT10gRXJybyBhbyBkZWxldGFyIGNodW5rcyBkZSB7ZmlsZV9wYXRofToge19mb3JtYXRfZXhjZXB0aW9uKGUpfSIpCgoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBJbmRleGHDp8OjbyBkZSB1bSDDum5pY28gYXJxdWl2bwojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKZGVmIGluZGV4X2ZpbGUoCiAgICBmaWxlcGF0aDogUGF0aCwKICAgIGNvbGxlY3Rpb246IGNocm9tYWRiLkNvbGxlY3Rpb24sCiAgICBtb2RlbDogU2VudGVuY2VUcmFuc2Zvcm1lciwKICAgIHNwbGl0dGVyOiBSZWN1cnNpdmVDaGFyYWN0ZXJUZXh0U3BsaXR0ZXIsCiAgICByb290X3BhdGg6IFBhdGgsCiAgICBlbWJlZGRpbmdfYmF0Y2hfc2l6ZTogaW50LAopIC0+IGludDoKICAgICIiIgogICAgSW5kZXhhIHVtIMO6bmljbyBhcnF1aXZvOiBsw6osIGRpdmlkZSBlbSBjaHVua3MsIGdlcmEgZW1iZWRkaW5ncyBlIGZheiB1cHNlcnQuCiAgICBSZXRvcm5hIG8gbsO6bWVybyBkZSBjaHVua3MgaW5kZXhhZG9zLgogICAgIiIiCiAgICBjb250ZW50ID0gcmVhZF9maWxlX3NhZmUoZmlsZXBhdGgpCiAgICBpZiBub3QgY29udGVudCBvciBub3QgY29udGVudC5zdHJpcCgpOgogICAgICAgIHJldHVybiAwCgogICAgIyBVc2EgY2FtaW5obyBhYnNvbHV0byBjb21vIG1ldGFkYWRvCiAgICBhYnNfcGF0aCA9IHN0cihmaWxlcGF0aC5yZXNvbHZlKCkpCgogICAgIyBSZW1vdmUgY2h1bmtzIGFudGlnb3MgZGVzdGUgYXJxdWl2byAoYXR1YWxpemHDp8OjbyBpZGVtcG90ZW50ZSkKICAgIGRlbGV0ZV9maWxlX2NodW5rcyhjb2xsZWN0aW9uLCBhYnNfcGF0aCkKCiAgICBjaHVua3MgPSBzcGxpdHRlci5zcGxpdF90ZXh0KGNvbnRlbnQpCiAgICBpZiBub3QgY2h1bmtzOgogICAgICAgIHJldHVybiAwCgogICAgcmVsYXRpdmVfcGF0aCA9IHN0cihmaWxlcGF0aC5yZWxhdGl2ZV90byhyb290X3BhdGgpKQogICAgaW5zZXJ0ZWRfY2h1bmtzID0gMAogICAgc2tpcHBlZF9jaHVua3MgPSAwCiAgICBzdG9wX2l0ZXJhdGlvbl93YXJuaW5ncyA9IDAKICAgIGJhdGNoX2lkczogbGlzdFtzdHJdID0gW10KICAgIGJhdGNoX2RvY3M6IGxpc3Rbc3RyXSA9IFtdCiAgICBiYXRjaF9tZXRhZGF0YXM6IGxpc3RbZGljdFtzdHIsIG9iamVjdF1dID0gW10KCiAgICBkZWYgX3dhcm5fc3RvcF9pdGVyYXRpb24obWVzc2FnZTogc3RyKSAtPiBOb25lOgogICAgICAgIG5vbmxvY2FsIHN0b3BfaXRlcmF0aW9uX3dhcm5pbmdzCiAgICAgICAgaWYgc3RvcF9pdGVyYXRpb25fd2FybmluZ3MgPCAzOgogICAgICAgICAgICB0cWRtLndyaXRlKG1lc3NhZ2UpCiAgICAgICAgc3RvcF9pdGVyYXRpb25fd2FybmluZ3MgKz0gMQoKICAgIGRlZiBfdG9fZW1iZWRkaW5nX3Jvd3MoZW5jb2RlZF9lbWJlZGRpbmdzOiBvYmplY3QpIC0+IGxpc3RbbGlzdFtmbG9hdF1dOgogICAgICAgIGlmIGhhc2F0dHIoZW5jb2RlZF9lbWJlZGRpbmdzLCAidG9saXN0Iik6CiAgICAgICAgICAgIHJvd3MgPSBlbmNvZGVkX2VtYmVkZGluZ3MudG9saXN0KCkKICAgICAgICAgICAgaWYgaXNpbnN0YW5jZShyb3dzLCBsaXN0KToKICAgICAgICAgICAgICAgIGlmIHJvd3MgYW5kIGlzaW5zdGFuY2Uocm93c1swXSwgKGludCwgZmxvYXQpKToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gW2xpc3Qocm93cyldCiAgICAgICAgICAgICAgICByZXR1cm4gcm93cwogICAgICAgIHJldHVybiBbbGlzdChyb3cpIGZvciByb3cgaW4gZW5jb2RlZF9lbWJlZGRpbmdzXSAgIyB0eXBlOiBpZ25vcmVbYXJnLXR5cGVdCgogICAgZGVmIF9mbHVzaF9iYXRjaCgpIC0+IE5vbmU6CiAgICAgICAgbm9ubG9jYWwgaW5zZXJ0ZWRfY2h1bmtzLCBza2lwcGVkX2NodW5rcwogICAgICAgIGlmIG5vdCBiYXRjaF9pZHM6CiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBwZW5kaW5nX2lkcyA9IGxpc3QoYmF0Y2hfaWRzKQogICAgICAgIHBlbmRpbmdfZG9jcyA9IGxpc3QoYmF0Y2hfZG9jcykKICAgICAgICBwZW5kaW5nX21ldGFkYXRhcyA9IGxpc3QoYmF0Y2hfbWV0YWRhdGFzKQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGVuY29kZWQgPSBtb2RlbC5lbmNvZGUoCiAgICAgICAgICAgICAgICBwZW5kaW5nX2RvY3MsCiAgICAgICAgICAgICAgICBzaG93X3Byb2dyZXNzX2Jhcj1GYWxzZSwKICAgICAgICAgICAgICAgIGJhdGNoX3NpemU9ZW1iZWRkaW5nX2JhdGNoX3NpemUsCiAgICAgICAgICAgICkKICAgICAgICAgICAgZW1iZWRkaW5ncyA9IF90b19lbWJlZGRpbmdfcm93cyhlbmNvZGVkKQogICAgICAgICAgICBjb2xsZWN0aW9uLnVwc2VydCgKICAgICAgICAgICAgICAgIGlkcz1wZW5kaW5nX2lkcywKICAgICAgICAgICAgICAgIGVtYmVkZGluZ3M9ZW1iZWRkaW5ncywKICAgICAgICAgICAgICAgIGRvY3VtZW50cz1wZW5kaW5nX2RvY3MsCiAgICAgICAgICAgICAgICBtZXRhZGF0YXM9cGVuZGluZ19tZXRhZGF0YXMsCiAgICAgICAgICAgICkKICAgICAgICAgICAgaW5zZXJ0ZWRfY2h1bmtzICs9IGxlbihwZW5kaW5nX2lkcykKICAgICAgICAgICAgZGVsIGVtYmVkZGluZ3MKICAgICAgICBleGNlcHQgU3RvcEl0ZXJhdGlvbjoKICAgICAgICAgICAgX3dhcm5fc3RvcF9pdGVyYXRpb24oCiAgICAgICAgICAgICAgICBmIiAgW0FWSVNPXSB7ZmlsZXBhdGgubmFtZX06IFN0b3BJdGVyYXRpb24gbm8gYmF0Y2ggZGUgZW1iZWRkaW5nczsgdGVudGFuZG8gZmFsbGJhY2sgcG9yIGNodW5rLiIKICAgICAgICAgICAgKQogICAgICAgICAgICBmb3IgY2h1bmtfaWQsIGNodW5rX2RvYywgY2h1bmtfbWV0YWRhdGEgaW4gemlwKHBlbmRpbmdfaWRzLCBwZW5kaW5nX2RvY3MsIHBlbmRpbmdfbWV0YWRhdGFzKToKICAgICAgICAgICAgICAgIGNhbmRpZGF0ZV9kb2MgPSBjaHVua19kb2Muc3RyaXAoKQogICAgICAgICAgICAgICAgaWYgbm90IGNhbmRpZGF0ZV9kb2M6CiAgICAgICAgICAgICAgICAgICAgc2tpcHBlZF9jaHVua3MgKz0gMQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIGVuY29kZWRfc2luZ2xlID0gbW9kZWwuZW5jb2RlKAogICAgICAgICAgICAgICAgICAgICAgICBbY2FuZGlkYXRlX2RvY10sCiAgICAgICAgICAgICAgICAgICAgICAgIHNob3dfcHJvZ3Jlc3NfYmFyPUZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICBiYXRjaF9zaXplPTEsCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgIHNpbmdsZV9lbWJlZGRpbmdzID0gX3RvX2VtYmVkZGluZ19yb3dzKGVuY29kZWRfc2luZ2xlKQogICAgICAgICAgICAgICAgICAgIGNvbGxlY3Rpb24udXBzZXJ0KAogICAgICAgICAgICAgICAgICAgICAgICBpZHM9W2NodW5rX2lkXSwKICAgICAgICAgICAgICAgICAgICAgICAgZW1iZWRkaW5ncz1zaW5nbGVfZW1iZWRkaW5ncywKICAgICAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnRzPVtjYW5kaWRhdGVfZG9jXSwKICAgICAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGFzPVtjaHVua19tZXRhZGF0YV0sCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgIGluc2VydGVkX2NodW5rcyArPSAxCiAgICAgICAgICAgICAgICAgICAgZGVsIHNpbmdsZV9lbWJlZGRpbmdzCiAgICAgICAgICAgICAgICBleGNlcHQgU3RvcEl0ZXJhdGlvbjoKICAgICAgICAgICAgICAgICAgICBjb21wYWN0X2RvYyA9ICIgIi5qb2luKGNhbmRpZGF0ZV9kb2Muc3BsaXQoKSkKICAgICAgICAgICAgICAgICAgICBpZiBub3QgY29tcGFjdF9kb2M6CiAgICAgICAgICAgICAgICAgICAgICAgIHNraXBwZWRfY2h1bmtzICs9IDEKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgICAgIGVuY29kZWRfc2luZ2xlID0gbW9kZWwuZW5jb2RlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NvbXBhY3RfZG9jXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3dfcHJvZ3Jlc3NfYmFyPUZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2hfc2l6ZT0xLAogICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgIHNpbmdsZV9lbWJlZGRpbmdzID0gX3RvX2VtYmVkZGluZ19yb3dzKGVuY29kZWRfc2luZ2xlKQogICAgICAgICAgICAgICAgICAgICAgICBjb2xsZWN0aW9uLnVwc2VydCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkcz1bY2h1bmtfaWRdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZW1iZWRkaW5ncz1zaW5nbGVfZW1iZWRkaW5ncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50cz1bY29tcGFjdF9kb2NdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGFzPVtjaHVua19tZXRhZGF0YV0sCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgaW5zZXJ0ZWRfY2h1bmtzICs9IDEKICAgICAgICAgICAgICAgICAgICAgICAgZGVsIHNpbmdsZV9lbWJlZGRpbmdzCiAgICAgICAgICAgICAgICAgICAgZXhjZXB0IFN0b3BJdGVyYXRpb246CiAgICAgICAgICAgICAgICAgICAgICAgIHNraXBwZWRfY2h1bmtzICs9IDEKICAgICAgICAgICAgICAgICAgICAgICAgX3dhcm5fc3RvcF9pdGVyYXRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIiAgW0FWSVNPXSB7ZmlsZXBhdGgubmFtZX06IGNodW5rIGlnbm9yYWRvIGFww7NzIFN0b3BJdGVyYXRpb24gcmVwZXRpZG8uIgogICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgYmF0Y2hfaWRzLmNsZWFyKCkKICAgICAgICBiYXRjaF9kb2NzLmNsZWFyKCkKICAgICAgICBiYXRjaF9tZXRhZGF0YXMuY2xlYXIoKQogICAgICAgIGdjLmNvbGxlY3QoKQoKICAgIGZvciBpLCBjaHVuayBpbiBlbnVtZXJhdGUoY2h1bmtzKToKICAgICAgICBpZiBub3QgY2h1bmsgb3Igbm90IGNodW5rLnN0cmlwKCk6CiAgICAgICAgICAgIHNraXBwZWRfY2h1bmtzICs9IDEKICAgICAgICAgICAgY29udGludWUKICAgICAgICBiYXRjaF9pZHMuYXBwZW5kKG1ha2VfY2h1bmtfaWQoYWJzX3BhdGgsIGkpKQogICAgICAgIGJhdGNoX2RvY3MuYXBwZW5kKGNodW5rKQogICAgICAgIGJhdGNoX21ldGFkYXRhcy5hcHBlbmQoCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJmaWxlX3BhdGgiOiBhYnNfcGF0aCwKICAgICAgICAgICAgICAgICJjaHVua19pbmRleCI6IGksCiAgICAgICAgICAgICAgICAiZmlsZV9uYW1lIjogZmlsZXBhdGgubmFtZSwKICAgICAgICAgICAgICAgICMgQ2FtaW5obyByZWxhdGl2byDDoCByYWl6IGRvIHByb2pldG8gcGFyYSBleGliacOnw6NvIGNvbXBhY3RhCiAgICAgICAgICAgICAgICAicmVsYXRpdmVfcGF0aCI6IHJlbGF0aXZlX3BhdGgsCiAgICAgICAgICAgIH0KICAgICAgICApCiAgICAgICAgaWYgbGVuKGJhdGNoX2lkcykgPj0gZW1iZWRkaW5nX2JhdGNoX3NpemU6CiAgICAgICAgICAgIF9mbHVzaF9iYXRjaCgpCgogICAgX2ZsdXNoX2JhdGNoKCkKICAgIGlmIHNraXBwZWRfY2h1bmtzOgogICAgICAgIF93YXJuX3N0b3BfaXRlcmF0aW9uKAogICAgICAgICAgICBmIiAgW0FWSVNPXSB7ZmlsZXBhdGgubmFtZX06IHtza2lwcGVkX2NodW5rc30gY2h1bmsocykgdmF6aW8ocykvaW52w6FsaWRvKHMpIGZvcmFtIGlnbm9yYWRvcy4iCiAgICAgICAgKQogICAgcmV0dXJuIGluc2VydGVkX2NodW5rcwoKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgUG9udG8gZGUgZW50cmFkYSBwcmluY2lwYWwKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmRlZiBtYWluKCk6CiAgICBwYXJzZXIgPSBhcmdwYXJzZS5Bcmd1bWVudFBhcnNlcigKICAgICAgICBkZXNjcmlwdGlvbj0iSW5kZXhhIHVtIHByb2pldG8gZGUgY8OzZGlnbyBubyBDaHJvbWFEQiBwYXJhIFJBRyBsb2NhbC4iCiAgICApCiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KAogICAgICAgICJwcm9qZWN0X3BhdGgiLAogICAgICAgIG5hcmdzPSI/IiwKICAgICAgICBkZWZhdWx0PSIuIiwKICAgICAgICBoZWxwPSJDYW1pbmhvIHJhaXogZG8gcHJvamV0byBhIGluZGV4YXIgKHBhZHLDo286IGRpcmV0w7NyaW8gYXR1YWwpIiwKICAgICkKICAgIHBhcnNlci5hZGRfYXJndW1lbnQoCiAgICAgICAgIi0tY2xlYXIiLAogICAgICAgIGFjdGlvbj0ic3RvcmVfdHJ1ZSIsCiAgICAgICAgaGVscD0iTGltcGEgdG9kYSBhIGNvbGXDp8OjbyBhbnRlcyBkZSByZWluZGV4YXIiLAogICAgKQogICAgcGFyc2VyLmFkZF9hcmd1bWVudCgKICAgICAgICAiLS1lbWJlZGRpbmctbW9kZWwiLAogICAgICAgIGNob2ljZXM9WyJqaW5hIiwgImJnZSIsICJoeWJyaWQiXSwKICAgICAgICBoZWxwPSgKICAgICAgICAgICAgIk1vZGVsbyBkZSBlbWJlZGRpbmdzOiAnamluYScgKGNvZGlnbyksICIKICAgICAgICAgICAgIidiZ2UnIChjb250ZXVkbyBtaXN0bykgb3UgJ2h5YnJpZCcgKGR1YXMgY29sZWNvZXM6IEppbmEgdjIgKyBCR0UpLiIKICAgICAgICApLAogICAgKQogICAgcGFyc2VyLmFkZF9hcmd1bWVudCgKICAgICAgICAiLS1qaW5hLXF1YW50aXphdGlvbiIsCiAgICAgICAgY2hvaWNlcz1bImRlZmF1bHQiLCAiZHluYW1pYy1pbnQ4Il0sCiAgICAgICAgaGVscD0iUXVhbnRpemFjYW8gcGFyYSBKaW5hOiAnZGVmYXVsdCcgKG1haXMgcXVhbGlkYWRlKSBvdSAnZHluYW1pYy1pbnQ4JyAobWFpcyB2ZWxvY2lkYWRlKS4iLAogICAgKQogICAgcGFyc2VyLmFkZF9hcmd1bWVudCgKICAgICAgICAiLS1wZXJmLXByb2ZpbGUiLAogICAgICAgIGNob2ljZXM9WyJhdXRvdHVuZSIsICJtYXgtcGVyZm9ybWFuY2UiXSwKICAgICAgICBoZWxwPSgKICAgICAgICAgICAgIlBlcmZpbCBkZSBwZXJmb3JtYW5jZSBkYSBpbmRleGHDp8OjbzogIgogICAgICAgICAgICAiJ2F1dG90dW5lJyAoY3VzdG8tYmVuZWbDrWNpbykgb3UgJ21heC1wZXJmb3JtYW5jZScgKG1haXMgdGhyb3VnaHB1dCwgbWFpb3IgdXNvIGRlIFJBTSkuIgogICAgICAgICksCiAgICApCiAgICBhcmdzID0gcGFyc2VyLnBhcnNlX2FyZ3MoKQoKICAgIHJvb3RfcGF0aCA9IFBhdGgoYXJncy5wcm9qZWN0X3BhdGgpLnJlc29sdmUoKQogICAgaWYgbm90IHJvb3RfcGF0aC5pc19kaXIoKToKICAgICAgICBwcmludChmIltFUlJPXSBDYW1pbmhvIG7Do28gZXhpc3RlIG91IG7Do28gw6kgdW0gZGlyZXTDs3Jpbzoge3Jvb3RfcGF0aH0iKQogICAgICAgIHN5cy5leGl0KDEpCgogICAgcHJpbnQoZiJcbnsnPScqNjB9IikKICAgIHByaW50KGYiICBSQUcgSW5kZXhlciDigJQgUHJvamV0bzoge3Jvb3RfcGF0aH0iKQogICAgcHJpbnQoZiJ7Jz0nKjYwfVxuIikKICAgIGluZGV4X3N0YXJ0ZWRfYXQgPSBkYXRldGltZS5ub3coKQogICAgcHJpbnQoZiJbSU5GT10gSW7DrWNpbzoge2luZGV4X3N0YXJ0ZWRfYXQuc3RyZnRpbWUoJyVZLSVtLSVkICVIOiVNOiVTJyl9IikKCiAgICBmb3JjZV9tb2RlbF9yZWNvbmZpZ3VyZSA9IF9lbnZfYm9vbCgiTUNQX0ZPUkNFX01PREVMX1JFQ09ORklHIiwgZGVmYXVsdD1GYWxzZSkKICAgIHBlcnNpc3RlZF9jb25maWcgPSBsb2FkX2luZGV4ZXJfdHVuaW5nX2NvbmZpZyhmb3JjZV9tb2RlbF9yZWNvbmZpZ3VyZSkKICAgIG1vZGVsX2Nob2ljZSwgamluYV9xdWFudGl6YXRpb24gPSByZXNvbHZlX2VtYmVkZGluZ19jb25maWcoCiAgICAgICAgYXJncy5lbWJlZGRpbmdfbW9kZWwsCiAgICAgICAgYXJncy5qaW5hX3F1YW50aXphdGlvbiwKICAgICAgICBwZXJzaXN0ZWRfY29uZmlnPXBlcnNpc3RlZF9jb25maWcsCiAgICApCiAgICBwZXJmX3Byb2ZpbGUgPSByZXNvbHZlX3BlcmZfcHJvZmlsZShhcmdzLnBlcmZfcHJvZmlsZSwgcGVyc2lzdGVkX2NvbmZpZykKCiAgICBjaHVua19zaXplX2xvY2tlZCA9ICJNQ1BfQ0hVTktfU0laRSIgaW4gb3MuZW52aXJvbgogICAgY2h1bmtfb3ZlcmxhcF9sb2NrZWQgPSAiTUNQX0NIVU5LX09WRVJMQVAiIGluIG9zLmVudmlyb24KICAgIGJhdGNoX3NpemVfbG9ja2VkID0gIk1DUF9FTUJFRERJTkdfQkFUQ0hfU0laRSIgaW4gb3MuZW52aXJvbgoKICAgIHBlcnNpc3RlZF9jaHVua19zaXplID0gX3BhcnNlX2NvbmZpZ19pbnQocGVyc2lzdGVkX2NvbmZpZywgImNodW5rX3NpemUiKQogICAgcGVyc2lzdGVkX2NodW5rX292ZXJsYXAgPSBfcGFyc2VfY29uZmlnX2ludChwZXJzaXN0ZWRfY29uZmlnLCAiY2h1bmtfb3ZlcmxhcCIpCiAgICBwZXJzaXN0ZWRfYmF0Y2hfc2l6ZSA9IF9wYXJzZV9jb25maWdfaW50KHBlcnNpc3RlZF9jb25maWcsICJlbWJlZGRpbmdfYmF0Y2hfc2l6ZSIpCiAgICBpZiBwZXJzaXN0ZWRfYmF0Y2hfc2l6ZSBpcyBOb25lOgogICAgICAgIHBlcnNpc3RlZF9iYXRjaF9zaXplID0gX3BhcnNlX2NvbmZpZ19pbnQocGVyc2lzdGVkX2NvbmZpZywgImJhdGNoX2NvdW50IikKCiAgICBlZmZlY3RpdmVfY2h1bmtfc2l6ZSA9IENIVU5LX1NJWkUKICAgIGlmIG5vdCBjaHVua19zaXplX2xvY2tlZCBhbmQgcGVyc2lzdGVkX2NodW5rX3NpemUgaXMgbm90IE5vbmU6CiAgICAgICAgZWZmZWN0aXZlX2NodW5rX3NpemUgPSBtYXgoMjU2LCBwZXJzaXN0ZWRfY2h1bmtfc2l6ZSkKCiAgICBlZmZlY3RpdmVfY2h1bmtfb3ZlcmxhcCA9IENIVU5LX09WRVJMQVAKICAgIGlmIG5vdCBjaHVua19vdmVybGFwX2xvY2tlZCBhbmQgcGVyc2lzdGVkX2NodW5rX292ZXJsYXAgaXMgbm90IE5vbmU6CiAgICAgICAgZWZmZWN0aXZlX2NodW5rX292ZXJsYXAgPSBtYXgoMCwgbWluKGVmZmVjdGl2ZV9jaHVua19zaXplIC0gMSwgcGVyc2lzdGVkX2NodW5rX292ZXJsYXApKQoKICAgIGVmZmVjdGl2ZV9iYXRjaF9zaXplID0gRU1CRURESU5HX0JBVENIX1NJWkUKICAgIGlmIG5vdCBiYXRjaF9zaXplX2xvY2tlZCBhbmQgcGVyc2lzdGVkX2JhdGNoX3NpemUgaXMgbm90IE5vbmU6CiAgICAgICAgZWZmZWN0aXZlX2JhdGNoX3NpemUgPSBtYXgoMSwgcGVyc2lzdGVkX2JhdGNoX3NpemUpCgogICAgcHJpbnQoCiAgICAgICAgZiJbQ09ORklHXSBNb2RlbG8gZXNjb2xoaWRvOiB7bW9kZWxfY2hvaWNlfSAiCiAgICAgICAgZiIoe19kZXNjcmliZV9lbWJlZGRpbmdfY2hvaWNlKG1vZGVsX2Nob2ljZSl9KSIKICAgICkKICAgIGlmIG1vZGVsX2Nob2ljZSA9PSAiamluYSI6CiAgICAgICAgcHJpbnQoZiJbQ09ORklHXSBRdWFudGl6YWNhbyBKaW5hOiB7amluYV9xdWFudGl6YXRpb259IikKICAgIGVsaWYgbW9kZWxfY2hvaWNlID09ICJoeWJyaWQiOgogICAgICAgIHByaW50KCJbQ09ORklHXSBRdWFudGl6YWNhbyBKaW5hOiBuYW8gYXBsaWNhdmVsIG5vIGh5YnJpZCAoSmluYSB2MiArIEJHRSkiKQogICAgZWxzZToKICAgICAgICBwcmludCgiW0NPTkZJR10gUXVhbnRpemFjYW8gSmluYTogbmFvIGFwbGljYXZlbCAobW9kZWxvIEJHRSBzZWxlY2lvbmFkbykiKQogICAgcHJpbnQoZiJbQ09ORklHXSBQZXJmaWwgZGUgcGVyZm9ybWFuY2U6IHtwZXJmX3Byb2ZpbGV9IikKICAgIGlmIHBlcmZfcHJvZmlsZSA9PSAibWF4LXBlcmZvcm1hbmNlIjoKICAgICAgICBwcmludCgKICAgICAgICAgICAgIltBVklTT10gRXN0ZSBtb2RvIHBvZGUgZWxldmFyIGNvbnNpZGVyYXZlbG1lbnRlIG8gY29uc3VtbyBkZSBtZW3Ds3JpYSAiCiAgICAgICAgICAgICJlIGNhdXNhciBlbmNlcnJhbWVudG8gcG9yIE9PTSAoZXhpdCAxMzcpLiIKICAgICAgICApCiAgICB3YXJuX2lmX2ppbmFfbWVtb3J5X3Jpc2sobW9kZWxfY2hvaWNlLCBqaW5hX3F1YW50aXphdGlvbikKCiAgICAjIEluaWNpYWxpemEgY29tcG9uZW50ZXMKICAgIGNsaWVudCA9IGNvbm5lY3RfdG9fY2hyb21hKCkKICAgIHRhcmdldHMgPSBfcmVzb2x2ZV9pbmRleF90YXJnZXRzKG1vZGVsX2Nob2ljZSkKCiAgICAjIE9idMOpbSBvdSByZWNyaWEgYXMgY29sZcOnw7VlcyBlbnZvbHZpZGFzLgogICAgY29sbGVjdGlvbnM6IGRpY3Rbc3RyLCBjaHJvbWFkYi5Db2xsZWN0aW9uXSA9IHt9CiAgICBjb2xsZWN0aW9uX2RpbWVuc2lvbl9yZXNldF9kb25lOiBkaWN0W3N0ciwgYm9vbF0gPSB7fQogICAgZm9yIHRhcmdldCBpbiB0YXJnZXRzOgogICAgICAgIGlmIGFyZ3MuY2xlYXI6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGNsaWVudC5kZWxldGVfY29sbGVjdGlvbih0YXJnZXQuY29sbGVjdGlvbl9uYW1lKQogICAgICAgICAgICAgICAgcHJpbnQoZiJbIV0gQ29sZcOnw6NvICd7dGFyZ2V0LmNvbGxlY3Rpb25fbmFtZX0nIHJlbW92aWRhIHBhcmEgcmVpbmRleGHDp8OjbyBsaW1wYS4iKQogICAgICAgICAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgICAgICAgICAgcGFzcwogICAgICAgIGNvbGxlY3Rpb25zW3RhcmdldC5jb2xsZWN0aW9uX25hbWVdID0gY2xpZW50LmdldF9vcl9jcmVhdGVfY29sbGVjdGlvbigKICAgICAgICAgICAgbmFtZT10YXJnZXQuY29sbGVjdGlvbl9uYW1lLAogICAgICAgICAgICBtZXRhZGF0YT17Imhuc3c6c3BhY2UiOiAiY29zaW5lIn0sCiAgICAgICAgKQogICAgICAgIGNvbGxlY3Rpb25fZGltZW5zaW9uX3Jlc2V0X2RvbmVbdGFyZ2V0LmNvbGxlY3Rpb25fbmFtZV0gPSBGYWxzZQoKICAgICMgQ2FycmVnYSBtb2RlbG9zIGRlIGZvcm1hIGxhenkgZSByZWFwcm92ZWl0YSBwb3IgdGFyZ2V0LgogICAgbG9hZGVkX21vZGVsczogZGljdFtzdHIsIFNlbnRlbmNlVHJhbnNmb3JtZXJdID0ge30KICAgIHRvdGFsX2NodW5rcyA9IDAKICAgIGVycm9ycyA9IDAKICAgIGZpbGVzX3NjYW5uZWQgPSAwCiAgICBmaWxlc19wcm9jZXNzZWRfdG90YWwgPSAwCiAgICBjaHVua3NfYnlfY29sbGVjdGlvbiA9IHt0YXJnZXQuY29sbGVjdGlvbl9uYW1lOiAwIGZvciB0YXJnZXQgaW4gdGFyZ2V0c30KICAgIGZpbGVzX2J5X2NvbGxlY3Rpb24gPSB7dGFyZ2V0LmNvbGxlY3Rpb25fbmFtZTogMCBmb3IgdGFyZ2V0IGluIHRhcmdldHN9CiAgICBmaWxlc19lbGlnaWJsZV9ieV9jb2xsZWN0aW9uID0ge3RhcmdldC5jb2xsZWN0aW9uX25hbWU6IDAgZm9yIHRhcmdldCBpbiB0YXJnZXRzfQogICAgZXJyb3JzX2J5X2NvbGxlY3Rpb24gPSB7dGFyZ2V0LmNvbGxlY3Rpb25fbmFtZTogMCBmb3IgdGFyZ2V0IGluIHRhcmdldHN9CiAgICBlcnJvcl9zYW1wbGVzX2J5X2NvbGxlY3Rpb246IGRpY3Rbc3RyLCBsaXN0W3N0cl1dID0ge3RhcmdldC5jb2xsZWN0aW9uX25hbWU6IFtdIGZvciB0YXJnZXQgaW4gdGFyZ2V0c30KICAgIHRhcmdldF9ieV9tb2RlbCA9IHt0YXJnZXQubW9kZWxfY2hvaWNlOiB0YXJnZXQgZm9yIHRhcmdldCBpbiB0YXJnZXRzfQoKICAgICMgQ2FycmVnYSBvIHByaW1laXJvIG1vZGVsbyBhbnRlcyBwYXJhIGF1dG90dW5lIGNvbSBtaWNyby1iZW5jaG1hcmsuCiAgICBwcmltYXJ5X3RhcmdldCA9IHRhcmdldHNbMF0KICAgIHByaW1hcnlfcXVhbnRpemF0aW9uID0gamluYV9xdWFudGl6YXRpb24gaWYgcHJpbWFyeV90YXJnZXQubW9kZWxfY2hvaWNlID09ICJqaW5hIiBlbHNlICJkZWZhdWx0IgogICAgbG9hZGVkX21vZGVsc1twcmltYXJ5X3RhcmdldC5tb2RlbF9jaG9pY2VdID0gbG9hZF9lbWJlZGRpbmdfbW9kZWwocHJpbWFyeV90YXJnZXQubW9kZWxfY2hvaWNlLCBwcmltYXJ5X3F1YW50aXphdGlvbikKICAgIHByaW1hcnlfbW9kZWwgPSBsb2FkZWRfbW9kZWxzW3ByaW1hcnlfdGFyZ2V0Lm1vZGVsX2Nob2ljZV0KCiAgICBpZiBwZXJmX3Byb2ZpbGUgPT0gImF1dG90dW5lIjoKICAgICAgICB0dW5lZCA9IF9yZXNvbHZlX2F1dG90dW5lZF9wYXJhbXMoCiAgICAgICAgICAgIG1vZGVsPXByaW1hcnlfbW9kZWwsCiAgICAgICAgICAgIGNodW5rX3NpemVfbG9ja2VkPWNodW5rX3NpemVfbG9ja2VkLAogICAgICAgICAgICBjaHVua19vdmVybGFwX2xvY2tlZD1jaHVua19vdmVybGFwX2xvY2tlZCwKICAgICAgICAgICAgYmF0Y2hfc2l6ZV9sb2NrZWQ9YmF0Y2hfc2l6ZV9sb2NrZWQsCiAgICAgICAgICAgIGNodW5rX3NpemU9ZWZmZWN0aXZlX2NodW5rX3NpemUsCiAgICAgICAgICAgIGNodW5rX292ZXJsYXA9ZWZmZWN0aXZlX2NodW5rX292ZXJsYXAsCiAgICAgICAgICAgIGVtYmVkZGluZ19iYXRjaF9zaXplPWVmZmVjdGl2ZV9iYXRjaF9zaXplLAogICAgICAgICkKICAgIGVsc2U6CiAgICAgICAgdHVuZWQgPSBfcmVzb2x2ZV9tYXhfcGVyZm9ybWFuY2VfcGFyYW1zKAogICAgICAgICAgICBjaHVua19zaXplX2xvY2tlZD1jaHVua19zaXplX2xvY2tlZCwKICAgICAgICAgICAgY2h1bmtfb3ZlcmxhcF9sb2NrZWQ9Y2h1bmtfb3ZlcmxhcF9sb2NrZWQsCiAgICAgICAgICAgIGJhdGNoX3NpemVfbG9ja2VkPWJhdGNoX3NpemVfbG9ja2VkLAogICAgICAgICAgICBjaHVua19zaXplPWVmZmVjdGl2ZV9jaHVua19zaXplLAogICAgICAgICAgICBjaHVua19vdmVybGFwPWVmZmVjdGl2ZV9jaHVua19vdmVybGFwLAogICAgICAgICAgICBlbWJlZGRpbmdfYmF0Y2hfc2l6ZT1lZmZlY3RpdmVfYmF0Y2hfc2l6ZSwKICAgICAgICApCgogICAgZWZmZWN0aXZlX2NodW5rX3NpemUgPSBtYXgoMjU2LCB0dW5lZC5jaHVua19zaXplKQogICAgZWZmZWN0aXZlX2NodW5rX292ZXJsYXAgPSBtYXgoMCwgbWluKGVmZmVjdGl2ZV9jaHVua19zaXplIC0gMSwgdHVuZWQuY2h1bmtfb3ZlcmxhcCkpCiAgICBlZmZlY3RpdmVfYmF0Y2hfc2l6ZSA9IG1heCgxLCB0dW5lZC5lbWJlZGRpbmdfYmF0Y2hfc2l6ZSkKCiAgICBmb3IgcmVhc29uIGluIHR1bmVkLnJlYXNvbnM6CiAgICAgICAgcHJpbnQoZiJbQ09ORklHXSB7cmVhc29ufSIpCgogICAgcHJpbnQoCiAgICAgICAgZiJbQ09ORklHXSBQYXLDom1ldHJvcyBmaW5haXM6ICIKICAgICAgICBmImNodW5rX3NpemU9e2VmZmVjdGl2ZV9jaHVua19zaXplfSwgY2h1bmtfb3ZlcmxhcD17ZWZmZWN0aXZlX2NodW5rX292ZXJsYXB9LCAiCiAgICAgICAgZiJlbWJlZGRpbmdfYmF0Y2g9e2VmZmVjdGl2ZV9iYXRjaF9zaXplfSIKICAgICkKCiAgICBzYXZlX2luZGV4ZXJfdHVuaW5nX2NvbmZpZygKICAgICAgICB7CiAgICAgICAgICAgICJlbWJlZGRpbmdfbW9kZWwiOiBtb2RlbF9jaG9pY2UsCiAgICAgICAgICAgICJqaW5hX3F1YW50aXphdGlvbiI6IGppbmFfcXVhbnRpemF0aW9uLAogICAgICAgICAgICAicGVyZl9wcm9maWxlIjogcGVyZl9wcm9maWxlLAogICAgICAgICAgICAiY2h1bmtfc2l6ZSI6IGVmZmVjdGl2ZV9jaHVua19zaXplLAogICAgICAgICAgICAiY2h1bmtfb3ZlcmxhcCI6IGVmZmVjdGl2ZV9jaHVua19vdmVybGFwLAogICAgICAgICAgICAiZW1iZWRkaW5nX2JhdGNoX3NpemUiOiBlZmZlY3RpdmVfYmF0Y2hfc2l6ZSwKICAgICAgICB9CiAgICApCgogICAgc3BsaXR0ZXIgPSBnZXRfdGV4dF9zcGxpdHRlcihlZmZlY3RpdmVfY2h1bmtfc2l6ZSwgZWZmZWN0aXZlX2NodW5rX292ZXJsYXApCgogICAgcHJpbnQoZiJcblsrXSBWYXJyZW5kbyBlIGluZGV4YW5kbyBhcnF1aXZvcyBlbToge3Jvb3RfcGF0aH0iKQogICAgZmlsZXMgPSBsaXN0KHNjYW5fZmlsZXMocm9vdF9wYXRoKSkKICAgIGZpbGVzX3NjYW5uZWQgPSBsZW4oZmlsZXMpCiAgICBpZiBmaWxlc19zY2FubmVkID09IDA6CiAgICAgICAgcHJpbnQoIltBVklTT10gTmVuaHVtIGFycXVpdm8gZW5jb250cmFkby4gVmVyaWZpcXVlIG8gY2FtaW5obyBlIG9zIGZpbHRyb3MuIikKICAgICAgICBzeXMuZXhpdCgwKQoKICAgIHByaW50KGYiWytdIHtmaWxlc19zY2FubmVkfSBhcnF1aXZvKHMpIGVsZWfDrXZlbChpcykgcGFyYSBpbmRleGHDp8Ojby4iKQogICAgd2l0aCB0cWRtKAogICAgICAgIHRvdGFsPWZpbGVzX3NjYW5uZWQsCiAgICAgICAgZGVzYz0iSW5kZXhhbmRvIiwKICAgICAgICB1bml0PSJhcnF1aXZvIiwKICAgICAgICBiYXJfZm9ybWF0PSJ7bF9iYXJ9e2Jhcn18IHtuX2ZtdH0ve3RvdGFsX2ZtdH0gW3tlbGFwc2VkfSwge3JhdGVfZm10fV0iLAogICAgKSBhcyBwYmFyOgogICAgICAgIGZvciBmaWxlcGF0aCBpbiBmaWxlczoKICAgICAgICAgICAgdGFyZ2V0X21vZGVscyA9IF9jbGFzc2lmeV9maWxlX3RhcmdldHMoZmlsZXBhdGgsIG1vZGVsX2Nob2ljZSkKCiAgICAgICAgICAgIGZvciB0YXJnZXRfbW9kZWwgaW4gdGFyZ2V0X21vZGVsczoKICAgICAgICAgICAgICAgIHRhcmdldCA9IHRhcmdldF9ieV9tb2RlbC5nZXQodGFyZ2V0X21vZGVsKQogICAgICAgICAgICAgICAgaWYgdGFyZ2V0IGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgY29udGludWUKCiAgICAgICAgICAgICAgICBpZiB0YXJnZXQubW9kZWxfY2hvaWNlIG5vdCBpbiBsb2FkZWRfbW9kZWxzOgogICAgICAgICAgICAgICAgICAgIHRhcmdldF9xdWFudGl6YXRpb24gPSBqaW5hX3F1YW50aXphdGlvbiBpZiB0YXJnZXQubW9kZWxfY2hvaWNlID09ICJqaW5hIiBlbHNlICJkZWZhdWx0IgogICAgICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICAgICAgbG9hZGVkX21vZGVsc1t0YXJnZXQubW9kZWxfY2hvaWNlXSA9IGxvYWRfZW1iZWRkaW5nX21vZGVsKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0Lm1vZGVsX2Nob2ljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldF9xdWFudGl6YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGxvYWRfZXJyb3I6CiAgICAgICAgICAgICAgICAgICAgICAgICMgRW0gaHlicmlkLCBwb2RlIGZhbHRhciBSQU0gYW8gbWFudGVyIGRvaXMgbW9kZWxvcyBncmFuZGVzIHNpbXVsdGFuZWFtZW50ZS4KICAgICAgICAgICAgICAgICAgICAgICAgaWYgbW9kZWxfY2hvaWNlID09ICJoeWJyaWQiIGFuZCBsb2FkZWRfbW9kZWxzIGFuZCBfaXNfbWVtb3J5X3JlbGF0ZWRfZXJyb3IobG9hZF9lcnJvcik6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmludCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiW0FWSVNPXSBGYWxoYSBhbyBjYXJyZWdhciBtb2RlbG8gYWRpY2lvbmFsIG5vIGh5YnJpZCBwb3IgbWVtw7NyaWEuICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTGliZXJhbmRvIG1vZGVsbyBhbnRlcmlvciBlIHRlbnRhbmRvIG5vdmFtZW50ZS4iCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2FkZWRfbW9kZWxzLmNsZWFyKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdjLmNvbGxlY3QoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9hZGVkX21vZGVsc1t0YXJnZXQubW9kZWxfY2hvaWNlXSA9IGxvYWRfZW1iZWRkaW5nX21vZGVsKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldC5tb2RlbF9jaG9pY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0X3F1YW50aXphdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhaXNlCgogICAgICAgICAgICAgICAgbW9kZWwgPSBsb2FkZWRfbW9kZWxzW3RhcmdldC5tb2RlbF9jaG9pY2VdCiAgICAgICAgICAgICAgICBjb2xsZWN0aW9uID0gY29sbGVjdGlvbnNbdGFyZ2V0LmNvbGxlY3Rpb25fbmFtZV0KICAgICAgICAgICAgICAgIGZpbGVzX2VsaWdpYmxlX2J5X2NvbGxlY3Rpb25bdGFyZ2V0LmNvbGxlY3Rpb25fbmFtZV0gKz0gMQoKICAgICAgICAgICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgICAgICBuX2NodW5rcyA9IGluZGV4X2ZpbGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlcGF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbGxlY3Rpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwbGl0dGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcm9vdF9wYXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZW1iZWRkaW5nX2JhdGNoX3NpemU9ZWZmZWN0aXZlX2JhdGNoX3NpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfY2h1bmtzICs9IG5fY2h1bmtzCiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzX3Byb2Nlc3NlZF90b3RhbCArPSAxCiAgICAgICAgICAgICAgICAgICAgICAgIGNodW5rc19ieV9jb2xsZWN0aW9uW3RhcmdldC5jb2xsZWN0aW9uX25hbWVdICs9IG5fY2h1bmtzCiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzX2J5X2NvbGxlY3Rpb25bdGFyZ2V0LmNvbGxlY3Rpb25fbmFtZV0gKz0gMQogICAgICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICAgICAgICAgICAgICAgICAgIyBGYWxsYmFjayBhdXRvbcOhdGljbyBwYXJhIGV2aXRhciBxdWVicmEgdG90YWwgZW0gbcOhcXVpbmFzIG5vIGxpbWl0ZSBkZSBSQU0uCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdCBiYXRjaF9zaXplX2xvY2tlZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5kIGVmZmVjdGl2ZV9iYXRjaF9zaXplID4gMQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5kIF9pc19tZW1vcnlfcmVsYXRlZF9lcnJvcihlKQogICAgICAgICAgICAgICAgICAgICAgICApOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3X2JhdGNoID0gbWF4KDEsIGVmZmVjdGl2ZV9iYXRjaF9zaXplIC8vIDIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBuZXdfYmF0Y2ggPCBlZmZlY3RpdmVfYmF0Y2hfc2l6ZToKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cWRtLndyaXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIiAgW0FKVVNURV0gTWVtw7NyaWEgYWx0YSBlbSB7dGFyZ2V0LmxhYmVsfS4gIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIkJhdGNoIHJlZHV6aWRvIHtlZmZlY3RpdmVfYmF0Y2hfc2l6ZX0gLT4ge25ld19iYXRjaH0uIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3RpdmVfYmF0Y2hfc2l6ZSA9IG5ld19iYXRjaAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdjLmNvbGxlY3QoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfaXNfZGltZW5zaW9uX21pc21hdGNoX2Vycm9yKGUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmQgbm90IGNvbGxlY3Rpb25fZGltZW5zaW9uX3Jlc2V0X2RvbmVbdGFyZ2V0LmNvbGxlY3Rpb25fbmFtZV0KICAgICAgICAgICAgICAgICAgICAgICAgKToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRxZG0ud3JpdGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiIgIFtBSlVTVEVdIERpbWVuc8OjbyBpbmNvbXBhdMOtdmVsIGRldGVjdGFkYSBlbSAne3RhcmdldC5jb2xsZWN0aW9uX25hbWV9Jy4gIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZWNyaWFuZG8gY29sZcOnw6NvIGUgdGVudGFuZG8gbm92YW1lbnRlLiIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGllbnQuZGVsZXRlX2NvbGxlY3Rpb24odGFyZ2V0LmNvbGxlY3Rpb25fbmFtZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFzcwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbGxlY3Rpb25zW3RhcmdldC5jb2xsZWN0aW9uX25hbWVdID0gY2xpZW50LmdldF9vcl9jcmVhdGVfY29sbGVjdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lPXRhcmdldC5jb2xsZWN0aW9uX25hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGE9eyJobnN3OnNwYWNlIjogImNvc2luZSJ9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sbGVjdGlvbl9kaW1lbnNpb25fcmVzZXRfZG9uZVt0YXJnZXQuY29sbGVjdGlvbl9uYW1lXSA9IFRydWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdjLmNvbGxlY3QoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUKCiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9ycyArPSAxCiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yc19ieV9jb2xsZWN0aW9uW3RhcmdldC5jb2xsZWN0aW9uX25hbWVdICs9IDEKICAgICAgICAgICAgICAgICAgICAgICAgaWYgbGVuKGVycm9yX3NhbXBsZXNfYnlfY29sbGVjdGlvblt0YXJnZXQuY29sbGVjdGlvbl9uYW1lXSkgPCAzOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3Jfc2FtcGxlc19ieV9jb2xsZWN0aW9uW3RhcmdldC5jb2xsZWN0aW9uX25hbWVdLmFwcGVuZCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIntmaWxlcGF0aC5uYW1lfToge19mb3JtYXRfZXhjZXB0aW9uKGUpfSIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgdHFkbS53cml0ZShmIiAgW0VSUk9dIHtmaWxlcGF0aH0gW3t0YXJnZXQubGFiZWx9XToge19mb3JtYXRfZXhjZXB0aW9uKGUpfSIpCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrCgogICAgICAgICAgICBwYmFyLnNldF9wb3N0Zml4KHsiY2h1bmtzIjogdG90YWxfY2h1bmtzLCAiYXR1YWwiOiBmaWxlcGF0aC5uYW1lWzoyMF19KQogICAgICAgICAgICBwYmFyLnVwZGF0ZSgxKQoKICAgIGZvciB0YXJnZXQgaW4gdGFyZ2V0czoKICAgICAgICBjb2xsZWN0aW9uX25hbWUgPSB0YXJnZXQuY29sbGVjdGlvbl9uYW1lCiAgICAgICAgZWxpZ2libGUgPSBmaWxlc19lbGlnaWJsZV9ieV9jb2xsZWN0aW9uW2NvbGxlY3Rpb25fbmFtZV0KICAgICAgICBwcm9jZXNzZWQgPSBmaWxlc19ieV9jb2xsZWN0aW9uW2NvbGxlY3Rpb25fbmFtZV0KICAgICAgICB0YXJnZXRfZXJyb3JzID0gZXJyb3JzX2J5X2NvbGxlY3Rpb25bY29sbGVjdGlvbl9uYW1lXQoKICAgICAgICBpZiBlbGlnaWJsZSA9PSAwOgogICAgICAgICAgICBwcmludChmIltBVklTT10gTmVuaHVtIGFycXVpdm8gZWxlZ8OtdmVsIHBhcmEge3RhcmdldC5sYWJlbH07IGV0YXBhIGlnbm9yYWRhLiIpCiAgICAgICAgZWxpZiBwcm9jZXNzZWQgPT0gMCBhbmQgdGFyZ2V0X2Vycm9ycyA+IDA6CiAgICAgICAgICAgIHByaW50KAogICAgICAgICAgICAgICAgZiJbQVZJU09dIHtlbGlnaWJsZX0gYXJxdWl2byhzKSBlbGVnw612ZWwoaXMpIHBhcmEge3RhcmdldC5sYWJlbH0sICIKICAgICAgICAgICAgICAgICJtYXMgdG9kb3MgZmFsaGFyYW0uIgogICAgICAgICAgICApCgogICAgICAgIGlmIHRhcmdldF9lcnJvcnM6CiAgICAgICAgICAgIHByaW50KGYiW0FWSVNPXSB7dGFyZ2V0X2Vycm9yc30gZXJybyhzKSBkdXJhbnRlIGEgaW5kZXhhw6fDo28gZG8gdGFyZ2V0IHt0YXJnZXQubGFiZWx9LiIpCiAgICAgICAgICAgIGZvciBzYW1wbGUgaW4gZXJyb3Jfc2FtcGxlc19ieV9jb2xsZWN0aW9uW2NvbGxlY3Rpb25fbmFtZV06CiAgICAgICAgICAgICAgICBwcmludChmIiAgICAgICAgLSB7c2FtcGxlfSIpCgogICAgaW5kZXhfZmluaXNoZWRfYXQgPSBkYXRldGltZS5ub3coKQogICAgZWxhcHNlZF9zZWNvbmRzID0gaW50KChpbmRleF9maW5pc2hlZF9hdCAtIGluZGV4X3N0YXJ0ZWRfYXQpLnRvdGFsX3NlY29uZHMoKSkKICAgIGVsYXBzZWRfaCA9IGVsYXBzZWRfc2Vjb25kcyAvLyAzNjAwCiAgICBlbGFwc2VkX20gPSAoZWxhcHNlZF9zZWNvbmRzICUgMzYwMCkgLy8gNjAKICAgIGVsYXBzZWRfcyA9IGVsYXBzZWRfc2Vjb25kcyAlIDYwCiAgICBwcmludChmIlxueyc9Jyo2MH0iKQogICAgcHJpbnQoZiIgIEluZGV4YcOnw6NvIGNvbmNsdcOtZGEhIikKICAgIHByaW50KGYiICBJbsOtY2lvICAgICAgICAgICAgICAgOiB7aW5kZXhfc3RhcnRlZF9hdC5zdHJmdGltZSgnJVktJW0tJWQgJUg6JU06JVMnKX0iKQogICAgcHJpbnQoZiIgIEZpbSAgICAgICAgICAgICAgICAgIDoge2luZGV4X2ZpbmlzaGVkX2F0LnN0cmZ0aW1lKCclWS0lbS0lZCAlSDolTTolUycpfSIpCiAgICBwcmludChmIiAgRHVyYcOnw6NvICAgICAgICAgICAgICA6IHtlbGFwc2VkX2g6MDJkfTp7ZWxhcHNlZF9tOjAyZH06e2VsYXBzZWRfczowMmR9IikKICAgIHByaW50KGYiICBBcnF1aXZvcyB2YXJyaWRvcyAgICA6IHtmaWxlc19zY2FubmVkfSIpCiAgICBwcmludChmIiAgQXJxdWl2b3MgcHJvY2Vzc2Fkb3MgOiB7ZmlsZXNfcHJvY2Vzc2VkX3RvdGFsfSIpCiAgICBwcmludChmIiAgVG90YWwgZGUgY2h1bmtzICAgICAgOiB7dG90YWxfY2h1bmtzfSIpCiAgICBwcmludChmIiAgRXJyb3MgICAgICAgICAgICAgICAgOiB7ZXJyb3JzfSIpCiAgICBmb3IgdGFyZ2V0IGluIHRhcmdldHM6CiAgICAgICAgY29sbGVjdGlvbl9uYW1lID0gdGFyZ2V0LmNvbGxlY3Rpb25fbmFtZQogICAgICAgIHByaW50KAogICAgICAgICAgICBmIiAgQ29sZcOnw6NvIENocm9tYURCICAgICA6ICd7Y29sbGVjdGlvbl9uYW1lfScgIgogICAgICAgICAgICBmIihlbGVnw612ZWlzPXtmaWxlc19lbGlnaWJsZV9ieV9jb2xsZWN0aW9uLmdldChjb2xsZWN0aW9uX25hbWUsIDApfSwgIgogICAgICAgICAgICBmImFycXVpdm9zPXtmaWxlc19ieV9jb2xsZWN0aW9uLmdldChjb2xsZWN0aW9uX25hbWUsIDApfSwgIgogICAgICAgICAgICBmImNodW5rcz17Y2h1bmtzX2J5X2NvbGxlY3Rpb24uZ2V0KGNvbGxlY3Rpb25fbmFtZSwgMCl9KSIKICAgICAgICApCiAgICBwcmludChmInsnPScqNjB9XG4iKQoKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICB0cnk6CiAgICAgICAgbWFpbigpCiAgICBleGNlcHQgTWVtb3J5RXJyb3I6CiAgICAgICAgcHJpbnQoCiAgICAgICAgICAgICJbRVJST10gRmFsaGEgZGUgbWVtw7NyaWEgZHVyYW50ZSBhIGluZGV4YcOnw6NvLiAiCiAgICAgICAgICAgICJVc2UgLS1lbWJlZGRpbmctbW9kZWwgYmdlIG91IGV4ZWN1dGUgbyBKaW5hIGVtIG3DoXF1aW5hIGNvbSBtYWlzIFJBTS9zd2FwLiIKICAgICAgICApCiAgICAgICAgc3lzLmV4aXQoMSkK"
|
|
728
|
-
B64_MCP="IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwpmcm9tIF9fZnV0dXJlX18gaW1wb3J0IGFubm90YXRpb25zCiIiIgptY3Bfc2VydmVyLnB5IOKAlCBTZXJ2aWRvciBNQ1AgcGFyYSBSQUcgbG9jYWwgZGUgY29kZWJhc2UuCgpFeHDDtWUgZmVycmFtZW50YXMgZGUgYnVzY2Egc2Vtw6JudGljYSBlIGluZGV4YcOnw6NvIHZpYSBzdGRpbyBwYXJhIG8gQ2xhdWRlIENvZGUgQ0xJLgpDb25lY3RhLXNlIGFvIENocm9tYURCIHJvZGFuZG8gZW0gRG9ja2VyIChsb2NhbGhvc3Q6ODAwMCkuCgpOb3ZpZGFkZTogbW9kbyBow61icmlkbyBlbnNlbWJsZSBjb20gZHVhcyBjb2xlw6fDtWVzIHNlcGFyYWRhcyArIFJSRiArIHJlcmFua2luZyBsZXZlLgoiIiIKCmltcG9ydCBzeXMKaW1wb3J0IG9zCmltcG9ydCBoYXNobGliCmltcG9ydCBqc29uCmltcG9ydCBsb2dnaW5nCmltcG9ydCBnZXRwYXNzCmltcG9ydCBzaHV0aWwKZnJvbSBjb2xsZWN0aW9ucy5hYmMgaW1wb3J0IEl0ZXJhdG9yCmZyb20gY29uY3VycmVudC5mdXR1cmVzIGltcG9ydCBUaHJlYWRQb29sRXhlY3V0b3IsIGFzX2NvbXBsZXRlZApmcm9tIGRhdGFjbGFzc2VzIGltcG9ydCBkYXRhY2xhc3MKZnJvbSBkYXRldGltZSBpbXBvcnQgZGF0ZXRpbWUsIHRpbWV6b25lCmZyb20gcGF0aGxpYiBpbXBvcnQgUGF0aApmcm9tIHVybGxpYi5wYXJzZSBpbXBvcnQgdXJscGFyc2UKCiMgRXZpdGEgbWVuc2FnZW5zIGFkdmlzb3J5IGRvIHRyYW5zZm9ybWVycyBlbSBzdGRlcnIgZHVyYW50ZSBhIGNhcmdhIGRvIG1vZGVsby4Kb3MuZW52aXJvbi5zZXRkZWZhdWx0KCJUUkFOU0ZPUk1FUlNfTk9fQURWSVNPUllfV0FSTklOR1MiLCAiMSIpCgoKY2xhc3MgX1RvcmNoRHR5cGVXYXJuaW5nRmlsdGVyKGxvZ2dpbmcuRmlsdGVyKToKICAgIGRlZiBmaWx0ZXIoc2VsZiwgcmVjb3JkOiBsb2dnaW5nLkxvZ1JlY29yZCkgLT4gYm9vbDoKICAgICAgICByZXR1cm4gImB0b3JjaF9kdHlwZWAgaXMgZGVwcmVjYXRlZCEgVXNlIGBkdHlwZWAgaW5zdGVhZCEiIG5vdCBpbiByZWNvcmQuZ2V0TWVzc2FnZSgpCgoKZm9yIF9sb2dnZXJfbmFtZSBpbiAoInRyYW5zZm9ybWVycy5jb25maWd1cmF0aW9uX3V0aWxzIiwgInRyYW5zZm9ybWVycy5tb2RlbGluZ191dGlscyIpOgogICAgbG9nZ2luZy5nZXRMb2dnZXIoX2xvZ2dlcl9uYW1lKS5hZGRGaWx0ZXIoX1RvcmNoRHR5cGVXYXJuaW5nRmlsdGVyKCkpCgppbXBvcnQgY2hyb21hZGIKZnJvbSBzZW50ZW5jZV90cmFuc2Zvcm1lcnMgaW1wb3J0IENyb3NzRW5jb2RlciwgU2VudGVuY2VUcmFuc2Zvcm1lcgpmcm9tIGxhbmdjaGFpbl90ZXh0X3NwbGl0dGVycyBpbXBvcnQgUmVjdXJzaXZlQ2hhcmFjdGVyVGV4dFNwbGl0dGVyCmZyb20gbWNwLnNlcnZlci5mYXN0bWNwIGltcG9ydCBGYXN0TUNQCmZyb20gZG93bmxvYWRfbW9kZWxfZnJvbV9odWdnaW5mYWNlIGltcG9ydCBkb3dubG9hZF9tb2RlbF93aXRoX2ZhbGxiYWNrCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIENvbmZpZ3VyYcOnw6NvIGRlIGxvZ2dpbmcgKHN0ZGVyciBwYXJhIG7Do28gcG9sdWlyIG8gcHJvdG9jb2xvIHN0ZGlvKQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKbG9nZ2luZy5iYXNpY0NvbmZpZygKICAgIGxldmVsPWxvZ2dpbmcuSU5GTywKICAgIGZvcm1hdD0iW01DUC1SQUddICUoYXNjdGltZSlzICUobGV2ZWxuYW1lKXM6ICUobWVzc2FnZSlzIiwKICAgIHN0cmVhbT1zeXMuc3RkZXJyLAopCmxvZyA9IGxvZ2dpbmcuZ2V0TG9nZ2VyKF9fbmFtZV9fKQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBMb2cgZXN0cnV0dXJhZG8gZGUgdXNvIE1DUCAoSlNPTkwpCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpNQ1BfVVNBR0VfTE9HX1BBVEggPSBQYXRoKAogICAgb3MuZW52aXJvbi5nZXQoIk1DUF9VU0FHRV9MT0ciLCBzdHIoUGF0aC5ob21lKCkgLyAiLnJhZ19kYiIgLyAibWNwX3VzYWdlLmxvZyIpKQopLmV4cGFuZHVzZXIoKQoKCmRlZiBfc2FmZV9wcmV2aWV3KHZhbHVlOiBzdHIsIGxpbWl0OiBpbnQgPSAxMjApIC0+IHN0cjoKICAgIGlmIGxlbih2YWx1ZSkgPD0gbGltaXQ6CiAgICAgICAgcmV0dXJuIHZhbHVlCiAgICByZXR1cm4gdmFsdWVbOmxpbWl0XSArICIuLi5bdHJ1bmNhdGVkXSIKCgpkZWYgX2dldF9wYXJlbnRfY21kbGluZSgpIC0+IHN0cjoKICAgIHBwaWQgPSBvcy5nZXRwcGlkKCkKICAgIGNtZGxpbmVfcGF0aCA9IFBhdGgoZiIvcHJvYy97cHBpZH0vY21kbGluZSIpCiAgICB0cnk6CiAgICAgICAgcmF3ID0gY21kbGluZV9wYXRoLnJlYWRfYnl0ZXMoKQogICAgICAgIGlmIG5vdCByYXc6CiAgICAgICAgICAgIHJldHVybiAidW5rbm93biIKICAgICAgICBwYXJ0cyA9IFtwLmRlY29kZSgidXRmLTgiLCBlcnJvcnM9Imlnbm9yZSIpIGZvciBwIGluIHJhdy5zcGxpdChiIlx4MDAiKSBpZiBwXQogICAgICAgIHJldHVybiAiICIuam9pbihwYXJ0cykgaWYgcGFydHMgZWxzZSAidW5rbm93biIKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcmV0dXJuICJ1bmtub3duIgoKCmRlZiBfaW5mZXJfYWN0b3IoKSAtPiBkaWN0W3N0ciwgc3RyXToKICAgIGFjdG9yID0gb3MuZW52aXJvbi5nZXQoIk1DUF9DTElFTlRfTkFNRSIpIG9yIG9zLmVudmlyb24uZ2V0KCJDTEFVREVfVVNFUiIpIG9yIGdldHBhc3MuZ2V0dXNlcigpCiAgICBzb3VyY2UgPSAoCiAgICAgICAgIk1DUF9DTElFTlRfTkFNRSIgaWYgb3MuZW52aXJvbi5nZXQoIk1DUF9DTElFTlRfTkFNRSIpCiAgICAgICAgZWxzZSAiQ0xBVURFX1VTRVIiIGlmIG9zLmVudmlyb24uZ2V0KCJDTEFVREVfVVNFUiIpCiAgICAgICAgZWxzZSAic3lzdGVtX3VzZXIiCiAgICApCiAgICByZXR1cm4gewogICAgICAgICJhY3RvciI6IGFjdG9yLAogICAgICAgICJhY3Rvcl9zb3VyY2UiOiBzb3VyY2UsCiAgICAgICAgImNsaWVudF9wcm9jZXNzIjogX2dldF9wYXJlbnRfY21kbGluZSgpLAogICAgfQoKCmRlZiBfbG9nX3Rvb2xfdXNhZ2UoZXZlbnQ6IHN0ciwgdG9vbF9uYW1lOiBzdHIsIGRldGFpbHM6IGRpY3Rbc3RyLCBvYmplY3RdIHwgTm9uZSA9IE5vbmUpIC0+IE5vbmU6CiAgICB0cnk6CiAgICAgICAgTUNQX1VTQUdFX0xPR19QQVRILnBhcmVudC5ta2RpcihwYXJlbnRzPVRydWUsIGV4aXN0X29rPVRydWUpCiAgICAgICAgcGF5bG9hZDogZGljdFtzdHIsIG9iamVjdF0gPSB7CiAgICAgICAgICAgICJ0aW1lc3RhbXAiOiBkYXRldGltZS5ub3codGltZXpvbmUudXRjKS5pc29mb3JtYXQoKSwKICAgICAgICAgICAgImV2ZW50IjogZXZlbnQsCiAgICAgICAgICAgICJ0b29sIjogdG9vbF9uYW1lLAogICAgICAgICAgICAicGlkIjogb3MuZ2V0cGlkKCksCiAgICAgICAgICAgICoqX2luZmVyX2FjdG9yKCksCiAgICAgICAgfQogICAgICAgIGlmIGRldGFpbHM6CiAgICAgICAgICAgIHBheWxvYWRbImRldGFpbHMiXSA9IGRldGFpbHMKCiAgICAgICAgd2l0aCBNQ1BfVVNBR0VfTE9HX1BBVEgub3BlbigiYSIsIGVuY29kaW5nPSJ1dGYtOCIpIGFzIGY6CiAgICAgICAgICAgIGYud3JpdGUoanNvbi5kdW1wcyhwYXlsb2FkLCBlbnN1cmVfYXNjaWk9VHJ1ZSkgKyAiXG4iKQogICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgIGxvZy53YXJuaW5nKCJGYWxoYSBhbyByZWdpc3RyYXIgdXNvIE1DUCBlbSAlczogJXMiLCBNQ1BfVVNBR0VfTE9HX1BBVEgsIGUpCgoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBDb25maWd1cmHDp8O1ZXMKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgpJTkRFWEVSX0NPTkZJR19QQVRIID0gUGF0aCgKICAgIG9zLmVudmlyb24uZ2V0KAogICAgICAgICJNQ1BfSU5ERVhFUl9DT05GSUdfRklMRSIsCiAgICAgICAgc3RyKFBhdGguaG9tZSgpIC8gIi5jYWNoZSIgLyAib3duLXJhZy1jbGkiIC8gImluZGV4ZXJfdHVuaW5nLmpzb24iKSwKICAgICkKKS5leHBhbmR1c2VyKCkKT1dOX1JBR19DTElfQ09ORklHX1BBVEggPSBQYXRoKAogICAgb3MuZW52aXJvbi5nZXQoIk9XTl9SQUdfQ0xJX0NPTkZJR19GSUxFIiwgc3RyKFBhdGguaG9tZSgpIC8gIi5vd24tcmFnLWNsaS5qc29uIikpCikuZXhwYW5kdXNlcigpCgoKZGVmIF9sb2FkX2luZGV4ZXJfdHVuaW5nX2NvbmZpZygpIC0+IGRpY3Rbc3RyLCBvYmplY3RdOgogICAgdHJ5OgogICAgICAgIGlmIG5vdCBJTkRFWEVSX0NPTkZJR19QQVRILmV4aXN0cygpOgogICAgICAgICAgICByZXR1cm4ge30KICAgICAgICBwYXlsb2FkID0ganNvbi5sb2FkcyhJTkRFWEVSX0NPTkZJR19QQVRILnJlYWRfdGV4dChlbmNvZGluZz0idXRmLTgiKSkKICAgICAgICByZXR1cm4gcGF5bG9hZCBpZiBpc2luc3RhbmNlKHBheWxvYWQsIGRpY3QpIGVsc2Uge30KICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcmV0dXJuIHt9CgoKSU5ERVhFUl9UVU5JTkdfQ09ORklHID0gX2xvYWRfaW5kZXhlcl90dW5pbmdfY29uZmlnKCkKCgpkZWYgX2xvYWRfb3duX3JhZ19jbGlfY29uZmlnX3BheWxvYWQoKSAtPiBkaWN0W3N0ciwgb2JqZWN0XToKICAgIHRyeToKICAgICAgICBpZiBub3QgT1dOX1JBR19DTElfQ09ORklHX1BBVEguZXhpc3RzKCk6CiAgICAgICAgICAgIHJldHVybiB7fQogICAgICAgIHBheWxvYWQgPSBqc29uLmxvYWRzKE9XTl9SQUdfQ0xJX0NPTkZJR19QQVRILnJlYWRfdGV4dChlbmNvZGluZz0idXRmLTgiKSkKICAgICAgICByZXR1cm4gcGF5bG9hZCBpZiBpc2luc3RhbmNlKHBheWxvYWQsIGRpY3QpIGVsc2Uge30KICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcmV0dXJuIHt9CgoKZGVmIF9jb25maWdfc3RyKGVudl9uYW1lOiBzdHIsIGNvbmZpZ19rZXk6IHN0ciwgZGVmYXVsdDogc3RyKSAtPiBzdHI6CiAgICBlbnZfcmF3ID0gb3MuZW52aXJvbi5nZXQoZW52X25hbWUpCiAgICBpZiBlbnZfcmF3IGlzIG5vdCBOb25lIGFuZCBlbnZfcmF3LnN0cmlwKCk6CiAgICAgICAgcmV0dXJuIGVudl9yYXcKICAgIGNmZ19yYXcgPSBJTkRFWEVSX1RVTklOR19DT05GSUcuZ2V0KGNvbmZpZ19rZXkpCiAgICBpZiBpc2luc3RhbmNlKGNmZ19yYXcsIHN0cikgYW5kIGNmZ19yYXcuc3RyaXAoKToKICAgICAgICByZXR1cm4gY2ZnX3JhdwogICAgcmV0dXJuIGRlZmF1bHQKCgpkZWYgX3BhcnNlX2ludChyYXc6IG9iamVjdCwgZGVmYXVsdDogaW50LCAqLCBtaW5fdmFsdWU6IGludCA9IDEpIC0+IGludDoKICAgIHRyeToKICAgICAgICBwYXJzZWQgPSBpbnQoc3RyKHJhdykuc3RyaXAoKSkKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcmV0dXJuIG1heChtaW5fdmFsdWUsIGRlZmF1bHQpCiAgICByZXR1cm4gbWF4KG1pbl92YWx1ZSwgcGFyc2VkKQoKCmRlZiBfZXh0cmFjdF9jaHJvbWFfZW5kcG9pbnRfZnJvbV9jb25maWcoY29uZmlnX3BheWxvYWQ6IG9iamVjdCkgLT4gdHVwbGVbc3RyLCBzdHIsIGludF06CiAgICBzY2hlbWUgPSAiaHR0cCIKICAgIGhvc3QgPSAibG9jYWxob3N0IgogICAgcG9ydCA9IDgwMDAKCiAgICBkZWYgX3JlYWRfc2NoZW1lKHJhdzogb2JqZWN0KSAtPiBOb25lOgogICAgICAgIG5vbmxvY2FsIHNjaGVtZQogICAgICAgIGlmIG5vdCBpc2luc3RhbmNlKHJhdywgc3RyKToKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgbG93ZXJlZCA9IHJhdy5zdHJpcCgpLmxvd2VyKCkKICAgICAgICBpZiBsb3dlcmVkIGluIHsiaHR0cCIsICJodHRwcyJ9OgogICAgICAgICAgICBzY2hlbWUgPSBsb3dlcmVkCgogICAgZGVmIF9yZWFkX2hvc3QocmF3OiBvYmplY3QpIC0+IE5vbmU6CiAgICAgICAgbm9ubG9jYWwgc2NoZW1lLCBob3N0LCBwb3J0CiAgICAgICAgaWYgbm90IGlzaW5zdGFuY2UocmF3LCBzdHIpOgogICAgICAgICAgICByZXR1cm4KICAgICAgICBjYW5kaWRhdGUgPSByYXcuc3RyaXAoKQogICAgICAgIGlmIG5vdCBjYW5kaWRhdGU6CiAgICAgICAgICAgIHJldHVybgogICAgICAgIHBhcnNlZCA9IHVybHBhcnNlKGNhbmRpZGF0ZSBpZiAiOi8vIiBpbiBjYW5kaWRhdGUgZWxzZSBmIi8ve2NhbmRpZGF0ZX0iKQogICAgICAgIGlmIHBhcnNlZC5zY2hlbWUgaW4geyJodHRwIiwgImh0dHBzIn06CiAgICAgICAgICAgIHNjaGVtZSA9IHBhcnNlZC5zY2hlbWUKICAgICAgICBpZiBwYXJzZWQuaG9zdG5hbWU6CiAgICAgICAgICAgIGhvc3QgPSBwYXJzZWQuaG9zdG5hbWUKICAgICAgICBlbGlmICI6Ly8iIG5vdCBpbiBjYW5kaWRhdGU6CiAgICAgICAgICAgIGhvc3QgPSBjYW5kaWRhdGUuc3RyaXAoKS5zdHJpcCgiLyIpCiAgICAgICAgaWYgcGFyc2VkLnBvcnQgYW5kIDEgPD0gcGFyc2VkLnBvcnQgPD0gNjU1MzU6CiAgICAgICAgICAgIHBvcnQgPSBwYXJzZWQucG9ydAoKICAgIGRlZiBfcmVhZF9wb3J0KHJhdzogb2JqZWN0KSAtPiBOb25lOgogICAgICAgIG5vbmxvY2FsIHBvcnQKICAgICAgICB0cnk6CiAgICAgICAgICAgIHBhcnNlZCA9IGludChzdHIocmF3KS5zdHJpcCgpKQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgICAgIHJldHVybgogICAgICAgIGlmIDEgPD0gcGFyc2VkIDw9IDY1NTM1OgogICAgICAgICAgICBwb3J0ID0gcGFyc2VkCgogICAgaWYgaXNpbnN0YW5jZShjb25maWdfcGF5bG9hZCwgZGljdCk6CiAgICAgICAgY2hyb21hX29iaiA9IGNvbmZpZ19wYXlsb2FkLmdldCgiY2hyb21hIikKICAgICAgICBpZiBpc2luc3RhbmNlKGNocm9tYV9vYmosIGRpY3QpOgogICAgICAgICAgICBfcmVhZF9zY2hlbWUoY2hyb21hX29iai5nZXQoInNjaGVtZSIpKQogICAgICAgICAgICBfcmVhZF9ob3N0KGNocm9tYV9vYmouZ2V0KCJob3N0IikpCiAgICAgICAgICAgIF9yZWFkX3BvcnQoY2hyb21hX29iai5nZXQoInBvcnQiKSkKCiAgICAgICAgIyBDb21wYXRpYmlsaWRhZGUgY29tIGZvcm1hdG9zIGZsYXQgYW50aWdvcy4KICAgICAgICBfcmVhZF9zY2hlbWUoY29uZmlnX3BheWxvYWQuZ2V0KCJDSFJPTUFfU0NIRU1FIikpCiAgICAgICAgX3JlYWRfaG9zdChjb25maWdfcGF5bG9hZC5nZXQoIkNIUk9NQV9IT1NUIikpCiAgICAgICAgX3JlYWRfcG9ydChjb25maWdfcGF5bG9hZC5nZXQoIkNIUk9NQV9QT1JUIikpCgogICAgcmV0dXJuIHNjaGVtZSwgaG9zdCwgcG9ydAoKCmRlZiBfZXh0cmFjdF9lbWJlZGRpbmdfYmF0Y2hfZnJvbV9jb25maWcoY29uZmlnX3BheWxvYWQ6IG9iamVjdCkgLT4gaW50IHwgTm9uZToKICAgIGlmIG5vdCBpc2luc3RhbmNlKGNvbmZpZ19wYXlsb2FkLCBkaWN0KToKICAgICAgICByZXR1cm4gTm9uZQoKICAgIGRlZiBfcmVhZChyYXc6IG9iamVjdCkgLT4gaW50IHwgTm9uZToKICAgICAgICB0cnk6CiAgICAgICAgICAgIHBhcnNlZCA9IGludChzdHIocmF3KS5zdHJpcCgpKQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgICAgIHJldHVybiBOb25lCiAgICAgICAgcmV0dXJuIHBhcnNlZCBpZiBwYXJzZWQgPj0gMSBlbHNlIE5vbmUKCiAgICBpbmRleGluZyA9IGNvbmZpZ19wYXlsb2FkLmdldCgiaW5kZXhpbmciKQogICAgaWYgaXNpbnN0YW5jZShpbmRleGluZywgZGljdCk6CiAgICAgICAgZm9yIGtleSBpbiAoImVtYmVkZGluZ19iYXRjaF9zaXplIiwgImJhdGNoX2NvdW50Iik6CiAgICAgICAgICAgIHBhcnNlZCA9IF9yZWFkKGluZGV4aW5nLmdldChrZXkpKQogICAgICAgICAgICBpZiBwYXJzZWQgaXMgbm90IE5vbmU6CiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VkCgogICAgZm9yIGtleSBpbiAoIk1DUF9FTUJFRERJTkdfQkFUQ0hfU0laRSIsICJlbWJlZGRpbmdfYmF0Y2hfc2l6ZSIsICJiYXRjaF9jb3VudCIpOgogICAgICAgIHBhcnNlZCA9IF9yZWFkKGNvbmZpZ19wYXlsb2FkLmdldChrZXkpKQogICAgICAgIGlmIHBhcnNlZCBpcyBub3QgTm9uZToKICAgICAgICAgICAgcmV0dXJuIHBhcnNlZAogICAgcmV0dXJuIE5vbmUKCgpkZWYgX2xvYWRfY2xpX2Nocm9tYV9kZWZhdWx0cygpIC0+IHR1cGxlW3N0ciwgc3RyLCBpbnRdOgogICAgcGF5bG9hZCA9IF9sb2FkX293bl9yYWdfY2xpX2NvbmZpZ19wYXlsb2FkKCkKICAgIGlmIG5vdCBwYXlsb2FkOgogICAgICAgIHJldHVybiAoImh0dHAiLCAibG9jYWxob3N0IiwgODAwMCkKICAgIHJldHVybiBfZXh0cmFjdF9jaHJvbWFfZW5kcG9pbnRfZnJvbV9jb25maWcocGF5bG9hZCkKCgpkZWYgX2NvbmZpZ19pbnQoCiAgICBlbnZfbmFtZTogc3RyLAogICAgY29uZmlnX2tleTogc3RyLAogICAgZGVmYXVsdDogaW50LAogICAgKiwKICAgIG1pbl92YWx1ZTogaW50ID0gMSwKICAgIGZhbGxiYWNrX2NvbmZpZ19rZXlzOiB0dXBsZVtzdHIsIC4uLl0gPSAoKSwKKSAtPiBpbnQ6CiAgICBlbnZfcmF3ID0gb3MuZW52aXJvbi5nZXQoZW52X25hbWUpCiAgICBpZiBlbnZfcmF3IGlzIG5vdCBOb25lIGFuZCBlbnZfcmF3LnN0cmlwKCk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICByZXR1cm4gbWF4KG1pbl92YWx1ZSwgaW50KGVudl9yYXcpKQogICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICBwYXNzCgogICAgZm9yIGtleSBpbiAoY29uZmlnX2tleSwgKmZhbGxiYWNrX2NvbmZpZ19rZXlzKToKICAgICAgICBjZmdfcmF3ID0gSU5ERVhFUl9UVU5JTkdfQ09ORklHLmdldChrZXkpCiAgICAgICAgaWYgaXNpbnN0YW5jZShjZmdfcmF3LCBpbnQpOgogICAgICAgICAgICByZXR1cm4gbWF4KG1pbl92YWx1ZSwgY2ZnX3JhdykKICAgICAgICBpZiBpc2luc3RhbmNlKGNmZ19yYXcsIHN0cik6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHJldHVybiBtYXgobWluX3ZhbHVlLCBpbnQoY2ZnX3JhdykpCiAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICAgICAgcGFzcwoKICAgIHJldHVybiBtYXgobWluX3ZhbHVlLCBkZWZhdWx0KQoKCl9ERUZBVUxUX0NIUk9NQV9TQ0hFTUUsIF9ERUZBVUxUX0NIUk9NQV9IT1NULCBfREVGQVVMVF9DSFJPTUFfUE9SVCA9IF9sb2FkX2NsaV9jaHJvbWFfZGVmYXVsdHMoKQpfREVGQVVMVF9FTUJFRERJTkdfQkFUQ0hfU0laRSA9IF9leHRyYWN0X2VtYmVkZGluZ19iYXRjaF9mcm9tX2NvbmZpZyhfbG9hZF9vd25fcmFnX2NsaV9jb25maWdfcGF5bG9hZCgpKSBvciA0CkNIUk9NQV9TQ0hFTUUgPSAoCiAgICBvcy5lbnZpcm9uLmdldCgiQ0hST01BX1NDSEVNRSIpCiAgICBvciBvcy5lbnZpcm9uLmdldCgiTUNQX0NIUk9NQV9TQ0hFTUUiKQogICAgb3IgX0RFRkFVTFRfQ0hST01BX1NDSEVNRQopLnN0cmlwKCkubG93ZXIoKQppZiBDSFJPTUFfU0NIRU1FIG5vdCBpbiB7Imh0dHAiLCAiaHR0cHMifToKICAgIENIUk9NQV9TQ0hFTUUgPSBfREVGQVVMVF9DSFJPTUFfU0NIRU1FCkNIUk9NQV9IT1NUID0gKAogICAgb3MuZW52aXJvbi5nZXQoIkNIUk9NQV9IT1NUIikKICAgIG9yIG9zLmVudmlyb24uZ2V0KCJNQ1BfQ0hST01BX0hPU1QiKQogICAgb3IgX0RFRkFVTFRfQ0hST01BX0hPU1QKKS5zdHJpcCgpIG9yIF9ERUZBVUxUX0NIUk9NQV9IT1NUCkNIUk9NQV9QT1JUID0gX3BhcnNlX2ludCgKICAgIG9zLmVudmlyb24uZ2V0KCJDSFJPTUFfUE9SVCIpCiAgICBvciBvcy5lbnZpcm9uLmdldCgiTUNQX0NIUk9NQV9QT1JUIikKICAgIG9yIF9ERUZBVUxUX0NIUk9NQV9QT1JULAogICAgX0RFRkFVTFRfQ0hST01BX1BPUlQsCiAgICBtaW5fdmFsdWU9MSwKKQpDSFJPTUFfU1NMID0gQ0hST01BX1NDSEVNRSA9PSAiaHR0cHMiCgojIENvbGXDp8O1ZXMgc2VwYXJhZGFzIHBvciBlc3BlY2lhbGl6YcOnw6NvIGRlIGVtYmVkZGluZwpDT0xMRUNUSU9OX0NPREVfSklOQSA9ICJjb2RlX3ZlY3RvcnNfamluYSIKQ09MTEVDVElPTl9ET0NfQkdFID0gImRvY192ZWN0b3JzX2JnZSIKCkpJTkFfVjNfRU1CRURESU5HX01PREVMID0gImppbmFhaS9qaW5hLWVtYmVkZGluZ3MtdjMiCkpJTkFfVjJfRU1CRURESU5HX01PREVMID0gImppbmFhaS9qaW5hLWVtYmVkZGluZ3MtdjItYmFzZS1jb2RlIgpCR0VfRU1CRURESU5HX01PREVMID0gIkJBQUkvYmdlLW0zIgoKREVGQVVMVF9FTUJFRERJTkdfTU9ERUxfQ0hPSUNFID0gImppbmEiCkRFRkFVTFRfSklOQV9RVUFOVElaQVRJT04gPSAiZHluYW1pYy1pbnQ4IgpERUZBVUxUX1NFQVJDSF9NT0RFID0gInNpbmdsZSIgICMgc2luZ2xlIHwgZW5zZW1ibGUKCl9lbWJlZGRpbmdfbW9kZWxfY2hvaWNlID0gX2NvbmZpZ19zdHIoCiAgICAiTUNQX0VNQkVERElOR19NT0RFTCIsCiAgICAiZW1iZWRkaW5nX21vZGVsIiwKICAgIERFRkFVTFRfRU1CRURESU5HX01PREVMX0NIT0lDRSwKKS5zdHJpcCgpLmxvd2VyKCkKaWYgX2VtYmVkZGluZ19tb2RlbF9jaG9pY2Ugbm90IGluIHsiamluYSIsICJiZ2UiLCAiaHlicmlkIn06CiAgICBsb2cud2FybmluZygKICAgICAgICAiTUNQX0VNQkVERElOR19NT0RFTCBpbnZhbGlkbyAnJXMnLiBVc2FuZG8gJyVzJy4iLAogICAgICAgIF9lbWJlZGRpbmdfbW9kZWxfY2hvaWNlLAogICAgICAgIERFRkFVTFRfRU1CRURESU5HX01PREVMX0NIT0lDRSwKICAgICkKICAgIF9lbWJlZGRpbmdfbW9kZWxfY2hvaWNlID0gREVGQVVMVF9FTUJFRERJTkdfTU9ERUxfQ0hPSUNFCgpfcmF3X2ppbmFfcXVhbnRpemF0aW9uID0gX2NvbmZpZ19zdHIoCiAgICAiTUNQX0pJTkFfUVVBTlRJWkFUSU9OIiwKICAgICJqaW5hX3F1YW50aXphdGlvbiIsCiAgICBERUZBVUxUX0pJTkFfUVVBTlRJWkFUSU9OLAopCkpJTkFfUVVBTlRJWkFUSU9OID0gX3Jhd19qaW5hX3F1YW50aXphdGlvbi5zdHJpcCgpLmxvd2VyKCkucmVwbGFjZSgiXyIsICItIikKaWYgSklOQV9RVUFOVElaQVRJT04gbm90IGluIHsiZGVmYXVsdCIsICJkeW5hbWljLWludDgifToKICAgIGxvZy53YXJuaW5nKAogICAgICAgICJNQ1BfSklOQV9RVUFOVElaQVRJT04gaW52YWxpZG8gJyVzJy4gVXNhbmRvICclcycuIiwKICAgICAgICBKSU5BX1FVQU5USVpBVElPTiwKICAgICAgICBERUZBVUxUX0pJTkFfUVVBTlRJWkFUSU9OLAogICAgKQogICAgSklOQV9RVUFOVElaQVRJT04gPSBERUZBVUxUX0pJTkFfUVVBTlRJWkFUSU9OCgpTRUFSQ0hfTU9ERV9ERUZBVUxUID0gb3MuZW52aXJvbi5nZXQoIk1DUF9TRUFSQ0hfTU9ERSIsIERFRkFVTFRfU0VBUkNIX01PREUpLnN0cmlwKCkubG93ZXIoKQppZiBTRUFSQ0hfTU9ERV9ERUZBVUxUIG5vdCBpbiB7InNpbmdsZSIsICJlbnNlbWJsZSJ9OgogICAgU0VBUkNIX01PREVfREVGQVVMVCA9IERFRkFVTFRfU0VBUkNIX01PREUKCmlmIF9lbWJlZGRpbmdfbW9kZWxfY2hvaWNlID09ICJoeWJyaWQiIGFuZCAiTUNQX1NFQVJDSF9NT0RFIiBub3QgaW4gb3MuZW52aXJvbjoKICAgICMgTm8gbW9kbyBow61icmlkbywgbyBjb21wb3J0YW1lbnRvIGVzcGVyYWRvIGNvc3R1bWEgc2VyIGVuc2VtYmxlIHBvciBwYWRyw6NvLgogICAgU0VBUkNIX01PREVfREVGQVVMVCA9ICJlbnNlbWJsZSIKClJFUkFOS19NT0RFTF9JRCA9IG9zLmVudmlyb24uZ2V0KCJNQ1BfUkVSQU5LX01PREVMIiwgImNyb3NzLWVuY29kZXIvbXMtbWFyY28tTWluaUxNLUwtNi12MiIpClJFUkFOS19FTkFCTEVEID0gb3MuZW52aXJvbi5nZXQoIk1DUF9SRVJBTktfRU5BQkxFRCIsICJ0cnVlIikuc3RyaXAoKS5sb3dlcigpIGluIHsiMSIsICJ0cnVlIiwgInllcyIsICJvbiJ9ClJFUkFOS19DQU5ESURBVEVfTVVMVElQTElFUiA9IGludChvcy5lbnZpcm9uLmdldCgiTUNQX1JFUkFOS19DQU5ESURBVEVfTVVMVElQTElFUiIsICIzIikpClJFUkFOS19NQVhfQ0FORElEQVRFUyA9IGludChvcy5lbnZpcm9uLmdldCgiTUNQX1JFUkFOS19NQVhfQ0FORElEQVRFUyIsICI0MCIpKQpSRVJBTktFUl9NQVhfTEVOR1RIID0gaW50KG9zLmVudmlyb24uZ2V0KCJNQ1BfUkVSQU5LX01BWF9MRU5HVEgiLCAiNTEyIikpClJFUkFOS0VSX1FVQU5USVpBVElPTiA9IG9zLmVudmlyb24uZ2V0KCJNQ1BfUkVSQU5LX1FVQU5USVpBVElPTiIsICJkeW5hbWljLWludDgiKS5zdHJpcCgpLmxvd2VyKCkKaWYgUkVSQU5LRVJfUVVBTlRJWkFUSU9OIG5vdCBpbiB7ImRlZmF1bHQiLCAiZHluYW1pYy1pbnQ4In06CiAgICBSRVJBTktFUl9RVUFOVElaQVRJT04gPSAiZHluYW1pYy1pbnQ4IgoKUlJGX0sgPSBpbnQob3MuZW52aXJvbi5nZXQoIk1DUF9SUkZfSyIsICI2MCIpKQpFTUJFRERJTkdfQkFUQ0hfU0laRSA9IF9jb25maWdfaW50KAogICAgIk1DUF9FTUJFRERJTkdfQkFUQ0hfU0laRSIsCiAgICAiZW1iZWRkaW5nX2JhdGNoX3NpemUiLAogICAgX0RFRkFVTFRfRU1CRURESU5HX0JBVENIX1NJWkUsCiAgICBtaW5fdmFsdWU9MSwKICAgIGZhbGxiYWNrX2NvbmZpZ19rZXlzPSgiYmF0Y2hfY291bnQiLCksCikKCl9lbnZfbW9kZWxfZGlyID0gb3MuZW52aXJvbi5nZXQoIk1DUF9NT0RFTF9ESVIiKQpNT0RFTF9ESVIgPSAoCiAgICBQYXRoKF9lbnZfbW9kZWxfZGlyKS5leHBhbmR1c2VyKCkKICAgIGlmIF9lbnZfbW9kZWxfZGlyCiAgICBlbHNlIFBhdGguaG9tZSgpIC8gIi5jYWNoZSIgLyAib3duLXJhZy1jbGkiIC8gIm1vZGVscyIKKQoKIyBQYXLDom1ldHJvcyBkbyBzcGxpdHRlciAoYWxpbmhhZG9zIGNvbSBpbmRleGVyX2Z1bGwucHksIHBlcmZpbCBsb3ctbWVtb3J5KQpDSFVOS19TSVpFID0gX2NvbmZpZ19pbnQoIk1DUF9DSFVOS19TSVpFIiwgImNodW5rX3NpemUiLCAzMDAwLCBtaW5fdmFsdWU9MjU2KQpDSFVOS19PVkVSTEFQID0gbWluKENIVU5LX1NJWkUgLSAxLCBfY29uZmlnX2ludCgiTUNQX0NIVU5LX09WRVJMQVAiLCAiY2h1bmtfb3ZlcmxhcCIsIDQwMCwgbWluX3ZhbHVlPTApKQoKTUFYX0ZJTEVfU0laRV9CWVRFUyA9IDUwMCAqIDEwMjQgICMgNTAwIEtCClRPUF9LX1JFU1VMVFMgPSA3Ck1BWF9RVUVSWV9SRVNVTFRTID0gMzAKCiMgRmlsdHJvcyBkZSB2YXJyZWR1cmEKSUdOT1JFRF9ESVJTID0gewogICAgIi5naXQiLCAibm9kZV9tb2R1bGVzIiwgIl9fcHljYWNoZV9fIiwgIi52ZW52IiwgInZlbnYiLCAiZW52IiwKICAgICJkaXN0IiwgImJ1aWxkIiwgIm91dCIsICIubmV4dCIsICIubnV4dCIsICIuY2FjaGUiLCAiY292ZXJhZ2UiLAogICAgIi5weXRlc3RfY2FjaGUiLCAiLm15cHlfY2FjaGUiLCAiLnJ1ZmZfY2FjaGUiLCAidGFyZ2V0IiwgImJpbiIsICJvYmoiLAogICAgIi5pZGVhIiwgIi52c2NvZGUiLCAidmVuZG9yIiwgInRtcCIsICJ0ZW1wIiwgImxvZ3MiLCAiLnJhZ19kYiIsCn0KCklHTk9SRURfRVhURU5TSU9OUyA9IHsKICAgICIucG5nIiwgIi5qcGciLCAiLmpwZWciLCAiLmdpZiIsICIuc3ZnIiwgIi5pY28iLCAiLndlYnAiLCAiLmJtcCIsCiAgICAiLm1wNCIsICIubXAzIiwgIi53YXYiLCAiLm9nZyIsICIuYXZpIiwgIi5tb3YiLAogICAgIi56aXAiLCAiLnRhciIsICIuZ3oiLCAiLnJhciIsICIuN3oiLCAiLmphciIsICIud2FyIiwKICAgICIucHljIiwgIi5weW8iLCAiLnNvIiwgIi5kbGwiLCAiLmV4ZSIsICIuYmluIiwgIi5ydW4iLAogICAgIi5sb2NrIiwgIi5zdW0iLCAiLnNxbGl0ZSIsICIuZGIiLCAiLnNxbGl0ZTMiLAogICAgIi50dGYiLCAiLndvZmYiLCAiLndvZmYyIiwgIi5lb3QiLAogICAgIi5wZGYiLCAiLmRvY3giLCAiLnhsc3giLCAiLnBwdHgiLAp9CgpDT0RFX0VYVEVOU0lPTlMgPSB7CiAgICAiLnB5IiwgIi5qcyIsICIudHMiLCAiLnRzeCIsICIuanN4IiwgIi5qYXZhIiwgIi5jIiwgIi5oIiwgIi5jcHAiLCAiLmhwcCIsCiAgICAiLmdvIiwgIi5ycyIsICIucmIiLCAiLnBocCIsICIuY3MiLCAiLnN3aWZ0IiwgIi5rdCIsICIua3RzIiwgIi5zY2FsYSIsICIuc3FsIiwKICAgICIuc2giLCAiLmJhc2giLCAiLnpzaCIsICIucHMxIiwgIi55YW1sIiwgIi55bWwiLCAiLnRvbWwiLCAiLmluaSIsICIuY29uZiIsCiAgICAiLmpzb24iLCAiLnhtbCIsICIuaHRtbCIsICIuY3NzIiwgIi5zY3NzIiwgIi5zYXNzIiwgIi52dWUiLCAiLnN2ZWx0ZSIsICIuZGFydCIsCiAgICAiLmx1YSIsICIuciIsICIubSIsICIubW0iLAp9CgpET0NfRVhURU5TSU9OUyA9IHsKICAgICIubWQiLCAiLm1keCIsICIucnN0IiwgIi50eHQiLCAiLmFkb2MiLCAiLm9yZyIsICIudGV4IiwgIi5jc3YiLAp9CgoKQGRhdGFjbGFzcyhmcm96ZW49VHJ1ZSkKY2xhc3MgQnJhbmNoU3BlYzoKICAgIGtleTogc3RyCiAgICBtb2RlbF9jaG9pY2U6IHN0cgogICAgbW9kZWxfaWQ6IHN0cgogICAgY29sbGVjdGlvbl9uYW1lOiBzdHIKICAgIGNvbnRlbnRfZG9tYWluOiBzdHIKICAgIGxhYmVsOiBzdHIKCgpKSU5BX0NPREVfQlJBTkNIX01PREVMX0NIT0lDRSA9ICJqaW5hX3YyIiBpZiBfZW1iZWRkaW5nX21vZGVsX2Nob2ljZSA9PSAiaHlicmlkIiBlbHNlICJqaW5hIgpKSU5BX0NPREVfQlJBTkNIX01PREVMX0lEID0gSklOQV9WMl9FTUJFRERJTkdfTU9ERUwgaWYgX2VtYmVkZGluZ19tb2RlbF9jaG9pY2UgPT0gImh5YnJpZCIgZWxzZSBKSU5BX1YzX0VNQkVERElOR19NT0RFTAoKQlJBTkNIX1NQRUNTOiBkaWN0W3N0ciwgQnJhbmNoU3BlY10gPSB7CiAgICAiamluYV9jb2RlIjogQnJhbmNoU3BlYygKICAgICAgICBrZXk9ImppbmFfY29kZSIsCiAgICAgICAgbW9kZWxfY2hvaWNlPUpJTkFfQ09ERV9CUkFOQ0hfTU9ERUxfQ0hPSUNFLAogICAgICAgIG1vZGVsX2lkPUpJTkFfQ09ERV9CUkFOQ0hfTU9ERUxfSUQsCiAgICAgICAgY29sbGVjdGlvbl9uYW1lPUNPTExFQ1RJT05fQ09ERV9KSU5BLAogICAgICAgIGNvbnRlbnRfZG9tYWluPSJjb2RlIiwKICAgICAgICBsYWJlbD0iSmluYSB2MiBDb2RlIiBpZiBfZW1iZWRkaW5nX21vZGVsX2Nob2ljZSA9PSAiaHlicmlkIiBlbHNlICJKaW5hIHYzIENvZGUiLAogICAgKSwKICAgICJiZ2VfZG9jIjogQnJhbmNoU3BlYygKICAgICAgICBrZXk9ImJnZV9kb2MiLAogICAgICAgIG1vZGVsX2Nob2ljZT0iYmdlIiwKICAgICAgICBtb2RlbF9pZD1CR0VfRU1CRURESU5HX01PREVMLAogICAgICAgIGNvbGxlY3Rpb25fbmFtZT1DT0xMRUNUSU9OX0RPQ19CR0UsCiAgICAgICAgY29udGVudF9kb21haW49ImRvYyIsCiAgICAgICAgbGFiZWw9IkJHRSBEb2NzIiwKICAgICksCn0KCkRFRkFVTFRfU0lOR0xFX0JSQU5DSF9LRVkgPSAiYmdlX2RvYyIgaWYgX2VtYmVkZGluZ19tb2RlbF9jaG9pY2UgPT0gImJnZSIgZWxzZSAiamluYV9jb2RlIgoKCkBkYXRhY2xhc3MKY2xhc3MgUmV0cmlldmVkSGl0OgogICAga2V5OiBzdHIKICAgIGRvY3VtZW50OiBzdHIKICAgIG1ldGFkYXRhOiBkaWN0W3N0ciwgb2JqZWN0XQogICAgZGlzdGFuY2U6IGZsb2F0IHwgTm9uZQogICAgc2ltaWxhcml0eTogZmxvYXQgfCBOb25lCiAgICBicmFuY2g6IEJyYW5jaFNwZWMKICAgIHJhbms6IGludAoKCkBkYXRhY2xhc3MKY2xhc3MgRnVzZWRIaXQ6CiAgICBrZXk6IHN0cgogICAgZG9jdW1lbnQ6IHN0cgogICAgbWV0YWRhdGE6IGRpY3Rbc3RyLCBvYmplY3RdCiAgICBycmZfc2NvcmU6IGZsb2F0CiAgICBzb3VyY2VfZGV0YWlsczogZGljdFtzdHIsIGRpY3Rbc3RyLCBvYmplY3RdXQogICAgcmVyYW5rX3Njb3JlOiBmbG9hdCB8IE5vbmUgPSBOb25lCgoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBSdW50aW1lIGNhY2hlcyAobGF6eSBsb2FkaW5nIHBhcmEgZWNvbm9taXphciBSQU0pCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpfY2hyb21hX2NsaWVudDogY2hyb21hZGIuSHR0cENsaWVudCB8IE5vbmUgPSBOb25lCl9jb2xsZWN0aW9uczogZGljdFtzdHIsIGNocm9tYWRiLkNvbGxlY3Rpb25dID0ge30KX21vZGVsczogZGljdFtzdHIsIFNlbnRlbmNlVHJhbnNmb3JtZXJdID0ge30KX21vZGVsX2xvYWRfZXJyb3JzOiBkaWN0W3N0ciwgc3RyXSA9IHt9Cl9zcGxpdHRlcjogUmVjdXJzaXZlQ2hhcmFjdGVyVGV4dFNwbGl0dGVyIHwgTm9uZSA9IE5vbmUKX3JlcmFua2VyOiBDcm9zc0VuY29kZXIgfCBOb25lID0gTm9uZQpfcmVyYW5rZXJfZXJyb3I6IHN0ciB8IE5vbmUgPSBOb25lCgoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBDaHJvbWEgZSBtb2RlbG9zCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoKZGVmIF9tb2RlbF9jYWNoZV9kaXIoYmFzZV9kaXI6IFBhdGgsIG1vZGVsX2lkOiBzdHIpIC0+IFBhdGg6CiAgICBzYWZlX25hbWUgPSBtb2RlbF9pZC5yZXBsYWNlKCIvIiwgIl9fIikucmVwbGFjZSgiOiIsICJfIikKICAgIHJldHVybiBiYXNlX2RpciAvIHNhZmVfbmFtZQoKCmRlZiBfZ2V0X2Nocm9tYV9jbGllbnQoKSAtPiBjaHJvbWFkYi5IdHRwQ2xpZW50OgogICAgZ2xvYmFsIF9jaHJvbWFfY2xpZW50CiAgICBpZiBfY2hyb21hX2NsaWVudCBpcyBOb25lOgogICAgICAgIF9jaHJvbWFfY2xpZW50ID0gY2hyb21hZGIuSHR0cENsaWVudChob3N0PUNIUk9NQV9IT1NULCBwb3J0PUNIUk9NQV9QT1JULCBzc2w9Q0hST01BX1NTTCkKICAgICAgICBfY2hyb21hX2NsaWVudC5oZWFydGJlYXQoKQogICAgICAgIGxvZy5pbmZvKCJDb25lY3RhZG8gYW8gQ2hyb21hREIgZW0gJXM6Ly8lczolcyIsIENIUk9NQV9TQ0hFTUUsIENIUk9NQV9IT1NULCBDSFJPTUFfUE9SVCkKICAgIHJldHVybiBfY2hyb21hX2NsaWVudAoKCmRlZiBnZXRfY2hyb21hX2NvbGxlY3Rpb24oY29sbGVjdGlvbl9uYW1lOiBzdHIpIC0+IGNocm9tYWRiLkNvbGxlY3Rpb246CiAgICBpZiBjb2xsZWN0aW9uX25hbWUgaW4gX2NvbGxlY3Rpb25zOgogICAgICAgIHJldHVybiBfY29sbGVjdGlvbnNbY29sbGVjdGlvbl9uYW1lXQoKICAgIHRyeToKICAgICAgICBjbGllbnQgPSBfZ2V0X2Nocm9tYV9jbGllbnQoKQogICAgICAgIGNvbGxlY3Rpb24gPSBjbGllbnQuZ2V0X29yX2NyZWF0ZV9jb2xsZWN0aW9uKAogICAgICAgICAgICBuYW1lPWNvbGxlY3Rpb25fbmFtZSwKICAgICAgICAgICAgbWV0YWRhdGE9eyJobnN3OnNwYWNlIjogImNvc2luZSJ9LAogICAgICAgICkKICAgICAgICBfY29sbGVjdGlvbnNbY29sbGVjdGlvbl9uYW1lXSA9IGNvbGxlY3Rpb24KICAgICAgICByZXR1cm4gY29sbGVjdGlvbgogICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgIHJhaXNlIFJ1bnRpbWVFcnJvcigKICAgICAgICAgICAgZiJOw6NvIGZvaSBwb3Nzw612ZWwgYWNlc3NhciBhIGNvbGXDp8OjbyAne2NvbGxlY3Rpb25fbmFtZX0nIG5vIENocm9tYURCICIKICAgICAgICAgICAgZiIoe0NIUk9NQV9TQ0hFTUV9Oi8ve0NIUk9NQV9IT1NUfTp7Q0hST01BX1BPUlR9KS4gRXJybzoge2V9IgogICAgICAgICkKCgpkZWYgX2xvYWRfc2VudGVuY2VfdHJhbnNmb3JtZXJfZnJvbV9sb2NhbChtb2RlbF9pZDogc3RyLCBsb2NhbF9tb2RlbF9kaXI6IFBhdGgpIC0+IFNlbnRlbmNlVHJhbnNmb3JtZXI6CiAgICB0cnVzdF9yZW1vdGVfY29kZSA9IG1vZGVsX2lkLnN0YXJ0c3dpdGgoImppbmFhaS8iKQogICAgdG9rZW5pemVyX2t3YXJncyA9IHsiZml4X21pc3RyYWxfcmVnZXgiOiBUcnVlfQoKICAgIGRlZiBfaW5zdGFudGlhdGVfbW9kZWwoKSAtPiBTZW50ZW5jZVRyYW5zZm9ybWVyOgogICAgICAgIHJldHVybiBTZW50ZW5jZVRyYW5zZm9ybWVyKAogICAgICAgICAgICBzdHIobG9jYWxfbW9kZWxfZGlyKSwKICAgICAgICAgICAgZGV2aWNlPSJjcHUiLAogICAgICAgICAgICB0cnVzdF9yZW1vdGVfY29kZT10cnVzdF9yZW1vdGVfY29kZSwKICAgICAgICAgICAgdG9rZW5pemVyX2t3YXJncz10b2tlbml6ZXJfa3dhcmdzLAogICAgICAgICkKCiAgICBkZWYgX2NsZWFyX2hmX2R5bmFtaWNfbW9kdWxlc19jYWNoZSgpIC0+IE5vbmU6CiAgICAgICAgY2FjaGVfZGlyID0gUGF0aC5ob21lKCkgLyAiLmNhY2hlIiAvICJodWdnaW5nZmFjZSIgLyAibW9kdWxlcyIgLyAidHJhbnNmb3JtZXJzX21vZHVsZXMiCiAgICAgICAgaWYgY2FjaGVfZGlyLmV4aXN0cygpOgogICAgICAgICAgICBsb2cud2FybmluZygiTGltcGFuZG8gY2FjaGUgZGluw6JtaWNvIGRvIEh1Z2dpbmcgRmFjZSBlbSAlcyIsIGNhY2hlX2RpcikKICAgICAgICAgICAgc2h1dGlsLnJtdHJlZShjYWNoZV9kaXIsIGlnbm9yZV9lcnJvcnM9VHJ1ZSkKCiAgICBkZWYgX2xvYWRfd2l0aF9qaW5hX3BhdGNoKCkgLT4gU2VudGVuY2VUcmFuc2Zvcm1lcjoKICAgICAgICBpZiBub3QgdHJ1c3RfcmVtb3RlX2NvZGU6CiAgICAgICAgICAgIHJldHVybiBfaW5zdGFudGlhdGVfbW9kZWwoKQoKICAgICAgICBmcm9tIHRyYW5zZm9ybWVycyBpbXBvcnQgQXV0b01vZGVsLCBBdXRvVG9rZW5pemVyCiAgICAgICAgZnJvbSB0cmFuc2Zvcm1lcnMubW9kZWxpbmdfdXRpbHMgaW1wb3J0IFByZVRyYWluZWRNb2RlbAoKICAgICAgICBvcmlnaW5hbF9mcm9tX3ByZXRyYWluZWQgPSBBdXRvVG9rZW5pemVyLmZyb21fcHJldHJhaW5lZAogICAgICAgIG9yaWdpbmFsX21vZGVsX2Zyb21fcHJldHJhaW5lZCA9IEF1dG9Nb2RlbC5mcm9tX3ByZXRyYWluZWQKICAgICAgICBvcmlnaW5hbF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fcHJldHJhaW5lZCA9IFByZVRyYWluZWRNb2RlbC5mcm9tX3ByZXRyYWluZWQKICAgICAgICBvcmlnaW5hbF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fY29uZmlnID0gUHJlVHJhaW5lZE1vZGVsLl9mcm9tX2NvbmZpZwogICAgICAgIG1vZGVsX3JlZnMgPSB7c3RyKGxvY2FsX21vZGVsX2RpciksIHN0cihsb2NhbF9tb2RlbF9kaXIucmVzb2x2ZSgpKX0KCiAgICAgICAgZGVmIF9wYXRjaGVkX2Zyb21fcHJldHJhaW5lZCgqYXJncywgKiprd2FyZ3MpOgogICAgICAgICAgICBtb2RlbF9yZWYgPSBhcmdzWzBdIGlmIGFyZ3MgZWxzZSBrd2FyZ3MuZ2V0KCJwcmV0cmFpbmVkX21vZGVsX25hbWVfb3JfcGF0aCIpCiAgICAgICAgICAgIGlmIG1vZGVsX3JlZiBpcyBub3QgTm9uZSBhbmQgc3RyKG1vZGVsX3JlZikgaW4gbW9kZWxfcmVmczoKICAgICAgICAgICAgICAgIGt3YXJncy5zZXRkZWZhdWx0KCJmaXhfbWlzdHJhbF9yZWdleCIsIFRydWUpCiAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbF9mcm9tX3ByZXRyYWluZWQoKmFyZ3MsICoqa3dhcmdzKQoKICAgICAgICBkZWYgX3BhdGNoZWRfbW9kZWxfZnJvbV9wcmV0cmFpbmVkKCphcmdzLCAqKmt3YXJncyk6CiAgICAgICAgICAgIG1vZGVsX3JlZiA9IGFyZ3NbMF0gaWYgYXJncyBlbHNlIGt3YXJncy5nZXQoInByZXRyYWluZWRfbW9kZWxfbmFtZV9vcl9wYXRoIikKICAgICAgICAgICAgaWYgbW9kZWxfcmVmIGlzIG5vdCBOb25lIGFuZCBzdHIobW9kZWxfcmVmKSBpbiBtb2RlbF9yZWZzIGFuZCAidG9yY2hfZHR5cGUiIGluIGt3YXJnczoKICAgICAgICAgICAgICAgIGt3YXJncyA9IGRpY3Qoa3dhcmdzKQogICAgICAgICAgICAgICAgaWYgImR0eXBlIiBub3QgaW4ga3dhcmdzOgogICAgICAgICAgICAgICAgICAgIGt3YXJnc1siZHR5cGUiXSA9IGt3YXJnc1sidG9yY2hfZHR5cGUiXQogICAgICAgICAgICAgICAga3dhcmdzLnBvcCgidG9yY2hfZHR5cGUiLCBOb25lKQogICAgICAgICAgICByZXR1cm4gb3JpZ2luYWxfbW9kZWxfZnJvbV9wcmV0cmFpbmVkKCphcmdzLCAqKmt3YXJncykKCiAgICAgICAgb3JpZ2luYWxfcHJldHJhaW5lZF9tb2RlbF9mcm9tX3ByZXRyYWluZWRfZm4gPSBvcmlnaW5hbF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fcHJldHJhaW5lZC5fX2Z1bmNfXwoKICAgICAgICBAY2xhc3NtZXRob2QKICAgICAgICBkZWYgX3BhdGNoZWRfcHJldHJhaW5lZF9tb2RlbF9mcm9tX3ByZXRyYWluZWQoY2xzLCAqYXJncywgKiprd2FyZ3MpOgogICAgICAgICAgICBpZiAidG9yY2hfZHR5cGUiIGluIGt3YXJnczoKICAgICAgICAgICAgICAgIGt3YXJncyA9IGRpY3Qoa3dhcmdzKQogICAgICAgICAgICAgICAgaWYgImR0eXBlIiBub3QgaW4ga3dhcmdzOgogICAgICAgICAgICAgICAgICAgIGt3YXJnc1siZHR5cGUiXSA9IGt3YXJnc1sidG9yY2hfZHR5cGUiXQogICAgICAgICAgICAgICAga3dhcmdzLnBvcCgidG9yY2hfZHR5cGUiLCBOb25lKQogICAgICAgICAgICByZXR1cm4gb3JpZ2luYWxfcHJldHJhaW5lZF9tb2RlbF9mcm9tX3ByZXRyYWluZWRfZm4oY2xzLCAqYXJncywgKiprd2FyZ3MpCgogICAgICAgIG9yaWdpbmFsX3ByZXRyYWluZWRfbW9kZWxfZnJvbV9jb25maWdfZm4gPSBvcmlnaW5hbF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fY29uZmlnLl9fZnVuY19fCgogICAgICAgIEBjbGFzc21ldGhvZAogICAgICAgIGRlZiBfcGF0Y2hlZF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fY29uZmlnKGNscywgKmFyZ3MsICoqa3dhcmdzKToKICAgICAgICAgICAgaWYgInRvcmNoX2R0eXBlIiBpbiBrd2FyZ3M6CiAgICAgICAgICAgICAgICBrd2FyZ3MgPSBkaWN0KGt3YXJncykKICAgICAgICAgICAgICAgIGlmICJkdHlwZSIgbm90IGluIGt3YXJnczoKICAgICAgICAgICAgICAgICAgICBrd2FyZ3NbImR0eXBlIl0gPSBrd2FyZ3NbInRvcmNoX2R0eXBlIl0KICAgICAgICAgICAgICAgIGt3YXJncy5wb3AoInRvcmNoX2R0eXBlIiwgTm9uZSkKICAgICAgICAgICAgcmV0dXJuIG9yaWdpbmFsX3ByZXRyYWluZWRfbW9kZWxfZnJvbV9jb25maWdfZm4oY2xzLCAqYXJncywgKiprd2FyZ3MpCgogICAgICAgIEF1dG9Ub2tlbml6ZXIuZnJvbV9wcmV0cmFpbmVkID0gX3BhdGNoZWRfZnJvbV9wcmV0cmFpbmVkCiAgICAgICAgQXV0b01vZGVsLmZyb21fcHJldHJhaW5lZCA9IF9wYXRjaGVkX21vZGVsX2Zyb21fcHJldHJhaW5lZAogICAgICAgIFByZVRyYWluZWRNb2RlbC5mcm9tX3ByZXRyYWluZWQgPSBfcGF0Y2hlZF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fcHJldHJhaW5lZAogICAgICAgIFByZVRyYWluZWRNb2RlbC5fZnJvbV9jb25maWcgPSBfcGF0Y2hlZF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fY29uZmlnCiAgICAgICAgdHJ5OgogICAgICAgICAgICByZXR1cm4gX2luc3RhbnRpYXRlX21vZGVsKCkKICAgICAgICBmaW5hbGx5OgogICAgICAgICAgICBBdXRvVG9rZW5pemVyLmZyb21fcHJldHJhaW5lZCA9IG9yaWdpbmFsX2Zyb21fcHJldHJhaW5lZAogICAgICAgICAgICBBdXRvTW9kZWwuZnJvbV9wcmV0cmFpbmVkID0gb3JpZ2luYWxfbW9kZWxfZnJvbV9wcmV0cmFpbmVkCiAgICAgICAgICAgIFByZVRyYWluZWRNb2RlbC5mcm9tX3ByZXRyYWluZWQgPSBvcmlnaW5hbF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fcHJldHJhaW5lZAogICAgICAgICAgICBQcmVUcmFpbmVkTW9kZWwuX2Zyb21fY29uZmlnID0gb3JpZ2luYWxfcHJldHJhaW5lZF9tb2RlbF9mcm9tX2NvbmZpZwoKICAgIHRyeToKICAgICAgICByZXR1cm4gX2xvYWRfd2l0aF9qaW5hX3BhdGNoKCkKICAgIGV4Y2VwdCBGaWxlTm90Rm91bmRFcnJvciBhcyBlOgogICAgICAgIGlmIHRydXN0X3JlbW90ZV9jb2RlIGFuZCAidHJhbnNmb3JtZXJzX21vZHVsZXMiIGluIHN0cihlKToKICAgICAgICAgICAgbG9nLndhcm5pbmcoIkNhY2hlIGRpbsOibWljbyBpbmNvbnNpc3RlbnRlIGRldGVjdGFkbzogJXMiLCBlKQogICAgICAgICAgICBfY2xlYXJfaGZfZHluYW1pY19tb2R1bGVzX2NhY2hlKCkKICAgICAgICAgICAgcmV0dXJuIF9sb2FkX3dpdGhfamluYV9wYXRjaCgpCiAgICAgICAgcmFpc2UKCgpkZWYgX2FwcGx5X2ppbmFfcXVhbnRpemF0aW9uX2lmX25lZWRlZChtb2RlbDogU2VudGVuY2VUcmFuc2Zvcm1lciwgbW9kZWxfaWQ6IHN0cikgLT4gU2VudGVuY2VUcmFuc2Zvcm1lcjoKICAgIGlmIG1vZGVsX2lkICE9IEpJTkFfVjNfRU1CRURESU5HX01PREVMIG9yIEpJTkFfUVVBTlRJWkFUSU9OID09ICJkZWZhdWx0IjoKICAgICAgICByZXR1cm4gbW9kZWwKCiAgICB0cnk6CiAgICAgICAgaW1wb3J0IHRvcmNoCiAgICAgICAgaW1wb3J0IHdhcm5pbmdzCgogICAgICAgIHF1YW50aXplZF9sYXllcnMgPSAwCiAgICAgICAgZm9yIG1vZHVsZSBpbiBtb2RlbC5tb2R1bGVzKCk6CiAgICAgICAgICAgIGlmIHR5cGUobW9kdWxlKS5fX25hbWVfXyAhPSAiUGFyYW1ldHJpemVkTGluZWFyIjoKICAgICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICAgICBmbG9hdF9saW5lYXIgPSB0b3JjaC5ubi5MaW5lYXIoCiAgICAgICAgICAgICAgICBtb2R1bGUuaW5fZmVhdHVyZXMsCiAgICAgICAgICAgICAgICBtb2R1bGUub3V0X2ZlYXR1cmVzLAogICAgICAgICAgICAgICAgYmlhcz1tb2R1bGUuYmlhcyBpcyBub3QgTm9uZSwKICAgICAgICAgICAgKQogICAgICAgICAgICB3aXRoIHRvcmNoLm5vX2dyYWQoKToKICAgICAgICAgICAgICAgIGZsb2F0X2xpbmVhci53ZWlnaHQuY29weV8obW9kdWxlLndlaWdodC5kZXRhY2goKS50byh0b3JjaC5mbG9hdDMyKSkKICAgICAgICAgICAgICAgIGlmIG1vZHVsZS5iaWFzIGlzIG5vdCBOb25lOgogICAgICAgICAgICAgICAgICAgIGZsb2F0X2xpbmVhci5iaWFzLmNvcHlfKG1vZHVsZS5iaWFzLmRldGFjaCgpLnRvKHRvcmNoLmZsb2F0MzIpKQoKICAgICAgICAgICAgd2l0aCB3YXJuaW5ncy5jYXRjaF93YXJuaW5ncygpOgogICAgICAgICAgICAgICAgd2FybmluZ3MuZmlsdGVyd2FybmluZ3MoImlnbm9yZSIsIGNhdGVnb3J5PURlcHJlY2F0aW9uV2FybmluZykKICAgICAgICAgICAgICAgIHF1YW50aXplZF9saW5lYXIgPSB0b3JjaC5xdWFudGl6YXRpb24ucXVhbnRpemVfZHluYW1pYygKICAgICAgICAgICAgICAgICAgICB0b3JjaC5ubi5TZXF1ZW50aWFsKGZsb2F0X2xpbmVhciksCiAgICAgICAgICAgICAgICAgICAge3RvcmNoLm5uLkxpbmVhcn0sCiAgICAgICAgICAgICAgICAgICAgZHR5cGU9dG9yY2gucWludDgsCiAgICAgICAgICAgICAgICApWzBdCgogICAgICAgICAgICBtb2R1bGUuX2R5bmFtaWNfaW50OF9saW5lYXIgPSBxdWFudGl6ZWRfbGluZWFyCgogICAgICAgICAgICBkZWYgX2ZvcndhcmRfZHluYW1pY19pbnQ4KHNlbGYsIGlucHV0LCB0YXNrX2lkPU5vbmUsIHJlc2lkdWFsPUZhbHNlKToKICAgICAgICAgICAgICAgIG91dCA9IHNlbGYuX2R5bmFtaWNfaW50OF9saW5lYXIoaW5wdXQpCiAgICAgICAgICAgICAgICBpZiByZXNpZHVhbDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3V0LCBpbnB1dAogICAgICAgICAgICAgICAgcmV0dXJuIG91dAoKICAgICAgICAgICAgbW9kdWxlLmZvcndhcmQgPSBfZm9yd2FyZF9keW5hbWljX2ludDguX19nZXRfXyhtb2R1bGUsIG1vZHVsZS5fX2NsYXNzX18pCiAgICAgICAgICAgIHF1YW50aXplZF9sYXllcnMgKz0gMQoKICAgICAgICBpZiBxdWFudGl6ZWRfbGF5ZXJzID09IDA6CiAgICAgICAgICAgIGxvZy53YXJuaW5nKCJOZW5odW1hIGNhbWFkYSBQYXJhbWV0cml6ZWRMaW5lYXIgZW5jb250cmFkYSBwYXJhIGR5bmFtaWMtaW50OCBubyBKaW5hLiIpCiAgICAgICAgICAgIHJldHVybiBtb2RlbAoKICAgICAgICBsb2cuaW5mbygiUXVhbnRpemFjYW8gSmluYSBhcGxpY2FkYTogZHluYW1pYy1pbnQ4IChDUFUsICVzIGNhbWFkYXMpLiIsIHF1YW50aXplZF9sYXllcnMpCiAgICAgICAgcmV0dXJuIG1vZGVsCiAgICBleGNlcHQgRXhjZXB0aW9uIGFzIHF1YW50X2Vycm9yOgogICAgICAgIGxvZy53YXJuaW5nKCJGYWxoYSBhbyBhcGxpY2FyIGR5bmFtaWMtaW50OCBubyBKaW5hICglcyk7IHVzYW5kbyBtb2RlbG8gcGFkcmFvLiIsIHF1YW50X2Vycm9yKQogICAgICAgIHJldHVybiBtb2RlbAoKCmRlZiBnZXRfZW1iZWRkaW5nX21vZGVsKG1vZGVsX2Nob2ljZTogc3RyKSAtPiBTZW50ZW5jZVRyYW5zZm9ybWVyOgogICAgaWYgbW9kZWxfY2hvaWNlIGluIF9tb2RlbHM6CiAgICAgICAgcmV0dXJuIF9tb2RlbHNbbW9kZWxfY2hvaWNlXQoKICAgIGlmIG1vZGVsX2Nob2ljZSBpbiBfbW9kZWxfbG9hZF9lcnJvcnM6CiAgICAgICAgcmFpc2UgUnVudGltZUVycm9yKF9tb2RlbF9sb2FkX2Vycm9yc1ttb2RlbF9jaG9pY2VdKQoKICAgIGlmIG1vZGVsX2Nob2ljZSA9PSAiamluYSI6CiAgICAgICAgbW9kZWxfaWQgPSBKSU5BX1YzX0VNQkVERElOR19NT0RFTAogICAgZWxpZiBtb2RlbF9jaG9pY2UgPT0gImppbmFfdjIiOgogICAgICAgIG1vZGVsX2lkID0gSklOQV9WMl9FTUJFRERJTkdfTU9ERUwKICAgIGVsaWYgbW9kZWxfY2hvaWNlID09ICJiZ2UiOgogICAgICAgIG1vZGVsX2lkID0gQkdFX0VNQkVERElOR19NT0RFTAogICAgZWxzZToKICAgICAgICByYWlzZSBSdW50aW1lRXJyb3IoZiJNb2RlbG8gbsOjbyBzdXBvcnRhZG86IHttb2RlbF9jaG9pY2V9IikKCiAgICB0cnk6CiAgICAgICAgTU9ERUxfRElSLm1rZGlyKHBhcmVudHM9VHJ1ZSwgZXhpc3Rfb2s9VHJ1ZSkKICAgICAgICBwcmVmZXJyZWRfbW9kZWxfY2FjaGVfZGlyID0gX21vZGVsX2NhY2hlX2RpcihNT0RFTF9ESVIsIG1vZGVsX2lkKQogICAgICAgIGxvZy5pbmZvKCJDYXJyZWdhbmRvIGVtYmVkZGluZ3MgJyVzJyBlbSBDUFUgKGNhY2hlOiAlcykiLCBtb2RlbF9pZCwgcHJlZmVycmVkX21vZGVsX2NhY2hlX2RpcikKCiAgICAgICAgc2VsZWN0aW9uID0gZG93bmxvYWRfbW9kZWxfd2l0aF9mYWxsYmFjaygKICAgICAgICAgICAgcHJlZmVycmVkX21vZGVsX2lkPW1vZGVsX2lkLAogICAgICAgICAgICBmYWxsYmFja19tb2RlbF9pZD1tb2RlbF9pZCwKICAgICAgICAgICAgbG9jYWxfZGlyPU1PREVMX0RJUiwKICAgICAgICApCiAgICAgICAgbW9kZWwgPSBfbG9hZF9zZW50ZW5jZV90cmFuc2Zvcm1lcl9mcm9tX2xvY2FsKHNlbGVjdGlvbi5tb2RlbF9pZCwgc2VsZWN0aW9uLmxvY2FsX2RpcikKICAgICAgICBpZiBtb2RlbF9jaG9pY2UgPT0gImppbmEiOgogICAgICAgICAgICBtb2RlbCA9IF9hcHBseV9qaW5hX3F1YW50aXphdGlvbl9pZl9uZWVkZWQobW9kZWwsIHNlbGVjdGlvbi5tb2RlbF9pZCkKCiAgICAgICAgX21vZGVsc1ttb2RlbF9jaG9pY2VdID0gbW9kZWwKICAgICAgICBsb2cuaW5mbygKICAgICAgICAgICAgIk1vZGVsbyBkZSBlbWJlZGRpbmdzIHByb250bzogJXMgKHByb3ZpZGVyPSVzLCBwYXRoPSVzKSIsCiAgICAgICAgICAgIHNlbGVjdGlvbi5tb2RlbF9pZCwKICAgICAgICAgICAgc2VsZWN0aW9uLnByb3ZpZGVyLAogICAgICAgICAgICBzZWxlY3Rpb24ubG9jYWxfZGlyLAogICAgICAgICkKICAgICAgICByZXR1cm4gbW9kZWwKICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICBtZXNzYWdlID0gZiJGYWxoYSBhbyBjYXJyZWdhciBtb2RlbG8gJ3ttb2RlbF9jaG9pY2V9JyAoe21vZGVsX2lkfSk6IHtlfSIKICAgICAgICBfbW9kZWxfbG9hZF9lcnJvcnNbbW9kZWxfY2hvaWNlXSA9IG1lc3NhZ2UKICAgICAgICByYWlzZSBSdW50aW1lRXJyb3IobWVzc2FnZSkKCgpkZWYgZ2V0X3JlcmFua2VyKCkgLT4gQ3Jvc3NFbmNvZGVyIHwgTm9uZToKICAgIGdsb2JhbCBfcmVyYW5rZXIsIF9yZXJhbmtlcl9lcnJvcgoKICAgIGlmIG5vdCBSRVJBTktfRU5BQkxFRDoKICAgICAgICByZXR1cm4gTm9uZQogICAgaWYgX3JlcmFua2VyIGlzIG5vdCBOb25lOgogICAgICAgIHJldHVybiBfcmVyYW5rZXIKICAgIGlmIF9yZXJhbmtlcl9lcnJvciBpcyBub3QgTm9uZToKICAgICAgICByZXR1cm4gTm9uZQoKICAgIHRyeToKICAgICAgICBNT0RFTF9ESVIubWtkaXIocGFyZW50cz1UcnVlLCBleGlzdF9vaz1UcnVlKQogICAgICAgIHNlbGVjdGlvbiA9IGRvd25sb2FkX21vZGVsX3dpdGhfZmFsbGJhY2soCiAgICAgICAgICAgIHByZWZlcnJlZF9tb2RlbF9pZD1SRVJBTktfTU9ERUxfSUQsCiAgICAgICAgICAgIGZhbGxiYWNrX21vZGVsX2lkPVJFUkFOS19NT0RFTF9JRCwKICAgICAgICAgICAgbG9jYWxfZGlyPU1PREVMX0RJUiwKICAgICAgICApCgogICAgICAgIHJlcmFua2VyID0gQ3Jvc3NFbmNvZGVyKAogICAgICAgICAgICBzdHIoc2VsZWN0aW9uLmxvY2FsX2RpciksCiAgICAgICAgICAgIGRldmljZT0iY3B1IiwKICAgICAgICAgICAgbWF4X2xlbmd0aD1SRVJBTktFUl9NQVhfTEVOR1RILAogICAgICAgICAgICB0cnVzdF9yZW1vdGVfY29kZT1GYWxzZSwKICAgICAgICApCgogICAgICAgIGlmIFJFUkFOS0VSX1FVQU5USVpBVElPTiA9PSAiZHluYW1pYy1pbnQ4IjoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgaW1wb3J0IHRvcmNoCgogICAgICAgICAgICAgICAgcmVyYW5rZXIubW9kZWwgPSB0b3JjaC5xdWFudGl6YXRpb24ucXVhbnRpemVfZHluYW1pYygKICAgICAgICAgICAgICAgICAgICByZXJhbmtlci5tb2RlbCwKICAgICAgICAgICAgICAgICAgICB7dG9yY2gubm4uTGluZWFyfSwKICAgICAgICAgICAgICAgICAgICBkdHlwZT10b3JjaC5xaW50OCwKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIGxvZy5pbmZvKCJSZXJhbmtlciBjb20gcXVhbnRpemFjYW8gZHluYW1pYy1pbnQ4IGhhYmlsaXRhZGEuIikKICAgICAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBxdWFudF9lcnJvcjoKICAgICAgICAgICAgICAgIGxvZy53YXJuaW5nKCJGYWxoYSBhbyBxdWFudGl6YXIgcmVyYW5rZXIgKCVzKS4gU2VndWluZG8gc2VtIHF1YW50aXphY2FvLiIsIHF1YW50X2Vycm9yKQoKICAgICAgICBfcmVyYW5rZXIgPSByZXJhbmtlcgogICAgICAgIGxvZy5pbmZvKAogICAgICAgICAgICAiUmVyYW5rZXIgcHJvbnRvOiAlcyAocHJvdmlkZXI9JXMsIHBhdGg9JXMpIiwKICAgICAgICAgICAgc2VsZWN0aW9uLm1vZGVsX2lkLAogICAgICAgICAgICBzZWxlY3Rpb24ucHJvdmlkZXIsCiAgICAgICAgICAgIHNlbGVjdGlvbi5sb2NhbF9kaXIsCiAgICAgICAgKQogICAgICAgIHJldHVybiBfcmVyYW5rZXIKICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICBfcmVyYW5rZXJfZXJyb3IgPSBzdHIoZSkKICAgICAgICBsb2cud2FybmluZygiUmVyYW5rZXIgaW5kaXNwb27DrXZlbC4gQnVzY2Egc2VndWlyw6Egc2VtIHJlcmFua2luZy4gRXJybzogJXMiLCBlKQogICAgICAgIHJldHVybiBOb25lCgoKZGVmIGdldF9zcGxpdHRlcigpIC0+IFJlY3Vyc2l2ZUNoYXJhY3RlclRleHRTcGxpdHRlcjoKICAgIGdsb2JhbCBfc3BsaXR0ZXIKICAgIGlmIF9zcGxpdHRlciBpcyBOb25lOgogICAgICAgIF9zcGxpdHRlciA9IFJlY3Vyc2l2ZUNoYXJhY3RlclRleHRTcGxpdHRlcigKICAgICAgICAgICAgY2h1bmtfc2l6ZT1DSFVOS19TSVpFLAogICAgICAgICAgICBjaHVua19vdmVybGFwPUNIVU5LX09WRVJMQVAsCiAgICAgICAgICAgIGxlbmd0aF9mdW5jdGlvbj1sZW4sCiAgICAgICAgICAgIHNlcGFyYXRvcnM9WyJcblxuIiwgIlxuIiwgIiAiLCAiIl0sCiAgICAgICAgKQogICAgcmV0dXJuIF9zcGxpdHRlcgoKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgSW5kZXhhw6fDo28gaW50ZXJuYQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCmRlZiBfbWFrZV9jaHVua19pZChmaWxlX3BhdGg6IHN0ciwgY2h1bmtfaW5kZXg6IGludCkgLT4gc3RyOgogICAgcmF3ID0gZiJ7ZmlsZV9wYXRofTo6Y2h1bms6OntjaHVua19pbmRleH0iCiAgICByZXR1cm4gaGFzaGxpYi5tZDUocmF3LmVuY29kZSgpKS5oZXhkaWdlc3QoKQoKCmRlZiBfbWFrZV9yZXN1bHRfa2V5KG1ldGFkYXRhOiBkaWN0W3N0ciwgb2JqZWN0XSwgZmFsbGJhY2tfaWQ6IHN0cikgLT4gc3RyOgogICAgZmlsZV9wYXRoID0gc3RyKG1ldGFkYXRhLmdldCgiZmlsZV9wYXRoIiwgIiIpKQogICAgY2h1bmtfaW5kZXggPSBzdHIobWV0YWRhdGEuZ2V0KCJjaHVua19pbmRleCIsICIiKSkKICAgIGlmIGZpbGVfcGF0aCBhbmQgY2h1bmtfaW5kZXg6CiAgICAgICAgcmV0dXJuIGYie2ZpbGVfcGF0aH06OmNodW5rOjp7Y2h1bmtfaW5kZXh9IgogICAgcmV0dXJuIGZhbGxiYWNrX2lkCgoKZGVmIF9kZWxldGVfZmlsZV9jaHVua3MoY29sbGVjdGlvbjogY2hyb21hZGIuQ29sbGVjdGlvbiwgZmlsZV9wYXRoOiBzdHIpIC0+IGludDoKICAgICMgUGVkZSBhcGVuYXMgSURzIHBhcmEgbsOjbyBtYXRlcmlhbGl6YXIgZG9jdW1lbnRvcy9tZXRhZGF0YSBkZXNuZWNlc3PDoXJpb3MgZW0gUkFNLgogICAgcmVzdWx0cyA9IGNvbGxlY3Rpb24uZ2V0KHdoZXJlPXsiZmlsZV9wYXRoIjogZmlsZV9wYXRofSwgaW5jbHVkZT1bXSkKICAgIGlkcyA9IHJlc3VsdHMuZ2V0KCJpZHMiLCBbXSkgaWYgcmVzdWx0cyBlbHNlIFtdCiAgICBpZiBpZHM6CiAgICAgICAgY29sbGVjdGlvbi5kZWxldGUoaWRzPWlkcykKICAgIHJldHVybiBsZW4oaWRzKQoKCmRlZiBfcmVhZF9maWxlX3NhZmUoZmlsZXBhdGg6IFBhdGgpIC0+IHN0ciB8IE5vbmU6CiAgICB0cnk6CiAgICAgICAgcmF3ID0gZmlsZXBhdGgucmVhZF9ieXRlcygpCiAgICBleGNlcHQgT1NFcnJvcjoKICAgICAgICByZXR1cm4gTm9uZQoKICAgIGlmIF9sb29rc19iaW5hcnlfY29udGVudChyYXcpOgogICAgICAgIHJldHVybiBOb25lCgogICAgZm9yIGVuY29kaW5nIGluICgidXRmLTgiLCAibGF0aW4tMSIsICJjcDEyNTIiKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIHJldHVybiByYXcuZGVjb2RlKGVuY29kaW5nKQogICAgICAgIGV4Y2VwdCBVbmljb2RlRGVjb2RlRXJyb3I6CiAgICAgICAgICAgIGNvbnRpbnVlCiAgICByZXR1cm4gTm9uZQoKCmRlZiBfbG9va3NfYmluYXJ5X2NvbnRlbnQocmF3OiBieXRlcykgLT4gYm9vbDoKICAgIGlmIG5vdCByYXc6CiAgICAgICAgcmV0dXJuIEZhbHNlCgogICAgc2FtcGxlID0gcmF3Wzo0MDk2XQogICAgaWYgYiJceDAwIiBpbiBzYW1wbGU6CiAgICAgICAgcmV0dXJuIFRydWUKCiAgICBub25fdGV4dF9ieXRlcyA9IDAKICAgIGZvciBieXRlIGluIHNhbXBsZToKICAgICAgICBpZiBieXRlIGluICg5LCAxMCwgMTMpOiAgIyBcdCBcbiBccgogICAgICAgICAgICBjb250aW51ZQogICAgICAgIGlmIDMyIDw9IGJ5dGUgPD0gMTI2OiAgIyBBU0NJSSBpbXByaW1pdmVsCiAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgaWYgMTYwIDw9IGJ5dGUgPD0gMjU1OiAgIyBMYXRpbi0xIGVzdGVuZGlkbwogICAgICAgICAgICBjb250aW51ZQogICAgICAgIG5vbl90ZXh0X2J5dGVzICs9IDEKCiAgICByZXR1cm4gKG5vbl90ZXh0X2J5dGVzIC8gbGVuKHNhbXBsZSkpID4gMC4zMAoKCmRlZiBfc2Nhbl9mb2xkZXIoZm9sZGVyX3BhdGg6IFBhdGgpIC0+IEl0ZXJhdG9yW1BhdGhdOgogICAgZm9yIGRpcnBhdGgsIGRpcm5hbWVzLCBmaWxlbmFtZXMgaW4gb3Mud2Fsayhmb2xkZXJfcGF0aCk6CiAgICAgICAgZGlybmFtZXNbOl0gPSBbCiAgICAgICAgICAgIGQgZm9yIGQgaW4gZGlybmFtZXMKICAgICAgICAgICAgaWYgZCBub3QgaW4gSUdOT1JFRF9ESVJTIGFuZCBub3QgZC5zdGFydHN3aXRoKCIuIikKICAgICAgICBdCiAgICAgICAgZGlybmFtZXMuc29ydCgpCiAgICAgICAgZm9yIGZpbGVuYW1lIGluIHNvcnRlZChmaWxlbmFtZXMpOgogICAgICAgICAgICBmcCA9IFBhdGgoZGlycGF0aCkgLyBmaWxlbmFtZQogICAgICAgICAgICBpZiBmcC5zdWZmaXgubG93ZXIoKSBpbiBJR05PUkVEX0VYVEVOU0lPTlM6CiAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpZiBmcC5zdGF0KCkuc3Rfc2l6ZSA+IE1BWF9GSUxFX1NJWkVfQllURVM6CiAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgZXhjZXB0IE9TRXJyb3I6CiAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICB5aWVsZCBmcAoKCmRlZiBfY2xhc3NpZnlfZmlsZV90YXJnZXRzKGZpbGVwYXRoOiBQYXRoKSAtPiBsaXN0W0JyYW5jaFNwZWNdOgogICAgc3VmZml4ID0gZmlsZXBhdGguc3VmZml4Lmxvd2VyKCkKICAgIGlzX2NvZGUgPSBzdWZmaXggaW4gQ09ERV9FWFRFTlNJT05TCiAgICBpc19kb2MgPSBzdWZmaXggaW4gRE9DX0VYVEVOU0lPTlMKCiAgICBpZiBpc19jb2RlIGFuZCBub3QgaXNfZG9jOgogICAgICAgIHJldHVybiBbQlJBTkNIX1NQRUNTWyJqaW5hX2NvZGUiXV0KICAgIGlmIGlzX2RvYyBhbmQgbm90IGlzX2NvZGU6CiAgICAgICAgcmV0dXJuIFtCUkFOQ0hfU1BFQ1NbImJnZV9kb2MiXV0KCiAgICAjIEFycXVpdm9zIGFtYsOtZ3Vvcy9leHRlbnPDo28gZGVzY29uaGVjaWRhOiBpbmRleGEgZW0gYW1iYXMgcGFyYSBuw6NvIHBlcmRlciByZWNhbGwuCiAgICByZXR1cm4gW0JSQU5DSF9TUEVDU1siamluYV9jb2RlIl0sIEJSQU5DSF9TUEVDU1siYmdlX2RvYyJdXQoKCmRlZiBfaW5kZXhfc2luZ2xlX2ZpbGVfZm9yX2JyYW5jaCgKICAgIGZpbGVwYXRoOiBQYXRoLAogICAgYnJhbmNoOiBCcmFuY2hTcGVjLAogICAgc3BsaXR0ZXI6IFJlY3Vyc2l2ZUNoYXJhY3RlclRleHRTcGxpdHRlciwKICAgICosCiAgICBkZWxldGVfZXhpc3Rpbmc6IGJvb2wgPSBUcnVlLAopIC0+IGludDoKICAgIGNvbnRlbnQgPSBfcmVhZF9maWxlX3NhZmUoZmlsZXBhdGgpCiAgICBpZiBub3QgY29udGVudCBvciBub3QgY29udGVudC5zdHJpcCgpOgogICAgICAgIHJldHVybiAwCgogICAgYWJzX3BhdGggPSBzdHIoZmlsZXBhdGgucmVzb2x2ZSgpKQogICAgbW9kZWwgPSBnZXRfZW1iZWRkaW5nX21vZGVsKGJyYW5jaC5tb2RlbF9jaG9pY2UpCiAgICBjb2xsZWN0aW9uID0gZ2V0X2Nocm9tYV9jb2xsZWN0aW9uKGJyYW5jaC5jb2xsZWN0aW9uX25hbWUpCgogICAgY2h1bmtzID0gc3BsaXR0ZXIuc3BsaXRfdGV4dChjb250ZW50KQogICAgaWYgbm90IGNodW5rczoKICAgICAgICByZXR1cm4gMAoKICAgICMgQXR1YWxpemHDp8OjbyBpZGVtcG90ZW50ZSBwb3IgYXJxdWl2byBlbSBjYWRhIGNvbGXDp8Ojby4KICAgIGlmIGRlbGV0ZV9leGlzdGluZzoKICAgICAgICBfZGVsZXRlX2ZpbGVfY2h1bmtzKGNvbGxlY3Rpb24sIGFic19wYXRoKQoKICAgIGluc2VydGVkX2NodW5rcyA9IDAKICAgIHNraXBwZWRfY2h1bmtzID0gMAogICAgc3RvcF9pdGVyYXRpb25fd2FybmluZ3MgPSAwCiAgICBiYXRjaF9pZHM6IGxpc3Rbc3RyXSA9IFtdCiAgICBiYXRjaF9kb2NzOiBsaXN0W3N0cl0gPSBbXQogICAgYmF0Y2hfbWV0YWRhdGFzOiBsaXN0W2RpY3Rbc3RyLCBvYmplY3RdXSA9IFtdCgogICAgZGVmIF93YXJuX3N0b3BfaXRlcmF0aW9uKG1lc3NhZ2U6IHN0cikgLT4gTm9uZToKICAgICAgICBub25sb2NhbCBzdG9wX2l0ZXJhdGlvbl93YXJuaW5ncwogICAgICAgIGlmIHN0b3BfaXRlcmF0aW9uX3dhcm5pbmdzIDwgMzoKICAgICAgICAgICAgbG9nLndhcm5pbmcobWVzc2FnZSkKICAgICAgICBzdG9wX2l0ZXJhdGlvbl93YXJuaW5ncyArPSAxCgogICAgZGVmIF90b19lbWJlZGRpbmdfcm93cyhlbmNvZGVkX2VtYmVkZGluZ3M6IG9iamVjdCkgLT4gbGlzdFtsaXN0W2Zsb2F0XV06CiAgICAgICAgaWYgaGFzYXR0cihlbmNvZGVkX2VtYmVkZGluZ3MsICJ0b2xpc3QiKToKICAgICAgICAgICAgcm93cyA9IGVuY29kZWRfZW1iZWRkaW5ncy50b2xpc3QoKQogICAgICAgICAgICBpZiBpc2luc3RhbmNlKHJvd3MsIGxpc3QpOgogICAgICAgICAgICAgICAgaWYgcm93cyBhbmQgaXNpbnN0YW5jZShyb3dzWzBdLCAoaW50LCBmbG9hdCkpOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBbbGlzdChyb3dzKV0KICAgICAgICAgICAgICAgIHJldHVybiByb3dzCiAgICAgICAgcmV0dXJuIFtsaXN0KHJvdykgZm9yIHJvdyBpbiBlbmNvZGVkX2VtYmVkZGluZ3NdICAjIHR5cGU6IGlnbm9yZVthcmctdHlwZV0KCiAgICBkZWYgX2ZsdXNoX2JhdGNoKCkgLT4gTm9uZToKICAgICAgICBub25sb2NhbCBpbnNlcnRlZF9jaHVua3MsIHNraXBwZWRfY2h1bmtzCiAgICAgICAgaWYgbm90IGJhdGNoX2lkczoKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgIHBlbmRpbmdfaWRzID0gbGlzdChiYXRjaF9pZHMpCiAgICAgICAgcGVuZGluZ19kb2NzID0gbGlzdChiYXRjaF9kb2NzKQogICAgICAgIHBlbmRpbmdfbWV0YWRhdGFzID0gbGlzdChiYXRjaF9tZXRhZGF0YXMpCgogICAgICAgIHRyeToKICAgICAgICAgICAgZW5jb2RlZCA9IG1vZGVsLmVuY29kZSgKICAgICAgICAgICAgICAgIHBlbmRpbmdfZG9jcywKICAgICAgICAgICAgICAgIHNob3dfcHJvZ3Jlc3NfYmFyPUZhbHNlLAogICAgICAgICAgICAgICAgYmF0Y2hfc2l6ZT1FTUJFRERJTkdfQkFUQ0hfU0laRSwKICAgICAgICAgICAgKQogICAgICAgICAgICBlbWJlZGRpbmdzID0gX3RvX2VtYmVkZGluZ19yb3dzKGVuY29kZWQpCiAgICAgICAgICAgIGNvbGxlY3Rpb24udXBzZXJ0KAogICAgICAgICAgICAgICAgaWRzPXBlbmRpbmdfaWRzLAogICAgICAgICAgICAgICAgZW1iZWRkaW5ncz1lbWJlZGRpbmdzLAogICAgICAgICAgICAgICAgZG9jdW1lbnRzPXBlbmRpbmdfZG9jcywKICAgICAgICAgICAgICAgIG1ldGFkYXRhcz1wZW5kaW5nX21ldGFkYXRhcywKICAgICAgICAgICAgKQogICAgICAgICAgICBpbnNlcnRlZF9jaHVua3MgKz0gbGVuKHBlbmRpbmdfaWRzKQogICAgICAgICAgICBkZWwgZW1iZWRkaW5ncwogICAgICAgIGV4Y2VwdCBTdG9wSXRlcmF0aW9uOgogICAgICAgICAgICBfd2Fybl9zdG9wX2l0ZXJhdGlvbigKICAgICAgICAgICAgICAgIGYie2ZpbGVwYXRoLm5hbWV9IFt7YnJhbmNoLmtleX1dIFN0b3BJdGVyYXRpb24gbm8gYmF0Y2g7IGFwbGljYW5kbyBmYWxsYmFjayBwb3IgY2h1bmsuIgogICAgICAgICAgICApCiAgICAgICAgICAgIGZvciBjaHVua19pZCwgY2h1bmtfZG9jLCBjaHVua19tZXRhZGF0YSBpbiB6aXAocGVuZGluZ19pZHMsIHBlbmRpbmdfZG9jcywgcGVuZGluZ19tZXRhZGF0YXMpOgogICAgICAgICAgICAgICAgY2FuZGlkYXRlX2RvYyA9IGNodW5rX2RvYy5zdHJpcCgpCiAgICAgICAgICAgICAgICBpZiBub3QgY2FuZGlkYXRlX2RvYzoKICAgICAgICAgICAgICAgICAgICBza2lwcGVkX2NodW5rcyArPSAxCiAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBlbmNvZGVkX3NpbmdsZSA9IG1vZGVsLmVuY29kZSgKICAgICAgICAgICAgICAgICAgICAgICAgW2NhbmRpZGF0ZV9kb2NdLAogICAgICAgICAgICAgICAgICAgICAgICBzaG93X3Byb2dyZXNzX2Jhcj1GYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2hfc2l6ZT0xLAogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICBzaW5nbGVfZW1iZWRkaW5ncyA9IF90b19lbWJlZGRpbmdfcm93cyhlbmNvZGVkX3NpbmdsZSkKICAgICAgICAgICAgICAgICAgICBjb2xsZWN0aW9uLnVwc2VydCgKICAgICAgICAgICAgICAgICAgICAgICAgaWRzPVtjaHVua19pZF0sCiAgICAgICAgICAgICAgICAgICAgICAgIGVtYmVkZGluZ3M9c2luZ2xlX2VtYmVkZGluZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50cz1bY2FuZGlkYXRlX2RvY10sCiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhcz1bY2h1bmtfbWV0YWRhdGFdLAogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICBpbnNlcnRlZF9jaHVua3MgKz0gMQogICAgICAgICAgICAgICAgICAgIGRlbCBzaW5nbGVfZW1iZWRkaW5ncwogICAgICAgICAgICAgICAgZXhjZXB0IFN0b3BJdGVyYXRpb246CiAgICAgICAgICAgICAgICAgICAgY29tcGFjdF9kb2MgPSAiICIuam9pbihjYW5kaWRhdGVfZG9jLnNwbGl0KCkpCiAgICAgICAgICAgICAgICAgICAgaWYgbm90IGNvbXBhY3RfZG9jOgogICAgICAgICAgICAgICAgICAgICAgICBza2lwcGVkX2NodW5rcyArPSAxCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgICAgICBlbmNvZGVkX3NpbmdsZSA9IG1vZGVsLmVuY29kZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjb21wYWN0X2RvY10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG93X3Byb2dyZXNzX2Jhcj1GYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoX3NpemU9MSwKICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICBzaW5nbGVfZW1iZWRkaW5ncyA9IF90b19lbWJlZGRpbmdfcm93cyhlbmNvZGVkX3NpbmdsZSkKICAgICAgICAgICAgICAgICAgICAgICAgY29sbGVjdGlvbi51cHNlcnQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZHM9W2NodW5rX2lkXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtYmVkZGluZ3M9c2luZ2xlX2VtYmVkZGluZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudHM9W2NvbXBhY3RfZG9jXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhcz1bY2h1bmtfbWV0YWRhdGFdLAogICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgIGluc2VydGVkX2NodW5rcyArPSAxCiAgICAgICAgICAgICAgICAgICAgICAgIGRlbCBzaW5nbGVfZW1iZWRkaW5ncwogICAgICAgICAgICAgICAgICAgIGV4Y2VwdCBTdG9wSXRlcmF0aW9uOgogICAgICAgICAgICAgICAgICAgICAgICBza2lwcGVkX2NodW5rcyArPSAxCiAgICAgICAgICAgICAgICAgICAgICAgIF93YXJuX3N0b3BfaXRlcmF0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZiJ7ZmlsZXBhdGgubmFtZX0gW3ticmFuY2gua2V5fV0gY2h1bmsgaWdub3JhZG8gYXDDs3MgU3RvcEl0ZXJhdGlvbiByZXBldGlkby4iCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICBiYXRjaF9pZHMuY2xlYXIoKQogICAgICAgIGJhdGNoX2RvY3MuY2xlYXIoKQogICAgICAgIGJhdGNoX21ldGFkYXRhcy5jbGVhcigpCgogICAgZm9yIGksIGNodW5rIGluIGVudW1lcmF0ZShjaHVua3MpOgogICAgICAgIGlmIG5vdCBjaHVuayBvciBub3QgY2h1bmsuc3RyaXAoKToKICAgICAgICAgICAgc2tpcHBlZF9jaHVua3MgKz0gMQogICAgICAgICAgICBjb250aW51ZQogICAgICAgIGJhdGNoX2lkcy5hcHBlbmQoX21ha2VfY2h1bmtfaWQoYWJzX3BhdGgsIGkpKQogICAgICAgIGJhdGNoX2RvY3MuYXBwZW5kKGNodW5rKQogICAgICAgIGJhdGNoX21ldGFkYXRhcy5hcHBlbmQoCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJmaWxlX3BhdGgiOiBhYnNfcGF0aCwKICAgICAgICAgICAgICAgICJmaWxlX25hbWUiOiBmaWxlcGF0aC5uYW1lLAogICAgICAgICAgICAgICAgImNodW5rX2luZGV4IjogaSwKICAgICAgICAgICAgICAgICJzb3VyY2VfY29sbGVjdGlvbiI6IGJyYW5jaC5jb2xsZWN0aW9uX25hbWUsCiAgICAgICAgICAgICAgICAic291cmNlX21vZGVsX2Nob2ljZSI6IGJyYW5jaC5tb2RlbF9jaG9pY2UsCiAgICAgICAgICAgICAgICAic291cmNlX21vZGVsX2lkIjogYnJhbmNoLm1vZGVsX2lkLAogICAgICAgICAgICAgICAgImNvbnRlbnRfZG9tYWluIjogYnJhbmNoLmNvbnRlbnRfZG9tYWluLAogICAgICAgICAgICB9CiAgICAgICAgKQogICAgICAgIGlmIGxlbihiYXRjaF9pZHMpID49IEVNQkVERElOR19CQVRDSF9TSVpFOgogICAgICAgICAgICBfZmx1c2hfYmF0Y2goKQoKICAgIF9mbHVzaF9iYXRjaCgpCiAgICBpZiBza2lwcGVkX2NodW5rczoKICAgICAgICBfd2Fybl9zdG9wX2l0ZXJhdGlvbigKICAgICAgICAgICAgZiJ7ZmlsZXBhdGgubmFtZX0gW3ticmFuY2gua2V5fV0gaWdub3JvdSB7c2tpcHBlZF9jaHVua3N9IGNodW5rKHMpIHZhemlvKHMpL2ludsOhbGlkbyhzKS4iCiAgICAgICAgKQogICAgcmV0dXJuIGluc2VydGVkX2NodW5rcwoKCmRlZiBfcmVtb3ZlX2ZpbGVfZnJvbV9hbGxfY29sbGVjdGlvbnMoYWJzX3BhdGg6IHN0cikgLT4gdHVwbGVbZGljdFtzdHIsIGludF0sIGxpc3Rbc3RyXV06CiAgICBkZWxldGVkX3Blcl9icmFuY2g6IGRpY3Rbc3RyLCBpbnRdID0ge30KICAgIGVycm9yczogbGlzdFtzdHJdID0gW10KCiAgICBmb3IgYnJhbmNoIGluIEJSQU5DSF9TUEVDUy52YWx1ZXMoKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIGNvbGxlY3Rpb24gPSBnZXRfY2hyb21hX2NvbGxlY3Rpb24oYnJhbmNoLmNvbGxlY3Rpb25fbmFtZSkKICAgICAgICAgICAgZGVsZXRlZCA9IF9kZWxldGVfZmlsZV9jaHVua3MoY29sbGVjdGlvbiwgYWJzX3BhdGgpCiAgICAgICAgICAgIGRlbGV0ZWRfcGVyX2JyYW5jaFticmFuY2gua2V5XSA9IGRlbGV0ZWQKICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgICAgIGVycm9ycy5hcHBlbmQoZiJ7YnJhbmNoLmtleX06IHtlfSIpCiAgICByZXR1cm4gZGVsZXRlZF9wZXJfYnJhbmNoLCBlcnJvcnMKCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIEJ1c2NhIHNlbcOibnRpY2EgaMOtYnJpZGEKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgpkZWYgX3F1ZXJ5X2JyYW5jaChicmFuY2g6IEJyYW5jaFNwZWMsIHF1ZXJ5OiBzdHIsIG5fcmVzdWx0czogaW50KSAtPiB0dXBsZVtsaXN0W1JldHJpZXZlZEhpdF0sIHN0ciB8IE5vbmVdOgogICAgdHJ5OgogICAgICAgIGNvbGxlY3Rpb24gPSBnZXRfY2hyb21hX2NvbGxlY3Rpb24oYnJhbmNoLmNvbGxlY3Rpb25fbmFtZSkKICAgICAgICBtb2RlbCA9IGdldF9lbWJlZGRpbmdfbW9kZWwoYnJhbmNoLm1vZGVsX2Nob2ljZSkKICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICByZXR1cm4gW10sIGYie2JyYW5jaC5rZXl9OiByZWN1cnNvIGluZGlzcG9uw612ZWwgKHtlfSkiCgogICAgdHJ5OgogICAgICAgIHF1ZXJ5X2VtYmVkZGluZyA9IG1vZGVsLmVuY29kZShbcXVlcnldLCBzaG93X3Byb2dyZXNzX2Jhcj1GYWxzZSkudG9saXN0KCkKICAgICAgICByZXN1bHRzID0gY29sbGVjdGlvbi5xdWVyeSgKICAgICAgICAgICAgcXVlcnlfZW1iZWRkaW5ncz1xdWVyeV9lbWJlZGRpbmcsCiAgICAgICAgICAgIG5fcmVzdWx0cz1uX3Jlc3VsdHMsCiAgICAgICAgICAgIGluY2x1ZGU9WyJkb2N1bWVudHMiLCAibWV0YWRhdGFzIiwgImRpc3RhbmNlcyJdLAogICAgICAgICkKICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICByZXR1cm4gW10sIGYie2JyYW5jaC5rZXl9OiBmYWxoYSBuYSBxdWVyeSAoe2V9KSIKCiAgICBkb2N1bWVudHMgPSByZXN1bHRzLmdldCgiZG9jdW1lbnRzIiwgW1tdXSlbMF0KICAgIG1ldGFkYXRhcyA9IHJlc3VsdHMuZ2V0KCJtZXRhZGF0YXMiLCBbW11dKVswXQogICAgZGlzdGFuY2VzID0gcmVzdWx0cy5nZXQoImRpc3RhbmNlcyIsIFtbXV0pWzBdCiAgICBpZHMgPSByZXN1bHRzLmdldCgiaWRzIiwgW1tdXSlbMF0KCiAgICBoaXRzOiBsaXN0W1JldHJpZXZlZEhpdF0gPSBbXQogICAgZm9yIGlkeCwgKGRvYywgbWV0YSwgZGlzdCkgaW4gZW51bWVyYXRlKHppcChkb2N1bWVudHMsIG1ldGFkYXRhcywgZGlzdGFuY2VzKSwgc3RhcnQ9MSk6CiAgICAgICAgbWV0YWRhdGEgPSBtZXRhIG9yIHt9CiAgICAgICAgZmFsbGJhY2tfaWQgPSBpZHNbaWR4IC0gMV0gaWYgaWR4IC0gMSA8IGxlbihpZHMpIGVsc2UgZiJ7YnJhbmNoLmtleX06e2lkeH0iCiAgICAgICAga2V5ID0gX21ha2VfcmVzdWx0X2tleShtZXRhZGF0YSwgZmFsbGJhY2tfaWQpCgogICAgICAgIHNpbWlsYXJpdHkgPSBOb25lCiAgICAgICAgaWYgZGlzdCBpcyBub3QgTm9uZToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgc2ltaWxhcml0eSA9IDEuMCAtIGZsb2F0KGRpc3QpCiAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgICAgICAgICBzaW1pbGFyaXR5ID0gTm9uZQoKICAgICAgICBoaXRzLmFwcGVuZCgKICAgICAgICAgICAgUmV0cmlldmVkSGl0KAogICAgICAgICAgICAgICAga2V5PWtleSwKICAgICAgICAgICAgICAgIGRvY3VtZW50PShkb2Mgb3IgIiIpLAogICAgICAgICAgICAgICAgbWV0YWRhdGE9bWV0YWRhdGEsCiAgICAgICAgICAgICAgICBkaXN0YW5jZT1mbG9hdChkaXN0KSBpZiBkaXN0IGlzIG5vdCBOb25lIGVsc2UgTm9uZSwKICAgICAgICAgICAgICAgIHNpbWlsYXJpdHk9c2ltaWxhcml0eSwKICAgICAgICAgICAgICAgIGJyYW5jaD1icmFuY2gsCiAgICAgICAgICAgICAgICByYW5rPWlkeCwKICAgICAgICAgICAgKQogICAgICAgICkKCiAgICByZXR1cm4gaGl0cywgTm9uZQoKCmRlZiBfcnJmX2Z1c2UoaGl0c19ieV9icmFuY2g6IGRpY3Rbc3RyLCBsaXN0W1JldHJpZXZlZEhpdF1dLCB0b3BfbGltaXQ6IGludCkgLT4gbGlzdFtGdXNlZEhpdF06CiAgICBmdXNlZDogZGljdFtzdHIsIEZ1c2VkSGl0XSA9IHt9CgogICAgZm9yIGJyYW5jaF9rZXksIGhpdHMgaW4gaGl0c19ieV9icmFuY2guaXRlbXMoKToKICAgICAgICBfID0gYnJhbmNoX2tleQogICAgICAgIGZvciByYW5rLCBoaXQgaW4gZW51bWVyYXRlKGhpdHMsIHN0YXJ0PTEpOgogICAgICAgICAgICBjb250cmlidXRpb24gPSAxLjAgLyAoUlJGX0sgKyByYW5rKQogICAgICAgICAgICBlbnRyeSA9IGZ1c2VkLmdldChoaXQua2V5KQoKICAgICAgICAgICAgaWYgZW50cnkgaXMgTm9uZToKICAgICAgICAgICAgICAgIGVudHJ5ID0gRnVzZWRIaXQoCiAgICAgICAgICAgICAgICAgICAga2V5PWhpdC5rZXksCiAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQ9aGl0LmRvY3VtZW50LAogICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhPWRpY3QoaGl0Lm1ldGFkYXRhKSwKICAgICAgICAgICAgICAgICAgICBycmZfc2NvcmU9MC4wLAogICAgICAgICAgICAgICAgICAgIHNvdXJjZV9kZXRhaWxzPXt9LAogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgZnVzZWRbaGl0LmtleV0gPSBlbnRyeQoKICAgICAgICAgICAgZW50cnkucnJmX3Njb3JlICs9IGNvbnRyaWJ1dGlvbgogICAgICAgICAgICBlbnRyeS5zb3VyY2VfZGV0YWlsc1toaXQuYnJhbmNoLmtleV0gPSB7CiAgICAgICAgICAgICAgICAicmFuayI6IHJhbmssCiAgICAgICAgICAgICAgICAiZGlzdGFuY2UiOiBoaXQuZGlzdGFuY2UsCiAgICAgICAgICAgICAgICAic2ltaWxhcml0eSI6IGhpdC5zaW1pbGFyaXR5LAogICAgICAgICAgICAgICAgImNvbGxlY3Rpb24iOiBoaXQuYnJhbmNoLmNvbGxlY3Rpb25fbmFtZSwKICAgICAgICAgICAgICAgICJtb2RlbF9jaG9pY2UiOiBoaXQuYnJhbmNoLm1vZGVsX2Nob2ljZSwKICAgICAgICAgICAgICAgICJtb2RlbF9pZCI6IGhpdC5icmFuY2gubW9kZWxfaWQsCiAgICAgICAgICAgICAgICAiY29udGVudF9kb21haW4iOiBoaXQuYnJhbmNoLmNvbnRlbnRfZG9tYWluLAogICAgICAgICAgICB9CgogICAgICAgICAgICAjIFVzYSBtZXRhZGFkb3MgZG8gaGl0IGNvbSBtZWxob3Igc2ltaWxhcmlkYWRlIGxvY2FsIGNvbW8gYmFzZSBwcmluY2lwYWwuCiAgICAgICAgICAgIGN1cnJlbnRfc2ltID0gZW50cnkubWV0YWRhdGEuZ2V0KCJfYmVzdF9zaW1pbGFyaXR5IiwgLTEwLjApCiAgICAgICAgICAgIGNhbmRpZGF0ZV9zaW0gPSBoaXQuc2ltaWxhcml0eSBpZiBoaXQuc2ltaWxhcml0eSBpcyBub3QgTm9uZSBlbHNlIC0xMC4wCiAgICAgICAgICAgIGlmIGNhbmRpZGF0ZV9zaW0gPiBjdXJyZW50X3NpbToKICAgICAgICAgICAgICAgIGVudHJ5LmRvY3VtZW50ID0gaGl0LmRvY3VtZW50CiAgICAgICAgICAgICAgICBlbnRyeS5tZXRhZGF0YSA9IGRpY3QoaGl0Lm1ldGFkYXRhKQogICAgICAgICAgICAgICAgZW50cnkubWV0YWRhdGFbIl9iZXN0X3NpbWlsYXJpdHkiXSA9IGNhbmRpZGF0ZV9zaW0KCiAgICBmdXNlZF9oaXRzID0gbGlzdChmdXNlZC52YWx1ZXMoKSkKICAgIGZ1c2VkX2hpdHMuc29ydChrZXk9bGFtYmRhIGg6IGgucnJmX3Njb3JlLCByZXZlcnNlPVRydWUpCgogICAgIyBMaW1pdGEgbyBwb29sIGFudGVzIGRvIHJlcmFua2luZyBwYXJhIHJlZHV6aXIgQ1BVL1JBTS4KICAgIHJldHVybiBmdXNlZF9oaXRzWzp0b3BfbGltaXRdCgoKZGVmIF9hcHBseV9yZXJhbmsocXVlcnk6IHN0ciwgZnVzZWRfaGl0czogbGlzdFtGdXNlZEhpdF0sIHRvcF9rOiBpbnQpIC0+IHR1cGxlW2xpc3RbRnVzZWRIaXRdLCBib29sLCBzdHIgfCBOb25lXToKICAgIGlmIG5vdCBmdXNlZF9oaXRzOgogICAgICAgIHJldHVybiBbXSwgRmFsc2UsIE5vbmUKCiAgICByZXJhbmtlciA9IGdldF9yZXJhbmtlcigpCiAgICBpZiByZXJhbmtlciBpcyBOb25lOgogICAgICAgIHJlYXNvbiA9IF9yZXJhbmtlcl9lcnJvciBpZiBfcmVyYW5rZXJfZXJyb3IgZWxzZSAicmVyYW5rZXJfZGVzYWJpbGl0YWRvIgogICAgICAgIHJldHVybiBmdXNlZF9oaXRzWzp0b3Bfa10sIEZhbHNlLCByZWFzb24KCiAgICB0cnk6CiAgICAgICAgcGFpcnMgPSBbKHF1ZXJ5LCBoaXQuZG9jdW1lbnQpIGZvciBoaXQgaW4gZnVzZWRfaGl0c10KICAgICAgICBzY29yZXMgPSByZXJhbmtlci5wcmVkaWN0KHBhaXJzLCBzaG93X3Byb2dyZXNzX2Jhcj1GYWxzZSwgY29udmVydF90b19udW1weT1UcnVlKQoKICAgICAgICBmb3IgaGl0LCBzY29yZSBpbiB6aXAoZnVzZWRfaGl0cywgc2NvcmVzKToKICAgICAgICAgICAgaGl0LnJlcmFua19zY29yZSA9IGZsb2F0KHNjb3JlKQoKICAgICAgICBmdXNlZF9oaXRzLnNvcnQoCiAgICAgICAgICAgIGtleT1sYW1iZGEgaDogKAogICAgICAgICAgICAgICAgaC5yZXJhbmtfc2NvcmUgaWYgaC5yZXJhbmtfc2NvcmUgaXMgbm90IE5vbmUgZWxzZSAtMWU5LAogICAgICAgICAgICAgICAgaC5ycmZfc2NvcmUsCiAgICAgICAgICAgICksCiAgICAgICAgICAgIHJldmVyc2U9VHJ1ZSwKICAgICAgICApCiAgICAgICAgcmV0dXJuIGZ1c2VkX2hpdHNbOnRvcF9rXSwgVHJ1ZSwgTm9uZQogICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgIHJldHVybiBmdXNlZF9oaXRzWzp0b3Bfa10sIEZhbHNlLCBzdHIoZSkKCgpkZWYgX2Zvcm1hdF9zaW1pbGFyaXR5KHNpbWlsYXJpdHk6IGZsb2F0IHwgTm9uZSkgLT4gc3RyOgogICAgaWYgc2ltaWxhcml0eSBpcyBOb25lOgogICAgICAgIHJldHVybiAibi9hIgogICAgcmV0dXJuIGYie3JvdW5kKHNpbWlsYXJpdHkgKiAxMDAsIDEpfSUiCgoKZGVmIF9mb3JtYXRfZnVzZWRfcmVzdWx0cygKICAgICosCiAgICBxdWVyeTogc3RyLAogICAgbW9kZTogc3RyLAogICAgaGl0czogbGlzdFtGdXNlZEhpdF0sCiAgICBicmFuY2hfZXJyb3JzOiBsaXN0W3N0cl0sCiAgICByZXJhbmtfYXBwbGllZDogYm9vbCwKICAgIHJlcmFua19lcnJvcjogc3RyIHwgTm9uZSwKKSAtPiBzdHI6CiAgICBpZiBub3QgaGl0czoKICAgICAgICBtc2cgPSAiTmVuaHVtIHJlc3VsdGFkbyBlbmNvbnRyYWRvLiBBcyBjb2xlw6fDtWVzIHBvZGVtIGVzdGFyIHZhemlhcy4iCiAgICAgICAgaWYgYnJhbmNoX2Vycm9yczoKICAgICAgICAgICAgbXNnICs9ICJcbkZhbGhhcyBkZXRlY3RhZGFzOiAiICsgIiB8ICIuam9pbihicmFuY2hfZXJyb3JzKQogICAgICAgIHJldHVybiBtc2cKCiAgICBsaW5lczogbGlzdFtzdHJdID0gW2YiIyBSZXN1bHRhZG9zIHBhcmE6ICd7cXVlcnl9JyIsIGYiKipNb2RvOioqIHttb2RlfSJdCgogICAgaWYgYnJhbmNoX2Vycm9yczoKICAgICAgICBsaW5lcy5hcHBlbmQoIioqQXZpc29zIGRlIGJyYW5jaDoqKiAiICsgIiB8ICIuam9pbihicmFuY2hfZXJyb3JzKSkKCiAgICBpZiBtb2RlID09ICJlbnNlbWJsZSI6CiAgICAgICAgaWYgcmVyYW5rX2FwcGxpZWQ6CiAgICAgICAgICAgIGxpbmVzLmFwcGVuZChmIioqUmVyYW5raW5nOioqIGF0aXZvICh7UkVSQU5LX01PREVMX0lEfSkiKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGxpbmVzLmFwcGVuZChmIioqUmVyYW5raW5nOioqIGluZGlzcG9uw612ZWwgKHtyZXJhbmtfZXJyb3Igb3IgJ3NlbSBkZXRhbGhlcyd9KSIpCgogICAgbGluZXMuYXBwZW5kKCIiKQoKICAgIGZvciBpZHgsIGhpdCBpbiBlbnVtZXJhdGUoaGl0cywgc3RhcnQ9MSk6CiAgICAgICAgbWV0YWRhdGEgPSBkaWN0KGhpdC5tZXRhZGF0YSkKICAgICAgICBtZXRhZGF0YS5wb3AoIl9iZXN0X3NpbWlsYXJpdHkiLCBOb25lKQoKICAgICAgICBmaWxlX3BhdGggPSBzdHIobWV0YWRhdGEuZ2V0KCJmaWxlX3BhdGgiLCAiZGVzY29uaGVjaWRvIikpCiAgICAgICAgY2h1bmtfaW5kZXggPSBtZXRhZGF0YS5nZXQoImNodW5rX2luZGV4IiwgIj8iKQogICAgICAgIGZpbGVfbmFtZSA9IHN0cihtZXRhZGF0YS5nZXQoImZpbGVfbmFtZSIsIFBhdGgoZmlsZV9wYXRoKS5uYW1lIGlmIGZpbGVfcGF0aCAhPSAiZGVzY29uaGVjaWRvIiBlbHNlICI/IikpCgogICAgICAgIHNvdXJjZV9tb2RlbHMgPSBzb3J0ZWQoe3N0cih2LmdldCgibW9kZWxfY2hvaWNlIiwgIj8iKSkgZm9yIHYgaW4gaGl0LnNvdXJjZV9kZXRhaWxzLnZhbHVlcygpfSkKICAgICAgICBzb3VyY2VfY29sbGVjdGlvbnMgPSBzb3J0ZWQoe3N0cih2LmdldCgiY29sbGVjdGlvbiIsICI/IikpIGZvciB2IGluIGhpdC5zb3VyY2VfZGV0YWlscy52YWx1ZXMoKX0pCgogICAgICAgIHNvdXJjZV9wYXJ0czogbGlzdFtzdHJdID0gW10KICAgICAgICBmb3Igc291cmNlX2tleSwgZGV0YWlscyBpbiBzb3J0ZWQoCiAgICAgICAgICAgIGhpdC5zb3VyY2VfZGV0YWlscy5pdGVtcygpLAogICAgICAgICAgICBrZXk9bGFtYmRhIGl0ZW06IGludChpdGVtWzFdLmdldCgicmFuayIsIDk5OTk5OSkpLAogICAgICAgICk6CiAgICAgICAgICAgIHNvdXJjZV9wYXJ0cy5hcHBlbmQoCiAgICAgICAgICAgICAgICBmIntzb3VyY2Vfa2V5fShyYW5rPXtkZXRhaWxzLmdldCgncmFuaycpfSwgc2ltPXtfZm9ybWF0X3NpbWlsYXJpdHkoZGV0YWlscy5nZXQoJ3NpbWlsYXJpdHknKSl9KSIKICAgICAgICAgICAgKQoKICAgICAgICBzbmlwcGV0ID0gaGl0LmRvY3VtZW50LnN0cmlwKCkKICAgICAgICBpZiBsZW4oc25pcHBldCkgPiA4MDA6CiAgICAgICAgICAgIHNuaXBwZXQgPSBzbmlwcGV0Wzo4MDBdICsgIlxuLi4uIFt0cnVuY2Fkb10iCgogICAgICAgIHNjb3JlX2xpbmUgPSBmIlJSRj17aGl0LnJyZl9zY29yZTouNGZ9IgogICAgICAgIGlmIGhpdC5yZXJhbmtfc2NvcmUgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNjb3JlX2xpbmUgKz0gZiIgfCByZXJhbms9e2hpdC5yZXJhbmtfc2NvcmU6LjRmfSIKCiAgICAgICAgbGluZXMuYXBwZW5kKGYiIyMgW3tpZHh9XSB7ZmlsZV9wYXRofSIpCiAgICAgICAgbGluZXMuYXBwZW5kKGYiKipTY29yZXM6Kioge3Njb3JlX2xpbmV9IikKICAgICAgICBsaW5lcy5hcHBlbmQoZiIqKkZvbnRlcyBkZSByZWN1cGVyYcOnw6NvOioqIHsnLCAnLmpvaW4oc291cmNlX3BhcnRzKX0iKQogICAgICAgIGxpbmVzLmFwcGVuZCgKICAgICAgICAgICAgIioqTWV0YWRhZG9zIHVuaWZpY2Fkb3M6KiogIgogICAgICAgICAgICBmImZpbGVfbmFtZT17ZmlsZV9uYW1lfSB8IGNodW5rX2luZGV4PXtjaHVua19pbmRleH0gfCAiCiAgICAgICAgICAgIGYic291cmNlX21vZGVscz17c291cmNlX21vZGVsc30gfCBzb3VyY2VfY29sbGVjdGlvbnM9e3NvdXJjZV9jb2xsZWN0aW9uc30iCiAgICAgICAgKQogICAgICAgIGxpbmVzLmFwcGVuZCgiIikKICAgICAgICBsaW5lcy5hcHBlbmQoZiJgYGBcbntzbmlwcGV0fVxuYGBgIikKICAgICAgICBsaW5lcy5hcHBlbmQoIiIpCgogICAgcmV0dXJuICJcbiIuam9pbihsaW5lcykKCgpkZWYgX3J1bl9zaW5nbGVfbW9kZShxdWVyeTogc3RyLCB0b3BfazogaW50KSAtPiB0dXBsZVtsaXN0W0Z1c2VkSGl0XSwgbGlzdFtzdHJdLCBib29sLCBzdHIgfCBOb25lXToKICAgIHByaW1hcnlfYnJhbmNoID0gQlJBTkNIX1NQRUNTW0RFRkFVTFRfU0lOR0xFX0JSQU5DSF9LRVldCgogICAgaGl0cywgZXJyb3IgPSBfcXVlcnlfYnJhbmNoKHByaW1hcnlfYnJhbmNoLCBxdWVyeSwgdG9wX2spCiAgICBlcnJvcnM6IGxpc3Rbc3RyXSA9IFtdCiAgICBpZiBlcnJvcjoKICAgICAgICBlcnJvcnMuYXBwZW5kKGVycm9yKQoKICAgICMgRmFsbGJhY2sgYXV0b23DoXRpY28gcGFyYSBhIGJyYW5jaCBhbHRlcm5hdGl2YSwgcHJlc2VydmFuZG8gZGlzcG9uaWJpbGlkYWRlLgogICAgaWYgbm90IGhpdHM6CiAgICAgICAgZmFsbGJhY2tfYnJhbmNoX2tleSA9ICJiZ2VfZG9jIiBpZiBwcmltYXJ5X2JyYW5jaC5rZXkgPT0gImppbmFfY29kZSIgZWxzZSAiamluYV9jb2RlIgogICAgICAgIGZhbGxiYWNrX2hpdHMsIGZhbGxiYWNrX2Vycm9yID0gX3F1ZXJ5X2JyYW5jaChCUkFOQ0hfU1BFQ1NbZmFsbGJhY2tfYnJhbmNoX2tleV0sIHF1ZXJ5LCB0b3BfaykKICAgICAgICBpZiBmYWxsYmFja19lcnJvcjoKICAgICAgICAgICAgZXJyb3JzLmFwcGVuZChmYWxsYmFja19lcnJvcikKICAgICAgICBpZiBmYWxsYmFja19oaXRzOgogICAgICAgICAgICBoaXRzID0gZmFsbGJhY2tfaGl0cwoKICAgIGlmIG5vdCBoaXRzOgogICAgICAgIHJldHVybiBbXSwgZXJyb3JzLCBGYWxzZSwgTm9uZQoKICAgIGZ1c2VkID0gX3JyZl9mdXNlKHsic2luZ2xlIjogaGl0c30sIHRvcF9rKQogICAgcmV0dXJuIGZ1c2VkLCBlcnJvcnMsIEZhbHNlLCBOb25lCgoKZGVmIF9ydW5fZW5zZW1ibGVfbW9kZShxdWVyeTogc3RyLCB0b3BfazogaW50KSAtPiB0dXBsZVtsaXN0W0Z1c2VkSGl0XSwgbGlzdFtzdHJdLCBib29sLCBzdHIgfCBOb25lXToKICAgIHBlcl9icmFuY2hfayA9IG1pbihNQVhfUVVFUllfUkVTVUxUUywgbWF4KHRvcF9rICogMiwgdG9wX2spKQogICAgYnJhbmNoZXMgPSBbQlJBTkNIX1NQRUNTWyJqaW5hX2NvZGUiXSwgQlJBTkNIX1NQRUNTWyJiZ2VfZG9jIl1dCgogICAgaGl0c19ieV9icmFuY2g6IGRpY3Rbc3RyLCBsaXN0W1JldHJpZXZlZEhpdF1dID0ge30KICAgIGJyYW5jaF9lcnJvcnM6IGxpc3Rbc3RyXSA9IFtdCgogICAgd2l0aCBUaHJlYWRQb29sRXhlY3V0b3IobWF4X3dvcmtlcnM9bGVuKGJyYW5jaGVzKSkgYXMgZXhlY3V0b3I6CiAgICAgICAgZnV0dXJlcyA9IHsKICAgICAgICAgICAgZXhlY3V0b3Iuc3VibWl0KF9xdWVyeV9icmFuY2gsIGJyYW5jaCwgcXVlcnksIHBlcl9icmFuY2hfayk6IGJyYW5jaAogICAgICAgICAgICBmb3IgYnJhbmNoIGluIGJyYW5jaGVzCiAgICAgICAgfQogICAgICAgIGZvciBmdXR1cmUgaW4gYXNfY29tcGxldGVkKGZ1dHVyZXMpOgogICAgICAgICAgICBicmFuY2ggPSBmdXR1cmVzW2Z1dHVyZV0KICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgaGl0cywgZXJyb3IgPSBmdXR1cmUucmVzdWx0KCkKICAgICAgICAgICAgICAgIGlmIGVycm9yOgogICAgICAgICAgICAgICAgICAgIGJyYW5jaF9lcnJvcnMuYXBwZW5kKGVycm9yKQogICAgICAgICAgICAgICAgaWYgaGl0czoKICAgICAgICAgICAgICAgICAgICBoaXRzX2J5X2JyYW5jaFticmFuY2gua2V5XSA9IGhpdHMKICAgICAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgICAgICAgICAgYnJhbmNoX2Vycm9ycy5hcHBlbmQoZiJ7YnJhbmNoLmtleX06IGZhbGhhIGluZXNwZXJhZGEgKHtlfSkiKQoKICAgIGlmIG5vdCBoaXRzX2J5X2JyYW5jaDoKICAgICAgICByZXR1cm4gW10sIGJyYW5jaF9lcnJvcnMsIEZhbHNlLCBOb25lCgogICAgY2FuZGlkYXRlX3Bvb2wgPSBtaW4oUkVSQU5LX01BWF9DQU5ESURBVEVTLCBtYXgodG9wX2ssIHRvcF9rICogUkVSQU5LX0NBTkRJREFURV9NVUxUSVBMSUVSKSkKICAgIGZ1c2VkX2NhbmRpZGF0ZXMgPSBfcnJmX2Z1c2UoaGl0c19ieV9icmFuY2gsIGNhbmRpZGF0ZV9wb29sKQogICAgcmVyYW5rZWRfaGl0cywgcmVyYW5rX2FwcGxpZWQsIHJlcmFua19lcnJvciA9IF9hcHBseV9yZXJhbmsocXVlcnksIGZ1c2VkX2NhbmRpZGF0ZXMsIHRvcF9rKQogICAgcmV0dXJuIHJlcmFua2VkX2hpdHMsIGJyYW5jaF9lcnJvcnMsIHJlcmFua19hcHBsaWVkLCByZXJhbmtfZXJyb3IKCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIFNlcnZpZG9yIE1DUCB2aWEgRmFzdE1DUAojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKRk9SQ0VfU0VNQU5USUNfRkFMTEJBQ0sgPSAoCiAgICBvcy5lbnZpcm9uLmdldCgiTUNQX0ZPUkNFX1NFTUFOVElDX0ZBTExCQUNLIiwgInRydWUiKS5zdHJpcCgpLmxvd2VyKCkKICAgIGluIHsiMSIsICJ0cnVlIiwgInllcyIsICJvbiJ9CikKCgpkZWYgX2J1aWxkX3NlcnZlcl9pbnN0cnVjdGlvbnMoKSAtPiBzdHI6CiAgICBpbnN0cnVjdGlvbnMgPSAoCiAgICAgICAgIlNlcnZpZG9yIFJBRyBwYXJhIGJ1c2NhIHNlbcOibnRpY2EgZW0gY8OzZGlnby1mb250ZSBsb2NhbCBjb20gc3Vwb3J0ZSBhIGVuc2VtYmxlIGjDrWJyaWRvLiAiCiAgICAgICAgIk5vIG1vZG8gaHlicmlkLCBhIGJyYW5jaCBkZSBjw7NkaWdvIHVzYSBKaW5hIHYyIGUgYSBkZSBkb2N1bWVudGHDp8OjbyB1c2EgQkdFLiAiCiAgICAgICAgIlVzZSBzZW1hbnRpY19zZWFyY2hfY29kZShxdWVyeSwgdG9wX2ssIG1vZGU9J2Vuc2VtYmxlJykgcGFyYSBjb21iaW5hciBKaW5hK0JHRSBjb20gUlJGIGUgcmVyYW5raW5nLiAiCiAgICAgICAgIlVzZSB1cGRhdGVfZmlsZV9pbmRleCBhcMOzcyBlZGl0YXIgdW0gYXJxdWl2byBwYXJhIG1hbnRlciBhcyBkdWFzIGNvbGXDp8O1ZXMgc2luY3Jvbml6YWRhcy4gIgogICAgICAgICJVc2UgaW5kZXhfc3BlY2lmaWNfZm9sZGVyIHBhcmEgaW5kZXhhw6fDo28gcmVjdXJzaXZhIHNvYiBkZW1hbmRhLiIKICAgICkKICAgIGlmIEZPUkNFX1NFTUFOVElDX0ZBTExCQUNLOgogICAgICAgIGluc3RydWN0aW9ucyArPSAoCiAgICAgICAgICAgICIgUmVncmEgb2JyaWdhdMOzcmlhOiBxdWFuZG8gYSBwZXJndW50YSBtZW5jaW9uYXIgZnVuw6fDo28vY2xhc3NlL2NvbXBvbmVudGUvYXJxdWl2byAiCiAgICAgICAgICAgICJlIGlzc28gbsOjbyBlc3RpdmVyIG5vIGNvbnRleHRvIGltZWRpYXRvLCBjaGFtZSBzZW1hbnRpY19zZWFyY2hfY29kZShtb2RlPSdlbnNlbWJsZScpICIKICAgICAgICAgICAgImFudGVzIGRlIHJlc3BvbmRlciBxdWUgbsOjbyBlbmNvbnRyb3UuIFPDsyBjb25jbHVhIGF1c8OqbmNpYSBhcMOzcyBhbyBtZW5vcyB1bWEgYnVzY2Egc2Vtw6JudGljYS4iCiAgICAgICAgKQogICAgcmV0dXJuIGluc3RydWN0aW9ucwoKCm1jcCA9IEZhc3RNQ1AoCiAgICBuYW1lPSJyYWctY29kZWJhc2UiLAogICAgaW5zdHJ1Y3Rpb25zPV9idWlsZF9zZXJ2ZXJfaW5zdHJ1Y3Rpb25zKCksCikKCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIFRvb2wgMTogc2VtYW50aWNfc2VhcmNoX2NvZGUKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkBtY3AudG9vbCgpCmRlZiBzZW1hbnRpY19zZWFyY2hfY29kZShxdWVyeTogc3RyLCB0b3BfazogaW50ID0gVE9QX0tfUkVTVUxUUywgbW9kZTogc3RyID0gU0VBUkNIX01PREVfREVGQVVMVCkgLT4gc3RyOgogICAgIiIiCiAgICBCdXNjYSBzZW3Dom50aWNhIG5vIMOtbmRpY2UgdmV0b3JpYWwgbG9jYWwuCgogICAgTW9kb3M6CiAgICAtIHNpbmdsZTogdXNhIGFwZW5hcyB1bWEgYnJhbmNoIChKaW5hL0JHRSBjb25mb3JtZSBNQ1BfRU1CRURESU5HX01PREVMOyBubyBoeWJyaWQsIEppbmEgdjIpLgogICAgLSBlbnNlbWJsZTogY29uc3VsdGEgZW0gcGFyYWxlbG8gY29kZV92ZWN0b3JzX2ppbmEgKyBkb2NfdmVjdG9yc19iZ2UsCiAgICAgIGZheiBmdXPDo28gdmlhIFJlY2lwcm9jYWwgUmFuayBGdXNpb24gKFJSRikgZSByZXJhbmtpbmcgbGV2ZS4KCiAgICBBcmdzOgogICAgICAgIHF1ZXJ5OiBEZXNjcmnDp8OjbyBkbyBxdWUgcHJvY3VyYXIuCiAgICAgICAgdG9wX2s6IFF1YW50aWRhZGUgZmluYWwgZGUgcmVzdWx0YWRvcy4KICAgICAgICBtb2RlOiAic2luZ2xlIiAocGFkcsOjbykgb3UgImVuc2VtYmxlIi4KCiAgICBSZXR1cm5zOgogICAgICAgIFJlc3VsdGFkbyB0ZXh0dWFsIGZvcm1hdGFkbyBwYXJhIGNvbnN1bW8gcGVsbyBMTE0uCiAgICAiIiIKICAgIHJhd19xdWVyeSA9IChxdWVyeSBvciAiIikuc3RyaXAoKQogICAgc2VhcmNoX21vZGUgPSAobW9kZSBvciBTRUFSQ0hfTU9ERV9ERUZBVUxUKS5zdHJpcCgpLmxvd2VyKCkKCiAgICBfbG9nX3Rvb2xfdXNhZ2UoCiAgICAgICAgZXZlbnQ9InRvb2xfY2FsbF9zdGFydCIsCiAgICAgICAgdG9vbF9uYW1lPSJzZW1hbnRpY19zZWFyY2hfY29kZSIsCiAgICAgICAgZGV0YWlscz17CiAgICAgICAgICAgICJxdWVyeV9wcmV2aWV3IjogX3NhZmVfcHJldmlldyhyYXdfcXVlcnkpLAogICAgICAgICAgICAicXVlcnlfbGVuIjogbGVuKHJhd19xdWVyeSksCiAgICAgICAgICAgICJ0b3BfayI6IHRvcF9rLAogICAgICAgICAgICAibW9kZSI6IHNlYXJjaF9tb2RlLAogICAgICAgIH0sCiAgICApCgogICAgaWYgbm90IHJhd19xdWVyeToKICAgICAgICBfbG9nX3Rvb2xfdXNhZ2UoCiAgICAgICAgICAgIGV2ZW50PSJ0b29sX2NhbGxfZW5kIiwKICAgICAgICAgICAgdG9vbF9uYW1lPSJzZW1hbnRpY19zZWFyY2hfY29kZSIsCiAgICAgICAgICAgIGRldGFpbHM9eyJzdGF0dXMiOiAiZXJyb3IiLCAicmVhc29uIjogImVtcHR5X3F1ZXJ5In0sCiAgICAgICAgKQogICAgICAgIHJldHVybiAiRXJybzogYSBxdWVyeSBuw6NvIHBvZGUgc2VyIHZhemlhLiIKCiAgICB0b3BfayA9IG1heCgxLCBtaW4odG9wX2ssIDIwKSkKICAgIGlmIHNlYXJjaF9tb2RlIG5vdCBpbiB7InNpbmdsZSIsICJlbnNlbWJsZSJ9OgogICAgICAgIF9sb2dfdG9vbF91c2FnZSgKICAgICAgICAgICAgZXZlbnQ9InRvb2xfY2FsbF9lbmQiLAogICAgICAgICAgICB0b29sX25hbWU9InNlbWFudGljX3NlYXJjaF9jb2RlIiwKICAgICAgICAgICAgZGV0YWlscz17InN0YXR1cyI6ICJlcnJvciIsICJyZWFzb24iOiAiaW52YWxpZF9tb2RlIiwgIm1vZGUiOiBzZWFyY2hfbW9kZX0sCiAgICAgICAgKQogICAgICAgIHJldHVybiAiRXJybzogbW9kZSBpbnbDoWxpZG8uIFVzZSAnc2luZ2xlJyBvdSAnZW5zZW1ibGUnLiIKCiAgICB0cnk6CiAgICAgICAgaWYgc2VhcmNoX21vZGUgPT0gImVuc2VtYmxlIjoKICAgICAgICAgICAgaGl0cywgYnJhbmNoX2Vycm9ycywgcmVyYW5rX2FwcGxpZWQsIHJlcmFua19lcnJvciA9IF9ydW5fZW5zZW1ibGVfbW9kZShyYXdfcXVlcnksIHRvcF9rKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGhpdHMsIGJyYW5jaF9lcnJvcnMsIHJlcmFua19hcHBsaWVkLCByZXJhbmtfZXJyb3IgPSBfcnVuX3NpbmdsZV9tb2RlKHJhd19xdWVyeSwgdG9wX2spCgogICAgICAgIHJlc3VsdF90ZXh0ID0gX2Zvcm1hdF9mdXNlZF9yZXN1bHRzKAogICAgICAgICAgICBxdWVyeT1yYXdfcXVlcnksCiAgICAgICAgICAgIG1vZGU9c2VhcmNoX21vZGUsCiAgICAgICAgICAgIGhpdHM9aGl0cywKICAgICAgICAgICAgYnJhbmNoX2Vycm9ycz1icmFuY2hfZXJyb3JzLAogICAgICAgICAgICByZXJhbmtfYXBwbGllZD1yZXJhbmtfYXBwbGllZCwKICAgICAgICAgICAgcmVyYW5rX2Vycm9yPXJlcmFua19lcnJvciwKICAgICAgICApCgogICAgICAgIF9sb2dfdG9vbF91c2FnZSgKICAgICAgICAgICAgZXZlbnQ9InRvb2xfY2FsbF9lbmQiLAogICAgICAgICAgICB0b29sX25hbWU9InNlbWFudGljX3NlYXJjaF9jb2RlIiwKICAgICAgICAgICAgZGV0YWlscz17CiAgICAgICAgICAgICAgICAic3RhdHVzIjogIm9rIiwKICAgICAgICAgICAgICAgICJtb2RlIjogc2VhcmNoX21vZGUsCiAgICAgICAgICAgICAgICAicmVzdWx0X2NvdW50IjogbGVuKGhpdHMpLAogICAgICAgICAgICAgICAgImJyYW5jaF9lcnJvcnMiOiBsZW4oYnJhbmNoX2Vycm9ycyksCiAgICAgICAgICAgICAgICAicmVyYW5rX2FwcGxpZWQiOiByZXJhbmtfYXBwbGllZCwKICAgICAgICAgICAgfSwKICAgICAgICApCiAgICAgICAgcmV0dXJuIHJlc3VsdF90ZXh0CiAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgX2xvZ190b29sX3VzYWdlKAogICAgICAgICAgICBldmVudD0idG9vbF9jYWxsX2VuZCIsCiAgICAgICAgICAgIHRvb2xfbmFtZT0ic2VtYW50aWNfc2VhcmNoX2NvZGUiLAogICAgICAgICAgICBkZXRhaWxzPXsic3RhdHVzIjogImVycm9yIiwgInJlYXNvbiI6ICJzZWFyY2hfZmFpbGVkIiwgImVycm9yIjogc3RyKGUpLCAibW9kZSI6IHNlYXJjaF9tb2RlfSwKICAgICAgICApCiAgICAgICAgcmV0dXJuIGYiRXJybyBhbyBleGVjdXRhciBidXNjYSBzZW3Dom50aWNhICh7c2VhcmNoX21vZGV9KToge2V9IgoKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgVG9vbCAyOiB1cGRhdGVfZmlsZV9pbmRleAojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKQG1jcC50b29sKCkKZGVmIHVwZGF0ZV9maWxlX2luZGV4KGZpbGVfcGF0aDogc3RyKSAtPiBzdHI6CiAgICAiIiIKICAgIEF0dWFsaXphIG8gw61uZGljZSBSQUcgcGFyYSB1bSBhcnF1aXZvIGVzcGVjw61maWNvLgoKICAgIE8gYXJxdWl2byDDqSBjbGFzc2lmaWNhZG8gY29tbyBjw7NkaWdvL2RvYyBlIGluZGV4YWRvIG5hIGNvbGXDp8OjbyBhcHJvcHJpYWRhLgogICAgUGFyYSBleHRlbnPDtWVzIGFtYsOtZ3VhcywgaW5kZXhhIGVtIGFtYmFzIGFzIGNvbGXDp8O1ZXMuCiAgICAiIiIKICAgIGZpbGVwYXRoID0gUGF0aChmaWxlX3BhdGgpLnJlc29sdmUoKQogICAgYWJzX3BhdGggPSBzdHIoZmlsZXBhdGgpCgogICAgX2xvZ190b29sX3VzYWdlKAogICAgICAgIGV2ZW50PSJ0b29sX2NhbGxfc3RhcnQiLAogICAgICAgIHRvb2xfbmFtZT0idXBkYXRlX2ZpbGVfaW5kZXgiLAogICAgICAgIGRldGFpbHM9eyJmaWxlX3BhdGgiOiBhYnNfcGF0aH0sCiAgICApCgogICAgaWYgbm90IGZpbGVwYXRoLmV4aXN0cygpOgogICAgICAgIF9sb2dfdG9vbF91c2FnZSgKICAgICAgICAgICAgZXZlbnQ9InRvb2xfY2FsbF9lbmQiLAogICAgICAgICAgICB0b29sX25hbWU9InVwZGF0ZV9maWxlX2luZGV4IiwKICAgICAgICAgICAgZGV0YWlscz17InN0YXR1cyI6ICJlcnJvciIsICJyZWFzb24iOiAiZmlsZV9ub3RfZm91bmQiLCAiZmlsZV9wYXRoIjogYWJzX3BhdGh9LAogICAgICAgICkKICAgICAgICByZXR1cm4gZiJFcnJvOiBhcnF1aXZvIG7Do28gZW5jb250cmFkbzoge2ZpbGVwYXRofSIKCiAgICBpZiBub3QgZmlsZXBhdGguaXNfZmlsZSgpOgogICAgICAgIF9sb2dfdG9vbF91c2FnZSgKICAgICAgICAgICAgZXZlbnQ9InRvb2xfY2FsbF9lbmQiLAogICAgICAgICAgICB0b29sX25hbWU9InVwZGF0ZV9maWxlX2luZGV4IiwKICAgICAgICAgICAgZGV0YWlscz17InN0YXR1cyI6ICJlcnJvciIsICJyZWFzb24iOiAibm90X2FfZmlsZSIsICJmaWxlX3BhdGgiOiBhYnNfcGF0aH0sCiAgICAgICAgKQogICAgICAgIHJldHVybiBmIkVycm86IG8gY2FtaW5obyBuw6NvIGFwb250YSBwYXJhIHVtIGFycXVpdm86IHtmaWxlcGF0aH0iCgogICAgaWYgZmlsZXBhdGguc3RhdCgpLnN0X3NpemUgPiBNQVhfRklMRV9TSVpFX0JZVEVTOgogICAgICAgIF9sb2dfdG9vbF91c2FnZSgKICAgICAgICAgICAgZXZlbnQ9InRvb2xfY2FsbF9lbmQiLAogICAgICAgICAgICB0b29sX25hbWU9InVwZGF0ZV9maWxlX2luZGV4IiwKICAgICAgICAgICAgZGV0YWlscz17InN0YXR1cyI6ICJlcnJvciIsICJyZWFzb24iOiAiZmlsZV90b29fbGFyZ2UiLCAiZmlsZV9wYXRoIjogYWJzX3BhdGh9LAogICAgICAgICkKICAgICAgICByZXR1cm4gZiJFcnJvOiBhcnF1aXZvIG11aXRvIGdyYW5kZSAoPntNQVhfRklMRV9TSVpFX0JZVEVTIC8vIDEwMjR9S0IpOiB7ZmlsZXBhdGh9IgoKICAgIHNwbGl0dGVyID0gZ2V0X3NwbGl0dGVyKCkKICAgIHRhcmdldHMgPSBfY2xhc3NpZnlfZmlsZV90YXJnZXRzKGZpbGVwYXRoKQoKICAgIGRlbGV0ZWRfcGVyX2JyYW5jaCwgZGVsZXRpb25fZXJyb3JzID0gX3JlbW92ZV9maWxlX2Zyb21fYWxsX2NvbGxlY3Rpb25zKGFic19wYXRoKQoKICAgIGluc2VydGVkX3Blcl9icmFuY2g6IGRpY3Rbc3RyLCBpbnRdID0ge30KICAgIGluZGV4X2Vycm9yczogbGlzdFtzdHJdID0gW10KICAgIGZvciBicmFuY2ggaW4gdGFyZ2V0czoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGluc2VydGVkID0gX2luZGV4X3NpbmdsZV9maWxlX2Zvcl9icmFuY2goCiAgICAgICAgICAgICAgICBmaWxlcGF0aCwKICAgICAgICAgICAgICAgIGJyYW5jaCwKICAgICAgICAgICAgICAgIHNwbGl0dGVyLAogICAgICAgICAgICAgICAgZGVsZXRlX2V4aXN0aW5nPUZhbHNlLCAgIyBqw6EgcmVtb3ZpZG8gZW0gdG9kYXMgYXMgY29sZcOnw7VlcyBhY2ltYQogICAgICAgICAgICApCiAgICAgICAgICAgIGluc2VydGVkX3Blcl9icmFuY2hbYnJhbmNoLmtleV0gPSBpbnNlcnRlZAogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICAgICAgaW5kZXhfZXJyb3JzLmFwcGVuZChmInticmFuY2gua2V5fToge2V9IikKCiAgICBzdWNjZXNzX2JyYW5jaGVzID0gW2sgZm9yIGssIHYgaW4gaW5zZXJ0ZWRfcGVyX2JyYW5jaC5pdGVtcygpIGlmIHYgPiAwXQoKICAgIGRldGFpbHMgPSB7CiAgICAgICAgInN0YXR1cyI6ICJvayIgaWYgc3VjY2Vzc19icmFuY2hlcyBlbHNlICJlcnJvciIsCiAgICAgICAgImZpbGVfcGF0aCI6IGFic19wYXRoLAogICAgICAgICJ0YXJnZXRzIjogW2Iua2V5IGZvciBiIGluIHRhcmdldHNdLAogICAgICAgICJkZWxldGVkX3Blcl9icmFuY2giOiBkZWxldGVkX3Blcl9icmFuY2gsCiAgICAgICAgImluc2VydGVkX3Blcl9icmFuY2giOiBpbnNlcnRlZF9wZXJfYnJhbmNoLAogICAgICAgICJkZWxldGlvbl9lcnJvcnMiOiBsZW4oZGVsZXRpb25fZXJyb3JzKSwKICAgICAgICAiaW5kZXhfZXJyb3JzIjogbGVuKGluZGV4X2Vycm9ycyksCiAgICB9CiAgICBfbG9nX3Rvb2xfdXNhZ2UoZXZlbnQ9InRvb2xfY2FsbF9lbmQiLCB0b29sX25hbWU9InVwZGF0ZV9maWxlX2luZGV4IiwgZGV0YWlscz1kZXRhaWxzKQoKICAgIGlmIG5vdCBzdWNjZXNzX2JyYW5jaGVzIGFuZCBpbmRleF9lcnJvcnM6CiAgICAgICAgcmV0dXJuICgKICAgICAgICAgICAgIkVycm86IG7Do28gZm9pIHBvc3PDrXZlbCByZWluZGV4YXIgbyBhcnF1aXZvIGVtIG5lbmh1bWEgY29sZcOnw6NvLlxuIgogICAgICAgICAgICBmIkFycXVpdm86IHtmaWxlcGF0aH1cbiIKICAgICAgICAgICAgIkZhbGhhczogIiArICIgfCAiLmpvaW4oaW5kZXhfZXJyb3JzKQogICAgICAgICkKCiAgICBsaW5lcyA9IFsKICAgICAgICAiQXJxdWl2byByZWluZGV4YWRvLiIsCiAgICAgICAgZiIgIEFycXVpdm8gOiB7ZmlsZXBhdGh9IiwKICAgICAgICBmIiAgQ29sZcOnw7VlcyBhbHZvOiB7W2IuY29sbGVjdGlvbl9uYW1lIGZvciBiIGluIHRhcmdldHNdfSIsCiAgICAgICAgZiIgIFJlbW/Dp8O1ZXMgcG9yIGNvbGXDp8Ojbzoge2RlbGV0ZWRfcGVyX2JyYW5jaH0iLAogICAgICAgIGYiICBJbnNlcsOnw7VlcyBwb3IgY29sZcOnw6NvOiB7aW5zZXJ0ZWRfcGVyX2JyYW5jaH0iLAogICAgXQogICAgaWYgZGVsZXRpb25fZXJyb3JzOgogICAgICAgIGxpbmVzLmFwcGVuZCgiICBBdmlzb3MgbmEgcmVtb8Onw6NvOiAiICsgIiB8ICIuam9pbihkZWxldGlvbl9lcnJvcnMpKQogICAgaWYgaW5kZXhfZXJyb3JzOgogICAgICAgIGxpbmVzLmFwcGVuZCgiICBBdmlzb3MgbmEgaW5kZXhhw6fDo286ICIgKyAiIHwgIi5qb2luKGluZGV4X2Vycm9ycykpCiAgICByZXR1cm4gIlxuIi5qb2luKGxpbmVzKQoKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgVG9vbCAzOiBkZWxldGVfZmlsZV9pbmRleAojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKQG1jcC50b29sKCkKZGVmIGRlbGV0ZV9maWxlX2luZGV4KGZpbGVfcGF0aDogc3RyKSAtPiBzdHI6CiAgICAiIiIKICAgIFJlbW92ZSB1bSBhcnF1aXZvIGRvIMOtbmRpY2UgZW0gdG9kYXMgYXMgY29sZcOnw7VlcyBnZXJlbmNpYWRhcy4KICAgICIiIgogICAgZmlsZXBhdGggPSBQYXRoKGZpbGVfcGF0aCkucmVzb2x2ZSgpCiAgICBhYnNfcGF0aCA9IHN0cihmaWxlcGF0aCkKCiAgICBfbG9nX3Rvb2xfdXNhZ2UoCiAgICAgICAgZXZlbnQ9InRvb2xfY2FsbF9zdGFydCIsCiAgICAgICAgdG9vbF9uYW1lPSJkZWxldGVfZmlsZV9pbmRleCIsCiAgICAgICAgZGV0YWlscz17ImZpbGVfcGF0aCI6IGFic19wYXRofSwKICAgICkKCiAgICBkZWxldGVkX3Blcl9icmFuY2gsIGVycm9ycyA9IF9yZW1vdmVfZmlsZV9mcm9tX2FsbF9jb2xsZWN0aW9ucyhhYnNfcGF0aCkKICAgIHRvdGFsX2RlbGV0ZWQgPSBzdW0oZGVsZXRlZF9wZXJfYnJhbmNoLnZhbHVlcygpKQoKICAgIF9sb2dfdG9vbF91c2FnZSgKICAgICAgICBldmVudD0idG9vbF9jYWxsX2VuZCIsCiAgICAgICAgdG9vbF9uYW1lPSJkZWxldGVfZmlsZV9pbmRleCIsCiAgICAgICAgZGV0YWlscz17CiAgICAgICAgICAgICJzdGF0dXMiOiAib2siIGlmIHRvdGFsX2RlbGV0ZWQgPiAwIGVsc2UgIndhcm5pbmciLAogICAgICAgICAgICAiZmlsZV9wYXRoIjogYWJzX3BhdGgsCiAgICAgICAgICAgICJkZWxldGVkX3Blcl9icmFuY2giOiBkZWxldGVkX3Blcl9icmFuY2gsCiAgICAgICAgICAgICJlcnJvcnMiOiBsZW4oZXJyb3JzKSwKICAgICAgICB9LAogICAgKQoKICAgIGlmIHRvdGFsX2RlbGV0ZWQgPT0gMDoKICAgICAgICBiYXNlID0gZiJOZW5odW0gY2h1bmsgZW5jb250cmFkbyBwYXJhIG8gYXJxdWl2bzoge2Fic19wYXRofSIKICAgICAgICBpZiBlcnJvcnM6CiAgICAgICAgICAgIGJhc2UgKz0gIlxuRmFsaGFzIHBhcmNpYWlzOiAiICsgIiB8ICIuam9pbihlcnJvcnMpCiAgICAgICAgcmV0dXJuIGJhc2UKCiAgICBvdXQgPSBbCiAgICAgICAgIlJlbW92aWRvIGRvIMOtbmRpY2UgY29tIHN1Y2Vzc28uIiwKICAgICAgICBmIiAgQXJxdWl2byA6IHthYnNfcGF0aH0iLAogICAgICAgIGYiICBEZWxlw6fDtWVzIHBvciBjb2xlw6fDo286IHtkZWxldGVkX3Blcl9icmFuY2h9IiwKICAgIF0KICAgIGlmIGVycm9yczoKICAgICAgICBvdXQuYXBwZW5kKCIgIEF2aXNvczogIiArICIgfCAiLmpvaW4oZXJyb3JzKSkKICAgIHJldHVybiAiXG4iLmpvaW4ob3V0KQoKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgVG9vbCA0OiBpbmRleF9zcGVjaWZpY19mb2xkZXIKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkBtY3AudG9vbCgpCmRlZiBpbmRleF9zcGVjaWZpY19mb2xkZXIoZm9sZGVyX3BhdGg6IHN0cikgLT4gc3RyOgogICAgIiIiCiAgICBJbmRleGEgcmVjdXJzaXZhbWVudGUgdW1hIHBhc3RhIGVtIGNvbGXDp8O1ZXMgc2VwYXJhZGFzIHBvciBkb23DrW5pby4KICAgICIiIgogICAgZm9sZGVyID0gUGF0aChmb2xkZXJfcGF0aCkucmVzb2x2ZSgpCgogICAgX2xvZ190b29sX3VzYWdlKAogICAgICAgIGV2ZW50PSJ0b29sX2NhbGxfc3RhcnQiLAogICAgICAgIHRvb2xfbmFtZT0iaW5kZXhfc3BlY2lmaWNfZm9sZGVyIiwKICAgICAgICBkZXRhaWxzPXsiZm9sZGVyX3BhdGgiOiBzdHIoZm9sZGVyKX0sCiAgICApCgogICAgaWYgbm90IGZvbGRlci5leGlzdHMoKToKICAgICAgICBfbG9nX3Rvb2xfdXNhZ2UoCiAgICAgICAgICAgIGV2ZW50PSJ0b29sX2NhbGxfZW5kIiwKICAgICAgICAgICAgdG9vbF9uYW1lPSJpbmRleF9zcGVjaWZpY19mb2xkZXIiLAogICAgICAgICAgICBkZXRhaWxzPXsic3RhdHVzIjogImVycm9yIiwgInJlYXNvbiI6ICJmb2xkZXJfbm90X2ZvdW5kIiwgImZvbGRlcl9wYXRoIjogc3RyKGZvbGRlcil9LAogICAgICAgICkKICAgICAgICByZXR1cm4gZiJFcnJvOiBwYXN0YSBuw6NvIGVuY29udHJhZGE6IHtmb2xkZXJ9IgoKICAgIGlmIG5vdCBmb2xkZXIuaXNfZGlyKCk6CiAgICAgICAgX2xvZ190b29sX3VzYWdlKAogICAgICAgICAgICBldmVudD0idG9vbF9jYWxsX2VuZCIsCiAgICAgICAgICAgIHRvb2xfbmFtZT0iaW5kZXhfc3BlY2lmaWNfZm9sZGVyIiwKICAgICAgICAgICAgZGV0YWlscz17InN0YXR1cyI6ICJlcnJvciIsICJyZWFzb24iOiAibm90X2FfZm9sZGVyIiwgImZvbGRlcl9wYXRoIjogc3RyKGZvbGRlcil9LAogICAgICAgICkKICAgICAgICByZXR1cm4gZiJFcnJvOiBvIGNhbWluaG8gbsOjbyDDqSB1bSBkaXJldMOzcmlvOiB7Zm9sZGVyfSIKCiAgICBzcGxpdHRlciA9IGdldF9zcGxpdHRlcigpCgogICAgcHJvY2Vzc2VkX2ZpbGVzID0gMAogICAgYnJhbmNoX2ZpbGVfY291bnRzID0ge2tleTogMCBmb3Iga2V5IGluIEJSQU5DSF9TUEVDU30KICAgIGJyYW5jaF9jaHVua19jb3VudHMgPSB7a2V5OiAwIGZvciBrZXkgaW4gQlJBTkNIX1NQRUNTfQogICAgZXJyb3JfY291bnQgPSAwCiAgICBlcnJvcl9zYW1wbGVzOiBsaXN0W3N0cl0gPSBbXQoKICAgIGZvciBmaWxlcGF0aCBpbiBfc2Nhbl9mb2xkZXIoZm9sZGVyKToKICAgICAgICBwcm9jZXNzZWRfZmlsZXMgKz0gMQogICAgICAgIHRhcmdldHMgPSBfY2xhc3NpZnlfZmlsZV90YXJnZXRzKGZpbGVwYXRoKQoKICAgICAgICBmb3IgYnJhbmNoIGluIHRhcmdldHM6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIG5fY2h1bmtzID0gX2luZGV4X3NpbmdsZV9maWxlX2Zvcl9icmFuY2goZmlsZXBhdGgsIGJyYW5jaCwgc3BsaXR0ZXIpCiAgICAgICAgICAgICAgICBicmFuY2hfZmlsZV9jb3VudHNbYnJhbmNoLmtleV0gKz0gMQogICAgICAgICAgICAgICAgYnJhbmNoX2NodW5rX2NvdW50c1ticmFuY2gua2V5XSArPSBuX2NodW5rcwogICAgICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgICAgICAgICBlcnJvcl9jb3VudCArPSAxCiAgICAgICAgICAgICAgICBpZiBsZW4oZXJyb3Jfc2FtcGxlcykgPCAxMDoKICAgICAgICAgICAgICAgICAgICBlcnJvcl9zYW1wbGVzLmFwcGVuZChmIntmaWxlcGF0aC5uYW1lfSBbe2JyYW5jaC5rZXl9XToge2V9IikKCiAgICBpZiBwcm9jZXNzZWRfZmlsZXMgPT0gMDoKICAgICAgICBfbG9nX3Rvb2xfdXNhZ2UoCiAgICAgICAgICAgIGV2ZW50PSJ0b29sX2NhbGxfZW5kIiwKICAgICAgICAgICAgdG9vbF9uYW1lPSJpbmRleF9zcGVjaWZpY19mb2xkZXIiLAogICAgICAgICAgICBkZXRhaWxzPXsic3RhdHVzIjogIm9rIiwgImZvbGRlcl9wYXRoIjogc3RyKGZvbGRlciksICJmaWxlc19wcm9jZXNzZWQiOiAwLCAiY2h1bmtzIjogMCwgImVycm9ycyI6IDB9LAogICAgICAgICkKICAgICAgICByZXR1cm4gZiJOZW5odW0gYXJxdWl2byBpbmRleMOhdmVsIGVuY29udHJhZG8gZW06IHtmb2xkZXJ9IgoKICAgIHRvdGFsX2NodW5rcyA9IHN1bShicmFuY2hfY2h1bmtfY291bnRzLnZhbHVlcygpKQoKICAgIF9sb2dfdG9vbF91c2FnZSgKICAgICAgICBldmVudD0idG9vbF9jYWxsX2VuZCIsCiAgICAgICAgdG9vbF9uYW1lPSJpbmRleF9zcGVjaWZpY19mb2xkZXIiLAogICAgICAgIGRldGFpbHM9ewogICAgICAgICAgICAic3RhdHVzIjogIm9rIiwKICAgICAgICAgICAgImZvbGRlcl9wYXRoIjogc3RyKGZvbGRlciksCiAgICAgICAgICAgICJmaWxlc19wcm9jZXNzZWQiOiBwcm9jZXNzZWRfZmlsZXMsCiAgICAgICAgICAgICJjaHVua3MiOiB0b3RhbF9jaHVua3MsCiAgICAgICAgICAgICJlcnJvcnMiOiBlcnJvcl9jb3VudCwKICAgICAgICAgICAgImJyYW5jaF9maWxlX2NvdW50cyI6IGJyYW5jaF9maWxlX2NvdW50cywKICAgICAgICAgICAgImJyYW5jaF9jaHVua19jb3VudHMiOiBicmFuY2hfY2h1bmtfY291bnRzLAogICAgICAgIH0sCiAgICApCgogICAgcmVwb3J0ID0gWwogICAgICAgICJJbmRleGHDp8OjbyBkYSBwYXN0YSBjb25jbHXDrWRhLiIsCiAgICAgICAgZiIgIFBhc3RhOiB7Zm9sZGVyfSIsCiAgICAgICAgZiIgIEFycXVpdm9zIHByb2Nlc3NhZG9zOiB7cHJvY2Vzc2VkX2ZpbGVzfSIsCiAgICAgICAgZiIgIFRvdGFsIGRlIGNodW5rczoge3RvdGFsX2NodW5rc30iLAogICAgICAgIGYiICBBcnF1aXZvcyBwb3IgYnJhbmNoOiB7YnJhbmNoX2ZpbGVfY291bnRzfSIsCiAgICAgICAgZiIgIENodW5rcyBwb3IgYnJhbmNoOiB7YnJhbmNoX2NodW5rX2NvdW50c30iLAogICAgXQoKICAgIGlmIGVycm9yX2NvdW50OgogICAgICAgIHJlcG9ydC5hcHBlbmQoZiIgIEVycm9zICh7ZXJyb3JfY291bnR9KToiKQogICAgICAgIGZvciBlcnIgaW4gZXJyb3Jfc2FtcGxlczoKICAgICAgICAgICAgcmVwb3J0LmFwcGVuZChmIiAgICAtIHtlcnJ9IikKICAgICAgICBpZiBlcnJvcl9jb3VudCA+IGxlbihlcnJvcl9zYW1wbGVzKToKICAgICAgICAgICAgcmVwb3J0LmFwcGVuZChmIiAgICAuLi4gZSBtYWlzIHtlcnJvcl9jb3VudCAtIGxlbihlcnJvcl9zYW1wbGVzKX0gZXJyb3MuIikKCiAgICByZXR1cm4gIlxuIi5qb2luKHJlcG9ydCkKCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIFBvbnRvIGRlIGVudHJhZGEKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICBsb2cuaW5mbygiSW5pY2lhbmRvIHNlcnZpZG9yIE1DUCBSQUcgKHN0ZGlvKS4uLiIpCiAgICBsb2cuaW5mbygiQ2hyb21hREI6ICVzOi8vJXM6JXMiLCBDSFJPTUFfU0NIRU1FLCBDSFJPTUFfSE9TVCwgQ0hST01BX1BPUlQpCiAgICBsb2cuaW5mbygKICAgICAgICAiQ29sZcOnw7VlczogJXMgKCVzKSwgJXMgKCVzKSIsCiAgICAgICAgQ09MTEVDVElPTl9DT0RFX0pJTkEsCiAgICAgICAgQlJBTkNIX1NQRUNTWyJqaW5hX2NvZGUiXS5tb2RlbF9pZCwKICAgICAgICBDT0xMRUNUSU9OX0RPQ19CR0UsCiAgICAgICAgQlJBTkNIX1NQRUNTWyJiZ2VfZG9jIl0ubW9kZWxfaWQsCiAgICApCiAgICBsb2cuaW5mbygiTW9kbyBwYWRyw6NvIGRlIGJ1c2NhOiAlcyIsIFNFQVJDSF9NT0RFX0RFRkFVTFQpCiAgICBsb2cuaW5mbygiTW9kZWxvIHNpbmdsZSBwYWRyw6NvOiAlcyIsIEJSQU5DSF9TUEVDU1tERUZBVUxUX1NJTkdMRV9CUkFOQ0hfS0VZXS5tb2RlbF9pZCkKICAgIGxvZy5pbmZvKCJRdWFudGl6YWNhbyBKaW5hOiAlcyIsIEpJTkFfUVVBTlRJWkFUSU9OKQogICAgbG9nLmluZm8oIkNvbmZpZyBkZSB0dW5pbmcgY2FycmVnYWRhIGRlOiAlcyAoZm91bmQ9JXMpIiwgSU5ERVhFUl9DT05GSUdfUEFUSCwgYm9vbChJTkRFWEVSX1RVTklOR19DT05GSUcpKQogICAgbG9nLmluZm8oIkVtYmVkZGluZyBiYXRjaCBzaXplOiAlcyIsIEVNQkVERElOR19CQVRDSF9TSVpFKQogICAgbG9nLmluZm8oIkNodW5rIHBhcmFtczogc2l6ZT0lcyBvdmVybGFwPSVzIiwgQ0hVTktfU0laRSwgQ0hVTktfT1ZFUkxBUCkKICAgIGxvZy5pbmZvKCJSZXJhbmtlcjogJXMgKGVuYWJsZWQ9JXMsIHF1YW50PSVzKSIsIFJFUkFOS19NT0RFTF9JRCwgUkVSQU5LX0VOQUJMRUQsIFJFUkFOS0VSX1FVQU5USVpBVElPTikKICAgIGxvZy5pbmZvKCJQYXN0YSBkZSBtb2RlbG9zIGxvY2FpczogJXMiLCBNT0RFTF9ESVIpCiAgICBsb2cuaW5mbygiVXNvIE1DUCBzZXLDoSByZWdpc3RyYWRvIGVtOiAlcyIsIE1DUF9VU0FHRV9MT0dfUEFUSCkKCiAgICAjIFByw6ktYXF1ZWNlIHNvbWVudGUgY29uZXjDo28gQ2hyb21hOyBtb2RlbG9zIGZpY2FtIGxhenkgcGFyYSBwb3VwYXIgUkFNLgogICAgdHJ5OgogICAgICAgIF9nZXRfY2hyb21hX2NsaWVudCgpCiAgICAgICAgZ2V0X2Nocm9tYV9jb2xsZWN0aW9uKENPTExFQ1RJT05fQ09ERV9KSU5BKQogICAgICAgIGdldF9jaHJvbWFfY29sbGVjdGlvbihDT0xMRUNUSU9OX0RPQ19CR0UpCiAgICAgICAgbG9nLmluZm8oIkNvbmV4w6NvIENocm9tYSBpbmljaWFsaXphZGEuIE1vZGVsb3Mgc2Vyw6NvIGNhcnJlZ2Fkb3Mgc29iIGRlbWFuZGEuIikKICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICBsb2cuZXJyb3IoIkZhbGhhIGFvIGluaWNpYWxpemFyIENocm9tYURCOiAlcyIsIGUpCiAgICAgICAgbG9nLmVycm9yKCJPIHNlcnZpZG9yIGNvbnRpbnVhcsOhLCBtYXMgYXMgZmVycmFtZW50YXMgcmV0b3JuYXLDo28gZXJybyBhdMOpIG8gQ2hyb21hREIgZXN0YXIgZGlzcG9uw612ZWwuIikKCiAgICBtY3AucnVuKHRyYW5zcG9ydD0ic3RkaW8iKQo="
|
|
727
|
+
B64_INDEXER="IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwoiIiIKaW5kZXhlcl9mdWxsLnB5IOKAlCBTY3JpcHQgc3RhbmRhbG9uZSBkZSBpbmRleGHDp8OjbyBkbyBSQUcgbG9jYWwuCgpVc286CiAgICBweXRob24gaW5kZXhlcl9mdWxsLnB5IFtjYW1pbmhvX2RvX3Byb2pldG9dCgpTZSBuZW5odW0gY2FtaW5obyBmb3IgcGFzc2FkbywgdXNhIG8gZGlyZXTDs3JpbyBhdHVhbC4KTyBDaHJvbWFEQiBkZXZlIGVzdGFyIHJvZGFuZG8gdmlhIERvY2tlciBlbSBsb2NhbGhvc3Q6ODAwMC4KIiIiCgppbXBvcnQgb3MKaW1wb3J0IHN5cwppbXBvcnQgaGFzaGxpYgppbXBvcnQgYXJncGFyc2UKaW1wb3J0IHNodXRpbAppbXBvcnQgbG9nZ2luZwppbXBvcnQgZ2MKaW1wb3J0IGpzb24KZnJvbSB0aW1lIGltcG9ydCBwZXJmX2NvdW50ZXIsIHRpbWUKZnJvbSBjb2xsZWN0aW9ucy5hYmMgaW1wb3J0IEl0ZXJhdG9yCmZyb20gcGF0aGxpYiBpbXBvcnQgUGF0aApmcm9tIGRhdGFjbGFzc2VzIGltcG9ydCBkYXRhY2xhc3MKZnJvbSBkYXRldGltZSBpbXBvcnQgZGF0ZXRpbWUKZnJvbSB1cmxsaWIucGFyc2UgaW1wb3J0IHVybHBhcnNlCgojIEV2aXRhIGF2aXNvcyAiYWR2aXNvcnkiIHJ1aWRvc29zIGRvIHRyYW5zZm9ybWVycyBubyBmbHV4byBpbnRlcmF0aXZvLgpvcy5lbnZpcm9uLnNldGRlZmF1bHQoIlRSQU5TRk9STUVSU19OT19BRFZJU09SWV9XQVJOSU5HUyIsICIxIikKCgpjbGFzcyBfVG9yY2hEdHlwZVdhcm5pbmdGaWx0ZXIobG9nZ2luZy5GaWx0ZXIpOgogICAgZGVmIGZpbHRlcihzZWxmLCByZWNvcmQ6IGxvZ2dpbmcuTG9nUmVjb3JkKSAtPiBib29sOgogICAgICAgIHJldHVybiAiYHRvcmNoX2R0eXBlYCBpcyBkZXByZWNhdGVkISBVc2UgYGR0eXBlYCBpbnN0ZWFkISIgbm90IGluIHJlY29yZC5nZXRNZXNzYWdlKCkKCgpmb3IgX2xvZ2dlcl9uYW1lIGluICgidHJhbnNmb3JtZXJzLmNvbmZpZ3VyYXRpb25fdXRpbHMiLCAidHJhbnNmb3JtZXJzLm1vZGVsaW5nX3V0aWxzIik6CiAgICBsb2dnaW5nLmdldExvZ2dlcihfbG9nZ2VyX25hbWUpLmFkZEZpbHRlcihfVG9yY2hEdHlwZVdhcm5pbmdGaWx0ZXIoKSkKCmltcG9ydCBjaHJvbWFkYgpmcm9tIHNlbnRlbmNlX3RyYW5zZm9ybWVycyBpbXBvcnQgU2VudGVuY2VUcmFuc2Zvcm1lcgpmcm9tIGxhbmdjaGFpbl90ZXh0X3NwbGl0dGVycyBpbXBvcnQgUmVjdXJzaXZlQ2hhcmFjdGVyVGV4dFNwbGl0dGVyCmZyb20gdHFkbSBpbXBvcnQgdHFkbQpmcm9tIGRvd25sb2FkX21vZGVsX2Zyb21faHVnZ2luZmFjZSBpbXBvcnQgZG93bmxvYWRfbW9kZWxfd2l0aF9mYWxsYmFjawoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBDb25maWd1cmHDp8O1ZXMgZ2xvYmFpcwojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCmRlZiBfZW52X2ludChuYW1lOiBzdHIsIGRlZmF1bHQ6IGludCwgKiwgbWluX3ZhbHVlOiBpbnQgPSAxKSAtPiBpbnQ6CiAgICByYXcgPSBvcy5lbnZpcm9uLmdldChuYW1lKQogICAgaWYgcmF3IGlzIE5vbmU6CiAgICAgICAgcmV0dXJuIG1heChtaW5fdmFsdWUsIGRlZmF1bHQpCiAgICB0cnk6CiAgICAgICAgcmV0dXJuIG1heChtaW5fdmFsdWUsIGludChyYXcpKQogICAgZXhjZXB0IFZhbHVlRXJyb3I6CiAgICAgICAgcmV0dXJuIG1heChtaW5fdmFsdWUsIGRlZmF1bHQpCgoKZGVmIF9lbnZfc3RyKG5hbWU6IHN0ciwgZGVmYXVsdDogc3RyKSAtPiBzdHI6CiAgICByYXcgPSBvcy5lbnZpcm9uLmdldChuYW1lKQogICAgaWYgcmF3IGlzIE5vbmU6CiAgICAgICAgcmV0dXJuIGRlZmF1bHQKICAgIHN0cmlwcGVkID0gcmF3LnN0cmlwKCkKICAgIHJldHVybiBzdHJpcHBlZCBpZiBzdHJpcHBlZCBlbHNlIGRlZmF1bHQKCgpkZWYgX3BhcnNlX3Bvc2l0aXZlX2ludChyYXc6IG9iamVjdCwgKiwgbWluX3ZhbHVlOiBpbnQgPSAxKSAtPiBpbnQgfCBOb25lOgogICAgdHJ5OgogICAgICAgIHBhcnNlZCA9IGludChzdHIocmF3KS5zdHJpcCgpKQogICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICByZXR1cm4gTm9uZQogICAgaWYgcGFyc2VkIDwgbWluX3ZhbHVlOgogICAgICAgIHJldHVybiBOb25lCiAgICByZXR1cm4gcGFyc2VkCgoKT1dOX1JBR19DTElfQ09ORklHX1BBVEggPSBQYXRoKAogICAgb3MuZW52aXJvbi5nZXQoIk9XTl9SQUdfQ0xJX0NPTkZJR19GSUxFIiwgc3RyKFBhdGguaG9tZSgpIC8gIi5vd24tcmFnLWNsaS5qc29uIikpCikuZXhwYW5kdXNlcigpCgoKZGVmIF9sb2FkX293bl9yYWdfY2xpX2NvbmZpZ19wYXlsb2FkKCkgLT4gZGljdFtzdHIsIG9iamVjdF06CiAgICB0cnk6CiAgICAgICAgaWYgbm90IE9XTl9SQUdfQ0xJX0NPTkZJR19QQVRILmV4aXN0cygpOgogICAgICAgICAgICByZXR1cm4ge30KICAgICAgICBwYXlsb2FkID0ganNvbi5sb2FkcyhPV05fUkFHX0NMSV9DT05GSUdfUEFUSC5yZWFkX3RleHQoZW5jb2Rpbmc9InV0Zi04IikpCiAgICAgICAgcmV0dXJuIHBheWxvYWQgaWYgaXNpbnN0YW5jZShwYXlsb2FkLCBkaWN0KSBlbHNlIHt9CiAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgIHJldHVybiB7fQoKCmRlZiBfZXh0cmFjdF9jaHJvbWFfZW5kcG9pbnRfZnJvbV9jb25maWcoY29uZmlnX3BheWxvYWQ6IG9iamVjdCkgLT4gdHVwbGVbc3RyLCBzdHIsIGludF06CiAgICBzY2hlbWUgPSAiaHR0cCIKICAgIGhvc3QgPSAibG9jYWxob3N0IgogICAgcG9ydCA9IDgwMDAKCiAgICBkZWYgX3JlYWRfc2NoZW1lKHJhdzogb2JqZWN0KSAtPiBOb25lOgogICAgICAgIG5vbmxvY2FsIHNjaGVtZQogICAgICAgIGlmIG5vdCBpc2luc3RhbmNlKHJhdywgc3RyKToKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgbG93ZXJlZCA9IHJhdy5zdHJpcCgpLmxvd2VyKCkKICAgICAgICBpZiBsb3dlcmVkIGluIHsiaHR0cCIsICJodHRwcyJ9OgogICAgICAgICAgICBzY2hlbWUgPSBsb3dlcmVkCgogICAgZGVmIF9yZWFkX2hvc3QocmF3OiBvYmplY3QpIC0+IE5vbmU6CiAgICAgICAgbm9ubG9jYWwgc2NoZW1lLCBob3N0LCBwb3J0CiAgICAgICAgaWYgbm90IGlzaW5zdGFuY2UocmF3LCBzdHIpOgogICAgICAgICAgICByZXR1cm4KICAgICAgICBjYW5kaWRhdGUgPSByYXcuc3RyaXAoKQogICAgICAgIGlmIG5vdCBjYW5kaWRhdGU6CiAgICAgICAgICAgIHJldHVybgogICAgICAgIHBhcnNlZCA9IHVybHBhcnNlKGNhbmRpZGF0ZSBpZiAiOi8vIiBpbiBjYW5kaWRhdGUgZWxzZSBmIi8ve2NhbmRpZGF0ZX0iKQogICAgICAgIGlmIHBhcnNlZC5zY2hlbWUgaW4geyJodHRwIiwgImh0dHBzIn06CiAgICAgICAgICAgIHNjaGVtZSA9IHBhcnNlZC5zY2hlbWUKICAgICAgICBpZiBwYXJzZWQuaG9zdG5hbWU6CiAgICAgICAgICAgIGhvc3QgPSBwYXJzZWQuaG9zdG5hbWUKICAgICAgICBlbGlmICI6Ly8iIG5vdCBpbiBjYW5kaWRhdGU6CiAgICAgICAgICAgIGhvc3QgPSBjYW5kaWRhdGUuc3RyaXAoKS5zdHJpcCgiLyIpCiAgICAgICAgaWYgcGFyc2VkLnBvcnQgYW5kIDEgPD0gcGFyc2VkLnBvcnQgPD0gNjU1MzU6CiAgICAgICAgICAgIHBvcnQgPSBwYXJzZWQucG9ydAoKICAgIGRlZiBfcmVhZF9wb3J0KHJhdzogb2JqZWN0KSAtPiBOb25lOgogICAgICAgIG5vbmxvY2FsIHBvcnQKICAgICAgICB0cnk6CiAgICAgICAgICAgIHBhcnNlZCA9IGludChzdHIocmF3KS5zdHJpcCgpKQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgICAgIHJldHVybgogICAgICAgIGlmIDEgPD0gcGFyc2VkIDw9IDY1NTM1OgogICAgICAgICAgICBwb3J0ID0gcGFyc2VkCgogICAgaWYgaXNpbnN0YW5jZShjb25maWdfcGF5bG9hZCwgZGljdCk6CiAgICAgICAgY2hyb21hX29iaiA9IGNvbmZpZ19wYXlsb2FkLmdldCgiY2hyb21hIikKICAgICAgICBpZiBpc2luc3RhbmNlKGNocm9tYV9vYmosIGRpY3QpOgogICAgICAgICAgICBfcmVhZF9zY2hlbWUoY2hyb21hX29iai5nZXQoInNjaGVtZSIpKQogICAgICAgICAgICBfcmVhZF9ob3N0KGNocm9tYV9vYmouZ2V0KCJob3N0IikpCiAgICAgICAgICAgIF9yZWFkX3BvcnQoY2hyb21hX29iai5nZXQoInBvcnQiKSkKCiAgICAgICAgIyBDb21wYXRpYmlsaWRhZGUgY29tIGZvcm1hdG9zIGZsYXQgYW50aWdvcy4KICAgICAgICBfcmVhZF9zY2hlbWUoY29uZmlnX3BheWxvYWQuZ2V0KCJDSFJPTUFfU0NIRU1FIikpCiAgICAgICAgX3JlYWRfaG9zdChjb25maWdfcGF5bG9hZC5nZXQoIkNIUk9NQV9IT1NUIikpCiAgICAgICAgX3JlYWRfcG9ydChjb25maWdfcGF5bG9hZC5nZXQoIkNIUk9NQV9QT1JUIikpCgogICAgcmV0dXJuIHNjaGVtZSwgaG9zdCwgcG9ydAoKCmRlZiBfZXh0cmFjdF9lbWJlZGRpbmdfYmF0Y2hfZnJvbV9jb25maWcoY29uZmlnX3BheWxvYWQ6IG9iamVjdCkgLT4gaW50IHwgTm9uZToKICAgIGlmIG5vdCBpc2luc3RhbmNlKGNvbmZpZ19wYXlsb2FkLCBkaWN0KToKICAgICAgICByZXR1cm4gTm9uZQoKICAgIGluZGV4aW5nID0gY29uZmlnX3BheWxvYWQuZ2V0KCJpbmRleGluZyIpCiAgICBpZiBpc2luc3RhbmNlKGluZGV4aW5nLCBkaWN0KToKICAgICAgICBmb3Iga2V5IGluICgiZW1iZWRkaW5nX2JhdGNoX3NpemUiLCAiYmF0Y2hfY291bnQiKToKICAgICAgICAgICAgcGFyc2VkID0gX3BhcnNlX3Bvc2l0aXZlX2ludChpbmRleGluZy5nZXQoa2V5KSwgbWluX3ZhbHVlPTEpCiAgICAgICAgICAgIGlmIHBhcnNlZCBpcyBub3QgTm9uZToKICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZWQKCiAgICBmb3Iga2V5IGluICgiTUNQX0VNQkVERElOR19CQVRDSF9TSVpFIiwgImVtYmVkZGluZ19iYXRjaF9zaXplIiwgImJhdGNoX2NvdW50Iik6CiAgICAgICAgcGFyc2VkID0gX3BhcnNlX3Bvc2l0aXZlX2ludChjb25maWdfcGF5bG9hZC5nZXQoa2V5KSwgbWluX3ZhbHVlPTEpCiAgICAgICAgaWYgcGFyc2VkIGlzIG5vdCBOb25lOgogICAgICAgICAgICByZXR1cm4gcGFyc2VkCiAgICByZXR1cm4gTm9uZQoKCmRlZiBfbG9hZF9jbGlfY2hyb21hX2RlZmF1bHRzKCkgLT4gdHVwbGVbc3RyLCBzdHIsIGludF06CiAgICBwYXlsb2FkID0gX2xvYWRfb3duX3JhZ19jbGlfY29uZmlnX3BheWxvYWQoKQogICAgaWYgbm90IHBheWxvYWQ6CiAgICAgICAgcmV0dXJuICgiaHR0cCIsICJsb2NhbGhvc3QiLCA4MDAwKQogICAgcmV0dXJuIF9leHRyYWN0X2Nocm9tYV9lbmRwb2ludF9mcm9tX2NvbmZpZyhwYXlsb2FkKQoKX0RFRkFVTFRfQ0hST01BX1NDSEVNRSwgX0RFRkFVTFRfQ0hST01BX0hPU1QsIF9ERUZBVUxUX0NIUk9NQV9QT1JUID0gX2xvYWRfY2xpX2Nocm9tYV9kZWZhdWx0cygpCl9ERUZBVUxUX0VNQkVERElOR19CQVRDSF9TSVpFID0gX2V4dHJhY3RfZW1iZWRkaW5nX2JhdGNoX2Zyb21fY29uZmlnKF9sb2FkX293bl9yYWdfY2xpX2NvbmZpZ19wYXlsb2FkKCkpIG9yIDQKQ0hST01BX1NDSEVNRSA9IF9lbnZfc3RyKCJNQ1BfQ0hST01BX1NDSEVNRSIsIF9ERUZBVUxUX0NIUk9NQV9TQ0hFTUUpLmxvd2VyKCkKaWYgQ0hST01BX1NDSEVNRSBub3QgaW4geyJodHRwIiwgImh0dHBzIn06CiAgICBDSFJPTUFfU0NIRU1FID0gX0RFRkFVTFRfQ0hST01BX1NDSEVNRQpDSFJPTUFfSE9TVCA9IF9lbnZfc3RyKCJNQ1BfQ0hST01BX0hPU1QiLCBfREVGQVVMVF9DSFJPTUFfSE9TVCkKQ0hST01BX1BPUlQgPSBfZW52X2ludCgiTUNQX0NIUk9NQV9QT1JUIiwgX0RFRkFVTFRfQ0hST01BX1BPUlQsIG1pbl92YWx1ZT0xKQpDSFJPTUFfU1NMID0gQ0hST01BX1NDSEVNRSA9PSAiaHR0cHMiCkNPTExFQ1RJT05fQ09ERV9KSU5BID0gImNvZGVfdmVjdG9yc19qaW5hIgpDT0xMRUNUSU9OX0RPQ19CR0UgPSAiZG9jX3ZlY3RvcnNfYmdlIgoKIyBQYXN0YXMgZSBleHRlbnPDtWVzIGlnbm9yYWRhcyBkdXJhbnRlIGEgdmFycmVkdXJhCklHTk9SRURfRElSUyA9IHsKICAgICIuZ2l0IiwgIm5vZGVfbW9kdWxlcyIsICJfX3B5Y2FjaGVfXyIsICIudmVudiIsICJ2ZW52IiwgImVudiIsCiAgICAiZGlzdCIsICJidWlsZCIsICJvdXQiLCAiLm5leHQiLCAiLm51eHQiLCAiLmNhY2hlIiwgImNvdmVyYWdlIiwKICAgICIucHl0ZXN0X2NhY2hlIiwgIi5teXB5X2NhY2hlIiwgIi5ydWZmX2NhY2hlIiwgInRhcmdldCIsICJiaW4iLCAib2JqIiwKICAgICIuaWRlYSIsICIudnNjb2RlIiwgIi5EU19TdG9yZSIsICJ2ZW5kb3IiLCAidG1wIiwgInRlbXAiLCAibG9ncyIsCiAgICAiLnJhZ19kYiIsCn0KCklHTk9SRURfRVhURU5TSU9OUyA9IHsKICAgICMgQmluw6FyaW9zIGUgaW1hZ2VucwogICAgIi5wbmciLCAiLmpwZyIsICIuanBlZyIsICIuZ2lmIiwgIi5zdmciLCAiLmljbyIsICIud2VicCIsICIuYm1wIiwKICAgICIubXA0IiwgIi5tcDMiLCAiLndhdiIsICIub2dnIiwgIi5hdmkiLCAiLm1vdiIsCiAgICAjIFBhY290ZXMgZSBjb21waWxhZG9zCiAgICAiLnppcCIsICIudGFyIiwgIi5neiIsICIucmFyIiwgIi43eiIsICIuamFyIiwgIi53YXIiLCAiLmVhciIsCiAgICAiLnB5YyIsICIucHlvIiwgIi5zbyIsICIuZGxsIiwgIi5leGUiLCAiLmJpbiIsICIucnVuIiwKICAgICMgTG9ja2ZpbGVzIGUgZ2VyYWRvcwogICAgIi5sb2NrIiwgIi5zdW0iLAogICAgIyBCYW5jbyBkZSBkYWRvcwogICAgIi5zcWxpdGUiLCAiLmRiIiwgIi5zcWxpdGUzIiwKICAgICMgRm9udGVzCiAgICAiLnR0ZiIsICIud29mZiIsICIud29mZjIiLCAiLmVvdCIsCiAgICAjIFBERi9Eb2N1bWVudG9zIGJpbsOhcmlvcwogICAgIi5wZGYiLCAiLmRvY3giLCAiLnhsc3giLCAiLnBwdHgiLAp9CgpDT0RFX0VYVEVOU0lPTlMgPSB7CiAgICAiLnB5IiwgIi5qcyIsICIudHMiLCAiLnRzeCIsICIuanN4IiwgIi5qYXZhIiwgIi5jIiwgIi5oIiwgIi5jcHAiLCAiLmhwcCIsCiAgICAiLmdvIiwgIi5ycyIsICIucmIiLCAiLnBocCIsICIuY3MiLCAiLnN3aWZ0IiwgIi5rdCIsICIua3RzIiwgIi5zY2FsYSIsICIuc3FsIiwKICAgICIuc2giLCAiLmJhc2giLCAiLnpzaCIsICIucHMxIiwgIi55YW1sIiwgIi55bWwiLCAiLnRvbWwiLCAiLmluaSIsICIuY29uZiIsCiAgICAiLmpzb24iLCAiLnhtbCIsICIuaHRtbCIsICIuY3NzIiwgIi5zY3NzIiwgIi5zYXNzIiwgIi52dWUiLCAiLnN2ZWx0ZSIsICIuZGFydCIsCiAgICAiLmx1YSIsICIuciIsICIubSIsICIubW0iLAp9CgpET0NfRVhURU5TSU9OUyA9IHsKICAgICIubWQiLCAiLm1keCIsICIucnN0IiwgIi50eHQiLCAiLmFkb2MiLCAiLm9yZyIsICIudGV4IiwgIi5jc3YiLAp9CgojIFRhbWFuaG8gbcOheGltbyBkZSBhcnF1aXZvIChldml0YSBpbmRleGFyIGFycXVpdm9zIGVub3JtZXMgZ2VyYWRvcykKTUFYX0ZJTEVfU0laRV9CWVRFUyA9IDUwMCAqIDEwMjQgICMgNTAwIEtCCgojIFBhcsOibWV0cm9zIGRvIHNwbGl0dGVyIGUgYmF0Y2ggKHBlcmZpbCBsb3ctbWVtb3J5IHBvciBwYWRyw6NvKS4KQ0hVTktfU0laRSA9IF9lbnZfaW50KCJNQ1BfQ0hVTktfU0laRSIsIDMwMDAsIG1pbl92YWx1ZT0yNTYpCkNIVU5LX09WRVJMQVAgPSBtaW4oQ0hVTktfU0laRSAtIDEsIF9lbnZfaW50KCJNQ1BfQ0hVTktfT1ZFUkxBUCIsIDQwMCwgbWluX3ZhbHVlPTApKQpFTUJFRERJTkdfQkFUQ0hfU0laRSA9IF9lbnZfaW50KAogICAgIk1DUF9FTUJFRERJTkdfQkFUQ0hfU0laRSIsCiAgICBfREVGQVVMVF9FTUJFRERJTkdfQkFUQ0hfU0laRSwKICAgIG1pbl92YWx1ZT0xLAopCkRFRkFVTFRfUEVSRl9QUk9GSUxFID0gImF1dG90dW5lIgpJTkRFWEVSX0NPTkZJR19QQVRIID0gUGF0aCgKICAgIG9zLmVudmlyb24uZ2V0KAogICAgICAgICJNQ1BfSU5ERVhFUl9DT05GSUdfRklMRSIsCiAgICAgICAgc3RyKFBhdGguaG9tZSgpIC8gIi5jYWNoZSIgLyAib3duLXJhZy1jbGkiIC8gImluZGV4ZXJfdHVuaW5nLmpzb24iKSwKICAgICkKKS5leHBhbmR1c2VyKCkKCiMgTW9kZWxvIGRlIGVtYmVkZGluZ3MgKHJvZGEgbmEgQ1BVKQpKSU5BX1YzX0VNQkVERElOR19NT0RFTCA9ICJqaW5hYWkvamluYS1lbWJlZGRpbmdzLXYzIgpKSU5BX1YyX0VNQkVERElOR19NT0RFTCA9ICJqaW5hYWkvamluYS1lbWJlZGRpbmdzLXYyLWJhc2UtY29kZSIKQkdFX0VNQkVERElOR19NT0RFTCA9ICJCQUFJL2JnZS1tMyIKREVGQVVMVF9FTUJFRERJTkdfTU9ERUxfQ0hPSUNFID0gImppbmEiCkRFRkFVTFRfSklOQV9RVUFOVElaQVRJT04gPSAiZHluYW1pYy1pbnQ4IgpNT0RFTF9DQUNIRV9CQVNFX0RJUiA9IFBhdGgoCiAgICBvcy5lbnZpcm9uLmdldCgiTUNQX01PREVMX0RJUiIsIHN0cihQYXRoLmhvbWUoKSAvICIuY2FjaGUiIC8gIm93bi1yYWctY2xpIiAvICJtb2RlbHMiKSkKKS5leHBhbmR1c2VyKCkKSklOQV9SRUNPTU1FTkRFRF9SQU1fR0JfREVGQVVMVCA9IDY0CkpJTkFfUkVDT01NRU5ERURfUkFNX0dCX0RZTkFNSUNfSU5UOCA9IDQ4CkpJTkFfUkVDT01NRU5ERURfU1dBUF9HQiA9IDE2CkpJTkFfTUlOX0FWQUlMQUJMRV9SQU1fR0JfSElOVCA9IDEyCgoKZGVmIF9lbnZfYm9vbChuYW1lOiBzdHIsIGRlZmF1bHQ6IGJvb2wgPSBGYWxzZSkgLT4gYm9vbDoKICAgIHJhdyA9IG9zLmVudmlyb24uZ2V0KG5hbWUpCiAgICBpZiByYXcgaXMgTm9uZToKICAgICAgICByZXR1cm4gZGVmYXVsdAogICAgcmV0dXJuIHJhdy5zdHJpcCgpLmxvd2VyKCkgaW4geyIxIiwgInRydWUiLCAieWVzIiwgIm9uIn0KCgpkZWYgX2NsYW1wKHZhbHVlOiBmbG9hdCwgbG93OiBmbG9hdCwgaGlnaDogZmxvYXQpIC0+IGZsb2F0OgogICAgcmV0dXJuIG1heChsb3csIG1pbihoaWdoLCB2YWx1ZSkpCgoKZGVmIF9pc19tZW1vcnlfcmVsYXRlZF9lcnJvcihleGM6IEV4Y2VwdGlvbikgLT4gYm9vbDoKICAgIGlmIGlzaW5zdGFuY2UoZXhjLCBNZW1vcnlFcnJvcik6CiAgICAgICAgcmV0dXJuIFRydWUKICAgIG1zZyA9IHN0cihleGMpLmxvd2VyKCkKICAgIG1lbW9yeV9tYXJrZXJzID0gKAogICAgICAgICJvdXQgb2YgbWVtb3J5IiwKICAgICAgICAib29tIiwKICAgICAgICAiY2Fubm90IGFsbG9jYXRlIG1lbW9yeSIsCiAgICAgICAgInN0ZDo6YmFkX2FsbG9jIiwKICAgICAgICAiYmFkIGFsbG9jIiwKICAgICAgICAiaW5zdWZmaWNpZW50IG1lbW9yeSIsCiAgICApCiAgICByZXR1cm4gYW55KG1hcmtlciBpbiBtc2cgZm9yIG1hcmtlciBpbiBtZW1vcnlfbWFya2VycykKCgpkZWYgX2lzX2RpbWVuc2lvbl9taXNtYXRjaF9lcnJvcihleGM6IEV4Y2VwdGlvbikgLT4gYm9vbDoKICAgIG1zZyA9IHN0cihleGMpLmxvd2VyKCkKICAgIHJldHVybiAoCiAgICAgICAgImV4cGVjdGluZyBlbWJlZGRpbmcgd2l0aCBkaW1lbnNpb24iIGluIG1zZwogICAgICAgIG9yICgiZW1iZWRkaW5nIiBpbiBtc2cgYW5kICJkaW1lbnNpb24iIGluIG1zZyBhbmQgImdvdCIgaW4gbXNnKQogICAgKQoKCmRlZiBfZm9ybWF0X2V4Y2VwdGlvbihleGM6IEV4Y2VwdGlvbikgLT4gc3RyOgogICAgbWVzc2FnZSA9IHN0cihleGMpLnN0cmlwKCkKICAgIGlmIG1lc3NhZ2U6CiAgICAgICAgcmV0dXJuIG1lc3NhZ2UKICAgIHJldHVybiByZXByKGV4YykKCgpAZGF0YWNsYXNzKGZyb3plbj1UcnVlKQpjbGFzcyBJbmRleFRhcmdldDoKICAgIG1vZGVsX2Nob2ljZTogc3RyCiAgICBjb2xsZWN0aW9uX25hbWU6IHN0cgogICAgbGFiZWw6IHN0cgoKCmRlZiBfcmVzb2x2ZV9tb2RlbF9pZChtb2RlbF9jaG9pY2U6IHN0cikgLT4gc3RyOgogICAgaWYgbW9kZWxfY2hvaWNlID09ICJqaW5hIjoKICAgICAgICByZXR1cm4gSklOQV9WM19FTUJFRERJTkdfTU9ERUwKICAgIGlmIG1vZGVsX2Nob2ljZSA9PSAiamluYS12MiI6CiAgICAgICAgcmV0dXJuIEpJTkFfVjJfRU1CRURESU5HX01PREVMCiAgICBpZiBtb2RlbF9jaG9pY2UgPT0gImJnZSI6CiAgICAgICAgcmV0dXJuIEJHRV9FTUJFRERJTkdfTU9ERUwKICAgIHJhaXNlIFZhbHVlRXJyb3IoZiJNb2RlbG8gbsOjbyBzdXBvcnRhZG86IHttb2RlbF9jaG9pY2V9IikKCgpkZWYgX3Jlc29sdmVfZmFsbGJhY2tfbW9kZWxfaWQobW9kZWxfY2hvaWNlOiBzdHIpIC0+IHN0cjoKICAgIHJldHVybiBCR0VfRU1CRURESU5HX01PREVMCgoKZGVmIF9kZXNjcmliZV9lbWJlZGRpbmdfY2hvaWNlKG1vZGVsX2Nob2ljZTogc3RyKSAtPiBzdHI6CiAgICBpZiBtb2RlbF9jaG9pY2UgPT0gImppbmEiOgogICAgICAgIHJldHVybiBmImppbmEgKHtKSU5BX1YzX0VNQkVERElOR19NT0RFTH0pIgogICAgaWYgbW9kZWxfY2hvaWNlID09ICJiZ2UiOgogICAgICAgIHJldHVybiBmImJnZSAoe0JHRV9FTUJFRERJTkdfTU9ERUx9KSIKICAgIGlmIG1vZGVsX2Nob2ljZSA9PSAiaHlicmlkIjoKICAgICAgICByZXR1cm4gZiJoeWJyaWQgKHtKSU5BX1YyX0VNQkVERElOR19NT0RFTH0gKyB7QkdFX0VNQkVERElOR19NT0RFTH0pIgogICAgcmV0dXJuIG1vZGVsX2Nob2ljZQoKCmRlZiBfcmVzb2x2ZV9pbmRleF90YXJnZXRzKG1vZGVsX2Nob2ljZTogc3RyKSAtPiBsaXN0W0luZGV4VGFyZ2V0XToKICAgIGlmIG1vZGVsX2Nob2ljZSA9PSAiamluYSI6CiAgICAgICAgcmV0dXJuIFsKICAgICAgICAgICAgSW5kZXhUYXJnZXQoCiAgICAgICAgICAgICAgICBtb2RlbF9jaG9pY2U9ImppbmEiLAogICAgICAgICAgICAgICAgY29sbGVjdGlvbl9uYW1lPUNPTExFQ1RJT05fQ09ERV9KSU5BLAogICAgICAgICAgICAgICAgbGFiZWw9IkNvZGUvSmluYSIsCiAgICAgICAgICAgICkKICAgICAgICBdCiAgICBpZiBtb2RlbF9jaG9pY2UgPT0gImJnZSI6CiAgICAgICAgcmV0dXJuIFsKICAgICAgICAgICAgSW5kZXhUYXJnZXQoCiAgICAgICAgICAgICAgICBtb2RlbF9jaG9pY2U9ImJnZSIsCiAgICAgICAgICAgICAgICBjb2xsZWN0aW9uX25hbWU9Q09MTEVDVElPTl9ET0NfQkdFLAogICAgICAgICAgICAgICAgbGFiZWw9IkRvYy9CR0UiLAogICAgICAgICAgICApCiAgICAgICAgXQogICAgaWYgbW9kZWxfY2hvaWNlID09ICJoeWJyaWQiOgogICAgICAgIHJldHVybiBbCiAgICAgICAgICAgIEluZGV4VGFyZ2V0KAogICAgICAgICAgICAgICAgbW9kZWxfY2hvaWNlPSJqaW5hLXYyIiwKICAgICAgICAgICAgICAgIGNvbGxlY3Rpb25fbmFtZT1DT0xMRUNUSU9OX0NPREVfSklOQSwKICAgICAgICAgICAgICAgIGxhYmVsPSJDb2RlL0ppbmEgdjIiLAogICAgICAgICAgICApLAogICAgICAgICAgICBJbmRleFRhcmdldCgKICAgICAgICAgICAgICAgIG1vZGVsX2Nob2ljZT0iYmdlIiwKICAgICAgICAgICAgICAgIGNvbGxlY3Rpb25fbmFtZT1DT0xMRUNUSU9OX0RPQ19CR0UsCiAgICAgICAgICAgICAgICBsYWJlbD0iRG9jL0JHRSIsCiAgICAgICAgICAgICksCiAgICAgICAgXQogICAgcmFpc2UgVmFsdWVFcnJvcihmIk1vZGVsbyBuw6NvIHN1cG9ydGFkbzoge21vZGVsX2Nob2ljZX0iKQoKCmRlZiBfY2xhc3NpZnlfZmlsZV90YXJnZXRzKGZpbGVwYXRoOiBQYXRoLCBtb2RlbF9jaG9pY2U6IHN0cikgLT4gc2V0W3N0cl06CiAgICBpZiBtb2RlbF9jaG9pY2UgIT0gImh5YnJpZCI6CiAgICAgICAgcmV0dXJuIHttb2RlbF9jaG9pY2V9CgogICAgc3VmZml4ID0gZmlsZXBhdGguc3VmZml4Lmxvd2VyKCkKICAgIGlzX2NvZGUgPSBzdWZmaXggaW4gQ09ERV9FWFRFTlNJT05TCiAgICBpc19kb2MgPSBzdWZmaXggaW4gRE9DX0VYVEVOU0lPTlMKCiAgICBpZiBpc19jb2RlIGFuZCBub3QgaXNfZG9jOgogICAgICAgIHJldHVybiB7ImppbmEtdjIifQogICAgaWYgaXNfZG9jIGFuZCBub3QgaXNfY29kZToKICAgICAgICByZXR1cm4geyJiZ2UifQoKICAgICMgRXh0ZW5zw6NvIGRlc2NvbmhlY2lkYS9hbWLDrWd1YTogaW5kZXhhIG5vcyBkb2lzIHJhbW9zIHBhcmEgbWFudGVyIHJlY2FsbC4KICAgIHJldHVybiB7ImppbmEtdjIiLCAiYmdlIn0KCgpkZWYgX21vZGVsX2NhY2hlX2RpcihiYXNlX2RpcjogUGF0aCwgbW9kZWxfaWQ6IHN0cikgLT4gUGF0aDoKICAgIHNhZmVfbmFtZSA9IG1vZGVsX2lkLnJlcGxhY2UoIi8iLCAiX18iKS5yZXBsYWNlKCI6IiwgIl8iKQogICAgcmV0dXJuIGJhc2VfZGlyIC8gc2FmZV9uYW1lCgoKZGVmIF9waWNrX3dpdGhfcHJvbXB0KAogICAgKiwKICAgIGN1cnJlbnRfdmFsdWU6IHN0ciB8IE5vbmUsCiAgICBkZWZhdWx0X3ZhbHVlOiBzdHIsCiAgICB0aXRsZTogc3RyLAogICAgb3B0aW9uczogbGlzdFt0dXBsZVtzdHIsIHN0cl1dLAopIC0+IHN0cjoKICAgIGlmIGN1cnJlbnRfdmFsdWU6CiAgICAgICAgcmV0dXJuIGN1cnJlbnRfdmFsdWUKICAgIGlmIG5vdCBzeXMuc3RkaW4uaXNhdHR5KCk6CiAgICAgICAgcmV0dXJuIGRlZmF1bHRfdmFsdWUKCiAgICBwcmludChmIlxuW0NPTkZJR10ge3RpdGxlfSIpCiAgICBmb3IgaW5kZXgsIChfLCBkZXNjcmlwdGlvbikgaW4gZW51bWVyYXRlKG9wdGlvbnMsIHN0YXJ0PTEpOgogICAgICAgIHByaW50KGYiICB7aW5kZXh9KSB7ZGVzY3JpcHRpb259IikKICAgIHByaW50KGYiICBFbnRlciA9IHBhZHLDo28gKHtkZWZhdWx0X3ZhbHVlfSkiKQoKICAgIGFuc3dlciA9IGlucHV0KCI+IEVzY29saGE6ICIpLnN0cmlwKCkKICAgIGlmIG5vdCBhbnN3ZXI6CiAgICAgICAgcmV0dXJuIGRlZmF1bHRfdmFsdWUKICAgIGlmIGFuc3dlci5pc2RpZ2l0KCk6CiAgICAgICAgaWR4ID0gaW50KGFuc3dlcikgLSAxCiAgICAgICAgaWYgMCA8PSBpZHggPCBsZW4ob3B0aW9ucyk6CiAgICAgICAgICAgIHJldHVybiBvcHRpb25zW2lkeF1bMF0KICAgIGxvd2VyZWQgPSBhbnN3ZXIubG93ZXIoKQogICAgdmFsaWRfa2V5cyA9IHtrIGZvciBrLCBfIGluIG9wdGlvbnN9CiAgICBpZiBsb3dlcmVkIGluIHZhbGlkX2tleXM6CiAgICAgICAgcmV0dXJuIGxvd2VyZWQKICAgIHByaW50KGYiW0FWSVNPXSBPcMOnw6NvIGludsOhbGlkYSAne2Fuc3dlcn0nLiBVc2FuZG8gcGFkcsOjbzoge2RlZmF1bHRfdmFsdWV9IikKICAgIHJldHVybiBkZWZhdWx0X3ZhbHVlCgoKZGVmIHJlc29sdmVfZW1iZWRkaW5nX2NvbmZpZygKICAgIG1vZGVsX2Nob2ljZV9hcmc6IHN0ciB8IE5vbmUsCiAgICBqaW5hX3F1YW50aXphdGlvbl9hcmc6IHN0ciB8IE5vbmUsCiAgICBwZXJzaXN0ZWRfY29uZmlnOiBkaWN0W3N0ciwgb2JqZWN0XSB8IE5vbmUgPSBOb25lLAopIC0+IHR1cGxlW3N0ciwgc3RyXToKICAgIHBlcnNpc3RlZF9jb25maWcgPSBwZXJzaXN0ZWRfY29uZmlnIG9yIHt9CiAgICBtb2RlbF9jaG9pY2VfZnJvbV9jb25maWcgPSBwZXJzaXN0ZWRfY29uZmlnLmdldCgiZW1iZWRkaW5nX21vZGVsIikKICAgIG1vZGVsX2Nob2ljZSA9IG1vZGVsX2Nob2ljZV9hcmcgb3Igb3MuZW52aXJvbi5nZXQoIk1DUF9FTUJFRERJTkdfTU9ERUwiKQogICAgaWYgbm90IG1vZGVsX2Nob2ljZSBhbmQgaXNpbnN0YW5jZShtb2RlbF9jaG9pY2VfZnJvbV9jb25maWcsIHN0cik6CiAgICAgICAgbW9kZWxfY2hvaWNlID0gbW9kZWxfY2hvaWNlX2Zyb21fY29uZmlnCiAgICBpZiBtb2RlbF9jaG9pY2U6CiAgICAgICAgbW9kZWxfY2hvaWNlID0gbW9kZWxfY2hvaWNlLnN0cmlwKCkubG93ZXIoKQogICAgbW9kZWxfY2hvaWNlID0gX3BpY2tfd2l0aF9wcm9tcHQoCiAgICAgICAgY3VycmVudF92YWx1ZT1tb2RlbF9jaG9pY2UsCiAgICAgICAgZGVmYXVsdF92YWx1ZT1ERUZBVUxUX0VNQkVERElOR19NT0RFTF9DSE9JQ0UsCiAgICAgICAgdGl0bGU9IkVzY29saGEgZG8gbW9kZWxvIGRlIGVtYmVkZGluZ3MiLAogICAgICAgIG9wdGlvbnM9WwogICAgICAgICAgICAoCiAgICAgICAgICAgICAgICAiamluYSIsCiAgICAgICAgICAgICAgICBmImppbmEgKHtKSU5BX1YzX0VNQkVERElOR19NT0RFTH0pIC0gZm9jbyBlbSBjw7NkaWdvLiIsCiAgICAgICAgICAgICksCiAgICAgICAgICAgICgKICAgICAgICAgICAgICAgICJiZ2UiLAogICAgICAgICAgICAgICAgZiJiZ2UgKHtCR0VfRU1CRURESU5HX01PREVMfSkgLSBjb250ZcO6ZG8gbWlzdG8uIiwKICAgICAgICAgICAgKSwKICAgICAgICAgICAgKAogICAgICAgICAgICAgICAgImh5YnJpZCIsCiAgICAgICAgICAgICAgICBmImh5YnJpZCAoSmluYSB2MiB7SklOQV9WMl9FTUJFRERJTkdfTU9ERUx9ICsgQkdFKSAtIGR1YXMgY29sZcOnw7Vlcy4iLAogICAgICAgICAgICApLAogICAgICAgIF0sCiAgICApCiAgICBpZiBtb2RlbF9jaG9pY2Ugbm90IGluIHsiamluYSIsICJiZ2UiLCAiaHlicmlkIn06CiAgICAgICAgcHJpbnQoZiJbQVZJU09dIE1DUF9FTUJFRERJTkdfTU9ERUwgaW52w6FsaWRvICd7bW9kZWxfY2hvaWNlfScuIFVzYW5kbyAne0RFRkFVTFRfRU1CRURESU5HX01PREVMX0NIT0lDRX0nLiIpCiAgICAgICAgbW9kZWxfY2hvaWNlID0gREVGQVVMVF9FTUJFRERJTkdfTU9ERUxfQ0hPSUNFCgogICAgcXVhbnRpemF0aW9uX2Zyb21fY29uZmlnID0gcGVyc2lzdGVkX2NvbmZpZy5nZXQoImppbmFfcXVhbnRpemF0aW9uIikKICAgIGppbmFfcXVhbnRpemF0aW9uID0gamluYV9xdWFudGl6YXRpb25fYXJnIG9yIG9zLmVudmlyb24uZ2V0KCJNQ1BfSklOQV9RVUFOVElaQVRJT04iKQogICAgaWYgbm90IGppbmFfcXVhbnRpemF0aW9uIGFuZCBpc2luc3RhbmNlKHF1YW50aXphdGlvbl9mcm9tX2NvbmZpZywgc3RyKToKICAgICAgICBqaW5hX3F1YW50aXphdGlvbiA9IHF1YW50aXphdGlvbl9mcm9tX2NvbmZpZwogICAgaWYgamluYV9xdWFudGl6YXRpb246CiAgICAgICAgamluYV9xdWFudGl6YXRpb24gPSBqaW5hX3F1YW50aXphdGlvbi5zdHJpcCgpLmxvd2VyKCkucmVwbGFjZSgiXyIsICItIikKCiAgICBpZiBtb2RlbF9jaG9pY2UgPT0gImppbmEiOgogICAgICAgIGppbmFfcXVhbnRpemF0aW9uID0gX3BpY2tfd2l0aF9wcm9tcHQoCiAgICAgICAgICAgIGN1cnJlbnRfdmFsdWU9amluYV9xdWFudGl6YXRpb24sCiAgICAgICAgICAgIGRlZmF1bHRfdmFsdWU9REVGQVVMVF9KSU5BX1FVQU5USVpBVElPTiwKICAgICAgICAgICAgdGl0bGU9IlF1YW50aXphY2FvIGRvIEppbmEgKGFwZW5hcyBwYXJhIENQVSkiLAogICAgICAgICAgICBvcHRpb25zPVsKICAgICAgICAgICAgICAgICgiZGVmYXVsdCIsICJkZWZhdWx0IChzZW0gcXVhbnRpemFjYW8pIC0gbWFpb3IgcXVhbGlkYWRlLCBpbmRleGFjYW8gbWFpcyBsZW50YS4iKSwKICAgICAgICAgICAgICAgICgiZHluYW1pYy1pbnQ4IiwgImR5bmFtaWMtaW50OCAtIGluZGV4YWNhbyBtYWlzIHJhcGlkYSBlIG1lbm9yIHVzbyBkZSBSQU0sIGNvbSBwZXF1ZW5hIHBlcmRhIGRlIHF1YWxpZGFkZS4iKSwKICAgICAgICAgICAgXSwKICAgICAgICApCiAgICAgICAgaWYgamluYV9xdWFudGl6YXRpb24gbm90IGluIHsiZGVmYXVsdCIsICJkeW5hbWljLWludDgifToKICAgICAgICAgICAgcHJpbnQoCiAgICAgICAgICAgICAgICBmIltBVklTT10gTUNQX0pJTkFfUVVBTlRJWkFUSU9OIGludsOhbGlkbyAne2ppbmFfcXVhbnRpemF0aW9ufScuICIKICAgICAgICAgICAgICAgIGYiVXNhbmRvICd7REVGQVVMVF9KSU5BX1FVQU5USVpBVElPTn0nLiIKICAgICAgICAgICAgKQogICAgICAgICAgICBqaW5hX3F1YW50aXphdGlvbiA9IERFRkFVTFRfSklOQV9RVUFOVElaQVRJT04KICAgIGVsc2U6CiAgICAgICAgamluYV9xdWFudGl6YXRpb24gPSAiZGVmYXVsdCIKCiAgICByZXR1cm4gbW9kZWxfY2hvaWNlLCBqaW5hX3F1YW50aXphdGlvbgoKCmRlZiBsb2FkX2luZGV4ZXJfdHVuaW5nX2NvbmZpZyhmb3JjZV9yZWNvbmZpZ3VyZTogYm9vbCkgLT4gZGljdFtzdHIsIG9iamVjdF06CiAgICBpZiBmb3JjZV9yZWNvbmZpZ3VyZToKICAgICAgICByZXR1cm4ge30KICAgIHRyeToKICAgICAgICBpZiBub3QgSU5ERVhFUl9DT05GSUdfUEFUSC5leGlzdHMoKToKICAgICAgICAgICAgcmV0dXJuIHt9CiAgICAgICAgZGF0YSA9IGpzb24ubG9hZHMoSU5ERVhFUl9DT05GSUdfUEFUSC5yZWFkX3RleHQoZW5jb2Rpbmc9InV0Zi04IikpCiAgICAgICAgaWYgaXNpbnN0YW5jZShkYXRhLCBkaWN0KToKICAgICAgICAgICAgcmV0dXJuIGRhdGEKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcmV0dXJuIHt9CiAgICByZXR1cm4ge30KCgpkZWYgX3BlcnNpc3RfYmF0Y2hfdG9fY2xpX2NvbmZpZyhiYXRjaF9zaXplOiBpbnQpIC0+IE5vbmU6CiAgICBwYXlsb2FkID0gX2xvYWRfb3duX3JhZ19jbGlfY29uZmlnX3BheWxvYWQoKQogICAgY2hyb21hID0gcGF5bG9hZC5nZXQoImNocm9tYSIpCiAgICBpZiBub3QgaXNpbnN0YW5jZShjaHJvbWEsIGRpY3QpOgogICAgICAgIGNocm9tYSA9IHsKICAgICAgICAgICAgInNjaGVtZSI6IENIUk9NQV9TQ0hFTUUsCiAgICAgICAgICAgICJob3N0IjogQ0hST01BX0hPU1QsCiAgICAgICAgICAgICJwb3J0IjogQ0hST01BX1BPUlQsCiAgICAgICAgfQogICAgICAgIHBheWxvYWRbImNocm9tYSJdID0gY2hyb21hCgogICAgaW5kZXhpbmcgPSBwYXlsb2FkLmdldCgiaW5kZXhpbmciKQogICAgaWYgbm90IGlzaW5zdGFuY2UoaW5kZXhpbmcsIGRpY3QpOgogICAgICAgIGluZGV4aW5nID0ge30KICAgIGluZGV4aW5nWyJlbWJlZGRpbmdfYmF0Y2hfc2l6ZSJdID0gYmF0Y2hfc2l6ZQogICAgaW5kZXhpbmdbImJhdGNoX2NvdW50Il0gPSBiYXRjaF9zaXplCiAgICBwYXlsb2FkWyJpbmRleGluZyJdID0gaW5kZXhpbmcKCiAgICB0cnk6CiAgICAgICAgT1dOX1JBR19DTElfQ09ORklHX1BBVEgucGFyZW50Lm1rZGlyKHBhcmVudHM9VHJ1ZSwgZXhpc3Rfb2s9VHJ1ZSkKICAgICAgICBPV05fUkFHX0NMSV9DT05GSUdfUEFUSC53cml0ZV90ZXh0KAogICAgICAgICAgICBqc29uLmR1bXBzKHBheWxvYWQsIGVuc3VyZV9hc2NpaT1GYWxzZSwgaW5kZW50PTIpICsgIlxuIiwKICAgICAgICAgICAgZW5jb2Rpbmc9InV0Zi04IiwKICAgICAgICApCiAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgcHJpbnQoCiAgICAgICAgICAgIGYiW0FWSVNPXSBOw6NvIGZvaSBwb3Nzw612ZWwgYXR1YWxpemFyIGJhdGNoIGVtICIKICAgICAgICAgICAgZiJ7T1dOX1JBR19DTElfQ09ORklHX1BBVEh9OiB7X2Zvcm1hdF9leGNlcHRpb24oZSl9IgogICAgICAgICkKCgpkZWYgc2F2ZV9pbmRleGVyX3R1bmluZ19jb25maWcoY29uZmlnOiBkaWN0W3N0ciwgb2JqZWN0XSkgLT4gTm9uZToKICAgIGJhdGNoX3NpemUgPSBfcGFyc2VfcG9zaXRpdmVfaW50KGNvbmZpZy5nZXQoImVtYmVkZGluZ19iYXRjaF9zaXplIiksIG1pbl92YWx1ZT0xKQogICAgcGF5bG9hZCA9IHsKICAgICAgICAqKmNvbmZpZywKICAgICAgICAidXBkYXRlZF9hdCI6IGludCh0aW1lKCkpLAogICAgfQogICAgaWYgYmF0Y2hfc2l6ZSBpcyBub3QgTm9uZToKICAgICAgICBwYXlsb2FkWyJiYXRjaF9jb3VudCJdID0gYmF0Y2hfc2l6ZQoKICAgIHRyeToKICAgICAgICBJTkRFWEVSX0NPTkZJR19QQVRILnBhcmVudC5ta2RpcihwYXJlbnRzPVRydWUsIGV4aXN0X29rPVRydWUpCiAgICAgICAgSU5ERVhFUl9DT05GSUdfUEFUSC53cml0ZV90ZXh0KAogICAgICAgICAgICBqc29uLmR1bXBzKHBheWxvYWQsIGVuc3VyZV9hc2NpaT1GYWxzZSwgaW5kZW50PTIpICsgIlxuIiwKICAgICAgICAgICAgZW5jb2Rpbmc9InV0Zi04IiwKICAgICAgICApCiAgICAgICAgcHJpbnQoZiJbQ09ORklHXSBDb25maWd1cmHDp8OjbyBwZXJzaXN0aWRhIGVtOiB7SU5ERVhFUl9DT05GSUdfUEFUSH0iKQogICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgIHByaW50KGYiW0FWSVNPXSBOw6NvIGZvaSBwb3Nzw612ZWwgcGVyc2lzdGlyIGNvbmZpZ3VyYcOnw6NvIGVtIHtJTkRFWEVSX0NPTkZJR19QQVRIfToge19mb3JtYXRfZXhjZXB0aW9uKGUpfSIpCgogICAgaWYgYmF0Y2hfc2l6ZSBpcyBub3QgTm9uZToKICAgICAgICBfcGVyc2lzdF9iYXRjaF90b19jbGlfY29uZmlnKGJhdGNoX3NpemUpCgoKZGVmIHJlc29sdmVfcGVyZl9wcm9maWxlKHBlcmZfcHJvZmlsZV9hcmc6IHN0ciB8IE5vbmUsIHBlcnNpc3RlZF9jb25maWc6IGRpY3Rbc3RyLCBvYmplY3RdKSAtPiBzdHI6CiAgICBwcm9maWxlX2Zyb21fY29uZmlnID0gcGVyc2lzdGVkX2NvbmZpZy5nZXQoInBlcmZfcHJvZmlsZSIpCiAgICBwcm9maWxlID0gcGVyZl9wcm9maWxlX2FyZyBvciBvcy5lbnZpcm9uLmdldCgiTUNQX1BFUkZfUFJPRklMRSIpCiAgICBpZiBub3QgcHJvZmlsZSBhbmQgaXNpbnN0YW5jZShwcm9maWxlX2Zyb21fY29uZmlnLCBzdHIpOgogICAgICAgIHByb2ZpbGUgPSBwcm9maWxlX2Zyb21fY29uZmlnCiAgICBpZiBwcm9maWxlOgogICAgICAgIHByb2ZpbGUgPSBwcm9maWxlLnN0cmlwKCkubG93ZXIoKQoKICAgIHByb2ZpbGUgPSBfcGlja193aXRoX3Byb21wdCgKICAgICAgICBjdXJyZW50X3ZhbHVlPXByb2ZpbGUsCiAgICAgICAgZGVmYXVsdF92YWx1ZT1ERUZBVUxUX1BFUkZfUFJPRklMRSwKICAgICAgICB0aXRsZT0iUGVyZmlsIGRlIHBlcmZvcm1hbmNlIGRhIGluZGV4YcOnw6NvIiwKICAgICAgICBvcHRpb25zPVsKICAgICAgICAgICAgKAogICAgICAgICAgICAgICAgImF1dG90dW5lIiwKICAgICAgICAgICAgICAgICJhdXRvdHVuZSAtIGVxdWlsw61icmlvIChyZWNvbWVuZGFkbykuIiwKICAgICAgICAgICAgKSwKICAgICAgICAgICAgKAogICAgICAgICAgICAgICAgIm1heC1wZXJmb3JtYW5jZSIsCiAgICAgICAgICAgICAgICAibWF4LXBlcmZvcm1hbmNlIC0gbcOheGltbyB0aHJvdWdocHV0IChtYWlzIFJBTSkuIiwKICAgICAgICAgICAgKSwKICAgICAgICBdLAogICAgKQogICAgaWYgcHJvZmlsZSBub3QgaW4geyJhdXRvdHVuZSIsICJtYXgtcGVyZm9ybWFuY2UifToKICAgICAgICBwcmludChmIltBVklTT10gUGVyZmlsIGludsOhbGlkbyAne3Byb2ZpbGV9Jy4gVXNhbmRvICd7REVGQVVMVF9QRVJGX1BST0ZJTEV9Jy4iKQogICAgICAgIHByb2ZpbGUgPSBERUZBVUxUX1BFUkZfUFJPRklMRQogICAgcmV0dXJuIHByb2ZpbGUKCgpkZWYgX3BhcnNlX2NvbmZpZ19pbnQoY29uZmlnOiBkaWN0W3N0ciwgb2JqZWN0XSwga2V5OiBzdHIpIC0+IGludCB8IE5vbmU6CiAgICByYXcgPSBjb25maWcuZ2V0KGtleSkKICAgIGlmIGlzaW5zdGFuY2UocmF3LCBpbnQpOgogICAgICAgIHJldHVybiByYXcKICAgIGlmIGlzaW5zdGFuY2UocmF3LCBzdHIpIGFuZCByYXcuaXNkaWdpdCgpOgogICAgICAgIHJldHVybiBpbnQocmF3KQogICAgcmV0dXJuIE5vbmUKCgpkZWYgX3JlYWRfbWVtaW5mb19naWIoKSAtPiB0dXBsZVtmbG9hdCB8IE5vbmUsIGZsb2F0IHwgTm9uZSwgZmxvYXQgfCBOb25lXToKICAgICIiIlJldG9ybmEgKG1lbV90b3RhbCwgbWVtX2F2YWlsYWJsZSwgc3dhcF90b3RhbCkgZW0gR2lCLCBxdWFuZG8gZGlzcG9uw612ZWwuIiIiCiAgICBtZW1fdG90YWxfa2liOiBpbnQgfCBOb25lID0gTm9uZQogICAgbWVtX2F2YWlsYWJsZV9raWI6IGludCB8IE5vbmUgPSBOb25lCiAgICBzd2FwX3RvdGFsX2tpYjogaW50IHwgTm9uZSA9IE5vbmUKCiAgICB0cnk6CiAgICAgICAgZm9yIGxpbmUgaW4gUGF0aCgiL3Byb2MvbWVtaW5mbyIpLnJlYWRfdGV4dChlbmNvZGluZz0idXRmLTgiKS5zcGxpdGxpbmVzKCk6CiAgICAgICAgICAgIGlmIGxpbmUuc3RhcnRzd2l0aCgiTWVtVG90YWw6Iik6CiAgICAgICAgICAgICAgICBtZW1fdG90YWxfa2liID0gaW50KGxpbmUuc3BsaXQoKVsxXSkKICAgICAgICAgICAgZWxpZiBsaW5lLnN0YXJ0c3dpdGgoIk1lbUF2YWlsYWJsZToiKToKICAgICAgICAgICAgICAgIG1lbV9hdmFpbGFibGVfa2liID0gaW50KGxpbmUuc3BsaXQoKVsxXSkKICAgICAgICAgICAgZWxpZiBsaW5lLnN0YXJ0c3dpdGgoIlN3YXBUb3RhbDoiKToKICAgICAgICAgICAgICAgIHN3YXBfdG90YWxfa2liID0gaW50KGxpbmUuc3BsaXQoKVsxXSkKICAgIGV4Y2VwdCAoT1NFcnJvciwgVmFsdWVFcnJvciwgSW5kZXhFcnJvcik6CiAgICAgICAgcmV0dXJuIE5vbmUsIE5vbmUsIE5vbmUKCiAgICB0b19naWIgPSBsYW1iZGEga2liOiAoa2liIC8gKDEwMjQgKiAxMDI0KSkgaWYga2liIGlzIG5vdCBOb25lIGVsc2UgTm9uZQogICAgcmV0dXJuIHRvX2dpYihtZW1fdG90YWxfa2liKSwgdG9fZ2liKG1lbV9hdmFpbGFibGVfa2liKSwgdG9fZ2liKHN3YXBfdG90YWxfa2liKQoKCmRlZiB3YXJuX2lmX2ppbmFfbWVtb3J5X3Jpc2sobW9kZWxfY2hvaWNlOiBzdHIsIGppbmFfcXVhbnRpemF0aW9uOiBzdHIpIC0+IE5vbmU6CiAgICAiIiJNb3N0cmEgYXZpc28gZGUgcmlzY28gZGUgT09NIHBhcmEgbyBtb2RlbG8gSmluYSBlbSBtw6FxdWluYXMgY29tIHBvdWNhIG1lbcOzcmlhLiIiIgogICAgaWYgbW9kZWxfY2hvaWNlIG5vdCBpbiB7ImppbmEiLCAiaHlicmlkIn06CiAgICAgICAgcmV0dXJuCgogICAgbWVtX3RvdGFsX2dpYiwgbWVtX2F2YWlsYWJsZV9naWIsIHN3YXBfdG90YWxfZ2liID0gX3JlYWRfbWVtaW5mb19naWIoKQogICAgaWYgbWVtX3RvdGFsX2dpYiBpcyBOb25lOgogICAgICAgIHJldHVybgoKICAgIHJlY29tbWVuZGVkX3JhbV9naWIgPSAoCiAgICAgICAgSklOQV9SRUNPTU1FTkRFRF9SQU1fR0JfREVGQVVMVAogICAgICAgIGlmIGppbmFfcXVhbnRpemF0aW9uID09ICJkZWZhdWx0IgogICAgICAgIGVsc2UgSklOQV9SRUNPTU1FTkRFRF9SQU1fR0JfRFlOQU1JQ19JTlQ4CiAgICApCgogICAgcmVhc29uczogbGlzdFtzdHJdID0gW10KICAgIGlmIG1lbV90b3RhbF9naWIgPCByZWNvbW1lbmRlZF9yYW1fZ2liOgogICAgICAgIHJlYXNvbnMuYXBwZW5kKAogICAgICAgICAgICBmIlJBTSB0b3RhbCBkZXRlY3RhZGE6IHttZW1fdG90YWxfZ2liOi4xZn0gR2lCIChyZWNvbWVuZGFkbyA+PSB7cmVjb21tZW5kZWRfcmFtX2dpYn0gR2lCIHBhcmEgSmluYS97amluYV9xdWFudGl6YXRpb259KS4iCiAgICAgICAgKQogICAgaWYgc3dhcF90b3RhbF9naWIgaXMgbm90IE5vbmUgYW5kIHN3YXBfdG90YWxfZ2liIDwgSklOQV9SRUNPTU1FTkRFRF9TV0FQX0dCOgogICAgICAgIHJlYXNvbnMuYXBwZW5kKAogICAgICAgICAgICBmIlN3YXAgZGV0ZWN0YWRhOiB7c3dhcF90b3RhbF9naWI6LjFmfSBHaUIgKHJlY29tZW5kYWRvID49IHtKSU5BX1JFQ09NTUVOREVEX1NXQVBfR0J9IEdpQikuIgogICAgICAgICkKICAgIGlmIG1lbV9hdmFpbGFibGVfZ2liIGlzIG5vdCBOb25lIGFuZCBtZW1fYXZhaWxhYmxlX2dpYiA8IEpJTkFfTUlOX0FWQUlMQUJMRV9SQU1fR0JfSElOVDoKICAgICAgICByZWFzb25zLmFwcGVuZCgKICAgICAgICAgICAgZiJSQU0gbGl2cmUgYXR1YWw6IHttZW1fYXZhaWxhYmxlX2dpYjouMWZ9IEdpQiAoYmFpeG8gcGFyYSBhIGNhcmdhIGluaWNpYWwgZG8gSmluYSkuIgogICAgICAgICkKCiAgICBpZiBub3QgcmVhc29uczoKICAgICAgICByZXR1cm4KCiAgICBwcmludCgiW0FWSVNPXSBBbHRvIHJpc2NvIGRlIE9PTSBjb20gSmluYSBuZXN0YSBtw6FxdWluYS9jYXJnYS4iKQogICAgZm9yIHJlYXNvbiBpbiByZWFzb25zOgogICAgICAgIHByaW50KGYiICAgICAgICAtIHtyZWFzb259IikKICAgIHByaW50KCIgICAgICAgIC0gU2Ugb2NvcnJlciAnS2lsbGVkJyAoZXhpdCAxMzcpLCB1c2UgQkdFOiAtLWVtYmVkZGluZy1tb2RlbCBiZ2UiKQogICAgcHJpbnQoIiAgICAgICAgLSBPdSByb2RlIG8gSmluYSBlbSBtw6FxdWluYSBjb20gbWFpcyBSQU0vc3dhcCBlIG1lbm9zIHByb2Nlc3NvcyBjb25jb3JyZW50ZXMuIikKCgpAZGF0YWNsYXNzKGZyb3plbj1UcnVlKQpjbGFzcyBSdW50aW1lSW5kZXhpbmdQYXJhbXM6CiAgICBjaHVua19zaXplOiBpbnQKICAgIGNodW5rX292ZXJsYXA6IGludAogICAgZW1iZWRkaW5nX2JhdGNoX3NpemU6IGludAogICAgcmVhc29uczogbGlzdFtzdHJdCgoKZGVmIF9yZXNvbHZlX21heF9wZXJmb3JtYW5jZV9wYXJhbXMoCiAgICAqLAogICAgY2h1bmtfc2l6ZV9sb2NrZWQ6IGJvb2wsCiAgICBjaHVua19vdmVybGFwX2xvY2tlZDogYm9vbCwKICAgIGJhdGNoX3NpemVfbG9ja2VkOiBib29sLAogICAgY2h1bmtfc2l6ZTogaW50LAogICAgY2h1bmtfb3ZlcmxhcDogaW50LAogICAgZW1iZWRkaW5nX2JhdGNoX3NpemU6IGludCwKKSAtPiBSdW50aW1lSW5kZXhpbmdQYXJhbXM6CiAgICBtZW1fdG90YWxfZ2liLCBtZW1fYXZhaWxhYmxlX2dpYiwgXyA9IF9yZWFkX21lbWluZm9fZ2liKCkKICAgIHJlYXNvbnMgPSBbCiAgICAgICAgIlBlcmZpbCBzZWxlY2lvbmFkbzogbWF4LXBlcmZvcm1hbmNlLiIsCiAgICAgICAgIk1vZG8gcG9kZSBlbGV2YXIgY29uc2lkZXJhdmVsbWVudGUgbyBjb25zdW1vIGRlIG1lbcOzcmlhIGUgY2F1c2FyIGVuY2VycmFtZW50byBwb3IgT09NIChleGl0IDEzNykuIiwKICAgIF0KCiAgICB0dW5lZF9jaHVua19zaXplID0gY2h1bmtfc2l6ZQogICAgdHVuZWRfY2h1bmtfb3ZlcmxhcCA9IGNodW5rX292ZXJsYXAKICAgIHR1bmVkX2JhdGNoID0gZW1iZWRkaW5nX2JhdGNoX3NpemUKCiAgICBpZiBub3QgY2h1bmtfc2l6ZV9sb2NrZWQ6CiAgICAgICAgaWYgbWVtX3RvdGFsX2dpYiBpcyBub3QgTm9uZSBhbmQgbWVtX3RvdGFsX2dpYiA+PSA2NCBhbmQgKG1lbV9hdmFpbGFibGVfZ2liIG9yIDApID49IDE2OgogICAgICAgICAgICB0dW5lZF9jaHVua19zaXplID0gNzAwMAogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHR1bmVkX2NodW5rX3NpemUgPSA2MDAwCiAgICAgICAgcmVhc29ucy5hcHBlbmQoZiJjaHVua19zaXplIGFqdXN0YWRvIHBhcmEge3R1bmVkX2NodW5rX3NpemV9IG5vIHBlcmZpbCBtYXgtcGVyZm9ybWFuY2UuIikKCiAgICBpZiBub3QgY2h1bmtfb3ZlcmxhcF9sb2NrZWQ6CiAgICAgICAgdHVuZWRfY2h1bmtfb3ZlcmxhcCA9IG1pbih0dW5lZF9jaHVua19zaXplIC0gMSwgbWF4KDMwMCwgaW50KHR1bmVkX2NodW5rX3NpemUgKiAwLjE1KSkpCiAgICAgICAgcmVhc29ucy5hcHBlbmQoZiJjaHVua19vdmVybGFwIGFqdXN0YWRvIHBhcmEge3R1bmVkX2NodW5rX292ZXJsYXB9LiIpCgogICAgaWYgbm90IGJhdGNoX3NpemVfbG9ja2VkOgogICAgICAgIGlmIG1lbV90b3RhbF9naWIgaXMgbm90IE5vbmUgYW5kIG1lbV90b3RhbF9naWIgPj0gNjQgYW5kIChtZW1fYXZhaWxhYmxlX2dpYiBvciAwKSA+PSAxNjoKICAgICAgICAgICAgdHVuZWRfYmF0Y2ggPSAyNAogICAgICAgIGVsaWYgbWVtX3RvdGFsX2dpYiBpcyBub3QgTm9uZSBhbmQgbWVtX3RvdGFsX2dpYiA+PSAzMjoKICAgICAgICAgICAgdHVuZWRfYmF0Y2ggPSAxNgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHR1bmVkX2JhdGNoID0gMTIKICAgICAgICByZWFzb25zLmFwcGVuZChmImVtYmVkZGluZ19iYXRjaF9zaXplIGFqdXN0YWRvIHBhcmEge3R1bmVkX2JhdGNofS4iKQoKICAgIHJldHVybiBSdW50aW1lSW5kZXhpbmdQYXJhbXMoCiAgICAgICAgY2h1bmtfc2l6ZT10dW5lZF9jaHVua19zaXplLAogICAgICAgIGNodW5rX292ZXJsYXA9dHVuZWRfY2h1bmtfb3ZlcmxhcCwKICAgICAgICBlbWJlZGRpbmdfYmF0Y2hfc2l6ZT1tYXgoMSwgdHVuZWRfYmF0Y2gpLAogICAgICAgIHJlYXNvbnM9cmVhc29ucywKICAgICkKCgpkZWYgX3Jlc29sdmVfYXV0b3R1bmVkX3BhcmFtcygKICAgICosCiAgICBtb2RlbDogU2VudGVuY2VUcmFuc2Zvcm1lciwKICAgIGNodW5rX3NpemVfbG9ja2VkOiBib29sLAogICAgY2h1bmtfb3ZlcmxhcF9sb2NrZWQ6IGJvb2wsCiAgICBiYXRjaF9zaXplX2xvY2tlZDogYm9vbCwKICAgIGNodW5rX3NpemU6IGludCwKICAgIGNodW5rX292ZXJsYXA6IGludCwKICAgIGVtYmVkZGluZ19iYXRjaF9zaXplOiBpbnQsCikgLT4gUnVudGltZUluZGV4aW5nUGFyYW1zOgogICAgcmVhc29uczogbGlzdFtzdHJdID0gWyJQZXJmaWwgc2VsZWNpb25hZG86IGF1dG90dW5lIChjdXN0by1iZW5lZsOtY2lvKS4iXQogICAgdmVyYm9zZV9hdXRvdHVuZSA9IF9lbnZfYm9vbCgiTUNQX0FVVE9UVU5FX1ZFUkJPU0UiLCBkZWZhdWx0PUZhbHNlKQoKICAgIHRyeToKICAgICAgICBpbXBvcnQgcHN1dGlsICAjIHR5cGU6IGlnbm9yZQogICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICByZWFzb25zLmFwcGVuZCgicHN1dGlsIGluZGlzcG9uw612ZWw7IG1hbnRlbmRvIHBhcsOibWV0cm9zIGF0dWFpcyBzZW0gYmVuY2htYXJrLiIpCiAgICAgICAgcmV0dXJuIFJ1bnRpbWVJbmRleGluZ1BhcmFtcygKICAgICAgICAgICAgY2h1bmtfc2l6ZT1jaHVua19zaXplLAogICAgICAgICAgICBjaHVua19vdmVybGFwPWNodW5rX292ZXJsYXAsCiAgICAgICAgICAgIGVtYmVkZGluZ19iYXRjaF9zaXplPWVtYmVkZGluZ19iYXRjaF9zaXplLAogICAgICAgICAgICByZWFzb25zPXJlYXNvbnMsCiAgICAgICAgKQoKICAgIHZtID0gcHN1dGlsLnZpcnR1YWxfbWVtb3J5KCkKICAgIHN3YXAgPSBwc3V0aWwuc3dhcF9tZW1vcnkoKQogICAgbWVtX3RvdGFsX2dpYiA9IHZtLnRvdGFsIC8gKDEwMjQqKjMpCiAgICBtZW1fYXZhaWxhYmxlX2dpYiA9IHZtLmF2YWlsYWJsZSAvICgxMDI0KiozKQogICAgc3dhcF90b3RhbF9naWIgPSBzd2FwLnRvdGFsIC8gKDEwMjQqKjMpCgogICAgdGFyZ2V0X3JhbV9wZXJjZW50ID0gX2NsYW1wKAogICAgICAgIGZsb2F0KG9zLmVudmlyb24uZ2V0KCJNQ1BfQVVUT1RVTkVfVEFSR0VUX1JBTV9QRVJDRU5UIiwgIjY4IikpLAogICAgICAgIDYwLjAsCiAgICAgICAgNzUuMCwKICAgICkKICAgIGlmIG1lbV9hdmFpbGFibGVfZ2liIDwgNiBvciBzd2FwX3RvdGFsX2dpYiA8IDQ6CiAgICAgICAgdGFyZ2V0X3JhbV9wZXJjZW50ID0gbWluKHRhcmdldF9yYW1fcGVyY2VudCwgNjMuMCkKICAgIHJlYXNvbnMuYXBwZW5kKAogICAgICAgIGYiTWVtw7NyaWEgZGV0ZWN0YWRhOiB0b3RhbD17bWVtX3RvdGFsX2dpYjouMWZ9IEdpQiwgbGl2cmU9e21lbV9hdmFpbGFibGVfZ2liOi4xZn0gR2lCLCAiCiAgICAgICAgZiJzd2FwPXtzd2FwX3RvdGFsX2dpYjouMWZ9IEdpQiwgYWx2bz17dGFyZ2V0X3JhbV9wZXJjZW50Oi4xZn0lLiIKICAgICkKCiAgICB0dW5lZF9jaHVua19zaXplID0gY2h1bmtfc2l6ZQogICAgdHVuZWRfY2h1bmtfb3ZlcmxhcCA9IGNodW5rX292ZXJsYXAKICAgIHR1bmVkX2JhdGNoID0gZW1iZWRkaW5nX2JhdGNoX3NpemUKCiAgICBpZiBub3QgY2h1bmtfc2l6ZV9sb2NrZWQ6CiAgICAgICAgaWYgbWVtX3RvdGFsX2dpYiA8IDggb3IgbWVtX2F2YWlsYWJsZV9naWIgPCAzOgogICAgICAgICAgICB0dW5lZF9jaHVua19zaXplID0gMTgwMAogICAgICAgIGVsaWYgbWVtX3RvdGFsX2dpYiA8IDE2IG9yIG1lbV9hdmFpbGFibGVfZ2liIDwgNjoKICAgICAgICAgICAgdHVuZWRfY2h1bmtfc2l6ZSA9IDI0MDAKICAgICAgICBlbGlmIG1lbV90b3RhbF9naWIgPCAzMiBvciBtZW1fYXZhaWxhYmxlX2dpYiA8IDEyOgogICAgICAgICAgICB0dW5lZF9jaHVua19zaXplID0gMzIwMAogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHR1bmVkX2NodW5rX3NpemUgPSA0MjAwCiAgICAgICAgcmVhc29ucy5hcHBlbmQoZiJjaHVua19zaXplIGF1dG90dW5hZG8gcGFyYSB7dHVuZWRfY2h1bmtfc2l6ZX0uIikKCiAgICBpZiBub3QgY2h1bmtfb3ZlcmxhcF9sb2NrZWQ6CiAgICAgICAgdHVuZWRfY2h1bmtfb3ZlcmxhcCA9IG1pbih0dW5lZF9jaHVua19zaXplIC0gMSwgbWF4KDEyMCwgaW50KHR1bmVkX2NodW5rX3NpemUgKiAwLjE1KSkpCiAgICAgICAgcmVhc29ucy5hcHBlbmQoZiJjaHVua19vdmVybGFwIGF1dG90dW5hZG8gcGFyYSB7dHVuZWRfY2h1bmtfb3ZlcmxhcH0uIikKCiAgICBpZiBub3QgYmF0Y2hfc2l6ZV9sb2NrZWQ6CiAgICAgICAgbWF4X2NhbmRpZGF0ZSA9IDE2CiAgICAgICAgaWYgbWVtX3RvdGFsX2dpYiA8IDggb3IgbWVtX2F2YWlsYWJsZV9naWIgPCAzIG9yIHN3YXBfdG90YWxfZ2liIDwgMjoKICAgICAgICAgICAgbWF4X2NhbmRpZGF0ZSA9IDIKICAgICAgICBlbGlmIG1lbV90b3RhbF9naWIgPCAxNiBvciBtZW1fYXZhaWxhYmxlX2dpYiA8IDY6CiAgICAgICAgICAgIG1heF9jYW5kaWRhdGUgPSA0CiAgICAgICAgZWxpZiBtZW1fdG90YWxfZ2liIDwgMzIgb3IgbWVtX2F2YWlsYWJsZV9naWIgPCAxMDoKICAgICAgICAgICAgbWF4X2NhbmRpZGF0ZSA9IDgKCiAgICAgICAgY2FuZGlkYXRlcyA9IFsyLCA0LCA2LCA4LCAxMiwgMTZdCiAgICAgICAgY2FuZGlkYXRlcyA9IFtjIGZvciBjIGluIGNhbmRpZGF0ZXMgaWYgYyA8PSBtYXhfY2FuZGlkYXRlXQogICAgICAgIGlmIG5vdCBjYW5kaWRhdGVzOgogICAgICAgICAgICBjYW5kaWRhdGVzID0gWzJdCgogICAgICAgIHByb2Nlc3MgPSBwc3V0aWwuUHJvY2VzcygpCiAgICAgICAgc2FtcGxlX3NpemUgPSBtaW4obWF4KDUxMiwgdHVuZWRfY2h1bmtfc2l6ZSksIDMwMDApCiAgICAgICAgc2FtcGxlX3RleHQgPSAoIiMgYXV0b3R1bmUtc2FtcGxlXG4iICsgKCJ4IiAqIHNhbXBsZV9zaXplKSkKCiAgICAgICAgYmVzdF9iYXRjaCA9IGNhbmRpZGF0ZXNbMF0KICAgICAgICBiZXN0X3Njb3JlID0gLTEuMAogICAgICAgIGJlc3RfbWVtb3J5X3BjdCA9IDEwMC4wCiAgICAgICAgc2VsZWN0ZWRfYmVuY2htYXJrX2xpbmU6IHN0ciB8IE5vbmUgPSBOb25lCiAgICAgICAgYmVuY2htYXJrX2xpbmVzOiBsaXN0W3N0cl0gPSBbXQoKICAgICAgICAjIFdhcm11cCBjdXJ0byBwYXJhIGVzdGFiaWxpemFyIGNhY2hlIGludGVybm8uCiAgICAgICAgdHJ5OgogICAgICAgICAgICBfID0gbW9kZWwuZW5jb2RlKFtzYW1wbGVfdGV4dF0sIHNob3dfcHJvZ3Jlc3NfYmFyPUZhbHNlLCBiYXRjaF9zaXplPTEpCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICAgICAgcGFzcwoKICAgICAgICBmb3IgY2FuZGlkYXRlIGluIGNhbmRpZGF0ZXM6CiAgICAgICAgICAgIGRvY3MgPSBbc2FtcGxlX3RleHRdICogY2FuZGlkYXRlCiAgICAgICAgICAgIGdjLmNvbGxlY3QoKQogICAgICAgICAgICBiZWZvcmVfdm0gPSBwc3V0aWwudmlydHVhbF9tZW1vcnkoKS5wZXJjZW50CiAgICAgICAgICAgIGJlZm9yZV9yc3MgPSBwcm9jZXNzLm1lbW9yeV9pbmZvKCkucnNzIC8gKDEwMjQqKjIpCiAgICAgICAgICAgIHN0YXJ0ZWQgPSBwZXJmX2NvdW50ZXIoKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBlbWJlZGRpbmdzID0gbW9kZWwuZW5jb2RlKAogICAgICAgICAgICAgICAgICAgIGRvY3MsCiAgICAgICAgICAgICAgICAgICAgc2hvd19wcm9ncmVzc19iYXI9RmFsc2UsCiAgICAgICAgICAgICAgICAgICAgYmF0Y2hfc2l6ZT1jYW5kaWRhdGUsCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICAgICAgICAgIGJlbmNobWFya19saW5lcy5hcHBlbmQoZiJiYXRjaD17Y2FuZGlkYXRlfTogZXJybyAoe2V9KSIpCiAgICAgICAgICAgICAgICBjb250aW51ZQoKICAgICAgICAgICAgZWxhcHNlZCA9IG1heChwZXJmX2NvdW50ZXIoKSAtIHN0YXJ0ZWQsIDFlLTYpCiAgICAgICAgICAgIGFmdGVyX3ZtID0gcHN1dGlsLnZpcnR1YWxfbWVtb3J5KCkucGVyY2VudAogICAgICAgICAgICBhZnRlcl9yc3MgPSBwcm9jZXNzLm1lbW9yeV9pbmZvKCkucnNzIC8gKDEwMjQqKjIpCiAgICAgICAgICAgIGRlbCBlbWJlZGRpbmdzCiAgICAgICAgICAgIGdjLmNvbGxlY3QoKQoKICAgICAgICAgICAgdGhyb3VnaHB1dCA9IGNhbmRpZGF0ZSAvIGVsYXBzZWQKICAgICAgICAgICAgc2FmZSA9IGFmdGVyX3ZtIDw9ICh0YXJnZXRfcmFtX3BlcmNlbnQgKyAzLjApCiAgICAgICAgICAgIGJlbmNobWFya19saW5lcy5hcHBlbmQoCiAgICAgICAgICAgICAgICBmImJhdGNoPXtjYW5kaWRhdGV9OiB7dGhyb3VnaHB1dDouMmZ9IGl0ZW5zL3MsIHZtPXthZnRlcl92bTouMWZ9JSwgcnNzX2RlbHRhPXthZnRlcl9yc3MgLSBiZWZvcmVfcnNzOisuMWZ9IE1pQiIKICAgICAgICAgICAgKQoKICAgICAgICAgICAgaWYgc2FmZSBhbmQgdGhyb3VnaHB1dCA+IGJlc3Rfc2NvcmU6CiAgICAgICAgICAgICAgICBiZXN0X3Njb3JlID0gdGhyb3VnaHB1dAogICAgICAgICAgICAgICAgYmVzdF9iYXRjaCA9IGNhbmRpZGF0ZQogICAgICAgICAgICAgICAgYmVzdF9tZW1vcnlfcGN0ID0gYWZ0ZXJfdm0KICAgICAgICAgICAgICAgIHNlbGVjdGVkX2JlbmNobWFya19saW5lID0gYmVuY2htYXJrX2xpbmVzWy0xXQogICAgICAgICAgICBlbGlmIGJlc3Rfc2NvcmUgPCAwIGFuZCBhZnRlcl92bSA8IGJlc3RfbWVtb3J5X3BjdDoKICAgICAgICAgICAgICAgICMgU2UgbmVuaHVtIGNhbmRpZGF0byBmaWNvdSAic2FmZSIsIGVzY29saGUgbyBtZW5vcyBhZ3Jlc3Npdm8gZW0gbWVtw7NyaWEuCiAgICAgICAgICAgICAgICBiZXN0X2JhdGNoID0gY2FuZGlkYXRlCiAgICAgICAgICAgICAgICBiZXN0X21lbW9yeV9wY3QgPSBhZnRlcl92bQogICAgICAgICAgICAgICAgc2VsZWN0ZWRfYmVuY2htYXJrX2xpbmUgPSBiZW5jaG1hcmtfbGluZXNbLTFdCgogICAgICAgICAgICAjIFNlIGrDoSBwYXNzb3UgbXVpdG8gZG8gbGltaXRlLCBldml0YSB0ZW50YXIgYmF0Y2hlcyBtYWlvcmVzLgogICAgICAgICAgICBpZiBhZnRlcl92bSA+IHRhcmdldF9yYW1fcGVyY2VudCArIDguMDoKICAgICAgICAgICAgICAgIGJyZWFrCgogICAgICAgICAgICAjIEV2aXRhIGVzY29saGVyIGNhbmRpZGF0byBxdWUgasOhIGNvbWXDp291IGFjaW1hIGRvIGxpbWl0ZS4KICAgICAgICAgICAgaWYgYmVmb3JlX3ZtID4gdGFyZ2V0X3JhbV9wZXJjZW50ICsgNS4wOgogICAgICAgICAgICAgICAgYnJlYWsKCiAgICAgICAgdHVuZWRfYmF0Y2ggPSBtYXgoMSwgYmVzdF9iYXRjaCkKICAgICAgICBpZiB2ZXJib3NlX2F1dG90dW5lOgogICAgICAgICAgICByZWFzb25zLmV4dGVuZChiZW5jaG1hcmtfbGluZXMpCiAgICAgICAgZWxpZiBzZWxlY3RlZF9iZW5jaG1hcmtfbGluZToKICAgICAgICAgICAgcmVhc29ucy5hcHBlbmQoZiJNaWNyby1iZW5jaG1hcms6IHtzZWxlY3RlZF9iZW5jaG1hcmtfbGluZX0iKQogICAgICAgIHJlYXNvbnMuYXBwZW5kKAogICAgICAgICAgICBmImVtYmVkZGluZ19iYXRjaF9zaXplIGF1dG90dW5hZG8gcGFyYSB7dHVuZWRfYmF0Y2h9IChhbHZvIGRlIG1lbcOzcmlhOiB7dGFyZ2V0X3JhbV9wZXJjZW50Oi4xZn0lKS4iCiAgICAgICAgKQoKICAgIHJldHVybiBSdW50aW1lSW5kZXhpbmdQYXJhbXMoCiAgICAgICAgY2h1bmtfc2l6ZT10dW5lZF9jaHVua19zaXplLAogICAgICAgIGNodW5rX292ZXJsYXA9dHVuZWRfY2h1bmtfb3ZlcmxhcCwKICAgICAgICBlbWJlZGRpbmdfYmF0Y2hfc2l6ZT1tYXgoMSwgdHVuZWRfYmF0Y2gpLAogICAgICAgIHJlYXNvbnM9cmVhc29ucywKICAgICkKCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIEZ1bsOnw7VlcyBhdXhpbGlhcmVzCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpkZWYgZ2V0X3RleHRfc3BsaXR0ZXIoY2h1bmtfc2l6ZTogaW50LCBjaHVua19vdmVybGFwOiBpbnQpIC0+IFJlY3Vyc2l2ZUNoYXJhY3RlclRleHRTcGxpdHRlcjoKICAgICIiIlJldG9ybmEgbyBzcGxpdHRlciBjb21wYXJ0aWxoYWRvIGNvbSBhcyBjb25maWd1cmHDp8O1ZXMgcGFkcsOjbyBkbyBwcm9qZXRvLiIiIgogICAgcmV0dXJuIFJlY3Vyc2l2ZUNoYXJhY3RlclRleHRTcGxpdHRlcigKICAgICAgICBjaHVua19zaXplPWNodW5rX3NpemUsCiAgICAgICAgY2h1bmtfb3ZlcmxhcD1jaHVua19vdmVybGFwLAogICAgICAgIGxlbmd0aF9mdW5jdGlvbj1sZW4sCiAgICAgICAgc2VwYXJhdG9ycz1bIlxuXG4iLCAiXG4iLCAiICIsICIiXSwKICAgICkKCgpkZWYgbG9hZF9lbWJlZGRpbmdfbW9kZWwobW9kZWxfY2hvaWNlOiBzdHIsIGppbmFfcXVhbnRpemF0aW9uOiBzdHIpIC0+IFNlbnRlbmNlVHJhbnNmb3JtZXI6CiAgICAiIiJDYXJyZWdhIG8gbW9kZWxvIGRlIGVtYmVkZGluZ3MgZm9yw6dhbmRvIHVzbyBkZSBDUFUuIiIiCiAgICBlbWJlZGRpbmdfbW9kZWxfaWQgPSBfcmVzb2x2ZV9tb2RlbF9pZChtb2RlbF9jaG9pY2UpCiAgICBmYWxsYmFja19tb2RlbF9pZCA9IF9yZXNvbHZlX2ZhbGxiYWNrX21vZGVsX2lkKG1vZGVsX2Nob2ljZSkKCiAgICBtb2RlbF9iYXNlX2RpciA9IE1PREVMX0NBQ0hFX0JBU0VfRElSCiAgICBtb2RlbF9iYXNlX2Rpci5ta2RpcihwYXJlbnRzPVRydWUsIGV4aXN0X29rPVRydWUpCiAgICBwcmVmZXJyZWRfbW9kZWxfY2FjaGVfZGlyID0gX21vZGVsX2NhY2hlX2Rpcihtb2RlbF9iYXNlX2RpciwgZW1iZWRkaW5nX21vZGVsX2lkKQoKICAgIHByaW50KGYiWytdIEJhaXhhbmRvIG1vZGVsbyBwcmVmZXJpZG86IHtlbWJlZGRpbmdfbW9kZWxfaWR9IikKICAgIHByaW50KGYiWytdIERpcmV0w7NyaW8gZGUgZG93bmxvYWQvY2FjaGUgZG8gbW9kZWxvOiB7cHJlZmVycmVkX21vZGVsX2NhY2hlX2Rpcn0iKQogICAgc2VsZWN0aW9uID0gZG93bmxvYWRfbW9kZWxfd2l0aF9mYWxsYmFjaygKICAgICAgICBwcmVmZXJyZWRfbW9kZWxfaWQ9ZW1iZWRkaW5nX21vZGVsX2lkLAogICAgICAgIGZhbGxiYWNrX21vZGVsX2lkPWZhbGxiYWNrX21vZGVsX2lkLAogICAgICAgIGxvY2FsX2Rpcj1tb2RlbF9iYXNlX2RpciwKICAgICkKICAgIHNlbGVjdGVkX21vZGVsX2RpciA9IHNlbGVjdGlvbi5sb2NhbF9kaXIKICAgIHByaW50KAogICAgICAgIGYiWytdIE1vZGVsbyBzZWxlY2lvbmFkbzoge3NlbGVjdGlvbi5tb2RlbF9pZH0gIgogICAgICAgIGYiKHByb3ZpZGVyPXtzZWxlY3Rpb24ucHJvdmlkZXJ9LCBwYXRoPXtzZWxlY3RlZF9tb2RlbF9kaXJ9KSIKICAgICkKCiAgICBkZWYgX2NsZWFyX2hmX2R5bmFtaWNfbW9kdWxlc19jYWNoZSgpIC0+IE5vbmU6CiAgICAgICAgY2FjaGVfZGlyID0gUGF0aC5ob21lKCkgLyAiLmNhY2hlIiAvICJodWdnaW5nZmFjZSIgLyAibW9kdWxlcyIgLyAidHJhbnNmb3JtZXJzX21vZHVsZXMiCiAgICAgICAgaWYgY2FjaGVfZGlyLmV4aXN0cygpOgogICAgICAgICAgICBwcmludChmIlshXSBMaW1wYW5kbyBjYWNoZSBkZSBtw7NkdWxvcyBkaW7Dom1pY29zIGRvIEh1Z2dpbmcgRmFjZToge2NhY2hlX2Rpcn0iKQogICAgICAgICAgICBzaHV0aWwucm10cmVlKGNhY2hlX2RpciwgaWdub3JlX2Vycm9ycz1UcnVlKQoKICAgIGRlZiBfbG9hZF9mcm9tX2xvY2FsX2Rpcihtb2RlbF9pZDogc3RyKSAtPiBTZW50ZW5jZVRyYW5zZm9ybWVyOgogICAgICAgICMgTyBtb2RlbG8gZGEgSmluYSBkZXBlbmRlIGRlIGPDs2RpZ28gcmVtb3RvOyBmYWxsYmFjayBub3JtYWxtZW50ZSBuw6NvLgogICAgICAgIHRydXN0X3JlbW90ZV9jb2RlID0gbW9kZWxfaWQuc3RhcnRzd2l0aCgiamluYWFpLyIpCiAgICAgICAgdG9rZW5pemVyX2t3YXJncyA9IHsiZml4X21pc3RyYWxfcmVnZXgiOiBUcnVlfQoKICAgICAgICBkZWYgX2luc3RhbnRpYXRlX21vZGVsKCkgLT4gU2VudGVuY2VUcmFuc2Zvcm1lcjoKICAgICAgICAgICAgcmV0dXJuIFNlbnRlbmNlVHJhbnNmb3JtZXIoCiAgICAgICAgICAgICAgICBzdHIoc2VsZWN0ZWRfbW9kZWxfZGlyKSwKICAgICAgICAgICAgICAgIGRldmljZT0iY3B1IiwKICAgICAgICAgICAgICAgIHRydXN0X3JlbW90ZV9jb2RlPXRydXN0X3JlbW90ZV9jb2RlLAogICAgICAgICAgICAgICAgdG9rZW5pemVyX2t3YXJncz10b2tlbml6ZXJfa3dhcmdzLAogICAgICAgICAgICApCgogICAgICAgIGRlZiBfbG9hZF93aXRoX21pc3RyYWxfcmVnZXhfcGF0Y2goKSAtPiBTZW50ZW5jZVRyYW5zZm9ybWVyOgogICAgICAgICAgICAjIE8gY8OzZGlnbyByZW1vdG8gZGEgSmluYSBpbnN0YW5jaWEgdW0gdG9rZW5pemVyIGludGVybm8gc2VtIHJlcGFzc2FyIHRva2VuaXplcl9rd2FyZ3MuCiAgICAgICAgICAgIGlmIG5vdCB0cnVzdF9yZW1vdGVfY29kZToKICAgICAgICAgICAgICAgIHJldHVybiBfaW5zdGFudGlhdGVfbW9kZWwoKQoKICAgICAgICAgICAgZnJvbSB0cmFuc2Zvcm1lcnMgaW1wb3J0IEF1dG9Nb2RlbCwgQXV0b1Rva2VuaXplcgogICAgICAgICAgICBmcm9tIHRyYW5zZm9ybWVycy5tb2RlbGluZ191dGlscyBpbXBvcnQgUHJlVHJhaW5lZE1vZGVsCgogICAgICAgICAgICBvcmlnaW5hbF9mcm9tX3ByZXRyYWluZWQgPSBBdXRvVG9rZW5pemVyLmZyb21fcHJldHJhaW5lZAogICAgICAgICAgICBvcmlnaW5hbF9tb2RlbF9mcm9tX3ByZXRyYWluZWQgPSBBdXRvTW9kZWwuZnJvbV9wcmV0cmFpbmVkCiAgICAgICAgICAgIG9yaWdpbmFsX3ByZXRyYWluZWRfbW9kZWxfZnJvbV9wcmV0cmFpbmVkID0gUHJlVHJhaW5lZE1vZGVsLmZyb21fcHJldHJhaW5lZAogICAgICAgICAgICBvcmlnaW5hbF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fY29uZmlnID0gUHJlVHJhaW5lZE1vZGVsLl9mcm9tX2NvbmZpZwogICAgICAgICAgICBtb2RlbF9yZWZzID0ge3N0cihzZWxlY3RlZF9tb2RlbF9kaXIpLCBzdHIoc2VsZWN0ZWRfbW9kZWxfZGlyLnJlc29sdmUoKSl9CgogICAgICAgICAgICBkZWYgX3BhdGNoZWRfZnJvbV9wcmV0cmFpbmVkKCphcmdzLCAqKmt3YXJncyk6CiAgICAgICAgICAgICAgICBtb2RlbF9yZWYgPSBhcmdzWzBdIGlmIGFyZ3MgZWxzZSBrd2FyZ3MuZ2V0KCJwcmV0cmFpbmVkX21vZGVsX25hbWVfb3JfcGF0aCIpCiAgICAgICAgICAgICAgICBpZiBtb2RlbF9yZWYgaXMgbm90IE5vbmUgYW5kIHN0cihtb2RlbF9yZWYpIGluIG1vZGVsX3JlZnM6CiAgICAgICAgICAgICAgICAgICAga3dhcmdzLnNldGRlZmF1bHQoImZpeF9taXN0cmFsX3JlZ2V4IiwgVHJ1ZSkKICAgICAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbF9mcm9tX3ByZXRyYWluZWQoKmFyZ3MsICoqa3dhcmdzKQoKICAgICAgICAgICAgZGVmIF9wYXRjaGVkX21vZGVsX2Zyb21fcHJldHJhaW5lZCgqYXJncywgKiprd2FyZ3MpOgogICAgICAgICAgICAgICAgbW9kZWxfcmVmID0gYXJnc1swXSBpZiBhcmdzIGVsc2Uga3dhcmdzLmdldCgicHJldHJhaW5lZF9tb2RlbF9uYW1lX29yX3BhdGgiKQogICAgICAgICAgICAgICAgaWYgbW9kZWxfcmVmIGlzIG5vdCBOb25lIGFuZCBzdHIobW9kZWxfcmVmKSBpbiBtb2RlbF9yZWZzIGFuZCAidG9yY2hfZHR5cGUiIGluIGt3YXJnczoKICAgICAgICAgICAgICAgICAgICBrd2FyZ3MgPSBkaWN0KGt3YXJncykKICAgICAgICAgICAgICAgICAgICBpZiAiZHR5cGUiIG5vdCBpbiBrd2FyZ3M6CiAgICAgICAgICAgICAgICAgICAgICAgIGt3YXJnc1siZHR5cGUiXSA9IGt3YXJnc1sidG9yY2hfZHR5cGUiXQogICAgICAgICAgICAgICAgICAgIGt3YXJncy5wb3AoInRvcmNoX2R0eXBlIiwgTm9uZSkKICAgICAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbF9tb2RlbF9mcm9tX3ByZXRyYWluZWQoKmFyZ3MsICoqa3dhcmdzKQoKICAgICAgICAgICAgb3JpZ2luYWxfcHJldHJhaW5lZF9tb2RlbF9mcm9tX3ByZXRyYWluZWRfZm4gPSBvcmlnaW5hbF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fcHJldHJhaW5lZC5fX2Z1bmNfXwoKICAgICAgICAgICAgQGNsYXNzbWV0aG9kCiAgICAgICAgICAgIGRlZiBfcGF0Y2hlZF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fcHJldHJhaW5lZChjbHMsICphcmdzLCAqKmt3YXJncyk6CiAgICAgICAgICAgICAgICBpZiAidG9yY2hfZHR5cGUiIGluIGt3YXJnczoKICAgICAgICAgICAgICAgICAgICBrd2FyZ3MgPSBkaWN0KGt3YXJncykKICAgICAgICAgICAgICAgICAgICBpZiAiZHR5cGUiIG5vdCBpbiBrd2FyZ3M6CiAgICAgICAgICAgICAgICAgICAgICAgIGt3YXJnc1siZHR5cGUiXSA9IGt3YXJnc1sidG9yY2hfZHR5cGUiXQogICAgICAgICAgICAgICAgICAgIGt3YXJncy5wb3AoInRvcmNoX2R0eXBlIiwgTm9uZSkKICAgICAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fcHJldHJhaW5lZF9mbihjbHMsICphcmdzLCAqKmt3YXJncykKCiAgICAgICAgICAgIG9yaWdpbmFsX3ByZXRyYWluZWRfbW9kZWxfZnJvbV9jb25maWdfZm4gPSBvcmlnaW5hbF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fY29uZmlnLl9fZnVuY19fCgogICAgICAgICAgICBAY2xhc3NtZXRob2QKICAgICAgICAgICAgZGVmIF9wYXRjaGVkX3ByZXRyYWluZWRfbW9kZWxfZnJvbV9jb25maWcoY2xzLCAqYXJncywgKiprd2FyZ3MpOgogICAgICAgICAgICAgICAgaWYgInRvcmNoX2R0eXBlIiBpbiBrd2FyZ3M6CiAgICAgICAgICAgICAgICAgICAga3dhcmdzID0gZGljdChrd2FyZ3MpCiAgICAgICAgICAgICAgICAgICAgaWYgImR0eXBlIiBub3QgaW4ga3dhcmdzOgogICAgICAgICAgICAgICAgICAgICAgICBrd2FyZ3NbImR0eXBlIl0gPSBrd2FyZ3NbInRvcmNoX2R0eXBlIl0KICAgICAgICAgICAgICAgICAgICBrd2FyZ3MucG9wKCJ0b3JjaF9kdHlwZSIsIE5vbmUpCiAgICAgICAgICAgICAgICByZXR1cm4gb3JpZ2luYWxfcHJldHJhaW5lZF9tb2RlbF9mcm9tX2NvbmZpZ19mbihjbHMsICphcmdzLCAqKmt3YXJncykKCiAgICAgICAgICAgIEF1dG9Ub2tlbml6ZXIuZnJvbV9wcmV0cmFpbmVkID0gX3BhdGNoZWRfZnJvbV9wcmV0cmFpbmVkCiAgICAgICAgICAgIEF1dG9Nb2RlbC5mcm9tX3ByZXRyYWluZWQgPSBfcGF0Y2hlZF9tb2RlbF9mcm9tX3ByZXRyYWluZWQKICAgICAgICAgICAgUHJlVHJhaW5lZE1vZGVsLmZyb21fcHJldHJhaW5lZCA9IF9wYXRjaGVkX3ByZXRyYWluZWRfbW9kZWxfZnJvbV9wcmV0cmFpbmVkCiAgICAgICAgICAgIFByZVRyYWluZWRNb2RlbC5fZnJvbV9jb25maWcgPSBfcGF0Y2hlZF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fY29uZmlnCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHJldHVybiBfaW5zdGFudGlhdGVfbW9kZWwoKQogICAgICAgICAgICBmaW5hbGx5OgogICAgICAgICAgICAgICAgQXV0b1Rva2VuaXplci5mcm9tX3ByZXRyYWluZWQgPSBvcmlnaW5hbF9mcm9tX3ByZXRyYWluZWQKICAgICAgICAgICAgICAgIEF1dG9Nb2RlbC5mcm9tX3ByZXRyYWluZWQgPSBvcmlnaW5hbF9tb2RlbF9mcm9tX3ByZXRyYWluZWQKICAgICAgICAgICAgICAgIFByZVRyYWluZWRNb2RlbC5mcm9tX3ByZXRyYWluZWQgPSBvcmlnaW5hbF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fcHJldHJhaW5lZAogICAgICAgICAgICAgICAgUHJlVHJhaW5lZE1vZGVsLl9mcm9tX2NvbmZpZyA9IG9yaWdpbmFsX3ByZXRyYWluZWRfbW9kZWxfZnJvbV9jb25maWcKCiAgICAgICAgcHJpbnQoZiJbK10gQ2FycmVnYW5kbyBtb2RlbG8gZGUgZW1iZWRkaW5ncyBhIHBhcnRpciBkZToge3NlbGVjdGVkX21vZGVsX2Rpcn0gKENQVSkuLi4iKQogICAgICAgIHRyeToKICAgICAgICAgICAgcmV0dXJuIF9sb2FkX3dpdGhfbWlzdHJhbF9yZWdleF9wYXRjaCgpCiAgICAgICAgZXhjZXB0IEZpbGVOb3RGb3VuZEVycm9yIGFzIGU6CiAgICAgICAgICAgICMgQ29ycmlnZSBjb3JydXDDp8Ojby9pbmNvbXBsZXR1ZGUgbm8gY2FjaGUgZGluw6JtaWNvIGRvIHRyYW5zZm9ybWVycy4KICAgICAgICAgICAgaWYgdHJ1c3RfcmVtb3RlX2NvZGUgYW5kICJ0cmFuc2Zvcm1lcnNfbW9kdWxlcyIgaW4gc3RyKGUpOgogICAgICAgICAgICAgICAgcHJpbnQoZiJbIV0gQ2FjaGUgZGluw6JtaWNvIGluY29uc2lzdGVudGUgZGV0ZWN0YWRvOiB7ZX0iKQogICAgICAgICAgICAgICAgX2NsZWFyX2hmX2R5bmFtaWNfbW9kdWxlc19jYWNoZSgpCiAgICAgICAgICAgICAgICByZXR1cm4gX2xvYWRfd2l0aF9taXN0cmFsX3JlZ2V4X3BhdGNoKCkKICAgICAgICAgICAgcmFpc2UKCiAgICBkZWYgX2FwcGx5X2ppbmFfcXVhbnRpemF0aW9uX2lmX25lZWRlZChtb2RlbDogU2VudGVuY2VUcmFuc2Zvcm1lciwgbW9kZWxfaWQ6IHN0cikgLT4gU2VudGVuY2VUcmFuc2Zvcm1lcjoKICAgICAgICBpZiBtb2RlbF9pZCAhPSBKSU5BX1YzX0VNQkVERElOR19NT0RFTCBvciBqaW5hX3F1YW50aXphdGlvbiA9PSAiZGVmYXVsdCI6CiAgICAgICAgICAgIHJldHVybiBtb2RlbAogICAgICAgIHRyeToKICAgICAgICAgICAgaW1wb3J0IHRvcmNoCiAgICAgICAgICAgIGltcG9ydCB3YXJuaW5ncwoKICAgICAgICAgICAgcXVhbnRpemVkX2xheWVycyA9IDAKICAgICAgICAgICAgZm9yIG1vZHVsZSBpbiBtb2RlbC5tb2R1bGVzKCk6CiAgICAgICAgICAgICAgICBpZiB0eXBlKG1vZHVsZSkuX19uYW1lX18gIT0gIlBhcmFtZXRyaXplZExpbmVhciI6CiAgICAgICAgICAgICAgICAgICAgY29udGludWUKCiAgICAgICAgICAgICAgICBmbG9hdF9saW5lYXIgPSB0b3JjaC5ubi5MaW5lYXIoCiAgICAgICAgICAgICAgICAgICAgbW9kdWxlLmluX2ZlYXR1cmVzLAogICAgICAgICAgICAgICAgICAgIG1vZHVsZS5vdXRfZmVhdHVyZXMsCiAgICAgICAgICAgICAgICAgICAgYmlhcz1tb2R1bGUuYmlhcyBpcyBub3QgTm9uZSwKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIHdpdGggdG9yY2gubm9fZ3JhZCgpOgogICAgICAgICAgICAgICAgICAgIGZsb2F0X2xpbmVhci53ZWlnaHQuY29weV8obW9kdWxlLndlaWdodC5kZXRhY2goKS50byh0b3JjaC5mbG9hdDMyKSkKICAgICAgICAgICAgICAgICAgICBpZiBtb2R1bGUuYmlhcyBpcyBub3QgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXRfbGluZWFyLmJpYXMuY29weV8obW9kdWxlLmJpYXMuZGV0YWNoKCkudG8odG9yY2guZmxvYXQzMikpCgogICAgICAgICAgICAgICAgd2l0aCB3YXJuaW5ncy5jYXRjaF93YXJuaW5ncygpOgogICAgICAgICAgICAgICAgICAgIHdhcm5pbmdzLmZpbHRlcndhcm5pbmdzKCJpZ25vcmUiLCBjYXRlZ29yeT1EZXByZWNhdGlvbldhcm5pbmcpCiAgICAgICAgICAgICAgICAgICAgcXVhbnRpemVkX2xpbmVhciA9IHRvcmNoLnF1YW50aXphdGlvbi5xdWFudGl6ZV9keW5hbWljKAogICAgICAgICAgICAgICAgICAgICAgICB0b3JjaC5ubi5TZXF1ZW50aWFsKGZsb2F0X2xpbmVhciksCiAgICAgICAgICAgICAgICAgICAgICAgIHt0b3JjaC5ubi5MaW5lYXJ9LAogICAgICAgICAgICAgICAgICAgICAgICBkdHlwZT10b3JjaC5xaW50OCwKICAgICAgICAgICAgICAgICAgICApWzBdCgogICAgICAgICAgICAgICAgbW9kdWxlLl9keW5hbWljX2ludDhfbGluZWFyID0gcXVhbnRpemVkX2xpbmVhcgoKICAgICAgICAgICAgICAgIGRlZiBfZm9yd2FyZF9keW5hbWljX2ludDgoc2VsZiwgaW5wdXQsIHRhc2tfaWQ9Tm9uZSwgcmVzaWR1YWw9RmFsc2UpOgogICAgICAgICAgICAgICAgICAgIG91dCA9IHNlbGYuX2R5bmFtaWNfaW50OF9saW5lYXIoaW5wdXQpCiAgICAgICAgICAgICAgICAgICAgaWYgcmVzaWR1YWw6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvdXQsIGlucHV0CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG91dAoKICAgICAgICAgICAgICAgIG1vZHVsZS5mb3J3YXJkID0gX2ZvcndhcmRfZHluYW1pY19pbnQ4Ll9fZ2V0X18obW9kdWxlLCBtb2R1bGUuX19jbGFzc19fKQogICAgICAgICAgICAgICAgcXVhbnRpemVkX2xheWVycyArPSAxCgogICAgICAgICAgICBpZiBxdWFudGl6ZWRfbGF5ZXJzID09IDA6CiAgICAgICAgICAgICAgICBwcmludCgKICAgICAgICAgICAgICAgICAgICAiW0FWSVNPXSBOZW5odW1hIGNhbWFkYSBQYXJhbWV0cml6ZWRMaW5lYXIgZW5jb250cmFkYSBwYXJhIGR5bmFtaWMtaW50ODsgdXNhbmRvIG1vZGVsbyBwYWRyYW8uIgogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgcmV0dXJuIG1vZGVsCgogICAgICAgICAgICBwcmludChmIlsrXSBRdWFudGl6YWNhbyBKaW5hIGFwbGljYWRhOiBkeW5hbWljLWludDggKENQVSwge3F1YW50aXplZF9sYXllcnN9IGNhbWFkYXMpLiIpCiAgICAgICAgICAgIHJldHVybiBtb2RlbAogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgcXVhbnRfZXJyb3I6CiAgICAgICAgICAgIHByaW50KGYiW0FWSVNPXSBGYWxoYSBhbyBhcGxpY2FyIGR5bmFtaWMtaW50OCAoe3F1YW50X2Vycm9yfSk7IHVzYW5kbyBtb2RlbG8gcGFkcmFvLiIpCiAgICAgICAgICAgIHJldHVybiBtb2RlbAoKICAgIHRyeToKICAgICAgICBtb2RlbCA9IF9sb2FkX2Zyb21fbG9jYWxfZGlyKHNlbGVjdGlvbi5tb2RlbF9pZCkKICAgICAgICBtb2RlbCA9IF9hcHBseV9qaW5hX3F1YW50aXphdGlvbl9pZl9uZWVkZWQobW9kZWwsIHNlbGVjdGlvbi5tb2RlbF9pZCkKICAgICAgICBwcmludCgiWytdIE1vZGVsbyBjYXJyZWdhZG8gY29tIHN1Y2Vzc28uIikKICAgICAgICByZXR1cm4gbW9kZWwKICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZmlyc3RfZXJyb3I6CiAgICAgICAgaWYgc2VsZWN0aW9uLm1vZGVsX2lkID09IGZhbGxiYWNrX21vZGVsX2lkOgogICAgICAgICAgICByYWlzZSBSdW50aW1lRXJyb3IoCiAgICAgICAgICAgICAgICBmIkZhbGhhIGFvIGNhcnJlZ2FyIG8gbW9kZWxvIGZhbGxiYWNrICd7ZmFsbGJhY2tfbW9kZWxfaWR9Jzoge2ZpcnN0X2Vycm9yfSIKICAgICAgICAgICAgKSBmcm9tIGZpcnN0X2Vycm9yCgogICAgICAgIHByaW50KAogICAgICAgICAgICBmIlshXSBGYWxoYSBhbyBjYXJyZWdhciAne3NlbGVjdGlvbi5tb2RlbF9pZH0nOiB7X2Zvcm1hdF9leGNlcHRpb24oZmlyc3RfZXJyb3IpfVxuIgogICAgICAgICAgICBmIiAgICBUZW50YW5kbyBmYWxsYmFjayBkZSBjYXJyZWdhbWVudG86IHtmYWxsYmFja19tb2RlbF9pZH0iCiAgICAgICAgKQogICAgICAgIGZhbGxiYWNrX3NlbGVjdGlvbiA9IGRvd25sb2FkX21vZGVsX3dpdGhfZmFsbGJhY2soCiAgICAgICAgICAgIHByZWZlcnJlZF9tb2RlbF9pZD1mYWxsYmFja19tb2RlbF9pZCwKICAgICAgICAgICAgZmFsbGJhY2tfbW9kZWxfaWQ9ZmFsbGJhY2tfbW9kZWxfaWQsCiAgICAgICAgICAgIGxvY2FsX2Rpcj1tb2RlbF9iYXNlX2RpciwKICAgICAgICApCiAgICAgICAgc2VsZWN0ZWRfbW9kZWxfZGlyID0gZmFsbGJhY2tfc2VsZWN0aW9uLmxvY2FsX2RpcgogICAgICAgIHByaW50KAogICAgICAgICAgICBmIlsrXSBNb2RlbG8gc2VsZWNpb25hZG86IHtmYWxsYmFja19zZWxlY3Rpb24ubW9kZWxfaWR9ICIKICAgICAgICAgICAgZiIocHJvdmlkZXI9e2ZhbGxiYWNrX3NlbGVjdGlvbi5wcm92aWRlcn0sIHBhdGg9e3NlbGVjdGVkX21vZGVsX2Rpcn0pIgogICAgICAgICkKICAgICAgICBtb2RlbCA9IF9sb2FkX2Zyb21fbG9jYWxfZGlyKGZhbGxiYWNrX3NlbGVjdGlvbi5tb2RlbF9pZCkKICAgICAgICBtb2RlbCA9IF9hcHBseV9qaW5hX3F1YW50aXphdGlvbl9pZl9uZWVkZWQobW9kZWwsIGZhbGxiYWNrX3NlbGVjdGlvbi5tb2RlbF9pZCkKICAgICAgICBwcmludCgiWytdIE1vZGVsbyBmYWxsYmFjayBjYXJyZWdhZG8gY29tIHN1Y2Vzc28uIikKICAgICAgICByZXR1cm4gbW9kZWwKCgpkZWYgY29ubmVjdF90b19jaHJvbWEoKSAtPiBjaHJvbWFkYi5IdHRwQ2xpZW50OgogICAgIiIiQ29uZWN0YSBhbyBDaHJvbWFEQiB2aWEgSFRUUCBlIHZhbGlkYSBhIGNvbmV4w6NvLiIiIgogICAgdHJ5OgogICAgICAgIGNsaWVudCA9IGNocm9tYWRiLkh0dHBDbGllbnQoaG9zdD1DSFJPTUFfSE9TVCwgcG9ydD1DSFJPTUFfUE9SVCwgc3NsPUNIUk9NQV9TU0wpCiAgICAgICAgIyBGYXogdW0gaGVhcnRiZWF0IHBhcmEgY29uZmlybWFyIHF1ZSBvIHNlcnZpZG9yIGVzdMOhIG5vIGFyCiAgICAgICAgY2xpZW50LmhlYXJ0YmVhdCgpCiAgICAgICAgcHJpbnQoZiJbK10gQ29uZWN0YWRvIGFvIENocm9tYURCIGVtIHtDSFJPTUFfU0NIRU1FfTovL3tDSFJPTUFfSE9TVH06e0NIUk9NQV9QT1JUfSIpCiAgICAgICAgcmV0dXJuIGNsaWVudAogICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgIHByaW50KGYiW0VSUk9dIE7Do28gZm9pIHBvc3PDrXZlbCBjb25lY3RhciBhbyBDaHJvbWFEQjoge2V9IikKICAgICAgICBwcmludChmIiAgICAgICBFbmRwb2ludCBjb25maWd1cmFkbzoge0NIUk9NQV9TQ0hFTUV9Oi8ve0NIUk9NQV9IT1NUfTp7Q0hST01BX1BPUlR9IikKICAgICAgICBzeXMuZXhpdCgxKQoKCmRlZiBzY2FuX2ZpbGVzKHJvb3RfcGF0aDogUGF0aCkgLT4gSXRlcmF0b3JbUGF0aF06CiAgICAiIiIKICAgIFZhcnJlIHJlY3Vyc2l2YW1lbnRlIG8gZGlyZXTDs3JpbyByYWl6LCByZXRvcm5hbmRvIGVtIHN0cmVhbWluZwogICAgb3MgYXJxdWl2b3MgZGUgdGV4dG8gcmVsZXZhbnRlcyBwYXJhIGluZGV4YcOnw6NvLgogICAgIiIiCiAgICBmb3IgZGlycGF0aCwgZGlybmFtZXMsIGZpbGVuYW1lcyBpbiBvcy53YWxrKHJvb3RfcGF0aCk6CiAgICAgICAgIyBSZW1vdmUgZGlycyBpZ25vcmFkb3MgaW4tcGxhY2UgcGFyYSBxdWUgb3Mud2FsayBuw6NvIGRlc8OnYSBuZWxlcwogICAgICAgIGRpcm5hbWVzWzpdID0gWwogICAgICAgICAgICBkIGZvciBkIGluIGRpcm5hbWVzCiAgICAgICAgICAgIGlmIGQgbm90IGluIElHTk9SRURfRElSUyBhbmQgbm90IGQuc3RhcnRzd2l0aCgiLiIpCiAgICAgICAgXQogICAgICAgIGRpcm5hbWVzLnNvcnQoKQoKICAgICAgICBmb3IgZmlsZW5hbWUgaW4gc29ydGVkKGZpbGVuYW1lcyk6CiAgICAgICAgICAgIGZpbGVwYXRoID0gUGF0aChkaXJwYXRoKSAvIGZpbGVuYW1lCgogICAgICAgICAgICAjIElnbm9yYSBwb3IgZXh0ZW5zw6NvCiAgICAgICAgICAgIGlmIGZpbGVwYXRoLnN1ZmZpeC5sb3dlcigpIGluIElHTk9SRURfRVhURU5TSU9OUzoKICAgICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICAgICAjIElnbm9yYSBhcnF1aXZvcyBtdWl0byBncmFuZGVzCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGlmIGZpbGVwYXRoLnN0YXQoKS5zdF9zaXplID4gTUFYX0ZJTEVfU0laRV9CWVRFUzoKICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICBleGNlcHQgT1NFcnJvcjoKICAgICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICAgICB5aWVsZCBmaWxlcGF0aAoKCmRlZiBtYWtlX2NodW5rX2lkKGZpbGVfcGF0aDogc3RyLCBjaHVua19pbmRleDogaW50KSAtPiBzdHI6CiAgICAiIiJHZXJhIHVtIElEIGRldGVybWluw61zdGljbyBwYXJhIGNhZGEgY2h1bmsgYmFzZWFkbyBubyBjYW1pbmhvICsgw61uZGljZS4iIiIKICAgIHJhdyA9IGYie2ZpbGVfcGF0aH06OmNodW5rOjp7Y2h1bmtfaW5kZXh9IgogICAgcmV0dXJuIGhhc2hsaWIubWQ1KHJhdy5lbmNvZGUoKSkuaGV4ZGlnZXN0KCkKCgpkZWYgX2xvb2tzX2JpbmFyeV9jb250ZW50KHJhdzogYnl0ZXMpIC0+IGJvb2w6CiAgICAiIiJEZXRlY3RhIGNvbnRlw7pkbyBiaW7DoXJpbyBwb3IgaGV1csOtc3RpY2EgZW0gYW1vc3RyYSBkZSBieXRlcy4iIiIKICAgIGlmIG5vdCByYXc6CiAgICAgICAgcmV0dXJuIEZhbHNlCgogICAgc2FtcGxlID0gcmF3Wzo0MDk2XQogICAgaWYgYiJceDAwIiBpbiBzYW1wbGU6CiAgICAgICAgcmV0dXJuIFRydWUKCiAgICBub25fdGV4dF9ieXRlcyA9IDAKICAgIGZvciBieXRlIGluIHNhbXBsZToKICAgICAgICBpZiBieXRlIGluICg5LCAxMCwgMTMpOiAgIyBcdCBcbiBccgogICAgICAgICAgICBjb250aW51ZQogICAgICAgIGlmIDMyIDw9IGJ5dGUgPD0gMTI2OiAgIyBBU0NJSSBpbXByaW3DrXZlbAogICAgICAgICAgICBjb250aW51ZQogICAgICAgIGlmIDE2MCA8PSBieXRlIDw9IDI1NTogICMgTGF0aW4tMSBlc3RlbmRpZG8gY29tdW0gZW0gdGV4dG8KICAgICAgICAgICAgY29udGludWUKICAgICAgICBub25fdGV4dF9ieXRlcyArPSAxCgogICAgcmV0dXJuIChub25fdGV4dF9ieXRlcyAvIGxlbihzYW1wbGUpKSA+IDAuMzAKCgpkZWYgcmVhZF9maWxlX3NhZmUoZmlsZXBhdGg6IFBhdGgpIC0+IHN0ciB8IE5vbmU6CiAgICAiIiJMw6ogdW0gYXJxdWl2byBkZSB0ZXh0bywgZXZpdGFuZG8gYmluw6FyaW9zIGUgdGVudGFuZG8gbcO6bHRpcGxvcyBlbmNvZGluZ3MuIiIiCiAgICB0cnk6CiAgICAgICAgcmF3ID0gZmlsZXBhdGgucmVhZF9ieXRlcygpCiAgICBleGNlcHQgT1NFcnJvciBhcyBlOgogICAgICAgIHByaW50KGYiICBbQVZJU09dIE7Do28gZm9pIHBvc3PDrXZlbCBsZXIge2ZpbGVwYXRofToge2V9IikKICAgICAgICByZXR1cm4gTm9uZQoKICAgIGlmIF9sb29rc19iaW5hcnlfY29udGVudChyYXcpOgogICAgICAgIHJldHVybiBOb25lCgogICAgZm9yIGVuY29kaW5nIGluICgidXRmLTgiLCAibGF0aW4tMSIsICJjcDEyNTIiKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIHJldHVybiByYXcuZGVjb2RlKGVuY29kaW5nKQogICAgICAgIGV4Y2VwdCBVbmljb2RlRGVjb2RlRXJyb3I6CiAgICAgICAgICAgIGNvbnRpbnVlCiAgICByZXR1cm4gTm9uZQoKCmRlZiBkZWxldGVfZmlsZV9jaHVua3MoY29sbGVjdGlvbjogY2hyb21hZGIuQ29sbGVjdGlvbiwgZmlsZV9wYXRoOiBzdHIpIC0+IE5vbmU6CiAgICAiIiJSZW1vdmUgdG9kb3Mgb3MgY2h1bmtzIGRlIHVtIGFycXVpdm8gZXNwZWPDrWZpY28gZGEgY29sZcOnw6NvLiIiIgogICAgdHJ5OgogICAgICAgICMgUGVkZSBzb21lbnRlIElEcyBwYXJhIGV2aXRhciBtYXRlcmlhbGl6YXIgZG9jcy9tZXRhZGF0YSBuYSBtZW3Ds3JpYS4KICAgICAgICByZXN1bHRzID0gY29sbGVjdGlvbi5nZXQod2hlcmU9eyJmaWxlX3BhdGgiOiBmaWxlX3BhdGh9LCBpbmNsdWRlPVtdKQogICAgICAgIGlmIHJlc3VsdHMgYW5kIHJlc3VsdHNbImlkcyJdOgogICAgICAgICAgICBjb2xsZWN0aW9uLmRlbGV0ZShpZHM9cmVzdWx0c1siaWRzIl0pCiAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgcHJpbnQoZiIgIFtBVklTT10gRXJybyBhbyBkZWxldGFyIGNodW5rcyBkZSB7ZmlsZV9wYXRofToge19mb3JtYXRfZXhjZXB0aW9uKGUpfSIpCgoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBJbmRleGHDp8OjbyBkZSB1bSDDum5pY28gYXJxdWl2bwojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKZGVmIGluZGV4X2ZpbGUoCiAgICBmaWxlcGF0aDogUGF0aCwKICAgIGNvbGxlY3Rpb246IGNocm9tYWRiLkNvbGxlY3Rpb24sCiAgICBtb2RlbDogU2VudGVuY2VUcmFuc2Zvcm1lciwKICAgIHNwbGl0dGVyOiBSZWN1cnNpdmVDaGFyYWN0ZXJUZXh0U3BsaXR0ZXIsCiAgICByb290X3BhdGg6IFBhdGgsCiAgICBlbWJlZGRpbmdfYmF0Y2hfc2l6ZTogaW50LAogICAgcmFpc2Vfb25fc3RvcF9pdGVyYXRpb246IGJvb2wgPSBGYWxzZSwKKSAtPiBpbnQ6CiAgICAiIiIKICAgIEluZGV4YSB1bSDDum5pY28gYXJxdWl2bzogbMOqLCBkaXZpZGUgZW0gY2h1bmtzLCBnZXJhIGVtYmVkZGluZ3MgZSBmYXogdXBzZXJ0LgogICAgUmV0b3JuYSBvIG7Dum1lcm8gZGUgY2h1bmtzIGluZGV4YWRvcy4KICAgICIiIgogICAgY29udGVudCA9IHJlYWRfZmlsZV9zYWZlKGZpbGVwYXRoKQogICAgaWYgbm90IGNvbnRlbnQgb3Igbm90IGNvbnRlbnQuc3RyaXAoKToKICAgICAgICByZXR1cm4gMAoKICAgICMgVXNhIGNhbWluaG8gYWJzb2x1dG8gY29tbyBtZXRhZGFkbwogICAgYWJzX3BhdGggPSBzdHIoZmlsZXBhdGgucmVzb2x2ZSgpKQoKICAgICMgUmVtb3ZlIGNodW5rcyBhbnRpZ29zIGRlc3RlIGFycXVpdm8gKGF0dWFsaXphw6fDo28gaWRlbXBvdGVudGUpCiAgICBkZWxldGVfZmlsZV9jaHVua3MoY29sbGVjdGlvbiwgYWJzX3BhdGgpCgogICAgY2h1bmtzID0gc3BsaXR0ZXIuc3BsaXRfdGV4dChjb250ZW50KQogICAgaWYgbm90IGNodW5rczoKICAgICAgICByZXR1cm4gMAoKICAgIHJlbGF0aXZlX3BhdGggPSBzdHIoZmlsZXBhdGgucmVsYXRpdmVfdG8ocm9vdF9wYXRoKSkKICAgIGluc2VydGVkX2NodW5rcyA9IDAKICAgIHNraXBwZWRfY2h1bmtzID0gMAogICAgc3RvcF9pdGVyYXRpb25fd2FybmluZ3MgPSAwCiAgICBiYXRjaF9pZHM6IGxpc3Rbc3RyXSA9IFtdCiAgICBiYXRjaF9kb2NzOiBsaXN0W3N0cl0gPSBbXQogICAgYmF0Y2hfbWV0YWRhdGFzOiBsaXN0W2RpY3Rbc3RyLCBvYmplY3RdXSA9IFtdCgogICAgZGVmIF93YXJuX3N0b3BfaXRlcmF0aW9uKG1lc3NhZ2U6IHN0cikgLT4gTm9uZToKICAgICAgICBub25sb2NhbCBzdG9wX2l0ZXJhdGlvbl93YXJuaW5ncwogICAgICAgIGlmIHN0b3BfaXRlcmF0aW9uX3dhcm5pbmdzIDwgMzoKICAgICAgICAgICAgdHFkbS53cml0ZShtZXNzYWdlKQogICAgICAgIHN0b3BfaXRlcmF0aW9uX3dhcm5pbmdzICs9IDEKCiAgICBkZWYgX3RvX2VtYmVkZGluZ19yb3dzKGVuY29kZWRfZW1iZWRkaW5nczogb2JqZWN0KSAtPiBsaXN0W2xpc3RbZmxvYXRdXToKICAgICAgICBpZiBoYXNhdHRyKGVuY29kZWRfZW1iZWRkaW5ncywgInRvbGlzdCIpOgogICAgICAgICAgICByb3dzID0gZW5jb2RlZF9lbWJlZGRpbmdzLnRvbGlzdCgpCiAgICAgICAgICAgIGlmIGlzaW5zdGFuY2Uocm93cywgbGlzdCk6CiAgICAgICAgICAgICAgICBpZiByb3dzIGFuZCBpc2luc3RhbmNlKHJvd3NbMF0sIChpbnQsIGZsb2F0KSk6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFtsaXN0KHJvd3MpXQogICAgICAgICAgICAgICAgcmV0dXJuIHJvd3MKICAgICAgICByZXR1cm4gW2xpc3Qocm93KSBmb3Igcm93IGluIGVuY29kZWRfZW1iZWRkaW5nc10gICMgdHlwZTogaWdub3JlW2FyZy10eXBlXQoKICAgIGRlZiBfZmx1c2hfYmF0Y2goKSAtPiBOb25lOgogICAgICAgIG5vbmxvY2FsIGluc2VydGVkX2NodW5rcywgc2tpcHBlZF9jaHVua3MKICAgICAgICBpZiBub3QgYmF0Y2hfaWRzOgogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgcGVuZGluZ19pZHMgPSBsaXN0KGJhdGNoX2lkcykKICAgICAgICBwZW5kaW5nX2RvY3MgPSBsaXN0KGJhdGNoX2RvY3MpCiAgICAgICAgcGVuZGluZ19tZXRhZGF0YXMgPSBsaXN0KGJhdGNoX21ldGFkYXRhcykKCiAgICAgICAgdHJ5OgogICAgICAgICAgICBlbmNvZGVkID0gbW9kZWwuZW5jb2RlKAogICAgICAgICAgICAgICAgcGVuZGluZ19kb2NzLAogICAgICAgICAgICAgICAgc2hvd19wcm9ncmVzc19iYXI9RmFsc2UsCiAgICAgICAgICAgICAgICBiYXRjaF9zaXplPWVtYmVkZGluZ19iYXRjaF9zaXplLAogICAgICAgICAgICApCiAgICAgICAgICAgIGVtYmVkZGluZ3MgPSBfdG9fZW1iZWRkaW5nX3Jvd3MoZW5jb2RlZCkKICAgICAgICAgICAgY29sbGVjdGlvbi51cHNlcnQoCiAgICAgICAgICAgICAgICBpZHM9cGVuZGluZ19pZHMsCiAgICAgICAgICAgICAgICBlbWJlZGRpbmdzPWVtYmVkZGluZ3MsCiAgICAgICAgICAgICAgICBkb2N1bWVudHM9cGVuZGluZ19kb2NzLAogICAgICAgICAgICAgICAgbWV0YWRhdGFzPXBlbmRpbmdfbWV0YWRhdGFzLAogICAgICAgICAgICApCiAgICAgICAgICAgIGluc2VydGVkX2NodW5rcyArPSBsZW4ocGVuZGluZ19pZHMpCiAgICAgICAgICAgIGRlbCBlbWJlZGRpbmdzCiAgICAgICAgZXhjZXB0IFN0b3BJdGVyYXRpb246CiAgICAgICAgICAgIF93YXJuX3N0b3BfaXRlcmF0aW9uKAogICAgICAgICAgICAgICAgZiIgIFtBVklTT10ge2ZpbGVwYXRoLm5hbWV9OiBTdG9wSXRlcmF0aW9uIG5vIGJhdGNoIGRlIGVtYmVkZGluZ3M7IHRlbnRhbmRvIGZhbGxiYWNrIHBvciBjaHVuay4iCiAgICAgICAgICAgICkKICAgICAgICAgICAgZm9yIGNodW5rX2lkLCBjaHVua19kb2MsIGNodW5rX21ldGFkYXRhIGluIHppcChwZW5kaW5nX2lkcywgcGVuZGluZ19kb2NzLCBwZW5kaW5nX21ldGFkYXRhcyk6CiAgICAgICAgICAgICAgICBjYW5kaWRhdGVfZG9jID0gY2h1bmtfZG9jLnN0cmlwKCkKICAgICAgICAgICAgICAgIGlmIG5vdCBjYW5kaWRhdGVfZG9jOgogICAgICAgICAgICAgICAgICAgIHNraXBwZWRfY2h1bmtzICs9IDEKICAgICAgICAgICAgICAgICAgICBjb250aW51ZQoKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBlbmNvZGVkX3NpbmdsZSA9IG1vZGVsLmVuY29kZSgKICAgICAgICAgICAgICAgICAgICAgICAgW2NhbmRpZGF0ZV9kb2NdLAogICAgICAgICAgICAgICAgICAgICAgICBzaG93X3Byb2dyZXNzX2Jhcj1GYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2hfc2l6ZT0xLAogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICBzaW5nbGVfZW1iZWRkaW5ncyA9IF90b19lbWJlZGRpbmdfcm93cyhlbmNvZGVkX3NpbmdsZSkKICAgICAgICAgICAgICAgICAgICBjb2xsZWN0aW9uLnVwc2VydCgKICAgICAgICAgICAgICAgICAgICAgICAgaWRzPVtjaHVua19pZF0sCiAgICAgICAgICAgICAgICAgICAgICAgIGVtYmVkZGluZ3M9c2luZ2xlX2VtYmVkZGluZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50cz1bY2FuZGlkYXRlX2RvY10sCiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhcz1bY2h1bmtfbWV0YWRhdGFdLAogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICBpbnNlcnRlZF9jaHVua3MgKz0gMQogICAgICAgICAgICAgICAgICAgIGRlbCBzaW5nbGVfZW1iZWRkaW5ncwogICAgICAgICAgICAgICAgZXhjZXB0IFN0b3BJdGVyYXRpb246CiAgICAgICAgICAgICAgICAgICAgY29tcGFjdF9kb2MgPSAiICIuam9pbihjYW5kaWRhdGVfZG9jLnNwbGl0KCkpCiAgICAgICAgICAgICAgICAgICAgaWYgbm90IGNvbXBhY3RfZG9jOgogICAgICAgICAgICAgICAgICAgICAgICBza2lwcGVkX2NodW5rcyArPSAxCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgICAgICBlbmNvZGVkX3NpbmdsZSA9IG1vZGVsLmVuY29kZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjb21wYWN0X2RvY10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG93X3Byb2dyZXNzX2Jhcj1GYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoX3NpemU9MSwKICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICBzaW5nbGVfZW1iZWRkaW5ncyA9IF90b19lbWJlZGRpbmdfcm93cyhlbmNvZGVkX3NpbmdsZSkKICAgICAgICAgICAgICAgICAgICAgICAgY29sbGVjdGlvbi51cHNlcnQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZHM9W2NodW5rX2lkXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtYmVkZGluZ3M9c2luZ2xlX2VtYmVkZGluZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudHM9W2NvbXBhY3RfZG9jXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhcz1bY2h1bmtfbWV0YWRhdGFdLAogICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgIGluc2VydGVkX2NodW5rcyArPSAxCiAgICAgICAgICAgICAgICAgICAgICAgIGRlbCBzaW5nbGVfZW1iZWRkaW5ncwogICAgICAgICAgICAgICAgICAgIGV4Y2VwdCBTdG9wSXRlcmF0aW9uOgogICAgICAgICAgICAgICAgICAgICAgICBza2lwcGVkX2NodW5rcyArPSAxCiAgICAgICAgICAgICAgICAgICAgICAgIF93YXJuX3N0b3BfaXRlcmF0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZiIgIFtBVklTT10ge2ZpbGVwYXRoLm5hbWV9OiBjaHVuayBpZ25vcmFkbyBhcMOzcyBTdG9wSXRlcmF0aW9uIHJlcGV0aWRvLiIKICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgIGJhdGNoX2lkcy5jbGVhcigpCiAgICAgICAgYmF0Y2hfZG9jcy5jbGVhcigpCiAgICAgICAgYmF0Y2hfbWV0YWRhdGFzLmNsZWFyKCkKICAgICAgICBnYy5jb2xsZWN0KCkKCiAgICBmb3IgaSwgY2h1bmsgaW4gZW51bWVyYXRlKGNodW5rcyk6CiAgICAgICAgaWYgbm90IGNodW5rIG9yIG5vdCBjaHVuay5zdHJpcCgpOgogICAgICAgICAgICBza2lwcGVkX2NodW5rcyArPSAxCiAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgYmF0Y2hfaWRzLmFwcGVuZChtYWtlX2NodW5rX2lkKGFic19wYXRoLCBpKSkKICAgICAgICBiYXRjaF9kb2NzLmFwcGVuZChjaHVuaykKICAgICAgICBiYXRjaF9tZXRhZGF0YXMuYXBwZW5kKAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiZmlsZV9wYXRoIjogYWJzX3BhdGgsCiAgICAgICAgICAgICAgICAiY2h1bmtfaW5kZXgiOiBpLAogICAgICAgICAgICAgICAgImZpbGVfbmFtZSI6IGZpbGVwYXRoLm5hbWUsCiAgICAgICAgICAgICAgICAjIENhbWluaG8gcmVsYXRpdm8gw6AgcmFpeiBkbyBwcm9qZXRvIHBhcmEgZXhpYmnDp8OjbyBjb21wYWN0YQogICAgICAgICAgICAgICAgInJlbGF0aXZlX3BhdGgiOiByZWxhdGl2ZV9wYXRoLAogICAgICAgICAgICB9CiAgICAgICAgKQogICAgICAgIGlmIGxlbihiYXRjaF9pZHMpID49IGVtYmVkZGluZ19iYXRjaF9zaXplOgogICAgICAgICAgICBfZmx1c2hfYmF0Y2goKQoKICAgIF9mbHVzaF9iYXRjaCgpCiAgICBpZiBza2lwcGVkX2NodW5rczoKICAgICAgICBfd2Fybl9zdG9wX2l0ZXJhdGlvbigKICAgICAgICAgICAgZiIgIFtBVklTT10ge2ZpbGVwYXRoLm5hbWV9OiB7c2tpcHBlZF9jaHVua3N9IGNodW5rKHMpIHZhemlvKHMpL2ludsOhbGlkbyhzKSBmb3JhbSBpZ25vcmFkb3MuIgogICAgICAgICkKICAgIGlmIHJhaXNlX29uX3N0b3BfaXRlcmF0aW9uIGFuZCBpbnNlcnRlZF9jaHVua3MgPT0gMCBhbmQgc3RvcF9pdGVyYXRpb25fd2FybmluZ3MgPiAwOgogICAgICAgIHJhaXNlIFJ1bnRpbWVFcnJvcigKICAgICAgICAgICAgZiJzdG9wX2l0ZXJhdGlvbl9hbGxfY2h1bmtzOntmaWxlcGF0aC5uYW1lfTp7c3RvcF9pdGVyYXRpb25fd2FybmluZ3N9IgogICAgICAgICkKICAgIHJldHVybiBpbnNlcnRlZF9jaHVua3MKCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIFBvbnRvIGRlIGVudHJhZGEgcHJpbmNpcGFsCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpkZWYgbWFpbigpOgogICAgcGFyc2VyID0gYXJncGFyc2UuQXJndW1lbnRQYXJzZXIoCiAgICAgICAgZGVzY3JpcHRpb249IkluZGV4YSB1bSBwcm9qZXRvIGRlIGPDs2RpZ28gbm8gQ2hyb21hREIgcGFyYSBSQUcgbG9jYWwuIgogICAgKQogICAgcGFyc2VyLmFkZF9hcmd1bWVudCgKICAgICAgICAicHJvamVjdF9wYXRoIiwKICAgICAgICBuYXJncz0iPyIsCiAgICAgICAgZGVmYXVsdD0iLiIsCiAgICAgICAgaGVscD0iQ2FtaW5obyByYWl6IGRvIHByb2pldG8gYSBpbmRleGFyIChwYWRyw6NvOiBkaXJldMOzcmlvIGF0dWFsKSIsCiAgICApCiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KAogICAgICAgICItLWNsZWFyIiwKICAgICAgICBhY3Rpb249InN0b3JlX3RydWUiLAogICAgICAgIGhlbHA9IkxpbXBhIHRvZGEgYSBjb2xlw6fDo28gYW50ZXMgZGUgcmVpbmRleGFyIiwKICAgICkKICAgIHBhcnNlci5hZGRfYXJndW1lbnQoCiAgICAgICAgIi0tZW1iZWRkaW5nLW1vZGVsIiwKICAgICAgICBjaG9pY2VzPVsiamluYSIsICJiZ2UiLCAiaHlicmlkIl0sCiAgICAgICAgaGVscD0oCiAgICAgICAgICAgICJNb2RlbG8gZGUgZW1iZWRkaW5nczogJ2ppbmEnIChjb2RpZ28pLCAiCiAgICAgICAgICAgICInYmdlJyAoY29udGV1ZG8gbWlzdG8pIG91ICdoeWJyaWQnIChkdWFzIGNvbGVjb2VzOiBKaW5hIHYyICsgQkdFKS4iCiAgICAgICAgKSwKICAgICkKICAgIHBhcnNlci5hZGRfYXJndW1lbnQoCiAgICAgICAgIi0tamluYS1xdWFudGl6YXRpb24iLAogICAgICAgIGNob2ljZXM9WyJkZWZhdWx0IiwgImR5bmFtaWMtaW50OCJdLAogICAgICAgIGhlbHA9IlF1YW50aXphY2FvIHBhcmEgSmluYTogJ2RlZmF1bHQnIChtYWlzIHF1YWxpZGFkZSkgb3UgJ2R5bmFtaWMtaW50OCcgKG1haXMgdmVsb2NpZGFkZSkuIiwKICAgICkKICAgIHBhcnNlci5hZGRfYXJndW1lbnQoCiAgICAgICAgIi0tcGVyZi1wcm9maWxlIiwKICAgICAgICBjaG9pY2VzPVsiYXV0b3R1bmUiLCAibWF4LXBlcmZvcm1hbmNlIl0sCiAgICAgICAgaGVscD0oCiAgICAgICAgICAgICJQZXJmaWwgZGUgcGVyZm9ybWFuY2UgZGEgaW5kZXhhw6fDo286ICIKICAgICAgICAgICAgIidhdXRvdHVuZScgKGN1c3RvLWJlbmVmw61jaW8pIG91ICdtYXgtcGVyZm9ybWFuY2UnIChtYWlzIHRocm91Z2hwdXQsIG1haW9yIHVzbyBkZSBSQU0pLiIKICAgICAgICApLAogICAgKQogICAgYXJncyA9IHBhcnNlci5wYXJzZV9hcmdzKCkKCiAgICByb290X3BhdGggPSBQYXRoKGFyZ3MucHJvamVjdF9wYXRoKS5yZXNvbHZlKCkKICAgIGlmIG5vdCByb290X3BhdGguaXNfZGlyKCk6CiAgICAgICAgcHJpbnQoZiJbRVJST10gQ2FtaW5obyBuw6NvIGV4aXN0ZSBvdSBuw6NvIMOpIHVtIGRpcmV0w7NyaW86IHtyb290X3BhdGh9IikKICAgICAgICBzeXMuZXhpdCgxKQoKICAgIHByaW50KGYiXG57Jz0nKjYwfSIpCiAgICBwcmludChmIiAgUkFHIEluZGV4ZXIg4oCUIFByb2pldG86IHtyb290X3BhdGh9IikKICAgIHByaW50KGYieyc9Jyo2MH1cbiIpCiAgICBpbmRleF9zdGFydGVkX2F0ID0gZGF0ZXRpbWUubm93KCkKICAgIHByaW50KGYiW0lORk9dIEluw61jaW86IHtpbmRleF9zdGFydGVkX2F0LnN0cmZ0aW1lKCclWS0lbS0lZCAlSDolTTolUycpfSIpCgogICAgZm9yY2VfbW9kZWxfcmVjb25maWd1cmUgPSBfZW52X2Jvb2woIk1DUF9GT1JDRV9NT0RFTF9SRUNPTkZJRyIsIGRlZmF1bHQ9RmFsc2UpCiAgICBwZXJzaXN0ZWRfY29uZmlnID0gbG9hZF9pbmRleGVyX3R1bmluZ19jb25maWcoZm9yY2VfbW9kZWxfcmVjb25maWd1cmUpCiAgICBtb2RlbF9jaG9pY2UsIGppbmFfcXVhbnRpemF0aW9uID0gcmVzb2x2ZV9lbWJlZGRpbmdfY29uZmlnKAogICAgICAgIGFyZ3MuZW1iZWRkaW5nX21vZGVsLAogICAgICAgIGFyZ3MuamluYV9xdWFudGl6YXRpb24sCiAgICAgICAgcGVyc2lzdGVkX2NvbmZpZz1wZXJzaXN0ZWRfY29uZmlnLAogICAgKQogICAgcGVyZl9wcm9maWxlID0gcmVzb2x2ZV9wZXJmX3Byb2ZpbGUoYXJncy5wZXJmX3Byb2ZpbGUsIHBlcnNpc3RlZF9jb25maWcpCgogICAgY2h1bmtfc2l6ZV9sb2NrZWQgPSAiTUNQX0NIVU5LX1NJWkUiIGluIG9zLmVudmlyb24KICAgIGNodW5rX292ZXJsYXBfbG9ja2VkID0gIk1DUF9DSFVOS19PVkVSTEFQIiBpbiBvcy5lbnZpcm9uCiAgICBiYXRjaF9zaXplX2xvY2tlZCA9ICJNQ1BfRU1CRURESU5HX0JBVENIX1NJWkUiIGluIG9zLmVudmlyb24KCiAgICBwZXJzaXN0ZWRfY2h1bmtfc2l6ZSA9IF9wYXJzZV9jb25maWdfaW50KHBlcnNpc3RlZF9jb25maWcsICJjaHVua19zaXplIikKICAgIHBlcnNpc3RlZF9jaHVua19vdmVybGFwID0gX3BhcnNlX2NvbmZpZ19pbnQocGVyc2lzdGVkX2NvbmZpZywgImNodW5rX292ZXJsYXAiKQogICAgcGVyc2lzdGVkX2JhdGNoX3NpemUgPSBfcGFyc2VfY29uZmlnX2ludChwZXJzaXN0ZWRfY29uZmlnLCAiZW1iZWRkaW5nX2JhdGNoX3NpemUiKQogICAgaWYgcGVyc2lzdGVkX2JhdGNoX3NpemUgaXMgTm9uZToKICAgICAgICBwZXJzaXN0ZWRfYmF0Y2hfc2l6ZSA9IF9wYXJzZV9jb25maWdfaW50KHBlcnNpc3RlZF9jb25maWcsICJiYXRjaF9jb3VudCIpCgogICAgZWZmZWN0aXZlX2NodW5rX3NpemUgPSBDSFVOS19TSVpFCiAgICBpZiBub3QgY2h1bmtfc2l6ZV9sb2NrZWQgYW5kIHBlcnNpc3RlZF9jaHVua19zaXplIGlzIG5vdCBOb25lOgogICAgICAgIGVmZmVjdGl2ZV9jaHVua19zaXplID0gbWF4KDI1NiwgcGVyc2lzdGVkX2NodW5rX3NpemUpCgogICAgZWZmZWN0aXZlX2NodW5rX292ZXJsYXAgPSBDSFVOS19PVkVSTEFQCiAgICBpZiBub3QgY2h1bmtfb3ZlcmxhcF9sb2NrZWQgYW5kIHBlcnNpc3RlZF9jaHVua19vdmVybGFwIGlzIG5vdCBOb25lOgogICAgICAgIGVmZmVjdGl2ZV9jaHVua19vdmVybGFwID0gbWF4KDAsIG1pbihlZmZlY3RpdmVfY2h1bmtfc2l6ZSAtIDEsIHBlcnNpc3RlZF9jaHVua19vdmVybGFwKSkKCiAgICBlZmZlY3RpdmVfYmF0Y2hfc2l6ZSA9IEVNQkVERElOR19CQVRDSF9TSVpFCiAgICBpZiBub3QgYmF0Y2hfc2l6ZV9sb2NrZWQgYW5kIHBlcnNpc3RlZF9iYXRjaF9zaXplIGlzIG5vdCBOb25lOgogICAgICAgIGVmZmVjdGl2ZV9iYXRjaF9zaXplID0gbWF4KDEsIHBlcnNpc3RlZF9iYXRjaF9zaXplKQoKICAgIHByaW50KAogICAgICAgIGYiW0NPTkZJR10gTW9kZWxvIGVzY29saGlkbzoge21vZGVsX2Nob2ljZX0gIgogICAgICAgIGYiKHtfZGVzY3JpYmVfZW1iZWRkaW5nX2Nob2ljZShtb2RlbF9jaG9pY2UpfSkiCiAgICApCiAgICBpZiBtb2RlbF9jaG9pY2UgPT0gImppbmEiOgogICAgICAgIHByaW50KGYiW0NPTkZJR10gUXVhbnRpemFjYW8gSmluYToge2ppbmFfcXVhbnRpemF0aW9ufSIpCiAgICBlbGlmIG1vZGVsX2Nob2ljZSA9PSAiaHlicmlkIjoKICAgICAgICBwcmludCgiW0NPTkZJR10gUXVhbnRpemFjYW8gSmluYTogbmFvIGFwbGljYXZlbCBubyBoeWJyaWQgKEppbmEgdjIgKyBCR0UpIikKICAgIGVsc2U6CiAgICAgICAgcHJpbnQoIltDT05GSUddIFF1YW50aXphY2FvIEppbmE6IG5hbyBhcGxpY2F2ZWwgKG1vZGVsbyBCR0Ugc2VsZWNpb25hZG8pIikKICAgIHByaW50KGYiW0NPTkZJR10gUGVyZmlsIGRlIHBlcmZvcm1hbmNlOiB7cGVyZl9wcm9maWxlfSIpCiAgICBpZiBwZXJmX3Byb2ZpbGUgPT0gIm1heC1wZXJmb3JtYW5jZSI6CiAgICAgICAgcHJpbnQoCiAgICAgICAgICAgICJbQVZJU09dIEVzdGUgbW9kbyBwb2RlIGVsZXZhciBjb25zaWRlcmF2ZWxtZW50ZSBvIGNvbnN1bW8gZGUgbWVtw7NyaWEgIgogICAgICAgICAgICAiZSBjYXVzYXIgZW5jZXJyYW1lbnRvIHBvciBPT00gKGV4aXQgMTM3KS4iCiAgICAgICAgKQogICAgd2Fybl9pZl9qaW5hX21lbW9yeV9yaXNrKG1vZGVsX2Nob2ljZSwgamluYV9xdWFudGl6YXRpb24pCgogICAgIyBJbmljaWFsaXphIGNvbXBvbmVudGVzCiAgICBjbGllbnQgPSBjb25uZWN0X3RvX2Nocm9tYSgpCiAgICB0YXJnZXRzID0gX3Jlc29sdmVfaW5kZXhfdGFyZ2V0cyhtb2RlbF9jaG9pY2UpCgogICAgIyBPYnTDqW0gb3UgcmVjcmlhIGFzIGNvbGXDp8O1ZXMgZW52b2x2aWRhcy4KICAgIGNvbGxlY3Rpb25zOiBkaWN0W3N0ciwgY2hyb21hZGIuQ29sbGVjdGlvbl0gPSB7fQogICAgY29sbGVjdGlvbl9kaW1lbnNpb25fcmVzZXRfZG9uZTogZGljdFtzdHIsIGJvb2xdID0ge30KICAgIGZvciB0YXJnZXQgaW4gdGFyZ2V0czoKICAgICAgICBpZiBhcmdzLmNsZWFyOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBjbGllbnQuZGVsZXRlX2NvbGxlY3Rpb24odGFyZ2V0LmNvbGxlY3Rpb25fbmFtZSkKICAgICAgICAgICAgICAgIHByaW50KGYiWyFdIENvbGXDp8OjbyAne3RhcmdldC5jb2xsZWN0aW9uX25hbWV9JyByZW1vdmlkYSBwYXJhIHJlaW5kZXhhw6fDo28gbGltcGEuIikKICAgICAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICAgICAgICAgIHBhc3MKICAgICAgICBjb2xsZWN0aW9uc1t0YXJnZXQuY29sbGVjdGlvbl9uYW1lXSA9IGNsaWVudC5nZXRfb3JfY3JlYXRlX2NvbGxlY3Rpb24oCiAgICAgICAgICAgIG5hbWU9dGFyZ2V0LmNvbGxlY3Rpb25fbmFtZSwKICAgICAgICAgICAgbWV0YWRhdGE9eyJobnN3OnNwYWNlIjogImNvc2luZSJ9LAogICAgICAgICkKICAgICAgICBjb2xsZWN0aW9uX2RpbWVuc2lvbl9yZXNldF9kb25lW3RhcmdldC5jb2xsZWN0aW9uX25hbWVdID0gRmFsc2UKCiAgICAjIENhcnJlZ2EgbW9kZWxvcyBkZSBmb3JtYSBsYXp5IGUgcmVhcHJvdmVpdGEgcG9yIHRhcmdldC4KICAgIGxvYWRlZF9tb2RlbHM6IGRpY3Rbc3RyLCBTZW50ZW5jZVRyYW5zZm9ybWVyXSA9IHt9CiAgICB0b3RhbF9jaHVua3MgPSAwCiAgICBlcnJvcnMgPSAwCiAgICBmaWxlc19zY2FubmVkID0gMAogICAgZmlsZXNfcHJvY2Vzc2VkX3RvdGFsID0gMAogICAgY2h1bmtzX2J5X2NvbGxlY3Rpb24gPSB7dGFyZ2V0LmNvbGxlY3Rpb25fbmFtZTogMCBmb3IgdGFyZ2V0IGluIHRhcmdldHN9CiAgICBmaWxlc19ieV9jb2xsZWN0aW9uID0ge3RhcmdldC5jb2xsZWN0aW9uX25hbWU6IDAgZm9yIHRhcmdldCBpbiB0YXJnZXRzfQogICAgZmlsZXNfZWxpZ2libGVfYnlfY29sbGVjdGlvbiA9IHt0YXJnZXQuY29sbGVjdGlvbl9uYW1lOiAwIGZvciB0YXJnZXQgaW4gdGFyZ2V0c30KICAgIGVycm9yc19ieV9jb2xsZWN0aW9uID0ge3RhcmdldC5jb2xsZWN0aW9uX25hbWU6IDAgZm9yIHRhcmdldCBpbiB0YXJnZXRzfQogICAgZXJyb3Jfc2FtcGxlc19ieV9jb2xsZWN0aW9uOiBkaWN0W3N0ciwgbGlzdFtzdHJdXSA9IHt0YXJnZXQuY29sbGVjdGlvbl9uYW1lOiBbXSBmb3IgdGFyZ2V0IGluIHRhcmdldHN9CiAgICB0YXJnZXRfYnlfbW9kZWwgPSB7dGFyZ2V0Lm1vZGVsX2Nob2ljZTogdGFyZ2V0IGZvciB0YXJnZXQgaW4gdGFyZ2V0c30KCiAgICAjIENhcnJlZ2EgbyBwcmltZWlybyBtb2RlbG8gYW50ZXMgcGFyYSBhdXRvdHVuZSBjb20gbWljcm8tYmVuY2htYXJrLgogICAgcHJpbWFyeV90YXJnZXQgPSB0YXJnZXRzWzBdCiAgICBwcmltYXJ5X3F1YW50aXphdGlvbiA9IGppbmFfcXVhbnRpemF0aW9uIGlmIHByaW1hcnlfdGFyZ2V0Lm1vZGVsX2Nob2ljZSA9PSAiamluYSIgZWxzZSAiZGVmYXVsdCIKICAgIGxvYWRlZF9tb2RlbHNbcHJpbWFyeV90YXJnZXQubW9kZWxfY2hvaWNlXSA9IGxvYWRfZW1iZWRkaW5nX21vZGVsKHByaW1hcnlfdGFyZ2V0Lm1vZGVsX2Nob2ljZSwgcHJpbWFyeV9xdWFudGl6YXRpb24pCiAgICBwcmltYXJ5X21vZGVsID0gbG9hZGVkX21vZGVsc1twcmltYXJ5X3RhcmdldC5tb2RlbF9jaG9pY2VdCgogICAgaWYgcGVyZl9wcm9maWxlID09ICJhdXRvdHVuZSI6CiAgICAgICAgdHVuZWQgPSBfcmVzb2x2ZV9hdXRvdHVuZWRfcGFyYW1zKAogICAgICAgICAgICBtb2RlbD1wcmltYXJ5X21vZGVsLAogICAgICAgICAgICBjaHVua19zaXplX2xvY2tlZD1jaHVua19zaXplX2xvY2tlZCwKICAgICAgICAgICAgY2h1bmtfb3ZlcmxhcF9sb2NrZWQ9Y2h1bmtfb3ZlcmxhcF9sb2NrZWQsCiAgICAgICAgICAgIGJhdGNoX3NpemVfbG9ja2VkPWJhdGNoX3NpemVfbG9ja2VkLAogICAgICAgICAgICBjaHVua19zaXplPWVmZmVjdGl2ZV9jaHVua19zaXplLAogICAgICAgICAgICBjaHVua19vdmVybGFwPWVmZmVjdGl2ZV9jaHVua19vdmVybGFwLAogICAgICAgICAgICBlbWJlZGRpbmdfYmF0Y2hfc2l6ZT1lZmZlY3RpdmVfYmF0Y2hfc2l6ZSwKICAgICAgICApCiAgICBlbHNlOgogICAgICAgIHR1bmVkID0gX3Jlc29sdmVfbWF4X3BlcmZvcm1hbmNlX3BhcmFtcygKICAgICAgICAgICAgY2h1bmtfc2l6ZV9sb2NrZWQ9Y2h1bmtfc2l6ZV9sb2NrZWQsCiAgICAgICAgICAgIGNodW5rX292ZXJsYXBfbG9ja2VkPWNodW5rX292ZXJsYXBfbG9ja2VkLAogICAgICAgICAgICBiYXRjaF9zaXplX2xvY2tlZD1iYXRjaF9zaXplX2xvY2tlZCwKICAgICAgICAgICAgY2h1bmtfc2l6ZT1lZmZlY3RpdmVfY2h1bmtfc2l6ZSwKICAgICAgICAgICAgY2h1bmtfb3ZlcmxhcD1lZmZlY3RpdmVfY2h1bmtfb3ZlcmxhcCwKICAgICAgICAgICAgZW1iZWRkaW5nX2JhdGNoX3NpemU9ZWZmZWN0aXZlX2JhdGNoX3NpemUsCiAgICAgICAgKQoKICAgIGVmZmVjdGl2ZV9jaHVua19zaXplID0gbWF4KDI1NiwgdHVuZWQuY2h1bmtfc2l6ZSkKICAgIGVmZmVjdGl2ZV9jaHVua19vdmVybGFwID0gbWF4KDAsIG1pbihlZmZlY3RpdmVfY2h1bmtfc2l6ZSAtIDEsIHR1bmVkLmNodW5rX292ZXJsYXApKQogICAgZWZmZWN0aXZlX2JhdGNoX3NpemUgPSBtYXgoMSwgdHVuZWQuZW1iZWRkaW5nX2JhdGNoX3NpemUpCgogICAgZm9yIHJlYXNvbiBpbiB0dW5lZC5yZWFzb25zOgogICAgICAgIHByaW50KGYiW0NPTkZJR10ge3JlYXNvbn0iKQoKICAgIHByaW50KAogICAgICAgIGYiW0NPTkZJR10gUGFyw6JtZXRyb3MgZmluYWlzOiAiCiAgICAgICAgZiJjaHVua19zaXplPXtlZmZlY3RpdmVfY2h1bmtfc2l6ZX0sIGNodW5rX292ZXJsYXA9e2VmZmVjdGl2ZV9jaHVua19vdmVybGFwfSwgIgogICAgICAgIGYiZW1iZWRkaW5nX2JhdGNoPXtlZmZlY3RpdmVfYmF0Y2hfc2l6ZX0iCiAgICApCgogICAgc2F2ZV9pbmRleGVyX3R1bmluZ19jb25maWcoCiAgICAgICAgewogICAgICAgICAgICAiZW1iZWRkaW5nX21vZGVsIjogbW9kZWxfY2hvaWNlLAogICAgICAgICAgICAiamluYV9xdWFudGl6YXRpb24iOiBqaW5hX3F1YW50aXphdGlvbiwKICAgICAgICAgICAgInBlcmZfcHJvZmlsZSI6IHBlcmZfcHJvZmlsZSwKICAgICAgICAgICAgImNodW5rX3NpemUiOiBlZmZlY3RpdmVfY2h1bmtfc2l6ZSwKICAgICAgICAgICAgImNodW5rX292ZXJsYXAiOiBlZmZlY3RpdmVfY2h1bmtfb3ZlcmxhcCwKICAgICAgICAgICAgImVtYmVkZGluZ19iYXRjaF9zaXplIjogZWZmZWN0aXZlX2JhdGNoX3NpemUsCiAgICAgICAgfQogICAgKQoKICAgIHNwbGl0dGVyID0gZ2V0X3RleHRfc3BsaXR0ZXIoZWZmZWN0aXZlX2NodW5rX3NpemUsIGVmZmVjdGl2ZV9jaHVua19vdmVybGFwKQoKICAgIHByaW50KGYiXG5bK10gVmFycmVuZG8gZSBpbmRleGFuZG8gYXJxdWl2b3MgZW06IHtyb290X3BhdGh9IikKICAgIGZpbGVzID0gbGlzdChzY2FuX2ZpbGVzKHJvb3RfcGF0aCkpCiAgICBmaWxlc19zY2FubmVkID0gbGVuKGZpbGVzKQogICAgaWYgZmlsZXNfc2Nhbm5lZCA9PSAwOgogICAgICAgIHByaW50KCJbQVZJU09dIE5lbmh1bSBhcnF1aXZvIGVuY29udHJhZG8uIFZlcmlmaXF1ZSBvIGNhbWluaG8gZSBvcyBmaWx0cm9zLiIpCiAgICAgICAgc3lzLmV4aXQoMCkKCiAgICBwcmludChmIlsrXSB7ZmlsZXNfc2Nhbm5lZH0gYXJxdWl2byhzKSBlbGVnw612ZWwoaXMpIHBhcmEgaW5kZXhhw6fDo28uIikKICAgIHdpdGggdHFkbSgKICAgICAgICB0b3RhbD1maWxlc19zY2FubmVkLAogICAgICAgIGRlc2M9IkluZGV4YW5kbyIsCiAgICAgICAgdW5pdD0iYXJxdWl2byIsCiAgICAgICAgYmFyX2Zvcm1hdD0ie2xfYmFyfXtiYXJ9fCB7bl9mbXR9L3t0b3RhbF9mbXR9IFt7ZWxhcHNlZH0sIHtyYXRlX2ZtdH1dIiwKICAgICkgYXMgcGJhcjoKICAgICAgICBmb3IgZmlsZXBhdGggaW4gZmlsZXM6CiAgICAgICAgICAgIHRhcmdldF9tb2RlbHMgPSBfY2xhc3NpZnlfZmlsZV90YXJnZXRzKGZpbGVwYXRoLCBtb2RlbF9jaG9pY2UpCgogICAgICAgICAgICBmb3IgdGFyZ2V0X21vZGVsIGluIHRhcmdldF9tb2RlbHM6CiAgICAgICAgICAgICAgICB0YXJnZXQgPSB0YXJnZXRfYnlfbW9kZWwuZ2V0KHRhcmdldF9tb2RlbCkKICAgICAgICAgICAgICAgIGlmIHRhcmdldCBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICAgICAgICAgdGFyZ2V0X3F1YW50aXphdGlvbiA9IGppbmFfcXVhbnRpemF0aW9uIGlmIHRhcmdldC5tb2RlbF9jaG9pY2UgPT0gImppbmEiIGVsc2UgImRlZmF1bHQiCiAgICAgICAgICAgICAgICBpZiB0YXJnZXQubW9kZWxfY2hvaWNlIG5vdCBpbiBsb2FkZWRfbW9kZWxzOgogICAgICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICAgICAgbG9hZGVkX21vZGVsc1t0YXJnZXQubW9kZWxfY2hvaWNlXSA9IGxvYWRfZW1iZWRkaW5nX21vZGVsKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0Lm1vZGVsX2Nob2ljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldF9xdWFudGl6YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGxvYWRfZXJyb3I6CiAgICAgICAgICAgICAgICAgICAgICAgICMgRW0gaHlicmlkLCBwb2RlIGZhbHRhciBSQU0gYW8gbWFudGVyIGRvaXMgbW9kZWxvcyBncmFuZGVzIHNpbXVsdGFuZWFtZW50ZS4KICAgICAgICAgICAgICAgICAgICAgICAgaWYgbW9kZWxfY2hvaWNlID09ICJoeWJyaWQiIGFuZCBsb2FkZWRfbW9kZWxzIGFuZCBfaXNfbWVtb3J5X3JlbGF0ZWRfZXJyb3IobG9hZF9lcnJvcik6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmludCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiW0FWSVNPXSBGYWxoYSBhbyBjYXJyZWdhciBtb2RlbG8gYWRpY2lvbmFsIG5vIGh5YnJpZCBwb3IgbWVtw7NyaWEuICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTGliZXJhbmRvIG1vZGVsbyBhbnRlcmlvciBlIHRlbnRhbmRvIG5vdmFtZW50ZS4iCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2FkZWRfbW9kZWxzLmNsZWFyKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdjLmNvbGxlY3QoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9hZGVkX21vZGVsc1t0YXJnZXQubW9kZWxfY2hvaWNlXSA9IGxvYWRfZW1iZWRkaW5nX21vZGVsKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldC5tb2RlbF9jaG9pY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0X3F1YW50aXphdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhaXNlCgogICAgICAgICAgICAgICAgbW9kZWwgPSBsb2FkZWRfbW9kZWxzW3RhcmdldC5tb2RlbF9jaG9pY2VdCiAgICAgICAgICAgICAgICBjb2xsZWN0aW9uID0gY29sbGVjdGlvbnNbdGFyZ2V0LmNvbGxlY3Rpb25fbmFtZV0KICAgICAgICAgICAgICAgIGZpbGVzX2VsaWdpYmxlX2J5X2NvbGxlY3Rpb25bdGFyZ2V0LmNvbGxlY3Rpb25fbmFtZV0gKz0gMQoKICAgICAgICAgICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgICAgICBuX2NodW5rcyA9IGluZGV4X2ZpbGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlcGF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbGxlY3Rpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwbGl0dGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcm9vdF9wYXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZW1iZWRkaW5nX2JhdGNoX3NpemU9ZWZmZWN0aXZlX2JhdGNoX3NpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByYWlzZV9vbl9zdG9wX2l0ZXJhdGlvbj0odGFyZ2V0Lm1vZGVsX2Nob2ljZSA9PSAiYmdlIiksCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfY2h1bmtzICs9IG5fY2h1bmtzCiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzX3Byb2Nlc3NlZF90b3RhbCArPSAxCiAgICAgICAgICAgICAgICAgICAgICAgIGNodW5rc19ieV9jb2xsZWN0aW9uW3RhcmdldC5jb2xsZWN0aW9uX25hbWVdICs9IG5fY2h1bmtzCiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzX2J5X2NvbGxlY3Rpb25bdGFyZ2V0LmNvbGxlY3Rpb25fbmFtZV0gKz0gMQogICAgICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICAgICAgICAgICAgICAgICAgIyBGYWxsYmFjayBhdXRvbcOhdGljbyBwYXJhIGV2aXRhciBxdWVicmEgdG90YWwgZW0gbcOhcXVpbmFzIG5vIGxpbWl0ZSBkZSBSQU0uCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdCBiYXRjaF9zaXplX2xvY2tlZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5kIGVmZmVjdGl2ZV9iYXRjaF9zaXplID4gMQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5kIF9pc19tZW1vcnlfcmVsYXRlZF9lcnJvcihlKQogICAgICAgICAgICAgICAgICAgICAgICApOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3X2JhdGNoID0gbWF4KDEsIGVmZmVjdGl2ZV9iYXRjaF9zaXplIC8vIDIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBuZXdfYmF0Y2ggPCBlZmZlY3RpdmVfYmF0Y2hfc2l6ZToKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cWRtLndyaXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIiAgW0FKVVNURV0gTWVtw7NyaWEgYWx0YSBlbSB7dGFyZ2V0LmxhYmVsfS4gIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIkJhdGNoIHJlZHV6aWRvIHtlZmZlY3RpdmVfYmF0Y2hfc2l6ZX0gLT4ge25ld19iYXRjaH0uIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3RpdmVfYmF0Y2hfc2l6ZSA9IG5ld19iYXRjaAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdjLmNvbGxlY3QoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICAgICAgICAgICAgICAgICBpZiB0YXJnZXQubW9kZWxfY2hvaWNlID09ICJiZ2UiOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsbGJhY2tfdGFyZ2V0ID0gdGFyZ2V0X2J5X21vZGVsLmdldCgiamluYS12MiIpIG9yIHRhcmdldF9ieV9tb2RlbC5nZXQoImppbmEiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgZmFsbGJhY2tfdGFyZ2V0IGlzIG5vdCBOb25lOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbGxiYWNrX3F1YW50aXphdGlvbiA9ICgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgamluYV9xdWFudGl6YXRpb24gaWYgZmFsbGJhY2tfdGFyZ2V0Lm1vZGVsX2Nob2ljZSA9PSAiamluYSIgZWxzZSAiZGVmYXVsdCIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBmYWxsYmFja190YXJnZXQubW9kZWxfY2hvaWNlIG5vdCBpbiBsb2FkZWRfbW9kZWxzOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9hZGVkX21vZGVsc1tmYWxsYmFja190YXJnZXQubW9kZWxfY2hvaWNlXSA9IGxvYWRfZW1iZWRkaW5nX21vZGVsKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbGxiYWNrX3RhcmdldC5tb2RlbF9jaG9pY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsbGJhY2tfcXVhbnRpemF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxsYmFja19tb2RlbCA9IGxvYWRlZF9tb2RlbHNbZmFsbGJhY2tfdGFyZ2V0Lm1vZGVsX2Nob2ljZV0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsbGJhY2tfY29sbGVjdGlvbiA9IGNvbGxlY3Rpb25zW2ZhbGxiYWNrX3RhcmdldC5jb2xsZWN0aW9uX25hbWVdCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRxZG0ud3JpdGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIiAgW0ZBTExCQUNLXSB7ZmlsZXBhdGgubmFtZX06IEJHRSBmYWxob3U7ICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYicmVpbmRleGFuZG8gY29tIHtmYWxsYmFja190YXJnZXQubGFiZWx9LiIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxsYmFja19jaHVua3MgPSBpbmRleF9maWxlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZXBhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxsYmFja19jb2xsZWN0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsbGJhY2tfbW9kZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGxpdHRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvb3RfcGF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtYmVkZGluZ19iYXRjaF9zaXplPWVmZmVjdGl2ZV9iYXRjaF9zaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFpc2Vfb25fc3RvcF9pdGVyYXRpb249RmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfY2h1bmtzICs9IGZhbGxiYWNrX2NodW5rcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlc19wcm9jZXNzZWRfdG90YWwgKz0gMQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlc19lbGlnaWJsZV9ieV9jb2xsZWN0aW9uW2ZhbGxiYWNrX3RhcmdldC5jb2xsZWN0aW9uX25hbWVdICs9IDEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2h1bmtzX2J5X2NvbGxlY3Rpb25bZmFsbGJhY2tfdGFyZ2V0LmNvbGxlY3Rpb25fbmFtZV0gKz0gZmFsbGJhY2tfY2h1bmtzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzX2J5X2NvbGxlY3Rpb25bZmFsbGJhY2tfdGFyZ2V0LmNvbGxlY3Rpb25fbmFtZV0gKz0gMQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZmFsbGJhY2tfZXJyb3I6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRxZG0ud3JpdGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIiAgW0VSUk9dIHtmaWxlcGF0aH0gW2ZhbGxiYWNrIHtmYWxsYmFja190YXJnZXQubGFiZWx9XTogIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiJ7X2Zvcm1hdF9leGNlcHRpb24oZmFsbGJhY2tfZXJyb3IpfSIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgX2lzX2RpbWVuc2lvbl9taXNtYXRjaF9lcnJvcihlKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5kIG5vdCBjb2xsZWN0aW9uX2RpbWVuc2lvbl9yZXNldF9kb25lW3RhcmdldC5jb2xsZWN0aW9uX25hbWVdCiAgICAgICAgICAgICAgICAgICAgICAgICk6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cWRtLndyaXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYiICBbQUpVU1RFXSBEaW1lbnPDo28gaW5jb21wYXTDrXZlbCBkZXRlY3RhZGEgZW0gJ3t0YXJnZXQuY29sbGVjdGlvbl9uYW1lfScuICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUmVjcmlhbmRvIGNvbGXDp8OjbyBlIHRlbnRhbmRvIG5vdmFtZW50ZS4iCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpZW50LmRlbGV0ZV9jb2xsZWN0aW9uKHRhcmdldC5jb2xsZWN0aW9uX25hbWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhc3MKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xsZWN0aW9uc1t0YXJnZXQuY29sbGVjdGlvbl9uYW1lXSA9IGNsaWVudC5nZXRfb3JfY3JlYXRlX2NvbGxlY3Rpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZT10YXJnZXQuY29sbGVjdGlvbl9uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhPXsiaG5zdzpzcGFjZSI6ICJjb3NpbmUifSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbGxlY3Rpb25fZGltZW5zaW9uX3Jlc2V0X2RvbmVbdGFyZ2V0LmNvbGxlY3Rpb25fbmFtZV0gPSBUcnVlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnYy5jb2xsZWN0KCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICAgICAgICAgICAgICAgICBlcnJvcnMgKz0gMQogICAgICAgICAgICAgICAgICAgICAgICBlcnJvcnNfYnlfY29sbGVjdGlvblt0YXJnZXQuY29sbGVjdGlvbl9uYW1lXSArPSAxCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIGxlbihlcnJvcl9zYW1wbGVzX2J5X2NvbGxlY3Rpb25bdGFyZ2V0LmNvbGxlY3Rpb25fbmFtZV0pIDwgMzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yX3NhbXBsZXNfYnlfY29sbGVjdGlvblt0YXJnZXQuY29sbGVjdGlvbl9uYW1lXS5hcHBlbmQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZiJ7ZmlsZXBhdGgubmFtZX06IHtfZm9ybWF0X2V4Y2VwdGlvbihlKX0iCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgIHRxZG0ud3JpdGUoZiIgIFtFUlJPXSB7ZmlsZXBhdGh9IFt7dGFyZ2V0LmxhYmVsfV06IHtfZm9ybWF0X2V4Y2VwdGlvbihlKX0iKQogICAgICAgICAgICAgICAgICAgICAgICBicmVhawoKICAgICAgICAgICAgcGJhci5zZXRfcG9zdGZpeCh7ImNodW5rcyI6IHRvdGFsX2NodW5rcywgImF0dWFsIjogZmlsZXBhdGgubmFtZVs6MjBdfSkKICAgICAgICAgICAgcGJhci51cGRhdGUoMSkKCiAgICBmb3IgdGFyZ2V0IGluIHRhcmdldHM6CiAgICAgICAgY29sbGVjdGlvbl9uYW1lID0gdGFyZ2V0LmNvbGxlY3Rpb25fbmFtZQogICAgICAgIGVsaWdpYmxlID0gZmlsZXNfZWxpZ2libGVfYnlfY29sbGVjdGlvbltjb2xsZWN0aW9uX25hbWVdCiAgICAgICAgcHJvY2Vzc2VkID0gZmlsZXNfYnlfY29sbGVjdGlvbltjb2xsZWN0aW9uX25hbWVdCiAgICAgICAgdGFyZ2V0X2Vycm9ycyA9IGVycm9yc19ieV9jb2xsZWN0aW9uW2NvbGxlY3Rpb25fbmFtZV0KCiAgICAgICAgaWYgZWxpZ2libGUgPT0gMDoKICAgICAgICAgICAgcHJpbnQoZiJbQVZJU09dIE5lbmh1bSBhcnF1aXZvIGVsZWfDrXZlbCBwYXJhIHt0YXJnZXQubGFiZWx9OyBldGFwYSBpZ25vcmFkYS4iKQogICAgICAgIGVsaWYgcHJvY2Vzc2VkID09IDAgYW5kIHRhcmdldF9lcnJvcnMgPiAwOgogICAgICAgICAgICBwcmludCgKICAgICAgICAgICAgICAgIGYiW0FWSVNPXSB7ZWxpZ2libGV9IGFycXVpdm8ocykgZWxlZ8OtdmVsKGlzKSBwYXJhIHt0YXJnZXQubGFiZWx9LCAiCiAgICAgICAgICAgICAgICAibWFzIHRvZG9zIGZhbGhhcmFtLiIKICAgICAgICAgICAgKQoKICAgICAgICBpZiB0YXJnZXRfZXJyb3JzOgogICAgICAgICAgICBwcmludChmIltBVklTT10ge3RhcmdldF9lcnJvcnN9IGVycm8ocykgZHVyYW50ZSBhIGluZGV4YcOnw6NvIGRvIHRhcmdldCB7dGFyZ2V0LmxhYmVsfS4iKQogICAgICAgICAgICBmb3Igc2FtcGxlIGluIGVycm9yX3NhbXBsZXNfYnlfY29sbGVjdGlvbltjb2xsZWN0aW9uX25hbWVdOgogICAgICAgICAgICAgICAgcHJpbnQoZiIgICAgICAgIC0ge3NhbXBsZX0iKQoKICAgIGluZGV4X2ZpbmlzaGVkX2F0ID0gZGF0ZXRpbWUubm93KCkKICAgIGVsYXBzZWRfc2Vjb25kcyA9IGludCgoaW5kZXhfZmluaXNoZWRfYXQgLSBpbmRleF9zdGFydGVkX2F0KS50b3RhbF9zZWNvbmRzKCkpCiAgICBlbGFwc2VkX2ggPSBlbGFwc2VkX3NlY29uZHMgLy8gMzYwMAogICAgZWxhcHNlZF9tID0gKGVsYXBzZWRfc2Vjb25kcyAlIDM2MDApIC8vIDYwCiAgICBlbGFwc2VkX3MgPSBlbGFwc2VkX3NlY29uZHMgJSA2MAogICAgcHJpbnQoZiJcbnsnPScqNjB9IikKICAgIHByaW50KGYiICBJbmRleGHDp8OjbyBjb25jbHXDrWRhISIpCiAgICBwcmludChmIiAgSW7DrWNpbyAgICAgICAgICAgICAgIDoge2luZGV4X3N0YXJ0ZWRfYXQuc3RyZnRpbWUoJyVZLSVtLSVkICVIOiVNOiVTJyl9IikKICAgIHByaW50KGYiICBGaW0gICAgICAgICAgICAgICAgICA6IHtpbmRleF9maW5pc2hlZF9hdC5zdHJmdGltZSgnJVktJW0tJWQgJUg6JU06JVMnKX0iKQogICAgcHJpbnQoZiIgIER1cmHDp8OjbyAgICAgICAgICAgICAgOiB7ZWxhcHNlZF9oOjAyZH06e2VsYXBzZWRfbTowMmR9OntlbGFwc2VkX3M6MDJkfSIpCiAgICBwcmludChmIiAgQXJxdWl2b3MgdmFycmlkb3MgICAgOiB7ZmlsZXNfc2Nhbm5lZH0iKQogICAgcHJpbnQoZiIgIEFycXVpdm9zIHByb2Nlc3NhZG9zIDoge2ZpbGVzX3Byb2Nlc3NlZF90b3RhbH0iKQogICAgcHJpbnQoZiIgIFRvdGFsIGRlIGNodW5rcyAgICAgIDoge3RvdGFsX2NodW5rc30iKQogICAgcHJpbnQoZiIgIEVycm9zICAgICAgICAgICAgICAgIDoge2Vycm9yc30iKQogICAgZm9yIHRhcmdldCBpbiB0YXJnZXRzOgogICAgICAgIGNvbGxlY3Rpb25fbmFtZSA9IHRhcmdldC5jb2xsZWN0aW9uX25hbWUKICAgICAgICBwcmludCgKICAgICAgICAgICAgZiIgIENvbGXDp8OjbyBDaHJvbWFEQiAgICAgOiAne2NvbGxlY3Rpb25fbmFtZX0nICIKICAgICAgICAgICAgZiIoZWxlZ8OtdmVpcz17ZmlsZXNfZWxpZ2libGVfYnlfY29sbGVjdGlvbi5nZXQoY29sbGVjdGlvbl9uYW1lLCAwKX0sICIKICAgICAgICAgICAgZiJhcnF1aXZvcz17ZmlsZXNfYnlfY29sbGVjdGlvbi5nZXQoY29sbGVjdGlvbl9uYW1lLCAwKX0sICIKICAgICAgICAgICAgZiJjaHVua3M9e2NodW5rc19ieV9jb2xsZWN0aW9uLmdldChjb2xsZWN0aW9uX25hbWUsIDApfSkiCiAgICAgICAgKQogICAgcHJpbnQoZiJ7Jz0nKjYwfVxuIikKCgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgdHJ5OgogICAgICAgIG1haW4oKQogICAgZXhjZXB0IE1lbW9yeUVycm9yOgogICAgICAgIHByaW50KAogICAgICAgICAgICAiW0VSUk9dIEZhbGhhIGRlIG1lbcOzcmlhIGR1cmFudGUgYSBpbmRleGHDp8Ojby4gIgogICAgICAgICAgICAiVXNlIC0tZW1iZWRkaW5nLW1vZGVsIGJnZSBvdSBleGVjdXRlIG8gSmluYSBlbSBtw6FxdWluYSBjb20gbWFpcyBSQU0vc3dhcC4iCiAgICAgICAgKQogICAgICAgIHN5cy5leGl0KDEpCg=="
|
|
728
|
+
B64_MCP="IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwpmcm9tIF9fZnV0dXJlX18gaW1wb3J0IGFubm90YXRpb25zCiIiIgptY3Bfc2VydmVyLnB5IOKAlCBTZXJ2aWRvciBNQ1AgcGFyYSBSQUcgbG9jYWwgZGUgY29kZWJhc2UuCgpFeHDDtWUgZmVycmFtZW50YXMgZGUgYnVzY2Egc2Vtw6JudGljYSBlIGluZGV4YcOnw6NvIHZpYSBzdGRpbyBwYXJhIG8gQ2xhdWRlIENvZGUgQ0xJLgpDb25lY3RhLXNlIGFvIENocm9tYURCIHJvZGFuZG8gZW0gRG9ja2VyIChsb2NhbGhvc3Q6ODAwMCkuCgpOb3ZpZGFkZTogbW9kbyBow61icmlkbyBlbnNlbWJsZSBjb20gZHVhcyBjb2xlw6fDtWVzIHNlcGFyYWRhcyArIFJSRiArIHJlcmFua2luZyBsZXZlLgoiIiIKCmltcG9ydCBzeXMKaW1wb3J0IG9zCmltcG9ydCBoYXNobGliCmltcG9ydCBqc29uCmltcG9ydCBsb2dnaW5nCmltcG9ydCBnZXRwYXNzCmltcG9ydCBzaHV0aWwKZnJvbSBjb2xsZWN0aW9ucy5hYmMgaW1wb3J0IEl0ZXJhdG9yCmZyb20gY29uY3VycmVudC5mdXR1cmVzIGltcG9ydCBUaHJlYWRQb29sRXhlY3V0b3IsIGFzX2NvbXBsZXRlZApmcm9tIGRhdGFjbGFzc2VzIGltcG9ydCBkYXRhY2xhc3MKZnJvbSBkYXRldGltZSBpbXBvcnQgZGF0ZXRpbWUsIHRpbWV6b25lCmZyb20gcGF0aGxpYiBpbXBvcnQgUGF0aApmcm9tIHVybGxpYi5wYXJzZSBpbXBvcnQgdXJscGFyc2UKCiMgRXZpdGEgbWVuc2FnZW5zIGFkdmlzb3J5IGRvIHRyYW5zZm9ybWVycyBlbSBzdGRlcnIgZHVyYW50ZSBhIGNhcmdhIGRvIG1vZGVsby4Kb3MuZW52aXJvbi5zZXRkZWZhdWx0KCJUUkFOU0ZPUk1FUlNfTk9fQURWSVNPUllfV0FSTklOR1MiLCAiMSIpCgoKY2xhc3MgX1RvcmNoRHR5cGVXYXJuaW5nRmlsdGVyKGxvZ2dpbmcuRmlsdGVyKToKICAgIGRlZiBmaWx0ZXIoc2VsZiwgcmVjb3JkOiBsb2dnaW5nLkxvZ1JlY29yZCkgLT4gYm9vbDoKICAgICAgICByZXR1cm4gImB0b3JjaF9kdHlwZWAgaXMgZGVwcmVjYXRlZCEgVXNlIGBkdHlwZWAgaW5zdGVhZCEiIG5vdCBpbiByZWNvcmQuZ2V0TWVzc2FnZSgpCgoKZm9yIF9sb2dnZXJfbmFtZSBpbiAoInRyYW5zZm9ybWVycy5jb25maWd1cmF0aW9uX3V0aWxzIiwgInRyYW5zZm9ybWVycy5tb2RlbGluZ191dGlscyIpOgogICAgbG9nZ2luZy5nZXRMb2dnZXIoX2xvZ2dlcl9uYW1lKS5hZGRGaWx0ZXIoX1RvcmNoRHR5cGVXYXJuaW5nRmlsdGVyKCkpCgppbXBvcnQgY2hyb21hZGIKZnJvbSBzZW50ZW5jZV90cmFuc2Zvcm1lcnMgaW1wb3J0IENyb3NzRW5jb2RlciwgU2VudGVuY2VUcmFuc2Zvcm1lcgpmcm9tIGxhbmdjaGFpbl90ZXh0X3NwbGl0dGVycyBpbXBvcnQgUmVjdXJzaXZlQ2hhcmFjdGVyVGV4dFNwbGl0dGVyCmZyb20gbWNwLnNlcnZlci5mYXN0bWNwIGltcG9ydCBGYXN0TUNQCmZyb20gZG93bmxvYWRfbW9kZWxfZnJvbV9odWdnaW5mYWNlIGltcG9ydCBkb3dubG9hZF9tb2RlbF93aXRoX2ZhbGxiYWNrCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIENvbmZpZ3VyYcOnw6NvIGRlIGxvZ2dpbmcgKHN0ZGVyciBwYXJhIG7Do28gcG9sdWlyIG8gcHJvdG9jb2xvIHN0ZGlvKQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKbG9nZ2luZy5iYXNpY0NvbmZpZygKICAgIGxldmVsPWxvZ2dpbmcuSU5GTywKICAgIGZvcm1hdD0iW01DUC1SQUddICUoYXNjdGltZSlzICUobGV2ZWxuYW1lKXM6ICUobWVzc2FnZSlzIiwKICAgIHN0cmVhbT1zeXMuc3RkZXJyLAopCmxvZyA9IGxvZ2dpbmcuZ2V0TG9nZ2VyKF9fbmFtZV9fKQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBMb2cgZXN0cnV0dXJhZG8gZGUgdXNvIE1DUCAoSlNPTkwpCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpNQ1BfVVNBR0VfTE9HX1BBVEggPSBQYXRoKAogICAgb3MuZW52aXJvbi5nZXQoIk1DUF9VU0FHRV9MT0ciLCBzdHIoUGF0aC5ob21lKCkgLyAiLnJhZ19kYiIgLyAibWNwX3VzYWdlLmxvZyIpKQopLmV4cGFuZHVzZXIoKQoKCmRlZiBfc2FmZV9wcmV2aWV3KHZhbHVlOiBzdHIsIGxpbWl0OiBpbnQgPSAxMjApIC0+IHN0cjoKICAgIGlmIGxlbih2YWx1ZSkgPD0gbGltaXQ6CiAgICAgICAgcmV0dXJuIHZhbHVlCiAgICByZXR1cm4gdmFsdWVbOmxpbWl0XSArICIuLi5bdHJ1bmNhdGVkXSIKCgpkZWYgX2dldF9wYXJlbnRfY21kbGluZSgpIC0+IHN0cjoKICAgIHBwaWQgPSBvcy5nZXRwcGlkKCkKICAgIGNtZGxpbmVfcGF0aCA9IFBhdGgoZiIvcHJvYy97cHBpZH0vY21kbGluZSIpCiAgICB0cnk6CiAgICAgICAgcmF3ID0gY21kbGluZV9wYXRoLnJlYWRfYnl0ZXMoKQogICAgICAgIGlmIG5vdCByYXc6CiAgICAgICAgICAgIHJldHVybiAidW5rbm93biIKICAgICAgICBwYXJ0cyA9IFtwLmRlY29kZSgidXRmLTgiLCBlcnJvcnM9Imlnbm9yZSIpIGZvciBwIGluIHJhdy5zcGxpdChiIlx4MDAiKSBpZiBwXQogICAgICAgIHJldHVybiAiICIuam9pbihwYXJ0cykgaWYgcGFydHMgZWxzZSAidW5rbm93biIKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcmV0dXJuICJ1bmtub3duIgoKCmRlZiBfaW5mZXJfYWN0b3IoKSAtPiBkaWN0W3N0ciwgc3RyXToKICAgIGFjdG9yID0gb3MuZW52aXJvbi5nZXQoIk1DUF9DTElFTlRfTkFNRSIpIG9yIG9zLmVudmlyb24uZ2V0KCJDTEFVREVfVVNFUiIpIG9yIGdldHBhc3MuZ2V0dXNlcigpCiAgICBzb3VyY2UgPSAoCiAgICAgICAgIk1DUF9DTElFTlRfTkFNRSIgaWYgb3MuZW52aXJvbi5nZXQoIk1DUF9DTElFTlRfTkFNRSIpCiAgICAgICAgZWxzZSAiQ0xBVURFX1VTRVIiIGlmIG9zLmVudmlyb24uZ2V0KCJDTEFVREVfVVNFUiIpCiAgICAgICAgZWxzZSAic3lzdGVtX3VzZXIiCiAgICApCiAgICByZXR1cm4gewogICAgICAgICJhY3RvciI6IGFjdG9yLAogICAgICAgICJhY3Rvcl9zb3VyY2UiOiBzb3VyY2UsCiAgICAgICAgImNsaWVudF9wcm9jZXNzIjogX2dldF9wYXJlbnRfY21kbGluZSgpLAogICAgfQoKCmRlZiBfbG9nX3Rvb2xfdXNhZ2UoZXZlbnQ6IHN0ciwgdG9vbF9uYW1lOiBzdHIsIGRldGFpbHM6IGRpY3Rbc3RyLCBvYmplY3RdIHwgTm9uZSA9IE5vbmUpIC0+IE5vbmU6CiAgICB0cnk6CiAgICAgICAgTUNQX1VTQUdFX0xPR19QQVRILnBhcmVudC5ta2RpcihwYXJlbnRzPVRydWUsIGV4aXN0X29rPVRydWUpCiAgICAgICAgcGF5bG9hZDogZGljdFtzdHIsIG9iamVjdF0gPSB7CiAgICAgICAgICAgICJ0aW1lc3RhbXAiOiBkYXRldGltZS5ub3codGltZXpvbmUudXRjKS5pc29mb3JtYXQoKSwKICAgICAgICAgICAgImV2ZW50IjogZXZlbnQsCiAgICAgICAgICAgICJ0b29sIjogdG9vbF9uYW1lLAogICAgICAgICAgICAicGlkIjogb3MuZ2V0cGlkKCksCiAgICAgICAgICAgICoqX2luZmVyX2FjdG9yKCksCiAgICAgICAgfQogICAgICAgIGlmIGRldGFpbHM6CiAgICAgICAgICAgIHBheWxvYWRbImRldGFpbHMiXSA9IGRldGFpbHMKCiAgICAgICAgd2l0aCBNQ1BfVVNBR0VfTE9HX1BBVEgub3BlbigiYSIsIGVuY29kaW5nPSJ1dGYtOCIpIGFzIGY6CiAgICAgICAgICAgIGYud3JpdGUoanNvbi5kdW1wcyhwYXlsb2FkLCBlbnN1cmVfYXNjaWk9VHJ1ZSkgKyAiXG4iKQogICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgIGxvZy53YXJuaW5nKCJGYWxoYSBhbyByZWdpc3RyYXIgdXNvIE1DUCBlbSAlczogJXMiLCBNQ1BfVVNBR0VfTE9HX1BBVEgsIGUpCgoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBDb25maWd1cmHDp8O1ZXMKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgpJTkRFWEVSX0NPTkZJR19QQVRIID0gUGF0aCgKICAgIG9zLmVudmlyb24uZ2V0KAogICAgICAgICJNQ1BfSU5ERVhFUl9DT05GSUdfRklMRSIsCiAgICAgICAgc3RyKFBhdGguaG9tZSgpIC8gIi5jYWNoZSIgLyAib3duLXJhZy1jbGkiIC8gImluZGV4ZXJfdHVuaW5nLmpzb24iKSwKICAgICkKKS5leHBhbmR1c2VyKCkKT1dOX1JBR19DTElfQ09ORklHX1BBVEggPSBQYXRoKAogICAgb3MuZW52aXJvbi5nZXQoIk9XTl9SQUdfQ0xJX0NPTkZJR19GSUxFIiwgc3RyKFBhdGguaG9tZSgpIC8gIi5vd24tcmFnLWNsaS5qc29uIikpCikuZXhwYW5kdXNlcigpCgoKZGVmIF9sb2FkX2luZGV4ZXJfdHVuaW5nX2NvbmZpZygpIC0+IGRpY3Rbc3RyLCBvYmplY3RdOgogICAgdHJ5OgogICAgICAgIGlmIG5vdCBJTkRFWEVSX0NPTkZJR19QQVRILmV4aXN0cygpOgogICAgICAgICAgICByZXR1cm4ge30KICAgICAgICBwYXlsb2FkID0ganNvbi5sb2FkcyhJTkRFWEVSX0NPTkZJR19QQVRILnJlYWRfdGV4dChlbmNvZGluZz0idXRmLTgiKSkKICAgICAgICByZXR1cm4gcGF5bG9hZCBpZiBpc2luc3RhbmNlKHBheWxvYWQsIGRpY3QpIGVsc2Uge30KICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcmV0dXJuIHt9CgoKSU5ERVhFUl9UVU5JTkdfQ09ORklHID0gX2xvYWRfaW5kZXhlcl90dW5pbmdfY29uZmlnKCkKCgpkZWYgX2xvYWRfb3duX3JhZ19jbGlfY29uZmlnX3BheWxvYWQoKSAtPiBkaWN0W3N0ciwgb2JqZWN0XToKICAgIHRyeToKICAgICAgICBpZiBub3QgT1dOX1JBR19DTElfQ09ORklHX1BBVEguZXhpc3RzKCk6CiAgICAgICAgICAgIHJldHVybiB7fQogICAgICAgIHBheWxvYWQgPSBqc29uLmxvYWRzKE9XTl9SQUdfQ0xJX0NPTkZJR19QQVRILnJlYWRfdGV4dChlbmNvZGluZz0idXRmLTgiKSkKICAgICAgICByZXR1cm4gcGF5bG9hZCBpZiBpc2luc3RhbmNlKHBheWxvYWQsIGRpY3QpIGVsc2Uge30KICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcmV0dXJuIHt9CgoKZGVmIF9jb25maWdfc3RyKGVudl9uYW1lOiBzdHIsIGNvbmZpZ19rZXk6IHN0ciwgZGVmYXVsdDogc3RyKSAtPiBzdHI6CiAgICBlbnZfcmF3ID0gb3MuZW52aXJvbi5nZXQoZW52X25hbWUpCiAgICBpZiBlbnZfcmF3IGlzIG5vdCBOb25lIGFuZCBlbnZfcmF3LnN0cmlwKCk6CiAgICAgICAgcmV0dXJuIGVudl9yYXcKICAgIGNmZ19yYXcgPSBJTkRFWEVSX1RVTklOR19DT05GSUcuZ2V0KGNvbmZpZ19rZXkpCiAgICBpZiBpc2luc3RhbmNlKGNmZ19yYXcsIHN0cikgYW5kIGNmZ19yYXcuc3RyaXAoKToKICAgICAgICByZXR1cm4gY2ZnX3JhdwogICAgcmV0dXJuIGRlZmF1bHQKCgpkZWYgX3BhcnNlX2ludChyYXc6IG9iamVjdCwgZGVmYXVsdDogaW50LCAqLCBtaW5fdmFsdWU6IGludCA9IDEpIC0+IGludDoKICAgIHRyeToKICAgICAgICBwYXJzZWQgPSBpbnQoc3RyKHJhdykuc3RyaXAoKSkKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgcmV0dXJuIG1heChtaW5fdmFsdWUsIGRlZmF1bHQpCiAgICByZXR1cm4gbWF4KG1pbl92YWx1ZSwgcGFyc2VkKQoKCmRlZiBfZXh0cmFjdF9jaHJvbWFfZW5kcG9pbnRfZnJvbV9jb25maWcoY29uZmlnX3BheWxvYWQ6IG9iamVjdCkgLT4gdHVwbGVbc3RyLCBzdHIsIGludF06CiAgICBzY2hlbWUgPSAiaHR0cCIKICAgIGhvc3QgPSAibG9jYWxob3N0IgogICAgcG9ydCA9IDgwMDAKCiAgICBkZWYgX3JlYWRfc2NoZW1lKHJhdzogb2JqZWN0KSAtPiBOb25lOgogICAgICAgIG5vbmxvY2FsIHNjaGVtZQogICAgICAgIGlmIG5vdCBpc2luc3RhbmNlKHJhdywgc3RyKToKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgbG93ZXJlZCA9IHJhdy5zdHJpcCgpLmxvd2VyKCkKICAgICAgICBpZiBsb3dlcmVkIGluIHsiaHR0cCIsICJodHRwcyJ9OgogICAgICAgICAgICBzY2hlbWUgPSBsb3dlcmVkCgogICAgZGVmIF9yZWFkX2hvc3QocmF3OiBvYmplY3QpIC0+IE5vbmU6CiAgICAgICAgbm9ubG9jYWwgc2NoZW1lLCBob3N0LCBwb3J0CiAgICAgICAgaWYgbm90IGlzaW5zdGFuY2UocmF3LCBzdHIpOgogICAgICAgICAgICByZXR1cm4KICAgICAgICBjYW5kaWRhdGUgPSByYXcuc3RyaXAoKQogICAgICAgIGlmIG5vdCBjYW5kaWRhdGU6CiAgICAgICAgICAgIHJldHVybgogICAgICAgIHBhcnNlZCA9IHVybHBhcnNlKGNhbmRpZGF0ZSBpZiAiOi8vIiBpbiBjYW5kaWRhdGUgZWxzZSBmIi8ve2NhbmRpZGF0ZX0iKQogICAgICAgIGlmIHBhcnNlZC5zY2hlbWUgaW4geyJodHRwIiwgImh0dHBzIn06CiAgICAgICAgICAgIHNjaGVtZSA9IHBhcnNlZC5zY2hlbWUKICAgICAgICBpZiBwYXJzZWQuaG9zdG5hbWU6CiAgICAgICAgICAgIGhvc3QgPSBwYXJzZWQuaG9zdG5hbWUKICAgICAgICBlbGlmICI6Ly8iIG5vdCBpbiBjYW5kaWRhdGU6CiAgICAgICAgICAgIGhvc3QgPSBjYW5kaWRhdGUuc3RyaXAoKS5zdHJpcCgiLyIpCiAgICAgICAgaWYgcGFyc2VkLnBvcnQgYW5kIDEgPD0gcGFyc2VkLnBvcnQgPD0gNjU1MzU6CiAgICAgICAgICAgIHBvcnQgPSBwYXJzZWQucG9ydAoKICAgIGRlZiBfcmVhZF9wb3J0KHJhdzogb2JqZWN0KSAtPiBOb25lOgogICAgICAgIG5vbmxvY2FsIHBvcnQKICAgICAgICB0cnk6CiAgICAgICAgICAgIHBhcnNlZCA9IGludChzdHIocmF3KS5zdHJpcCgpKQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgICAgIHJldHVybgogICAgICAgIGlmIDEgPD0gcGFyc2VkIDw9IDY1NTM1OgogICAgICAgICAgICBwb3J0ID0gcGFyc2VkCgogICAgaWYgaXNpbnN0YW5jZShjb25maWdfcGF5bG9hZCwgZGljdCk6CiAgICAgICAgY2hyb21hX29iaiA9IGNvbmZpZ19wYXlsb2FkLmdldCgiY2hyb21hIikKICAgICAgICBpZiBpc2luc3RhbmNlKGNocm9tYV9vYmosIGRpY3QpOgogICAgICAgICAgICBfcmVhZF9zY2hlbWUoY2hyb21hX29iai5nZXQoInNjaGVtZSIpKQogICAgICAgICAgICBfcmVhZF9ob3N0KGNocm9tYV9vYmouZ2V0KCJob3N0IikpCiAgICAgICAgICAgIF9yZWFkX3BvcnQoY2hyb21hX29iai5nZXQoInBvcnQiKSkKCiAgICAgICAgIyBDb21wYXRpYmlsaWRhZGUgY29tIGZvcm1hdG9zIGZsYXQgYW50aWdvcy4KICAgICAgICBfcmVhZF9zY2hlbWUoY29uZmlnX3BheWxvYWQuZ2V0KCJDSFJPTUFfU0NIRU1FIikpCiAgICAgICAgX3JlYWRfaG9zdChjb25maWdfcGF5bG9hZC5nZXQoIkNIUk9NQV9IT1NUIikpCiAgICAgICAgX3JlYWRfcG9ydChjb25maWdfcGF5bG9hZC5nZXQoIkNIUk9NQV9QT1JUIikpCgogICAgcmV0dXJuIHNjaGVtZSwgaG9zdCwgcG9ydAoKCmRlZiBfZXh0cmFjdF9lbWJlZGRpbmdfYmF0Y2hfZnJvbV9jb25maWcoY29uZmlnX3BheWxvYWQ6IG9iamVjdCkgLT4gaW50IHwgTm9uZToKICAgIGlmIG5vdCBpc2luc3RhbmNlKGNvbmZpZ19wYXlsb2FkLCBkaWN0KToKICAgICAgICByZXR1cm4gTm9uZQoKICAgIGRlZiBfcmVhZChyYXc6IG9iamVjdCkgLT4gaW50IHwgTm9uZToKICAgICAgICB0cnk6CiAgICAgICAgICAgIHBhcnNlZCA9IGludChzdHIocmF3KS5zdHJpcCgpKQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgICAgIHJldHVybiBOb25lCiAgICAgICAgcmV0dXJuIHBhcnNlZCBpZiBwYXJzZWQgPj0gMSBlbHNlIE5vbmUKCiAgICBpbmRleGluZyA9IGNvbmZpZ19wYXlsb2FkLmdldCgiaW5kZXhpbmciKQogICAgaWYgaXNpbnN0YW5jZShpbmRleGluZywgZGljdCk6CiAgICAgICAgZm9yIGtleSBpbiAoImVtYmVkZGluZ19iYXRjaF9zaXplIiwgImJhdGNoX2NvdW50Iik6CiAgICAgICAgICAgIHBhcnNlZCA9IF9yZWFkKGluZGV4aW5nLmdldChrZXkpKQogICAgICAgICAgICBpZiBwYXJzZWQgaXMgbm90IE5vbmU6CiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VkCgogICAgZm9yIGtleSBpbiAoIk1DUF9FTUJFRERJTkdfQkFUQ0hfU0laRSIsICJlbWJlZGRpbmdfYmF0Y2hfc2l6ZSIsICJiYXRjaF9jb3VudCIpOgogICAgICAgIHBhcnNlZCA9IF9yZWFkKGNvbmZpZ19wYXlsb2FkLmdldChrZXkpKQogICAgICAgIGlmIHBhcnNlZCBpcyBub3QgTm9uZToKICAgICAgICAgICAgcmV0dXJuIHBhcnNlZAogICAgcmV0dXJuIE5vbmUKCgpkZWYgX2xvYWRfY2xpX2Nocm9tYV9kZWZhdWx0cygpIC0+IHR1cGxlW3N0ciwgc3RyLCBpbnRdOgogICAgcGF5bG9hZCA9IF9sb2FkX293bl9yYWdfY2xpX2NvbmZpZ19wYXlsb2FkKCkKICAgIGlmIG5vdCBwYXlsb2FkOgogICAgICAgIHJldHVybiAoImh0dHAiLCAibG9jYWxob3N0IiwgODAwMCkKICAgIHJldHVybiBfZXh0cmFjdF9jaHJvbWFfZW5kcG9pbnRfZnJvbV9jb25maWcocGF5bG9hZCkKCgpkZWYgX2NvbmZpZ19pbnQoCiAgICBlbnZfbmFtZTogc3RyLAogICAgY29uZmlnX2tleTogc3RyLAogICAgZGVmYXVsdDogaW50LAogICAgKiwKICAgIG1pbl92YWx1ZTogaW50ID0gMSwKICAgIGZhbGxiYWNrX2NvbmZpZ19rZXlzOiB0dXBsZVtzdHIsIC4uLl0gPSAoKSwKKSAtPiBpbnQ6CiAgICBlbnZfcmF3ID0gb3MuZW52aXJvbi5nZXQoZW52X25hbWUpCiAgICBpZiBlbnZfcmF3IGlzIG5vdCBOb25lIGFuZCBlbnZfcmF3LnN0cmlwKCk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICByZXR1cm4gbWF4KG1pbl92YWx1ZSwgaW50KGVudl9yYXcpKQogICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICBwYXNzCgogICAgZm9yIGtleSBpbiAoY29uZmlnX2tleSwgKmZhbGxiYWNrX2NvbmZpZ19rZXlzKToKICAgICAgICBjZmdfcmF3ID0gSU5ERVhFUl9UVU5JTkdfQ09ORklHLmdldChrZXkpCiAgICAgICAgaWYgaXNpbnN0YW5jZShjZmdfcmF3LCBpbnQpOgogICAgICAgICAgICByZXR1cm4gbWF4KG1pbl92YWx1ZSwgY2ZnX3JhdykKICAgICAgICBpZiBpc2luc3RhbmNlKGNmZ19yYXcsIHN0cik6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHJldHVybiBtYXgobWluX3ZhbHVlLCBpbnQoY2ZnX3JhdykpCiAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICAgICAgcGFzcwoKICAgIHJldHVybiBtYXgobWluX3ZhbHVlLCBkZWZhdWx0KQoKCl9ERUZBVUxUX0NIUk9NQV9TQ0hFTUUsIF9ERUZBVUxUX0NIUk9NQV9IT1NULCBfREVGQVVMVF9DSFJPTUFfUE9SVCA9IF9sb2FkX2NsaV9jaHJvbWFfZGVmYXVsdHMoKQpfREVGQVVMVF9FTUJFRERJTkdfQkFUQ0hfU0laRSA9IF9leHRyYWN0X2VtYmVkZGluZ19iYXRjaF9mcm9tX2NvbmZpZyhfbG9hZF9vd25fcmFnX2NsaV9jb25maWdfcGF5bG9hZCgpKSBvciA0CkNIUk9NQV9TQ0hFTUUgPSAoCiAgICBvcy5lbnZpcm9uLmdldCgiQ0hST01BX1NDSEVNRSIpCiAgICBvciBvcy5lbnZpcm9uLmdldCgiTUNQX0NIUk9NQV9TQ0hFTUUiKQogICAgb3IgX0RFRkFVTFRfQ0hST01BX1NDSEVNRQopLnN0cmlwKCkubG93ZXIoKQppZiBDSFJPTUFfU0NIRU1FIG5vdCBpbiB7Imh0dHAiLCAiaHR0cHMifToKICAgIENIUk9NQV9TQ0hFTUUgPSBfREVGQVVMVF9DSFJPTUFfU0NIRU1FCkNIUk9NQV9IT1NUID0gKAogICAgb3MuZW52aXJvbi5nZXQoIkNIUk9NQV9IT1NUIikKICAgIG9yIG9zLmVudmlyb24uZ2V0KCJNQ1BfQ0hST01BX0hPU1QiKQogICAgb3IgX0RFRkFVTFRfQ0hST01BX0hPU1QKKS5zdHJpcCgpIG9yIF9ERUZBVUxUX0NIUk9NQV9IT1NUCkNIUk9NQV9QT1JUID0gX3BhcnNlX2ludCgKICAgIG9zLmVudmlyb24uZ2V0KCJDSFJPTUFfUE9SVCIpCiAgICBvciBvcy5lbnZpcm9uLmdldCgiTUNQX0NIUk9NQV9QT1JUIikKICAgIG9yIF9ERUZBVUxUX0NIUk9NQV9QT1JULAogICAgX0RFRkFVTFRfQ0hST01BX1BPUlQsCiAgICBtaW5fdmFsdWU9MSwKKQpDSFJPTUFfU1NMID0gQ0hST01BX1NDSEVNRSA9PSAiaHR0cHMiCgojIENvbGXDp8O1ZXMgc2VwYXJhZGFzIHBvciBlc3BlY2lhbGl6YcOnw6NvIGRlIGVtYmVkZGluZwpDT0xMRUNUSU9OX0NPREVfSklOQSA9ICJjb2RlX3ZlY3RvcnNfamluYSIKQ09MTEVDVElPTl9ET0NfQkdFID0gImRvY192ZWN0b3JzX2JnZSIKCkpJTkFfVjNfRU1CRURESU5HX01PREVMID0gImppbmFhaS9qaW5hLWVtYmVkZGluZ3MtdjMiCkpJTkFfVjJfRU1CRURESU5HX01PREVMID0gImppbmFhaS9qaW5hLWVtYmVkZGluZ3MtdjItYmFzZS1jb2RlIgpCR0VfRU1CRURESU5HX01PREVMID0gIkJBQUkvYmdlLW0zIgoKREVGQVVMVF9FTUJFRERJTkdfTU9ERUxfQ0hPSUNFID0gImppbmEiCkRFRkFVTFRfSklOQV9RVUFOVElaQVRJT04gPSAiZHluYW1pYy1pbnQ4IgpERUZBVUxUX1NFQVJDSF9NT0RFID0gInNpbmdsZSIgICMgc2luZ2xlIHwgZW5zZW1ibGUKCl9lbWJlZGRpbmdfbW9kZWxfY2hvaWNlID0gX2NvbmZpZ19zdHIoCiAgICAiTUNQX0VNQkVERElOR19NT0RFTCIsCiAgICAiZW1iZWRkaW5nX21vZGVsIiwKICAgIERFRkFVTFRfRU1CRURESU5HX01PREVMX0NIT0lDRSwKKS5zdHJpcCgpLmxvd2VyKCkKaWYgX2VtYmVkZGluZ19tb2RlbF9jaG9pY2Ugbm90IGluIHsiamluYSIsICJiZ2UiLCAiaHlicmlkIn06CiAgICBsb2cud2FybmluZygKICAgICAgICAiTUNQX0VNQkVERElOR19NT0RFTCBpbnZhbGlkbyAnJXMnLiBVc2FuZG8gJyVzJy4iLAogICAgICAgIF9lbWJlZGRpbmdfbW9kZWxfY2hvaWNlLAogICAgICAgIERFRkFVTFRfRU1CRURESU5HX01PREVMX0NIT0lDRSwKICAgICkKICAgIF9lbWJlZGRpbmdfbW9kZWxfY2hvaWNlID0gREVGQVVMVF9FTUJFRERJTkdfTU9ERUxfQ0hPSUNFCgpfcmF3X2ppbmFfcXVhbnRpemF0aW9uID0gX2NvbmZpZ19zdHIoCiAgICAiTUNQX0pJTkFfUVVBTlRJWkFUSU9OIiwKICAgICJqaW5hX3F1YW50aXphdGlvbiIsCiAgICBERUZBVUxUX0pJTkFfUVVBTlRJWkFUSU9OLAopCkpJTkFfUVVBTlRJWkFUSU9OID0gX3Jhd19qaW5hX3F1YW50aXphdGlvbi5zdHJpcCgpLmxvd2VyKCkucmVwbGFjZSgiXyIsICItIikKaWYgSklOQV9RVUFOVElaQVRJT04gbm90IGluIHsiZGVmYXVsdCIsICJkeW5hbWljLWludDgifToKICAgIGxvZy53YXJuaW5nKAogICAgICAgICJNQ1BfSklOQV9RVUFOVElaQVRJT04gaW52YWxpZG8gJyVzJy4gVXNhbmRvICclcycuIiwKICAgICAgICBKSU5BX1FVQU5USVpBVElPTiwKICAgICAgICBERUZBVUxUX0pJTkFfUVVBTlRJWkFUSU9OLAogICAgKQogICAgSklOQV9RVUFOVElaQVRJT04gPSBERUZBVUxUX0pJTkFfUVVBTlRJWkFUSU9OCgpTRUFSQ0hfTU9ERV9ERUZBVUxUID0gb3MuZW52aXJvbi5nZXQoIk1DUF9TRUFSQ0hfTU9ERSIsIERFRkFVTFRfU0VBUkNIX01PREUpLnN0cmlwKCkubG93ZXIoKQppZiBTRUFSQ0hfTU9ERV9ERUZBVUxUIG5vdCBpbiB7InNpbmdsZSIsICJlbnNlbWJsZSJ9OgogICAgU0VBUkNIX01PREVfREVGQVVMVCA9IERFRkFVTFRfU0VBUkNIX01PREUKCmlmIF9lbWJlZGRpbmdfbW9kZWxfY2hvaWNlID09ICJoeWJyaWQiIGFuZCAiTUNQX1NFQVJDSF9NT0RFIiBub3QgaW4gb3MuZW52aXJvbjoKICAgICMgTm8gbW9kbyBow61icmlkbywgbyBjb21wb3J0YW1lbnRvIGVzcGVyYWRvIGNvc3R1bWEgc2VyIGVuc2VtYmxlIHBvciBwYWRyw6NvLgogICAgU0VBUkNIX01PREVfREVGQVVMVCA9ICJlbnNlbWJsZSIKClJFUkFOS19NT0RFTF9JRCA9IG9zLmVudmlyb24uZ2V0KCJNQ1BfUkVSQU5LX01PREVMIiwgImNyb3NzLWVuY29kZXIvbXMtbWFyY28tTWluaUxNLUwtNi12MiIpClJFUkFOS19FTkFCTEVEID0gb3MuZW52aXJvbi5nZXQoIk1DUF9SRVJBTktfRU5BQkxFRCIsICJ0cnVlIikuc3RyaXAoKS5sb3dlcigpIGluIHsiMSIsICJ0cnVlIiwgInllcyIsICJvbiJ9ClJFUkFOS19DQU5ESURBVEVfTVVMVElQTElFUiA9IGludChvcy5lbnZpcm9uLmdldCgiTUNQX1JFUkFOS19DQU5ESURBVEVfTVVMVElQTElFUiIsICIzIikpClJFUkFOS19NQVhfQ0FORElEQVRFUyA9IGludChvcy5lbnZpcm9uLmdldCgiTUNQX1JFUkFOS19NQVhfQ0FORElEQVRFUyIsICI0MCIpKQpSRVJBTktFUl9NQVhfTEVOR1RIID0gaW50KG9zLmVudmlyb24uZ2V0KCJNQ1BfUkVSQU5LX01BWF9MRU5HVEgiLCAiNTEyIikpClJFUkFOS0VSX1FVQU5USVpBVElPTiA9IG9zLmVudmlyb24uZ2V0KCJNQ1BfUkVSQU5LX1FVQU5USVpBVElPTiIsICJkeW5hbWljLWludDgiKS5zdHJpcCgpLmxvd2VyKCkKaWYgUkVSQU5LRVJfUVVBTlRJWkFUSU9OIG5vdCBpbiB7ImRlZmF1bHQiLCAiZHluYW1pYy1pbnQ4In06CiAgICBSRVJBTktFUl9RVUFOVElaQVRJT04gPSAiZHluYW1pYy1pbnQ4IgoKUlJGX0sgPSBpbnQob3MuZW52aXJvbi5nZXQoIk1DUF9SUkZfSyIsICI2MCIpKQpFTUJFRERJTkdfQkFUQ0hfU0laRSA9IF9jb25maWdfaW50KAogICAgIk1DUF9FTUJFRERJTkdfQkFUQ0hfU0laRSIsCiAgICAiZW1iZWRkaW5nX2JhdGNoX3NpemUiLAogICAgX0RFRkFVTFRfRU1CRURESU5HX0JBVENIX1NJWkUsCiAgICBtaW5fdmFsdWU9MSwKICAgIGZhbGxiYWNrX2NvbmZpZ19rZXlzPSgiYmF0Y2hfY291bnQiLCksCikKCl9lbnZfbW9kZWxfZGlyID0gb3MuZW52aXJvbi5nZXQoIk1DUF9NT0RFTF9ESVIiKQpNT0RFTF9ESVIgPSAoCiAgICBQYXRoKF9lbnZfbW9kZWxfZGlyKS5leHBhbmR1c2VyKCkKICAgIGlmIF9lbnZfbW9kZWxfZGlyCiAgICBlbHNlIFBhdGguaG9tZSgpIC8gIi5jYWNoZSIgLyAib3duLXJhZy1jbGkiIC8gIm1vZGVscyIKKQoKIyBQYXLDom1ldHJvcyBkbyBzcGxpdHRlciAoYWxpbmhhZG9zIGNvbSBpbmRleGVyX2Z1bGwucHksIHBlcmZpbCBsb3ctbWVtb3J5KQpDSFVOS19TSVpFID0gX2NvbmZpZ19pbnQoIk1DUF9DSFVOS19TSVpFIiwgImNodW5rX3NpemUiLCAzMDAwLCBtaW5fdmFsdWU9MjU2KQpDSFVOS19PVkVSTEFQID0gbWluKENIVU5LX1NJWkUgLSAxLCBfY29uZmlnX2ludCgiTUNQX0NIVU5LX09WRVJMQVAiLCAiY2h1bmtfb3ZlcmxhcCIsIDQwMCwgbWluX3ZhbHVlPTApKQoKTUFYX0ZJTEVfU0laRV9CWVRFUyA9IDUwMCAqIDEwMjQgICMgNTAwIEtCClRPUF9LX1JFU1VMVFMgPSA3Ck1BWF9RVUVSWV9SRVNVTFRTID0gMzAKCiMgRmlsdHJvcyBkZSB2YXJyZWR1cmEKSUdOT1JFRF9ESVJTID0gewogICAgIi5naXQiLCAibm9kZV9tb2R1bGVzIiwgIl9fcHljYWNoZV9fIiwgIi52ZW52IiwgInZlbnYiLCAiZW52IiwKICAgICJkaXN0IiwgImJ1aWxkIiwgIm91dCIsICIubmV4dCIsICIubnV4dCIsICIuY2FjaGUiLCAiY292ZXJhZ2UiLAogICAgIi5weXRlc3RfY2FjaGUiLCAiLm15cHlfY2FjaGUiLCAiLnJ1ZmZfY2FjaGUiLCAidGFyZ2V0IiwgImJpbiIsICJvYmoiLAogICAgIi5pZGVhIiwgIi52c2NvZGUiLCAidmVuZG9yIiwgInRtcCIsICJ0ZW1wIiwgImxvZ3MiLCAiLnJhZ19kYiIsCn0KCklHTk9SRURfRVhURU5TSU9OUyA9IHsKICAgICIucG5nIiwgIi5qcGciLCAiLmpwZWciLCAiLmdpZiIsICIuc3ZnIiwgIi5pY28iLCAiLndlYnAiLCAiLmJtcCIsCiAgICAiLm1wNCIsICIubXAzIiwgIi53YXYiLCAiLm9nZyIsICIuYXZpIiwgIi5tb3YiLAogICAgIi56aXAiLCAiLnRhciIsICIuZ3oiLCAiLnJhciIsICIuN3oiLCAiLmphciIsICIud2FyIiwKICAgICIucHljIiwgIi5weW8iLCAiLnNvIiwgIi5kbGwiLCAiLmV4ZSIsICIuYmluIiwgIi5ydW4iLAogICAgIi5sb2NrIiwgIi5zdW0iLCAiLnNxbGl0ZSIsICIuZGIiLCAiLnNxbGl0ZTMiLAogICAgIi50dGYiLCAiLndvZmYiLCAiLndvZmYyIiwgIi5lb3QiLAogICAgIi5wZGYiLCAiLmRvY3giLCAiLnhsc3giLCAiLnBwdHgiLAp9CgpDT0RFX0VYVEVOU0lPTlMgPSB7CiAgICAiLnB5IiwgIi5qcyIsICIudHMiLCAiLnRzeCIsICIuanN4IiwgIi5qYXZhIiwgIi5jIiwgIi5oIiwgIi5jcHAiLCAiLmhwcCIsCiAgICAiLmdvIiwgIi5ycyIsICIucmIiLCAiLnBocCIsICIuY3MiLCAiLnN3aWZ0IiwgIi5rdCIsICIua3RzIiwgIi5zY2FsYSIsICIuc3FsIiwKICAgICIuc2giLCAiLmJhc2giLCAiLnpzaCIsICIucHMxIiwgIi55YW1sIiwgIi55bWwiLCAiLnRvbWwiLCAiLmluaSIsICIuY29uZiIsCiAgICAiLmpzb24iLCAiLnhtbCIsICIuaHRtbCIsICIuY3NzIiwgIi5zY3NzIiwgIi5zYXNzIiwgIi52dWUiLCAiLnN2ZWx0ZSIsICIuZGFydCIsCiAgICAiLmx1YSIsICIuciIsICIubSIsICIubW0iLAp9CgpET0NfRVhURU5TSU9OUyA9IHsKICAgICIubWQiLCAiLm1keCIsICIucnN0IiwgIi50eHQiLCAiLmFkb2MiLCAiLm9yZyIsICIudGV4IiwgIi5jc3YiLAp9CgoKQGRhdGFjbGFzcyhmcm96ZW49VHJ1ZSkKY2xhc3MgQnJhbmNoU3BlYzoKICAgIGtleTogc3RyCiAgICBtb2RlbF9jaG9pY2U6IHN0cgogICAgbW9kZWxfaWQ6IHN0cgogICAgY29sbGVjdGlvbl9uYW1lOiBzdHIKICAgIGNvbnRlbnRfZG9tYWluOiBzdHIKICAgIGxhYmVsOiBzdHIKCgpKSU5BX0NPREVfQlJBTkNIX01PREVMX0NIT0lDRSA9ICJqaW5hX3YyIiBpZiBfZW1iZWRkaW5nX21vZGVsX2Nob2ljZSA9PSAiaHlicmlkIiBlbHNlICJqaW5hIgpKSU5BX0NPREVfQlJBTkNIX01PREVMX0lEID0gSklOQV9WMl9FTUJFRERJTkdfTU9ERUwgaWYgX2VtYmVkZGluZ19tb2RlbF9jaG9pY2UgPT0gImh5YnJpZCIgZWxzZSBKSU5BX1YzX0VNQkVERElOR19NT0RFTAoKQlJBTkNIX1NQRUNTOiBkaWN0W3N0ciwgQnJhbmNoU3BlY10gPSB7CiAgICAiamluYV9jb2RlIjogQnJhbmNoU3BlYygKICAgICAgICBrZXk9ImppbmFfY29kZSIsCiAgICAgICAgbW9kZWxfY2hvaWNlPUpJTkFfQ09ERV9CUkFOQ0hfTU9ERUxfQ0hPSUNFLAogICAgICAgIG1vZGVsX2lkPUpJTkFfQ09ERV9CUkFOQ0hfTU9ERUxfSUQsCiAgICAgICAgY29sbGVjdGlvbl9uYW1lPUNPTExFQ1RJT05fQ09ERV9KSU5BLAogICAgICAgIGNvbnRlbnRfZG9tYWluPSJjb2RlIiwKICAgICAgICBsYWJlbD0iSmluYSB2MiBDb2RlIiBpZiBfZW1iZWRkaW5nX21vZGVsX2Nob2ljZSA9PSAiaHlicmlkIiBlbHNlICJKaW5hIHYzIENvZGUiLAogICAgKSwKICAgICJiZ2VfZG9jIjogQnJhbmNoU3BlYygKICAgICAgICBrZXk9ImJnZV9kb2MiLAogICAgICAgIG1vZGVsX2Nob2ljZT0iYmdlIiwKICAgICAgICBtb2RlbF9pZD1CR0VfRU1CRURESU5HX01PREVMLAogICAgICAgIGNvbGxlY3Rpb25fbmFtZT1DT0xMRUNUSU9OX0RPQ19CR0UsCiAgICAgICAgY29udGVudF9kb21haW49ImRvYyIsCiAgICAgICAgbGFiZWw9IkJHRSBEb2NzIiwKICAgICksCn0KCkRFRkFVTFRfU0lOR0xFX0JSQU5DSF9LRVkgPSAiYmdlX2RvYyIgaWYgX2VtYmVkZGluZ19tb2RlbF9jaG9pY2UgPT0gImJnZSIgZWxzZSAiamluYV9jb2RlIgoKCkBkYXRhY2xhc3MKY2xhc3MgUmV0cmlldmVkSGl0OgogICAga2V5OiBzdHIKICAgIGRvY3VtZW50OiBzdHIKICAgIG1ldGFkYXRhOiBkaWN0W3N0ciwgb2JqZWN0XQogICAgZGlzdGFuY2U6IGZsb2F0IHwgTm9uZQogICAgc2ltaWxhcml0eTogZmxvYXQgfCBOb25lCiAgICBicmFuY2g6IEJyYW5jaFNwZWMKICAgIHJhbms6IGludAoKCkBkYXRhY2xhc3MKY2xhc3MgRnVzZWRIaXQ6CiAgICBrZXk6IHN0cgogICAgZG9jdW1lbnQ6IHN0cgogICAgbWV0YWRhdGE6IGRpY3Rbc3RyLCBvYmplY3RdCiAgICBycmZfc2NvcmU6IGZsb2F0CiAgICBzb3VyY2VfZGV0YWlsczogZGljdFtzdHIsIGRpY3Rbc3RyLCBvYmplY3RdXQogICAgcmVyYW5rX3Njb3JlOiBmbG9hdCB8IE5vbmUgPSBOb25lCgoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBSdW50aW1lIGNhY2hlcyAobGF6eSBsb2FkaW5nIHBhcmEgZWNvbm9taXphciBSQU0pCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpfY2hyb21hX2NsaWVudDogY2hyb21hZGIuSHR0cENsaWVudCB8IE5vbmUgPSBOb25lCl9jb2xsZWN0aW9uczogZGljdFtzdHIsIGNocm9tYWRiLkNvbGxlY3Rpb25dID0ge30KX21vZGVsczogZGljdFtzdHIsIFNlbnRlbmNlVHJhbnNmb3JtZXJdID0ge30KX21vZGVsX2xvYWRfZXJyb3JzOiBkaWN0W3N0ciwgc3RyXSA9IHt9Cl9zcGxpdHRlcjogUmVjdXJzaXZlQ2hhcmFjdGVyVGV4dFNwbGl0dGVyIHwgTm9uZSA9IE5vbmUKX3JlcmFua2VyOiBDcm9zc0VuY29kZXIgfCBOb25lID0gTm9uZQpfcmVyYW5rZXJfZXJyb3I6IHN0ciB8IE5vbmUgPSBOb25lCgoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBDaHJvbWEgZSBtb2RlbG9zCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoKZGVmIF9tb2RlbF9jYWNoZV9kaXIoYmFzZV9kaXI6IFBhdGgsIG1vZGVsX2lkOiBzdHIpIC0+IFBhdGg6CiAgICBzYWZlX25hbWUgPSBtb2RlbF9pZC5yZXBsYWNlKCIvIiwgIl9fIikucmVwbGFjZSgiOiIsICJfIikKICAgIHJldHVybiBiYXNlX2RpciAvIHNhZmVfbmFtZQoKCmRlZiBfZ2V0X2Nocm9tYV9jbGllbnQoKSAtPiBjaHJvbWFkYi5IdHRwQ2xpZW50OgogICAgZ2xvYmFsIF9jaHJvbWFfY2xpZW50CiAgICBpZiBfY2hyb21hX2NsaWVudCBpcyBOb25lOgogICAgICAgIF9jaHJvbWFfY2xpZW50ID0gY2hyb21hZGIuSHR0cENsaWVudChob3N0PUNIUk9NQV9IT1NULCBwb3J0PUNIUk9NQV9QT1JULCBzc2w9Q0hST01BX1NTTCkKICAgICAgICBfY2hyb21hX2NsaWVudC5oZWFydGJlYXQoKQogICAgICAgIGxvZy5pbmZvKCJDb25lY3RhZG8gYW8gQ2hyb21hREIgZW0gJXM6Ly8lczolcyIsIENIUk9NQV9TQ0hFTUUsIENIUk9NQV9IT1NULCBDSFJPTUFfUE9SVCkKICAgIHJldHVybiBfY2hyb21hX2NsaWVudAoKCmRlZiBnZXRfY2hyb21hX2NvbGxlY3Rpb24oY29sbGVjdGlvbl9uYW1lOiBzdHIpIC0+IGNocm9tYWRiLkNvbGxlY3Rpb246CiAgICBpZiBjb2xsZWN0aW9uX25hbWUgaW4gX2NvbGxlY3Rpb25zOgogICAgICAgIHJldHVybiBfY29sbGVjdGlvbnNbY29sbGVjdGlvbl9uYW1lXQoKICAgIHRyeToKICAgICAgICBjbGllbnQgPSBfZ2V0X2Nocm9tYV9jbGllbnQoKQogICAgICAgIGNvbGxlY3Rpb24gPSBjbGllbnQuZ2V0X29yX2NyZWF0ZV9jb2xsZWN0aW9uKAogICAgICAgICAgICBuYW1lPWNvbGxlY3Rpb25fbmFtZSwKICAgICAgICAgICAgbWV0YWRhdGE9eyJobnN3OnNwYWNlIjogImNvc2luZSJ9LAogICAgICAgICkKICAgICAgICBfY29sbGVjdGlvbnNbY29sbGVjdGlvbl9uYW1lXSA9IGNvbGxlY3Rpb24KICAgICAgICByZXR1cm4gY29sbGVjdGlvbgogICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgIHJhaXNlIFJ1bnRpbWVFcnJvcigKICAgICAgICAgICAgZiJOw6NvIGZvaSBwb3Nzw612ZWwgYWNlc3NhciBhIGNvbGXDp8OjbyAne2NvbGxlY3Rpb25fbmFtZX0nIG5vIENocm9tYURCICIKICAgICAgICAgICAgZiIoe0NIUk9NQV9TQ0hFTUV9Oi8ve0NIUk9NQV9IT1NUfTp7Q0hST01BX1BPUlR9KS4gRXJybzoge2V9IgogICAgICAgICkKCgpkZWYgX2xvYWRfc2VudGVuY2VfdHJhbnNmb3JtZXJfZnJvbV9sb2NhbChtb2RlbF9pZDogc3RyLCBsb2NhbF9tb2RlbF9kaXI6IFBhdGgpIC0+IFNlbnRlbmNlVHJhbnNmb3JtZXI6CiAgICB0cnVzdF9yZW1vdGVfY29kZSA9IG1vZGVsX2lkLnN0YXJ0c3dpdGgoImppbmFhaS8iKQogICAgdG9rZW5pemVyX2t3YXJncyA9IHsiZml4X21pc3RyYWxfcmVnZXgiOiBUcnVlfQoKICAgIGRlZiBfaW5zdGFudGlhdGVfbW9kZWwoKSAtPiBTZW50ZW5jZVRyYW5zZm9ybWVyOgogICAgICAgIHJldHVybiBTZW50ZW5jZVRyYW5zZm9ybWVyKAogICAgICAgICAgICBzdHIobG9jYWxfbW9kZWxfZGlyKSwKICAgICAgICAgICAgZGV2aWNlPSJjcHUiLAogICAgICAgICAgICB0cnVzdF9yZW1vdGVfY29kZT10cnVzdF9yZW1vdGVfY29kZSwKICAgICAgICAgICAgdG9rZW5pemVyX2t3YXJncz10b2tlbml6ZXJfa3dhcmdzLAogICAgICAgICkKCiAgICBkZWYgX2NsZWFyX2hmX2R5bmFtaWNfbW9kdWxlc19jYWNoZSgpIC0+IE5vbmU6CiAgICAgICAgY2FjaGVfZGlyID0gUGF0aC5ob21lKCkgLyAiLmNhY2hlIiAvICJodWdnaW5nZmFjZSIgLyAibW9kdWxlcyIgLyAidHJhbnNmb3JtZXJzX21vZHVsZXMiCiAgICAgICAgaWYgY2FjaGVfZGlyLmV4aXN0cygpOgogICAgICAgICAgICBsb2cud2FybmluZygiTGltcGFuZG8gY2FjaGUgZGluw6JtaWNvIGRvIEh1Z2dpbmcgRmFjZSBlbSAlcyIsIGNhY2hlX2RpcikKICAgICAgICAgICAgc2h1dGlsLnJtdHJlZShjYWNoZV9kaXIsIGlnbm9yZV9lcnJvcnM9VHJ1ZSkKCiAgICBkZWYgX2xvYWRfd2l0aF9qaW5hX3BhdGNoKCkgLT4gU2VudGVuY2VUcmFuc2Zvcm1lcjoKICAgICAgICBpZiBub3QgdHJ1c3RfcmVtb3RlX2NvZGU6CiAgICAgICAgICAgIHJldHVybiBfaW5zdGFudGlhdGVfbW9kZWwoKQoKICAgICAgICBmcm9tIHRyYW5zZm9ybWVycyBpbXBvcnQgQXV0b01vZGVsLCBBdXRvVG9rZW5pemVyCiAgICAgICAgZnJvbSB0cmFuc2Zvcm1lcnMubW9kZWxpbmdfdXRpbHMgaW1wb3J0IFByZVRyYWluZWRNb2RlbAoKICAgICAgICBvcmlnaW5hbF9mcm9tX3ByZXRyYWluZWQgPSBBdXRvVG9rZW5pemVyLmZyb21fcHJldHJhaW5lZAogICAgICAgIG9yaWdpbmFsX21vZGVsX2Zyb21fcHJldHJhaW5lZCA9IEF1dG9Nb2RlbC5mcm9tX3ByZXRyYWluZWQKICAgICAgICBvcmlnaW5hbF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fcHJldHJhaW5lZCA9IFByZVRyYWluZWRNb2RlbC5mcm9tX3ByZXRyYWluZWQKICAgICAgICBvcmlnaW5hbF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fY29uZmlnID0gUHJlVHJhaW5lZE1vZGVsLl9mcm9tX2NvbmZpZwogICAgICAgIG1vZGVsX3JlZnMgPSB7c3RyKGxvY2FsX21vZGVsX2RpciksIHN0cihsb2NhbF9tb2RlbF9kaXIucmVzb2x2ZSgpKX0KCiAgICAgICAgZGVmIF9wYXRjaGVkX2Zyb21fcHJldHJhaW5lZCgqYXJncywgKiprd2FyZ3MpOgogICAgICAgICAgICBtb2RlbF9yZWYgPSBhcmdzWzBdIGlmIGFyZ3MgZWxzZSBrd2FyZ3MuZ2V0KCJwcmV0cmFpbmVkX21vZGVsX25hbWVfb3JfcGF0aCIpCiAgICAgICAgICAgIGlmIG1vZGVsX3JlZiBpcyBub3QgTm9uZSBhbmQgc3RyKG1vZGVsX3JlZikgaW4gbW9kZWxfcmVmczoKICAgICAgICAgICAgICAgIGt3YXJncy5zZXRkZWZhdWx0KCJmaXhfbWlzdHJhbF9yZWdleCIsIFRydWUpCiAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbF9mcm9tX3ByZXRyYWluZWQoKmFyZ3MsICoqa3dhcmdzKQoKICAgICAgICBkZWYgX3BhdGNoZWRfbW9kZWxfZnJvbV9wcmV0cmFpbmVkKCphcmdzLCAqKmt3YXJncyk6CiAgICAgICAgICAgIG1vZGVsX3JlZiA9IGFyZ3NbMF0gaWYgYXJncyBlbHNlIGt3YXJncy5nZXQoInByZXRyYWluZWRfbW9kZWxfbmFtZV9vcl9wYXRoIikKICAgICAgICAgICAgaWYgbW9kZWxfcmVmIGlzIG5vdCBOb25lIGFuZCBzdHIobW9kZWxfcmVmKSBpbiBtb2RlbF9yZWZzIGFuZCAidG9yY2hfZHR5cGUiIGluIGt3YXJnczoKICAgICAgICAgICAgICAgIGt3YXJncyA9IGRpY3Qoa3dhcmdzKQogICAgICAgICAgICAgICAgaWYgImR0eXBlIiBub3QgaW4ga3dhcmdzOgogICAgICAgICAgICAgICAgICAgIGt3YXJnc1siZHR5cGUiXSA9IGt3YXJnc1sidG9yY2hfZHR5cGUiXQogICAgICAgICAgICAgICAga3dhcmdzLnBvcCgidG9yY2hfZHR5cGUiLCBOb25lKQogICAgICAgICAgICByZXR1cm4gb3JpZ2luYWxfbW9kZWxfZnJvbV9wcmV0cmFpbmVkKCphcmdzLCAqKmt3YXJncykKCiAgICAgICAgb3JpZ2luYWxfcHJldHJhaW5lZF9tb2RlbF9mcm9tX3ByZXRyYWluZWRfZm4gPSBvcmlnaW5hbF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fcHJldHJhaW5lZC5fX2Z1bmNfXwoKICAgICAgICBAY2xhc3NtZXRob2QKICAgICAgICBkZWYgX3BhdGNoZWRfcHJldHJhaW5lZF9tb2RlbF9mcm9tX3ByZXRyYWluZWQoY2xzLCAqYXJncywgKiprd2FyZ3MpOgogICAgICAgICAgICBpZiAidG9yY2hfZHR5cGUiIGluIGt3YXJnczoKICAgICAgICAgICAgICAgIGt3YXJncyA9IGRpY3Qoa3dhcmdzKQogICAgICAgICAgICAgICAgaWYgImR0eXBlIiBub3QgaW4ga3dhcmdzOgogICAgICAgICAgICAgICAgICAgIGt3YXJnc1siZHR5cGUiXSA9IGt3YXJnc1sidG9yY2hfZHR5cGUiXQogICAgICAgICAgICAgICAga3dhcmdzLnBvcCgidG9yY2hfZHR5cGUiLCBOb25lKQogICAgICAgICAgICByZXR1cm4gb3JpZ2luYWxfcHJldHJhaW5lZF9tb2RlbF9mcm9tX3ByZXRyYWluZWRfZm4oY2xzLCAqYXJncywgKiprd2FyZ3MpCgogICAgICAgIG9yaWdpbmFsX3ByZXRyYWluZWRfbW9kZWxfZnJvbV9jb25maWdfZm4gPSBvcmlnaW5hbF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fY29uZmlnLl9fZnVuY19fCgogICAgICAgIEBjbGFzc21ldGhvZAogICAgICAgIGRlZiBfcGF0Y2hlZF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fY29uZmlnKGNscywgKmFyZ3MsICoqa3dhcmdzKToKICAgICAgICAgICAgaWYgInRvcmNoX2R0eXBlIiBpbiBrd2FyZ3M6CiAgICAgICAgICAgICAgICBrd2FyZ3MgPSBkaWN0KGt3YXJncykKICAgICAgICAgICAgICAgIGlmICJkdHlwZSIgbm90IGluIGt3YXJnczoKICAgICAgICAgICAgICAgICAgICBrd2FyZ3NbImR0eXBlIl0gPSBrd2FyZ3NbInRvcmNoX2R0eXBlIl0KICAgICAgICAgICAgICAgIGt3YXJncy5wb3AoInRvcmNoX2R0eXBlIiwgTm9uZSkKICAgICAgICAgICAgcmV0dXJuIG9yaWdpbmFsX3ByZXRyYWluZWRfbW9kZWxfZnJvbV9jb25maWdfZm4oY2xzLCAqYXJncywgKiprd2FyZ3MpCgogICAgICAgIEF1dG9Ub2tlbml6ZXIuZnJvbV9wcmV0cmFpbmVkID0gX3BhdGNoZWRfZnJvbV9wcmV0cmFpbmVkCiAgICAgICAgQXV0b01vZGVsLmZyb21fcHJldHJhaW5lZCA9IF9wYXRjaGVkX21vZGVsX2Zyb21fcHJldHJhaW5lZAogICAgICAgIFByZVRyYWluZWRNb2RlbC5mcm9tX3ByZXRyYWluZWQgPSBfcGF0Y2hlZF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fcHJldHJhaW5lZAogICAgICAgIFByZVRyYWluZWRNb2RlbC5fZnJvbV9jb25maWcgPSBfcGF0Y2hlZF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fY29uZmlnCiAgICAgICAgdHJ5OgogICAgICAgICAgICByZXR1cm4gX2luc3RhbnRpYXRlX21vZGVsKCkKICAgICAgICBmaW5hbGx5OgogICAgICAgICAgICBBdXRvVG9rZW5pemVyLmZyb21fcHJldHJhaW5lZCA9IG9yaWdpbmFsX2Zyb21fcHJldHJhaW5lZAogICAgICAgICAgICBBdXRvTW9kZWwuZnJvbV9wcmV0cmFpbmVkID0gb3JpZ2luYWxfbW9kZWxfZnJvbV9wcmV0cmFpbmVkCiAgICAgICAgICAgIFByZVRyYWluZWRNb2RlbC5mcm9tX3ByZXRyYWluZWQgPSBvcmlnaW5hbF9wcmV0cmFpbmVkX21vZGVsX2Zyb21fcHJldHJhaW5lZAogICAgICAgICAgICBQcmVUcmFpbmVkTW9kZWwuX2Zyb21fY29uZmlnID0gb3JpZ2luYWxfcHJldHJhaW5lZF9tb2RlbF9mcm9tX2NvbmZpZwoKICAgIHRyeToKICAgICAgICByZXR1cm4gX2xvYWRfd2l0aF9qaW5hX3BhdGNoKCkKICAgIGV4Y2VwdCBGaWxlTm90Rm91bmRFcnJvciBhcyBlOgogICAgICAgIGlmIHRydXN0X3JlbW90ZV9jb2RlIGFuZCAidHJhbnNmb3JtZXJzX21vZHVsZXMiIGluIHN0cihlKToKICAgICAgICAgICAgbG9nLndhcm5pbmcoIkNhY2hlIGRpbsOibWljbyBpbmNvbnNpc3RlbnRlIGRldGVjdGFkbzogJXMiLCBlKQogICAgICAgICAgICBfY2xlYXJfaGZfZHluYW1pY19tb2R1bGVzX2NhY2hlKCkKICAgICAgICAgICAgcmV0dXJuIF9sb2FkX3dpdGhfamluYV9wYXRjaCgpCiAgICAgICAgcmFpc2UKCgpkZWYgX2FwcGx5X2ppbmFfcXVhbnRpemF0aW9uX2lmX25lZWRlZChtb2RlbDogU2VudGVuY2VUcmFuc2Zvcm1lciwgbW9kZWxfaWQ6IHN0cikgLT4gU2VudGVuY2VUcmFuc2Zvcm1lcjoKICAgIGlmIG1vZGVsX2lkICE9IEpJTkFfVjNfRU1CRURESU5HX01PREVMIG9yIEpJTkFfUVVBTlRJWkFUSU9OID09ICJkZWZhdWx0IjoKICAgICAgICByZXR1cm4gbW9kZWwKCiAgICB0cnk6CiAgICAgICAgaW1wb3J0IHRvcmNoCiAgICAgICAgaW1wb3J0IHdhcm5pbmdzCgogICAgICAgIHF1YW50aXplZF9sYXllcnMgPSAwCiAgICAgICAgZm9yIG1vZHVsZSBpbiBtb2RlbC5tb2R1bGVzKCk6CiAgICAgICAgICAgIGlmIHR5cGUobW9kdWxlKS5fX25hbWVfXyAhPSAiUGFyYW1ldHJpemVkTGluZWFyIjoKICAgICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICAgICBmbG9hdF9saW5lYXIgPSB0b3JjaC5ubi5MaW5lYXIoCiAgICAgICAgICAgICAgICBtb2R1bGUuaW5fZmVhdHVyZXMsCiAgICAgICAgICAgICAgICBtb2R1bGUub3V0X2ZlYXR1cmVzLAogICAgICAgICAgICAgICAgYmlhcz1tb2R1bGUuYmlhcyBpcyBub3QgTm9uZSwKICAgICAgICAgICAgKQogICAgICAgICAgICB3aXRoIHRvcmNoLm5vX2dyYWQoKToKICAgICAgICAgICAgICAgIGZsb2F0X2xpbmVhci53ZWlnaHQuY29weV8obW9kdWxlLndlaWdodC5kZXRhY2goKS50byh0b3JjaC5mbG9hdDMyKSkKICAgICAgICAgICAgICAgIGlmIG1vZHVsZS5iaWFzIGlzIG5vdCBOb25lOgogICAgICAgICAgICAgICAgICAgIGZsb2F0X2xpbmVhci5iaWFzLmNvcHlfKG1vZHVsZS5iaWFzLmRldGFjaCgpLnRvKHRvcmNoLmZsb2F0MzIpKQoKICAgICAgICAgICAgd2l0aCB3YXJuaW5ncy5jYXRjaF93YXJuaW5ncygpOgogICAgICAgICAgICAgICAgd2FybmluZ3MuZmlsdGVyd2FybmluZ3MoImlnbm9yZSIsIGNhdGVnb3J5PURlcHJlY2F0aW9uV2FybmluZykKICAgICAgICAgICAgICAgIHF1YW50aXplZF9saW5lYXIgPSB0b3JjaC5xdWFudGl6YXRpb24ucXVhbnRpemVfZHluYW1pYygKICAgICAgICAgICAgICAgICAgICB0b3JjaC5ubi5TZXF1ZW50aWFsKGZsb2F0X2xpbmVhciksCiAgICAgICAgICAgICAgICAgICAge3RvcmNoLm5uLkxpbmVhcn0sCiAgICAgICAgICAgICAgICAgICAgZHR5cGU9dG9yY2gucWludDgsCiAgICAgICAgICAgICAgICApWzBdCgogICAgICAgICAgICBtb2R1bGUuX2R5bmFtaWNfaW50OF9saW5lYXIgPSBxdWFudGl6ZWRfbGluZWFyCgogICAgICAgICAgICBkZWYgX2ZvcndhcmRfZHluYW1pY19pbnQ4KHNlbGYsIGlucHV0LCB0YXNrX2lkPU5vbmUsIHJlc2lkdWFsPUZhbHNlKToKICAgICAgICAgICAgICAgIG91dCA9IHNlbGYuX2R5bmFtaWNfaW50OF9saW5lYXIoaW5wdXQpCiAgICAgICAgICAgICAgICBpZiByZXNpZHVhbDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3V0LCBpbnB1dAogICAgICAgICAgICAgICAgcmV0dXJuIG91dAoKICAgICAgICAgICAgbW9kdWxlLmZvcndhcmQgPSBfZm9yd2FyZF9keW5hbWljX2ludDguX19nZXRfXyhtb2R1bGUsIG1vZHVsZS5fX2NsYXNzX18pCiAgICAgICAgICAgIHF1YW50aXplZF9sYXllcnMgKz0gMQoKICAgICAgICBpZiBxdWFudGl6ZWRfbGF5ZXJzID09IDA6CiAgICAgICAgICAgIGxvZy53YXJuaW5nKCJOZW5odW1hIGNhbWFkYSBQYXJhbWV0cml6ZWRMaW5lYXIgZW5jb250cmFkYSBwYXJhIGR5bmFtaWMtaW50OCBubyBKaW5hLiIpCiAgICAgICAgICAgIHJldHVybiBtb2RlbAoKICAgICAgICBsb2cuaW5mbygiUXVhbnRpemFjYW8gSmluYSBhcGxpY2FkYTogZHluYW1pYy1pbnQ4IChDUFUsICVzIGNhbWFkYXMpLiIsIHF1YW50aXplZF9sYXllcnMpCiAgICAgICAgcmV0dXJuIG1vZGVsCiAgICBleGNlcHQgRXhjZXB0aW9uIGFzIHF1YW50X2Vycm9yOgogICAgICAgIGxvZy53YXJuaW5nKCJGYWxoYSBhbyBhcGxpY2FyIGR5bmFtaWMtaW50OCBubyBKaW5hICglcyk7IHVzYW5kbyBtb2RlbG8gcGFkcmFvLiIsIHF1YW50X2Vycm9yKQogICAgICAgIHJldHVybiBtb2RlbAoKCmRlZiBnZXRfZW1iZWRkaW5nX21vZGVsKG1vZGVsX2Nob2ljZTogc3RyKSAtPiBTZW50ZW5jZVRyYW5zZm9ybWVyOgogICAgaWYgbW9kZWxfY2hvaWNlIGluIF9tb2RlbHM6CiAgICAgICAgcmV0dXJuIF9tb2RlbHNbbW9kZWxfY2hvaWNlXQoKICAgIGlmIG1vZGVsX2Nob2ljZSBpbiBfbW9kZWxfbG9hZF9lcnJvcnM6CiAgICAgICAgcmFpc2UgUnVudGltZUVycm9yKF9tb2RlbF9sb2FkX2Vycm9yc1ttb2RlbF9jaG9pY2VdKQoKICAgIGlmIG1vZGVsX2Nob2ljZSA9PSAiamluYSI6CiAgICAgICAgbW9kZWxfaWQgPSBKSU5BX1YzX0VNQkVERElOR19NT0RFTAogICAgZWxpZiBtb2RlbF9jaG9pY2UgPT0gImppbmFfdjIiOgogICAgICAgIG1vZGVsX2lkID0gSklOQV9WMl9FTUJFRERJTkdfTU9ERUwKICAgIGVsaWYgbW9kZWxfY2hvaWNlID09ICJiZ2UiOgogICAgICAgIG1vZGVsX2lkID0gQkdFX0VNQkVERElOR19NT0RFTAogICAgZWxzZToKICAgICAgICByYWlzZSBSdW50aW1lRXJyb3IoZiJNb2RlbG8gbsOjbyBzdXBvcnRhZG86IHttb2RlbF9jaG9pY2V9IikKCiAgICB0cnk6CiAgICAgICAgTU9ERUxfRElSLm1rZGlyKHBhcmVudHM9VHJ1ZSwgZXhpc3Rfb2s9VHJ1ZSkKICAgICAgICBwcmVmZXJyZWRfbW9kZWxfY2FjaGVfZGlyID0gX21vZGVsX2NhY2hlX2RpcihNT0RFTF9ESVIsIG1vZGVsX2lkKQogICAgICAgIGxvZy5pbmZvKCJDYXJyZWdhbmRvIGVtYmVkZGluZ3MgJyVzJyBlbSBDUFUgKGNhY2hlOiAlcykiLCBtb2RlbF9pZCwgcHJlZmVycmVkX21vZGVsX2NhY2hlX2RpcikKCiAgICAgICAgc2VsZWN0aW9uID0gZG93bmxvYWRfbW9kZWxfd2l0aF9mYWxsYmFjaygKICAgICAgICAgICAgcHJlZmVycmVkX21vZGVsX2lkPW1vZGVsX2lkLAogICAgICAgICAgICBmYWxsYmFja19tb2RlbF9pZD1tb2RlbF9pZCwKICAgICAgICAgICAgbG9jYWxfZGlyPU1PREVMX0RJUiwKICAgICAgICApCiAgICAgICAgbW9kZWwgPSBfbG9hZF9zZW50ZW5jZV90cmFuc2Zvcm1lcl9mcm9tX2xvY2FsKHNlbGVjdGlvbi5tb2RlbF9pZCwgc2VsZWN0aW9uLmxvY2FsX2RpcikKICAgICAgICBpZiBtb2RlbF9jaG9pY2UgPT0gImppbmEiOgogICAgICAgICAgICBtb2RlbCA9IF9hcHBseV9qaW5hX3F1YW50aXphdGlvbl9pZl9uZWVkZWQobW9kZWwsIHNlbGVjdGlvbi5tb2RlbF9pZCkKCiAgICAgICAgX21vZGVsc1ttb2RlbF9jaG9pY2VdID0gbW9kZWwKICAgICAgICBsb2cuaW5mbygKICAgICAgICAgICAgIk1vZGVsbyBkZSBlbWJlZGRpbmdzIHByb250bzogJXMgKHByb3ZpZGVyPSVzLCBwYXRoPSVzKSIsCiAgICAgICAgICAgIHNlbGVjdGlvbi5tb2RlbF9pZCwKICAgICAgICAgICAgc2VsZWN0aW9uLnByb3ZpZGVyLAogICAgICAgICAgICBzZWxlY3Rpb24ubG9jYWxfZGlyLAogICAgICAgICkKICAgICAgICByZXR1cm4gbW9kZWwKICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICBtZXNzYWdlID0gZiJGYWxoYSBhbyBjYXJyZWdhciBtb2RlbG8gJ3ttb2RlbF9jaG9pY2V9JyAoe21vZGVsX2lkfSk6IHtlfSIKICAgICAgICBfbW9kZWxfbG9hZF9lcnJvcnNbbW9kZWxfY2hvaWNlXSA9IG1lc3NhZ2UKICAgICAgICByYWlzZSBSdW50aW1lRXJyb3IobWVzc2FnZSkKCgpkZWYgZ2V0X3JlcmFua2VyKCkgLT4gQ3Jvc3NFbmNvZGVyIHwgTm9uZToKICAgIGdsb2JhbCBfcmVyYW5rZXIsIF9yZXJhbmtlcl9lcnJvcgoKICAgIGlmIG5vdCBSRVJBTktfRU5BQkxFRDoKICAgICAgICByZXR1cm4gTm9uZQogICAgaWYgX3JlcmFua2VyIGlzIG5vdCBOb25lOgogICAgICAgIHJldHVybiBfcmVyYW5rZXIKICAgIGlmIF9yZXJhbmtlcl9lcnJvciBpcyBub3QgTm9uZToKICAgICAgICByZXR1cm4gTm9uZQoKICAgIHRyeToKICAgICAgICBNT0RFTF9ESVIubWtkaXIocGFyZW50cz1UcnVlLCBleGlzdF9vaz1UcnVlKQogICAgICAgIHNlbGVjdGlvbiA9IGRvd25sb2FkX21vZGVsX3dpdGhfZmFsbGJhY2soCiAgICAgICAgICAgIHByZWZlcnJlZF9tb2RlbF9pZD1SRVJBTktfTU9ERUxfSUQsCiAgICAgICAgICAgIGZhbGxiYWNrX21vZGVsX2lkPVJFUkFOS19NT0RFTF9JRCwKICAgICAgICAgICAgbG9jYWxfZGlyPU1PREVMX0RJUiwKICAgICAgICApCgogICAgICAgIHJlcmFua2VyID0gQ3Jvc3NFbmNvZGVyKAogICAgICAgICAgICBzdHIoc2VsZWN0aW9uLmxvY2FsX2RpciksCiAgICAgICAgICAgIGRldmljZT0iY3B1IiwKICAgICAgICAgICAgbWF4X2xlbmd0aD1SRVJBTktFUl9NQVhfTEVOR1RILAogICAgICAgICAgICB0cnVzdF9yZW1vdGVfY29kZT1GYWxzZSwKICAgICAgICApCgogICAgICAgIGlmIFJFUkFOS0VSX1FVQU5USVpBVElPTiA9PSAiZHluYW1pYy1pbnQ4IjoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgaW1wb3J0IHRvcmNoCgogICAgICAgICAgICAgICAgcmVyYW5rZXIubW9kZWwgPSB0b3JjaC5xdWFudGl6YXRpb24ucXVhbnRpemVfZHluYW1pYygKICAgICAgICAgICAgICAgICAgICByZXJhbmtlci5tb2RlbCwKICAgICAgICAgICAgICAgICAgICB7dG9yY2gubm4uTGluZWFyfSwKICAgICAgICAgICAgICAgICAgICBkdHlwZT10b3JjaC5xaW50OCwKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIGxvZy5pbmZvKCJSZXJhbmtlciBjb20gcXVhbnRpemFjYW8gZHluYW1pYy1pbnQ4IGhhYmlsaXRhZGEuIikKICAgICAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBxdWFudF9lcnJvcjoKICAgICAgICAgICAgICAgIGxvZy53YXJuaW5nKCJGYWxoYSBhbyBxdWFudGl6YXIgcmVyYW5rZXIgKCVzKS4gU2VndWluZG8gc2VtIHF1YW50aXphY2FvLiIsIHF1YW50X2Vycm9yKQoKICAgICAgICBfcmVyYW5rZXIgPSByZXJhbmtlcgogICAgICAgIGxvZy5pbmZvKAogICAgICAgICAgICAiUmVyYW5rZXIgcHJvbnRvOiAlcyAocHJvdmlkZXI9JXMsIHBhdGg9JXMpIiwKICAgICAgICAgICAgc2VsZWN0aW9uLm1vZGVsX2lkLAogICAgICAgICAgICBzZWxlY3Rpb24ucHJvdmlkZXIsCiAgICAgICAgICAgIHNlbGVjdGlvbi5sb2NhbF9kaXIsCiAgICAgICAgKQogICAgICAgIHJldHVybiBfcmVyYW5rZXIKICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICBfcmVyYW5rZXJfZXJyb3IgPSBzdHIoZSkKICAgICAgICBsb2cud2FybmluZygiUmVyYW5rZXIgaW5kaXNwb27DrXZlbC4gQnVzY2Egc2VndWlyw6Egc2VtIHJlcmFua2luZy4gRXJybzogJXMiLCBlKQogICAgICAgIHJldHVybiBOb25lCgoKZGVmIGdldF9zcGxpdHRlcigpIC0+IFJlY3Vyc2l2ZUNoYXJhY3RlclRleHRTcGxpdHRlcjoKICAgIGdsb2JhbCBfc3BsaXR0ZXIKICAgIGlmIF9zcGxpdHRlciBpcyBOb25lOgogICAgICAgIF9zcGxpdHRlciA9IFJlY3Vyc2l2ZUNoYXJhY3RlclRleHRTcGxpdHRlcigKICAgICAgICAgICAgY2h1bmtfc2l6ZT1DSFVOS19TSVpFLAogICAgICAgICAgICBjaHVua19vdmVybGFwPUNIVU5LX09WRVJMQVAsCiAgICAgICAgICAgIGxlbmd0aF9mdW5jdGlvbj1sZW4sCiAgICAgICAgICAgIHNlcGFyYXRvcnM9WyJcblxuIiwgIlxuIiwgIiAiLCAiIl0sCiAgICAgICAgKQogICAgcmV0dXJuIF9zcGxpdHRlcgoKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgSW5kZXhhw6fDo28gaW50ZXJuYQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCmRlZiBfbWFrZV9jaHVua19pZChmaWxlX3BhdGg6IHN0ciwgY2h1bmtfaW5kZXg6IGludCkgLT4gc3RyOgogICAgcmF3ID0gZiJ7ZmlsZV9wYXRofTo6Y2h1bms6OntjaHVua19pbmRleH0iCiAgICByZXR1cm4gaGFzaGxpYi5tZDUocmF3LmVuY29kZSgpKS5oZXhkaWdlc3QoKQoKCmRlZiBfbWFrZV9yZXN1bHRfa2V5KG1ldGFkYXRhOiBkaWN0W3N0ciwgb2JqZWN0XSwgZmFsbGJhY2tfaWQ6IHN0cikgLT4gc3RyOgogICAgZmlsZV9wYXRoID0gc3RyKG1ldGFkYXRhLmdldCgiZmlsZV9wYXRoIiwgIiIpKQogICAgY2h1bmtfaW5kZXggPSBzdHIobWV0YWRhdGEuZ2V0KCJjaHVua19pbmRleCIsICIiKSkKICAgIGlmIGZpbGVfcGF0aCBhbmQgY2h1bmtfaW5kZXg6CiAgICAgICAgcmV0dXJuIGYie2ZpbGVfcGF0aH06OmNodW5rOjp7Y2h1bmtfaW5kZXh9IgogICAgcmV0dXJuIGZhbGxiYWNrX2lkCgoKZGVmIF9kZWxldGVfZmlsZV9jaHVua3MoY29sbGVjdGlvbjogY2hyb21hZGIuQ29sbGVjdGlvbiwgZmlsZV9wYXRoOiBzdHIpIC0+IGludDoKICAgICMgUGVkZSBhcGVuYXMgSURzIHBhcmEgbsOjbyBtYXRlcmlhbGl6YXIgZG9jdW1lbnRvcy9tZXRhZGF0YSBkZXNuZWNlc3PDoXJpb3MgZW0gUkFNLgogICAgcmVzdWx0cyA9IGNvbGxlY3Rpb24uZ2V0KHdoZXJlPXsiZmlsZV9wYXRoIjogZmlsZV9wYXRofSwgaW5jbHVkZT1bXSkKICAgIGlkcyA9IHJlc3VsdHMuZ2V0KCJpZHMiLCBbXSkgaWYgcmVzdWx0cyBlbHNlIFtdCiAgICBpZiBpZHM6CiAgICAgICAgY29sbGVjdGlvbi5kZWxldGUoaWRzPWlkcykKICAgIHJldHVybiBsZW4oaWRzKQoKCmRlZiBfcmVhZF9maWxlX3NhZmUoZmlsZXBhdGg6IFBhdGgpIC0+IHN0ciB8IE5vbmU6CiAgICB0cnk6CiAgICAgICAgcmF3ID0gZmlsZXBhdGgucmVhZF9ieXRlcygpCiAgICBleGNlcHQgT1NFcnJvcjoKICAgICAgICByZXR1cm4gTm9uZQoKICAgIGlmIF9sb29rc19iaW5hcnlfY29udGVudChyYXcpOgogICAgICAgIHJldHVybiBOb25lCgogICAgZm9yIGVuY29kaW5nIGluICgidXRmLTgiLCAibGF0aW4tMSIsICJjcDEyNTIiKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIHJldHVybiByYXcuZGVjb2RlKGVuY29kaW5nKQogICAgICAgIGV4Y2VwdCBVbmljb2RlRGVjb2RlRXJyb3I6CiAgICAgICAgICAgIGNvbnRpbnVlCiAgICByZXR1cm4gTm9uZQoKCmRlZiBfbG9va3NfYmluYXJ5X2NvbnRlbnQocmF3OiBieXRlcykgLT4gYm9vbDoKICAgIGlmIG5vdCByYXc6CiAgICAgICAgcmV0dXJuIEZhbHNlCgogICAgc2FtcGxlID0gcmF3Wzo0MDk2XQogICAgaWYgYiJceDAwIiBpbiBzYW1wbGU6CiAgICAgICAgcmV0dXJuIFRydWUKCiAgICBub25fdGV4dF9ieXRlcyA9IDAKICAgIGZvciBieXRlIGluIHNhbXBsZToKICAgICAgICBpZiBieXRlIGluICg5LCAxMCwgMTMpOiAgIyBcdCBcbiBccgogICAgICAgICAgICBjb250aW51ZQogICAgICAgIGlmIDMyIDw9IGJ5dGUgPD0gMTI2OiAgIyBBU0NJSSBpbXByaW1pdmVsCiAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgaWYgMTYwIDw9IGJ5dGUgPD0gMjU1OiAgIyBMYXRpbi0xIGVzdGVuZGlkbwogICAgICAgICAgICBjb250aW51ZQogICAgICAgIG5vbl90ZXh0X2J5dGVzICs9IDEKCiAgICByZXR1cm4gKG5vbl90ZXh0X2J5dGVzIC8gbGVuKHNhbXBsZSkpID4gMC4zMAoKCmRlZiBfc2Nhbl9mb2xkZXIoZm9sZGVyX3BhdGg6IFBhdGgpIC0+IEl0ZXJhdG9yW1BhdGhdOgogICAgZm9yIGRpcnBhdGgsIGRpcm5hbWVzLCBmaWxlbmFtZXMgaW4gb3Mud2Fsayhmb2xkZXJfcGF0aCk6CiAgICAgICAgZGlybmFtZXNbOl0gPSBbCiAgICAgICAgICAgIGQgZm9yIGQgaW4gZGlybmFtZXMKICAgICAgICAgICAgaWYgZCBub3QgaW4gSUdOT1JFRF9ESVJTIGFuZCBub3QgZC5zdGFydHN3aXRoKCIuIikKICAgICAgICBdCiAgICAgICAgZGlybmFtZXMuc29ydCgpCiAgICAgICAgZm9yIGZpbGVuYW1lIGluIHNvcnRlZChmaWxlbmFtZXMpOgogICAgICAgICAgICBmcCA9IFBhdGgoZGlycGF0aCkgLyBmaWxlbmFtZQogICAgICAgICAgICBpZiBmcC5zdWZmaXgubG93ZXIoKSBpbiBJR05PUkVEX0VYVEVOU0lPTlM6CiAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpZiBmcC5zdGF0KCkuc3Rfc2l6ZSA+IE1BWF9GSUxFX1NJWkVfQllURVM6CiAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgZXhjZXB0IE9TRXJyb3I6CiAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICB5aWVsZCBmcAoKCmRlZiBfY2xhc3NpZnlfZmlsZV90YXJnZXRzKGZpbGVwYXRoOiBQYXRoKSAtPiBsaXN0W0JyYW5jaFNwZWNdOgogICAgc3VmZml4ID0gZmlsZXBhdGguc3VmZml4Lmxvd2VyKCkKICAgIGlzX2NvZGUgPSBzdWZmaXggaW4gQ09ERV9FWFRFTlNJT05TCiAgICBpc19kb2MgPSBzdWZmaXggaW4gRE9DX0VYVEVOU0lPTlMKCiAgICBpZiBpc19jb2RlIGFuZCBub3QgaXNfZG9jOgogICAgICAgIHJldHVybiBbQlJBTkNIX1NQRUNTWyJqaW5hX2NvZGUiXV0KICAgIGlmIGlzX2RvYyBhbmQgbm90IGlzX2NvZGU6CiAgICAgICAgcmV0dXJuIFtCUkFOQ0hfU1BFQ1NbImJnZV9kb2MiXV0KCiAgICAjIEFycXVpdm9zIGFtYsOtZ3Vvcy9leHRlbnPDo28gZGVzY29uaGVjaWRhOiBpbmRleGEgZW0gYW1iYXMgcGFyYSBuw6NvIHBlcmRlciByZWNhbGwuCiAgICByZXR1cm4gW0JSQU5DSF9TUEVDU1siamluYV9jb2RlIl0sIEJSQU5DSF9TUEVDU1siYmdlX2RvYyJdXQoKCmRlZiBfaW5kZXhfc2luZ2xlX2ZpbGVfZm9yX2JyYW5jaCgKICAgIGZpbGVwYXRoOiBQYXRoLAogICAgYnJhbmNoOiBCcmFuY2hTcGVjLAogICAgc3BsaXR0ZXI6IFJlY3Vyc2l2ZUNoYXJhY3RlclRleHRTcGxpdHRlciwKICAgICosCiAgICBkZWxldGVfZXhpc3Rpbmc6IGJvb2wgPSBUcnVlLAopIC0+IGludDoKICAgIGNvbnRlbnQgPSBfcmVhZF9maWxlX3NhZmUoZmlsZXBhdGgpCiAgICBpZiBub3QgY29udGVudCBvciBub3QgY29udGVudC5zdHJpcCgpOgogICAgICAgIHJldHVybiAwCgogICAgYWJzX3BhdGggPSBzdHIoZmlsZXBhdGgucmVzb2x2ZSgpKQogICAgbW9kZWwgPSBnZXRfZW1iZWRkaW5nX21vZGVsKGJyYW5jaC5tb2RlbF9jaG9pY2UpCiAgICBjb2xsZWN0aW9uID0gZ2V0X2Nocm9tYV9jb2xsZWN0aW9uKGJyYW5jaC5jb2xsZWN0aW9uX25hbWUpCgogICAgY2h1bmtzID0gc3BsaXR0ZXIuc3BsaXRfdGV4dChjb250ZW50KQogICAgaWYgbm90IGNodW5rczoKICAgICAgICByZXR1cm4gMAoKICAgICMgQXR1YWxpemHDp8OjbyBpZGVtcG90ZW50ZSBwb3IgYXJxdWl2byBlbSBjYWRhIGNvbGXDp8Ojby4KICAgIGlmIGRlbGV0ZV9leGlzdGluZzoKICAgICAgICBfZGVsZXRlX2ZpbGVfY2h1bmtzKGNvbGxlY3Rpb24sIGFic19wYXRoKQoKICAgIGluc2VydGVkX2NodW5rcyA9IDAKICAgIHNraXBwZWRfY2h1bmtzID0gMAogICAgc3RvcF9pdGVyYXRpb25fd2FybmluZ3MgPSAwCiAgICBiYXRjaF9pZHM6IGxpc3Rbc3RyXSA9IFtdCiAgICBiYXRjaF9kb2NzOiBsaXN0W3N0cl0gPSBbXQogICAgYmF0Y2hfbWV0YWRhdGFzOiBsaXN0W2RpY3Rbc3RyLCBvYmplY3RdXSA9IFtdCgogICAgZGVmIF93YXJuX3N0b3BfaXRlcmF0aW9uKG1lc3NhZ2U6IHN0cikgLT4gTm9uZToKICAgICAgICBub25sb2NhbCBzdG9wX2l0ZXJhdGlvbl93YXJuaW5ncwogICAgICAgIGlmIHN0b3BfaXRlcmF0aW9uX3dhcm5pbmdzIDwgMzoKICAgICAgICAgICAgbG9nLndhcm5pbmcobWVzc2FnZSkKICAgICAgICBzdG9wX2l0ZXJhdGlvbl93YXJuaW5ncyArPSAxCgogICAgZGVmIF90b19lbWJlZGRpbmdfcm93cyhlbmNvZGVkX2VtYmVkZGluZ3M6IG9iamVjdCkgLT4gbGlzdFtsaXN0W2Zsb2F0XV06CiAgICAgICAgaWYgaGFzYXR0cihlbmNvZGVkX2VtYmVkZGluZ3MsICJ0b2xpc3QiKToKICAgICAgICAgICAgcm93cyA9IGVuY29kZWRfZW1iZWRkaW5ncy50b2xpc3QoKQogICAgICAgICAgICBpZiBpc2luc3RhbmNlKHJvd3MsIGxpc3QpOgogICAgICAgICAgICAgICAgaWYgcm93cyBhbmQgaXNpbnN0YW5jZShyb3dzWzBdLCAoaW50LCBmbG9hdCkpOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBbbGlzdChyb3dzKV0KICAgICAgICAgICAgICAgIHJldHVybiByb3dzCiAgICAgICAgcmV0dXJuIFtsaXN0KHJvdykgZm9yIHJvdyBpbiBlbmNvZGVkX2VtYmVkZGluZ3NdICAjIHR5cGU6IGlnbm9yZVthcmctdHlwZV0KCiAgICBkZWYgX2ZsdXNoX2JhdGNoKCkgLT4gTm9uZToKICAgICAgICBub25sb2NhbCBpbnNlcnRlZF9jaHVua3MsIHNraXBwZWRfY2h1bmtzCiAgICAgICAgaWYgbm90IGJhdGNoX2lkczoKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgIHBlbmRpbmdfaWRzID0gbGlzdChiYXRjaF9pZHMpCiAgICAgICAgcGVuZGluZ19kb2NzID0gbGlzdChiYXRjaF9kb2NzKQogICAgICAgIHBlbmRpbmdfbWV0YWRhdGFzID0gbGlzdChiYXRjaF9tZXRhZGF0YXMpCgogICAgICAgIHRyeToKICAgICAgICAgICAgZW5jb2RlZCA9IG1vZGVsLmVuY29kZSgKICAgICAgICAgICAgICAgIHBlbmRpbmdfZG9jcywKICAgICAgICAgICAgICAgIHNob3dfcHJvZ3Jlc3NfYmFyPUZhbHNlLAogICAgICAgICAgICAgICAgYmF0Y2hfc2l6ZT1FTUJFRERJTkdfQkFUQ0hfU0laRSwKICAgICAgICAgICAgKQogICAgICAgICAgICBlbWJlZGRpbmdzID0gX3RvX2VtYmVkZGluZ19yb3dzKGVuY29kZWQpCiAgICAgICAgICAgIGNvbGxlY3Rpb24udXBzZXJ0KAogICAgICAgICAgICAgICAgaWRzPXBlbmRpbmdfaWRzLAogICAgICAgICAgICAgICAgZW1iZWRkaW5ncz1lbWJlZGRpbmdzLAogICAgICAgICAgICAgICAgZG9jdW1lbnRzPXBlbmRpbmdfZG9jcywKICAgICAgICAgICAgICAgIG1ldGFkYXRhcz1wZW5kaW5nX21ldGFkYXRhcywKICAgICAgICAgICAgKQogICAgICAgICAgICBpbnNlcnRlZF9jaHVua3MgKz0gbGVuKHBlbmRpbmdfaWRzKQogICAgICAgICAgICBkZWwgZW1iZWRkaW5ncwogICAgICAgIGV4Y2VwdCBTdG9wSXRlcmF0aW9uOgogICAgICAgICAgICBfd2Fybl9zdG9wX2l0ZXJhdGlvbigKICAgICAgICAgICAgICAgIGYie2ZpbGVwYXRoLm5hbWV9IFt7YnJhbmNoLmtleX1dIFN0b3BJdGVyYXRpb24gbm8gYmF0Y2g7IGFwbGljYW5kbyBmYWxsYmFjayBwb3IgY2h1bmsuIgogICAgICAgICAgICApCiAgICAgICAgICAgIGZvciBjaHVua19pZCwgY2h1bmtfZG9jLCBjaHVua19tZXRhZGF0YSBpbiB6aXAocGVuZGluZ19pZHMsIHBlbmRpbmdfZG9jcywgcGVuZGluZ19tZXRhZGF0YXMpOgogICAgICAgICAgICAgICAgY2FuZGlkYXRlX2RvYyA9IGNodW5rX2RvYy5zdHJpcCgpCiAgICAgICAgICAgICAgICBpZiBub3QgY2FuZGlkYXRlX2RvYzoKICAgICAgICAgICAgICAgICAgICBza2lwcGVkX2NodW5rcyArPSAxCiAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBlbmNvZGVkX3NpbmdsZSA9IG1vZGVsLmVuY29kZSgKICAgICAgICAgICAgICAgICAgICAgICAgW2NhbmRpZGF0ZV9kb2NdLAogICAgICAgICAgICAgICAgICAgICAgICBzaG93X3Byb2dyZXNzX2Jhcj1GYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2hfc2l6ZT0xLAogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICBzaW5nbGVfZW1iZWRkaW5ncyA9IF90b19lbWJlZGRpbmdfcm93cyhlbmNvZGVkX3NpbmdsZSkKICAgICAgICAgICAgICAgICAgICBjb2xsZWN0aW9uLnVwc2VydCgKICAgICAgICAgICAgICAgICAgICAgICAgaWRzPVtjaHVua19pZF0sCiAgICAgICAgICAgICAgICAgICAgICAgIGVtYmVkZGluZ3M9c2luZ2xlX2VtYmVkZGluZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50cz1bY2FuZGlkYXRlX2RvY10sCiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhcz1bY2h1bmtfbWV0YWRhdGFdLAogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICBpbnNlcnRlZF9jaHVua3MgKz0gMQogICAgICAgICAgICAgICAgICAgIGRlbCBzaW5nbGVfZW1iZWRkaW5ncwogICAgICAgICAgICAgICAgZXhjZXB0IFN0b3BJdGVyYXRpb246CiAgICAgICAgICAgICAgICAgICAgY29tcGFjdF9kb2MgPSAiICIuam9pbihjYW5kaWRhdGVfZG9jLnNwbGl0KCkpCiAgICAgICAgICAgICAgICAgICAgaWYgbm90IGNvbXBhY3RfZG9jOgogICAgICAgICAgICAgICAgICAgICAgICBza2lwcGVkX2NodW5rcyArPSAxCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgICAgICBlbmNvZGVkX3NpbmdsZSA9IG1vZGVsLmVuY29kZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjb21wYWN0X2RvY10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG93X3Byb2dyZXNzX2Jhcj1GYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoX3NpemU9MSwKICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICBzaW5nbGVfZW1iZWRkaW5ncyA9IF90b19lbWJlZGRpbmdfcm93cyhlbmNvZGVkX3NpbmdsZSkKICAgICAgICAgICAgICAgICAgICAgICAgY29sbGVjdGlvbi51cHNlcnQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZHM9W2NodW5rX2lkXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtYmVkZGluZ3M9c2luZ2xlX2VtYmVkZGluZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudHM9W2NvbXBhY3RfZG9jXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhcz1bY2h1bmtfbWV0YWRhdGFdLAogICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgIGluc2VydGVkX2NodW5rcyArPSAxCiAgICAgICAgICAgICAgICAgICAgICAgIGRlbCBzaW5nbGVfZW1iZWRkaW5ncwogICAgICAgICAgICAgICAgICAgIGV4Y2VwdCBTdG9wSXRlcmF0aW9uOgogICAgICAgICAgICAgICAgICAgICAgICBza2lwcGVkX2NodW5rcyArPSAxCiAgICAgICAgICAgICAgICAgICAgICAgIF93YXJuX3N0b3BfaXRlcmF0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZiJ7ZmlsZXBhdGgubmFtZX0gW3ticmFuY2gua2V5fV0gY2h1bmsgaWdub3JhZG8gYXDDs3MgU3RvcEl0ZXJhdGlvbiByZXBldGlkby4iCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICBiYXRjaF9pZHMuY2xlYXIoKQogICAgICAgIGJhdGNoX2RvY3MuY2xlYXIoKQogICAgICAgIGJhdGNoX21ldGFkYXRhcy5jbGVhcigpCgogICAgZm9yIGksIGNodW5rIGluIGVudW1lcmF0ZShjaHVua3MpOgogICAgICAgIGlmIG5vdCBjaHVuayBvciBub3QgY2h1bmsuc3RyaXAoKToKICAgICAgICAgICAgc2tpcHBlZF9jaHVua3MgKz0gMQogICAgICAgICAgICBjb250aW51ZQogICAgICAgIGJhdGNoX2lkcy5hcHBlbmQoX21ha2VfY2h1bmtfaWQoYWJzX3BhdGgsIGkpKQogICAgICAgIGJhdGNoX2RvY3MuYXBwZW5kKGNodW5rKQogICAgICAgIGJhdGNoX21ldGFkYXRhcy5hcHBlbmQoCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJmaWxlX3BhdGgiOiBhYnNfcGF0aCwKICAgICAgICAgICAgICAgICJmaWxlX25hbWUiOiBmaWxlcGF0aC5uYW1lLAogICAgICAgICAgICAgICAgImNodW5rX2luZGV4IjogaSwKICAgICAgICAgICAgICAgICJzb3VyY2VfY29sbGVjdGlvbiI6IGJyYW5jaC5jb2xsZWN0aW9uX25hbWUsCiAgICAgICAgICAgICAgICAic291cmNlX21vZGVsX2Nob2ljZSI6IGJyYW5jaC5tb2RlbF9jaG9pY2UsCiAgICAgICAgICAgICAgICAic291cmNlX21vZGVsX2lkIjogYnJhbmNoLm1vZGVsX2lkLAogICAgICAgICAgICAgICAgImNvbnRlbnRfZG9tYWluIjogYnJhbmNoLmNvbnRlbnRfZG9tYWluLAogICAgICAgICAgICB9CiAgICAgICAgKQogICAgICAgIGlmIGxlbihiYXRjaF9pZHMpID49IEVNQkVERElOR19CQVRDSF9TSVpFOgogICAgICAgICAgICBfZmx1c2hfYmF0Y2goKQoKICAgIF9mbHVzaF9iYXRjaCgpCiAgICBpZiBza2lwcGVkX2NodW5rczoKICAgICAgICBfd2Fybl9zdG9wX2l0ZXJhdGlvbigKICAgICAgICAgICAgZiJ7ZmlsZXBhdGgubmFtZX0gW3ticmFuY2gua2V5fV0gaWdub3JvdSB7c2tpcHBlZF9jaHVua3N9IGNodW5rKHMpIHZhemlvKHMpL2ludsOhbGlkbyhzKS4iCiAgICAgICAgKQogICAgaWYgYnJhbmNoLmtleSA9PSAiYmdlX2RvYyIgYW5kIGluc2VydGVkX2NodW5rcyA9PSAwIGFuZCBzdG9wX2l0ZXJhdGlvbl93YXJuaW5ncyA+IDA6CiAgICAgICAgcmFpc2UgUnVudGltZUVycm9yKAogICAgICAgICAgICBmInN0b3BfaXRlcmF0aW9uX2FsbF9jaHVua3M6e2ZpbGVwYXRoLm5hbWV9OntzdG9wX2l0ZXJhdGlvbl93YXJuaW5nc30iCiAgICAgICAgKQogICAgcmV0dXJuIGluc2VydGVkX2NodW5rcwoKCmRlZiBfcmVtb3ZlX2ZpbGVfZnJvbV9hbGxfY29sbGVjdGlvbnMoYWJzX3BhdGg6IHN0cikgLT4gdHVwbGVbZGljdFtzdHIsIGludF0sIGxpc3Rbc3RyXV06CiAgICBkZWxldGVkX3Blcl9icmFuY2g6IGRpY3Rbc3RyLCBpbnRdID0ge30KICAgIGVycm9yczogbGlzdFtzdHJdID0gW10KCiAgICBmb3IgYnJhbmNoIGluIEJSQU5DSF9TUEVDUy52YWx1ZXMoKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIGNvbGxlY3Rpb24gPSBnZXRfY2hyb21hX2NvbGxlY3Rpb24oYnJhbmNoLmNvbGxlY3Rpb25fbmFtZSkKICAgICAgICAgICAgZGVsZXRlZCA9IF9kZWxldGVfZmlsZV9jaHVua3MoY29sbGVjdGlvbiwgYWJzX3BhdGgpCiAgICAgICAgICAgIGRlbGV0ZWRfcGVyX2JyYW5jaFticmFuY2gua2V5XSA9IGRlbGV0ZWQKICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgICAgIGVycm9ycy5hcHBlbmQoZiJ7YnJhbmNoLmtleX06IHtlfSIpCiAgICByZXR1cm4gZGVsZXRlZF9wZXJfYnJhbmNoLCBlcnJvcnMKCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIEJ1c2NhIHNlbcOibnRpY2EgaMOtYnJpZGEKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgpkZWYgX3F1ZXJ5X2JyYW5jaChicmFuY2g6IEJyYW5jaFNwZWMsIHF1ZXJ5OiBzdHIsIG5fcmVzdWx0czogaW50KSAtPiB0dXBsZVtsaXN0W1JldHJpZXZlZEhpdF0sIHN0ciB8IE5vbmVdOgogICAgdHJ5OgogICAgICAgIGNvbGxlY3Rpb24gPSBnZXRfY2hyb21hX2NvbGxlY3Rpb24oYnJhbmNoLmNvbGxlY3Rpb25fbmFtZSkKICAgICAgICBtb2RlbCA9IGdldF9lbWJlZGRpbmdfbW9kZWwoYnJhbmNoLm1vZGVsX2Nob2ljZSkKICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICByZXR1cm4gW10sIGYie2JyYW5jaC5rZXl9OiByZWN1cnNvIGluZGlzcG9uw612ZWwgKHtlfSkiCgogICAgdHJ5OgogICAgICAgIHF1ZXJ5X2VtYmVkZGluZyA9IG1vZGVsLmVuY29kZShbcXVlcnldLCBzaG93X3Byb2dyZXNzX2Jhcj1GYWxzZSkudG9saXN0KCkKICAgICAgICByZXN1bHRzID0gY29sbGVjdGlvbi5xdWVyeSgKICAgICAgICAgICAgcXVlcnlfZW1iZWRkaW5ncz1xdWVyeV9lbWJlZGRpbmcsCiAgICAgICAgICAgIG5fcmVzdWx0cz1uX3Jlc3VsdHMsCiAgICAgICAgICAgIGluY2x1ZGU9WyJkb2N1bWVudHMiLCAibWV0YWRhdGFzIiwgImRpc3RhbmNlcyJdLAogICAgICAgICkKICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICByZXR1cm4gW10sIGYie2JyYW5jaC5rZXl9OiBmYWxoYSBuYSBxdWVyeSAoe2V9KSIKCiAgICBkb2N1bWVudHMgPSByZXN1bHRzLmdldCgiZG9jdW1lbnRzIiwgW1tdXSlbMF0KICAgIG1ldGFkYXRhcyA9IHJlc3VsdHMuZ2V0KCJtZXRhZGF0YXMiLCBbW11dKVswXQogICAgZGlzdGFuY2VzID0gcmVzdWx0cy5nZXQoImRpc3RhbmNlcyIsIFtbXV0pWzBdCiAgICBpZHMgPSByZXN1bHRzLmdldCgiaWRzIiwgW1tdXSlbMF0KCiAgICBoaXRzOiBsaXN0W1JldHJpZXZlZEhpdF0gPSBbXQogICAgZm9yIGlkeCwgKGRvYywgbWV0YSwgZGlzdCkgaW4gZW51bWVyYXRlKHppcChkb2N1bWVudHMsIG1ldGFkYXRhcywgZGlzdGFuY2VzKSwgc3RhcnQ9MSk6CiAgICAgICAgbWV0YWRhdGEgPSBtZXRhIG9yIHt9CiAgICAgICAgZmFsbGJhY2tfaWQgPSBpZHNbaWR4IC0gMV0gaWYgaWR4IC0gMSA8IGxlbihpZHMpIGVsc2UgZiJ7YnJhbmNoLmtleX06e2lkeH0iCiAgICAgICAga2V5ID0gX21ha2VfcmVzdWx0X2tleShtZXRhZGF0YSwgZmFsbGJhY2tfaWQpCgogICAgICAgIHNpbWlsYXJpdHkgPSBOb25lCiAgICAgICAgaWYgZGlzdCBpcyBub3QgTm9uZToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgc2ltaWxhcml0eSA9IDEuMCAtIGZsb2F0KGRpc3QpCiAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgICAgICAgICBzaW1pbGFyaXR5ID0gTm9uZQoKICAgICAgICBoaXRzLmFwcGVuZCgKICAgICAgICAgICAgUmV0cmlldmVkSGl0KAogICAgICAgICAgICAgICAga2V5PWtleSwKICAgICAgICAgICAgICAgIGRvY3VtZW50PShkb2Mgb3IgIiIpLAogICAgICAgICAgICAgICAgbWV0YWRhdGE9bWV0YWRhdGEsCiAgICAgICAgICAgICAgICBkaXN0YW5jZT1mbG9hdChkaXN0KSBpZiBkaXN0IGlzIG5vdCBOb25lIGVsc2UgTm9uZSwKICAgICAgICAgICAgICAgIHNpbWlsYXJpdHk9c2ltaWxhcml0eSwKICAgICAgICAgICAgICAgIGJyYW5jaD1icmFuY2gsCiAgICAgICAgICAgICAgICByYW5rPWlkeCwKICAgICAgICAgICAgKQogICAgICAgICkKCiAgICByZXR1cm4gaGl0cywgTm9uZQoKCmRlZiBfcnJmX2Z1c2UoaGl0c19ieV9icmFuY2g6IGRpY3Rbc3RyLCBsaXN0W1JldHJpZXZlZEhpdF1dLCB0b3BfbGltaXQ6IGludCkgLT4gbGlzdFtGdXNlZEhpdF06CiAgICBmdXNlZDogZGljdFtzdHIsIEZ1c2VkSGl0XSA9IHt9CgogICAgZm9yIGJyYW5jaF9rZXksIGhpdHMgaW4gaGl0c19ieV9icmFuY2guaXRlbXMoKToKICAgICAgICBfID0gYnJhbmNoX2tleQogICAgICAgIGZvciByYW5rLCBoaXQgaW4gZW51bWVyYXRlKGhpdHMsIHN0YXJ0PTEpOgogICAgICAgICAgICBjb250cmlidXRpb24gPSAxLjAgLyAoUlJGX0sgKyByYW5rKQogICAgICAgICAgICBlbnRyeSA9IGZ1c2VkLmdldChoaXQua2V5KQoKICAgICAgICAgICAgaWYgZW50cnkgaXMgTm9uZToKICAgICAgICAgICAgICAgIGVudHJ5ID0gRnVzZWRIaXQoCiAgICAgICAgICAgICAgICAgICAga2V5PWhpdC5rZXksCiAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQ9aGl0LmRvY3VtZW50LAogICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhPWRpY3QoaGl0Lm1ldGFkYXRhKSwKICAgICAgICAgICAgICAgICAgICBycmZfc2NvcmU9MC4wLAogICAgICAgICAgICAgICAgICAgIHNvdXJjZV9kZXRhaWxzPXt9LAogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgZnVzZWRbaGl0LmtleV0gPSBlbnRyeQoKICAgICAgICAgICAgZW50cnkucnJmX3Njb3JlICs9IGNvbnRyaWJ1dGlvbgogICAgICAgICAgICBlbnRyeS5zb3VyY2VfZGV0YWlsc1toaXQuYnJhbmNoLmtleV0gPSB7CiAgICAgICAgICAgICAgICAicmFuayI6IHJhbmssCiAgICAgICAgICAgICAgICAiZGlzdGFuY2UiOiBoaXQuZGlzdGFuY2UsCiAgICAgICAgICAgICAgICAic2ltaWxhcml0eSI6IGhpdC5zaW1pbGFyaXR5LAogICAgICAgICAgICAgICAgImNvbGxlY3Rpb24iOiBoaXQuYnJhbmNoLmNvbGxlY3Rpb25fbmFtZSwKICAgICAgICAgICAgICAgICJtb2RlbF9jaG9pY2UiOiBoaXQuYnJhbmNoLm1vZGVsX2Nob2ljZSwKICAgICAgICAgICAgICAgICJtb2RlbF9pZCI6IGhpdC5icmFuY2gubW9kZWxfaWQsCiAgICAgICAgICAgICAgICAiY29udGVudF9kb21haW4iOiBoaXQuYnJhbmNoLmNvbnRlbnRfZG9tYWluLAogICAgICAgICAgICB9CgogICAgICAgICAgICAjIFVzYSBtZXRhZGFkb3MgZG8gaGl0IGNvbSBtZWxob3Igc2ltaWxhcmlkYWRlIGxvY2FsIGNvbW8gYmFzZSBwcmluY2lwYWwuCiAgICAgICAgICAgIGN1cnJlbnRfc2ltID0gZW50cnkubWV0YWRhdGEuZ2V0KCJfYmVzdF9zaW1pbGFyaXR5IiwgLTEwLjApCiAgICAgICAgICAgIGNhbmRpZGF0ZV9zaW0gPSBoaXQuc2ltaWxhcml0eSBpZiBoaXQuc2ltaWxhcml0eSBpcyBub3QgTm9uZSBlbHNlIC0xMC4wCiAgICAgICAgICAgIGlmIGNhbmRpZGF0ZV9zaW0gPiBjdXJyZW50X3NpbToKICAgICAgICAgICAgICAgIGVudHJ5LmRvY3VtZW50ID0gaGl0LmRvY3VtZW50CiAgICAgICAgICAgICAgICBlbnRyeS5tZXRhZGF0YSA9IGRpY3QoaGl0Lm1ldGFkYXRhKQogICAgICAgICAgICAgICAgZW50cnkubWV0YWRhdGFbIl9iZXN0X3NpbWlsYXJpdHkiXSA9IGNhbmRpZGF0ZV9zaW0KCiAgICBmdXNlZF9oaXRzID0gbGlzdChmdXNlZC52YWx1ZXMoKSkKICAgIGZ1c2VkX2hpdHMuc29ydChrZXk9bGFtYmRhIGg6IGgucnJmX3Njb3JlLCByZXZlcnNlPVRydWUpCgogICAgIyBMaW1pdGEgbyBwb29sIGFudGVzIGRvIHJlcmFua2luZyBwYXJhIHJlZHV6aXIgQ1BVL1JBTS4KICAgIHJldHVybiBmdXNlZF9oaXRzWzp0b3BfbGltaXRdCgoKZGVmIF9hcHBseV9yZXJhbmsocXVlcnk6IHN0ciwgZnVzZWRfaGl0czogbGlzdFtGdXNlZEhpdF0sIHRvcF9rOiBpbnQpIC0+IHR1cGxlW2xpc3RbRnVzZWRIaXRdLCBib29sLCBzdHIgfCBOb25lXToKICAgIGdsb2JhbCBfcmVyYW5rZXIsIF9yZXJhbmtlcl9lcnJvcgogICAgaWYgbm90IGZ1c2VkX2hpdHM6CiAgICAgICAgcmV0dXJuIFtdLCBGYWxzZSwgTm9uZQoKICAgIHJlcmFua2VyID0gZ2V0X3JlcmFua2VyKCkKICAgIGlmIHJlcmFua2VyIGlzIE5vbmU6CiAgICAgICAgcmVhc29uID0gX3JlcmFua2VyX2Vycm9yIGlmIF9yZXJhbmtlcl9lcnJvciBlbHNlICJyZXJhbmtlcl9kZXNhYmlsaXRhZG8iCiAgICAgICAgcmV0dXJuIGZ1c2VkX2hpdHNbOnRvcF9rXSwgRmFsc2UsIHJlYXNvbgoKICAgIHRyeToKICAgICAgICBwYWlycyA9IFsocXVlcnksIGhpdC5kb2N1bWVudCkgZm9yIGhpdCBpbiBmdXNlZF9oaXRzXQogICAgICAgIHNjb3JlcyA9IHJlcmFua2VyLnByZWRpY3QocGFpcnMsIHNob3dfcHJvZ3Jlc3NfYmFyPUZhbHNlLCBjb252ZXJ0X3RvX251bXB5PVRydWUpCgogICAgICAgIGZvciBoaXQsIHNjb3JlIGluIHppcChmdXNlZF9oaXRzLCBzY29yZXMpOgogICAgICAgICAgICBoaXQucmVyYW5rX3Njb3JlID0gZmxvYXQoc2NvcmUpCgogICAgICAgIGZ1c2VkX2hpdHMuc29ydCgKICAgICAgICAgICAga2V5PWxhbWJkYSBoOiAoCiAgICAgICAgICAgICAgICBoLnJlcmFua19zY29yZSBpZiBoLnJlcmFua19zY29yZSBpcyBub3QgTm9uZSBlbHNlIC0xZTksCiAgICAgICAgICAgICAgICBoLnJyZl9zY29yZSwKICAgICAgICAgICAgKSwKICAgICAgICAgICAgcmV2ZXJzZT1UcnVlLAogICAgICAgICkKICAgICAgICByZXR1cm4gZnVzZWRfaGl0c1s6dG9wX2tdLCBUcnVlLCBOb25lCiAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgX3JlcmFua2VyID0gTm9uZQogICAgICAgIF9yZXJhbmtlcl9lcnJvciA9IGYicnVudGltZV9lcnJvcjp7ZX0iCiAgICAgICAgcmV0dXJuIGZ1c2VkX2hpdHNbOnRvcF9rXSwgRmFsc2UsIGYiZmFsbGJhY2tfc2VtX3JlcmFuazp7ZX0iCgoKZGVmIF9mb3JtYXRfc2ltaWxhcml0eShzaW1pbGFyaXR5OiBmbG9hdCB8IE5vbmUpIC0+IHN0cjoKICAgIGlmIHNpbWlsYXJpdHkgaXMgTm9uZToKICAgICAgICByZXR1cm4gIm4vYSIKICAgIHJldHVybiBmIntyb3VuZChzaW1pbGFyaXR5ICogMTAwLCAxKX0lIgoKCmRlZiBfZm9ybWF0X2Z1c2VkX3Jlc3VsdHMoCiAgICAqLAogICAgcXVlcnk6IHN0ciwKICAgIG1vZGU6IHN0ciwKICAgIGhpdHM6IGxpc3RbRnVzZWRIaXRdLAogICAgYnJhbmNoX2Vycm9yczogbGlzdFtzdHJdLAogICAgcmVyYW5rX2FwcGxpZWQ6IGJvb2wsCiAgICByZXJhbmtfZXJyb3I6IHN0ciB8IE5vbmUsCikgLT4gc3RyOgogICAgaWYgbm90IGhpdHM6CiAgICAgICAgbXNnID0gIk5lbmh1bSByZXN1bHRhZG8gZW5jb250cmFkby4gQXMgY29sZcOnw7VlcyBwb2RlbSBlc3RhciB2YXppYXMuIgogICAgICAgIGlmIGJyYW5jaF9lcnJvcnM6CiAgICAgICAgICAgIG1zZyArPSAiXG5GYWxoYXMgZGV0ZWN0YWRhczogIiArICIgfCAiLmpvaW4oYnJhbmNoX2Vycm9ycykKICAgICAgICByZXR1cm4gbXNnCgogICAgbGluZXM6IGxpc3Rbc3RyXSA9IFtmIiMgUmVzdWx0YWRvcyBwYXJhOiAne3F1ZXJ5fSciLCBmIioqTW9kbzoqKiB7bW9kZX0iXQoKICAgIGlmIGJyYW5jaF9lcnJvcnM6CiAgICAgICAgbGluZXMuYXBwZW5kKCIqKkF2aXNvcyBkZSBicmFuY2g6KiogIiArICIgfCAiLmpvaW4oYnJhbmNoX2Vycm9ycykpCgogICAgaWYgbW9kZSA9PSAiZW5zZW1ibGUiOgogICAgICAgIGlmIHJlcmFua19hcHBsaWVkOgogICAgICAgICAgICBsaW5lcy5hcHBlbmQoZiIqKlJlcmFua2luZzoqKiBhdGl2byAoe1JFUkFOS19NT0RFTF9JRH0pIikKICAgICAgICBlbHNlOgogICAgICAgICAgICBsaW5lcy5hcHBlbmQoZiIqKlJlcmFua2luZzoqKiBpbmRpc3BvbsOtdmVsICh7cmVyYW5rX2Vycm9yIG9yICdzZW0gZGV0YWxoZXMnfSkiKQoKICAgIGxpbmVzLmFwcGVuZCgiIikKCiAgICBmb3IgaWR4LCBoaXQgaW4gZW51bWVyYXRlKGhpdHMsIHN0YXJ0PTEpOgogICAgICAgIG1ldGFkYXRhID0gZGljdChoaXQubWV0YWRhdGEpCiAgICAgICAgbWV0YWRhdGEucG9wKCJfYmVzdF9zaW1pbGFyaXR5IiwgTm9uZSkKCiAgICAgICAgZmlsZV9wYXRoID0gc3RyKG1ldGFkYXRhLmdldCgiZmlsZV9wYXRoIiwgImRlc2NvbmhlY2lkbyIpKQogICAgICAgIGNodW5rX2luZGV4ID0gbWV0YWRhdGEuZ2V0KCJjaHVua19pbmRleCIsICI/IikKICAgICAgICBmaWxlX25hbWUgPSBzdHIobWV0YWRhdGEuZ2V0KCJmaWxlX25hbWUiLCBQYXRoKGZpbGVfcGF0aCkubmFtZSBpZiBmaWxlX3BhdGggIT0gImRlc2NvbmhlY2lkbyIgZWxzZSAiPyIpKQoKICAgICAgICBzb3VyY2VfbW9kZWxzID0gc29ydGVkKHtzdHIodi5nZXQoIm1vZGVsX2Nob2ljZSIsICI/IikpIGZvciB2IGluIGhpdC5zb3VyY2VfZGV0YWlscy52YWx1ZXMoKX0pCiAgICAgICAgc291cmNlX2NvbGxlY3Rpb25zID0gc29ydGVkKHtzdHIodi5nZXQoImNvbGxlY3Rpb24iLCAiPyIpKSBmb3IgdiBpbiBoaXQuc291cmNlX2RldGFpbHMudmFsdWVzKCl9KQoKICAgICAgICBzb3VyY2VfcGFydHM6IGxpc3Rbc3RyXSA9IFtdCiAgICAgICAgZm9yIHNvdXJjZV9rZXksIGRldGFpbHMgaW4gc29ydGVkKAogICAgICAgICAgICBoaXQuc291cmNlX2RldGFpbHMuaXRlbXMoKSwKICAgICAgICAgICAga2V5PWxhbWJkYSBpdGVtOiBpbnQoaXRlbVsxXS5nZXQoInJhbmsiLCA5OTk5OTkpKSwKICAgICAgICApOgogICAgICAgICAgICBzb3VyY2VfcGFydHMuYXBwZW5kKAogICAgICAgICAgICAgICAgZiJ7c291cmNlX2tleX0ocmFuaz17ZGV0YWlscy5nZXQoJ3JhbmsnKX0sIHNpbT17X2Zvcm1hdF9zaW1pbGFyaXR5KGRldGFpbHMuZ2V0KCdzaW1pbGFyaXR5JykpfSkiCiAgICAgICAgICAgICkKCiAgICAgICAgc25pcHBldCA9IGhpdC5kb2N1bWVudC5zdHJpcCgpCiAgICAgICAgaWYgbGVuKHNuaXBwZXQpID4gODAwOgogICAgICAgICAgICBzbmlwcGV0ID0gc25pcHBldFs6ODAwXSArICJcbi4uLiBbdHJ1bmNhZG9dIgoKICAgICAgICBzY29yZV9saW5lID0gZiJSUkY9e2hpdC5ycmZfc2NvcmU6LjRmfSIKICAgICAgICBpZiBoaXQucmVyYW5rX3Njb3JlIGlzIG5vdCBOb25lOgogICAgICAgICAgICBzY29yZV9saW5lICs9IGYiIHwgcmVyYW5rPXtoaXQucmVyYW5rX3Njb3JlOi40Zn0iCgogICAgICAgIGxpbmVzLmFwcGVuZChmIiMjIFt7aWR4fV0ge2ZpbGVfcGF0aH0iKQogICAgICAgIGxpbmVzLmFwcGVuZChmIioqU2NvcmVzOioqIHtzY29yZV9saW5lfSIpCiAgICAgICAgbGluZXMuYXBwZW5kKGYiKipGb250ZXMgZGUgcmVjdXBlcmHDp8OjbzoqKiB7JywgJy5qb2luKHNvdXJjZV9wYXJ0cyl9IikKICAgICAgICBsaW5lcy5hcHBlbmQoCiAgICAgICAgICAgICIqKk1ldGFkYWRvcyB1bmlmaWNhZG9zOioqICIKICAgICAgICAgICAgZiJmaWxlX25hbWU9e2ZpbGVfbmFtZX0gfCBjaHVua19pbmRleD17Y2h1bmtfaW5kZXh9IHwgIgogICAgICAgICAgICBmInNvdXJjZV9tb2RlbHM9e3NvdXJjZV9tb2RlbHN9IHwgc291cmNlX2NvbGxlY3Rpb25zPXtzb3VyY2VfY29sbGVjdGlvbnN9IgogICAgICAgICkKICAgICAgICBsaW5lcy5hcHBlbmQoIiIpCiAgICAgICAgbGluZXMuYXBwZW5kKGYiYGBgXG57c25pcHBldH1cbmBgYCIpCiAgICAgICAgbGluZXMuYXBwZW5kKCIiKQoKICAgIHJldHVybiAiXG4iLmpvaW4obGluZXMpCgoKZGVmIF9ydW5fc2luZ2xlX21vZGUocXVlcnk6IHN0ciwgdG9wX2s6IGludCkgLT4gdHVwbGVbbGlzdFtGdXNlZEhpdF0sIGxpc3Rbc3RyXSwgYm9vbCwgc3RyIHwgTm9uZV06CiAgICBwcmltYXJ5X2JyYW5jaCA9IEJSQU5DSF9TUEVDU1tERUZBVUxUX1NJTkdMRV9CUkFOQ0hfS0VZXQoKICAgIGhpdHMsIGVycm9yID0gX3F1ZXJ5X2JyYW5jaChwcmltYXJ5X2JyYW5jaCwgcXVlcnksIHRvcF9rKQogICAgZXJyb3JzOiBsaXN0W3N0cl0gPSBbXQogICAgaWYgZXJyb3I6CiAgICAgICAgZXJyb3JzLmFwcGVuZChlcnJvcikKCiAgICAjIEZhbGxiYWNrIGF1dG9tw6F0aWNvIHBhcmEgYSBicmFuY2ggYWx0ZXJuYXRpdmEsIHByZXNlcnZhbmRvIGRpc3BvbmliaWxpZGFkZS4KICAgIGlmIG5vdCBoaXRzOgogICAgICAgIGZhbGxiYWNrX2JyYW5jaF9rZXkgPSAiYmdlX2RvYyIgaWYgcHJpbWFyeV9icmFuY2gua2V5ID09ICJqaW5hX2NvZGUiIGVsc2UgImppbmFfY29kZSIKICAgICAgICBmYWxsYmFja19oaXRzLCBmYWxsYmFja19lcnJvciA9IF9xdWVyeV9icmFuY2goQlJBTkNIX1NQRUNTW2ZhbGxiYWNrX2JyYW5jaF9rZXldLCBxdWVyeSwgdG9wX2spCiAgICAgICAgaWYgZmFsbGJhY2tfZXJyb3I6CiAgICAgICAgICAgIGVycm9ycy5hcHBlbmQoZmFsbGJhY2tfZXJyb3IpCiAgICAgICAgaWYgZmFsbGJhY2tfaGl0czoKICAgICAgICAgICAgaGl0cyA9IGZhbGxiYWNrX2hpdHMKCiAgICBpZiBub3QgaGl0czoKICAgICAgICByZXR1cm4gW10sIGVycm9ycywgRmFsc2UsIE5vbmUKCiAgICBmdXNlZCA9IF9ycmZfZnVzZSh7InNpbmdsZSI6IGhpdHN9LCB0b3BfaykKICAgIHJldHVybiBmdXNlZCwgZXJyb3JzLCBGYWxzZSwgTm9uZQoKCmRlZiBfcnVuX2Vuc2VtYmxlX21vZGUocXVlcnk6IHN0ciwgdG9wX2s6IGludCkgLT4gdHVwbGVbbGlzdFtGdXNlZEhpdF0sIGxpc3Rbc3RyXSwgYm9vbCwgc3RyIHwgTm9uZV06CiAgICBwZXJfYnJhbmNoX2sgPSBtaW4oTUFYX1FVRVJZX1JFU1VMVFMsIG1heCh0b3BfayAqIDIsIHRvcF9rKSkKICAgIGJyYW5jaGVzID0gW0JSQU5DSF9TUEVDU1siamluYV9jb2RlIl0sIEJSQU5DSF9TUEVDU1siYmdlX2RvYyJdXQoKICAgIGhpdHNfYnlfYnJhbmNoOiBkaWN0W3N0ciwgbGlzdFtSZXRyaWV2ZWRIaXRdXSA9IHt9CiAgICBicmFuY2hfZXJyb3JzOiBsaXN0W3N0cl0gPSBbXQoKICAgIHdpdGggVGhyZWFkUG9vbEV4ZWN1dG9yKG1heF93b3JrZXJzPWxlbihicmFuY2hlcykpIGFzIGV4ZWN1dG9yOgogICAgICAgIGZ1dHVyZXMgPSB7CiAgICAgICAgICAgIGV4ZWN1dG9yLnN1Ym1pdChfcXVlcnlfYnJhbmNoLCBicmFuY2gsIHF1ZXJ5LCBwZXJfYnJhbmNoX2spOiBicmFuY2gKICAgICAgICAgICAgZm9yIGJyYW5jaCBpbiBicmFuY2hlcwogICAgICAgIH0KICAgICAgICBmb3IgZnV0dXJlIGluIGFzX2NvbXBsZXRlZChmdXR1cmVzKToKICAgICAgICAgICAgYnJhbmNoID0gZnV0dXJlc1tmdXR1cmVdCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGhpdHMsIGVycm9yID0gZnV0dXJlLnJlc3VsdCgpCiAgICAgICAgICAgICAgICBpZiBlcnJvcjoKICAgICAgICAgICAgICAgICAgICBicmFuY2hfZXJyb3JzLmFwcGVuZChlcnJvcikKICAgICAgICAgICAgICAgIGlmIGhpdHM6CiAgICAgICAgICAgICAgICAgICAgaGl0c19ieV9icmFuY2hbYnJhbmNoLmtleV0gPSBoaXRzCiAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICAgICAgICAgIGJyYW5jaF9lcnJvcnMuYXBwZW5kKGYie2JyYW5jaC5rZXl9OiBmYWxoYSBpbmVzcGVyYWRhICh7ZX0pIikKCiAgICBpZiBub3QgaGl0c19ieV9icmFuY2g6CiAgICAgICAgcmV0dXJuIFtdLCBicmFuY2hfZXJyb3JzLCBGYWxzZSwgTm9uZQoKICAgIGNhbmRpZGF0ZV9wb29sID0gbWluKFJFUkFOS19NQVhfQ0FORElEQVRFUywgbWF4KHRvcF9rLCB0b3BfayAqIFJFUkFOS19DQU5ESURBVEVfTVVMVElQTElFUikpCiAgICBmdXNlZF9jYW5kaWRhdGVzID0gX3JyZl9mdXNlKGhpdHNfYnlfYnJhbmNoLCBjYW5kaWRhdGVfcG9vbCkKICAgIHJlcmFua2VkX2hpdHMsIHJlcmFua19hcHBsaWVkLCByZXJhbmtfZXJyb3IgPSBfYXBwbHlfcmVyYW5rKHF1ZXJ5LCBmdXNlZF9jYW5kaWRhdGVzLCB0b3BfaykKICAgIHJldHVybiByZXJhbmtlZF9oaXRzLCBicmFuY2hfZXJyb3JzLCByZXJhbmtfYXBwbGllZCwgcmVyYW5rX2Vycm9yCgoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBTZXJ2aWRvciBNQ1AgdmlhIEZhc3RNQ1AKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkZPUkNFX1NFTUFOVElDX0ZBTExCQUNLID0gKAogICAgb3MuZW52aXJvbi5nZXQoIk1DUF9GT1JDRV9TRU1BTlRJQ19GQUxMQkFDSyIsICJ0cnVlIikuc3RyaXAoKS5sb3dlcigpCiAgICBpbiB7IjEiLCAidHJ1ZSIsICJ5ZXMiLCAib24ifQopCgoKZGVmIF9idWlsZF9zZXJ2ZXJfaW5zdHJ1Y3Rpb25zKCkgLT4gc3RyOgogICAgaW5zdHJ1Y3Rpb25zID0gKAogICAgICAgICJTZXJ2aWRvciBSQUcgcGFyYSBidXNjYSBzZW3Dom50aWNhIGVtIGPDs2RpZ28tZm9udGUgbG9jYWwgY29tIHN1cG9ydGUgYSBlbnNlbWJsZSBow61icmlkby4gIgogICAgICAgICJObyBtb2RvIGh5YnJpZCwgYSBicmFuY2ggZGUgY8OzZGlnbyB1c2EgSmluYSB2MiBlIGEgZGUgZG9jdW1lbnRhw6fDo28gdXNhIEJHRS4gIgogICAgICAgICJVc2Ugc2VtYW50aWNfc2VhcmNoX2NvZGUocXVlcnksIHRvcF9rLCBtb2RlPSdlbnNlbWJsZScpIHBhcmEgY29tYmluYXIgSmluYStCR0UgY29tIFJSRiBlIHJlcmFua2luZy4gIgogICAgICAgICJVc2UgdXBkYXRlX2ZpbGVfaW5kZXggYXDDs3MgZWRpdGFyIHVtIGFycXVpdm8gcGFyYSBtYW50ZXIgYXMgZHVhcyBjb2xlw6fDtWVzIHNpbmNyb25pemFkYXMuICIKICAgICAgICAiVXNlIGluZGV4X3NwZWNpZmljX2ZvbGRlciBwYXJhIGluZGV4YcOnw6NvIHJlY3Vyc2l2YSBzb2IgZGVtYW5kYS4iCiAgICApCiAgICBpZiBGT1JDRV9TRU1BTlRJQ19GQUxMQkFDSzoKICAgICAgICBpbnN0cnVjdGlvbnMgKz0gKAogICAgICAgICAgICAiIFJlZ3JhIG9icmlnYXTDs3JpYTogcXVhbmRvIGEgcGVyZ3VudGEgbWVuY2lvbmFyIGZ1bsOnw6NvL2NsYXNzZS9jb21wb25lbnRlL2FycXVpdm8gIgogICAgICAgICAgICAiZSBpc3NvIG7Do28gZXN0aXZlciBubyBjb250ZXh0byBpbWVkaWF0bywgY2hhbWUgc2VtYW50aWNfc2VhcmNoX2NvZGUobW9kZT0nZW5zZW1ibGUnKSAiCiAgICAgICAgICAgICJhbnRlcyBkZSByZXNwb25kZXIgcXVlIG7Do28gZW5jb250cm91LiBTw7MgY29uY2x1YSBhdXPDqm5jaWEgYXDDs3MgYW8gbWVub3MgdW1hIGJ1c2NhIHNlbcOibnRpY2EuIgogICAgICAgICkKICAgIHJldHVybiBpbnN0cnVjdGlvbnMKCgptY3AgPSBGYXN0TUNQKAogICAgbmFtZT0icmFnLWNvZGViYXNlIiwKICAgIGluc3RydWN0aW9ucz1fYnVpbGRfc2VydmVyX2luc3RydWN0aW9ucygpLAopCgoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBUb29sIDE6IHNlbWFudGljX3NlYXJjaF9jb2RlCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpAbWNwLnRvb2woKQpkZWYgc2VtYW50aWNfc2VhcmNoX2NvZGUocXVlcnk6IHN0ciwgdG9wX2s6IGludCA9IFRPUF9LX1JFU1VMVFMsIG1vZGU6IHN0ciA9IFNFQVJDSF9NT0RFX0RFRkFVTFQpIC0+IHN0cjoKICAgICIiIgogICAgQnVzY2Egc2Vtw6JudGljYSBubyDDrW5kaWNlIHZldG9yaWFsIGxvY2FsLgoKICAgIE1vZG9zOgogICAgLSBzaW5nbGU6IHVzYSBhcGVuYXMgdW1hIGJyYW5jaCAoSmluYS9CR0UgY29uZm9ybWUgTUNQX0VNQkVERElOR19NT0RFTDsgbm8gaHlicmlkLCBKaW5hIHYyKS4KICAgIC0gZW5zZW1ibGU6IGNvbnN1bHRhIGVtIHBhcmFsZWxvIGNvZGVfdmVjdG9yc19qaW5hICsgZG9jX3ZlY3RvcnNfYmdlLAogICAgICBmYXogZnVzw6NvIHZpYSBSZWNpcHJvY2FsIFJhbmsgRnVzaW9uIChSUkYpIGUgcmVyYW5raW5nIGxldmUuCgogICAgQXJnczoKICAgICAgICBxdWVyeTogRGVzY3Jpw6fDo28gZG8gcXVlIHByb2N1cmFyLgogICAgICAgIHRvcF9rOiBRdWFudGlkYWRlIGZpbmFsIGRlIHJlc3VsdGFkb3MuCiAgICAgICAgbW9kZTogInNpbmdsZSIgKHBhZHLDo28pIG91ICJlbnNlbWJsZSIuCgogICAgUmV0dXJuczoKICAgICAgICBSZXN1bHRhZG8gdGV4dHVhbCBmb3JtYXRhZG8gcGFyYSBjb25zdW1vIHBlbG8gTExNLgogICAgIiIiCiAgICByYXdfcXVlcnkgPSAocXVlcnkgb3IgIiIpLnN0cmlwKCkKICAgIHNlYXJjaF9tb2RlID0gKG1vZGUgb3IgU0VBUkNIX01PREVfREVGQVVMVCkuc3RyaXAoKS5sb3dlcigpCgogICAgX2xvZ190b29sX3VzYWdlKAogICAgICAgIGV2ZW50PSJ0b29sX2NhbGxfc3RhcnQiLAogICAgICAgIHRvb2xfbmFtZT0ic2VtYW50aWNfc2VhcmNoX2NvZGUiLAogICAgICAgIGRldGFpbHM9ewogICAgICAgICAgICAicXVlcnlfcHJldmlldyI6IF9zYWZlX3ByZXZpZXcocmF3X3F1ZXJ5KSwKICAgICAgICAgICAgInF1ZXJ5X2xlbiI6IGxlbihyYXdfcXVlcnkpLAogICAgICAgICAgICAidG9wX2siOiB0b3BfaywKICAgICAgICAgICAgIm1vZGUiOiBzZWFyY2hfbW9kZSwKICAgICAgICB9LAogICAgKQoKICAgIGlmIG5vdCByYXdfcXVlcnk6CiAgICAgICAgX2xvZ190b29sX3VzYWdlKAogICAgICAgICAgICBldmVudD0idG9vbF9jYWxsX2VuZCIsCiAgICAgICAgICAgIHRvb2xfbmFtZT0ic2VtYW50aWNfc2VhcmNoX2NvZGUiLAogICAgICAgICAgICBkZXRhaWxzPXsic3RhdHVzIjogImVycm9yIiwgInJlYXNvbiI6ICJlbXB0eV9xdWVyeSJ9LAogICAgICAgICkKICAgICAgICByZXR1cm4gIkVycm86IGEgcXVlcnkgbsOjbyBwb2RlIHNlciB2YXppYS4iCgogICAgdG9wX2sgPSBtYXgoMSwgbWluKHRvcF9rLCAyMCkpCiAgICBpZiBzZWFyY2hfbW9kZSBub3QgaW4geyJzaW5nbGUiLCAiZW5zZW1ibGUifToKICAgICAgICBfbG9nX3Rvb2xfdXNhZ2UoCiAgICAgICAgICAgIGV2ZW50PSJ0b29sX2NhbGxfZW5kIiwKICAgICAgICAgICAgdG9vbF9uYW1lPSJzZW1hbnRpY19zZWFyY2hfY29kZSIsCiAgICAgICAgICAgIGRldGFpbHM9eyJzdGF0dXMiOiAiZXJyb3IiLCAicmVhc29uIjogImludmFsaWRfbW9kZSIsICJtb2RlIjogc2VhcmNoX21vZGV9LAogICAgICAgICkKICAgICAgICByZXR1cm4gIkVycm86IG1vZGUgaW52w6FsaWRvLiBVc2UgJ3NpbmdsZScgb3UgJ2Vuc2VtYmxlJy4iCgogICAgdHJ5OgogICAgICAgIGlmIHNlYXJjaF9tb2RlID09ICJlbnNlbWJsZSI6CiAgICAgICAgICAgIGhpdHMsIGJyYW5jaF9lcnJvcnMsIHJlcmFua19hcHBsaWVkLCByZXJhbmtfZXJyb3IgPSBfcnVuX2Vuc2VtYmxlX21vZGUocmF3X3F1ZXJ5LCB0b3BfaykKICAgICAgICBlbHNlOgogICAgICAgICAgICBoaXRzLCBicmFuY2hfZXJyb3JzLCByZXJhbmtfYXBwbGllZCwgcmVyYW5rX2Vycm9yID0gX3J1bl9zaW5nbGVfbW9kZShyYXdfcXVlcnksIHRvcF9rKQoKICAgICAgICByZXN1bHRfdGV4dCA9IF9mb3JtYXRfZnVzZWRfcmVzdWx0cygKICAgICAgICAgICAgcXVlcnk9cmF3X3F1ZXJ5LAogICAgICAgICAgICBtb2RlPXNlYXJjaF9tb2RlLAogICAgICAgICAgICBoaXRzPWhpdHMsCiAgICAgICAgICAgIGJyYW5jaF9lcnJvcnM9YnJhbmNoX2Vycm9ycywKICAgICAgICAgICAgcmVyYW5rX2FwcGxpZWQ9cmVyYW5rX2FwcGxpZWQsCiAgICAgICAgICAgIHJlcmFua19lcnJvcj1yZXJhbmtfZXJyb3IsCiAgICAgICAgKQoKICAgICAgICBfbG9nX3Rvb2xfdXNhZ2UoCiAgICAgICAgICAgIGV2ZW50PSJ0b29sX2NhbGxfZW5kIiwKICAgICAgICAgICAgdG9vbF9uYW1lPSJzZW1hbnRpY19zZWFyY2hfY29kZSIsCiAgICAgICAgICAgIGRldGFpbHM9ewogICAgICAgICAgICAgICAgInN0YXR1cyI6ICJvayIsCiAgICAgICAgICAgICAgICAibW9kZSI6IHNlYXJjaF9tb2RlLAogICAgICAgICAgICAgICAgInJlc3VsdF9jb3VudCI6IGxlbihoaXRzKSwKICAgICAgICAgICAgICAgICJicmFuY2hfZXJyb3JzIjogbGVuKGJyYW5jaF9lcnJvcnMpLAogICAgICAgICAgICAgICAgInJlcmFua19hcHBsaWVkIjogcmVyYW5rX2FwcGxpZWQsCiAgICAgICAgICAgIH0sCiAgICAgICAgKQogICAgICAgIHJldHVybiByZXN1bHRfdGV4dAogICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgIF9sb2dfdG9vbF91c2FnZSgKICAgICAgICAgICAgZXZlbnQ9InRvb2xfY2FsbF9lbmQiLAogICAgICAgICAgICB0b29sX25hbWU9InNlbWFudGljX3NlYXJjaF9jb2RlIiwKICAgICAgICAgICAgZGV0YWlscz17InN0YXR1cyI6ICJlcnJvciIsICJyZWFzb24iOiAic2VhcmNoX2ZhaWxlZCIsICJlcnJvciI6IHN0cihlKSwgIm1vZGUiOiBzZWFyY2hfbW9kZX0sCiAgICAgICAgKQogICAgICAgIHJldHVybiBmIkVycm8gYW8gZXhlY3V0YXIgYnVzY2Egc2Vtw6JudGljYSAoe3NlYXJjaF9tb2RlfSk6IHtlfSIKCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIFRvb2wgMjogdXBkYXRlX2ZpbGVfaW5kZXgKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkBtY3AudG9vbCgpCmRlZiB1cGRhdGVfZmlsZV9pbmRleChmaWxlX3BhdGg6IHN0cikgLT4gc3RyOgogICAgIiIiCiAgICBBdHVhbGl6YSBvIMOtbmRpY2UgUkFHIHBhcmEgdW0gYXJxdWl2byBlc3BlY8OtZmljby4KCiAgICBPIGFycXVpdm8gw6kgY2xhc3NpZmljYWRvIGNvbW8gY8OzZGlnby9kb2MgZSBpbmRleGFkbyBuYSBjb2xlw6fDo28gYXByb3ByaWFkYS4KICAgIFBhcmEgZXh0ZW5zw7VlcyBhbWLDrWd1YXMsIGluZGV4YSBlbSBhbWJhcyBhcyBjb2xlw6fDtWVzLgogICAgIiIiCiAgICBmaWxlcGF0aCA9IFBhdGgoZmlsZV9wYXRoKS5yZXNvbHZlKCkKICAgIGFic19wYXRoID0gc3RyKGZpbGVwYXRoKQoKICAgIF9sb2dfdG9vbF91c2FnZSgKICAgICAgICBldmVudD0idG9vbF9jYWxsX3N0YXJ0IiwKICAgICAgICB0b29sX25hbWU9InVwZGF0ZV9maWxlX2luZGV4IiwKICAgICAgICBkZXRhaWxzPXsiZmlsZV9wYXRoIjogYWJzX3BhdGh9LAogICAgKQoKICAgIGlmIG5vdCBmaWxlcGF0aC5leGlzdHMoKToKICAgICAgICBfbG9nX3Rvb2xfdXNhZ2UoCiAgICAgICAgICAgIGV2ZW50PSJ0b29sX2NhbGxfZW5kIiwKICAgICAgICAgICAgdG9vbF9uYW1lPSJ1cGRhdGVfZmlsZV9pbmRleCIsCiAgICAgICAgICAgIGRldGFpbHM9eyJzdGF0dXMiOiAiZXJyb3IiLCAicmVhc29uIjogImZpbGVfbm90X2ZvdW5kIiwgImZpbGVfcGF0aCI6IGFic19wYXRofSwKICAgICAgICApCiAgICAgICAgcmV0dXJuIGYiRXJybzogYXJxdWl2byBuw6NvIGVuY29udHJhZG86IHtmaWxlcGF0aH0iCgogICAgaWYgbm90IGZpbGVwYXRoLmlzX2ZpbGUoKToKICAgICAgICBfbG9nX3Rvb2xfdXNhZ2UoCiAgICAgICAgICAgIGV2ZW50PSJ0b29sX2NhbGxfZW5kIiwKICAgICAgICAgICAgdG9vbF9uYW1lPSJ1cGRhdGVfZmlsZV9pbmRleCIsCiAgICAgICAgICAgIGRldGFpbHM9eyJzdGF0dXMiOiAiZXJyb3IiLCAicmVhc29uIjogIm5vdF9hX2ZpbGUiLCAiZmlsZV9wYXRoIjogYWJzX3BhdGh9LAogICAgICAgICkKICAgICAgICByZXR1cm4gZiJFcnJvOiBvIGNhbWluaG8gbsOjbyBhcG9udGEgcGFyYSB1bSBhcnF1aXZvOiB7ZmlsZXBhdGh9IgoKICAgIGlmIGZpbGVwYXRoLnN0YXQoKS5zdF9zaXplID4gTUFYX0ZJTEVfU0laRV9CWVRFUzoKICAgICAgICBfbG9nX3Rvb2xfdXNhZ2UoCiAgICAgICAgICAgIGV2ZW50PSJ0b29sX2NhbGxfZW5kIiwKICAgICAgICAgICAgdG9vbF9uYW1lPSJ1cGRhdGVfZmlsZV9pbmRleCIsCiAgICAgICAgICAgIGRldGFpbHM9eyJzdGF0dXMiOiAiZXJyb3IiLCAicmVhc29uIjogImZpbGVfdG9vX2xhcmdlIiwgImZpbGVfcGF0aCI6IGFic19wYXRofSwKICAgICAgICApCiAgICAgICAgcmV0dXJuIGYiRXJybzogYXJxdWl2byBtdWl0byBncmFuZGUgKD57TUFYX0ZJTEVfU0laRV9CWVRFUyAvLyAxMDI0fUtCKToge2ZpbGVwYXRofSIKCiAgICBzcGxpdHRlciA9IGdldF9zcGxpdHRlcigpCiAgICB0YXJnZXRzID0gX2NsYXNzaWZ5X2ZpbGVfdGFyZ2V0cyhmaWxlcGF0aCkKCiAgICBkZWxldGVkX3Blcl9icmFuY2gsIGRlbGV0aW9uX2Vycm9ycyA9IF9yZW1vdmVfZmlsZV9mcm9tX2FsbF9jb2xsZWN0aW9ucyhhYnNfcGF0aCkKCiAgICBpbnNlcnRlZF9wZXJfYnJhbmNoOiBkaWN0W3N0ciwgaW50XSA9IHt9CiAgICBpbmRleF9lcnJvcnM6IGxpc3Rbc3RyXSA9IFtdCiAgICBmb3IgYnJhbmNoIGluIHRhcmdldHM6CiAgICAgICAgdHJ5OgogICAgICAgICAgICBpbnNlcnRlZCA9IF9pbmRleF9zaW5nbGVfZmlsZV9mb3JfYnJhbmNoKAogICAgICAgICAgICAgICAgZmlsZXBhdGgsCiAgICAgICAgICAgICAgICBicmFuY2gsCiAgICAgICAgICAgICAgICBzcGxpdHRlciwKICAgICAgICAgICAgICAgIGRlbGV0ZV9leGlzdGluZz1GYWxzZSwgICMgasOhIHJlbW92aWRvIGVtIHRvZGFzIGFzIGNvbGXDp8O1ZXMgYWNpbWEKICAgICAgICAgICAgKQogICAgICAgICAgICBpbnNlcnRlZF9wZXJfYnJhbmNoW2JyYW5jaC5rZXldID0gaW5zZXJ0ZWQKICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgICAgIGlmIGJyYW5jaC5rZXkgPT0gImJnZV9kb2MiIGFuZCAiamluYV9jb2RlIiBub3QgaW4gaW5zZXJ0ZWRfcGVyX2JyYW5jaDoKICAgICAgICAgICAgICAgIGZhbGxiYWNrX2JyYW5jaCA9IEJSQU5DSF9TUEVDU1siamluYV9jb2RlIl0KICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBpbnNlcnRlZCA9IF9pbmRleF9zaW5nbGVfZmlsZV9mb3JfYnJhbmNoKAogICAgICAgICAgICAgICAgICAgICAgICBmaWxlcGF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgZmFsbGJhY2tfYnJhbmNoLAogICAgICAgICAgICAgICAgICAgICAgICBzcGxpdHRlciwKICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlX2V4aXN0aW5nPUZhbHNlLAogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICBpbnNlcnRlZF9wZXJfYnJhbmNoW2ZhbGxiYWNrX2JyYW5jaC5rZXldID0gaW5zZXJ0ZWQKICAgICAgICAgICAgICAgICAgICBpbmRleF9lcnJvcnMuYXBwZW5kKGYie2JyYW5jaC5rZXl9OiB7ZX0gKGZhbGxiYWNrIHBhcmEge2ZhbGxiYWNrX2JyYW5jaC5rZXl9IGFwbGljYWRvKSIpCiAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZmFsbGJhY2tfZXJyb3I6CiAgICAgICAgICAgICAgICAgICAgaW5kZXhfZXJyb3JzLmFwcGVuZCgKICAgICAgICAgICAgICAgICAgICAgICAgZiJ7YnJhbmNoLmtleX06IHtlfSB8IGZhbGxiYWNrIHtmYWxsYmFja19icmFuY2gua2V5fToge2ZhbGxiYWNrX2Vycm9yfSIKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgaW5kZXhfZXJyb3JzLmFwcGVuZChmInticmFuY2gua2V5fToge2V9IikKCiAgICBzdWNjZXNzX2JyYW5jaGVzID0gW2sgZm9yIGssIHYgaW4gaW5zZXJ0ZWRfcGVyX2JyYW5jaC5pdGVtcygpIGlmIHYgPiAwXQoKICAgIGRldGFpbHMgPSB7CiAgICAgICAgInN0YXR1cyI6ICJvayIgaWYgc3VjY2Vzc19icmFuY2hlcyBlbHNlICJlcnJvciIsCiAgICAgICAgImZpbGVfcGF0aCI6IGFic19wYXRoLAogICAgICAgICJ0YXJnZXRzIjogW2Iua2V5IGZvciBiIGluIHRhcmdldHNdLAogICAgICAgICJkZWxldGVkX3Blcl9icmFuY2giOiBkZWxldGVkX3Blcl9icmFuY2gsCiAgICAgICAgImluc2VydGVkX3Blcl9icmFuY2giOiBpbnNlcnRlZF9wZXJfYnJhbmNoLAogICAgICAgICJkZWxldGlvbl9lcnJvcnMiOiBsZW4oZGVsZXRpb25fZXJyb3JzKSwKICAgICAgICAiaW5kZXhfZXJyb3JzIjogbGVuKGluZGV4X2Vycm9ycyksCiAgICB9CiAgICBfbG9nX3Rvb2xfdXNhZ2UoZXZlbnQ9InRvb2xfY2FsbF9lbmQiLCB0b29sX25hbWU9InVwZGF0ZV9maWxlX2luZGV4IiwgZGV0YWlscz1kZXRhaWxzKQoKICAgIGlmIG5vdCBzdWNjZXNzX2JyYW5jaGVzIGFuZCBpbmRleF9lcnJvcnM6CiAgICAgICAgcmV0dXJuICgKICAgICAgICAgICAgIkVycm86IG7Do28gZm9pIHBvc3PDrXZlbCByZWluZGV4YXIgbyBhcnF1aXZvIGVtIG5lbmh1bWEgY29sZcOnw6NvLlxuIgogICAgICAgICAgICBmIkFycXVpdm86IHtmaWxlcGF0aH1cbiIKICAgICAgICAgICAgIkZhbGhhczogIiArICIgfCAiLmpvaW4oaW5kZXhfZXJyb3JzKQogICAgICAgICkKCiAgICBsaW5lcyA9IFsKICAgICAgICAiQXJxdWl2byByZWluZGV4YWRvLiIsCiAgICAgICAgZiIgIEFycXVpdm8gOiB7ZmlsZXBhdGh9IiwKICAgICAgICBmIiAgQ29sZcOnw7VlcyBhbHZvOiB7W2IuY29sbGVjdGlvbl9uYW1lIGZvciBiIGluIHRhcmdldHNdfSIsCiAgICAgICAgZiIgIFJlbW/Dp8O1ZXMgcG9yIGNvbGXDp8Ojbzoge2RlbGV0ZWRfcGVyX2JyYW5jaH0iLAogICAgICAgIGYiICBJbnNlcsOnw7VlcyBwb3IgY29sZcOnw6NvOiB7aW5zZXJ0ZWRfcGVyX2JyYW5jaH0iLAogICAgXQogICAgaWYgZGVsZXRpb25fZXJyb3JzOgogICAgICAgIGxpbmVzLmFwcGVuZCgiICBBdmlzb3MgbmEgcmVtb8Onw6NvOiAiICsgIiB8ICIuam9pbihkZWxldGlvbl9lcnJvcnMpKQogICAgaWYgaW5kZXhfZXJyb3JzOgogICAgICAgIGxpbmVzLmFwcGVuZCgiICBBdmlzb3MgbmEgaW5kZXhhw6fDo286ICIgKyAiIHwgIi5qb2luKGluZGV4X2Vycm9ycykpCiAgICByZXR1cm4gIlxuIi5qb2luKGxpbmVzKQoKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgVG9vbCAzOiBkZWxldGVfZmlsZV9pbmRleAojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKQG1jcC50b29sKCkKZGVmIGRlbGV0ZV9maWxlX2luZGV4KGZpbGVfcGF0aDogc3RyKSAtPiBzdHI6CiAgICAiIiIKICAgIFJlbW92ZSB1bSBhcnF1aXZvIGRvIMOtbmRpY2UgZW0gdG9kYXMgYXMgY29sZcOnw7VlcyBnZXJlbmNpYWRhcy4KICAgICIiIgogICAgZmlsZXBhdGggPSBQYXRoKGZpbGVfcGF0aCkucmVzb2x2ZSgpCiAgICBhYnNfcGF0aCA9IHN0cihmaWxlcGF0aCkKCiAgICBfbG9nX3Rvb2xfdXNhZ2UoCiAgICAgICAgZXZlbnQ9InRvb2xfY2FsbF9zdGFydCIsCiAgICAgICAgdG9vbF9uYW1lPSJkZWxldGVfZmlsZV9pbmRleCIsCiAgICAgICAgZGV0YWlscz17ImZpbGVfcGF0aCI6IGFic19wYXRofSwKICAgICkKCiAgICBkZWxldGVkX3Blcl9icmFuY2gsIGVycm9ycyA9IF9yZW1vdmVfZmlsZV9mcm9tX2FsbF9jb2xsZWN0aW9ucyhhYnNfcGF0aCkKICAgIHRvdGFsX2RlbGV0ZWQgPSBzdW0oZGVsZXRlZF9wZXJfYnJhbmNoLnZhbHVlcygpKQoKICAgIF9sb2dfdG9vbF91c2FnZSgKICAgICAgICBldmVudD0idG9vbF9jYWxsX2VuZCIsCiAgICAgICAgdG9vbF9uYW1lPSJkZWxldGVfZmlsZV9pbmRleCIsCiAgICAgICAgZGV0YWlscz17CiAgICAgICAgICAgICJzdGF0dXMiOiAib2siIGlmIHRvdGFsX2RlbGV0ZWQgPiAwIGVsc2UgIndhcm5pbmciLAogICAgICAgICAgICAiZmlsZV9wYXRoIjogYWJzX3BhdGgsCiAgICAgICAgICAgICJkZWxldGVkX3Blcl9icmFuY2giOiBkZWxldGVkX3Blcl9icmFuY2gsCiAgICAgICAgICAgICJlcnJvcnMiOiBsZW4oZXJyb3JzKSwKICAgICAgICB9LAogICAgKQoKICAgIGlmIHRvdGFsX2RlbGV0ZWQgPT0gMDoKICAgICAgICBiYXNlID0gZiJOZW5odW0gY2h1bmsgZW5jb250cmFkbyBwYXJhIG8gYXJxdWl2bzoge2Fic19wYXRofSIKICAgICAgICBpZiBlcnJvcnM6CiAgICAgICAgICAgIGJhc2UgKz0gIlxuRmFsaGFzIHBhcmNpYWlzOiAiICsgIiB8ICIuam9pbihlcnJvcnMpCiAgICAgICAgcmV0dXJuIGJhc2UKCiAgICBvdXQgPSBbCiAgICAgICAgIlJlbW92aWRvIGRvIMOtbmRpY2UgY29tIHN1Y2Vzc28uIiwKICAgICAgICBmIiAgQXJxdWl2byA6IHthYnNfcGF0aH0iLAogICAgICAgIGYiICBEZWxlw6fDtWVzIHBvciBjb2xlw6fDo286IHtkZWxldGVkX3Blcl9icmFuY2h9IiwKICAgIF0KICAgIGlmIGVycm9yczoKICAgICAgICBvdXQuYXBwZW5kKCIgIEF2aXNvczogIiArICIgfCAiLmpvaW4oZXJyb3JzKSkKICAgIHJldHVybiAiXG4iLmpvaW4ob3V0KQoKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgVG9vbCA0OiBpbmRleF9zcGVjaWZpY19mb2xkZXIKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkBtY3AudG9vbCgpCmRlZiBpbmRleF9zcGVjaWZpY19mb2xkZXIoZm9sZGVyX3BhdGg6IHN0cikgLT4gc3RyOgogICAgIiIiCiAgICBJbmRleGEgcmVjdXJzaXZhbWVudGUgdW1hIHBhc3RhIGVtIGNvbGXDp8O1ZXMgc2VwYXJhZGFzIHBvciBkb23DrW5pby4KICAgICIiIgogICAgZm9sZGVyID0gUGF0aChmb2xkZXJfcGF0aCkucmVzb2x2ZSgpCgogICAgX2xvZ190b29sX3VzYWdlKAogICAgICAgIGV2ZW50PSJ0b29sX2NhbGxfc3RhcnQiLAogICAgICAgIHRvb2xfbmFtZT0iaW5kZXhfc3BlY2lmaWNfZm9sZGVyIiwKICAgICAgICBkZXRhaWxzPXsiZm9sZGVyX3BhdGgiOiBzdHIoZm9sZGVyKX0sCiAgICApCgogICAgaWYgbm90IGZvbGRlci5leGlzdHMoKToKICAgICAgICBfbG9nX3Rvb2xfdXNhZ2UoCiAgICAgICAgICAgIGV2ZW50PSJ0b29sX2NhbGxfZW5kIiwKICAgICAgICAgICAgdG9vbF9uYW1lPSJpbmRleF9zcGVjaWZpY19mb2xkZXIiLAogICAgICAgICAgICBkZXRhaWxzPXsic3RhdHVzIjogImVycm9yIiwgInJlYXNvbiI6ICJmb2xkZXJfbm90X2ZvdW5kIiwgImZvbGRlcl9wYXRoIjogc3RyKGZvbGRlcil9LAogICAgICAgICkKICAgICAgICByZXR1cm4gZiJFcnJvOiBwYXN0YSBuw6NvIGVuY29udHJhZGE6IHtmb2xkZXJ9IgoKICAgIGlmIG5vdCBmb2xkZXIuaXNfZGlyKCk6CiAgICAgICAgX2xvZ190b29sX3VzYWdlKAogICAgICAgICAgICBldmVudD0idG9vbF9jYWxsX2VuZCIsCiAgICAgICAgICAgIHRvb2xfbmFtZT0iaW5kZXhfc3BlY2lmaWNfZm9sZGVyIiwKICAgICAgICAgICAgZGV0YWlscz17InN0YXR1cyI6ICJlcnJvciIsICJyZWFzb24iOiAibm90X2FfZm9sZGVyIiwgImZvbGRlcl9wYXRoIjogc3RyKGZvbGRlcil9LAogICAgICAgICkKICAgICAgICByZXR1cm4gZiJFcnJvOiBvIGNhbWluaG8gbsOjbyDDqSB1bSBkaXJldMOzcmlvOiB7Zm9sZGVyfSIKCiAgICBzcGxpdHRlciA9IGdldF9zcGxpdHRlcigpCgogICAgcHJvY2Vzc2VkX2ZpbGVzID0gMAogICAgYnJhbmNoX2ZpbGVfY291bnRzID0ge2tleTogMCBmb3Iga2V5IGluIEJSQU5DSF9TUEVDU30KICAgIGJyYW5jaF9jaHVua19jb3VudHMgPSB7a2V5OiAwIGZvciBrZXkgaW4gQlJBTkNIX1NQRUNTfQogICAgZXJyb3JfY291bnQgPSAwCiAgICBlcnJvcl9zYW1wbGVzOiBsaXN0W3N0cl0gPSBbXQoKICAgIGZvciBmaWxlcGF0aCBpbiBfc2Nhbl9mb2xkZXIoZm9sZGVyKToKICAgICAgICBwcm9jZXNzZWRfZmlsZXMgKz0gMQogICAgICAgIHRhcmdldHMgPSBfY2xhc3NpZnlfZmlsZV90YXJnZXRzKGZpbGVwYXRoKQogICAgICAgIGluZGV4ZWRfYnJhbmNoZXNfZm9yX2ZpbGU6IHNldFtzdHJdID0gc2V0KCkKCiAgICAgICAgZm9yIGJyYW5jaCBpbiB0YXJnZXRzOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBuX2NodW5rcyA9IF9pbmRleF9zaW5nbGVfZmlsZV9mb3JfYnJhbmNoKGZpbGVwYXRoLCBicmFuY2gsIHNwbGl0dGVyKQogICAgICAgICAgICAgICAgYnJhbmNoX2ZpbGVfY291bnRzW2JyYW5jaC5rZXldICs9IDEKICAgICAgICAgICAgICAgIGJyYW5jaF9jaHVua19jb3VudHNbYnJhbmNoLmtleV0gKz0gbl9jaHVua3MKICAgICAgICAgICAgICAgIGluZGV4ZWRfYnJhbmNoZXNfZm9yX2ZpbGUuYWRkKGJyYW5jaC5rZXkpCiAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICAgICAgICAgIGlmIGJyYW5jaC5rZXkgPT0gImJnZV9kb2MiIGFuZCAiamluYV9jb2RlIiBub3QgaW4gaW5kZXhlZF9icmFuY2hlc19mb3JfZmlsZToKICAgICAgICAgICAgICAgICAgICBmYWxsYmFja19icmFuY2ggPSBCUkFOQ0hfU1BFQ1NbImppbmFfY29kZSJdCiAgICAgICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgICAgICBuX2NodW5rcyA9IF9pbmRleF9zaW5nbGVfZmlsZV9mb3JfYnJhbmNoKGZpbGVwYXRoLCBmYWxsYmFja19icmFuY2gsIHNwbGl0dGVyKQogICAgICAgICAgICAgICAgICAgICAgICBicmFuY2hfZmlsZV9jb3VudHNbZmFsbGJhY2tfYnJhbmNoLmtleV0gKz0gMQogICAgICAgICAgICAgICAgICAgICAgICBicmFuY2hfY2h1bmtfY291bnRzW2ZhbGxiYWNrX2JyYW5jaC5rZXldICs9IG5fY2h1bmtzCiAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ZWRfYnJhbmNoZXNfZm9yX2ZpbGUuYWRkKGZhbGxiYWNrX2JyYW5jaC5rZXkpCiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yX2NvdW50ICs9IDEKICAgICAgICAgICAgICAgICAgICAgICAgaWYgbGVuKGVycm9yX3NhbXBsZXMpIDwgMTA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcl9zYW1wbGVzLmFwcGVuZCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIntmaWxlcGF0aC5uYW1lfSBbe2JyYW5jaC5rZXl9XToge2V9ICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmIihmYWxsYmFjayBwYXJhIHtmYWxsYmFja19icmFuY2gua2V5fSBhcGxpY2FkbykiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgICAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBmYWxsYmFja19lcnJvcjoKICAgICAgICAgICAgICAgICAgICAgICAgZSA9IFJ1bnRpbWVFcnJvcihmIntlfSB8IGZhbGxiYWNrIHtmYWxsYmFja19icmFuY2gua2V5fToge2ZhbGxiYWNrX2Vycm9yfSIpCiAgICAgICAgICAgICAgICBlcnJvcl9jb3VudCArPSAxCiAgICAgICAgICAgICAgICBpZiBsZW4oZXJyb3Jfc2FtcGxlcykgPCAxMDoKICAgICAgICAgICAgICAgICAgICBlcnJvcl9zYW1wbGVzLmFwcGVuZChmIntmaWxlcGF0aC5uYW1lfSBbe2JyYW5jaC5rZXl9XToge2V9IikKCiAgICBpZiBwcm9jZXNzZWRfZmlsZXMgPT0gMDoKICAgICAgICBfbG9nX3Rvb2xfdXNhZ2UoCiAgICAgICAgICAgIGV2ZW50PSJ0b29sX2NhbGxfZW5kIiwKICAgICAgICAgICAgdG9vbF9uYW1lPSJpbmRleF9zcGVjaWZpY19mb2xkZXIiLAogICAgICAgICAgICBkZXRhaWxzPXsic3RhdHVzIjogIm9rIiwgImZvbGRlcl9wYXRoIjogc3RyKGZvbGRlciksICJmaWxlc19wcm9jZXNzZWQiOiAwLCAiY2h1bmtzIjogMCwgImVycm9ycyI6IDB9LAogICAgICAgICkKICAgICAgICByZXR1cm4gZiJOZW5odW0gYXJxdWl2byBpbmRleMOhdmVsIGVuY29udHJhZG8gZW06IHtmb2xkZXJ9IgoKICAgIHRvdGFsX2NodW5rcyA9IHN1bShicmFuY2hfY2h1bmtfY291bnRzLnZhbHVlcygpKQoKICAgIF9sb2dfdG9vbF91c2FnZSgKICAgICAgICBldmVudD0idG9vbF9jYWxsX2VuZCIsCiAgICAgICAgdG9vbF9uYW1lPSJpbmRleF9zcGVjaWZpY19mb2xkZXIiLAogICAgICAgIGRldGFpbHM9ewogICAgICAgICAgICAic3RhdHVzIjogIm9rIiwKICAgICAgICAgICAgImZvbGRlcl9wYXRoIjogc3RyKGZvbGRlciksCiAgICAgICAgICAgICJmaWxlc19wcm9jZXNzZWQiOiBwcm9jZXNzZWRfZmlsZXMsCiAgICAgICAgICAgICJjaHVua3MiOiB0b3RhbF9jaHVua3MsCiAgICAgICAgICAgICJlcnJvcnMiOiBlcnJvcl9jb3VudCwKICAgICAgICAgICAgImJyYW5jaF9maWxlX2NvdW50cyI6IGJyYW5jaF9maWxlX2NvdW50cywKICAgICAgICAgICAgImJyYW5jaF9jaHVua19jb3VudHMiOiBicmFuY2hfY2h1bmtfY291bnRzLAogICAgICAgIH0sCiAgICApCgogICAgcmVwb3J0ID0gWwogICAgICAgICJJbmRleGHDp8OjbyBkYSBwYXN0YSBjb25jbHXDrWRhLiIsCiAgICAgICAgZiIgIFBhc3RhOiB7Zm9sZGVyfSIsCiAgICAgICAgZiIgIEFycXVpdm9zIHByb2Nlc3NhZG9zOiB7cHJvY2Vzc2VkX2ZpbGVzfSIsCiAgICAgICAgZiIgIFRvdGFsIGRlIGNodW5rczoge3RvdGFsX2NodW5rc30iLAogICAgICAgIGYiICBBcnF1aXZvcyBwb3IgYnJhbmNoOiB7YnJhbmNoX2ZpbGVfY291bnRzfSIsCiAgICAgICAgZiIgIENodW5rcyBwb3IgYnJhbmNoOiB7YnJhbmNoX2NodW5rX2NvdW50c30iLAogICAgXQoKICAgIGlmIGVycm9yX2NvdW50OgogICAgICAgIHJlcG9ydC5hcHBlbmQoZiIgIEVycm9zICh7ZXJyb3JfY291bnR9KToiKQogICAgICAgIGZvciBlcnIgaW4gZXJyb3Jfc2FtcGxlczoKICAgICAgICAgICAgcmVwb3J0LmFwcGVuZChmIiAgICAtIHtlcnJ9IikKICAgICAgICBpZiBlcnJvcl9jb3VudCA+IGxlbihlcnJvcl9zYW1wbGVzKToKICAgICAgICAgICAgcmVwb3J0LmFwcGVuZChmIiAgICAuLi4gZSBtYWlzIHtlcnJvcl9jb3VudCAtIGxlbihlcnJvcl9zYW1wbGVzKX0gZXJyb3MuIikKCiAgICByZXR1cm4gIlxuIi5qb2luKHJlcG9ydCkKCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIFBvbnRvIGRlIGVudHJhZGEKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICBsb2cuaW5mbygiSW5pY2lhbmRvIHNlcnZpZG9yIE1DUCBSQUcgKHN0ZGlvKS4uLiIpCiAgICBsb2cuaW5mbygiQ2hyb21hREI6ICVzOi8vJXM6JXMiLCBDSFJPTUFfU0NIRU1FLCBDSFJPTUFfSE9TVCwgQ0hST01BX1BPUlQpCiAgICBsb2cuaW5mbygKICAgICAgICAiQ29sZcOnw7VlczogJXMgKCVzKSwgJXMgKCVzKSIsCiAgICAgICAgQ09MTEVDVElPTl9DT0RFX0pJTkEsCiAgICAgICAgQlJBTkNIX1NQRUNTWyJqaW5hX2NvZGUiXS5tb2RlbF9pZCwKICAgICAgICBDT0xMRUNUSU9OX0RPQ19CR0UsCiAgICAgICAgQlJBTkNIX1NQRUNTWyJiZ2VfZG9jIl0ubW9kZWxfaWQsCiAgICApCiAgICBsb2cuaW5mbygiTW9kbyBwYWRyw6NvIGRlIGJ1c2NhOiAlcyIsIFNFQVJDSF9NT0RFX0RFRkFVTFQpCiAgICBsb2cuaW5mbygiTW9kZWxvIHNpbmdsZSBwYWRyw6NvOiAlcyIsIEJSQU5DSF9TUEVDU1tERUZBVUxUX1NJTkdMRV9CUkFOQ0hfS0VZXS5tb2RlbF9pZCkKICAgIGxvZy5pbmZvKCJRdWFudGl6YWNhbyBKaW5hOiAlcyIsIEpJTkFfUVVBTlRJWkFUSU9OKQogICAgbG9nLmluZm8oIkNvbmZpZyBkZSB0dW5pbmcgY2FycmVnYWRhIGRlOiAlcyAoZm91bmQ9JXMpIiwgSU5ERVhFUl9DT05GSUdfUEFUSCwgYm9vbChJTkRFWEVSX1RVTklOR19DT05GSUcpKQogICAgbG9nLmluZm8oIkVtYmVkZGluZyBiYXRjaCBzaXplOiAlcyIsIEVNQkVERElOR19CQVRDSF9TSVpFKQogICAgbG9nLmluZm8oIkNodW5rIHBhcmFtczogc2l6ZT0lcyBvdmVybGFwPSVzIiwgQ0hVTktfU0laRSwgQ0hVTktfT1ZFUkxBUCkKICAgIGxvZy5pbmZvKCJSZXJhbmtlcjogJXMgKGVuYWJsZWQ9JXMsIHF1YW50PSVzKSIsIFJFUkFOS19NT0RFTF9JRCwgUkVSQU5LX0VOQUJMRUQsIFJFUkFOS0VSX1FVQU5USVpBVElPTikKICAgIGxvZy5pbmZvKCJQYXN0YSBkZSBtb2RlbG9zIGxvY2FpczogJXMiLCBNT0RFTF9ESVIpCiAgICBsb2cuaW5mbygiVXNvIE1DUCBzZXLDoSByZWdpc3RyYWRvIGVtOiAlcyIsIE1DUF9VU0FHRV9MT0dfUEFUSCkKCiAgICAjIFByw6ktYXF1ZWNlIHNvbWVudGUgY29uZXjDo28gQ2hyb21hOyBtb2RlbG9zIGZpY2FtIGxhenkgcGFyYSBwb3VwYXIgUkFNLgogICAgdHJ5OgogICAgICAgIF9nZXRfY2hyb21hX2NsaWVudCgpCiAgICAgICAgZ2V0X2Nocm9tYV9jb2xsZWN0aW9uKENPTExFQ1RJT05fQ09ERV9KSU5BKQogICAgICAgIGdldF9jaHJvbWFfY29sbGVjdGlvbihDT0xMRUNUSU9OX0RPQ19CR0UpCiAgICAgICAgbG9nLmluZm8oIkNvbmV4w6NvIENocm9tYSBpbmljaWFsaXphZGEuIE1vZGVsb3Mgc2Vyw6NvIGNhcnJlZ2Fkb3Mgc29iIGRlbWFuZGEuIikKICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICBsb2cuZXJyb3IoIkZhbGhhIGFvIGluaWNpYWxpemFyIENocm9tYURCOiAlcyIsIGUpCiAgICAgICAgbG9nLmVycm9yKCJPIHNlcnZpZG9yIGNvbnRpbnVhcsOhLCBtYXMgYXMgZmVycmFtZW50YXMgcmV0b3JuYXLDo28gZXJybyBhdMOpIG8gQ2hyb21hREIgZXN0YXIgZGlzcG9uw612ZWwuIikKCiAgICBtY3AucnVuKHRyYW5zcG9ydD0ic3RkaW8iKQo="
|
|
729
729
|
B64_MODEL_DL_HF="IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwpmcm9tIF9fZnV0dXJlX18gaW1wb3J0IGFubm90YXRpb25zCgoiIiIKZG93bmxvYWRfbW9kZWxfZnJvbV9odWdnaW5mYWNlLnB5CgpDYW1hZGEgZGUgZG93bmxvYWQgZGUgbW9kZWxvcyBjb20gcHJpb3JpZGFkZSBkZSBwcm92ZWRvcmVzIGUgZmFsbGJhY2sgZGUgbW9kZWxvLgpGbHV4byBwYWRyw6NvOgoxKSB0ZW50YSBiYWl4YXIgbyBtb2RlbG8gcHJlZmVyaWRvIHZpYSBIdWdnaW5nIEZhY2U7CjIpIHNlIGZhbGhhciwgdGVudGEgcHJvdmVkb3JlcyBhbHRlcm5hdGl2b3MgKHF1YW5kbyBkaXNwb27DrXZlaXMpOwozKSBzZSBvIG1vZGVsbyBwcmVmZXJpZG8gZmFsaGFyIGVtIHRvZG9zIG9zIHByb3ZlZG9yZXMsIHRlbnRhIG1vZGVsbyBmYWxsYmFjay4KIiIiCgpmcm9tIGRhdGFjbGFzc2VzIGltcG9ydCBkYXRhY2xhc3MKaW1wb3J0IGdldHBhc3MKaW1wb3J0IG9zCmZyb20gcGF0aGxpYiBpbXBvcnQgUGF0aAppbXBvcnQgc2h1dGlsCmltcG9ydCBzeXMKZnJvbSB0eXBpbmcgaW1wb3J0IFByb3RvY29sCgoKY2xhc3MgTW9kZWxEb3dubG9hZFN0cmF0ZWd5KFByb3RvY29sKToKICAgIG5hbWU6IHN0cgoKICAgIGRlZiBkb3dubG9hZChzZWxmLCBtb2RlbF9pZDogc3RyLCBsb2NhbF9kaXI6IFBhdGgpIC0+IE5vbmU6CiAgICAgICAgIiIiQmFpeGEgbW9kZWxfaWQgcGFyYSBsb2NhbF9kaXIgb3UgbGV2YW50YSBleGNlw6fDo28uIiIiCgoKY2xhc3MgSHVnZ2luZ0ZhY2VEb3dubG9hZFN0cmF0ZWd5OgogICAgbmFtZSA9ICJodWdnaW5nZmFjZSIKCiAgICBkZWYgZG93bmxvYWQoc2VsZiwgbW9kZWxfaWQ6IHN0ciwgbG9jYWxfZGlyOiBQYXRoKSAtPiBOb25lOgogICAgICAgIGZyb20gaHVnZ2luZ2ZhY2VfaHViIGltcG9ydCBzbmFwc2hvdF9kb3dubG9hZAoKICAgICAgICBoZl90b2tlbiA9IG9zLmVudmlyb24uZ2V0KCJIRl9UT0tFTiIpIG9yIG9zLmVudmlyb24uZ2V0KCJIVUdHSU5HX0ZBQ0VfSFVCX1RPS0VOIikKICAgICAgICBfZG93bmxvYWRfd2l0aF9oZl90b2tlbl9yZWNvdmVyeSgKICAgICAgICAgICAgcmVwb19pZD1tb2RlbF9pZCwKICAgICAgICAgICAgbG9jYWxfZGlyPWxvY2FsX2RpciwKICAgICAgICAgICAgaGZfdG9rZW49aGZfdG9rZW4sCiAgICAgICAgICAgIHNuYXBzaG90X2Rvd25sb2FkPXNuYXBzaG90X2Rvd25sb2FkLAogICAgICAgICkKCgpAZGF0YWNsYXNzKGZyb3plbj1UcnVlKQpjbGFzcyBEb3dubG9hZFNlbGVjdGlvbjoKICAgIG1vZGVsX2lkOiBzdHIKICAgIHByb3ZpZGVyOiBzdHIKICAgIGxvY2FsX2RpcjogUGF0aAoKCmRlZiBfbG9hZF9vcHRpb25hbF9zdHJhdGVnaWVzKCkgLT4gbGlzdFtNb2RlbERvd25sb2FkU3RyYXRlZ3ldOgogICAgc3RyYXRlZ2llczogbGlzdFtNb2RlbERvd25sb2FkU3RyYXRlZ3ldID0gW10KCiAgICB0cnk6CiAgICAgICAgZnJvbSBkb3dubG9hZF9tb2RlbF9mcm9tX21vZGVsc2NvcGUgaW1wb3J0IE1vZGVsU2NvcGVEb3dubG9hZFN0cmF0ZWd5CgogICAgICAgIHN0cmF0ZWdpZXMuYXBwZW5kKE1vZGVsU2NvcGVEb3dubG9hZFN0cmF0ZWd5KCkpCiAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgICMgUHJvdmlkZXIgb3BjaW9uYWw6IGlnbm9yYSBzZSBuw6NvIGVzdGl2ZXIgZGlzcG9uw612ZWwgbm8gYW1iaWVudGUuCiAgICAgICAgcGFzcwoKICAgIHJldHVybiBzdHJhdGVnaWVzCgoKZGVmIGJ1aWxkX2RlZmF1bHRfc3RyYXRlZ2llcygpIC0+IGxpc3RbTW9kZWxEb3dubG9hZFN0cmF0ZWd5XToKICAgICIiIkZhY3Rvcnkgc2ltcGxlczogb3JkZW0gZGUgcHJpb3JpZGFkZSBkZSBwcm92ZWRvcmVzIGRlIGRvd25sb2FkLiIiIgogICAgcmV0dXJuIFtIdWdnaW5nRmFjZURvd25sb2FkU3RyYXRlZ3koKSwgKl9sb2FkX29wdGlvbmFsX3N0cmF0ZWdpZXMoKV0KCgpfTU9ERUxfUkVBRFlfTUFSS0VSID0gIi5kb3dubG9hZF9jb21wbGV0ZSIKCgpkZWYgX3ByZXBhcmVfZGVzdGluYXRpb24obG9jYWxfZGlyOiBQYXRoLCAqLCBjbGVhbjogYm9vbCkgLT4gTm9uZToKICAgIGlmIGNsZWFuIGFuZCBsb2NhbF9kaXIuZXhpc3RzKCk6CiAgICAgICAgc2h1dGlsLnJtdHJlZShsb2NhbF9kaXIpCiAgICBsb2NhbF9kaXIubWtkaXIocGFyZW50cz1UcnVlLCBleGlzdF9vaz1UcnVlKQoKCmRlZiBfbW9kZWxfY2FjaGVfZGlyKGJhc2VfZGlyOiBQYXRoLCBtb2RlbF9pZDogc3RyKSAtPiBQYXRoOgogICAgIyBFdml0YSBjb2xpc8OjbyBkZSBub21lcyBlIG1hbnTDqW0gZGlyZXTDs3JpbyBzZWd1cm8gZW0gcXVhbHF1ZXIgU08uCiAgICBzYWZlX25hbWUgPSBtb2RlbF9pZC5yZXBsYWNlKCIvIiwgIl9fIikucmVwbGFjZSgiOiIsICJfIikKICAgIHJldHVybiBiYXNlX2RpciAvIHNhZmVfbmFtZQoKCmRlZiBfY2FjaGVfcmVhZHkobG9jYWxfZGlyOiBQYXRoKSAtPiBib29sOgogICAgbWFya2VyID0gbG9jYWxfZGlyIC8gX01PREVMX1JFQURZX01BUktFUgogICAgaWYgbm90IG1hcmtlci5leGlzdHMoKSBvciBub3QgbG9jYWxfZGlyLmV4aXN0cygpOgogICAgICAgIHJldHVybiBGYWxzZQogICAgcmV0dXJuIGFueShwLm5hbWUgIT0gX01PREVMX1JFQURZX01BUktFUiBmb3IgcCBpbiBsb2NhbF9kaXIuaXRlcmRpcigpKQoKCmRlZiBfbWFya19jYWNoZV9yZWFkeShsb2NhbF9kaXI6IFBhdGgpIC0+IE5vbmU6CiAgICAobG9jYWxfZGlyIC8gX01PREVMX1JFQURZX01BUktFUikud3JpdGVfdGV4dCgib2tcbiIsIGVuY29kaW5nPSJ1dGYtOCIpCgoKZGVmIF9zdGF0dXNfY29kZV9mcm9tX2Vycm9yKGV4YzogRXhjZXB0aW9uKSAtPiBpbnQgfCBOb25lOgogICAgcmVzcG9uc2UgPSBnZXRhdHRyKGV4YywgInJlc3BvbnNlIiwgTm9uZSkKICAgIGlmIHJlc3BvbnNlIGlzIE5vbmU6CiAgICAgICAgcmV0dXJuIE5vbmUKICAgIHN0YXR1c19jb2RlID0gZ2V0YXR0cihyZXNwb25zZSwgInN0YXR1c19jb2RlIiwgTm9uZSkKICAgIGlmIGlzaW5zdGFuY2Uoc3RhdHVzX2NvZGUsIGludCk6CiAgICAgICAgcmV0dXJuIHN0YXR1c19jb2RlCiAgICByZXR1cm4gTm9uZQoKCmRlZiBfaXNfaW52YWxpZF9oZl90b2tlbl9lcnJvcihleGM6IEV4Y2VwdGlvbikgLT4gYm9vbDoKICAgIG1lc3NhZ2UgPSBzdHIoZXhjKS5sb3dlcigpCiAgICBzdGF0dXNfY29kZSA9IF9zdGF0dXNfY29kZV9mcm9tX2Vycm9yKGV4YykKICAgIHRva2VuX2tleXdvcmRzID0gKCJpbnZhbGlkIHRva2VuIiwgInRva2VuIGlzIGludmFsaWQiLCAidW5hdXRob3JpemVkIiwgIjQwMSIpCiAgICBpZiBzdGF0dXNfY29kZSA9PSA0MDE6CiAgICAgICAgcmV0dXJuIFRydWUKICAgIHJldHVybiBhbnkoa2V5d29yZCBpbiBtZXNzYWdlIGZvciBrZXl3b3JkIGluIHRva2VuX2tleXdvcmRzKQoKCmRlZiBfcHJvbXB0X3JlY292ZXJfaW52YWxpZF9oZl90b2tlbigpIC0+IHR1cGxlW3N0ciwgc3RyIHwgTm9uZV06CiAgICBpZiBub3Qgc3lzLnN0ZGluLmlzYXR0eSgpOgogICAgICAgIHJldHVybiAoIm5vLXRva2VuIiwgTm9uZSkKCiAgICB3aGlsZSBUcnVlOgogICAgICAgIHByaW50KAogICAgICAgICAgICAiWyFdIE8gdG9rZW4gZG8gSHVnZ2luZ0ZhY2UgcGFyZWNlIGludsOhbGlkby4gRXNjb2xoYTogIgogICAgICAgICAgICAiWzFdIGluZm9ybWFyIG5vdm8gdG9rZW4sIFsyXSBjb250aW51YXIgc2VtIHRva2VuLiIsCiAgICAgICAgICAgIGZpbGU9c3lzLnN0ZGVyciwKICAgICAgICApCiAgICAgICAgYW5zd2VyID0gaW5wdXQoIj4gRXNjb2xoYSBbMS8yXTogIikuc3RyaXAoKS5sb3dlcigpCiAgICAgICAgaWYgYW5zd2VyIGluIHsiMSIsICJub3ZvIiwgIm5ldyJ9OgogICAgICAgICAgICBuZXdfdG9rZW4gPSBnZXRwYXNzLmdldHBhc3MoIkNvbGUgbyBub3ZvIEhGX1RPS0VOOiAiKS5zdHJpcCgpCiAgICAgICAgICAgIGlmIG5ld190b2tlbjoKICAgICAgICAgICAgICAgIHJldHVybiAoIm5ldy10b2tlbiIsIG5ld190b2tlbikKICAgICAgICAgICAgcHJpbnQoIlshXSBUb2tlbiB2YXppby4gVGVudGUgbm92YW1lbnRlLiIsIGZpbGU9c3lzLnN0ZGVycikKICAgICAgICAgICAgY29udGludWUKICAgICAgICBpZiBhbnN3ZXIgaW4geyIyIiwgIiIsICJzZW0iLCAibm8ifToKICAgICAgICAgICAgcmV0dXJuICgibm8tdG9rZW4iLCBOb25lKQogICAgICAgIHByaW50KCJbIV0gT3DDp8OjbyBpbnbDoWxpZGEuIERpZ2l0ZSAxIG91IDIuIiwgZmlsZT1zeXMuc3RkZXJyKQoKCmRlZiBfZG93bmxvYWRfd2l0aF9oZl90b2tlbl9yZWNvdmVyeSgKICAgICosCiAgICByZXBvX2lkOiBzdHIsCiAgICBsb2NhbF9kaXI6IFBhdGgsCiAgICBoZl90b2tlbjogc3RyIHwgTm9uZSwKICAgIHNuYXBzaG90X2Rvd25sb2FkLAopIC0+IE5vbmU6CiAgICBhdHRlbXB0X3Rva2VuID0gaGZfdG9rZW4KCiAgICB3aGlsZSBUcnVlOgogICAgICAgIHRyeToKICAgICAgICAgICAgc25hcHNob3RfZG93bmxvYWQoCiAgICAgICAgICAgICAgICByZXBvX2lkPXJlcG9faWQsCiAgICAgICAgICAgICAgICBsb2NhbF9kaXI9c3RyKGxvY2FsX2RpciksCiAgICAgICAgICAgICAgICB0b2tlbj1hdHRlbXB0X3Rva2VuLAogICAgICAgICAgICApCiAgICAgICAgICAgIGlmIGF0dGVtcHRfdG9rZW46CiAgICAgICAgICAgICAgICBvcy5lbnZpcm9uWyJIRl9UT0tFTiJdID0gYXR0ZW1wdF90b2tlbgogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgb3MuZW52aXJvbi5wb3AoIkhGX1RPS0VOIiwgTm9uZSkKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBleGM6CiAgICAgICAgICAgIGlmIGF0dGVtcHRfdG9rZW4gYW5kIF9pc19pbnZhbGlkX2hmX3Rva2VuX2Vycm9yKGV4Yyk6CiAgICAgICAgICAgICAgICBwcmludCgKICAgICAgICAgICAgICAgICAgICAiWyFdIEZhbGhhIGRlIGF1dGVudGljYcOnw6NvIG5vIEh1Z2dpbmdGYWNlIGNvbSBvIHRva2VuIGF0dWFsLiAiCiAgICAgICAgICAgICAgICAgICAgIlZvY8OqIHBvZGUgaW5mb3JtYXIgb3V0cm8gdG9rZW4gb3Ugc2VndWlyIHNlbSB0b2tlbi4iLAogICAgICAgICAgICAgICAgICAgIGZpbGU9c3lzLnN0ZGVyciwKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIGFjdGlvbiwgcmVwbGFjZW1lbnQgPSBfcHJvbXB0X3JlY292ZXJfaW52YWxpZF9oZl90b2tlbigpCiAgICAgICAgICAgICAgICBpZiBhY3Rpb24gPT0gIm5ldy10b2tlbiIgYW5kIHJlcGxhY2VtZW50OgogICAgICAgICAgICAgICAgICAgIGF0dGVtcHRfdG9rZW4gPSByZXBsYWNlbWVudAogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgICAgICBhdHRlbXB0X3Rva2VuID0gTm9uZQogICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgcmFpc2UKCgpkZWYgZG93bmxvYWRfbW9kZWxfd2l0aF9mYWxsYmFjaygKICAgIHByZWZlcnJlZF9tb2RlbF9pZDogc3RyLAogICAgZmFsbGJhY2tfbW9kZWxfaWQ6IHN0ciwKICAgIGxvY2FsX2RpcjogUGF0aCwKICAgIHN0cmF0ZWdpZXM6IGxpc3RbTW9kZWxEb3dubG9hZFN0cmF0ZWd5XSB8IE5vbmUgPSBOb25lLAopIC0+IERvd25sb2FkU2VsZWN0aW9uOgogICAgIiIiCiAgICBUZW50YSBiYWl4YXIgYHByZWZlcnJlZF9tb2RlbF9pZGA7IHNlIGZhbGhhciBlbSB0b2RvcyBvcyBwcm92ZWRvcmVzLAogICAgdGVudGEgYGZhbGxiYWNrX21vZGVsX2lkYC4KICAgICIiIgogICAgYmFzZV9kaXIgPSBsb2NhbF9kaXIuZXhwYW5kdXNlcigpCiAgICBiYXNlX2Rpci5ta2RpcihwYXJlbnRzPVRydWUsIGV4aXN0X29rPVRydWUpCiAgICBwcm92aWRlcnMgPSBzdHJhdGVnaWVzIG9yIGJ1aWxkX2RlZmF1bHRfc3RyYXRlZ2llcygpCiAgICBlcnJvcnM6IGxpc3Rbc3RyXSA9IFtdCgogICAgZm9yIG1vZGVsX2lkIGluIChwcmVmZXJyZWRfbW9kZWxfaWQsIGZhbGxiYWNrX21vZGVsX2lkKToKICAgICAgICBtb2RlbF9sb2NhbF9kaXIgPSBfbW9kZWxfY2FjaGVfZGlyKGJhc2VfZGlyLCBtb2RlbF9pZCkKICAgICAgICBpZiBfY2FjaGVfcmVhZHkobW9kZWxfbG9jYWxfZGlyKToKICAgICAgICAgICAgcmV0dXJuIERvd25sb2FkU2VsZWN0aW9uKAogICAgICAgICAgICAgICAgbW9kZWxfaWQ9bW9kZWxfaWQsCiAgICAgICAgICAgICAgICBwcm92aWRlcj0ibG9jYWwtY2FjaGUiLAogICAgICAgICAgICAgICAgbG9jYWxfZGlyPW1vZGVsX2xvY2FsX2RpciwKICAgICAgICAgICAgKQoKICAgICAgICBmb3Igc3RyYXRlZ3kgaW4gcHJvdmlkZXJzOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBwcmludCgKICAgICAgICAgICAgICAgICAgICBmIlsrXSBJbmljaWFuZG8gZG93bmxvYWQgZG8gbW9kZWxvICd7bW9kZWxfaWR9JyB2aWEge3N0cmF0ZWd5Lm5hbWV9IGVtOiB7bW9kZWxfbG9jYWxfZGlyfSIsCiAgICAgICAgICAgICAgICAgICAgZmlsZT1zeXMuc3RkZXJyLAogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgX3ByZXBhcmVfZGVzdGluYXRpb24obW9kZWxfbG9jYWxfZGlyLCBjbGVhbj1UcnVlKQogICAgICAgICAgICAgICAgc3RyYXRlZ3kuZG93bmxvYWQobW9kZWxfaWQ9bW9kZWxfaWQsIGxvY2FsX2Rpcj1tb2RlbF9sb2NhbF9kaXIpCiAgICAgICAgICAgICAgICBfbWFya19jYWNoZV9yZWFkeShtb2RlbF9sb2NhbF9kaXIpCiAgICAgICAgICAgICAgICByZXR1cm4gRG93bmxvYWRTZWxlY3Rpb24oCiAgICAgICAgICAgICAgICAgICAgbW9kZWxfaWQ9bW9kZWxfaWQsCiAgICAgICAgICAgICAgICAgICAgcHJvdmlkZXI9c3RyYXRlZ3kubmFtZSwKICAgICAgICAgICAgICAgICAgICBsb2NhbF9kaXI9bW9kZWxfbG9jYWxfZGlyLAogICAgICAgICAgICAgICAgKQogICAgICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGV4YzoKICAgICAgICAgICAgICAgIGVycm9ycy5hcHBlbmQoZiJ7c3RyYXRlZ3kubmFtZX06e21vZGVsX2lkfToge2V4Y30iKQoKICAgIHJhaXNlIFJ1bnRpbWVFcnJvcigKICAgICAgICAiRmFsaGEgbm8gZG93bmxvYWQgZG9zIG1vZGVsb3MgZW0gdG9kb3Mgb3MgcHJvdmVkb3JlcyBjb25maWd1cmFkb3MuICIKICAgICAgICArICIgfCAiLmpvaW4oZXJyb3JzKQogICAgKQo="
|
|
730
730
|
B64_MODEL_DL_MS="IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwpmcm9tIF9fZnV0dXJlX18gaW1wb3J0IGFubm90YXRpb25zCgoiIiIKUHJvdmlkZXIgb3BjaW9uYWwgZGUgZG93bmxvYWQgdmlhIE1vZGVsU2NvcGUuClVzYWRvIGFwZW5hcyBzZSBvIHBhY290ZSBgbW9kZWxzY29wZWAgZXN0aXZlciBpbnN0YWxhZG8uCiIiIgoKZnJvbSBwYXRobGliIGltcG9ydCBQYXRoCgoKY2xhc3MgTW9kZWxTY29wZURvd25sb2FkU3RyYXRlZ3k6CiAgICBuYW1lID0gIm1vZGVsc2NvcGUiCgogICAgZGVmIGRvd25sb2FkKHNlbGYsIG1vZGVsX2lkOiBzdHIsIGxvY2FsX2RpcjogUGF0aCkgLT4gTm9uZToKICAgICAgICB0cnk6CiAgICAgICAgICAgIGZyb20gbW9kZWxzY29wZS5odWIuc25hcHNob3RfZG93bmxvYWQgaW1wb3J0IHNuYXBzaG90X2Rvd25sb2FkCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBleGM6CiAgICAgICAgICAgIHJhaXNlIFJ1bnRpbWVFcnJvcigKICAgICAgICAgICAgICAgICJQYWNvdGUgYG1vZGVsc2NvcGVgIGluZGlzcG9uw612ZWwgcGFyYSBwcm92aWRlciBhbHRlcm5hdGl2byIKICAgICAgICAgICAgKSBmcm9tIGV4YwoKICAgICAgICBzbmFwc2hvdF9kb3dubG9hZCgKICAgICAgICAgICAgbW9kZWxfaWQ9bW9kZWxfaWQsCiAgICAgICAgICAgIGxvY2FsX2Rpcj1zdHIobG9jYWxfZGlyKSwKICAgICAgICApCg=="
|
|
731
731
|
|
|
@@ -1104,6 +1104,11 @@ if command -v codex &>/dev/null || [[ -d "${USER_HOME}/.codex" ]]; then
|
|
|
1104
1104
|
fi
|
|
1105
1105
|
|
|
1106
1106
|
configure_codex_mcp() {
|
|
1107
|
+
if check_codex_mcp_up_to_date; then
|
|
1108
|
+
echo "ok:already_exists"
|
|
1109
|
+
return 0
|
|
1110
|
+
fi
|
|
1111
|
+
|
|
1107
1112
|
if command -v codex &>/dev/null; then
|
|
1108
1113
|
codex mcp remove rag-codebase >/dev/null 2>&1 || true
|
|
1109
1114
|
if codex mcp add rag-codebase \
|
|
@@ -1317,7 +1322,7 @@ PYEOF
|
|
|
1317
1322
|
fi
|
|
1318
1323
|
done
|
|
1319
1324
|
|
|
1320
|
-
if [[ "${CODEX_APP_INSTALLED}" == "true" ]]
|
|
1325
|
+
if [[ "${CODEX_APP_INSTALLED}" == "true" ]]; then
|
|
1321
1326
|
PENDING_CONFIGS+=("${CODEX_CONFIG_TOML}")
|
|
1322
1327
|
PENDING_LABELS+=("Codex")
|
|
1323
1328
|
fi
|