wherdr 1.3.2 → 1.3.3
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/.output/nitro.json +1 -1
- package/.output/public/_nuxt/{AgentView.C4YOwvZG.css → AgentView.DzFWBd2A.css} +1 -1
- package/.output/public/_nuxt/B4Yk2tB1.js +23 -0
- package/.output/public/_nuxt/BBw_0a4M.js +6 -0
- package/.output/public/_nuxt/{D7sxNXx1.js → BSy6OCIY.js} +1 -1
- package/.output/public/_nuxt/BX5PM2JQ.js +1 -0
- package/.output/public/_nuxt/BgPDnf2S.js +1 -0
- package/.output/public/_nuxt/BkOxQzbS.js +2 -0
- package/.output/public/_nuxt/{8ksjcuDu.js → CKhgznq4.js} +45 -56
- package/.output/public/_nuxt/{Cd8j9O5w.js → CP8o925U.js} +1 -1
- package/.output/public/_nuxt/CkbmecwS.js +1 -0
- package/.output/public/_nuxt/Cr3SrGky.js +1 -0
- package/.output/public/_nuxt/DAg9fiVh.js +89 -0
- package/.output/public/_nuxt/DT8qZ0Wv.js +1 -0
- package/.output/public/_nuxt/DaaJIRB3.js +1 -0
- package/.output/public/_nuxt/{DViwOclv.js → DcJi16XA.js} +1 -1
- package/.output/public/_nuxt/VpjCgSXu.js +36 -0
- package/.output/public/_nuxt/builds/latest.json +1 -1
- package/.output/public/_nuxt/builds/meta/c735b6c0-1bd0-47d7-a208-d310f0a06287.json +1 -0
- package/.output/public/_nuxt/dPxB2L94.js +89 -0
- package/.output/public/_nuxt/{entry.Crt1r4l3.css → entry.CGWKmYU3.css} +1 -1
- package/.output/public/_nuxt/xYX85SPI.js +1 -0
- package/.output/public/sw.js +1 -1
- package/.output/server/chunks/_/branding.mjs +1 -1
- package/.output/server/chunks/_/filePaths.mjs +25 -0
- package/.output/server/chunks/_/files.mjs +204 -0
- package/.output/server/chunks/_/machineOrder.mjs +1 -1
- package/.output/server/chunks/_/onboarding.mjs +1 -1
- package/.output/server/chunks/_/package.mjs +3 -2
- package/.output/server/chunks/_/pluginPolicy.mjs +93 -0
- package/.output/server/chunks/_/plugins.mjs +4 -94
- package/.output/server/chunks/_/projectBoard.mjs +120 -29
- package/.output/server/chunks/_/projectDocs.mjs +106 -0
- package/.output/server/chunks/_/projectInbox.mjs +135 -0
- package/.output/server/chunks/_/projectThreads.mjs +46 -0
- package/.output/server/chunks/_/projectThreads2.mjs +61 -0
- package/.output/server/chunks/_/projectsActions.mjs +1 -1
- package/.output/server/chunks/_/projectsPlugin.mjs +1 -1
- package/.output/server/chunks/_/restart.mjs +2 -312
- package/.output/server/chunks/_/reveal.mjs +2 -24
- package/.output/server/chunks/_/selfupdate.mjs +3 -2
- package/.output/server/chunks/_/updates.mjs +51 -10
- package/.output/server/chunks/_/worktrees.mjs +1 -1
- package/.output/server/chunks/_/ws.mjs +1 -1
- package/.output/server/chunks/nitro/nitro.mjs +1096 -268
- package/.output/server/chunks/raw/bump-homebrew.mjs +1 -1
- package/.output/server/chunks/raw/herdr-plugin.mjs +1 -1
- package/.output/server/chunks/raw/release-ready.mjs +5 -0
- package/.output/server/chunks/routes/api/_..._.mjs +1 -1
- package/.output/server/chunks/routes/api/agents.post.mjs +1 -1
- package/.output/server/chunks/routes/api/ask-tab.post.mjs +1 -1
- package/.output/server/chunks/routes/api/attach.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/disable.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/lock-all.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/lock.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/login/options.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/login/verify.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/max-session.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/register/options.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/register/verify.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/status.get.mjs +1 -1
- package/.output/server/chunks/routes/api/board.get.mjs +147 -0
- package/.output/server/chunks/routes/api/changes.get.mjs +2 -2
- package/.output/server/chunks/routes/api/chat/image.get.mjs +2 -2
- package/.output/server/chunks/routes/api/chat.get.mjs +2 -2
- package/.output/server/chunks/routes/api/choose.post.mjs +29 -3
- package/.output/server/chunks/routes/api/claude-statusline.post.mjs +2 -2
- package/.output/server/chunks/routes/api/close/status.get.mjs +2 -2
- package/.output/server/chunks/routes/api/close.post.mjs +1 -1
- package/.output/server/chunks/routes/api/codex-update.post.mjs +2 -2
- package/.output/server/chunks/routes/api/commands.get.mjs +2 -2
- package/.output/server/chunks/routes/api/config.get.mjs +3 -2
- package/.output/server/chunks/routes/api/dirs.get.mjs +2 -2
- package/.output/server/chunks/routes/api/dismiss-stopped.post.mjs +43 -0
- package/.output/server/chunks/routes/api/dismiss.post.mjs +2 -2
- package/.output/server/chunks/routes/api/effort.post.mjs +2 -2
- package/.output/server/chunks/routes/api/efforts.get.mjs +2 -2
- package/.output/server/chunks/routes/api/file.post.mjs +2 -2
- package/.output/server/chunks/routes/api/files/download.get.mjs +53 -0
- package/.output/server/chunks/routes/api/files/read.get.mjs +45 -0
- package/.output/server/chunks/routes/api/files.get.mjs +44 -0
- package/.output/server/chunks/routes/api/gitroot.get.mjs +2 -2
- package/.output/server/chunks/routes/api/health.get.mjs +1 -1
- package/.output/server/chunks/routes/api/index.get.mjs +1 -1
- package/.output/server/chunks/routes/api/input.post.mjs +13 -3
- package/.output/server/chunks/routes/api/interrupt.post.mjs +2 -2
- package/.output/server/chunks/routes/api/isgit.get.mjs +2 -2
- package/.output/server/chunks/routes/api/machine/awake.get.mjs +2 -2
- package/.output/server/chunks/routes/api/machine/awake.post.mjs +2 -2
- package/.output/server/chunks/routes/api/machine/order.get.mjs +1 -1
- package/.output/server/chunks/routes/api/machine/order.post.mjs +1 -1
- package/.output/server/chunks/routes/api/machine/rename.post.mjs +2 -2
- package/.output/server/chunks/routes/api/menu.post.mjs +2 -2
- package/.output/server/chunks/routes/api/model.post.mjs +2 -2
- package/.output/server/chunks/routes/api/models.get.mjs +2 -2
- package/.output/server/chunks/routes/api/nav.post.mjs +5 -4
- package/.output/server/chunks/routes/api/onboarding.get.mjs +1 -1
- package/.output/server/chunks/routes/api/onboarding.post.mjs +1 -1
- package/.output/server/chunks/routes/api/phone.get.mjs +2 -2
- package/.output/server/chunks/routes/api/phone.post.mjs +2 -2
- package/.output/server/chunks/routes/api/plugins/actions.get.mjs +2 -1
- package/.output/server/chunks/routes/api/plugins/invoke.post.mjs +2 -1
- package/.output/server/chunks/routes/api/plugins/profiles.get.mjs +2 -1
- package/.output/server/chunks/routes/api/plugins/projects.get.mjs +2 -2
- package/.output/server/chunks/routes/api/plugins/projects.post.mjs +2 -2
- package/.output/server/chunks/routes/api/plugins/thread-limits.get.mjs +2 -2
- package/.output/server/chunks/routes/api/plugins/thread-limits.post.mjs +2 -2
- package/.output/server/chunks/routes/api/project/inbox.get.mjs +43 -0
- package/.output/server/chunks/routes/api/project/inbox.post.mjs +43 -0
- package/.output/server/chunks/routes/api/project/memory.get.mjs +42 -0
- package/.output/server/chunks/routes/api/project/report.get.mjs +2 -2
- package/.output/server/chunks/routes/api/project/routines.get.mjs +43 -0
- package/.output/server/chunks/routes/api/project/settings.get.mjs +41 -0
- package/.output/server/chunks/routes/api/project/thread.get.mjs +44 -0
- package/.output/server/chunks/routes/api/project/thread.post.mjs +45 -0
- package/.output/server/chunks/routes/api/prompt.post.mjs +21 -3
- package/.output/server/chunks/routes/api/push/quiet.post.mjs +2 -2
- package/.output/server/chunks/routes/api/push/subscribe.post.mjs +2 -2
- package/.output/server/chunks/routes/api/push/test.post.mjs +2 -2
- package/.output/server/chunks/routes/api/push/unsubscribe.post.mjs +2 -2
- package/.output/server/chunks/routes/api/quotas.get.mjs +2 -2
- package/.output/server/chunks/routes/api/rename.post.mjs +1 -1
- package/.output/server/chunks/routes/api/requeue.post.mjs +2 -2
- package/.output/server/chunks/routes/api/restart.get.mjs +1 -1
- package/.output/server/chunks/routes/api/restart.post.mjs +1 -1
- package/.output/server/chunks/routes/api/reveal.post.mjs +2 -1
- package/.output/server/chunks/routes/api/screen-key.post.mjs +2 -2
- package/.output/server/chunks/routes/api/screen.get.mjs +5 -3
- package/.output/server/chunks/routes/api/search.get.mjs +2 -2
- package/.output/server/chunks/routes/api/seen.post.mjs +2 -2
- package/.output/server/chunks/routes/api/sessions.get.mjs +2 -2
- package/.output/server/chunks/routes/api/sessions.post.mjs +2 -2
- package/.output/server/chunks/routes/api/space.post.mjs +14 -14
- package/.output/server/chunks/routes/api/state.get.mjs +2 -2
- package/.output/server/chunks/routes/api/unqueue.post.mjs +2 -2
- package/.output/server/chunks/routes/api/update/status.get.mjs +1 -1
- package/.output/server/chunks/routes/api/update.get.mjs +2 -2
- package/.output/server/chunks/routes/api/update.post.mjs +2 -2
- package/.output/server/chunks/routes/api/upload.post.mjs +2 -2
- package/.output/server/chunks/routes/api/worktrees/remove.post.mjs +1 -1
- package/.output/server/chunks/routes/api/worktrees.get.mjs +1 -1
- package/.output/server/chunks/routes/favicon.ico.get.mjs +1 -1
- package/.output/server/chunks/routes/icons/_name_.get.mjs +2 -2
- package/.output/server/chunks/routes/renderer.mjs +3 -3
- package/.output/server/chunks/routes/uploads/_...name_.get.mjs +2 -2
- package/.output/server/chunks/routes/ws/_..._.mjs +2 -2
- package/.output/server/chunks/routes/ws/events.mjs +2 -2
- package/.output/server/chunks/routes/ws/term.mjs +2 -2
- package/.output/server/chunks/virtual/precomputed.mjs +1 -1
- package/.output/server/index.mjs +2 -2
- package/.output/server/package.json +1 -1
- package/README.md +332 -25
- package/bin/install-docker-skill.sh +20 -0
- package/bin/lib/commands.mjs +5 -1
- package/bin/lib/core.mjs +1 -0
- package/bin/lib/install-skill.sh +100 -0
- package/bin/lib/skill.mjs +16 -0
- package/bin/lib/updater.mjs +65 -12
- package/bin/lib/verify-release.mjs +20 -0
- package/package.json +3 -2
- package/skills/wherdr/SKILL.md +180 -0
- package/.output/public/_nuxt/B7QP1TFs.js +0 -23
- package/.output/public/_nuxt/BDNMzG2s.js +0 -1
- package/.output/public/_nuxt/BOpBIziZ.js +0 -6
- package/.output/public/_nuxt/BWXdFfeg.js +0 -17
- package/.output/public/_nuxt/COFCNFpG.js +0 -83
- package/.output/public/_nuxt/CXG-cOdh.js +0 -1
- package/.output/public/_nuxt/CkZ8t6uB.js +0 -1
- package/.output/public/_nuxt/D4Yz4rat.js +0 -65
- package/.output/public/_nuxt/DoD7Qb5P.js +0 -30
- package/.output/public/_nuxt/DyBZDSCV.js +0 -2
- package/.output/public/_nuxt/bLP7Jj-b.js +0 -1
- package/.output/public/_nuxt/builds/meta/7afbf062-5369-4002-b20d-7a582ff6e0f1.json +0 -1
- package/.output/server/chunks/routes/ws/mirror.mjs +0 -161
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { b as base64ToUint8Array } from '../virtual/_raw-helpers.mjs';
|
|
2
2
|
|
|
3
3
|
// ROLLUP_NO_REPLACE
|
|
4
|
-
const bumpHomebrew = base64ToUint8Array("IyEvYmluL3NoCiMgUG9pbnRzIHRoZSBIb21lYnJldyBmb3JtdWxhICg8b3duZXI+
|
|
4
|
+
const bumpHomebrew = base64ToUint8Array("IyEvYmluL3NoCiMgUG9pbnRzIHRoZSBIb21lYnJldyBmb3JtdWxhICg8b3duZXI+L2hvbWVicmV3LXRhcCwgRm9ybXVsYS93aGVyZHIucmIpIGF0IGEKIyB2ZXJzaW9uIGFscmVhZHkgcHVibGlzaGVkIG9uIEdpdEh1Yi4gTWFudWFsIGZhbGxiYWNrIGZvciB0aGUgYGhvbWVicmV3YCBqb2Igb2YKIyAuZ2l0aHViL3dvcmtmbG93cy9yZWxlYXNlLnltbCB3aGVuIHRoZSBIT01FQlJFV19UQVBfVE9LRU4gc2VjcmV0IGlzIG1pc3NpbmcuCiMgVXNlcyB0aGUgR2l0SHViIENMSSBhdXRoZW50aWNhdGlvbiAoYGdoIGF1dGggbG9naW5gKSB0byBjbG9uZSBhbmQgcHVzaC4KIwojICAgc2NyaXB0cy9idW1wLWhvbWVicmV3LnNoIFt2ZXJzaW9uXSBbb3duZXJdCiMKIyB2ZXJzaW9uIGRlZmF1bHRzIHRvIHBhY2thZ2UuanNvbidzLCBvd25lciB0byB0aGUgb3duZXIgb2YgdGhpcyBjaGVja291dCdzIEdpdEh1YiByZXBvLgpzZXQgLWV1CgpjZCAiJChkaXJuYW1lICIkMCIpLy4uIgp2ZXJzaW9uPSR7MTotJChub2RlIC1wICdyZXF1aXJlKCIuL3BhY2thZ2UuanNvbiIpLnZlcnNpb24nIDI+L2Rldi9udWxsIHx8IHNlZCAtbiAncy9eICAidmVyc2lvbiI6ICJcKC4qXCkiLCQvXDEvcCcgcGFja2FnZS5qc29uKX0Kb3duZXI9JHsyOi0kKGdoIHJlcG8gdmlldyAtLWpzb24gb3duZXIgLXEgLm93bmVyLmxvZ2luKX0KdXJsPSJodHRwczovL2dpdGh1Yi5jb20vJHtvd25lcn0vd2hlcmRyL3JlbGVhc2VzL2Rvd25sb2FkL3Yke3ZlcnNpb259L3doZXJkci0ke3ZlcnNpb259LnRneiIKCnRtcD0kKG1rdGVtcCAtZCkKdHJhcCAncm0gLXJmICIkdG1wIicgRVhJVAoKY3VybCAtZnNTTCAiJHVybCIgLW8gIiR0bXAvd2hlcmRyLnRneiIgfHwgeyBlY2hvICJ3aGVyZHJAJHt2ZXJzaW9ufSBpcyBub3Qgb24gR2l0SHViIHlldCAoJHVybCkiID4mMjsgZXhpdCAxOyB9CmlmIGNvbW1hbmQgLXYgc2hhMjU2c3VtID4vZGV2L251bGw7IHRoZW4KICBzaGE9JChzaGEyNTZzdW0gIiR0bXAvd2hlcmRyLnRneiIgfCBjdXQgLWQnICcgLWYxKQplbHNlCiAgc2hhPSQoc2hhc3VtIC1hIDI1NiAiJHRtcC93aGVyZHIudGd6IiB8IGN1dCAtZCcgJyAtZjEpCmZpCmN1cmwgLWZzU0wgIiR1cmwuc2hhMjU2IiAtbyAiJHRtcC9jaGVja3N1bSIKZXhwZWN0ZWQ9JChjdXQgLWQnICcgLWYxICIkdG1wL2NoZWNrc3VtIikKWyAiJHNoYSIgPSAiJGV4cGVjdGVkIiBdIHx8IHsgZWNobyAiUmVsZWFzZSBTSEEtMjU2IG1pc21hdGNoIiA+JjI7IGV4aXQgMTsgfQpbIC1uICIkc2hhIiBdIHx8IHsgZWNobyAiQ291bGQgbm90IGNvbXB1dGUgc2hhMjU2IiA+JjI7IGV4aXQgMTsgfQoKZ2ggcmVwbyBjbG9uZSAiJHtvd25lcn0vaG9tZWJyZXctdGFwIiAiJHRtcC90YXAiIC0tIC1xCmNkICIkdG1wL3RhcCIKc2VkIC1FICJzfF4gIHVybCBcIi4qXCJ8ICB1cmwgXCIke3VybH1cInw7IHN8XiAgc2hhMjU2IFwiLipcInwgIHNoYTI1NiBcIiR7c2hhfVwifCIgRm9ybXVsYS93aGVyZHIucmIgPiBGb3JtdWxhL3doZXJkci5yYi5uZXcKbXYgRm9ybXVsYS93aGVyZHIucmIubmV3IEZvcm11bGEvd2hlcmRyLnJiCmlmIGdpdCBkaWZmIC0tcXVpZXQ7IHRoZW4gZWNobyAiRm9ybXVsYSBhbHJlYWR5IGF0ICR7dmVyc2lvbn0uIjsgZXhpdCAwOyBmaQojIFNjb3BlIHRoZSBhdXRoZW50aWNhdGVkIG93bmVyJ3MgcHVibGljIGlkZW50aXR5IHRvIHRoaXMgdGVtcG9yYXJ5IGNsb25lLgpsb2dpbj0kKGdoIGFwaSB1c2VyIC0tanEgLmxvZ2luKQp1c2VyX2lkPSQoZ2ggYXBpIHVzZXIgLS1qcSAuaWQpCm5hbWU9JChnaCBhcGkgdXNlciAtLWpxICcubmFtZSAvLyAubG9naW4nKQpbIC1uICIkbG9naW4iIF0gJiYgWyAtbiAiJG5hbWUiIF0gfHwgeyBlY2hvICJNaXNzaW5nIEdpdEh1YiBpZGVudGl0eSIgPiYyOyBleGl0IDE7IH0KY2FzZSAiJHVzZXJfaWQiIGluICcnfCpbITAtOV0qKSBlY2hvICJJbnZhbGlkIEdpdEh1YiB1c2VyIGlkIiA+JjI7IGV4aXQgMSA7OyBlc2FjCmdpdCBjb25maWcgLS1sb2NhbCB1c2VyLm5hbWUgIiRuYW1lIgpnaXQgY29uZmlnIC0tbG9jYWwgdXNlci5lbWFpbCAiJHt1c2VyX2lkfSske2xvZ2lufUB1c2Vycy5ub3JlcGx5LmdpdGh1Yi5jb20iCmdpdCBkaWZmCmdpdCBjb21taXQgLXFhbSAid2hlcmRyICR7dmVyc2lvbn0iCmdpdCBwdXNoIC1xCmVjaG8gIkZvcm11bGEvd2hlcmRyLnJiIG5vdyBwb2ludHMgYXQgd2hlcmRyICR7dmVyc2lvbn0gKHNoYTI1NiAke3NoYX0pLiIK");
|
|
5
5
|
|
|
6
6
|
export { bumpHomebrew as default };
|
|
7
7
|
//# sourceMappingURL=bump-homebrew.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { b as base64ToUint8Array } from '../virtual/_raw-helpers.mjs';
|
|
2
2
|
|
|
3
3
|
// ROLLUP_NO_REPLACE
|
|
4
|
-
const herdrPlugin = base64ToUint8Array("IyEvYmluL3NoCiMgd2hlcmRyIGFzIGEgSGVyZHIgcGx1Z2luIChoZXJkci1wbHVnaW4udG9tbCk6IGJ1aWxkIChpbnN0YWxsICsgZmlyc3Qgc3RhcnQpLAojIHRoZSBwYW5lbCwgc3RhcnQsIHN0b3AsIHN0YXR1cywgb3BlbiwgdXBkYXRlLCBzZXJ2aWNlLCBza2lsbCwga2V5LgojCiMgICBoZXJkciBwbHVnaW4gaW5zdGFsbCA8b3duZXI+L3doZXJkcgojCiMgVHdvIHdheXMgdG8gcnVuIHdoZXJkciwgcGlja2VkIG9uY2UgYXQgaW5zdGFsbCB0aW1lIGFuZCBrZXB0IGluCiMgJFdIRVJEUl9ESVIvcGx1Z2luLmVudjoKIyAgIGRvY2tlciAgTGludXggd2l0aCBEb2NrZXIgQ29tcG9zZSB2MiB1c2FibGUgYnkgdGhpcyB1c2VyOiB0aGUgcHVibGlzaGVkCiMgICAgICAgICAgIGltYWdlLCBydW4gZnJvbSAkV0hFUkRSX0RJUiBleGFjdGx5IGxpa2UgaHR0cHM6Ly93aGVyZHIuZGV2L2luc3RhbGwuCiMgICBuYXRpdmUgIGV2ZXJ5d2hlcmUgZWxzZSAoYWx3YXlzIG9uIG1hY09TOiBEb2NrZXIgRGVza3RvcCBjYW5ub3QgcmVhY2gKIyAgICAgICAgICAgSGVyZHIncyBVbml4IHNvY2tldCk6IE5vZGUuanMgMjIgKG9yIEJ1bikgcnVucyB0aGUgcHJlYnVpbHQgbnBtCiMgICAgICAgICAgIHBhY2thZ2Ugb2YgdGhpcyB2ZXJzaW9uIChvciBhIGJ1aWxkIG1hZGUgaW4gdGhlIHBsdWdpbiBmb2xkZXIpLAojICAgICAgICAgICBjb3BpZWQgdG8gJFdIRVJEUl9ESVIvYXBwIGFuZCBzdGFydGVkIGRldGFjaGVkIGZyb20gdGhlcmUsIHdpdGgKIyAgICAgICAgICAgaXRzIHBpZCBhbmQgbG9nIGluICRXSEVSRFJfRElSLgojIEhlcmRyIGJ1aWxkcyBhIHBsdWdpbiBpbiBhIHRlbXBvcmFyeSBmb2xkZXIsIHRoZW4gbW92ZXMgaXQ6IGEgc2VydmVyIHN0YXJ0ZWQKIyBmcm9tIHRoZSBjaGVja291dCBkdXJpbmcgdGhlIGJ1aWxkIHdvdWxkIGxvc2UgaXRzIGZpbGVzLiAkV0hFUkRSX0RJUi9hcHAKIyBzdGF5cyBwdXQsIGFjcm9zcyBwbHVnaW4gdXBkYXRlcyB0b28sIHNvIHRoZSBidWlsZCBjYW4gc3RhcnQgd2hlcmRyIGFuZCBhCiMgbG9naW4gc2VydmljZSBjYW4gcG9pbnQgYXQgaXQuCiMgV0hFUkRSX01PREU9bmF0aXZlIChvciBkb2NrZXIpIGluIHRoZSBlbnZpcm9ubWVudCBvZiBgaGVyZHIgcGx1Z2luIGluc3RhbGxgCiMgZm9yY2VzIHRoZSBjaG9pY2U7IGVkaXQgcGx1Z2luLmVudiB0byBjaGFuZ2UgaXQgbGF0ZXIsIHRoZW4gcnVuIFVwZGF0ZS4KIwojIFNhZmV0eSBydWxlczoKIyAgIC0gbm90aGluZyBnbG9iYWwgaXMgaW5zdGFsbGVkLCBubyBzdWRvOyBmaWxlcyBhcmUgb25seSB3cml0dGVuIHRvIHRoZQojICAgICBwbHVnaW4gZm9sZGVyIGFuZCAkV0hFUkRSX0RJUiAoZGVmYXVsdCB+L3doZXJkciksIHBsdXMgdGhlIGZvbGRlcnMgdGhlCiMgICAgIERvY2tlciBzZXR1cCBtb3VudHMgKH4vLmNvbmZpZy9oZXJkciwgfi8uY2FjaGUvaGVyZHItd2Vi4oCmKSwgYW5kIHRoZQojICAgICBsb2dpbiBzZXJ2aWNlIG9ubHkgd2hlbiBhc2tlZCAoa2V5IEEgb2YgdGhlIHBhbmVsKSwgcGx1cyBhICJ3aGVyZHIiCiMgICAgIGxpbmsgaW4gdGhlIGFnZW50cycgdXNlciBza2lsbCBmb2xkZXJzIChzZWUgY21kX3NraWxsKSwgcGx1cyBvbmUgbWFya2VkCiMgICAgIGJsb2NrIGFwcGVuZGVkIHRvIEhlcmRyJ3MgY29uZmlnLnRvbWw6IHRoZSBrZXkgdGhhdCBvcGVucyB0aGUgcGFuZWwKIyAgICAgKHNlZSBjbWRfa2V5KTsKIyAgIC0gdGhlIGluc3RhbGwgc3RhcnRzIHdoZXJkciwgYW5kIEhlcmRyJ3Mgc3RhcnR1cCBob29rIHN0YXJ0cyBpdCBhZ2FpbiwKIyAgICAgYnV0IG9ubHkgd2hlbiBub3RoaW5nIGFuc3dlcnMgb24gdGhlIHBvcnQ6IGEgd2hlcmRyIHN0YXJ0ZWQgYW5vdGhlciB3YXkKIyAgICAgKERvY2tlciwgc3lzdGVtZCwgYnkgaGFuZCkgaXMgbmV2ZXIgdG91Y2hlZCwgbm8gc2Vjb25kIHdoZXJkciBpcyBzdGFydGVkOwojICAgLSBzdG9wIG9ubHkgc3RvcHMgd2hhdCB0aGlzIHBsdWdpbiBzdGFydGVkIChpdHMgcGlkLCBpdHMgbG9naW4gc2VydmljZSwgb3IKIyAgICAgdGhlIGNvbnRhaW5lciBvZiBpdHMgb3duIGNvbXBvc2UgZm9sZGVyKS4KIwojIFVuaW5zdGFsbDogSGVyZHIgaGFzIG5vIHVuaW5zdGFsbCBob29rLiBTdG9wIHdoZXJkciAoYW5kIHJlbW92ZSB0aGUgbG9naW4KIyBzZXJ2aWNlKSBmcm9tIHRoZSBwYW5lbCBmaXJzdCwgdGhlbjoKIyAgIHNoIHNjcmlwdHMvaGVyZHItcGx1Z2luLnNoIHNraWxsIHVuaW5zdGFsbCAgIChpbiB0aGUgcGx1Z2luIGZvbGRlcikKIyAgIHNoIHNjcmlwdHMvaGVyZHItcGx1Z2luLnNoIGtleSB1bmluc3RhbGwgICAgICh0aGUgSGVyZHIga2V5IG9mIHRoZSBwYW5lbCkKIyAgIGhlcmRyIHBsdWdpbiB1bmluc3RhbGwgPG93bmVyPi53aGVyZHIgJiYgcm0gLXJmIH4vd2hlcmRyCiMKIyBTZXR0aW5ncyAoJFdIRVJEUl9ESVIvcGx1Z2luLmVudiwgb3IgdGhlIGVudmlyb25tZW50KToKIyAgIFdIRVJEUl9NT0RFICBkb2NrZXIgfCBuYXRpdmUgICAgICAgIChkZWZhdWx0OiBjaG9zZW4gYXQgaW5zdGFsbCkKIyAgIFdIRVJEUl9QT1JUICBsb2NhbCBwb3J0ICAgICAgICAgICAgICAoZGVmYXVsdDogNzY4MykKIyAgIEFQUF9VUkwgICAgICBwcml2YXRlIEhUVFBTIGFkZHJlc3MgICAobmF0aXZlOyBEb2NrZXIgcmVhZHMgaXRzIC5lbnYpCiMgICBXSEVSRFJfUlVOVElNRSAgYWJzb2x1dGUgcGF0aCBvZiBub2RlIC8gYnVuIChuYXRpdmU7IGZvdW5kIGF0IGluc3RhbGwpCgpzZXQgLWV1CgpST09UPSIkKGNkICIkKGRpcm5hbWUgIiQwIikvLi4iICYmIHB3ZCAtUCkiCiMgQnVpbGQgY29tbWFuZHMgZ2V0IG5vIHBsdWdpbiBlbnZpcm9ubWVudDogdGhlIGZvbGRlciBjaG9zZW4gYXQgaW5zdGFsbAojIHRpbWUgaXMgcmVtZW1iZXJlZCBpbiB0aGUgcGx1Z2luIGNoZWNrb3V0IGZvciB0aGUgcnVudGltZSBjb21tYW5kcy4KaWYgWyAteiAiJHtXSEVSRFJfRElSOi19IiBdICYmIFsgLWYgIiRST09ULy53aGVyZHItZGlyIiBdOyB0aGVuCiAgV0hFUkRSX0RJUj0iJChjYXQgIiRST09ULy53aGVyZHItZGlyIikiCmZpCkRJUj0iJHtXSEVSRFJfRElSOi0kSE9NRS93aGVyZHJ9IgpDT05GPSIkRElSL3BsdWdpbi5lbnYiCiMgTmF0aXZlIG1vZGU6IHRoZSBpbnN0YWxsZWQgY29weSBvZiB3aGVyZHIgKGJpbiArIGJ1aWx0IHNlcnZlcikuCkFQUD0iJERJUi9hcHAiCiMgR2l0SHViIHNvdXJjZSBvZiB0aGlzIHBsdWdpbjogaXRzIG1hbmlmZXN0IGlkIHdpdGggIi8iIGZvciAiLiIgKG93bmVyLndoZXJkcikuClNPVVJDRT0iJChzZWQgLW4gJ3MvXmlkID0gIlwoLipcKSIkL1wxL3AnICIkUk9PVC9oZXJkci1wbHVnaW4udG9tbCIgfCBoZWFkIC1uIDEgfCB0ciAuIC8pIgojIGNvbnRhaW5lcl9uYW1lIG9mIHRoZSBjb21wb3NlIGZpbGUgKHdoZXJkciB1bmxlc3MgeW91IHJlbmFtZWQgaXQpLgpDT05UQUlORVI9IiQoc2VkIC1uICdzL14gKmNvbnRhaW5lcl9uYW1lOiAqLy9wJyAiJERJUi9kb2NrZXItY29tcG9zZS55bWwiIDI+L2Rldi9udWxsIHwgaGVhZCAtbiAxKSIKQ09OVEFJTkVSPSIke0NPTlRBSU5FUjotd2hlcmRyfSIKIyBUaGUgZW52aXJvbm1lbnQgd2lucyBvdmVyIHBsdWdpbi5lbnYuCkVOVl9NT0RFPSIke1dIRVJEUl9NT0RFOi19IiBFTlZfUE9SVD0iJHtXSEVSRFJfUE9SVDotfSIgRU5WX0FQUF9VUkw9IiR7QVBQX1VSTDotfSIgRU5WX1JVTlRJTUU9IiR7V0hFUkRSX1JVTlRJTUU6LX0iCmlmIFsgLWYgIiRDT05GIiBdOyB0aGVuCiAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MxMDkwCiAgLiAiJENPTkYiCmZpCk1PREU9IiR7RU5WX01PREU6LSR7V0hFUkRSX01PREU6LX19IgpQT1JUPSIke0VOVl9QT1JUOi0ke1dIRVJEUl9QT1JUOi03NjgzfX0iCkFQUF9VUkw9IiR7RU5WX0FQUF9VUkw6LSR7QVBQX1VSTDotfX0iCiMgTmF0aXZlIG1vZGU6IGFic29sdXRlIHBhdGggb2YgdGhlIG5vZGUgKG9yIGJ1bikgdGhhdCBydW5zIHRoZSBzZXJ2ZXIuIEhlcmRyCiMgcnVucyBhY3Rpb25zIHdpdGggaXRzIHNlcnZlcidzIFBBVEgsIHdoaWNoIG9mdGVuIGxhY2tzIG52bSAvIG4gLyBmbm0gZm9sZGVycy4KUlVOVElNRT0iJHtFTlZfUlVOVElNRTotJHtXSEVSRFJfUlVOVElNRTotfX0iClVSTD0iaHR0cDovL2xvY2FsaG9zdDokUE9SVCIKCnNheSgpIHsgcHJpbnRmICclc1xuJyAiJCoiOyB9Cm9rKCkgeyBwcmludGYgJyAg4pyTICVzXG4nICIkKiI7IH0Kd2FybigpIHsgcHJpbnRmICcgICEgJXNcbicgIiQqIiA+JjI7IH0KZGllKCkgeyBwcmludGYgJyAg4pyXICVzXG4nICIkKiIgPiYyOyBleGl0IDE7IH0KCiMgQW55IEhUVFAgYW5zd2VyIGNvdW50cyAoYSBsb2NrZWQgd2hlcmRyIGFuc3dlcnMgNDAxKTogdGhlIHBvcnQgaXMgdGFrZW4uCmFuc3dlcnMoKSB7CiAgaWYgY29tbWFuZCAtdiBjdXJsID4vZGV2L251bGwgMj4mMTsgdGhlbgogICAgY29kZT0iJChjdXJsIC1zIC1vIC9kZXYvbnVsbCAtLW1heC10aW1lIDIgLXcgJyV7aHR0cF9jb2RlfScgImh0dHA6Ly8xMjcuMC4wLjE6JFBPUlQvIiAyPi9kZXYvbnVsbCB8fCB0cnVlKSIKICAgIFsgLW4gIiRjb2RlIiBdICYmIFsgIiRjb2RlIiAhPSAiMDAwIiBdCiAgZWxpZiBjb21tYW5kIC12IG5jID4vZGV2L251bGwgMj4mMTsgdGhlbgogICAgbmMgLXogMTI3LjAuMC4xICIkUE9SVCIgPi9kZXYvbnVsbCAyPiYxCiAgZWxzZQogICAgZGllICJjdXJsIG9yIG5jIGlzIG5lZWRlZCB0byBjaGVjayBwb3J0ICRQT1JULiIKICBmaQp9Cgpkb2NrZXJfdXNhYmxlKCkgewogIFsgIiQodW5hbWUgLXMpIiA9ICJMaW51eCIgXSB8fCByZXR1cm4gMQogIGNvbW1hbmQgLXYgZG9ja2VyID4vZGV2L251bGwgMj4mMSB8fCByZXR1cm4gMQogIGRvY2tlciBjb21wb3NlIHZlcnNpb24gPi9kZXYvbnVsbCAyPiYxIHx8IHJldHVybiAxCiAgZG9ja2VyIGluZm8gPi9kZXYvbnVsbCAyPiYxCn0KCiMgTWFqb3IgdmVyc2lvbiBvZiBhIG5vZGUgYmluYXJ5LCAwIHdoZW4gaXQgaXMgbm90IG9uZS4Kbm9kZV9tYWpvcigpIHsKICAiJDEiIC1wICdwcm9jZXNzLnZlcnNpb25zLm5vZGUuc3BsaXQoIi4iKVswXScgMj4vZGV2L251bGwgfHwgZWNobyAwCn0KCiMgQSB1c2FibGUgcnVudGltZTogTm9kZS5qcyAyMiBvciBuZXdlciwgb3IgQnVuIChpdCBydW5zIHRoZSBidWlsdCBzZXJ2ZXIgdG9vKS4KcnVudGltZV9vaygpIHsKICBbIC1uICIkMSIgXSAmJiBbIC14ICIkMSIgXSAmJiBbICEgLWQgIiQxIiBdIHx8IHJldHVybiAxCiAgY2FzZSAiJChiYXNlbmFtZSAiJDEiKSIgaW4KICAgIGJ1bikgIiQxIiAtLXZlcnNpb24gPi9kZXYvbnVsbCAyPiYxIDs7CiAgICAqKSBbICIkKG5vZGVfbWFqb3IgIiQxIikiIC1nZSAyMiBdIDI+L2Rldi9udWxsIDs7CiAgZXNhYwp9CgojIEFic29sdXRlIHBhdGggb2YgdGhlIHJ1bnRpbWU6IFdIRVJEUl9SVU5USU1FLCB0aGVuIG5vZGUgb24gdGhlIFBBVEgsIHRoZW4gdGhlCiMgdXN1YWwgaW5zdGFsbCBmb2xkZXJzIChuLCBudm0sIFZvbHRhLCBmbm0sIGFzZGYsIEhvbWVicmV3KSwgdGhlbiBCdW4uCiMgUHJpbnRzIG5vdGhpbmcgYW5kIGZhaWxzIHdoZW4gbm9uZSBpcyBmb3VuZC4KZmluZF9ydW50aW1lKCkgewogIGZvciBjIGluICIkUlVOVElNRSIgIiQoY29tbWFuZCAtdiBub2RlIDI+L2Rldi9udWxsIHx8IHRydWUpIiBcCiAgICAiJEhPTUUvLm4vYmluL25vZGUiICIke05fUFJFRklYOiskTl9QUkVGSVgvYmluL25vZGV9IiBcCiAgICAkKGxzIC1kICIkSE9NRSIvLm52bS92ZXJzaW9ucy9ub2RlL3YqL2Jpbi9ub2RlIDI+L2Rldi9udWxsIHwgc29ydCAtciAtVikgXAogICAgIiRIT01FLy52b2x0YS9iaW4vbm9kZSIgXAogICAgJChscyAtZCAiJEhPTUUiLy5sb2NhbC9zaGFyZS9mbm0vbm9kZS12ZXJzaW9ucy8qL2luc3RhbGxhdGlvbi9iaW4vbm9kZSAiJEhPTUUiLy5mbm0vbm9kZS12ZXJzaW9ucy8qL2luc3RhbGxhdGlvbi9iaW4vbm9kZSAyPi9kZXYvbnVsbCB8IHNvcnQgLXIgLVYpIFwKICAgICIkSE9NRS8uYXNkZi9zaGltcy9ub2RlIiAvb3B0L2hvbWVicmV3L2Jpbi9ub2RlIC91c3IvbG9jYWwvYmluL25vZGUgL3Vzci9iaW4vbm9kZSBcCiAgICAiJChjb21tYW5kIC12IGJ1biAyPi9kZXYvbnVsbCB8fCB0cnVlKSIgIiRIT01FLy5idW4vYmluL2J1biIgL29wdC9ob21lYnJldy9iaW4vYnVuIC91c3IvbG9jYWwvYmluL2J1bjsgZG8KICAgIGlmIHJ1bnRpbWVfb2sgIiRjIjsgdGhlbiBlY2hvICIkYyI7IHJldHVybiAwOyBmaQogIGRvbmUKICByZXR1cm4gMQp9CgpSVU5USU1FX0hFTFA9Ik5vZGUuanMgMjIgb3IgbmV3ZXIgKG9yIEJ1bikgaXMgcmVxdWlyZWQgdG8gcnVuIHdoZXJkciB3aXRob3V0IERvY2tlci4KICAgICBJbnN0YWxsIGl0IGZyb20gaHR0cHM6Ly9ub2RlanMub3JnLCBvciBzZXQgaXRzIGFic29sdXRlIHBhdGggaW4gJENPTkY6CiAgICAgICBXSEVSRFJfUlVOVElNRT0vcGF0aC90by9ub2RlIgoKIyBUaGUgbWFjaGluZSdzIHNob3J0IG5hbWUgKG5vIGRvbWFpbik6IHdoYXQgdGhlIGFwcCBzaG93cywgYW5kIHRoZSBjb250YWluZXIncwojIGhvc3QgbmFtZS4gV2l0aG91dCBpdCB0aGUgY29udGFpbmVyIHdvdWxkIGJlIGNhbGxlZCAid2hlcmRyIi4Kc2hvcnRfaG9zdCgpIHsKICBoPSIkKGhvc3RuYW1lIDI+L2Rldi9udWxsIHwgY3V0IC1kLiAtZjEpIgogIGVjaG8gIiR7aDotc2VydmVyfSIKfQoKaGVyZHJfYmluKCkgewogIGlmIFsgLW4gIiR7SEVSRFJfQklOX1BBVEg6LX0iIF07IHRoZW4gZWNobyAiJEhFUkRSX0JJTl9QQVRIIgogIGVsaWYgWyAteCAiJEhPTUUvLmxvY2FsL2Jpbi9oZXJkciIgXTsgdGhlbiBlY2hvICIkSE9NRS8ubG9jYWwvYmluL2hlcmRyIgogIGVsc2UgY29tbWFuZCAtdiBoZXJkciAyPi9kZXYvbnVsbCB8fCBlY2hvIGhlcmRyCiAgZmkKfQoKcmVhbF9kaXIoKSB7IChjZCAiJDEiIDI+L2Rldi9udWxsICYmIHB3ZCAtUCkgfHwgZWNobyAiJDEiOyB9CgojIENvbXBvc2UgZm9sZGVyIG9mIHRoZSBgd2hlcmRyYCBjb250YWluZXIsIGVtcHR5IHdoZW4gdGhlcmUgaXMgbm9uZS4KY29udGFpbmVyX2RpcigpIHsKICBkb2NrZXIgaW5zcGVjdCAiJENPTlRBSU5FUiIgLS1mb3JtYXQgJ3t7IGluZGV4IC5Db25maWcuTGFiZWxzICJjb20uZG9ja2VyLmNvbXBvc2UucHJvamVjdC53b3JraW5nX2RpciIgfX0nIDI+L2Rldi9udWxsIHx8IHRydWUKfQoKIyBUcnVlIHdoZW4gdGhlIGB3aGVyZHJgIGNvbnRhaW5lciBiZWxvbmdzIHRvICRESVIgKG9yIGRvZXMgbm90IGV4aXN0IHlldCkuCmNvbnRhaW5lcl9vdXJzKCkgewogIG93bmVyPSIkKGNvbnRhaW5lcl9kaXIpIgogIFsgLXogIiRvd25lciIgXSB8fCBbICIkKHJlYWxfZGlyICIkb3duZXIiKSIgPSAiJChyZWFsX2RpciAiJERJUiIpIiBdCn0KCmNvbXBvc2UoKSB7IGRvY2tlciBjb21wb3NlIC0tcHJvamVjdC1kaXJlY3RvcnkgIiRESVIiIC1mICIkRElSL2RvY2tlci1jb21wb3NlLnltbCIgIiRAIjsgfQoKd2FpdF91cCgpIHsKICBpPTAKICB3aGlsZSBbICIkaSIgLWx0ICIkezE6LTMwfSIgXTsgZG8KICAgIGlmIGFuc3dlcnM7IHRoZW4gcmV0dXJuIDA7IGZpCiAgICBpPSQoKGkgKyAxKSk7IHNsZWVwIDEKICBkb25lCiAgcmV0dXJuIDEKfQoKIyBUaGUgY29tbWFuZHMgb2YgdGhlIG5hdGl2ZSBtb2RlOiB0aGUgaW5zdGFsbGVkIGNvcHksIG9yIHRoZSBjaGVja291dCBpdHNlbGYKIyAoYSBsaW5rZWQgcGx1Z2luIGJ1aWx0IGJ5IGhhbmQsIG9yIGEgcGx1Z2luIGluc3RhbGxlZCBiZWZvcmUgJEFQUCBleGlzdGVkKS4KY2xpX3Jvb3QoKSB7CiAgaWYgWyAtZiAiJEFQUC9iaW4vd2hlcmRyLm1qcyIgXSAmJiBbIC1mICIkQVBQLy5vdXRwdXQvc2VydmVyL2luZGV4Lm1qcyIgXTsgdGhlbiBlY2hvICIkQVBQIjsgZWxzZSBlY2hvICIkUk9PVCI7IGZpCn0KCiMgVGhlIHBlcnNvbiBydW5uaW5nIGBoZXJkciBwbHVnaW4gaW5zdGFsbGAgc2VlcyBvbmx5IEhlcmRyJ3Mgb3duIGxpbmVzOiB0aGUKIyBvdXRwdXQgb2YgYnVpbGQgY29tbWFuZHMgaXMgY2FwdHVyZWQuIEltcG9ydGFudCBsaW5lcyBhbHNvIGdvIHRvIHRoZSB0ZXJtaW5hbC4KdGVsbCgpIHsKICBwcmludGYgJyVzXG4nICIkKiIKICB7IHByaW50ZiAnJXNcbicgIiQqIiA+IC9kZXYvdHR5OyB9IDI+L2Rldi9udWxsIHx8IHRydWUKfQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gYnVpbGQKY21kX2J1aWxkKCkgewogIHRlbGwgIndoZXJkcjogaW5zdGFsbGluZyBpbiAkRElSIgogICMgRmlyc3QgaW5zdGFsbCAobm8gcGx1Z2luLmVudiB5ZXQpOiB0aGUgYnJvd3NlciBvcGVucyBvbiB0aGUgc2V0dXAgZ3VpZGUKICAjIG9uY2Ugd2hlcmRyIHJ1bnMuIFVwZGF0ZXMga2VlcCBwbHVnaW4uZW52IGFuZCBvcGVuIG5vdGhpbmcuCiAgRklSU1RfSU5TVEFMTD0wCiAgWyAtZiAiJENPTkYiIF0gfHwgRklSU1RfSU5TVEFMTD0xCiAgbWtkaXIgLXAgIiRESVIiCiAgcHJpbnRmICclc1xuJyAiJERJUiIgPiAiJFJPT1QvLndoZXJkci1kaXIiCgogIGlmIFsgLXogIiRNT0RFIiBdOyB0aGVuCiAgICBpZiBkb2NrZXJfdXNhYmxlOyB0aGVuIE1PREU9ZG9ja2VyOyBlbHNlIE1PREU9bmF0aXZlOyBmaQogIGZpCiAgY2FzZSAiJE1PREUiIGluCiAgICBkb2NrZXIpIGRvY2tlcl91c2FibGUgfHwgZGllICJXSEVSRFJfTU9ERT1kb2NrZXIsIGJ1dCBEb2NrZXIgQ29tcG9zZSB2MiBpcyBub3QgdXNhYmxlIGJ5ICQoaWQgLXVuKSBvbiB0aGlzIHN5c3RlbS4iIDs7CiAgICBuYXRpdmUpIDs7CiAgICAqKSBkaWUgIldIRVJEUl9NT0RFIG11c3QgYmUgZG9ja2VyIG9yIG5hdGl2ZSAoZ290OiAkTU9ERSkuIiA7OwogIGVzYWMKCiAgaWYgWyAiJE1PREUiID0gImRvY2tlciIgXTsgdGhlbiBidWlsZF9kb2NrZXI7IGVsc2UgYnVpbGRfbmF0aXZlOyBmaQogICMgV3JpdHRlbiBsYXN0OiBhIGZhaWxlZCBidWlsZCBrZWVwcyBubyBoYWxmLW1hZGUgY2hvaWNlLiBSZXdyaXR0ZW4gb24gZWFjaAogICMgaW5zdGFsbCBmcm9tIHRoZSBtZXJnZWQgc2V0dGluZ3MgKGVudmlyb25tZW50IG92ZXIgdGhlIHByZXZpb3VzIGZpbGUpLgogIHdyaXRlX2NvbmYKICBvayAicGx1Z2luLmVudiB3cml0dGVuIChtb2RlOiAkTU9ERSkiCiAgKCBjbWRfc2tpbGwgaW5zdGFsbCApIHx8IHdhcm4gIndoZXJkciBza2lsbCBub3QgbGlua2VkIChvcHRpb25hbCk6IHJ1biAkMCBza2lsbCBpbnN0YWxsIgogICggY21kX2tleSBpbnN0YWxsICkgfHwgd2FybiAibm8gSGVyZHIga2V5IGZvciB0aGUgcGFuZWwgKG9wdGlvbmFsKTogcnVuICQwIGtleSBpbnN0YWxsIgogIGJ1aWxkX3N0YXJ0Cn0KCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHNraWxsCiMgVGhlICJ3aGVyZHIiIGFnZW50IHNraWxsIChza2lsbHMvd2hlcmRyL1NLSUxMLm1kKTogdGhlIGNvbnZlbnRpb25zIG9mIHRoZQojIFByb2plY3QgcGFuZWwgZm9yIGhlcmRyLXByb2plY3RzIGNvb3JkaW5hdG9ycy4gQ29waWVkIHRvICRESVIvc2tpbGxzL3doZXJkcgojICh0aGUgY2hlY2tvdXQgaXMgYnVpbHQgaW4gYSB0ZW1wb3JhcnkgZm9sZGVyLCB0aGVuIG1vdmVkKSwgdGhlbiBsaW5rZWQgaW50bwojIHRoZSB1c2VyIHNraWxsIGZvbGRlcnM6IENsYXVkZSBDb2RlJ3MgJHtDTEFVREVfQ09ORklHX0RJUjotfi8uY2xhdWRlfS9za2lsbHMsCiMgYW5kIH4vLmFnZW50cy9za2lsbHMsIHJlYWQgYnkgQ29kZXggYW5kIG9tcC4gT25seSBsaW5rcyB0byB0aGF0IGNvcHkgYXJlCiMgZXZlciBjcmVhdGVkIG9yIHJlbW92ZWQ6IGEgIndoZXJkciIgc2tpbGwgb2Ygc29tZW9uZSBlbHNlIGlzIGxlZnQgYWxvbmUuClNLSUxMX0NPUFk9IiRESVIvc2tpbGxzL3doZXJkciIKCnNraWxsX2RpcnMoKSB7CiAgY2xhdWRlPSIke0NMQVVERV9DT05GSUdfRElSOi0kSE9NRS8uY2xhdWRlfSIKICBbIC1kICIkY2xhdWRlIiBdICYmIGVjaG8gIiRjbGF1ZGUvc2tpbGxzIgogIGlmIFsgLWQgIiRIT01FLy5hZ2VudHMiIF0gfHwgWyAtZCAiJEhPTUUvLmNvZGV4IiBdIHx8IFsgLWQgIiRIT01FLy5vbXAiIF07IHRoZW4gZWNobyAiJEhPTUUvLmFnZW50cy9za2lsbHMiOyBmaQogIHJldHVybiAwCn0KCmNtZF9za2lsbCgpIHsKICBjYXNlICIkezE6LX0iIGluCiAgICBpbnN0YWxsKQogICAgICBta2RpciAtcCAiJFNLSUxMX0NPUFkiCiAgICAgIGNwICIkUk9PVC9za2lsbHMvd2hlcmRyL1NLSUxMLm1kIiAiJFNLSUxMX0NPUFkvU0tJTEwubWQiCiAgICAgIHNraWxsX2RpcnMgfCB3aGlsZSBJRlM9IHJlYWQgLXIgZDsgZG8KICAgICAgICBsaW5rPSIkZC93aGVyZHIiCiAgICAgICAgaWYgWyAtTCAiJGxpbmsiIF0gJiYgWyAiJChyZWFkbGluayAiJGxpbmsiKSIgPSAiJFNLSUxMX0NPUFkiIF07IHRoZW4gb2sgInNraWxsIGFscmVhZHkgbGlua2VkOiAkbGluayIKICAgICAgICBlbGlmIFsgLWUgIiRsaW5rIiBdIHx8IFsgLUwgIiRsaW5rIiBdOyB0aGVuIHdhcm4gInNraWxsIG5vdCBsaW5rZWQ6ICRsaW5rIGFscmVhZHkgZXhpc3RzIChsZWZ0IGFsb25lKSIKICAgICAgICBlbHNlIG1rZGlyIC1wICIkZCIgJiYgbG4gLXMgIiRTS0lMTF9DT1BZIiAiJGxpbmsiICYmIG9rICJza2lsbCBsaW5rZWQ6ICRsaW5rIgogICAgICAgIGZpCiAgICAgIGRvbmUKICAgICAgOzsKICAgIHVuaW5zdGFsbCkKICAgICAgc2tpbGxfZGlycyB8IHdoaWxlIElGUz0gcmVhZCAtciBkOyBkbwogICAgICAgIGxpbms9IiRkL3doZXJkciIKICAgICAgICBpZiBbIC1MICIkbGluayIgXSAmJiBbICIkKHJlYWRsaW5rICIkbGluayIpIiA9ICIkU0tJTExfQ09QWSIgXTsgdGhlbiBybSAiJGxpbmsiICYmIG9rICJza2lsbCB1bmxpbmtlZDogJGxpbmsiOyBmaQogICAgICBkb25lCiAgICAgIHJtIC1yZiAiJFNLSUxMX0NPUFkiCiAgICAgIHJtZGlyICIkRElSL3NraWxscyIgMj4vZGV2L251bGwgfHwgdHJ1ZQogICAgICA7OwogICAgKikgZGllICJ1c2FnZTogJDAgc2tpbGwgaW5zdGFsbHx1bmluc3RhbGwiIDs7CiAgZXNhYwp9CgojIExhc3Qgc3RlcCBvZiB0aGUgaW5zdGFsbDogc3RhcnQgd2hlcmRyIChvciByZXN0YXJ0IHRoZSBvbmUgdGhpcyBwbHVnaW4KIyBydW5zLCBvbiBhbiB1cGRhdGUpLiBOZXZlciBmYWlscyB0aGUgaW5zdGFsbDogYSB3aGVyZHIgdGhhdCBjYW5ub3Qgc3RhcnQgaXMKIyByZXBvcnRlZCB3aXRoIHdoYXQgdG8gZG8sIHRoZSBwbHVnaW4gc3RheXMgaW5zdGFsbGVkLgpidWlsZF9zdGFydCgpIHsKICBzZXQgK2UKICBvdXQ9IiQoIChjbWRfc3RhcnQpIDI+JjEgKSIKICBjb2RlPSQ/CiAgc2V0IC1lCiAgcHJpbnRmICclc1xuJyAiJG91dCIKICBpZiBbICIkY29kZSIgLWVxIDAgXSAmJiBhbnN3ZXJzOyB0aGVuCiAgICAjIGh0dHBzOi8vd2hlcmRyLmRldi9pbnN0YWxsIHByaW50cyBpdHMgb3duIHN1bW1hcnkgKFdIRVJEUl9JTlNUQUxMRVI9MSkuCiAgICBxdWlldD0wCiAgICBbICIke1dIRVJEUl9JTlNUQUxMRVI6LTB9IiA9IDEgXSAmJiBxdWlldD0xCiAgICBbICIkcXVpZXQiID0gMSBdIHx8IHRlbGwgIiIKICAgIFsgIiRxdWlldCIgPSAxIF0gfHwgdGVsbCAi4pyTIHdoZXJkciBpcyBydW5uaW5nIOKGkiAkVVJMIgogICAgaWYgWyAiJHtGSVJTVF9JTlNUQUxMOi0wfSIgPSAxIF07IHRoZW4KICAgICAgIyBBbHJlYWR5IHB1Ymxpc2hlZCBvbiB0aGUgdGFpbG5ldCAoYSByZWluc3RhbGwsIG9yIGB0YWlsc2NhbGUgc2VydmVgCiAgICAgICMgcnVuIGZpcnN0KTogdGhlIGd1aWRlIG9wZW5zIG9uIHRoYXQgYWRkcmVzcywgd2hlcmUgcGFzc2tleXMgYmVsb25nLgogICAgICBndWlkZT0iJChvcGVuX2FkZHJlc3MpLyMvc2V0dXAiCiAgICAgIGlmIG9wZW5fYnJvd3NlciAiJGd1aWRlIjsgdGhlbiBbICIkcXVpZXQiID0gMSBdIHx8IHRlbGwgIiAgU2V0dXAgZ3VpZGUgb3BlbmVkIGluIHlvdXIgYnJvd3NlcjogJGd1aWRlIgogICAgICBlbHNlIFsgIiRxdWlldCIgPSAxIF0gfHwgdGVsbCAiICBTZXR1cCBndWlkZTogb3BlbiAkZ3VpZGUgaW4gYSBicm93c2VyIgogICAgICBmaQogICAgZmkKICAgIFsgIiRxdWlldCIgPSAxIF0gfHwgdGVsbCAiICBQaG9uZTogb3BlbiB0aGUgd2hlcmRyIHBhbmVsIGluIEhlcmRyIChrZXkgYWJvdmUsIG9yIGhlcmRyIHBsdWdpbiBhY3Rpb24gaW52b2tlIHBhbmVsIC0tcGx1Z2luICRQTFVHSU5fSUQpIgogIGVsc2UKICAgIHRlbGwgIiIKICAgIHRlbGwgIiEgd2hlcmRyIGlzIGluc3RhbGxlZCBidXQgZGlkIG5vdCBzdGFydDoiCiAgICBwcmludGYgJyVzXG4nICIkb3V0IiB8IHRhaWwgLW4gOCB8IHdoaWxlIElGUz0gcmVhZCAtciBsOyBkbyB0ZWxsICIgICAgJGwiOyBkb25lCiAgICB0ZWxsICIgIE9wZW4gdGhlIHdoZXJkciBwYW5lbCBpbiBIZXJkciwgdGhlbiBwcmVzcyBTIHRvIHN0YXJ0IGl0IG9yIEwgZm9yIGl0cyBsb2cuIgogIGZpCn0KCndyaXRlX2NvbmYoKSB7CiAgewogICAgZWNobyAiIyB3aGVyZHIgSGVyZHIgcGx1Z2luIHNldHRpbmdzIChoZXJkci1wbHVnaW4uc2gpLiIKICAgIGVjaG8gIiMgVG8gc3dpdGNoIG1vZGUsIHNldCBXSEVSRFJfTU9ERSBhbmQgcnVuOiBoZXJkciBwbHVnaW4gaW5zdGFsbCAkU09VUkNFIgogICAgZWNobyAiV0hFUkRSX01PREU9JE1PREUiCiAgICBlY2hvICJXSEVSRFJfUE9SVD0kUE9SVCIKICAgIGVjaG8gIiMgTmF0aXZlIG1vZGU6IHByaXZhdGUgSFRUUFMgYWRkcmVzcyAodGFpbHNjYWxlIHNlcnZlKSwgZm9yIHB1c2ggbm90aWZpY2F0aW9ucy4iCiAgICBlY2hvICJBUFBfVVJMPSR7QVBQX1VSTDotfSIKICAgIGlmIFsgIiRNT0RFIiA9ICJuYXRpdmUiIF07IHRoZW4KICAgICAgZWNobyAiIyBOYXRpdmUgbW9kZTogYWJzb2x1dGUgcGF0aCBvZiB0aGUgbm9kZSAoMjIrKSBvciBidW4gdGhhdCBydW5zIHdoZXJkci4iCiAgICAgIGVjaG8gIldIRVJEUl9SVU5USU1FPSRSVU5USU1FIgogICAgZmkKICB9ID4gIiRDT05GIgp9CgojIFRoZSBwdWJsaXNoZWQgbnBtIHBhY2thZ2Ugb2YgdGhpcyBleGFjdCB2ZXJzaW9uIGhvbGRzIHRoZSBidWlsdCBzZXJ2ZXI6CiMgZG93bmxvYWQgaXQgaW5zdGVhZCBvZiBidWlsZGluZyAobm8gbnBtIGNpKS4gRmFpbHMgd2hlbiBpdCBpcyBub3QgcHVibGlzaGVkLgpmZXRjaF9wcmVidWlsdCgpIHsKICBjb21tYW5kIC12IGN1cmwgPi9kZXYvbnVsbCAyPiYxICYmIGNvbW1hbmQgLXYgdGFyID4vZGV2L251bGwgMj4mMSB8fCByZXR1cm4gMQogIHZlcnNpb249IiQoc2VkIC1uICdzL152ZXJzaW9uID0gIlwoLipcKSIkL1wxL3AnICIkUk9PVC9oZXJkci1wbHVnaW4udG9tbCIgfCBoZWFkIC1uIDEpIgogIHRtcD0iJChta3RlbXAgLWQpIgogIGlmIGN1cmwgLWZzU0wgLS1tYXgtdGltZSAxMjAgImh0dHBzOi8vcmVnaXN0cnkubnBtanMub3JnL3doZXJkci8tL3doZXJkci0kdmVyc2lvbi50Z3oiIC1vICIkdG1wL3doZXJkci50Z3oiIDI+L2Rldi9udWxsIFwKICAgICYmIHRhciAteHpmICIkdG1wL3doZXJkci50Z3oiIC1DICIkdG1wIiBcCiAgICAmJiBbIC1mICIkdG1wL3BhY2thZ2UvLm91dHB1dC9zZXJ2ZXIvaW5kZXgubWpzIiBdOyB0aGVuCiAgICBybSAtcmYgIiRST09ULy5vdXRwdXQiCiAgICBtdiAiJHRtcC9wYWNrYWdlLy5vdXRwdXQiICIkUk9PVC8ub3V0cHV0IgogICAgcm0gLXJmICIkdG1wIgogICAgb2sgIndoZXJkciAkdmVyc2lvbiBkb3dubG9hZGVkIChwcmVidWlsdCBucG0gcGFja2FnZSkiCiAgICByZXR1cm4gMAogIGZpCiAgcm0gLXJmICIkdG1wIgogIHJldHVybiAxCn0KCiMgcXJjb2RlLXRlcm1pbmFsICh0aGUgcGFuZWwncyBRUiBjb2RlKSwgdGhlIG9ubHkgcGFja2FnZSB0aGUgY29tbWFuZHMgbmVlZAojIGF0IHJ1bnRpbWUsIHdoZW4gdGhlIGZvbGRlciBkb2VzIG5vdCBoYXZlIGl0IHlldCAobm8gbnBtIGNpIHdhcyBydW4pLgpmZXRjaF9xcigpIHsKICBbIC1mICIkMS9ub2RlX21vZHVsZXMvcXJjb2RlLXRlcm1pbmFsL3BhY2thZ2UuanNvbiIgXSAmJiByZXR1cm4gMAogIGNvbW1hbmQgLXYgY3VybCA+L2Rldi9udWxsIDI+JjEgJiYgY29tbWFuZCAtdiB0YXIgPi9kZXYvbnVsbCAyPiYxIHx8IHJldHVybiAwCiAgdG1wPSIkKG1rdGVtcCAtZCkiCiAgaWYgY3VybCAtZnNTTCAtLW1heC10aW1lIDYwIGh0dHBzOi8vcmVnaXN0cnkubnBtanMub3JnL3FyY29kZS10ZXJtaW5hbC8tL3FyY29kZS10ZXJtaW5hbC0wLjEyLjAudGd6IC1vICIkdG1wL3FyLnRneiIgMj4vZGV2L251bGwgXAogICAgJiYgdGFyIC14emYgIiR0bXAvcXIudGd6IiAtQyAiJHRtcCI7IHRoZW4KICAgIG1rZGlyIC1wICIkMS9ub2RlX21vZHVsZXMiCiAgICBybSAtcmYgIiQxL25vZGVfbW9kdWxlcy9xcmNvZGUtdGVybWluYWwiCiAgICBtdiAiJHRtcC9wYWNrYWdlIiAiJDEvbm9kZV9tb2R1bGVzL3FyY29kZS10ZXJtaW5hbCIKICBlbHNlCiAgICB3YXJuICJObyBRUiBjb2RlIGluIHRoZSBwYW5lbCAocXJjb2RlLXRlcm1pbmFsIGNvdWxkIG5vdCBiZSBkb3dubG9hZGVkKS4iCiAgZmkKICBybSAtcmYgIiR0bXAiCn0KCmJ1aWxkX25hdGl2ZSgpIHsKICBSVU5USU1FPSIkKGZpbmRfcnVudGltZSkiIHx8IGRpZSAiJFJVTlRJTUVfSEVMUCIKICBvayAiUnVudGltZTogJFJVTlRJTUUgKCQoIiRSVU5USU1FIiAtLXZlcnNpb24gMj4vZGV2L251bGwpKSIKICBpZiBmZXRjaF9wcmVidWlsdDsgdGhlbgogICAgaW5zdGFsbF9hcHAKICAgIHJldHVybiAwCiAgZmkKICBjYXNlICIkKGJhc2VuYW1lICIkUlVOVElNRSIpIiBpbgogICAgYnVuKSBkaWUgIlRoZSBwcmVidWlsdCB3aGVyZHIgcGFja2FnZSBjb3VsZCBub3QgYmUgZG93bmxvYWRlZCwgYW5kIGJ1aWxkaW5nIGl0IG5lZWRzIE5vZGUuanMgMjIgd2l0aCBucG0uCiAgICAgQ2hlY2sgdGhlIG5ldHdvcmssIG9yIGluc3RhbGwgTm9kZS5qcyAyMiwgdGhlbiBpbnN0YWxsIHRoZSBwbHVnaW4gYWdhaW4uIiA7OwogIGVzYWMKICBiaW5kaXI9IiQoZGlybmFtZSAiJFJVTlRJTUUiKSIKICBbIC14ICIkYmluZGlyL25wbSIgXSB8fCBjb21tYW5kIC12IG5wbSA+L2Rldi9udWxsIDI+JjEgfHwgZGllICJucG0gaXMgbWlzc2luZyAoaXQgY29tZXMgd2l0aCBOb2RlLmpzKS4iCiAgdGVsbCAid2hlcmRyOiBidWlsZGluZyAoYSBmZXcgbWludXRlcyB0aGUgZmlyc3QgdGltZSnigKYiCiAgKAogICAgY2QgIiRST09UIgogICAgUEFUSD0iJGJpbmRpcjokUEFUSCIgbnBtIGNpIC0tbm8tYXVkaXQgLS1uby1mdW5kCiAgICBQQVRIPSIkYmluZGlyOiRQQVRIIiBucG0gcnVuIGJ1aWxkCiAgKQogIG9rICJ3aGVyZHIgYnVpbHQgaW4gdGhlIHBsdWdpbiBmb2xkZXIiCiAgaW5zdGFsbF9hcHAKfQoKIyBDb3BpZXMgdGhlIGNvbW1hbmRzIGFuZCB0aGUgYnVpbHQgc2VydmVyIHRvICRBUFAsIHdoaWNoIG91dGxpdmVzIHRoaXMKIyBjaGVja291dC4gQSB3aGVyZHIgdGhpcyBwbHVnaW4gcnVucyBmcm9tIHRoZSBwcmV2aW91cyBjb3B5IGlzIHN0b3BwZWQgZm9yCiMgdGhlIHN3YXA7IGJ1aWxkX3N0YXJ0IHN0YXJ0cyB0aGUgbmV3IG9uZS4KaW5zdGFsbF9hcHAoKSB7CiAgIyBOaXRybyBsaW5rcyBzb21lIHBhY2thZ2VzICh0c2xpYikgdG8gaXRzIG93biBmb2xkZXI6IGNvcGllcywgbm90IGxpbmtzLgogIGlmIFsgLWQgIiRST09ULy5vdXRwdXQvc2VydmVyL25vZGVfbW9kdWxlcyIgXTsgdGhlbiAiJFJVTlRJTUUiICIkUk9PVC9zY3JpcHRzL3BhY2stb3V0cHV0Lm1qcyIgPi9kZXYvbnVsbDsgZmkKICBuZXc9IiRBUFAubmV3IgogIHJtIC1yZiAiJG5ldyIKICBta2RpciAtcCAiJG5ldyIKICBjcCAtUiAiJFJPT1QvYmluIiAiJFJPT1QvLm91dHB1dCIgIiRST09UL3BhY2thZ2UuanNvbiIgIiRuZXcvIgogIGlmIFsgLWQgIiRST09UL25vZGVfbW9kdWxlcy9xcmNvZGUtdGVybWluYWwiIF07IHRoZW4KICAgIG1rZGlyIC1wICIkbmV3L25vZGVfbW9kdWxlcyIKICAgIGNwIC1SICIkUk9PVC9ub2RlX21vZHVsZXMvcXJjb2RlLXRlcm1pbmFsIiAiJG5ldy9ub2RlX21vZHVsZXMvIgogIGZpCiAgZmV0Y2hfcXIgIiRuZXciCiAgIyBUaGUgd2hlcmRyIHRoaXMgcGx1Z2luIHJ1bnMgKGZyb20gdGhlIHByZXZpb3VzIGNvcHksIG9yIGZyb20gYW4gb2xkZXIKICAjIHBsdWdpbiBjaGVja291dCk6IHN0b3BwZWQgZm9yIHRoZSBzd2FwLCBzdGFydGVkIGFnYWluIGJ5IGJ1aWxkX3N0YXJ0LgogIGlmIFsgLWYgIiRESVIvd2hlcmRyLnBpZCIgXSB8fCBbIC1mICIkQVBQL2Jpbi93aGVyZHIubWpzIiBdOyB0aGVuIGNsaSBzdG9wID4vZGV2L251bGwgMj4mMSB8fCB0cnVlOyBmaQogIHJtIC1yZiAiJEFQUC5vbGQiCiAgaWYgWyAtZCAiJEFQUCIgXTsgdGhlbiBtdiAiJEFQUCIgIiRBUFAub2xkIjsgZmkKICBtdiAiJG5ldyIgIiRBUFAiCiAgcm0gLXJmICIkQVBQLm9sZCIKICBvayAid2hlcmRyICQoc2VkIC1uICdzL14gKiJ2ZXJzaW9uIjogKiJcKC4qXCkiLCQvXDEvcCcgIiRBUFAvcGFja2FnZS5qc29uIiB8IGhlYWQgLW4gMSkgaW5zdGFsbGVkIGluICRBUFAiCn0KCmJ1aWxkX2RvY2tlcigpIHsKICBvayAiRG9ja2VyICQoZG9ja2VyIHZlcnNpb24gLS1mb3JtYXQgJ3t7LlNlcnZlci5WZXJzaW9ufX0nIDI+L2Rldi9udWxsIHx8IGVjaG8gJz8nKSIKICBzdGFtcD0iJERJUi8uY29tcG9zZS1mcm9tLXBsdWdpbiIKICBpZiBbICEgLWYgIiRESVIvZG9ja2VyLWNvbXBvc2UueW1sIiBdOyB0aGVuCiAgICBjcCAiJFJPT1QvZG9ja2VyLWNvbXBvc2UueW1sIiAiJERJUi9kb2NrZXItY29tcG9zZS55bWwiCiAgICBja3N1bSA8ICIkRElSL2RvY2tlci1jb21wb3NlLnltbCIgPiAiJHN0YW1wIgogICAgb2sgImRvY2tlci1jb21wb3NlLnltbCBjb3BpZWQiCiAgZWxpZiBjbXAgLXMgIiRST09UL2RvY2tlci1jb21wb3NlLnltbCIgIiRESVIvZG9ja2VyLWNvbXBvc2UueW1sIjsgdGhlbgogICAgb2sgImRvY2tlci1jb21wb3NlLnltbCBpcyB1cCB0byBkYXRlIgogIGVsaWYgWyAtZiAiJHN0YW1wIiBdICYmIFsgIiQoY2tzdW0gPCAiJERJUi9kb2NrZXItY29tcG9zZS55bWwiKSIgPSAiJChjYXQgIiRzdGFtcCIpIiBdOyB0aGVuCiAgICAjIFVuY2hhbmdlZCBzaW5jZSB0aGUgcGx1Z2luIHdyb3RlIGl0OiBzYWZlIHRvIHJlZnJlc2guCiAgICBjcCAiJFJPT1QvZG9ja2VyLWNvbXBvc2UueW1sIiAiJERJUi9kb2NrZXItY29tcG9zZS55bWwiCiAgICBja3N1bSA8ICIkRElSL2RvY2tlci1jb21wb3NlLnltbCIgPiAiJHN0YW1wIgogICAgb2sgImRvY2tlci1jb21wb3NlLnltbCB1cGRhdGVkIgogIGVsc2UKICAgIHdhcm4gIktlZXBpbmcgeW91ciBlZGl0ZWQgZG9ja2VyLWNvbXBvc2UueW1sICh0aGUgbmV3IG9uZSBpcyAkUk9PVC9kb2NrZXItY29tcG9zZS55bWwpLiIKICBmaQogIGlmIFsgISAtZiAiJERJUi8uZW52IiBdOyB0aGVuCiAgICBoZXJkcj0iJChoZXJkcl9iaW4pIgogICAgewogICAgICBlY2hvICIjIHdoZXJkciBzZXR0aW5ncywgcmVhZCBieSBkb2NrZXIgY29tcG9zZSAoc2VlIC5lbnYuZXhhbXBsZSBpbiB0aGUgcmVwb3NpdG9yeSkuIgogICAgICBlY2hvICJIT1NUX0hPTUU9JEhPTUUiCiAgICAgIGVjaG8gIlBVSUQ9JChpZCAtdSkiCiAgICAgIGVjaG8gIlBHSUQ9JChpZCAtZykiCiAgICAgIGVjaG8gIlBPUlQ9JFBPUlQiCiAgICAgIGVjaG8gIiMgUHJpdmF0ZSBIVFRQUyBhZGRyZXNzICh0YWlsc2NhbGUgc2VydmUpLCBuZWVkZWQgZm9yIHB1c2ggbm90aWZpY2F0aW9ucy4iCiAgICAgIGVjaG8gIkFQUF9VUkw9JHtBUFBfVVJMOi1odHRwOi8vbG9jYWxob3N0OiRQT1JUL30iCiAgICAgIGVjaG8gIkhPU1RfTEFCRUw9JChzaG9ydF9ob3N0KSIKICAgICAgZWNobyAiVFo9JHtUWjotVVRDfSIKICAgICAgaWYgWyAiJGhlcmRyIiAhPSAiJEhPTUUvLmxvY2FsL2Jpbi9oZXJkciIgXTsgdGhlbiBlY2hvICJIRVJEUl9CSU49JGhlcmRyIjsgZmkKICAgIH0gPiAiJERJUi8uZW52IgogICAgb2sgIi5lbnYgY3JlYXRlZCIKICBlbHNlCiAgICBvayAiLmVudiBrZXB0IgogIGZpCiAgY29tcG9zZSBwdWxsIC0tcXVpZXQgfHwgZGllICJDb3VsZCBub3QgcHVsbCB0aGUgd2hlcmRyIGltYWdlLiBDaGVjayB0aGUgbmV0d29yaywgdGhlbiBpbnN0YWxsIHRoZSBwbHVnaW4gYWdhaW4uIgogIG9rICJJbWFnZSBwdWxsZWQiCiAgIyBUaGUgcGFuZWwgcnVucyBmcm9tIHRoZSBjaGVja291dCB3aXRoIG5vZGUgd2hlbiB0aGVyZSBpcyBvbmUuCiAgZmV0Y2hfcXIgIiRST09UIgp9CgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBzdGFydApjbWRfc3RhcnQoKSB7CiAgaWYgYW5zd2VyczsgdGhlbgogICAgc2F5ICJ3aGVyZHI6IHNvbWV0aGluZyBhbHJlYWR5IGFuc3dlcnMgb24gcG9ydCAkUE9SVCwgbm90aGluZyB0byBzdGFydCAoJFVSTCkuIgogICAgcmV0dXJuIDAKICBmaQogIGNhc2UgIiRNT0RFIiBpbgogICAgZG9ja2VyKSBzdGFydF9kb2NrZXIgOzsKICAgIG5hdGl2ZSkgc3RhcnRfbmF0aXZlIDs7CiAgICAqKSBkaWUgIndoZXJkciBwbHVnaW4gaXMgbm90IHNldCB1cCAoJENPTkYgaXMgbWlzc2luZyk6IGluc3RhbGwgaXQgYWdhaW4gd2l0aCBoZXJkciBwbHVnaW4gaW5zdGFsbCAkU09VUkNFLiIgOzsKICBlc2FjCiAgaWYgWyAiJE1PREUiID0gIm5hdGl2ZSIgXTsgdGhlbiByZXR1cm4gMDsgZmkKICBpZiB3YWl0X3VwIDQ1OyB0aGVuCiAgICBzYXkgIndoZXJkciBpcyBydW5uaW5nOiAkVVJMIgogIGVsc2UKICAgIHdhcm4gIndoZXJkciBkb2VzIG5vdCBhbnN3ZXIgb24gcG9ydCAkUE9SVCB5ZXQuIExvZzogJChsb2dfaGludCkiCiAgICBleGl0IDEKICBmaQp9CgojIE5hdGl2ZSBtb2RlOiB0aGUgd2hlcmRyIGNvbW1hbmQgKGJpbi93aGVyZHIubWpzKSBkb2VzIHRoZSB3b3JrLCB3aXRoIHRoZQojIHJ1bnRpbWUgc2F2ZWQgYXQgaW5zdGFsbDsgaXQgc2F5cyAic3RhcnRlZCIgb25seSBvbmNlIHRoZSBwb3J0IGFuc3dlcnMuCmVuc3VyZV9ydW50aW1lKCkgewogIGlmICEgcnVudGltZV9vayAiJFJVTlRJTUUiOyB0aGVuCiAgICBzYXZlZD0iJFJVTlRJTUUiCiAgICBSVU5USU1FPSIkKGZpbmRfcnVudGltZSkiIHx8IGRpZSAiJHtzYXZlZDorVGhlIHNhdmVkIHJ1bnRpbWUgKCRzYXZlZCkgaXMgZ29uZS4gfSRSVU5USU1FX0hFTFAiCiAgICB3YXJuICIke3NhdmVkOiskc2F2ZWQgaXMgZ29uZTogfXVzaW5nICRSVU5USU1FIChzYXZlZCBpbiAkQ09ORikuIgogICAgd3JpdGVfY29uZgogIGZpCn0KCmNsaSgpIHsKICBlbnN1cmVfcnVudGltZQogIHNvY2s9IiR7SEVSRFJfU09DS0VUX1BBVEg6LX0iCiAgIyBBIHBsdWdpbiBzdGFydGVkIGZyb20gYSBuYW1lZCBIZXJkciBzZXNzaW9uIGRyaXZlcyB0aGF0IHNlc3Npb24uCiAgc2Vzc2lvbj0iIgogIGNhc2UgIiRzb2NrIiBpbiAqL3Nlc3Npb25zLyovaGVyZHIuc29jaykgc2Vzc2lvbj0iJChiYXNlbmFtZSAiJChkaXJuYW1lICIkc29jayIpIikiIDs7IGVzYWMKICAoCiAgICBjZCAiJERJUiIKICAgIEhFUkRSX0JJTj0iJChoZXJkcl9iaW4pIgogICAgIyBUaGUgcnVudGltZSdzIGZvbGRlciBmaXJzdDogdG9vbHMgaXQgc3RhcnRzIGZpbmQgdGhlIHNhbWUgbm9kZS4KICAgIFBBVEg9IiQoZGlybmFtZSAiJFJVTlRJTUUiKTokUEFUSCIKICAgIGV4cG9ydCBQQVRIIFdIRVJEUl9ESVI9IiRESVIiIFdIRVJEUl9SVU5USU1FPSIkUlVOVElNRSIgSE9TVD0xMjcuMC4wLjEgUE9SVCBIRVJEUl9CSU4KICAgIGlmIFsgLW4gIiRzZXNzaW9uIiBdOyB0aGVuIGV4cG9ydCBIRVJEUl9XRUJfU0VTU0lPTj0iJHNlc3Npb24iOyBmaQogICAgaWYgWyAtbiAiJHNvY2siIF07IHRoZW4gZXhwb3J0IEhFUkRSX1NPQ0s9IiRzb2NrIjsgZmkKICAgIGlmIFsgLW4gIiR7QVBQX1VSTDotfSIgXTsgdGhlbiBleHBvcnQgQVBQX1VSTDsgZmkKICAgIGV4ZWMgIiRSVU5USU1FIiAiJChjbGlfcm9vdCkvYmluL3doZXJkci5tanMiICIkQCIKICApCn0KCnN0YXJ0X25hdGl2ZSgpIHsKICBbIC1mICIkKGNsaV9yb290KS8ub3V0cHV0L3NlcnZlci9pbmRleC5tanMiIF0gfHwgZGllICJ3aGVyZHIgaXMgbm90IGJ1aWx0OiBpbnN0YWxsIHRoZSBwbHVnaW4gYWdhaW4gKGhlcmRyIHBsdWdpbiBpbnN0YWxsICRTT1VSQ0UgLS15ZXMpLiIKICBta2RpciAtcCAiJERJUiIKICBjbGkgc3RhcnQKfQoKc3RhcnRfZG9ja2VyKCkgewogIFsgLWYgIiRESVIvZG9ja2VyLWNvbXBvc2UueW1sIiBdIHx8IGRpZSAiJERJUi9kb2NrZXItY29tcG9zZS55bWwgaXMgbWlzc2luZzogcnVuIHRoZSBVcGRhdGUgYWN0aW9uLiIKICBpZiAhIGNvbnRhaW5lcl9vdXJzOyB0aGVuCiAgICBzYXkgIndoZXJkcjogdGhlIFwiJENPTlRBSU5FUlwiIGNvbnRhaW5lciBiZWxvbmdzIHRvICQoY29udGFpbmVyX2Rpcik7IHN0YXJ0IGl0IGZyb20gdGhlcmUuIE5vdGhpbmcgZG9uZS4iCiAgICBleGl0IDAKICBmaQogICMgQ3JlYXRlZCBhcyB0aGlzIHVzZXIgZmlyc3Q6IERvY2tlciB3b3VsZCBjcmVhdGUgbWlzc2luZyBiaW5kIG1vdW50cyBhcyByb290LgogIG1rZGlyIC1wICIkRElSL2RhdGEiICIkSE9NRS8uY29uZmlnL2hlcmRyIiAiJEhPTUUvLmxvY2FsL3N0YXRlL2hlcmRyL2NsaWVudCIgXAogICAgIiRIT01FLy5jYWNoZS9oZXJkci13ZWIiICIkSE9NRS8uaGVyZHItcHJvamVjdHMiCiAgY29tcG9zZSB1cCAtZCAtLXJlbW92ZS1vcnBoYW5zCiAgb2sgImNvbnRhaW5lciBzdGFydGVkIgp9Cgpsb2dfaGludCgpIHsgZWNobyAiY2QgJERJUiAmJiBkb2NrZXIgY29tcG9zZSBsb2dzIjsgfQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHN0b3AKY21kX3N0b3AoKSB7CiAgY2FzZSAiJE1PREUiIGluCiAgICBuYXRpdmUpIGNsaSBzdG9wOyByZXR1cm4gMCA7OwogICAgZG9ja2VyKQogICAgICBpZiBbIC1uICIkKGNvbnRhaW5lcl9kaXIpIiBdICYmIGNvbnRhaW5lcl9vdXJzOyB0aGVuCiAgICAgICAgY29tcG9zZSBzdG9wCiAgICAgICAgc2F5ICJ3aGVyZHIgc3RvcHBlZCAoY29udGFpbmVyICRDT05UQUlORVIpLiIKICAgICAgICByZXR1cm4gMAogICAgICBmaQogICAgICA7OwogIGVzYWMKICBpZiBhbnN3ZXJzOyB0aGVuCiAgICBzYXkgIndoZXJkciBvbiBwb3J0ICRQT1JUIHdhcyBub3Qgc3RhcnRlZCBieSB0aGlzIHBsdWdpbjogbGVmdCBydW5uaW5nLiIKICBlbHNlCiAgICBzYXkgIndoZXJkciBpcyBub3QgcnVubmluZy4iCiAgZmkKfQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBzdGF0dXMKY21kX3N0YXR1cygpIHsKICBpZiBbICIkTU9ERSIgPSAibmF0aXZlIiBdOyB0aGVuCiAgICBjbGkgc3RhdHVzCiAgICBzYXkgIiAgUGx1Z2luICAgbmF0aXZlIG1vZGUsIHNldHRpbmdzIGluICRDT05GIgogICAgcmV0dXJuIDAKICBmaQogIHNheSAiTW9kZTogICAgJHtNT0RFOi1ub3Qgc2V0IHVwfSIKICBzYXkgIkZvbGRlcjogICRESVIiCiAgaWYgYW5zd2VyczsgdGhlbiBzYXkgIlBvcnQ6ICAgICRQT1JUIGFuc3dlcnMgKCRVUkwpIjsgZWxzZSBzYXkgIlBvcnQ6ICAgICRQT1JUIGZyZWUiOyBmaQogIGlmIFsgIiRNT0RFIiA9ICJkb2NrZXIiIF07IHRoZW4KICAgIG93bmVyPSIkKGNvbnRhaW5lcl9kaXIpIgogICAgaWYgWyAteiAiJG93bmVyIiBdOyB0aGVuIHNheSAiQ29udGFpbmVyOiBub25lIgogICAgZWxpZiBjb250YWluZXJfb3VyczsgdGhlbiBzYXkgIkNvbnRhaW5lcjogJENPTlRBSU5FUiAoJChkb2NrZXIgaW5zcGVjdCAiJENPTlRBSU5FUiIgLS1mb3JtYXQgJ3t7LlN0YXRlLlN0YXR1c319JyAyPi9kZXYvbnVsbCkpLCBtYW5hZ2VkIGJ5IHRoZSBwbHVnaW4iCiAgICBlbHNlIHNheSAiQ29udGFpbmVyOiAkQ09OVEFJTkVSLCBtYW5hZ2VkIGZyb20gJG93bmVyIChsZWZ0IGFsb25lKSIKICAgIGZpCiAgZmkKfQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGxvZ3MsIGRvY3RvcgpjbWRfbG9ncygpIHsKICBjYXNlICIkTU9ERSIgaW4KICAgIG5hdGl2ZSkgY2xpIGxvZ3MgLS1mb2xsb3cgOzsKICAgIGRvY2tlcikgY29tcG9zZSBsb2dzIC0tZm9sbG93IC0tdGFpbCAxMDAgOzsKICAgICopIGRpZSAid2hlcmRyIHBsdWdpbiBpcyBub3Qgc2V0IHVwOiBpbnN0YWxsIGl0IGFnYWluIHdpdGggaGVyZHIgcGx1Z2luIGluc3RhbGwgJFNPVVJDRS4iIDs7CiAgZXNhYwp9CgpjbWRfZG9jdG9yKCkgewogIGlmIFsgIiRNT0RFIiA9ICJuYXRpdmUiIF07IHRoZW4gY2xpIGRvY3RvcjsgZWxzZSBjbWRfc3RhdHVzOyBmaQp9CgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gb3BlbgojIFRoZSBkZWZhdWx0IGJyb3dzZXIsIG9uIGEgY29tcHV0ZXIgd2l0aCBhIHNjcmVlbiBvbmx5OiBgb3BlbmAgb24gbWFjT1MsCiMgYHhkZy1vcGVuYCBvbiBMaW51eCB3aXRoIGEgZGlzcGxheS4gRmFpbHMgKG9wZW5zIG5vdGhpbmcpIG9uIGEgaGVhZGxlc3Mgc2VydmVyLAojIG9yIHdpdGggV0hFUkRSX05PX0JST1dTRVI9MSAoc2V0IGJ5IGh0dHBzOi8vd2hlcmRyLmRldi9pbnN0YWxsIG92ZXIgU1NIKS4Kb3Blbl9icm93c2VyKCkgewogIGlmIFsgIiR7V0hFUkRSX05PX0JST1dTRVI6LTB9IiA9ICIxIiBdOyB0aGVuIHJldHVybiAxCiAgZWxpZiBbICIkKHVuYW1lIC1zKSIgPSAiRGFyd2luIiBdICYmIGNvbW1hbmQgLXYgb3BlbiA+L2Rldi9udWxsIDI+JjE7IHRoZW4gb3BlbiAiJDEiCiAgZWxpZiBbIC1uICIke0RJU1BMQVk6LX0ke1dBWUxBTkRfRElTUExBWTotfSIgXSAmJiBjb21tYW5kIC12IHhkZy1vcGVuID4vZGV2L251bGwgMj4mMTsgdGhlbiB4ZGctb3BlbiAiJDEiID4vZGV2L251bGwgMj4mMSAmCiAgZWxzZSByZXR1cm4gMQogIGZpCn0KCiMgVGhlIHRhaWxzY2FsZSBDTEk6IG9uIHRoZSBQQVRILCBvciBpbnNpZGUgdGhlIG1hY09TIGFwcC4KdGFpbHNjYWxlX2JpbigpIHsKICBpZiBjb21tYW5kIC12IHRhaWxzY2FsZSA+L2Rldi9udWxsIDI+JjE7IHRoZW4gY29tbWFuZCAtdiB0YWlsc2NhbGUKICBlbGlmIFsgLXggL0FwcGxpY2F0aW9ucy9UYWlsc2NhbGUuYXBwL0NvbnRlbnRzL01hY09TL1RhaWxzY2FsZSBdOyB0aGVuIGVjaG8gL0FwcGxpY2F0aW9ucy9UYWlsc2NhbGUuYXBwL0NvbnRlbnRzL01hY09TL1RhaWxzY2FsZQogIGVsc2UgcmV0dXJuIDEKICBmaQp9CgojICI8bWFjaGluZT4uPHRhaWxuZXQ+LnRzLm5ldFs6cG9ydF0iIG9mIHRoZSBhZGRyZXNzIGB0YWlsc2NhbGUgc2VydmVgCiMgcHVibGlzaGVzIGZvciB3aGVyZHIncyBsb2NhbCBwb3J0LCByZWFkIGZyb20gVGFpbHNjYWxlIG9uIHRoaXMgbWFjaGluZS4Kc2VydmVkX2hvc3QoKSB7CiAgdHM9IiQodGFpbHNjYWxlX2JpbikiIHx8IHJldHVybiAxCiAgIyAiPG5hbWU+OjxodHRwcyBwb3J0PiIgb2YgdGhlIFdlYiBlbnRyeSB3aG9zZSBwcm94eSB0YXJnZXRzIG91ciBwb3J0LgogIGhvc3Q9IiQoIiR0cyIgc2VydmUgc3RhdHVzIC0tanNvbiAyPi9kZXYvbnVsbCB8IHRyICd7LCcgJ1xuXG4nIHwgYXdrIC12IHBvcnQ9IiRQT1JUIiAnCiAgICAvIlteIl0qOlswLTldKyJbIFx0XSo6WyBcdF0qJC8geyBrZXkgPSAkMDsgc3ViKC9eW14iXSoiLywgIiIsIGtleSk7IHN1YigvIi4qJC8sICIiLCBrZXkpIH0KICAgIC8iUHJveHkiLyAmJiAkMCB+ICgiXCIoaHR0cHM/Oi8vKT8oMTI3XFwuMFxcLjBcXC4xfGxvY2FsaG9zdCk6IiBwb3J0ICIvP1wiIikgeyBwcmludCBrZXk7IGV4aXQgfScpIgogIFsgLW4gIiRob3N0IiBdIHx8IHJldHVybiAxCiAgcHJpbnRmICclc1xuJyAiJHtob3N0JTo0NDN9Igp9CgojIHdoZXJkciBhZG9wdHMgdGhlIGFkZHJlc3MgYHRhaWxzY2FsZSBzZXJ2ZWAgcHVibGlzaGVzIGJ5IGl0c2VsZjogYSBsb2NhbAojIHJlcXVlc3QgbWFrZXMgaXQgcmVhZCBUYWlsc2NhbGUgYWdhaW4gYXQgb25jZS4gQSBjb250YWluZXIgc3RhcnRlZCB3aXRob3V0CiMgVGFpbHNjYWxlJ3Mgc29ja2V0IChhbiBvbGRlciBkb2NrZXItY29tcG9zZS55bWwpIGNhbm5vdCByZWFkIGl0OiB0aGUgYWRkcmVzcwojIHJlYWQgaGVyZSwgb24gdGhlIGhvc3QsIGlzIHNlbnQgdG8gaXQgaW5zdGVhZC4gQm90aCBvbmx5IHdvcmsgZnJvbSB0aGlzCiMgbWFjaGluZSAoc2VydmVyL3V0aWxzL3Bob25lLnRzLCBwaG9uZUFjY2VzcykuCmFkb3B0X2FkZHJlc3MoKSB7CiAgY29tbWFuZCAtdiBjdXJsID4vZGV2L251bGwgMj4mMSB8fCByZXR1cm4gMAogIGN1cmwgLXMgLW8gL2Rldi9udWxsIC0tbWF4LXRpbWUgMjAgLUggJ2NvbnRlbnQtdHlwZTogYXBwbGljYXRpb24vanNvbicgXAogICAgLWQgIntcImFjdGlvblwiOlwiYWRkcmVzc1wiLFwidXJsXCI6XCJodHRwczovLyQxL1wifSIgImh0dHA6Ly8xMjcuMC4wLjE6JFBPUlQvYXBpL3Bob25lIiAyPi9kZXYvbnVsbCB8fCB0cnVlCn0KCiMgRG9lcyB0aGUgcGhvbmUgYWRkcmVzcyBhbnN3ZXI/ICJvayIgKHdoZXJkciwgYW5kIGl0IGFjY2VwdHMgdGhhdCBhZGRyZXNzKSwKIyAiaG9zdCIgKHdoZXJkciByZWZ1c2VzIHRoYXQgYWRkcmVzcyksIG9yICJub25lIi4gL2FwaS9oZWFsdGggZ29lcyB0aHJvdWdoCiMgd2hlcmRyJ3MgaG9zdCBjaGVjazsgdGhlIHN0YXRpYyBtYW5pZmVzdCBhbnN3ZXJzIGZvciBhbnkgaG9zdCBuYW1lIGFuZCBvbmx5CiMgcmVjb2duaXplcyBhIHdoZXJkciBvbGRlciB0aGFuIHRoYXQgcm91dGUuCnBob25lX3JlYWNoKCkgewogIGNvbW1hbmQgLXYgY3VybCA+L2Rldi9udWxsIDI+JjEgfHwgeyBlY2hvIG5vbmU7IHJldHVybiAwOyB9CiAgYm9keT0iJChjdXJsIC1zIC0tbWF4LXRpbWUgOCAiJHsxfWFwaS9oZWFsdGgiIDI+L2Rldi9udWxsIHx8IHRydWUpIgogIGNhc2UgIiRib2R5IiBpbgogICAgKicibmFtZSI6IndoZXJkciInKikgZWNobyBvayA7OwogICAgKiciY29kZSI6Imhvc3QiJyopIGVjaG8gaG9zdCA7OwogICAgKikgaWYgY3VybCAtZnNTIC0tbWF4LXRpbWUgOCAiJHsxfW1hbmlmZXN0LndlYm1hbmlmZXN0IiAyPi9kZXYvbnVsbCB8IGdyZXAgLXEgd2hlcmRyOyB0aGVuIGVjaG8gb2s7IGVsc2UgZWNobyBub25lOyBmaSA7OwogIGVzYWMKfQoKIyBUaGUgdGFpbG5ldCBhZGRyZXNzIGB0YWlsc2NhbGUgc2VydmVgIGFscmVhZHkgcHVibGlzaGVzIGZvciB3aGVyZHIncyBsb2NhbAojIHBvcnQgKGh0dHBzOi8vPG1hY2hpbmU+Ljx0YWlsbmV0Pi50cy5uZXRbOnBvcnRdKSwgb25seSB3aGVuIGl0IGFuc3dlcnMgbGlrZQojIHdoZXJkci4gUGFzc2tleXMgYXJlIHRpZWQgdG8gdGhlIGFkZHJlc3M6IHRoYXQgaXMgdGhlIG9uZSB0byBvcGVuLgp0YWlsbmV0X2FkZHJlc3MoKSB7CiAgY29tbWFuZCAtdiBjdXJsID4vZGV2L251bGwgMj4mMSB8fCByZXR1cm4gMQogIGhvc3Q9IiQoc2VydmVkX2hvc3QpIiB8fCByZXR1cm4gMQogIGFkb3B0X2FkZHJlc3MgIiRob3N0IgogIFsgIiQocGhvbmVfcmVhY2ggImh0dHBzOi8vJGhvc3QvIikiID0gb2sgXSB8fCByZXR1cm4gMQogIHByaW50ZiAnaHR0cHM6Ly8lc1xuJyAiJGhvc3QiCn0KCiMgVGhlIGFkZHJlc3MgdG8gb3BlbjogdGhlIHRhaWxuZXQgb25lIHdoZW4gcHVibGlzaGVkIGFuZCBhbnN3ZXJpbmcsIGVsc2UgbG9jYWxob3N0LgpvcGVuX2FkZHJlc3MoKSB7IHRhaWxuZXRfYWRkcmVzcyB8fCBwcmludGYgJyVzXG4nICIkVVJMIjsgfQoKY21kX29wZW4oKSB7CiAgYWRkcmVzcz0iJChvcGVuX2FkZHJlc3MpIgogIG9wZW5fYnJvd3NlciAiJGFkZHJlc3MiIHx8IHRydWUKICBzYXkgIiRhZGRyZXNzIgp9CgojIGBhZGRyZXNzYDogd2hhdCBgb3BlbmAgd291bGQgb3Blbiwgd2l0aG91dCBvcGVuaW5nIGl0IChodHRwczovL3doZXJkci5kZXYvaW5zdGFsbCkuCmNtZF9hZGRyZXNzKCkgeyBvcGVuX2FkZHJlc3M7IH0KCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gdXBkYXRlCmNtZF91cGRhdGUoKSB7CiAgY2FzZSAiJE1PREUiIGluCiAgICBkb2NrZXIpCiAgICAgIGNvbnRhaW5lcl9vdXJzIHx8IGRpZSAiVGhlIFwiJENPTlRBSU5FUlwiIGNvbnRhaW5lciBiZWxvbmdzIHRvICQoY29udGFpbmVyX2Rpcik6IHVwZGF0ZSBpdCBmcm9tIHRoZXJlLiIKICAgICAgY29tcG9zZSBwdWxsIC0tcXVpZXQKICAgICAgaWYgWyAiJChkb2NrZXIgaW5zcGVjdCAiJENPTlRBSU5FUiIgLS1mb3JtYXQgJ3t7LlN0YXRlLlJ1bm5pbmd9fScgMj4vZGV2L251bGwpIiA9ICJ0cnVlIiBdOyB0aGVuCiAgICAgICAgY29tcG9zZSB1cCAtZCAtLXJlbW92ZS1vcnBoYW5zCiAgICAgICAgc2F5ICJ3aGVyZHIgdXBkYXRlZCBhbmQgcmVzdGFydGVkLiIKICAgICAgZWxzZQogICAgICAgIHNheSAid2hlcmRyIGltYWdlIHVwZGF0ZWQ7IGl0IHJ1bnMgdGhlIG5ldyB2ZXJzaW9uIGF0IHRoZSBuZXh0IHN0YXJ0LiIKICAgICAgZmkKICAgICAgOzsKICAgIG5hdGl2ZSkKICAgICAgIyBBIG5ldyBjaGVja291dCwgYSBuZXcgY29weSBpbiAkQVBQLCBhbmQgd2hlcmRyIHJlc3RhcnRlZCAoYnVpbGRfc3RhcnQpLgogICAgICBzYXkgIlVwZGF0aW5nIHRoZSB3aGVyZHIgcGx1Z2luIGZyb20gJFNPVVJDReKApiIKICAgICAgIiQoaGVyZHJfYmluKSIgcGx1Z2luIGluc3RhbGwgIiRTT1VSQ0UiIC0teWVzCiAgICAgIDs7CiAgICAqKSBkaWUgIndoZXJkciBwbHVnaW4gaXMgbm90IHNldCB1cDogaW5zdGFsbCBpdCBhZ2FpbiB3aXRoIGhlcmRyIHBsdWdpbiBpbnN0YWxsICRTT1VSQ0UuIiA7OwogIGVzYWMKfQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gcGhvbmUKdGFpbG5ldF9uYW1lKCkgewogIHRzPSIkKHRhaWxzY2FsZV9iaW4pIiB8fCByZXR1cm4gMQogICMgU2VsZiBjb21lcyBiZWZvcmUgUGVlciBpbiBgdGFpbHNjYWxlIHN0YXR1cyAtLWpzb25gOiB0aGUgZmlyc3QgRE5TTmFtZSBpcyB0aGlzIG1hY2hpbmUuCiAgIiR0cyIgc3RhdHVzIC0tanNvbiAyPi9kZXYvbnVsbCB8IHNlZCAtbiAncy8uKiJETlNOYW1lIjogKiJcKFteIl0qXClcLiIuKi9cMS9wJyB8IGhlYWQgLW4gMQp9CgojIFRoZSBwaG9uZSBzZXR1cCBpcyBhIHBhZ2Ugb2YgdGhlIGFwcCAoU2V0dGluZ3Mg4oC6IFBob25lKTsgYHdoZXJkciBwaG9uZWAKIyBwcmludHMgdGhlIHN0YXRlIGFuZCBpdHMgbGluay4gRG9ja2VyIHdpdGhvdXQgTm9kZS5qczogdGhlIHNhbWUgc3RhdGUgZnJvbQojIGhlcmUsIHdoZXJlIHRoZSB0YWlsc2NhbGUgY29tbWFuZCBpczogcHVibGlzaGVkIG9yIG5vdCwgdGhlIGFkZHJlc3MgaGFuZGVkCiMgdG8gd2hlcmRyIChhZG9wdF9hZGRyZXNzKSwgYW5kIHdoZXRoZXIgaXQgYW5zd2Vycy4KY21kX3Bob25lKCkgewogIGlmIFsgIiRNT0RFIiA9ICJuYXRpdmUiIF07IHRoZW4gY2xpIHBob25lOyByZXR1cm4gMDsgZmkKICBzYXkgIiIKICBzYXkgIiAgV0hFUkRSIMK3IFBIT05FIFNFVFVQIgogIHNheSAiIgogIGlmIGFuc3dlcnM7IHRoZW4gc2F5ICIgIOKckyB3aGVyZHIgYW5zd2VycyBvbiAkVVJMIjsgZWxzZSBzYXkgIiAgISB3aGVyZHIgaXMgbm90IHJ1bm5pbmc6IHByZXNzIFMgaW4gdGhlIHdoZXJkciBwYW5lbCBmaXJzdC4iOyBmaQogIHB1Ymxpc2g9InRhaWxzY2FsZSBzZXJ2ZSAtLWJnIC0taHR0cHM9JFBPUlQgaHR0cDovLzEyNy4wLjAuMTokUE9SVCIKICBuYW1lPSIkKHRhaWxuZXRfbmFtZSB8fCB0cnVlKSIKICBob3N0PSIkKHNlcnZlZF9ob3N0IHx8IHRydWUpIgogIGlmIFsgLW4gIiRob3N0IiBdOyB0aGVuCiAgICBwaG9uZT0iaHR0cHM6Ly8kaG9zdC8iCiAgICBhZG9wdF9hZGRyZXNzICIkaG9zdCIKICAgIHJlYWNoPSIkKHBob25lX3JlYWNoICIkcGhvbmUiKSIKICAgIGlmIFsgIiRyZWFjaCIgPSBvayBdOyB0aGVuCiAgICAgIHNheSAiICDinJMgJHBob25lIGFuc3dlcnMiCiAgICAgIHNheSAiIgogICAgICBpZiBjb21tYW5kIC12IHFyZW5jb2RlID4vZGV2L251bGwgMj4mMTsgdGhlbgogICAgICAgIHFyZW5jb2RlIC10IEFOU0lVVEY4IC1tIDIgIiRwaG9uZSIKICAgICAgZWxzZQogICAgICAgIHNheSAiICAoSW5zdGFsbCBxcmVuY29kZSB0byBzaG93IGEgUVIgY29kZSBvZiAkcGhvbmUgaGVyZS4pIgogICAgICBmaQogICAgICBzYXkgIiAgT3BlbiBpdCBvbiB0aGUgcGhvbmUsIGFkZCBpdCB0byB0aGUgaG9tZSBzY3JlZW4sIHRoZW4gaW4gdGhlIGFwcDoiCiAgICAgIHNheSAiICBTZXR0aW5ncyDihpIgRW5hYmxlIG5vdGlmaWNhdGlvbnMsIHRoZW4gU2VjdXJpdHkg4oaSIEVuYWJsZSBwYXNza2V5IGxvY2suIgogICAgZWxpZiBbICIkcmVhY2giID0gaG9zdCBdOyB0aGVuCiAgICAgIHNheSAiICAhIE5vdCByZWFjaGFibGUgZnJvbSB5b3VyIHBob25lIHlldDogd2hlcmRyIGFuc3dlcnMgb24gJHBob25lIGJ1dCByZWZ1c2VzIHRoYXQgYWRkcmVzcy4iCiAgICAgIHNheSAiICAgIFJlc3RhcnQgd2hlcmRyIChYIHRoZW4gUyBpbiB0aGUgcGFuZWwpOiBpdCByZWFkcyBUYWlsc2NhbGUgYXQgc3RhcnR1cC4gVGhlbiBydW4gdGhpcyBhZ2Fpbi4iCiAgICBlbHNlCiAgICAgIHNheSAiICAhIE5vdCByZWFjaGFibGUgZnJvbSB5b3VyIHBob25lIHlldDogJHBob25lIGlzIHB1Ymxpc2hlZCBidXQgZG9lcyBub3QgYW5zd2VyIGxpa2Ugd2hlcmRyLiIKICAgICAgc2F5ICIgICAgQSBuZXcgYWRkcmVzcyBjYW4gdGFrZSBhIG1pbnV0ZSAoSFRUUFMgY2VydGlmaWNhdGUpOyB0aGVuIHJ1biB0aGlzIGFnYWluLiIKICAgIGZpCiAgZWxpZiAhIHRhaWxzY2FsZV9iaW4gPi9kZXYvbnVsbCAyPiYxOyB0aGVuCiAgICBzYXkgIiAgISBUYWlsc2NhbGUgaXMgbm90IGluc3RhbGxlZCBvbiB0aGlzIG1hY2hpbmU6IGh0dHBzOi8vdGFpbHNjYWxlLmNvbS9kb3dubG9hZCIKICAgIHNheSAiICAgIFlvdXIgcGhvbmUgbmVlZHMgaXQgdG9vIChzYW1lIGFjY291bnQpLCB3aXRoIEhUVFBTIGNlcnRpZmljYXRlcyBlbmFibGVkLiIKICBlbGlmIFsgLXogIiRuYW1lIiBdOyB0aGVuCiAgICBzYXkgIiAgISBUYWlsc2NhbGUgaXMgbm90IGNvbm5lY3RlZCBvbiB0aGlzIG1hY2hpbmU6IHRhaWxzY2FsZSB1cCIKICBlbHNlCiAgICBzYXkgIiAgISBOb3QgcmVhY2hhYmxlIGZyb20geW91ciBwaG9uZSB5ZXQ6IHdoZXJkciBpcyBub3QgcHVibGlzaGVkIG9uIHlvdXIgdGFpbG5ldC4iCiAgICBzYXkgIiAgICBQdWJsaXNoIGl0IChwcml2YXRlLCBvbmx5IHlvdXIgVGFpbHNjYWxlIGRldmljZXMpOiIKICAgIHNheSAiICAgICAgJHB1Ymxpc2giCiAgICBzYXkgIiAgICB3aGVyZHIgZW5hYmxlcyBodHRwczovLyRuYW1lOiRQT1JULyBieSBpdHNlbGY7IHJ1biB0aGlzIGFnYWluIGZvciBpdHMgUVIgY29kZS4iCiAgZmkKICBzYXkgIiIKICBzYXkgIiAgR3VpZGU6IGh0dHBzOi8vZ2l0aHViLmNvbS8kU09VUkNFI2luc3RhbGwtaXQtYXMtYW4tYXBwIgp9CgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBzZXJ2aWNlCmNtZF9zZXJ2aWNlKCkgewogIGNhc2UgIiR7MTotfSIgaW4gaW5zdGFsbHx1bmluc3RhbGwpIDs7ICopIGRpZSAidXNhZ2U6ICQwIHNlcnZpY2UgaW5zdGFsbHx1bmluc3RhbGwiIDs7IGVzYWMKICBpZiBbICIkTU9ERSIgPSAiZG9ja2VyIiBdOyB0aGVuCiAgICBzYXkgIndoZXJkciBydW5zIGluIERvY2tlcjogdGhlIGNvbnRhaW5lciBhbHJlYWR5IHN0YXJ0cyB3aXRoIERvY2tlciAocmVzdGFydDogYWx3YXlzKS4iCiAgICByZXR1cm4gMAogIGZpCiAgY2xpIHNlcnZpY2UgIiQxIgogICMgV2l0aG91dCB0aGUgc2VydmljZSwgdGhlIHBsdWdpbiBydW5zIHdoZXJkciBhZ2FpbiAoYW5kIGl0cyBzdGFydHVwIGhvb2sKICAjIHN0YXJ0cyBpdCB3aXRoIEhlcmRyKS4KICBpZiBbICIkMSIgPSAidW5pbnN0YWxsIiBdOyB0aGVuIGNtZF9zdGFydDsgZmkKfQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0ga2V5CiMgQSBIZXJkciBrZXkgdGhhdCBvcGVucyB0aGUgd2hlcmRyIHBhbmVsOiBIZXJkciB2MSBwbHVnaW5zIGhhdmUgbm8gbWVudSwgc28KIyB0aGUgaW5zdGFsbCBhcHBlbmRzIG9uZSBtYXJrZWQgW1trZXlzLmNvbW1hbmRdXSBibG9jayB0byBIZXJkcidzCiMgY29uZmlnLnRvbWwsIG9uIHRoZSBmaXJzdCBmcmVlIGtleSBvZiBIT1RLRVlTIChuZXZlciBvbmUgSGVyZHIgb3IgdGhlIHVzZXIKIyBhbHJlYWR5IGJpbmRzKS4gRXhpc3RpbmcgbGluZXMgYXJlIG5ldmVyIGNoYW5nZWQ6IHRoZSBibG9jayBpcyBvbmx5IGV2ZXIKIyBhcHBlbmRlZCwgdGhlbiByZW1vdmVkIGJ5IGBrZXkgdW5pbnN0YWxsYC4gTm90aGluZyBpcyBhZGRlZCB3aGVuIHRoZSBwYW5lbAojIGFscmVhZHkgaGFzIGEga2V5LCBvciB3aGVuIG5vIGNhbmRpZGF0ZSBpcyBmcmVlLgpIT1RLRVlTPSIke1dIRVJEUl9IT1RLRVlTOi1wcmVmaXgraSBwcmVmaXgrdSBwcmVmaXgreSBwcmVmaXgrbSBwcmVmaXgrYWx0K3d9IgpIRVJEUl9DT05GSUc9IiR7SEVSRFJfQ09ORklHX1BBVEg6LSR7WERHX0NPTkZJR19IT01FOi0kSE9NRS8uY29uZmlnfS9oZXJkci9jb25maWcudG9tbH0iClBMVUdJTl9JRD0iJChwcmludGYgJyVzJyAiJFNPVVJDRSIgfCB0ciAvIC4pIgpQQU5FTF9BQ1RJT049IiRQTFVHSU5fSUQucGFuZWwiCktFWV9CRUdJTj0iIyB3aGVyZHI6IGtleSB0aGF0IG9wZW5zIHRoZSB3aGVyZHIgcGFuZWwgKHJlbW92ZSB0aGlzIGJsb2NrIHRvIHVuYmluZCBpdCkiCktFWV9FTkQ9IiMgZW5kIHdoZXJkciIKCiMgSGVyZHIncyBkZWZhdWx0IGtleW1hcCwgZnJvbSB0aGUgcnVubmluZyBiaW5hcnkgd2hlbiBpdCBjYW4gcHJpbnQgaXQsCiMgb3RoZXJ3aXNlIGFzIG9mIEhlcmRyIDAuOS4zICgibmFtZTxUQUI+a2V5IiBsaW5lcykuCmRlZmF1bHRfa2V5cygpIHsKICBvdXQ9IiQoIiQoaGVyZHJfYmluKSIgLS1kZWZhdWx0LWNvbmZpZyAyPi9kZXYvbnVsbCB8IGF3ayAnCiAgICAvXlxba2V5c1xdLyB7IGsgPSAxOyBuZXh0IH0KICAgIGsgJiYgL15cWy8geyBleGl0IH0KICAgIGsgJiYgbWF0Y2goJDAsIC9eIyBbYS16X10rID0gIlteIl0qIi8pIHsKICAgICAgbGluZSA9IHN1YnN0cigkMCwgMywgUkxFTkdUSCAtIDIpOyBlcSA9IGluZGV4KGxpbmUsICIgPSAiKQogICAgICB2ID0gc3Vic3RyKGxpbmUsIGVxICsgNCk7IHN1YigvIiQvLCAiIiwgdikKICAgICAgaWYgKHYgIT0gIiIpIHByaW50ZiAiJXNcdCVzXG4iLCBzdWJzdHIobGluZSwgMSwgZXEgLSAxKSwgdgogICAgfScpIiB8fCBvdXQ9IiIKICBpZiBbIC1uICIkb3V0IiBdOyB0aGVuIHByaW50ZiAnJXNcbicgIiRvdXQiOyByZXR1cm47IGZpCiAgZm9yIHAgaW4gaGVscDo/IHNldHRpbmdzOnMgZGV0YWNoOnEgcmVsb2FkX2NvbmZpZzpzaGlmdCtyIG9wZW5fbm90aWZpY2F0aW9uX3RhcmdldDpvIFwKICAgIHdvcmtzcGFjZV9waWNrZXI6dyBnb3RvOmcgbmV3X3dvcmtzcGFjZTpzaGlmdCtuIG5ld193b3JrdHJlZTpzaGlmdCtnIHJlbmFtZV93b3Jrc3BhY2U6c2hpZnQrdyBcCiAgICBjbG9zZV93b3Jrc3BhY2U6c2hpZnQrZCBuZXdfdGFiOmMgcmVuYW1lX3RhYjpzaGlmdCt0IHByZXZpb3VzX3RhYjpwIG5leHRfdGFiOm4gXAogICAgY2xvc2VfdGFiOnNoaWZ0K3ggcmVuYW1lX3BhbmU6c2hpZnQrcCBlZGl0X3Njcm9sbGJhY2s6ZSBmb2N1c19wYW5lX2xlZnQ6aCBmb2N1c19wYW5lX2Rvd246aiBcCiAgICBmb2N1c19wYW5lX3VwOmsgZm9jdXNfcGFuZV9yaWdodDpsIGN5Y2xlX3BhbmVfbmV4dDp0YWIgY3ljbGVfcGFuZV9wcmV2aW91czpzaGlmdCt0YWIgXAogICAgc3BsaXRfdmVydGljYWw6diBzcGxpdF9ob3Jpem9udGFsOm1pbnVzIGNsb3NlX3BhbmU6eCB6b29tOnogcmVzaXplX21vZGU6ciB0b2dnbGVfc2lkZWJhcjpiOyBkbwogICAgcHJpbnRmICclc1x0cHJlZml4KyVzXG4nICIke3AlJToqfSIgIiR7cCMqOn0iCiAgZG9uZQp9CgojIE9uZSBsaW5lIG9uIHRoZSBjb25maWc6ICJib3VuZCA8a2V5PiIgd2hlbiBhIFtba2V5cy5jb21tYW5kXV0gYWxyZWFkeSBydW5zCiMgdGhlIHBhbmVsLCBlbHNlICJmcmVlIDxrZXk+IiAoZmlyc3QgZnJlZSBjYW5kaWRhdGUpIG9yICJub25lIi4gQWxzbwojICJvbGQgPGtleT4iIGZvciBhIGJpbmRpbmcgb2YgdGhlIHBhbmVsJ3MgZm9ybWVyIGFjdGlvbiBpZCAoPGlkPi53aGVyZHIpLgprZXlfc2NhbigpIHsKICBkZWZhdWx0cz0iJChkZWZhdWx0X2tleXMpIgogIHsgcHJpbnRmICclc1xuJyAiJGRlZmF1bHRzIjsgcHJpbnRmICdcMDAxXG4nOyBjYXQgIiRIRVJEUl9DT05GSUciIDI+L2Rldi9udWxsOyB9IHwgYXdrIFwKICAgIC12IGNhbmRzPSIkSE9US0VZUyIgLXYgYWN0aW9uPSIkUEFORUxfQUNUSU9OIiAtdiBvbGQ9IiRQTFVHSU5fSUQud2hlcmRyIiAnCiAgICBmdW5jdGlvbiBub3JtKGspIHsKICAgICAgZ3N1YigvWyBcdF0vLCAiIiwgaykKICAgICAgIyAicHJlZml4K1ciIGlzICJwcmVmaXgrc2hpZnQrdyIKICAgICAgaWYgKG1hdGNoKGssIC9cK1tBLVpdJC8pKSBrID0gc3Vic3RyKGssIDEsIFJTVEFSVCkgInNoaWZ0KyIgdG9sb3dlcihzdWJzdHIoaywgUlNUQVJUICsgMSkpCiAgICAgIHJldHVybiB0b2xvd2VyKGspCiAgICB9CiAgICBmdW5jdGlvbiBzdHJpbmdzKHMsIG91dCwgICBuKSB7CiAgICAgIG4gPSAwCiAgICAgIHdoaWxlIChtYXRjaChzLCAvIlteIl0qIi8pKSB7IG91dFsrK25dID0gc3Vic3RyKHMsIFJTVEFSVCArIDEsIFJMRU5HVEggLSAyKTsgcyA9IHN1YnN0cihzLCBSU1RBUlQgKyBSTEVOR1RIKSB9CiAgICAgIHJldHVybiBuCiAgICB9CiAgICBmdW5jdGlvbiBmbHVzaCgpIHsKICAgICAgaWYgKGNrZXkgIT0gIiIgJiYgY21kID09IGFjdGlvbiAmJiBib3VuZCA9PSAiIikgYm91bmQgPSBja2V5CiAgICAgIGlmIChja2V5ICE9ICIiICYmIGNtZCA9PSBvbGQgJiYgb2xka2V5ID09ICIiKSBvbGRrZXkgPSBja2V5CiAgICAgIGNrZXkgPSAiIjsgY21kID0gIiIKICAgIH0KICAgICQwID09ICJcMDAxIiB7IGNvbmYgPSAxOyBuZXh0IH0KICAgICFjb25mIHsgc3BsaXQoJDAsIGQsICJcdCIpOyBkZWZbZFsxXV0gPSBkWzJdOyBuZXh0IH0KICAgIC9eWyBcdF0qXFsvIHsKICAgICAgZmx1c2goKTsgdCA9ICQwOyBzdWIoLyMuKi8sICIiLCB0KTsgZ3N1YigvWyBcdF0vLCAiIiwgdCkKICAgICAgc2VjdCA9IHQgPT0gIltrZXlzXSIgPyAia2V5cyIgOiB0ID09ICJbW2tleXMuY29tbWFuZF1dIiA/ICJjbWQiIDogIiIKICAgICAgbmV4dAogICAgfQogICAgL15bIFx0XSooI3wkKS8geyBuZXh0IH0KICAgIHsKICAgICAgZXEgPSBpbmRleCgkMCwgIj0iKTsgaWYgKCFlcSkgbmV4dAogICAgICBuYW1lID0gc3Vic3RyKCQwLCAxLCBlcSAtIDEpOyBnc3ViKC9bIFx0XS8sICIiLCBuYW1lKTsgdmFsID0gc3Vic3RyKCQwLCBlcSArIDEpCiAgICAgIGlmIChzZWN0ID09ICJrZXlzIikgewogICAgICAgIG92ZXJbbmFtZV0gPSAxOyBuID0gc3RyaW5ncyh2YWwsIHMpCiAgICAgICAgZm9yIChpID0gMTsgaSA8PSBuOyBpKyspIHRha2VuW25vcm0oc1tpXSldID0gMQogICAgICB9IGVsc2UgaWYgKHNlY3QgPT0gImNtZCIgJiYgc3RyaW5ncyh2YWwsIHMpKSB7CiAgICAgICAgaWYgKG5hbWUgPT0gImtleSIpIHsgY2tleSA9IHNbMV07IHRha2VuW25vcm0oc1sxXSldID0gMSB9CiAgICAgICAgaWYgKG5hbWUgPT0gImNvbW1hbmQiKSBjbWQgPSBzWzFdCiAgICAgIH0KICAgIH0KICAgIEVORCB7CiAgICAgIGZsdXNoKCkKICAgICAgaWYgKG9sZGtleSAhPSAiIikgcHJpbnQgIm9sZCAiIG9sZGtleQogICAgICBpZiAoYm91bmQgIT0gIiIpIHsgcHJpbnQgImJvdW5kICIgYm91bmQ7IGV4aXQgfQogICAgICBmb3IgKGEgaW4gZGVmKSBpZiAoIShhIGluIG92ZXIpKSB0YWtlbltub3JtKGRlZlthXSldID0gMQogICAgICBuID0gc3BsaXQoY2FuZHMsIGMsICIgIikKICAgICAgZm9yIChpID0gMTsgaSA8PSBuOyBpKyspIGlmICghKG5vcm0oY1tpXSkgaW4gdGFrZW4pKSB7IHByaW50ICJmcmVlICIgY1tpXTsgZXhpdCB9CiAgICAgIHByaW50ICJub25lIgogICAgfScKfQoKIyBUaGUga2V5IGJvdW5kIHRvIHRoZSBwYW5lbCwgaWYgYW55LgprZXlfYm91bmQoKSB7IGtleV9zY2FuIHwgc2VkIC1uICdzL15ib3VuZCAvL3AnOyB9CgojIEhlcmRyIGFwcGxpZXMga2V5YmluZGluZ3Mgb24gYGhlcmRyIHNlcnZlciByZWxvYWQtY29uZmlnYCAobm8gcmVzdGFydCkuCmtleV9yZWxvYWQoKSB7CiAgaWYgIiQoaGVyZHJfYmluKSIgc2VydmVyIHJlbG9hZC1jb25maWcgPi9kZXYvbnVsbCAyPiYxOyB0aGVuCiAgICB0ZWxsICIgIEhlcmRyIHJlbG9hZGVkIGl0cyBjb25maWc6IG5vIHJlc3RhcnQgbmVlZGVkLiIKICBlbHNlCiAgICB0ZWxsICIgIFJ1biBoZXJkciBzZXJ2ZXIgcmVsb2FkLWNvbmZpZyAob3IgcmVzdGFydCBIZXJkcikgdG8gYXBwbHkgaXQuIgogIGZpCn0KCmNtZF9rZXkoKSB7CiAgY2FzZSAiJHsxOi19IiBpbgogICAgaW5zdGFsbCkKICAgICAgc2Nhbj0iJChrZXlfc2NhbikiCiAgICAgIG9sZD0iJChwcmludGYgJyVzXG4nICIkc2NhbiIgfCBzZWQgLW4gJ3MvXm9sZCAvL3AnKSIKICAgICAgWyAteiAiJG9sZCIgXSB8fCB3YXJuICIkb2xkIHJ1bnMgJFBMVUdJTl9JRC53aGVyZHIsIHJlbmFtZWQgJFBBTkVMX0FDVElPTjogZWRpdCB0aGF0IGxpbmUgb2YgJEhFUkRSX0NPTkZJRy4iCiAgICAgIHJlcz0iJChwcmludGYgJyVzXG4nICIkc2NhbiIgfCBzZWQgJy9eb2xkIC9kJykiCiAgICAgIGNhc2UgIiRyZXMiIGluCiAgICAgICAgYm91bmRcICopIHRlbGwgIlByZXNzICR7cmVzI2JvdW5kIH0gaW4gSGVyZHIgdG8gb3BlbiB0aGUgd2hlcmRyIHBhbmVsLiIgOzsKICAgICAgICBmcmVlXCAqKQogICAgICAgICAga2V5PSIke3JlcyNmcmVlIH0iCiAgICAgICAgICBta2RpciAtcCAiJChkaXJuYW1lICIkSEVSRFJfQ09ORklHIikiCiAgICAgICAgICBibG9jaz0iJChwcmludGYgJyVzXG5bW2tleXMuY29tbWFuZF1dXG5rZXkgPSAiJXMiXG50eXBlID0gInBsdWdpbl9hY3Rpb24iXG5jb21tYW5kID0gIiVzIlxuZGVzY3JpcHRpb24gPSAid2hlcmRyIlxuJXMnIFwKICAgICAgICAgICAgIiRLRVlfQkVHSU4iICIka2V5IiAiJFBBTkVMX0FDVElPTiIgIiRLRVlfRU5EIikiCiAgICAgICAgICBzZXA9IiIKICAgICAgICAgIGlmIFsgLXMgIiRIRVJEUl9DT05GSUciIF07IHRoZW4KICAgICAgICAgICAgc2VwPSIKIgogICAgICAgICAgICAjIEEgbGFzdCBsaW5lIHdpdGhvdXQgaXRzIG5ld2xpbmUgZ2V0cyBvbmUgZmlyc3QuCiAgICAgICAgICAgIFsgIiQodGFpbCAtYyAxICIkSEVSRFJfQ09ORklHIiB8IG9kIC1BbiAtYyB8IHRyIC1kICcgJykiID0gJ1xuJyBdIHx8IHNlcD0iCiRzZXAiCiAgICAgICAgICBmaQogICAgICAgICAgIyBDaGVja2VkIG9uIGEgY29weSBmaXJzdCB3aGVuIHRoaXMgSGVyZHIgY2FuIHZhbGlkYXRlIGEgY29uZmlnOgogICAgICAgICAgIyBhIGNvbmZpZyBIZXJkciB3b3VsZCByZWplY3QgaXMgbmV2ZXIgd3JpdHRlbi4KICAgICAgICAgIHRtcD0iJEhFUkRSX0NPTkZJRy53aGVyZHItY2hlY2sudG9tbCIKICAgICAgICAgIHsgaWYgWyAtZiAiJEhFUkRSX0NPTkZJRyIgXTsgdGhlbiBjYXQgIiRIRVJEUl9DT05GSUciOyBmaTsgcHJpbnRmICclcyVzXG4nICIkc2VwIiAiJGJsb2NrIjsgfSA+ICIkdG1wIgogICAgICAgICAgaWYgIiQoaGVyZHJfYmluKSIgY29uZmlnIC0taGVscCA+L2Rldi9udWxsIDI+JjEgJiYgISBIRVJEUl9DT05GSUdfUEFUSD0iJHRtcCIgIiQoaGVyZHJfYmluKSIgY29uZmlnIGNoZWNrID4vZGV2L251bGwgMj4mMTsgdGhlbgogICAgICAgICAgICBybSAtZiAiJHRtcCIKICAgICAgICAgICAgd2FybiAibm8gSGVyZHIga2V5IGFkZGVkOiAkSEVSRFJfQ09ORklHIHdvdWxkIG5vdCB2YWxpZGF0ZSB3aXRoIGl0IChoZXJkciBjb25maWcgY2hlY2spLiIKICAgICAgICAgICAgcmV0dXJuIDAKICAgICAgICAgIGZpCiAgICAgICAgICBybSAtZiAiJHRtcCIKICAgICAgICAgIHByaW50ZiAnJXMlc1xuJyAiJHNlcCIgIiRibG9jayIgPj4gIiRIRVJEUl9DT05GSUciCiAgICAgICAgICBvayAiSGVyZHIga2V5ICRrZXkgYWRkZWQgdG8gJEhFUkRSX0NPTkZJRyIKICAgICAgICAgIHRlbGwgIlByZXNzICRrZXkgaW4gSGVyZHIgdG8gb3BlbiB0aGUgd2hlcmRyIHBhbmVsLiIKICAgICAgICAgIGtleV9yZWxvYWQKICAgICAgICAgIDs7CiAgICAgICAgKikgd2FybiAibm8gSGVyZHIga2V5IGFkZGVkOiAkSE9US0VZUyBhcmUgYWxsIHRha2VuLiBCaW5kIG9uZSB0byAkUEFORUxfQUNUSU9OICh0eXBlID0gXCJwbHVnaW5fYWN0aW9uXCIpIGluICRIRVJEUl9DT05GSUcuIiA7OwogICAgICBlc2FjCiAgICAgIDs7CiAgICB1bmluc3RhbGwpCiAgICAgIGlmICEgZ3JlcCAtcXhGICIkS0VZX0JFR0lOIiAiJEhFUkRSX0NPTkZJRyIgMj4vZGV2L251bGw7IHRoZW4gb2sgIm5vIHdoZXJkciBrZXkgaW4gJEhFUkRSX0NPTkZJRyI7IHJldHVybiAwOyBmaQogICAgICAjIERyb3BzIHRoZSBtYXJrZWQgYmxvY2sgYW5kIHRoZSBibGFuayBsaW5lIHdyaXR0ZW4gYmVmb3JlIGl0LgogICAgICB0bXA9IiRIRVJEUl9DT05GSUcud2hlcmRyLXRtcCIKICAgICAgYXdrIC12IGI9IiRLRVlfQkVHSU4iIC12IGU9IiRLRVlfRU5EIiAnCiAgICAgICAgJDAgPT0gYiB7IHNraXAgPSAxOyBpZiAoYmxhbmspIGJsYW5rLS07IG5leHQgfQogICAgICAgIHNraXAgeyBpZiAoJDAgPT0gZSkgc2tpcCA9IDA7IG5leHQgfQogICAgICAgICQwID09ICIiIHsgYmxhbmsrKzsgbmV4dCB9CiAgICAgICAgeyB3aGlsZSAoYmxhbmspIHsgcHJpbnQgIiI7IGJsYW5rLS0gfSBwcmludCB9CiAgICAgICAgRU5EIHsgd2hpbGUgKGJsYW5rKSB7IHByaW50ICIiOyBibGFuay0tIH0gfScgIiRIRVJEUl9DT05GSUciID4gIiR0bXAiCiAgICAgICMgUmV3cml0dGVuIGluIHBsYWNlOiB0aGUgZmlsZSBrZWVwcyBpdHMgb3duZXIgYW5kIG1vZGUuCiAgICAgIGNhdCAiJHRtcCIgPiAiJEhFUkRSX0NPTkZJRyIgJiYgcm0gLWYgIiR0bXAiCiAgICAgIG9rICJ3aGVyZHIga2V5IHJlbW92ZWQgZnJvbSAkSEVSRFJfQ09ORklHIgogICAgICBrZXlfcmVsb2FkCiAgICAgIDs7CiAgICBzdGF0dXMpIGI9IiQoa2V5X2JvdW5kKSI7IGlmIFsgLW4gIiRiIiBdOyB0aGVuIHNheSAiJGIiOyBlbHNlIHNheSAibm9uZSI7IGZpIDs7CiAgICAqKSBkaWUgInVzYWdlOiAkMCBrZXkgaW5zdGFsbHx1bmluc3RhbGx8c3RhdHVzIiA7OwogIGVzYWMKfQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gcGFuZWwKIyBUaGUgInBhbmVsIiBhY3Rpb246IG9uZSBwb3B1cCB3aXRoIHRoZSBzdGF0ZSwgT3BlbiB3aGVyZHIsIFNldCB1cCBteSBwaG9uZQojIChvcGVucyBTZXR0aW5ncyDigLogUGhvbmUpIGFuZCB0aGUgb3RoZXIgY29tbWFuZHMgKGJpbi9saWIvcGFuZWwubWpzKSwKIyBkcml2aW5nIHRoaXMgc2NyaXB0LgpjbWRfcGFuZWwoKSB7CiAgY29udHJvbD0iJChwcmludGYgJ1sic2giLCIlcyJdJyAiJChwcmludGYgJyVzJyAiJFJPT1Qvc2NyaXB0cy9oZXJkci1wbHVnaW4uc2giIHwgc2VkICdzL1tcXCJdL1xcJi9nJykiKSIKICBpZiBbICIkTU9ERSIgPSAibmF0aXZlIiBdIHx8IHsgWyAtbiAiJE1PREUiIF0gJiYgUlVOVElNRT0iJChmaW5kX3J1bnRpbWUpIjsgfTsgdGhlbgogICAgV0hFUkRSX0NPTlRST0w9IiRjb250cm9sIiBXSEVSRFJfTU9ERT0iJE1PREUiIFdIRVJEUl9IT1RLRVk9IiQoa2V5X2JvdW5kKSIgY2xpIHBhbmVsCiAgZWxpZiBbIC1uICIkTU9ERSIgXTsgdGhlbgogICAgc2hfcGFuZWwKICBlbHNlCiAgICBkaWUgIndoZXJkciBwbHVnaW4gaXMgbm90IHNldCB1cCAoJENPTkYgaXMgbWlzc2luZyk6IGluc3RhbGwgaXQgYWdhaW4gd2l0aCBoZXJkciBwbHVnaW4gaW5zdGFsbCAkU09VUkNFIC0teWVzLiIKICBmaQp9CgojIERvY2tlciBtb2RlIHdpdGhvdXQgTm9kZS5qczogdGhlIHNhbWUga2V5cywgd2l0aG91dCB0aGUgUVIgY29kZS4Kc2hfcGFuZWwoKSB7CiAgc2F2ZWQ9IiQoc3R0eSAtZykiCiAgdHJhcCAnc3R0eSAiJHNhdmVkIicgRVhJVAogIHdoaWxlIDo7IGRvCiAgICBwcmludGYgJ1wwMzNbSFwwMzNbMkpcbiAgV0hFUkRSXG5cbicKICAgICggY21kX3N0YXR1cyApIHx8IHRydWUKICAgIHByaW50ZiAnXG4gIFMgc3RhcnQgIFggc3RvcCAgUiByZXN0YXJ0ICBPIG9wZW4gIEwgbG9nICBVIHVwZGF0ZSAgUCBwaG9uZSAgUSBxdWl0XG4nCiAgICBwcmludGYgJyAgUmVtb3ZlOiBYLCB0aGVuIHNoICVzIGtleSB1bmluc3RhbGwsIHRoZW4gaGVyZHIgcGx1Z2luIHVuaW5zdGFsbCAlcyAmJiBybSAtcmYgJXNcbicgIiRST09UL3NjcmlwdHMvaGVyZHItcGx1Z2luLnNoIiAiJFBMVUdJTl9JRCIgIiRESVIiCiAgICBzdHR5IC1pY2Fub24gLWVjaG8gbWluIDAgdGltZSA1MAogICAgaz0iJChkZCBicz0xIGNvdW50PTEgMj4vZGV2L251bGwgfHwgdHJ1ZSkiCiAgICBzdHR5ICIkc2F2ZWQiCiAgICBjYXNlICIkayIgaW4KICAgICAgc3xTKSBhY3Q9c3RhcnQgOzsgeHxYKSBhY3Q9c3RvcCA7OyByfFIpIGFjdD1yZXN0YXJ0IDs7IG98TykgYWN0PW9wZW4gOzsKICAgICAgbHxMKSBhY3Q9bG9ncyA7OyB1fFUpIGFjdD11cGRhdGUgOzsgcHxQKSBhY3Q9cGhvbmUgOzsgcXxRKSBicmVhayA7OwogICAgICAqKSBjb250aW51ZSA7OwogICAgZXNhYwogICAgcHJpbnRmICdcMDMzW0hcMDMzWzJKXG4nCiAgICAoIHRyYXAgLSBJTlQ7ICJjbWRfJGFjdCIgKSB8fCB0cnVlCiAgICBwcmludGYgJ1xuICBQcmVzcyBFbnRlciB0byBnbyBiYWNrLiAnCiAgICByZWFkIC1yIF8gfHwgdHJ1ZQogIGRvbmUKfQoKY21kX3Jlc3RhcnQoKSB7IGNtZF9zdG9wOyBjbWRfc3RhcnQ7IH0KCmNhc2UgIiR7MTotfSIgaW4KICBidWlsZCkgY21kX2J1aWxkIDs7CiAgcGFuZWwpIGNtZF9wYW5lbCA7OwogIHN0YXJ0fHN0b3B8cmVzdGFydHxzdGF0dXN8b3BlbnxhZGRyZXNzfHVwZGF0ZXxwaG9uZXxsb2dzfGRvY3RvcikgImNtZF8kMSIgOzsKICBzZXJ2aWNlKSBjbWRfc2VydmljZSAiJHsyOi19IiA7OwogIHNraWxsKSBjbWRfc2tpbGwgIiR7MjotfSIgOzsKICBrZXkpIGNtZF9rZXkgIiR7MjotfSIgOzsKICAqKSBkaWUgInVzYWdlOiAkMCBidWlsZHxwYW5lbHxzdGFydHxzdG9wfHJlc3RhcnR8c3RhdHVzfG9wZW58YWRkcmVzc3x1cGRhdGV8cGhvbmV8bG9nc3xkb2N0b3J8c2VydmljZSBpbnN0YWxsfHVuaW5zdGFsbHxza2lsbCBpbnN0YWxsfHVuaW5zdGFsbHxrZXkgaW5zdGFsbHx1bmluc3RhbGx8c3RhdHVzIiA7Owplc2FjCg==");
|
|
4
|
+
const herdrPlugin = base64ToUint8Array("IyEvYmluL3NoCiMgd2hlcmRyIGFzIGEgSGVyZHIgcGx1Z2luIChoZXJkci1wbHVnaW4udG9tbCk6IGJ1aWxkIChpbnN0YWxsICsgZmlyc3Qgc3RhcnQpLAojIHRoZSBwYW5lbCwgc3RhcnQsIHN0b3AsIHN0YXR1cywgb3BlbiwgdXBkYXRlLCBzZXJ2aWNlLCBza2lsbCwga2V5LgojCiMgICBoZXJkciBwbHVnaW4gaW5zdGFsbCA8b3duZXI+L3doZXJkcgojCiMgVHdvIHdheXMgdG8gcnVuIHdoZXJkciwgcGlja2VkIG9uY2UgYXQgaW5zdGFsbCB0aW1lIGFuZCBrZXB0IGluCiMgJFdIRVJEUl9ESVIvcGx1Z2luLmVudjoKIyAgIGRvY2tlciAgTGludXggd2l0aCBEb2NrZXIgQ29tcG9zZSB2MiB1c2FibGUgYnkgdGhpcyB1c2VyOiB0aGUgcHVibGlzaGVkCiMgICAgICAgICAgIGltYWdlLCBydW4gZnJvbSAkV0hFUkRSX0RJUiBleGFjdGx5IGxpa2UgaHR0cHM6Ly93aGVyZHIuZGV2L2luc3RhbGwuCiMgICBuYXRpdmUgIGV2ZXJ5d2hlcmUgZWxzZSAoYWx3YXlzIG9uIG1hY09TOiBEb2NrZXIgRGVza3RvcCBjYW5ub3QgcmVhY2gKIyAgICAgICAgICAgSGVyZHIncyBVbml4IHNvY2tldCk6IE5vZGUuanMgMjIgKG9yIEJ1bikgcnVucyB0aGUgcHJlYnVpbHQgR2l0SHViCiMgICAgICAgICAgIHBhY2thZ2Ugb2YgdGhpcyB2ZXJzaW9uIChvciBhIGJ1aWxkIG1hZGUgaW4gdGhlIHBsdWdpbiBmb2xkZXIpLAojICAgICAgICAgICBjb3BpZWQgdG8gJFdIRVJEUl9ESVIvYXBwIGFuZCBzdGFydGVkIGRldGFjaGVkIGZyb20gdGhlcmUsIHdpdGgKIyAgICAgICAgICAgaXRzIHBpZCBhbmQgbG9nIGluICRXSEVSRFJfRElSLgojIEhlcmRyIGJ1aWxkcyBhIHBsdWdpbiBpbiBhIHRlbXBvcmFyeSBmb2xkZXIsIHRoZW4gbW92ZXMgaXQ6IGEgc2VydmVyIHN0YXJ0ZWQKIyBmcm9tIHRoZSBjaGVja291dCBkdXJpbmcgdGhlIGJ1aWxkIHdvdWxkIGxvc2UgaXRzIGZpbGVzLiAkV0hFUkRSX0RJUi9hcHAKIyBzdGF5cyBwdXQsIGFjcm9zcyBwbHVnaW4gdXBkYXRlcyB0b28sIHNvIHRoZSBidWlsZCBjYW4gc3RhcnQgd2hlcmRyIGFuZCBhCiMgbG9naW4gc2VydmljZSBjYW4gcG9pbnQgYXQgaXQuCiMgV0hFUkRSX01PREU9bmF0aXZlIChvciBkb2NrZXIpIGluIHRoZSBlbnZpcm9ubWVudCBvZiBgaGVyZHIgcGx1Z2luIGluc3RhbGxgCiMgZm9yY2VzIHRoZSBjaG9pY2U7IGVkaXQgcGx1Z2luLmVudiB0byBjaGFuZ2UgaXQgbGF0ZXIsIHRoZW4gcnVuIFVwZGF0ZS4KIwojIFNhZmV0eSBydWxlczoKIyAgIC0gbm90aGluZyBnbG9iYWwgaXMgaW5zdGFsbGVkLCBubyBzdWRvOyBmaWxlcyBhcmUgb25seSB3cml0dGVuIHRvIHRoZQojICAgICBwbHVnaW4gZm9sZGVyIGFuZCAkV0hFUkRSX0RJUiAoZGVmYXVsdCB+L3doZXJkciksIHBsdXMgdGhlIGZvbGRlcnMgdGhlCiMgICAgIERvY2tlciBzZXR1cCBtb3VudHMgKH4vLmNvbmZpZy9oZXJkciwgfi8uY2FjaGUvaGVyZHItd2Vi4oCmKSwgYW5kIHRoZQojICAgICBsb2dpbiBzZXJ2aWNlIG9ubHkgd2hlbiBhc2tlZCAoa2V5IEEgb2YgdGhlIHBhbmVsKSwgcGx1cyBhICJ3aGVyZHIiCiMgICAgIGxpbmsgaW4gdGhlIGFnZW50cycgdXNlciBza2lsbCBmb2xkZXJzIChzZWUgY21kX3NraWxsKSwgcGx1cyBvbmUgbWFya2VkCiMgICAgIGJsb2NrIGFwcGVuZGVkIHRvIEhlcmRyJ3MgY29uZmlnLnRvbWw6IHRoZSBrZXkgdGhhdCBvcGVucyB0aGUgcGFuZWwKIyAgICAgKHNlZSBjbWRfa2V5KTsKIyAgIC0gdGhlIGluc3RhbGwgc3RhcnRzIHdoZXJkciwgYW5kIEhlcmRyJ3Mgc3RhcnR1cCBob29rIHN0YXJ0cyBpdCBhZ2FpbiwKIyAgICAgYnV0IG9ubHkgd2hlbiBub3RoaW5nIGFuc3dlcnMgb24gdGhlIHBvcnQ6IGEgd2hlcmRyIHN0YXJ0ZWQgYW5vdGhlciB3YXkKIyAgICAgKERvY2tlciwgc3lzdGVtZCwgYnkgaGFuZCkgaXMgbmV2ZXIgdG91Y2hlZCwgbm8gc2Vjb25kIHdoZXJkciBpcyBzdGFydGVkOwojICAgLSBzdG9wIG9ubHkgc3RvcHMgd2hhdCB0aGlzIHBsdWdpbiBzdGFydGVkIChpdHMgcGlkLCBpdHMgbG9naW4gc2VydmljZSwgb3IKIyAgICAgdGhlIGNvbnRhaW5lciBvZiBpdHMgb3duIGNvbXBvc2UgZm9sZGVyKS4KIwojIFVuaW5zdGFsbDogSGVyZHIgaGFzIG5vIHVuaW5zdGFsbCBob29rLiBTdG9wIHdoZXJkciAoYW5kIHJlbW92ZSB0aGUgbG9naW4KIyBzZXJ2aWNlKSBmcm9tIHRoZSBwYW5lbCBmaXJzdCwgdGhlbjoKIyAgIHNoIHNjcmlwdHMvaGVyZHItcGx1Z2luLnNoIHNraWxsIHVuaW5zdGFsbCAgIChpbiB0aGUgcGx1Z2luIGZvbGRlcikKIyAgIHNoIHNjcmlwdHMvaGVyZHItcGx1Z2luLnNoIGtleSB1bmluc3RhbGwgICAgICh0aGUgSGVyZHIga2V5IG9mIHRoZSBwYW5lbCkKIyAgIGhlcmRyIHBsdWdpbiB1bmluc3RhbGwgPG93bmVyPi53aGVyZHIgJiYgcm0gLXJmIH4vd2hlcmRyCiMKIyBTZXR0aW5ncyAoJFdIRVJEUl9ESVIvcGx1Z2luLmVudiwgb3IgdGhlIGVudmlyb25tZW50KToKIyAgIFdIRVJEUl9NT0RFICBkb2NrZXIgfCBuYXRpdmUgICAgICAgIChkZWZhdWx0OiBjaG9zZW4gYXQgaW5zdGFsbCkKIyAgIFdIRVJEUl9QT1JUICBsb2NhbCBwb3J0ICAgICAgICAgICAgICAoZGVmYXVsdDogNzY4MykKIyAgIEFQUF9VUkwgICAgICBwcml2YXRlIEhUVFBTIGFkZHJlc3MgICAobmF0aXZlOyBEb2NrZXIgcmVhZHMgaXRzIC5lbnYpCiMgICBXSEVSRFJfUlVOVElNRSAgYWJzb2x1dGUgcGF0aCBvZiBub2RlIC8gYnVuIChuYXRpdmU7IGZvdW5kIGF0IGluc3RhbGwpCgpzZXQgLWV1CgpST09UPSIkKGNkICIkKGRpcm5hbWUgIiQwIikvLi4iICYmIHB3ZCAtUCkiCiMgQnVpbGQgY29tbWFuZHMgZ2V0IG5vIHBsdWdpbiBlbnZpcm9ubWVudDogdGhlIGZvbGRlciBjaG9zZW4gYXQgaW5zdGFsbAojIHRpbWUgaXMgcmVtZW1iZXJlZCBpbiB0aGUgcGx1Z2luIGNoZWNrb3V0IGZvciB0aGUgcnVudGltZSBjb21tYW5kcy4KaWYgWyAteiAiJHtXSEVSRFJfRElSOi19IiBdICYmIFsgLWYgIiRST09ULy53aGVyZHItZGlyIiBdOyB0aGVuCiAgV0hFUkRSX0RJUj0iJChjYXQgIiRST09ULy53aGVyZHItZGlyIikiCmZpCkRJUj0iJHtXSEVSRFJfRElSOi0kSE9NRS93aGVyZHJ9IgpjYXNlICIkRElSIiBpbiAvKikgOzsgKikgRElSPSIkUFdELyRESVIiIDs7IGVzYWMKQ09ORj0iJERJUi9wbHVnaW4uZW52IgojIE5hdGl2ZSBtb2RlOiB0aGUgaW5zdGFsbGVkIGNvcHkgb2Ygd2hlcmRyIChiaW4gKyBidWlsdCBzZXJ2ZXIpLgpBUFA9IiRESVIvYXBwIgojIEdpdEh1YiBzb3VyY2Ugb2YgdGhpcyBwbHVnaW46IGl0cyBtYW5pZmVzdCBpZCB3aXRoICIvIiBmb3IgIi4iIChvd25lci53aGVyZHIpLgpTT1VSQ0U9IiQoc2VkIC1uICdzL15pZCA9ICJcKC4qXCkiJC9cMS9wJyAiJFJPT1QvaGVyZHItcGx1Z2luLnRvbWwiIHwgaGVhZCAtbiAxIHwgdHIgLiAvKSIKIyBjb250YWluZXJfbmFtZSBvZiB0aGUgY29tcG9zZSBmaWxlICh3aGVyZHIgdW5sZXNzIHlvdSByZW5hbWVkIGl0KS4KQ09OVEFJTkVSPSIkKHNlZCAtbiAncy9eICpjb250YWluZXJfbmFtZTogKi8vcCcgIiRESVIvZG9ja2VyLWNvbXBvc2UueW1sIiAyPi9kZXYvbnVsbCB8IGhlYWQgLW4gMSkiCkNPTlRBSU5FUj0iJHtDT05UQUlORVI6LXdoZXJkcn0iCiMgVGhlIGVudmlyb25tZW50IHdpbnMgb3ZlciBwbHVnaW4uZW52LgpFTlZfTU9ERT0iJHtXSEVSRFJfTU9ERTotfSIgRU5WX1BPUlQ9IiR7V0hFUkRSX1BPUlQ6LX0iIEVOVl9BUFBfVVJMPSIke0FQUF9VUkw6LX0iIEVOVl9SVU5USU1FPSIke1dIRVJEUl9SVU5USU1FOi19IgppZiBbIC1mICIkQ09ORiIgXTsgdGhlbgogICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMTA5MAogIC4gIiRDT05GIgpmaQpNT0RFPSIke0VOVl9NT0RFOi0ke1dIRVJEUl9NT0RFOi19fSIKUE9SVD0iJHtFTlZfUE9SVDotJHtXSEVSRFJfUE9SVDotNzY4M319IgpBUFBfVVJMPSIke0VOVl9BUFBfVVJMOi0ke0FQUF9VUkw6LX19IgojIE5hdGl2ZSBtb2RlOiBhYnNvbHV0ZSBwYXRoIG9mIHRoZSBub2RlIChvciBidW4pIHRoYXQgcnVucyB0aGUgc2VydmVyLiBIZXJkcgojIHJ1bnMgYWN0aW9ucyB3aXRoIGl0cyBzZXJ2ZXIncyBQQVRILCB3aGljaCBvZnRlbiBsYWNrcyBudm0gLyBuIC8gZm5tIGZvbGRlcnMuClJVTlRJTUU9IiR7RU5WX1JVTlRJTUU6LSR7V0hFUkRSX1JVTlRJTUU6LX19IgpVUkw9Imh0dHA6Ly9sb2NhbGhvc3Q6JFBPUlQiCgpzYXkoKSB7IHByaW50ZiAnJXNcbicgIiQqIjsgfQpvaygpIHsgcHJpbnRmICcgIOKckyAlc1xuJyAiJCoiOyB9Cndhcm4oKSB7IHByaW50ZiAnICAhICVzXG4nICIkKiIgPiYyOyB9CmRpZSgpIHsgcHJpbnRmICcgIOKclyAlc1xuJyAiJCoiID4mMjsgZXhpdCAxOyB9CgojIEFueSBIVFRQIGFuc3dlciBjb3VudHMgKGEgbG9ja2VkIHdoZXJkciBhbnN3ZXJzIDQwMSk6IHRoZSBwb3J0IGlzIHRha2VuLgphbnN3ZXJzKCkgewogIGlmIGNvbW1hbmQgLXYgY3VybCA+L2Rldi9udWxsIDI+JjE7IHRoZW4KICAgIGNvZGU9IiQoY3VybCAtcyAtbyAvZGV2L251bGwgLS1tYXgtdGltZSAyIC13ICcle2h0dHBfY29kZX0nICJodHRwOi8vMTI3LjAuMC4xOiRQT1JULyIgMj4vZGV2L251bGwgfHwgdHJ1ZSkiCiAgICBbIC1uICIkY29kZSIgXSAmJiBbICIkY29kZSIgIT0gIjAwMCIgXQogIGVsaWYgY29tbWFuZCAtdiBuYyA+L2Rldi9udWxsIDI+JjE7IHRoZW4KICAgIG5jIC16IDEyNy4wLjAuMSAiJFBPUlQiID4vZGV2L251bGwgMj4mMQogIGVsc2UKICAgIGRpZSAiY3VybCBvciBuYyBpcyBuZWVkZWQgdG8gY2hlY2sgcG9ydCAkUE9SVC4iCiAgZmkKfQoKZG9ja2VyX3VzYWJsZSgpIHsKICBbICIkKHVuYW1lIC1zKSIgPSAiTGludXgiIF0gfHwgcmV0dXJuIDEKICBjb21tYW5kIC12IGRvY2tlciA+L2Rldi9udWxsIDI+JjEgfHwgcmV0dXJuIDEKICBkb2NrZXIgY29tcG9zZSB2ZXJzaW9uID4vZGV2L251bGwgMj4mMSB8fCByZXR1cm4gMQogIGRvY2tlciBpbmZvID4vZGV2L251bGwgMj4mMQp9CgojIE1ham9yIHZlcnNpb24gb2YgYSBub2RlIGJpbmFyeSwgMCB3aGVuIGl0IGlzIG5vdCBvbmUuCm5vZGVfbWFqb3IoKSB7CiAgIiQxIiAtcCAncHJvY2Vzcy52ZXJzaW9ucy5ub2RlLnNwbGl0KCIuIilbMF0nIDI+L2Rldi9udWxsIHx8IGVjaG8gMAp9CgojIEEgdXNhYmxlIHJ1bnRpbWU6IE5vZGUuanMgMjIgb3IgbmV3ZXIsIG9yIEJ1biAoaXQgcnVucyB0aGUgYnVpbHQgc2VydmVyIHRvbykuCnJ1bnRpbWVfb2soKSB7CiAgWyAtbiAiJDEiIF0gJiYgWyAteCAiJDEiIF0gJiYgWyAhIC1kICIkMSIgXSB8fCByZXR1cm4gMQogIGNhc2UgIiQoYmFzZW5hbWUgIiQxIikiIGluCiAgICBidW4pICIkMSIgLS12ZXJzaW9uID4vZGV2L251bGwgMj4mMSA7OwogICAgKikgWyAiJChub2RlX21ham9yICIkMSIpIiAtZ2UgMjIgXSAyPi9kZXYvbnVsbCA7OwogIGVzYWMKfQoKIyBBYnNvbHV0ZSBwYXRoIG9mIHRoZSBydW50aW1lOiBXSEVSRFJfUlVOVElNRSwgdGhlbiBub2RlIG9uIHRoZSBQQVRILCB0aGVuIHRoZQojIHVzdWFsIGluc3RhbGwgZm9sZGVycyAobiwgbnZtLCBWb2x0YSwgZm5tLCBhc2RmLCBIb21lYnJldyksIHRoZW4gQnVuLgojIFByaW50cyBub3RoaW5nIGFuZCBmYWlscyB3aGVuIG5vbmUgaXMgZm91bmQuCmZpbmRfcnVudGltZSgpIHsKICBmb3IgYyBpbiAiJFJVTlRJTUUiICIkKGNvbW1hbmQgLXYgbm9kZSAyPi9kZXYvbnVsbCB8fCB0cnVlKSIgXAogICAgIiRIT01FLy5uL2Jpbi9ub2RlIiAiJHtOX1BSRUZJWDorJE5fUFJFRklYL2Jpbi9ub2RlfSIgXAogICAgJChscyAtZCAiJEhPTUUiLy5udm0vdmVyc2lvbnMvbm9kZS92Ki9iaW4vbm9kZSAyPi9kZXYvbnVsbCB8IHNvcnQgLXIgLVYpIFwKICAgICIkSE9NRS8udm9sdGEvYmluL25vZGUiIFwKICAgICQobHMgLWQgIiRIT01FIi8ubG9jYWwvc2hhcmUvZm5tL25vZGUtdmVyc2lvbnMvKi9pbnN0YWxsYXRpb24vYmluL25vZGUgIiRIT01FIi8uZm5tL25vZGUtdmVyc2lvbnMvKi9pbnN0YWxsYXRpb24vYmluL25vZGUgMj4vZGV2L251bGwgfCBzb3J0IC1yIC1WKSBcCiAgICAiJEhPTUUvLmFzZGYvc2hpbXMvbm9kZSIgL29wdC9ob21lYnJldy9iaW4vbm9kZSAvdXNyL2xvY2FsL2Jpbi9ub2RlIC91c3IvYmluL25vZGUgXAogICAgIiQoY29tbWFuZCAtdiBidW4gMj4vZGV2L251bGwgfHwgdHJ1ZSkiICIkSE9NRS8uYnVuL2Jpbi9idW4iIC9vcHQvaG9tZWJyZXcvYmluL2J1biAvdXNyL2xvY2FsL2Jpbi9idW47IGRvCiAgICBpZiBydW50aW1lX29rICIkYyI7IHRoZW4gZWNobyAiJGMiOyByZXR1cm4gMDsgZmkKICBkb25lCiAgcmV0dXJuIDEKfQoKUlVOVElNRV9IRUxQPSJOb2RlLmpzIDIyIG9yIG5ld2VyIChvciBCdW4pIGlzIHJlcXVpcmVkIHRvIHJ1biB3aGVyZHIgd2l0aG91dCBEb2NrZXIuCiAgICAgSW5zdGFsbCBpdCBmcm9tIGh0dHBzOi8vbm9kZWpzLm9yZywgb3Igc2V0IGl0cyBhYnNvbHV0ZSBwYXRoIGluICRDT05GOgogICAgICAgV0hFUkRSX1JVTlRJTUU9L3BhdGgvdG8vbm9kZSIKCiMgVGhlIG1hY2hpbmUncyBzaG9ydCBuYW1lIChubyBkb21haW4pOiB3aGF0IHRoZSBhcHAgc2hvd3MsIGFuZCB0aGUgY29udGFpbmVyJ3MKIyBob3N0IG5hbWUuIFdpdGhvdXQgaXQgdGhlIGNvbnRhaW5lciB3b3VsZCBiZSBjYWxsZWQgIndoZXJkciIuCnNob3J0X2hvc3QoKSB7CiAgaD0iJChob3N0bmFtZSAyPi9kZXYvbnVsbCB8IGN1dCAtZC4gLWYxKSIKICBlY2hvICIke2g6LXNlcnZlcn0iCn0KCmhlcmRyX2JpbigpIHsKICBpZiBbIC1uICIke0hFUkRSX0JJTl9QQVRIOi19IiBdOyB0aGVuIGVjaG8gIiRIRVJEUl9CSU5fUEFUSCIKICBlbGlmIFsgLXggIiRIT01FLy5sb2NhbC9iaW4vaGVyZHIiIF07IHRoZW4gZWNobyAiJEhPTUUvLmxvY2FsL2Jpbi9oZXJkciIKICBlbHNlIGNvbW1hbmQgLXYgaGVyZHIgMj4vZGV2L251bGwgfHwgZWNobyBoZXJkcgogIGZpCn0KCnJlYWxfZGlyKCkgeyAoY2QgIiQxIiAyPi9kZXYvbnVsbCAmJiBwd2QgLVApIHx8IGVjaG8gIiQxIjsgfQoKIyBDb21wb3NlIGZvbGRlciBvZiB0aGUgYHdoZXJkcmAgY29udGFpbmVyLCBlbXB0eSB3aGVuIHRoZXJlIGlzIG5vbmUuCmNvbnRhaW5lcl9kaXIoKSB7CiAgZG9ja2VyIGluc3BlY3QgIiRDT05UQUlORVIiIC0tZm9ybWF0ICd7eyBpbmRleCAuQ29uZmlnLkxhYmVscyAiY29tLmRvY2tlci5jb21wb3NlLnByb2plY3Qud29ya2luZ19kaXIiIH19JyAyPi9kZXYvbnVsbCB8fCB0cnVlCn0KCiMgVHJ1ZSB3aGVuIHRoZSBgd2hlcmRyYCBjb250YWluZXIgYmVsb25ncyB0byAkRElSIChvciBkb2VzIG5vdCBleGlzdCB5ZXQpLgpjb250YWluZXJfb3VycygpIHsKICBvd25lcj0iJChjb250YWluZXJfZGlyKSIKICBbIC16ICIkb3duZXIiIF0gfHwgWyAiJChyZWFsX2RpciAiJG93bmVyIikiID0gIiQocmVhbF9kaXIgIiRESVIiKSIgXQp9Cgpjb21wb3NlKCkgeyBkb2NrZXIgY29tcG9zZSAtLXByb2plY3QtZGlyZWN0b3J5ICIkRElSIiAtZiAiJERJUi9kb2NrZXItY29tcG9zZS55bWwiICIkQCI7IH0KCndhaXRfdXAoKSB7CiAgaT0wCiAgd2hpbGUgWyAiJGkiIC1sdCAiJHsxOi0zMH0iIF07IGRvCiAgICBpZiBhbnN3ZXJzOyB0aGVuIHJldHVybiAwOyBmaQogICAgaT0kKChpICsgMSkpOyBzbGVlcCAxCiAgZG9uZQogIHJldHVybiAxCn0KCiMgVGhlIGNvbW1hbmRzIG9mIHRoZSBuYXRpdmUgbW9kZTogdGhlIGluc3RhbGxlZCBjb3B5LCBvciB0aGUgY2hlY2tvdXQgaXRzZWxmCiMgKGEgbGlua2VkIHBsdWdpbiBidWlsdCBieSBoYW5kLCBvciBhIHBsdWdpbiBpbnN0YWxsZWQgYmVmb3JlICRBUFAgZXhpc3RlZCkuCmNsaV9yb290KCkgewogIGlmIFsgLWYgIiRBUFAvYmluL3doZXJkci5tanMiIF0gJiYgWyAtZiAiJEFQUC8ub3V0cHV0L3NlcnZlci9pbmRleC5tanMiIF07IHRoZW4gZWNobyAiJEFQUCI7IGVsc2UgZWNobyAiJFJPT1QiOyBmaQp9CgojIFRoZSBwZXJzb24gcnVubmluZyBgaGVyZHIgcGx1Z2luIGluc3RhbGxgIHNlZXMgb25seSBIZXJkcidzIG93biBsaW5lczogdGhlCiMgb3V0cHV0IG9mIGJ1aWxkIGNvbW1hbmRzIGlzIGNhcHR1cmVkLiBJbXBvcnRhbnQgbGluZXMgYWxzbyBnbyB0byB0aGUgdGVybWluYWwuCnRlbGwoKSB7CiAgcHJpbnRmICclc1xuJyAiJCoiCiAgeyBwcmludGYgJyVzXG4nICIkKiIgPiAvZGV2L3R0eTsgfSAyPi9kZXYvbnVsbCB8fCB0cnVlCn0KCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGJ1aWxkCmNtZF9idWlsZCgpIHsKICB0ZWxsICJ3aGVyZHI6IGluc3RhbGxpbmcgaW4gJERJUiIKICAjIEZpcnN0IGluc3RhbGwgKG5vIHBsdWdpbi5lbnYgeWV0KTogdGhlIGJyb3dzZXIgb3BlbnMgb24gdGhlIHNldHVwIGd1aWRlCiAgIyBvbmNlIHdoZXJkciBydW5zLiBVcGRhdGVzIGtlZXAgcGx1Z2luLmVudiBhbmQgb3BlbiBub3RoaW5nLgogIEZJUlNUX0lOU1RBTEw9MAogIFsgLWYgIiRDT05GIiBdIHx8IEZJUlNUX0lOU1RBTEw9MQogIG1rZGlyIC1wICIkRElSIgogIHByaW50ZiAnJXNcbicgIiRESVIiID4gIiRST09ULy53aGVyZHItZGlyIgoKICBpZiBbIC16ICIkTU9ERSIgXTsgdGhlbgogICAgaWYgZG9ja2VyX3VzYWJsZTsgdGhlbiBNT0RFPWRvY2tlcjsgZWxzZSBNT0RFPW5hdGl2ZTsgZmkKICBmaQogIGNhc2UgIiRNT0RFIiBpbgogICAgZG9ja2VyKSBkb2NrZXJfdXNhYmxlIHx8IGRpZSAiV0hFUkRSX01PREU9ZG9ja2VyLCBidXQgRG9ja2VyIENvbXBvc2UgdjIgaXMgbm90IHVzYWJsZSBieSAkKGlkIC11bikgb24gdGhpcyBzeXN0ZW0uIiA7OwogICAgbmF0aXZlKSA7OwogICAgKikgZGllICJXSEVSRFJfTU9ERSBtdXN0IGJlIGRvY2tlciBvciBuYXRpdmUgKGdvdDogJE1PREUpLiIgOzsKICBlc2FjCgogIGlmIFsgIiRNT0RFIiA9ICJkb2NrZXIiIF07IHRoZW4gYnVpbGRfZG9ja2VyOyBlbHNlIGJ1aWxkX25hdGl2ZTsgZmkKICAjIFdyaXR0ZW4gbGFzdDogYSBmYWlsZWQgYnVpbGQga2VlcHMgbm8gaGFsZi1tYWRlIGNob2ljZS4gUmV3cml0dGVuIG9uIGVhY2gKICAjIGluc3RhbGwgZnJvbSB0aGUgbWVyZ2VkIHNldHRpbmdzIChlbnZpcm9ubWVudCBvdmVyIHRoZSBwcmV2aW91cyBmaWxlKS4KICB3cml0ZV9jb25mCiAgb2sgInBsdWdpbi5lbnYgd3JpdHRlbiAobW9kZTogJE1PREUpIgogICggY21kX3NraWxsIHJlZnJlc2ggKSB8fCB3YXJuICJ3aGVyZHIgc2tpbGwgbm90IGxpbmtlZCAob3B0aW9uYWwpOiBydW4gJDAgc2tpbGwgaW5zdGFsbCIKICAoIGNtZF9rZXkgaW5zdGFsbCApIHx8IHdhcm4gIm5vIEhlcmRyIGtleSBmb3IgdGhlIHBhbmVsIChvcHRpb25hbCk6IHJ1biAkMCBrZXkgaW5zdGFsbCIKICBidWlsZF9zdGFydAp9CgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBza2lsbAojIEluc3RhbGxhdGlvbiBpcyBzaGFyZWQgd2l0aCBucG0gLyBIb21lYnJldzsgRG9ja2VyIHJlYWRzIHRoZSBwdWxsZWQgaW1hZ2UuCmNtZF9za2lsbCgpIHsKICBjYXNlICIkezE6LX0iIGluCiAgICByZWZyZXNofGluc3RhbGwpCiAgICAgIGlmIFsgIiRNT0RFIiA9IGRvY2tlciBdOyB0aGVuCiAgICAgICAgKCBpbWFnZT0iJChjb21wb3NlIGNvbmZpZyAtLWltYWdlcyBoZXJkci13ZWIgfCBoZWFkIC1uIDEpIgogICAgICAgICAgV0hFUkRSX0RJUj0iJERJUiIgc2ggIiRST09UL2Jpbi9pbnN0YWxsLWRvY2tlci1za2lsbC5zaCIgIiRpbWFnZSIgIiQxIgogICAgICAgICkKICAgICAgZWxzZQogICAgICAgIFdIRVJEUl9ESVI9IiRESVIiIHNoICIkUk9PVC9iaW4vbGliL2luc3RhbGwtc2tpbGwuc2giICIkMSIgIiRST09UIgogICAgICBmaQogICAgICA7OwogICAgdW5pbnN0YWxsKSBXSEVSRFJfRElSPSIkRElSIiBzaCAiJFJPT1QvYmluL2xpYi9pbnN0YWxsLXNraWxsLnNoIiB1bmluc3RhbGwgIiRST09UIiA7OwogICAgKikgZGllICJ1c2FnZTogJDAgc2tpbGwgaW5zdGFsbHx1bmluc3RhbGwiIDs7CiAgZXNhYwp9CgojIExhc3Qgc3RlcCBvZiB0aGUgaW5zdGFsbDogc3RhcnQgd2hlcmRyIChvciByZXN0YXJ0IHRoZSBvbmUgdGhpcyBwbHVnaW4KIyBydW5zLCBvbiBhbiB1cGRhdGUpLiBOZXZlciBmYWlscyB0aGUgaW5zdGFsbDogYSB3aGVyZHIgdGhhdCBjYW5ub3Qgc3RhcnQgaXMKIyByZXBvcnRlZCB3aXRoIHdoYXQgdG8gZG8sIHRoZSBwbHVnaW4gc3RheXMgaW5zdGFsbGVkLgpidWlsZF9zdGFydCgpIHsKICBzZXQgK2UKICBvdXQ9IiQoIChjbWRfc3RhcnQpIDI+JjEgKSIKICBjb2RlPSQ/CiAgc2V0IC1lCiAgcHJpbnRmICclc1xuJyAiJG91dCIKICBpZiBbICIkY29kZSIgLWVxIDAgXSAmJiBhbnN3ZXJzOyB0aGVuCiAgICAjIGh0dHBzOi8vd2hlcmRyLmRldi9pbnN0YWxsIHByaW50cyBpdHMgb3duIHN1bW1hcnkgKFdIRVJEUl9JTlNUQUxMRVI9MSkuCiAgICBxdWlldD0wCiAgICBbICIke1dIRVJEUl9JTlNUQUxMRVI6LTB9IiA9IDEgXSAmJiBxdWlldD0xCiAgICBbICIkcXVpZXQiID0gMSBdIHx8IHRlbGwgIiIKICAgIFsgIiRxdWlldCIgPSAxIF0gfHwgdGVsbCAi4pyTIHdoZXJkciBpcyBydW5uaW5nIOKGkiAkVVJMIgogICAgaWYgWyAiJHF1aWV0IiAhPSAxIF07IHRoZW4KICAgICAga2V5PSIkKGtleV9ib3VuZCkiCiAgICAgIGlmIFsgLW4gIiRrZXkiIF07IHRoZW4gdGVsbCAiICBJbiBIZXJkciwgJGtleSBvcGVucyB0aGUgd2hlcmRyIHBhbmVsLiIKICAgICAgZWxzZSB0ZWxsICIgIEluIEhlcmRyOiBoZXJkciBwbHVnaW4gYWN0aW9uIGludm9rZSBwYW5lbCAtLXBsdWdpbiAkUExVR0lOX0lEIgogICAgICBmaQogICAgZmkKICAgIGlmIFsgIiR7RklSU1RfSU5TVEFMTDotMH0iID0gMSBdOyB0aGVuCiAgICAgICMgQWxyZWFkeSBwdWJsaXNoZWQgb24gdGhlIHRhaWxuZXQgKGEgcmVpbnN0YWxsLCBvciBgdGFpbHNjYWxlIHNlcnZlYAogICAgICAjIHJ1biBmaXJzdCk6IHRoZSBndWlkZSBvcGVucyBvbiB0aGF0IGFkZHJlc3MsIHdoZXJlIHBhc3NrZXlzIGJlbG9uZy4KICAgICAgZ3VpZGU9IiQob3Blbl9hZGRyZXNzKS8jL3NldHVwIgogICAgICBpZiBvcGVuX2Jyb3dzZXIgIiRndWlkZSI7IHRoZW4gWyAiJHF1aWV0IiA9IDEgXSB8fCB0ZWxsICIgIFNldHVwIGd1aWRlIG9wZW5lZCBpbiB5b3VyIGJyb3dzZXI6ICRndWlkZSIKICAgICAgZWxzZSBbICIkcXVpZXQiID0gMSBdIHx8IHRlbGwgIiAgU2V0dXAgZ3VpZGU6IG9wZW4gJGd1aWRlIGluIGEgYnJvd3NlciIKICAgICAgZmkKICAgIGZpCiAgICBbICIkcXVpZXQiID0gMSBdIHx8IHRlbGwgIiAgUGhvbmU6IHByZXNzIFAgaW4gdGhlIHBhbmVsIHRvIGdldCB5b3VyIFRhaWxzY2FsZSBhZGRyZXNzIChwcml2YXRlIG5ldHdvcmsgb25seSkuIgogIGVsc2UKICAgIHRlbGwgIiIKICAgIHRlbGwgIiEgd2hlcmRyIGlzIGluc3RhbGxlZCBidXQgZGlkIG5vdCBzdGFydDoiCiAgICBwcmludGYgJyVzXG4nICIkb3V0IiB8IHRhaWwgLW4gOCB8IHdoaWxlIElGUz0gcmVhZCAtciBsOyBkbyB0ZWxsICIgICAgJGwiOyBkb25lCiAgICB0ZWxsICIgIE9wZW4gdGhlIHdoZXJkciBwYW5lbCBpbiBIZXJkciwgdGhlbiBwcmVzcyBTIHRvIHN0YXJ0IGl0IG9yIEwgZm9yIGl0cyBsb2cuIgogIGZpCn0KCndyaXRlX2NvbmYoKSB7CiAgewogICAgZWNobyAiIyB3aGVyZHIgSGVyZHIgcGx1Z2luIHNldHRpbmdzIChoZXJkci1wbHVnaW4uc2gpLiIKICAgIGVjaG8gIiMgVG8gc3dpdGNoIG1vZGUsIHNldCBXSEVSRFJfTU9ERSBhbmQgcnVuOiBoZXJkciBwbHVnaW4gaW5zdGFsbCAkU09VUkNFIgogICAgZWNobyAiV0hFUkRSX01PREU9JE1PREUiCiAgICBlY2hvICJXSEVSRFJfUE9SVD0kUE9SVCIKICAgIGVjaG8gIiMgTmF0aXZlIG1vZGU6IHByaXZhdGUgSFRUUFMgYWRkcmVzcyAodGFpbHNjYWxlIHNlcnZlKSwgZm9yIHB1c2ggbm90aWZpY2F0aW9ucy4iCiAgICBlY2hvICJBUFBfVVJMPSR7QVBQX1VSTDotfSIKICAgIGlmIFsgIiRNT0RFIiA9ICJuYXRpdmUiIF07IHRoZW4KICAgICAgZWNobyAiIyBOYXRpdmUgbW9kZTogYWJzb2x1dGUgcGF0aCBvZiB0aGUgbm9kZSAoMjIrKSBvciBidW4gdGhhdCBydW5zIHdoZXJkci4iCiAgICAgIGVjaG8gIldIRVJEUl9SVU5USU1FPSRSVU5USU1FIgogICAgZmkKICB9ID4gIiRDT05GIgp9CgojIFByZWZlciB0aGUgcmVsZWFzZSBhcmNoaXZlLCB0aGVuIHRoZSBhbHJlYWR5LWJ1aWx0IG5wbSBwYWNrYWdlLiBDb21waWxlIG9ubHkKIyB3aGVuIG5laXRoZXIgc291cmNlIHByb3ZpZGVzIGEgdXNhYmxlIHBhY2thZ2Ugb2YgdGhpcyBleGFjdCB2ZXJzaW9uLgpmZXRjaF9wcmVidWlsdCgpIHsKICBjb21tYW5kIC12IGN1cmwgPi9kZXYvbnVsbCAyPiYxICYmIGNvbW1hbmQgLXYgdGFyID4vZGV2L251bGwgMj4mMSB8fCByZXR1cm4gMQogIHZlcnNpb249IiQoc2VkIC1uICdzL152ZXJzaW9uID0gIlwoLipcKSIkL1wxL3AnICIkUk9PVC9oZXJkci1wbHVnaW4udG9tbCIgfCBoZWFkIC1uIDEpIgogIHRtcD0iJChta3RlbXAgLWQpIgogIGZvciBzb3VyY2UgaW4gZ2l0aHViIG5wbTsgZG8KICAgIHJtIC1yZiAiJHRtcC9wYWNrYWdlIgogICAgaWYgWyAiJHNvdXJjZSIgPSBnaXRodWIgXTsgdGhlbgogICAgICB1cmw9Imh0dHBzOi8vZ2l0aHViLmNvbS8kU09VUkNFL3JlbGVhc2VzL2Rvd25sb2FkL3YkdmVyc2lvbi93aGVyZHItJHZlcnNpb24udGd6IgogICAgICBjdXJsIC1mc1NMIC0tbWF4LXRpbWUgMTIwICIkdXJsIiAtbyAiJHRtcC93aGVyZHIudGd6IiAyPi9kZXYvbnVsbCBcCiAgICAgICAgJiYgY3VybCAtZnNTTCAtLW1heC10aW1lIDMwICIkdXJsLnNoYTI1NiIgLW8gIiR0bXAvY2hlY2tzdW0iIDI+L2Rldi9udWxsIFwKICAgICAgICAmJiAiJFJVTlRJTUUiICIkUk9PVC9iaW4vbGliL3ZlcmlmeS1yZWxlYXNlLm1qcyIgIiR0bXAvd2hlcmRyLnRneiIgIiR0bXAvY2hlY2tzdW0iIDI+L2Rldi9udWxsIHx8IGNvbnRpbnVlCiAgICBlbHNlCiAgICAgIHVybD0iaHR0cHM6Ly9yZWdpc3RyeS5ucG1qcy5vcmcvd2hlcmRyLy0vd2hlcmRyLSR2ZXJzaW9uLnRneiIKICAgICAgY3VybCAtZnNTTCAtLW1heC10aW1lIDEyMCAiJHVybCIgLW8gIiR0bXAvd2hlcmRyLnRneiIgMj4vZGV2L251bGwgXAogICAgICAgICYmIGN1cmwgLWZzU0wgLS1tYXgtdGltZSAzMCAiaHR0cHM6Ly9yZWdpc3RyeS5ucG1qcy5vcmcvd2hlcmRyLyR2ZXJzaW9uIiAtbyAiJHRtcC9tZXRhZGF0YSIgMj4vZGV2L251bGwgXAogICAgICAgICYmICIkUlVOVElNRSIgIiRST09UL2Jpbi9saWIvdmVyaWZ5LXJlbGVhc2UubWpzIiAiJHRtcC93aGVyZHIudGd6IiAiJHRtcC9tZXRhZGF0YSIgbnBtICIkdmVyc2lvbiIgMj4vZGV2L251bGwgfHwgY29udGludWUKICAgIGZpCiAgICB0YXIgLXh6ZiAiJHRtcC93aGVyZHIudGd6IiAtQyAiJHRtcCIgMj4vZGV2L251bGwgfHwgY29udGludWUKICAgIFsgLWYgIiR0bXAvcGFja2FnZS8ub3V0cHV0L3NlcnZlci9pbmRleC5tanMiIF0gXAogICAgICAmJiBbIC1kICIkdG1wL3BhY2thZ2UvYmluIiBdICYmIFsgLWYgIiR0bXAvcGFja2FnZS9wYWNrYWdlLmpzb24iIF0gfHwgY29udGludWUKICAgICMgTGVnYWN5IHBhY2thZ2VzIGhhdmUgbmVpdGhlciB0aGUgc2tpbGwgbm9yIGl0cyBoZWxwZXJzLiBLZWVwIHRoZQogICAgIyBjaGVja291dCdzIGNvbW1hbmRzIHNvIHBsdWdpbiBza2lsbCBpbnN0YWxsL3VuaW5zdGFsbCBzdGlsbCB3b3JrLgogICAgZm9yIGVudHJ5IGluIC5vdXRwdXQgYmluIHBhY2thZ2UuanNvbiBza2lsbHM7IGRvCiAgICAgIFsgLWUgIiR0bXAvcGFja2FnZS8kZW50cnkiIF0gfHwgY29udGludWUKICAgICAgaWYgWyAiJGVudHJ5IiA9IGJpbiBdOyB0aGVuCiAgICAgICAgWyAtZiAiJHRtcC9wYWNrYWdlL3NraWxscy93aGVyZHIvU0tJTEwubWQiIF0gXAogICAgICAgICAgJiYgWyAtZiAiJHRtcC9wYWNrYWdlL2Jpbi9saWIvaW5zdGFsbC1za2lsbC5zaCIgXSB8fCBjb250aW51ZQogICAgICBmaQogICAgICBybSAtcmYgIiRST09ULyRlbnRyeSIKICAgICAgbXYgIiR0bXAvcGFja2FnZS8kZW50cnkiICIkUk9PVC8kZW50cnkiCiAgICBkb25lCiAgICBybSAtcmYgIiR0bXAiCiAgICBvayAid2hlcmRyICR2ZXJzaW9uIGRvd25sb2FkZWQgKCRzb3VyY2UgcGFja2FnZSwgY2hlY2tzdW0gbWF0Y2hlZCkiCiAgICByZXR1cm4gMAogIGRvbmUKICBybSAtcmYgIiR0bXAiCiAgcmV0dXJuIDEKfQoKIyBxcmNvZGUtdGVybWluYWwgKHRoZSBwYW5lbCdzIFFSIGNvZGUpLCB0aGUgb25seSBwYWNrYWdlIHRoZSBjb21tYW5kcyBuZWVkCiMgYXQgcnVudGltZSwgd2hlbiB0aGUgZm9sZGVyIGRvZXMgbm90IGhhdmUgaXQgeWV0IChubyBucG0gY2kgd2FzIHJ1bikuCmZldGNoX3FyKCkgewogIFsgLWYgIiQxL25vZGVfbW9kdWxlcy9xcmNvZGUtdGVybWluYWwvcGFja2FnZS5qc29uIiBdICYmIHJldHVybiAwCiAgY29tbWFuZCAtdiBjdXJsID4vZGV2L251bGwgMj4mMSAmJiBjb21tYW5kIC12IHRhciA+L2Rldi9udWxsIDI+JjEgfHwgcmV0dXJuIDAKICB0bXA9IiQobWt0ZW1wIC1kKSIKICBpZiBjdXJsIC1mc1NMIC0tbWF4LXRpbWUgNjAgaHR0cHM6Ly9yZWdpc3RyeS5ucG1qcy5vcmcvcXJjb2RlLXRlcm1pbmFsLy0vcXJjb2RlLXRlcm1pbmFsLTAuMTIuMC50Z3ogLW8gIiR0bXAvcXIudGd6IiAyPi9kZXYvbnVsbCBcCiAgICAmJiB0YXIgLXh6ZiAiJHRtcC9xci50Z3oiIC1DICIkdG1wIjsgdGhlbgogICAgbWtkaXIgLXAgIiQxL25vZGVfbW9kdWxlcyIKICAgIHJtIC1yZiAiJDEvbm9kZV9tb2R1bGVzL3FyY29kZS10ZXJtaW5hbCIKICAgIG12ICIkdG1wL3BhY2thZ2UiICIkMS9ub2RlX21vZHVsZXMvcXJjb2RlLXRlcm1pbmFsIgogIGVsc2UKICAgIHdhcm4gIk5vIFFSIGNvZGUgaW4gdGhlIHBhbmVsIChxcmNvZGUtdGVybWluYWwgY291bGQgbm90IGJlIGRvd25sb2FkZWQpLiIKICBmaQogIHJtIC1yZiAiJHRtcCIKfQoKYnVpbGRfbmF0aXZlKCkgewogIFJVTlRJTUU9IiQoZmluZF9ydW50aW1lKSIgfHwgZGllICIkUlVOVElNRV9IRUxQIgogIG9rICJSdW50aW1lOiAkUlVOVElNRSAoJCgiJFJVTlRJTUUiIC0tdmVyc2lvbiAyPi9kZXYvbnVsbCkpIgogIGlmIGZldGNoX3ByZWJ1aWx0OyB0aGVuCiAgICBpbnN0YWxsX2FwcAogICAgcmV0dXJuIDAKICBmaQogIGNhc2UgIiQoYmFzZW5hbWUgIiRSVU5USU1FIikiIGluCiAgICBidW4pIGRpZSAiVGhlIHByZWJ1aWx0IHdoZXJkciBwYWNrYWdlIGNvdWxkIG5vdCBiZSBkb3dubG9hZGVkLCBhbmQgYnVpbGRpbmcgaXQgbmVlZHMgTm9kZS5qcyAyMiB3aXRoIG5wbS4KICAgICBDaGVjayB0aGUgbmV0d29yaywgb3IgaW5zdGFsbCBOb2RlLmpzIDIyLCB0aGVuIGluc3RhbGwgdGhlIHBsdWdpbiBhZ2Fpbi4iIDs7CiAgZXNhYwogIGJpbmRpcj0iJChkaXJuYW1lICIkUlVOVElNRSIpIgogIFsgLXggIiRiaW5kaXIvbnBtIiBdIHx8IGNvbW1hbmQgLXYgbnBtID4vZGV2L251bGwgMj4mMSB8fCBkaWUgIm5wbSBpcyBtaXNzaW5nIChpdCBjb21lcyB3aXRoIE5vZGUuanMpLiIKICB0ZWxsICJ3aGVyZHI6IGJ1aWxkaW5nIChhIGZldyBtaW51dGVzIHRoZSBmaXJzdCB0aW1lKeKApiIKICAoCiAgICBjZCAiJFJPT1QiCiAgICBQQVRIPSIkYmluZGlyOiRQQVRIIiBucG0gY2kgLS1uby1hdWRpdCAtLW5vLWZ1bmQKICAgIFBBVEg9IiRiaW5kaXI6JFBBVEgiIG5wbSBydW4gYnVpbGQKICApCiAgb2sgIndoZXJkciBidWlsdCBpbiB0aGUgcGx1Z2luIGZvbGRlciIKICBpbnN0YWxsX2FwcAp9CgojIENvcGllcyB0aGUgY29tbWFuZHMgYW5kIHRoZSBidWlsdCBzZXJ2ZXIgdG8gJEFQUCwgd2hpY2ggb3V0bGl2ZXMgdGhpcwojIGNoZWNrb3V0LiBBIHdoZXJkciB0aGlzIHBsdWdpbiBydW5zIGZyb20gdGhlIHByZXZpb3VzIGNvcHkgaXMgc3RvcHBlZCBmb3IKIyB0aGUgc3dhcDsgYnVpbGRfc3RhcnQgc3RhcnRzIHRoZSBuZXcgb25lLgppbnN0YWxsX2FwcCgpIHsKICAjIE5pdHJvIGxpbmtzIHNvbWUgcGFja2FnZXMgKHRzbGliKSB0byBpdHMgb3duIGZvbGRlcjogY29waWVzLCBub3QgbGlua3MuCiAgaWYgWyAtZCAiJFJPT1QvLm91dHB1dC9zZXJ2ZXIvbm9kZV9tb2R1bGVzIiBdOyB0aGVuICIkUlVOVElNRSIgIiRST09UL3NjcmlwdHMvcGFjay1vdXRwdXQubWpzIiA+L2Rldi9udWxsOyBmaQogIG5ldz0iJEFQUC5uZXciCiAgcm0gLXJmICIkbmV3IgogIG1rZGlyIC1wICIkbmV3IgogIGNwIC1SICIkUk9PVC9iaW4iICIkUk9PVC9za2lsbHMiICIkUk9PVC8ub3V0cHV0IiAiJFJPT1QvcGFja2FnZS5qc29uIiAiJG5ldy8iCiAgaWYgWyAtZCAiJFJPT1Qvbm9kZV9tb2R1bGVzL3FyY29kZS10ZXJtaW5hbCIgXTsgdGhlbgogICAgbWtkaXIgLXAgIiRuZXcvbm9kZV9tb2R1bGVzIgogICAgY3AgLVIgIiRST09UL25vZGVfbW9kdWxlcy9xcmNvZGUtdGVybWluYWwiICIkbmV3L25vZGVfbW9kdWxlcy8iCiAgZmkKICBmZXRjaF9xciAiJG5ldyIKICAjIFRoZSB3aGVyZHIgdGhpcyBwbHVnaW4gcnVucyAoZnJvbSB0aGUgcHJldmlvdXMgY29weSwgb3IgZnJvbSBhbiBvbGRlcgogICMgcGx1Z2luIGNoZWNrb3V0KTogc3RvcHBlZCBmb3IgdGhlIHN3YXAsIHN0YXJ0ZWQgYWdhaW4gYnkgYnVpbGRfc3RhcnQuCiAgaWYgWyAtZiAiJERJUi93aGVyZHIucGlkIiBdIHx8IFsgLWYgIiRBUFAvYmluL3doZXJkci5tanMiIF07IHRoZW4gY2xpIHN0b3AgPi9kZXYvbnVsbCAyPiYxIHx8IHRydWU7IGZpCiAgcm0gLXJmICIkQVBQLm9sZCIKICBpZiBbIC1kICIkQVBQIiBdOyB0aGVuIG12ICIkQVBQIiAiJEFQUC5vbGQiOyBmaQogIG12ICIkbmV3IiAiJEFQUCIKICBybSAtcmYgIiRBUFAub2xkIgogIG9rICJ3aGVyZHIgJChzZWQgLW4gJ3MvXiAqInZlcnNpb24iOiAqIlwoLipcKSIsJC9cMS9wJyAiJEFQUC9wYWNrYWdlLmpzb24iIHwgaGVhZCAtbiAxKSBpbnN0YWxsZWQgaW4gJEFQUCIKfQoKYnVpbGRfZG9ja2VyKCkgewogIG9rICJEb2NrZXIgJChkb2NrZXIgdmVyc2lvbiAtLWZvcm1hdCAne3suU2VydmVyLlZlcnNpb259fScgMj4vZGV2L251bGwgfHwgZWNobyAnPycpIgogIHN0YW1wPSIkRElSLy5jb21wb3NlLWZyb20tcGx1Z2luIgogIGlmIFsgISAtZiAiJERJUi9kb2NrZXItY29tcG9zZS55bWwiIF07IHRoZW4KICAgIGNwICIkUk9PVC9kb2NrZXItY29tcG9zZS55bWwiICIkRElSL2RvY2tlci1jb21wb3NlLnltbCIKICAgIGNrc3VtIDwgIiRESVIvZG9ja2VyLWNvbXBvc2UueW1sIiA+ICIkc3RhbXAiCiAgICBvayAiZG9ja2VyLWNvbXBvc2UueW1sIGNvcGllZCIKICBlbGlmIGNtcCAtcyAiJFJPT1QvZG9ja2VyLWNvbXBvc2UueW1sIiAiJERJUi9kb2NrZXItY29tcG9zZS55bWwiOyB0aGVuCiAgICBvayAiZG9ja2VyLWNvbXBvc2UueW1sIGlzIHVwIHRvIGRhdGUiCiAgZWxpZiBbIC1mICIkc3RhbXAiIF0gJiYgWyAiJChja3N1bSA8ICIkRElSL2RvY2tlci1jb21wb3NlLnltbCIpIiA9ICIkKGNhdCAiJHN0YW1wIikiIF07IHRoZW4KICAgICMgVW5jaGFuZ2VkIHNpbmNlIHRoZSBwbHVnaW4gd3JvdGUgaXQ6IHNhZmUgdG8gcmVmcmVzaC4KICAgIGNwICIkUk9PVC9kb2NrZXItY29tcG9zZS55bWwiICIkRElSL2RvY2tlci1jb21wb3NlLnltbCIKICAgIGNrc3VtIDwgIiRESVIvZG9ja2VyLWNvbXBvc2UueW1sIiA+ICIkc3RhbXAiCiAgICBvayAiZG9ja2VyLWNvbXBvc2UueW1sIHVwZGF0ZWQiCiAgZWxzZQogICAgd2FybiAiS2VlcGluZyB5b3VyIGVkaXRlZCBkb2NrZXItY29tcG9zZS55bWwgKHRoZSBuZXcgb25lIGlzICRST09UL2RvY2tlci1jb21wb3NlLnltbCkuIgogIGZpCiAgaWYgWyAhIC1mICIkRElSLy5lbnYiIF07IHRoZW4KICAgIGhlcmRyPSIkKGhlcmRyX2JpbikiCiAgICB7CiAgICAgIGVjaG8gIiMgd2hlcmRyIHNldHRpbmdzLCByZWFkIGJ5IGRvY2tlciBjb21wb3NlIChzZWUgLmVudi5leGFtcGxlIGluIHRoZSByZXBvc2l0b3J5KS4iCiAgICAgIGVjaG8gIkhPU1RfSE9NRT0kSE9NRSIKICAgICAgZWNobyAiUFVJRD0kKGlkIC11KSIKICAgICAgZWNobyAiUEdJRD0kKGlkIC1nKSIKICAgICAgZWNobyAiUE9SVD0kUE9SVCIKICAgICAgZWNobyAiIyBQcml2YXRlIEhUVFBTIGFkZHJlc3MgKHRhaWxzY2FsZSBzZXJ2ZSksIG5lZWRlZCBmb3IgcHVzaCBub3RpZmljYXRpb25zLiIKICAgICAgZWNobyAiQVBQX1VSTD0ke0FQUF9VUkw6LWh0dHA6Ly9sb2NhbGhvc3Q6JFBPUlQvfSIKICAgICAgZWNobyAiSE9TVF9MQUJFTD0kKHNob3J0X2hvc3QpIgogICAgICBlY2hvICJUWj0ke1RaOi1VVEN9IgogICAgICBpZiBbICIkaGVyZHIiICE9ICIkSE9NRS8ubG9jYWwvYmluL2hlcmRyIiBdOyB0aGVuIGVjaG8gIkhFUkRSX0JJTj0kaGVyZHIiOyBmaQogICAgfSA+ICIkRElSLy5lbnYiCiAgICBvayAiLmVudiBjcmVhdGVkIgogIGVsc2UKICAgIG9rICIuZW52IGtlcHQiCiAgZmkKICBjb21wb3NlIHB1bGwgLS1xdWlldCB8fCBkaWUgIkNvdWxkIG5vdCBwdWxsIHRoZSB3aGVyZHIgaW1hZ2UuIENoZWNrIHRoZSBuZXR3b3JrLCB0aGVuIGluc3RhbGwgdGhlIHBsdWdpbiBhZ2Fpbi4iCiAgb2sgIkltYWdlIHB1bGxlZCIKICAjIFRoZSBwYW5lbCBydW5zIGZyb20gdGhlIGNoZWNrb3V0IHdpdGggbm9kZSB3aGVuIHRoZXJlIGlzIG9uZS4KICBmZXRjaF9xciAiJFJPT1QiCn0KCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHN0YXJ0CmNtZF9zdGFydCgpIHsKICBpZiBhbnN3ZXJzOyB0aGVuCiAgICBzYXkgIndoZXJkcjogc29tZXRoaW5nIGFscmVhZHkgYW5zd2VycyBvbiBwb3J0ICRQT1JULCBub3RoaW5nIHRvIHN0YXJ0ICgkVVJMKS4iCiAgICByZXR1cm4gMAogIGZpCiAgY2FzZSAiJE1PREUiIGluCiAgICBkb2NrZXIpIHN0YXJ0X2RvY2tlciA7OwogICAgbmF0aXZlKSBzdGFydF9uYXRpdmUgOzsKICAgICopIGRpZSAid2hlcmRyIHBsdWdpbiBpcyBub3Qgc2V0IHVwICgkQ09ORiBpcyBtaXNzaW5nKTogaW5zdGFsbCBpdCBhZ2FpbiB3aXRoIGhlcmRyIHBsdWdpbiBpbnN0YWxsICRTT1VSQ0UuIiA7OwogIGVzYWMKICBpZiBbICIkTU9ERSIgPSAibmF0aXZlIiBdOyB0aGVuIHJldHVybiAwOyBmaQogIGlmIHdhaXRfdXAgNDU7IHRoZW4KICAgIHNheSAid2hlcmRyIGlzIHJ1bm5pbmc6ICRVUkwiCiAgZWxzZQogICAgd2FybiAid2hlcmRyIGRvZXMgbm90IGFuc3dlciBvbiBwb3J0ICRQT1JUIHlldC4gTG9nOiAkKGxvZ19oaW50KSIKICAgIGV4aXQgMQogIGZpCn0KCiMgTmF0aXZlIG1vZGU6IHRoZSB3aGVyZHIgY29tbWFuZCAoYmluL3doZXJkci5tanMpIGRvZXMgdGhlIHdvcmssIHdpdGggdGhlCiMgcnVudGltZSBzYXZlZCBhdCBpbnN0YWxsOyBpdCBzYXlzICJzdGFydGVkIiBvbmx5IG9uY2UgdGhlIHBvcnQgYW5zd2Vycy4KZW5zdXJlX3J1bnRpbWUoKSB7CiAgaWYgISBydW50aW1lX29rICIkUlVOVElNRSI7IHRoZW4KICAgIHNhdmVkPSIkUlVOVElNRSIKICAgIFJVTlRJTUU9IiQoZmluZF9ydW50aW1lKSIgfHwgZGllICIke3NhdmVkOitUaGUgc2F2ZWQgcnVudGltZSAoJHNhdmVkKSBpcyBnb25lLiB9JFJVTlRJTUVfSEVMUCIKICAgIHdhcm4gIiR7c2F2ZWQ6KyRzYXZlZCBpcyBnb25lOiB9dXNpbmcgJFJVTlRJTUUgKHNhdmVkIGluICRDT05GKS4iCiAgICB3cml0ZV9jb25mCiAgZmkKfQoKY2xpKCkgewogIGVuc3VyZV9ydW50aW1lCiAgc29jaz0iJHtIRVJEUl9TT0NLRVRfUEFUSDotfSIKICAjIEEgcGx1Z2luIHN0YXJ0ZWQgZnJvbSBhIG5hbWVkIEhlcmRyIHNlc3Npb24gZHJpdmVzIHRoYXQgc2Vzc2lvbi4KICBzZXNzaW9uPSIiCiAgY2FzZSAiJHNvY2siIGluICovc2Vzc2lvbnMvKi9oZXJkci5zb2NrKSBzZXNzaW9uPSIkKGJhc2VuYW1lICIkKGRpcm5hbWUgIiRzb2NrIikiKSIgOzsgZXNhYwogICgKICAgIGNkICIkRElSIgogICAgSEVSRFJfQklOPSIkKGhlcmRyX2JpbikiCiAgICAjIFRoZSBydW50aW1lJ3MgZm9sZGVyIGZpcnN0OiB0b29scyBpdCBzdGFydHMgZmluZCB0aGUgc2FtZSBub2RlLgogICAgUEFUSD0iJChkaXJuYW1lICIkUlVOVElNRSIpOiRQQVRIIgogICAgZXhwb3J0IFBBVEggV0hFUkRSX0RJUj0iJERJUiIgV0hFUkRSX1JVTlRJTUU9IiRSVU5USU1FIiBIT1NUPTEyNy4wLjAuMSBQT1JUIEhFUkRSX0JJTgogICAgaWYgWyAtbiAiJHNlc3Npb24iIF07IHRoZW4gZXhwb3J0IEhFUkRSX1dFQl9TRVNTSU9OPSIkc2Vzc2lvbiI7IGZpCiAgICBpZiBbIC1uICIkc29jayIgXTsgdGhlbiBleHBvcnQgSEVSRFJfU09DSz0iJHNvY2siOyBmaQogICAgaWYgWyAtbiAiJHtBUFBfVVJMOi19IiBdOyB0aGVuIGV4cG9ydCBBUFBfVVJMOyBmaQogICAgZXhlYyAiJFJVTlRJTUUiICIkKGNsaV9yb290KS9iaW4vd2hlcmRyLm1qcyIgIiRAIgogICkKfQoKc3RhcnRfbmF0aXZlKCkgewogIFsgLWYgIiQoY2xpX3Jvb3QpLy5vdXRwdXQvc2VydmVyL2luZGV4Lm1qcyIgXSB8fCBkaWUgIndoZXJkciBpcyBub3QgYnVpbHQ6IGluc3RhbGwgdGhlIHBsdWdpbiBhZ2FpbiAoaGVyZHIgcGx1Z2luIGluc3RhbGwgJFNPVVJDRSAtLXllcykuIgogIG1rZGlyIC1wICIkRElSIgogIGNsaSBzdGFydAp9CgpzdGFydF9kb2NrZXIoKSB7CiAgWyAtZiAiJERJUi9kb2NrZXItY29tcG9zZS55bWwiIF0gfHwgZGllICIkRElSL2RvY2tlci1jb21wb3NlLnltbCBpcyBtaXNzaW5nOiBydW4gdGhlIFVwZGF0ZSBhY3Rpb24uIgogIGlmICEgY29udGFpbmVyX291cnM7IHRoZW4KICAgIHNheSAid2hlcmRyOiB0aGUgXCIkQ09OVEFJTkVSXCIgY29udGFpbmVyIGJlbG9uZ3MgdG8gJChjb250YWluZXJfZGlyKTsgc3RhcnQgaXQgZnJvbSB0aGVyZS4gTm90aGluZyBkb25lLiIKICAgIGV4aXQgMAogIGZpCiAgIyBDcmVhdGVkIGFzIHRoaXMgdXNlciBmaXJzdDogRG9ja2VyIHdvdWxkIGNyZWF0ZSBtaXNzaW5nIGJpbmQgbW91bnRzIGFzIHJvb3QuCiAgbWtkaXIgLXAgIiRESVIvZGF0YSIgIiRIT01FLy5jb25maWcvaGVyZHIiICIkSE9NRS8ubG9jYWwvc3RhdGUvaGVyZHIvY2xpZW50IiBcCiAgICAiJEhPTUUvLmNhY2hlL2hlcmRyLXdlYiIgIiRIT01FLy5oZXJkci1wcm9qZWN0cyIKICBjb21wb3NlIHVwIC1kIC0tcmVtb3ZlLW9ycGhhbnMKICBvayAiY29udGFpbmVyIHN0YXJ0ZWQiCn0KCmxvZ19oaW50KCkgeyBlY2hvICJjZCAkRElSICYmIGRvY2tlciBjb21wb3NlIGxvZ3MiOyB9CgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gc3RvcApjbWRfc3RvcCgpIHsKICBjYXNlICIkTU9ERSIgaW4KICAgIG5hdGl2ZSkgY2xpIHN0b3A7IHJldHVybiAwIDs7CiAgICBkb2NrZXIpCiAgICAgIGlmIFsgLW4gIiQoY29udGFpbmVyX2RpcikiIF0gJiYgY29udGFpbmVyX291cnM7IHRoZW4KICAgICAgICBjb21wb3NlIHN0b3AKICAgICAgICBzYXkgIndoZXJkciBzdG9wcGVkIChjb250YWluZXIgJENPTlRBSU5FUikuIgogICAgICAgIHJldHVybiAwCiAgICAgIGZpCiAgICAgIDs7CiAgZXNhYwogIGlmIGFuc3dlcnM7IHRoZW4KICAgIHNheSAid2hlcmRyIG9uIHBvcnQgJFBPUlQgd2FzIG5vdCBzdGFydGVkIGJ5IHRoaXMgcGx1Z2luOiBsZWZ0IHJ1bm5pbmcuIgogIGVsc2UKICAgIHNheSAid2hlcmRyIGlzIG5vdCBydW5uaW5nLiIKICBmaQp9CgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHN0YXR1cwpjbWRfc3RhdHVzKCkgewogIGlmIFsgIiRNT0RFIiA9ICJuYXRpdmUiIF07IHRoZW4KICAgIGNsaSBzdGF0dXMKICAgIHNheSAiICBQbHVnaW4gICBuYXRpdmUgbW9kZSwgc2V0dGluZ3MgaW4gJENPTkYiCiAgICByZXR1cm4gMAogIGZpCiAgc2F5ICJNb2RlOiAgICAke01PREU6LW5vdCBzZXQgdXB9IgogIHNheSAiRm9sZGVyOiAgJERJUiIKICBpZiBhbnN3ZXJzOyB0aGVuIHNheSAiUG9ydDogICAgJFBPUlQgYW5zd2VycyAoJFVSTCkiOyBlbHNlIHNheSAiUG9ydDogICAgJFBPUlQgZnJlZSI7IGZpCiAgaWYgWyAiJE1PREUiID0gImRvY2tlciIgXTsgdGhlbgogICAgb3duZXI9IiQoY29udGFpbmVyX2RpcikiCiAgICBpZiBbIC16ICIkb3duZXIiIF07IHRoZW4gc2F5ICJDb250YWluZXI6IG5vbmUiCiAgICBlbGlmIGNvbnRhaW5lcl9vdXJzOyB0aGVuIHNheSAiQ29udGFpbmVyOiAkQ09OVEFJTkVSICgkKGRvY2tlciBpbnNwZWN0ICIkQ09OVEFJTkVSIiAtLWZvcm1hdCAne3suU3RhdGUuU3RhdHVzfX0nIDI+L2Rldi9udWxsKSksIG1hbmFnZWQgYnkgdGhlIHBsdWdpbiIKICAgIGVsc2Ugc2F5ICJDb250YWluZXI6ICRDT05UQUlORVIsIG1hbmFnZWQgZnJvbSAkb3duZXIgKGxlZnQgYWxvbmUpIgogICAgZmkKICBmaQp9CgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gbG9ncywgZG9jdG9yCmNtZF9sb2dzKCkgewogIGNhc2UgIiRNT0RFIiBpbgogICAgbmF0aXZlKSBjbGkgbG9ncyAtLWZvbGxvdyA7OwogICAgZG9ja2VyKSBjb21wb3NlIGxvZ3MgLS1mb2xsb3cgLS10YWlsIDEwMCA7OwogICAgKikgZGllICJ3aGVyZHIgcGx1Z2luIGlzIG5vdCBzZXQgdXA6IGluc3RhbGwgaXQgYWdhaW4gd2l0aCBoZXJkciBwbHVnaW4gaW5zdGFsbCAkU09VUkNFLiIgOzsKICBlc2FjCn0KCmNtZF9kb2N0b3IoKSB7CiAgaWYgWyAiJE1PREUiID0gIm5hdGl2ZSIgXTsgdGhlbiBjbGkgZG9jdG9yOyBlbHNlIGNtZF9zdGF0dXM7IGZpCn0KCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBvcGVuCiMgVGhlIGRlZmF1bHQgYnJvd3Nlciwgb24gYSBjb21wdXRlciB3aXRoIGEgc2NyZWVuIG9ubHk6IGBvcGVuYCBvbiBtYWNPUywKIyBgeGRnLW9wZW5gIG9uIExpbnV4IHdpdGggYSBkaXNwbGF5LiBGYWlscyAob3BlbnMgbm90aGluZykgb24gYSBoZWFkbGVzcyBzZXJ2ZXIsCiMgb3Igd2l0aCBXSEVSRFJfTk9fQlJPV1NFUj0xIChzZXQgYnkgaHR0cHM6Ly93aGVyZHIuZGV2L2luc3RhbGwgb3ZlciBTU0gpLgpvcGVuX2Jyb3dzZXIoKSB7CiAgaWYgWyAiJHtXSEVSRFJfTk9fQlJPV1NFUjotMH0iID0gIjEiIF07IHRoZW4gcmV0dXJuIDEKICBlbGlmIFsgIiQodW5hbWUgLXMpIiA9ICJEYXJ3aW4iIF0gJiYgY29tbWFuZCAtdiBvcGVuID4vZGV2L251bGwgMj4mMTsgdGhlbiBvcGVuICIkMSIKICBlbGlmIFsgLW4gIiR7RElTUExBWTotfSR7V0FZTEFORF9ESVNQTEFZOi19IiBdICYmIGNvbW1hbmQgLXYgeGRnLW9wZW4gPi9kZXYvbnVsbCAyPiYxOyB0aGVuIHhkZy1vcGVuICIkMSIgPi9kZXYvbnVsbCAyPiYxICYKICBlbHNlIHJldHVybiAxCiAgZmkKfQoKIyBUaGUgdGFpbHNjYWxlIENMSTogb24gdGhlIFBBVEgsIG9yIGluc2lkZSB0aGUgbWFjT1MgYXBwLgp0YWlsc2NhbGVfYmluKCkgewogIGlmIGNvbW1hbmQgLXYgdGFpbHNjYWxlID4vZGV2L251bGwgMj4mMTsgdGhlbiBjb21tYW5kIC12IHRhaWxzY2FsZQogIGVsaWYgWyAteCAvQXBwbGljYXRpb25zL1RhaWxzY2FsZS5hcHAvQ29udGVudHMvTWFjT1MvVGFpbHNjYWxlIF07IHRoZW4gZWNobyAvQXBwbGljYXRpb25zL1RhaWxzY2FsZS5hcHAvQ29udGVudHMvTWFjT1MvVGFpbHNjYWxlCiAgZWxzZSByZXR1cm4gMQogIGZpCn0KCiMgIjxtYWNoaW5lPi48dGFpbG5ldD4udHMubmV0Wzpwb3J0XSIgb2YgdGhlIGFkZHJlc3MgYHRhaWxzY2FsZSBzZXJ2ZWAKIyBwdWJsaXNoZXMgZm9yIHdoZXJkcidzIGxvY2FsIHBvcnQsIHJlYWQgZnJvbSBUYWlsc2NhbGUgb24gdGhpcyBtYWNoaW5lLgpzZXJ2ZWRfaG9zdCgpIHsKICB0cz0iJCh0YWlsc2NhbGVfYmluKSIgfHwgcmV0dXJuIDEKICAjICI8bmFtZT46PGh0dHBzIHBvcnQ+IiBvZiB0aGUgV2ViIGVudHJ5IHdob3NlIHByb3h5IHRhcmdldHMgb3VyIHBvcnQuCiAgaG9zdD0iJCgiJHRzIiBzZXJ2ZSBzdGF0dXMgLS1qc29uIDI+L2Rldi9udWxsIHwgdHIgJ3ssJyAnXG5cbicgfCBhd2sgLXYgcG9ydD0iJFBPUlQiICcKICAgIC8iW14iXSo6WzAtOV0rIlsgXHRdKjpbIFx0XSokLyB7IGtleSA9ICQwOyBzdWIoL15bXiJdKiIvLCAiIiwga2V5KTsgc3ViKC8iLiokLywgIiIsIGtleSkgfQogICAgLyJQcm94eSIvICYmICQwIH4gKCJcIihodHRwcz86Ly8pPygxMjdcXC4wXFwuMFxcLjF8bG9jYWxob3N0KToiIHBvcnQgIi8/XCIiKSB7IHByaW50IGtleTsgZXhpdCB9JykiCiAgWyAtbiAiJGhvc3QiIF0gfHwgcmV0dXJuIDEKICBwcmludGYgJyVzXG4nICIke2hvc3QlOjQ0M30iCn0KCiMgd2hlcmRyIGFkb3B0cyB0aGUgYWRkcmVzcyBgdGFpbHNjYWxlIHNlcnZlYCBwdWJsaXNoZXMgYnkgaXRzZWxmOiBhIGxvY2FsCiMgcmVxdWVzdCBtYWtlcyBpdCByZWFkIFRhaWxzY2FsZSBhZ2FpbiBhdCBvbmNlLiBBIGNvbnRhaW5lciBzdGFydGVkIHdpdGhvdXQKIyBUYWlsc2NhbGUncyBzb2NrZXQgKGFuIG9sZGVyIGRvY2tlci1jb21wb3NlLnltbCkgY2Fubm90IHJlYWQgaXQ6IHRoZSBhZGRyZXNzCiMgcmVhZCBoZXJlLCBvbiB0aGUgaG9zdCwgaXMgc2VudCB0byBpdCBpbnN0ZWFkLiBCb3RoIG9ubHkgd29yayBmcm9tIHRoaXMKIyBtYWNoaW5lIChzZXJ2ZXIvdXRpbHMvcGhvbmUudHMsIHBob25lQWNjZXNzKS4KYWRvcHRfYWRkcmVzcygpIHsKICBjb21tYW5kIC12IGN1cmwgPi9kZXYvbnVsbCAyPiYxIHx8IHJldHVybiAwCiAgY3VybCAtcyAtbyAvZGV2L251bGwgLS1tYXgtdGltZSAyMCAtSCAnY29udGVudC10eXBlOiBhcHBsaWNhdGlvbi9qc29uJyBcCiAgICAtZCAie1wiYWN0aW9uXCI6XCJhZGRyZXNzXCIsXCJ1cmxcIjpcImh0dHBzOi8vJDEvXCJ9IiAiaHR0cDovLzEyNy4wLjAuMTokUE9SVC9hcGkvcGhvbmUiIDI+L2Rldi9udWxsIHx8IHRydWUKfQoKIyBEb2VzIHRoZSBwaG9uZSBhZGRyZXNzIGFuc3dlcj8gIm9rIiAod2hlcmRyLCBhbmQgaXQgYWNjZXB0cyB0aGF0IGFkZHJlc3MpLAojICJob3N0IiAod2hlcmRyIHJlZnVzZXMgdGhhdCBhZGRyZXNzKSwgb3IgIm5vbmUiLiAvYXBpL2hlYWx0aCBnb2VzIHRocm91Z2gKIyB3aGVyZHIncyBob3N0IGNoZWNrOyB0aGUgc3RhdGljIG1hbmlmZXN0IGFuc3dlcnMgZm9yIGFueSBob3N0IG5hbWUgYW5kIG9ubHkKIyByZWNvZ25pemVzIGEgd2hlcmRyIG9sZGVyIHRoYW4gdGhhdCByb3V0ZS4KcGhvbmVfcmVhY2goKSB7CiAgY29tbWFuZCAtdiBjdXJsID4vZGV2L251bGwgMj4mMSB8fCB7IGVjaG8gbm9uZTsgcmV0dXJuIDA7IH0KICBib2R5PSIkKGN1cmwgLXMgLS1tYXgtdGltZSA4ICIkezF9YXBpL2hlYWx0aCIgMj4vZGV2L251bGwgfHwgdHJ1ZSkiCiAgY2FzZSAiJGJvZHkiIGluCiAgICAqJyJuYW1lIjoid2hlcmRyIicqKSBlY2hvIG9rIDs7CiAgICAqJyJjb2RlIjoiaG9zdCInKikgZWNobyBob3N0IDs7CiAgICAqKSBpZiBjdXJsIC1mc1MgLS1tYXgtdGltZSA4ICIkezF9bWFuaWZlc3Qud2VibWFuaWZlc3QiIDI+L2Rldi9udWxsIHwgZ3JlcCAtcSB3aGVyZHI7IHRoZW4gZWNobyBvazsgZWxzZSBlY2hvIG5vbmU7IGZpIDs7CiAgZXNhYwp9CgojIFRoZSB0YWlsbmV0IGFkZHJlc3MgYHRhaWxzY2FsZSBzZXJ2ZWAgYWxyZWFkeSBwdWJsaXNoZXMgZm9yIHdoZXJkcidzIGxvY2FsCiMgcG9ydCAoaHR0cHM6Ly88bWFjaGluZT4uPHRhaWxuZXQ+LnRzLm5ldFs6cG9ydF0pLCBvbmx5IHdoZW4gaXQgYW5zd2VycyBsaWtlCiMgd2hlcmRyLiBQYXNza2V5cyBhcmUgdGllZCB0byB0aGUgYWRkcmVzczogdGhhdCBpcyB0aGUgb25lIHRvIG9wZW4uCnRhaWxuZXRfYWRkcmVzcygpIHsKICBjb21tYW5kIC12IGN1cmwgPi9kZXYvbnVsbCAyPiYxIHx8IHJldHVybiAxCiAgaG9zdD0iJChzZXJ2ZWRfaG9zdCkiIHx8IHJldHVybiAxCiAgYWRvcHRfYWRkcmVzcyAiJGhvc3QiCiAgWyAiJChwaG9uZV9yZWFjaCAiaHR0cHM6Ly8kaG9zdC8iKSIgPSBvayBdIHx8IHJldHVybiAxCiAgcHJpbnRmICdodHRwczovLyVzXG4nICIkaG9zdCIKfQoKIyBUaGUgYWRkcmVzcyB0byBvcGVuOiB0aGUgdGFpbG5ldCBvbmUgd2hlbiBwdWJsaXNoZWQgYW5kIGFuc3dlcmluZywgZWxzZSBsb2NhbGhvc3QuCm9wZW5fYWRkcmVzcygpIHsgdGFpbG5ldF9hZGRyZXNzIHx8IHByaW50ZiAnJXNcbicgIiRVUkwiOyB9CgpjbWRfb3BlbigpIHsKICBhZGRyZXNzPSIkKG9wZW5fYWRkcmVzcykiCiAgb3Blbl9icm93c2VyICIkYWRkcmVzcyIgfHwgdHJ1ZQogIHNheSAiJGFkZHJlc3MiCn0KCiMgYGFkZHJlc3NgOiB3aGF0IGBvcGVuYCB3b3VsZCBvcGVuLCB3aXRob3V0IG9wZW5pbmcgaXQgKGh0dHBzOi8vd2hlcmRyLmRldi9pbnN0YWxsKS4KY21kX2FkZHJlc3MoKSB7IG9wZW5fYWRkcmVzczsgfQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB1cGRhdGUKY21kX3VwZGF0ZSgpIHsKICBjYXNlICIkTU9ERSIgaW4KICAgIGRvY2tlcikKICAgICAgY29udGFpbmVyX291cnMgfHwgZGllICJUaGUgXCIkQ09OVEFJTkVSXCIgY29udGFpbmVyIGJlbG9uZ3MgdG8gJChjb250YWluZXJfZGlyKTogdXBkYXRlIGl0IGZyb20gdGhlcmUuIgogICAgICBjb21wb3NlIHB1bGwgLS1xdWlldAogICAgICBjbWRfc2tpbGwgcmVmcmVzaCB8fCB3YXJuICJ3aGVyZHIgc2tpbGwgcmVmcmVzaCBmYWlsZWQgKG9wdGlvbmFsKSIKICAgICAgaWYgWyAiJChkb2NrZXIgaW5zcGVjdCAiJENPTlRBSU5FUiIgLS1mb3JtYXQgJ3t7LlN0YXRlLlJ1bm5pbmd9fScgMj4vZGV2L251bGwpIiA9ICJ0cnVlIiBdOyB0aGVuCiAgICAgICAgY29tcG9zZSB1cCAtZCAtLXJlbW92ZS1vcnBoYW5zCiAgICAgICAgc2F5ICJ3aGVyZHIgdXBkYXRlZCBhbmQgcmVzdGFydGVkLiIKICAgICAgZWxzZQogICAgICAgIHNheSAid2hlcmRyIGltYWdlIHVwZGF0ZWQ7IGl0IHJ1bnMgdGhlIG5ldyB2ZXJzaW9uIGF0IHRoZSBuZXh0IHN0YXJ0LiIKICAgICAgZmkKICAgICAgOzsKICAgIG5hdGl2ZSkKICAgICAgIyBBIG5ldyBjaGVja291dCwgYSBuZXcgY29weSBpbiAkQVBQLCBhbmQgd2hlcmRyIHJlc3RhcnRlZCAoYnVpbGRfc3RhcnQpLgogICAgICBzYXkgIlVwZGF0aW5nIHRoZSB3aGVyZHIgcGx1Z2luIGZyb20gJFNPVVJDReKApiIKICAgICAgIiQoaGVyZHJfYmluKSIgcGx1Z2luIGluc3RhbGwgIiRTT1VSQ0UiIC0tcmVmIG1haW4gLS15ZXMKICAgICAgOzsKICAgICopIGRpZSAid2hlcmRyIHBsdWdpbiBpcyBub3Qgc2V0IHVwOiBpbnN0YWxsIGl0IGFnYWluIHdpdGggaGVyZHIgcGx1Z2luIGluc3RhbGwgJFNPVVJDRS4iIDs7CiAgZXNhYwp9CgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBwaG9uZQp0YWlsbmV0X25hbWUoKSB7CiAgdHM9IiQodGFpbHNjYWxlX2JpbikiIHx8IHJldHVybiAxCiAgIyBTZWxmIGNvbWVzIGJlZm9yZSBQZWVyIGluIGB0YWlsc2NhbGUgc3RhdHVzIC0tanNvbmA6IHRoZSBmaXJzdCBETlNOYW1lIGlzIHRoaXMgbWFjaGluZS4KICAiJHRzIiBzdGF0dXMgLS1qc29uIDI+L2Rldi9udWxsIHwgc2VkIC1uICdzLy4qIkROU05hbWUiOiAqIlwoW14iXSpcKVwuIi4qL1wxL3AnIHwgaGVhZCAtbiAxCn0KCiMgVGhlIHBob25lIHNldHVwIGlzIGEgcGFnZSBvZiB0aGUgYXBwIChTZXR0aW5ncyDigLogUGhvbmUpOyBgd2hlcmRyIHBob25lYAojIHByaW50cyB0aGUgc3RhdGUgYW5kIGl0cyBsaW5rLiBEb2NrZXIgd2l0aG91dCBOb2RlLmpzOiB0aGUgc2FtZSBzdGF0ZSBmcm9tCiMgaGVyZSwgd2hlcmUgdGhlIHRhaWxzY2FsZSBjb21tYW5kIGlzOiBwdWJsaXNoZWQgb3Igbm90LCB0aGUgYWRkcmVzcyBoYW5kZWQKIyB0byB3aGVyZHIgKGFkb3B0X2FkZHJlc3MpLCBhbmQgd2hldGhlciBpdCBhbnN3ZXJzLgpjbWRfcGhvbmUoKSB7CiAgaWYgWyAiJE1PREUiID0gIm5hdGl2ZSIgXTsgdGhlbiBjbGkgcGhvbmU7IHJldHVybiAwOyBmaQogIHNheSAiIgogIHNheSAiICBXSEVSRFIgwrcgUEhPTkUgU0VUVVAiCiAgc2F5ICIiCiAgaWYgYW5zd2VyczsgdGhlbiBzYXkgIiAg4pyTIHdoZXJkciBhbnN3ZXJzIG9uICRVUkwiOyBlbHNlIHNheSAiICAhIHdoZXJkciBpcyBub3QgcnVubmluZzogcHJlc3MgUyBpbiB0aGUgd2hlcmRyIHBhbmVsIGZpcnN0LiI7IGZpCiAgcHVibGlzaD0idGFpbHNjYWxlIHNlcnZlIC0tYmcgLS1odHRwcz0kUE9SVCBodHRwOi8vMTI3LjAuMC4xOiRQT1JUIgogIG5hbWU9IiQodGFpbG5ldF9uYW1lIHx8IHRydWUpIgogIGhvc3Q9IiQoc2VydmVkX2hvc3QgfHwgdHJ1ZSkiCiAgaWYgWyAtbiAiJGhvc3QiIF07IHRoZW4KICAgIHBob25lPSJodHRwczovLyRob3N0LyIKICAgIGFkb3B0X2FkZHJlc3MgIiRob3N0IgogICAgcmVhY2g9IiQocGhvbmVfcmVhY2ggIiRwaG9uZSIpIgogICAgaWYgWyAiJHJlYWNoIiA9IG9rIF07IHRoZW4KICAgICAgc2F5ICIgIOKckyAkcGhvbmUgYW5zd2VycyIKICAgICAgc2F5ICIiCiAgICAgIGlmIGNvbW1hbmQgLXYgcXJlbmNvZGUgPi9kZXYvbnVsbCAyPiYxOyB0aGVuCiAgICAgICAgcXJlbmNvZGUgLXQgQU5TSVVURjggLW0gMiAiJHBob25lIgogICAgICBlbHNlCiAgICAgICAgc2F5ICIgIChJbnN0YWxsIHFyZW5jb2RlIHRvIHNob3cgYSBRUiBjb2RlIG9mICRwaG9uZSBoZXJlLikiCiAgICAgIGZpCiAgICAgIHNheSAiICBPcGVuIGl0IG9uIHRoZSBwaG9uZSwgYWRkIGl0IHRvIHRoZSBob21lIHNjcmVlbiwgdGhlbiBpbiB0aGUgYXBwOiIKICAgICAgc2F5ICIgIFNldHRpbmdzIOKGkiBFbmFibGUgbm90aWZpY2F0aW9ucywgdGhlbiBTZWN1cml0eSDihpIgRW5hYmxlIHBhc3NrZXkgbG9jay4iCiAgICBlbGlmIFsgIiRyZWFjaCIgPSBob3N0IF07IHRoZW4KICAgICAgc2F5ICIgICEgTm90IHJlYWNoYWJsZSBmcm9tIHlvdXIgcGhvbmUgeWV0OiB3aGVyZHIgYW5zd2VycyBvbiAkcGhvbmUgYnV0IHJlZnVzZXMgdGhhdCBhZGRyZXNzLiIKICAgICAgc2F5ICIgICAgUmVzdGFydCB3aGVyZHIgKFggdGhlbiBTIGluIHRoZSBwYW5lbCk6IGl0IHJlYWRzIFRhaWxzY2FsZSBhdCBzdGFydHVwLiBUaGVuIHJ1biB0aGlzIGFnYWluLiIKICAgIGVsc2UKICAgICAgc2F5ICIgICEgTm90IHJlYWNoYWJsZSBmcm9tIHlvdXIgcGhvbmUgeWV0OiAkcGhvbmUgaXMgcHVibGlzaGVkIGJ1dCBkb2VzIG5vdCBhbnN3ZXIgbGlrZSB3aGVyZHIuIgogICAgICBzYXkgIiAgICBBIG5ldyBhZGRyZXNzIGNhbiB0YWtlIGEgbWludXRlIChIVFRQUyBjZXJ0aWZpY2F0ZSk7IHRoZW4gcnVuIHRoaXMgYWdhaW4uIgogICAgZmkKICBlbGlmICEgdGFpbHNjYWxlX2JpbiA+L2Rldi9udWxsIDI+JjE7IHRoZW4KICAgIHNheSAiICAhIFRhaWxzY2FsZSBpcyBub3QgaW5zdGFsbGVkIG9uIHRoaXMgbWFjaGluZTogaHR0cHM6Ly90YWlsc2NhbGUuY29tL2Rvd25sb2FkIgogICAgc2F5ICIgICAgWW91ciBwaG9uZSBuZWVkcyBpdCB0b28gKHNhbWUgYWNjb3VudCksIHdpdGggSFRUUFMgY2VydGlmaWNhdGVzIGVuYWJsZWQuIgogIGVsaWYgWyAteiAiJG5hbWUiIF07IHRoZW4KICAgIHNheSAiICAhIFRhaWxzY2FsZSBpcyBub3QgY29ubmVjdGVkIG9uIHRoaXMgbWFjaGluZTogdGFpbHNjYWxlIHVwIgogIGVsc2UKICAgIHNheSAiICAhIE5vdCByZWFjaGFibGUgZnJvbSB5b3VyIHBob25lIHlldDogd2hlcmRyIGlzIG5vdCBwdWJsaXNoZWQgb24geW91ciB0YWlsbmV0LiIKICAgIHNheSAiICAgIFB1Ymxpc2ggaXQgKHByaXZhdGUsIG9ubHkgeW91ciBUYWlsc2NhbGUgZGV2aWNlcyk6IgogICAgc2F5ICIgICAgICAkcHVibGlzaCIKICAgIHNheSAiICAgIHdoZXJkciBlbmFibGVzIGh0dHBzOi8vJG5hbWU6JFBPUlQvIGJ5IGl0c2VsZjsgcnVuIHRoaXMgYWdhaW4gZm9yIGl0cyBRUiBjb2RlLiIKICBmaQogIHNheSAiIgogIHNheSAiICBHdWlkZTogaHR0cHM6Ly9naXRodWIuY29tLyRTT1VSQ0UjaW5zdGFsbC1pdC1hcy1hbi1hcHAiCn0KCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHNlcnZpY2UKY21kX3NlcnZpY2UoKSB7CiAgY2FzZSAiJHsxOi19IiBpbiBpbnN0YWxsfHVuaW5zdGFsbCkgOzsgKikgZGllICJ1c2FnZTogJDAgc2VydmljZSBpbnN0YWxsfHVuaW5zdGFsbCIgOzsgZXNhYwogIGlmIFsgIiRNT0RFIiA9ICJkb2NrZXIiIF07IHRoZW4KICAgIHNheSAid2hlcmRyIHJ1bnMgaW4gRG9ja2VyOiB0aGUgY29udGFpbmVyIGFscmVhZHkgc3RhcnRzIHdpdGggRG9ja2VyIChyZXN0YXJ0OiBhbHdheXMpLiIKICAgIHJldHVybiAwCiAgZmkKICBjbGkgc2VydmljZSAiJDEiCiAgIyBXaXRob3V0IHRoZSBzZXJ2aWNlLCB0aGUgcGx1Z2luIHJ1bnMgd2hlcmRyIGFnYWluIChhbmQgaXRzIHN0YXJ0dXAgaG9vawogICMgc3RhcnRzIGl0IHdpdGggSGVyZHIpLgogIGlmIFsgIiQxIiA9ICJ1bmluc3RhbGwiIF07IHRoZW4gY21kX3N0YXJ0OyBmaQp9CgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBrZXkKIyBBIEhlcmRyIGtleSB0aGF0IG9wZW5zIHRoZSB3aGVyZHIgcGFuZWw6IEhlcmRyIHYxIHBsdWdpbnMgaGF2ZSBubyBtZW51LCBzbwojIHRoZSBpbnN0YWxsIGFwcGVuZHMgb25lIG1hcmtlZCBbW2tleXMuY29tbWFuZF1dIGJsb2NrIHRvIEhlcmRyJ3MKIyBjb25maWcudG9tbCwgb24gdGhlIGZpcnN0IGZyZWUga2V5IG9mIEhPVEtFWVMgKG5ldmVyIG9uZSBIZXJkciBvciB0aGUgdXNlcgojIGFscmVhZHkgYmluZHMpLiBFeGlzdGluZyBsaW5lcyBhcmUgbmV2ZXIgY2hhbmdlZDogdGhlIGJsb2NrIGlzIG9ubHkgZXZlcgojIGFwcGVuZGVkLCB0aGVuIHJlbW92ZWQgYnkgYGtleSB1bmluc3RhbGxgLiBOb3RoaW5nIGlzIGFkZGVkIHdoZW4gdGhlIHBhbmVsCiMgYWxyZWFkeSBoYXMgYSBrZXksIG9yIHdoZW4gbm8gY2FuZGlkYXRlIGlzIGZyZWUuCkhPVEtFWVM9IiR7V0hFUkRSX0hPVEtFWVM6LXByZWZpeCtpIHByZWZpeCt1IHByZWZpeCt5IHByZWZpeCttIHByZWZpeCthbHQrd30iCkhFUkRSX0NPTkZJRz0iJHtIRVJEUl9DT05GSUdfUEFUSDotJHtYREdfQ09ORklHX0hPTUU6LSRIT01FLy5jb25maWd9L2hlcmRyL2NvbmZpZy50b21sfSIKUExVR0lOX0lEPSIkKHByaW50ZiAnJXMnICIkU09VUkNFIiB8IHRyIC8gLikiClBBTkVMX0FDVElPTj0iJFBMVUdJTl9JRC5wYW5lbCIKS0VZX0JFR0lOPSIjIHdoZXJkcjoga2V5IHRoYXQgb3BlbnMgdGhlIHdoZXJkciBwYW5lbCAocmVtb3ZlIHRoaXMgYmxvY2sgdG8gdW5iaW5kIGl0KSIKS0VZX0VORD0iIyBlbmQgd2hlcmRyIgoKIyBIZXJkcidzIGRlZmF1bHQga2V5bWFwLCBmcm9tIHRoZSBydW5uaW5nIGJpbmFyeSB3aGVuIGl0IGNhbiBwcmludCBpdCwKIyBvdGhlcndpc2UgYXMgb2YgSGVyZHIgMC45LjMgKCJuYW1lPFRBQj5rZXkiIGxpbmVzKS4KZGVmYXVsdF9rZXlzKCkgewogIG91dD0iJCgiJChoZXJkcl9iaW4pIiAtLWRlZmF1bHQtY29uZmlnIDI+L2Rldi9udWxsIHwgYXdrICcKICAgIC9eXFtrZXlzXF0vIHsgayA9IDE7IG5leHQgfQogICAgayAmJiAvXlxbLyB7IGV4aXQgfQogICAgayAmJiBtYXRjaCgkMCwgL14jIFthLXpfXSsgPSAiW14iXSoiLykgewogICAgICBsaW5lID0gc3Vic3RyKCQwLCAzLCBSTEVOR1RIIC0gMik7IGVxID0gaW5kZXgobGluZSwgIiA9ICIpCiAgICAgIHYgPSBzdWJzdHIobGluZSwgZXEgKyA0KTsgc3ViKC8iJC8sICIiLCB2KQogICAgICBpZiAodiAhPSAiIikgcHJpbnRmICIlc1x0JXNcbiIsIHN1YnN0cihsaW5lLCAxLCBlcSAtIDEpLCB2CiAgICB9JykiIHx8IG91dD0iIgogIGlmIFsgLW4gIiRvdXQiIF07IHRoZW4gcHJpbnRmICclc1xuJyAiJG91dCI7IHJldHVybjsgZmkKICBmb3IgcCBpbiBoZWxwOj8gc2V0dGluZ3M6cyBkZXRhY2g6cSByZWxvYWRfY29uZmlnOnNoaWZ0K3Igb3Blbl9ub3RpZmljYXRpb25fdGFyZ2V0Om8gXAogICAgd29ya3NwYWNlX3BpY2tlcjp3IGdvdG86ZyBuZXdfd29ya3NwYWNlOnNoaWZ0K24gbmV3X3dvcmt0cmVlOnNoaWZ0K2cgcmVuYW1lX3dvcmtzcGFjZTpzaGlmdCt3IFwKICAgIGNsb3NlX3dvcmtzcGFjZTpzaGlmdCtkIG5ld190YWI6YyByZW5hbWVfdGFiOnNoaWZ0K3QgcHJldmlvdXNfdGFiOnAgbmV4dF90YWI6biBcCiAgICBjbG9zZV90YWI6c2hpZnQreCByZW5hbWVfcGFuZTpzaGlmdCtwIGVkaXRfc2Nyb2xsYmFjazplIGZvY3VzX3BhbmVfbGVmdDpoIGZvY3VzX3BhbmVfZG93bjpqIFwKICAgIGZvY3VzX3BhbmVfdXA6ayBmb2N1c19wYW5lX3JpZ2h0OmwgY3ljbGVfcGFuZV9uZXh0OnRhYiBjeWNsZV9wYW5lX3ByZXZpb3VzOnNoaWZ0K3RhYiBcCiAgICBzcGxpdF92ZXJ0aWNhbDp2IHNwbGl0X2hvcml6b250YWw6bWludXMgY2xvc2VfcGFuZTp4IHpvb206eiByZXNpemVfbW9kZTpyIHRvZ2dsZV9zaWRlYmFyOmI7IGRvCiAgICBwcmludGYgJyVzXHRwcmVmaXgrJXNcbicgIiR7cCUlOip9IiAiJHtwIyo6fSIKICBkb25lCn0KCiMgT25lIGxpbmUgb24gdGhlIGNvbmZpZzogImJvdW5kIDxrZXk+IiB3aGVuIGEgW1trZXlzLmNvbW1hbmRdXSBhbHJlYWR5IHJ1bnMKIyB0aGUgcGFuZWwsIGVsc2UgImZyZWUgPGtleT4iIChmaXJzdCBmcmVlIGNhbmRpZGF0ZSkgb3IgIm5vbmUiLiBBbHNvCiMgIm9sZCA8a2V5PiIgZm9yIGEgYmluZGluZyBvZiB0aGUgcGFuZWwncyBmb3JtZXIgYWN0aW9uIGlkICg8aWQ+LndoZXJkcikuCmtleV9zY2FuKCkgewogIGRlZmF1bHRzPSIkKGRlZmF1bHRfa2V5cykiCiAgeyBwcmludGYgJyVzXG4nICIkZGVmYXVsdHMiOyBwcmludGYgJ1wwMDFcbic7IGNhdCAiJEhFUkRSX0NPTkZJRyIgMj4vZGV2L251bGw7IH0gfCBhd2sgXAogICAgLXYgY2FuZHM9IiRIT1RLRVlTIiAtdiBhY3Rpb249IiRQQU5FTF9BQ1RJT04iIC12IG9sZD0iJFBMVUdJTl9JRC53aGVyZHIiICcKICAgIGZ1bmN0aW9uIG5vcm0oaykgewogICAgICBnc3ViKC9bIFx0XS8sICIiLCBrKQogICAgICAjICJwcmVmaXgrVyIgaXMgInByZWZpeCtzaGlmdCt3IgogICAgICBpZiAobWF0Y2goaywgL1wrW0EtWl0kLykpIGsgPSBzdWJzdHIoaywgMSwgUlNUQVJUKSAic2hpZnQrIiB0b2xvd2VyKHN1YnN0cihrLCBSU1RBUlQgKyAxKSkKICAgICAgcmV0dXJuIHRvbG93ZXIoaykKICAgIH0KICAgIGZ1bmN0aW9uIHN0cmluZ3Mocywgb3V0LCAgIG4pIHsKICAgICAgbiA9IDAKICAgICAgd2hpbGUgKG1hdGNoKHMsIC8iW14iXSoiLykpIHsgb3V0Wysrbl0gPSBzdWJzdHIocywgUlNUQVJUICsgMSwgUkxFTkdUSCAtIDIpOyBzID0gc3Vic3RyKHMsIFJTVEFSVCArIFJMRU5HVEgpIH0KICAgICAgcmV0dXJuIG4KICAgIH0KICAgIGZ1bmN0aW9uIGZsdXNoKCkgewogICAgICBpZiAoY2tleSAhPSAiIiAmJiBjbWQgPT0gYWN0aW9uICYmIGJvdW5kID09ICIiKSBib3VuZCA9IGNrZXkKICAgICAgaWYgKGNrZXkgIT0gIiIgJiYgY21kID09IG9sZCAmJiBvbGRrZXkgPT0gIiIpIG9sZGtleSA9IGNrZXkKICAgICAgY2tleSA9ICIiOyBjbWQgPSAiIgogICAgfQogICAgJDAgPT0gIlwwMDEiIHsgY29uZiA9IDE7IG5leHQgfQogICAgIWNvbmYgeyBzcGxpdCgkMCwgZCwgIlx0Iik7IGRlZltkWzFdXSA9IGRbMl07IG5leHQgfQogICAgL15bIFx0XSpcWy8gewogICAgICBmbHVzaCgpOyB0ID0gJDA7IHN1YigvIy4qLywgIiIsIHQpOyBnc3ViKC9bIFx0XS8sICIiLCB0KQogICAgICBzZWN0ID0gdCA9PSAiW2tleXNdIiA/ICJrZXlzIiA6IHQgPT0gIltba2V5cy5jb21tYW5kXV0iID8gImNtZCIgOiAiIgogICAgICBuZXh0CiAgICB9CiAgICAvXlsgXHRdKigjfCQpLyB7IG5leHQgfQogICAgewogICAgICBlcSA9IGluZGV4KCQwLCAiPSIpOyBpZiAoIWVxKSBuZXh0CiAgICAgIG5hbWUgPSBzdWJzdHIoJDAsIDEsIGVxIC0gMSk7IGdzdWIoL1sgXHRdLywgIiIsIG5hbWUpOyB2YWwgPSBzdWJzdHIoJDAsIGVxICsgMSkKICAgICAgaWYgKHNlY3QgPT0gImtleXMiKSB7CiAgICAgICAgb3ZlcltuYW1lXSA9IDE7IG4gPSBzdHJpbmdzKHZhbCwgcykKICAgICAgICBmb3IgKGkgPSAxOyBpIDw9IG47IGkrKykgdGFrZW5bbm9ybShzW2ldKV0gPSAxCiAgICAgIH0gZWxzZSBpZiAoc2VjdCA9PSAiY21kIiAmJiBzdHJpbmdzKHZhbCwgcykpIHsKICAgICAgICBpZiAobmFtZSA9PSAia2V5IikgeyBja2V5ID0gc1sxXTsgdGFrZW5bbm9ybShzWzFdKV0gPSAxIH0KICAgICAgICBpZiAobmFtZSA9PSAiY29tbWFuZCIpIGNtZCA9IHNbMV0KICAgICAgfQogICAgfQogICAgRU5EIHsKICAgICAgZmx1c2goKQogICAgICBpZiAob2xka2V5ICE9ICIiKSBwcmludCAib2xkICIgb2xka2V5CiAgICAgIGlmIChib3VuZCAhPSAiIikgeyBwcmludCAiYm91bmQgIiBib3VuZDsgZXhpdCB9CiAgICAgIGZvciAoYSBpbiBkZWYpIGlmICghKGEgaW4gb3ZlcikpIHRha2VuW25vcm0oZGVmW2FdKV0gPSAxCiAgICAgIG4gPSBzcGxpdChjYW5kcywgYywgIiAiKQogICAgICBmb3IgKGkgPSAxOyBpIDw9IG47IGkrKykgaWYgKCEobm9ybShjW2ldKSBpbiB0YWtlbikpIHsgcHJpbnQgImZyZWUgIiBjW2ldOyBleGl0IH0KICAgICAgcHJpbnQgIm5vbmUiCiAgICB9Jwp9CgojIFRoZSBrZXkgYm91bmQgdG8gdGhlIHBhbmVsLCBpZiBhbnkuCmtleV9ib3VuZCgpIHsga2V5X3NjYW4gfCBzZWQgLW4gJ3MvXmJvdW5kIC8vcCc7IH0KCiMgSGVyZHIgYXBwbGllcyBrZXliaW5kaW5ncyBvbiBgaGVyZHIgc2VydmVyIHJlbG9hZC1jb25maWdgIChubyByZXN0YXJ0KS4Ka2V5X3JlbG9hZCgpIHsKICBpZiAiJChoZXJkcl9iaW4pIiBzZXJ2ZXIgcmVsb2FkLWNvbmZpZyA+L2Rldi9udWxsIDI+JjE7IHRoZW4KICAgIHRlbGwgIiAgSGVyZHIgcmVsb2FkZWQgaXRzIGNvbmZpZzogbm8gcmVzdGFydCBuZWVkZWQuIgogIGVsc2UKICAgIHRlbGwgIiAgUnVuIGhlcmRyIHNlcnZlciByZWxvYWQtY29uZmlnIChvciByZXN0YXJ0IEhlcmRyKSB0byBhcHBseSBpdC4iCiAgZmkKfQoKY21kX2tleSgpIHsKICBjYXNlICIkezE6LX0iIGluCiAgICBpbnN0YWxsKQogICAgICBzY2FuPSIkKGtleV9zY2FuKSIKICAgICAgb2xkPSIkKHByaW50ZiAnJXNcbicgIiRzY2FuIiB8IHNlZCAtbiAncy9eb2xkIC8vcCcpIgogICAgICBbIC16ICIkb2xkIiBdIHx8IHdhcm4gIiRvbGQgcnVucyAkUExVR0lOX0lELndoZXJkciwgcmVuYW1lZCAkUEFORUxfQUNUSU9OOiBlZGl0IHRoYXQgbGluZSBvZiAkSEVSRFJfQ09ORklHLiIKICAgICAgcmVzPSIkKHByaW50ZiAnJXNcbicgIiRzY2FuIiB8IHNlZCAnL15vbGQgL2QnKSIKICAgICAgY2FzZSAiJHJlcyIgaW4KICAgICAgICBib3VuZFwgKikgdGVsbCAiUHJlc3MgJHtyZXMjYm91bmQgfSBpbiBIZXJkciB0byBvcGVuIHRoZSB3aGVyZHIgcGFuZWwuIiA7OwogICAgICAgIGZyZWVcICopCiAgICAgICAgICBrZXk9IiR7cmVzI2ZyZWUgfSIKICAgICAgICAgIG1rZGlyIC1wICIkKGRpcm5hbWUgIiRIRVJEUl9DT05GSUciKSIKICAgICAgICAgIGJsb2NrPSIkKHByaW50ZiAnJXNcbltba2V5cy5jb21tYW5kXV1cbmtleSA9ICIlcyJcbnR5cGUgPSAicGx1Z2luX2FjdGlvbiJcbmNvbW1hbmQgPSAiJXMiXG5kZXNjcmlwdGlvbiA9ICJ3aGVyZHIiXG4lcycgXAogICAgICAgICAgICAiJEtFWV9CRUdJTiIgIiRrZXkiICIkUEFORUxfQUNUSU9OIiAiJEtFWV9FTkQiKSIKICAgICAgICAgIHNlcD0iIgogICAgICAgICAgaWYgWyAtcyAiJEhFUkRSX0NPTkZJRyIgXTsgdGhlbgogICAgICAgICAgICBzZXA9IgoiCiAgICAgICAgICAgICMgQSBsYXN0IGxpbmUgd2l0aG91dCBpdHMgbmV3bGluZSBnZXRzIG9uZSBmaXJzdC4KICAgICAgICAgICAgWyAiJCh0YWlsIC1jIDEgIiRIRVJEUl9DT05GSUciIHwgb2QgLUFuIC1jIHwgdHIgLWQgJyAnKSIgPSAnXG4nIF0gfHwgc2VwPSIKJHNlcCIKICAgICAgICAgIGZpCiAgICAgICAgICAjIENoZWNrZWQgb24gYSBjb3B5IGZpcnN0IHdoZW4gdGhpcyBIZXJkciBjYW4gdmFsaWRhdGUgYSBjb25maWc6CiAgICAgICAgICAjIGEgY29uZmlnIEhlcmRyIHdvdWxkIHJlamVjdCBpcyBuZXZlciB3cml0dGVuLgogICAgICAgICAgdG1wPSIkSEVSRFJfQ09ORklHLndoZXJkci1jaGVjay50b21sIgogICAgICAgICAgeyBpZiBbIC1mICIkSEVSRFJfQ09ORklHIiBdOyB0aGVuIGNhdCAiJEhFUkRSX0NPTkZJRyI7IGZpOyBwcmludGYgJyVzJXNcbicgIiRzZXAiICIkYmxvY2siOyB9ID4gIiR0bXAiCiAgICAgICAgICBpZiAiJChoZXJkcl9iaW4pIiBjb25maWcgLS1oZWxwID4vZGV2L251bGwgMj4mMSAmJiAhIEhFUkRSX0NPTkZJR19QQVRIPSIkdG1wIiAiJChoZXJkcl9iaW4pIiBjb25maWcgY2hlY2sgPi9kZXYvbnVsbCAyPiYxOyB0aGVuCiAgICAgICAgICAgIHJtIC1mICIkdG1wIgogICAgICAgICAgICB3YXJuICJubyBIZXJkciBrZXkgYWRkZWQ6ICRIRVJEUl9DT05GSUcgd291bGQgbm90IHZhbGlkYXRlIHdpdGggaXQgKGhlcmRyIGNvbmZpZyBjaGVjaykuIgogICAgICAgICAgICByZXR1cm4gMAogICAgICAgICAgZmkKICAgICAgICAgIHJtIC1mICIkdG1wIgogICAgICAgICAgcHJpbnRmICclcyVzXG4nICIkc2VwIiAiJGJsb2NrIiA+PiAiJEhFUkRSX0NPTkZJRyIKICAgICAgICAgIG9rICJIZXJkciBrZXkgJGtleSBhZGRlZCB0byAkSEVSRFJfQ09ORklHIgogICAgICAgICAgdGVsbCAiUHJlc3MgJGtleSBpbiBIZXJkciB0byBvcGVuIHRoZSB3aGVyZHIgcGFuZWwuIgogICAgICAgICAga2V5X3JlbG9hZAogICAgICAgICAgOzsKICAgICAgICAqKSB3YXJuICJubyBIZXJkciBrZXkgYWRkZWQ6ICRIT1RLRVlTIGFyZSBhbGwgdGFrZW4uIEJpbmQgb25lIHRvICRQQU5FTF9BQ1RJT04gKHR5cGUgPSBcInBsdWdpbl9hY3Rpb25cIikgaW4gJEhFUkRSX0NPTkZJRy4iIDs7CiAgICAgIGVzYWMKICAgICAgOzsKICAgIHVuaW5zdGFsbCkKICAgICAgaWYgISBncmVwIC1xeEYgIiRLRVlfQkVHSU4iICIkSEVSRFJfQ09ORklHIiAyPi9kZXYvbnVsbDsgdGhlbiBvayAibm8gd2hlcmRyIGtleSBpbiAkSEVSRFJfQ09ORklHIjsgcmV0dXJuIDA7IGZpCiAgICAgICMgRHJvcHMgdGhlIG1hcmtlZCBibG9jayBhbmQgdGhlIGJsYW5rIGxpbmUgd3JpdHRlbiBiZWZvcmUgaXQuCiAgICAgIHRtcD0iJEhFUkRSX0NPTkZJRy53aGVyZHItdG1wIgogICAgICBhd2sgLXYgYj0iJEtFWV9CRUdJTiIgLXYgZT0iJEtFWV9FTkQiICcKICAgICAgICAkMCA9PSBiIHsgc2tpcCA9IDE7IGlmIChibGFuaykgYmxhbmstLTsgbmV4dCB9CiAgICAgICAgc2tpcCB7IGlmICgkMCA9PSBlKSBza2lwID0gMDsgbmV4dCB9CiAgICAgICAgJDAgPT0gIiIgeyBibGFuaysrOyBuZXh0IH0KICAgICAgICB7IHdoaWxlIChibGFuaykgeyBwcmludCAiIjsgYmxhbmstLSB9IHByaW50IH0KICAgICAgICBFTkQgeyB3aGlsZSAoYmxhbmspIHsgcHJpbnQgIiI7IGJsYW5rLS0gfSB9JyAiJEhFUkRSX0NPTkZJRyIgPiAiJHRtcCIKICAgICAgIyBSZXdyaXR0ZW4gaW4gcGxhY2U6IHRoZSBmaWxlIGtlZXBzIGl0cyBvd25lciBhbmQgbW9kZS4KICAgICAgY2F0ICIkdG1wIiA+ICIkSEVSRFJfQ09ORklHIiAmJiBybSAtZiAiJHRtcCIKICAgICAgb2sgIndoZXJkciBrZXkgcmVtb3ZlZCBmcm9tICRIRVJEUl9DT05GSUciCiAgICAgIGtleV9yZWxvYWQKICAgICAgOzsKICAgIHN0YXR1cykgYj0iJChrZXlfYm91bmQpIjsgaWYgWyAtbiAiJGIiIF07IHRoZW4gc2F5ICIkYiI7IGVsc2Ugc2F5ICJub25lIjsgZmkgOzsKICAgICopIGRpZSAidXNhZ2U6ICQwIGtleSBpbnN0YWxsfHVuaW5zdGFsbHxzdGF0dXMiIDs7CiAgZXNhYwp9CgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBwYW5lbAojIFRoZSAicGFuZWwiIGFjdGlvbjogb25lIHBvcHVwIHdpdGggdGhlIHN0YXRlLCBPcGVuIHdoZXJkciwgU2V0IHVwIG15IHBob25lCiMgKG9wZW5zIFNldHRpbmdzIOKAuiBQaG9uZSkgYW5kIHRoZSBvdGhlciBjb21tYW5kcyAoYmluL2xpYi9wYW5lbC5tanMpLAojIGRyaXZpbmcgdGhpcyBzY3JpcHQuCmNtZF9wYW5lbCgpIHsKICBjb250cm9sPSIkKHByaW50ZiAnWyJzaCIsIiVzIl0nICIkKHByaW50ZiAnJXMnICIkUk9PVC9zY3JpcHRzL2hlcmRyLXBsdWdpbi5zaCIgfCBzZWQgJ3MvW1xcIl0vXFwmL2cnKSIpIgogIGlmIFsgIiRNT0RFIiA9ICJuYXRpdmUiIF0gfHwgeyBbIC1uICIkTU9ERSIgXSAmJiBSVU5USU1FPSIkKGZpbmRfcnVudGltZSkiOyB9OyB0aGVuCiAgICBXSEVSRFJfQ09OVFJPTD0iJGNvbnRyb2wiIFdIRVJEUl9NT0RFPSIkTU9ERSIgV0hFUkRSX0hPVEtFWT0iJChrZXlfYm91bmQpIiBjbGkgcGFuZWwKICBlbGlmIFsgLW4gIiRNT0RFIiBdOyB0aGVuCiAgICBzaF9wYW5lbAogIGVsc2UKICAgIGRpZSAid2hlcmRyIHBsdWdpbiBpcyBub3Qgc2V0IHVwICgkQ09ORiBpcyBtaXNzaW5nKTogaW5zdGFsbCBpdCBhZ2FpbiB3aXRoIGhlcmRyIHBsdWdpbiBpbnN0YWxsICRTT1VSQ0UgLS15ZXMuIgogIGZpCn0KCiMgRG9ja2VyIG1vZGUgd2l0aG91dCBOb2RlLmpzOiB0aGUgc2FtZSBrZXlzLCB3aXRob3V0IHRoZSBRUiBjb2RlLgpzaF9wYW5lbCgpIHsKICBzYXZlZD0iJChzdHR5IC1nKSIKICB0cmFwICdzdHR5ICIkc2F2ZWQiJyBFWElUCiAgd2hpbGUgOjsgZG8KICAgIHByaW50ZiAnXDAzM1tIXDAzM1sySlxuICBXSEVSRFJcblxuJwogICAgKCBjbWRfc3RhdHVzICkgfHwgdHJ1ZQogICAgcHJpbnRmICdcbiAgUyBzdGFydCAgWCBzdG9wICBSIHJlc3RhcnQgIE8gb3BlbiAgTCBsb2cgIFUgdXBkYXRlICBQIHBob25lICBRIHF1aXRcbicKICAgIHByaW50ZiAnICBSZW1vdmU6IFgsIHRoZW4gc2ggJXMga2V5IHVuaW5zdGFsbCwgdGhlbiBoZXJkciBwbHVnaW4gdW5pbnN0YWxsICVzICYmIHJtIC1yZiAlc1xuJyAiJFJPT1Qvc2NyaXB0cy9oZXJkci1wbHVnaW4uc2giICIkUExVR0lOX0lEIiAiJERJUiIKICAgIHN0dHkgLWljYW5vbiAtZWNobyBtaW4gMCB0aW1lIDUwCiAgICBrPSIkKGRkIGJzPTEgY291bnQ9MSAyPi9kZXYvbnVsbCB8fCB0cnVlKSIKICAgIHN0dHkgIiRzYXZlZCIKICAgIGNhc2UgIiRrIiBpbgogICAgICBzfFMpIGFjdD1zdGFydCA7OyB4fFgpIGFjdD1zdG9wIDs7IHJ8UikgYWN0PXJlc3RhcnQgOzsgb3xPKSBhY3Q9b3BlbiA7OwogICAgICBsfEwpIGFjdD1sb2dzIDs7IHV8VSkgYWN0PXVwZGF0ZSA7OyBwfFApIGFjdD1waG9uZSA7OyBxfFEpIGJyZWFrIDs7CiAgICAgICopIGNvbnRpbnVlIDs7CiAgICBlc2FjCiAgICBwcmludGYgJ1wwMzNbSFwwMzNbMkpcbicKICAgICggdHJhcCAtIElOVDsgImNtZF8kYWN0IiApIHx8IHRydWUKICAgIHByaW50ZiAnXG4gIFByZXNzIEVudGVyIHRvIGdvIGJhY2suICcKICAgIHJlYWQgLXIgXyB8fCB0cnVlCiAgZG9uZQp9CgpjbWRfcmVzdGFydCgpIHsgY21kX3N0b3A7IGNtZF9zdGFydDsgfQoKY2FzZSAiJHsxOi19IiBpbgogIGJ1aWxkKSBjbWRfYnVpbGQgOzsKICBwYW5lbCkgY21kX3BhbmVsIDs7CiAgc3RhcnR8c3RvcHxyZXN0YXJ0fHN0YXR1c3xvcGVufGFkZHJlc3N8dXBkYXRlfHBob25lfGxvZ3N8ZG9jdG9yKSAiY21kXyQxIiA7OwogIHNlcnZpY2UpIGNtZF9zZXJ2aWNlICIkezI6LX0iIDs7CiAgc2tpbGwpIGNtZF9za2lsbCAiJHsyOi19IiA7OwogIGtleSkgY21kX2tleSAiJHsyOi19IiA7OwogICopIGRpZSAidXNhZ2U6ICQwIGJ1aWxkfHBhbmVsfHN0YXJ0fHN0b3B8cmVzdGFydHxzdGF0dXN8b3BlbnxhZGRyZXNzfHVwZGF0ZXxwaG9uZXxsb2dzfGRvY3RvcnxzZXJ2aWNlIGluc3RhbGx8dW5pbnN0YWxsfHNraWxsIGluc3RhbGx8dW5pbnN0YWxsfGtleSBpbnN0YWxsfHVuaW5zdGFsbHxzdGF0dXMiIDs7CmVzYWMK");
|
|
5
5
|
|
|
6
6
|
export { herdrPlugin as default };
|
|
7
7
|
//# sourceMappingURL=herdr-plugin.mjs.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// ROLLUP_NO_REPLACE
|
|
2
|
+
const releaseReady = "// Legacy updaters require both npm and Homebrew before releases/latest moves.\nimport { execFileSync } from 'node:child_process'\nimport { pathToFileURL } from 'node:url'\n\nexport async function readiness(version, request = fetch, repo = process.env.GITHUB_REPOSITORY) {\n if (!repo) throw new Error('GITHUB_REPOSITORY is required')\n const get = (url, method = 'GET') => request(url, { method, signal: AbortSignal.timeout(15_000) })\n const missing = []\n try {\n const metadata = await get('https://registry.npmjs.org/wherdr/latest')\n if (!metadata.ok || (await metadata.json()).version !== version) missing.push(`npm latest is not ${version}`)\n const tar = await get(`https://registry.npmjs.org/wherdr/-/wherdr-${version}.tgz`, 'HEAD')\n if (!tar.ok) missing.push(`npm archive ${version} is unavailable`)\n } catch { missing.push('npm availability check failed') }\n try {\n const formula = await get(`https://raw.githubusercontent.com/${repo.split('/')[0]}/homebrew-tap/main/Formula/wherdr.rb`)\n if (!formula.ok || !(await formula.text()).includes(`/v${version}/wherdr-${version}.tgz\"`)) {\n missing.push(`Homebrew formula is not ready: run scripts/bump-homebrew.sh ${version} after release.yml completes`)\n }\n } catch { missing.push('Homebrew availability check failed') }\n return { ready: missing.length === 0, missing }\n}\n\nexport async function ready(...args) { return (await readiness(...args)).ready }\n\nexport async function promote({ repo, request = fetch, run = execFileSync, log = console.log }) {\n if (!repo) throw new Error('GITHUB_REPOSITORY is required')\n const releases = JSON.parse(run('gh', ['api', `repos/${repo}/releases?per_page=100`], { encoding: 'utf8' }))\n const versions = releases.filter(r => !r.draft && !r.prerelease && /^v\\d+\\.\\d+\\.\\d+$/.test(r.tag_name))\n .sort((a, b) => b.tag_name.slice(1).localeCompare(a.tag_name.slice(1), 'en', { numeric: true }))\n const tag = versions[0]?.tag_name\n if (!tag) { log('No published stable release.'); return }\n const current = JSON.parse(run('gh', ['api', `repos/${repo}/releases/latest`], { encoding: 'utf8' }))\n if (current.tag_name === tag) { log(`Legacy update channel already at ${tag}.`); return }\n const result = await readiness(tag.slice(1), request, repo)\n if (!result.ready) {\n for (const reason of result.missing) log(`Legacy update channel unchanged: ${reason}.`)\n return\n }\n run('gh', ['release', 'edit', tag, '--repo', repo, '--latest'], { stdio: 'inherit' })\n}\n\nif (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {\n await promote({ repo: process.env.GITHUB_REPOSITORY })\n}\n";
|
|
3
|
+
|
|
4
|
+
export { releaseReady as default };
|
|
5
|
+
//# sourceMappingURL=release-ready.mjs.map
|
|
@@ -20,8 +20,8 @@ import 'web-push';
|
|
|
20
20
|
import 'node:os';
|
|
21
21
|
import 'node:child_process';
|
|
22
22
|
import 'node:net';
|
|
23
|
-
import 'node:readline';
|
|
24
23
|
import 'node:fs/promises';
|
|
24
|
+
import 'node:readline';
|
|
25
25
|
import 'node:dns';
|
|
26
26
|
import 'node:util';
|
|
27
27
|
import 'qrcode-terminal/vendor/QRCode/index.js';
|
|
@@ -20,8 +20,8 @@ import 'web-push';
|
|
|
20
20
|
import 'node:os';
|
|
21
21
|
import 'node:child_process';
|
|
22
22
|
import 'node:net';
|
|
23
|
-
import 'node:readline';
|
|
24
23
|
import 'node:fs/promises';
|
|
24
|
+
import 'node:readline';
|
|
25
25
|
import 'node:dns';
|
|
26
26
|
import 'node:util';
|
|
27
27
|
import 'qrcode-terminal/vendor/QRCode/index.js';
|
|
@@ -20,8 +20,8 @@ import 'web-push';
|
|
|
20
20
|
import 'node:os';
|
|
21
21
|
import 'node:child_process';
|
|
22
22
|
import 'node:net';
|
|
23
|
-
import 'node:readline';
|
|
24
23
|
import 'node:fs/promises';
|
|
24
|
+
import 'node:readline';
|
|
25
25
|
import 'node:dns';
|
|
26
26
|
import 'node:util';
|
|
27
27
|
import 'qrcode-terminal/vendor/QRCode/index.js';
|
|
@@ -20,8 +20,8 @@ import 'web-push';
|
|
|
20
20
|
import 'node:os';
|
|
21
21
|
import 'node:child_process';
|
|
22
22
|
import 'node:net';
|
|
23
|
-
import 'node:readline';
|
|
24
23
|
import 'node:fs/promises';
|
|
24
|
+
import 'node:readline';
|
|
25
25
|
import 'node:dns';
|
|
26
26
|
import 'node:util';
|
|
27
27
|
import 'qrcode-terminal/vendor/QRCode/index.js';
|
|
@@ -20,8 +20,8 @@ import 'web-push';
|
|
|
20
20
|
import 'node:os';
|
|
21
21
|
import 'node:child_process';
|
|
22
22
|
import 'node:net';
|
|
23
|
-
import 'node:readline';
|
|
24
23
|
import 'node:fs/promises';
|
|
24
|
+
import 'node:readline';
|
|
25
25
|
import 'node:dns';
|
|
26
26
|
import 'node:util';
|
|
27
27
|
import 'qrcode-terminal/vendor/QRCode/index.js';
|
|
@@ -20,8 +20,8 @@ import 'web-push';
|
|
|
20
20
|
import 'node:os';
|
|
21
21
|
import 'node:child_process';
|
|
22
22
|
import 'node:net';
|
|
23
|
-
import 'node:readline';
|
|
24
23
|
import 'node:fs/promises';
|
|
24
|
+
import 'node:readline';
|
|
25
25
|
import 'node:dns';
|
|
26
26
|
import 'node:util';
|
|
27
27
|
import 'qrcode-terminal/vendor/QRCode/index.js';
|
|
@@ -20,8 +20,8 @@ import 'web-push';
|
|
|
20
20
|
import 'node:os';
|
|
21
21
|
import 'node:child_process';
|
|
22
22
|
import 'node:net';
|
|
23
|
-
import 'node:readline';
|
|
24
23
|
import 'node:fs/promises';
|
|
24
|
+
import 'node:readline';
|
|
25
25
|
import 'node:dns';
|
|
26
26
|
import 'node:util';
|
|
27
27
|
import 'qrcode-terminal/vendor/QRCode/index.js';
|
|
@@ -20,8 +20,8 @@ import 'web-push';
|
|
|
20
20
|
import 'node:os';
|
|
21
21
|
import 'node:child_process';
|
|
22
22
|
import 'node:net';
|
|
23
|
-
import 'node:readline';
|
|
24
23
|
import 'node:fs/promises';
|
|
24
|
+
import 'node:readline';
|
|
25
25
|
import 'node:dns';
|
|
26
26
|
import 'node:util';
|
|
27
27
|
import 'qrcode-terminal/vendor/QRCode/index.js';
|
|
@@ -20,8 +20,8 @@ import 'web-push';
|
|
|
20
20
|
import 'node:os';
|
|
21
21
|
import 'node:child_process';
|
|
22
22
|
import 'node:net';
|
|
23
|
-
import 'node:readline';
|
|
24
23
|
import 'node:fs/promises';
|
|
24
|
+
import 'node:readline';
|
|
25
25
|
import 'node:dns';
|
|
26
26
|
import 'node:util';
|
|
27
27
|
import 'qrcode-terminal/vendor/QRCode/index.js';
|
|
@@ -20,8 +20,8 @@ import 'web-push';
|
|
|
20
20
|
import 'node:os';
|
|
21
21
|
import 'node:child_process';
|
|
22
22
|
import 'node:net';
|
|
23
|
-
import 'node:readline';
|
|
24
23
|
import 'node:fs/promises';
|
|
24
|
+
import 'node:readline';
|
|
25
25
|
import 'node:dns';
|
|
26
26
|
import 'node:util';
|
|
27
27
|
import 'qrcode-terminal/vendor/QRCode/index.js';
|
|
@@ -20,8 +20,8 @@ import 'web-push';
|
|
|
20
20
|
import 'node:os';
|
|
21
21
|
import 'node:child_process';
|
|
22
22
|
import 'node:net';
|
|
23
|
-
import 'node:readline';
|
|
24
23
|
import 'node:fs/promises';
|
|
24
|
+
import 'node:readline';
|
|
25
25
|
import 'node:dns';
|
|
26
26
|
import 'node:util';
|
|
27
27
|
import 'qrcode-terminal/vendor/QRCode/index.js';
|
|
@@ -20,8 +20,8 @@ import 'web-push';
|
|
|
20
20
|
import 'node:os';
|
|
21
21
|
import 'node:child_process';
|
|
22
22
|
import 'node:net';
|
|
23
|
-
import 'node:readline';
|
|
24
23
|
import 'node:fs/promises';
|
|
24
|
+
import 'node:readline';
|
|
25
25
|
import 'node:dns';
|
|
26
26
|
import 'node:util';
|
|
27
27
|
import 'qrcode-terminal/vendor/QRCode/index.js';
|
|
@@ -20,8 +20,8 @@ import 'web-push';
|
|
|
20
20
|
import 'node:os';
|
|
21
21
|
import 'node:child_process';
|
|
22
22
|
import 'node:net';
|
|
23
|
-
import 'node:readline';
|
|
24
23
|
import 'node:fs/promises';
|
|
24
|
+
import 'node:readline';
|
|
25
25
|
import 'node:dns';
|
|
26
26
|
import 'node:util';
|
|
27
27
|
import 'qrcode-terminal/vendor/QRCode/index.js';
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { m as getState, n as projectOf, o as isCoordinator, q as paneBaseMachine, t as pickCoordinator, a as defineApi, i as getQuery } from '../../nitro/nitro.mjs';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { r as readProjectBoard } from '../../_/projectBoard.mjs';
|
|
5
|
+
import 'node:http';
|
|
6
|
+
import 'node:https';
|
|
7
|
+
import 'stream';
|
|
8
|
+
import 'events';
|
|
9
|
+
import 'http';
|
|
10
|
+
import 'crypto';
|
|
11
|
+
import 'buffer';
|
|
12
|
+
import 'zlib';
|
|
13
|
+
import 'https';
|
|
14
|
+
import 'net';
|
|
15
|
+
import 'tls';
|
|
16
|
+
import 'url';
|
|
17
|
+
import 'node:events';
|
|
18
|
+
import 'node:buffer';
|
|
19
|
+
import 'node:fs';
|
|
20
|
+
import 'web-push';
|
|
21
|
+
import 'node:os';
|
|
22
|
+
import 'node:child_process';
|
|
23
|
+
import 'node:net';
|
|
24
|
+
import 'node:fs/promises';
|
|
25
|
+
import 'node:readline';
|
|
26
|
+
import 'node:dns';
|
|
27
|
+
import 'node:util';
|
|
28
|
+
import 'qrcode-terminal/vendor/QRCode/index.js';
|
|
29
|
+
import 'qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js';
|
|
30
|
+
import '@simplewebauthn/server';
|
|
31
|
+
import 'node:url';
|
|
32
|
+
|
|
33
|
+
const RESOLVED_KEPT = 20;
|
|
34
|
+
|
|
35
|
+
const READ_DEADLINE_MS = 4e3;
|
|
36
|
+
const INFLIGHT_MAX_MS = 6e4;
|
|
37
|
+
const REUSE_MS = 5e3;
|
|
38
|
+
const cache = /* @__PURE__ */ new Map();
|
|
39
|
+
const inflight = /* @__PURE__ */ new Map();
|
|
40
|
+
function groupProjects(panes) {
|
|
41
|
+
const groups = /* @__PURE__ */ new Map();
|
|
42
|
+
for (const p of panes) {
|
|
43
|
+
const cwd = (p.cwd || "").replace(/\/+$/, "");
|
|
44
|
+
const slug = projectOf(p);
|
|
45
|
+
if (!isCoordinator(p) || !slug || !path.posix.isAbsolute(cwd)) continue;
|
|
46
|
+
const dirName = path.posix.basename(cwd);
|
|
47
|
+
if (dirName.toLowerCase() !== slug.toLowerCase()) continue;
|
|
48
|
+
const key = `${paneBaseMachine(p)}|${cwd}`;
|
|
49
|
+
const g = groups.get(key);
|
|
50
|
+
if (g) g.panes.push(p);
|
|
51
|
+
else groups.set(key, { key, slug: dirName, panes: [p] });
|
|
52
|
+
}
|
|
53
|
+
return [...groups.values()];
|
|
54
|
+
}
|
|
55
|
+
function isOnline(machine) {
|
|
56
|
+
var _a;
|
|
57
|
+
if (!machine) return true;
|
|
58
|
+
const info = (_a = getState().machines) == null ? void 0 : _a.find((m) => m.key === machine);
|
|
59
|
+
return !info || info.status === "online";
|
|
60
|
+
}
|
|
61
|
+
function startRead(key, pane, since) {
|
|
62
|
+
const running = inflight.get(key);
|
|
63
|
+
if (running && Date.now() - running.since < INFLIGHT_MAX_MS) return running.read;
|
|
64
|
+
const read = readProjectBoard(pane, since).then((r) => {
|
|
65
|
+
const at = Date.now();
|
|
66
|
+
if ("same" in r) {
|
|
67
|
+
const kept = cache.get(key);
|
|
68
|
+
if (kept) kept.at = at;
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const board = "available" in r ? null : r;
|
|
72
|
+
cache.set(key, { board, digest: createHash("sha1").update(JSON.stringify(board)).digest("hex"), at });
|
|
73
|
+
}).finally(() => {
|
|
74
|
+
var _a;
|
|
75
|
+
if (((_a = inflight.get(key)) == null ? void 0 : _a.read) === read) inflight.delete(key);
|
|
76
|
+
});
|
|
77
|
+
inflight.set(key, { read, since: Date.now() });
|
|
78
|
+
return read;
|
|
79
|
+
}
|
|
80
|
+
async function withDeadline(read) {
|
|
81
|
+
const late = Promise.withResolvers();
|
|
82
|
+
const timer = setTimeout(() => late.reject(new Error("Board read timed out")), READ_DEADLINE_MS);
|
|
83
|
+
try {
|
|
84
|
+
await Promise.race([read, late.promise]);
|
|
85
|
+
} finally {
|
|
86
|
+
clearTimeout(timer);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async function readGroup(g, refresh) {
|
|
90
|
+
var _a, _b, _c, _d;
|
|
91
|
+
const pane = (_a = pickCoordinator(g.panes, g.slug)) != null ? _a : g.panes[0];
|
|
92
|
+
const panes = [pane, ...g.panes.filter((p) => p !== pane)].map((p) => p.id);
|
|
93
|
+
const project = { key: g.key, slug: g.slug, panes, board: null };
|
|
94
|
+
let failure;
|
|
95
|
+
const kept = cache.get(g.key);
|
|
96
|
+
if (!isOnline(pane.machine)) {
|
|
97
|
+
failure = "";
|
|
98
|
+
} else if (refresh || !kept || Date.now() - kept.at >= REUSE_MS) {
|
|
99
|
+
try {
|
|
100
|
+
await withDeadline(startRead(g.key, pane, refresh ? void 0 : (_b = kept == null ? void 0 : kept.board) == null ? void 0 : _b.version));
|
|
101
|
+
} catch (e) {
|
|
102
|
+
failure = e.message || "Board read failed";
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const board = (_d = (_c = cache.get(g.key)) == null ? void 0 : _c.board) != null ? _d : null;
|
|
106
|
+
if (board) {
|
|
107
|
+
project.board = { ...board, resolved: board.resolved.slice(0, RESOLVED_KEPT) };
|
|
108
|
+
project.resolvedTotal = board.resolved.length;
|
|
109
|
+
}
|
|
110
|
+
if (failure !== void 0) {
|
|
111
|
+
project.stale = true;
|
|
112
|
+
if (failure) project.error = failure;
|
|
113
|
+
}
|
|
114
|
+
return project;
|
|
115
|
+
}
|
|
116
|
+
function versionOf(projects) {
|
|
117
|
+
const h = createHash("sha1");
|
|
118
|
+
h.update(JSON.stringify(projects.map((p) => {
|
|
119
|
+
var _a, _b, _c, _d;
|
|
120
|
+
return [p.key, p.panes, (_b = (_a = cache.get(p.key)) == null ? void 0 : _a.digest) != null ? _b : null, (_c = p.stale) != null ? _c : false, (_d = p.error) != null ? _d : null];
|
|
121
|
+
})));
|
|
122
|
+
return h.digest("hex").slice(0, 16);
|
|
123
|
+
}
|
|
124
|
+
async function readGlobalBoard(since, refresh = []) {
|
|
125
|
+
const groups = groupProjects(getState().panes);
|
|
126
|
+
const keys = new Set(groups.map((g) => g.key));
|
|
127
|
+
for (const k of cache.keys()) if (!keys.has(k)) cache.delete(k);
|
|
128
|
+
const again = new Set(refresh);
|
|
129
|
+
const projects = await Promise.all(groups.map((g) => readGroup(g, again.has(g.key))));
|
|
130
|
+
projects.sort((a, b) => a.slug.localeCompare(b.slug) || (a.key < b.key ? -1 : 1));
|
|
131
|
+
const version = versionOf(projects);
|
|
132
|
+
if (since === version) return { same: true, version };
|
|
133
|
+
return { version, projects };
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const REFRESH_KEYS = 50;
|
|
137
|
+
const REFRESH_KEY_CHARS = 400;
|
|
138
|
+
const board_get = defineApi(async (event) => {
|
|
139
|
+
var _a;
|
|
140
|
+
const q = getQuery(event);
|
|
141
|
+
const raw = [(_a = q.refresh) != null ? _a : []].flat();
|
|
142
|
+
const refresh = raw.filter((k) => typeof k === "string" && !!k && k.length <= REFRESH_KEY_CHARS).slice(0, REFRESH_KEYS);
|
|
143
|
+
return readGlobalBoard(typeof q.since === "string" ? q.since.slice(0, 64) : void 0, refresh);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
export { board_get as default };
|
|
147
|
+
//# sourceMappingURL=board.get.mjs.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as defineApi, i as getQuery, f as findPane, H as HerdrError,
|
|
1
|
+
import { a as defineApi, i as getQuery, f as findPane, H as HerdrError, v as machineFor } from '../../nitro/nitro.mjs';
|
|
2
2
|
import { r as readChanges } from '../../_/changes.mjs';
|
|
3
3
|
import 'node:http';
|
|
4
4
|
import 'node:https';
|
|
@@ -21,8 +21,8 @@ import 'web-push';
|
|
|
21
21
|
import 'node:os';
|
|
22
22
|
import 'node:child_process';
|
|
23
23
|
import 'node:net';
|
|
24
|
-
import 'node:readline';
|
|
25
24
|
import 'node:fs/promises';
|
|
25
|
+
import 'node:readline';
|
|
26
26
|
import 'node:dns';
|
|
27
27
|
import 'node:util';
|
|
28
28
|
import 'qrcode-terminal/vendor/QRCode/index.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { d as defineEventHandler, i as getQuery, f as findPane,
|
|
1
|
+
import { d as defineEventHandler, i as getQuery, f as findPane, G as transcripts, s as sendError, M as sendImage } from '../../../nitro/nitro.mjs';
|
|
2
2
|
import 'node:http';
|
|
3
3
|
import 'node:https';
|
|
4
4
|
import 'node:crypto';
|
|
@@ -20,8 +20,8 @@ import 'web-push';
|
|
|
20
20
|
import 'node:os';
|
|
21
21
|
import 'node:child_process';
|
|
22
22
|
import 'node:net';
|
|
23
|
-
import 'node:readline';
|
|
24
23
|
import 'node:fs/promises';
|
|
24
|
+
import 'node:readline';
|
|
25
25
|
import 'node:dns';
|
|
26
26
|
import 'node:util';
|
|
27
27
|
import 'qrcode-terminal/vendor/QRCode/index.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { U as UPLOAD_DIR,
|
|
1
|
+
import { U as UPLOAD_DIR, C as uploadNames, a as defineApi, i as getQuery, f as findPane, H as HerdrError, D as machineOfPane, E as fmt, F as takenBackOf, G as transcripts, I as chatPasted, J as withoutTakenBack, K as withSentText, L as currentModel } from '../../nitro/nitro.mjs';
|
|
2
2
|
import { createHash } from 'node:crypto';
|
|
3
3
|
import fs from 'node:fs/promises';
|
|
4
4
|
import path from 'node:path';
|
|
@@ -87,7 +87,7 @@ const chat_get = defineApi(async (event) => {
|
|
|
87
87
|
});
|
|
88
88
|
if (r.token) r.token += mark;
|
|
89
89
|
if (r.items) {
|
|
90
|
-
r.items = withoutTakenBack(r.items, hidden);
|
|
90
|
+
r.items = chatPasted(withoutTakenBack(r.items, hidden));
|
|
91
91
|
await addUploadHashes(r.items);
|
|
92
92
|
}
|
|
93
93
|
if (r.queue && r.queue.length) r.queue = withSentText(p.id, r.queue);
|