🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@sentry/node-core

Package Overview
Dependencies
Maintainers
1
Versions
98
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@sentry/node-core - npm Package Compare versions

Comparing version
10.64.0
to
10.65.0
+1
-0
build/cjs/index.js

@@ -50,2 +50,3 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });

exports.SentryHttpInstrumentation = SentryHttpInstrumentation.SentryHttpInstrumentation;
exports.instrumentHttpOutgoingRequests = SentryHttpInstrumentation.instrumentHttpOutgoingRequests;
exports.nativeNodeFetchIntegration = index$5.nativeNodeFetchIntegration;

@@ -52,0 +53,0 @@ exports.instrumentUndici = undiciInstrumentation.instrumentUndici;

+1
-1

@@ -1,1 +0,1 @@

{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}

@@ -10,3 +10,3 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });

const { isPromise } = util.types;
const base64WorkerScript = "LyohIEBzZW50cnkvbm9kZS1jb3JlIDEwLjY0LjAgKDU3MzZhMzgpIHwgaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdCAqLwppbXBvcnR7U2Vzc2lvbiBhcyB0fWZyb20ibm9kZTppbnNwZWN0b3IiO2ltcG9ydHt3b3JrZXJEYXRhIGFzIG4scGFyZW50UG9ydCBhcyBlfWZyb20ibm9kZTp3b3JrZXJfdGhyZWFkcyI7aW1wb3J0e3Bvc2l4IGFzIHIsc2VwIGFzIG99ZnJvbSJub2RlOnBhdGgiO2ltcG9ydCphcyBpIGZyb20ibm9kZTpodHRwIjtpbXBvcnQqYXMgcyBmcm9tIm5vZGU6aHR0cHMiO2ltcG9ydHtSZWFkYWJsZSBhcyBjfWZyb20ibm9kZTpzdHJlYW0iO2ltcG9ydHtjcmVhdGVHemlwIGFzIHV9ZnJvbSJub2RlOnpsaWIiO2ltcG9ydCphcyBhIGZyb20ibm9kZTpuZXQiO2ltcG9ydCphcyBmIGZyb20ibm9kZTp0bHMiO2NvbnN0IGg9InVuZGVmaW5lZCI9PXR5cGVvZiBfX1NFTlRSWV9ERUJVR19ffHxfX1NFTlRSWV9ERUJVR19fLHA9Z2xvYmFsVGhpcyxkPSIxMC42NC4wIjtmdW5jdGlvbiBsKCl7cmV0dXJuIGcocCkscH1mdW5jdGlvbiBnKHQpe2NvbnN0IG49dC5fX1NFTlRSWV9fPXQuX19TRU5UUllfX3x8e307cmV0dXJuIG4udmVyc2lvbj1uLnZlcnNpb258fGQsbltkXT1uW2RdfHx7fX1mdW5jdGlvbiBtKHQsbixlPXApe2NvbnN0IHI9ZS5fX1NFTlRSWV9fPWUuX19TRU5UUllfX3x8e30sbz1yW2RdPXJbZF18fHt9O3JldHVybiBvW3RdfHwob1t0XT1uKCkpfWNvbnN0IHk9e307ZnVuY3Rpb24gYih0KXtpZighKCJjb25zb2xlImluIHApKXJldHVybiB0KCk7Y29uc3Qgbj1wLmNvbnNvbGUsZT17fSxyPU9iamVjdC5rZXlzKHkpO3IuZm9yRWFjaCh0PT57Y29uc3Qgcj15W3RdO2VbdF09blt0XSxuW3RdPXJ9KTt0cnl7cmV0dXJuIHQoKX1maW5hbGx5e3IuZm9yRWFjaCh0PT57blt0XT1lW3RdfSl9fWZ1bmN0aW9uIHYoKXtyZXR1cm4gUygpLmVuYWJsZWR9ZnVuY3Rpb24gXyh0LC4uLm4pe2gmJnYoKSYmYigoKT0+e3AuY29uc29sZVt0XShgU2VudHJ5IExvZ2dlciBbJHt0fV06YCwuLi5uKX0pfWZ1bmN0aW9uIFMoKXtyZXR1cm4gaD9tKCJsb2dnZXJTZXR0aW5ncyIsKCk9Pih7ZW5hYmxlZDohMX0pKTp7ZW5hYmxlZDohMX19Y29uc3Qgdz17ZW5hYmxlOmZ1bmN0aW9uKCl7UygpLmVuYWJsZWQ9ITB9LGRpc2FibGU6ZnVuY3Rpb24oKXtTKCkuZW5hYmxlZD0hMX0saXNFbmFibGVkOnYsbG9nOmZ1bmN0aW9uKC4uLnQpe18oImxvZyIsLi4udCl9LHdhcm46ZnVuY3Rpb24oLi4udCl7Xygid2FybiIsLi4udCl9LGVycm9yOmZ1bmN0aW9uKC4uLnQpe18oImVycm9yIiwuLi50KX19LCQ9L2NhcHR1cmVNZXNzYWdlfGNhcHR1cmVFeGNlcHRpb24vO2Z1bmN0aW9uIEUodCl7cmV0dXJuIHRbdC5sZW5ndGgtMV18fHt9fWNvbnN0IHg9Ijxhbm9ueW1vdXM+Ijtjb25zdCBOPU9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7ZnVuY3Rpb24gQyh0LG4pe3JldHVybiBOLmNhbGwodCk9PT1gW29iamVjdCAke259XWB9ZnVuY3Rpb24gaih0KXtyZXR1cm4gQm9vbGVhbih0Py50aGVuJiYiZnVuY3Rpb24iPT10eXBlb2YgdC50aGVuKX1mdW5jdGlvbiBSKHQsbil7dHJ5e3JldHVybiB0IGluc3RhbmNlb2Ygbn1jYXRjaHtyZXR1cm4hMX19ZnVuY3Rpb24gQSh0KXtpZihmdW5jdGlvbih0KXtzd2l0Y2goTi5jYWxsKHQpKXtjYXNlIltvYmplY3QgRXJyb3JdIjpjYXNlIltvYmplY3QgRXhjZXB0aW9uXSI6Y2FzZSJbb2JqZWN0IERPTUV4Y2VwdGlvbl0iOmNhc2UiW29iamVjdCBXZWJBc3NlbWJseS5FeGNlcHRpb25dIjpyZXR1cm4hMDtkZWZhdWx0OnJldHVybiBSKHQsRXJyb3IpfX0odCkpcmV0dXJue21lc3NhZ2U6dC5tZXNzYWdlLG5hbWU6dC5uYW1lLHN0YWNrOnQuc3RhY2ssLi4uSSh0KX07aWYobj10LCJ1bmRlZmluZWQiIT10eXBlb2YgRXZlbnQmJlIobixFdmVudCkpe2NvbnN0e3R5cGU6bix0YXJnZXQ6ZSxjdXJyZW50VGFyZ2V0OnIsZGV0YWlsOm99PXQ7cmV0dXJue3R5cGU6bix0YXJnZXQ6ZSxjdXJyZW50VGFyZ2V0OnIsLi4ubz97ZGV0YWlsOm99Ont9LC4uLkkodCl9fXZhciBuO3JldHVybiB0fWZ1bmN0aW9uIEkodCl7cmV0dXJuIm9iamVjdCI9PXR5cGVvZiB0JiZudWxsIT09dD9PYmplY3QuZnJvbUVudHJpZXMoT2JqZWN0LmVudHJpZXModCkpOnt9fWxldCBPO2Z1bmN0aW9uIFQodCl7aWYodm9pZCAwIT09TylyZXR1cm4gTz9PKHQpOnQoKTtjb25zdCBuPVN5bWJvbC5mb3IoIl9fU0VOVFJZX1NBRkVfUkFORE9NX0lEX1dSQVBQRVJfXyIpLGU9cDtyZXR1cm4gbiBpbiBlJiYiZnVuY3Rpb24iPT10eXBlb2YgZVtuXT8oTz1lW25dLE8odCkpOihPPW51bGwsdCgpKX1mdW5jdGlvbiBrKCl7cmV0dXJuIFQoKCk9Pk1hdGgucmFuZG9tKCkpfWZ1bmN0aW9uIFAoKXtyZXR1cm4gVCgoKT0+RGF0ZS5ub3coKSl9Y29uc3QgRD1TeW1ib2wuZm9yKCJzZW50cnkuc2tpcE5vcm1hbGl6YXRpb24iKSxVPVN5bWJvbC5mb3IoInNlbnRyeS5vdmVycmlkZU5vcm1hbGl6YXRpb25EZXB0aCIpO2Z1bmN0aW9uIEIodCxuPTEwMCxlPTEvMCl7dHJ5e3JldHVybiBMKCIiLHQsbixlKX1jYXRjaCh0KXtyZXR1cm57RVJST1I6YCoqbm9uLXNlcmlhbGl6YWJsZSoqICgke3R9KWB9fX1mdW5jdGlvbiBMKHQsbixlPTEvMCxyPTEvMCxvPWZ1bmN0aW9uKCl7Y29uc3QgdD1uZXcgV2Vha1NldDtmdW5jdGlvbiBuKG4pe3JldHVybiEhdC5oYXMobil8fCh0LmFkZChuKSwhMSl9ZnVuY3Rpb24gZShuKXt0LmRlbGV0ZShuKX1yZXR1cm5bbixlXX0oKSl7Y29uc3RbaSxzXT1vO2lmKG51bGw9PW58fFsiYm9vbGVhbiIsInN0cmluZyJdLmluY2x1ZGVzKHR5cGVvZiBuKXx8Im51bWJlciI9PXR5cGVvZiBuJiZOdW1iZXIuaXNGaW5pdGUobikpcmV0dXJuIG47Y29uc3QgYz1mdW5jdGlvbih0LG4pe3RyeXtpZigidW5kZWZpbmVkIiE9dHlwZW9mIGdsb2JhbCYmbj09PWdsb2JhbClyZXR1cm4iW0dsb2JhbF0iO2lmKCJudW1iZXIiPT10eXBlb2YgbiYmIU51bWJlci5pc0Zpbml0ZShuKSlyZXR1cm5gWyR7bn1dYDtpZigiZnVuY3Rpb24iPT10eXBlb2YgbilyZXR1cm5gW0Z1bmN0aW9uOiAke2Z1bmN0aW9uKHQpe3RyeXtyZXR1cm4gdCYmImZ1bmN0aW9uIj09dHlwZW9mIHQmJnQubmFtZXx8eH1jYXRjaHtyZXR1cm4geH19KG4pfV1gO2lmKCJzeW1ib2wiPT10eXBlb2YgbilyZXR1cm5gWyR7U3RyaW5nKG4pfV1gO2lmKCJiaWdpbnQiPT10eXBlb2YgbilyZXR1cm5gW0JpZ0ludDogJHtTdHJpbmcobil9XWA7Y29uc3QgdD1mdW5jdGlvbih0KXtjb25zdCBuPU9iamVjdC5nZXRQcm90b3R5cGVPZih0KTtyZXR1cm4gbj8uY29uc3RydWN0b3I/bi5jb25zdHJ1Y3Rvci5uYW1lOiJudWxsIHByb3RvdHlwZSJ9KG4pO3JldHVybmBbb2JqZWN0ICR7dH1dYH1jYXRjaCh0KXtyZXR1cm5gKipub24tc2VyaWFsaXphYmxlKiogKCR7dH0pYH19KDAsbik7aWYoIWMuc3RhcnRzV2l0aCgiW29iamVjdCAiKSlyZXR1cm4gYztpZihmdW5jdGlvbih0KXtyZXR1cm4gQm9vbGVhbih0W0RdKX0obikpcmV0dXJuIG47Y29uc3QgdT1mdW5jdGlvbih0KXtjb25zdCBuPXRbVV07cmV0dXJuIm51bWJlciI9PXR5cGVvZiBuP246dm9pZCAwfShuKSxhPXZvaWQgMCE9PXU/dTplO2lmKDA9PT1hKXJldHVybiBjLnJlcGxhY2UoIm9iamVjdCAiLCIiKTtpZihpKG4pKXJldHVybiJbQ2lyY3VsYXIgfl0iO2NvbnN0IGY9bjtpZihmJiYiZnVuY3Rpb24iPT10eXBlb2YgZi50b0pTT04pdHJ5e3JldHVybiBMKCIiLGYudG9KU09OKCksYS0xLHIsbyl9Y2F0Y2h7fWNvbnN0IGg9QXJyYXkuaXNBcnJheShuKT9bXTp7fTtsZXQgcD0wO2NvbnN0IGQ9QShuKTtmb3IoY29uc3QgdCBpbiBkKXtpZighT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGQsdCkpY29udGludWU7aWYocD49cil7aFt0XT0iW01heFByb3BlcnRpZXMgfl0iO2JyZWFrfWNvbnN0IG49ZFt0XTtoW3RdPUwodCxuLGEtMSxyLG8pLHArK31yZXR1cm4gcyhuKSxofWZ1bmN0aW9uIE0odCxuKXtjb25zdCBlPW4ucmVwbGFjZSgvXFwvZywiLyIpLnJlcGxhY2UoL1t8XFx7fSgpW1xdXiQrKj8uXS9nLCJcXCQmIik7bGV0IHI9dDt0cnl7cj1kZWNvZGVVUkkodCl9Y2F0Y2h7fXJldHVybiByLnJlcGxhY2UoL1xcL2csIi8iKS5yZXBsYWNlKC93ZWJwYWNrOlwvPy9nLCIiKS5yZXBsYWNlKG5ldyBSZWdFeHAoYChmaWxlOi8vKT8vKiR7ZX0vKmAsImlnIiksImFwcDovLy8iKX1mdW5jdGlvbiB6KHQsbj0wKXtyZXR1cm4ic3RyaW5nIiE9dHlwZW9mIHR8fDA9PT1ufHx0Lmxlbmd0aDw9bj90OmAke3Quc2xpY2UoMCxuKX0uLi5gfWxldCBGO2Z1bmN0aW9uIEcodD1mdW5jdGlvbigpe2NvbnN0IHQ9cDtyZXR1cm4gdC5jcnlwdG98fHQubXNDcnlwdG99KCkpe3RyeXtpZih0Py5yYW5kb21VVUlEKXJldHVybiBUKCgpPT50LnJhbmRvbVVVSUQoKSkucmVwbGFjZSgvLS9nLCIiKX1jYXRjaHt9cmV0dXJuIEZ8fChGPSIxMDAwMDAwMDEwMDA0MDAwODAwMDEwMDAwMDAwMDAwMCIpLEYucmVwbGFjZSgvWzAxOF0vZyx0PT4odF4oMTYqaygpJjE1KT4+dC80KS50b1N0cmluZygxNikpfWZ1bmN0aW9uIEooKXtyZXR1cm4gUCgpLzFlM31sZXQgVztmdW5jdGlvbiBZKCl7cmV0dXJuKFc/PyhXPWZ1bmN0aW9uKCl7Y29uc3R7cGVyZm9ybWFuY2U6dH09cDtpZighdD8ubm93fHwhdC50aW1lT3JpZ2luKXJldHVybiBKO2NvbnN0IG49dC50aW1lT3JpZ2luO3JldHVybigpPT4obitUKCgpPT50Lm5vdygpKSkvMWUzfSgpKSkoKX1mdW5jdGlvbiBIKHQpe2NvbnN0IG49WSgpLGU9e3NpZDpHKCksaW5pdDohMCx0aW1lc3RhbXA6bixzdGFydGVkOm4sZHVyYXRpb246MCxzdGF0dXM6Im9rIixlcnJvcnM6MCxpZ25vcmVEdXJhdGlvbjohMSx0b0pTT046KCk9PmZ1bmN0aW9uKHQpe3JldHVybntzaWQ6YCR7dC5zaWR9YCxpbml0OnQuaW5pdCxzdGFydGVkOm5ldyBEYXRlKDFlMyp0LnN0YXJ0ZWQpLnRvSVNPU3RyaW5nKCksdGltZXN0YW1wOm5ldyBEYXRlKDFlMyp0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxzdGF0dXM6dC5zdGF0dXMsZXJyb3JzOnQuZXJyb3JzLGRpZDoibnVtYmVyIj09dHlwZW9mIHQuZGlkfHwic3RyaW5nIj09dHlwZW9mIHQuZGlkP2Ake3QuZGlkfWA6dm9pZCAwLGR1cmF0aW9uOnQuZHVyYXRpb24sYWJub3JtYWxfbWVjaGFuaXNtOnQuYWJub3JtYWxfbWVjaGFuaXNtLGF0dHJzOntyZWxlYXNlOnQucmVsZWFzZSxlbnZpcm9ubWVudDp0LmVudmlyb25tZW50LGlwX2FkZHJlc3M6dC5pcEFkZHJlc3MsdXNlcl9hZ2VudDp0LnVzZXJBZ2VudH19fShlKX07cmV0dXJuIHQmJksoZSx0KSxlfWZ1bmN0aW9uIEsodCxuPXt9KXtpZihuLnVzZXImJighdC5pcEFkZHJlc3MmJm4udXNlci5pcF9hZGRyZXNzJiYodC5pcEFkZHJlc3M9bi51c2VyLmlwX2FkZHJlc3MpLHQuZGlkfHxuLmRpZHx8KHQuZGlkPW4udXNlci5pZHx8bi51c2VyLmVtYWlsfHxuLnVzZXIudXNlcm5hbWUpKSx0LnRpbWVzdGFtcD1uLnRpbWVzdGFtcHx8WSgpLG4uYWJub3JtYWxfbWVjaGFuaXNtJiYodC5hYm5vcm1hbF9tZWNoYW5pc209bi5hYm5vcm1hbF9tZWNoYW5pc20pLG4uaWdub3JlRHVyYXRpb24mJih0Lmlnbm9yZUR1cmF0aW9uPW4uaWdub3JlRHVyYXRpb24pLG4uc2lkJiYodC5zaWQ9MzI9PT1uLnNpZC5sZW5ndGg/bi5zaWQ6RygpKSx2b2lkIDAhPT1uLmluaXQmJih0LmluaXQ9bi5pbml0KSwhdC5kaWQmJm4uZGlkJiYodC5kaWQ9YCR7bi5kaWR9YCksIm51bWJlciI9PXR5cGVvZiBuLnN0YXJ0ZWQmJih0LnN0YXJ0ZWQ9bi5zdGFydGVkKSx0Lmlnbm9yZUR1cmF0aW9uKXQuZHVyYXRpb249dm9pZCAwO2Vsc2UgaWYoIm51bWJlciI9PXR5cGVvZiBuLmR1cmF0aW9uKXQuZHVyYXRpb249bi5kdXJhdGlvbjtlbHNle2NvbnN0IG49dC50aW1lc3RhbXAtdC5zdGFydGVkO3QuZHVyYXRpb249bj49MD9uOjB9bi5yZWxlYXNlJiYodC5yZWxlYXNlPW4ucmVsZWFzZSksbi5lbnZpcm9ubWVudCYmKHQuZW52aXJvbm1lbnQ9bi5lbnZpcm9ubWVudCksIXQuaXBBZGRyZXNzJiZuLmlwQWRkcmVzcyYmKHQuaXBBZGRyZXNzPW4uaXBBZGRyZXNzKSwhdC51c2VyQWdlbnQmJm4udXNlckFnZW50JiYodC51c2VyQWdlbnQ9bi51c2VyQWdlbnQpLCJudW1iZXIiPT10eXBlb2Ygbi5lcnJvcnMmJih0LmVycm9ycz1uLmVycm9ycyksbi5zdGF0dXMmJih0LnN0YXR1cz1uLnN0YXR1cyl9ZnVuY3Rpb24gWih0LG4sZT0yKXtpZighbnx8Im9iamVjdCIhPXR5cGVvZiBufHxlPD0wKXJldHVybiBuO2lmKHQmJjA9PT1PYmplY3Qua2V5cyhuKS5sZW5ndGgpcmV0dXJuIHQ7Y29uc3Qgcj17Li4udH07Zm9yKGNvbnN0IHQgaW4gbilPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobix0KSYmKHJbdF09WihyW3RdLG5bdF0sZS0xKSk7cmV0dXJuIHJ9ZnVuY3Rpb24gcSgpe3JldHVybiBHKCl9ZnVuY3Rpb24gVigpe3JldHVybiBHKCkuc3Vic3RyaW5nKDE2KX1mdW5jdGlvbiBRKHQpe2lmKHQpe2lmKCJvYmplY3QiPT10eXBlb2YgdCYmImRlcmVmImluIHQmJiJmdW5jdGlvbiI9PXR5cGVvZiB0LmRlcmVmKXRyeXtyZXR1cm4gdC5kZXJlZigpfWNhdGNoe3JldHVybn1yZXR1cm4gdH19Y29uc3QgWD0iX3NlbnRyeVNwYW4iO2Z1bmN0aW9uIHR0KHQsbil7bj9mdW5jdGlvbih0LG4sZSl7dHJ5e09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LG4se3ZhbHVlOmUsd3JpdGFibGU6ITAsY29uZmlndXJhYmxlOiEwfSl9Y2F0Y2h7aCYmdy5sb2coYEZhaWxlZCB0byBhZGQgbm9uLWVudW1lcmFibGUgcHJvcGVydHkgIiR7U3RyaW5nKG4pfSIgdG8gb2JqZWN0YCx0KX19KHQsWCxmdW5jdGlvbih0KXt0cnl7Y29uc3Qgbj1wLldlYWtSZWY7aWYoImZ1bmN0aW9uIj09dHlwZW9mIG4pcmV0dXJuIG5ldyBuKHQpfWNhdGNoe31yZXR1cm4gdH0obikpOmRlbGV0ZSB0W1hdfWZ1bmN0aW9uIG50KHQpe3JldHVybiBRKHRbWF0pfWNsYXNzIGV0e2NvbnN0cnVjdG9yKCl7dGhpcy50PSExLHRoaXMubz1bXSx0aGlzLmk9W10sdGhpcy51PVtdLHRoaXMuaD1bXSx0aGlzLnA9e30sdGhpcy5sPXt9LHRoaXMubT17fSx0aGlzLnY9e30sdGhpcy5fPXt9LHRoaXMuUz17fSx0aGlzLk49e3RyYWNlSWQ6cSgpLHNhbXBsZVJhbmQ6aygpfX1jbG9uZSgpe2NvbnN0IHQ9bmV3IGV0O3JldHVybiB0LnU9Wy4uLnRoaXMudV0sdC5sPXsuLi50aGlzLmx9LHQubT17Li4udGhpcy5tfSx0LnY9ey4uLnRoaXMudn0sdC5fPXsuLi50aGlzLl99LHRoaXMuXy5mbGFncyYmKHQuXy5mbGFncz17dmFsdWVzOlsuLi50aGlzLl8uZmxhZ3MudmFsdWVzXX0pLHQucD10aGlzLnAsdC5DPXRoaXMuQyx0Lmo9dGhpcy5qLHQuUj10aGlzLlIsdC5BPXRoaXMuQSx0Lmk9Wy4uLnRoaXMuaV0sdC5oPVsuLi50aGlzLmhdLHQuUz17Li4udGhpcy5TfSx0Lk49ey4uLnRoaXMuTn0sdC5JPXRoaXMuSSx0Lk89dGhpcy5PLHQuVD10aGlzLlQsdHQodCxudCh0aGlzKSksdH1zZXRDbGllbnQodCl7dGhpcy5JPXR9c2V0TGFzdEV2ZW50SWQodCl7dGhpcy5PPXR9Z2V0Q2xpZW50KCl7cmV0dXJuIHRoaXMuSX1sYXN0RXZlbnRJZCgpe3JldHVybiB0aGlzLk99YWRkU2NvcGVMaXN0ZW5lcih0KXt0aGlzLm8ucHVzaCh0KX1hZGRFdmVudFByb2Nlc3Nvcih0KXtyZXR1cm4gdGhpcy5pLnB1c2godCksdGhpc31zZXRVc2VyKHQpe3JldHVybiB0aGlzLnA9dHx8e2VtYWlsOnZvaWQgMCxpZDp2b2lkIDAsaXBfYWRkcmVzczp2b2lkIDAsdXNlcm5hbWU6dm9pZCAwfSx0aGlzLmomJksodGhpcy5qLHt1c2VyOnR9KSx0aGlzLmsoKSx0aGlzfWdldFVzZXIoKXtyZXR1cm4gdGhpcy5wfXNldENvbnZlcnNhdGlvbklkKHQpe3JldHVybiB0aGlzLlQ9dHx8dm9pZCAwLHRoaXMuaygpLHRoaXN9c2V0VGFncyh0KXtyZXR1cm4gdGhpcy5sPXsuLi50aGlzLmwsLi4udH0sdGhpcy5rKCksdGhpc31zZXRUYWcodCxuKXtyZXR1cm4gdGhpcy5zZXRUYWdzKHtbdF06bn0pfXNldEF0dHJpYnV0ZXModCl7cmV0dXJuIHRoaXMubT17Li4udGhpcy5tLC4uLnR9LHRoaXMuaygpLHRoaXN9c2V0QXR0cmlidXRlKHQsbil7cmV0dXJuIHRoaXMuc2V0QXR0cmlidXRlcyh7W3RdOm59KX1yZW1vdmVBdHRyaWJ1dGUodCl7cmV0dXJuIHQgaW4gdGhpcy5tJiYoZGVsZXRlIHRoaXMubVt0XSx0aGlzLmsoKSksdGhpc31zZXRFeHRyYXModCl7cmV0dXJuIHRoaXMudj17Li4udGhpcy52LC4uLnR9LHRoaXMuaygpLHRoaXN9c2V0RXh0cmEodCxuKXtyZXR1cm4gdGhpcy52PXsuLi50aGlzLnYsW3RdOm59LHRoaXMuaygpLHRoaXN9c2V0RmluZ2VycHJpbnQodCl7cmV0dXJuIHRoaXMuQT10LHRoaXMuaygpLHRoaXN9c2V0TGV2ZWwodCl7cmV0dXJuIHRoaXMuQz10LHRoaXMuaygpLHRoaXN9c2V0VHJhbnNhY3Rpb25OYW1lKHQpe3JldHVybiB0aGlzLlI9dCx0aGlzLmsoKSx0aGlzfXNldENvbnRleHQodCxuKXtyZXR1cm4gbnVsbD09PW4/ZGVsZXRlIHRoaXMuX1t0XTp0aGlzLl9bdF09bix0aGlzLmsoKSx0aGlzfXNldFNlc3Npb24odCl7cmV0dXJuIHQ/dGhpcy5qPXQ6ZGVsZXRlIHRoaXMuaix0aGlzLmsoKSx0aGlzfWdldFNlc3Npb24oKXtyZXR1cm4gdGhpcy5qfXVwZGF0ZSh0KXtpZighdClyZXR1cm4gdGhpcztjb25zdCBuPSJmdW5jdGlvbiI9PXR5cGVvZiB0P3QodGhpcyk6dCxlPW4gaW5zdGFuY2VvZiBldD9uLmdldFNjb3BlRGF0YSgpOkMobiwiT2JqZWN0Iik/dDp2b2lkIDA7Y29uc3R7dGFnczpyLGF0dHJpYnV0ZXM6byxleHRyYTppLHVzZXI6cyxjb250ZXh0czpjLGxldmVsOnUsZmluZ2VycHJpbnQ6YT1bXSxwcm9wYWdhdGlvbkNvbnRleHQ6Zixjb252ZXJzYXRpb25JZDpofT1lfHx7fTtyZXR1cm4gdGhpcy5sPXsuLi50aGlzLmwsLi4ucn0sdGhpcy5tPXsuLi50aGlzLm0sLi4ub30sdGhpcy52PXsuLi50aGlzLnYsLi4uaX0sdGhpcy5fPXsuLi50aGlzLl8sLi4uY30scyYmT2JqZWN0LmtleXMocykubGVuZ3RoJiYodGhpcy5wPXMpLHUmJih0aGlzLkM9dSksYS5sZW5ndGgmJih0aGlzLkE9YSksZiYmKHRoaXMuTj1mKSxoJiYodGhpcy5UPWgpLHRoaXN9Y2xlYXIoKXtyZXR1cm4gdGhpcy51PVtdLHRoaXMubD17fSx0aGlzLm09e30sdGhpcy52PXt9LHRoaXMucD17fSx0aGlzLl89e30sdGhpcy5DPXZvaWQgMCx0aGlzLlI9dm9pZCAwLHRoaXMuQT12b2lkIDAsdGhpcy5qPXZvaWQgMCx0aGlzLlQ9dm9pZCAwLHR0KHRoaXMsdm9pZCAwKSx0aGlzLmg9W10sdGhpcy5zZXRQcm9wYWdhdGlvbkNvbnRleHQoe3RyYWNlSWQ6cSgpLHNhbXBsZVJhbmQ6aygpfSksdGhpcy5rKCksdGhpc31hZGRCcmVhZGNydW1iKHQsbil7Y29uc3QgZT0ibnVtYmVyIj09dHlwZW9mIG4/bjoxMDA7aWYoZTw9MClyZXR1cm4gdGhpcztjb25zdCByPXt0aW1lc3RhbXA6SigpLC4uLnQsbWVzc2FnZTp0Lm1lc3NhZ2U/eih0Lm1lc3NhZ2UsMjA0OCk6dC5tZXNzYWdlfTtyZXR1cm4gdGhpcy51LnB1c2gociksdGhpcy51Lmxlbmd0aD5lJiYodGhpcy51PXRoaXMudS5zbGljZSgtZSksdGhpcy5JPy5yZWNvcmREcm9wcGVkRXZlbnQoImJ1ZmZlcl9vdmVyZmxvdyIsImxvZ19pdGVtIikpLHRoaXMuaygpLHRoaXN9Z2V0TGFzdEJyZWFkY3J1bWIoKXtyZXR1cm4gdGhpcy51W3RoaXMudS5sZW5ndGgtMV19Y2xlYXJCcmVhZGNydW1icygpe3JldHVybiB0aGlzLnU9W10sdGhpcy5rKCksdGhpc31hZGRBdHRhY2htZW50KHQpe3JldHVybiB0aGlzLmgucHVzaCh0KSx0aGlzfWNsZWFyQXR0YWNobWVudHMoKXtyZXR1cm4gdGhpcy5oPVtdLHRoaXN9Z2V0U2NvcGVEYXRhKCl7cmV0dXJue2JyZWFkY3J1bWJzOnRoaXMudSxhdHRhY2htZW50czp0aGlzLmgsY29udGV4dHM6dGhpcy5fLHRhZ3M6dGhpcy5sLGF0dHJpYnV0ZXM6dGhpcy5tLGV4dHJhOnRoaXMudix1c2VyOnRoaXMucCxsZXZlbDp0aGlzLkMsZmluZ2VycHJpbnQ6dGhpcy5BfHxbXSxldmVudFByb2Nlc3NvcnM6dGhpcy5pLHByb3BhZ2F0aW9uQ29udGV4dDp0aGlzLk4sc2RrUHJvY2Vzc2luZ01ldGFkYXRhOnRoaXMuUyx0cmFuc2FjdGlvbk5hbWU6dGhpcy5SLHNwYW46bnQodGhpcyksY29udmVyc2F0aW9uSWQ6dGhpcy5UfX1zZXRTREtQcm9jZXNzaW5nTWV0YWRhdGEodCl7cmV0dXJuIHRoaXMuUz1aKHRoaXMuUyx0LDIpLHRoaXN9c2V0UHJvcGFnYXRpb25Db250ZXh0KHQpe3JldHVybiB0aGlzLk49dCx0aGlzfWdldFByb3BhZ2F0aW9uQ29udGV4dCgpe3JldHVybiB0aGlzLk59Y2FwdHVyZUV4Y2VwdGlvbih0LG4pe2NvbnN0IGU9bj8uZXZlbnRfaWR8fEcoKTtpZighdGhpcy5JKXJldHVybiBoJiZ3Lndhcm4oIk5vIGNsaWVudCBjb25maWd1cmVkIG9uIHNjb3BlIC0gd2lsbCBub3QgY2FwdHVyZSBleGNlcHRpb24hIiksZTtjb25zdCByPW5ldyBFcnJvcigiU2VudHJ5IHN5bnRoZXRpY0V4Y2VwdGlvbiIpO3JldHVybiB0aGlzLkkuY2FwdHVyZUV4Y2VwdGlvbih0LHtvcmlnaW5hbEV4Y2VwdGlvbjp0LHN5bnRoZXRpY0V4Y2VwdGlvbjpyLC4uLm4sZXZlbnRfaWQ6ZX0sdGhpcyksZX1jYXB0dXJlTWVzc2FnZSh0LG4sZSl7Y29uc3Qgcj1lPy5ldmVudF9pZHx8RygpO2lmKCF0aGlzLkkpcmV0dXJuIGgmJncud2FybigiTm8gY2xpZW50IGNvbmZpZ3VyZWQgb24gc2NvcGUgLSB3aWxsIG5vdCBjYXB0dXJlIG1lc3NhZ2UhIikscjtjb25zdCBvPWU/LnN5bnRoZXRpY0V4Y2VwdGlvbj8/bmV3IEVycm9yKHQpO3JldHVybiB0aGlzLkkuY2FwdHVyZU1lc3NhZ2UodCxuLHtvcmlnaW5hbEV4Y2VwdGlvbjp0LHN5bnRoZXRpY0V4Y2VwdGlvbjpvLC4uLmUsZXZlbnRfaWQ6cn0sdGhpcykscn1jYXB0dXJlRXZlbnQodCxuKXtjb25zdCBlPXQuZXZlbnRfaWR8fG4/LmV2ZW50X2lkfHxHKCk7cmV0dXJuIHRoaXMuST8odGhpcy5JLmNhcHR1cmVFdmVudCh0LHsuLi5uLGV2ZW50X2lkOmV9LHRoaXMpLGUpOihoJiZ3Lndhcm4oIk5vIGNsaWVudCBjb25maWd1cmVkIG9uIHNjb3BlIC0gd2lsbCBub3QgY2FwdHVyZSBldmVudCEiKSxlKX1rKCl7dGhpcy50fHwodGhpcy50PSEwLHRoaXMuby5mb3JFYWNoKHQ9Pnt0KHRoaXMpfSksdGhpcy50PSExKX19Y29uc3QgcnQ9dD0+dCBpbnN0YW5jZW9mIFByb21pc2UmJiF0W290XSxvdD1TeW1ib2woImNoYWluZWQgUHJvbWlzZUxpa2UiKSxpdD0odCxuKT0+e2lmKCFuKXJldHVybiB0O2xldCBlPSExO2Zvcihjb25zdCByIGluIHQpe2lmKHIgaW4gbiljb250aW51ZTtlPSEwO2NvbnN0IG89dFtyXTsiZnVuY3Rpb24iPT10eXBlb2Ygbz9PYmplY3QuZGVmaW5lUHJvcGVydHkobixyLHt2YWx1ZTooLi4ubik9Pm8uYXBwbHkodCxuKSxlbnVtZXJhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMCx3cml0YWJsZTohMH0pOm5bcl09b31yZXR1cm4gZSYmT2JqZWN0LmFzc2lnbihuLHtbb3RdOiEwfSksbn07Y2xhc3Mgc3R7Y29uc3RydWN0b3IodCxuKXtsZXQgZSxyO2U9dHx8bmV3IGV0LHI9bnx8bmV3IGV0LHRoaXMuUD1be3Njb3BlOmV9XSx0aGlzLkQ9cn13aXRoU2NvcGUodCl7Y29uc3Qgbj10aGlzLlUoKTtsZXQgZTt0cnl7ZT10KG4pfWNhdGNoKHQpe3Rocm93IHRoaXMuQigpLHR9cmV0dXJuIGooZSk/KCh0LG4sZSk9Pntjb25zdCByPXQudGhlbih0PT4obih0KSx0KSx0PT57dGhyb3cgZSh0KSx0fSk7cmV0dXJuIHJ0KHIpJiZydCh0KT9yOml0KHQscil9KShlLCgpPT50aGlzLkIoKSwoKT0+dGhpcy5CKCkpOih0aGlzLkIoKSxlKX1nZXRDbGllbnQoKXtyZXR1cm4gdGhpcy5nZXRTdGFja1RvcCgpLmNsaWVudH1nZXRTY29wZSgpe3JldHVybiB0aGlzLmdldFN0YWNrVG9wKCkuc2NvcGV9Z2V0SXNvbGF0aW9uU2NvcGUoKXtyZXR1cm4gdGhpcy5EfWdldFN0YWNrVG9wKCl7cmV0dXJuIHRoaXMuUFt0aGlzLlAubGVuZ3RoLTFdfVUoKXtjb25zdCB0PXRoaXMuZ2V0U2NvcGUoKS5jbG9uZSgpO3JldHVybiB0aGlzLlAucHVzaCh7Y2xpZW50OnRoaXMuZ2V0Q2xpZW50KCksc2NvcGU6dH0pLHR9Qigpe3JldHVybiEodGhpcy5QLmxlbmd0aDw9MSkmJiEhdGhpcy5QLnBvcCgpfX1mdW5jdGlvbiBjdCgpe2NvbnN0IHQ9ZyhsKCkpO3JldHVybiB0LnN0YWNrPXQuc3RhY2t8fG5ldyBzdChtKCJkZWZhdWx0Q3VycmVudFNjb3BlIiwoKT0+bmV3IGV0KSxtKCJkZWZhdWx0SXNvbGF0aW9uU2NvcGUiLCgpPT5uZXcgZXQpKX1mdW5jdGlvbiB1dCh0KXtyZXR1cm4gY3QoKS53aXRoU2NvcGUodCl9ZnVuY3Rpb24gYXQodCxuKXtjb25zdCBlPWN0KCk7cmV0dXJuIGUud2l0aFNjb3BlKCgpPT4oZS5nZXRTdGFja1RvcCgpLnNjb3BlPXQsbih0KSkpfWZ1bmN0aW9uIGZ0KHQpe3JldHVybiBjdCgpLndpdGhTY29wZSgoKT0+dChjdCgpLmdldElzb2xhdGlvblNjb3BlKCkpKX1mdW5jdGlvbiBodCh0KXtjb25zdCBuPWcodCk7cmV0dXJuIG4uYWNzP24uYWNzOnt3aXRoSXNvbGF0aW9uU2NvcGU6ZnQsd2l0aFNjb3BlOnV0LHdpdGhTZXRTY29wZTphdCx3aXRoU2V0SXNvbGF0aW9uU2NvcGU6KHQsbik9PmZ0KG4pLGdldEN1cnJlbnRTY29wZTooKT0+Y3QoKS5nZXRTY29wZSgpLGdldElzb2xhdGlvblNjb3BlOigpPT5jdCgpLmdldElzb2xhdGlvblNjb3BlKCl9fWZ1bmN0aW9uIHB0KCl7cmV0dXJuIGh0KGwoKSkuZ2V0Q3VycmVudFNjb3BlKCkuZ2V0Q2xpZW50KCl9ZnVuY3Rpb24gZHQodCl7Y29uc3Qgbj10O3JldHVybntzY29wZTpuLl9zZW50cnlTY29wZSxpc29sYXRpb25TY29wZTpRKG4uX3NlbnRyeUlzb2xhdGlvblNjb3BlKX19Y29uc3QgbHQ9InNlbnRyeS0iO2Z1bmN0aW9uIGd0KHQpe2NvbnN0IG49ZnVuY3Rpb24odCl7aWYoIXR8fChuPXQsIUMobiwiU3RyaW5nIikmJiFBcnJheS5pc0FycmF5KHQpKSlyZXR1cm47dmFyIG47aWYoQXJyYXkuaXNBcnJheSh0KSlyZXR1cm4gdC5yZWR1Y2UoKHQsbik9Pntjb25zdCBlPW10KG4pO3JldHVybiBPYmplY3QuZW50cmllcyhlKS5mb3JFYWNoKChbbixlXSk9Pnt0W25dPWV9KSx0fSx7fSk7cmV0dXJuIG10KHQpfSh0KTtpZighbilyZXR1cm47Y29uc3QgZT1PYmplY3QuZW50cmllcyhuKS5yZWR1Y2UoKHQsW24sZV0pPT57aWYobi5zdGFydHNXaXRoKGx0KSl7dFtuLnNsaWNlKDcpXT1lfXJldHVybiB0fSx7fSk7cmV0dXJuIE9iamVjdC5rZXlzKGUpLmxlbmd0aD4wP2U6dm9pZCAwfWZ1bmN0aW9uIG10KHQpe3JldHVybiB0LnNwbGl0KCIsIikubWFwKHQ9Pntjb25zdCBuPXQuaW5kZXhPZigiPSIpO2lmKC0xPT09bilyZXR1cm5bXTtyZXR1cm5bdC5zbGljZSgwLG4pLHQuc2xpY2UobisxKV0ubWFwKHQ9Pnt0cnl7cmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudCh0LnRyaW0oKSl9Y2F0Y2h7cmV0dXJufX0pfSkucmVkdWNlKCh0LFtuLGVdKT0+KG4mJmUmJih0W25dPWUpLHQpLHt9KX1jb25zdCB5dD0vXm8oXGQrKVwuLztmdW5jdGlvbiBidCh0LG49ITEpe2NvbnN0e2hvc3Q6ZSxwYXRoOnIscGFzczpvLHBvcnQ6aSxwcm9qZWN0SWQ6cyxwcm90b2NvbDpjLHB1YmxpY0tleTp1fT10O3JldHVybmAke2N9Oi8vJHt1fSR7biYmbz9gOiR7b31gOiIifUAke2V9JHtpP2A6JHtpfWA6IiJ9LyR7cj9gJHtyfS9gOnJ9JHtzfWB9ZnVuY3Rpb24gdnQodCl7Y29uc3Qgbj10LmdldE9wdGlvbnMoKSx7aG9zdDplfT10LmdldERzbigpfHx7fTtsZXQgcjtyZXR1cm4gbi5vcmdJZD9yPVN0cmluZyhuLm9yZ0lkKTplJiYocj1mdW5jdGlvbih0KXtjb25zdCBuPXQubWF0Y2goeXQpO3JldHVybiBuPy5bMV19KGUpKSxyfWZ1bmN0aW9uIF90KHQpe2NvbnN0e3NwYW5JZDpuLHRyYWNlSWQ6ZSxpc1JlbW90ZTpyfT10LnNwYW5Db250ZXh0KCksbz1yP246RXQodCkucGFyZW50X3NwYW5faWQsaT1kdCh0KS5zY29wZTtyZXR1cm57cGFyZW50X3NwYW5faWQ6byxzcGFuX2lkOnI/aT8uZ2V0UHJvcGFnYXRpb25Db250ZXh0KCkucHJvcGFnYXRpb25TcGFuSWR8fFYoKTpuLHRyYWNlX2lkOmV9fWZ1bmN0aW9uIFN0KHQpe3JldHVybiB0JiZ0Lmxlbmd0aD4wP3QubWFwKCh7Y29udGV4dDp7c3BhbklkOnQsdHJhY2VJZDpuLHRyYWNlRmxhZ3M6ZSwuLi5yfSxhdHRyaWJ1dGVzOm99KT0+KHtzcGFuX2lkOnQsdHJhY2VfaWQ6bixzYW1wbGVkOjE9PT1lLGF0dHJpYnV0ZXM6bywuLi5yfSkpOnZvaWQgMH1mdW5jdGlvbiB3dCh0KXtyZXR1cm4ibnVtYmVyIj09dHlwZW9mIHQ/JHQodCk6QXJyYXkuaXNBcnJheSh0KT90WzBdK3RbMV0vMWU5OnQgaW5zdGFuY2VvZiBEYXRlPyR0KHQuZ2V0VGltZSgpKTpZKCl9ZnVuY3Rpb24gJHQodCl7cmV0dXJuIHQ+OTk5OTk5OTk5OT90LzFlMzp0fWZ1bmN0aW9uIEV0KHQpe2lmKGZ1bmN0aW9uKHQpe3JldHVybiJmdW5jdGlvbiI9PXR5cGVvZiB0LmdldFNwYW5KU09OfSh0KSlyZXR1cm4gdC5nZXRTcGFuSlNPTigpO2NvbnN0e3NwYW5JZDpuLHRyYWNlSWQ6ZX09dC5zcGFuQ29udGV4dCgpO2lmKGZ1bmN0aW9uKHQpe2NvbnN0IG49dDtyZXR1cm4hIShuLmF0dHJpYnV0ZXMmJm4uc3RhcnRUaW1lJiZuLm5hbWUmJm4uZW5kVGltZSYmbi5zdGF0dXMpfSh0KSl7Y29uc3R7YXR0cmlidXRlczpyLHN0YXJ0VGltZTpvLG5hbWU6aSxlbmRUaW1lOnMsc3RhdHVzOmMsbGlua3M6dX09dDtyZXR1cm57c3Bhbl9pZDpuLHRyYWNlX2lkOmUsZGF0YTpyLGRlc2NyaXB0aW9uOmkscGFyZW50X3NwYW5faWQ6eHQodCksc3RhcnRfdGltZXN0YW1wOnd0KG8pLHRpbWVzdGFtcDp3dChzKXx8dm9pZCAwLHN0YXR1czpOdChjKSxvcDpyWyJzZW50cnkub3AiXSxvcmlnaW46clsic2VudHJ5Lm9yaWdpbiJdLGxpbmtzOlN0KHUpfX1yZXR1cm57c3Bhbl9pZDpuLHRyYWNlX2lkOmUsc3RhcnRfdGltZXN0YW1wOjAsZGF0YTp7fX19ZnVuY3Rpb24geHQodCl7cmV0dXJuInBhcmVudFNwYW5JZCJpbiB0P3QucGFyZW50U3BhbklkOiJwYXJlbnRTcGFuQ29udGV4dCJpbiB0P3QucGFyZW50U3BhbkNvbnRleHQ/LnNwYW5JZDp2b2lkIDB9ZnVuY3Rpb24gTnQodCl7aWYodCYmMCE9PXQuY29kZSlyZXR1cm4gMT09PXQuY29kZT8ib2siOnQubWVzc2FnZXx8ImludGVybmFsX2Vycm9yIn1jb25zdCBDdD1mdW5jdGlvbih0KXtyZXR1cm4gdC5fc2VudHJ5Um9vdFNwYW58fHR9O2Z1bmN0aW9uIGp0KHQpe2lmKCJib29sZWFuIj09dHlwZW9mIF9fU0VOVFJZX1RSQUNJTkdfXyYmIV9fU0VOVFJZX1RSQUNJTkdfXylyZXR1cm4hMTtjb25zdCBuPXR8fHB0KCk/LmdldE9wdGlvbnMoKTtyZXR1cm4hKCFufHxudWxsPT1uLnRyYWNlc1NhbXBsZVJhdGUmJiFuLnRyYWNlc1NhbXBsZXIpfWNvbnN0IFJ0PVN5bWJvbC5mb3IoInNlbnRyeS5ub25SZWNvcmRpbmdTcGFuIik7ZnVuY3Rpb24gQXQodCxuKXtjb25zdCBlPW4uZ2V0T3B0aW9ucygpLHtwdWJsaWNLZXk6cn09bi5nZXREc24oKXx8e30sbz17ZW52aXJvbm1lbnQ6ZS5lbnZpcm9ubWVudHx8InByb2R1Y3Rpb24iLHJlbGVhc2U6ZS5yZWxlYXNlLHB1YmxpY19rZXk6cix0cmFjZV9pZDp0LG9yZ19pZDp2dChuKX07cmV0dXJuIG4uZW1pdCgiY3JlYXRlRHNjIixvKSxvfWZ1bmN0aW9uIEl0KHQsbil7Y29uc3QgZT1uLmdldFByb3BhZ2F0aW9uQ29udGV4dCgpO3JldHVybiBlLmRzY3x8QXQoZS50cmFjZUlkLHQpfWZ1bmN0aW9uIE90KHQpe2NvbnN0IG49cHQoKTtpZighbilyZXR1cm57fTtjb25zdCBlPUN0KHQpLHI9RXQoZSksbz1yLmRhdGEsaT1lLnNwYW5Db250ZXh0KCkudHJhY2VTdGF0ZSxzPWk/LmdldCgic2VudHJ5LnNhbXBsZV9yYXRlIik/P29bInNlbnRyeS5zYW1wbGVfcmF0ZSJdPz9vWyJzZW50cnkucHJldmlvdXNfdHJhY2Vfc2FtcGxlX3JhdGUiXTtmdW5jdGlvbiBjKHQpe3JldHVybiJudW1iZXIiIT10eXBlb2YgcyYmInN0cmluZyIhPXR5cGVvZiBzfHwodC5zYW1wbGVfcmF0ZT1gJHtzfWApLHR9Y29uc3QgdT1lLl9mcm96ZW5Ec2M7aWYodSlyZXR1cm4gYyh1KTtpZihmdW5jdGlvbih0KXtyZXR1cm4hIXQmJiEwPT09dFtSdF19KGUpJiYhanQobi5nZXRPcHRpb25zKCkpKXtjb25zdCB0PWR0KGUpLnNjb3BlO2lmKHQpcmV0dXJuIGMoey4uLkl0KG4sdCl9KX1jb25zdCBhPWk/LmdldCgic2VudHJ5LmRzYyIpLGY9YSYmZ3QoYSk7aWYoZilyZXR1cm4gYyhmKTtjb25zdCBoPUF0KHQuc3BhbkNvbnRleHQoKS50cmFjZUlkLG4pLHA9b1sic2VudHJ5LnNvdXJjZSJdPz9vWyJzZW50cnkuc3Bhbi5zb3VyY2UiXSxkPXIuZGVzY3JpcHRpb247cmV0dXJuInVybCIhPT1wJiZkJiYoaC50cmFuc2FjdGlvbj1kKSxqdCgpJiYoaC5zYW1wbGVkPVN0cmluZyhmdW5jdGlvbih0KXtjb25zdHt0cmFjZUZsYWdzOm59PXQuc3BhbkNvbnRleHQoKTtyZXR1cm4gMT09PW59KGUpKSxoLnNhbXBsZV9yYW5kPWk/LmdldCgic2VudHJ5LnNhbXBsZV9yYW5kIik/P2R0KGUpLnNjb3BlPy5nZXRQcm9wYWdhdGlvbkNvbnRleHQoKS5zYW1wbGVSYW5kLnRvU3RyaW5nKCkpLGMoaCksbi5lbWl0KCJjcmVhdGVEc2MiLGgsZSksaH1mdW5jdGlvbiBUdCh0LG49W10pe3JldHVyblt0LG5dfWZ1bmN0aW9uIGt0KHQsbil7Y29uc3QgZT10WzFdO2Zvcihjb25zdCB0IG9mIGUpe2lmKG4odCx0WzBdLnR5cGUpKXJldHVybiEwfXJldHVybiExfWZ1bmN0aW9uIFB0KHQpe2NvbnN0IG49ZyhwKTtyZXR1cm4gbi5lbmNvZGVQb2x5ZmlsbD9uLmVuY29kZVBvbHlmaWxsKHQpOihuZXcgVGV4dEVuY29kZXIpLmVuY29kZSh0KX1mdW5jdGlvbiBEdCh0KXtjb25zdFtuLGVdPXQ7bGV0IHI9SlNPTi5zdHJpbmdpZnkobik7ZnVuY3Rpb24gbyh0KXsic3RyaW5nIj09dHlwZW9mIHI/cj0ic3RyaW5nIj09dHlwZW9mIHQ/cit0OltQdChyKSx0XTpyLnB1c2goInN0cmluZyI9PXR5cGVvZiB0P1B0KHQpOnQpfWZvcihjb25zdCB0IG9mIGUpe2NvbnN0W24sZV09dDtpZihvKGBcbiR7SlNPTi5zdHJpbmdpZnkobil9XG5gKSwic3RyaW5nIj09dHlwZW9mIGV8fGUgaW5zdGFuY2VvZiBVaW50OEFycmF5KW8oZSk7ZWxzZXtsZXQgdDt0cnl7dD1KU09OLnN0cmluZ2lmeShlKX1jYXRjaHt0PUpTT04uc3RyaW5naWZ5KEIoZSkpfW8odCl9fXJldHVybiJzdHJpbmciPT10eXBlb2Ygcj9yOmZ1bmN0aW9uKHQpe2NvbnN0IG49dC5yZWR1Y2UoKHQsbik9PnQrbi5sZW5ndGgsMCksZT1uZXcgVWludDhBcnJheShuKTtsZXQgcj0wO2Zvcihjb25zdCBuIG9mIHQpZS5zZXQobixyKSxyKz1uLmxlbmd0aDtyZXR1cm4gZX0ocil9Y29uc3QgVXQ9e3Nlc3Npb25zOiJzZXNzaW9uIixldmVudDoiZXJyb3IiLGNsaWVudF9yZXBvcnQ6ImludGVybmFsIix1c2VyX3JlcG9ydDoiZGVmYXVsdCIscHJvZmlsZV9jaHVuazoicHJvZmlsZSIscmVwbGF5X2V2ZW50OiJyZXBsYXkiLHJlcGxheV9yZWNvcmRpbmc6InJlcGxheSIsY2hlY2tfaW46Im1vbml0b3IiLHJhd19zZWN1cml0eToic2VjdXJpdHkiLGxvZzoibG9nX2l0ZW0iLHRyYWNlX21ldHJpYzoibWV0cmljIn07ZnVuY3Rpb24gQnQodCl7cmV0dXJuIGZ1bmN0aW9uKHQpe3JldHVybiB0IGluIFV0fSh0KT9VdFt0XTp0fWZ1bmN0aW9uIEx0KHQpe2lmKCF0Py5zZGspcmV0dXJuO2NvbnN0e25hbWU6bix2ZXJzaW9uOmV9PXQuc2RrO3JldHVybntuYW1lOm4sdmVyc2lvbjplfX1mdW5jdGlvbiBNdCh0LG4sZSxyKXtjb25zdCBvPUx0KGUpLGk9dC50eXBlJiYicmVwbGF5X2V2ZW50IiE9PXQudHlwZT90LnR5cGU6ImV2ZW50IjshZnVuY3Rpb24odCxuKXtpZighbilyZXR1cm4gdDtjb25zdCBlPXQuc2RrfHx7fTt0LnNkaz17Li4uZSxuYW1lOmUubmFtZXx8bi5uYW1lLHZlcnNpb246ZS52ZXJzaW9ufHxuLnZlcnNpb24saW50ZWdyYXRpb25zOlsuLi50LnNkaz8uaW50ZWdyYXRpb25zfHxbXSwuLi5uLmludGVncmF0aW9uc3x8W11dLHBhY2thZ2VzOlsuLi50LnNkaz8ucGFja2FnZXN8fFtdLC4uLm4ucGFja2FnZXN8fFtdXSxzZXR0aW5nczp0LnNkaz8uc2V0dGluZ3N8fG4uc2V0dGluZ3M/ey4uLnQuc2RrPy5zZXR0aW5ncywuLi5uLnNldHRpbmdzfTp2b2lkIDB9fSh0LGU/LnNkayk7Y29uc3Qgcz1mdW5jdGlvbih0LG4sZSxyKXtjb25zdCBvPXQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhPy5keW5hbWljU2FtcGxpbmdDb250ZXh0O3JldHVybntldmVudF9pZDp0LmV2ZW50X2lkLHNlbnRfYXQ6bmV3IERhdGUoUCgpKS50b0lTT1N0cmluZygpLC4uLm4mJntzZGs6bn0sLi4uISFlJiZyJiZ7ZHNuOmJ0KHIpfSwuLi5vJiZ7dHJhY2U6b319fSh0LG8scixuKTtkZWxldGUgdC5zZGtQcm9jZXNzaW5nTWV0YWRhdGE7cmV0dXJuIFR0KHMsW1t7dHlwZTppfSx0XV0pfWNvbnN0IHp0PSJfX1NFTlRSWV9TVVBQUkVTU19UUkFDSU5HX18iO2Z1bmN0aW9uIEZ0KHQpe2NvbnN0IG49aHQobCgpKTtyZXR1cm4gbi5zdXBwcmVzc1RyYWNpbmc/bi5zdXBwcmVzc1RyYWNpbmcodCk6ZnVuY3Rpb24oLi4udCl7Y29uc3Qgbj1odChsKCkpO2lmKDI9PT10Lmxlbmd0aCl7Y29uc3RbZSxyXT10O3JldHVybiBlP24ud2l0aFNldFNjb3BlKGUscik6bi53aXRoU2NvcGUocil9cmV0dXJuIG4ud2l0aFNjb3BlKHRbMF0pfShuPT57bi5zZXRTREtQcm9jZXNzaW5nTWV0YWRhdGEoe1t6dF06ITB9KTtjb25zdCBlPXQoKTtyZXR1cm4gbi5zZXRTREtQcm9jZXNzaW5nTWV0YWRhdGEoe1t6dF06dm9pZCAwfSksZX0pfWZ1bmN0aW9uIEd0KHQsbil7Y29uc3R7ZmluZ2VycHJpbnQ6ZSxzcGFuOnIsYnJlYWRjcnVtYnM6byxzZGtQcm9jZXNzaW5nTWV0YWRhdGE6aX09bjshZnVuY3Rpb24odCxuKXtjb25zdHtleHRyYTplLHRhZ3M6cix1c2VyOm8sY29udGV4dHM6aSxsZXZlbDpzLHRyYW5zYWN0aW9uTmFtZTpjfT1uO09iamVjdC5rZXlzKGUpLmxlbmd0aCYmKHQuZXh0cmE9ey4uLmUsLi4udC5leHRyYX0pO09iamVjdC5rZXlzKHIpLmxlbmd0aCYmKHQudGFncz17Li4uciwuLi50LnRhZ3N9KTtPYmplY3Qua2V5cyhvKS5sZW5ndGgmJih0LnVzZXI9ey4uLm8sLi4udC51c2VyfSk7T2JqZWN0LmtleXMoaSkubGVuZ3RoJiYodC5jb250ZXh0cz17Li4uaSwuLi50LmNvbnRleHRzfSk7cyYmKHQubGV2ZWw9cyk7YyYmInRyYW5zYWN0aW9uIiE9PXQudHlwZSYmKHQudHJhbnNhY3Rpb249Yyl9KHQsbiksciYmZnVuY3Rpb24odCxuKXt0LmNvbnRleHRzPXt0cmFjZTpfdChuKSwuLi50LmNvbnRleHRzfSx0LnNka1Byb2Nlc3NpbmdNZXRhZGF0YT17ZHluYW1pY1NhbXBsaW5nQ29udGV4dDpPdChuKSwuLi50LnNka1Byb2Nlc3NpbmdNZXRhZGF0YX07Y29uc3QgZT1DdChuKSxyPUV0KGUpLmRlc2NyaXB0aW9uO3ImJiF0LnRyYW5zYWN0aW9uJiYidHJhbnNhY3Rpb24iPT09dC50eXBlJiYodC50cmFuc2FjdGlvbj1yKX0odCxyKSxmdW5jdGlvbih0LG4pe3QuZmluZ2VycHJpbnQ9dC5maW5nZXJwcmludD9BcnJheS5pc0FycmF5KHQuZmluZ2VycHJpbnQpP3QuZmluZ2VycHJpbnQ6W3QuZmluZ2VycHJpbnRdOltdLG4mJih0LmZpbmdlcnByaW50PXQuZmluZ2VycHJpbnQuY29uY2F0KG4pKTt0LmZpbmdlcnByaW50Lmxlbmd0aHx8ZGVsZXRlIHQuZmluZ2VycHJpbnR9KHQsZSksZnVuY3Rpb24odCxuKXtjb25zdCBlPVsuLi50LmJyZWFkY3J1bWJzfHxbXSwuLi5uXTt0LmJyZWFkY3J1bWJzPWUubGVuZ3RoP2U6dm9pZCAwfSh0LG8pLGZ1bmN0aW9uKHQsbil7dC5zZGtQcm9jZXNzaW5nTWV0YWRhdGE9ey4uLnQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhLC4uLm59fSh0LGkpfWNsYXNzIEp0e2NvbnN0cnVjdG9yKHQpe3RoaXMuTD0wLHRoaXMuTT1bXSx0aGlzLkYodCl9dGhlbih0LG4pe3JldHVybiBuZXcgSnQoKGUscik9Pnt0aGlzLk0ucHVzaChbITEsbj0+e2lmKHQpdHJ5e2UodChuKSl9Y2F0Y2godCl7cih0KX1lbHNlIGUobil9LHQ9PntpZihuKXRyeXtlKG4odCkpfWNhdGNoKHQpe3IodCl9ZWxzZSByKHQpfV0pLHRoaXMuRygpfSl9Y2F0Y2godCl7cmV0dXJuIHRoaXMudGhlbih0PT50LHQpfWZpbmFsbHkodCl7cmV0dXJuIG5ldyBKdCgobixlKT0+e2xldCByLG87cmV0dXJuIHRoaXMudGhlbihuPT57bz0hMSxyPW4sdCYmdCgpfSxuPT57bz0hMCxyPW4sdCYmdCgpfSkudGhlbigoKT0+e28/ZShyKTpuKHIpfSl9KX1HKCl7aWYoMD09PXRoaXMuTClyZXR1cm47Y29uc3QgdD10aGlzLk0uc2xpY2UoKTt0aGlzLk09W10sdC5mb3JFYWNoKHQ9Pnt0WzBdfHwoMT09PXRoaXMuTCYmdFsxXSh0aGlzLkopLDI9PT10aGlzLkwmJnRbMl0odGhpcy5KKSx0WzBdPSEwKX0pfUYodCl7Y29uc3Qgbj0odCxuKT0+ezA9PT10aGlzLkwmJihqKG4pP24udGhlbihlLHIpOih0aGlzLkw9dCx0aGlzLko9bix0aGlzLkcoKSkpfSxlPXQ9PntuKDEsdCl9LHI9dD0+e24oMix0KX07dHJ5e3QoZSxyKX1jYXRjaCh0KXtyKHQpfX19Y29uc3QgV3Q9U3ltYm9sLmZvcigiU2VudHJ5QnVmZmVyRnVsbEVycm9yIik7ZnVuY3Rpb24gWXQodD0xMDApe2NvbnN0IG49bmV3IFNldDtmdW5jdGlvbiBlKHQpe24uZGVsZXRlKHQpfXJldHVybntnZXQgJCgpe3JldHVybiBBcnJheS5mcm9tKG4pfSxhZGQ6ZnVuY3Rpb24ocil7aWYoIShuLnNpemU8dCkpcmV0dXJuIG89V3QsbmV3IEp0KCh0LG4pPT57bihvKX0pO3ZhciBvO2NvbnN0IGk9cigpO3JldHVybiBuLmFkZChpKSxpLnRoZW4oKCk9PmUoaSksKCk9PmUoaSkpLGl9LGRyYWluOmZ1bmN0aW9uKHQpe2lmKCFuLnNpemUpcmV0dXJuIGU9ITAsbmV3IEp0KHQ9Pnt0KGUpfSk7dmFyIGU7Y29uc3Qgcj1Qcm9taXNlLmFsbFNldHRsZWQoQXJyYXkuZnJvbShuKSkudGhlbigoKT0+ITApO2lmKCF0KXJldHVybiByO2NvbnN0IG89W3IsbmV3IFByb21pc2Uobj0+e3JldHVybiJvYmplY3QiPT10eXBlb2YoZT1zZXRUaW1lb3V0KCgpPT5uKCExKSx0KSkmJiJmdW5jdGlvbiI9PXR5cGVvZiBlLnVucmVmJiZlLnVucmVmKCksZTt2YXIgZX0pXTtyZXR1cm4gUHJvbWlzZS5yYWNlKG8pfX19ZnVuY3Rpb24gSHQodCx7c3RhdHVzQ29kZTpuLGhlYWRlcnM6ZX0scj1QKCkpe2NvbnN0IG89ey4uLnR9LGk9ZT8uWyJ4LXNlbnRyeS1yYXRlLWxpbWl0cyJdLHM9ZT8uWyJyZXRyeS1hZnRlciJdO2lmKGkpZm9yKGNvbnN0IHQgb2YgaS50cmltKCkuc3BsaXQoIiwiKSl7Y29uc3RbbixlLCwsaV09dC5zcGxpdCgiOiIsNSkscz1wYXJzZUludChuLDEwKSxjPTFlMyooaXNOYU4ocyk/NjA6cyk7aWYoZSlmb3IoY29uc3QgdCBvZiBlLnNwbGl0KCI7IikpIm1ldHJpY19idWNrZXQiPT09dCYmaSYmIWkuc3BsaXQoIjsiKS5pbmNsdWRlcygiY3VzdG9tIil8fChvW3RdPXIrYyk7ZWxzZSBvLmFsbD1yK2N9ZWxzZSBzP28uYWxsPXIrZnVuY3Rpb24odCxuPVAoKSl7Y29uc3QgZT1wYXJzZUludChgJHt0fWAsMTApO2lmKCFpc05hTihlKSlyZXR1cm4gMWUzKmU7Y29uc3Qgcj1EYXRlLnBhcnNlKGAke3R9YCk7cmV0dXJuIGlzTmFOKHIpPzZlNDpyLW59KHMscik6NDI5PT09biYmKG8uYWxsPXIrNmU0KTtyZXR1cm4gb31mdW5jdGlvbiBLdCh0LG4sZT1ZdCh0LmJ1ZmZlclNpemV8fDY0KSl7bGV0IHI9e307cmV0dXJue3NlbmQ6ZnVuY3Rpb24odCl7Y29uc3Qgbz1bXTtpZihrdCh0LCh0LG4pPT57Y29uc3QgZT1CdChuKTsoZnVuY3Rpb24odCxuLGU9UCgpKXtyZXR1cm4gZnVuY3Rpb24odCxuKXtyZXR1cm4gdFtuXXx8dC5hbGx8fDB9KHQsbik+ZX0pKHIsZSl8fG8ucHVzaCh0KX0pLDA9PT1vLmxlbmd0aClyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtjb25zdCBpPVR0KHRbMF0sbykscz10PT57IWZ1bmN0aW9uKHQsbil7cmV0dXJuIGt0KHQsKHQsZSk9Pm4uaW5jbHVkZXMoZSkpfShpLFsiY2xpZW50X3JlcG9ydCJdKT9rdChpLCh0LG4pPT57fSk6aCYmdy53YXJuKGBEcm9wcGluZyBjbGllbnQgcmVwb3J0LiBXaWxsIG5vdCBzZW5kIG91dGNvbWVzIChyZWFzb246ICR7dH0pLmApfTtyZXR1cm4gZS5hZGQoKCk9Pm4oe2JvZHk6RHQoaSl9KS50aGVuKHQ9PjQxMz09PXQuc3RhdHVzQ29kZT8oaCYmdy5lcnJvcigiU2VudHJ5IHJlc3BvbmRlZCB3aXRoIHN0YXR1cyBjb2RlIDQxMy4gRW52ZWxvcGUgd2FzIGRpc2NhcmRlZCBkdWUgdG8gZXhjZWVkaW5nIHNpemUgbGltaXRzLiIpLHMoInNlbmRfZXJyb3IiKSx0KTooaCYmdm9pZCAwIT09dC5zdGF0dXNDb2RlJiYodC5zdGF0dXNDb2RlPDIwMHx8dC5zdGF0dXNDb2RlPj0zMDApJiZ3Lndhcm4oYFNlbnRyeSByZXNwb25kZWQgd2l0aCBzdGF0dXMgY29kZSAke3Quc3RhdHVzQ29kZX0gdG8gc2VudCBldmVudC5gKSxyPUh0KHIsdCksdCksdD0+e3Rocm93IHMoIm5ldHdvcmtfZXJyb3IiKSxoJiZ3LmVycm9yKCJFbmNvdW50ZXJlZCBlcnJvciBydW5uaW5nIHRyYW5zcG9ydCByZXF1ZXN0OiIsdCksdH0pKS50aGVuKHQ9PnQsdD0+e2lmKHQ9PT1XdClyZXR1cm4gaCYmdy5lcnJvcigiU2tpcHBlZCBzZW5kaW5nIGV2ZW50IGJlY2F1c2UgYnVmZmVyIGlzIGZ1bGwuIikscygicXVldWVfb3ZlcmZsb3ciKSxQcm9taXNlLnJlc29sdmUoe30pO3Rocm93IHR9KX0sZmx1c2g6dD0+ZS5kcmFpbih0KX19Y29uc3QgWnQ9L14oXFMrOlxcfFwvPykoW1xzXFNdKj8pKCg/OlwuezEsMn18W14vXFxdKz98KShcLlteLi9cXF0qfCkpKD86Wy9cXF0qKSQvO2Z1bmN0aW9uIHF0KHQpe2NvbnN0IG49ZnVuY3Rpb24odCl7Y29uc3Qgbj10Lmxlbmd0aD4xMDI0P2A8dHJ1bmNhdGVkPiR7dC5zbGljZSgtMTAyNCl9YDp0LGU9WnQuZXhlYyhuKTtyZXR1cm4gZT9lLnNsaWNlKDEpOltdfSh0KSxlPW5bMF18fCIiO2xldCByPW5bMV07cmV0dXJuIGV8fHI/KHImJihyPXIuc2xpY2UoMCxyLmxlbmd0aC0xKSksZStyKToiLiJ9ZnVuY3Rpb24gVnQodCxuPSExKXtyZXR1cm4hKG58fHQmJiF0LnN0YXJ0c1dpdGgoIi8iKSYmIXQubWF0Y2goL15bQS1aXTovKSYmIXQuc3RhcnRzV2l0aCgiLiIpJiYhdC5tYXRjaCgvXlthLXpBLVpdKFthLXpBLVowLTkuXC0rXSkqOlwvXC8vKSkmJnZvaWQgMCE9PXQmJiF0LmluY2x1ZGVzKCJub2RlX21vZHVsZXMvIil9dmFyIFF0O2NvbnN0IFh0PVN5bWJvbCgiQWdlbnRCYXNlSW50ZXJuYWxTdGF0ZSIpO2NsYXNzIHRuIGV4dGVuZHMoUXQ9aS5BZ2VudCxRdCl7Y29uc3RydWN0b3IodCl7c3VwZXIodCksdGhpc1tYdF09e319aXNTZWN1cmVFbmRwb2ludCh0KXtpZih0KXtpZigiYm9vbGVhbiI9PXR5cGVvZiB0LnNlY3VyZUVuZHBvaW50KXJldHVybiB0LnNlY3VyZUVuZHBvaW50O2lmKCJzdHJpbmciPT10eXBlb2YgdC5wcm90b2NvbClyZXR1cm4iaHR0cHM6Ij09PXQucHJvdG9jb2x9Y29uc3R7c3RhY2s6bn09bmV3IEVycm9yO3JldHVybiJzdHJpbmciPT10eXBlb2YgbiYmbi5zcGxpdCgiXG4iKS5zb21lKHQ9Pi0xIT09dC5pbmRleE9mKCIoaHR0cHMuanM6Iil8fC0xIT09dC5pbmRleE9mKCJub2RlOmh0dHBzOiIpKX1jcmVhdGVTb2NrZXQodCxuLGUpe2NvbnN0IHI9ey4uLm4sc2VjdXJlRW5kcG9pbnQ6dGhpcy5pc1NlY3VyZUVuZHBvaW50KG4pfTtQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpPT50aGlzLmNvbm5lY3QodCxyKSkudGhlbihvPT57aWYobyBpbnN0YW5jZW9mIGkuQWdlbnQpcmV0dXJuIG8uYWRkUmVxdWVzdCh0LHIpO3RoaXNbWHRdLmN1cnJlbnRTb2NrZXQ9byxzdXBlci5jcmVhdGVTb2NrZXQodCxuLGUpfSxlKX1jcmVhdGVDb25uZWN0aW9uKCl7Y29uc3QgdD10aGlzW1h0XS5jdXJyZW50U29ja2V0O2lmKHRoaXNbWHRdLmN1cnJlbnRTb2NrZXQ9dm9pZCAwLCF0KXRocm93IG5ldyBFcnJvcigiTm8gc29ja2V0IHdhcyByZXR1cm5lZCBpbiB0aGUgYGNvbm5lY3QoKWAgZnVuY3Rpb24iKTtyZXR1cm4gdH1nZXQgZGVmYXVsdFBvcnQoKXtyZXR1cm4gdGhpc1tYdF0uZGVmYXVsdFBvcnQ/PygiaHR0cHM6Ij09PXRoaXMucHJvdG9jb2w/NDQzOjgwKX1zZXQgZGVmYXVsdFBvcnQodCl7dGhpc1tYdF0mJih0aGlzW1h0XS5kZWZhdWx0UG9ydD10KX1nZXQgcHJvdG9jb2woKXtyZXR1cm4gdGhpc1tYdF0ucHJvdG9jb2w/Pyh0aGlzLmlzU2VjdXJlRW5kcG9pbnQoKT8iaHR0cHM6IjoiaHR0cDoiKX1zZXQgcHJvdG9jb2wodCl7dGhpc1tYdF0mJih0aGlzW1h0XS5wcm90b2NvbD10KX19ZnVuY3Rpb24gbm4oLi4udCl7dy5sb2coIltodHRwcy1wcm94eS1hZ2VudDpwYXJzZS1wcm94eS1yZXNwb25zZV0iLC4uLnQpfWZ1bmN0aW9uIGVuKHQpe3JldHVybiBuZXcgUHJvbWlzZSgobixlKT0+e2xldCByPTA7Y29uc3Qgbz1bXTtmdW5jdGlvbiBpKCl7Y29uc3QgYz10LnJlYWQoKTtjP2Z1bmN0aW9uKGMpe28ucHVzaChjKSxyKz1jLmxlbmd0aDtjb25zdCB1PUJ1ZmZlci5jb25jYXQobyxyKSxhPXUuaW5kZXhPZigiXHJcblxyXG4iKTtpZigtMT09PWEpcmV0dXJuIG5uKCJoYXZlIG5vdCByZWNlaXZlZCBlbmQgb2YgSFRUUCBoZWFkZXJzIHlldC4uLiIpLHZvaWQgaSgpO2NvbnN0IGY9dS5zdWJhcnJheSgwLGEpLnRvU3RyaW5nKCJhc2NpaSIpLnNwbGl0KCJcclxuIiksaD1mLnNoaWZ0KCk7aWYoIWgpcmV0dXJuIHQuZGVzdHJveSgpLGUobmV3IEVycm9yKCJObyBoZWFkZXIgcmVjZWl2ZWQgZnJvbSBwcm94eSBDT05ORUNUIHJlc3BvbnNlIikpO2NvbnN0IHA9aC5zcGxpdCgiICIpLGQ9KyhwWzFdfHwwKSxsPXAuc2xpY2UoMikuam9pbigiICIpLGc9e307Zm9yKGNvbnN0IG4gb2YgZil7aWYoIW4pY29udGludWU7Y29uc3Qgcj1uLmluZGV4T2YoIjoiKTtpZigtMT09PXIpcmV0dXJuIHQuZGVzdHJveSgpLGUobmV3IEVycm9yKGBJbnZhbGlkIGhlYWRlciBmcm9tIHByb3h5IENPTk5FQ1QgcmVzcG9uc2U6ICIke259ImApKTtjb25zdCBvPW4uc2xpY2UoMCxyKS50b0xvd2VyQ2FzZSgpLGk9bi5zbGljZShyKzEpLnRyaW1TdGFydCgpLHM9Z1tvXTsic3RyaW5nIj09dHlwZW9mIHM/Z1tvXT1bcyxpXTpBcnJheS5pc0FycmF5KHMpP3MucHVzaChpKTpnW29dPWl9bm4oImdvdCBwcm94eSBzZXJ2ZXIgcmVzcG9uc2U6ICVvICVvIixoLGcpLHMoKSxuKHtjb25uZWN0OntzdGF0dXNDb2RlOmQsc3RhdHVzVGV4dDpsLGhlYWRlcnM6Z30sYnVmZmVyZWQ6dX0pfShjKTp0Lm9uY2UoInJlYWRhYmxlIixpKX1mdW5jdGlvbiBzKCl7dC5yZW1vdmVMaXN0ZW5lcigiZW5kIixjKSx0LnJlbW92ZUxpc3RlbmVyKCJlcnJvciIsdSksdC5yZW1vdmVMaXN0ZW5lcigicmVhZGFibGUiLGkpfWZ1bmN0aW9uIGMoKXtzKCksbm4oIm9uZW5kIiksZShuZXcgRXJyb3IoIlByb3h5IGNvbm5lY3Rpb24gZW5kZWQgYmVmb3JlIHJlY2VpdmluZyBDT05ORUNUIHJlc3BvbnNlIikpfWZ1bmN0aW9uIHUodCl7cygpLG5uKCJvbmVycm9yICVvIix0KSxlKHQpfXQub24oImVycm9yIix1KSx0Lm9uKCJlbmQiLGMpLGkoKX0pfWZ1bmN0aW9uIHJuKC4uLnQpe3cubG9nKCJbaHR0cHMtcHJveHktYWdlbnRdIiwuLi50KX1jbGFzcyBvbiBleHRlbmRzIHRue2NvbnN0cnVjdG9yKHQsbil7c3VwZXIobiksdGhpcy5vcHRpb25zPXt9LHRoaXMucHJveHk9InN0cmluZyI9PXR5cGVvZiB0P25ldyBVUkwodCk6dCx0aGlzLnByb3h5SGVhZGVycz1uPy5oZWFkZXJzPz97fSxybigiQ3JlYXRpbmcgbmV3IEh0dHBzUHJveHlBZ2VudCBpbnN0YW5jZTogJW8iLHRoaXMucHJveHkuaHJlZik7Y29uc3QgZT0odGhpcy5wcm94eS5ob3N0bmFtZXx8dGhpcy5wcm94eS5ob3N0KS5yZXBsYWNlKC9eXFt8XF0kL2csIiIpLHI9dGhpcy5wcm94eS5wb3J0P3BhcnNlSW50KHRoaXMucHJveHkucG9ydCwxMCk6Imh0dHBzOiI9PT10aGlzLnByb3h5LnByb3RvY29sPzQ0Mzo4MDt0aGlzLmNvbm5lY3RPcHRzPXtBTFBOUHJvdG9jb2xzOlsiaHR0cC8xLjEiXSwuLi5uP2NuKG4sImhlYWRlcnMiKTpudWxsLGhvc3Q6ZSxwb3J0OnJ9fWFzeW5jIGNvbm5lY3QodCxuKXtjb25zdHtwcm94eTplfT10aGlzO2lmKCFuLmhvc3QpdGhyb3cgbmV3IFR5cGVFcnJvcignTm8gImhvc3QiIHByb3ZpZGVkJyk7bGV0IHI7aWYoImh0dHBzOiI9PT1lLnByb3RvY29sKXtybigiQ3JlYXRpbmcgYHRscy5Tb2NrZXRgOiAlbyIsdGhpcy5jb25uZWN0T3B0cyk7Y29uc3QgdD10aGlzLmNvbm5lY3RPcHRzLnNlcnZlcm5hbWV8fHRoaXMuY29ubmVjdE9wdHMuaG9zdDtyPWYuY29ubmVjdCh7Li4udGhpcy5jb25uZWN0T3B0cyxzZXJ2ZXJuYW1lOnQmJmEuaXNJUCh0KT92b2lkIDA6dH0pfWVsc2Ugcm4oIkNyZWF0aW5nIGBuZXQuU29ja2V0YDogJW8iLHRoaXMuY29ubmVjdE9wdHMpLHI9YS5jb25uZWN0KHRoaXMuY29ubmVjdE9wdHMpO2NvbnN0IG89ImZ1bmN0aW9uIj09dHlwZW9mIHRoaXMucHJveHlIZWFkZXJzP3RoaXMucHJveHlIZWFkZXJzKCk6ey4uLnRoaXMucHJveHlIZWFkZXJzfSxpPWEuaXNJUHY2KG4uaG9zdCk/YFske24uaG9zdH1dYDpuLmhvc3Q7bGV0IHM9YENPTk5FQ1QgJHtpfToke24ucG9ydH0gSFRUUC8xLjFcclxuYDtpZihlLnVzZXJuYW1lfHxlLnBhc3N3b3JkKXtjb25zdCB0PWAke2RlY29kZVVSSUNvbXBvbmVudChlLnVzZXJuYW1lKX06JHtkZWNvZGVVUklDb21wb25lbnQoZS5wYXNzd29yZCl9YDtvWyJQcm94eS1BdXRob3JpemF0aW9uIl09YEJhc2ljICR7QnVmZmVyLmZyb20odCkudG9TdHJpbmcoImJhc2U2NCIpfWB9by5Ib3N0PWAke2l9OiR7bi5wb3J0fWAsb1siUHJveHktQ29ubmVjdGlvbiJdfHwob1siUHJveHktQ29ubmVjdGlvbiJdPXRoaXMua2VlcEFsaXZlPyJLZWVwLUFsaXZlIjoiY2xvc2UiKTtmb3IoY29uc3QgdCBvZiBPYmplY3Qua2V5cyhvKSlzKz1gJHt0fTogJHtvW3RdfVxyXG5gO2NvbnN0IGM9ZW4ocik7ci53cml0ZShgJHtzfVxyXG5gKTtjb25zdHtjb25uZWN0OnUsYnVmZmVyZWQ6aH09YXdhaXQgYztpZih0LmVtaXQoInByb3h5Q29ubmVjdCIsdSksdGhpcy5lbWl0KCJwcm94eUNvbm5lY3QiLHUsdCksMjAwPT09dS5zdGF0dXNDb2RlKXtpZih0Lm9uY2UoInNvY2tldCIsc24pLG4uc2VjdXJlRW5kcG9pbnQpe3JuKCJVcGdyYWRpbmcgc29ja2V0IGNvbm5lY3Rpb24gdG8gVExTIik7Y29uc3QgdD1uLnNlcnZlcm5hbWV8fG4uaG9zdDtyZXR1cm4gZi5jb25uZWN0KHsuLi5jbihuLCJob3N0IiwicGF0aCIsInBvcnQiKSxzb2NrZXQ6cixzZXJ2ZXJuYW1lOmEuaXNJUCh0KT92b2lkIDA6dH0pfXJldHVybiByfXIuZGVzdHJveSgpO2NvbnN0IHA9bmV3IGEuU29ja2V0KHt3cml0YWJsZTohMX0pO3JldHVybiBwLnJlYWRhYmxlPSEwLHQub25jZSgic29ja2V0Iix0PT57cm4oIlJlcGxheWluZyBwcm94eSBidWZmZXIgZm9yIGZhaWxlZCByZXF1ZXN0IiksdC5wdXNoKGgpLHQucHVzaChudWxsKX0pLHB9fWZ1bmN0aW9uIHNuKHQpe3QucmVzdW1lKCl9ZnVuY3Rpb24gY24odCwuLi5uKXtjb25zdCBlPXt9O2xldCByO2ZvcihyIGluIHQpbi5pbmNsdWRlcyhyKXx8KGVbcl09dFtyXSk7cmV0dXJuIGV9b24ucHJvdG9jb2xzPVsiaHR0cCIsImh0dHBzIl07ZnVuY3Rpb24gdW4odCl7cmV0dXJuIHQucmVwbGFjZSgvXltBLVpdOi8sIiIpLnJlcGxhY2UoL1xcL2csIi8iKX1jb25zdCBhbj1uO2xldCBmbixobj0wLHBuPXt9O2Z1bmN0aW9uIGRuKHQpe2FuLmRlYnVnJiZjb25zb2xlLmxvZyhgW0FOUiBXb3JrZXJdICR7dH1gKX12YXIgbG4sZ24sbW47Y29uc3QgeW49ZnVuY3Rpb24odCl7bGV0IG47dHJ5e249bmV3IFVSTCh0LnVybCl9Y2F0Y2gobil7cmV0dXJuIGIoKCk9Pntjb25zb2xlLndhcm4oIltAc2VudHJ5L25vZGVdOiBJbnZhbGlkIGRzbiBvciB0dW5uZWwgb3B0aW9uLCB3aWxsIG5vdCBzZW5kIGFueSBldmVudHMuIFRoZSB0dW5uZWwgb3B0aW9uIG11c3QgYmUgYSBmdWxsIFVSTCB3aGVuIHVzZWQuIil9KSxLdCh0LCgpPT5Qcm9taXNlLnJlc29sdmUoe30pKX1jb25zdCBlPSJodHRwczoiPT09bi5wcm90b2NvbCxyPWZ1bmN0aW9uKHQsbil7Y29uc3R7bm9fcHJveHk6ZX09cHJvY2Vzcy5lbnYscj1lPy5zcGxpdCgiLCIpLnNvbWUobj0+dC5ob3N0LmVuZHNXaXRoKG4pfHx0Lmhvc3RuYW1lLmVuZHNXaXRoKG4pKTtyZXR1cm4gcj92b2lkIDA6bn0obix0LnByb3h5fHwoZT9wcm9jZXNzLmVudi5odHRwc19wcm94eTp2b2lkIDApfHxwcm9jZXNzLmVudi5odHRwX3Byb3h5KSxvPWU/czppLGE9dm9pZCAwIT09dC5rZWVwQWxpdmUmJnQua2VlcEFsaXZlLGY9cj9uZXcgb24ocik6bmV3IG8uQWdlbnQoe2tlZXBBbGl2ZTphLG1heFNvY2tldHM6MzAsdGltZW91dDoyZTN9KSxoPWZ1bmN0aW9uKHQsbixlKXtjb25zdHtob3N0bmFtZTpyLHBhdGhuYW1lOm8scG9ydDppLHByb3RvY29sOnMsc2VhcmNoOmF9PW5ldyBVUkwodC51cmwpO3JldHVybiBmdW5jdGlvbihmKXtyZXR1cm4gbmV3IFByb21pc2UoKGgscCk9PntGdCgoKT0+e2xldCBkPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgYyh7cmVhZCgpe3RoaXMucHVzaCh0KSx0aGlzLnB1c2gobnVsbCl9fSl9KGYuYm9keSk7Y29uc3QgbD17Li4udC5oZWFkZXJzfTtmLmJvZHkubGVuZ3RoPjMyNzY4JiYobFsiY29udGVudC1lbmNvZGluZyJdPSJnemlwIixkPWQucGlwZSh1KCkpKTtjb25zdCBnPXIuc3RhcnRzV2l0aCgiWyIpLG09bi5yZXF1ZXN0KHttZXRob2Q6IlBPU1QiLGFnZW50OmUsaGVhZGVyczpsLGhvc3RuYW1lOmc/ci5zbGljZSgxLC0xKTpyLHBhdGg6YCR7b30ke2F9YCxwb3J0OmkscHJvdG9jb2w6cyxjYTp0LmNhQ2VydHN9LHQ9Pnt0Lm9uKCJkYXRhIiwoKT0+e30pLHQub24oImVuZCIsKCk9Pnt9KSx0LnNldEVuY29kaW5nKCJ1dGY4Iik7Y29uc3Qgbj10LmhlYWRlcnNbInJldHJ5LWFmdGVyIl0/P251bGwsZT10LmhlYWRlcnNbIngtc2VudHJ5LXJhdGUtbGltaXRzIl0/P251bGw7aCh7c3RhdHVzQ29kZTp0LnN0YXR1c0NvZGUsaGVhZGVyczp7InJldHJ5LWFmdGVyIjpuLCJ4LXNlbnRyeS1yYXRlLWxpbWl0cyI6QXJyYXkuaXNBcnJheShlKT9lWzBdfHxudWxsOmV9fSl9KTttLm9uKCJlcnJvciIscCksZC5waXBlKG0pfSl9KX19KHQsdC5odHRwTW9kdWxlPz9vLGYpO3JldHVybiBLdCh0LGgpfSh7dXJsOihsbj1hbi5kc24sZ249YW4udHVubmVsLG1uPWFuLnNka01ldGFkYXRhLnNkayxnbnx8YCR7ZnVuY3Rpb24odCl7cmV0dXJuYCR7ZnVuY3Rpb24odCl7Y29uc3Qgbj10LnByb3RvY29sP2Ake3QucHJvdG9jb2x9OmA6IiIsZT10LnBvcnQ/YDoke3QucG9ydH1gOiIiO3JldHVybmAke259Ly8ke3QuaG9zdH0ke2V9JHt0LnBhdGg/YC8ke3QucGF0aH1gOiIifS9hcGkvYH0odCl9JHt0LnByb2plY3RJZH0vZW52ZWxvcGUvYH0obG4pfT8ke2Z1bmN0aW9uKHQsbil7Y29uc3QgZT17c2VudHJ5X3ZlcnNpb246IjcifTtyZXR1cm4gdC5wdWJsaWNLZXkmJihlLnNlbnRyeV9rZXk9dC5wdWJsaWNLZXkpLG4mJihlLnNlbnRyeV9jbGllbnQ9YCR7bi5uYW1lfS8ke24udmVyc2lvbn1gKSxuZXcgVVJMU2VhcmNoUGFyYW1zKGUpLnRvU3RyaW5nKCl9KGxuLG1uKX1gKX0pO2FzeW5jIGZ1bmN0aW9uIGJuKCl7aWYoZm4pe2RuKCJTZW5kaW5nIGFibm9ybWFsIHNlc3Npb24iKSxLKGZuLHtzdGF0dXM6ImFibm9ybWFsIixhYm5vcm1hbF9tZWNoYW5pc206ImFucl9mb3JlZ3JvdW5kIixyZWxlYXNlOmFuLnJlbGVhc2UsZW52aXJvbm1lbnQ6YW4uZW52aXJvbm1lbnR9KTtjb25zdCB0PWZ1bmN0aW9uKHQsbixlLHIpe2NvbnN0IG89THQoZSk7cmV0dXJuIFR0KHtzZW50X2F0Om5ldyBEYXRlKFAoKSkudG9JU09TdHJpbmcoKSwuLi5vJiZ7c2RrOm99LC4uLiEhciYmbiYme2RzbjpidChuKX19LFsiYWdncmVnYXRlcyJpbiB0P1t7dHlwZToic2Vzc2lvbnMifSx0XTpbe3R5cGU6InNlc3Npb24ifSx0LnRvSlNPTigpXV0pfShmbixhbi5kc24sYW4uc2RrTWV0YWRhdGEsYW4udHVubmVsKTtkbihKU09OLnN0cmluZ2lmeSh0KSksYXdhaXQgeW4uc2VuZCh0KTt0cnl7ZT8ucG9zdE1lc3NhZ2UoInNlc3Npb24tZW5kZWQiKX1jYXRjaHt9fX1mdW5jdGlvbiB2bih0KXtpZighdClyZXR1cm47Y29uc3Qgbj1mdW5jdGlvbih0KXtpZighdC5sZW5ndGgpcmV0dXJuW107Y29uc3Qgbj1BcnJheS5mcm9tKHQpO3JldHVybi9zZW50cnlXcmFwcGVkLy50ZXN0KEUobikuZnVuY3Rpb258fCIiKSYmbi5wb3AoKSxuLnJldmVyc2UoKSwkLnRlc3QoRShuKS5mdW5jdGlvbnx8IiIpJiYobi5wb3AoKSwkLnRlc3QoRShuKS5mdW5jdGlvbnx8IiIpJiZuLnBvcCgpKSxuLnNsaWNlKDAsNTApLm1hcCh0PT4oey4uLnQsZmlsZW5hbWU6dC5maWxlbmFtZXx8RShuKS5maWxlbmFtZSxmdW5jdGlvbjp0LmZ1bmN0aW9ufHwiPyJ9KSl9KHQpO2lmKGFuLmFwcFJvb3RQYXRoKWZvcihjb25zdCB0IG9mIG4pdC5maWxlbmFtZSYmKHQuZmlsZW5hbWU9TSh0LmZpbGVuYW1lLGFuLmFwcFJvb3RQYXRoKSk7cmV0dXJuIG59YXN5bmMgZnVuY3Rpb24gX24odCxuKXtpZihobj49YW4ubWF4QW5yRXZlbnRzKXJldHVybjtobis9MSxhd2FpdCBibigpLGRuKCJTZW5kaW5nIGV2ZW50Iik7Y29uc3QgZT17ZXZlbnRfaWQ6RygpLGNvbnRleHRzOmFuLmNvbnRleHRzLHJlbGVhc2U6YW4ucmVsZWFzZSxlbnZpcm9ubWVudDphbi5lbnZpcm9ubWVudCxkaXN0OmFuLmRpc3QscGxhdGZvcm06Im5vZGUiLGxldmVsOiJlcnJvciIsZXhjZXB0aW9uOnt2YWx1ZXM6W3t0eXBlOiJBcHBsaWNhdGlvbk5vdFJlc3BvbmRpbmciLHZhbHVlOmBBcHBsaWNhdGlvbiBOb3QgUmVzcG9uZGluZyBmb3IgYXQgbGVhc3QgJHthbi5hbnJUaHJlc2hvbGR9IG1zYCxzdGFja3RyYWNlOntmcmFtZXM6dm4odCl9LG1lY2hhbmlzbTp7dHlwZToiQU5SIn19XX0sdGFnczphbi5zdGF0aWNUYWdzfTtuJiZmdW5jdGlvbih0LG4pe2lmKEd0KHQsbiksIXQuY29udGV4dHM/LnRyYWNlKXtjb25zdHt0cmFjZUlkOmUscGFyZW50U3BhbklkOnIscHJvcGFnYXRpb25TcGFuSWQ6b309bi5wcm9wYWdhdGlvbkNvbnRleHQ7dC5jb250ZXh0cz17dHJhY2U6e3RyYWNlX2lkOmUsc3Bhbl9pZDpvfHxWKCkscGFyZW50X3NwYW5faWQ6cn0sLi4udC5jb250ZXh0c319fShlLG4pLGZ1bmN0aW9uKHQpe2lmKDA9PT1PYmplY3Qua2V5cyhwbikubGVuZ3RoKXJldHVybjtjb25zdCBuPWFuLmFwcFJvb3RQYXRoP3t9OnBuO2lmKGFuLmFwcFJvb3RQYXRoKWZvcihjb25zdFt0LGVdb2YgT2JqZWN0LmVudHJpZXMocG4pKW5bTSh0LGFuLmFwcFJvb3RQYXRoKV09ZTtjb25zdCBlPW5ldyBNYXA7Zm9yKGNvbnN0IHIgb2YgdC5leGNlcHRpb24/LnZhbHVlc3x8W10pZm9yKGNvbnN0IHQgb2Ygci5zdGFja3RyYWNlPy5mcmFtZXN8fFtdKXtjb25zdCByPXQuYWJzX3BhdGh8fHQuZmlsZW5hbWU7ciYmbltyXSYmZS5zZXQocixuW3JdKX1pZihlLnNpemU+MCl7Y29uc3Qgbj1bXTtmb3IoY29uc3RbdCxyXW9mIGUuZW50cmllcygpKW4ucHVzaCh7dHlwZToic291cmNlbWFwIixjb2RlX2ZpbGU6dCxkZWJ1Z19pZDpyfSk7dC5kZWJ1Z19tZXRhPXtpbWFnZXM6bn19fShlKTtjb25zdCByPU10KGUsYW4uZHNuLGFuLnNka01ldGFkYXRhLGFuLnR1bm5lbCk7ZG4oSlNPTi5zdHJpbmdpZnkocikpLGF3YWl0IHluLnNlbmQociksYXdhaXQgeW4uZmx1c2goMmUzKSxobj49YW4ubWF4QW5yRXZlbnRzJiZzZXRUaW1lb3V0KCgpPT57cHJvY2Vzcy5leGl0KDApfSw1ZTMpfWxldCBTbjtpZihkbigiU3RhcnRlZCIpLGFuLmNhcHR1cmVTdGFja1RyYWNlKXtkbigiQ29ubmVjdGluZyB0byBkZWJ1Z2dlciIpO2NvbnN0IG49bmV3IHQ7bi5jb25uZWN0VG9NYWluVGhyZWFkKCksZG4oIkNvbm5lY3RlZCB0byBkZWJ1Z2dlciIpO2NvbnN0IGU9bmV3IE1hcDtuLm9uKCJEZWJ1Z2dlci5zY3JpcHRQYXJzZWQiLHQ9PntlLnNldCh0LnBhcmFtcy5zY3JpcHRJZCx0LnBhcmFtcy51cmwpfSksbi5vbigiRGVidWdnZXIucGF1c2VkIix0PT57aWYoIm90aGVyIj09PXQucGFyYW1zLnJlYXNvbil0cnl7ZG4oIkRlYnVnZ2VyIHBhdXNlZCIpO2NvbnN0IGk9Wy4uLnQucGFyYW1zLmNhbGxGcmFtZXNdLHM9YW4uYXBwUm9vdFBhdGg/ZnVuY3Rpb24odD0ocHJvY2Vzcy5hcmd2WzFdP3F0KHByb2Nlc3MuYXJndlsxXSk6cHJvY2Vzcy5jd2QoKSksbj0iXFwiPT09byl7Y29uc3QgZT1uP3VuKHQpOnQ7cmV0dXJuIHQ9PntpZighdClyZXR1cm47Y29uc3Qgbz1uP3VuKHQpOnQ7bGV0e2RpcjppLGJhc2U6cyxleHQ6Y309ci5wYXJzZShvKTsiLmpzIiE9PWMmJiIubWpzIiE9PWMmJiIuY2pzIiE9PWN8fChzPXMuc2xpY2UoMCwtMSpjLmxlbmd0aCkpO2NvbnN0IHU9ZGVjb2RlVVJJQ29tcG9uZW50KHMpO2l8fChpPSIuIik7Y29uc3QgYT1pLmxhc3RJbmRleE9mKCIvbm9kZV9tb2R1bGVzIik7aWYoYT4tMSlyZXR1cm5gJHtpLnNsaWNlKGErMTQpLnJlcGxhY2UoL1wvL2csIi4iKX06JHt1fWA7aWYoaS5zdGFydHNXaXRoKGUpKXtjb25zdCB0PWkuc2xpY2UoZS5sZW5ndGgrMSkucmVwbGFjZSgvXC8vZywiLiIpO3JldHVybiB0P2Ake3R9OiR7dX1gOnV9cmV0dXJuIHV9fShhbi5hcHBSb290UGF0aCk6KCk9Pnt9LGM9aS5tYXAodD0+ZnVuY3Rpb24odCxuLGUpe2NvbnN0IHI9bj9uLnJlcGxhY2UoL15maWxlOlwvXC8vLCIiKTp2b2lkIDAsbz10LmxvY2F0aW9uLmNvbHVtbk51bWJlcj90LmxvY2F0aW9uLmNvbHVtbk51bWJlcisxOnZvaWQgMCxpPXQubG9jYXRpb24ubGluZU51bWJlcj90LmxvY2F0aW9uLmxpbmVOdW1iZXIrMTp2b2lkIDA7cmV0dXJue2ZpbGVuYW1lOnIsbW9kdWxlOmUociksZnVuY3Rpb246dC5mdW5jdGlvbk5hbWV8fCI/Iixjb2xubzpvLGxpbmVubzppLGluX2FwcDpyP1Z0KHIpOnZvaWQgMH19KHQsZS5nZXQodC5sb2NhdGlvbi5zY3JpcHRJZCkscykpLHU9c2V0VGltZW91dCgoKT0+e19uKGMpLnRoZW4obnVsbCwoKT0+e2RuKCJTZW5kaW5nIEFOUiBldmVudCBmYWlsZWQuIil9KX0sNWUzKTtuLnBvc3QoIlJ1bnRpbWUuZXZhbHVhdGUiLHtleHByZXNzaW9uOiJnbG9iYWwuX19TRU5UUllfR0VUX1NDT1BFU19fKCk7IixzaWxlbnQ6ITAscmV0dXJuQnlWYWx1ZTohMH0sKHQsZSk9Pnt0JiZkbihgRXJyb3IgZXhlY3V0aW5nIHNjcmlwdDogJyR7dC5tZXNzYWdlfSdgKSxjbGVhclRpbWVvdXQodSk7Y29uc3Qgcj1lPy5yZXN1bHQ/ZS5yZXN1bHQudmFsdWU6dm9pZCAwO24ucG9zdCgiRGVidWdnZXIucmVzdW1lIiksbi5wb3N0KCJEZWJ1Z2dlci5kaXNhYmxlIiksX24oYyxyKS50aGVuKG51bGwsKCk9PntkbigiU2VuZGluZyBBTlIgZXZlbnQgZmFpbGVkLiIpfSl9KX1jYXRjaCh0KXt0aHJvdyBuLnBvc3QoIkRlYnVnZ2VyLnJlc3VtZSIpLG4ucG9zdCgiRGVidWdnZXIuZGlzYWJsZSIpLHR9fSksU249KCk9Pnt0cnl7bi5wb3N0KCJEZWJ1Z2dlci5lbmFibGUiLCgpPT57bi5wb3N0KCJEZWJ1Z2dlci5wYXVzZSIpfSl9Y2F0Y2h7fX19Y29uc3R7cG9sbDp3bn09ZnVuY3Rpb24odCxuLGUscil7Y29uc3Qgbz10KCk7bGV0IGk9ITEscz0hMDtyZXR1cm4gc2V0SW50ZXJ2YWwoKCk9Pntjb25zdCB0PW8uZ2V0VGltZU1zKCk7ITE9PT1pJiZ0Pm4rZSYmKGk9ITAscyYmcigpKSx0PG4rZSYmKGk9ITEpfSwyMCkse3BvbGw6KCk9PntvLnJlc2V0KCl9LGVuYWJsZWQ6dD0+e3M9dH19fShmdW5jdGlvbigpe2xldCB0PXByb2Nlc3MuaHJ0aW1lKCk7cmV0dXJue2dldFRpbWVNczooKT0+e2NvbnN0W24sZV09cHJvY2Vzcy5ocnRpbWUodCk7cmV0dXJuIE1hdGguZmxvb3IoMWUzKm4rZS8xZTYpfSxyZXNldDooKT0+e3Q9cHJvY2Vzcy5ocnRpbWUoKX19fSxhbi5wb2xsSW50ZXJ2YWwsYW4uYW5yVGhyZXNob2xkLGZ1bmN0aW9uKCl7ZG4oIldhdGNoZG9nIHRpbWVvdXQiKSxTbj8oZG4oIlBhdXNpbmcgZGVidWdnZXIgdG8gY2FwdHVyZSBzdGFjayB0cmFjZSIpLFNuKCkpOihkbigiQ2FwdHVyaW5nIGV2ZW50IHdpdGhvdXQgYSBzdGFjayB0cmFjZSIpLF9uKCkudGhlbihudWxsLCgpPT57ZG4oIlNlbmRpbmcgQU5SIGV2ZW50IGZhaWxlZCBvbiB3YXRjaGRvZyB0aW1lb3V0LiIpfSkpfSk7ZT8ub24oIm1lc3NhZ2UiLHQ9Pnt0LnNlc3Npb24mJihmbj1IKHQuc2Vzc2lvbikpLHQuZGVidWdJbWFnZXMmJihwbj10LmRlYnVnSW1hZ2VzKSx3bigpfSk7";
const base64WorkerScript = "LyohIEBzZW50cnkvbm9kZS1jb3JlIDEwLjY1LjAgKGM2NmE4MTUpIHwgaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdCAqLwppbXBvcnR7U2Vzc2lvbiBhcyB0fWZyb20ibm9kZTppbnNwZWN0b3IiO2ltcG9ydHt3b3JrZXJEYXRhIGFzIG4scGFyZW50UG9ydCBhcyBlfWZyb20ibm9kZTp3b3JrZXJfdGhyZWFkcyI7aW1wb3J0e3Bvc2l4IGFzIHIsc2VwIGFzIG99ZnJvbSJub2RlOnBhdGgiO2ltcG9ydCphcyBpIGZyb20ibm9kZTpodHRwIjtpbXBvcnQqYXMgcyBmcm9tIm5vZGU6aHR0cHMiO2ltcG9ydHtSZWFkYWJsZSBhcyBjfWZyb20ibm9kZTpzdHJlYW0iO2ltcG9ydHtjcmVhdGVHemlwIGFzIHV9ZnJvbSJub2RlOnpsaWIiO2ltcG9ydCphcyBhIGZyb20ibm9kZTpuZXQiO2ltcG9ydCphcyBmIGZyb20ibm9kZTp0bHMiO2NvbnN0IGg9InVuZGVmaW5lZCI9PXR5cGVvZiBfX1NFTlRSWV9ERUJVR19ffHxfX1NFTlRSWV9ERUJVR19fLHA9Z2xvYmFsVGhpcyxkPSIxMC42NS4wIjtmdW5jdGlvbiBsKCl7cmV0dXJuIGcocCkscH1mdW5jdGlvbiBnKHQpe2NvbnN0IG49dC5fX1NFTlRSWV9fPXQuX19TRU5UUllfX3x8e307cmV0dXJuIG4udmVyc2lvbj1uLnZlcnNpb258fGQsbltkXT1uW2RdfHx7fX1mdW5jdGlvbiBtKHQsbixlPXApe2NvbnN0IHI9ZS5fX1NFTlRSWV9fPWUuX19TRU5UUllfX3x8e30sbz1yW2RdPXJbZF18fHt9O3JldHVybiBvW3RdfHwob1t0XT1uKCkpfWNvbnN0IHk9e307ZnVuY3Rpb24gYih0KXtpZighKCJjb25zb2xlImluIHApKXJldHVybiB0KCk7Y29uc3Qgbj1wLmNvbnNvbGUsZT17fSxyPU9iamVjdC5rZXlzKHkpO3IuZm9yRWFjaCh0PT57Y29uc3Qgcj15W3RdO2VbdF09blt0XSxuW3RdPXJ9KTt0cnl7cmV0dXJuIHQoKX1maW5hbGx5e3IuZm9yRWFjaCh0PT57blt0XT1lW3RdfSl9fWZ1bmN0aW9uIHYoKXtyZXR1cm4gUygpLmVuYWJsZWR9ZnVuY3Rpb24gXyh0LC4uLm4pe2gmJnYoKSYmYigoKT0+e3AuY29uc29sZVt0XShgU2VudHJ5IExvZ2dlciBbJHt0fV06YCwuLi5uKX0pfWZ1bmN0aW9uIFMoKXtyZXR1cm4gaD9tKCJsb2dnZXJTZXR0aW5ncyIsKCk9Pih7ZW5hYmxlZDohMX0pKTp7ZW5hYmxlZDohMX19Y29uc3Qgdz17ZW5hYmxlOmZ1bmN0aW9uKCl7UygpLmVuYWJsZWQ9ITB9LGRpc2FibGU6ZnVuY3Rpb24oKXtTKCkuZW5hYmxlZD0hMX0saXNFbmFibGVkOnYsbG9nOmZ1bmN0aW9uKC4uLnQpe18oImxvZyIsLi4udCl9LHdhcm46ZnVuY3Rpb24oLi4udCl7Xygid2FybiIsLi4udCl9LGVycm9yOmZ1bmN0aW9uKC4uLnQpe18oImVycm9yIiwuLi50KX19LCQ9L2NhcHR1cmVNZXNzYWdlfGNhcHR1cmVFeGNlcHRpb24vO2Z1bmN0aW9uIEUodCl7cmV0dXJuIHRbdC5sZW5ndGgtMV18fHt9fWNvbnN0IHg9Ijxhbm9ueW1vdXM+Ijtjb25zdCBOPU9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7ZnVuY3Rpb24gQyh0LG4pe3JldHVybiBOLmNhbGwodCk9PT1gW29iamVjdCAke259XWB9ZnVuY3Rpb24gaih0KXtyZXR1cm4gQm9vbGVhbih0Py50aGVuJiYiZnVuY3Rpb24iPT10eXBlb2YgdC50aGVuKX1mdW5jdGlvbiBSKHQsbil7dHJ5e3JldHVybiB0IGluc3RhbmNlb2Ygbn1jYXRjaHtyZXR1cm4hMX19ZnVuY3Rpb24gQSh0KXtpZihmdW5jdGlvbih0KXtzd2l0Y2goTi5jYWxsKHQpKXtjYXNlIltvYmplY3QgRXJyb3JdIjpjYXNlIltvYmplY3QgRXhjZXB0aW9uXSI6Y2FzZSJbb2JqZWN0IERPTUV4Y2VwdGlvbl0iOmNhc2UiW29iamVjdCBXZWJBc3NlbWJseS5FeGNlcHRpb25dIjpyZXR1cm4hMDtkZWZhdWx0OnJldHVybiBSKHQsRXJyb3IpfX0odCkpcmV0dXJue21lc3NhZ2U6dC5tZXNzYWdlLG5hbWU6dC5uYW1lLHN0YWNrOnQuc3RhY2ssLi4uSSh0KX07aWYobj10LCJ1bmRlZmluZWQiIT10eXBlb2YgRXZlbnQmJlIobixFdmVudCkpe2NvbnN0e3R5cGU6bix0YXJnZXQ6ZSxjdXJyZW50VGFyZ2V0OnIsZGV0YWlsOm99PXQ7cmV0dXJue3R5cGU6bix0YXJnZXQ6ZSxjdXJyZW50VGFyZ2V0OnIsLi4ubz97ZGV0YWlsOm99Ont9LC4uLkkodCl9fXZhciBuO3JldHVybiB0fWZ1bmN0aW9uIEkodCl7cmV0dXJuIm9iamVjdCI9PXR5cGVvZihuPXQpJiZudWxsIT09bj9PYmplY3QuZnJvbUVudHJpZXMoT2JqZWN0LmVudHJpZXModCkpOnt9O3ZhciBufWxldCBPO2Z1bmN0aW9uIFQodCl7aWYodm9pZCAwIT09TylyZXR1cm4gTz9PKHQpOnQoKTtjb25zdCBuPVN5bWJvbC5mb3IoIl9fU0VOVFJZX1NBRkVfUkFORE9NX0lEX1dSQVBQRVJfXyIpLGU9cDtyZXR1cm4gbiBpbiBlJiYiZnVuY3Rpb24iPT10eXBlb2YgZVtuXT8oTz1lW25dLE8odCkpOihPPW51bGwsdCgpKX1mdW5jdGlvbiBrKCl7cmV0dXJuIFQoKCk9Pk1hdGgucmFuZG9tKCkpfWZ1bmN0aW9uIFAoKXtyZXR1cm4gVCgoKT0+RGF0ZS5ub3coKSl9Y29uc3QgRD1TeW1ib2wuZm9yKCJzZW50cnkuc2tpcE5vcm1hbGl6YXRpb24iKSxVPVN5bWJvbC5mb3IoInNlbnRyeS5vdmVycmlkZU5vcm1hbGl6YXRpb25EZXB0aCIpO2Z1bmN0aW9uIEIodCxuPTEwMCxlPTEvMCl7dHJ5e3JldHVybiBMKCIiLHQsbixlKX1jYXRjaCh0KXtyZXR1cm57RVJST1I6YCoqbm9uLXNlcmlhbGl6YWJsZSoqICgke3R9KWB9fX1mdW5jdGlvbiBMKHQsbixlPTEvMCxyPTEvMCxvPWZ1bmN0aW9uKCl7Y29uc3QgdD1uZXcgV2Vha1NldDtmdW5jdGlvbiBuKG4pe3JldHVybiEhdC5oYXMobil8fCh0LmFkZChuKSwhMSl9ZnVuY3Rpb24gZShuKXt0LmRlbGV0ZShuKX1yZXR1cm5bbixlXX0oKSl7Y29uc3RbaSxzXT1vO2lmKG51bGw9PW58fFsiYm9vbGVhbiIsInN0cmluZyJdLmluY2x1ZGVzKHR5cGVvZiBuKXx8Im51bWJlciI9PXR5cGVvZiBuJiZOdW1iZXIuaXNGaW5pdGUobikpcmV0dXJuIG47Y29uc3QgYz1mdW5jdGlvbih0LG4pe3RyeXtpZigidW5kZWZpbmVkIiE9dHlwZW9mIGdsb2JhbCYmbj09PWdsb2JhbClyZXR1cm4iW0dsb2JhbF0iO2lmKCJudW1iZXIiPT10eXBlb2YgbiYmIU51bWJlci5pc0Zpbml0ZShuKSlyZXR1cm5gWyR7bn1dYDtpZigiZnVuY3Rpb24iPT10eXBlb2YgbilyZXR1cm5gW0Z1bmN0aW9uOiAke2Z1bmN0aW9uKHQpe3RyeXtyZXR1cm4gdCYmImZ1bmN0aW9uIj09dHlwZW9mIHQmJnQubmFtZXx8eH1jYXRjaHtyZXR1cm4geH19KG4pfV1gO2lmKCJzeW1ib2wiPT10eXBlb2YgbilyZXR1cm5gWyR7U3RyaW5nKG4pfV1gO2lmKCJiaWdpbnQiPT10eXBlb2YgbilyZXR1cm5gW0JpZ0ludDogJHtTdHJpbmcobil9XWA7Y29uc3QgdD1mdW5jdGlvbih0KXtjb25zdCBuPU9iamVjdC5nZXRQcm90b3R5cGVPZih0KTtyZXR1cm4gbj8uY29uc3RydWN0b3I/bi5jb25zdHJ1Y3Rvci5uYW1lOiJudWxsIHByb3RvdHlwZSJ9KG4pO3JldHVybmBbb2JqZWN0ICR7dH1dYH1jYXRjaCh0KXtyZXR1cm5gKipub24tc2VyaWFsaXphYmxlKiogKCR7dH0pYH19KDAsbik7aWYoIWMuc3RhcnRzV2l0aCgiW29iamVjdCAiKSlyZXR1cm4gYztpZihmdW5jdGlvbih0KXtyZXR1cm4gQm9vbGVhbih0W0RdKX0obikpcmV0dXJuIG47Y29uc3QgdT1mdW5jdGlvbih0KXtjb25zdCBuPXRbVV07cmV0dXJuIm51bWJlciI9PXR5cGVvZiBuP246dm9pZCAwfShuKSxhPXZvaWQgMCE9PXU/dTplO2lmKDA9PT1hKXJldHVybiBjLnJlcGxhY2UoIm9iamVjdCAiLCIiKTtpZihpKG4pKXJldHVybiJbQ2lyY3VsYXIgfl0iO2NvbnN0IGY9bjtpZihmJiYiZnVuY3Rpb24iPT10eXBlb2YgZi50b0pTT04pdHJ5e3JldHVybiBMKCIiLGYudG9KU09OKCksYS0xLHIsbyl9Y2F0Y2h7fWNvbnN0IGg9QXJyYXkuaXNBcnJheShuKT9bXTp7fTtsZXQgcD0wO2NvbnN0IGQ9QShuKTtmb3IoY29uc3QgdCBpbiBkKXtpZighT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGQsdCkpY29udGludWU7aWYocD49cil7aFt0XT0iW01heFByb3BlcnRpZXMgfl0iO2JyZWFrfWNvbnN0IG49ZFt0XTtoW3RdPUwodCxuLGEtMSxyLG8pLHArK31yZXR1cm4gcyhuKSxofWZ1bmN0aW9uIE0odCxuKXtjb25zdCBlPW4ucmVwbGFjZSgvXFwvZywiLyIpLnJlcGxhY2UoL1t8XFx7fSgpW1xdXiQrKj8uXS9nLCJcXCQmIik7bGV0IHI9dDt0cnl7cj1kZWNvZGVVUkkodCl9Y2F0Y2h7fXJldHVybiByLnJlcGxhY2UoL1xcL2csIi8iKS5yZXBsYWNlKC93ZWJwYWNrOlwvPy9nLCIiKS5yZXBsYWNlKG5ldyBSZWdFeHAoYChmaWxlOi8vKT8vKiR7ZX0vKmAsImlnIiksImFwcDovLy8iKX1mdW5jdGlvbiB6KHQsbj0wKXtyZXR1cm4ic3RyaW5nIiE9dHlwZW9mIHR8fDA9PT1ufHx0Lmxlbmd0aDw9bj90OmAke3Quc2xpY2UoMCxuKX0uLi5gfWxldCBGO2Z1bmN0aW9uIEcodD1mdW5jdGlvbigpe2NvbnN0IHQ9cDtyZXR1cm4gdC5jcnlwdG98fHQubXNDcnlwdG99KCkpe3RyeXtpZih0Py5yYW5kb21VVUlEKXJldHVybiBUKCgpPT50LnJhbmRvbVVVSUQoKSkucmVwbGFjZSgvLS9nLCIiKX1jYXRjaHt9cmV0dXJuIEZ8fChGPSIxMDAwMDAwMDEwMDA0MDAwODAwMDEwMDAwMDAwMDAwMCIpLEYucmVwbGFjZSgvWzAxOF0vZyx0PT4odF4oMTYqaygpJjE1KT4+dC80KS50b1N0cmluZygxNikpfWZ1bmN0aW9uIEooKXtyZXR1cm4gUCgpLzFlM31sZXQgVztmdW5jdGlvbiBZKCl7cmV0dXJuKFc/PyhXPWZ1bmN0aW9uKCl7Y29uc3R7cGVyZm9ybWFuY2U6dH09cDtpZighdD8ubm93fHwhdC50aW1lT3JpZ2luKXJldHVybiBKO2NvbnN0IG49dC50aW1lT3JpZ2luO3JldHVybigpPT4obitUKCgpPT50Lm5vdygpKSkvMWUzfSgpKSkoKX1mdW5jdGlvbiBIKHQpe2NvbnN0IG49WSgpLGU9e3NpZDpHKCksaW5pdDohMCx0aW1lc3RhbXA6bixzdGFydGVkOm4sZHVyYXRpb246MCxzdGF0dXM6Im9rIixlcnJvcnM6MCxpZ25vcmVEdXJhdGlvbjohMSx0b0pTT046KCk9PmZ1bmN0aW9uKHQpe3JldHVybntzaWQ6YCR7dC5zaWR9YCxpbml0OnQuaW5pdCxzdGFydGVkOm5ldyBEYXRlKDFlMyp0LnN0YXJ0ZWQpLnRvSVNPU3RyaW5nKCksdGltZXN0YW1wOm5ldyBEYXRlKDFlMyp0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxzdGF0dXM6dC5zdGF0dXMsZXJyb3JzOnQuZXJyb3JzLGRpZDoibnVtYmVyIj09dHlwZW9mIHQuZGlkfHwic3RyaW5nIj09dHlwZW9mIHQuZGlkP2Ake3QuZGlkfWA6dm9pZCAwLGR1cmF0aW9uOnQuZHVyYXRpb24sYWJub3JtYWxfbWVjaGFuaXNtOnQuYWJub3JtYWxfbWVjaGFuaXNtLGF0dHJzOntyZWxlYXNlOnQucmVsZWFzZSxlbnZpcm9ubWVudDp0LmVudmlyb25tZW50LGlwX2FkZHJlc3M6dC5pcEFkZHJlc3MsdXNlcl9hZ2VudDp0LnVzZXJBZ2VudH19fShlKX07cmV0dXJuIHQmJksoZSx0KSxlfWZ1bmN0aW9uIEsodCxuPXt9KXtpZihuLnVzZXImJighdC5pcEFkZHJlc3MmJm4udXNlci5pcF9hZGRyZXNzJiYodC5pcEFkZHJlc3M9bi51c2VyLmlwX2FkZHJlc3MpLHQuZGlkfHxuLmRpZHx8KHQuZGlkPW4udXNlci5pZHx8bi51c2VyLmVtYWlsfHxuLnVzZXIudXNlcm5hbWUpKSx0LnRpbWVzdGFtcD1uLnRpbWVzdGFtcHx8WSgpLG4uYWJub3JtYWxfbWVjaGFuaXNtJiYodC5hYm5vcm1hbF9tZWNoYW5pc209bi5hYm5vcm1hbF9tZWNoYW5pc20pLG4uaWdub3JlRHVyYXRpb24mJih0Lmlnbm9yZUR1cmF0aW9uPW4uaWdub3JlRHVyYXRpb24pLG4uc2lkJiYodC5zaWQ9MzI9PT1uLnNpZC5sZW5ndGg/bi5zaWQ6RygpKSx2b2lkIDAhPT1uLmluaXQmJih0LmluaXQ9bi5pbml0KSwhdC5kaWQmJm4uZGlkJiYodC5kaWQ9YCR7bi5kaWR9YCksIm51bWJlciI9PXR5cGVvZiBuLnN0YXJ0ZWQmJih0LnN0YXJ0ZWQ9bi5zdGFydGVkKSx0Lmlnbm9yZUR1cmF0aW9uKXQuZHVyYXRpb249dm9pZCAwO2Vsc2UgaWYoIm51bWJlciI9PXR5cGVvZiBuLmR1cmF0aW9uKXQuZHVyYXRpb249bi5kdXJhdGlvbjtlbHNle2NvbnN0IG49dC50aW1lc3RhbXAtdC5zdGFydGVkO3QuZHVyYXRpb249bj49MD9uOjB9bi5yZWxlYXNlJiYodC5yZWxlYXNlPW4ucmVsZWFzZSksbi5lbnZpcm9ubWVudCYmKHQuZW52aXJvbm1lbnQ9bi5lbnZpcm9ubWVudCksIXQuaXBBZGRyZXNzJiZuLmlwQWRkcmVzcyYmKHQuaXBBZGRyZXNzPW4uaXBBZGRyZXNzKSwhdC51c2VyQWdlbnQmJm4udXNlckFnZW50JiYodC51c2VyQWdlbnQ9bi51c2VyQWdlbnQpLCJudW1iZXIiPT10eXBlb2Ygbi5lcnJvcnMmJih0LmVycm9ycz1uLmVycm9ycyksbi5zdGF0dXMmJih0LnN0YXR1cz1uLnN0YXR1cyl9ZnVuY3Rpb24gWih0LG4sZT0yKXtpZighbnx8Im9iamVjdCIhPXR5cGVvZiBufHxlPD0wKXJldHVybiBuO2lmKHQmJjA9PT1PYmplY3Qua2V5cyhuKS5sZW5ndGgpcmV0dXJuIHQ7Y29uc3Qgcj17Li4udH07Zm9yKGNvbnN0IHQgaW4gbilPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobix0KSYmKHJbdF09WihyW3RdLG5bdF0sZS0xKSk7cmV0dXJuIHJ9ZnVuY3Rpb24gcSgpe3JldHVybiBHKCl9ZnVuY3Rpb24gVigpe3JldHVybiBHKCkuc3Vic3RyaW5nKDE2KX1mdW5jdGlvbiBRKHQpe2lmKHQpe2lmKCJvYmplY3QiPT10eXBlb2YgdCYmImRlcmVmImluIHQmJiJmdW5jdGlvbiI9PXR5cGVvZiB0LmRlcmVmKXRyeXtyZXR1cm4gdC5kZXJlZigpfWNhdGNoe3JldHVybn1yZXR1cm4gdH19Y29uc3QgWD0iX3NlbnRyeVNwYW4iO2Z1bmN0aW9uIHR0KHQsbil7bj9mdW5jdGlvbih0LG4sZSl7dHJ5e09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LG4se3ZhbHVlOmUsd3JpdGFibGU6ITAsY29uZmlndXJhYmxlOiEwfSl9Y2F0Y2h7aCYmdy5sb2coYEZhaWxlZCB0byBhZGQgbm9uLWVudW1lcmFibGUgcHJvcGVydHkgIiR7U3RyaW5nKG4pfSIgdG8gb2JqZWN0YCx0KX19KHQsWCxmdW5jdGlvbih0KXt0cnl7Y29uc3Qgbj1wLldlYWtSZWY7aWYoImZ1bmN0aW9uIj09dHlwZW9mIG4pcmV0dXJuIG5ldyBuKHQpfWNhdGNoe31yZXR1cm4gdH0obikpOmRlbGV0ZSB0W1hdfWZ1bmN0aW9uIG50KHQpe3JldHVybiBRKHRbWF0pfWNsYXNzIGV0e2NvbnN0cnVjdG9yKCl7dGhpcy50PSExLHRoaXMubz1bXSx0aGlzLmk9W10sdGhpcy51PVtdLHRoaXMuaD1bXSx0aGlzLnA9e30sdGhpcy5sPXt9LHRoaXMubT17fSx0aGlzLnY9e30sdGhpcy5fPXt9LHRoaXMuUz17fSx0aGlzLk49e3RyYWNlSWQ6cSgpLHNhbXBsZVJhbmQ6aygpfX1jbG9uZSgpe2NvbnN0IHQ9bmV3IGV0O3JldHVybiB0LnU9Wy4uLnRoaXMudV0sdC5sPXsuLi50aGlzLmx9LHQubT17Li4udGhpcy5tfSx0LnY9ey4uLnRoaXMudn0sdC5fPXsuLi50aGlzLl99LHRoaXMuXy5mbGFncyYmKHQuXy5mbGFncz17dmFsdWVzOlsuLi50aGlzLl8uZmxhZ3MudmFsdWVzXX0pLHQucD10aGlzLnAsdC5DPXRoaXMuQyx0Lmo9dGhpcy5qLHQuUj10aGlzLlIsdC5BPXRoaXMuQSx0Lmk9Wy4uLnRoaXMuaV0sdC5oPVsuLi50aGlzLmhdLHQuUz17Li4udGhpcy5TfSx0Lk49ey4uLnRoaXMuTn0sdC5JPXRoaXMuSSx0Lk89dGhpcy5PLHQuVD10aGlzLlQsdHQodCxudCh0aGlzKSksdH1zZXRDbGllbnQodCl7dGhpcy5JPXR9c2V0TGFzdEV2ZW50SWQodCl7dGhpcy5PPXR9Z2V0Q2xpZW50KCl7cmV0dXJuIHRoaXMuSX1sYXN0RXZlbnRJZCgpe3JldHVybiB0aGlzLk99YWRkU2NvcGVMaXN0ZW5lcih0KXt0aGlzLm8ucHVzaCh0KX1hZGRFdmVudFByb2Nlc3Nvcih0KXtyZXR1cm4gdGhpcy5pLnB1c2godCksdGhpc31zZXRVc2VyKHQpe3JldHVybiB0aGlzLnA9dHx8e2VtYWlsOnZvaWQgMCxpZDp2b2lkIDAsaXBfYWRkcmVzczp2b2lkIDAsdXNlcm5hbWU6dm9pZCAwfSx0aGlzLmomJksodGhpcy5qLHt1c2VyOnR9KSx0aGlzLmsoKSx0aGlzfWdldFVzZXIoKXtyZXR1cm4gdGhpcy5wfXNldENvbnZlcnNhdGlvbklkKHQpe3JldHVybiB0aGlzLlQ9dHx8dm9pZCAwLHRoaXMuaygpLHRoaXN9c2V0VGFncyh0KXtyZXR1cm4gdGhpcy5sPXsuLi50aGlzLmwsLi4udH0sdGhpcy5rKCksdGhpc31zZXRUYWcodCxuKXtyZXR1cm4gdGhpcy5zZXRUYWdzKHtbdF06bn0pfXNldEF0dHJpYnV0ZXModCl7cmV0dXJuIHRoaXMubT17Li4udGhpcy5tLC4uLnR9LHRoaXMuaygpLHRoaXN9c2V0QXR0cmlidXRlKHQsbil7cmV0dXJuIHRoaXMuc2V0QXR0cmlidXRlcyh7W3RdOm59KX1yZW1vdmVBdHRyaWJ1dGUodCl7cmV0dXJuIHQgaW4gdGhpcy5tJiYoZGVsZXRlIHRoaXMubVt0XSx0aGlzLmsoKSksdGhpc31zZXRFeHRyYXModCl7cmV0dXJuIHRoaXMudj17Li4udGhpcy52LC4uLnR9LHRoaXMuaygpLHRoaXN9c2V0RXh0cmEodCxuKXtyZXR1cm4gdGhpcy52PXsuLi50aGlzLnYsW3RdOm59LHRoaXMuaygpLHRoaXN9c2V0RmluZ2VycHJpbnQodCl7cmV0dXJuIHRoaXMuQT10LHRoaXMuaygpLHRoaXN9c2V0TGV2ZWwodCl7cmV0dXJuIHRoaXMuQz10LHRoaXMuaygpLHRoaXN9c2V0VHJhbnNhY3Rpb25OYW1lKHQpe3JldHVybiB0aGlzLlI9dCx0aGlzLmsoKSx0aGlzfXNldENvbnRleHQodCxuKXtyZXR1cm4gbnVsbD09PW4/ZGVsZXRlIHRoaXMuX1t0XTp0aGlzLl9bdF09bix0aGlzLmsoKSx0aGlzfXNldFNlc3Npb24odCl7cmV0dXJuIHQ/dGhpcy5qPXQ6ZGVsZXRlIHRoaXMuaix0aGlzLmsoKSx0aGlzfWdldFNlc3Npb24oKXtyZXR1cm4gdGhpcy5qfXVwZGF0ZSh0KXtpZighdClyZXR1cm4gdGhpcztjb25zdCBuPSJmdW5jdGlvbiI9PXR5cGVvZiB0P3QodGhpcyk6dCxlPW4gaW5zdGFuY2VvZiBldD9uLmdldFNjb3BlRGF0YSgpOkMobiwiT2JqZWN0Iik/dDp2b2lkIDA7Y29uc3R7dGFnczpyLGF0dHJpYnV0ZXM6byxleHRyYTppLHVzZXI6cyxjb250ZXh0czpjLGxldmVsOnUsZmluZ2VycHJpbnQ6YT1bXSxwcm9wYWdhdGlvbkNvbnRleHQ6Zixjb252ZXJzYXRpb25JZDpofT1lfHx7fTtyZXR1cm4gdGhpcy5sPXsuLi50aGlzLmwsLi4ucn0sdGhpcy5tPXsuLi50aGlzLm0sLi4ub30sdGhpcy52PXsuLi50aGlzLnYsLi4uaX0sdGhpcy5fPXsuLi50aGlzLl8sLi4uY30scyYmT2JqZWN0LmtleXMocykubGVuZ3RoJiYodGhpcy5wPXMpLHUmJih0aGlzLkM9dSksYS5sZW5ndGgmJih0aGlzLkE9YSksZiYmKHRoaXMuTj1mKSxoJiYodGhpcy5UPWgpLHRoaXN9Y2xlYXIoKXtyZXR1cm4gdGhpcy51PVtdLHRoaXMubD17fSx0aGlzLm09e30sdGhpcy52PXt9LHRoaXMucD17fSx0aGlzLl89e30sdGhpcy5DPXZvaWQgMCx0aGlzLlI9dm9pZCAwLHRoaXMuQT12b2lkIDAsdGhpcy5qPXZvaWQgMCx0aGlzLlQ9dm9pZCAwLHR0KHRoaXMsdm9pZCAwKSx0aGlzLmg9W10sdGhpcy5zZXRQcm9wYWdhdGlvbkNvbnRleHQoe3RyYWNlSWQ6cSgpLHNhbXBsZVJhbmQ6aygpfSksdGhpcy5rKCksdGhpc31hZGRCcmVhZGNydW1iKHQsbil7Y29uc3QgZT0ibnVtYmVyIj09dHlwZW9mIG4/bjoxMDA7aWYoZTw9MClyZXR1cm4gdGhpcztjb25zdCByPXt0aW1lc3RhbXA6SigpLC4uLnQsbWVzc2FnZTp0Lm1lc3NhZ2U/eih0Lm1lc3NhZ2UsMjA0OCk6dC5tZXNzYWdlfTtyZXR1cm4gdGhpcy51LnB1c2gociksdGhpcy51Lmxlbmd0aD5lJiYodGhpcy51PXRoaXMudS5zbGljZSgtZSksdGhpcy5JPy5yZWNvcmREcm9wcGVkRXZlbnQoImJ1ZmZlcl9vdmVyZmxvdyIsImxvZ19pdGVtIikpLHRoaXMuaygpLHRoaXN9Z2V0TGFzdEJyZWFkY3J1bWIoKXtyZXR1cm4gdGhpcy51W3RoaXMudS5sZW5ndGgtMV19Y2xlYXJCcmVhZGNydW1icygpe3JldHVybiB0aGlzLnU9W10sdGhpcy5rKCksdGhpc31hZGRBdHRhY2htZW50KHQpe3JldHVybiB0aGlzLmgucHVzaCh0KSx0aGlzfWNsZWFyQXR0YWNobWVudHMoKXtyZXR1cm4gdGhpcy5oPVtdLHRoaXN9Z2V0U2NvcGVEYXRhKCl7cmV0dXJue2JyZWFkY3J1bWJzOnRoaXMudSxhdHRhY2htZW50czp0aGlzLmgsY29udGV4dHM6dGhpcy5fLHRhZ3M6dGhpcy5sLGF0dHJpYnV0ZXM6dGhpcy5tLGV4dHJhOnRoaXMudix1c2VyOnRoaXMucCxsZXZlbDp0aGlzLkMsZmluZ2VycHJpbnQ6dGhpcy5BfHxbXSxldmVudFByb2Nlc3NvcnM6dGhpcy5pLHByb3BhZ2F0aW9uQ29udGV4dDp0aGlzLk4sc2RrUHJvY2Vzc2luZ01ldGFkYXRhOnRoaXMuUyx0cmFuc2FjdGlvbk5hbWU6dGhpcy5SLHNwYW46bnQodGhpcyksY29udmVyc2F0aW9uSWQ6dGhpcy5UfX1zZXRTREtQcm9jZXNzaW5nTWV0YWRhdGEodCl7cmV0dXJuIHRoaXMuUz1aKHRoaXMuUyx0LDIpLHRoaXN9c2V0UHJvcGFnYXRpb25Db250ZXh0KHQpe3JldHVybiB0aGlzLk49dCx0aGlzfWdldFByb3BhZ2F0aW9uQ29udGV4dCgpe3JldHVybiB0aGlzLk59Y2FwdHVyZUV4Y2VwdGlvbih0LG4pe2NvbnN0IGU9bj8uZXZlbnRfaWR8fEcoKTtpZighdGhpcy5JKXJldHVybiBoJiZ3Lndhcm4oIk5vIGNsaWVudCBjb25maWd1cmVkIG9uIHNjb3BlIC0gd2lsbCBub3QgY2FwdHVyZSBleGNlcHRpb24hIiksZTtjb25zdCByPW5ldyBFcnJvcigiU2VudHJ5IHN5bnRoZXRpY0V4Y2VwdGlvbiIpO3JldHVybiB0aGlzLkkuY2FwdHVyZUV4Y2VwdGlvbih0LHtvcmlnaW5hbEV4Y2VwdGlvbjp0LHN5bnRoZXRpY0V4Y2VwdGlvbjpyLC4uLm4sZXZlbnRfaWQ6ZX0sdGhpcyksZX1jYXB0dXJlTWVzc2FnZSh0LG4sZSl7Y29uc3Qgcj1lPy5ldmVudF9pZHx8RygpO2lmKCF0aGlzLkkpcmV0dXJuIGgmJncud2FybigiTm8gY2xpZW50IGNvbmZpZ3VyZWQgb24gc2NvcGUgLSB3aWxsIG5vdCBjYXB0dXJlIG1lc3NhZ2UhIikscjtjb25zdCBvPWU/LnN5bnRoZXRpY0V4Y2VwdGlvbj8/bmV3IEVycm9yKHQpO3JldHVybiB0aGlzLkkuY2FwdHVyZU1lc3NhZ2UodCxuLHtvcmlnaW5hbEV4Y2VwdGlvbjp0LHN5bnRoZXRpY0V4Y2VwdGlvbjpvLC4uLmUsZXZlbnRfaWQ6cn0sdGhpcykscn1jYXB0dXJlRXZlbnQodCxuKXtjb25zdCBlPXQuZXZlbnRfaWR8fG4/LmV2ZW50X2lkfHxHKCk7cmV0dXJuIHRoaXMuST8odGhpcy5JLmNhcHR1cmVFdmVudCh0LHsuLi5uLGV2ZW50X2lkOmV9LHRoaXMpLGUpOihoJiZ3Lndhcm4oIk5vIGNsaWVudCBjb25maWd1cmVkIG9uIHNjb3BlIC0gd2lsbCBub3QgY2FwdHVyZSBldmVudCEiKSxlKX1rKCl7dGhpcy50fHwodGhpcy50PSEwLHRoaXMuby5mb3JFYWNoKHQ9Pnt0KHRoaXMpfSksdGhpcy50PSExKX19Y29uc3QgcnQ9dD0+dCBpbnN0YW5jZW9mIFByb21pc2UmJiF0W290XSxvdD1TeW1ib2woImNoYWluZWQgUHJvbWlzZUxpa2UiKSxpdD0odCxuKT0+e2lmKCFuKXJldHVybiB0O2xldCBlPSExO2Zvcihjb25zdCByIGluIHQpe2lmKHIgaW4gbiljb250aW51ZTtlPSEwO2NvbnN0IG89dFtyXTsiZnVuY3Rpb24iPT10eXBlb2Ygbz9PYmplY3QuZGVmaW5lUHJvcGVydHkobixyLHt2YWx1ZTooLi4ubik9Pm8uYXBwbHkodCxuKSxlbnVtZXJhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMCx3cml0YWJsZTohMH0pOm5bcl09b31yZXR1cm4gZSYmT2JqZWN0LmFzc2lnbihuLHtbb3RdOiEwfSksbn07Y2xhc3Mgc3R7Y29uc3RydWN0b3IodCxuKXtsZXQgZSxyO2U9dHx8bmV3IGV0LHI9bnx8bmV3IGV0LHRoaXMuUD1be3Njb3BlOmV9XSx0aGlzLkQ9cn13aXRoU2NvcGUodCl7Y29uc3Qgbj10aGlzLlUoKTtsZXQgZTt0cnl7ZT10KG4pfWNhdGNoKHQpe3Rocm93IHRoaXMuQigpLHR9cmV0dXJuIGooZSk/KCh0LG4sZSk9Pntjb25zdCByPXQudGhlbih0PT4obih0KSx0KSx0PT57dGhyb3cgZSh0KSx0fSk7cmV0dXJuIHJ0KHIpJiZydCh0KT9yOml0KHQscil9KShlLCgpPT50aGlzLkIoKSwoKT0+dGhpcy5CKCkpOih0aGlzLkIoKSxlKX1nZXRDbGllbnQoKXtyZXR1cm4gdGhpcy5nZXRTdGFja1RvcCgpLmNsaWVudH1nZXRTY29wZSgpe3JldHVybiB0aGlzLmdldFN0YWNrVG9wKCkuc2NvcGV9Z2V0SXNvbGF0aW9uU2NvcGUoKXtyZXR1cm4gdGhpcy5EfWdldFN0YWNrVG9wKCl7cmV0dXJuIHRoaXMuUFt0aGlzLlAubGVuZ3RoLTFdfVUoKXtjb25zdCB0PXRoaXMuZ2V0U2NvcGUoKS5jbG9uZSgpO3JldHVybiB0aGlzLlAucHVzaCh7Y2xpZW50OnRoaXMuZ2V0Q2xpZW50KCksc2NvcGU6dH0pLHR9Qigpe3JldHVybiEodGhpcy5QLmxlbmd0aDw9MSkmJiEhdGhpcy5QLnBvcCgpfX1mdW5jdGlvbiBjdCgpe2NvbnN0IHQ9ZyhsKCkpO3JldHVybiB0LnN0YWNrPXQuc3RhY2t8fG5ldyBzdChtKCJkZWZhdWx0Q3VycmVudFNjb3BlIiwoKT0+bmV3IGV0KSxtKCJkZWZhdWx0SXNvbGF0aW9uU2NvcGUiLCgpPT5uZXcgZXQpKX1mdW5jdGlvbiB1dCh0KXtyZXR1cm4gY3QoKS53aXRoU2NvcGUodCl9ZnVuY3Rpb24gYXQodCxuKXtjb25zdCBlPWN0KCk7cmV0dXJuIGUud2l0aFNjb3BlKCgpPT4oZS5nZXRTdGFja1RvcCgpLnNjb3BlPXQsbih0KSkpfWZ1bmN0aW9uIGZ0KHQpe3JldHVybiBjdCgpLndpdGhTY29wZSgoKT0+dChjdCgpLmdldElzb2xhdGlvblNjb3BlKCkpKX1mdW5jdGlvbiBodCh0KXtjb25zdCBuPWcodCk7cmV0dXJuIG4uYWNzP24uYWNzOnt3aXRoSXNvbGF0aW9uU2NvcGU6ZnQsd2l0aFNjb3BlOnV0LHdpdGhTZXRTY29wZTphdCx3aXRoU2V0SXNvbGF0aW9uU2NvcGU6KHQsbik9PmZ0KG4pLGdldEN1cnJlbnRTY29wZTooKT0+Y3QoKS5nZXRTY29wZSgpLGdldElzb2xhdGlvblNjb3BlOigpPT5jdCgpLmdldElzb2xhdGlvblNjb3BlKCl9fWZ1bmN0aW9uIHB0KCl7cmV0dXJuIGh0KGwoKSkuZ2V0Q3VycmVudFNjb3BlKCkuZ2V0Q2xpZW50KCl9ZnVuY3Rpb24gZHQodCl7Y29uc3Qgbj10O3JldHVybntzY29wZTpuLl9zZW50cnlTY29wZSxpc29sYXRpb25TY29wZTpRKG4uX3NlbnRyeUlzb2xhdGlvblNjb3BlKX19Y29uc3QgbHQ9InNlbnRyeS0iO2Z1bmN0aW9uIGd0KHQpe2NvbnN0IG49ZnVuY3Rpb24odCl7aWYoIXR8fChuPXQsIUMobiwiU3RyaW5nIikmJiFBcnJheS5pc0FycmF5KHQpKSlyZXR1cm47dmFyIG47aWYoQXJyYXkuaXNBcnJheSh0KSlyZXR1cm4gdC5yZWR1Y2UoKHQsbik9Pntjb25zdCBlPW10KG4pO3JldHVybiBPYmplY3QuZW50cmllcyhlKS5mb3JFYWNoKChbbixlXSk9Pnt0W25dPWV9KSx0fSx7fSk7cmV0dXJuIG10KHQpfSh0KTtpZighbilyZXR1cm47Y29uc3QgZT1PYmplY3QuZW50cmllcyhuKS5yZWR1Y2UoKHQsW24sZV0pPT57aWYobi5zdGFydHNXaXRoKGx0KSl7dFtuLnNsaWNlKDcpXT1lfXJldHVybiB0fSx7fSk7cmV0dXJuIE9iamVjdC5rZXlzKGUpLmxlbmd0aD4wP2U6dm9pZCAwfWZ1bmN0aW9uIG10KHQpe3JldHVybiB0LnNwbGl0KCIsIikubWFwKHQ9Pntjb25zdCBuPXQuaW5kZXhPZigiPSIpO2lmKC0xPT09bilyZXR1cm5bXTtyZXR1cm5bdC5zbGljZSgwLG4pLHQuc2xpY2UobisxKV0ubWFwKHQ9Pnt0cnl7cmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudCh0LnRyaW0oKSl9Y2F0Y2h7cmV0dXJufX0pfSkucmVkdWNlKCh0LFtuLGVdKT0+KG4mJmUmJih0W25dPWUpLHQpLHt9KX1jb25zdCB5dD0vXm8oXGQrKVwuLztmdW5jdGlvbiBidCh0LG49ITEpe2NvbnN0e2hvc3Q6ZSxwYXRoOnIscGFzczpvLHBvcnQ6aSxwcm9qZWN0SWQ6cyxwcm90b2NvbDpjLHB1YmxpY0tleTp1fT10O3JldHVybmAke2N9Oi8vJHt1fSR7biYmbz9gOiR7b31gOiIifUAke2V9JHtpP2A6JHtpfWA6IiJ9LyR7cj9gJHtyfS9gOnJ9JHtzfWB9ZnVuY3Rpb24gdnQodCl7Y29uc3Qgbj10LmdldE9wdGlvbnMoKSx7aG9zdDplfT10LmdldERzbigpfHx7fTtsZXQgcjtyZXR1cm4gbi5vcmdJZD9yPVN0cmluZyhuLm9yZ0lkKTplJiYocj1mdW5jdGlvbih0KXtjb25zdCBuPXQubWF0Y2goeXQpO3JldHVybiBuPy5bMV19KGUpKSxyfWZ1bmN0aW9uIF90KHQpe2NvbnN0e3NwYW5JZDpuLHRyYWNlSWQ6ZSxpc1JlbW90ZTpyfT10LnNwYW5Db250ZXh0KCksbz1yP246RXQodCkucGFyZW50X3NwYW5faWQsaT1kdCh0KS5zY29wZTtyZXR1cm57cGFyZW50X3NwYW5faWQ6byxzcGFuX2lkOnI/aT8uZ2V0UHJvcGFnYXRpb25Db250ZXh0KCkucHJvcGFnYXRpb25TcGFuSWR8fFYoKTpuLHRyYWNlX2lkOmV9fWZ1bmN0aW9uIFN0KHQpe3JldHVybiB0JiZ0Lmxlbmd0aD4wP3QubWFwKCh7Y29udGV4dDp7c3BhbklkOnQsdHJhY2VJZDpuLHRyYWNlRmxhZ3M6ZSwuLi5yfSxhdHRyaWJ1dGVzOm99KT0+KHtzcGFuX2lkOnQsdHJhY2VfaWQ6bixzYW1wbGVkOjE9PT1lLGF0dHJpYnV0ZXM6bywuLi5yfSkpOnZvaWQgMH1mdW5jdGlvbiB3dCh0KXtyZXR1cm4ibnVtYmVyIj09dHlwZW9mIHQ/JHQodCk6QXJyYXkuaXNBcnJheSh0KT90WzBdK3RbMV0vMWU5OnQgaW5zdGFuY2VvZiBEYXRlPyR0KHQuZ2V0VGltZSgpKTpZKCl9ZnVuY3Rpb24gJHQodCl7cmV0dXJuIHQ+OTk5OTk5OTk5OT90LzFlMzp0fWZ1bmN0aW9uIEV0KHQpe2lmKGZ1bmN0aW9uKHQpe3JldHVybiJmdW5jdGlvbiI9PXR5cGVvZiB0LmdldFNwYW5KU09OfSh0KSlyZXR1cm4gdC5nZXRTcGFuSlNPTigpO2NvbnN0e3NwYW5JZDpuLHRyYWNlSWQ6ZX09dC5zcGFuQ29udGV4dCgpO2lmKGZ1bmN0aW9uKHQpe2NvbnN0IG49dDtyZXR1cm4hIShuLmF0dHJpYnV0ZXMmJm4uc3RhcnRUaW1lJiZuLm5hbWUmJm4uZW5kVGltZSYmbi5zdGF0dXMpfSh0KSl7Y29uc3R7YXR0cmlidXRlczpyLHN0YXJ0VGltZTpvLG5hbWU6aSxlbmRUaW1lOnMsc3RhdHVzOmMsbGlua3M6dX09dDtyZXR1cm57c3Bhbl9pZDpuLHRyYWNlX2lkOmUsZGF0YTpyLGRlc2NyaXB0aW9uOmkscGFyZW50X3NwYW5faWQ6eHQodCksc3RhcnRfdGltZXN0YW1wOnd0KG8pLHRpbWVzdGFtcDp3dChzKXx8dm9pZCAwLHN0YXR1czpOdChjKSxvcDpyWyJzZW50cnkub3AiXSxvcmlnaW46clsic2VudHJ5Lm9yaWdpbiJdLGxpbmtzOlN0KHUpfX1yZXR1cm57c3Bhbl9pZDpuLHRyYWNlX2lkOmUsc3RhcnRfdGltZXN0YW1wOjAsZGF0YTp7fX19ZnVuY3Rpb24geHQodCl7cmV0dXJuInBhcmVudFNwYW5JZCJpbiB0P3QucGFyZW50U3BhbklkOiJwYXJlbnRTcGFuQ29udGV4dCJpbiB0P3QucGFyZW50U3BhbkNvbnRleHQ/LnNwYW5JZDp2b2lkIDB9ZnVuY3Rpb24gTnQodCl7aWYodCYmMCE9PXQuY29kZSlyZXR1cm4gMT09PXQuY29kZT8ib2siOnQubWVzc2FnZXx8ImludGVybmFsX2Vycm9yIn1jb25zdCBDdD1mdW5jdGlvbih0KXtyZXR1cm4gdC5fc2VudHJ5Um9vdFNwYW58fHR9O2Z1bmN0aW9uIGp0KHQpe2lmKCJib29sZWFuIj09dHlwZW9mIF9fU0VOVFJZX1RSQUNJTkdfXyYmIV9fU0VOVFJZX1RSQUNJTkdfXylyZXR1cm4hMTtjb25zdCBuPXR8fHB0KCk/LmdldE9wdGlvbnMoKTtyZXR1cm4hKCFufHxudWxsPT1uLnRyYWNlc1NhbXBsZVJhdGUmJiFuLnRyYWNlc1NhbXBsZXIpfWNvbnN0IFJ0PVN5bWJvbC5mb3IoInNlbnRyeS5ub25SZWNvcmRpbmdTcGFuIik7ZnVuY3Rpb24gQXQodCxuKXtjb25zdCBlPW4uZ2V0T3B0aW9ucygpLHtwdWJsaWNLZXk6cn09bi5nZXREc24oKXx8e30sbz17ZW52aXJvbm1lbnQ6ZS5lbnZpcm9ubWVudHx8InByb2R1Y3Rpb24iLHJlbGVhc2U6ZS5yZWxlYXNlLHB1YmxpY19rZXk6cix0cmFjZV9pZDp0LG9yZ19pZDp2dChuKX07cmV0dXJuIG4uZW1pdCgiY3JlYXRlRHNjIixvKSxvfWZ1bmN0aW9uIEl0KHQsbil7Y29uc3QgZT1uLmdldFByb3BhZ2F0aW9uQ29udGV4dCgpO3JldHVybiBlLmRzY3x8QXQoZS50cmFjZUlkLHQpfWZ1bmN0aW9uIE90KHQpe2NvbnN0IG49cHQoKTtpZighbilyZXR1cm57fTtjb25zdCBlPUN0KHQpLHI9RXQoZSksbz1yLmRhdGEsaT1lLnNwYW5Db250ZXh0KCkudHJhY2VTdGF0ZSxzPWk/LmdldCgic2VudHJ5LnNhbXBsZV9yYXRlIik/P29bInNlbnRyeS5zYW1wbGVfcmF0ZSJdPz9vWyJzZW50cnkucHJldmlvdXNfdHJhY2Vfc2FtcGxlX3JhdGUiXTtmdW5jdGlvbiBjKHQpe3JldHVybiJudW1iZXIiIT10eXBlb2YgcyYmInN0cmluZyIhPXR5cGVvZiBzfHwodC5zYW1wbGVfcmF0ZT1gJHtzfWApLHR9Y29uc3QgdT1lLl9mcm96ZW5Ec2M7aWYodSlyZXR1cm4gYyh1KTtpZihmdW5jdGlvbih0KXtyZXR1cm4hIXQmJiEwPT09dFtSdF19KGUpJiYhanQobi5nZXRPcHRpb25zKCkpKXtjb25zdCB0PWR0KGUpLnNjb3BlO2lmKHQpcmV0dXJuIGMoey4uLkl0KG4sdCl9KX1jb25zdCBhPWk/LmdldCgic2VudHJ5LmRzYyIpLGY9YSYmZ3QoYSk7aWYoZilyZXR1cm4gYyhmKTtjb25zdCBoPUF0KHQuc3BhbkNvbnRleHQoKS50cmFjZUlkLG4pLHA9b1sic2VudHJ5LnNvdXJjZSJdPz9vWyJzZW50cnkuc3Bhbi5zb3VyY2UiXSxkPXIuZGVzY3JpcHRpb247cmV0dXJuInVybCIhPT1wJiZkJiYoaC50cmFuc2FjdGlvbj1kKSxqdCgpJiYoaC5zYW1wbGVkPVN0cmluZyhmdW5jdGlvbih0KXtjb25zdHt0cmFjZUZsYWdzOm59PXQuc3BhbkNvbnRleHQoKTtyZXR1cm4gMT09PW59KGUpKSxoLnNhbXBsZV9yYW5kPWk/LmdldCgic2VudHJ5LnNhbXBsZV9yYW5kIik/P2R0KGUpLnNjb3BlPy5nZXRQcm9wYWdhdGlvbkNvbnRleHQoKS5zYW1wbGVSYW5kLnRvU3RyaW5nKCkpLGMoaCksbi5lbWl0KCJjcmVhdGVEc2MiLGgsZSksaH1mdW5jdGlvbiBUdCh0LG49W10pe3JldHVyblt0LG5dfWZ1bmN0aW9uIGt0KHQsbil7Y29uc3QgZT10WzFdO2Zvcihjb25zdCB0IG9mIGUpe2lmKG4odCx0WzBdLnR5cGUpKXJldHVybiEwfXJldHVybiExfWZ1bmN0aW9uIFB0KHQpe2NvbnN0IG49ZyhwKTtyZXR1cm4gbi5lbmNvZGVQb2x5ZmlsbD9uLmVuY29kZVBvbHlmaWxsKHQpOihuZXcgVGV4dEVuY29kZXIpLmVuY29kZSh0KX1mdW5jdGlvbiBEdCh0KXtjb25zdFtuLGVdPXQ7bGV0IHI9SlNPTi5zdHJpbmdpZnkobik7ZnVuY3Rpb24gbyh0KXsic3RyaW5nIj09dHlwZW9mIHI/cj0ic3RyaW5nIj09dHlwZW9mIHQ/cit0OltQdChyKSx0XTpyLnB1c2goInN0cmluZyI9PXR5cGVvZiB0P1B0KHQpOnQpfWZvcihjb25zdCB0IG9mIGUpe2NvbnN0W24sZV09dDtpZihvKGBcbiR7SlNPTi5zdHJpbmdpZnkobil9XG5gKSwic3RyaW5nIj09dHlwZW9mIGV8fGUgaW5zdGFuY2VvZiBVaW50OEFycmF5KW8oZSk7ZWxzZXtsZXQgdDt0cnl7dD1KU09OLnN0cmluZ2lmeShlKX1jYXRjaHt0PUpTT04uc3RyaW5naWZ5KEIoZSkpfW8odCl9fXJldHVybiJzdHJpbmciPT10eXBlb2Ygcj9yOmZ1bmN0aW9uKHQpe2NvbnN0IG49dC5yZWR1Y2UoKHQsbik9PnQrbi5sZW5ndGgsMCksZT1uZXcgVWludDhBcnJheShuKTtsZXQgcj0wO2Zvcihjb25zdCBuIG9mIHQpZS5zZXQobixyKSxyKz1uLmxlbmd0aDtyZXR1cm4gZX0ocil9Y29uc3QgVXQ9e3Nlc3Npb25zOiJzZXNzaW9uIixldmVudDoiZXJyb3IiLGNsaWVudF9yZXBvcnQ6ImludGVybmFsIix1c2VyX3JlcG9ydDoiZGVmYXVsdCIscHJvZmlsZV9jaHVuazoicHJvZmlsZSIscmVwbGF5X2V2ZW50OiJyZXBsYXkiLHJlcGxheV9yZWNvcmRpbmc6InJlcGxheSIsY2hlY2tfaW46Im1vbml0b3IiLHJhd19zZWN1cml0eToic2VjdXJpdHkiLGxvZzoibG9nX2l0ZW0iLHRyYWNlX21ldHJpYzoibWV0cmljIn07ZnVuY3Rpb24gQnQodCl7cmV0dXJuIGZ1bmN0aW9uKHQpe3JldHVybiB0IGluIFV0fSh0KT9VdFt0XTp0fWZ1bmN0aW9uIEx0KHQpe2lmKCF0Py5zZGspcmV0dXJuO2NvbnN0e25hbWU6bix2ZXJzaW9uOmV9PXQuc2RrO3JldHVybntuYW1lOm4sdmVyc2lvbjplfX1mdW5jdGlvbiBNdCh0LG4sZSxyKXtjb25zdCBvPUx0KGUpLGk9dC50eXBlJiYicmVwbGF5X2V2ZW50IiE9PXQudHlwZT90LnR5cGU6ImV2ZW50IjshZnVuY3Rpb24odCxuKXtpZighbilyZXR1cm4gdDtjb25zdCBlPXQuc2RrfHx7fTt0LnNkaz17Li4uZSxuYW1lOmUubmFtZXx8bi5uYW1lLHZlcnNpb246ZS52ZXJzaW9ufHxuLnZlcnNpb24saW50ZWdyYXRpb25zOlsuLi50LnNkaz8uaW50ZWdyYXRpb25zfHxbXSwuLi5uLmludGVncmF0aW9uc3x8W11dLHBhY2thZ2VzOlsuLi50LnNkaz8ucGFja2FnZXN8fFtdLC4uLm4ucGFja2FnZXN8fFtdXSxzZXR0aW5nczp0LnNkaz8uc2V0dGluZ3N8fG4uc2V0dGluZ3M/ey4uLnQuc2RrPy5zZXR0aW5ncywuLi5uLnNldHRpbmdzfTp2b2lkIDB9fSh0LGU/LnNkayk7Y29uc3Qgcz1mdW5jdGlvbih0LG4sZSxyKXtjb25zdCBvPXQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhPy5keW5hbWljU2FtcGxpbmdDb250ZXh0O3JldHVybntldmVudF9pZDp0LmV2ZW50X2lkLHNlbnRfYXQ6bmV3IERhdGUoUCgpKS50b0lTT1N0cmluZygpLC4uLm4mJntzZGs6bn0sLi4uISFlJiZyJiZ7ZHNuOmJ0KHIpfSwuLi5vJiZ7dHJhY2U6b319fSh0LG8scixuKTtkZWxldGUgdC5zZGtQcm9jZXNzaW5nTWV0YWRhdGE7cmV0dXJuIFR0KHMsW1t7dHlwZTppfSx0XV0pfWNvbnN0IHp0PSJfX1NFTlRSWV9TVVBQUkVTU19UUkFDSU5HX18iO2Z1bmN0aW9uIEZ0KHQpe2NvbnN0IG49aHQobCgpKTtyZXR1cm4gbi5zdXBwcmVzc1RyYWNpbmc/bi5zdXBwcmVzc1RyYWNpbmcodCk6ZnVuY3Rpb24oLi4udCl7Y29uc3Qgbj1odChsKCkpO2lmKDI9PT10Lmxlbmd0aCl7Y29uc3RbZSxyXT10O3JldHVybiBlP24ud2l0aFNldFNjb3BlKGUscik6bi53aXRoU2NvcGUocil9cmV0dXJuIG4ud2l0aFNjb3BlKHRbMF0pfShuPT57bi5zZXRTREtQcm9jZXNzaW5nTWV0YWRhdGEoe1t6dF06ITB9KTtjb25zdCBlPXQoKTtyZXR1cm4gbi5zZXRTREtQcm9jZXNzaW5nTWV0YWRhdGEoe1t6dF06dm9pZCAwfSksZX0pfWZ1bmN0aW9uIEd0KHQsbil7Y29uc3R7ZmluZ2VycHJpbnQ6ZSxzcGFuOnIsYnJlYWRjcnVtYnM6byxzZGtQcm9jZXNzaW5nTWV0YWRhdGE6aX09bjshZnVuY3Rpb24odCxuKXtjb25zdHtleHRyYTplLHRhZ3M6cix1c2VyOm8sY29udGV4dHM6aSxsZXZlbDpzLHRyYW5zYWN0aW9uTmFtZTpjfT1uO09iamVjdC5rZXlzKGUpLmxlbmd0aCYmKHQuZXh0cmE9ey4uLmUsLi4udC5leHRyYX0pO09iamVjdC5rZXlzKHIpLmxlbmd0aCYmKHQudGFncz17Li4uciwuLi50LnRhZ3N9KTtPYmplY3Qua2V5cyhvKS5sZW5ndGgmJih0LnVzZXI9ey4uLm8sLi4udC51c2VyfSk7T2JqZWN0LmtleXMoaSkubGVuZ3RoJiYodC5jb250ZXh0cz17Li4uaSwuLi50LmNvbnRleHRzfSk7cyYmKHQubGV2ZWw9cyk7YyYmInRyYW5zYWN0aW9uIiE9PXQudHlwZSYmKHQudHJhbnNhY3Rpb249Yyl9KHQsbiksciYmZnVuY3Rpb24odCxuKXt0LmNvbnRleHRzPXt0cmFjZTpfdChuKSwuLi50LmNvbnRleHRzfSx0LnNka1Byb2Nlc3NpbmdNZXRhZGF0YT17ZHluYW1pY1NhbXBsaW5nQ29udGV4dDpPdChuKSwuLi50LnNka1Byb2Nlc3NpbmdNZXRhZGF0YX07Y29uc3QgZT1DdChuKSxyPUV0KGUpLmRlc2NyaXB0aW9uO3ImJiF0LnRyYW5zYWN0aW9uJiYidHJhbnNhY3Rpb24iPT09dC50eXBlJiYodC50cmFuc2FjdGlvbj1yKX0odCxyKSxmdW5jdGlvbih0LG4pe3QuZmluZ2VycHJpbnQ9dC5maW5nZXJwcmludD9BcnJheS5pc0FycmF5KHQuZmluZ2VycHJpbnQpP3QuZmluZ2VycHJpbnQ6W3QuZmluZ2VycHJpbnRdOltdLG4mJih0LmZpbmdlcnByaW50PXQuZmluZ2VycHJpbnQuY29uY2F0KG4pKTt0LmZpbmdlcnByaW50Lmxlbmd0aHx8ZGVsZXRlIHQuZmluZ2VycHJpbnR9KHQsZSksZnVuY3Rpb24odCxuKXtjb25zdCBlPVsuLi50LmJyZWFkY3J1bWJzfHxbXSwuLi5uXTt0LmJyZWFkY3J1bWJzPWUubGVuZ3RoP2U6dm9pZCAwfSh0LG8pLGZ1bmN0aW9uKHQsbil7dC5zZGtQcm9jZXNzaW5nTWV0YWRhdGE9ey4uLnQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhLC4uLm59fSh0LGkpfWNsYXNzIEp0e2NvbnN0cnVjdG9yKHQpe3RoaXMuTD0wLHRoaXMuTT1bXSx0aGlzLkYodCl9dGhlbih0LG4pe3JldHVybiBuZXcgSnQoKGUscik9Pnt0aGlzLk0ucHVzaChbITEsbj0+e2lmKHQpdHJ5e2UodChuKSl9Y2F0Y2godCl7cih0KX1lbHNlIGUobil9LHQ9PntpZihuKXRyeXtlKG4odCkpfWNhdGNoKHQpe3IodCl9ZWxzZSByKHQpfV0pLHRoaXMuRygpfSl9Y2F0Y2godCl7cmV0dXJuIHRoaXMudGhlbih0PT50LHQpfWZpbmFsbHkodCl7cmV0dXJuIG5ldyBKdCgobixlKT0+e2xldCByLG87cmV0dXJuIHRoaXMudGhlbihuPT57bz0hMSxyPW4sdCYmdCgpfSxuPT57bz0hMCxyPW4sdCYmdCgpfSkudGhlbigoKT0+e28/ZShyKTpuKHIpfSl9KX1HKCl7aWYoMD09PXRoaXMuTClyZXR1cm47Y29uc3QgdD10aGlzLk0uc2xpY2UoKTt0aGlzLk09W10sdC5mb3JFYWNoKHQ9Pnt0WzBdfHwoMT09PXRoaXMuTCYmdFsxXSh0aGlzLkopLDI9PT10aGlzLkwmJnRbMl0odGhpcy5KKSx0WzBdPSEwKX0pfUYodCl7Y29uc3Qgbj0odCxuKT0+ezA9PT10aGlzLkwmJihqKG4pP24udGhlbihlLHIpOih0aGlzLkw9dCx0aGlzLko9bix0aGlzLkcoKSkpfSxlPXQ9PntuKDEsdCl9LHI9dD0+e24oMix0KX07dHJ5e3QoZSxyKX1jYXRjaCh0KXtyKHQpfX19Y29uc3QgV3Q9U3ltYm9sLmZvcigiU2VudHJ5QnVmZmVyRnVsbEVycm9yIik7ZnVuY3Rpb24gWXQodD0xMDApe2NvbnN0IG49bmV3IFNldDtmdW5jdGlvbiBlKHQpe24uZGVsZXRlKHQpfXJldHVybntnZXQgJCgpe3JldHVybiBBcnJheS5mcm9tKG4pfSxhZGQ6ZnVuY3Rpb24ocil7aWYoIShuLnNpemU8dCkpcmV0dXJuIG89V3QsbmV3IEp0KCh0LG4pPT57bihvKX0pO3ZhciBvO2NvbnN0IGk9cigpO3JldHVybiBuLmFkZChpKSxpLnRoZW4oKCk9PmUoaSksKCk9PmUoaSkpLGl9LGRyYWluOmZ1bmN0aW9uKHQpe2lmKCFuLnNpemUpcmV0dXJuIGU9ITAsbmV3IEp0KHQ9Pnt0KGUpfSk7dmFyIGU7Y29uc3Qgcj1Qcm9taXNlLmFsbFNldHRsZWQoQXJyYXkuZnJvbShuKSkudGhlbigoKT0+ITApO2lmKCF0KXJldHVybiByO2NvbnN0IG89W3IsbmV3IFByb21pc2Uobj0+e3JldHVybiJvYmplY3QiPT10eXBlb2YoZT1zZXRUaW1lb3V0KCgpPT5uKCExKSx0KSkmJiJmdW5jdGlvbiI9PXR5cGVvZiBlLnVucmVmJiZlLnVucmVmKCksZTt2YXIgZX0pXTtyZXR1cm4gUHJvbWlzZS5yYWNlKG8pfX19ZnVuY3Rpb24gSHQodCx7c3RhdHVzQ29kZTpuLGhlYWRlcnM6ZX0scj1QKCkpe2NvbnN0IG89ey4uLnR9LGk9ZT8uWyJ4LXNlbnRyeS1yYXRlLWxpbWl0cyJdLHM9ZT8uWyJyZXRyeS1hZnRlciJdO2lmKGkpZm9yKGNvbnN0IHQgb2YgaS50cmltKCkuc3BsaXQoIiwiKSl7Y29uc3RbbixlLCwsaV09dC5zcGxpdCgiOiIsNSkscz1wYXJzZUludChuLDEwKSxjPTFlMyooaXNOYU4ocyk/NjA6cyk7aWYoZSlmb3IoY29uc3QgdCBvZiBlLnNwbGl0KCI7IikpIm1ldHJpY19idWNrZXQiPT09dCYmaSYmIWkuc3BsaXQoIjsiKS5pbmNsdWRlcygiY3VzdG9tIil8fChvW3RdPXIrYyk7ZWxzZSBvLmFsbD1yK2N9ZWxzZSBzP28uYWxsPXIrZnVuY3Rpb24odCxuPVAoKSl7Y29uc3QgZT1wYXJzZUludChgJHt0fWAsMTApO2lmKCFpc05hTihlKSlyZXR1cm4gMWUzKmU7Y29uc3Qgcj1EYXRlLnBhcnNlKGAke3R9YCk7cmV0dXJuIGlzTmFOKHIpPzZlNDpyLW59KHMscik6NDI5PT09biYmKG8uYWxsPXIrNmU0KTtyZXR1cm4gb31mdW5jdGlvbiBLdCh0LG4sZT1ZdCh0LmJ1ZmZlclNpemV8fDY0KSl7bGV0IHI9e307cmV0dXJue3NlbmQ6ZnVuY3Rpb24odCl7Y29uc3Qgbz1bXTtpZihrdCh0LCh0LG4pPT57Y29uc3QgZT1CdChuKTsoZnVuY3Rpb24odCxuLGU9UCgpKXtyZXR1cm4gZnVuY3Rpb24odCxuKXtyZXR1cm4gdFtuXXx8dC5hbGx8fDB9KHQsbik+ZX0pKHIsZSl8fG8ucHVzaCh0KX0pLDA9PT1vLmxlbmd0aClyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtjb25zdCBpPVR0KHRbMF0sbykscz10PT57IWZ1bmN0aW9uKHQsbil7cmV0dXJuIGt0KHQsKHQsZSk9Pm4uaW5jbHVkZXMoZSkpfShpLFsiY2xpZW50X3JlcG9ydCJdKT9rdChpLCh0LG4pPT57fSk6aCYmdy53YXJuKGBEcm9wcGluZyBjbGllbnQgcmVwb3J0LiBXaWxsIG5vdCBzZW5kIG91dGNvbWVzIChyZWFzb246ICR7dH0pLmApfTtyZXR1cm4gZS5hZGQoKCk9Pm4oe2JvZHk6RHQoaSl9KS50aGVuKHQ9PjQxMz09PXQuc3RhdHVzQ29kZT8oaCYmdy5lcnJvcigiU2VudHJ5IHJlc3BvbmRlZCB3aXRoIHN0YXR1cyBjb2RlIDQxMy4gRW52ZWxvcGUgd2FzIGRpc2NhcmRlZCBkdWUgdG8gZXhjZWVkaW5nIHNpemUgbGltaXRzLiIpLHMoInNlbmRfZXJyb3IiKSx0KTooaCYmdm9pZCAwIT09dC5zdGF0dXNDb2RlJiYodC5zdGF0dXNDb2RlPDIwMHx8dC5zdGF0dXNDb2RlPj0zMDApJiZ3Lndhcm4oYFNlbnRyeSByZXNwb25kZWQgd2l0aCBzdGF0dXMgY29kZSAke3Quc3RhdHVzQ29kZX0gdG8gc2VudCBldmVudC5gKSxyPUh0KHIsdCksdCksdD0+e3Rocm93IHMoIm5ldHdvcmtfZXJyb3IiKSxoJiZ3LmVycm9yKCJFbmNvdW50ZXJlZCBlcnJvciBydW5uaW5nIHRyYW5zcG9ydCByZXF1ZXN0OiIsdCksdH0pKS50aGVuKHQ9PnQsdD0+e2lmKHQ9PT1XdClyZXR1cm4gaCYmdy5lcnJvcigiU2tpcHBlZCBzZW5kaW5nIGV2ZW50IGJlY2F1c2UgYnVmZmVyIGlzIGZ1bGwuIikscygicXVldWVfb3ZlcmZsb3ciKSxQcm9taXNlLnJlc29sdmUoe30pO3Rocm93IHR9KX0sZmx1c2g6dD0+ZS5kcmFpbih0KX19Y29uc3QgWnQ9L14oXFMrOlxcfFwvPykoW1xzXFNdKj8pKCg/OlwuezEsMn18W14vXFxdKz98KShcLlteLi9cXF0qfCkpKD86Wy9cXF0qKSQvO2Z1bmN0aW9uIHF0KHQpe2NvbnN0IG49ZnVuY3Rpb24odCl7Y29uc3Qgbj10Lmxlbmd0aD4xMDI0P2A8dHJ1bmNhdGVkPiR7dC5zbGljZSgtMTAyNCl9YDp0LGU9WnQuZXhlYyhuKTtyZXR1cm4gZT9lLnNsaWNlKDEpOltdfSh0KSxlPW5bMF18fCIiO2xldCByPW5bMV07cmV0dXJuIGV8fHI/KHImJihyPXIuc2xpY2UoMCxyLmxlbmd0aC0xKSksZStyKToiLiJ9ZnVuY3Rpb24gVnQodCxuPSExKXtyZXR1cm4hKG58fHQmJiF0LnN0YXJ0c1dpdGgoIi8iKSYmIXQubWF0Y2goL15bQS1aXTovKSYmIXQuc3RhcnRzV2l0aCgiLiIpJiYhdC5tYXRjaCgvXlthLXpBLVpdKFthLXpBLVowLTkuXC0rXSkqOlwvXC8vKSkmJnZvaWQgMCE9PXQmJiF0LmluY2x1ZGVzKCJub2RlX21vZHVsZXMvIil9dmFyIFF0O2NvbnN0IFh0PVN5bWJvbCgiQWdlbnRCYXNlSW50ZXJuYWxTdGF0ZSIpO2NsYXNzIHRuIGV4dGVuZHMoUXQ9aS5BZ2VudCxRdCl7Y29uc3RydWN0b3IodCl7c3VwZXIodCksdGhpc1tYdF09e319aXNTZWN1cmVFbmRwb2ludCh0KXtpZih0KXtpZigiYm9vbGVhbiI9PXR5cGVvZiB0LnNlY3VyZUVuZHBvaW50KXJldHVybiB0LnNlY3VyZUVuZHBvaW50O2lmKCJzdHJpbmciPT10eXBlb2YgdC5wcm90b2NvbClyZXR1cm4iaHR0cHM6Ij09PXQucHJvdG9jb2x9Y29uc3R7c3RhY2s6bn09bmV3IEVycm9yO3JldHVybiJzdHJpbmciPT10eXBlb2YgbiYmbi5zcGxpdCgiXG4iKS5zb21lKHQ9Pi0xIT09dC5pbmRleE9mKCIoaHR0cHMuanM6Iil8fC0xIT09dC5pbmRleE9mKCJub2RlOmh0dHBzOiIpKX1jcmVhdGVTb2NrZXQodCxuLGUpe2NvbnN0IHI9ey4uLm4sc2VjdXJlRW5kcG9pbnQ6dGhpcy5pc1NlY3VyZUVuZHBvaW50KG4pfTtQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpPT50aGlzLmNvbm5lY3QodCxyKSkudGhlbihvPT57aWYobyBpbnN0YW5jZW9mIGkuQWdlbnQpcmV0dXJuIG8uYWRkUmVxdWVzdCh0LHIpO3RoaXNbWHRdLmN1cnJlbnRTb2NrZXQ9byxzdXBlci5jcmVhdGVTb2NrZXQodCxuLGUpfSxlKX1jcmVhdGVDb25uZWN0aW9uKCl7Y29uc3QgdD10aGlzW1h0XS5jdXJyZW50U29ja2V0O2lmKHRoaXNbWHRdLmN1cnJlbnRTb2NrZXQ9dm9pZCAwLCF0KXRocm93IG5ldyBFcnJvcigiTm8gc29ja2V0IHdhcyByZXR1cm5lZCBpbiB0aGUgYGNvbm5lY3QoKWAgZnVuY3Rpb24iKTtyZXR1cm4gdH1nZXQgZGVmYXVsdFBvcnQoKXtyZXR1cm4gdGhpc1tYdF0uZGVmYXVsdFBvcnQ/PygiaHR0cHM6Ij09PXRoaXMucHJvdG9jb2w/NDQzOjgwKX1zZXQgZGVmYXVsdFBvcnQodCl7dGhpc1tYdF0mJih0aGlzW1h0XS5kZWZhdWx0UG9ydD10KX1nZXQgcHJvdG9jb2woKXtyZXR1cm4gdGhpc1tYdF0ucHJvdG9jb2w/Pyh0aGlzLmlzU2VjdXJlRW5kcG9pbnQoKT8iaHR0cHM6IjoiaHR0cDoiKX1zZXQgcHJvdG9jb2wodCl7dGhpc1tYdF0mJih0aGlzW1h0XS5wcm90b2NvbD10KX19ZnVuY3Rpb24gbm4oLi4udCl7dy5sb2coIltodHRwcy1wcm94eS1hZ2VudDpwYXJzZS1wcm94eS1yZXNwb25zZV0iLC4uLnQpfWZ1bmN0aW9uIGVuKHQpe3JldHVybiBuZXcgUHJvbWlzZSgobixlKT0+e2xldCByPTA7Y29uc3Qgbz1bXTtmdW5jdGlvbiBpKCl7Y29uc3QgYz10LnJlYWQoKTtjP2Z1bmN0aW9uKGMpe28ucHVzaChjKSxyKz1jLmxlbmd0aDtjb25zdCB1PUJ1ZmZlci5jb25jYXQobyxyKSxhPXUuaW5kZXhPZigiXHJcblxyXG4iKTtpZigtMT09PWEpcmV0dXJuIG5uKCJoYXZlIG5vdCByZWNlaXZlZCBlbmQgb2YgSFRUUCBoZWFkZXJzIHlldC4uLiIpLHZvaWQgaSgpO2NvbnN0IGY9dS5zdWJhcnJheSgwLGEpLnRvU3RyaW5nKCJhc2NpaSIpLnNwbGl0KCJcclxuIiksaD1mLnNoaWZ0KCk7aWYoIWgpcmV0dXJuIHQuZGVzdHJveSgpLGUobmV3IEVycm9yKCJObyBoZWFkZXIgcmVjZWl2ZWQgZnJvbSBwcm94eSBDT05ORUNUIHJlc3BvbnNlIikpO2NvbnN0IHA9aC5zcGxpdCgiICIpLGQ9KyhwWzFdfHwwKSxsPXAuc2xpY2UoMikuam9pbigiICIpLGc9e307Zm9yKGNvbnN0IG4gb2YgZil7aWYoIW4pY29udGludWU7Y29uc3Qgcj1uLmluZGV4T2YoIjoiKTtpZigtMT09PXIpcmV0dXJuIHQuZGVzdHJveSgpLGUobmV3IEVycm9yKGBJbnZhbGlkIGhlYWRlciBmcm9tIHByb3h5IENPTk5FQ1QgcmVzcG9uc2U6ICIke259ImApKTtjb25zdCBvPW4uc2xpY2UoMCxyKS50b0xvd2VyQ2FzZSgpLGk9bi5zbGljZShyKzEpLnRyaW1TdGFydCgpLHM9Z1tvXTsic3RyaW5nIj09dHlwZW9mIHM/Z1tvXT1bcyxpXTpBcnJheS5pc0FycmF5KHMpP3MucHVzaChpKTpnW29dPWl9bm4oImdvdCBwcm94eSBzZXJ2ZXIgcmVzcG9uc2U6ICVvICVvIixoLGcpLHMoKSxuKHtjb25uZWN0OntzdGF0dXNDb2RlOmQsc3RhdHVzVGV4dDpsLGhlYWRlcnM6Z30sYnVmZmVyZWQ6dX0pfShjKTp0Lm9uY2UoInJlYWRhYmxlIixpKX1mdW5jdGlvbiBzKCl7dC5yZW1vdmVMaXN0ZW5lcigiZW5kIixjKSx0LnJlbW92ZUxpc3RlbmVyKCJlcnJvciIsdSksdC5yZW1vdmVMaXN0ZW5lcigicmVhZGFibGUiLGkpfWZ1bmN0aW9uIGMoKXtzKCksbm4oIm9uZW5kIiksZShuZXcgRXJyb3IoIlByb3h5IGNvbm5lY3Rpb24gZW5kZWQgYmVmb3JlIHJlY2VpdmluZyBDT05ORUNUIHJlc3BvbnNlIikpfWZ1bmN0aW9uIHUodCl7cygpLG5uKCJvbmVycm9yICVvIix0KSxlKHQpfXQub24oImVycm9yIix1KSx0Lm9uKCJlbmQiLGMpLGkoKX0pfWZ1bmN0aW9uIHJuKC4uLnQpe3cubG9nKCJbaHR0cHMtcHJveHktYWdlbnRdIiwuLi50KX1jbGFzcyBvbiBleHRlbmRzIHRue2NvbnN0cnVjdG9yKHQsbil7c3VwZXIobiksdGhpcy5vcHRpb25zPXt9LHRoaXMucHJveHk9InN0cmluZyI9PXR5cGVvZiB0P25ldyBVUkwodCk6dCx0aGlzLnByb3h5SGVhZGVycz1uPy5oZWFkZXJzPz97fSxybigiQ3JlYXRpbmcgbmV3IEh0dHBzUHJveHlBZ2VudCBpbnN0YW5jZTogJW8iLHRoaXMucHJveHkuaHJlZik7Y29uc3QgZT0odGhpcy5wcm94eS5ob3N0bmFtZXx8dGhpcy5wcm94eS5ob3N0KS5yZXBsYWNlKC9eXFt8XF0kL2csIiIpLHI9dGhpcy5wcm94eS5wb3J0P3BhcnNlSW50KHRoaXMucHJveHkucG9ydCwxMCk6Imh0dHBzOiI9PT10aGlzLnByb3h5LnByb3RvY29sPzQ0Mzo4MDt0aGlzLmNvbm5lY3RPcHRzPXtBTFBOUHJvdG9jb2xzOlsiaHR0cC8xLjEiXSwuLi5uP2NuKG4sImhlYWRlcnMiKTpudWxsLGhvc3Q6ZSxwb3J0OnJ9fWFzeW5jIGNvbm5lY3QodCxuKXtjb25zdHtwcm94eTplfT10aGlzO2lmKCFuLmhvc3QpdGhyb3cgbmV3IFR5cGVFcnJvcignTm8gImhvc3QiIHByb3ZpZGVkJyk7bGV0IHI7aWYoImh0dHBzOiI9PT1lLnByb3RvY29sKXtybigiQ3JlYXRpbmcgYHRscy5Tb2NrZXRgOiAlbyIsdGhpcy5jb25uZWN0T3B0cyk7Y29uc3QgdD10aGlzLmNvbm5lY3RPcHRzLnNlcnZlcm5hbWV8fHRoaXMuY29ubmVjdE9wdHMuaG9zdDtyPWYuY29ubmVjdCh7Li4udGhpcy5jb25uZWN0T3B0cyxzZXJ2ZXJuYW1lOnQmJmEuaXNJUCh0KT92b2lkIDA6dH0pfWVsc2Ugcm4oIkNyZWF0aW5nIGBuZXQuU29ja2V0YDogJW8iLHRoaXMuY29ubmVjdE9wdHMpLHI9YS5jb25uZWN0KHRoaXMuY29ubmVjdE9wdHMpO2NvbnN0IG89ImZ1bmN0aW9uIj09dHlwZW9mIHRoaXMucHJveHlIZWFkZXJzP3RoaXMucHJveHlIZWFkZXJzKCk6ey4uLnRoaXMucHJveHlIZWFkZXJzfSxpPWEuaXNJUHY2KG4uaG9zdCk/YFske24uaG9zdH1dYDpuLmhvc3Q7bGV0IHM9YENPTk5FQ1QgJHtpfToke24ucG9ydH0gSFRUUC8xLjFcclxuYDtpZihlLnVzZXJuYW1lfHxlLnBhc3N3b3JkKXtjb25zdCB0PWAke2RlY29kZVVSSUNvbXBvbmVudChlLnVzZXJuYW1lKX06JHtkZWNvZGVVUklDb21wb25lbnQoZS5wYXNzd29yZCl9YDtvWyJQcm94eS1BdXRob3JpemF0aW9uIl09YEJhc2ljICR7QnVmZmVyLmZyb20odCkudG9TdHJpbmcoImJhc2U2NCIpfWB9by5Ib3N0PWAke2l9OiR7bi5wb3J0fWAsb1siUHJveHktQ29ubmVjdGlvbiJdfHwob1siUHJveHktQ29ubmVjdGlvbiJdPXRoaXMua2VlcEFsaXZlPyJLZWVwLUFsaXZlIjoiY2xvc2UiKTtmb3IoY29uc3QgdCBvZiBPYmplY3Qua2V5cyhvKSlzKz1gJHt0fTogJHtvW3RdfVxyXG5gO2NvbnN0IGM9ZW4ocik7ci53cml0ZShgJHtzfVxyXG5gKTtjb25zdHtjb25uZWN0OnUsYnVmZmVyZWQ6aH09YXdhaXQgYztpZih0LmVtaXQoInByb3h5Q29ubmVjdCIsdSksdGhpcy5lbWl0KCJwcm94eUNvbm5lY3QiLHUsdCksMjAwPT09dS5zdGF0dXNDb2RlKXtpZih0Lm9uY2UoInNvY2tldCIsc24pLG4uc2VjdXJlRW5kcG9pbnQpe3JuKCJVcGdyYWRpbmcgc29ja2V0IGNvbm5lY3Rpb24gdG8gVExTIik7Y29uc3QgdD1uLnNlcnZlcm5hbWV8fG4uaG9zdDtyZXR1cm4gZi5jb25uZWN0KHsuLi5jbihuLCJob3N0IiwicGF0aCIsInBvcnQiKSxzb2NrZXQ6cixzZXJ2ZXJuYW1lOmEuaXNJUCh0KT92b2lkIDA6dH0pfXJldHVybiByfXIuZGVzdHJveSgpO2NvbnN0IHA9bmV3IGEuU29ja2V0KHt3cml0YWJsZTohMX0pO3JldHVybiBwLnJlYWRhYmxlPSEwLHQub25jZSgic29ja2V0Iix0PT57cm4oIlJlcGxheWluZyBwcm94eSBidWZmZXIgZm9yIGZhaWxlZCByZXF1ZXN0IiksdC5wdXNoKGgpLHQucHVzaChudWxsKX0pLHB9fWZ1bmN0aW9uIHNuKHQpe3QucmVzdW1lKCl9ZnVuY3Rpb24gY24odCwuLi5uKXtjb25zdCBlPXt9O2xldCByO2ZvcihyIGluIHQpbi5pbmNsdWRlcyhyKXx8KGVbcl09dFtyXSk7cmV0dXJuIGV9b24ucHJvdG9jb2xzPVsiaHR0cCIsImh0dHBzIl07ZnVuY3Rpb24gdW4odCl7cmV0dXJuIHQucmVwbGFjZSgvXltBLVpdOi8sIiIpLnJlcGxhY2UoL1xcL2csIi8iKX1jb25zdCBhbj1uO2xldCBmbixobj0wLHBuPXt9O2Z1bmN0aW9uIGRuKHQpe2FuLmRlYnVnJiZjb25zb2xlLmxvZyhgW0FOUiBXb3JrZXJdICR7dH1gKX12YXIgbG4sZ24sbW47Y29uc3QgeW49ZnVuY3Rpb24odCl7bGV0IG47dHJ5e249bmV3IFVSTCh0LnVybCl9Y2F0Y2gobil7cmV0dXJuIGIoKCk9Pntjb25zb2xlLndhcm4oIltAc2VudHJ5L25vZGVdOiBJbnZhbGlkIGRzbiBvciB0dW5uZWwgb3B0aW9uLCB3aWxsIG5vdCBzZW5kIGFueSBldmVudHMuIFRoZSB0dW5uZWwgb3B0aW9uIG11c3QgYmUgYSBmdWxsIFVSTCB3aGVuIHVzZWQuIil9KSxLdCh0LCgpPT5Qcm9taXNlLnJlc29sdmUoe30pKX1jb25zdCBlPSJodHRwczoiPT09bi5wcm90b2NvbCxyPWZ1bmN0aW9uKHQsbil7Y29uc3R7bm9fcHJveHk6ZX09cHJvY2Vzcy5lbnYscj1lPy5zcGxpdCgiLCIpLnNvbWUobj0+dC5ob3N0LmVuZHNXaXRoKG4pfHx0Lmhvc3RuYW1lLmVuZHNXaXRoKG4pKTtyZXR1cm4gcj92b2lkIDA6bn0obix0LnByb3h5fHwoZT9wcm9jZXNzLmVudi5odHRwc19wcm94eTp2b2lkIDApfHxwcm9jZXNzLmVudi5odHRwX3Byb3h5KSxvPWU/czppLGE9dm9pZCAwIT09dC5rZWVwQWxpdmUmJnQua2VlcEFsaXZlLGY9cj9uZXcgb24ocik6bmV3IG8uQWdlbnQoe2tlZXBBbGl2ZTphLG1heFNvY2tldHM6MzAsdGltZW91dDoyZTN9KSxoPWZ1bmN0aW9uKHQsbixlKXtjb25zdHtob3N0bmFtZTpyLHBhdGhuYW1lOm8scG9ydDppLHByb3RvY29sOnMsc2VhcmNoOmF9PW5ldyBVUkwodC51cmwpO3JldHVybiBmdW5jdGlvbihmKXtyZXR1cm4gbmV3IFByb21pc2UoKGgscCk9PntGdCgoKT0+e2xldCBkPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgYyh7cmVhZCgpe3RoaXMucHVzaCh0KSx0aGlzLnB1c2gobnVsbCl9fSl9KGYuYm9keSk7Y29uc3QgbD17Li4udC5oZWFkZXJzfTtmLmJvZHkubGVuZ3RoPjMyNzY4JiYobFsiY29udGVudC1lbmNvZGluZyJdPSJnemlwIixkPWQucGlwZSh1KCkpKTtjb25zdCBnPXIuc3RhcnRzV2l0aCgiWyIpLG09bi5yZXF1ZXN0KHttZXRob2Q6IlBPU1QiLGFnZW50OmUsaGVhZGVyczpsLGhvc3RuYW1lOmc/ci5zbGljZSgxLC0xKTpyLHBhdGg6YCR7b30ke2F9YCxwb3J0OmkscHJvdG9jb2w6cyxjYTp0LmNhQ2VydHN9LHQ9Pnt0Lm9uKCJkYXRhIiwoKT0+e30pLHQub24oImVuZCIsKCk9Pnt9KSx0LnNldEVuY29kaW5nKCJ1dGY4Iik7Y29uc3Qgbj10LmhlYWRlcnNbInJldHJ5LWFmdGVyIl0/P251bGwsZT10LmhlYWRlcnNbIngtc2VudHJ5LXJhdGUtbGltaXRzIl0/P251bGw7aCh7c3RhdHVzQ29kZTp0LnN0YXR1c0NvZGUsaGVhZGVyczp7InJldHJ5LWFmdGVyIjpuLCJ4LXNlbnRyeS1yYXRlLWxpbWl0cyI6QXJyYXkuaXNBcnJheShlKT9lWzBdfHxudWxsOmV9fSl9KTttLm9uKCJlcnJvciIscCksZC5waXBlKG0pfSl9KX19KHQsdC5odHRwTW9kdWxlPz9vLGYpO3JldHVybiBLdCh0LGgpfSh7dXJsOihsbj1hbi5kc24sZ249YW4udHVubmVsLG1uPWFuLnNka01ldGFkYXRhLnNkayxnbnx8YCR7ZnVuY3Rpb24odCl7cmV0dXJuYCR7ZnVuY3Rpb24odCl7Y29uc3Qgbj10LnByb3RvY29sP2Ake3QucHJvdG9jb2x9OmA6IiIsZT10LnBvcnQ/YDoke3QucG9ydH1gOiIiO3JldHVybmAke259Ly8ke3QuaG9zdH0ke2V9JHt0LnBhdGg/YC8ke3QucGF0aH1gOiIifS9hcGkvYH0odCl9JHt0LnByb2plY3RJZH0vZW52ZWxvcGUvYH0obG4pfT8ke2Z1bmN0aW9uKHQsbil7Y29uc3QgZT17c2VudHJ5X3ZlcnNpb246IjcifTtyZXR1cm4gdC5wdWJsaWNLZXkmJihlLnNlbnRyeV9rZXk9dC5wdWJsaWNLZXkpLG4mJihlLnNlbnRyeV9jbGllbnQ9YCR7bi5uYW1lfS8ke24udmVyc2lvbn1gKSxuZXcgVVJMU2VhcmNoUGFyYW1zKGUpLnRvU3RyaW5nKCl9KGxuLG1uKX1gKX0pO2FzeW5jIGZ1bmN0aW9uIGJuKCl7aWYoZm4pe2RuKCJTZW5kaW5nIGFibm9ybWFsIHNlc3Npb24iKSxLKGZuLHtzdGF0dXM6ImFibm9ybWFsIixhYm5vcm1hbF9tZWNoYW5pc206ImFucl9mb3JlZ3JvdW5kIixyZWxlYXNlOmFuLnJlbGVhc2UsZW52aXJvbm1lbnQ6YW4uZW52aXJvbm1lbnR9KTtjb25zdCB0PWZ1bmN0aW9uKHQsbixlLHIpe2NvbnN0IG89THQoZSk7cmV0dXJuIFR0KHtzZW50X2F0Om5ldyBEYXRlKFAoKSkudG9JU09TdHJpbmcoKSwuLi5vJiZ7c2RrOm99LC4uLiEhciYmbiYme2RzbjpidChuKX19LFsiYWdncmVnYXRlcyJpbiB0P1t7dHlwZToic2Vzc2lvbnMifSx0XTpbe3R5cGU6InNlc3Npb24ifSx0LnRvSlNPTigpXV0pfShmbixhbi5kc24sYW4uc2RrTWV0YWRhdGEsYW4udHVubmVsKTtkbihKU09OLnN0cmluZ2lmeSh0KSksYXdhaXQgeW4uc2VuZCh0KTt0cnl7ZT8ucG9zdE1lc3NhZ2UoInNlc3Npb24tZW5kZWQiKX1jYXRjaHt9fX1mdW5jdGlvbiB2bih0KXtpZighdClyZXR1cm47Y29uc3Qgbj1mdW5jdGlvbih0KXtpZighdC5sZW5ndGgpcmV0dXJuW107Y29uc3Qgbj1BcnJheS5mcm9tKHQpO3JldHVybi9zZW50cnlXcmFwcGVkLy50ZXN0KEUobikuZnVuY3Rpb258fCIiKSYmbi5wb3AoKSxuLnJldmVyc2UoKSwkLnRlc3QoRShuKS5mdW5jdGlvbnx8IiIpJiYobi5wb3AoKSwkLnRlc3QoRShuKS5mdW5jdGlvbnx8IiIpJiZuLnBvcCgpKSxuLnNsaWNlKDAsNTApLm1hcCh0PT4oey4uLnQsZmlsZW5hbWU6dC5maWxlbmFtZXx8RShuKS5maWxlbmFtZSxmdW5jdGlvbjp0LmZ1bmN0aW9ufHwiPyJ9KSl9KHQpO2lmKGFuLmFwcFJvb3RQYXRoKWZvcihjb25zdCB0IG9mIG4pdC5maWxlbmFtZSYmKHQuZmlsZW5hbWU9TSh0LmZpbGVuYW1lLGFuLmFwcFJvb3RQYXRoKSk7cmV0dXJuIG59YXN5bmMgZnVuY3Rpb24gX24odCxuKXtpZihobj49YW4ubWF4QW5yRXZlbnRzKXJldHVybjtobis9MSxhd2FpdCBibigpLGRuKCJTZW5kaW5nIGV2ZW50Iik7Y29uc3QgZT17ZXZlbnRfaWQ6RygpLGNvbnRleHRzOmFuLmNvbnRleHRzLHJlbGVhc2U6YW4ucmVsZWFzZSxlbnZpcm9ubWVudDphbi5lbnZpcm9ubWVudCxkaXN0OmFuLmRpc3QscGxhdGZvcm06Im5vZGUiLGxldmVsOiJlcnJvciIsZXhjZXB0aW9uOnt2YWx1ZXM6W3t0eXBlOiJBcHBsaWNhdGlvbk5vdFJlc3BvbmRpbmciLHZhbHVlOmBBcHBsaWNhdGlvbiBOb3QgUmVzcG9uZGluZyBmb3IgYXQgbGVhc3QgJHthbi5hbnJUaHJlc2hvbGR9IG1zYCxzdGFja3RyYWNlOntmcmFtZXM6dm4odCl9LG1lY2hhbmlzbTp7dHlwZToiQU5SIn19XX0sdGFnczphbi5zdGF0aWNUYWdzfTtuJiZmdW5jdGlvbih0LG4pe2lmKEd0KHQsbiksIXQuY29udGV4dHM/LnRyYWNlKXtjb25zdHt0cmFjZUlkOmUscGFyZW50U3BhbklkOnIscHJvcGFnYXRpb25TcGFuSWQ6b309bi5wcm9wYWdhdGlvbkNvbnRleHQ7dC5jb250ZXh0cz17dHJhY2U6e3RyYWNlX2lkOmUsc3Bhbl9pZDpvfHxWKCkscGFyZW50X3NwYW5faWQ6cn0sLi4udC5jb250ZXh0c319fShlLG4pLGZ1bmN0aW9uKHQpe2lmKDA9PT1PYmplY3Qua2V5cyhwbikubGVuZ3RoKXJldHVybjtjb25zdCBuPWFuLmFwcFJvb3RQYXRoP3t9OnBuO2lmKGFuLmFwcFJvb3RQYXRoKWZvcihjb25zdFt0LGVdb2YgT2JqZWN0LmVudHJpZXMocG4pKW5bTSh0LGFuLmFwcFJvb3RQYXRoKV09ZTtjb25zdCBlPW5ldyBNYXA7Zm9yKGNvbnN0IHIgb2YgdC5leGNlcHRpb24/LnZhbHVlc3x8W10pZm9yKGNvbnN0IHQgb2Ygci5zdGFja3RyYWNlPy5mcmFtZXN8fFtdKXtjb25zdCByPXQuYWJzX3BhdGh8fHQuZmlsZW5hbWU7ciYmbltyXSYmZS5zZXQocixuW3JdKX1pZihlLnNpemU+MCl7Y29uc3Qgbj1bXTtmb3IoY29uc3RbdCxyXW9mIGUuZW50cmllcygpKW4ucHVzaCh7dHlwZToic291cmNlbWFwIixjb2RlX2ZpbGU6dCxkZWJ1Z19pZDpyfSk7dC5kZWJ1Z19tZXRhPXtpbWFnZXM6bn19fShlKTtjb25zdCByPU10KGUsYW4uZHNuLGFuLnNka01ldGFkYXRhLGFuLnR1bm5lbCk7ZG4oSlNPTi5zdHJpbmdpZnkocikpLGF3YWl0IHluLnNlbmQociksYXdhaXQgeW4uZmx1c2goMmUzKSxobj49YW4ubWF4QW5yRXZlbnRzJiZzZXRUaW1lb3V0KCgpPT57cHJvY2Vzcy5leGl0KDApfSw1ZTMpfWxldCBTbjtpZihkbigiU3RhcnRlZCIpLGFuLmNhcHR1cmVTdGFja1RyYWNlKXtkbigiQ29ubmVjdGluZyB0byBkZWJ1Z2dlciIpO2NvbnN0IG49bmV3IHQ7bi5jb25uZWN0VG9NYWluVGhyZWFkKCksZG4oIkNvbm5lY3RlZCB0byBkZWJ1Z2dlciIpO2NvbnN0IGU9bmV3IE1hcDtuLm9uKCJEZWJ1Z2dlci5zY3JpcHRQYXJzZWQiLHQ9PntlLnNldCh0LnBhcmFtcy5zY3JpcHRJZCx0LnBhcmFtcy51cmwpfSksbi5vbigiRGVidWdnZXIucGF1c2VkIix0PT57aWYoIm90aGVyIj09PXQucGFyYW1zLnJlYXNvbil0cnl7ZG4oIkRlYnVnZ2VyIHBhdXNlZCIpO2NvbnN0IGk9Wy4uLnQucGFyYW1zLmNhbGxGcmFtZXNdLHM9YW4uYXBwUm9vdFBhdGg/ZnVuY3Rpb24odD0ocHJvY2Vzcy5hcmd2WzFdP3F0KHByb2Nlc3MuYXJndlsxXSk6cHJvY2Vzcy5jd2QoKSksbj0iXFwiPT09byl7Y29uc3QgZT1uP3VuKHQpOnQ7cmV0dXJuIHQ9PntpZighdClyZXR1cm47Y29uc3Qgbz1uP3VuKHQpOnQ7bGV0e2RpcjppLGJhc2U6cyxleHQ6Y309ci5wYXJzZShvKTsiLmpzIiE9PWMmJiIubWpzIiE9PWMmJiIuY2pzIiE9PWN8fChzPXMuc2xpY2UoMCwtMSpjLmxlbmd0aCkpO2NvbnN0IHU9ZGVjb2RlVVJJQ29tcG9uZW50KHMpO2l8fChpPSIuIik7Y29uc3QgYT1pLmxhc3RJbmRleE9mKCIvbm9kZV9tb2R1bGVzIik7aWYoYT4tMSlyZXR1cm5gJHtpLnNsaWNlKGErMTQpLnJlcGxhY2UoL1wvL2csIi4iKX06JHt1fWA7aWYoaS5zdGFydHNXaXRoKGUpKXtjb25zdCB0PWkuc2xpY2UoZS5sZW5ndGgrMSkucmVwbGFjZSgvXC8vZywiLiIpO3JldHVybiB0P2Ake3R9OiR7dX1gOnV9cmV0dXJuIHV9fShhbi5hcHBSb290UGF0aCk6KCk9Pnt9LGM9aS5tYXAodD0+ZnVuY3Rpb24odCxuLGUpe2NvbnN0IHI9bj9uLnJlcGxhY2UoL15maWxlOlwvXC8vLCIiKTp2b2lkIDAsbz10LmxvY2F0aW9uLmNvbHVtbk51bWJlcj90LmxvY2F0aW9uLmNvbHVtbk51bWJlcisxOnZvaWQgMCxpPXQubG9jYXRpb24ubGluZU51bWJlcj90LmxvY2F0aW9uLmxpbmVOdW1iZXIrMTp2b2lkIDA7cmV0dXJue2ZpbGVuYW1lOnIsbW9kdWxlOmUociksZnVuY3Rpb246dC5mdW5jdGlvbk5hbWV8fCI/Iixjb2xubzpvLGxpbmVubzppLGluX2FwcDpyP1Z0KHIpOnZvaWQgMH19KHQsZS5nZXQodC5sb2NhdGlvbi5zY3JpcHRJZCkscykpLHU9c2V0VGltZW91dCgoKT0+e19uKGMpLnRoZW4obnVsbCwoKT0+e2RuKCJTZW5kaW5nIEFOUiBldmVudCBmYWlsZWQuIil9KX0sNWUzKTtuLnBvc3QoIlJ1bnRpbWUuZXZhbHVhdGUiLHtleHByZXNzaW9uOiJnbG9iYWwuX19TRU5UUllfR0VUX1NDT1BFU19fKCk7IixzaWxlbnQ6ITAscmV0dXJuQnlWYWx1ZTohMH0sKHQsZSk9Pnt0JiZkbihgRXJyb3IgZXhlY3V0aW5nIHNjcmlwdDogJyR7dC5tZXNzYWdlfSdgKSxjbGVhclRpbWVvdXQodSk7Y29uc3Qgcj1lPy5yZXN1bHQ/ZS5yZXN1bHQudmFsdWU6dm9pZCAwO24ucG9zdCgiRGVidWdnZXIucmVzdW1lIiksbi5wb3N0KCJEZWJ1Z2dlci5kaXNhYmxlIiksX24oYyxyKS50aGVuKG51bGwsKCk9PntkbigiU2VuZGluZyBBTlIgZXZlbnQgZmFpbGVkLiIpfSl9KX1jYXRjaCh0KXt0aHJvdyBuLnBvc3QoIkRlYnVnZ2VyLnJlc3VtZSIpLG4ucG9zdCgiRGVidWdnZXIuZGlzYWJsZSIpLHR9fSksU249KCk9Pnt0cnl7bi5wb3N0KCJEZWJ1Z2dlci5lbmFibGUiLCgpPT57bi5wb3N0KCJEZWJ1Z2dlci5wYXVzZSIpfSl9Y2F0Y2h7fX19Y29uc3R7cG9sbDp3bn09ZnVuY3Rpb24odCxuLGUscil7Y29uc3Qgbz10KCk7bGV0IGk9ITEscz0hMDtyZXR1cm4gc2V0SW50ZXJ2YWwoKCk9Pntjb25zdCB0PW8uZ2V0VGltZU1zKCk7ITE9PT1pJiZ0Pm4rZSYmKGk9ITAscyYmcigpKSx0PG4rZSYmKGk9ITEpfSwyMCkse3BvbGw6KCk9PntvLnJlc2V0KCl9LGVuYWJsZWQ6dD0+e3M9dH19fShmdW5jdGlvbigpe2xldCB0PXByb2Nlc3MuaHJ0aW1lKCk7cmV0dXJue2dldFRpbWVNczooKT0+e2NvbnN0W24sZV09cHJvY2Vzcy5ocnRpbWUodCk7cmV0dXJuIE1hdGguZmxvb3IoMWUzKm4rZS8xZTYpfSxyZXNldDooKT0+e3Q9cHJvY2Vzcy5ocnRpbWUoKX19fSxhbi5wb2xsSW50ZXJ2YWwsYW4uYW5yVGhyZXNob2xkLGZ1bmN0aW9uKCl7ZG4oIldhdGNoZG9nIHRpbWVvdXQiKSxTbj8oZG4oIlBhdXNpbmcgZGVidWdnZXIgdG8gY2FwdHVyZSBzdGFjayB0cmFjZSIpLFNuKCkpOihkbigiQ2FwdHVyaW5nIGV2ZW50IHdpdGhvdXQgYSBzdGFjayB0cmFjZSIpLF9uKCkudGhlbihudWxsLCgpPT57ZG4oIlNlbmRpbmcgQU5SIGV2ZW50IGZhaWxlZCBvbiB3YXRjaGRvZyB0aW1lb3V0LiIpfSkpfSk7ZT8ub24oIm1lc3NhZ2UiLHQ9Pnt0LnNlc3Npb24mJihmbj1IKHQuc2Vzc2lvbikpLHQuZGVidWdJbWFnZXMmJihwbj10LmRlYnVnSW1hZ2VzKSx3bigpfSk7";
const DEFAULT_INTERVAL = 50;

@@ -13,0 +13,0 @@ const DEFAULT_HANG_THRESHOLD = 5e3;

@@ -12,3 +12,3 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });

diagnosticsChannel.channel("child_process").subscribe((event) => {
if (event && typeof event === "object" && "process" in event) {
if (core.isObjectLike(event) && "process" in event) {
captureChildProcessEvents(event.process, options);

@@ -18,3 +18,3 @@ }

diagnosticsChannel.channel("worker_threads").subscribe((event) => {
if (event && typeof event === "object" && "worker" in event) {
if (core.isObjectLike(event) && "worker" in event) {
captureWorkerThreadEvents(event.worker, options);

@@ -21,0 +21,0 @@ }

@@ -1,1 +0,1 @@

{"version":3,"file":"childProcess.js","sources":["../../../src/integrations/childProcess.ts"],"sourcesContent":["import type { ChildProcess } from 'node:child_process';\nimport * as diagnosticsChannel from 'node:diagnostics_channel';\nimport type { Worker } from 'node:worker_threads';\nimport { addBreadcrumb, captureException, defineIntegration } from '@sentry/core';\n\ninterface Options {\n /**\n * Whether to include child process arguments in breadcrumbs data.\n *\n * @default false\n */\n includeChildProcessArgs?: boolean;\n\n /**\n * Whether to capture errors from worker threads.\n *\n * @default true\n */\n captureWorkerErrors?: boolean;\n}\n\nconst INTEGRATION_NAME = 'ChildProcess' as const;\n\n/**\n * Capture breadcrumbs and events for child processes and worker threads.\n */\nexport const childProcessIntegration = defineIntegration((options: Options = {}) => {\n return {\n name: INTEGRATION_NAME,\n setup() {\n diagnosticsChannel.channel('child_process').subscribe((event: unknown) => {\n if (event && typeof event === 'object' && 'process' in event) {\n captureChildProcessEvents(event.process as ChildProcess, options);\n }\n });\n\n diagnosticsChannel.channel('worker_threads').subscribe((event: unknown) => {\n if (event && typeof event === 'object' && 'worker' in event) {\n captureWorkerThreadEvents(event.worker as Worker, options);\n }\n });\n },\n };\n});\n\nfunction captureChildProcessEvents(child: ChildProcess, options: Options): void {\n let hasExited = false;\n let data: Record<string, unknown> | undefined;\n\n child\n .on('spawn', () => {\n // This is Sentry getting macOS OS context\n if (child.spawnfile === '/usr/bin/sw_vers') {\n hasExited = true;\n return;\n }\n\n data = { spawnfile: child.spawnfile };\n if (options.includeChildProcessArgs) {\n data.spawnargs = child.spawnargs;\n }\n })\n .on('exit', code => {\n if (!hasExited) {\n hasExited = true;\n\n // Only log for non-zero exit codes\n if (code !== null && code !== 0) {\n addBreadcrumb({\n category: 'child_process',\n message: `Child process exited with code '${code}'`,\n level: code === 0 ? 'info' : 'warning',\n data,\n });\n }\n }\n })\n .on('error', error => {\n if (!hasExited) {\n hasExited = true;\n\n addBreadcrumb({\n category: 'child_process',\n message: `Child process errored with '${error.message}'`,\n level: 'error',\n data,\n });\n }\n });\n}\n\nfunction captureWorkerThreadEvents(worker: Worker, options: Options): void {\n let threadId: number | undefined;\n\n worker\n .on('online', () => {\n threadId = worker.threadId;\n })\n .on('error', error => {\n if (options.captureWorkerErrors !== false) {\n captureException(error, {\n mechanism: { type: 'auto.child_process.worker_thread', handled: false, data: { threadId: String(threadId) } },\n });\n } else {\n addBreadcrumb({\n category: 'worker_thread',\n message: `Worker thread errored with '${error.message}'`,\n level: 'error',\n data: { threadId },\n });\n }\n });\n}\n"],"names":["defineIntegration","addBreadcrumb","captureException"],"mappings":"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"}
{"version":3,"file":"childProcess.js","sources":["../../../src/integrations/childProcess.ts"],"sourcesContent":["import type { ChildProcess } from 'node:child_process';\nimport * as diagnosticsChannel from 'node:diagnostics_channel';\nimport type { Worker } from 'node:worker_threads';\nimport { addBreadcrumb, captureException, defineIntegration, isObjectLike } from '@sentry/core';\n\ninterface Options {\n /**\n * Whether to include child process arguments in breadcrumbs data.\n *\n * @default false\n */\n includeChildProcessArgs?: boolean;\n\n /**\n * Whether to capture errors from worker threads.\n *\n * @default true\n */\n captureWorkerErrors?: boolean;\n}\n\nconst INTEGRATION_NAME = 'ChildProcess' as const;\n\n/**\n * Capture breadcrumbs and events for child processes and worker threads.\n */\nexport const childProcessIntegration = defineIntegration((options: Options = {}) => {\n return {\n name: INTEGRATION_NAME,\n setup() {\n diagnosticsChannel.channel('child_process').subscribe((event: unknown) => {\n if (isObjectLike(event) && 'process' in event) {\n captureChildProcessEvents(event.process as ChildProcess, options);\n }\n });\n\n diagnosticsChannel.channel('worker_threads').subscribe((event: unknown) => {\n if (isObjectLike(event) && 'worker' in event) {\n captureWorkerThreadEvents(event.worker as Worker, options);\n }\n });\n },\n };\n});\n\nfunction captureChildProcessEvents(child: ChildProcess, options: Options): void {\n let hasExited = false;\n let data: Record<string, unknown> | undefined;\n\n child\n .on('spawn', () => {\n // This is Sentry getting macOS OS context\n if (child.spawnfile === '/usr/bin/sw_vers') {\n hasExited = true;\n return;\n }\n\n data = { spawnfile: child.spawnfile };\n if (options.includeChildProcessArgs) {\n data.spawnargs = child.spawnargs;\n }\n })\n .on('exit', code => {\n if (!hasExited) {\n hasExited = true;\n\n // Only log for non-zero exit codes\n if (code !== null && code !== 0) {\n addBreadcrumb({\n category: 'child_process',\n message: `Child process exited with code '${code}'`,\n level: code === 0 ? 'info' : 'warning',\n data,\n });\n }\n }\n })\n .on('error', error => {\n if (!hasExited) {\n hasExited = true;\n\n addBreadcrumb({\n category: 'child_process',\n message: `Child process errored with '${error.message}'`,\n level: 'error',\n data,\n });\n }\n });\n}\n\nfunction captureWorkerThreadEvents(worker: Worker, options: Options): void {\n let threadId: number | undefined;\n\n worker\n .on('online', () => {\n threadId = worker.threadId;\n })\n .on('error', error => {\n if (options.captureWorkerErrors !== false) {\n captureException(error, {\n mechanism: { type: 'auto.child_process.worker_thread', handled: false, data: { threadId: String(threadId) } },\n });\n } else {\n addBreadcrumb({\n category: 'worker_thread',\n message: `Worker thread errored with '${error.message}'`,\n level: 'error',\n data: { threadId },\n });\n }\n });\n}\n"],"names":["defineIntegration","isObjectLike","addBreadcrumb","captureException"],"mappings":"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"}
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const core = require('@sentry/core');
const instrument = require('../../otel/instrument.js');
const httpServerIntegration = require('./httpServerIntegration.js');

@@ -10,9 +9,9 @@ const httpServerSpansIntegration = require('./httpServerSpansIntegration.js');

const INTEGRATION_NAME = "Http";
const instrumentSentryHttp = instrument.generateInstrumentOnce(
`${INTEGRATION_NAME}.sentry`,
(options) => {
return new SentryHttpInstrumentation.SentryHttpInstrumentation(options);
}
);
Object.assign(SentryHttpInstrumentation.instrumentHttpOutgoingRequests, {
id: `${INTEGRATION_NAME}.sentry`
});
const httpIntegration = core.defineIntegration((options = {}) => {
const spans = options.spans ?? false;
const disableIncomingRequestSpans = options.disableIncomingRequestSpans ?? false;
const enabledServerSpans = spans && !disableIncomingRequestSpans;
const serverOptions = {

@@ -32,9 +31,7 @@ sessions: options.trackIncomingRequestsAsSessions,

propagateTraceInOutgoingRequests: options.tracePropagation ?? true,
ignoreOutgoingRequests: options.ignoreOutgoingRequests
ignoreOutgoingRequests: options.ignoreOutgoingRequests,
spans
};
const server = httpServerIntegration.httpServerIntegration(serverOptions);
const serverSpans = httpServerSpansIntegration.httpServerSpansIntegration(serverSpansOptions);
const spans = options.spans ?? false;
const disableIncomingRequestSpans = options.disableIncomingRequestSpans ?? false;
const enabledServerSpans = spans && !disableIncomingRequestSpans;
return {

@@ -49,3 +46,3 @@ name: INTEGRATION_NAME,

server.setupOnce();
instrumentSentryHttp(httpInstrumentationOptions);
SentryHttpInstrumentation.instrumentHttpOutgoingRequests(httpInstrumentationOptions);
},

@@ -59,3 +56,2 @@ processEvent(event) {

exports.httpIntegration = httpIntegration;
exports.instrumentSentryHttp = instrumentSentryHttp;
//# sourceMappingURL=index.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"index.js","sources":["../../../../src/integrations/http/index.ts"],"sourcesContent":["import type { RequestOptions } from 'node:http';\nimport type { HttpIncomingMessage } from '@sentry/core';\nimport { defineIntegration } from '@sentry/core';\nimport { generateInstrumentOnce } from '../../otel/instrument';\nimport type { NodeClient } from '../../sdk/client';\nimport type { HttpServerIntegrationOptions } from './httpServerIntegration';\nimport { httpServerIntegration } from './httpServerIntegration';\nimport type { HttpServerSpansIntegrationOptions } from './httpServerSpansIntegration';\nimport { httpServerSpansIntegration } from './httpServerSpansIntegration';\nimport type { SentryHttpInstrumentationOptions } from './SentryHttpInstrumentation';\nimport { SentryHttpInstrumentation } from './SentryHttpInstrumentation';\n\nconst INTEGRATION_NAME = 'Http' as const;\n\ninterface HttpOptions {\n /**\n * Whether breadcrumbs should be recorded for outgoing requests.\n * Defaults to true\n */\n breadcrumbs?: boolean;\n\n /**\n * Whether to create spans for requests or not.\n * As of now, creates spans for incoming requests, but not outgoing requests.\n *\n * @default `true`\n */\n spans?: boolean;\n\n /**\n * Whether the integration should create [Sessions](https://docs.sentry.io/product/releases/health/#sessions) for incoming requests to track the health and crash-free rate of your releases in Sentry.\n * Read more about Release Health: https://docs.sentry.io/product/releases/health/\n *\n * Defaults to `true`.\n */\n trackIncomingRequestsAsSessions?: boolean;\n\n /**\n * Number of milliseconds until sessions tracked with `trackIncomingRequestsAsSessions` will be flushed as a session aggregate.\n *\n * Defaults to `60000` (60s).\n */\n sessionFlushingDelayMS?: number;\n\n /**\n * Whether to inject trace propagation headers (sentry-trace, baggage, traceparent) into outgoing HTTP requests.\n *\n * When set to `false`, Sentry will not inject any trace propagation headers, but will still create breadcrumbs\n * (if `breadcrumbs` is enabled).\n *\n * @default `true`\n */\n tracePropagation?: boolean;\n\n /**\n * Do not capture spans or breadcrumbs for outgoing HTTP requests to URLs where the given callback returns `true`.\n * This controls both span & breadcrumb creation - spans will be non recording if tracing is disabled.\n *\n * The `url` param contains the entire URL, including query string (if any), protocol, host, etc. of the outgoing request.\n * For example: `'https://someService.com/users/details?id=123'`\n *\n * The `request` param contains the original {@type RequestOptions} object used to make the outgoing request.\n * You can use it to filter on additional properties like method, headers, etc.\n */\n ignoreOutgoingRequests?: (url: string, request: RequestOptions) => boolean;\n\n /**\n * Do not capture spans for incoming HTTP requests to URLs where the given callback returns `true`.\n * Spans will be non recording if tracing is disabled.\n *\n * The `urlPath` param consists of the URL path and query string (if any) of the incoming request.\n * For example: `'/users/details?id=123'`\n *\n * The `request` param contains the original {@type IncomingMessage} object of the incoming request.\n * You can use it to filter on additional properties like method, headers, etc.\n */\n ignoreIncomingRequests?: (urlPath: string, request: HttpIncomingMessage) => boolean;\n\n /**\n * Do not capture spans for incoming HTTP requests with the given status codes.\n * By default, spans with some 3xx and 4xx status codes are ignored (see @default).\n * Expects an array of status codes or a range of status codes, e.g. [[300,399], 404] would ignore 3xx and 404 status codes.\n *\n * @default `[[401, 404], [301, 303], [305, 399]]`\n */\n dropSpansForIncomingRequestStatusCodes?: (number | [number, number])[];\n\n /**\n * Do not capture the request body for incoming HTTP requests to URLs where the given callback returns `true`.\n * This can be useful for long running requests where the body is not needed and we want to avoid capturing it.\n *\n * @param url Contains the entire URL, including query string (if any), protocol, host, etc. of the incoming request.\n * @param request Contains the {@type RequestOptions} object used to make the incoming request.\n */\n ignoreIncomingRequestBody?: (url: string, request: RequestOptions) => boolean;\n\n /**\n * Whether to automatically ignore common static asset requests like favicon.ico, robots.txt, etc.\n * This helps reduce noise in your transactions.\n *\n * @default `true`\n */\n ignoreStaticAssets?: boolean;\n\n /**\n * Controls the maximum size of incoming HTTP request bodies attached to events.\n *\n * Available options:\n * - 'none': No request bodies will be attached\n * - 'small': Request bodies up to 1,000 bytes will be attached\n * - 'medium': Request bodies up to 10,000 bytes will be attached (default)\n * - 'always': Request bodies will always be attached\n *\n * Note that even with 'always' setting, bodies exceeding 1MB will never be attached\n * for performance and security reasons.\n *\n * @default 'medium'\n */\n maxIncomingRequestBodySize?: 'none' | 'small' | 'medium' | 'always';\n\n /**\n * If true, do not generate spans for incoming requests at all.\n * This is used by Remix to avoid generating spans for incoming requests, as it generates its own spans.\n */\n disableIncomingRequestSpans?: boolean;\n}\n\nexport const instrumentSentryHttp = generateInstrumentOnce<SentryHttpInstrumentationOptions>(\n `${INTEGRATION_NAME}.sentry`,\n options => {\n return new SentryHttpInstrumentation(options);\n },\n);\n\n/**\n * The http integration instruments Node's internal http and https modules.\n * It creates breadcrumbs for outgoing HTTP requests which will be attached to the currently active span.\n */\nexport const httpIntegration = defineIntegration((options: HttpOptions = {}) => {\n const serverOptions: HttpServerIntegrationOptions = {\n sessions: options.trackIncomingRequestsAsSessions,\n sessionFlushingDelayMS: options.sessionFlushingDelayMS,\n ignoreRequestBody: options.ignoreIncomingRequestBody,\n maxRequestBodySize: options.maxIncomingRequestBodySize,\n };\n\n const serverSpansOptions: HttpServerSpansIntegrationOptions = {\n ignoreIncomingRequests: options.ignoreIncomingRequests,\n ignoreStaticAssets: options.ignoreStaticAssets,\n ignoreStatusCodes: options.dropSpansForIncomingRequestStatusCodes,\n };\n\n const httpInstrumentationOptions: SentryHttpInstrumentationOptions = {\n breadcrumbs: options.breadcrumbs,\n propagateTraceInOutgoingRequests: options.tracePropagation ?? true,\n ignoreOutgoingRequests: options.ignoreOutgoingRequests,\n };\n\n const server = httpServerIntegration(serverOptions);\n const serverSpans = httpServerSpansIntegration(serverSpansOptions);\n\n // In node-core, for now we disable incoming requests spans by default\n // we may revisit this in a future release\n const spans = options.spans ?? false;\n const disableIncomingRequestSpans = options.disableIncomingRequestSpans ?? false;\n const enabledServerSpans = spans && !disableIncomingRequestSpans;\n\n return {\n name: INTEGRATION_NAME,\n setup(client: NodeClient) {\n if (enabledServerSpans) {\n serverSpans.setup(client);\n }\n },\n setupOnce() {\n server.setupOnce();\n\n instrumentSentryHttp(httpInstrumentationOptions);\n },\n\n processEvent(event) {\n // Note: We always run this, even if spans are disabled\n // The reason being that e.g. the remix integration disables span creation here but still wants to use the ignore status codes option\n return serverSpans.processEvent(event);\n },\n };\n});\n"],"names":["generateInstrumentOnce","SentryHttpInstrumentation","defineIntegration","httpServerIntegration","httpServerSpansIntegration"],"mappings":";;;;;;;;AAYA,MAAM,gBAAA,GAAmB,MAAA;AAmHlB,MAAM,oBAAA,GAAuBA,iCAAA;AAAA,EAClC,GAAG,gBAAgB,CAAA,OAAA,CAAA;AAAA,EACnB,CAAA,OAAA,KAAW;AACT,IAAA,OAAO,IAAIC,oDAA0B,OAAO,CAAA;AAAA,EAC9C;AACF;AAMO,MAAM,eAAA,GAAkBC,sBAAA,CAAkB,CAAC,OAAA,GAAuB,EAAC,KAAM;AAC9E,EAAA,MAAM,aAAA,GAA8C;AAAA,IAClD,UAAU,OAAA,CAAQ,+BAAA;AAAA,IAClB,wBAAwB,OAAA,CAAQ,sBAAA;AAAA,IAChC,mBAAmB,OAAA,CAAQ,yBAAA;AAAA,IAC3B,oBAAoB,OAAA,CAAQ;AAAA,GAC9B;AAEA,EAAA,MAAM,kBAAA,GAAwD;AAAA,IAC5D,wBAAwB,OAAA,CAAQ,sBAAA;AAAA,IAChC,oBAAoB,OAAA,CAAQ,kBAAA;AAAA,IAC5B,mBAAmB,OAAA,CAAQ;AAAA,GAC7B;AAEA,EAAA,MAAM,0BAAA,GAA+D;AAAA,IACnE,aAAa,OAAA,CAAQ,WAAA;AAAA,IACrB,gCAAA,EAAkC,QAAQ,gBAAA,IAAoB,IAAA;AAAA,IAC9D,wBAAwB,OAAA,CAAQ;AAAA,GAClC;AAEA,EAAA,MAAM,MAAA,GAASC,4CAAsB,aAAa,CAAA;AAClD,EAAA,MAAM,WAAA,GAAcC,sDAA2B,kBAAkB,CAAA;AAIjE,EAAA,MAAM,KAAA,GAAQ,QAAQ,KAAA,IAAS,KAAA;AAC/B,EAAA,MAAM,2BAAA,GAA8B,QAAQ,2BAAA,IAA+B,KAAA;AAC3E,EAAA,MAAM,kBAAA,GAAqB,SAAS,CAAC,2BAAA;AAErC,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,gBAAA;AAAA,IACN,MAAM,MAAA,EAAoB;AACxB,MAAA,IAAI,kBAAA,EAAoB;AACtB,QAAA,WAAA,CAAY,MAAM,MAAM,CAAA;AAAA,MAC1B;AAAA,IACF,CAAA;AAAA,IACA,SAAA,GAAY;AACV,MAAA,MAAA,CAAO,SAAA,EAAU;AAEjB,MAAA,oBAAA,CAAqB,0BAA0B,CAAA;AAAA,IACjD,CAAA;AAAA,IAEA,aAAa,KAAA,EAAO;AAGlB,MAAA,OAAO,WAAA,CAAY,aAAa,KAAK,CAAA;AAAA,IACvC;AAAA,GACF;AACF,CAAC;;;;;"}
{"version":3,"file":"index.js","sources":["../../../../src/integrations/http/index.ts"],"sourcesContent":["import type { RequestOptions } from 'node:http';\nimport type { HttpIncomingMessage } from '@sentry/core';\nimport { defineIntegration } from '@sentry/core';\nimport type { NodeClient } from '../../sdk/client';\nimport type { HttpServerIntegrationOptions } from './httpServerIntegration';\nimport { httpServerIntegration } from './httpServerIntegration';\nimport type { HttpServerSpansIntegrationOptions } from './httpServerSpansIntegration';\nimport { httpServerSpansIntegration } from './httpServerSpansIntegration';\nimport type { SentryHttpInstrumentationOptions } from './SentryHttpInstrumentation';\nimport { instrumentHttpOutgoingRequests } from './SentryHttpInstrumentation';\n\nconst INTEGRATION_NAME = 'Http' as const;\n\ninterface HttpOptions {\n /**\n * Whether breadcrumbs should be recorded for outgoing requests.\n * Defaults to true\n */\n breadcrumbs?: boolean;\n\n /**\n * Whether to create spans for requests or not.\n * As of now, creates spans for incoming requests, but not outgoing requests.\n *\n * @default `true`\n */\n spans?: boolean;\n\n /**\n * Whether the integration should create [Sessions](https://docs.sentry.io/product/releases/health/#sessions) for incoming requests to track the health and crash-free rate of your releases in Sentry.\n * Read more about Release Health: https://docs.sentry.io/product/releases/health/\n *\n * Defaults to `true`.\n */\n trackIncomingRequestsAsSessions?: boolean;\n\n /**\n * Number of milliseconds until sessions tracked with `trackIncomingRequestsAsSessions` will be flushed as a session aggregate.\n *\n * Defaults to `60000` (60s).\n */\n sessionFlushingDelayMS?: number;\n\n /**\n * Whether to inject trace propagation headers (sentry-trace, baggage, traceparent) into outgoing HTTP requests.\n *\n * When set to `false`, Sentry will not inject any trace propagation headers, but will still create breadcrumbs\n * (if `breadcrumbs` is enabled).\n *\n * @default `true`\n */\n tracePropagation?: boolean;\n\n /**\n * Do not capture spans or breadcrumbs for outgoing HTTP requests to URLs where the given callback returns `true`.\n * This controls both span & breadcrumb creation - spans will be non recording if tracing is disabled.\n *\n * The `url` param contains the entire URL, including query string (if any), protocol, host, etc. of the outgoing request.\n * For example: `'https://someService.com/users/details?id=123'`\n *\n * The `request` param contains the original {@type RequestOptions} object used to make the outgoing request.\n * You can use it to filter on additional properties like method, headers, etc.\n */\n ignoreOutgoingRequests?: (url: string, request: RequestOptions) => boolean;\n\n /**\n * Do not capture spans for incoming HTTP requests to URLs where the given callback returns `true`.\n * Spans will be non recording if tracing is disabled.\n *\n * The `urlPath` param consists of the URL path and query string (if any) of the incoming request.\n * For example: `'/users/details?id=123'`\n *\n * The `request` param contains the original {@type IncomingMessage} object of the incoming request.\n * You can use it to filter on additional properties like method, headers, etc.\n */\n ignoreIncomingRequests?: (urlPath: string, request: HttpIncomingMessage) => boolean;\n\n /**\n * Do not capture spans for incoming HTTP requests with the given status codes.\n * By default, spans with some 3xx and 4xx status codes are ignored (see @default).\n * Expects an array of status codes or a range of status codes, e.g. [[300,399], 404] would ignore 3xx and 404 status codes.\n *\n * @default `[[401, 404], [301, 303], [305, 399]]`\n */\n dropSpansForIncomingRequestStatusCodes?: (number | [number, number])[];\n\n /**\n * Do not capture the request body for incoming HTTP requests to URLs where the given callback returns `true`.\n * This can be useful for long running requests where the body is not needed and we want to avoid capturing it.\n *\n * @param url Contains the entire URL, including query string (if any), protocol, host, etc. of the incoming request.\n * @param request Contains the {@type RequestOptions} object used to make the incoming request.\n */\n ignoreIncomingRequestBody?: (url: string, request: RequestOptions) => boolean;\n\n /**\n * Whether to automatically ignore common static asset requests like favicon.ico, robots.txt, etc.\n * This helps reduce noise in your transactions.\n *\n * @default `true`\n */\n ignoreStaticAssets?: boolean;\n\n /**\n * Controls the maximum size of incoming HTTP request bodies attached to events.\n *\n * Available options:\n * - 'none': No request bodies will be attached\n * - 'small': Request bodies up to 1,000 bytes will be attached\n * - 'medium': Request bodies up to 10,000 bytes will be attached (default)\n * - 'always': Request bodies will always be attached\n *\n * Note that even with 'always' setting, bodies exceeding 1MB will never be attached\n * for performance and security reasons.\n *\n * @default 'medium'\n */\n maxIncomingRequestBodySize?: 'none' | 'small' | 'medium' | 'always';\n\n /**\n * If true, do not generate spans for incoming requests at all.\n * This is used by Remix to avoid generating spans for incoming requests, as it generates its own spans.\n */\n disableIncomingRequestSpans?: boolean;\n}\n\nexport const instrumentSentryHttp = Object.assign(instrumentHttpOutgoingRequests, {\n id: `${INTEGRATION_NAME}.sentry`,\n});\n\n/**\n * The http integration instruments Node's internal http and https modules.\n * It creates breadcrumbs for outgoing HTTP requests which will be attached to the currently active span.\n */\nexport const httpIntegration = defineIntegration((options: HttpOptions = {}) => {\n // In node-core, for now we disable incoming requests spans by default\n // we may revisit this in a future release\n const spans = options.spans ?? false;\n const disableIncomingRequestSpans = options.disableIncomingRequestSpans ?? false;\n const enabledServerSpans = spans && !disableIncomingRequestSpans;\n\n const serverOptions: HttpServerIntegrationOptions = {\n sessions: options.trackIncomingRequestsAsSessions,\n sessionFlushingDelayMS: options.sessionFlushingDelayMS,\n ignoreRequestBody: options.ignoreIncomingRequestBody,\n maxRequestBodySize: options.maxIncomingRequestBodySize,\n };\n\n const serverSpansOptions: HttpServerSpansIntegrationOptions = {\n ignoreIncomingRequests: options.ignoreIncomingRequests,\n ignoreStaticAssets: options.ignoreStaticAssets,\n ignoreStatusCodes: options.dropSpansForIncomingRequestStatusCodes,\n };\n\n const httpInstrumentationOptions: SentryHttpInstrumentationOptions = {\n breadcrumbs: options.breadcrumbs,\n propagateTraceInOutgoingRequests: options.tracePropagation ?? true,\n ignoreOutgoingRequests: options.ignoreOutgoingRequests,\n spans,\n };\n\n const server = httpServerIntegration(serverOptions);\n const serverSpans = httpServerSpansIntegration(serverSpansOptions);\n\n return {\n name: INTEGRATION_NAME,\n setup(client: NodeClient) {\n if (enabledServerSpans) {\n serverSpans.setup(client);\n }\n },\n setupOnce() {\n server.setupOnce();\n\n instrumentHttpOutgoingRequests(httpInstrumentationOptions);\n },\n\n processEvent(event) {\n // Note: We always run this, even if spans are disabled\n // The reason being that e.g. the remix integration disables span creation here but still wants to use the ignore status codes option\n return serverSpans.processEvent(event);\n },\n };\n});\n"],"names":["instrumentHttpOutgoingRequests","defineIntegration","httpServerIntegration","httpServerSpansIntegration"],"mappings":";;;;;;;AAWA,MAAM,gBAAA,GAAmB,MAAA;AAmHW,MAAA,CAAO,MAAA,CAAOA,wDAAA,EAAgC;AAAA,EAChF,EAAA,EAAI,GAAG,gBAAgB,CAAA,OAAA;AACzB,CAAC;AAMM,MAAM,eAAA,GAAkBC,sBAAA,CAAkB,CAAC,OAAA,GAAuB,EAAC,KAAM;AAG9E,EAAA,MAAM,KAAA,GAAQ,QAAQ,KAAA,IAAS,KAAA;AAC/B,EAAA,MAAM,2BAAA,GAA8B,QAAQ,2BAAA,IAA+B,KAAA;AAC3E,EAAA,MAAM,kBAAA,GAAqB,SAAS,CAAC,2BAAA;AAErC,EAAA,MAAM,aAAA,GAA8C;AAAA,IAClD,UAAU,OAAA,CAAQ,+BAAA;AAAA,IAClB,wBAAwB,OAAA,CAAQ,sBAAA;AAAA,IAChC,mBAAmB,OAAA,CAAQ,yBAAA;AAAA,IAC3B,oBAAoB,OAAA,CAAQ;AAAA,GAC9B;AAEA,EAAA,MAAM,kBAAA,GAAwD;AAAA,IAC5D,wBAAwB,OAAA,CAAQ,sBAAA;AAAA,IAChC,oBAAoB,OAAA,CAAQ,kBAAA;AAAA,IAC5B,mBAAmB,OAAA,CAAQ;AAAA,GAC7B;AAEA,EAAA,MAAM,0BAAA,GAA+D;AAAA,IACnE,aAAa,OAAA,CAAQ,WAAA;AAAA,IACrB,gCAAA,EAAkC,QAAQ,gBAAA,IAAoB,IAAA;AAAA,IAC9D,wBAAwB,OAAA,CAAQ,sBAAA;AAAA,IAChC;AAAA,GACF;AAEA,EAAA,MAAM,MAAA,GAASC,4CAAsB,aAAa,CAAA;AAClD,EAAA,MAAM,WAAA,GAAcC,sDAA2B,kBAAkB,CAAA;AAEjE,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,gBAAA;AAAA,IACN,MAAM,MAAA,EAAoB;AACxB,MAAA,IAAI,kBAAA,EAAoB;AACtB,QAAA,WAAA,CAAY,MAAM,MAAM,CAAA;AAAA,MAC1B;AAAA,IACF,CAAA;AAAA,IACA,SAAA,GAAY;AACV,MAAA,MAAA,CAAO,SAAA,EAAU;AAEjB,MAAAH,wDAAA,CAA+B,0BAA0B,CAAA;AAAA,IAC3D,CAAA;AAAA,IAEA,aAAa,KAAA,EAAO;AAGlB,MAAA,OAAO,WAAA,CAAY,aAAa,KAAK,CAAA;AAAA,IACvC;AAAA,GACF;AACF,CAAC;;;;"}

@@ -11,5 +11,59 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });

const http = require('node:http');
const https = require('node:https');
const FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL = nodeVersion.NODE_VERSION.major === 22 && nodeVersion.NODE_VERSION.minor >= 12 || nodeVersion.NODE_VERSION.major === 23 && nodeVersion.NODE_VERSION.minor >= 2 || nodeVersion.NODE_VERSION.major >= 24;
function instrumentHttpOutgoingRequests(instrumentationOptions = {}) {
const { outgoingRequestApplyCustomAttributes: applyCustomAttributesOnSpan, ...options } = instrumentationOptions;
const patchOptions = {
propagateTrace: options.propagateTraceInOutgoingRequests ?? true,
applyCustomAttributesOnSpan,
...options,
// oxlint-disable-next-line typescript/no-deprecated
spans: options.createSpansForOutgoingRequests !== false && (options.spans ?? true),
ignoreOutgoingRequests(url, request) {
return core.isTracingSuppressed() || !!options.ignoreOutgoingRequests?.(url, core.getRequestOptions(request));
},
outgoingRequestHook(span, request) {
options.outgoingRequestHook?.(span, request);
const originalOnce = request.once;
const newOnce = new Proxy(originalOnce, {
apply(target, thisArg, args) {
const [event] = args;
if (event !== "response") {
return target.apply(thisArg, args);
}
const parentContext = api.context.active();
const requestContext = api.trace.setSpan(parentContext, span);
return api.context.with(requestContext, () => {
return target.apply(thisArg, args);
});
}
});
request.once = newOnce;
},
outgoingResponseHook(span, response) {
options.outgoingResponseHook?.(span, response);
api.context.bind(api.context.active(), response);
},
errorMonitor: node_events.errorMonitor,
// Pass these in to detect OTel double-wrapping if we're enabling spans
http
};
if (FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL) {
instrumentHttpOutgoingRequestsViaChannel(patchOptions);
} else {
instrumentHttpOutgoingRequestsViaMonkeyPatching(patchOptions);
}
}
let _currentListener;
function instrumentHttpOutgoingRequestsViaChannel(options) {
const { [core.HTTP_ON_CLIENT_REQUEST]: onHttpClientRequestCreated } = core.getHttpClientSubscriptions(options);
if (_currentListener) {
diagnosticsChannel.unsubscribe(core.HTTP_ON_CLIENT_REQUEST, _currentListener);
}
diagnosticsChannel.subscribe(core.HTTP_ON_CLIENT_REQUEST, onHttpClientRequestCreated);
_currentListener = onHttpClientRequestCreated;
}
function instrumentHttpOutgoingRequestsViaMonkeyPatching(options) {
core.patchHttpModuleClient(http, options);
}
class SentryHttpInstrumentation extends instrumentation.InstrumentationBase {

@@ -21,53 +75,3 @@ constructor(config = {}) {

init() {
const { outgoingRequestApplyCustomAttributes: applyCustomAttributesOnSpan, ...options } = this.getConfig();
const patchOptions = {
propagateTrace: options.propagateTraceInOutgoingRequests,
applyCustomAttributesOnSpan,
...options,
spans: options.createSpansForOutgoingRequests && (options.spans ?? true),
ignoreOutgoingRequests(url, request) {
return core.isTracingSuppressed() || !!options.ignoreOutgoingRequests?.(url, core.getRequestOptions(request));
},
outgoingRequestHook(span, request) {
options.outgoingRequestHook?.(span, request);
const originalOnce = request.once;
const newOnce = new Proxy(originalOnce, {
apply(target, thisArg, args) {
const [event] = args;
if (event !== "response") {
return target.apply(thisArg, args);
}
const parentContext = api.context.active();
const requestContext = api.trace.setSpan(parentContext, span);
return api.context.with(requestContext, () => {
return target.apply(thisArg, args);
});
}
});
request.once = newOnce;
},
outgoingResponseHook(span, response) {
options.outgoingResponseHook?.(span, response);
api.context.bind(api.context.active(), response);
},
errorMonitor: node_events.errorMonitor,
// Pass these in to detect OTel double-wrapping if we're enabling spans
http,
https
};
const { [core.HTTP_ON_CLIENT_REQUEST]: onHttpClientRequestCreated } = FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL ? core.getHttpClientSubscriptions(patchOptions) : {};
let hasRegisteredHandlers = false;
const sub = onHttpClientRequestCreated ? (moduleExports) => {
if (!hasRegisteredHandlers && onHttpClientRequestCreated) {
hasRegisteredHandlers = true;
diagnosticsChannel.subscribe(core.HTTP_ON_CLIENT_REQUEST, onHttpClientRequestCreated);
}
return moduleExports;
} : void 0;
const wrapHttp = sub ?? ((moduleExports) => core.patchHttpModuleClient(moduleExports, patchOptions));
const wrapHttps = sub ?? ((moduleExports) => core.patchHttpModuleClient(moduleExports, patchOptions));
return [
new instrumentation.InstrumentationNodeModuleDefinition("http", ["*"], wrapHttp),
new instrumentation.InstrumentationNodeModuleDefinition("https", ["*"], wrapHttps)
];
instrumentHttpOutgoingRequests(this.getConfig());
}

@@ -77,2 +81,3 @@ }

exports.SentryHttpInstrumentation = SentryHttpInstrumentation;
exports.instrumentHttpOutgoingRequests = instrumentHttpOutgoingRequests;
//# sourceMappingURL=SentryHttpInstrumentation.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"SentryHttpInstrumentation.js","sources":["../../../../src/integrations/http/SentryHttpInstrumentation.ts"],"sourcesContent":["import { subscribe } from 'node:diagnostics_channel';\nimport { context, trace } from '@opentelemetry/api';\nimport type { InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport { InstrumentationBase, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';\nimport type { ClientRequest, IncomingMessage, ServerResponse } from 'node:http';\nimport type {\n HttpClientRequest,\n HttpIncomingMessage,\n HttpInstrumentationOptions,\n HttpModuleExport,\n Span,\n} from '@sentry/core';\nimport {\n getHttpClientSubscriptions,\n patchHttpModuleClient,\n SDK_VERSION,\n getRequestOptions,\n isTracingSuppressed,\n} from '@sentry/core';\nimport { INSTRUMENTATION_NAME } from './constants';\nimport { HTTP_ON_CLIENT_REQUEST } from '@sentry/core';\nimport { NODE_VERSION } from '../../nodeVersion';\nimport { errorMonitor } from 'node:events';\nimport * as http from 'node:http';\nimport * as https from 'node:https';\n\nconst FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL =\n (NODE_VERSION.major === 22 && NODE_VERSION.minor >= 12) ||\n (NODE_VERSION.major === 23 && NODE_VERSION.minor >= 2) ||\n NODE_VERSION.major >= 24;\n\nexport type SentryHttpInstrumentationOptions = InstrumentationConfig & {\n /**\n * Whether breadcrumbs should be recorded for outgoing requests.\n *\n * @default `true`\n */\n breadcrumbs?: boolean;\n\n /**\n * Whether to propagate Sentry trace headers in outgoing requests.\n * By default this is done by the HttpInstrumentation, but if that is not added (e.g. because tracing is disabled)\n * then this instrumentation can take over.\n *\n * @default `false`\n */\n propagateTraceInOutgoingRequests?: boolean;\n\n /**\n * Whether to enable the capability to create spans for outgoing requests via diagnostic channels.\n * If enabled, spans will only be created if the `spans` option is also enabled (default: true).\n *\n * This is a feature flag that should be enabled by SDKs when the runtime supports it (Node 22.12+).\n * Individual users should not need to configure this directly.\n *\n * @default `false`\n */\n createSpansForOutgoingRequests?: boolean;\n\n /**\n * Whether to create spans for outgoing requests (user preference).\n * This only takes effect if `createSpansForOutgoingRequests` is also enabled.\n * If `createSpansForOutgoingRequests` is not enabled, this option is ignored.\n *\n * @default `true`\n */\n spans?: boolean;\n\n /**\n * Do not capture breadcrumbs for outgoing HTTP requests to URLs where the given callback returns `true`.\n * For the scope of this instrumentation, this callback only controls breadcrumb creation.\n * The same option can be passed to the top-level httpIntegration where it controls both, breadcrumb and\n * span creation.\n *\n * @param url Contains the entire URL, including query string (if any), protocol, host, etc. of the outgoing request.\n * @param request Contains the {@type RequestOptions} object used to make the outgoing request.\n */\n ignoreOutgoingRequests?: (url: string, request: http.RequestOptions) => boolean;\n\n /**\n * Hooks for outgoing request spans, called when `createSpansForOutgoingRequests` is enabled.\n * These mirror the OTEL HttpInstrumentation hooks for backwards compatibility.\n */\n outgoingRequestHook?: (span: Span, request: ClientRequest | HttpClientRequest) => void;\n outgoingResponseHook?: (span: Span, response: IncomingMessage | HttpIncomingMessage) => void;\n outgoingRequestApplyCustomAttributes?: (\n span: Span,\n request: HttpClientRequest,\n response: HttpIncomingMessage,\n ) => void;\n\n // All options below do not do anything anymore in this instrumentation, and will be removed in the future.\n // They are only kept here for backwards compatibility - the respective functionality is now handled by the httpServerIntegration/httpServerSpansIntegration.\n\n /**\n * @deprecated This no longer does anything.\n */\n extractIncomingTraceFromHeader?: boolean;\n\n /**\n * @deprecated This no longer does anything.\n */\n ignoreStaticAssets?: boolean;\n\n /**\n * @deprecated This no longer does anything.\n */\n disableIncomingRequestSpans?: boolean;\n\n /**\n * @deprecated This no longer does anything.\n */\n ignoreSpansForIncomingRequests?: (urlPath: string, request: IncomingMessage) => boolean;\n\n /**\n * @deprecated This no longer does anything.\n */\n ignoreIncomingRequestBody?: (url: string, request: http.RequestOptions) => boolean;\n\n /**\n * @deprecated This no longer does anything.\n */\n maxIncomingRequestBodySize?: 'none' | 'small' | 'medium' | 'always';\n\n /**\n * @deprecated This no longer does anything.\n */\n trackIncomingRequestsAsSessions?: boolean;\n\n /**\n * @deprecated This no longer does anything.\n */\n instrumentation?: {\n requestHook?: (span: Span, req: ClientRequest | IncomingMessage) => void;\n responseHook?: (span: Span, response: IncomingMessage | ServerResponse) => void;\n applyCustomAttributesOnSpan?: (\n span: Span,\n request: ClientRequest | IncomingMessage,\n response: IncomingMessage | ServerResponse,\n ) => void;\n };\n\n /**\n * @deprecated This no longer does anything.\n */\n sessionFlushingDelayMS?: number;\n};\n\n/**\n * This custom HTTP instrumentation handles outgoing HTTP requests.\n *\n * It provides:\n * - Breadcrumbs for all outgoing requests\n * - Trace propagation headers (when enabled)\n * - Span creation for outgoing requests (when createSpansForOutgoingRequests is enabled)\n *\n * Span creation requires Node 22+ and uses diagnostic channels to avoid monkey-patching.\n * By default, this is only enabled in the node SDK, not in node-core or other runtime SDKs.\n *\n * Important note: Contrary to other OTEL instrumentation, this one cannot be unwrapped.\n *\n * This is heavily inspired & adapted from:\n * https://github.com/open-telemetry/opentelemetry-js/blob/f8ab5592ddea5cba0a3b33bf8d74f27872c0367f/experimental/packages/opentelemetry-instrumentation-http/src/http.ts\n */\nexport class SentryHttpInstrumentation extends InstrumentationBase<SentryHttpInstrumentationOptions> {\n public constructor(config: SentryHttpInstrumentationOptions = {}) {\n super(INSTRUMENTATION_NAME, SDK_VERSION, config);\n }\n\n /** @inheritdoc */\n public init(): [InstrumentationNodeModuleDefinition, InstrumentationNodeModuleDefinition] {\n const { outgoingRequestApplyCustomAttributes: applyCustomAttributesOnSpan, ...options } = this.getConfig();\n const patchOptions: HttpInstrumentationOptions = {\n propagateTrace: options.propagateTraceInOutgoingRequests,\n applyCustomAttributesOnSpan,\n ...options,\n spans: options.createSpansForOutgoingRequests && (options.spans ?? true),\n ignoreOutgoingRequests(url, request) {\n return (\n isTracingSuppressed() || !!options.ignoreOutgoingRequests?.(url, getRequestOptions(request as ClientRequest))\n );\n },\n outgoingRequestHook(span, request) {\n options.outgoingRequestHook?.(span, request);\n // We monkey-patch `req.once('response'), which is used to trigger\n // the callback of the request, so that it runs in the active context\n // eslint-disable-next-line @typescript-eslint/unbound-method, typescript/no-deprecated\n const originalOnce = request.once;\n\n const newOnce = new Proxy(originalOnce, {\n apply(target, thisArg, args: Parameters<typeof originalOnce>) {\n const [event] = args;\n if (event !== 'response') {\n return target.apply(thisArg, args);\n }\n\n const parentContext = context.active();\n const requestContext = trace.setSpan(parentContext, span);\n\n return context.with(requestContext, () => {\n return target.apply(thisArg, args);\n });\n },\n });\n\n // eslint-disable-next-line typescript/no-deprecated\n request.once = newOnce;\n },\n outgoingResponseHook(span, response) {\n options.outgoingResponseHook?.(span, response);\n context.bind(context.active(), response);\n },\n errorMonitor,\n // Pass these in to detect OTel double-wrapping if we're enabling spans\n http,\n https,\n };\n\n // only generate the subscriber function if we'll actually use it\n const { [HTTP_ON_CLIENT_REQUEST]: onHttpClientRequestCreated } = FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL\n ? getHttpClientSubscriptions(patchOptions)\n : {};\n\n // guard because we cover both http and https with the same subscribers\n let hasRegisteredHandlers = false;\n const sub = onHttpClientRequestCreated\n ? <T extends HttpModuleExport>(moduleExports: T): T => {\n if (!hasRegisteredHandlers && onHttpClientRequestCreated) {\n hasRegisteredHandlers = true;\n subscribe(HTTP_ON_CLIENT_REQUEST, onHttpClientRequestCreated);\n }\n return moduleExports;\n }\n : undefined;\n\n const wrapHttp = sub ?? ((moduleExports: HttpModuleExport) => patchHttpModuleClient(moduleExports, patchOptions));\n\n const wrapHttps = sub ?? ((moduleExports: HttpModuleExport) => patchHttpModuleClient(moduleExports, patchOptions));\n\n /**\n * You may be wondering why we register these diagnostics-channel listeners\n * in such a convoluted way (as InstrumentationNodeModuleDefinition...)˝,\n * instead of simply subscribing to the events once in here.\n * The reason for this is timing semantics: These functions are called once the http or https module is loaded.\n * If we'd subscribe before that, there seem to be conflicts with the OTEL native instrumentation in some scenarios,\n * especially the \"import-on-top\" pattern of setting up ESM applications.\n */\n return [\n new InstrumentationNodeModuleDefinition('http', ['*'], wrapHttp),\n new InstrumentationNodeModuleDefinition('https', ['*'], wrapHttps),\n ];\n }\n}\n"],"names":["NODE_VERSION","InstrumentationBase","INSTRUMENTATION_NAME","SDK_VERSION","isTracingSuppressed","getRequestOptions","context","trace","errorMonitor","HTTP_ON_CLIENT_REQUEST","getHttpClientSubscriptions","subscribe","patchHttpModuleClient","InstrumentationNodeModuleDefinition"],"mappings":"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"}
{"version":3,"file":"SentryHttpInstrumentation.js","sources":["../../../../src/integrations/http/SentryHttpInstrumentation.ts"],"sourcesContent":["import type { ChannelListener } from 'node:diagnostics_channel';\nimport { subscribe, unsubscribe } from 'node:diagnostics_channel';\nimport { context, trace } from '@opentelemetry/api';\nimport type { InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport { InstrumentationBase } from '@opentelemetry/instrumentation';\nimport type { ClientRequest, IncomingMessage, ServerResponse } from 'node:http';\nimport type { HttpClientRequest, HttpIncomingMessage, HttpInstrumentationOptions, Span } from '@sentry/core';\nimport {\n getHttpClientSubscriptions,\n patchHttpModuleClient,\n SDK_VERSION,\n getRequestOptions,\n isTracingSuppressed,\n} from '@sentry/core';\nimport { INSTRUMENTATION_NAME } from './constants';\nimport { HTTP_ON_CLIENT_REQUEST } from '@sentry/core';\nimport { NODE_VERSION } from '../../nodeVersion';\nimport { errorMonitor } from 'node:events';\nimport * as http from 'node:http';\n\nconst FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL =\n (NODE_VERSION.major === 22 && NODE_VERSION.minor >= 12) ||\n (NODE_VERSION.major === 23 && NODE_VERSION.minor >= 2) ||\n NODE_VERSION.major >= 24;\n\ninterface OutgoingHttpRequestInstrumentationOptions {\n /**\n * Whether breadcrumbs should be recorded for outgoing requests.\n *\n * @default `true`\n */\n breadcrumbs?: boolean;\n\n /**\n * Whether to create spans for outgoing requests (user preference).\n * This only takes effect if `createSpansForOutgoingRequests` is not disabled.\n * If `createSpansForOutgoingRequests` is explicitly set false, this option is ignored.\n *\n * @default `true`\n */\n spans?: boolean;\n\n /**\n * Whether to propagate Sentry trace headers in outgoing requests.\n *\n * @default `true`\n */\n propagateTraceInOutgoingRequests?: boolean;\n\n /**\n * @deprecated Use spans option instead.\n *\n * @default `true`\n */\n createSpansForOutgoingRequests?: boolean;\n\n /**\n * Do not instrument outgoing HTTP requests to URLs where the given callback returns `true`.\n * When it returns `true`, the request is skipped entirely: no breadcrumb and no span are created,\n * and no trace headers are propagated for that request.\n *\n * @param url Contains the entire URL, including query string (if any), protocol, host, etc. of the outgoing request.\n * @param request Contains the {@type RequestOptions} object used to make the outgoing request.\n */\n ignoreOutgoingRequests?: (url: string, request: http.RequestOptions) => boolean;\n\n /**\n * Hooks for outgoing request spans, only called when spans are created for outgoing requests\n * (i.e. when `spans` is enabled).\n * These mirror the OTEL HttpInstrumentation hooks for backwards compatibility.\n */\n outgoingRequestHook?: (span: Span, request: ClientRequest | HttpClientRequest) => void;\n outgoingResponseHook?: (span: Span, response: IncomingMessage | HttpIncomingMessage) => void;\n outgoingRequestApplyCustomAttributes?: (\n span: Span,\n request: HttpClientRequest,\n response: HttpIncomingMessage,\n ) => void;\n}\n\nexport type SentryHttpInstrumentationOptions = InstrumentationConfig &\n OutgoingHttpRequestInstrumentationOptions & {\n // All options below do not do anything anymore in this instrumentation, and will be removed in the future.\n // They are only kept here for backwards compatibility - the respective functionality is now handled by the httpServerIntegration/httpServerSpansIntegration.\n\n /**\n * @deprecated This no longer does anything.\n */\n extractIncomingTraceFromHeader?: boolean;\n\n /**\n * @deprecated This no longer does anything.\n */\n ignoreStaticAssets?: boolean;\n\n /**\n * @deprecated This no longer does anything.\n */\n disableIncomingRequestSpans?: boolean;\n\n /**\n * @deprecated This no longer does anything.\n */\n ignoreSpansForIncomingRequests?: (urlPath: string, request: IncomingMessage) => boolean;\n\n /**\n * @deprecated This no longer does anything.\n */\n ignoreIncomingRequestBody?: (url: string, request: http.RequestOptions) => boolean;\n\n /**\n * @deprecated This no longer does anything.\n */\n maxIncomingRequestBodySize?: 'none' | 'small' | 'medium' | 'always';\n\n /**\n * @deprecated This no longer does anything.\n */\n trackIncomingRequestsAsSessions?: boolean;\n\n /**\n * @deprecated This no longer does anything.\n */\n instrumentation?: {\n requestHook?: (span: Span, req: ClientRequest | IncomingMessage) => void;\n responseHook?: (span: Span, response: IncomingMessage | ServerResponse) => void;\n applyCustomAttributesOnSpan?: (\n span: Span,\n request: ClientRequest | IncomingMessage,\n response: IncomingMessage | ServerResponse,\n ) => void;\n };\n\n /**\n * @deprecated This no longer does anything.\n */\n sessionFlushingDelayMS?: number;\n };\n\n/**\n * This instruments the http modules for outgoing requests.\n * It uses the diagnostics channel if available, otherwise it falls back to monkey-patching.\n *\n * The instrumentation will start spans, create breadcrumbs, and propagate trace headers in outgoing requests (depending on the settings).\n * This can be called multiple times, where the last invocation will have the current options.\n *\n * @TODO Cleanup options in v11\n */\nexport function instrumentHttpOutgoingRequests(\n instrumentationOptions: OutgoingHttpRequestInstrumentationOptions = {},\n): void {\n const { outgoingRequestApplyCustomAttributes: applyCustomAttributesOnSpan, ...options } = instrumentationOptions;\n const patchOptions = {\n propagateTrace: options.propagateTraceInOutgoingRequests ?? true,\n applyCustomAttributesOnSpan,\n ...options,\n // oxlint-disable-next-line typescript/no-deprecated\n spans: options.createSpansForOutgoingRequests !== false && (options.spans ?? true),\n ignoreOutgoingRequests(url, request) {\n return (\n isTracingSuppressed() || !!options.ignoreOutgoingRequests?.(url, getRequestOptions(request as ClientRequest))\n );\n },\n outgoingRequestHook(span, request) {\n options.outgoingRequestHook?.(span, request);\n // We monkey-patch `req.once('response'), which is used to trigger\n // the callback of the request, so that it runs in the active context\n // eslint-disable-next-line @typescript-eslint/unbound-method, typescript/no-deprecated\n const originalOnce = request.once;\n\n const newOnce = new Proxy(originalOnce, {\n apply(target, thisArg, args: Parameters<typeof originalOnce>) {\n const [event] = args;\n if (event !== 'response') {\n return target.apply(thisArg, args);\n }\n\n const parentContext = context.active();\n const requestContext = trace.setSpan(parentContext, span);\n\n return context.with(requestContext, () => {\n return target.apply(thisArg, args);\n });\n },\n });\n\n // eslint-disable-next-line typescript/no-deprecated\n request.once = newOnce;\n },\n outgoingResponseHook(span, response) {\n options.outgoingResponseHook?.(span, response);\n context.bind(context.active(), response);\n },\n errorMonitor,\n // Pass these in to detect OTel double-wrapping if we're enabling spans\n http,\n } satisfies HttpInstrumentationOptions;\n\n if (FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL) {\n instrumentHttpOutgoingRequestsViaChannel(patchOptions);\n } else {\n instrumentHttpOutgoingRequestsViaMonkeyPatching(patchOptions);\n }\n}\n\nlet _currentListener: ChannelListener | undefined;\nfunction instrumentHttpOutgoingRequestsViaChannel(options: HttpInstrumentationOptions): void {\n const { [HTTP_ON_CLIENT_REQUEST]: onHttpClientRequestCreated } = getHttpClientSubscriptions(options);\n // If it was previously subscribed, first unsubscribe it\n // TODO(v11): We can likely remove this when we drop preload support\n if (_currentListener) {\n unsubscribe(HTTP_ON_CLIENT_REQUEST, _currentListener);\n }\n\n subscribe(HTTP_ON_CLIENT_REQUEST, onHttpClientRequestCreated);\n _currentListener = onHttpClientRequestCreated;\n}\n\n/**\n * Instrument outgoing HTTP(S) requests by old-school monkey-patching the `http` module.\n * This is the fallback for runtimes that do not fully support the `node:http` client diagnostics channel\n * (Node < 22.12).\n */\nfunction instrumentHttpOutgoingRequestsViaMonkeyPatching(options: HttpInstrumentationOptions): void {\n // Patching http also patches https, as this uses the same underlying object\n patchHttpModuleClient(http, options);\n}\n\n/**\n * This custom HTTP instrumentation handles outgoing HTTP requests.\n *\n * It provides:\n * - Breadcrumbs for all outgoing requests\n * - Trace propagation headers (when enabled)\n * - Span creation for outgoing requests (when createSpansForOutgoingRequests is enabled)\n *\n * Span creation requires Node 22+ and uses diagnostic channels to avoid monkey-patching.\n * By default, this is only enabled in the node SDK, not in node-core or other runtime SDKs.\n *\n * Important note: Contrary to other OTEL instrumentation, this one cannot be unwrapped.\n *\n * This is heavily inspired & adapted from:\n * https://github.com/open-telemetry/opentelemetry-js/blob/f8ab5592ddea5cba0a3b33bf8d74f27872c0367f/experimental/packages/opentelemetry-instrumentation-http/src/http.ts\n *\n * @deprecated This will be removed in v11. Use instrumentHttpOutgoingRequests() instead.\n */\nexport class SentryHttpInstrumentation extends InstrumentationBase<SentryHttpInstrumentationOptions> {\n public constructor(config: SentryHttpInstrumentationOptions = {}) {\n super(INSTRUMENTATION_NAME, SDK_VERSION, config);\n }\n\n /** @inheritdoc */\n public init(): void {\n instrumentHttpOutgoingRequests(this.getConfig());\n }\n}\n"],"names":["NODE_VERSION","isTracingSuppressed","getRequestOptions","context","trace","errorMonitor","HTTP_ON_CLIENT_REQUEST","getHttpClientSubscriptions","unsubscribe","subscribe","patchHttpModuleClient","InstrumentationBase","INSTRUMENTATION_NAME","SDK_VERSION"],"mappings":"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"}

@@ -8,3 +8,3 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });

const base64WorkerScript = "LyohIEBzZW50cnkvbm9kZS1jb3JlIDEwLjY0LjAgKDU3MzZhMzgpIHwgaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdCAqLwppbXBvcnR7U2Vzc2lvbiBhcyBlfWZyb20ibm9kZTppbnNwZWN0b3IvcHJvbWlzZXMiO2ltcG9ydHt3b3JrZXJEYXRhIGFzIHR9ZnJvbSJub2RlOndvcmtlcl90aHJlYWRzIjtjb25zdCBuPWdsb2JhbFRoaXMsaT17fTtjb25zdCBvPSJfX1NFTlRSWV9FUlJPUl9MT0NBTF9WQVJJQUJMRVNfXyI7Y29uc3QgYT10O2Z1bmN0aW9uIHMoLi4uZSl7YS5kZWJ1ZyYmZnVuY3Rpb24oZSl7aWYoISgiY29uc29sZSJpbiBuKSlyZXR1cm4gZSgpO2NvbnN0IHQ9bi5jb25zb2xlLG89e30sYT1PYmplY3Qua2V5cyhpKTthLmZvckVhY2goZT0+e2NvbnN0IG49aVtlXTtvW2VdPXRbZV0sdFtlXT1ufSk7dHJ5e3JldHVybiBlKCl9ZmluYWxseXthLmZvckVhY2goZT0+e3RbZV09b1tlXX0pfX0oKCk9PmNvbnNvbGUubG9nKCJbTG9jYWxWYXJpYWJsZXMgV29ya2VyXSIsLi4uZSkpfWFzeW5jIGZ1bmN0aW9uIGMoZSx0LG4saSl7Y29uc3Qgbz1hd2FpdCBlLnBvc3QoIlJ1bnRpbWUuZ2V0UHJvcGVydGllcyIse29iamVjdElkOnQsb3duUHJvcGVydGllczohMH0pO2lbbl09by5yZXN1bHQuZmlsdGVyKGU9PiJsZW5ndGgiIT09ZS5uYW1lJiYhaXNOYU4ocGFyc2VJbnQoZS5uYW1lLDEwKSkpLnNvcnQoKGUsdCk9PnBhcnNlSW50KGUubmFtZSwxMCktcGFyc2VJbnQodC5uYW1lLDEwKSkubWFwKGU9PmUudmFsdWU/LnZhbHVlKX1hc3luYyBmdW5jdGlvbiByKGUsdCxuLGkpe2NvbnN0IG89YXdhaXQgZS5wb3N0KCJSdW50aW1lLmdldFByb3BlcnRpZXMiLHtvYmplY3RJZDp0LG93blByb3BlcnRpZXM6ITB9KTtpW25dPW8ucmVzdWx0Lm1hcChlPT5bZS5uYW1lLGUudmFsdWU/LnZhbHVlXSkucmVkdWNlKChlLFt0LG5dKT0+KGVbdF09bixlKSx7fSl9ZnVuY3Rpb24gdShlLHQpe2UudmFsdWUmJigidmFsdWUiaW4gZS52YWx1ZT92b2lkIDA9PT1lLnZhbHVlLnZhbHVlfHxudWxsPT09ZS52YWx1ZS52YWx1ZT90W2UubmFtZV09YDwke2UudmFsdWUudmFsdWV9PmA6dFtlLm5hbWVdPWUudmFsdWUudmFsdWU6ImRlc2NyaXB0aW9uImluIGUudmFsdWUmJiJmdW5jdGlvbiIhPT1lLnZhbHVlLnR5cGU/dFtlLm5hbWVdPWA8JHtlLnZhbHVlLmRlc2NyaXB0aW9ufT5gOiJ1bmRlZmluZWQiPT09ZS52YWx1ZS50eXBlJiYodFtlLm5hbWVdPSI8dW5kZWZpbmVkPiIpKX1hc3luYyBmdW5jdGlvbiBsKGUsdCl7Y29uc3Qgbj1hd2FpdCBlLnBvc3QoIlJ1bnRpbWUuZ2V0UHJvcGVydGllcyIse29iamVjdElkOnQsb3duUHJvcGVydGllczohMH0pLGk9e307Zm9yKGNvbnN0IHQgb2Ygbi5yZXN1bHQpaWYodC52YWx1ZT8ub2JqZWN0SWQmJiJBcnJheSI9PT10LnZhbHVlLmNsYXNzTmFtZSl7Y29uc3Qgbj10LnZhbHVlLm9iamVjdElkO2F3YWl0IGMoZSxuLHQubmFtZSxpKX1lbHNlIGlmKHQudmFsdWU/Lm9iamVjdElkJiYiT2JqZWN0Ij09PXQudmFsdWUuY2xhc3NOYW1lKXtjb25zdCBuPXQudmFsdWUub2JqZWN0SWQ7YXdhaXQgcihlLG4sdC5uYW1lLGkpfWVsc2UgdC52YWx1ZSYmdSh0LGkpO3JldHVybiBpfWxldCBmOyhhc3luYyBmdW5jdGlvbigpe2NvbnN0IHQ9bmV3IGU7dC5jb25uZWN0VG9NYWluVGhyZWFkKCkscygiQ29ubmVjdGVkIHRvIG1haW4gdGhyZWFkIik7bGV0IG49ITE7dC5vbigiRGVidWdnZXIucmVzdW1lZCIsKCk9PntuPSExfSksdC5vbigiRGVidWdnZXIucGF1c2VkIixlPT57bj0hMCxhc3luYyBmdW5jdGlvbihlLHtyZWFzb246dCxkYXRhOntvYmplY3RJZDpufSxjYWxsRnJhbWVzOml9KXtpZigiZXhjZXB0aW9uIiE9PXQmJiJwcm9taXNlUmVqZWN0aW9uIiE9PXQpcmV0dXJuO2lmKGY/LigpLG51bGw9PW4pcmV0dXJuO2NvbnN0IGE9W107Zm9yKGxldCB0PTA7dDxpLmxlbmd0aDt0Kyspe2NvbnN0e3Njb3BlQ2hhaW46bixmdW5jdGlvbk5hbWU6byx0aGlzOnN9PWlbdF0sYz1uLmZpbmQoZT0+ImxvY2FsIj09PWUudHlwZSkscj0iZ2xvYmFsIiE9PXMuY2xhc3NOYW1lJiZzLmNsYXNzTmFtZT9gJHtzLmNsYXNzTmFtZX0uJHtvfWA6bztpZih2b2lkIDA9PT1jPy5vYmplY3Qub2JqZWN0SWQpYVt0XT17ZnVuY3Rpb246cn07ZWxzZXtjb25zdCBuPWF3YWl0IGwoZSxjLm9iamVjdC5vYmplY3RJZCk7YVt0XT17ZnVuY3Rpb246cix2YXJzOm59fX1hd2FpdCBlLnBvc3QoIlJ1bnRpbWUuY2FsbEZ1bmN0aW9uT24iLHtmdW5jdGlvbkRlY2xhcmF0aW9uOmBmdW5jdGlvbigpIHsgdGhpcy4ke299ID0gdGhpcy4ke299IHx8ICR7SlNPTi5zdHJpbmdpZnkoYSl9OyB9YCxzaWxlbnQ6ITAsb2JqZWN0SWQ6bn0pLGF3YWl0IGUucG9zdCgiUnVudGltZS5yZWxlYXNlT2JqZWN0Iix7b2JqZWN0SWQ6bn0pfSh0LGUucGFyYW1zKS50aGVuKGFzeW5jKCk9PntuJiZhd2FpdCB0LnBvc3QoIkRlYnVnZ2VyLnJlc3VtZSIpfSxhc3luYyBlPT57biYmYXdhaXQgdC5wb3N0KCJEZWJ1Z2dlci5yZXN1bWUiKX0pfSksYXdhaXQgdC5wb3N0KCJEZWJ1Z2dlci5lbmFibGUiKTtjb25zdCBpPSExIT09YS5jYXB0dXJlQWxsRXhjZXB0aW9ucztpZihhd2FpdCB0LnBvc3QoIkRlYnVnZ2VyLnNldFBhdXNlT25FeGNlcHRpb25zIix7c3RhdGU6aT8iYWxsIjoidW5jYXVnaHQifSksaSl7Y29uc3QgZT1hLm1heEV4Y2VwdGlvbnNQZXJTZWNvbmR8fDUwO2Y9ZnVuY3Rpb24oZSx0LG4pe2xldCBpPTAsbz01LGE9MDtyZXR1cm4gc2V0SW50ZXJ2YWwoKCk9PnswPT09YT9pPmUmJihvKj0yLG4obyksbz44NjQwMCYmKG89ODY0MDApLGE9byk6KGEtPTEsMD09PWEmJnQoKSksaT0wfSwxZTMpLnVucmVmKCksKCk9PntpKz0xfX0oZSxhc3luYygpPT57cygiUmF0ZS1saW1pdCBsaWZ0ZWQuIiksYXdhaXQgdC5wb3N0KCJEZWJ1Z2dlci5zZXRQYXVzZU9uRXhjZXB0aW9ucyIse3N0YXRlOiJhbGwifSl9LGFzeW5jIGU9PntzKGBSYXRlLWxpbWl0IGV4Y2VlZGVkLiBEaXNhYmxpbmcgY2FwdHVyaW5nIG9mIGNhdWdodCBleGNlcHRpb25zIGZvciAke2V9IHNlY29uZHMuYCksYXdhaXQgdC5wb3N0KCJEZWJ1Z2dlci5zZXRQYXVzZU9uRXhjZXB0aW9ucyIse3N0YXRlOiJ1bmNhdWdodCJ9KX0pfX0pKCkuY2F0Y2goZT0+e3MoIkZhaWxlZCB0byBzdGFydCBkZWJ1Z2dlciIsZSl9KSxzZXRJbnRlcnZhbCgoKT0+e30sMWU0KTs=";
const base64WorkerScript = "LyohIEBzZW50cnkvbm9kZS1jb3JlIDEwLjY1LjAgKGM2NmE4MTUpIHwgaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdCAqLwppbXBvcnR7U2Vzc2lvbiBhcyBlfWZyb20ibm9kZTppbnNwZWN0b3IvcHJvbWlzZXMiO2ltcG9ydHt3b3JrZXJEYXRhIGFzIHR9ZnJvbSJub2RlOndvcmtlcl90aHJlYWRzIjtjb25zdCBuPWdsb2JhbFRoaXMsaT17fTtjb25zdCBvPSJfX1NFTlRSWV9FUlJPUl9MT0NBTF9WQVJJQUJMRVNfXyI7Y29uc3QgYT10O2Z1bmN0aW9uIHMoLi4uZSl7YS5kZWJ1ZyYmZnVuY3Rpb24oZSl7aWYoISgiY29uc29sZSJpbiBuKSlyZXR1cm4gZSgpO2NvbnN0IHQ9bi5jb25zb2xlLG89e30sYT1PYmplY3Qua2V5cyhpKTthLmZvckVhY2goZT0+e2NvbnN0IG49aVtlXTtvW2VdPXRbZV0sdFtlXT1ufSk7dHJ5e3JldHVybiBlKCl9ZmluYWxseXthLmZvckVhY2goZT0+e3RbZV09b1tlXX0pfX0oKCk9PmNvbnNvbGUubG9nKCJbTG9jYWxWYXJpYWJsZXMgV29ya2VyXSIsLi4uZSkpfWFzeW5jIGZ1bmN0aW9uIGMoZSx0LG4saSl7Y29uc3Qgbz1hd2FpdCBlLnBvc3QoIlJ1bnRpbWUuZ2V0UHJvcGVydGllcyIse29iamVjdElkOnQsb3duUHJvcGVydGllczohMH0pO2lbbl09by5yZXN1bHQuZmlsdGVyKGU9PiJsZW5ndGgiIT09ZS5uYW1lJiYhaXNOYU4ocGFyc2VJbnQoZS5uYW1lLDEwKSkpLnNvcnQoKGUsdCk9PnBhcnNlSW50KGUubmFtZSwxMCktcGFyc2VJbnQodC5uYW1lLDEwKSkubWFwKGU9PmUudmFsdWU/LnZhbHVlKX1hc3luYyBmdW5jdGlvbiByKGUsdCxuLGkpe2NvbnN0IG89YXdhaXQgZS5wb3N0KCJSdW50aW1lLmdldFByb3BlcnRpZXMiLHtvYmplY3RJZDp0LG93blByb3BlcnRpZXM6ITB9KTtpW25dPW8ucmVzdWx0Lm1hcChlPT5bZS5uYW1lLGUudmFsdWU/LnZhbHVlXSkucmVkdWNlKChlLFt0LG5dKT0+KGVbdF09bixlKSx7fSl9ZnVuY3Rpb24gdShlLHQpe2UudmFsdWUmJigidmFsdWUiaW4gZS52YWx1ZT92b2lkIDA9PT1lLnZhbHVlLnZhbHVlfHxudWxsPT09ZS52YWx1ZS52YWx1ZT90W2UubmFtZV09YDwke2UudmFsdWUudmFsdWV9PmA6dFtlLm5hbWVdPWUudmFsdWUudmFsdWU6ImRlc2NyaXB0aW9uImluIGUudmFsdWUmJiJmdW5jdGlvbiIhPT1lLnZhbHVlLnR5cGU/dFtlLm5hbWVdPWA8JHtlLnZhbHVlLmRlc2NyaXB0aW9ufT5gOiJ1bmRlZmluZWQiPT09ZS52YWx1ZS50eXBlJiYodFtlLm5hbWVdPSI8dW5kZWZpbmVkPiIpKX1hc3luYyBmdW5jdGlvbiBsKGUsdCl7Y29uc3Qgbj1hd2FpdCBlLnBvc3QoIlJ1bnRpbWUuZ2V0UHJvcGVydGllcyIse29iamVjdElkOnQsb3duUHJvcGVydGllczohMH0pLGk9e307Zm9yKGNvbnN0IHQgb2Ygbi5yZXN1bHQpaWYodC52YWx1ZT8ub2JqZWN0SWQmJiJBcnJheSI9PT10LnZhbHVlLmNsYXNzTmFtZSl7Y29uc3Qgbj10LnZhbHVlLm9iamVjdElkO2F3YWl0IGMoZSxuLHQubmFtZSxpKX1lbHNlIGlmKHQudmFsdWU/Lm9iamVjdElkJiYiT2JqZWN0Ij09PXQudmFsdWUuY2xhc3NOYW1lKXtjb25zdCBuPXQudmFsdWUub2JqZWN0SWQ7YXdhaXQgcihlLG4sdC5uYW1lLGkpfWVsc2UgdC52YWx1ZSYmdSh0LGkpO3JldHVybiBpfWxldCBmOyhhc3luYyBmdW5jdGlvbigpe2NvbnN0IHQ9bmV3IGU7dC5jb25uZWN0VG9NYWluVGhyZWFkKCkscygiQ29ubmVjdGVkIHRvIG1haW4gdGhyZWFkIik7bGV0IG49ITE7dC5vbigiRGVidWdnZXIucmVzdW1lZCIsKCk9PntuPSExfSksdC5vbigiRGVidWdnZXIucGF1c2VkIixlPT57bj0hMCxhc3luYyBmdW5jdGlvbihlLHtyZWFzb246dCxkYXRhOntvYmplY3RJZDpufSxjYWxsRnJhbWVzOml9KXtpZigiZXhjZXB0aW9uIiE9PXQmJiJwcm9taXNlUmVqZWN0aW9uIiE9PXQpcmV0dXJuO2lmKGY/LigpLG51bGw9PW4pcmV0dXJuO2NvbnN0IGE9W107Zm9yKGxldCB0PTA7dDxpLmxlbmd0aDt0Kyspe2NvbnN0e3Njb3BlQ2hhaW46bixmdW5jdGlvbk5hbWU6byx0aGlzOnN9PWlbdF0sYz1uLmZpbmQoZT0+ImxvY2FsIj09PWUudHlwZSkscj0iZ2xvYmFsIiE9PXMuY2xhc3NOYW1lJiZzLmNsYXNzTmFtZT9gJHtzLmNsYXNzTmFtZX0uJHtvfWA6bztpZih2b2lkIDA9PT1jPy5vYmplY3Qub2JqZWN0SWQpYVt0XT17ZnVuY3Rpb246cn07ZWxzZXtjb25zdCBuPWF3YWl0IGwoZSxjLm9iamVjdC5vYmplY3RJZCk7YVt0XT17ZnVuY3Rpb246cix2YXJzOm59fX1hd2FpdCBlLnBvc3QoIlJ1bnRpbWUuY2FsbEZ1bmN0aW9uT24iLHtmdW5jdGlvbkRlY2xhcmF0aW9uOmBmdW5jdGlvbigpIHsgdGhpcy4ke299ID0gdGhpcy4ke299IHx8ICR7SlNPTi5zdHJpbmdpZnkoYSl9OyB9YCxzaWxlbnQ6ITAsb2JqZWN0SWQ6bn0pLGF3YWl0IGUucG9zdCgiUnVudGltZS5yZWxlYXNlT2JqZWN0Iix7b2JqZWN0SWQ6bn0pfSh0LGUucGFyYW1zKS50aGVuKGFzeW5jKCk9PntuJiZhd2FpdCB0LnBvc3QoIkRlYnVnZ2VyLnJlc3VtZSIpfSxhc3luYyBlPT57biYmYXdhaXQgdC5wb3N0KCJEZWJ1Z2dlci5yZXN1bWUiKX0pfSksYXdhaXQgdC5wb3N0KCJEZWJ1Z2dlci5lbmFibGUiKTtjb25zdCBpPSExIT09YS5jYXB0dXJlQWxsRXhjZXB0aW9ucztpZihhd2FpdCB0LnBvc3QoIkRlYnVnZ2VyLnNldFBhdXNlT25FeGNlcHRpb25zIix7c3RhdGU6aT8iYWxsIjoidW5jYXVnaHQifSksaSl7Y29uc3QgZT1hLm1heEV4Y2VwdGlvbnNQZXJTZWNvbmR8fDUwO2Y9ZnVuY3Rpb24oZSx0LG4pe2xldCBpPTAsbz01LGE9MDtyZXR1cm4gc2V0SW50ZXJ2YWwoKCk9PnswPT09YT9pPmUmJihvKj0yLG4obyksbz44NjQwMCYmKG89ODY0MDApLGE9byk6KGEtPTEsMD09PWEmJnQoKSksaT0wfSwxZTMpLnVucmVmKCksKCk9PntpKz0xfX0oZSxhc3luYygpPT57cygiUmF0ZS1saW1pdCBsaWZ0ZWQuIiksYXdhaXQgdC5wb3N0KCJEZWJ1Z2dlci5zZXRQYXVzZU9uRXhjZXB0aW9ucyIse3N0YXRlOiJhbGwifSl9LGFzeW5jIGU9PntzKGBSYXRlLWxpbWl0IGV4Y2VlZGVkLiBEaXNhYmxpbmcgY2FwdHVyaW5nIG9mIGNhdWdodCBleGNlcHRpb25zIGZvciAke2V9IHNlY29uZHMuYCksYXdhaXQgdC5wb3N0KCJEZWJ1Z2dlci5zZXRQYXVzZU9uRXhjZXB0aW9ucyIse3N0YXRlOiJ1bmNhdWdodCJ9KX0pfX0pKCkuY2F0Y2goZT0+e3MoIkZhaWxlZCB0byBzdGFydCBkZWJ1Z2dlciIsZSl9KSxzZXRJbnRlcnZhbCgoKT0+e30sMWU0KTs=";
function log(...args) {

@@ -11,0 +11,0 @@ core.debug.log("[LocalVariables]", ...args);

@@ -31,3 +31,3 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });

function extractErrorInfo(reason) {
if (typeof reason !== "object" || reason === null) {
if (!core.isObjectLike(reason)) {
return { name: "", message: String(reason ?? "") };

@@ -58,3 +58,3 @@ }

const level = options.mode === "strict" ? "fatal" : "error";
const activeSpanForError = reason && typeof reason === "object" ? reason._sentry_active_span : void 0;
const activeSpanForError = core.isObjectLike(reason) ? reason._sentry_active_span : void 0;
const activeSpanWrapper = activeSpanForError ? (fn) => core.withActiveSpan(activeSpanForError, fn) : (fn) => fn();

@@ -82,3 +82,3 @@ activeSpanWrapper(() => {

console.warn(rejectionWarning);
console.error(reason && typeof reason === "object" && "stack" in reason ? reason.stack : reason);
console.error(core.isObjectLike(reason) && "stack" in reason ? reason.stack : reason);
});

@@ -85,0 +85,0 @@ } else if (mode === "strict") {

@@ -1,1 +0,1 @@

{"version":3,"file":"onunhandledrejection.js","sources":["../../../src/integrations/onunhandledrejection.ts"],"sourcesContent":["import type { Client, IntegrationFn, SeverityLevel, Span } from '@sentry/core';\nimport {\n captureException,\n consoleSandbox,\n defineIntegration,\n getClient,\n isMatchingPattern,\n withActiveSpan,\n} from '@sentry/core';\nimport { logAndExitProcess } from '../utils/errorhandling';\n\ntype UnhandledRejectionMode = 'none' | 'warn' | 'strict';\n\ntype IgnoreMatcher = { name?: string | RegExp; message?: string | RegExp };\n\ninterface OnUnhandledRejectionOptions {\n /**\n * Option deciding what to do after capturing unhandledRejection,\n * that mimicks behavior of node's --unhandled-rejection flag.\n */\n mode: UnhandledRejectionMode;\n /** Rejection Errors to ignore (don't capture or warn). */\n ignore?: IgnoreMatcher[];\n}\n\nconst INTEGRATION_NAME = 'OnUnhandledRejection';\n\nconst DEFAULT_IGNORES: IgnoreMatcher[] = [\n {\n name: 'AI_NoOutputGeneratedError', // When stream aborts in Vercel AI SDK V5, Vercel flush() fails with an error\n },\n {\n name: 'AbortError', // When stream aborts in Vercel AI SDK V6\n },\n];\n\nconst _onUnhandledRejectionIntegration = ((options: Partial<OnUnhandledRejectionOptions> = {}) => {\n const opts: OnUnhandledRejectionOptions = {\n mode: options.mode ?? 'warn',\n ignore: [...DEFAULT_IGNORES, ...(options.ignore ?? [])],\n };\n\n return {\n name: INTEGRATION_NAME,\n setup(client) {\n global.process.on('unhandledRejection', makeUnhandledPromiseHandler(client, opts));\n },\n };\n}) satisfies IntegrationFn;\n\nexport const onUnhandledRejectionIntegration = defineIntegration(_onUnhandledRejectionIntegration);\n\n/** Extract error info safely */\nfunction extractErrorInfo(reason: unknown): { name: string; message: string } {\n // Check if reason is an object (including Error instances, not just plain objects)\n if (typeof reason !== 'object' || reason === null) {\n return { name: '', message: String(reason ?? '') };\n }\n\n const errorLike = reason as Record<string, unknown>;\n const name = typeof errorLike.name === 'string' ? errorLike.name : '';\n const message = typeof errorLike.message === 'string' ? errorLike.message : String(reason);\n\n return { name, message };\n}\n\n/** Check if a matcher matches the reason */\nfunction isMatchingReason(matcher: IgnoreMatcher, errorInfo: ReturnType<typeof extractErrorInfo>): boolean {\n // name/message matcher\n const nameMatches = matcher.name === undefined || isMatchingPattern(errorInfo.name, matcher.name, true);\n\n const messageMatches = matcher.message === undefined || isMatchingPattern(errorInfo.message, matcher.message);\n\n return nameMatches && messageMatches;\n}\n\n/** Match helper */\nfunction matchesIgnore(list: IgnoreMatcher[], reason: unknown): boolean {\n const errorInfo = extractErrorInfo(reason);\n return list.some(matcher => isMatchingReason(matcher, errorInfo));\n}\n\n/** Core handler */\nexport function makeUnhandledPromiseHandler(\n client: Client,\n options: OnUnhandledRejectionOptions,\n): (reason: unknown, promise: unknown) => void {\n return function sendUnhandledPromise(reason: unknown, _promise: unknown): void {\n // Only handle for the active client\n if (getClient() !== client) {\n return;\n }\n\n // Skip if configured to ignore\n if (matchesIgnore(options.ignore ?? [], reason)) {\n return;\n }\n\n const level: SeverityLevel = options.mode === 'strict' ? 'fatal' : 'error';\n\n // this can be set in places where we cannot reliably get access to the active span/error\n // when the error bubbles up to this handler, we can use this to set the active span\n const activeSpanForError =\n reason && typeof reason === 'object' ? (reason as { _sentry_active_span?: Span })._sentry_active_span : undefined;\n\n const activeSpanWrapper = activeSpanForError\n ? (fn: () => void) => withActiveSpan(activeSpanForError, fn)\n : (fn: () => void) => fn();\n\n activeSpanWrapper(() => {\n captureException(reason, {\n originalException: reason,\n captureContext: {\n extra: { unhandledPromiseRejection: true },\n level,\n },\n mechanism: {\n handled: false,\n type: 'auto.node.onunhandledrejection',\n },\n });\n });\n\n handleRejection(reason, options.mode);\n };\n}\n\n/**\n * Handler for `mode` option\n */\nfunction handleRejection(reason: unknown, mode: UnhandledRejectionMode): void {\n // https://github.com/nodejs/node/blob/7cf6f9e964aa00772965391c23acda6d71972a9a/lib/internal/process/promises.js#L234-L240\n const rejectionWarning =\n 'This error originated either by ' +\n 'throwing inside of an async function without a catch block, ' +\n 'or by rejecting a promise which was not handled with .catch().' +\n ' The promise rejected with the reason:';\n\n /* eslint-disable no-console */\n if (mode === 'warn') {\n consoleSandbox(() => {\n console.warn(rejectionWarning);\n console.error(reason && typeof reason === 'object' && 'stack' in reason ? reason.stack : reason);\n });\n } else if (mode === 'strict') {\n consoleSandbox(() => {\n console.warn(rejectionWarning);\n });\n logAndExitProcess(reason);\n }\n /* eslint-enable no-console */\n}\n"],"names":["defineIntegration","isMatchingPattern","getClient","withActiveSpan","captureException","consoleSandbox","logAndExitProcess"],"mappings":"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"}
{"version":3,"file":"onunhandledrejection.js","sources":["../../../src/integrations/onunhandledrejection.ts"],"sourcesContent":["import type { Client, IntegrationFn, SeverityLevel, Span } from '@sentry/core';\nimport {\n captureException,\n consoleSandbox,\n defineIntegration,\n getClient,\n isMatchingPattern,\n isObjectLike,\n withActiveSpan,\n} from '@sentry/core';\nimport { logAndExitProcess } from '../utils/errorhandling';\n\ntype UnhandledRejectionMode = 'none' | 'warn' | 'strict';\n\ntype IgnoreMatcher = { name?: string | RegExp; message?: string | RegExp };\n\ninterface OnUnhandledRejectionOptions {\n /**\n * Option deciding what to do after capturing unhandledRejection,\n * that mimicks behavior of node's --unhandled-rejection flag.\n */\n mode: UnhandledRejectionMode;\n /** Rejection Errors to ignore (don't capture or warn). */\n ignore?: IgnoreMatcher[];\n}\n\nconst INTEGRATION_NAME = 'OnUnhandledRejection';\n\nconst DEFAULT_IGNORES: IgnoreMatcher[] = [\n {\n name: 'AI_NoOutputGeneratedError', // When stream aborts in Vercel AI SDK V5, Vercel flush() fails with an error\n },\n {\n name: 'AbortError', // When stream aborts in Vercel AI SDK V6\n },\n];\n\nconst _onUnhandledRejectionIntegration = ((options: Partial<OnUnhandledRejectionOptions> = {}) => {\n const opts: OnUnhandledRejectionOptions = {\n mode: options.mode ?? 'warn',\n ignore: [...DEFAULT_IGNORES, ...(options.ignore ?? [])],\n };\n\n return {\n name: INTEGRATION_NAME,\n setup(client) {\n global.process.on('unhandledRejection', makeUnhandledPromiseHandler(client, opts));\n },\n };\n}) satisfies IntegrationFn;\n\nexport const onUnhandledRejectionIntegration = defineIntegration(_onUnhandledRejectionIntegration);\n\n/** Extract error info safely */\nfunction extractErrorInfo(reason: unknown): { name: string; message: string } {\n // Check if reason is an object (including Error instances, not just plain objects)\n if (!isObjectLike(reason)) {\n return { name: '', message: String(reason ?? '') };\n }\n\n const errorLike = reason as Record<string, unknown>;\n const name = typeof errorLike.name === 'string' ? errorLike.name : '';\n const message = typeof errorLike.message === 'string' ? errorLike.message : String(reason);\n\n return { name, message };\n}\n\n/** Check if a matcher matches the reason */\nfunction isMatchingReason(matcher: IgnoreMatcher, errorInfo: ReturnType<typeof extractErrorInfo>): boolean {\n // name/message matcher\n const nameMatches = matcher.name === undefined || isMatchingPattern(errorInfo.name, matcher.name, true);\n\n const messageMatches = matcher.message === undefined || isMatchingPattern(errorInfo.message, matcher.message);\n\n return nameMatches && messageMatches;\n}\n\n/** Match helper */\nfunction matchesIgnore(list: IgnoreMatcher[], reason: unknown): boolean {\n const errorInfo = extractErrorInfo(reason);\n return list.some(matcher => isMatchingReason(matcher, errorInfo));\n}\n\n/** Core handler */\nexport function makeUnhandledPromiseHandler(\n client: Client,\n options: OnUnhandledRejectionOptions,\n): (reason: unknown, promise: unknown) => void {\n return function sendUnhandledPromise(reason: unknown, _promise: unknown): void {\n // Only handle for the active client\n if (getClient() !== client) {\n return;\n }\n\n // Skip if configured to ignore\n if (matchesIgnore(options.ignore ?? [], reason)) {\n return;\n }\n\n const level: SeverityLevel = options.mode === 'strict' ? 'fatal' : 'error';\n\n // this can be set in places where we cannot reliably get access to the active span/error\n // when the error bubbles up to this handler, we can use this to set the active span\n const activeSpanForError = isObjectLike(reason)\n ? (reason as { _sentry_active_span?: Span })._sentry_active_span\n : undefined;\n\n const activeSpanWrapper = activeSpanForError\n ? (fn: () => void) => withActiveSpan(activeSpanForError, fn)\n : (fn: () => void) => fn();\n\n activeSpanWrapper(() => {\n captureException(reason, {\n originalException: reason,\n captureContext: {\n extra: { unhandledPromiseRejection: true },\n level,\n },\n mechanism: {\n handled: false,\n type: 'auto.node.onunhandledrejection',\n },\n });\n });\n\n handleRejection(reason, options.mode);\n };\n}\n\n/**\n * Handler for `mode` option\n */\nfunction handleRejection(reason: unknown, mode: UnhandledRejectionMode): void {\n // https://github.com/nodejs/node/blob/7cf6f9e964aa00772965391c23acda6d71972a9a/lib/internal/process/promises.js#L234-L240\n const rejectionWarning =\n 'This error originated either by ' +\n 'throwing inside of an async function without a catch block, ' +\n 'or by rejecting a promise which was not handled with .catch().' +\n ' The promise rejected with the reason:';\n\n /* eslint-disable no-console */\n if (mode === 'warn') {\n consoleSandbox(() => {\n console.warn(rejectionWarning);\n console.error(isObjectLike(reason) && 'stack' in reason ? reason.stack : reason);\n });\n } else if (mode === 'strict') {\n consoleSandbox(() => {\n console.warn(rejectionWarning);\n });\n logAndExitProcess(reason);\n }\n /* eslint-enable no-console */\n}\n"],"names":["defineIntegration","isObjectLike","isMatchingPattern","getClient","withActiveSpan","captureException","consoleSandbox","logAndExitProcess"],"mappings":"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"}

@@ -104,3 +104,3 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });

trackLogger(logger) {
if (logger && typeof logger === "object" && "levels" in logger) {
if (core.isObjectLike(logger) && "levels" in logger) {
logger[SENTRY_TRACK_SYMBOL] = "track";

@@ -110,3 +110,3 @@ }

untrackLogger(logger) {
if (logger && typeof logger === "object" && "levels" in logger) {
if (core.isObjectLike(logger) && "levels" in logger) {
logger[SENTRY_TRACK_SYMBOL] = "ignore";

@@ -113,0 +113,0 @@ }

@@ -1,1 +0,1 @@

{"version":3,"file":"pino.js","sources":["../../../src/integrations/pino.ts"],"sourcesContent":["import * as diagnosticsChannel from 'node:diagnostics_channel';\nimport type { Integration, IntegrationFn, LogSeverityLevel } from '@sentry/core';\nimport {\n _INTERNAL_captureLog,\n addExceptionMechanism,\n captureException,\n captureMessage,\n defineIntegration,\n severityLevelFromString,\n withScope,\n} from '@sentry/core';\n\nconst SENTRY_TRACK_SYMBOL = Symbol('sentry-track-pino-logger');\n\ntype LevelMapping = {\n // Fortunately pino uses the same levels as Sentry\n labels: { [level: number]: LogSeverityLevel };\n};\n\ntype Pino = {\n [key: symbol]: unknown;\n levels: LevelMapping;\n [SENTRY_TRACK_SYMBOL]?: 'track' | 'ignore';\n};\n\n/**\n * Gets a custom Pino key from a logger instance by searching for the symbol.\n * Pino uses non-global symbols like Symbol('pino.messageKey'): https://github.com/pinojs/pino/blob/8a816c0b1f72de5ae9181f3bb402109b66f7d812/lib/symbols.js\n */\nfunction getPinoKey(logger: Pino, symbolName: string, defaultKey: string): string {\n const symbols = Object.getOwnPropertySymbols(logger);\n const symbolString = `Symbol(${symbolName})`;\n for (const sym of symbols) {\n if (sym.toString() === symbolString) {\n const value = logger[sym];\n return typeof value === 'string' ? value : defaultKey;\n }\n }\n return defaultKey;\n}\n\ntype MergeObject = {\n [key: string]: unknown;\n err?: Error;\n};\n\ntype PinoHookArgs = [MergeObject, string, number];\n\ntype PinoOptions = {\n /**\n * Automatically instrument all Pino loggers.\n *\n * When set to `false`, only loggers marked with `pinoIntegration.trackLogger(logger)` will be captured.\n *\n * @default true\n */\n autoInstrument: boolean;\n /**\n * Options to enable capturing of error events.\n */\n error: {\n /**\n * Levels that trigger capturing of events.\n *\n * @default []\n */\n levels: LogSeverityLevel[];\n /**\n * By default, Sentry will mark captured errors as handled.\n * Set this to `false` if you want to mark them as unhandled instead.\n *\n * @default true\n */\n handled: boolean;\n };\n /**\n * Options to enable capturing of logs.\n */\n log: {\n /**\n * Levels that trigger capturing of logs. Logs are only captured if\n * `enableLogs` is enabled.\n *\n * @default [\"trace\", \"debug\", \"info\", \"warn\", \"error\", \"fatal\"]\n */\n levels: LogSeverityLevel[];\n };\n};\n\nconst DEFAULT_OPTIONS: PinoOptions = {\n autoInstrument: true,\n error: { levels: [], handled: true },\n log: { levels: ['trace', 'debug', 'info', 'warn', 'error', 'fatal'] },\n};\n\ntype DeepPartial<T> = {\n [P in keyof T]?: T[P] extends object ? Partial<T[P]> : T[P];\n};\n\ntype PinoResult = {\n level?: string;\n time?: string;\n pid?: number;\n hostname?: string;\n} & Record<string, unknown>;\n\nfunction stripIgnoredFields(result: PinoResult): PinoResult {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { level, time, pid, hostname, ...rest } = result;\n return rest;\n}\n\nconst _pinoIntegration = defineIntegration((userOptions: DeepPartial<PinoOptions> = {}) => {\n const options: PinoOptions = {\n autoInstrument: userOptions.autoInstrument !== false,\n error: { ...DEFAULT_OPTIONS.error, ...userOptions.error },\n log: { ...DEFAULT_OPTIONS.log, ...userOptions.log },\n };\n\n function shouldTrackLogger(logger: Pino): boolean {\n const override = logger[SENTRY_TRACK_SYMBOL];\n return override === 'track' || (override !== 'ignore' && options.autoInstrument);\n }\n\n return {\n name: 'Pino',\n setup: client => {\n const enableLogs = !!client.getOptions().enableLogs;\n\n const integratedChannel = diagnosticsChannel.tracingChannel('pino_asJson');\n\n function onPinoStart(self: Pino, args: PinoHookArgs, result: PinoResult): void {\n if (!shouldTrackLogger(self)) {\n return;\n }\n\n const resultObj = stripIgnoredFields(result);\n\n const [captureObj, message, levelNumber] = args;\n const level = self?.levels?.labels?.[levelNumber] || 'info';\n const messageKey = getPinoKey(self, 'pino.messageKey', 'msg');\n const logMessage = message || (resultObj?.[messageKey] as string | undefined) || '';\n\n if (enableLogs && options.log.levels.includes(level)) {\n const attributes: Record<string, unknown> = {\n ...resultObj,\n 'sentry.origin': 'auto.log.pino',\n 'pino.logger.level': levelNumber,\n };\n\n _INTERNAL_captureLog({ level, message: logMessage, attributes });\n }\n\n if (options.error.levels.includes(level)) {\n const errorKey = getPinoKey(self, 'pino.errorKey', 'err');\n\n // Attach the log message and remaining log fields (e.g. child logger\n // bindings, merge object fields) to the event. The serialized error is\n // excluded since it is captured as the event exception itself.\n const pinoContext: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(resultObj)) {\n if (key !== errorKey && key !== messageKey) {\n pinoContext[key] = value;\n }\n }\n if (logMessage) {\n pinoContext[messageKey] = logMessage;\n }\n\n const captureContext = {\n level: severityLevelFromString(level),\n contexts: { pino: pinoContext },\n };\n\n withScope(scope => {\n scope.addEventProcessor(event => {\n event.logger = 'pino';\n\n addExceptionMechanism(event, {\n handled: options.error.handled,\n type: 'auto.log.pino',\n });\n\n return event;\n });\n\n const error = captureObj[errorKey];\n if (error) {\n captureException(error, captureContext);\n return;\n }\n\n captureMessage(logMessage, captureContext);\n });\n }\n }\n\n integratedChannel.end.subscribe(data => {\n const {\n instance,\n arguments: args,\n result,\n } = data as { instance: Pino; arguments: PinoHookArgs; result: string };\n onPinoStart(instance, args, JSON.parse(result));\n });\n },\n };\n}) satisfies IntegrationFn;\n\ninterface PinoIntegrationFunction {\n (userOptions?: DeepPartial<PinoOptions>): Integration;\n /**\n * Marks a Pino logger to be tracked by the Pino integration.\n *\n * @param logger A Pino logger instance.\n */\n trackLogger(logger: unknown): void;\n /**\n * Marks a Pino logger to be ignored by the Pino integration.\n *\n * @param logger A Pino logger instance.\n */\n untrackLogger(logger: unknown): void;\n}\n\n/**\n * Integration for Pino logging library.\n * Captures Pino logs as Sentry logs and optionally captures some log levels as events.\n *\n * By default, all Pino loggers will be captured. To ignore a specific logger, use `pinoIntegration.untrackLogger(logger)`.\n *\n * If you disable automatic instrumentation with `autoInstrument: false`, you can mark specific loggers to be tracked with `pinoIntegration.trackLogger(logger)`.\n *\n * Requires Pino >=v8.0.0 and Node >=20.6.0 or >=18.19.0\n */\nexport const pinoIntegration = Object.assign(_pinoIntegration, {\n trackLogger(logger: unknown): void {\n if (logger && typeof logger === 'object' && 'levels' in logger) {\n (logger as Pino)[SENTRY_TRACK_SYMBOL] = 'track';\n }\n },\n untrackLogger(logger: unknown): void {\n if (logger && typeof logger === 'object' && 'levels' in logger) {\n (logger as Pino)[SENTRY_TRACK_SYMBOL] = 'ignore';\n }\n },\n}) as PinoIntegrationFunction;\n"],"names":["defineIntegration","_INTERNAL_captureLog","severityLevelFromString","withScope","addExceptionMechanism","captureException","captureMessage"],"mappings":"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"}
{"version":3,"file":"pino.js","sources":["../../../src/integrations/pino.ts"],"sourcesContent":["import * as diagnosticsChannel from 'node:diagnostics_channel';\nimport type { Integration, IntegrationFn, LogSeverityLevel } from '@sentry/core';\nimport {\n _INTERNAL_captureLog,\n addExceptionMechanism,\n captureException,\n captureMessage,\n defineIntegration,\n isObjectLike,\n severityLevelFromString,\n withScope,\n} from '@sentry/core';\n\nconst SENTRY_TRACK_SYMBOL = Symbol('sentry-track-pino-logger');\n\ntype LevelMapping = {\n // Fortunately pino uses the same levels as Sentry\n labels: { [level: number]: LogSeverityLevel };\n};\n\ntype Pino = {\n [key: symbol]: unknown;\n levels: LevelMapping;\n [SENTRY_TRACK_SYMBOL]?: 'track' | 'ignore';\n};\n\n/**\n * Gets a custom Pino key from a logger instance by searching for the symbol.\n * Pino uses non-global symbols like Symbol('pino.messageKey'): https://github.com/pinojs/pino/blob/8a816c0b1f72de5ae9181f3bb402109b66f7d812/lib/symbols.js\n */\nfunction getPinoKey(logger: Pino, symbolName: string, defaultKey: string): string {\n const symbols = Object.getOwnPropertySymbols(logger);\n const symbolString = `Symbol(${symbolName})`;\n for (const sym of symbols) {\n if (sym.toString() === symbolString) {\n const value = logger[sym];\n return typeof value === 'string' ? value : defaultKey;\n }\n }\n return defaultKey;\n}\n\ntype MergeObject = {\n [key: string]: unknown;\n err?: Error;\n};\n\ntype PinoHookArgs = [MergeObject, string, number];\n\ntype PinoOptions = {\n /**\n * Automatically instrument all Pino loggers.\n *\n * When set to `false`, only loggers marked with `pinoIntegration.trackLogger(logger)` will be captured.\n *\n * @default true\n */\n autoInstrument: boolean;\n /**\n * Options to enable capturing of error events.\n */\n error: {\n /**\n * Levels that trigger capturing of events.\n *\n * @default []\n */\n levels: LogSeverityLevel[];\n /**\n * By default, Sentry will mark captured errors as handled.\n * Set this to `false` if you want to mark them as unhandled instead.\n *\n * @default true\n */\n handled: boolean;\n };\n /**\n * Options to enable capturing of logs.\n */\n log: {\n /**\n * Levels that trigger capturing of logs. Logs are only captured if\n * `enableLogs` is enabled.\n *\n * @default [\"trace\", \"debug\", \"info\", \"warn\", \"error\", \"fatal\"]\n */\n levels: LogSeverityLevel[];\n };\n};\n\nconst DEFAULT_OPTIONS: PinoOptions = {\n autoInstrument: true,\n error: { levels: [], handled: true },\n log: { levels: ['trace', 'debug', 'info', 'warn', 'error', 'fatal'] },\n};\n\ntype DeepPartial<T> = {\n [P in keyof T]?: T[P] extends object ? Partial<T[P]> : T[P];\n};\n\ntype PinoResult = {\n level?: string;\n time?: string;\n pid?: number;\n hostname?: string;\n} & Record<string, unknown>;\n\nfunction stripIgnoredFields(result: PinoResult): PinoResult {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { level, time, pid, hostname, ...rest } = result;\n return rest;\n}\n\nconst _pinoIntegration = defineIntegration((userOptions: DeepPartial<PinoOptions> = {}) => {\n const options: PinoOptions = {\n autoInstrument: userOptions.autoInstrument !== false,\n error: { ...DEFAULT_OPTIONS.error, ...userOptions.error },\n log: { ...DEFAULT_OPTIONS.log, ...userOptions.log },\n };\n\n function shouldTrackLogger(logger: Pino): boolean {\n const override = logger[SENTRY_TRACK_SYMBOL];\n return override === 'track' || (override !== 'ignore' && options.autoInstrument);\n }\n\n return {\n name: 'Pino',\n setup: client => {\n const enableLogs = !!client.getOptions().enableLogs;\n\n const integratedChannel = diagnosticsChannel.tracingChannel('pino_asJson');\n\n function onPinoStart(self: Pino, args: PinoHookArgs, result: PinoResult): void {\n if (!shouldTrackLogger(self)) {\n return;\n }\n\n const resultObj = stripIgnoredFields(result);\n\n const [captureObj, message, levelNumber] = args;\n const level = self?.levels?.labels?.[levelNumber] || 'info';\n const messageKey = getPinoKey(self, 'pino.messageKey', 'msg');\n const logMessage = message || (resultObj?.[messageKey] as string | undefined) || '';\n\n if (enableLogs && options.log.levels.includes(level)) {\n const attributes: Record<string, unknown> = {\n ...resultObj,\n 'sentry.origin': 'auto.log.pino',\n 'pino.logger.level': levelNumber,\n };\n\n _INTERNAL_captureLog({ level, message: logMessage, attributes });\n }\n\n if (options.error.levels.includes(level)) {\n const errorKey = getPinoKey(self, 'pino.errorKey', 'err');\n\n // Attach the log message and remaining log fields (e.g. child logger\n // bindings, merge object fields) to the event. The serialized error is\n // excluded since it is captured as the event exception itself.\n const pinoContext: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(resultObj)) {\n if (key !== errorKey && key !== messageKey) {\n pinoContext[key] = value;\n }\n }\n if (logMessage) {\n pinoContext[messageKey] = logMessage;\n }\n\n const captureContext = {\n level: severityLevelFromString(level),\n contexts: { pino: pinoContext },\n };\n\n withScope(scope => {\n scope.addEventProcessor(event => {\n event.logger = 'pino';\n\n addExceptionMechanism(event, {\n handled: options.error.handled,\n type: 'auto.log.pino',\n });\n\n return event;\n });\n\n const error = captureObj[errorKey];\n if (error) {\n captureException(error, captureContext);\n return;\n }\n\n captureMessage(logMessage, captureContext);\n });\n }\n }\n\n integratedChannel.end.subscribe(data => {\n const {\n instance,\n arguments: args,\n result,\n } = data as { instance: Pino; arguments: PinoHookArgs; result: string };\n onPinoStart(instance, args, JSON.parse(result));\n });\n },\n };\n}) satisfies IntegrationFn;\n\ninterface PinoIntegrationFunction {\n (userOptions?: DeepPartial<PinoOptions>): Integration;\n /**\n * Marks a Pino logger to be tracked by the Pino integration.\n *\n * @param logger A Pino logger instance.\n */\n trackLogger(logger: unknown): void;\n /**\n * Marks a Pino logger to be ignored by the Pino integration.\n *\n * @param logger A Pino logger instance.\n */\n untrackLogger(logger: unknown): void;\n}\n\n/**\n * Integration for Pino logging library.\n * Captures Pino logs as Sentry logs and optionally captures some log levels as events.\n *\n * By default, all Pino loggers will be captured. To ignore a specific logger, use `pinoIntegration.untrackLogger(logger)`.\n *\n * If you disable automatic instrumentation with `autoInstrument: false`, you can mark specific loggers to be tracked with `pinoIntegration.trackLogger(logger)`.\n *\n * Requires Pino >=v8.0.0 and Node >=20.6.0 or >=18.19.0\n */\nexport const pinoIntegration = Object.assign(_pinoIntegration, {\n trackLogger(logger: unknown): void {\n if (isObjectLike(logger) && 'levels' in logger) {\n (logger as Pino)[SENTRY_TRACK_SYMBOL] = 'track';\n }\n },\n untrackLogger(logger: unknown): void {\n if (isObjectLike(logger) && 'levels' in logger) {\n (logger as Pino)[SENTRY_TRACK_SYMBOL] = 'ignore';\n }\n },\n}) as PinoIntegrationFunction;\n"],"names":["defineIntegration","_INTERNAL_captureLog","severityLevelFromString","withScope","addExceptionMechanism","captureException","captureMessage","isObjectLike"],"mappings":"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"}

@@ -26,3 +26,3 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });

});
if (!isObject(info)) {
if (!core.isObjectLike(info)) {
return;

@@ -57,5 +57,2 @@ }

}
function isObject(anything) {
return typeof anything === "object" && anything != null;
}
const WINSTON_LEVEL_TO_LOG_SEVERITY_LEVEL_MAP = {

@@ -62,0 +59,0 @@ // npm

@@ -1,1 +0,1 @@

{"version":3,"file":"winston.js","sources":["../../../src/integrations/winston.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/ban-ts-comment */\nimport type { LogSeverityLevel } from '@sentry/core';\nimport { debug } from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { captureLog } from '../logs/capture';\n\nconst DEFAULT_CAPTURED_LEVELS: Array<LogSeverityLevel> = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'];\n\n// See: https://github.com/winstonjs/triple-beam\nconst LEVEL_SYMBOL = Symbol.for('level');\nconst MESSAGE_SYMBOL = Symbol.for('message');\nconst SPLAT_SYMBOL = Symbol.for('splat');\n\n/**\n * Options for the Sentry Winston transport.\n */\ninterface WinstonTransportOptions {\n /**\n * Use this option to filter which levels should be captured. By default, all levels are captured.\n *\n * @example\n * ```ts\n * const SentryWinstonTransport = Sentry.createSentryWinstonTransport(Transport, {\n * // Only capture error and warn logs\n * levels: ['error', 'warn'],\n * });\n * ```\n */\n levels?: Array<LogSeverityLevel>;\n\n /**\n * Use this option to map custom levels to Sentry log severity levels.\n *\n * @example\n * ```ts\n * const SentryWinstonTransport = Sentry.createSentryWinstonTransport(Transport, {\n * customLevelMap: {\n * myCustomLevel: 'info',\n * customError: 'error',\n * },\n * });\n * ```\n */\n customLevelMap?: Record<string, LogSeverityLevel>;\n}\n\n/**\n * Creates a new Sentry Winston transport that fowards logs to Sentry. Requires the `enableLogs` option to be enabled.\n *\n * Supports Winston 3.x.x.\n *\n * @param TransportClass - The Winston transport class to extend.\n * @returns The extended transport class.\n *\n * @example\n * ```ts\n * const winston = require('winston');\n * const Transport = require('winston-transport');\n *\n * const SentryWinstonTransport = Sentry.createSentryWinstonTransport(Transport);\n *\n * const logger = winston.createLogger({\n * transports: [new SentryWinstonTransport()],\n * });\n * ```\n */\nexport function createSentryWinstonTransport<TransportStreamInstance extends object>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n TransportClass: new (options?: any) => TransportStreamInstance,\n sentryWinstonOptions?: WinstonTransportOptions,\n): typeof TransportClass {\n // @ts-ignore - We know this is safe because SentryWinstonTransport extends TransportClass\n class SentryWinstonTransport extends TransportClass {\n private _levels: Set<LogSeverityLevel>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public constructor(options?: any) {\n super(options);\n this._levels = new Set(sentryWinstonOptions?.levels ?? DEFAULT_CAPTURED_LEVELS);\n }\n\n /**\n * Forwards a winston log to the Sentry SDK.\n */\n public log(info: unknown, callback: () => void): void {\n try {\n setImmediate(() => {\n // @ts-ignore - We know this is safe because SentryWinstonTransport extends TransportClass\n this.emit('logged', info);\n });\n\n if (!isObject(info)) {\n return;\n }\n\n const levelFromSymbol = info[LEVEL_SYMBOL];\n\n // See: https://github.com/winstonjs/winston?tab=readme-ov-file#streams-objectmode-and-info-objects\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { level, message, timestamp, ...attributes } = info;\n // Remove all symbols from the remaining attributes\n attributes[LEVEL_SYMBOL] = undefined;\n attributes[MESSAGE_SYMBOL] = undefined;\n attributes[SPLAT_SYMBOL] = undefined;\n\n const customLevel = sentryWinstonOptions?.customLevelMap?.[levelFromSymbol as string];\n const winstonLogLevel = WINSTON_LEVEL_TO_LOG_SEVERITY_LEVEL_MAP[levelFromSymbol as string];\n const logSeverityLevel = customLevel ?? winstonLogLevel ?? 'info';\n\n if (this._levels.has(logSeverityLevel)) {\n captureLog(logSeverityLevel, message as string, {\n ...attributes,\n 'sentry.origin': 'auto.log.winston',\n });\n } else if (!customLevel && !winstonLogLevel) {\n DEBUG_BUILD &&\n debug.log(\n `Winston log level ${levelFromSymbol} is not captured by Sentry. Please add ${levelFromSymbol} to the \"customLevelMap\" option of the Sentry Winston transport.`,\n );\n }\n } catch {\n // do nothing\n }\n\n if (callback) {\n callback();\n }\n }\n }\n\n return SentryWinstonTransport as typeof TransportClass;\n}\n\nfunction isObject(anything: unknown): anything is Record<string | symbol, unknown> {\n return typeof anything === 'object' && anything != null;\n}\n\n// npm\n// {\n// error: 0,\n// warn: 1,\n// info: 2,\n// http: 3,\n// verbose: 4,\n// debug: 5,\n// silly: 6\n// }\n//\n// syslog\n// {\n// emerg: 0,\n// alert: 1,\n// crit: 2,\n// error: 3,\n// warning: 4,\n// notice: 5,\n// info: 6,\n// debug: 7,\n// }\nconst WINSTON_LEVEL_TO_LOG_SEVERITY_LEVEL_MAP: Record<string, LogSeverityLevel> = {\n // npm\n silly: 'trace',\n // npm and syslog\n debug: 'debug',\n // npm\n verbose: 'debug',\n // npm\n http: 'debug',\n // npm and syslog\n info: 'info',\n // syslog\n notice: 'info',\n // npm\n warn: 'warn',\n // syslog\n warning: 'warn',\n // npm and syslog\n error: 'error',\n // syslog\n emerg: 'fatal',\n // syslog\n alert: 'fatal',\n // syslog\n crit: 'fatal',\n};\n"],"names":["captureLog","DEBUG_BUILD","debug"],"mappings":"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"}
{"version":3,"file":"winston.js","sources":["../../../src/integrations/winston.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/ban-ts-comment */\nimport type { LogSeverityLevel } from '@sentry/core';\nimport { debug, isObjectLike } from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { captureLog } from '../logs/capture';\n\nconst DEFAULT_CAPTURED_LEVELS: Array<LogSeverityLevel> = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'];\n\n// See: https://github.com/winstonjs/triple-beam\nconst LEVEL_SYMBOL = Symbol.for('level');\nconst MESSAGE_SYMBOL = Symbol.for('message');\nconst SPLAT_SYMBOL = Symbol.for('splat');\n\n/**\n * Options for the Sentry Winston transport.\n */\ninterface WinstonTransportOptions {\n /**\n * Use this option to filter which levels should be captured. By default, all levels are captured.\n *\n * @example\n * ```ts\n * const SentryWinstonTransport = Sentry.createSentryWinstonTransport(Transport, {\n * // Only capture error and warn logs\n * levels: ['error', 'warn'],\n * });\n * ```\n */\n levels?: Array<LogSeverityLevel>;\n\n /**\n * Use this option to map custom levels to Sentry log severity levels.\n *\n * @example\n * ```ts\n * const SentryWinstonTransport = Sentry.createSentryWinstonTransport(Transport, {\n * customLevelMap: {\n * myCustomLevel: 'info',\n * customError: 'error',\n * },\n * });\n * ```\n */\n customLevelMap?: Record<string, LogSeverityLevel>;\n}\n\n/**\n * Creates a new Sentry Winston transport that fowards logs to Sentry. Requires the `enableLogs` option to be enabled.\n *\n * Supports Winston 3.x.x.\n *\n * @param TransportClass - The Winston transport class to extend.\n * @returns The extended transport class.\n *\n * @example\n * ```ts\n * const winston = require('winston');\n * const Transport = require('winston-transport');\n *\n * const SentryWinstonTransport = Sentry.createSentryWinstonTransport(Transport);\n *\n * const logger = winston.createLogger({\n * transports: [new SentryWinstonTransport()],\n * });\n * ```\n */\nexport function createSentryWinstonTransport<TransportStreamInstance extends object>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n TransportClass: new (options?: any) => TransportStreamInstance,\n sentryWinstonOptions?: WinstonTransportOptions,\n): typeof TransportClass {\n // @ts-ignore - We know this is safe because SentryWinstonTransport extends TransportClass\n class SentryWinstonTransport extends TransportClass {\n private _levels: Set<LogSeverityLevel>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public constructor(options?: any) {\n super(options);\n this._levels = new Set(sentryWinstonOptions?.levels ?? DEFAULT_CAPTURED_LEVELS);\n }\n\n /**\n * Forwards a winston log to the Sentry SDK.\n */\n public log(info: unknown, callback: () => void): void {\n try {\n setImmediate(() => {\n // @ts-ignore - We know this is safe because SentryWinstonTransport extends TransportClass\n this.emit('logged', info);\n });\n\n if (!isObjectLike(info)) {\n return;\n }\n\n const levelFromSymbol = info[LEVEL_SYMBOL];\n\n // See: https://github.com/winstonjs/winston?tab=readme-ov-file#streams-objectmode-and-info-objects\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { level, message, timestamp, ...attributes } = info;\n // Remove all symbols from the remaining attributes\n attributes[LEVEL_SYMBOL] = undefined;\n attributes[MESSAGE_SYMBOL] = undefined;\n attributes[SPLAT_SYMBOL] = undefined;\n\n const customLevel = sentryWinstonOptions?.customLevelMap?.[levelFromSymbol as string];\n const winstonLogLevel = WINSTON_LEVEL_TO_LOG_SEVERITY_LEVEL_MAP[levelFromSymbol as string];\n const logSeverityLevel = customLevel ?? winstonLogLevel ?? 'info';\n\n if (this._levels.has(logSeverityLevel)) {\n captureLog(logSeverityLevel, message as string, {\n ...attributes,\n 'sentry.origin': 'auto.log.winston',\n });\n } else if (!customLevel && !winstonLogLevel) {\n DEBUG_BUILD &&\n debug.log(\n `Winston log level ${levelFromSymbol} is not captured by Sentry. Please add ${levelFromSymbol} to the \"customLevelMap\" option of the Sentry Winston transport.`,\n );\n }\n } catch {\n // do nothing\n }\n\n if (callback) {\n callback();\n }\n }\n }\n\n return SentryWinstonTransport as typeof TransportClass;\n}\n\n// npm\n// {\n// error: 0,\n// warn: 1,\n// info: 2,\n// http: 3,\n// verbose: 4,\n// debug: 5,\n// silly: 6\n// }\n//\n// syslog\n// {\n// emerg: 0,\n// alert: 1,\n// crit: 2,\n// error: 3,\n// warning: 4,\n// notice: 5,\n// info: 6,\n// debug: 7,\n// }\nconst WINSTON_LEVEL_TO_LOG_SEVERITY_LEVEL_MAP: Record<string, LogSeverityLevel> = {\n // npm\n silly: 'trace',\n // npm and syslog\n debug: 'debug',\n // npm\n verbose: 'debug',\n // npm\n http: 'debug',\n // npm and syslog\n info: 'info',\n // syslog\n notice: 'info',\n // npm\n warn: 'warn',\n // syslog\n warning: 'warn',\n // npm and syslog\n error: 'error',\n // syslog\n emerg: 'fatal',\n // syslog\n alert: 'fatal',\n // syslog\n crit: 'fatal',\n};\n"],"names":["isObjectLike","captureLog","DEBUG_BUILD","debug"],"mappings":";;;;;;AAMA,MAAM,0BAAmD,CAAC,OAAA,EAAS,SAAS,MAAA,EAAQ,MAAA,EAAQ,SAAS,OAAO,CAAA;AAG5G,MAAM,YAAA,mBAAe,MAAA,CAAO,GAAA,CAAI,OAAO,CAAA;AACvC,MAAM,cAAA,mBAAiB,MAAA,CAAO,GAAA,CAAI,SAAS,CAAA;AAC3C,MAAM,YAAA,mBAAe,MAAA,CAAO,GAAA,CAAI,OAAO,CAAA;AAuDhC,SAAS,4BAAA,CAEd,gBACA,oBAAA,EACuB;AAAA,EAEvB,MAAM,+BAA+B,cAAA,CAAe;AAAA;AAAA,IAG3C,YAAY,OAAA,EAAe;AAChC,MAAA,KAAA,CAAM,OAAO,CAAA;AACb,MAAA,IAAA,CAAK,OAAA,GAAU,IAAI,GAAA,CAAI,oBAAA,EAAsB,UAAU,uBAAuB,CAAA;AAAA,IAChF;AAAA;AAAA;AAAA;AAAA,IAKO,GAAA,CAAI,MAAe,QAAA,EAA4B;AACpD,MAAA,IAAI;AACF,QAAA,YAAA,CAAa,MAAM;AAEjB,UAAA,IAAA,CAAK,IAAA,CAAK,UAAU,IAAI,CAAA;AAAA,QAC1B,CAAC,CAAA;AAED,QAAA,IAAI,CAACA,iBAAA,CAAa,IAAI,CAAA,EAAG;AACvB,UAAA;AAAA,QACF;AAEA,QAAA,MAAM,eAAA,GAAkB,KAAK,YAAY,CAAA;AAIzC,QAAA,MAAM,EAAE,KAAA,EAAO,OAAA,EAAS,SAAA,EAAW,GAAG,YAAW,GAAI,IAAA;AAErD,QAAA,UAAA,CAAW,YAAY,CAAA,GAAI,KAAA,CAAA;AAC3B,QAAA,UAAA,CAAW,cAAc,CAAA,GAAI,KAAA,CAAA;AAC7B,QAAA,UAAA,CAAW,YAAY,CAAA,GAAI,KAAA,CAAA;AAE3B,QAAA,MAAM,WAAA,GAAc,oBAAA,EAAsB,cAAA,GAAiB,eAAyB,CAAA;AACpF,QAAA,MAAM,eAAA,GAAkB,wCAAwC,eAAyB,CAAA;AACzF,QAAA,MAAM,gBAAA,GAAmB,eAAe,eAAA,IAAmB,MAAA;AAE3D,QAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,gBAAgB,CAAA,EAAG;AACtC,UAAAC,kBAAA,CAAW,kBAAkB,OAAA,EAAmB;AAAA,YAC9C,GAAG,UAAA;AAAA,YACH,eAAA,EAAiB;AAAA,WAClB,CAAA;AAAA,QACH,CAAA,MAAA,IAAW,CAAC,WAAA,IAAe,CAAC,eAAA,EAAiB;AAC3C,UAAAC,sBAAA,IACEC,UAAA,CAAM,GAAA;AAAA,YACJ,CAAA,kBAAA,EAAqB,eAAe,CAAA,uCAAA,EAA0C,eAAe,CAAA,gEAAA;AAAA,WAC/F;AAAA,QACJ;AAAA,MACF,CAAA,CAAA,MAAQ;AAAA,MAER;AAEA,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,QAAA,EAAS;AAAA,MACX;AAAA,IACF;AAAA;AAGF,EAAA,OAAO,sBAAA;AACT;AAwBA,MAAM,uCAAA,GAA4E;AAAA;AAAA,EAEhF,KAAA,EAAO,OAAA;AAAA;AAAA,EAEP,KAAA,EAAO,OAAA;AAAA;AAAA,EAEP,OAAA,EAAS,OAAA;AAAA;AAAA,EAET,IAAA,EAAM,OAAA;AAAA;AAAA,EAEN,IAAA,EAAM,MAAA;AAAA;AAAA,EAEN,MAAA,EAAQ,MAAA;AAAA;AAAA,EAER,IAAA,EAAM,MAAA;AAAA;AAAA,EAEN,OAAA,EAAS,MAAA;AAAA;AAAA,EAET,KAAA,EAAO,OAAA;AAAA;AAAA,EAEP,KAAA,EAAO,OAAA;AAAA;AAAA,EAEP,KAAA,EAAO,OAAA;AAAA;AAAA,EAEP,IAAA,EAAM;AACR,CAAA;;;;"}
export { httpIntegration } from './integrations/http/index.js';
export { httpServerSpansIntegration } from './integrations/http/httpServerSpansIntegration.js';
export { httpServerIntegration } from './integrations/http/httpServerIntegration.js';
export { SentryHttpInstrumentation } from './integrations/http/SentryHttpInstrumentation.js';
export { SentryHttpInstrumentation, instrumentHttpOutgoingRequests } from './integrations/http/SentryHttpInstrumentation.js';
export { nativeNodeFetchIntegration } from './integrations/node-fetch/index.js';

@@ -6,0 +6,0 @@ export { instrumentUndici } from './integrations/node-fetch/undici-instrumentation.js';

@@ -8,3 +8,3 @@ import { types } from 'node:util';

const { isPromise } = types;
const base64WorkerScript = "LyohIEBzZW50cnkvbm9kZS1jb3JlIDEwLjY0LjAgKDU3MzZhMzgpIHwgaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdCAqLwppbXBvcnR7U2Vzc2lvbiBhcyB0fWZyb20ibm9kZTppbnNwZWN0b3IiO2ltcG9ydHt3b3JrZXJEYXRhIGFzIG4scGFyZW50UG9ydCBhcyBlfWZyb20ibm9kZTp3b3JrZXJfdGhyZWFkcyI7aW1wb3J0e3Bvc2l4IGFzIHIsc2VwIGFzIG99ZnJvbSJub2RlOnBhdGgiO2ltcG9ydCphcyBpIGZyb20ibm9kZTpodHRwIjtpbXBvcnQqYXMgcyBmcm9tIm5vZGU6aHR0cHMiO2ltcG9ydHtSZWFkYWJsZSBhcyBjfWZyb20ibm9kZTpzdHJlYW0iO2ltcG9ydHtjcmVhdGVHemlwIGFzIHV9ZnJvbSJub2RlOnpsaWIiO2ltcG9ydCphcyBhIGZyb20ibm9kZTpuZXQiO2ltcG9ydCphcyBmIGZyb20ibm9kZTp0bHMiO2NvbnN0IGg9InVuZGVmaW5lZCI9PXR5cGVvZiBfX1NFTlRSWV9ERUJVR19ffHxfX1NFTlRSWV9ERUJVR19fLHA9Z2xvYmFsVGhpcyxkPSIxMC42NC4wIjtmdW5jdGlvbiBsKCl7cmV0dXJuIGcocCkscH1mdW5jdGlvbiBnKHQpe2NvbnN0IG49dC5fX1NFTlRSWV9fPXQuX19TRU5UUllfX3x8e307cmV0dXJuIG4udmVyc2lvbj1uLnZlcnNpb258fGQsbltkXT1uW2RdfHx7fX1mdW5jdGlvbiBtKHQsbixlPXApe2NvbnN0IHI9ZS5fX1NFTlRSWV9fPWUuX19TRU5UUllfX3x8e30sbz1yW2RdPXJbZF18fHt9O3JldHVybiBvW3RdfHwob1t0XT1uKCkpfWNvbnN0IHk9e307ZnVuY3Rpb24gYih0KXtpZighKCJjb25zb2xlImluIHApKXJldHVybiB0KCk7Y29uc3Qgbj1wLmNvbnNvbGUsZT17fSxyPU9iamVjdC5rZXlzKHkpO3IuZm9yRWFjaCh0PT57Y29uc3Qgcj15W3RdO2VbdF09blt0XSxuW3RdPXJ9KTt0cnl7cmV0dXJuIHQoKX1maW5hbGx5e3IuZm9yRWFjaCh0PT57blt0XT1lW3RdfSl9fWZ1bmN0aW9uIHYoKXtyZXR1cm4gUygpLmVuYWJsZWR9ZnVuY3Rpb24gXyh0LC4uLm4pe2gmJnYoKSYmYigoKT0+e3AuY29uc29sZVt0XShgU2VudHJ5IExvZ2dlciBbJHt0fV06YCwuLi5uKX0pfWZ1bmN0aW9uIFMoKXtyZXR1cm4gaD9tKCJsb2dnZXJTZXR0aW5ncyIsKCk9Pih7ZW5hYmxlZDohMX0pKTp7ZW5hYmxlZDohMX19Y29uc3Qgdz17ZW5hYmxlOmZ1bmN0aW9uKCl7UygpLmVuYWJsZWQ9ITB9LGRpc2FibGU6ZnVuY3Rpb24oKXtTKCkuZW5hYmxlZD0hMX0saXNFbmFibGVkOnYsbG9nOmZ1bmN0aW9uKC4uLnQpe18oImxvZyIsLi4udCl9LHdhcm46ZnVuY3Rpb24oLi4udCl7Xygid2FybiIsLi4udCl9LGVycm9yOmZ1bmN0aW9uKC4uLnQpe18oImVycm9yIiwuLi50KX19LCQ9L2NhcHR1cmVNZXNzYWdlfGNhcHR1cmVFeGNlcHRpb24vO2Z1bmN0aW9uIEUodCl7cmV0dXJuIHRbdC5sZW5ndGgtMV18fHt9fWNvbnN0IHg9Ijxhbm9ueW1vdXM+Ijtjb25zdCBOPU9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7ZnVuY3Rpb24gQyh0LG4pe3JldHVybiBOLmNhbGwodCk9PT1gW29iamVjdCAke259XWB9ZnVuY3Rpb24gaih0KXtyZXR1cm4gQm9vbGVhbih0Py50aGVuJiYiZnVuY3Rpb24iPT10eXBlb2YgdC50aGVuKX1mdW5jdGlvbiBSKHQsbil7dHJ5e3JldHVybiB0IGluc3RhbmNlb2Ygbn1jYXRjaHtyZXR1cm4hMX19ZnVuY3Rpb24gQSh0KXtpZihmdW5jdGlvbih0KXtzd2l0Y2goTi5jYWxsKHQpKXtjYXNlIltvYmplY3QgRXJyb3JdIjpjYXNlIltvYmplY3QgRXhjZXB0aW9uXSI6Y2FzZSJbb2JqZWN0IERPTUV4Y2VwdGlvbl0iOmNhc2UiW29iamVjdCBXZWJBc3NlbWJseS5FeGNlcHRpb25dIjpyZXR1cm4hMDtkZWZhdWx0OnJldHVybiBSKHQsRXJyb3IpfX0odCkpcmV0dXJue21lc3NhZ2U6dC5tZXNzYWdlLG5hbWU6dC5uYW1lLHN0YWNrOnQuc3RhY2ssLi4uSSh0KX07aWYobj10LCJ1bmRlZmluZWQiIT10eXBlb2YgRXZlbnQmJlIobixFdmVudCkpe2NvbnN0e3R5cGU6bix0YXJnZXQ6ZSxjdXJyZW50VGFyZ2V0OnIsZGV0YWlsOm99PXQ7cmV0dXJue3R5cGU6bix0YXJnZXQ6ZSxjdXJyZW50VGFyZ2V0OnIsLi4ubz97ZGV0YWlsOm99Ont9LC4uLkkodCl9fXZhciBuO3JldHVybiB0fWZ1bmN0aW9uIEkodCl7cmV0dXJuIm9iamVjdCI9PXR5cGVvZiB0JiZudWxsIT09dD9PYmplY3QuZnJvbUVudHJpZXMoT2JqZWN0LmVudHJpZXModCkpOnt9fWxldCBPO2Z1bmN0aW9uIFQodCl7aWYodm9pZCAwIT09TylyZXR1cm4gTz9PKHQpOnQoKTtjb25zdCBuPVN5bWJvbC5mb3IoIl9fU0VOVFJZX1NBRkVfUkFORE9NX0lEX1dSQVBQRVJfXyIpLGU9cDtyZXR1cm4gbiBpbiBlJiYiZnVuY3Rpb24iPT10eXBlb2YgZVtuXT8oTz1lW25dLE8odCkpOihPPW51bGwsdCgpKX1mdW5jdGlvbiBrKCl7cmV0dXJuIFQoKCk9Pk1hdGgucmFuZG9tKCkpfWZ1bmN0aW9uIFAoKXtyZXR1cm4gVCgoKT0+RGF0ZS5ub3coKSl9Y29uc3QgRD1TeW1ib2wuZm9yKCJzZW50cnkuc2tpcE5vcm1hbGl6YXRpb24iKSxVPVN5bWJvbC5mb3IoInNlbnRyeS5vdmVycmlkZU5vcm1hbGl6YXRpb25EZXB0aCIpO2Z1bmN0aW9uIEIodCxuPTEwMCxlPTEvMCl7dHJ5e3JldHVybiBMKCIiLHQsbixlKX1jYXRjaCh0KXtyZXR1cm57RVJST1I6YCoqbm9uLXNlcmlhbGl6YWJsZSoqICgke3R9KWB9fX1mdW5jdGlvbiBMKHQsbixlPTEvMCxyPTEvMCxvPWZ1bmN0aW9uKCl7Y29uc3QgdD1uZXcgV2Vha1NldDtmdW5jdGlvbiBuKG4pe3JldHVybiEhdC5oYXMobil8fCh0LmFkZChuKSwhMSl9ZnVuY3Rpb24gZShuKXt0LmRlbGV0ZShuKX1yZXR1cm5bbixlXX0oKSl7Y29uc3RbaSxzXT1vO2lmKG51bGw9PW58fFsiYm9vbGVhbiIsInN0cmluZyJdLmluY2x1ZGVzKHR5cGVvZiBuKXx8Im51bWJlciI9PXR5cGVvZiBuJiZOdW1iZXIuaXNGaW5pdGUobikpcmV0dXJuIG47Y29uc3QgYz1mdW5jdGlvbih0LG4pe3RyeXtpZigidW5kZWZpbmVkIiE9dHlwZW9mIGdsb2JhbCYmbj09PWdsb2JhbClyZXR1cm4iW0dsb2JhbF0iO2lmKCJudW1iZXIiPT10eXBlb2YgbiYmIU51bWJlci5pc0Zpbml0ZShuKSlyZXR1cm5gWyR7bn1dYDtpZigiZnVuY3Rpb24iPT10eXBlb2YgbilyZXR1cm5gW0Z1bmN0aW9uOiAke2Z1bmN0aW9uKHQpe3RyeXtyZXR1cm4gdCYmImZ1bmN0aW9uIj09dHlwZW9mIHQmJnQubmFtZXx8eH1jYXRjaHtyZXR1cm4geH19KG4pfV1gO2lmKCJzeW1ib2wiPT10eXBlb2YgbilyZXR1cm5gWyR7U3RyaW5nKG4pfV1gO2lmKCJiaWdpbnQiPT10eXBlb2YgbilyZXR1cm5gW0JpZ0ludDogJHtTdHJpbmcobil9XWA7Y29uc3QgdD1mdW5jdGlvbih0KXtjb25zdCBuPU9iamVjdC5nZXRQcm90b3R5cGVPZih0KTtyZXR1cm4gbj8uY29uc3RydWN0b3I/bi5jb25zdHJ1Y3Rvci5uYW1lOiJudWxsIHByb3RvdHlwZSJ9KG4pO3JldHVybmBbb2JqZWN0ICR7dH1dYH1jYXRjaCh0KXtyZXR1cm5gKipub24tc2VyaWFsaXphYmxlKiogKCR7dH0pYH19KDAsbik7aWYoIWMuc3RhcnRzV2l0aCgiW29iamVjdCAiKSlyZXR1cm4gYztpZihmdW5jdGlvbih0KXtyZXR1cm4gQm9vbGVhbih0W0RdKX0obikpcmV0dXJuIG47Y29uc3QgdT1mdW5jdGlvbih0KXtjb25zdCBuPXRbVV07cmV0dXJuIm51bWJlciI9PXR5cGVvZiBuP246dm9pZCAwfShuKSxhPXZvaWQgMCE9PXU/dTplO2lmKDA9PT1hKXJldHVybiBjLnJlcGxhY2UoIm9iamVjdCAiLCIiKTtpZihpKG4pKXJldHVybiJbQ2lyY3VsYXIgfl0iO2NvbnN0IGY9bjtpZihmJiYiZnVuY3Rpb24iPT10eXBlb2YgZi50b0pTT04pdHJ5e3JldHVybiBMKCIiLGYudG9KU09OKCksYS0xLHIsbyl9Y2F0Y2h7fWNvbnN0IGg9QXJyYXkuaXNBcnJheShuKT9bXTp7fTtsZXQgcD0wO2NvbnN0IGQ9QShuKTtmb3IoY29uc3QgdCBpbiBkKXtpZighT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGQsdCkpY29udGludWU7aWYocD49cil7aFt0XT0iW01heFByb3BlcnRpZXMgfl0iO2JyZWFrfWNvbnN0IG49ZFt0XTtoW3RdPUwodCxuLGEtMSxyLG8pLHArK31yZXR1cm4gcyhuKSxofWZ1bmN0aW9uIE0odCxuKXtjb25zdCBlPW4ucmVwbGFjZSgvXFwvZywiLyIpLnJlcGxhY2UoL1t8XFx7fSgpW1xdXiQrKj8uXS9nLCJcXCQmIik7bGV0IHI9dDt0cnl7cj1kZWNvZGVVUkkodCl9Y2F0Y2h7fXJldHVybiByLnJlcGxhY2UoL1xcL2csIi8iKS5yZXBsYWNlKC93ZWJwYWNrOlwvPy9nLCIiKS5yZXBsYWNlKG5ldyBSZWdFeHAoYChmaWxlOi8vKT8vKiR7ZX0vKmAsImlnIiksImFwcDovLy8iKX1mdW5jdGlvbiB6KHQsbj0wKXtyZXR1cm4ic3RyaW5nIiE9dHlwZW9mIHR8fDA9PT1ufHx0Lmxlbmd0aDw9bj90OmAke3Quc2xpY2UoMCxuKX0uLi5gfWxldCBGO2Z1bmN0aW9uIEcodD1mdW5jdGlvbigpe2NvbnN0IHQ9cDtyZXR1cm4gdC5jcnlwdG98fHQubXNDcnlwdG99KCkpe3RyeXtpZih0Py5yYW5kb21VVUlEKXJldHVybiBUKCgpPT50LnJhbmRvbVVVSUQoKSkucmVwbGFjZSgvLS9nLCIiKX1jYXRjaHt9cmV0dXJuIEZ8fChGPSIxMDAwMDAwMDEwMDA0MDAwODAwMDEwMDAwMDAwMDAwMCIpLEYucmVwbGFjZSgvWzAxOF0vZyx0PT4odF4oMTYqaygpJjE1KT4+dC80KS50b1N0cmluZygxNikpfWZ1bmN0aW9uIEooKXtyZXR1cm4gUCgpLzFlM31sZXQgVztmdW5jdGlvbiBZKCl7cmV0dXJuKFc/PyhXPWZ1bmN0aW9uKCl7Y29uc3R7cGVyZm9ybWFuY2U6dH09cDtpZighdD8ubm93fHwhdC50aW1lT3JpZ2luKXJldHVybiBKO2NvbnN0IG49dC50aW1lT3JpZ2luO3JldHVybigpPT4obitUKCgpPT50Lm5vdygpKSkvMWUzfSgpKSkoKX1mdW5jdGlvbiBIKHQpe2NvbnN0IG49WSgpLGU9e3NpZDpHKCksaW5pdDohMCx0aW1lc3RhbXA6bixzdGFydGVkOm4sZHVyYXRpb246MCxzdGF0dXM6Im9rIixlcnJvcnM6MCxpZ25vcmVEdXJhdGlvbjohMSx0b0pTT046KCk9PmZ1bmN0aW9uKHQpe3JldHVybntzaWQ6YCR7dC5zaWR9YCxpbml0OnQuaW5pdCxzdGFydGVkOm5ldyBEYXRlKDFlMyp0LnN0YXJ0ZWQpLnRvSVNPU3RyaW5nKCksdGltZXN0YW1wOm5ldyBEYXRlKDFlMyp0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxzdGF0dXM6dC5zdGF0dXMsZXJyb3JzOnQuZXJyb3JzLGRpZDoibnVtYmVyIj09dHlwZW9mIHQuZGlkfHwic3RyaW5nIj09dHlwZW9mIHQuZGlkP2Ake3QuZGlkfWA6dm9pZCAwLGR1cmF0aW9uOnQuZHVyYXRpb24sYWJub3JtYWxfbWVjaGFuaXNtOnQuYWJub3JtYWxfbWVjaGFuaXNtLGF0dHJzOntyZWxlYXNlOnQucmVsZWFzZSxlbnZpcm9ubWVudDp0LmVudmlyb25tZW50LGlwX2FkZHJlc3M6dC5pcEFkZHJlc3MsdXNlcl9hZ2VudDp0LnVzZXJBZ2VudH19fShlKX07cmV0dXJuIHQmJksoZSx0KSxlfWZ1bmN0aW9uIEsodCxuPXt9KXtpZihuLnVzZXImJighdC5pcEFkZHJlc3MmJm4udXNlci5pcF9hZGRyZXNzJiYodC5pcEFkZHJlc3M9bi51c2VyLmlwX2FkZHJlc3MpLHQuZGlkfHxuLmRpZHx8KHQuZGlkPW4udXNlci5pZHx8bi51c2VyLmVtYWlsfHxuLnVzZXIudXNlcm5hbWUpKSx0LnRpbWVzdGFtcD1uLnRpbWVzdGFtcHx8WSgpLG4uYWJub3JtYWxfbWVjaGFuaXNtJiYodC5hYm5vcm1hbF9tZWNoYW5pc209bi5hYm5vcm1hbF9tZWNoYW5pc20pLG4uaWdub3JlRHVyYXRpb24mJih0Lmlnbm9yZUR1cmF0aW9uPW4uaWdub3JlRHVyYXRpb24pLG4uc2lkJiYodC5zaWQ9MzI9PT1uLnNpZC5sZW5ndGg/bi5zaWQ6RygpKSx2b2lkIDAhPT1uLmluaXQmJih0LmluaXQ9bi5pbml0KSwhdC5kaWQmJm4uZGlkJiYodC5kaWQ9YCR7bi5kaWR9YCksIm51bWJlciI9PXR5cGVvZiBuLnN0YXJ0ZWQmJih0LnN0YXJ0ZWQ9bi5zdGFydGVkKSx0Lmlnbm9yZUR1cmF0aW9uKXQuZHVyYXRpb249dm9pZCAwO2Vsc2UgaWYoIm51bWJlciI9PXR5cGVvZiBuLmR1cmF0aW9uKXQuZHVyYXRpb249bi5kdXJhdGlvbjtlbHNle2NvbnN0IG49dC50aW1lc3RhbXAtdC5zdGFydGVkO3QuZHVyYXRpb249bj49MD9uOjB9bi5yZWxlYXNlJiYodC5yZWxlYXNlPW4ucmVsZWFzZSksbi5lbnZpcm9ubWVudCYmKHQuZW52aXJvbm1lbnQ9bi5lbnZpcm9ubWVudCksIXQuaXBBZGRyZXNzJiZuLmlwQWRkcmVzcyYmKHQuaXBBZGRyZXNzPW4uaXBBZGRyZXNzKSwhdC51c2VyQWdlbnQmJm4udXNlckFnZW50JiYodC51c2VyQWdlbnQ9bi51c2VyQWdlbnQpLCJudW1iZXIiPT10eXBlb2Ygbi5lcnJvcnMmJih0LmVycm9ycz1uLmVycm9ycyksbi5zdGF0dXMmJih0LnN0YXR1cz1uLnN0YXR1cyl9ZnVuY3Rpb24gWih0LG4sZT0yKXtpZighbnx8Im9iamVjdCIhPXR5cGVvZiBufHxlPD0wKXJldHVybiBuO2lmKHQmJjA9PT1PYmplY3Qua2V5cyhuKS5sZW5ndGgpcmV0dXJuIHQ7Y29uc3Qgcj17Li4udH07Zm9yKGNvbnN0IHQgaW4gbilPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobix0KSYmKHJbdF09WihyW3RdLG5bdF0sZS0xKSk7cmV0dXJuIHJ9ZnVuY3Rpb24gcSgpe3JldHVybiBHKCl9ZnVuY3Rpb24gVigpe3JldHVybiBHKCkuc3Vic3RyaW5nKDE2KX1mdW5jdGlvbiBRKHQpe2lmKHQpe2lmKCJvYmplY3QiPT10eXBlb2YgdCYmImRlcmVmImluIHQmJiJmdW5jdGlvbiI9PXR5cGVvZiB0LmRlcmVmKXRyeXtyZXR1cm4gdC5kZXJlZigpfWNhdGNoe3JldHVybn1yZXR1cm4gdH19Y29uc3QgWD0iX3NlbnRyeVNwYW4iO2Z1bmN0aW9uIHR0KHQsbil7bj9mdW5jdGlvbih0LG4sZSl7dHJ5e09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LG4se3ZhbHVlOmUsd3JpdGFibGU6ITAsY29uZmlndXJhYmxlOiEwfSl9Y2F0Y2h7aCYmdy5sb2coYEZhaWxlZCB0byBhZGQgbm9uLWVudW1lcmFibGUgcHJvcGVydHkgIiR7U3RyaW5nKG4pfSIgdG8gb2JqZWN0YCx0KX19KHQsWCxmdW5jdGlvbih0KXt0cnl7Y29uc3Qgbj1wLldlYWtSZWY7aWYoImZ1bmN0aW9uIj09dHlwZW9mIG4pcmV0dXJuIG5ldyBuKHQpfWNhdGNoe31yZXR1cm4gdH0obikpOmRlbGV0ZSB0W1hdfWZ1bmN0aW9uIG50KHQpe3JldHVybiBRKHRbWF0pfWNsYXNzIGV0e2NvbnN0cnVjdG9yKCl7dGhpcy50PSExLHRoaXMubz1bXSx0aGlzLmk9W10sdGhpcy51PVtdLHRoaXMuaD1bXSx0aGlzLnA9e30sdGhpcy5sPXt9LHRoaXMubT17fSx0aGlzLnY9e30sdGhpcy5fPXt9LHRoaXMuUz17fSx0aGlzLk49e3RyYWNlSWQ6cSgpLHNhbXBsZVJhbmQ6aygpfX1jbG9uZSgpe2NvbnN0IHQ9bmV3IGV0O3JldHVybiB0LnU9Wy4uLnRoaXMudV0sdC5sPXsuLi50aGlzLmx9LHQubT17Li4udGhpcy5tfSx0LnY9ey4uLnRoaXMudn0sdC5fPXsuLi50aGlzLl99LHRoaXMuXy5mbGFncyYmKHQuXy5mbGFncz17dmFsdWVzOlsuLi50aGlzLl8uZmxhZ3MudmFsdWVzXX0pLHQucD10aGlzLnAsdC5DPXRoaXMuQyx0Lmo9dGhpcy5qLHQuUj10aGlzLlIsdC5BPXRoaXMuQSx0Lmk9Wy4uLnRoaXMuaV0sdC5oPVsuLi50aGlzLmhdLHQuUz17Li4udGhpcy5TfSx0Lk49ey4uLnRoaXMuTn0sdC5JPXRoaXMuSSx0Lk89dGhpcy5PLHQuVD10aGlzLlQsdHQodCxudCh0aGlzKSksdH1zZXRDbGllbnQodCl7dGhpcy5JPXR9c2V0TGFzdEV2ZW50SWQodCl7dGhpcy5PPXR9Z2V0Q2xpZW50KCl7cmV0dXJuIHRoaXMuSX1sYXN0RXZlbnRJZCgpe3JldHVybiB0aGlzLk99YWRkU2NvcGVMaXN0ZW5lcih0KXt0aGlzLm8ucHVzaCh0KX1hZGRFdmVudFByb2Nlc3Nvcih0KXtyZXR1cm4gdGhpcy5pLnB1c2godCksdGhpc31zZXRVc2VyKHQpe3JldHVybiB0aGlzLnA9dHx8e2VtYWlsOnZvaWQgMCxpZDp2b2lkIDAsaXBfYWRkcmVzczp2b2lkIDAsdXNlcm5hbWU6dm9pZCAwfSx0aGlzLmomJksodGhpcy5qLHt1c2VyOnR9KSx0aGlzLmsoKSx0aGlzfWdldFVzZXIoKXtyZXR1cm4gdGhpcy5wfXNldENvbnZlcnNhdGlvbklkKHQpe3JldHVybiB0aGlzLlQ9dHx8dm9pZCAwLHRoaXMuaygpLHRoaXN9c2V0VGFncyh0KXtyZXR1cm4gdGhpcy5sPXsuLi50aGlzLmwsLi4udH0sdGhpcy5rKCksdGhpc31zZXRUYWcodCxuKXtyZXR1cm4gdGhpcy5zZXRUYWdzKHtbdF06bn0pfXNldEF0dHJpYnV0ZXModCl7cmV0dXJuIHRoaXMubT17Li4udGhpcy5tLC4uLnR9LHRoaXMuaygpLHRoaXN9c2V0QXR0cmlidXRlKHQsbil7cmV0dXJuIHRoaXMuc2V0QXR0cmlidXRlcyh7W3RdOm59KX1yZW1vdmVBdHRyaWJ1dGUodCl7cmV0dXJuIHQgaW4gdGhpcy5tJiYoZGVsZXRlIHRoaXMubVt0XSx0aGlzLmsoKSksdGhpc31zZXRFeHRyYXModCl7cmV0dXJuIHRoaXMudj17Li4udGhpcy52LC4uLnR9LHRoaXMuaygpLHRoaXN9c2V0RXh0cmEodCxuKXtyZXR1cm4gdGhpcy52PXsuLi50aGlzLnYsW3RdOm59LHRoaXMuaygpLHRoaXN9c2V0RmluZ2VycHJpbnQodCl7cmV0dXJuIHRoaXMuQT10LHRoaXMuaygpLHRoaXN9c2V0TGV2ZWwodCl7cmV0dXJuIHRoaXMuQz10LHRoaXMuaygpLHRoaXN9c2V0VHJhbnNhY3Rpb25OYW1lKHQpe3JldHVybiB0aGlzLlI9dCx0aGlzLmsoKSx0aGlzfXNldENvbnRleHQodCxuKXtyZXR1cm4gbnVsbD09PW4/ZGVsZXRlIHRoaXMuX1t0XTp0aGlzLl9bdF09bix0aGlzLmsoKSx0aGlzfXNldFNlc3Npb24odCl7cmV0dXJuIHQ/dGhpcy5qPXQ6ZGVsZXRlIHRoaXMuaix0aGlzLmsoKSx0aGlzfWdldFNlc3Npb24oKXtyZXR1cm4gdGhpcy5qfXVwZGF0ZSh0KXtpZighdClyZXR1cm4gdGhpcztjb25zdCBuPSJmdW5jdGlvbiI9PXR5cGVvZiB0P3QodGhpcyk6dCxlPW4gaW5zdGFuY2VvZiBldD9uLmdldFNjb3BlRGF0YSgpOkMobiwiT2JqZWN0Iik/dDp2b2lkIDA7Y29uc3R7dGFnczpyLGF0dHJpYnV0ZXM6byxleHRyYTppLHVzZXI6cyxjb250ZXh0czpjLGxldmVsOnUsZmluZ2VycHJpbnQ6YT1bXSxwcm9wYWdhdGlvbkNvbnRleHQ6Zixjb252ZXJzYXRpb25JZDpofT1lfHx7fTtyZXR1cm4gdGhpcy5sPXsuLi50aGlzLmwsLi4ucn0sdGhpcy5tPXsuLi50aGlzLm0sLi4ub30sdGhpcy52PXsuLi50aGlzLnYsLi4uaX0sdGhpcy5fPXsuLi50aGlzLl8sLi4uY30scyYmT2JqZWN0LmtleXMocykubGVuZ3RoJiYodGhpcy5wPXMpLHUmJih0aGlzLkM9dSksYS5sZW5ndGgmJih0aGlzLkE9YSksZiYmKHRoaXMuTj1mKSxoJiYodGhpcy5UPWgpLHRoaXN9Y2xlYXIoKXtyZXR1cm4gdGhpcy51PVtdLHRoaXMubD17fSx0aGlzLm09e30sdGhpcy52PXt9LHRoaXMucD17fSx0aGlzLl89e30sdGhpcy5DPXZvaWQgMCx0aGlzLlI9dm9pZCAwLHRoaXMuQT12b2lkIDAsdGhpcy5qPXZvaWQgMCx0aGlzLlQ9dm9pZCAwLHR0KHRoaXMsdm9pZCAwKSx0aGlzLmg9W10sdGhpcy5zZXRQcm9wYWdhdGlvbkNvbnRleHQoe3RyYWNlSWQ6cSgpLHNhbXBsZVJhbmQ6aygpfSksdGhpcy5rKCksdGhpc31hZGRCcmVhZGNydW1iKHQsbil7Y29uc3QgZT0ibnVtYmVyIj09dHlwZW9mIG4/bjoxMDA7aWYoZTw9MClyZXR1cm4gdGhpcztjb25zdCByPXt0aW1lc3RhbXA6SigpLC4uLnQsbWVzc2FnZTp0Lm1lc3NhZ2U/eih0Lm1lc3NhZ2UsMjA0OCk6dC5tZXNzYWdlfTtyZXR1cm4gdGhpcy51LnB1c2gociksdGhpcy51Lmxlbmd0aD5lJiYodGhpcy51PXRoaXMudS5zbGljZSgtZSksdGhpcy5JPy5yZWNvcmREcm9wcGVkRXZlbnQoImJ1ZmZlcl9vdmVyZmxvdyIsImxvZ19pdGVtIikpLHRoaXMuaygpLHRoaXN9Z2V0TGFzdEJyZWFkY3J1bWIoKXtyZXR1cm4gdGhpcy51W3RoaXMudS5sZW5ndGgtMV19Y2xlYXJCcmVhZGNydW1icygpe3JldHVybiB0aGlzLnU9W10sdGhpcy5rKCksdGhpc31hZGRBdHRhY2htZW50KHQpe3JldHVybiB0aGlzLmgucHVzaCh0KSx0aGlzfWNsZWFyQXR0YWNobWVudHMoKXtyZXR1cm4gdGhpcy5oPVtdLHRoaXN9Z2V0U2NvcGVEYXRhKCl7cmV0dXJue2JyZWFkY3J1bWJzOnRoaXMudSxhdHRhY2htZW50czp0aGlzLmgsY29udGV4dHM6dGhpcy5fLHRhZ3M6dGhpcy5sLGF0dHJpYnV0ZXM6dGhpcy5tLGV4dHJhOnRoaXMudix1c2VyOnRoaXMucCxsZXZlbDp0aGlzLkMsZmluZ2VycHJpbnQ6dGhpcy5BfHxbXSxldmVudFByb2Nlc3NvcnM6dGhpcy5pLHByb3BhZ2F0aW9uQ29udGV4dDp0aGlzLk4sc2RrUHJvY2Vzc2luZ01ldGFkYXRhOnRoaXMuUyx0cmFuc2FjdGlvbk5hbWU6dGhpcy5SLHNwYW46bnQodGhpcyksY29udmVyc2F0aW9uSWQ6dGhpcy5UfX1zZXRTREtQcm9jZXNzaW5nTWV0YWRhdGEodCl7cmV0dXJuIHRoaXMuUz1aKHRoaXMuUyx0LDIpLHRoaXN9c2V0UHJvcGFnYXRpb25Db250ZXh0KHQpe3JldHVybiB0aGlzLk49dCx0aGlzfWdldFByb3BhZ2F0aW9uQ29udGV4dCgpe3JldHVybiB0aGlzLk59Y2FwdHVyZUV4Y2VwdGlvbih0LG4pe2NvbnN0IGU9bj8uZXZlbnRfaWR8fEcoKTtpZighdGhpcy5JKXJldHVybiBoJiZ3Lndhcm4oIk5vIGNsaWVudCBjb25maWd1cmVkIG9uIHNjb3BlIC0gd2lsbCBub3QgY2FwdHVyZSBleGNlcHRpb24hIiksZTtjb25zdCByPW5ldyBFcnJvcigiU2VudHJ5IHN5bnRoZXRpY0V4Y2VwdGlvbiIpO3JldHVybiB0aGlzLkkuY2FwdHVyZUV4Y2VwdGlvbih0LHtvcmlnaW5hbEV4Y2VwdGlvbjp0LHN5bnRoZXRpY0V4Y2VwdGlvbjpyLC4uLm4sZXZlbnRfaWQ6ZX0sdGhpcyksZX1jYXB0dXJlTWVzc2FnZSh0LG4sZSl7Y29uc3Qgcj1lPy5ldmVudF9pZHx8RygpO2lmKCF0aGlzLkkpcmV0dXJuIGgmJncud2FybigiTm8gY2xpZW50IGNvbmZpZ3VyZWQgb24gc2NvcGUgLSB3aWxsIG5vdCBjYXB0dXJlIG1lc3NhZ2UhIikscjtjb25zdCBvPWU/LnN5bnRoZXRpY0V4Y2VwdGlvbj8/bmV3IEVycm9yKHQpO3JldHVybiB0aGlzLkkuY2FwdHVyZU1lc3NhZ2UodCxuLHtvcmlnaW5hbEV4Y2VwdGlvbjp0LHN5bnRoZXRpY0V4Y2VwdGlvbjpvLC4uLmUsZXZlbnRfaWQ6cn0sdGhpcykscn1jYXB0dXJlRXZlbnQodCxuKXtjb25zdCBlPXQuZXZlbnRfaWR8fG4/LmV2ZW50X2lkfHxHKCk7cmV0dXJuIHRoaXMuST8odGhpcy5JLmNhcHR1cmVFdmVudCh0LHsuLi5uLGV2ZW50X2lkOmV9LHRoaXMpLGUpOihoJiZ3Lndhcm4oIk5vIGNsaWVudCBjb25maWd1cmVkIG9uIHNjb3BlIC0gd2lsbCBub3QgY2FwdHVyZSBldmVudCEiKSxlKX1rKCl7dGhpcy50fHwodGhpcy50PSEwLHRoaXMuby5mb3JFYWNoKHQ9Pnt0KHRoaXMpfSksdGhpcy50PSExKX19Y29uc3QgcnQ9dD0+dCBpbnN0YW5jZW9mIFByb21pc2UmJiF0W290XSxvdD1TeW1ib2woImNoYWluZWQgUHJvbWlzZUxpa2UiKSxpdD0odCxuKT0+e2lmKCFuKXJldHVybiB0O2xldCBlPSExO2Zvcihjb25zdCByIGluIHQpe2lmKHIgaW4gbiljb250aW51ZTtlPSEwO2NvbnN0IG89dFtyXTsiZnVuY3Rpb24iPT10eXBlb2Ygbz9PYmplY3QuZGVmaW5lUHJvcGVydHkobixyLHt2YWx1ZTooLi4ubik9Pm8uYXBwbHkodCxuKSxlbnVtZXJhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMCx3cml0YWJsZTohMH0pOm5bcl09b31yZXR1cm4gZSYmT2JqZWN0LmFzc2lnbihuLHtbb3RdOiEwfSksbn07Y2xhc3Mgc3R7Y29uc3RydWN0b3IodCxuKXtsZXQgZSxyO2U9dHx8bmV3IGV0LHI9bnx8bmV3IGV0LHRoaXMuUD1be3Njb3BlOmV9XSx0aGlzLkQ9cn13aXRoU2NvcGUodCl7Y29uc3Qgbj10aGlzLlUoKTtsZXQgZTt0cnl7ZT10KG4pfWNhdGNoKHQpe3Rocm93IHRoaXMuQigpLHR9cmV0dXJuIGooZSk/KCh0LG4sZSk9Pntjb25zdCByPXQudGhlbih0PT4obih0KSx0KSx0PT57dGhyb3cgZSh0KSx0fSk7cmV0dXJuIHJ0KHIpJiZydCh0KT9yOml0KHQscil9KShlLCgpPT50aGlzLkIoKSwoKT0+dGhpcy5CKCkpOih0aGlzLkIoKSxlKX1nZXRDbGllbnQoKXtyZXR1cm4gdGhpcy5nZXRTdGFja1RvcCgpLmNsaWVudH1nZXRTY29wZSgpe3JldHVybiB0aGlzLmdldFN0YWNrVG9wKCkuc2NvcGV9Z2V0SXNvbGF0aW9uU2NvcGUoKXtyZXR1cm4gdGhpcy5EfWdldFN0YWNrVG9wKCl7cmV0dXJuIHRoaXMuUFt0aGlzLlAubGVuZ3RoLTFdfVUoKXtjb25zdCB0PXRoaXMuZ2V0U2NvcGUoKS5jbG9uZSgpO3JldHVybiB0aGlzLlAucHVzaCh7Y2xpZW50OnRoaXMuZ2V0Q2xpZW50KCksc2NvcGU6dH0pLHR9Qigpe3JldHVybiEodGhpcy5QLmxlbmd0aDw9MSkmJiEhdGhpcy5QLnBvcCgpfX1mdW5jdGlvbiBjdCgpe2NvbnN0IHQ9ZyhsKCkpO3JldHVybiB0LnN0YWNrPXQuc3RhY2t8fG5ldyBzdChtKCJkZWZhdWx0Q3VycmVudFNjb3BlIiwoKT0+bmV3IGV0KSxtKCJkZWZhdWx0SXNvbGF0aW9uU2NvcGUiLCgpPT5uZXcgZXQpKX1mdW5jdGlvbiB1dCh0KXtyZXR1cm4gY3QoKS53aXRoU2NvcGUodCl9ZnVuY3Rpb24gYXQodCxuKXtjb25zdCBlPWN0KCk7cmV0dXJuIGUud2l0aFNjb3BlKCgpPT4oZS5nZXRTdGFja1RvcCgpLnNjb3BlPXQsbih0KSkpfWZ1bmN0aW9uIGZ0KHQpe3JldHVybiBjdCgpLndpdGhTY29wZSgoKT0+dChjdCgpLmdldElzb2xhdGlvblNjb3BlKCkpKX1mdW5jdGlvbiBodCh0KXtjb25zdCBuPWcodCk7cmV0dXJuIG4uYWNzP24uYWNzOnt3aXRoSXNvbGF0aW9uU2NvcGU6ZnQsd2l0aFNjb3BlOnV0LHdpdGhTZXRTY29wZTphdCx3aXRoU2V0SXNvbGF0aW9uU2NvcGU6KHQsbik9PmZ0KG4pLGdldEN1cnJlbnRTY29wZTooKT0+Y3QoKS5nZXRTY29wZSgpLGdldElzb2xhdGlvblNjb3BlOigpPT5jdCgpLmdldElzb2xhdGlvblNjb3BlKCl9fWZ1bmN0aW9uIHB0KCl7cmV0dXJuIGh0KGwoKSkuZ2V0Q3VycmVudFNjb3BlKCkuZ2V0Q2xpZW50KCl9ZnVuY3Rpb24gZHQodCl7Y29uc3Qgbj10O3JldHVybntzY29wZTpuLl9zZW50cnlTY29wZSxpc29sYXRpb25TY29wZTpRKG4uX3NlbnRyeUlzb2xhdGlvblNjb3BlKX19Y29uc3QgbHQ9InNlbnRyeS0iO2Z1bmN0aW9uIGd0KHQpe2NvbnN0IG49ZnVuY3Rpb24odCl7aWYoIXR8fChuPXQsIUMobiwiU3RyaW5nIikmJiFBcnJheS5pc0FycmF5KHQpKSlyZXR1cm47dmFyIG47aWYoQXJyYXkuaXNBcnJheSh0KSlyZXR1cm4gdC5yZWR1Y2UoKHQsbik9Pntjb25zdCBlPW10KG4pO3JldHVybiBPYmplY3QuZW50cmllcyhlKS5mb3JFYWNoKChbbixlXSk9Pnt0W25dPWV9KSx0fSx7fSk7cmV0dXJuIG10KHQpfSh0KTtpZighbilyZXR1cm47Y29uc3QgZT1PYmplY3QuZW50cmllcyhuKS5yZWR1Y2UoKHQsW24sZV0pPT57aWYobi5zdGFydHNXaXRoKGx0KSl7dFtuLnNsaWNlKDcpXT1lfXJldHVybiB0fSx7fSk7cmV0dXJuIE9iamVjdC5rZXlzKGUpLmxlbmd0aD4wP2U6dm9pZCAwfWZ1bmN0aW9uIG10KHQpe3JldHVybiB0LnNwbGl0KCIsIikubWFwKHQ9Pntjb25zdCBuPXQuaW5kZXhPZigiPSIpO2lmKC0xPT09bilyZXR1cm5bXTtyZXR1cm5bdC5zbGljZSgwLG4pLHQuc2xpY2UobisxKV0ubWFwKHQ9Pnt0cnl7cmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudCh0LnRyaW0oKSl9Y2F0Y2h7cmV0dXJufX0pfSkucmVkdWNlKCh0LFtuLGVdKT0+KG4mJmUmJih0W25dPWUpLHQpLHt9KX1jb25zdCB5dD0vXm8oXGQrKVwuLztmdW5jdGlvbiBidCh0LG49ITEpe2NvbnN0e2hvc3Q6ZSxwYXRoOnIscGFzczpvLHBvcnQ6aSxwcm9qZWN0SWQ6cyxwcm90b2NvbDpjLHB1YmxpY0tleTp1fT10O3JldHVybmAke2N9Oi8vJHt1fSR7biYmbz9gOiR7b31gOiIifUAke2V9JHtpP2A6JHtpfWA6IiJ9LyR7cj9gJHtyfS9gOnJ9JHtzfWB9ZnVuY3Rpb24gdnQodCl7Y29uc3Qgbj10LmdldE9wdGlvbnMoKSx7aG9zdDplfT10LmdldERzbigpfHx7fTtsZXQgcjtyZXR1cm4gbi5vcmdJZD9yPVN0cmluZyhuLm9yZ0lkKTplJiYocj1mdW5jdGlvbih0KXtjb25zdCBuPXQubWF0Y2goeXQpO3JldHVybiBuPy5bMV19KGUpKSxyfWZ1bmN0aW9uIF90KHQpe2NvbnN0e3NwYW5JZDpuLHRyYWNlSWQ6ZSxpc1JlbW90ZTpyfT10LnNwYW5Db250ZXh0KCksbz1yP246RXQodCkucGFyZW50X3NwYW5faWQsaT1kdCh0KS5zY29wZTtyZXR1cm57cGFyZW50X3NwYW5faWQ6byxzcGFuX2lkOnI/aT8uZ2V0UHJvcGFnYXRpb25Db250ZXh0KCkucHJvcGFnYXRpb25TcGFuSWR8fFYoKTpuLHRyYWNlX2lkOmV9fWZ1bmN0aW9uIFN0KHQpe3JldHVybiB0JiZ0Lmxlbmd0aD4wP3QubWFwKCh7Y29udGV4dDp7c3BhbklkOnQsdHJhY2VJZDpuLHRyYWNlRmxhZ3M6ZSwuLi5yfSxhdHRyaWJ1dGVzOm99KT0+KHtzcGFuX2lkOnQsdHJhY2VfaWQ6bixzYW1wbGVkOjE9PT1lLGF0dHJpYnV0ZXM6bywuLi5yfSkpOnZvaWQgMH1mdW5jdGlvbiB3dCh0KXtyZXR1cm4ibnVtYmVyIj09dHlwZW9mIHQ/JHQodCk6QXJyYXkuaXNBcnJheSh0KT90WzBdK3RbMV0vMWU5OnQgaW5zdGFuY2VvZiBEYXRlPyR0KHQuZ2V0VGltZSgpKTpZKCl9ZnVuY3Rpb24gJHQodCl7cmV0dXJuIHQ+OTk5OTk5OTk5OT90LzFlMzp0fWZ1bmN0aW9uIEV0KHQpe2lmKGZ1bmN0aW9uKHQpe3JldHVybiJmdW5jdGlvbiI9PXR5cGVvZiB0LmdldFNwYW5KU09OfSh0KSlyZXR1cm4gdC5nZXRTcGFuSlNPTigpO2NvbnN0e3NwYW5JZDpuLHRyYWNlSWQ6ZX09dC5zcGFuQ29udGV4dCgpO2lmKGZ1bmN0aW9uKHQpe2NvbnN0IG49dDtyZXR1cm4hIShuLmF0dHJpYnV0ZXMmJm4uc3RhcnRUaW1lJiZuLm5hbWUmJm4uZW5kVGltZSYmbi5zdGF0dXMpfSh0KSl7Y29uc3R7YXR0cmlidXRlczpyLHN0YXJ0VGltZTpvLG5hbWU6aSxlbmRUaW1lOnMsc3RhdHVzOmMsbGlua3M6dX09dDtyZXR1cm57c3Bhbl9pZDpuLHRyYWNlX2lkOmUsZGF0YTpyLGRlc2NyaXB0aW9uOmkscGFyZW50X3NwYW5faWQ6eHQodCksc3RhcnRfdGltZXN0YW1wOnd0KG8pLHRpbWVzdGFtcDp3dChzKXx8dm9pZCAwLHN0YXR1czpOdChjKSxvcDpyWyJzZW50cnkub3AiXSxvcmlnaW46clsic2VudHJ5Lm9yaWdpbiJdLGxpbmtzOlN0KHUpfX1yZXR1cm57c3Bhbl9pZDpuLHRyYWNlX2lkOmUsc3RhcnRfdGltZXN0YW1wOjAsZGF0YTp7fX19ZnVuY3Rpb24geHQodCl7cmV0dXJuInBhcmVudFNwYW5JZCJpbiB0P3QucGFyZW50U3BhbklkOiJwYXJlbnRTcGFuQ29udGV4dCJpbiB0P3QucGFyZW50U3BhbkNvbnRleHQ/LnNwYW5JZDp2b2lkIDB9ZnVuY3Rpb24gTnQodCl7aWYodCYmMCE9PXQuY29kZSlyZXR1cm4gMT09PXQuY29kZT8ib2siOnQubWVzc2FnZXx8ImludGVybmFsX2Vycm9yIn1jb25zdCBDdD1mdW5jdGlvbih0KXtyZXR1cm4gdC5fc2VudHJ5Um9vdFNwYW58fHR9O2Z1bmN0aW9uIGp0KHQpe2lmKCJib29sZWFuIj09dHlwZW9mIF9fU0VOVFJZX1RSQUNJTkdfXyYmIV9fU0VOVFJZX1RSQUNJTkdfXylyZXR1cm4hMTtjb25zdCBuPXR8fHB0KCk/LmdldE9wdGlvbnMoKTtyZXR1cm4hKCFufHxudWxsPT1uLnRyYWNlc1NhbXBsZVJhdGUmJiFuLnRyYWNlc1NhbXBsZXIpfWNvbnN0IFJ0PVN5bWJvbC5mb3IoInNlbnRyeS5ub25SZWNvcmRpbmdTcGFuIik7ZnVuY3Rpb24gQXQodCxuKXtjb25zdCBlPW4uZ2V0T3B0aW9ucygpLHtwdWJsaWNLZXk6cn09bi5nZXREc24oKXx8e30sbz17ZW52aXJvbm1lbnQ6ZS5lbnZpcm9ubWVudHx8InByb2R1Y3Rpb24iLHJlbGVhc2U6ZS5yZWxlYXNlLHB1YmxpY19rZXk6cix0cmFjZV9pZDp0LG9yZ19pZDp2dChuKX07cmV0dXJuIG4uZW1pdCgiY3JlYXRlRHNjIixvKSxvfWZ1bmN0aW9uIEl0KHQsbil7Y29uc3QgZT1uLmdldFByb3BhZ2F0aW9uQ29udGV4dCgpO3JldHVybiBlLmRzY3x8QXQoZS50cmFjZUlkLHQpfWZ1bmN0aW9uIE90KHQpe2NvbnN0IG49cHQoKTtpZighbilyZXR1cm57fTtjb25zdCBlPUN0KHQpLHI9RXQoZSksbz1yLmRhdGEsaT1lLnNwYW5Db250ZXh0KCkudHJhY2VTdGF0ZSxzPWk/LmdldCgic2VudHJ5LnNhbXBsZV9yYXRlIik/P29bInNlbnRyeS5zYW1wbGVfcmF0ZSJdPz9vWyJzZW50cnkucHJldmlvdXNfdHJhY2Vfc2FtcGxlX3JhdGUiXTtmdW5jdGlvbiBjKHQpe3JldHVybiJudW1iZXIiIT10eXBlb2YgcyYmInN0cmluZyIhPXR5cGVvZiBzfHwodC5zYW1wbGVfcmF0ZT1gJHtzfWApLHR9Y29uc3QgdT1lLl9mcm96ZW5Ec2M7aWYodSlyZXR1cm4gYyh1KTtpZihmdW5jdGlvbih0KXtyZXR1cm4hIXQmJiEwPT09dFtSdF19KGUpJiYhanQobi5nZXRPcHRpb25zKCkpKXtjb25zdCB0PWR0KGUpLnNjb3BlO2lmKHQpcmV0dXJuIGMoey4uLkl0KG4sdCl9KX1jb25zdCBhPWk/LmdldCgic2VudHJ5LmRzYyIpLGY9YSYmZ3QoYSk7aWYoZilyZXR1cm4gYyhmKTtjb25zdCBoPUF0KHQuc3BhbkNvbnRleHQoKS50cmFjZUlkLG4pLHA9b1sic2VudHJ5LnNvdXJjZSJdPz9vWyJzZW50cnkuc3Bhbi5zb3VyY2UiXSxkPXIuZGVzY3JpcHRpb247cmV0dXJuInVybCIhPT1wJiZkJiYoaC50cmFuc2FjdGlvbj1kKSxqdCgpJiYoaC5zYW1wbGVkPVN0cmluZyhmdW5jdGlvbih0KXtjb25zdHt0cmFjZUZsYWdzOm59PXQuc3BhbkNvbnRleHQoKTtyZXR1cm4gMT09PW59KGUpKSxoLnNhbXBsZV9yYW5kPWk/LmdldCgic2VudHJ5LnNhbXBsZV9yYW5kIik/P2R0KGUpLnNjb3BlPy5nZXRQcm9wYWdhdGlvbkNvbnRleHQoKS5zYW1wbGVSYW5kLnRvU3RyaW5nKCkpLGMoaCksbi5lbWl0KCJjcmVhdGVEc2MiLGgsZSksaH1mdW5jdGlvbiBUdCh0LG49W10pe3JldHVyblt0LG5dfWZ1bmN0aW9uIGt0KHQsbil7Y29uc3QgZT10WzFdO2Zvcihjb25zdCB0IG9mIGUpe2lmKG4odCx0WzBdLnR5cGUpKXJldHVybiEwfXJldHVybiExfWZ1bmN0aW9uIFB0KHQpe2NvbnN0IG49ZyhwKTtyZXR1cm4gbi5lbmNvZGVQb2x5ZmlsbD9uLmVuY29kZVBvbHlmaWxsKHQpOihuZXcgVGV4dEVuY29kZXIpLmVuY29kZSh0KX1mdW5jdGlvbiBEdCh0KXtjb25zdFtuLGVdPXQ7bGV0IHI9SlNPTi5zdHJpbmdpZnkobik7ZnVuY3Rpb24gbyh0KXsic3RyaW5nIj09dHlwZW9mIHI/cj0ic3RyaW5nIj09dHlwZW9mIHQ/cit0OltQdChyKSx0XTpyLnB1c2goInN0cmluZyI9PXR5cGVvZiB0P1B0KHQpOnQpfWZvcihjb25zdCB0IG9mIGUpe2NvbnN0W24sZV09dDtpZihvKGBcbiR7SlNPTi5zdHJpbmdpZnkobil9XG5gKSwic3RyaW5nIj09dHlwZW9mIGV8fGUgaW5zdGFuY2VvZiBVaW50OEFycmF5KW8oZSk7ZWxzZXtsZXQgdDt0cnl7dD1KU09OLnN0cmluZ2lmeShlKX1jYXRjaHt0PUpTT04uc3RyaW5naWZ5KEIoZSkpfW8odCl9fXJldHVybiJzdHJpbmciPT10eXBlb2Ygcj9yOmZ1bmN0aW9uKHQpe2NvbnN0IG49dC5yZWR1Y2UoKHQsbik9PnQrbi5sZW5ndGgsMCksZT1uZXcgVWludDhBcnJheShuKTtsZXQgcj0wO2Zvcihjb25zdCBuIG9mIHQpZS5zZXQobixyKSxyKz1uLmxlbmd0aDtyZXR1cm4gZX0ocil9Y29uc3QgVXQ9e3Nlc3Npb25zOiJzZXNzaW9uIixldmVudDoiZXJyb3IiLGNsaWVudF9yZXBvcnQ6ImludGVybmFsIix1c2VyX3JlcG9ydDoiZGVmYXVsdCIscHJvZmlsZV9jaHVuazoicHJvZmlsZSIscmVwbGF5X2V2ZW50OiJyZXBsYXkiLHJlcGxheV9yZWNvcmRpbmc6InJlcGxheSIsY2hlY2tfaW46Im1vbml0b3IiLHJhd19zZWN1cml0eToic2VjdXJpdHkiLGxvZzoibG9nX2l0ZW0iLHRyYWNlX21ldHJpYzoibWV0cmljIn07ZnVuY3Rpb24gQnQodCl7cmV0dXJuIGZ1bmN0aW9uKHQpe3JldHVybiB0IGluIFV0fSh0KT9VdFt0XTp0fWZ1bmN0aW9uIEx0KHQpe2lmKCF0Py5zZGspcmV0dXJuO2NvbnN0e25hbWU6bix2ZXJzaW9uOmV9PXQuc2RrO3JldHVybntuYW1lOm4sdmVyc2lvbjplfX1mdW5jdGlvbiBNdCh0LG4sZSxyKXtjb25zdCBvPUx0KGUpLGk9dC50eXBlJiYicmVwbGF5X2V2ZW50IiE9PXQudHlwZT90LnR5cGU6ImV2ZW50IjshZnVuY3Rpb24odCxuKXtpZighbilyZXR1cm4gdDtjb25zdCBlPXQuc2RrfHx7fTt0LnNkaz17Li4uZSxuYW1lOmUubmFtZXx8bi5uYW1lLHZlcnNpb246ZS52ZXJzaW9ufHxuLnZlcnNpb24saW50ZWdyYXRpb25zOlsuLi50LnNkaz8uaW50ZWdyYXRpb25zfHxbXSwuLi5uLmludGVncmF0aW9uc3x8W11dLHBhY2thZ2VzOlsuLi50LnNkaz8ucGFja2FnZXN8fFtdLC4uLm4ucGFja2FnZXN8fFtdXSxzZXR0aW5nczp0LnNkaz8uc2V0dGluZ3N8fG4uc2V0dGluZ3M/ey4uLnQuc2RrPy5zZXR0aW5ncywuLi5uLnNldHRpbmdzfTp2b2lkIDB9fSh0LGU/LnNkayk7Y29uc3Qgcz1mdW5jdGlvbih0LG4sZSxyKXtjb25zdCBvPXQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhPy5keW5hbWljU2FtcGxpbmdDb250ZXh0O3JldHVybntldmVudF9pZDp0LmV2ZW50X2lkLHNlbnRfYXQ6bmV3IERhdGUoUCgpKS50b0lTT1N0cmluZygpLC4uLm4mJntzZGs6bn0sLi4uISFlJiZyJiZ7ZHNuOmJ0KHIpfSwuLi5vJiZ7dHJhY2U6b319fSh0LG8scixuKTtkZWxldGUgdC5zZGtQcm9jZXNzaW5nTWV0YWRhdGE7cmV0dXJuIFR0KHMsW1t7dHlwZTppfSx0XV0pfWNvbnN0IHp0PSJfX1NFTlRSWV9TVVBQUkVTU19UUkFDSU5HX18iO2Z1bmN0aW9uIEZ0KHQpe2NvbnN0IG49aHQobCgpKTtyZXR1cm4gbi5zdXBwcmVzc1RyYWNpbmc/bi5zdXBwcmVzc1RyYWNpbmcodCk6ZnVuY3Rpb24oLi4udCl7Y29uc3Qgbj1odChsKCkpO2lmKDI9PT10Lmxlbmd0aCl7Y29uc3RbZSxyXT10O3JldHVybiBlP24ud2l0aFNldFNjb3BlKGUscik6bi53aXRoU2NvcGUocil9cmV0dXJuIG4ud2l0aFNjb3BlKHRbMF0pfShuPT57bi5zZXRTREtQcm9jZXNzaW5nTWV0YWRhdGEoe1t6dF06ITB9KTtjb25zdCBlPXQoKTtyZXR1cm4gbi5zZXRTREtQcm9jZXNzaW5nTWV0YWRhdGEoe1t6dF06dm9pZCAwfSksZX0pfWZ1bmN0aW9uIEd0KHQsbil7Y29uc3R7ZmluZ2VycHJpbnQ6ZSxzcGFuOnIsYnJlYWRjcnVtYnM6byxzZGtQcm9jZXNzaW5nTWV0YWRhdGE6aX09bjshZnVuY3Rpb24odCxuKXtjb25zdHtleHRyYTplLHRhZ3M6cix1c2VyOm8sY29udGV4dHM6aSxsZXZlbDpzLHRyYW5zYWN0aW9uTmFtZTpjfT1uO09iamVjdC5rZXlzKGUpLmxlbmd0aCYmKHQuZXh0cmE9ey4uLmUsLi4udC5leHRyYX0pO09iamVjdC5rZXlzKHIpLmxlbmd0aCYmKHQudGFncz17Li4uciwuLi50LnRhZ3N9KTtPYmplY3Qua2V5cyhvKS5sZW5ndGgmJih0LnVzZXI9ey4uLm8sLi4udC51c2VyfSk7T2JqZWN0LmtleXMoaSkubGVuZ3RoJiYodC5jb250ZXh0cz17Li4uaSwuLi50LmNvbnRleHRzfSk7cyYmKHQubGV2ZWw9cyk7YyYmInRyYW5zYWN0aW9uIiE9PXQudHlwZSYmKHQudHJhbnNhY3Rpb249Yyl9KHQsbiksciYmZnVuY3Rpb24odCxuKXt0LmNvbnRleHRzPXt0cmFjZTpfdChuKSwuLi50LmNvbnRleHRzfSx0LnNka1Byb2Nlc3NpbmdNZXRhZGF0YT17ZHluYW1pY1NhbXBsaW5nQ29udGV4dDpPdChuKSwuLi50LnNka1Byb2Nlc3NpbmdNZXRhZGF0YX07Y29uc3QgZT1DdChuKSxyPUV0KGUpLmRlc2NyaXB0aW9uO3ImJiF0LnRyYW5zYWN0aW9uJiYidHJhbnNhY3Rpb24iPT09dC50eXBlJiYodC50cmFuc2FjdGlvbj1yKX0odCxyKSxmdW5jdGlvbih0LG4pe3QuZmluZ2VycHJpbnQ9dC5maW5nZXJwcmludD9BcnJheS5pc0FycmF5KHQuZmluZ2VycHJpbnQpP3QuZmluZ2VycHJpbnQ6W3QuZmluZ2VycHJpbnRdOltdLG4mJih0LmZpbmdlcnByaW50PXQuZmluZ2VycHJpbnQuY29uY2F0KG4pKTt0LmZpbmdlcnByaW50Lmxlbmd0aHx8ZGVsZXRlIHQuZmluZ2VycHJpbnR9KHQsZSksZnVuY3Rpb24odCxuKXtjb25zdCBlPVsuLi50LmJyZWFkY3J1bWJzfHxbXSwuLi5uXTt0LmJyZWFkY3J1bWJzPWUubGVuZ3RoP2U6dm9pZCAwfSh0LG8pLGZ1bmN0aW9uKHQsbil7dC5zZGtQcm9jZXNzaW5nTWV0YWRhdGE9ey4uLnQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhLC4uLm59fSh0LGkpfWNsYXNzIEp0e2NvbnN0cnVjdG9yKHQpe3RoaXMuTD0wLHRoaXMuTT1bXSx0aGlzLkYodCl9dGhlbih0LG4pe3JldHVybiBuZXcgSnQoKGUscik9Pnt0aGlzLk0ucHVzaChbITEsbj0+e2lmKHQpdHJ5e2UodChuKSl9Y2F0Y2godCl7cih0KX1lbHNlIGUobil9LHQ9PntpZihuKXRyeXtlKG4odCkpfWNhdGNoKHQpe3IodCl9ZWxzZSByKHQpfV0pLHRoaXMuRygpfSl9Y2F0Y2godCl7cmV0dXJuIHRoaXMudGhlbih0PT50LHQpfWZpbmFsbHkodCl7cmV0dXJuIG5ldyBKdCgobixlKT0+e2xldCByLG87cmV0dXJuIHRoaXMudGhlbihuPT57bz0hMSxyPW4sdCYmdCgpfSxuPT57bz0hMCxyPW4sdCYmdCgpfSkudGhlbigoKT0+e28/ZShyKTpuKHIpfSl9KX1HKCl7aWYoMD09PXRoaXMuTClyZXR1cm47Y29uc3QgdD10aGlzLk0uc2xpY2UoKTt0aGlzLk09W10sdC5mb3JFYWNoKHQ9Pnt0WzBdfHwoMT09PXRoaXMuTCYmdFsxXSh0aGlzLkopLDI9PT10aGlzLkwmJnRbMl0odGhpcy5KKSx0WzBdPSEwKX0pfUYodCl7Y29uc3Qgbj0odCxuKT0+ezA9PT10aGlzLkwmJihqKG4pP24udGhlbihlLHIpOih0aGlzLkw9dCx0aGlzLko9bix0aGlzLkcoKSkpfSxlPXQ9PntuKDEsdCl9LHI9dD0+e24oMix0KX07dHJ5e3QoZSxyKX1jYXRjaCh0KXtyKHQpfX19Y29uc3QgV3Q9U3ltYm9sLmZvcigiU2VudHJ5QnVmZmVyRnVsbEVycm9yIik7ZnVuY3Rpb24gWXQodD0xMDApe2NvbnN0IG49bmV3IFNldDtmdW5jdGlvbiBlKHQpe24uZGVsZXRlKHQpfXJldHVybntnZXQgJCgpe3JldHVybiBBcnJheS5mcm9tKG4pfSxhZGQ6ZnVuY3Rpb24ocil7aWYoIShuLnNpemU8dCkpcmV0dXJuIG89V3QsbmV3IEp0KCh0LG4pPT57bihvKX0pO3ZhciBvO2NvbnN0IGk9cigpO3JldHVybiBuLmFkZChpKSxpLnRoZW4oKCk9PmUoaSksKCk9PmUoaSkpLGl9LGRyYWluOmZ1bmN0aW9uKHQpe2lmKCFuLnNpemUpcmV0dXJuIGU9ITAsbmV3IEp0KHQ9Pnt0KGUpfSk7dmFyIGU7Y29uc3Qgcj1Qcm9taXNlLmFsbFNldHRsZWQoQXJyYXkuZnJvbShuKSkudGhlbigoKT0+ITApO2lmKCF0KXJldHVybiByO2NvbnN0IG89W3IsbmV3IFByb21pc2Uobj0+e3JldHVybiJvYmplY3QiPT10eXBlb2YoZT1zZXRUaW1lb3V0KCgpPT5uKCExKSx0KSkmJiJmdW5jdGlvbiI9PXR5cGVvZiBlLnVucmVmJiZlLnVucmVmKCksZTt2YXIgZX0pXTtyZXR1cm4gUHJvbWlzZS5yYWNlKG8pfX19ZnVuY3Rpb24gSHQodCx7c3RhdHVzQ29kZTpuLGhlYWRlcnM6ZX0scj1QKCkpe2NvbnN0IG89ey4uLnR9LGk9ZT8uWyJ4LXNlbnRyeS1yYXRlLWxpbWl0cyJdLHM9ZT8uWyJyZXRyeS1hZnRlciJdO2lmKGkpZm9yKGNvbnN0IHQgb2YgaS50cmltKCkuc3BsaXQoIiwiKSl7Y29uc3RbbixlLCwsaV09dC5zcGxpdCgiOiIsNSkscz1wYXJzZUludChuLDEwKSxjPTFlMyooaXNOYU4ocyk/NjA6cyk7aWYoZSlmb3IoY29uc3QgdCBvZiBlLnNwbGl0KCI7IikpIm1ldHJpY19idWNrZXQiPT09dCYmaSYmIWkuc3BsaXQoIjsiKS5pbmNsdWRlcygiY3VzdG9tIil8fChvW3RdPXIrYyk7ZWxzZSBvLmFsbD1yK2N9ZWxzZSBzP28uYWxsPXIrZnVuY3Rpb24odCxuPVAoKSl7Y29uc3QgZT1wYXJzZUludChgJHt0fWAsMTApO2lmKCFpc05hTihlKSlyZXR1cm4gMWUzKmU7Y29uc3Qgcj1EYXRlLnBhcnNlKGAke3R9YCk7cmV0dXJuIGlzTmFOKHIpPzZlNDpyLW59KHMscik6NDI5PT09biYmKG8uYWxsPXIrNmU0KTtyZXR1cm4gb31mdW5jdGlvbiBLdCh0LG4sZT1ZdCh0LmJ1ZmZlclNpemV8fDY0KSl7bGV0IHI9e307cmV0dXJue3NlbmQ6ZnVuY3Rpb24odCl7Y29uc3Qgbz1bXTtpZihrdCh0LCh0LG4pPT57Y29uc3QgZT1CdChuKTsoZnVuY3Rpb24odCxuLGU9UCgpKXtyZXR1cm4gZnVuY3Rpb24odCxuKXtyZXR1cm4gdFtuXXx8dC5hbGx8fDB9KHQsbik+ZX0pKHIsZSl8fG8ucHVzaCh0KX0pLDA9PT1vLmxlbmd0aClyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtjb25zdCBpPVR0KHRbMF0sbykscz10PT57IWZ1bmN0aW9uKHQsbil7cmV0dXJuIGt0KHQsKHQsZSk9Pm4uaW5jbHVkZXMoZSkpfShpLFsiY2xpZW50X3JlcG9ydCJdKT9rdChpLCh0LG4pPT57fSk6aCYmdy53YXJuKGBEcm9wcGluZyBjbGllbnQgcmVwb3J0LiBXaWxsIG5vdCBzZW5kIG91dGNvbWVzIChyZWFzb246ICR7dH0pLmApfTtyZXR1cm4gZS5hZGQoKCk9Pm4oe2JvZHk6RHQoaSl9KS50aGVuKHQ9PjQxMz09PXQuc3RhdHVzQ29kZT8oaCYmdy5lcnJvcigiU2VudHJ5IHJlc3BvbmRlZCB3aXRoIHN0YXR1cyBjb2RlIDQxMy4gRW52ZWxvcGUgd2FzIGRpc2NhcmRlZCBkdWUgdG8gZXhjZWVkaW5nIHNpemUgbGltaXRzLiIpLHMoInNlbmRfZXJyb3IiKSx0KTooaCYmdm9pZCAwIT09dC5zdGF0dXNDb2RlJiYodC5zdGF0dXNDb2RlPDIwMHx8dC5zdGF0dXNDb2RlPj0zMDApJiZ3Lndhcm4oYFNlbnRyeSByZXNwb25kZWQgd2l0aCBzdGF0dXMgY29kZSAke3Quc3RhdHVzQ29kZX0gdG8gc2VudCBldmVudC5gKSxyPUh0KHIsdCksdCksdD0+e3Rocm93IHMoIm5ldHdvcmtfZXJyb3IiKSxoJiZ3LmVycm9yKCJFbmNvdW50ZXJlZCBlcnJvciBydW5uaW5nIHRyYW5zcG9ydCByZXF1ZXN0OiIsdCksdH0pKS50aGVuKHQ9PnQsdD0+e2lmKHQ9PT1XdClyZXR1cm4gaCYmdy5lcnJvcigiU2tpcHBlZCBzZW5kaW5nIGV2ZW50IGJlY2F1c2UgYnVmZmVyIGlzIGZ1bGwuIikscygicXVldWVfb3ZlcmZsb3ciKSxQcm9taXNlLnJlc29sdmUoe30pO3Rocm93IHR9KX0sZmx1c2g6dD0+ZS5kcmFpbih0KX19Y29uc3QgWnQ9L14oXFMrOlxcfFwvPykoW1xzXFNdKj8pKCg/OlwuezEsMn18W14vXFxdKz98KShcLlteLi9cXF0qfCkpKD86Wy9cXF0qKSQvO2Z1bmN0aW9uIHF0KHQpe2NvbnN0IG49ZnVuY3Rpb24odCl7Y29uc3Qgbj10Lmxlbmd0aD4xMDI0P2A8dHJ1bmNhdGVkPiR7dC5zbGljZSgtMTAyNCl9YDp0LGU9WnQuZXhlYyhuKTtyZXR1cm4gZT9lLnNsaWNlKDEpOltdfSh0KSxlPW5bMF18fCIiO2xldCByPW5bMV07cmV0dXJuIGV8fHI/KHImJihyPXIuc2xpY2UoMCxyLmxlbmd0aC0xKSksZStyKToiLiJ9ZnVuY3Rpb24gVnQodCxuPSExKXtyZXR1cm4hKG58fHQmJiF0LnN0YXJ0c1dpdGgoIi8iKSYmIXQubWF0Y2goL15bQS1aXTovKSYmIXQuc3RhcnRzV2l0aCgiLiIpJiYhdC5tYXRjaCgvXlthLXpBLVpdKFthLXpBLVowLTkuXC0rXSkqOlwvXC8vKSkmJnZvaWQgMCE9PXQmJiF0LmluY2x1ZGVzKCJub2RlX21vZHVsZXMvIil9dmFyIFF0O2NvbnN0IFh0PVN5bWJvbCgiQWdlbnRCYXNlSW50ZXJuYWxTdGF0ZSIpO2NsYXNzIHRuIGV4dGVuZHMoUXQ9aS5BZ2VudCxRdCl7Y29uc3RydWN0b3IodCl7c3VwZXIodCksdGhpc1tYdF09e319aXNTZWN1cmVFbmRwb2ludCh0KXtpZih0KXtpZigiYm9vbGVhbiI9PXR5cGVvZiB0LnNlY3VyZUVuZHBvaW50KXJldHVybiB0LnNlY3VyZUVuZHBvaW50O2lmKCJzdHJpbmciPT10eXBlb2YgdC5wcm90b2NvbClyZXR1cm4iaHR0cHM6Ij09PXQucHJvdG9jb2x9Y29uc3R7c3RhY2s6bn09bmV3IEVycm9yO3JldHVybiJzdHJpbmciPT10eXBlb2YgbiYmbi5zcGxpdCgiXG4iKS5zb21lKHQ9Pi0xIT09dC5pbmRleE9mKCIoaHR0cHMuanM6Iil8fC0xIT09dC5pbmRleE9mKCJub2RlOmh0dHBzOiIpKX1jcmVhdGVTb2NrZXQodCxuLGUpe2NvbnN0IHI9ey4uLm4sc2VjdXJlRW5kcG9pbnQ6dGhpcy5pc1NlY3VyZUVuZHBvaW50KG4pfTtQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpPT50aGlzLmNvbm5lY3QodCxyKSkudGhlbihvPT57aWYobyBpbnN0YW5jZW9mIGkuQWdlbnQpcmV0dXJuIG8uYWRkUmVxdWVzdCh0LHIpO3RoaXNbWHRdLmN1cnJlbnRTb2NrZXQ9byxzdXBlci5jcmVhdGVTb2NrZXQodCxuLGUpfSxlKX1jcmVhdGVDb25uZWN0aW9uKCl7Y29uc3QgdD10aGlzW1h0XS5jdXJyZW50U29ja2V0O2lmKHRoaXNbWHRdLmN1cnJlbnRTb2NrZXQ9dm9pZCAwLCF0KXRocm93IG5ldyBFcnJvcigiTm8gc29ja2V0IHdhcyByZXR1cm5lZCBpbiB0aGUgYGNvbm5lY3QoKWAgZnVuY3Rpb24iKTtyZXR1cm4gdH1nZXQgZGVmYXVsdFBvcnQoKXtyZXR1cm4gdGhpc1tYdF0uZGVmYXVsdFBvcnQ/PygiaHR0cHM6Ij09PXRoaXMucHJvdG9jb2w/NDQzOjgwKX1zZXQgZGVmYXVsdFBvcnQodCl7dGhpc1tYdF0mJih0aGlzW1h0XS5kZWZhdWx0UG9ydD10KX1nZXQgcHJvdG9jb2woKXtyZXR1cm4gdGhpc1tYdF0ucHJvdG9jb2w/Pyh0aGlzLmlzU2VjdXJlRW5kcG9pbnQoKT8iaHR0cHM6IjoiaHR0cDoiKX1zZXQgcHJvdG9jb2wodCl7dGhpc1tYdF0mJih0aGlzW1h0XS5wcm90b2NvbD10KX19ZnVuY3Rpb24gbm4oLi4udCl7dy5sb2coIltodHRwcy1wcm94eS1hZ2VudDpwYXJzZS1wcm94eS1yZXNwb25zZV0iLC4uLnQpfWZ1bmN0aW9uIGVuKHQpe3JldHVybiBuZXcgUHJvbWlzZSgobixlKT0+e2xldCByPTA7Y29uc3Qgbz1bXTtmdW5jdGlvbiBpKCl7Y29uc3QgYz10LnJlYWQoKTtjP2Z1bmN0aW9uKGMpe28ucHVzaChjKSxyKz1jLmxlbmd0aDtjb25zdCB1PUJ1ZmZlci5jb25jYXQobyxyKSxhPXUuaW5kZXhPZigiXHJcblxyXG4iKTtpZigtMT09PWEpcmV0dXJuIG5uKCJoYXZlIG5vdCByZWNlaXZlZCBlbmQgb2YgSFRUUCBoZWFkZXJzIHlldC4uLiIpLHZvaWQgaSgpO2NvbnN0IGY9dS5zdWJhcnJheSgwLGEpLnRvU3RyaW5nKCJhc2NpaSIpLnNwbGl0KCJcclxuIiksaD1mLnNoaWZ0KCk7aWYoIWgpcmV0dXJuIHQuZGVzdHJveSgpLGUobmV3IEVycm9yKCJObyBoZWFkZXIgcmVjZWl2ZWQgZnJvbSBwcm94eSBDT05ORUNUIHJlc3BvbnNlIikpO2NvbnN0IHA9aC5zcGxpdCgiICIpLGQ9KyhwWzFdfHwwKSxsPXAuc2xpY2UoMikuam9pbigiICIpLGc9e307Zm9yKGNvbnN0IG4gb2YgZil7aWYoIW4pY29udGludWU7Y29uc3Qgcj1uLmluZGV4T2YoIjoiKTtpZigtMT09PXIpcmV0dXJuIHQuZGVzdHJveSgpLGUobmV3IEVycm9yKGBJbnZhbGlkIGhlYWRlciBmcm9tIHByb3h5IENPTk5FQ1QgcmVzcG9uc2U6ICIke259ImApKTtjb25zdCBvPW4uc2xpY2UoMCxyKS50b0xvd2VyQ2FzZSgpLGk9bi5zbGljZShyKzEpLnRyaW1TdGFydCgpLHM9Z1tvXTsic3RyaW5nIj09dHlwZW9mIHM/Z1tvXT1bcyxpXTpBcnJheS5pc0FycmF5KHMpP3MucHVzaChpKTpnW29dPWl9bm4oImdvdCBwcm94eSBzZXJ2ZXIgcmVzcG9uc2U6ICVvICVvIixoLGcpLHMoKSxuKHtjb25uZWN0OntzdGF0dXNDb2RlOmQsc3RhdHVzVGV4dDpsLGhlYWRlcnM6Z30sYnVmZmVyZWQ6dX0pfShjKTp0Lm9uY2UoInJlYWRhYmxlIixpKX1mdW5jdGlvbiBzKCl7dC5yZW1vdmVMaXN0ZW5lcigiZW5kIixjKSx0LnJlbW92ZUxpc3RlbmVyKCJlcnJvciIsdSksdC5yZW1vdmVMaXN0ZW5lcigicmVhZGFibGUiLGkpfWZ1bmN0aW9uIGMoKXtzKCksbm4oIm9uZW5kIiksZShuZXcgRXJyb3IoIlByb3h5IGNvbm5lY3Rpb24gZW5kZWQgYmVmb3JlIHJlY2VpdmluZyBDT05ORUNUIHJlc3BvbnNlIikpfWZ1bmN0aW9uIHUodCl7cygpLG5uKCJvbmVycm9yICVvIix0KSxlKHQpfXQub24oImVycm9yIix1KSx0Lm9uKCJlbmQiLGMpLGkoKX0pfWZ1bmN0aW9uIHJuKC4uLnQpe3cubG9nKCJbaHR0cHMtcHJveHktYWdlbnRdIiwuLi50KX1jbGFzcyBvbiBleHRlbmRzIHRue2NvbnN0cnVjdG9yKHQsbil7c3VwZXIobiksdGhpcy5vcHRpb25zPXt9LHRoaXMucHJveHk9InN0cmluZyI9PXR5cGVvZiB0P25ldyBVUkwodCk6dCx0aGlzLnByb3h5SGVhZGVycz1uPy5oZWFkZXJzPz97fSxybigiQ3JlYXRpbmcgbmV3IEh0dHBzUHJveHlBZ2VudCBpbnN0YW5jZTogJW8iLHRoaXMucHJveHkuaHJlZik7Y29uc3QgZT0odGhpcy5wcm94eS5ob3N0bmFtZXx8dGhpcy5wcm94eS5ob3N0KS5yZXBsYWNlKC9eXFt8XF0kL2csIiIpLHI9dGhpcy5wcm94eS5wb3J0P3BhcnNlSW50KHRoaXMucHJveHkucG9ydCwxMCk6Imh0dHBzOiI9PT10aGlzLnByb3h5LnByb3RvY29sPzQ0Mzo4MDt0aGlzLmNvbm5lY3RPcHRzPXtBTFBOUHJvdG9jb2xzOlsiaHR0cC8xLjEiXSwuLi5uP2NuKG4sImhlYWRlcnMiKTpudWxsLGhvc3Q6ZSxwb3J0OnJ9fWFzeW5jIGNvbm5lY3QodCxuKXtjb25zdHtwcm94eTplfT10aGlzO2lmKCFuLmhvc3QpdGhyb3cgbmV3IFR5cGVFcnJvcignTm8gImhvc3QiIHByb3ZpZGVkJyk7bGV0IHI7aWYoImh0dHBzOiI9PT1lLnByb3RvY29sKXtybigiQ3JlYXRpbmcgYHRscy5Tb2NrZXRgOiAlbyIsdGhpcy5jb25uZWN0T3B0cyk7Y29uc3QgdD10aGlzLmNvbm5lY3RPcHRzLnNlcnZlcm5hbWV8fHRoaXMuY29ubmVjdE9wdHMuaG9zdDtyPWYuY29ubmVjdCh7Li4udGhpcy5jb25uZWN0T3B0cyxzZXJ2ZXJuYW1lOnQmJmEuaXNJUCh0KT92b2lkIDA6dH0pfWVsc2Ugcm4oIkNyZWF0aW5nIGBuZXQuU29ja2V0YDogJW8iLHRoaXMuY29ubmVjdE9wdHMpLHI9YS5jb25uZWN0KHRoaXMuY29ubmVjdE9wdHMpO2NvbnN0IG89ImZ1bmN0aW9uIj09dHlwZW9mIHRoaXMucHJveHlIZWFkZXJzP3RoaXMucHJveHlIZWFkZXJzKCk6ey4uLnRoaXMucHJveHlIZWFkZXJzfSxpPWEuaXNJUHY2KG4uaG9zdCk/YFske24uaG9zdH1dYDpuLmhvc3Q7bGV0IHM9YENPTk5FQ1QgJHtpfToke24ucG9ydH0gSFRUUC8xLjFcclxuYDtpZihlLnVzZXJuYW1lfHxlLnBhc3N3b3JkKXtjb25zdCB0PWAke2RlY29kZVVSSUNvbXBvbmVudChlLnVzZXJuYW1lKX06JHtkZWNvZGVVUklDb21wb25lbnQoZS5wYXNzd29yZCl9YDtvWyJQcm94eS1BdXRob3JpemF0aW9uIl09YEJhc2ljICR7QnVmZmVyLmZyb20odCkudG9TdHJpbmcoImJhc2U2NCIpfWB9by5Ib3N0PWAke2l9OiR7bi5wb3J0fWAsb1siUHJveHktQ29ubmVjdGlvbiJdfHwob1siUHJveHktQ29ubmVjdGlvbiJdPXRoaXMua2VlcEFsaXZlPyJLZWVwLUFsaXZlIjoiY2xvc2UiKTtmb3IoY29uc3QgdCBvZiBPYmplY3Qua2V5cyhvKSlzKz1gJHt0fTogJHtvW3RdfVxyXG5gO2NvbnN0IGM9ZW4ocik7ci53cml0ZShgJHtzfVxyXG5gKTtjb25zdHtjb25uZWN0OnUsYnVmZmVyZWQ6aH09YXdhaXQgYztpZih0LmVtaXQoInByb3h5Q29ubmVjdCIsdSksdGhpcy5lbWl0KCJwcm94eUNvbm5lY3QiLHUsdCksMjAwPT09dS5zdGF0dXNDb2RlKXtpZih0Lm9uY2UoInNvY2tldCIsc24pLG4uc2VjdXJlRW5kcG9pbnQpe3JuKCJVcGdyYWRpbmcgc29ja2V0IGNvbm5lY3Rpb24gdG8gVExTIik7Y29uc3QgdD1uLnNlcnZlcm5hbWV8fG4uaG9zdDtyZXR1cm4gZi5jb25uZWN0KHsuLi5jbihuLCJob3N0IiwicGF0aCIsInBvcnQiKSxzb2NrZXQ6cixzZXJ2ZXJuYW1lOmEuaXNJUCh0KT92b2lkIDA6dH0pfXJldHVybiByfXIuZGVzdHJveSgpO2NvbnN0IHA9bmV3IGEuU29ja2V0KHt3cml0YWJsZTohMX0pO3JldHVybiBwLnJlYWRhYmxlPSEwLHQub25jZSgic29ja2V0Iix0PT57cm4oIlJlcGxheWluZyBwcm94eSBidWZmZXIgZm9yIGZhaWxlZCByZXF1ZXN0IiksdC5wdXNoKGgpLHQucHVzaChudWxsKX0pLHB9fWZ1bmN0aW9uIHNuKHQpe3QucmVzdW1lKCl9ZnVuY3Rpb24gY24odCwuLi5uKXtjb25zdCBlPXt9O2xldCByO2ZvcihyIGluIHQpbi5pbmNsdWRlcyhyKXx8KGVbcl09dFtyXSk7cmV0dXJuIGV9b24ucHJvdG9jb2xzPVsiaHR0cCIsImh0dHBzIl07ZnVuY3Rpb24gdW4odCl7cmV0dXJuIHQucmVwbGFjZSgvXltBLVpdOi8sIiIpLnJlcGxhY2UoL1xcL2csIi8iKX1jb25zdCBhbj1uO2xldCBmbixobj0wLHBuPXt9O2Z1bmN0aW9uIGRuKHQpe2FuLmRlYnVnJiZjb25zb2xlLmxvZyhgW0FOUiBXb3JrZXJdICR7dH1gKX12YXIgbG4sZ24sbW47Y29uc3QgeW49ZnVuY3Rpb24odCl7bGV0IG47dHJ5e249bmV3IFVSTCh0LnVybCl9Y2F0Y2gobil7cmV0dXJuIGIoKCk9Pntjb25zb2xlLndhcm4oIltAc2VudHJ5L25vZGVdOiBJbnZhbGlkIGRzbiBvciB0dW5uZWwgb3B0aW9uLCB3aWxsIG5vdCBzZW5kIGFueSBldmVudHMuIFRoZSB0dW5uZWwgb3B0aW9uIG11c3QgYmUgYSBmdWxsIFVSTCB3aGVuIHVzZWQuIil9KSxLdCh0LCgpPT5Qcm9taXNlLnJlc29sdmUoe30pKX1jb25zdCBlPSJodHRwczoiPT09bi5wcm90b2NvbCxyPWZ1bmN0aW9uKHQsbil7Y29uc3R7bm9fcHJveHk6ZX09cHJvY2Vzcy5lbnYscj1lPy5zcGxpdCgiLCIpLnNvbWUobj0+dC5ob3N0LmVuZHNXaXRoKG4pfHx0Lmhvc3RuYW1lLmVuZHNXaXRoKG4pKTtyZXR1cm4gcj92b2lkIDA6bn0obix0LnByb3h5fHwoZT9wcm9jZXNzLmVudi5odHRwc19wcm94eTp2b2lkIDApfHxwcm9jZXNzLmVudi5odHRwX3Byb3h5KSxvPWU/czppLGE9dm9pZCAwIT09dC5rZWVwQWxpdmUmJnQua2VlcEFsaXZlLGY9cj9uZXcgb24ocik6bmV3IG8uQWdlbnQoe2tlZXBBbGl2ZTphLG1heFNvY2tldHM6MzAsdGltZW91dDoyZTN9KSxoPWZ1bmN0aW9uKHQsbixlKXtjb25zdHtob3N0bmFtZTpyLHBhdGhuYW1lOm8scG9ydDppLHByb3RvY29sOnMsc2VhcmNoOmF9PW5ldyBVUkwodC51cmwpO3JldHVybiBmdW5jdGlvbihmKXtyZXR1cm4gbmV3IFByb21pc2UoKGgscCk9PntGdCgoKT0+e2xldCBkPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgYyh7cmVhZCgpe3RoaXMucHVzaCh0KSx0aGlzLnB1c2gobnVsbCl9fSl9KGYuYm9keSk7Y29uc3QgbD17Li4udC5oZWFkZXJzfTtmLmJvZHkubGVuZ3RoPjMyNzY4JiYobFsiY29udGVudC1lbmNvZGluZyJdPSJnemlwIixkPWQucGlwZSh1KCkpKTtjb25zdCBnPXIuc3RhcnRzV2l0aCgiWyIpLG09bi5yZXF1ZXN0KHttZXRob2Q6IlBPU1QiLGFnZW50OmUsaGVhZGVyczpsLGhvc3RuYW1lOmc/ci5zbGljZSgxLC0xKTpyLHBhdGg6YCR7b30ke2F9YCxwb3J0OmkscHJvdG9jb2w6cyxjYTp0LmNhQ2VydHN9LHQ9Pnt0Lm9uKCJkYXRhIiwoKT0+e30pLHQub24oImVuZCIsKCk9Pnt9KSx0LnNldEVuY29kaW5nKCJ1dGY4Iik7Y29uc3Qgbj10LmhlYWRlcnNbInJldHJ5LWFmdGVyIl0/P251bGwsZT10LmhlYWRlcnNbIngtc2VudHJ5LXJhdGUtbGltaXRzIl0/P251bGw7aCh7c3RhdHVzQ29kZTp0LnN0YXR1c0NvZGUsaGVhZGVyczp7InJldHJ5LWFmdGVyIjpuLCJ4LXNlbnRyeS1yYXRlLWxpbWl0cyI6QXJyYXkuaXNBcnJheShlKT9lWzBdfHxudWxsOmV9fSl9KTttLm9uKCJlcnJvciIscCksZC5waXBlKG0pfSl9KX19KHQsdC5odHRwTW9kdWxlPz9vLGYpO3JldHVybiBLdCh0LGgpfSh7dXJsOihsbj1hbi5kc24sZ249YW4udHVubmVsLG1uPWFuLnNka01ldGFkYXRhLnNkayxnbnx8YCR7ZnVuY3Rpb24odCl7cmV0dXJuYCR7ZnVuY3Rpb24odCl7Y29uc3Qgbj10LnByb3RvY29sP2Ake3QucHJvdG9jb2x9OmA6IiIsZT10LnBvcnQ/YDoke3QucG9ydH1gOiIiO3JldHVybmAke259Ly8ke3QuaG9zdH0ke2V9JHt0LnBhdGg/YC8ke3QucGF0aH1gOiIifS9hcGkvYH0odCl9JHt0LnByb2plY3RJZH0vZW52ZWxvcGUvYH0obG4pfT8ke2Z1bmN0aW9uKHQsbil7Y29uc3QgZT17c2VudHJ5X3ZlcnNpb246IjcifTtyZXR1cm4gdC5wdWJsaWNLZXkmJihlLnNlbnRyeV9rZXk9dC5wdWJsaWNLZXkpLG4mJihlLnNlbnRyeV9jbGllbnQ9YCR7bi5uYW1lfS8ke24udmVyc2lvbn1gKSxuZXcgVVJMU2VhcmNoUGFyYW1zKGUpLnRvU3RyaW5nKCl9KGxuLG1uKX1gKX0pO2FzeW5jIGZ1bmN0aW9uIGJuKCl7aWYoZm4pe2RuKCJTZW5kaW5nIGFibm9ybWFsIHNlc3Npb24iKSxLKGZuLHtzdGF0dXM6ImFibm9ybWFsIixhYm5vcm1hbF9tZWNoYW5pc206ImFucl9mb3JlZ3JvdW5kIixyZWxlYXNlOmFuLnJlbGVhc2UsZW52aXJvbm1lbnQ6YW4uZW52aXJvbm1lbnR9KTtjb25zdCB0PWZ1bmN0aW9uKHQsbixlLHIpe2NvbnN0IG89THQoZSk7cmV0dXJuIFR0KHtzZW50X2F0Om5ldyBEYXRlKFAoKSkudG9JU09TdHJpbmcoKSwuLi5vJiZ7c2RrOm99LC4uLiEhciYmbiYme2RzbjpidChuKX19LFsiYWdncmVnYXRlcyJpbiB0P1t7dHlwZToic2Vzc2lvbnMifSx0XTpbe3R5cGU6InNlc3Npb24ifSx0LnRvSlNPTigpXV0pfShmbixhbi5kc24sYW4uc2RrTWV0YWRhdGEsYW4udHVubmVsKTtkbihKU09OLnN0cmluZ2lmeSh0KSksYXdhaXQgeW4uc2VuZCh0KTt0cnl7ZT8ucG9zdE1lc3NhZ2UoInNlc3Npb24tZW5kZWQiKX1jYXRjaHt9fX1mdW5jdGlvbiB2bih0KXtpZighdClyZXR1cm47Y29uc3Qgbj1mdW5jdGlvbih0KXtpZighdC5sZW5ndGgpcmV0dXJuW107Y29uc3Qgbj1BcnJheS5mcm9tKHQpO3JldHVybi9zZW50cnlXcmFwcGVkLy50ZXN0KEUobikuZnVuY3Rpb258fCIiKSYmbi5wb3AoKSxuLnJldmVyc2UoKSwkLnRlc3QoRShuKS5mdW5jdGlvbnx8IiIpJiYobi5wb3AoKSwkLnRlc3QoRShuKS5mdW5jdGlvbnx8IiIpJiZuLnBvcCgpKSxuLnNsaWNlKDAsNTApLm1hcCh0PT4oey4uLnQsZmlsZW5hbWU6dC5maWxlbmFtZXx8RShuKS5maWxlbmFtZSxmdW5jdGlvbjp0LmZ1bmN0aW9ufHwiPyJ9KSl9KHQpO2lmKGFuLmFwcFJvb3RQYXRoKWZvcihjb25zdCB0IG9mIG4pdC5maWxlbmFtZSYmKHQuZmlsZW5hbWU9TSh0LmZpbGVuYW1lLGFuLmFwcFJvb3RQYXRoKSk7cmV0dXJuIG59YXN5bmMgZnVuY3Rpb24gX24odCxuKXtpZihobj49YW4ubWF4QW5yRXZlbnRzKXJldHVybjtobis9MSxhd2FpdCBibigpLGRuKCJTZW5kaW5nIGV2ZW50Iik7Y29uc3QgZT17ZXZlbnRfaWQ6RygpLGNvbnRleHRzOmFuLmNvbnRleHRzLHJlbGVhc2U6YW4ucmVsZWFzZSxlbnZpcm9ubWVudDphbi5lbnZpcm9ubWVudCxkaXN0OmFuLmRpc3QscGxhdGZvcm06Im5vZGUiLGxldmVsOiJlcnJvciIsZXhjZXB0aW9uOnt2YWx1ZXM6W3t0eXBlOiJBcHBsaWNhdGlvbk5vdFJlc3BvbmRpbmciLHZhbHVlOmBBcHBsaWNhdGlvbiBOb3QgUmVzcG9uZGluZyBmb3IgYXQgbGVhc3QgJHthbi5hbnJUaHJlc2hvbGR9IG1zYCxzdGFja3RyYWNlOntmcmFtZXM6dm4odCl9LG1lY2hhbmlzbTp7dHlwZToiQU5SIn19XX0sdGFnczphbi5zdGF0aWNUYWdzfTtuJiZmdW5jdGlvbih0LG4pe2lmKEd0KHQsbiksIXQuY29udGV4dHM/LnRyYWNlKXtjb25zdHt0cmFjZUlkOmUscGFyZW50U3BhbklkOnIscHJvcGFnYXRpb25TcGFuSWQ6b309bi5wcm9wYWdhdGlvbkNvbnRleHQ7dC5jb250ZXh0cz17dHJhY2U6e3RyYWNlX2lkOmUsc3Bhbl9pZDpvfHxWKCkscGFyZW50X3NwYW5faWQ6cn0sLi4udC5jb250ZXh0c319fShlLG4pLGZ1bmN0aW9uKHQpe2lmKDA9PT1PYmplY3Qua2V5cyhwbikubGVuZ3RoKXJldHVybjtjb25zdCBuPWFuLmFwcFJvb3RQYXRoP3t9OnBuO2lmKGFuLmFwcFJvb3RQYXRoKWZvcihjb25zdFt0LGVdb2YgT2JqZWN0LmVudHJpZXMocG4pKW5bTSh0LGFuLmFwcFJvb3RQYXRoKV09ZTtjb25zdCBlPW5ldyBNYXA7Zm9yKGNvbnN0IHIgb2YgdC5leGNlcHRpb24/LnZhbHVlc3x8W10pZm9yKGNvbnN0IHQgb2Ygci5zdGFja3RyYWNlPy5mcmFtZXN8fFtdKXtjb25zdCByPXQuYWJzX3BhdGh8fHQuZmlsZW5hbWU7ciYmbltyXSYmZS5zZXQocixuW3JdKX1pZihlLnNpemU+MCl7Y29uc3Qgbj1bXTtmb3IoY29uc3RbdCxyXW9mIGUuZW50cmllcygpKW4ucHVzaCh7dHlwZToic291cmNlbWFwIixjb2RlX2ZpbGU6dCxkZWJ1Z19pZDpyfSk7dC5kZWJ1Z19tZXRhPXtpbWFnZXM6bn19fShlKTtjb25zdCByPU10KGUsYW4uZHNuLGFuLnNka01ldGFkYXRhLGFuLnR1bm5lbCk7ZG4oSlNPTi5zdHJpbmdpZnkocikpLGF3YWl0IHluLnNlbmQociksYXdhaXQgeW4uZmx1c2goMmUzKSxobj49YW4ubWF4QW5yRXZlbnRzJiZzZXRUaW1lb3V0KCgpPT57cHJvY2Vzcy5leGl0KDApfSw1ZTMpfWxldCBTbjtpZihkbigiU3RhcnRlZCIpLGFuLmNhcHR1cmVTdGFja1RyYWNlKXtkbigiQ29ubmVjdGluZyB0byBkZWJ1Z2dlciIpO2NvbnN0IG49bmV3IHQ7bi5jb25uZWN0VG9NYWluVGhyZWFkKCksZG4oIkNvbm5lY3RlZCB0byBkZWJ1Z2dlciIpO2NvbnN0IGU9bmV3IE1hcDtuLm9uKCJEZWJ1Z2dlci5zY3JpcHRQYXJzZWQiLHQ9PntlLnNldCh0LnBhcmFtcy5zY3JpcHRJZCx0LnBhcmFtcy51cmwpfSksbi5vbigiRGVidWdnZXIucGF1c2VkIix0PT57aWYoIm90aGVyIj09PXQucGFyYW1zLnJlYXNvbil0cnl7ZG4oIkRlYnVnZ2VyIHBhdXNlZCIpO2NvbnN0IGk9Wy4uLnQucGFyYW1zLmNhbGxGcmFtZXNdLHM9YW4uYXBwUm9vdFBhdGg/ZnVuY3Rpb24odD0ocHJvY2Vzcy5hcmd2WzFdP3F0KHByb2Nlc3MuYXJndlsxXSk6cHJvY2Vzcy5jd2QoKSksbj0iXFwiPT09byl7Y29uc3QgZT1uP3VuKHQpOnQ7cmV0dXJuIHQ9PntpZighdClyZXR1cm47Y29uc3Qgbz1uP3VuKHQpOnQ7bGV0e2RpcjppLGJhc2U6cyxleHQ6Y309ci5wYXJzZShvKTsiLmpzIiE9PWMmJiIubWpzIiE9PWMmJiIuY2pzIiE9PWN8fChzPXMuc2xpY2UoMCwtMSpjLmxlbmd0aCkpO2NvbnN0IHU9ZGVjb2RlVVJJQ29tcG9uZW50KHMpO2l8fChpPSIuIik7Y29uc3QgYT1pLmxhc3RJbmRleE9mKCIvbm9kZV9tb2R1bGVzIik7aWYoYT4tMSlyZXR1cm5gJHtpLnNsaWNlKGErMTQpLnJlcGxhY2UoL1wvL2csIi4iKX06JHt1fWA7aWYoaS5zdGFydHNXaXRoKGUpKXtjb25zdCB0PWkuc2xpY2UoZS5sZW5ndGgrMSkucmVwbGFjZSgvXC8vZywiLiIpO3JldHVybiB0P2Ake3R9OiR7dX1gOnV9cmV0dXJuIHV9fShhbi5hcHBSb290UGF0aCk6KCk9Pnt9LGM9aS5tYXAodD0+ZnVuY3Rpb24odCxuLGUpe2NvbnN0IHI9bj9uLnJlcGxhY2UoL15maWxlOlwvXC8vLCIiKTp2b2lkIDAsbz10LmxvY2F0aW9uLmNvbHVtbk51bWJlcj90LmxvY2F0aW9uLmNvbHVtbk51bWJlcisxOnZvaWQgMCxpPXQubG9jYXRpb24ubGluZU51bWJlcj90LmxvY2F0aW9uLmxpbmVOdW1iZXIrMTp2b2lkIDA7cmV0dXJue2ZpbGVuYW1lOnIsbW9kdWxlOmUociksZnVuY3Rpb246dC5mdW5jdGlvbk5hbWV8fCI/Iixjb2xubzpvLGxpbmVubzppLGluX2FwcDpyP1Z0KHIpOnZvaWQgMH19KHQsZS5nZXQodC5sb2NhdGlvbi5zY3JpcHRJZCkscykpLHU9c2V0VGltZW91dCgoKT0+e19uKGMpLnRoZW4obnVsbCwoKT0+e2RuKCJTZW5kaW5nIEFOUiBldmVudCBmYWlsZWQuIil9KX0sNWUzKTtuLnBvc3QoIlJ1bnRpbWUuZXZhbHVhdGUiLHtleHByZXNzaW9uOiJnbG9iYWwuX19TRU5UUllfR0VUX1NDT1BFU19fKCk7IixzaWxlbnQ6ITAscmV0dXJuQnlWYWx1ZTohMH0sKHQsZSk9Pnt0JiZkbihgRXJyb3IgZXhlY3V0aW5nIHNjcmlwdDogJyR7dC5tZXNzYWdlfSdgKSxjbGVhclRpbWVvdXQodSk7Y29uc3Qgcj1lPy5yZXN1bHQ/ZS5yZXN1bHQudmFsdWU6dm9pZCAwO24ucG9zdCgiRGVidWdnZXIucmVzdW1lIiksbi5wb3N0KCJEZWJ1Z2dlci5kaXNhYmxlIiksX24oYyxyKS50aGVuKG51bGwsKCk9PntkbigiU2VuZGluZyBBTlIgZXZlbnQgZmFpbGVkLiIpfSl9KX1jYXRjaCh0KXt0aHJvdyBuLnBvc3QoIkRlYnVnZ2VyLnJlc3VtZSIpLG4ucG9zdCgiRGVidWdnZXIuZGlzYWJsZSIpLHR9fSksU249KCk9Pnt0cnl7bi5wb3N0KCJEZWJ1Z2dlci5lbmFibGUiLCgpPT57bi5wb3N0KCJEZWJ1Z2dlci5wYXVzZSIpfSl9Y2F0Y2h7fX19Y29uc3R7cG9sbDp3bn09ZnVuY3Rpb24odCxuLGUscil7Y29uc3Qgbz10KCk7bGV0IGk9ITEscz0hMDtyZXR1cm4gc2V0SW50ZXJ2YWwoKCk9Pntjb25zdCB0PW8uZ2V0VGltZU1zKCk7ITE9PT1pJiZ0Pm4rZSYmKGk9ITAscyYmcigpKSx0PG4rZSYmKGk9ITEpfSwyMCkse3BvbGw6KCk9PntvLnJlc2V0KCl9LGVuYWJsZWQ6dD0+e3M9dH19fShmdW5jdGlvbigpe2xldCB0PXByb2Nlc3MuaHJ0aW1lKCk7cmV0dXJue2dldFRpbWVNczooKT0+e2NvbnN0W24sZV09cHJvY2Vzcy5ocnRpbWUodCk7cmV0dXJuIE1hdGguZmxvb3IoMWUzKm4rZS8xZTYpfSxyZXNldDooKT0+e3Q9cHJvY2Vzcy5ocnRpbWUoKX19fSxhbi5wb2xsSW50ZXJ2YWwsYW4uYW5yVGhyZXNob2xkLGZ1bmN0aW9uKCl7ZG4oIldhdGNoZG9nIHRpbWVvdXQiKSxTbj8oZG4oIlBhdXNpbmcgZGVidWdnZXIgdG8gY2FwdHVyZSBzdGFjayB0cmFjZSIpLFNuKCkpOihkbigiQ2FwdHVyaW5nIGV2ZW50IHdpdGhvdXQgYSBzdGFjayB0cmFjZSIpLF9uKCkudGhlbihudWxsLCgpPT57ZG4oIlNlbmRpbmcgQU5SIGV2ZW50IGZhaWxlZCBvbiB3YXRjaGRvZyB0aW1lb3V0LiIpfSkpfSk7ZT8ub24oIm1lc3NhZ2UiLHQ9Pnt0LnNlc3Npb24mJihmbj1IKHQuc2Vzc2lvbikpLHQuZGVidWdJbWFnZXMmJihwbj10LmRlYnVnSW1hZ2VzKSx3bigpfSk7";
const base64WorkerScript = "LyohIEBzZW50cnkvbm9kZS1jb3JlIDEwLjY1LjAgKGM2NmE4MTUpIHwgaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdCAqLwppbXBvcnR7U2Vzc2lvbiBhcyB0fWZyb20ibm9kZTppbnNwZWN0b3IiO2ltcG9ydHt3b3JrZXJEYXRhIGFzIG4scGFyZW50UG9ydCBhcyBlfWZyb20ibm9kZTp3b3JrZXJfdGhyZWFkcyI7aW1wb3J0e3Bvc2l4IGFzIHIsc2VwIGFzIG99ZnJvbSJub2RlOnBhdGgiO2ltcG9ydCphcyBpIGZyb20ibm9kZTpodHRwIjtpbXBvcnQqYXMgcyBmcm9tIm5vZGU6aHR0cHMiO2ltcG9ydHtSZWFkYWJsZSBhcyBjfWZyb20ibm9kZTpzdHJlYW0iO2ltcG9ydHtjcmVhdGVHemlwIGFzIHV9ZnJvbSJub2RlOnpsaWIiO2ltcG9ydCphcyBhIGZyb20ibm9kZTpuZXQiO2ltcG9ydCphcyBmIGZyb20ibm9kZTp0bHMiO2NvbnN0IGg9InVuZGVmaW5lZCI9PXR5cGVvZiBfX1NFTlRSWV9ERUJVR19ffHxfX1NFTlRSWV9ERUJVR19fLHA9Z2xvYmFsVGhpcyxkPSIxMC42NS4wIjtmdW5jdGlvbiBsKCl7cmV0dXJuIGcocCkscH1mdW5jdGlvbiBnKHQpe2NvbnN0IG49dC5fX1NFTlRSWV9fPXQuX19TRU5UUllfX3x8e307cmV0dXJuIG4udmVyc2lvbj1uLnZlcnNpb258fGQsbltkXT1uW2RdfHx7fX1mdW5jdGlvbiBtKHQsbixlPXApe2NvbnN0IHI9ZS5fX1NFTlRSWV9fPWUuX19TRU5UUllfX3x8e30sbz1yW2RdPXJbZF18fHt9O3JldHVybiBvW3RdfHwob1t0XT1uKCkpfWNvbnN0IHk9e307ZnVuY3Rpb24gYih0KXtpZighKCJjb25zb2xlImluIHApKXJldHVybiB0KCk7Y29uc3Qgbj1wLmNvbnNvbGUsZT17fSxyPU9iamVjdC5rZXlzKHkpO3IuZm9yRWFjaCh0PT57Y29uc3Qgcj15W3RdO2VbdF09blt0XSxuW3RdPXJ9KTt0cnl7cmV0dXJuIHQoKX1maW5hbGx5e3IuZm9yRWFjaCh0PT57blt0XT1lW3RdfSl9fWZ1bmN0aW9uIHYoKXtyZXR1cm4gUygpLmVuYWJsZWR9ZnVuY3Rpb24gXyh0LC4uLm4pe2gmJnYoKSYmYigoKT0+e3AuY29uc29sZVt0XShgU2VudHJ5IExvZ2dlciBbJHt0fV06YCwuLi5uKX0pfWZ1bmN0aW9uIFMoKXtyZXR1cm4gaD9tKCJsb2dnZXJTZXR0aW5ncyIsKCk9Pih7ZW5hYmxlZDohMX0pKTp7ZW5hYmxlZDohMX19Y29uc3Qgdz17ZW5hYmxlOmZ1bmN0aW9uKCl7UygpLmVuYWJsZWQ9ITB9LGRpc2FibGU6ZnVuY3Rpb24oKXtTKCkuZW5hYmxlZD0hMX0saXNFbmFibGVkOnYsbG9nOmZ1bmN0aW9uKC4uLnQpe18oImxvZyIsLi4udCl9LHdhcm46ZnVuY3Rpb24oLi4udCl7Xygid2FybiIsLi4udCl9LGVycm9yOmZ1bmN0aW9uKC4uLnQpe18oImVycm9yIiwuLi50KX19LCQ9L2NhcHR1cmVNZXNzYWdlfGNhcHR1cmVFeGNlcHRpb24vO2Z1bmN0aW9uIEUodCl7cmV0dXJuIHRbdC5sZW5ndGgtMV18fHt9fWNvbnN0IHg9Ijxhbm9ueW1vdXM+Ijtjb25zdCBOPU9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7ZnVuY3Rpb24gQyh0LG4pe3JldHVybiBOLmNhbGwodCk9PT1gW29iamVjdCAke259XWB9ZnVuY3Rpb24gaih0KXtyZXR1cm4gQm9vbGVhbih0Py50aGVuJiYiZnVuY3Rpb24iPT10eXBlb2YgdC50aGVuKX1mdW5jdGlvbiBSKHQsbil7dHJ5e3JldHVybiB0IGluc3RhbmNlb2Ygbn1jYXRjaHtyZXR1cm4hMX19ZnVuY3Rpb24gQSh0KXtpZihmdW5jdGlvbih0KXtzd2l0Y2goTi5jYWxsKHQpKXtjYXNlIltvYmplY3QgRXJyb3JdIjpjYXNlIltvYmplY3QgRXhjZXB0aW9uXSI6Y2FzZSJbb2JqZWN0IERPTUV4Y2VwdGlvbl0iOmNhc2UiW29iamVjdCBXZWJBc3NlbWJseS5FeGNlcHRpb25dIjpyZXR1cm4hMDtkZWZhdWx0OnJldHVybiBSKHQsRXJyb3IpfX0odCkpcmV0dXJue21lc3NhZ2U6dC5tZXNzYWdlLG5hbWU6dC5uYW1lLHN0YWNrOnQuc3RhY2ssLi4uSSh0KX07aWYobj10LCJ1bmRlZmluZWQiIT10eXBlb2YgRXZlbnQmJlIobixFdmVudCkpe2NvbnN0e3R5cGU6bix0YXJnZXQ6ZSxjdXJyZW50VGFyZ2V0OnIsZGV0YWlsOm99PXQ7cmV0dXJue3R5cGU6bix0YXJnZXQ6ZSxjdXJyZW50VGFyZ2V0OnIsLi4ubz97ZGV0YWlsOm99Ont9LC4uLkkodCl9fXZhciBuO3JldHVybiB0fWZ1bmN0aW9uIEkodCl7cmV0dXJuIm9iamVjdCI9PXR5cGVvZihuPXQpJiZudWxsIT09bj9PYmplY3QuZnJvbUVudHJpZXMoT2JqZWN0LmVudHJpZXModCkpOnt9O3ZhciBufWxldCBPO2Z1bmN0aW9uIFQodCl7aWYodm9pZCAwIT09TylyZXR1cm4gTz9PKHQpOnQoKTtjb25zdCBuPVN5bWJvbC5mb3IoIl9fU0VOVFJZX1NBRkVfUkFORE9NX0lEX1dSQVBQRVJfXyIpLGU9cDtyZXR1cm4gbiBpbiBlJiYiZnVuY3Rpb24iPT10eXBlb2YgZVtuXT8oTz1lW25dLE8odCkpOihPPW51bGwsdCgpKX1mdW5jdGlvbiBrKCl7cmV0dXJuIFQoKCk9Pk1hdGgucmFuZG9tKCkpfWZ1bmN0aW9uIFAoKXtyZXR1cm4gVCgoKT0+RGF0ZS5ub3coKSl9Y29uc3QgRD1TeW1ib2wuZm9yKCJzZW50cnkuc2tpcE5vcm1hbGl6YXRpb24iKSxVPVN5bWJvbC5mb3IoInNlbnRyeS5vdmVycmlkZU5vcm1hbGl6YXRpb25EZXB0aCIpO2Z1bmN0aW9uIEIodCxuPTEwMCxlPTEvMCl7dHJ5e3JldHVybiBMKCIiLHQsbixlKX1jYXRjaCh0KXtyZXR1cm57RVJST1I6YCoqbm9uLXNlcmlhbGl6YWJsZSoqICgke3R9KWB9fX1mdW5jdGlvbiBMKHQsbixlPTEvMCxyPTEvMCxvPWZ1bmN0aW9uKCl7Y29uc3QgdD1uZXcgV2Vha1NldDtmdW5jdGlvbiBuKG4pe3JldHVybiEhdC5oYXMobil8fCh0LmFkZChuKSwhMSl9ZnVuY3Rpb24gZShuKXt0LmRlbGV0ZShuKX1yZXR1cm5bbixlXX0oKSl7Y29uc3RbaSxzXT1vO2lmKG51bGw9PW58fFsiYm9vbGVhbiIsInN0cmluZyJdLmluY2x1ZGVzKHR5cGVvZiBuKXx8Im51bWJlciI9PXR5cGVvZiBuJiZOdW1iZXIuaXNGaW5pdGUobikpcmV0dXJuIG47Y29uc3QgYz1mdW5jdGlvbih0LG4pe3RyeXtpZigidW5kZWZpbmVkIiE9dHlwZW9mIGdsb2JhbCYmbj09PWdsb2JhbClyZXR1cm4iW0dsb2JhbF0iO2lmKCJudW1iZXIiPT10eXBlb2YgbiYmIU51bWJlci5pc0Zpbml0ZShuKSlyZXR1cm5gWyR7bn1dYDtpZigiZnVuY3Rpb24iPT10eXBlb2YgbilyZXR1cm5gW0Z1bmN0aW9uOiAke2Z1bmN0aW9uKHQpe3RyeXtyZXR1cm4gdCYmImZ1bmN0aW9uIj09dHlwZW9mIHQmJnQubmFtZXx8eH1jYXRjaHtyZXR1cm4geH19KG4pfV1gO2lmKCJzeW1ib2wiPT10eXBlb2YgbilyZXR1cm5gWyR7U3RyaW5nKG4pfV1gO2lmKCJiaWdpbnQiPT10eXBlb2YgbilyZXR1cm5gW0JpZ0ludDogJHtTdHJpbmcobil9XWA7Y29uc3QgdD1mdW5jdGlvbih0KXtjb25zdCBuPU9iamVjdC5nZXRQcm90b3R5cGVPZih0KTtyZXR1cm4gbj8uY29uc3RydWN0b3I/bi5jb25zdHJ1Y3Rvci5uYW1lOiJudWxsIHByb3RvdHlwZSJ9KG4pO3JldHVybmBbb2JqZWN0ICR7dH1dYH1jYXRjaCh0KXtyZXR1cm5gKipub24tc2VyaWFsaXphYmxlKiogKCR7dH0pYH19KDAsbik7aWYoIWMuc3RhcnRzV2l0aCgiW29iamVjdCAiKSlyZXR1cm4gYztpZihmdW5jdGlvbih0KXtyZXR1cm4gQm9vbGVhbih0W0RdKX0obikpcmV0dXJuIG47Y29uc3QgdT1mdW5jdGlvbih0KXtjb25zdCBuPXRbVV07cmV0dXJuIm51bWJlciI9PXR5cGVvZiBuP246dm9pZCAwfShuKSxhPXZvaWQgMCE9PXU/dTplO2lmKDA9PT1hKXJldHVybiBjLnJlcGxhY2UoIm9iamVjdCAiLCIiKTtpZihpKG4pKXJldHVybiJbQ2lyY3VsYXIgfl0iO2NvbnN0IGY9bjtpZihmJiYiZnVuY3Rpb24iPT10eXBlb2YgZi50b0pTT04pdHJ5e3JldHVybiBMKCIiLGYudG9KU09OKCksYS0xLHIsbyl9Y2F0Y2h7fWNvbnN0IGg9QXJyYXkuaXNBcnJheShuKT9bXTp7fTtsZXQgcD0wO2NvbnN0IGQ9QShuKTtmb3IoY29uc3QgdCBpbiBkKXtpZighT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGQsdCkpY29udGludWU7aWYocD49cil7aFt0XT0iW01heFByb3BlcnRpZXMgfl0iO2JyZWFrfWNvbnN0IG49ZFt0XTtoW3RdPUwodCxuLGEtMSxyLG8pLHArK31yZXR1cm4gcyhuKSxofWZ1bmN0aW9uIE0odCxuKXtjb25zdCBlPW4ucmVwbGFjZSgvXFwvZywiLyIpLnJlcGxhY2UoL1t8XFx7fSgpW1xdXiQrKj8uXS9nLCJcXCQmIik7bGV0IHI9dDt0cnl7cj1kZWNvZGVVUkkodCl9Y2F0Y2h7fXJldHVybiByLnJlcGxhY2UoL1xcL2csIi8iKS5yZXBsYWNlKC93ZWJwYWNrOlwvPy9nLCIiKS5yZXBsYWNlKG5ldyBSZWdFeHAoYChmaWxlOi8vKT8vKiR7ZX0vKmAsImlnIiksImFwcDovLy8iKX1mdW5jdGlvbiB6KHQsbj0wKXtyZXR1cm4ic3RyaW5nIiE9dHlwZW9mIHR8fDA9PT1ufHx0Lmxlbmd0aDw9bj90OmAke3Quc2xpY2UoMCxuKX0uLi5gfWxldCBGO2Z1bmN0aW9uIEcodD1mdW5jdGlvbigpe2NvbnN0IHQ9cDtyZXR1cm4gdC5jcnlwdG98fHQubXNDcnlwdG99KCkpe3RyeXtpZih0Py5yYW5kb21VVUlEKXJldHVybiBUKCgpPT50LnJhbmRvbVVVSUQoKSkucmVwbGFjZSgvLS9nLCIiKX1jYXRjaHt9cmV0dXJuIEZ8fChGPSIxMDAwMDAwMDEwMDA0MDAwODAwMDEwMDAwMDAwMDAwMCIpLEYucmVwbGFjZSgvWzAxOF0vZyx0PT4odF4oMTYqaygpJjE1KT4+dC80KS50b1N0cmluZygxNikpfWZ1bmN0aW9uIEooKXtyZXR1cm4gUCgpLzFlM31sZXQgVztmdW5jdGlvbiBZKCl7cmV0dXJuKFc/PyhXPWZ1bmN0aW9uKCl7Y29uc3R7cGVyZm9ybWFuY2U6dH09cDtpZighdD8ubm93fHwhdC50aW1lT3JpZ2luKXJldHVybiBKO2NvbnN0IG49dC50aW1lT3JpZ2luO3JldHVybigpPT4obitUKCgpPT50Lm5vdygpKSkvMWUzfSgpKSkoKX1mdW5jdGlvbiBIKHQpe2NvbnN0IG49WSgpLGU9e3NpZDpHKCksaW5pdDohMCx0aW1lc3RhbXA6bixzdGFydGVkOm4sZHVyYXRpb246MCxzdGF0dXM6Im9rIixlcnJvcnM6MCxpZ25vcmVEdXJhdGlvbjohMSx0b0pTT046KCk9PmZ1bmN0aW9uKHQpe3JldHVybntzaWQ6YCR7dC5zaWR9YCxpbml0OnQuaW5pdCxzdGFydGVkOm5ldyBEYXRlKDFlMyp0LnN0YXJ0ZWQpLnRvSVNPU3RyaW5nKCksdGltZXN0YW1wOm5ldyBEYXRlKDFlMyp0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxzdGF0dXM6dC5zdGF0dXMsZXJyb3JzOnQuZXJyb3JzLGRpZDoibnVtYmVyIj09dHlwZW9mIHQuZGlkfHwic3RyaW5nIj09dHlwZW9mIHQuZGlkP2Ake3QuZGlkfWA6dm9pZCAwLGR1cmF0aW9uOnQuZHVyYXRpb24sYWJub3JtYWxfbWVjaGFuaXNtOnQuYWJub3JtYWxfbWVjaGFuaXNtLGF0dHJzOntyZWxlYXNlOnQucmVsZWFzZSxlbnZpcm9ubWVudDp0LmVudmlyb25tZW50LGlwX2FkZHJlc3M6dC5pcEFkZHJlc3MsdXNlcl9hZ2VudDp0LnVzZXJBZ2VudH19fShlKX07cmV0dXJuIHQmJksoZSx0KSxlfWZ1bmN0aW9uIEsodCxuPXt9KXtpZihuLnVzZXImJighdC5pcEFkZHJlc3MmJm4udXNlci5pcF9hZGRyZXNzJiYodC5pcEFkZHJlc3M9bi51c2VyLmlwX2FkZHJlc3MpLHQuZGlkfHxuLmRpZHx8KHQuZGlkPW4udXNlci5pZHx8bi51c2VyLmVtYWlsfHxuLnVzZXIudXNlcm5hbWUpKSx0LnRpbWVzdGFtcD1uLnRpbWVzdGFtcHx8WSgpLG4uYWJub3JtYWxfbWVjaGFuaXNtJiYodC5hYm5vcm1hbF9tZWNoYW5pc209bi5hYm5vcm1hbF9tZWNoYW5pc20pLG4uaWdub3JlRHVyYXRpb24mJih0Lmlnbm9yZUR1cmF0aW9uPW4uaWdub3JlRHVyYXRpb24pLG4uc2lkJiYodC5zaWQ9MzI9PT1uLnNpZC5sZW5ndGg/bi5zaWQ6RygpKSx2b2lkIDAhPT1uLmluaXQmJih0LmluaXQ9bi5pbml0KSwhdC5kaWQmJm4uZGlkJiYodC5kaWQ9YCR7bi5kaWR9YCksIm51bWJlciI9PXR5cGVvZiBuLnN0YXJ0ZWQmJih0LnN0YXJ0ZWQ9bi5zdGFydGVkKSx0Lmlnbm9yZUR1cmF0aW9uKXQuZHVyYXRpb249dm9pZCAwO2Vsc2UgaWYoIm51bWJlciI9PXR5cGVvZiBuLmR1cmF0aW9uKXQuZHVyYXRpb249bi5kdXJhdGlvbjtlbHNle2NvbnN0IG49dC50aW1lc3RhbXAtdC5zdGFydGVkO3QuZHVyYXRpb249bj49MD9uOjB9bi5yZWxlYXNlJiYodC5yZWxlYXNlPW4ucmVsZWFzZSksbi5lbnZpcm9ubWVudCYmKHQuZW52aXJvbm1lbnQ9bi5lbnZpcm9ubWVudCksIXQuaXBBZGRyZXNzJiZuLmlwQWRkcmVzcyYmKHQuaXBBZGRyZXNzPW4uaXBBZGRyZXNzKSwhdC51c2VyQWdlbnQmJm4udXNlckFnZW50JiYodC51c2VyQWdlbnQ9bi51c2VyQWdlbnQpLCJudW1iZXIiPT10eXBlb2Ygbi5lcnJvcnMmJih0LmVycm9ycz1uLmVycm9ycyksbi5zdGF0dXMmJih0LnN0YXR1cz1uLnN0YXR1cyl9ZnVuY3Rpb24gWih0LG4sZT0yKXtpZighbnx8Im9iamVjdCIhPXR5cGVvZiBufHxlPD0wKXJldHVybiBuO2lmKHQmJjA9PT1PYmplY3Qua2V5cyhuKS5sZW5ndGgpcmV0dXJuIHQ7Y29uc3Qgcj17Li4udH07Zm9yKGNvbnN0IHQgaW4gbilPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobix0KSYmKHJbdF09WihyW3RdLG5bdF0sZS0xKSk7cmV0dXJuIHJ9ZnVuY3Rpb24gcSgpe3JldHVybiBHKCl9ZnVuY3Rpb24gVigpe3JldHVybiBHKCkuc3Vic3RyaW5nKDE2KX1mdW5jdGlvbiBRKHQpe2lmKHQpe2lmKCJvYmplY3QiPT10eXBlb2YgdCYmImRlcmVmImluIHQmJiJmdW5jdGlvbiI9PXR5cGVvZiB0LmRlcmVmKXRyeXtyZXR1cm4gdC5kZXJlZigpfWNhdGNoe3JldHVybn1yZXR1cm4gdH19Y29uc3QgWD0iX3NlbnRyeVNwYW4iO2Z1bmN0aW9uIHR0KHQsbil7bj9mdW5jdGlvbih0LG4sZSl7dHJ5e09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LG4se3ZhbHVlOmUsd3JpdGFibGU6ITAsY29uZmlndXJhYmxlOiEwfSl9Y2F0Y2h7aCYmdy5sb2coYEZhaWxlZCB0byBhZGQgbm9uLWVudW1lcmFibGUgcHJvcGVydHkgIiR7U3RyaW5nKG4pfSIgdG8gb2JqZWN0YCx0KX19KHQsWCxmdW5jdGlvbih0KXt0cnl7Y29uc3Qgbj1wLldlYWtSZWY7aWYoImZ1bmN0aW9uIj09dHlwZW9mIG4pcmV0dXJuIG5ldyBuKHQpfWNhdGNoe31yZXR1cm4gdH0obikpOmRlbGV0ZSB0W1hdfWZ1bmN0aW9uIG50KHQpe3JldHVybiBRKHRbWF0pfWNsYXNzIGV0e2NvbnN0cnVjdG9yKCl7dGhpcy50PSExLHRoaXMubz1bXSx0aGlzLmk9W10sdGhpcy51PVtdLHRoaXMuaD1bXSx0aGlzLnA9e30sdGhpcy5sPXt9LHRoaXMubT17fSx0aGlzLnY9e30sdGhpcy5fPXt9LHRoaXMuUz17fSx0aGlzLk49e3RyYWNlSWQ6cSgpLHNhbXBsZVJhbmQ6aygpfX1jbG9uZSgpe2NvbnN0IHQ9bmV3IGV0O3JldHVybiB0LnU9Wy4uLnRoaXMudV0sdC5sPXsuLi50aGlzLmx9LHQubT17Li4udGhpcy5tfSx0LnY9ey4uLnRoaXMudn0sdC5fPXsuLi50aGlzLl99LHRoaXMuXy5mbGFncyYmKHQuXy5mbGFncz17dmFsdWVzOlsuLi50aGlzLl8uZmxhZ3MudmFsdWVzXX0pLHQucD10aGlzLnAsdC5DPXRoaXMuQyx0Lmo9dGhpcy5qLHQuUj10aGlzLlIsdC5BPXRoaXMuQSx0Lmk9Wy4uLnRoaXMuaV0sdC5oPVsuLi50aGlzLmhdLHQuUz17Li4udGhpcy5TfSx0Lk49ey4uLnRoaXMuTn0sdC5JPXRoaXMuSSx0Lk89dGhpcy5PLHQuVD10aGlzLlQsdHQodCxudCh0aGlzKSksdH1zZXRDbGllbnQodCl7dGhpcy5JPXR9c2V0TGFzdEV2ZW50SWQodCl7dGhpcy5PPXR9Z2V0Q2xpZW50KCl7cmV0dXJuIHRoaXMuSX1sYXN0RXZlbnRJZCgpe3JldHVybiB0aGlzLk99YWRkU2NvcGVMaXN0ZW5lcih0KXt0aGlzLm8ucHVzaCh0KX1hZGRFdmVudFByb2Nlc3Nvcih0KXtyZXR1cm4gdGhpcy5pLnB1c2godCksdGhpc31zZXRVc2VyKHQpe3JldHVybiB0aGlzLnA9dHx8e2VtYWlsOnZvaWQgMCxpZDp2b2lkIDAsaXBfYWRkcmVzczp2b2lkIDAsdXNlcm5hbWU6dm9pZCAwfSx0aGlzLmomJksodGhpcy5qLHt1c2VyOnR9KSx0aGlzLmsoKSx0aGlzfWdldFVzZXIoKXtyZXR1cm4gdGhpcy5wfXNldENvbnZlcnNhdGlvbklkKHQpe3JldHVybiB0aGlzLlQ9dHx8dm9pZCAwLHRoaXMuaygpLHRoaXN9c2V0VGFncyh0KXtyZXR1cm4gdGhpcy5sPXsuLi50aGlzLmwsLi4udH0sdGhpcy5rKCksdGhpc31zZXRUYWcodCxuKXtyZXR1cm4gdGhpcy5zZXRUYWdzKHtbdF06bn0pfXNldEF0dHJpYnV0ZXModCl7cmV0dXJuIHRoaXMubT17Li4udGhpcy5tLC4uLnR9LHRoaXMuaygpLHRoaXN9c2V0QXR0cmlidXRlKHQsbil7cmV0dXJuIHRoaXMuc2V0QXR0cmlidXRlcyh7W3RdOm59KX1yZW1vdmVBdHRyaWJ1dGUodCl7cmV0dXJuIHQgaW4gdGhpcy5tJiYoZGVsZXRlIHRoaXMubVt0XSx0aGlzLmsoKSksdGhpc31zZXRFeHRyYXModCl7cmV0dXJuIHRoaXMudj17Li4udGhpcy52LC4uLnR9LHRoaXMuaygpLHRoaXN9c2V0RXh0cmEodCxuKXtyZXR1cm4gdGhpcy52PXsuLi50aGlzLnYsW3RdOm59LHRoaXMuaygpLHRoaXN9c2V0RmluZ2VycHJpbnQodCl7cmV0dXJuIHRoaXMuQT10LHRoaXMuaygpLHRoaXN9c2V0TGV2ZWwodCl7cmV0dXJuIHRoaXMuQz10LHRoaXMuaygpLHRoaXN9c2V0VHJhbnNhY3Rpb25OYW1lKHQpe3JldHVybiB0aGlzLlI9dCx0aGlzLmsoKSx0aGlzfXNldENvbnRleHQodCxuKXtyZXR1cm4gbnVsbD09PW4/ZGVsZXRlIHRoaXMuX1t0XTp0aGlzLl9bdF09bix0aGlzLmsoKSx0aGlzfXNldFNlc3Npb24odCl7cmV0dXJuIHQ/dGhpcy5qPXQ6ZGVsZXRlIHRoaXMuaix0aGlzLmsoKSx0aGlzfWdldFNlc3Npb24oKXtyZXR1cm4gdGhpcy5qfXVwZGF0ZSh0KXtpZighdClyZXR1cm4gdGhpcztjb25zdCBuPSJmdW5jdGlvbiI9PXR5cGVvZiB0P3QodGhpcyk6dCxlPW4gaW5zdGFuY2VvZiBldD9uLmdldFNjb3BlRGF0YSgpOkMobiwiT2JqZWN0Iik/dDp2b2lkIDA7Y29uc3R7dGFnczpyLGF0dHJpYnV0ZXM6byxleHRyYTppLHVzZXI6cyxjb250ZXh0czpjLGxldmVsOnUsZmluZ2VycHJpbnQ6YT1bXSxwcm9wYWdhdGlvbkNvbnRleHQ6Zixjb252ZXJzYXRpb25JZDpofT1lfHx7fTtyZXR1cm4gdGhpcy5sPXsuLi50aGlzLmwsLi4ucn0sdGhpcy5tPXsuLi50aGlzLm0sLi4ub30sdGhpcy52PXsuLi50aGlzLnYsLi4uaX0sdGhpcy5fPXsuLi50aGlzLl8sLi4uY30scyYmT2JqZWN0LmtleXMocykubGVuZ3RoJiYodGhpcy5wPXMpLHUmJih0aGlzLkM9dSksYS5sZW5ndGgmJih0aGlzLkE9YSksZiYmKHRoaXMuTj1mKSxoJiYodGhpcy5UPWgpLHRoaXN9Y2xlYXIoKXtyZXR1cm4gdGhpcy51PVtdLHRoaXMubD17fSx0aGlzLm09e30sdGhpcy52PXt9LHRoaXMucD17fSx0aGlzLl89e30sdGhpcy5DPXZvaWQgMCx0aGlzLlI9dm9pZCAwLHRoaXMuQT12b2lkIDAsdGhpcy5qPXZvaWQgMCx0aGlzLlQ9dm9pZCAwLHR0KHRoaXMsdm9pZCAwKSx0aGlzLmg9W10sdGhpcy5zZXRQcm9wYWdhdGlvbkNvbnRleHQoe3RyYWNlSWQ6cSgpLHNhbXBsZVJhbmQ6aygpfSksdGhpcy5rKCksdGhpc31hZGRCcmVhZGNydW1iKHQsbil7Y29uc3QgZT0ibnVtYmVyIj09dHlwZW9mIG4/bjoxMDA7aWYoZTw9MClyZXR1cm4gdGhpcztjb25zdCByPXt0aW1lc3RhbXA6SigpLC4uLnQsbWVzc2FnZTp0Lm1lc3NhZ2U/eih0Lm1lc3NhZ2UsMjA0OCk6dC5tZXNzYWdlfTtyZXR1cm4gdGhpcy51LnB1c2gociksdGhpcy51Lmxlbmd0aD5lJiYodGhpcy51PXRoaXMudS5zbGljZSgtZSksdGhpcy5JPy5yZWNvcmREcm9wcGVkRXZlbnQoImJ1ZmZlcl9vdmVyZmxvdyIsImxvZ19pdGVtIikpLHRoaXMuaygpLHRoaXN9Z2V0TGFzdEJyZWFkY3J1bWIoKXtyZXR1cm4gdGhpcy51W3RoaXMudS5sZW5ndGgtMV19Y2xlYXJCcmVhZGNydW1icygpe3JldHVybiB0aGlzLnU9W10sdGhpcy5rKCksdGhpc31hZGRBdHRhY2htZW50KHQpe3JldHVybiB0aGlzLmgucHVzaCh0KSx0aGlzfWNsZWFyQXR0YWNobWVudHMoKXtyZXR1cm4gdGhpcy5oPVtdLHRoaXN9Z2V0U2NvcGVEYXRhKCl7cmV0dXJue2JyZWFkY3J1bWJzOnRoaXMudSxhdHRhY2htZW50czp0aGlzLmgsY29udGV4dHM6dGhpcy5fLHRhZ3M6dGhpcy5sLGF0dHJpYnV0ZXM6dGhpcy5tLGV4dHJhOnRoaXMudix1c2VyOnRoaXMucCxsZXZlbDp0aGlzLkMsZmluZ2VycHJpbnQ6dGhpcy5BfHxbXSxldmVudFByb2Nlc3NvcnM6dGhpcy5pLHByb3BhZ2F0aW9uQ29udGV4dDp0aGlzLk4sc2RrUHJvY2Vzc2luZ01ldGFkYXRhOnRoaXMuUyx0cmFuc2FjdGlvbk5hbWU6dGhpcy5SLHNwYW46bnQodGhpcyksY29udmVyc2F0aW9uSWQ6dGhpcy5UfX1zZXRTREtQcm9jZXNzaW5nTWV0YWRhdGEodCl7cmV0dXJuIHRoaXMuUz1aKHRoaXMuUyx0LDIpLHRoaXN9c2V0UHJvcGFnYXRpb25Db250ZXh0KHQpe3JldHVybiB0aGlzLk49dCx0aGlzfWdldFByb3BhZ2F0aW9uQ29udGV4dCgpe3JldHVybiB0aGlzLk59Y2FwdHVyZUV4Y2VwdGlvbih0LG4pe2NvbnN0IGU9bj8uZXZlbnRfaWR8fEcoKTtpZighdGhpcy5JKXJldHVybiBoJiZ3Lndhcm4oIk5vIGNsaWVudCBjb25maWd1cmVkIG9uIHNjb3BlIC0gd2lsbCBub3QgY2FwdHVyZSBleGNlcHRpb24hIiksZTtjb25zdCByPW5ldyBFcnJvcigiU2VudHJ5IHN5bnRoZXRpY0V4Y2VwdGlvbiIpO3JldHVybiB0aGlzLkkuY2FwdHVyZUV4Y2VwdGlvbih0LHtvcmlnaW5hbEV4Y2VwdGlvbjp0LHN5bnRoZXRpY0V4Y2VwdGlvbjpyLC4uLm4sZXZlbnRfaWQ6ZX0sdGhpcyksZX1jYXB0dXJlTWVzc2FnZSh0LG4sZSl7Y29uc3Qgcj1lPy5ldmVudF9pZHx8RygpO2lmKCF0aGlzLkkpcmV0dXJuIGgmJncud2FybigiTm8gY2xpZW50IGNvbmZpZ3VyZWQgb24gc2NvcGUgLSB3aWxsIG5vdCBjYXB0dXJlIG1lc3NhZ2UhIikscjtjb25zdCBvPWU/LnN5bnRoZXRpY0V4Y2VwdGlvbj8/bmV3IEVycm9yKHQpO3JldHVybiB0aGlzLkkuY2FwdHVyZU1lc3NhZ2UodCxuLHtvcmlnaW5hbEV4Y2VwdGlvbjp0LHN5bnRoZXRpY0V4Y2VwdGlvbjpvLC4uLmUsZXZlbnRfaWQ6cn0sdGhpcykscn1jYXB0dXJlRXZlbnQodCxuKXtjb25zdCBlPXQuZXZlbnRfaWR8fG4/LmV2ZW50X2lkfHxHKCk7cmV0dXJuIHRoaXMuST8odGhpcy5JLmNhcHR1cmVFdmVudCh0LHsuLi5uLGV2ZW50X2lkOmV9LHRoaXMpLGUpOihoJiZ3Lndhcm4oIk5vIGNsaWVudCBjb25maWd1cmVkIG9uIHNjb3BlIC0gd2lsbCBub3QgY2FwdHVyZSBldmVudCEiKSxlKX1rKCl7dGhpcy50fHwodGhpcy50PSEwLHRoaXMuby5mb3JFYWNoKHQ9Pnt0KHRoaXMpfSksdGhpcy50PSExKX19Y29uc3QgcnQ9dD0+dCBpbnN0YW5jZW9mIFByb21pc2UmJiF0W290XSxvdD1TeW1ib2woImNoYWluZWQgUHJvbWlzZUxpa2UiKSxpdD0odCxuKT0+e2lmKCFuKXJldHVybiB0O2xldCBlPSExO2Zvcihjb25zdCByIGluIHQpe2lmKHIgaW4gbiljb250aW51ZTtlPSEwO2NvbnN0IG89dFtyXTsiZnVuY3Rpb24iPT10eXBlb2Ygbz9PYmplY3QuZGVmaW5lUHJvcGVydHkobixyLHt2YWx1ZTooLi4ubik9Pm8uYXBwbHkodCxuKSxlbnVtZXJhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMCx3cml0YWJsZTohMH0pOm5bcl09b31yZXR1cm4gZSYmT2JqZWN0LmFzc2lnbihuLHtbb3RdOiEwfSksbn07Y2xhc3Mgc3R7Y29uc3RydWN0b3IodCxuKXtsZXQgZSxyO2U9dHx8bmV3IGV0LHI9bnx8bmV3IGV0LHRoaXMuUD1be3Njb3BlOmV9XSx0aGlzLkQ9cn13aXRoU2NvcGUodCl7Y29uc3Qgbj10aGlzLlUoKTtsZXQgZTt0cnl7ZT10KG4pfWNhdGNoKHQpe3Rocm93IHRoaXMuQigpLHR9cmV0dXJuIGooZSk/KCh0LG4sZSk9Pntjb25zdCByPXQudGhlbih0PT4obih0KSx0KSx0PT57dGhyb3cgZSh0KSx0fSk7cmV0dXJuIHJ0KHIpJiZydCh0KT9yOml0KHQscil9KShlLCgpPT50aGlzLkIoKSwoKT0+dGhpcy5CKCkpOih0aGlzLkIoKSxlKX1nZXRDbGllbnQoKXtyZXR1cm4gdGhpcy5nZXRTdGFja1RvcCgpLmNsaWVudH1nZXRTY29wZSgpe3JldHVybiB0aGlzLmdldFN0YWNrVG9wKCkuc2NvcGV9Z2V0SXNvbGF0aW9uU2NvcGUoKXtyZXR1cm4gdGhpcy5EfWdldFN0YWNrVG9wKCl7cmV0dXJuIHRoaXMuUFt0aGlzLlAubGVuZ3RoLTFdfVUoKXtjb25zdCB0PXRoaXMuZ2V0U2NvcGUoKS5jbG9uZSgpO3JldHVybiB0aGlzLlAucHVzaCh7Y2xpZW50OnRoaXMuZ2V0Q2xpZW50KCksc2NvcGU6dH0pLHR9Qigpe3JldHVybiEodGhpcy5QLmxlbmd0aDw9MSkmJiEhdGhpcy5QLnBvcCgpfX1mdW5jdGlvbiBjdCgpe2NvbnN0IHQ9ZyhsKCkpO3JldHVybiB0LnN0YWNrPXQuc3RhY2t8fG5ldyBzdChtKCJkZWZhdWx0Q3VycmVudFNjb3BlIiwoKT0+bmV3IGV0KSxtKCJkZWZhdWx0SXNvbGF0aW9uU2NvcGUiLCgpPT5uZXcgZXQpKX1mdW5jdGlvbiB1dCh0KXtyZXR1cm4gY3QoKS53aXRoU2NvcGUodCl9ZnVuY3Rpb24gYXQodCxuKXtjb25zdCBlPWN0KCk7cmV0dXJuIGUud2l0aFNjb3BlKCgpPT4oZS5nZXRTdGFja1RvcCgpLnNjb3BlPXQsbih0KSkpfWZ1bmN0aW9uIGZ0KHQpe3JldHVybiBjdCgpLndpdGhTY29wZSgoKT0+dChjdCgpLmdldElzb2xhdGlvblNjb3BlKCkpKX1mdW5jdGlvbiBodCh0KXtjb25zdCBuPWcodCk7cmV0dXJuIG4uYWNzP24uYWNzOnt3aXRoSXNvbGF0aW9uU2NvcGU6ZnQsd2l0aFNjb3BlOnV0LHdpdGhTZXRTY29wZTphdCx3aXRoU2V0SXNvbGF0aW9uU2NvcGU6KHQsbik9PmZ0KG4pLGdldEN1cnJlbnRTY29wZTooKT0+Y3QoKS5nZXRTY29wZSgpLGdldElzb2xhdGlvblNjb3BlOigpPT5jdCgpLmdldElzb2xhdGlvblNjb3BlKCl9fWZ1bmN0aW9uIHB0KCl7cmV0dXJuIGh0KGwoKSkuZ2V0Q3VycmVudFNjb3BlKCkuZ2V0Q2xpZW50KCl9ZnVuY3Rpb24gZHQodCl7Y29uc3Qgbj10O3JldHVybntzY29wZTpuLl9zZW50cnlTY29wZSxpc29sYXRpb25TY29wZTpRKG4uX3NlbnRyeUlzb2xhdGlvblNjb3BlKX19Y29uc3QgbHQ9InNlbnRyeS0iO2Z1bmN0aW9uIGd0KHQpe2NvbnN0IG49ZnVuY3Rpb24odCl7aWYoIXR8fChuPXQsIUMobiwiU3RyaW5nIikmJiFBcnJheS5pc0FycmF5KHQpKSlyZXR1cm47dmFyIG47aWYoQXJyYXkuaXNBcnJheSh0KSlyZXR1cm4gdC5yZWR1Y2UoKHQsbik9Pntjb25zdCBlPW10KG4pO3JldHVybiBPYmplY3QuZW50cmllcyhlKS5mb3JFYWNoKChbbixlXSk9Pnt0W25dPWV9KSx0fSx7fSk7cmV0dXJuIG10KHQpfSh0KTtpZighbilyZXR1cm47Y29uc3QgZT1PYmplY3QuZW50cmllcyhuKS5yZWR1Y2UoKHQsW24sZV0pPT57aWYobi5zdGFydHNXaXRoKGx0KSl7dFtuLnNsaWNlKDcpXT1lfXJldHVybiB0fSx7fSk7cmV0dXJuIE9iamVjdC5rZXlzKGUpLmxlbmd0aD4wP2U6dm9pZCAwfWZ1bmN0aW9uIG10KHQpe3JldHVybiB0LnNwbGl0KCIsIikubWFwKHQ9Pntjb25zdCBuPXQuaW5kZXhPZigiPSIpO2lmKC0xPT09bilyZXR1cm5bXTtyZXR1cm5bdC5zbGljZSgwLG4pLHQuc2xpY2UobisxKV0ubWFwKHQ9Pnt0cnl7cmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudCh0LnRyaW0oKSl9Y2F0Y2h7cmV0dXJufX0pfSkucmVkdWNlKCh0LFtuLGVdKT0+KG4mJmUmJih0W25dPWUpLHQpLHt9KX1jb25zdCB5dD0vXm8oXGQrKVwuLztmdW5jdGlvbiBidCh0LG49ITEpe2NvbnN0e2hvc3Q6ZSxwYXRoOnIscGFzczpvLHBvcnQ6aSxwcm9qZWN0SWQ6cyxwcm90b2NvbDpjLHB1YmxpY0tleTp1fT10O3JldHVybmAke2N9Oi8vJHt1fSR7biYmbz9gOiR7b31gOiIifUAke2V9JHtpP2A6JHtpfWA6IiJ9LyR7cj9gJHtyfS9gOnJ9JHtzfWB9ZnVuY3Rpb24gdnQodCl7Y29uc3Qgbj10LmdldE9wdGlvbnMoKSx7aG9zdDplfT10LmdldERzbigpfHx7fTtsZXQgcjtyZXR1cm4gbi5vcmdJZD9yPVN0cmluZyhuLm9yZ0lkKTplJiYocj1mdW5jdGlvbih0KXtjb25zdCBuPXQubWF0Y2goeXQpO3JldHVybiBuPy5bMV19KGUpKSxyfWZ1bmN0aW9uIF90KHQpe2NvbnN0e3NwYW5JZDpuLHRyYWNlSWQ6ZSxpc1JlbW90ZTpyfT10LnNwYW5Db250ZXh0KCksbz1yP246RXQodCkucGFyZW50X3NwYW5faWQsaT1kdCh0KS5zY29wZTtyZXR1cm57cGFyZW50X3NwYW5faWQ6byxzcGFuX2lkOnI/aT8uZ2V0UHJvcGFnYXRpb25Db250ZXh0KCkucHJvcGFnYXRpb25TcGFuSWR8fFYoKTpuLHRyYWNlX2lkOmV9fWZ1bmN0aW9uIFN0KHQpe3JldHVybiB0JiZ0Lmxlbmd0aD4wP3QubWFwKCh7Y29udGV4dDp7c3BhbklkOnQsdHJhY2VJZDpuLHRyYWNlRmxhZ3M6ZSwuLi5yfSxhdHRyaWJ1dGVzOm99KT0+KHtzcGFuX2lkOnQsdHJhY2VfaWQ6bixzYW1wbGVkOjE9PT1lLGF0dHJpYnV0ZXM6bywuLi5yfSkpOnZvaWQgMH1mdW5jdGlvbiB3dCh0KXtyZXR1cm4ibnVtYmVyIj09dHlwZW9mIHQ/JHQodCk6QXJyYXkuaXNBcnJheSh0KT90WzBdK3RbMV0vMWU5OnQgaW5zdGFuY2VvZiBEYXRlPyR0KHQuZ2V0VGltZSgpKTpZKCl9ZnVuY3Rpb24gJHQodCl7cmV0dXJuIHQ+OTk5OTk5OTk5OT90LzFlMzp0fWZ1bmN0aW9uIEV0KHQpe2lmKGZ1bmN0aW9uKHQpe3JldHVybiJmdW5jdGlvbiI9PXR5cGVvZiB0LmdldFNwYW5KU09OfSh0KSlyZXR1cm4gdC5nZXRTcGFuSlNPTigpO2NvbnN0e3NwYW5JZDpuLHRyYWNlSWQ6ZX09dC5zcGFuQ29udGV4dCgpO2lmKGZ1bmN0aW9uKHQpe2NvbnN0IG49dDtyZXR1cm4hIShuLmF0dHJpYnV0ZXMmJm4uc3RhcnRUaW1lJiZuLm5hbWUmJm4uZW5kVGltZSYmbi5zdGF0dXMpfSh0KSl7Y29uc3R7YXR0cmlidXRlczpyLHN0YXJ0VGltZTpvLG5hbWU6aSxlbmRUaW1lOnMsc3RhdHVzOmMsbGlua3M6dX09dDtyZXR1cm57c3Bhbl9pZDpuLHRyYWNlX2lkOmUsZGF0YTpyLGRlc2NyaXB0aW9uOmkscGFyZW50X3NwYW5faWQ6eHQodCksc3RhcnRfdGltZXN0YW1wOnd0KG8pLHRpbWVzdGFtcDp3dChzKXx8dm9pZCAwLHN0YXR1czpOdChjKSxvcDpyWyJzZW50cnkub3AiXSxvcmlnaW46clsic2VudHJ5Lm9yaWdpbiJdLGxpbmtzOlN0KHUpfX1yZXR1cm57c3Bhbl9pZDpuLHRyYWNlX2lkOmUsc3RhcnRfdGltZXN0YW1wOjAsZGF0YTp7fX19ZnVuY3Rpb24geHQodCl7cmV0dXJuInBhcmVudFNwYW5JZCJpbiB0P3QucGFyZW50U3BhbklkOiJwYXJlbnRTcGFuQ29udGV4dCJpbiB0P3QucGFyZW50U3BhbkNvbnRleHQ/LnNwYW5JZDp2b2lkIDB9ZnVuY3Rpb24gTnQodCl7aWYodCYmMCE9PXQuY29kZSlyZXR1cm4gMT09PXQuY29kZT8ib2siOnQubWVzc2FnZXx8ImludGVybmFsX2Vycm9yIn1jb25zdCBDdD1mdW5jdGlvbih0KXtyZXR1cm4gdC5fc2VudHJ5Um9vdFNwYW58fHR9O2Z1bmN0aW9uIGp0KHQpe2lmKCJib29sZWFuIj09dHlwZW9mIF9fU0VOVFJZX1RSQUNJTkdfXyYmIV9fU0VOVFJZX1RSQUNJTkdfXylyZXR1cm4hMTtjb25zdCBuPXR8fHB0KCk/LmdldE9wdGlvbnMoKTtyZXR1cm4hKCFufHxudWxsPT1uLnRyYWNlc1NhbXBsZVJhdGUmJiFuLnRyYWNlc1NhbXBsZXIpfWNvbnN0IFJ0PVN5bWJvbC5mb3IoInNlbnRyeS5ub25SZWNvcmRpbmdTcGFuIik7ZnVuY3Rpb24gQXQodCxuKXtjb25zdCBlPW4uZ2V0T3B0aW9ucygpLHtwdWJsaWNLZXk6cn09bi5nZXREc24oKXx8e30sbz17ZW52aXJvbm1lbnQ6ZS5lbnZpcm9ubWVudHx8InByb2R1Y3Rpb24iLHJlbGVhc2U6ZS5yZWxlYXNlLHB1YmxpY19rZXk6cix0cmFjZV9pZDp0LG9yZ19pZDp2dChuKX07cmV0dXJuIG4uZW1pdCgiY3JlYXRlRHNjIixvKSxvfWZ1bmN0aW9uIEl0KHQsbil7Y29uc3QgZT1uLmdldFByb3BhZ2F0aW9uQ29udGV4dCgpO3JldHVybiBlLmRzY3x8QXQoZS50cmFjZUlkLHQpfWZ1bmN0aW9uIE90KHQpe2NvbnN0IG49cHQoKTtpZighbilyZXR1cm57fTtjb25zdCBlPUN0KHQpLHI9RXQoZSksbz1yLmRhdGEsaT1lLnNwYW5Db250ZXh0KCkudHJhY2VTdGF0ZSxzPWk/LmdldCgic2VudHJ5LnNhbXBsZV9yYXRlIik/P29bInNlbnRyeS5zYW1wbGVfcmF0ZSJdPz9vWyJzZW50cnkucHJldmlvdXNfdHJhY2Vfc2FtcGxlX3JhdGUiXTtmdW5jdGlvbiBjKHQpe3JldHVybiJudW1iZXIiIT10eXBlb2YgcyYmInN0cmluZyIhPXR5cGVvZiBzfHwodC5zYW1wbGVfcmF0ZT1gJHtzfWApLHR9Y29uc3QgdT1lLl9mcm96ZW5Ec2M7aWYodSlyZXR1cm4gYyh1KTtpZihmdW5jdGlvbih0KXtyZXR1cm4hIXQmJiEwPT09dFtSdF19KGUpJiYhanQobi5nZXRPcHRpb25zKCkpKXtjb25zdCB0PWR0KGUpLnNjb3BlO2lmKHQpcmV0dXJuIGMoey4uLkl0KG4sdCl9KX1jb25zdCBhPWk/LmdldCgic2VudHJ5LmRzYyIpLGY9YSYmZ3QoYSk7aWYoZilyZXR1cm4gYyhmKTtjb25zdCBoPUF0KHQuc3BhbkNvbnRleHQoKS50cmFjZUlkLG4pLHA9b1sic2VudHJ5LnNvdXJjZSJdPz9vWyJzZW50cnkuc3Bhbi5zb3VyY2UiXSxkPXIuZGVzY3JpcHRpb247cmV0dXJuInVybCIhPT1wJiZkJiYoaC50cmFuc2FjdGlvbj1kKSxqdCgpJiYoaC5zYW1wbGVkPVN0cmluZyhmdW5jdGlvbih0KXtjb25zdHt0cmFjZUZsYWdzOm59PXQuc3BhbkNvbnRleHQoKTtyZXR1cm4gMT09PW59KGUpKSxoLnNhbXBsZV9yYW5kPWk/LmdldCgic2VudHJ5LnNhbXBsZV9yYW5kIik/P2R0KGUpLnNjb3BlPy5nZXRQcm9wYWdhdGlvbkNvbnRleHQoKS5zYW1wbGVSYW5kLnRvU3RyaW5nKCkpLGMoaCksbi5lbWl0KCJjcmVhdGVEc2MiLGgsZSksaH1mdW5jdGlvbiBUdCh0LG49W10pe3JldHVyblt0LG5dfWZ1bmN0aW9uIGt0KHQsbil7Y29uc3QgZT10WzFdO2Zvcihjb25zdCB0IG9mIGUpe2lmKG4odCx0WzBdLnR5cGUpKXJldHVybiEwfXJldHVybiExfWZ1bmN0aW9uIFB0KHQpe2NvbnN0IG49ZyhwKTtyZXR1cm4gbi5lbmNvZGVQb2x5ZmlsbD9uLmVuY29kZVBvbHlmaWxsKHQpOihuZXcgVGV4dEVuY29kZXIpLmVuY29kZSh0KX1mdW5jdGlvbiBEdCh0KXtjb25zdFtuLGVdPXQ7bGV0IHI9SlNPTi5zdHJpbmdpZnkobik7ZnVuY3Rpb24gbyh0KXsic3RyaW5nIj09dHlwZW9mIHI/cj0ic3RyaW5nIj09dHlwZW9mIHQ/cit0OltQdChyKSx0XTpyLnB1c2goInN0cmluZyI9PXR5cGVvZiB0P1B0KHQpOnQpfWZvcihjb25zdCB0IG9mIGUpe2NvbnN0W24sZV09dDtpZihvKGBcbiR7SlNPTi5zdHJpbmdpZnkobil9XG5gKSwic3RyaW5nIj09dHlwZW9mIGV8fGUgaW5zdGFuY2VvZiBVaW50OEFycmF5KW8oZSk7ZWxzZXtsZXQgdDt0cnl7dD1KU09OLnN0cmluZ2lmeShlKX1jYXRjaHt0PUpTT04uc3RyaW5naWZ5KEIoZSkpfW8odCl9fXJldHVybiJzdHJpbmciPT10eXBlb2Ygcj9yOmZ1bmN0aW9uKHQpe2NvbnN0IG49dC5yZWR1Y2UoKHQsbik9PnQrbi5sZW5ndGgsMCksZT1uZXcgVWludDhBcnJheShuKTtsZXQgcj0wO2Zvcihjb25zdCBuIG9mIHQpZS5zZXQobixyKSxyKz1uLmxlbmd0aDtyZXR1cm4gZX0ocil9Y29uc3QgVXQ9e3Nlc3Npb25zOiJzZXNzaW9uIixldmVudDoiZXJyb3IiLGNsaWVudF9yZXBvcnQ6ImludGVybmFsIix1c2VyX3JlcG9ydDoiZGVmYXVsdCIscHJvZmlsZV9jaHVuazoicHJvZmlsZSIscmVwbGF5X2V2ZW50OiJyZXBsYXkiLHJlcGxheV9yZWNvcmRpbmc6InJlcGxheSIsY2hlY2tfaW46Im1vbml0b3IiLHJhd19zZWN1cml0eToic2VjdXJpdHkiLGxvZzoibG9nX2l0ZW0iLHRyYWNlX21ldHJpYzoibWV0cmljIn07ZnVuY3Rpb24gQnQodCl7cmV0dXJuIGZ1bmN0aW9uKHQpe3JldHVybiB0IGluIFV0fSh0KT9VdFt0XTp0fWZ1bmN0aW9uIEx0KHQpe2lmKCF0Py5zZGspcmV0dXJuO2NvbnN0e25hbWU6bix2ZXJzaW9uOmV9PXQuc2RrO3JldHVybntuYW1lOm4sdmVyc2lvbjplfX1mdW5jdGlvbiBNdCh0LG4sZSxyKXtjb25zdCBvPUx0KGUpLGk9dC50eXBlJiYicmVwbGF5X2V2ZW50IiE9PXQudHlwZT90LnR5cGU6ImV2ZW50IjshZnVuY3Rpb24odCxuKXtpZighbilyZXR1cm4gdDtjb25zdCBlPXQuc2RrfHx7fTt0LnNkaz17Li4uZSxuYW1lOmUubmFtZXx8bi5uYW1lLHZlcnNpb246ZS52ZXJzaW9ufHxuLnZlcnNpb24saW50ZWdyYXRpb25zOlsuLi50LnNkaz8uaW50ZWdyYXRpb25zfHxbXSwuLi5uLmludGVncmF0aW9uc3x8W11dLHBhY2thZ2VzOlsuLi50LnNkaz8ucGFja2FnZXN8fFtdLC4uLm4ucGFja2FnZXN8fFtdXSxzZXR0aW5nczp0LnNkaz8uc2V0dGluZ3N8fG4uc2V0dGluZ3M/ey4uLnQuc2RrPy5zZXR0aW5ncywuLi5uLnNldHRpbmdzfTp2b2lkIDB9fSh0LGU/LnNkayk7Y29uc3Qgcz1mdW5jdGlvbih0LG4sZSxyKXtjb25zdCBvPXQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhPy5keW5hbWljU2FtcGxpbmdDb250ZXh0O3JldHVybntldmVudF9pZDp0LmV2ZW50X2lkLHNlbnRfYXQ6bmV3IERhdGUoUCgpKS50b0lTT1N0cmluZygpLC4uLm4mJntzZGs6bn0sLi4uISFlJiZyJiZ7ZHNuOmJ0KHIpfSwuLi5vJiZ7dHJhY2U6b319fSh0LG8scixuKTtkZWxldGUgdC5zZGtQcm9jZXNzaW5nTWV0YWRhdGE7cmV0dXJuIFR0KHMsW1t7dHlwZTppfSx0XV0pfWNvbnN0IHp0PSJfX1NFTlRSWV9TVVBQUkVTU19UUkFDSU5HX18iO2Z1bmN0aW9uIEZ0KHQpe2NvbnN0IG49aHQobCgpKTtyZXR1cm4gbi5zdXBwcmVzc1RyYWNpbmc/bi5zdXBwcmVzc1RyYWNpbmcodCk6ZnVuY3Rpb24oLi4udCl7Y29uc3Qgbj1odChsKCkpO2lmKDI9PT10Lmxlbmd0aCl7Y29uc3RbZSxyXT10O3JldHVybiBlP24ud2l0aFNldFNjb3BlKGUscik6bi53aXRoU2NvcGUocil9cmV0dXJuIG4ud2l0aFNjb3BlKHRbMF0pfShuPT57bi5zZXRTREtQcm9jZXNzaW5nTWV0YWRhdGEoe1t6dF06ITB9KTtjb25zdCBlPXQoKTtyZXR1cm4gbi5zZXRTREtQcm9jZXNzaW5nTWV0YWRhdGEoe1t6dF06dm9pZCAwfSksZX0pfWZ1bmN0aW9uIEd0KHQsbil7Y29uc3R7ZmluZ2VycHJpbnQ6ZSxzcGFuOnIsYnJlYWRjcnVtYnM6byxzZGtQcm9jZXNzaW5nTWV0YWRhdGE6aX09bjshZnVuY3Rpb24odCxuKXtjb25zdHtleHRyYTplLHRhZ3M6cix1c2VyOm8sY29udGV4dHM6aSxsZXZlbDpzLHRyYW5zYWN0aW9uTmFtZTpjfT1uO09iamVjdC5rZXlzKGUpLmxlbmd0aCYmKHQuZXh0cmE9ey4uLmUsLi4udC5leHRyYX0pO09iamVjdC5rZXlzKHIpLmxlbmd0aCYmKHQudGFncz17Li4uciwuLi50LnRhZ3N9KTtPYmplY3Qua2V5cyhvKS5sZW5ndGgmJih0LnVzZXI9ey4uLm8sLi4udC51c2VyfSk7T2JqZWN0LmtleXMoaSkubGVuZ3RoJiYodC5jb250ZXh0cz17Li4uaSwuLi50LmNvbnRleHRzfSk7cyYmKHQubGV2ZWw9cyk7YyYmInRyYW5zYWN0aW9uIiE9PXQudHlwZSYmKHQudHJhbnNhY3Rpb249Yyl9KHQsbiksciYmZnVuY3Rpb24odCxuKXt0LmNvbnRleHRzPXt0cmFjZTpfdChuKSwuLi50LmNvbnRleHRzfSx0LnNka1Byb2Nlc3NpbmdNZXRhZGF0YT17ZHluYW1pY1NhbXBsaW5nQ29udGV4dDpPdChuKSwuLi50LnNka1Byb2Nlc3NpbmdNZXRhZGF0YX07Y29uc3QgZT1DdChuKSxyPUV0KGUpLmRlc2NyaXB0aW9uO3ImJiF0LnRyYW5zYWN0aW9uJiYidHJhbnNhY3Rpb24iPT09dC50eXBlJiYodC50cmFuc2FjdGlvbj1yKX0odCxyKSxmdW5jdGlvbih0LG4pe3QuZmluZ2VycHJpbnQ9dC5maW5nZXJwcmludD9BcnJheS5pc0FycmF5KHQuZmluZ2VycHJpbnQpP3QuZmluZ2VycHJpbnQ6W3QuZmluZ2VycHJpbnRdOltdLG4mJih0LmZpbmdlcnByaW50PXQuZmluZ2VycHJpbnQuY29uY2F0KG4pKTt0LmZpbmdlcnByaW50Lmxlbmd0aHx8ZGVsZXRlIHQuZmluZ2VycHJpbnR9KHQsZSksZnVuY3Rpb24odCxuKXtjb25zdCBlPVsuLi50LmJyZWFkY3J1bWJzfHxbXSwuLi5uXTt0LmJyZWFkY3J1bWJzPWUubGVuZ3RoP2U6dm9pZCAwfSh0LG8pLGZ1bmN0aW9uKHQsbil7dC5zZGtQcm9jZXNzaW5nTWV0YWRhdGE9ey4uLnQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhLC4uLm59fSh0LGkpfWNsYXNzIEp0e2NvbnN0cnVjdG9yKHQpe3RoaXMuTD0wLHRoaXMuTT1bXSx0aGlzLkYodCl9dGhlbih0LG4pe3JldHVybiBuZXcgSnQoKGUscik9Pnt0aGlzLk0ucHVzaChbITEsbj0+e2lmKHQpdHJ5e2UodChuKSl9Y2F0Y2godCl7cih0KX1lbHNlIGUobil9LHQ9PntpZihuKXRyeXtlKG4odCkpfWNhdGNoKHQpe3IodCl9ZWxzZSByKHQpfV0pLHRoaXMuRygpfSl9Y2F0Y2godCl7cmV0dXJuIHRoaXMudGhlbih0PT50LHQpfWZpbmFsbHkodCl7cmV0dXJuIG5ldyBKdCgobixlKT0+e2xldCByLG87cmV0dXJuIHRoaXMudGhlbihuPT57bz0hMSxyPW4sdCYmdCgpfSxuPT57bz0hMCxyPW4sdCYmdCgpfSkudGhlbigoKT0+e28/ZShyKTpuKHIpfSl9KX1HKCl7aWYoMD09PXRoaXMuTClyZXR1cm47Y29uc3QgdD10aGlzLk0uc2xpY2UoKTt0aGlzLk09W10sdC5mb3JFYWNoKHQ9Pnt0WzBdfHwoMT09PXRoaXMuTCYmdFsxXSh0aGlzLkopLDI9PT10aGlzLkwmJnRbMl0odGhpcy5KKSx0WzBdPSEwKX0pfUYodCl7Y29uc3Qgbj0odCxuKT0+ezA9PT10aGlzLkwmJihqKG4pP24udGhlbihlLHIpOih0aGlzLkw9dCx0aGlzLko9bix0aGlzLkcoKSkpfSxlPXQ9PntuKDEsdCl9LHI9dD0+e24oMix0KX07dHJ5e3QoZSxyKX1jYXRjaCh0KXtyKHQpfX19Y29uc3QgV3Q9U3ltYm9sLmZvcigiU2VudHJ5QnVmZmVyRnVsbEVycm9yIik7ZnVuY3Rpb24gWXQodD0xMDApe2NvbnN0IG49bmV3IFNldDtmdW5jdGlvbiBlKHQpe24uZGVsZXRlKHQpfXJldHVybntnZXQgJCgpe3JldHVybiBBcnJheS5mcm9tKG4pfSxhZGQ6ZnVuY3Rpb24ocil7aWYoIShuLnNpemU8dCkpcmV0dXJuIG89V3QsbmV3IEp0KCh0LG4pPT57bihvKX0pO3ZhciBvO2NvbnN0IGk9cigpO3JldHVybiBuLmFkZChpKSxpLnRoZW4oKCk9PmUoaSksKCk9PmUoaSkpLGl9LGRyYWluOmZ1bmN0aW9uKHQpe2lmKCFuLnNpemUpcmV0dXJuIGU9ITAsbmV3IEp0KHQ9Pnt0KGUpfSk7dmFyIGU7Y29uc3Qgcj1Qcm9taXNlLmFsbFNldHRsZWQoQXJyYXkuZnJvbShuKSkudGhlbigoKT0+ITApO2lmKCF0KXJldHVybiByO2NvbnN0IG89W3IsbmV3IFByb21pc2Uobj0+e3JldHVybiJvYmplY3QiPT10eXBlb2YoZT1zZXRUaW1lb3V0KCgpPT5uKCExKSx0KSkmJiJmdW5jdGlvbiI9PXR5cGVvZiBlLnVucmVmJiZlLnVucmVmKCksZTt2YXIgZX0pXTtyZXR1cm4gUHJvbWlzZS5yYWNlKG8pfX19ZnVuY3Rpb24gSHQodCx7c3RhdHVzQ29kZTpuLGhlYWRlcnM6ZX0scj1QKCkpe2NvbnN0IG89ey4uLnR9LGk9ZT8uWyJ4LXNlbnRyeS1yYXRlLWxpbWl0cyJdLHM9ZT8uWyJyZXRyeS1hZnRlciJdO2lmKGkpZm9yKGNvbnN0IHQgb2YgaS50cmltKCkuc3BsaXQoIiwiKSl7Y29uc3RbbixlLCwsaV09dC5zcGxpdCgiOiIsNSkscz1wYXJzZUludChuLDEwKSxjPTFlMyooaXNOYU4ocyk/NjA6cyk7aWYoZSlmb3IoY29uc3QgdCBvZiBlLnNwbGl0KCI7IikpIm1ldHJpY19idWNrZXQiPT09dCYmaSYmIWkuc3BsaXQoIjsiKS5pbmNsdWRlcygiY3VzdG9tIil8fChvW3RdPXIrYyk7ZWxzZSBvLmFsbD1yK2N9ZWxzZSBzP28uYWxsPXIrZnVuY3Rpb24odCxuPVAoKSl7Y29uc3QgZT1wYXJzZUludChgJHt0fWAsMTApO2lmKCFpc05hTihlKSlyZXR1cm4gMWUzKmU7Y29uc3Qgcj1EYXRlLnBhcnNlKGAke3R9YCk7cmV0dXJuIGlzTmFOKHIpPzZlNDpyLW59KHMscik6NDI5PT09biYmKG8uYWxsPXIrNmU0KTtyZXR1cm4gb31mdW5jdGlvbiBLdCh0LG4sZT1ZdCh0LmJ1ZmZlclNpemV8fDY0KSl7bGV0IHI9e307cmV0dXJue3NlbmQ6ZnVuY3Rpb24odCl7Y29uc3Qgbz1bXTtpZihrdCh0LCh0LG4pPT57Y29uc3QgZT1CdChuKTsoZnVuY3Rpb24odCxuLGU9UCgpKXtyZXR1cm4gZnVuY3Rpb24odCxuKXtyZXR1cm4gdFtuXXx8dC5hbGx8fDB9KHQsbik+ZX0pKHIsZSl8fG8ucHVzaCh0KX0pLDA9PT1vLmxlbmd0aClyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtjb25zdCBpPVR0KHRbMF0sbykscz10PT57IWZ1bmN0aW9uKHQsbil7cmV0dXJuIGt0KHQsKHQsZSk9Pm4uaW5jbHVkZXMoZSkpfShpLFsiY2xpZW50X3JlcG9ydCJdKT9rdChpLCh0LG4pPT57fSk6aCYmdy53YXJuKGBEcm9wcGluZyBjbGllbnQgcmVwb3J0LiBXaWxsIG5vdCBzZW5kIG91dGNvbWVzIChyZWFzb246ICR7dH0pLmApfTtyZXR1cm4gZS5hZGQoKCk9Pm4oe2JvZHk6RHQoaSl9KS50aGVuKHQ9PjQxMz09PXQuc3RhdHVzQ29kZT8oaCYmdy5lcnJvcigiU2VudHJ5IHJlc3BvbmRlZCB3aXRoIHN0YXR1cyBjb2RlIDQxMy4gRW52ZWxvcGUgd2FzIGRpc2NhcmRlZCBkdWUgdG8gZXhjZWVkaW5nIHNpemUgbGltaXRzLiIpLHMoInNlbmRfZXJyb3IiKSx0KTooaCYmdm9pZCAwIT09dC5zdGF0dXNDb2RlJiYodC5zdGF0dXNDb2RlPDIwMHx8dC5zdGF0dXNDb2RlPj0zMDApJiZ3Lndhcm4oYFNlbnRyeSByZXNwb25kZWQgd2l0aCBzdGF0dXMgY29kZSAke3Quc3RhdHVzQ29kZX0gdG8gc2VudCBldmVudC5gKSxyPUh0KHIsdCksdCksdD0+e3Rocm93IHMoIm5ldHdvcmtfZXJyb3IiKSxoJiZ3LmVycm9yKCJFbmNvdW50ZXJlZCBlcnJvciBydW5uaW5nIHRyYW5zcG9ydCByZXF1ZXN0OiIsdCksdH0pKS50aGVuKHQ9PnQsdD0+e2lmKHQ9PT1XdClyZXR1cm4gaCYmdy5lcnJvcigiU2tpcHBlZCBzZW5kaW5nIGV2ZW50IGJlY2F1c2UgYnVmZmVyIGlzIGZ1bGwuIikscygicXVldWVfb3ZlcmZsb3ciKSxQcm9taXNlLnJlc29sdmUoe30pO3Rocm93IHR9KX0sZmx1c2g6dD0+ZS5kcmFpbih0KX19Y29uc3QgWnQ9L14oXFMrOlxcfFwvPykoW1xzXFNdKj8pKCg/OlwuezEsMn18W14vXFxdKz98KShcLlteLi9cXF0qfCkpKD86Wy9cXF0qKSQvO2Z1bmN0aW9uIHF0KHQpe2NvbnN0IG49ZnVuY3Rpb24odCl7Y29uc3Qgbj10Lmxlbmd0aD4xMDI0P2A8dHJ1bmNhdGVkPiR7dC5zbGljZSgtMTAyNCl9YDp0LGU9WnQuZXhlYyhuKTtyZXR1cm4gZT9lLnNsaWNlKDEpOltdfSh0KSxlPW5bMF18fCIiO2xldCByPW5bMV07cmV0dXJuIGV8fHI/KHImJihyPXIuc2xpY2UoMCxyLmxlbmd0aC0xKSksZStyKToiLiJ9ZnVuY3Rpb24gVnQodCxuPSExKXtyZXR1cm4hKG58fHQmJiF0LnN0YXJ0c1dpdGgoIi8iKSYmIXQubWF0Y2goL15bQS1aXTovKSYmIXQuc3RhcnRzV2l0aCgiLiIpJiYhdC5tYXRjaCgvXlthLXpBLVpdKFthLXpBLVowLTkuXC0rXSkqOlwvXC8vKSkmJnZvaWQgMCE9PXQmJiF0LmluY2x1ZGVzKCJub2RlX21vZHVsZXMvIil9dmFyIFF0O2NvbnN0IFh0PVN5bWJvbCgiQWdlbnRCYXNlSW50ZXJuYWxTdGF0ZSIpO2NsYXNzIHRuIGV4dGVuZHMoUXQ9aS5BZ2VudCxRdCl7Y29uc3RydWN0b3IodCl7c3VwZXIodCksdGhpc1tYdF09e319aXNTZWN1cmVFbmRwb2ludCh0KXtpZih0KXtpZigiYm9vbGVhbiI9PXR5cGVvZiB0LnNlY3VyZUVuZHBvaW50KXJldHVybiB0LnNlY3VyZUVuZHBvaW50O2lmKCJzdHJpbmciPT10eXBlb2YgdC5wcm90b2NvbClyZXR1cm4iaHR0cHM6Ij09PXQucHJvdG9jb2x9Y29uc3R7c3RhY2s6bn09bmV3IEVycm9yO3JldHVybiJzdHJpbmciPT10eXBlb2YgbiYmbi5zcGxpdCgiXG4iKS5zb21lKHQ9Pi0xIT09dC5pbmRleE9mKCIoaHR0cHMuanM6Iil8fC0xIT09dC5pbmRleE9mKCJub2RlOmh0dHBzOiIpKX1jcmVhdGVTb2NrZXQodCxuLGUpe2NvbnN0IHI9ey4uLm4sc2VjdXJlRW5kcG9pbnQ6dGhpcy5pc1NlY3VyZUVuZHBvaW50KG4pfTtQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpPT50aGlzLmNvbm5lY3QodCxyKSkudGhlbihvPT57aWYobyBpbnN0YW5jZW9mIGkuQWdlbnQpcmV0dXJuIG8uYWRkUmVxdWVzdCh0LHIpO3RoaXNbWHRdLmN1cnJlbnRTb2NrZXQ9byxzdXBlci5jcmVhdGVTb2NrZXQodCxuLGUpfSxlKX1jcmVhdGVDb25uZWN0aW9uKCl7Y29uc3QgdD10aGlzW1h0XS5jdXJyZW50U29ja2V0O2lmKHRoaXNbWHRdLmN1cnJlbnRTb2NrZXQ9dm9pZCAwLCF0KXRocm93IG5ldyBFcnJvcigiTm8gc29ja2V0IHdhcyByZXR1cm5lZCBpbiB0aGUgYGNvbm5lY3QoKWAgZnVuY3Rpb24iKTtyZXR1cm4gdH1nZXQgZGVmYXVsdFBvcnQoKXtyZXR1cm4gdGhpc1tYdF0uZGVmYXVsdFBvcnQ/PygiaHR0cHM6Ij09PXRoaXMucHJvdG9jb2w/NDQzOjgwKX1zZXQgZGVmYXVsdFBvcnQodCl7dGhpc1tYdF0mJih0aGlzW1h0XS5kZWZhdWx0UG9ydD10KX1nZXQgcHJvdG9jb2woKXtyZXR1cm4gdGhpc1tYdF0ucHJvdG9jb2w/Pyh0aGlzLmlzU2VjdXJlRW5kcG9pbnQoKT8iaHR0cHM6IjoiaHR0cDoiKX1zZXQgcHJvdG9jb2wodCl7dGhpc1tYdF0mJih0aGlzW1h0XS5wcm90b2NvbD10KX19ZnVuY3Rpb24gbm4oLi4udCl7dy5sb2coIltodHRwcy1wcm94eS1hZ2VudDpwYXJzZS1wcm94eS1yZXNwb25zZV0iLC4uLnQpfWZ1bmN0aW9uIGVuKHQpe3JldHVybiBuZXcgUHJvbWlzZSgobixlKT0+e2xldCByPTA7Y29uc3Qgbz1bXTtmdW5jdGlvbiBpKCl7Y29uc3QgYz10LnJlYWQoKTtjP2Z1bmN0aW9uKGMpe28ucHVzaChjKSxyKz1jLmxlbmd0aDtjb25zdCB1PUJ1ZmZlci5jb25jYXQobyxyKSxhPXUuaW5kZXhPZigiXHJcblxyXG4iKTtpZigtMT09PWEpcmV0dXJuIG5uKCJoYXZlIG5vdCByZWNlaXZlZCBlbmQgb2YgSFRUUCBoZWFkZXJzIHlldC4uLiIpLHZvaWQgaSgpO2NvbnN0IGY9dS5zdWJhcnJheSgwLGEpLnRvU3RyaW5nKCJhc2NpaSIpLnNwbGl0KCJcclxuIiksaD1mLnNoaWZ0KCk7aWYoIWgpcmV0dXJuIHQuZGVzdHJveSgpLGUobmV3IEVycm9yKCJObyBoZWFkZXIgcmVjZWl2ZWQgZnJvbSBwcm94eSBDT05ORUNUIHJlc3BvbnNlIikpO2NvbnN0IHA9aC5zcGxpdCgiICIpLGQ9KyhwWzFdfHwwKSxsPXAuc2xpY2UoMikuam9pbigiICIpLGc9e307Zm9yKGNvbnN0IG4gb2YgZil7aWYoIW4pY29udGludWU7Y29uc3Qgcj1uLmluZGV4T2YoIjoiKTtpZigtMT09PXIpcmV0dXJuIHQuZGVzdHJveSgpLGUobmV3IEVycm9yKGBJbnZhbGlkIGhlYWRlciBmcm9tIHByb3h5IENPTk5FQ1QgcmVzcG9uc2U6ICIke259ImApKTtjb25zdCBvPW4uc2xpY2UoMCxyKS50b0xvd2VyQ2FzZSgpLGk9bi5zbGljZShyKzEpLnRyaW1TdGFydCgpLHM9Z1tvXTsic3RyaW5nIj09dHlwZW9mIHM/Z1tvXT1bcyxpXTpBcnJheS5pc0FycmF5KHMpP3MucHVzaChpKTpnW29dPWl9bm4oImdvdCBwcm94eSBzZXJ2ZXIgcmVzcG9uc2U6ICVvICVvIixoLGcpLHMoKSxuKHtjb25uZWN0OntzdGF0dXNDb2RlOmQsc3RhdHVzVGV4dDpsLGhlYWRlcnM6Z30sYnVmZmVyZWQ6dX0pfShjKTp0Lm9uY2UoInJlYWRhYmxlIixpKX1mdW5jdGlvbiBzKCl7dC5yZW1vdmVMaXN0ZW5lcigiZW5kIixjKSx0LnJlbW92ZUxpc3RlbmVyKCJlcnJvciIsdSksdC5yZW1vdmVMaXN0ZW5lcigicmVhZGFibGUiLGkpfWZ1bmN0aW9uIGMoKXtzKCksbm4oIm9uZW5kIiksZShuZXcgRXJyb3IoIlByb3h5IGNvbm5lY3Rpb24gZW5kZWQgYmVmb3JlIHJlY2VpdmluZyBDT05ORUNUIHJlc3BvbnNlIikpfWZ1bmN0aW9uIHUodCl7cygpLG5uKCJvbmVycm9yICVvIix0KSxlKHQpfXQub24oImVycm9yIix1KSx0Lm9uKCJlbmQiLGMpLGkoKX0pfWZ1bmN0aW9uIHJuKC4uLnQpe3cubG9nKCJbaHR0cHMtcHJveHktYWdlbnRdIiwuLi50KX1jbGFzcyBvbiBleHRlbmRzIHRue2NvbnN0cnVjdG9yKHQsbil7c3VwZXIobiksdGhpcy5vcHRpb25zPXt9LHRoaXMucHJveHk9InN0cmluZyI9PXR5cGVvZiB0P25ldyBVUkwodCk6dCx0aGlzLnByb3h5SGVhZGVycz1uPy5oZWFkZXJzPz97fSxybigiQ3JlYXRpbmcgbmV3IEh0dHBzUHJveHlBZ2VudCBpbnN0YW5jZTogJW8iLHRoaXMucHJveHkuaHJlZik7Y29uc3QgZT0odGhpcy5wcm94eS5ob3N0bmFtZXx8dGhpcy5wcm94eS5ob3N0KS5yZXBsYWNlKC9eXFt8XF0kL2csIiIpLHI9dGhpcy5wcm94eS5wb3J0P3BhcnNlSW50KHRoaXMucHJveHkucG9ydCwxMCk6Imh0dHBzOiI9PT10aGlzLnByb3h5LnByb3RvY29sPzQ0Mzo4MDt0aGlzLmNvbm5lY3RPcHRzPXtBTFBOUHJvdG9jb2xzOlsiaHR0cC8xLjEiXSwuLi5uP2NuKG4sImhlYWRlcnMiKTpudWxsLGhvc3Q6ZSxwb3J0OnJ9fWFzeW5jIGNvbm5lY3QodCxuKXtjb25zdHtwcm94eTplfT10aGlzO2lmKCFuLmhvc3QpdGhyb3cgbmV3IFR5cGVFcnJvcignTm8gImhvc3QiIHByb3ZpZGVkJyk7bGV0IHI7aWYoImh0dHBzOiI9PT1lLnByb3RvY29sKXtybigiQ3JlYXRpbmcgYHRscy5Tb2NrZXRgOiAlbyIsdGhpcy5jb25uZWN0T3B0cyk7Y29uc3QgdD10aGlzLmNvbm5lY3RPcHRzLnNlcnZlcm5hbWV8fHRoaXMuY29ubmVjdE9wdHMuaG9zdDtyPWYuY29ubmVjdCh7Li4udGhpcy5jb25uZWN0T3B0cyxzZXJ2ZXJuYW1lOnQmJmEuaXNJUCh0KT92b2lkIDA6dH0pfWVsc2Ugcm4oIkNyZWF0aW5nIGBuZXQuU29ja2V0YDogJW8iLHRoaXMuY29ubmVjdE9wdHMpLHI9YS5jb25uZWN0KHRoaXMuY29ubmVjdE9wdHMpO2NvbnN0IG89ImZ1bmN0aW9uIj09dHlwZW9mIHRoaXMucHJveHlIZWFkZXJzP3RoaXMucHJveHlIZWFkZXJzKCk6ey4uLnRoaXMucHJveHlIZWFkZXJzfSxpPWEuaXNJUHY2KG4uaG9zdCk/YFske24uaG9zdH1dYDpuLmhvc3Q7bGV0IHM9YENPTk5FQ1QgJHtpfToke24ucG9ydH0gSFRUUC8xLjFcclxuYDtpZihlLnVzZXJuYW1lfHxlLnBhc3N3b3JkKXtjb25zdCB0PWAke2RlY29kZVVSSUNvbXBvbmVudChlLnVzZXJuYW1lKX06JHtkZWNvZGVVUklDb21wb25lbnQoZS5wYXNzd29yZCl9YDtvWyJQcm94eS1BdXRob3JpemF0aW9uIl09YEJhc2ljICR7QnVmZmVyLmZyb20odCkudG9TdHJpbmcoImJhc2U2NCIpfWB9by5Ib3N0PWAke2l9OiR7bi5wb3J0fWAsb1siUHJveHktQ29ubmVjdGlvbiJdfHwob1siUHJveHktQ29ubmVjdGlvbiJdPXRoaXMua2VlcEFsaXZlPyJLZWVwLUFsaXZlIjoiY2xvc2UiKTtmb3IoY29uc3QgdCBvZiBPYmplY3Qua2V5cyhvKSlzKz1gJHt0fTogJHtvW3RdfVxyXG5gO2NvbnN0IGM9ZW4ocik7ci53cml0ZShgJHtzfVxyXG5gKTtjb25zdHtjb25uZWN0OnUsYnVmZmVyZWQ6aH09YXdhaXQgYztpZih0LmVtaXQoInByb3h5Q29ubmVjdCIsdSksdGhpcy5lbWl0KCJwcm94eUNvbm5lY3QiLHUsdCksMjAwPT09dS5zdGF0dXNDb2RlKXtpZih0Lm9uY2UoInNvY2tldCIsc24pLG4uc2VjdXJlRW5kcG9pbnQpe3JuKCJVcGdyYWRpbmcgc29ja2V0IGNvbm5lY3Rpb24gdG8gVExTIik7Y29uc3QgdD1uLnNlcnZlcm5hbWV8fG4uaG9zdDtyZXR1cm4gZi5jb25uZWN0KHsuLi5jbihuLCJob3N0IiwicGF0aCIsInBvcnQiKSxzb2NrZXQ6cixzZXJ2ZXJuYW1lOmEuaXNJUCh0KT92b2lkIDA6dH0pfXJldHVybiByfXIuZGVzdHJveSgpO2NvbnN0IHA9bmV3IGEuU29ja2V0KHt3cml0YWJsZTohMX0pO3JldHVybiBwLnJlYWRhYmxlPSEwLHQub25jZSgic29ja2V0Iix0PT57cm4oIlJlcGxheWluZyBwcm94eSBidWZmZXIgZm9yIGZhaWxlZCByZXF1ZXN0IiksdC5wdXNoKGgpLHQucHVzaChudWxsKX0pLHB9fWZ1bmN0aW9uIHNuKHQpe3QucmVzdW1lKCl9ZnVuY3Rpb24gY24odCwuLi5uKXtjb25zdCBlPXt9O2xldCByO2ZvcihyIGluIHQpbi5pbmNsdWRlcyhyKXx8KGVbcl09dFtyXSk7cmV0dXJuIGV9b24ucHJvdG9jb2xzPVsiaHR0cCIsImh0dHBzIl07ZnVuY3Rpb24gdW4odCl7cmV0dXJuIHQucmVwbGFjZSgvXltBLVpdOi8sIiIpLnJlcGxhY2UoL1xcL2csIi8iKX1jb25zdCBhbj1uO2xldCBmbixobj0wLHBuPXt9O2Z1bmN0aW9uIGRuKHQpe2FuLmRlYnVnJiZjb25zb2xlLmxvZyhgW0FOUiBXb3JrZXJdICR7dH1gKX12YXIgbG4sZ24sbW47Y29uc3QgeW49ZnVuY3Rpb24odCl7bGV0IG47dHJ5e249bmV3IFVSTCh0LnVybCl9Y2F0Y2gobil7cmV0dXJuIGIoKCk9Pntjb25zb2xlLndhcm4oIltAc2VudHJ5L25vZGVdOiBJbnZhbGlkIGRzbiBvciB0dW5uZWwgb3B0aW9uLCB3aWxsIG5vdCBzZW5kIGFueSBldmVudHMuIFRoZSB0dW5uZWwgb3B0aW9uIG11c3QgYmUgYSBmdWxsIFVSTCB3aGVuIHVzZWQuIil9KSxLdCh0LCgpPT5Qcm9taXNlLnJlc29sdmUoe30pKX1jb25zdCBlPSJodHRwczoiPT09bi5wcm90b2NvbCxyPWZ1bmN0aW9uKHQsbil7Y29uc3R7bm9fcHJveHk6ZX09cHJvY2Vzcy5lbnYscj1lPy5zcGxpdCgiLCIpLnNvbWUobj0+dC5ob3N0LmVuZHNXaXRoKG4pfHx0Lmhvc3RuYW1lLmVuZHNXaXRoKG4pKTtyZXR1cm4gcj92b2lkIDA6bn0obix0LnByb3h5fHwoZT9wcm9jZXNzLmVudi5odHRwc19wcm94eTp2b2lkIDApfHxwcm9jZXNzLmVudi5odHRwX3Byb3h5KSxvPWU/czppLGE9dm9pZCAwIT09dC5rZWVwQWxpdmUmJnQua2VlcEFsaXZlLGY9cj9uZXcgb24ocik6bmV3IG8uQWdlbnQoe2tlZXBBbGl2ZTphLG1heFNvY2tldHM6MzAsdGltZW91dDoyZTN9KSxoPWZ1bmN0aW9uKHQsbixlKXtjb25zdHtob3N0bmFtZTpyLHBhdGhuYW1lOm8scG9ydDppLHByb3RvY29sOnMsc2VhcmNoOmF9PW5ldyBVUkwodC51cmwpO3JldHVybiBmdW5jdGlvbihmKXtyZXR1cm4gbmV3IFByb21pc2UoKGgscCk9PntGdCgoKT0+e2xldCBkPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgYyh7cmVhZCgpe3RoaXMucHVzaCh0KSx0aGlzLnB1c2gobnVsbCl9fSl9KGYuYm9keSk7Y29uc3QgbD17Li4udC5oZWFkZXJzfTtmLmJvZHkubGVuZ3RoPjMyNzY4JiYobFsiY29udGVudC1lbmNvZGluZyJdPSJnemlwIixkPWQucGlwZSh1KCkpKTtjb25zdCBnPXIuc3RhcnRzV2l0aCgiWyIpLG09bi5yZXF1ZXN0KHttZXRob2Q6IlBPU1QiLGFnZW50OmUsaGVhZGVyczpsLGhvc3RuYW1lOmc/ci5zbGljZSgxLC0xKTpyLHBhdGg6YCR7b30ke2F9YCxwb3J0OmkscHJvdG9jb2w6cyxjYTp0LmNhQ2VydHN9LHQ9Pnt0Lm9uKCJkYXRhIiwoKT0+e30pLHQub24oImVuZCIsKCk9Pnt9KSx0LnNldEVuY29kaW5nKCJ1dGY4Iik7Y29uc3Qgbj10LmhlYWRlcnNbInJldHJ5LWFmdGVyIl0/P251bGwsZT10LmhlYWRlcnNbIngtc2VudHJ5LXJhdGUtbGltaXRzIl0/P251bGw7aCh7c3RhdHVzQ29kZTp0LnN0YXR1c0NvZGUsaGVhZGVyczp7InJldHJ5LWFmdGVyIjpuLCJ4LXNlbnRyeS1yYXRlLWxpbWl0cyI6QXJyYXkuaXNBcnJheShlKT9lWzBdfHxudWxsOmV9fSl9KTttLm9uKCJlcnJvciIscCksZC5waXBlKG0pfSl9KX19KHQsdC5odHRwTW9kdWxlPz9vLGYpO3JldHVybiBLdCh0LGgpfSh7dXJsOihsbj1hbi5kc24sZ249YW4udHVubmVsLG1uPWFuLnNka01ldGFkYXRhLnNkayxnbnx8YCR7ZnVuY3Rpb24odCl7cmV0dXJuYCR7ZnVuY3Rpb24odCl7Y29uc3Qgbj10LnByb3RvY29sP2Ake3QucHJvdG9jb2x9OmA6IiIsZT10LnBvcnQ/YDoke3QucG9ydH1gOiIiO3JldHVybmAke259Ly8ke3QuaG9zdH0ke2V9JHt0LnBhdGg/YC8ke3QucGF0aH1gOiIifS9hcGkvYH0odCl9JHt0LnByb2plY3RJZH0vZW52ZWxvcGUvYH0obG4pfT8ke2Z1bmN0aW9uKHQsbil7Y29uc3QgZT17c2VudHJ5X3ZlcnNpb246IjcifTtyZXR1cm4gdC5wdWJsaWNLZXkmJihlLnNlbnRyeV9rZXk9dC5wdWJsaWNLZXkpLG4mJihlLnNlbnRyeV9jbGllbnQ9YCR7bi5uYW1lfS8ke24udmVyc2lvbn1gKSxuZXcgVVJMU2VhcmNoUGFyYW1zKGUpLnRvU3RyaW5nKCl9KGxuLG1uKX1gKX0pO2FzeW5jIGZ1bmN0aW9uIGJuKCl7aWYoZm4pe2RuKCJTZW5kaW5nIGFibm9ybWFsIHNlc3Npb24iKSxLKGZuLHtzdGF0dXM6ImFibm9ybWFsIixhYm5vcm1hbF9tZWNoYW5pc206ImFucl9mb3JlZ3JvdW5kIixyZWxlYXNlOmFuLnJlbGVhc2UsZW52aXJvbm1lbnQ6YW4uZW52aXJvbm1lbnR9KTtjb25zdCB0PWZ1bmN0aW9uKHQsbixlLHIpe2NvbnN0IG89THQoZSk7cmV0dXJuIFR0KHtzZW50X2F0Om5ldyBEYXRlKFAoKSkudG9JU09TdHJpbmcoKSwuLi5vJiZ7c2RrOm99LC4uLiEhciYmbiYme2RzbjpidChuKX19LFsiYWdncmVnYXRlcyJpbiB0P1t7dHlwZToic2Vzc2lvbnMifSx0XTpbe3R5cGU6InNlc3Npb24ifSx0LnRvSlNPTigpXV0pfShmbixhbi5kc24sYW4uc2RrTWV0YWRhdGEsYW4udHVubmVsKTtkbihKU09OLnN0cmluZ2lmeSh0KSksYXdhaXQgeW4uc2VuZCh0KTt0cnl7ZT8ucG9zdE1lc3NhZ2UoInNlc3Npb24tZW5kZWQiKX1jYXRjaHt9fX1mdW5jdGlvbiB2bih0KXtpZighdClyZXR1cm47Y29uc3Qgbj1mdW5jdGlvbih0KXtpZighdC5sZW5ndGgpcmV0dXJuW107Y29uc3Qgbj1BcnJheS5mcm9tKHQpO3JldHVybi9zZW50cnlXcmFwcGVkLy50ZXN0KEUobikuZnVuY3Rpb258fCIiKSYmbi5wb3AoKSxuLnJldmVyc2UoKSwkLnRlc3QoRShuKS5mdW5jdGlvbnx8IiIpJiYobi5wb3AoKSwkLnRlc3QoRShuKS5mdW5jdGlvbnx8IiIpJiZuLnBvcCgpKSxuLnNsaWNlKDAsNTApLm1hcCh0PT4oey4uLnQsZmlsZW5hbWU6dC5maWxlbmFtZXx8RShuKS5maWxlbmFtZSxmdW5jdGlvbjp0LmZ1bmN0aW9ufHwiPyJ9KSl9KHQpO2lmKGFuLmFwcFJvb3RQYXRoKWZvcihjb25zdCB0IG9mIG4pdC5maWxlbmFtZSYmKHQuZmlsZW5hbWU9TSh0LmZpbGVuYW1lLGFuLmFwcFJvb3RQYXRoKSk7cmV0dXJuIG59YXN5bmMgZnVuY3Rpb24gX24odCxuKXtpZihobj49YW4ubWF4QW5yRXZlbnRzKXJldHVybjtobis9MSxhd2FpdCBibigpLGRuKCJTZW5kaW5nIGV2ZW50Iik7Y29uc3QgZT17ZXZlbnRfaWQ6RygpLGNvbnRleHRzOmFuLmNvbnRleHRzLHJlbGVhc2U6YW4ucmVsZWFzZSxlbnZpcm9ubWVudDphbi5lbnZpcm9ubWVudCxkaXN0OmFuLmRpc3QscGxhdGZvcm06Im5vZGUiLGxldmVsOiJlcnJvciIsZXhjZXB0aW9uOnt2YWx1ZXM6W3t0eXBlOiJBcHBsaWNhdGlvbk5vdFJlc3BvbmRpbmciLHZhbHVlOmBBcHBsaWNhdGlvbiBOb3QgUmVzcG9uZGluZyBmb3IgYXQgbGVhc3QgJHthbi5hbnJUaHJlc2hvbGR9IG1zYCxzdGFja3RyYWNlOntmcmFtZXM6dm4odCl9LG1lY2hhbmlzbTp7dHlwZToiQU5SIn19XX0sdGFnczphbi5zdGF0aWNUYWdzfTtuJiZmdW5jdGlvbih0LG4pe2lmKEd0KHQsbiksIXQuY29udGV4dHM/LnRyYWNlKXtjb25zdHt0cmFjZUlkOmUscGFyZW50U3BhbklkOnIscHJvcGFnYXRpb25TcGFuSWQ6b309bi5wcm9wYWdhdGlvbkNvbnRleHQ7dC5jb250ZXh0cz17dHJhY2U6e3RyYWNlX2lkOmUsc3Bhbl9pZDpvfHxWKCkscGFyZW50X3NwYW5faWQ6cn0sLi4udC5jb250ZXh0c319fShlLG4pLGZ1bmN0aW9uKHQpe2lmKDA9PT1PYmplY3Qua2V5cyhwbikubGVuZ3RoKXJldHVybjtjb25zdCBuPWFuLmFwcFJvb3RQYXRoP3t9OnBuO2lmKGFuLmFwcFJvb3RQYXRoKWZvcihjb25zdFt0LGVdb2YgT2JqZWN0LmVudHJpZXMocG4pKW5bTSh0LGFuLmFwcFJvb3RQYXRoKV09ZTtjb25zdCBlPW5ldyBNYXA7Zm9yKGNvbnN0IHIgb2YgdC5leGNlcHRpb24/LnZhbHVlc3x8W10pZm9yKGNvbnN0IHQgb2Ygci5zdGFja3RyYWNlPy5mcmFtZXN8fFtdKXtjb25zdCByPXQuYWJzX3BhdGh8fHQuZmlsZW5hbWU7ciYmbltyXSYmZS5zZXQocixuW3JdKX1pZihlLnNpemU+MCl7Y29uc3Qgbj1bXTtmb3IoY29uc3RbdCxyXW9mIGUuZW50cmllcygpKW4ucHVzaCh7dHlwZToic291cmNlbWFwIixjb2RlX2ZpbGU6dCxkZWJ1Z19pZDpyfSk7dC5kZWJ1Z19tZXRhPXtpbWFnZXM6bn19fShlKTtjb25zdCByPU10KGUsYW4uZHNuLGFuLnNka01ldGFkYXRhLGFuLnR1bm5lbCk7ZG4oSlNPTi5zdHJpbmdpZnkocikpLGF3YWl0IHluLnNlbmQociksYXdhaXQgeW4uZmx1c2goMmUzKSxobj49YW4ubWF4QW5yRXZlbnRzJiZzZXRUaW1lb3V0KCgpPT57cHJvY2Vzcy5leGl0KDApfSw1ZTMpfWxldCBTbjtpZihkbigiU3RhcnRlZCIpLGFuLmNhcHR1cmVTdGFja1RyYWNlKXtkbigiQ29ubmVjdGluZyB0byBkZWJ1Z2dlciIpO2NvbnN0IG49bmV3IHQ7bi5jb25uZWN0VG9NYWluVGhyZWFkKCksZG4oIkNvbm5lY3RlZCB0byBkZWJ1Z2dlciIpO2NvbnN0IGU9bmV3IE1hcDtuLm9uKCJEZWJ1Z2dlci5zY3JpcHRQYXJzZWQiLHQ9PntlLnNldCh0LnBhcmFtcy5zY3JpcHRJZCx0LnBhcmFtcy51cmwpfSksbi5vbigiRGVidWdnZXIucGF1c2VkIix0PT57aWYoIm90aGVyIj09PXQucGFyYW1zLnJlYXNvbil0cnl7ZG4oIkRlYnVnZ2VyIHBhdXNlZCIpO2NvbnN0IGk9Wy4uLnQucGFyYW1zLmNhbGxGcmFtZXNdLHM9YW4uYXBwUm9vdFBhdGg/ZnVuY3Rpb24odD0ocHJvY2Vzcy5hcmd2WzFdP3F0KHByb2Nlc3MuYXJndlsxXSk6cHJvY2Vzcy5jd2QoKSksbj0iXFwiPT09byl7Y29uc3QgZT1uP3VuKHQpOnQ7cmV0dXJuIHQ9PntpZighdClyZXR1cm47Y29uc3Qgbz1uP3VuKHQpOnQ7bGV0e2RpcjppLGJhc2U6cyxleHQ6Y309ci5wYXJzZShvKTsiLmpzIiE9PWMmJiIubWpzIiE9PWMmJiIuY2pzIiE9PWN8fChzPXMuc2xpY2UoMCwtMSpjLmxlbmd0aCkpO2NvbnN0IHU9ZGVjb2RlVVJJQ29tcG9uZW50KHMpO2l8fChpPSIuIik7Y29uc3QgYT1pLmxhc3RJbmRleE9mKCIvbm9kZV9tb2R1bGVzIik7aWYoYT4tMSlyZXR1cm5gJHtpLnNsaWNlKGErMTQpLnJlcGxhY2UoL1wvL2csIi4iKX06JHt1fWA7aWYoaS5zdGFydHNXaXRoKGUpKXtjb25zdCB0PWkuc2xpY2UoZS5sZW5ndGgrMSkucmVwbGFjZSgvXC8vZywiLiIpO3JldHVybiB0P2Ake3R9OiR7dX1gOnV9cmV0dXJuIHV9fShhbi5hcHBSb290UGF0aCk6KCk9Pnt9LGM9aS5tYXAodD0+ZnVuY3Rpb24odCxuLGUpe2NvbnN0IHI9bj9uLnJlcGxhY2UoL15maWxlOlwvXC8vLCIiKTp2b2lkIDAsbz10LmxvY2F0aW9uLmNvbHVtbk51bWJlcj90LmxvY2F0aW9uLmNvbHVtbk51bWJlcisxOnZvaWQgMCxpPXQubG9jYXRpb24ubGluZU51bWJlcj90LmxvY2F0aW9uLmxpbmVOdW1iZXIrMTp2b2lkIDA7cmV0dXJue2ZpbGVuYW1lOnIsbW9kdWxlOmUociksZnVuY3Rpb246dC5mdW5jdGlvbk5hbWV8fCI/Iixjb2xubzpvLGxpbmVubzppLGluX2FwcDpyP1Z0KHIpOnZvaWQgMH19KHQsZS5nZXQodC5sb2NhdGlvbi5zY3JpcHRJZCkscykpLHU9c2V0VGltZW91dCgoKT0+e19uKGMpLnRoZW4obnVsbCwoKT0+e2RuKCJTZW5kaW5nIEFOUiBldmVudCBmYWlsZWQuIil9KX0sNWUzKTtuLnBvc3QoIlJ1bnRpbWUuZXZhbHVhdGUiLHtleHByZXNzaW9uOiJnbG9iYWwuX19TRU5UUllfR0VUX1NDT1BFU19fKCk7IixzaWxlbnQ6ITAscmV0dXJuQnlWYWx1ZTohMH0sKHQsZSk9Pnt0JiZkbihgRXJyb3IgZXhlY3V0aW5nIHNjcmlwdDogJyR7dC5tZXNzYWdlfSdgKSxjbGVhclRpbWVvdXQodSk7Y29uc3Qgcj1lPy5yZXN1bHQ/ZS5yZXN1bHQudmFsdWU6dm9pZCAwO24ucG9zdCgiRGVidWdnZXIucmVzdW1lIiksbi5wb3N0KCJEZWJ1Z2dlci5kaXNhYmxlIiksX24oYyxyKS50aGVuKG51bGwsKCk9PntkbigiU2VuZGluZyBBTlIgZXZlbnQgZmFpbGVkLiIpfSl9KX1jYXRjaCh0KXt0aHJvdyBuLnBvc3QoIkRlYnVnZ2VyLnJlc3VtZSIpLG4ucG9zdCgiRGVidWdnZXIuZGlzYWJsZSIpLHR9fSksU249KCk9Pnt0cnl7bi5wb3N0KCJEZWJ1Z2dlci5lbmFibGUiLCgpPT57bi5wb3N0KCJEZWJ1Z2dlci5wYXVzZSIpfSl9Y2F0Y2h7fX19Y29uc3R7cG9sbDp3bn09ZnVuY3Rpb24odCxuLGUscil7Y29uc3Qgbz10KCk7bGV0IGk9ITEscz0hMDtyZXR1cm4gc2V0SW50ZXJ2YWwoKCk9Pntjb25zdCB0PW8uZ2V0VGltZU1zKCk7ITE9PT1pJiZ0Pm4rZSYmKGk9ITAscyYmcigpKSx0PG4rZSYmKGk9ITEpfSwyMCkse3BvbGw6KCk9PntvLnJlc2V0KCl9LGVuYWJsZWQ6dD0+e3M9dH19fShmdW5jdGlvbigpe2xldCB0PXByb2Nlc3MuaHJ0aW1lKCk7cmV0dXJue2dldFRpbWVNczooKT0+e2NvbnN0W24sZV09cHJvY2Vzcy5ocnRpbWUodCk7cmV0dXJuIE1hdGguZmxvb3IoMWUzKm4rZS8xZTYpfSxyZXNldDooKT0+e3Q9cHJvY2Vzcy5ocnRpbWUoKX19fSxhbi5wb2xsSW50ZXJ2YWwsYW4uYW5yVGhyZXNob2xkLGZ1bmN0aW9uKCl7ZG4oIldhdGNoZG9nIHRpbWVvdXQiKSxTbj8oZG4oIlBhdXNpbmcgZGVidWdnZXIgdG8gY2FwdHVyZSBzdGFjayB0cmFjZSIpLFNuKCkpOihkbigiQ2FwdHVyaW5nIGV2ZW50IHdpdGhvdXQgYSBzdGFjayB0cmFjZSIpLF9uKCkudGhlbihudWxsLCgpPT57ZG4oIlNlbmRpbmcgQU5SIGV2ZW50IGZhaWxlZCBvbiB3YXRjaGRvZyB0aW1lb3V0LiIpfSkpfSk7ZT8ub24oIm1lc3NhZ2UiLHQ9Pnt0LnNlc3Npb24mJihmbj1IKHQuc2Vzc2lvbikpLHQuZGVidWdJbWFnZXMmJihwbj10LmRlYnVnSW1hZ2VzKSx3bigpfSk7";
const DEFAULT_INTERVAL = 50;

@@ -11,0 +11,0 @@ const DEFAULT_HANG_THRESHOLD = 5e3;

@@ -1,2 +0,2 @@

/*! @sentry/node-core 10.64.0 (5736a38) | https://github.com/getsentry/sentry-javascript */
import{Session as t}from"node:inspector";import{workerData as n,parentPort as e}from"node:worker_threads";import{posix as r,sep as o}from"node:path";import*as i from"node:http";import*as s from"node:https";import{Readable as c}from"node:stream";import{createGzip as u}from"node:zlib";import*as a from"node:net";import*as f from"node:tls";const h="undefined"==typeof __SENTRY_DEBUG__||__SENTRY_DEBUG__,p=globalThis,d="10.64.0";function l(){return g(p),p}function g(t){const n=t.__SENTRY__=t.__SENTRY__||{};return n.version=n.version||d,n[d]=n[d]||{}}function m(t,n,e=p){const r=e.__SENTRY__=e.__SENTRY__||{},o=r[d]=r[d]||{};return o[t]||(o[t]=n())}const y={};function b(t){if(!("console"in p))return t();const n=p.console,e={},r=Object.keys(y);r.forEach(t=>{const r=y[t];e[t]=n[t],n[t]=r});try{return t()}finally{r.forEach(t=>{n[t]=e[t]})}}function v(){return S().enabled}function _(t,...n){h&&v()&&b(()=>{p.console[t](`Sentry Logger [${t}]:`,...n)})}function S(){return h?m("loggerSettings",()=>({enabled:!1})):{enabled:!1}}const w={enable:function(){S().enabled=!0},disable:function(){S().enabled=!1},isEnabled:v,log:function(...t){_("log",...t)},warn:function(...t){_("warn",...t)},error:function(...t){_("error",...t)}},$=/captureMessage|captureException/;function E(t){return t[t.length-1]||{}}const x="<anonymous>";const N=Object.prototype.toString;function C(t,n){return N.call(t)===`[object ${n}]`}function j(t){return Boolean(t?.then&&"function"==typeof t.then)}function R(t,n){try{return t instanceof n}catch{return!1}}function A(t){if(function(t){switch(N.call(t)){case"[object Error]":case"[object Exception]":case"[object DOMException]":case"[object WebAssembly.Exception]":return!0;default:return R(t,Error)}}(t))return{message:t.message,name:t.name,stack:t.stack,...I(t)};if(n=t,"undefined"!=typeof Event&&R(n,Event)){const{type:n,target:e,currentTarget:r,detail:o}=t;return{type:n,target:e,currentTarget:r,...o?{detail:o}:{},...I(t)}}var n;return t}function I(t){return"object"==typeof t&&null!==t?Object.fromEntries(Object.entries(t)):{}}let O;function T(t){if(void 0!==O)return O?O(t):t();const n=Symbol.for("__SENTRY_SAFE_RANDOM_ID_WRAPPER__"),e=p;return n in e&&"function"==typeof e[n]?(O=e[n],O(t)):(O=null,t())}function k(){return T(()=>Math.random())}function P(){return T(()=>Date.now())}const D=Symbol.for("sentry.skipNormalization"),U=Symbol.for("sentry.overrideNormalizationDepth");function B(t,n=100,e=1/0){try{return L("",t,n,e)}catch(t){return{ERROR:`**non-serializable** (${t})`}}}function L(t,n,e=1/0,r=1/0,o=function(){const t=new WeakSet;function n(n){return!!t.has(n)||(t.add(n),!1)}function e(n){t.delete(n)}return[n,e]}()){const[i,s]=o;if(null==n||["boolean","string"].includes(typeof n)||"number"==typeof n&&Number.isFinite(n))return n;const c=function(t,n){try{if("undefined"!=typeof global&&n===global)return"[Global]";if("number"==typeof n&&!Number.isFinite(n))return`[${n}]`;if("function"==typeof n)return`[Function: ${function(t){try{return t&&"function"==typeof t&&t.name||x}catch{return x}}(n)}]`;if("symbol"==typeof n)return`[${String(n)}]`;if("bigint"==typeof n)return`[BigInt: ${String(n)}]`;const t=function(t){const n=Object.getPrototypeOf(t);return n?.constructor?n.constructor.name:"null prototype"}(n);return`[object ${t}]`}catch(t){return`**non-serializable** (${t})`}}(0,n);if(!c.startsWith("[object "))return c;if(function(t){return Boolean(t[D])}(n))return n;const u=function(t){const n=t[U];return"number"==typeof n?n:void 0}(n),a=void 0!==u?u:e;if(0===a)return c.replace("object ","");if(i(n))return"[Circular ~]";const f=n;if(f&&"function"==typeof f.toJSON)try{return L("",f.toJSON(),a-1,r,o)}catch{}const h=Array.isArray(n)?[]:{};let p=0;const d=A(n);for(const t in d){if(!Object.prototype.hasOwnProperty.call(d,t))continue;if(p>=r){h[t]="[MaxProperties ~]";break}const n=d[t];h[t]=L(t,n,a-1,r,o),p++}return s(n),h}function M(t,n){const e=n.replace(/\\/g,"/").replace(/[|\\{}()[\]^$+*?.]/g,"\\$&");let r=t;try{r=decodeURI(t)}catch{}return r.replace(/\\/g,"/").replace(/webpack:\/?/g,"").replace(new RegExp(`(file://)?/*${e}/*`,"ig"),"app:///")}function z(t,n=0){return"string"!=typeof t||0===n||t.length<=n?t:`${t.slice(0,n)}...`}let F;function G(t=function(){const t=p;return t.crypto||t.msCrypto}()){try{if(t?.randomUUID)return T(()=>t.randomUUID()).replace(/-/g,"")}catch{}return F||(F="10000000100040008000100000000000"),F.replace(/[018]/g,t=>(t^(16*k()&15)>>t/4).toString(16))}function J(){return P()/1e3}let W;function Y(){return(W??(W=function(){const{performance:t}=p;if(!t?.now||!t.timeOrigin)return J;const n=t.timeOrigin;return()=>(n+T(()=>t.now()))/1e3}()))()}function H(t){const n=Y(),e={sid:G(),init:!0,timestamp:n,started:n,duration:0,status:"ok",errors:0,ignoreDuration:!1,toJSON:()=>function(t){return{sid:`${t.sid}`,init:t.init,started:new Date(1e3*t.started).toISOString(),timestamp:new Date(1e3*t.timestamp).toISOString(),status:t.status,errors:t.errors,did:"number"==typeof t.did||"string"==typeof t.did?`${t.did}`:void 0,duration:t.duration,abnormal_mechanism:t.abnormal_mechanism,attrs:{release:t.release,environment:t.environment,ip_address:t.ipAddress,user_agent:t.userAgent}}}(e)};return t&&K(e,t),e}function K(t,n={}){if(n.user&&(!t.ipAddress&&n.user.ip_address&&(t.ipAddress=n.user.ip_address),t.did||n.did||(t.did=n.user.id||n.user.email||n.user.username)),t.timestamp=n.timestamp||Y(),n.abnormal_mechanism&&(t.abnormal_mechanism=n.abnormal_mechanism),n.ignoreDuration&&(t.ignoreDuration=n.ignoreDuration),n.sid&&(t.sid=32===n.sid.length?n.sid:G()),void 0!==n.init&&(t.init=n.init),!t.did&&n.did&&(t.did=`${n.did}`),"number"==typeof n.started&&(t.started=n.started),t.ignoreDuration)t.duration=void 0;else if("number"==typeof n.duration)t.duration=n.duration;else{const n=t.timestamp-t.started;t.duration=n>=0?n:0}n.release&&(t.release=n.release),n.environment&&(t.environment=n.environment),!t.ipAddress&&n.ipAddress&&(t.ipAddress=n.ipAddress),!t.userAgent&&n.userAgent&&(t.userAgent=n.userAgent),"number"==typeof n.errors&&(t.errors=n.errors),n.status&&(t.status=n.status)}function Z(t,n,e=2){if(!n||"object"!=typeof n||e<=0)return n;if(t&&0===Object.keys(n).length)return t;const r={...t};for(const t in n)Object.prototype.hasOwnProperty.call(n,t)&&(r[t]=Z(r[t],n[t],e-1));return r}function q(){return G()}function V(){return G().substring(16)}function Q(t){if(t){if("object"==typeof t&&"deref"in t&&"function"==typeof t.deref)try{return t.deref()}catch{return}return t}}const X="_sentrySpan";function tt(t,n){n?function(t,n,e){try{Object.defineProperty(t,n,{value:e,writable:!0,configurable:!0})}catch{h&&w.log(`Failed to add non-enumerable property "${String(n)}" to object`,t)}}(t,X,function(t){try{const n=p.WeakRef;if("function"==typeof n)return new n(t)}catch{}return t}(n)):delete t[X]}function nt(t){return Q(t[X])}class et{constructor(){this.t=!1,this.o=[],this.i=[],this.u=[],this.h=[],this.p={},this.l={},this.m={},this.v={},this._={},this.S={},this.N={traceId:q(),sampleRand:k()}}clone(){const t=new et;return t.u=[...this.u],t.l={...this.l},t.m={...this.m},t.v={...this.v},t._={...this._},this._.flags&&(t._.flags={values:[...this._.flags.values]}),t.p=this.p,t.C=this.C,t.j=this.j,t.R=this.R,t.A=this.A,t.i=[...this.i],t.h=[...this.h],t.S={...this.S},t.N={...this.N},t.I=this.I,t.O=this.O,t.T=this.T,tt(t,nt(this)),t}setClient(t){this.I=t}setLastEventId(t){this.O=t}getClient(){return this.I}lastEventId(){return this.O}addScopeListener(t){this.o.push(t)}addEventProcessor(t){return this.i.push(t),this}setUser(t){return this.p=t||{email:void 0,id:void 0,ip_address:void 0,username:void 0},this.j&&K(this.j,{user:t}),this.k(),this}getUser(){return this.p}setConversationId(t){return this.T=t||void 0,this.k(),this}setTags(t){return this.l={...this.l,...t},this.k(),this}setTag(t,n){return this.setTags({[t]:n})}setAttributes(t){return this.m={...this.m,...t},this.k(),this}setAttribute(t,n){return this.setAttributes({[t]:n})}removeAttribute(t){return t in this.m&&(delete this.m[t],this.k()),this}setExtras(t){return this.v={...this.v,...t},this.k(),this}setExtra(t,n){return this.v={...this.v,[t]:n},this.k(),this}setFingerprint(t){return this.A=t,this.k(),this}setLevel(t){return this.C=t,this.k(),this}setTransactionName(t){return this.R=t,this.k(),this}setContext(t,n){return null===n?delete this._[t]:this._[t]=n,this.k(),this}setSession(t){return t?this.j=t:delete this.j,this.k(),this}getSession(){return this.j}update(t){if(!t)return this;const n="function"==typeof t?t(this):t,e=n instanceof et?n.getScopeData():C(n,"Object")?t:void 0;const{tags:r,attributes:o,extra:i,user:s,contexts:c,level:u,fingerprint:a=[],propagationContext:f,conversationId:h}=e||{};return this.l={...this.l,...r},this.m={...this.m,...o},this.v={...this.v,...i},this._={...this._,...c},s&&Object.keys(s).length&&(this.p=s),u&&(this.C=u),a.length&&(this.A=a),f&&(this.N=f),h&&(this.T=h),this}clear(){return this.u=[],this.l={},this.m={},this.v={},this.p={},this._={},this.C=void 0,this.R=void 0,this.A=void 0,this.j=void 0,this.T=void 0,tt(this,void 0),this.h=[],this.setPropagationContext({traceId:q(),sampleRand:k()}),this.k(),this}addBreadcrumb(t,n){const e="number"==typeof n?n:100;if(e<=0)return this;const r={timestamp:J(),...t,message:t.message?z(t.message,2048):t.message};return this.u.push(r),this.u.length>e&&(this.u=this.u.slice(-e),this.I?.recordDroppedEvent("buffer_overflow","log_item")),this.k(),this}getLastBreadcrumb(){return this.u[this.u.length-1]}clearBreadcrumbs(){return this.u=[],this.k(),this}addAttachment(t){return this.h.push(t),this}clearAttachments(){return this.h=[],this}getScopeData(){return{breadcrumbs:this.u,attachments:this.h,contexts:this._,tags:this.l,attributes:this.m,extra:this.v,user:this.p,level:this.C,fingerprint:this.A||[],eventProcessors:this.i,propagationContext:this.N,sdkProcessingMetadata:this.S,transactionName:this.R,span:nt(this),conversationId:this.T}}setSDKProcessingMetadata(t){return this.S=Z(this.S,t,2),this}setPropagationContext(t){return this.N=t,this}getPropagationContext(){return this.N}captureException(t,n){const e=n?.event_id||G();if(!this.I)return h&&w.warn("No client configured on scope - will not capture exception!"),e;const r=new Error("Sentry syntheticException");return this.I.captureException(t,{originalException:t,syntheticException:r,...n,event_id:e},this),e}captureMessage(t,n,e){const r=e?.event_id||G();if(!this.I)return h&&w.warn("No client configured on scope - will not capture message!"),r;const o=e?.syntheticException??new Error(t);return this.I.captureMessage(t,n,{originalException:t,syntheticException:o,...e,event_id:r},this),r}captureEvent(t,n){const e=t.event_id||n?.event_id||G();return this.I?(this.I.captureEvent(t,{...n,event_id:e},this),e):(h&&w.warn("No client configured on scope - will not capture event!"),e)}k(){this.t||(this.t=!0,this.o.forEach(t=>{t(this)}),this.t=!1)}}const rt=t=>t instanceof Promise&&!t[ot],ot=Symbol("chained PromiseLike"),it=(t,n)=>{if(!n)return t;let e=!1;for(const r in t){if(r in n)continue;e=!0;const o=t[r];"function"==typeof o?Object.defineProperty(n,r,{value:(...n)=>o.apply(t,n),enumerable:!0,configurable:!0,writable:!0}):n[r]=o}return e&&Object.assign(n,{[ot]:!0}),n};class st{constructor(t,n){let e,r;e=t||new et,r=n||new et,this.P=[{scope:e}],this.D=r}withScope(t){const n=this.U();let e;try{e=t(n)}catch(t){throw this.B(),t}return j(e)?((t,n,e)=>{const r=t.then(t=>(n(t),t),t=>{throw e(t),t});return rt(r)&&rt(t)?r:it(t,r)})(e,()=>this.B(),()=>this.B()):(this.B(),e)}getClient(){return this.getStackTop().client}getScope(){return this.getStackTop().scope}getIsolationScope(){return this.D}getStackTop(){return this.P[this.P.length-1]}U(){const t=this.getScope().clone();return this.P.push({client:this.getClient(),scope:t}),t}B(){return!(this.P.length<=1)&&!!this.P.pop()}}function ct(){const t=g(l());return t.stack=t.stack||new st(m("defaultCurrentScope",()=>new et),m("defaultIsolationScope",()=>new et))}function ut(t){return ct().withScope(t)}function at(t,n){const e=ct();return e.withScope(()=>(e.getStackTop().scope=t,n(t)))}function ft(t){return ct().withScope(()=>t(ct().getIsolationScope()))}function ht(t){const n=g(t);return n.acs?n.acs:{withIsolationScope:ft,withScope:ut,withSetScope:at,withSetIsolationScope:(t,n)=>ft(n),getCurrentScope:()=>ct().getScope(),getIsolationScope:()=>ct().getIsolationScope()}}function pt(){return ht(l()).getCurrentScope().getClient()}function dt(t){const n=t;return{scope:n._sentryScope,isolationScope:Q(n._sentryIsolationScope)}}const lt="sentry-";function gt(t){const n=function(t){if(!t||(n=t,!C(n,"String")&&!Array.isArray(t)))return;var n;if(Array.isArray(t))return t.reduce((t,n)=>{const e=mt(n);return Object.entries(e).forEach(([n,e])=>{t[n]=e}),t},{});return mt(t)}(t);if(!n)return;const e=Object.entries(n).reduce((t,[n,e])=>{if(n.startsWith(lt)){t[n.slice(7)]=e}return t},{});return Object.keys(e).length>0?e:void 0}function mt(t){return t.split(",").map(t=>{const n=t.indexOf("=");if(-1===n)return[];return[t.slice(0,n),t.slice(n+1)].map(t=>{try{return decodeURIComponent(t.trim())}catch{return}})}).reduce((t,[n,e])=>(n&&e&&(t[n]=e),t),{})}const yt=/^o(\d+)\./;function bt(t,n=!1){const{host:e,path:r,pass:o,port:i,projectId:s,protocol:c,publicKey:u}=t;return`${c}://${u}${n&&o?`:${o}`:""}@${e}${i?`:${i}`:""}/${r?`${r}/`:r}${s}`}function vt(t){const n=t.getOptions(),{host:e}=t.getDsn()||{};let r;return n.orgId?r=String(n.orgId):e&&(r=function(t){const n=t.match(yt);return n?.[1]}(e)),r}function _t(t){const{spanId:n,traceId:e,isRemote:r}=t.spanContext(),o=r?n:Et(t).parent_span_id,i=dt(t).scope;return{parent_span_id:o,span_id:r?i?.getPropagationContext().propagationSpanId||V():n,trace_id:e}}function St(t){return t&&t.length>0?t.map(({context:{spanId:t,traceId:n,traceFlags:e,...r},attributes:o})=>({span_id:t,trace_id:n,sampled:1===e,attributes:o,...r})):void 0}function wt(t){return"number"==typeof t?$t(t):Array.isArray(t)?t[0]+t[1]/1e9:t instanceof Date?$t(t.getTime()):Y()}function $t(t){return t>9999999999?t/1e3:t}function Et(t){if(function(t){return"function"==typeof t.getSpanJSON}(t))return t.getSpanJSON();const{spanId:n,traceId:e}=t.spanContext();if(function(t){const n=t;return!!(n.attributes&&n.startTime&&n.name&&n.endTime&&n.status)}(t)){const{attributes:r,startTime:o,name:i,endTime:s,status:c,links:u}=t;return{span_id:n,trace_id:e,data:r,description:i,parent_span_id:xt(t),start_timestamp:wt(o),timestamp:wt(s)||void 0,status:Nt(c),op:r["sentry.op"],origin:r["sentry.origin"],links:St(u)}}return{span_id:n,trace_id:e,start_timestamp:0,data:{}}}function xt(t){return"parentSpanId"in t?t.parentSpanId:"parentSpanContext"in t?t.parentSpanContext?.spanId:void 0}function Nt(t){if(t&&0!==t.code)return 1===t.code?"ok":t.message||"internal_error"}const Ct=function(t){return t._sentryRootSpan||t};function jt(t){if("boolean"==typeof __SENTRY_TRACING__&&!__SENTRY_TRACING__)return!1;const n=t||pt()?.getOptions();return!(!n||null==n.tracesSampleRate&&!n.tracesSampler)}const Rt=Symbol.for("sentry.nonRecordingSpan");function At(t,n){const e=n.getOptions(),{publicKey:r}=n.getDsn()||{},o={environment:e.environment||"production",release:e.release,public_key:r,trace_id:t,org_id:vt(n)};return n.emit("createDsc",o),o}function It(t,n){const e=n.getPropagationContext();return e.dsc||At(e.traceId,t)}function Ot(t){const n=pt();if(!n)return{};const e=Ct(t),r=Et(e),o=r.data,i=e.spanContext().traceState,s=i?.get("sentry.sample_rate")??o["sentry.sample_rate"]??o["sentry.previous_trace_sample_rate"];function c(t){return"number"!=typeof s&&"string"!=typeof s||(t.sample_rate=`${s}`),t}const u=e._frozenDsc;if(u)return c(u);if(function(t){return!!t&&!0===t[Rt]}(e)&&!jt(n.getOptions())){const t=dt(e).scope;if(t)return c({...It(n,t)})}const a=i?.get("sentry.dsc"),f=a&&gt(a);if(f)return c(f);const h=At(t.spanContext().traceId,n),p=o["sentry.source"]??o["sentry.span.source"],d=r.description;return"url"!==p&&d&&(h.transaction=d),jt()&&(h.sampled=String(function(t){const{traceFlags:n}=t.spanContext();return 1===n}(e)),h.sample_rand=i?.get("sentry.sample_rand")??dt(e).scope?.getPropagationContext().sampleRand.toString()),c(h),n.emit("createDsc",h,e),h}function Tt(t,n=[]){return[t,n]}function kt(t,n){const e=t[1];for(const t of e){if(n(t,t[0].type))return!0}return!1}function Pt(t){const n=g(p);return n.encodePolyfill?n.encodePolyfill(t):(new TextEncoder).encode(t)}function Dt(t){const[n,e]=t;let r=JSON.stringify(n);function o(t){"string"==typeof r?r="string"==typeof t?r+t:[Pt(r),t]:r.push("string"==typeof t?Pt(t):t)}for(const t of e){const[n,e]=t;if(o(`\n${JSON.stringify(n)}\n`),"string"==typeof e||e instanceof Uint8Array)o(e);else{let t;try{t=JSON.stringify(e)}catch{t=JSON.stringify(B(e))}o(t)}}return"string"==typeof r?r:function(t){const n=t.reduce((t,n)=>t+n.length,0),e=new Uint8Array(n);let r=0;for(const n of t)e.set(n,r),r+=n.length;return e}(r)}const Ut={sessions:"session",event:"error",client_report:"internal",user_report:"default",profile_chunk:"profile",replay_event:"replay",replay_recording:"replay",check_in:"monitor",raw_security:"security",log:"log_item",trace_metric:"metric"};function Bt(t){return function(t){return t in Ut}(t)?Ut[t]:t}function Lt(t){if(!t?.sdk)return;const{name:n,version:e}=t.sdk;return{name:n,version:e}}function Mt(t,n,e,r){const o=Lt(e),i=t.type&&"replay_event"!==t.type?t.type:"event";!function(t,n){if(!n)return t;const e=t.sdk||{};t.sdk={...e,name:e.name||n.name,version:e.version||n.version,integrations:[...t.sdk?.integrations||[],...n.integrations||[]],packages:[...t.sdk?.packages||[],...n.packages||[]],settings:t.sdk?.settings||n.settings?{...t.sdk?.settings,...n.settings}:void 0}}(t,e?.sdk);const s=function(t,n,e,r){const o=t.sdkProcessingMetadata?.dynamicSamplingContext;return{event_id:t.event_id,sent_at:new Date(P()).toISOString(),...n&&{sdk:n},...!!e&&r&&{dsn:bt(r)},...o&&{trace:o}}}(t,o,r,n);delete t.sdkProcessingMetadata;return Tt(s,[[{type:i},t]])}const zt="__SENTRY_SUPPRESS_TRACING__";function Ft(t){const n=ht(l());return n.suppressTracing?n.suppressTracing(t):function(...t){const n=ht(l());if(2===t.length){const[e,r]=t;return e?n.withSetScope(e,r):n.withScope(r)}return n.withScope(t[0])}(n=>{n.setSDKProcessingMetadata({[zt]:!0});const e=t();return n.setSDKProcessingMetadata({[zt]:void 0}),e})}function Gt(t,n){const{fingerprint:e,span:r,breadcrumbs:o,sdkProcessingMetadata:i}=n;!function(t,n){const{extra:e,tags:r,user:o,contexts:i,level:s,transactionName:c}=n;Object.keys(e).length&&(t.extra={...e,...t.extra});Object.keys(r).length&&(t.tags={...r,...t.tags});Object.keys(o).length&&(t.user={...o,...t.user});Object.keys(i).length&&(t.contexts={...i,...t.contexts});s&&(t.level=s);c&&"transaction"!==t.type&&(t.transaction=c)}(t,n),r&&function(t,n){t.contexts={trace:_t(n),...t.contexts},t.sdkProcessingMetadata={dynamicSamplingContext:Ot(n),...t.sdkProcessingMetadata};const e=Ct(n),r=Et(e).description;r&&!t.transaction&&"transaction"===t.type&&(t.transaction=r)}(t,r),function(t,n){t.fingerprint=t.fingerprint?Array.isArray(t.fingerprint)?t.fingerprint:[t.fingerprint]:[],n&&(t.fingerprint=t.fingerprint.concat(n));t.fingerprint.length||delete t.fingerprint}(t,e),function(t,n){const e=[...t.breadcrumbs||[],...n];t.breadcrumbs=e.length?e:void 0}(t,o),function(t,n){t.sdkProcessingMetadata={...t.sdkProcessingMetadata,...n}}(t,i)}class Jt{constructor(t){this.L=0,this.M=[],this.F(t)}then(t,n){return new Jt((e,r)=>{this.M.push([!1,n=>{if(t)try{e(t(n))}catch(t){r(t)}else e(n)},t=>{if(n)try{e(n(t))}catch(t){r(t)}else r(t)}]),this.G()})}catch(t){return this.then(t=>t,t)}finally(t){return new Jt((n,e)=>{let r,o;return this.then(n=>{o=!1,r=n,t&&t()},n=>{o=!0,r=n,t&&t()}).then(()=>{o?e(r):n(r)})})}G(){if(0===this.L)return;const t=this.M.slice();this.M=[],t.forEach(t=>{t[0]||(1===this.L&&t[1](this.J),2===this.L&&t[2](this.J),t[0]=!0)})}F(t){const n=(t,n)=>{0===this.L&&(j(n)?n.then(e,r):(this.L=t,this.J=n,this.G()))},e=t=>{n(1,t)},r=t=>{n(2,t)};try{t(e,r)}catch(t){r(t)}}}const Wt=Symbol.for("SentryBufferFullError");function Yt(t=100){const n=new Set;function e(t){n.delete(t)}return{get $(){return Array.from(n)},add:function(r){if(!(n.size<t))return o=Wt,new Jt((t,n)=>{n(o)});var o;const i=r();return n.add(i),i.then(()=>e(i),()=>e(i)),i},drain:function(t){if(!n.size)return e=!0,new Jt(t=>{t(e)});var e;const r=Promise.allSettled(Array.from(n)).then(()=>!0);if(!t)return r;const o=[r,new Promise(n=>{return"object"==typeof(e=setTimeout(()=>n(!1),t))&&"function"==typeof e.unref&&e.unref(),e;var e})];return Promise.race(o)}}}function Ht(t,{statusCode:n,headers:e},r=P()){const o={...t},i=e?.["x-sentry-rate-limits"],s=e?.["retry-after"];if(i)for(const t of i.trim().split(",")){const[n,e,,,i]=t.split(":",5),s=parseInt(n,10),c=1e3*(isNaN(s)?60:s);if(e)for(const t of e.split(";"))"metric_bucket"===t&&i&&!i.split(";").includes("custom")||(o[t]=r+c);else o.all=r+c}else s?o.all=r+function(t,n=P()){const e=parseInt(`${t}`,10);if(!isNaN(e))return 1e3*e;const r=Date.parse(`${t}`);return isNaN(r)?6e4:r-n}(s,r):429===n&&(o.all=r+6e4);return o}function Kt(t,n,e=Yt(t.bufferSize||64)){let r={};return{send:function(t){const o=[];if(kt(t,(t,n)=>{const e=Bt(n);(function(t,n,e=P()){return function(t,n){return t[n]||t.all||0}(t,n)>e})(r,e)||o.push(t)}),0===o.length)return Promise.resolve({});const i=Tt(t[0],o),s=t=>{!function(t,n){return kt(t,(t,e)=>n.includes(e))}(i,["client_report"])?kt(i,(t,n)=>{}):h&&w.warn(`Dropping client report. Will not send outcomes (reason: ${t}).`)};return e.add(()=>n({body:Dt(i)}).then(t=>413===t.statusCode?(h&&w.error("Sentry responded with status code 413. Envelope was discarded due to exceeding size limits."),s("send_error"),t):(h&&void 0!==t.statusCode&&(t.statusCode<200||t.statusCode>=300)&&w.warn(`Sentry responded with status code ${t.statusCode} to sent event.`),r=Ht(r,t),t),t=>{throw s("network_error"),h&&w.error("Encountered error running transport request:",t),t})).then(t=>t,t=>{if(t===Wt)return h&&w.error("Skipped sending event because buffer is full."),s("queue_overflow"),Promise.resolve({});throw t})},flush:t=>e.drain(t)}}const Zt=/^(\S+:\\|\/?)([\s\S]*?)((?:\.{1,2}|[^/\\]+?|)(\.[^./\\]*|))(?:[/\\]*)$/;function qt(t){const n=function(t){const n=t.length>1024?`<truncated>${t.slice(-1024)}`:t,e=Zt.exec(n);return e?e.slice(1):[]}(t),e=n[0]||"";let r=n[1];return e||r?(r&&(r=r.slice(0,r.length-1)),e+r):"."}function Vt(t,n=!1){return!(n||t&&!t.startsWith("/")&&!t.match(/^[A-Z]:/)&&!t.startsWith(".")&&!t.match(/^[a-zA-Z]([a-zA-Z0-9.\-+])*:\/\//))&&void 0!==t&&!t.includes("node_modules/")}var Qt;const Xt=Symbol("AgentBaseInternalState");class tn extends(Qt=i.Agent,Qt){constructor(t){super(t),this[Xt]={}}isSecureEndpoint(t){if(t){if("boolean"==typeof t.secureEndpoint)return t.secureEndpoint;if("string"==typeof t.protocol)return"https:"===t.protocol}const{stack:n}=new Error;return"string"==typeof n&&n.split("\n").some(t=>-1!==t.indexOf("(https.js:")||-1!==t.indexOf("node:https:"))}createSocket(t,n,e){const r={...n,secureEndpoint:this.isSecureEndpoint(n)};Promise.resolve().then(()=>this.connect(t,r)).then(o=>{if(o instanceof i.Agent)return o.addRequest(t,r);this[Xt].currentSocket=o,super.createSocket(t,n,e)},e)}createConnection(){const t=this[Xt].currentSocket;if(this[Xt].currentSocket=void 0,!t)throw new Error("No socket was returned in the `connect()` function");return t}get defaultPort(){return this[Xt].defaultPort??("https:"===this.protocol?443:80)}set defaultPort(t){this[Xt]&&(this[Xt].defaultPort=t)}get protocol(){return this[Xt].protocol??(this.isSecureEndpoint()?"https:":"http:")}set protocol(t){this[Xt]&&(this[Xt].protocol=t)}}function nn(...t){w.log("[https-proxy-agent:parse-proxy-response]",...t)}function en(t){return new Promise((n,e)=>{let r=0;const o=[];function i(){const c=t.read();c?function(c){o.push(c),r+=c.length;const u=Buffer.concat(o,r),a=u.indexOf("\r\n\r\n");if(-1===a)return nn("have not received end of HTTP headers yet..."),void i();const f=u.subarray(0,a).toString("ascii").split("\r\n"),h=f.shift();if(!h)return t.destroy(),e(new Error("No header received from proxy CONNECT response"));const p=h.split(" "),d=+(p[1]||0),l=p.slice(2).join(" "),g={};for(const n of f){if(!n)continue;const r=n.indexOf(":");if(-1===r)return t.destroy(),e(new Error(`Invalid header from proxy CONNECT response: "${n}"`));const o=n.slice(0,r).toLowerCase(),i=n.slice(r+1).trimStart(),s=g[o];"string"==typeof s?g[o]=[s,i]:Array.isArray(s)?s.push(i):g[o]=i}nn("got proxy server response: %o %o",h,g),s(),n({connect:{statusCode:d,statusText:l,headers:g},buffered:u})}(c):t.once("readable",i)}function s(){t.removeListener("end",c),t.removeListener("error",u),t.removeListener("readable",i)}function c(){s(),nn("onend"),e(new Error("Proxy connection ended before receiving CONNECT response"))}function u(t){s(),nn("onerror %o",t),e(t)}t.on("error",u),t.on("end",c),i()})}function rn(...t){w.log("[https-proxy-agent]",...t)}class on extends tn{constructor(t,n){super(n),this.options={},this.proxy="string"==typeof t?new URL(t):t,this.proxyHeaders=n?.headers??{},rn("Creating new HttpsProxyAgent instance: %o",this.proxy.href);const e=(this.proxy.hostname||this.proxy.host).replace(/^\[|\]$/g,""),r=this.proxy.port?parseInt(this.proxy.port,10):"https:"===this.proxy.protocol?443:80;this.connectOpts={ALPNProtocols:["http/1.1"],...n?cn(n,"headers"):null,host:e,port:r}}async connect(t,n){const{proxy:e}=this;if(!n.host)throw new TypeError('No "host" provided');let r;if("https:"===e.protocol){rn("Creating `tls.Socket`: %o",this.connectOpts);const t=this.connectOpts.servername||this.connectOpts.host;r=f.connect({...this.connectOpts,servername:t&&a.isIP(t)?void 0:t})}else rn("Creating `net.Socket`: %o",this.connectOpts),r=a.connect(this.connectOpts);const o="function"==typeof this.proxyHeaders?this.proxyHeaders():{...this.proxyHeaders},i=a.isIPv6(n.host)?`[${n.host}]`:n.host;let s=`CONNECT ${i}:${n.port} HTTP/1.1\r\n`;if(e.username||e.password){const t=`${decodeURIComponent(e.username)}:${decodeURIComponent(e.password)}`;o["Proxy-Authorization"]=`Basic ${Buffer.from(t).toString("base64")}`}o.Host=`${i}:${n.port}`,o["Proxy-Connection"]||(o["Proxy-Connection"]=this.keepAlive?"Keep-Alive":"close");for(const t of Object.keys(o))s+=`${t}: ${o[t]}\r\n`;const c=en(r);r.write(`${s}\r\n`);const{connect:u,buffered:h}=await c;if(t.emit("proxyConnect",u),this.emit("proxyConnect",u,t),200===u.statusCode){if(t.once("socket",sn),n.secureEndpoint){rn("Upgrading socket connection to TLS");const t=n.servername||n.host;return f.connect({...cn(n,"host","path","port"),socket:r,servername:a.isIP(t)?void 0:t})}return r}r.destroy();const p=new a.Socket({writable:!1});return p.readable=!0,t.once("socket",t=>{rn("Replaying proxy buffer for failed request"),t.push(h),t.push(null)}),p}}function sn(t){t.resume()}function cn(t,...n){const e={};let r;for(r in t)n.includes(r)||(e[r]=t[r]);return e}on.protocols=["http","https"];function un(t){return t.replace(/^[A-Z]:/,"").replace(/\\/g,"/")}const an=n;let fn,hn=0,pn={};function dn(t){an.debug&&console.log(`[ANR Worker] ${t}`)}var ln,gn,mn;const yn=function(t){let n;try{n=new URL(t.url)}catch(n){return b(()=>{console.warn("[@sentry/node]: Invalid dsn or tunnel option, will not send any events. The tunnel option must be a full URL when used.")}),Kt(t,()=>Promise.resolve({}))}const e="https:"===n.protocol,r=function(t,n){const{no_proxy:e}=process.env,r=e?.split(",").some(n=>t.host.endsWith(n)||t.hostname.endsWith(n));return r?void 0:n}(n,t.proxy||(e?process.env.https_proxy:void 0)||process.env.http_proxy),o=e?s:i,a=void 0!==t.keepAlive&&t.keepAlive,f=r?new on(r):new o.Agent({keepAlive:a,maxSockets:30,timeout:2e3}),h=function(t,n,e){const{hostname:r,pathname:o,port:i,protocol:s,search:a}=new URL(t.url);return function(f){return new Promise((h,p)=>{Ft(()=>{let d=function(t){return new c({read(){this.push(t),this.push(null)}})}(f.body);const l={...t.headers};f.body.length>32768&&(l["content-encoding"]="gzip",d=d.pipe(u()));const g=r.startsWith("["),m=n.request({method:"POST",agent:e,headers:l,hostname:g?r.slice(1,-1):r,path:`${o}${a}`,port:i,protocol:s,ca:t.caCerts},t=>{t.on("data",()=>{}),t.on("end",()=>{}),t.setEncoding("utf8");const n=t.headers["retry-after"]??null,e=t.headers["x-sentry-rate-limits"]??null;h({statusCode:t.statusCode,headers:{"retry-after":n,"x-sentry-rate-limits":Array.isArray(e)?e[0]||null:e}})});m.on("error",p),d.pipe(m)})})}}(t,t.httpModule??o,f);return Kt(t,h)}({url:(ln=an.dsn,gn=an.tunnel,mn=an.sdkMetadata.sdk,gn||`${function(t){return`${function(t){const n=t.protocol?`${t.protocol}:`:"",e=t.port?`:${t.port}`:"";return`${n}//${t.host}${e}${t.path?`/${t.path}`:""}/api/`}(t)}${t.projectId}/envelope/`}(ln)}?${function(t,n){const e={sentry_version:"7"};return t.publicKey&&(e.sentry_key=t.publicKey),n&&(e.sentry_client=`${n.name}/${n.version}`),new URLSearchParams(e).toString()}(ln,mn)}`)});async function bn(){if(fn){dn("Sending abnormal session"),K(fn,{status:"abnormal",abnormal_mechanism:"anr_foreground",release:an.release,environment:an.environment});const t=function(t,n,e,r){const o=Lt(e);return Tt({sent_at:new Date(P()).toISOString(),...o&&{sdk:o},...!!r&&n&&{dsn:bt(n)}},["aggregates"in t?[{type:"sessions"},t]:[{type:"session"},t.toJSON()]])}(fn,an.dsn,an.sdkMetadata,an.tunnel);dn(JSON.stringify(t)),await yn.send(t);try{e?.postMessage("session-ended")}catch{}}}function vn(t){if(!t)return;const n=function(t){if(!t.length)return[];const n=Array.from(t);return/sentryWrapped/.test(E(n).function||"")&&n.pop(),n.reverse(),$.test(E(n).function||"")&&(n.pop(),$.test(E(n).function||"")&&n.pop()),n.slice(0,50).map(t=>({...t,filename:t.filename||E(n).filename,function:t.function||"?"}))}(t);if(an.appRootPath)for(const t of n)t.filename&&(t.filename=M(t.filename,an.appRootPath));return n}async function _n(t,n){if(hn>=an.maxAnrEvents)return;hn+=1,await bn(),dn("Sending event");const e={event_id:G(),contexts:an.contexts,release:an.release,environment:an.environment,dist:an.dist,platform:"node",level:"error",exception:{values:[{type:"ApplicationNotResponding",value:`Application Not Responding for at least ${an.anrThreshold} ms`,stacktrace:{frames:vn(t)},mechanism:{type:"ANR"}}]},tags:an.staticTags};n&&function(t,n){if(Gt(t,n),!t.contexts?.trace){const{traceId:e,parentSpanId:r,propagationSpanId:o}=n.propagationContext;t.contexts={trace:{trace_id:e,span_id:o||V(),parent_span_id:r},...t.contexts}}}(e,n),function(t){if(0===Object.keys(pn).length)return;const n=an.appRootPath?{}:pn;if(an.appRootPath)for(const[t,e]of Object.entries(pn))n[M(t,an.appRootPath)]=e;const e=new Map;for(const r of t.exception?.values||[])for(const t of r.stacktrace?.frames||[]){const r=t.abs_path||t.filename;r&&n[r]&&e.set(r,n[r])}if(e.size>0){const n=[];for(const[t,r]of e.entries())n.push({type:"sourcemap",code_file:t,debug_id:r});t.debug_meta={images:n}}}(e);const r=Mt(e,an.dsn,an.sdkMetadata,an.tunnel);dn(JSON.stringify(r)),await yn.send(r),await yn.flush(2e3),hn>=an.maxAnrEvents&&setTimeout(()=>{process.exit(0)},5e3)}let Sn;if(dn("Started"),an.captureStackTrace){dn("Connecting to debugger");const n=new t;n.connectToMainThread(),dn("Connected to debugger");const e=new Map;n.on("Debugger.scriptParsed",t=>{e.set(t.params.scriptId,t.params.url)}),n.on("Debugger.paused",t=>{if("other"===t.params.reason)try{dn("Debugger paused");const i=[...t.params.callFrames],s=an.appRootPath?function(t=(process.argv[1]?qt(process.argv[1]):process.cwd()),n="\\"===o){const e=n?un(t):t;return t=>{if(!t)return;const o=n?un(t):t;let{dir:i,base:s,ext:c}=r.parse(o);".js"!==c&&".mjs"!==c&&".cjs"!==c||(s=s.slice(0,-1*c.length));const u=decodeURIComponent(s);i||(i=".");const a=i.lastIndexOf("/node_modules");if(a>-1)return`${i.slice(a+14).replace(/\//g,".")}:${u}`;if(i.startsWith(e)){const t=i.slice(e.length+1).replace(/\//g,".");return t?`${t}:${u}`:u}return u}}(an.appRootPath):()=>{},c=i.map(t=>function(t,n,e){const r=n?n.replace(/^file:\/\//,""):void 0,o=t.location.columnNumber?t.location.columnNumber+1:void 0,i=t.location.lineNumber?t.location.lineNumber+1:void 0;return{filename:r,module:e(r),function:t.functionName||"?",colno:o,lineno:i,in_app:r?Vt(r):void 0}}(t,e.get(t.location.scriptId),s)),u=setTimeout(()=>{_n(c).then(null,()=>{dn("Sending ANR event failed.")})},5e3);n.post("Runtime.evaluate",{expression:"global.__SENTRY_GET_SCOPES__();",silent:!0,returnByValue:!0},(t,e)=>{t&&dn(`Error executing script: '${t.message}'`),clearTimeout(u);const r=e?.result?e.result.value:void 0;n.post("Debugger.resume"),n.post("Debugger.disable"),_n(c,r).then(null,()=>{dn("Sending ANR event failed.")})})}catch(t){throw n.post("Debugger.resume"),n.post("Debugger.disable"),t}}),Sn=()=>{try{n.post("Debugger.enable",()=>{n.post("Debugger.pause")})}catch{}}}const{poll:wn}=function(t,n,e,r){const o=t();let i=!1,s=!0;return setInterval(()=>{const t=o.getTimeMs();!1===i&&t>n+e&&(i=!0,s&&r()),t<n+e&&(i=!1)},20),{poll:()=>{o.reset()},enabled:t=>{s=t}}}(function(){let t=process.hrtime();return{getTimeMs:()=>{const[n,e]=process.hrtime(t);return Math.floor(1e3*n+e/1e6)},reset:()=>{t=process.hrtime()}}},an.pollInterval,an.anrThreshold,function(){dn("Watchdog timeout"),Sn?(dn("Pausing debugger to capture stack trace"),Sn()):(dn("Capturing event without a stack trace"),_n().then(null,()=>{dn("Sending ANR event failed on watchdog timeout.")}))});e?.on("message",t=>{t.session&&(fn=H(t.session)),t.debugImages&&(pn=t.debugImages),wn()});
/*! @sentry/node-core 10.65.0 (c66a815) | https://github.com/getsentry/sentry-javascript */
import{Session as t}from"node:inspector";import{workerData as n,parentPort as e}from"node:worker_threads";import{posix as r,sep as o}from"node:path";import*as i from"node:http";import*as s from"node:https";import{Readable as c}from"node:stream";import{createGzip as u}from"node:zlib";import*as a from"node:net";import*as f from"node:tls";const h="undefined"==typeof __SENTRY_DEBUG__||__SENTRY_DEBUG__,p=globalThis,d="10.65.0";function l(){return g(p),p}function g(t){const n=t.__SENTRY__=t.__SENTRY__||{};return n.version=n.version||d,n[d]=n[d]||{}}function m(t,n,e=p){const r=e.__SENTRY__=e.__SENTRY__||{},o=r[d]=r[d]||{};return o[t]||(o[t]=n())}const y={};function b(t){if(!("console"in p))return t();const n=p.console,e={},r=Object.keys(y);r.forEach(t=>{const r=y[t];e[t]=n[t],n[t]=r});try{return t()}finally{r.forEach(t=>{n[t]=e[t]})}}function v(){return S().enabled}function _(t,...n){h&&v()&&b(()=>{p.console[t](`Sentry Logger [${t}]:`,...n)})}function S(){return h?m("loggerSettings",()=>({enabled:!1})):{enabled:!1}}const w={enable:function(){S().enabled=!0},disable:function(){S().enabled=!1},isEnabled:v,log:function(...t){_("log",...t)},warn:function(...t){_("warn",...t)},error:function(...t){_("error",...t)}},$=/captureMessage|captureException/;function E(t){return t[t.length-1]||{}}const x="<anonymous>";const N=Object.prototype.toString;function C(t,n){return N.call(t)===`[object ${n}]`}function j(t){return Boolean(t?.then&&"function"==typeof t.then)}function R(t,n){try{return t instanceof n}catch{return!1}}function A(t){if(function(t){switch(N.call(t)){case"[object Error]":case"[object Exception]":case"[object DOMException]":case"[object WebAssembly.Exception]":return!0;default:return R(t,Error)}}(t))return{message:t.message,name:t.name,stack:t.stack,...I(t)};if(n=t,"undefined"!=typeof Event&&R(n,Event)){const{type:n,target:e,currentTarget:r,detail:o}=t;return{type:n,target:e,currentTarget:r,...o?{detail:o}:{},...I(t)}}var n;return t}function I(t){return"object"==typeof(n=t)&&null!==n?Object.fromEntries(Object.entries(t)):{};var n}let O;function T(t){if(void 0!==O)return O?O(t):t();const n=Symbol.for("__SENTRY_SAFE_RANDOM_ID_WRAPPER__"),e=p;return n in e&&"function"==typeof e[n]?(O=e[n],O(t)):(O=null,t())}function k(){return T(()=>Math.random())}function P(){return T(()=>Date.now())}const D=Symbol.for("sentry.skipNormalization"),U=Symbol.for("sentry.overrideNormalizationDepth");function B(t,n=100,e=1/0){try{return L("",t,n,e)}catch(t){return{ERROR:`**non-serializable** (${t})`}}}function L(t,n,e=1/0,r=1/0,o=function(){const t=new WeakSet;function n(n){return!!t.has(n)||(t.add(n),!1)}function e(n){t.delete(n)}return[n,e]}()){const[i,s]=o;if(null==n||["boolean","string"].includes(typeof n)||"number"==typeof n&&Number.isFinite(n))return n;const c=function(t,n){try{if("undefined"!=typeof global&&n===global)return"[Global]";if("number"==typeof n&&!Number.isFinite(n))return`[${n}]`;if("function"==typeof n)return`[Function: ${function(t){try{return t&&"function"==typeof t&&t.name||x}catch{return x}}(n)}]`;if("symbol"==typeof n)return`[${String(n)}]`;if("bigint"==typeof n)return`[BigInt: ${String(n)}]`;const t=function(t){const n=Object.getPrototypeOf(t);return n?.constructor?n.constructor.name:"null prototype"}(n);return`[object ${t}]`}catch(t){return`**non-serializable** (${t})`}}(0,n);if(!c.startsWith("[object "))return c;if(function(t){return Boolean(t[D])}(n))return n;const u=function(t){const n=t[U];return"number"==typeof n?n:void 0}(n),a=void 0!==u?u:e;if(0===a)return c.replace("object ","");if(i(n))return"[Circular ~]";const f=n;if(f&&"function"==typeof f.toJSON)try{return L("",f.toJSON(),a-1,r,o)}catch{}const h=Array.isArray(n)?[]:{};let p=0;const d=A(n);for(const t in d){if(!Object.prototype.hasOwnProperty.call(d,t))continue;if(p>=r){h[t]="[MaxProperties ~]";break}const n=d[t];h[t]=L(t,n,a-1,r,o),p++}return s(n),h}function M(t,n){const e=n.replace(/\\/g,"/").replace(/[|\\{}()[\]^$+*?.]/g,"\\$&");let r=t;try{r=decodeURI(t)}catch{}return r.replace(/\\/g,"/").replace(/webpack:\/?/g,"").replace(new RegExp(`(file://)?/*${e}/*`,"ig"),"app:///")}function z(t,n=0){return"string"!=typeof t||0===n||t.length<=n?t:`${t.slice(0,n)}...`}let F;function G(t=function(){const t=p;return t.crypto||t.msCrypto}()){try{if(t?.randomUUID)return T(()=>t.randomUUID()).replace(/-/g,"")}catch{}return F||(F="10000000100040008000100000000000"),F.replace(/[018]/g,t=>(t^(16*k()&15)>>t/4).toString(16))}function J(){return P()/1e3}let W;function Y(){return(W??(W=function(){const{performance:t}=p;if(!t?.now||!t.timeOrigin)return J;const n=t.timeOrigin;return()=>(n+T(()=>t.now()))/1e3}()))()}function H(t){const n=Y(),e={sid:G(),init:!0,timestamp:n,started:n,duration:0,status:"ok",errors:0,ignoreDuration:!1,toJSON:()=>function(t){return{sid:`${t.sid}`,init:t.init,started:new Date(1e3*t.started).toISOString(),timestamp:new Date(1e3*t.timestamp).toISOString(),status:t.status,errors:t.errors,did:"number"==typeof t.did||"string"==typeof t.did?`${t.did}`:void 0,duration:t.duration,abnormal_mechanism:t.abnormal_mechanism,attrs:{release:t.release,environment:t.environment,ip_address:t.ipAddress,user_agent:t.userAgent}}}(e)};return t&&K(e,t),e}function K(t,n={}){if(n.user&&(!t.ipAddress&&n.user.ip_address&&(t.ipAddress=n.user.ip_address),t.did||n.did||(t.did=n.user.id||n.user.email||n.user.username)),t.timestamp=n.timestamp||Y(),n.abnormal_mechanism&&(t.abnormal_mechanism=n.abnormal_mechanism),n.ignoreDuration&&(t.ignoreDuration=n.ignoreDuration),n.sid&&(t.sid=32===n.sid.length?n.sid:G()),void 0!==n.init&&(t.init=n.init),!t.did&&n.did&&(t.did=`${n.did}`),"number"==typeof n.started&&(t.started=n.started),t.ignoreDuration)t.duration=void 0;else if("number"==typeof n.duration)t.duration=n.duration;else{const n=t.timestamp-t.started;t.duration=n>=0?n:0}n.release&&(t.release=n.release),n.environment&&(t.environment=n.environment),!t.ipAddress&&n.ipAddress&&(t.ipAddress=n.ipAddress),!t.userAgent&&n.userAgent&&(t.userAgent=n.userAgent),"number"==typeof n.errors&&(t.errors=n.errors),n.status&&(t.status=n.status)}function Z(t,n,e=2){if(!n||"object"!=typeof n||e<=0)return n;if(t&&0===Object.keys(n).length)return t;const r={...t};for(const t in n)Object.prototype.hasOwnProperty.call(n,t)&&(r[t]=Z(r[t],n[t],e-1));return r}function q(){return G()}function V(){return G().substring(16)}function Q(t){if(t){if("object"==typeof t&&"deref"in t&&"function"==typeof t.deref)try{return t.deref()}catch{return}return t}}const X="_sentrySpan";function tt(t,n){n?function(t,n,e){try{Object.defineProperty(t,n,{value:e,writable:!0,configurable:!0})}catch{h&&w.log(`Failed to add non-enumerable property "${String(n)}" to object`,t)}}(t,X,function(t){try{const n=p.WeakRef;if("function"==typeof n)return new n(t)}catch{}return t}(n)):delete t[X]}function nt(t){return Q(t[X])}class et{constructor(){this.t=!1,this.o=[],this.i=[],this.u=[],this.h=[],this.p={},this.l={},this.m={},this.v={},this._={},this.S={},this.N={traceId:q(),sampleRand:k()}}clone(){const t=new et;return t.u=[...this.u],t.l={...this.l},t.m={...this.m},t.v={...this.v},t._={...this._},this._.flags&&(t._.flags={values:[...this._.flags.values]}),t.p=this.p,t.C=this.C,t.j=this.j,t.R=this.R,t.A=this.A,t.i=[...this.i],t.h=[...this.h],t.S={...this.S},t.N={...this.N},t.I=this.I,t.O=this.O,t.T=this.T,tt(t,nt(this)),t}setClient(t){this.I=t}setLastEventId(t){this.O=t}getClient(){return this.I}lastEventId(){return this.O}addScopeListener(t){this.o.push(t)}addEventProcessor(t){return this.i.push(t),this}setUser(t){return this.p=t||{email:void 0,id:void 0,ip_address:void 0,username:void 0},this.j&&K(this.j,{user:t}),this.k(),this}getUser(){return this.p}setConversationId(t){return this.T=t||void 0,this.k(),this}setTags(t){return this.l={...this.l,...t},this.k(),this}setTag(t,n){return this.setTags({[t]:n})}setAttributes(t){return this.m={...this.m,...t},this.k(),this}setAttribute(t,n){return this.setAttributes({[t]:n})}removeAttribute(t){return t in this.m&&(delete this.m[t],this.k()),this}setExtras(t){return this.v={...this.v,...t},this.k(),this}setExtra(t,n){return this.v={...this.v,[t]:n},this.k(),this}setFingerprint(t){return this.A=t,this.k(),this}setLevel(t){return this.C=t,this.k(),this}setTransactionName(t){return this.R=t,this.k(),this}setContext(t,n){return null===n?delete this._[t]:this._[t]=n,this.k(),this}setSession(t){return t?this.j=t:delete this.j,this.k(),this}getSession(){return this.j}update(t){if(!t)return this;const n="function"==typeof t?t(this):t,e=n instanceof et?n.getScopeData():C(n,"Object")?t:void 0;const{tags:r,attributes:o,extra:i,user:s,contexts:c,level:u,fingerprint:a=[],propagationContext:f,conversationId:h}=e||{};return this.l={...this.l,...r},this.m={...this.m,...o},this.v={...this.v,...i},this._={...this._,...c},s&&Object.keys(s).length&&(this.p=s),u&&(this.C=u),a.length&&(this.A=a),f&&(this.N=f),h&&(this.T=h),this}clear(){return this.u=[],this.l={},this.m={},this.v={},this.p={},this._={},this.C=void 0,this.R=void 0,this.A=void 0,this.j=void 0,this.T=void 0,tt(this,void 0),this.h=[],this.setPropagationContext({traceId:q(),sampleRand:k()}),this.k(),this}addBreadcrumb(t,n){const e="number"==typeof n?n:100;if(e<=0)return this;const r={timestamp:J(),...t,message:t.message?z(t.message,2048):t.message};return this.u.push(r),this.u.length>e&&(this.u=this.u.slice(-e),this.I?.recordDroppedEvent("buffer_overflow","log_item")),this.k(),this}getLastBreadcrumb(){return this.u[this.u.length-1]}clearBreadcrumbs(){return this.u=[],this.k(),this}addAttachment(t){return this.h.push(t),this}clearAttachments(){return this.h=[],this}getScopeData(){return{breadcrumbs:this.u,attachments:this.h,contexts:this._,tags:this.l,attributes:this.m,extra:this.v,user:this.p,level:this.C,fingerprint:this.A||[],eventProcessors:this.i,propagationContext:this.N,sdkProcessingMetadata:this.S,transactionName:this.R,span:nt(this),conversationId:this.T}}setSDKProcessingMetadata(t){return this.S=Z(this.S,t,2),this}setPropagationContext(t){return this.N=t,this}getPropagationContext(){return this.N}captureException(t,n){const e=n?.event_id||G();if(!this.I)return h&&w.warn("No client configured on scope - will not capture exception!"),e;const r=new Error("Sentry syntheticException");return this.I.captureException(t,{originalException:t,syntheticException:r,...n,event_id:e},this),e}captureMessage(t,n,e){const r=e?.event_id||G();if(!this.I)return h&&w.warn("No client configured on scope - will not capture message!"),r;const o=e?.syntheticException??new Error(t);return this.I.captureMessage(t,n,{originalException:t,syntheticException:o,...e,event_id:r},this),r}captureEvent(t,n){const e=t.event_id||n?.event_id||G();return this.I?(this.I.captureEvent(t,{...n,event_id:e},this),e):(h&&w.warn("No client configured on scope - will not capture event!"),e)}k(){this.t||(this.t=!0,this.o.forEach(t=>{t(this)}),this.t=!1)}}const rt=t=>t instanceof Promise&&!t[ot],ot=Symbol("chained PromiseLike"),it=(t,n)=>{if(!n)return t;let e=!1;for(const r in t){if(r in n)continue;e=!0;const o=t[r];"function"==typeof o?Object.defineProperty(n,r,{value:(...n)=>o.apply(t,n),enumerable:!0,configurable:!0,writable:!0}):n[r]=o}return e&&Object.assign(n,{[ot]:!0}),n};class st{constructor(t,n){let e,r;e=t||new et,r=n||new et,this.P=[{scope:e}],this.D=r}withScope(t){const n=this.U();let e;try{e=t(n)}catch(t){throw this.B(),t}return j(e)?((t,n,e)=>{const r=t.then(t=>(n(t),t),t=>{throw e(t),t});return rt(r)&&rt(t)?r:it(t,r)})(e,()=>this.B(),()=>this.B()):(this.B(),e)}getClient(){return this.getStackTop().client}getScope(){return this.getStackTop().scope}getIsolationScope(){return this.D}getStackTop(){return this.P[this.P.length-1]}U(){const t=this.getScope().clone();return this.P.push({client:this.getClient(),scope:t}),t}B(){return!(this.P.length<=1)&&!!this.P.pop()}}function ct(){const t=g(l());return t.stack=t.stack||new st(m("defaultCurrentScope",()=>new et),m("defaultIsolationScope",()=>new et))}function ut(t){return ct().withScope(t)}function at(t,n){const e=ct();return e.withScope(()=>(e.getStackTop().scope=t,n(t)))}function ft(t){return ct().withScope(()=>t(ct().getIsolationScope()))}function ht(t){const n=g(t);return n.acs?n.acs:{withIsolationScope:ft,withScope:ut,withSetScope:at,withSetIsolationScope:(t,n)=>ft(n),getCurrentScope:()=>ct().getScope(),getIsolationScope:()=>ct().getIsolationScope()}}function pt(){return ht(l()).getCurrentScope().getClient()}function dt(t){const n=t;return{scope:n._sentryScope,isolationScope:Q(n._sentryIsolationScope)}}const lt="sentry-";function gt(t){const n=function(t){if(!t||(n=t,!C(n,"String")&&!Array.isArray(t)))return;var n;if(Array.isArray(t))return t.reduce((t,n)=>{const e=mt(n);return Object.entries(e).forEach(([n,e])=>{t[n]=e}),t},{});return mt(t)}(t);if(!n)return;const e=Object.entries(n).reduce((t,[n,e])=>{if(n.startsWith(lt)){t[n.slice(7)]=e}return t},{});return Object.keys(e).length>0?e:void 0}function mt(t){return t.split(",").map(t=>{const n=t.indexOf("=");if(-1===n)return[];return[t.slice(0,n),t.slice(n+1)].map(t=>{try{return decodeURIComponent(t.trim())}catch{return}})}).reduce((t,[n,e])=>(n&&e&&(t[n]=e),t),{})}const yt=/^o(\d+)\./;function bt(t,n=!1){const{host:e,path:r,pass:o,port:i,projectId:s,protocol:c,publicKey:u}=t;return`${c}://${u}${n&&o?`:${o}`:""}@${e}${i?`:${i}`:""}/${r?`${r}/`:r}${s}`}function vt(t){const n=t.getOptions(),{host:e}=t.getDsn()||{};let r;return n.orgId?r=String(n.orgId):e&&(r=function(t){const n=t.match(yt);return n?.[1]}(e)),r}function _t(t){const{spanId:n,traceId:e,isRemote:r}=t.spanContext(),o=r?n:Et(t).parent_span_id,i=dt(t).scope;return{parent_span_id:o,span_id:r?i?.getPropagationContext().propagationSpanId||V():n,trace_id:e}}function St(t){return t&&t.length>0?t.map(({context:{spanId:t,traceId:n,traceFlags:e,...r},attributes:o})=>({span_id:t,trace_id:n,sampled:1===e,attributes:o,...r})):void 0}function wt(t){return"number"==typeof t?$t(t):Array.isArray(t)?t[0]+t[1]/1e9:t instanceof Date?$t(t.getTime()):Y()}function $t(t){return t>9999999999?t/1e3:t}function Et(t){if(function(t){return"function"==typeof t.getSpanJSON}(t))return t.getSpanJSON();const{spanId:n,traceId:e}=t.spanContext();if(function(t){const n=t;return!!(n.attributes&&n.startTime&&n.name&&n.endTime&&n.status)}(t)){const{attributes:r,startTime:o,name:i,endTime:s,status:c,links:u}=t;return{span_id:n,trace_id:e,data:r,description:i,parent_span_id:xt(t),start_timestamp:wt(o),timestamp:wt(s)||void 0,status:Nt(c),op:r["sentry.op"],origin:r["sentry.origin"],links:St(u)}}return{span_id:n,trace_id:e,start_timestamp:0,data:{}}}function xt(t){return"parentSpanId"in t?t.parentSpanId:"parentSpanContext"in t?t.parentSpanContext?.spanId:void 0}function Nt(t){if(t&&0!==t.code)return 1===t.code?"ok":t.message||"internal_error"}const Ct=function(t){return t._sentryRootSpan||t};function jt(t){if("boolean"==typeof __SENTRY_TRACING__&&!__SENTRY_TRACING__)return!1;const n=t||pt()?.getOptions();return!(!n||null==n.tracesSampleRate&&!n.tracesSampler)}const Rt=Symbol.for("sentry.nonRecordingSpan");function At(t,n){const e=n.getOptions(),{publicKey:r}=n.getDsn()||{},o={environment:e.environment||"production",release:e.release,public_key:r,trace_id:t,org_id:vt(n)};return n.emit("createDsc",o),o}function It(t,n){const e=n.getPropagationContext();return e.dsc||At(e.traceId,t)}function Ot(t){const n=pt();if(!n)return{};const e=Ct(t),r=Et(e),o=r.data,i=e.spanContext().traceState,s=i?.get("sentry.sample_rate")??o["sentry.sample_rate"]??o["sentry.previous_trace_sample_rate"];function c(t){return"number"!=typeof s&&"string"!=typeof s||(t.sample_rate=`${s}`),t}const u=e._frozenDsc;if(u)return c(u);if(function(t){return!!t&&!0===t[Rt]}(e)&&!jt(n.getOptions())){const t=dt(e).scope;if(t)return c({...It(n,t)})}const a=i?.get("sentry.dsc"),f=a&&gt(a);if(f)return c(f);const h=At(t.spanContext().traceId,n),p=o["sentry.source"]??o["sentry.span.source"],d=r.description;return"url"!==p&&d&&(h.transaction=d),jt()&&(h.sampled=String(function(t){const{traceFlags:n}=t.spanContext();return 1===n}(e)),h.sample_rand=i?.get("sentry.sample_rand")??dt(e).scope?.getPropagationContext().sampleRand.toString()),c(h),n.emit("createDsc",h,e),h}function Tt(t,n=[]){return[t,n]}function kt(t,n){const e=t[1];for(const t of e){if(n(t,t[0].type))return!0}return!1}function Pt(t){const n=g(p);return n.encodePolyfill?n.encodePolyfill(t):(new TextEncoder).encode(t)}function Dt(t){const[n,e]=t;let r=JSON.stringify(n);function o(t){"string"==typeof r?r="string"==typeof t?r+t:[Pt(r),t]:r.push("string"==typeof t?Pt(t):t)}for(const t of e){const[n,e]=t;if(o(`\n${JSON.stringify(n)}\n`),"string"==typeof e||e instanceof Uint8Array)o(e);else{let t;try{t=JSON.stringify(e)}catch{t=JSON.stringify(B(e))}o(t)}}return"string"==typeof r?r:function(t){const n=t.reduce((t,n)=>t+n.length,0),e=new Uint8Array(n);let r=0;for(const n of t)e.set(n,r),r+=n.length;return e}(r)}const Ut={sessions:"session",event:"error",client_report:"internal",user_report:"default",profile_chunk:"profile",replay_event:"replay",replay_recording:"replay",check_in:"monitor",raw_security:"security",log:"log_item",trace_metric:"metric"};function Bt(t){return function(t){return t in Ut}(t)?Ut[t]:t}function Lt(t){if(!t?.sdk)return;const{name:n,version:e}=t.sdk;return{name:n,version:e}}function Mt(t,n,e,r){const o=Lt(e),i=t.type&&"replay_event"!==t.type?t.type:"event";!function(t,n){if(!n)return t;const e=t.sdk||{};t.sdk={...e,name:e.name||n.name,version:e.version||n.version,integrations:[...t.sdk?.integrations||[],...n.integrations||[]],packages:[...t.sdk?.packages||[],...n.packages||[]],settings:t.sdk?.settings||n.settings?{...t.sdk?.settings,...n.settings}:void 0}}(t,e?.sdk);const s=function(t,n,e,r){const o=t.sdkProcessingMetadata?.dynamicSamplingContext;return{event_id:t.event_id,sent_at:new Date(P()).toISOString(),...n&&{sdk:n},...!!e&&r&&{dsn:bt(r)},...o&&{trace:o}}}(t,o,r,n);delete t.sdkProcessingMetadata;return Tt(s,[[{type:i},t]])}const zt="__SENTRY_SUPPRESS_TRACING__";function Ft(t){const n=ht(l());return n.suppressTracing?n.suppressTracing(t):function(...t){const n=ht(l());if(2===t.length){const[e,r]=t;return e?n.withSetScope(e,r):n.withScope(r)}return n.withScope(t[0])}(n=>{n.setSDKProcessingMetadata({[zt]:!0});const e=t();return n.setSDKProcessingMetadata({[zt]:void 0}),e})}function Gt(t,n){const{fingerprint:e,span:r,breadcrumbs:o,sdkProcessingMetadata:i}=n;!function(t,n){const{extra:e,tags:r,user:o,contexts:i,level:s,transactionName:c}=n;Object.keys(e).length&&(t.extra={...e,...t.extra});Object.keys(r).length&&(t.tags={...r,...t.tags});Object.keys(o).length&&(t.user={...o,...t.user});Object.keys(i).length&&(t.contexts={...i,...t.contexts});s&&(t.level=s);c&&"transaction"!==t.type&&(t.transaction=c)}(t,n),r&&function(t,n){t.contexts={trace:_t(n),...t.contexts},t.sdkProcessingMetadata={dynamicSamplingContext:Ot(n),...t.sdkProcessingMetadata};const e=Ct(n),r=Et(e).description;r&&!t.transaction&&"transaction"===t.type&&(t.transaction=r)}(t,r),function(t,n){t.fingerprint=t.fingerprint?Array.isArray(t.fingerprint)?t.fingerprint:[t.fingerprint]:[],n&&(t.fingerprint=t.fingerprint.concat(n));t.fingerprint.length||delete t.fingerprint}(t,e),function(t,n){const e=[...t.breadcrumbs||[],...n];t.breadcrumbs=e.length?e:void 0}(t,o),function(t,n){t.sdkProcessingMetadata={...t.sdkProcessingMetadata,...n}}(t,i)}class Jt{constructor(t){this.L=0,this.M=[],this.F(t)}then(t,n){return new Jt((e,r)=>{this.M.push([!1,n=>{if(t)try{e(t(n))}catch(t){r(t)}else e(n)},t=>{if(n)try{e(n(t))}catch(t){r(t)}else r(t)}]),this.G()})}catch(t){return this.then(t=>t,t)}finally(t){return new Jt((n,e)=>{let r,o;return this.then(n=>{o=!1,r=n,t&&t()},n=>{o=!0,r=n,t&&t()}).then(()=>{o?e(r):n(r)})})}G(){if(0===this.L)return;const t=this.M.slice();this.M=[],t.forEach(t=>{t[0]||(1===this.L&&t[1](this.J),2===this.L&&t[2](this.J),t[0]=!0)})}F(t){const n=(t,n)=>{0===this.L&&(j(n)?n.then(e,r):(this.L=t,this.J=n,this.G()))},e=t=>{n(1,t)},r=t=>{n(2,t)};try{t(e,r)}catch(t){r(t)}}}const Wt=Symbol.for("SentryBufferFullError");function Yt(t=100){const n=new Set;function e(t){n.delete(t)}return{get $(){return Array.from(n)},add:function(r){if(!(n.size<t))return o=Wt,new Jt((t,n)=>{n(o)});var o;const i=r();return n.add(i),i.then(()=>e(i),()=>e(i)),i},drain:function(t){if(!n.size)return e=!0,new Jt(t=>{t(e)});var e;const r=Promise.allSettled(Array.from(n)).then(()=>!0);if(!t)return r;const o=[r,new Promise(n=>{return"object"==typeof(e=setTimeout(()=>n(!1),t))&&"function"==typeof e.unref&&e.unref(),e;var e})];return Promise.race(o)}}}function Ht(t,{statusCode:n,headers:e},r=P()){const o={...t},i=e?.["x-sentry-rate-limits"],s=e?.["retry-after"];if(i)for(const t of i.trim().split(",")){const[n,e,,,i]=t.split(":",5),s=parseInt(n,10),c=1e3*(isNaN(s)?60:s);if(e)for(const t of e.split(";"))"metric_bucket"===t&&i&&!i.split(";").includes("custom")||(o[t]=r+c);else o.all=r+c}else s?o.all=r+function(t,n=P()){const e=parseInt(`${t}`,10);if(!isNaN(e))return 1e3*e;const r=Date.parse(`${t}`);return isNaN(r)?6e4:r-n}(s,r):429===n&&(o.all=r+6e4);return o}function Kt(t,n,e=Yt(t.bufferSize||64)){let r={};return{send:function(t){const o=[];if(kt(t,(t,n)=>{const e=Bt(n);(function(t,n,e=P()){return function(t,n){return t[n]||t.all||0}(t,n)>e})(r,e)||o.push(t)}),0===o.length)return Promise.resolve({});const i=Tt(t[0],o),s=t=>{!function(t,n){return kt(t,(t,e)=>n.includes(e))}(i,["client_report"])?kt(i,(t,n)=>{}):h&&w.warn(`Dropping client report. Will not send outcomes (reason: ${t}).`)};return e.add(()=>n({body:Dt(i)}).then(t=>413===t.statusCode?(h&&w.error("Sentry responded with status code 413. Envelope was discarded due to exceeding size limits."),s("send_error"),t):(h&&void 0!==t.statusCode&&(t.statusCode<200||t.statusCode>=300)&&w.warn(`Sentry responded with status code ${t.statusCode} to sent event.`),r=Ht(r,t),t),t=>{throw s("network_error"),h&&w.error("Encountered error running transport request:",t),t})).then(t=>t,t=>{if(t===Wt)return h&&w.error("Skipped sending event because buffer is full."),s("queue_overflow"),Promise.resolve({});throw t})},flush:t=>e.drain(t)}}const Zt=/^(\S+:\\|\/?)([\s\S]*?)((?:\.{1,2}|[^/\\]+?|)(\.[^./\\]*|))(?:[/\\]*)$/;function qt(t){const n=function(t){const n=t.length>1024?`<truncated>${t.slice(-1024)}`:t,e=Zt.exec(n);return e?e.slice(1):[]}(t),e=n[0]||"";let r=n[1];return e||r?(r&&(r=r.slice(0,r.length-1)),e+r):"."}function Vt(t,n=!1){return!(n||t&&!t.startsWith("/")&&!t.match(/^[A-Z]:/)&&!t.startsWith(".")&&!t.match(/^[a-zA-Z]([a-zA-Z0-9.\-+])*:\/\//))&&void 0!==t&&!t.includes("node_modules/")}var Qt;const Xt=Symbol("AgentBaseInternalState");class tn extends(Qt=i.Agent,Qt){constructor(t){super(t),this[Xt]={}}isSecureEndpoint(t){if(t){if("boolean"==typeof t.secureEndpoint)return t.secureEndpoint;if("string"==typeof t.protocol)return"https:"===t.protocol}const{stack:n}=new Error;return"string"==typeof n&&n.split("\n").some(t=>-1!==t.indexOf("(https.js:")||-1!==t.indexOf("node:https:"))}createSocket(t,n,e){const r={...n,secureEndpoint:this.isSecureEndpoint(n)};Promise.resolve().then(()=>this.connect(t,r)).then(o=>{if(o instanceof i.Agent)return o.addRequest(t,r);this[Xt].currentSocket=o,super.createSocket(t,n,e)},e)}createConnection(){const t=this[Xt].currentSocket;if(this[Xt].currentSocket=void 0,!t)throw new Error("No socket was returned in the `connect()` function");return t}get defaultPort(){return this[Xt].defaultPort??("https:"===this.protocol?443:80)}set defaultPort(t){this[Xt]&&(this[Xt].defaultPort=t)}get protocol(){return this[Xt].protocol??(this.isSecureEndpoint()?"https:":"http:")}set protocol(t){this[Xt]&&(this[Xt].protocol=t)}}function nn(...t){w.log("[https-proxy-agent:parse-proxy-response]",...t)}function en(t){return new Promise((n,e)=>{let r=0;const o=[];function i(){const c=t.read();c?function(c){o.push(c),r+=c.length;const u=Buffer.concat(o,r),a=u.indexOf("\r\n\r\n");if(-1===a)return nn("have not received end of HTTP headers yet..."),void i();const f=u.subarray(0,a).toString("ascii").split("\r\n"),h=f.shift();if(!h)return t.destroy(),e(new Error("No header received from proxy CONNECT response"));const p=h.split(" "),d=+(p[1]||0),l=p.slice(2).join(" "),g={};for(const n of f){if(!n)continue;const r=n.indexOf(":");if(-1===r)return t.destroy(),e(new Error(`Invalid header from proxy CONNECT response: "${n}"`));const o=n.slice(0,r).toLowerCase(),i=n.slice(r+1).trimStart(),s=g[o];"string"==typeof s?g[o]=[s,i]:Array.isArray(s)?s.push(i):g[o]=i}nn("got proxy server response: %o %o",h,g),s(),n({connect:{statusCode:d,statusText:l,headers:g},buffered:u})}(c):t.once("readable",i)}function s(){t.removeListener("end",c),t.removeListener("error",u),t.removeListener("readable",i)}function c(){s(),nn("onend"),e(new Error("Proxy connection ended before receiving CONNECT response"))}function u(t){s(),nn("onerror %o",t),e(t)}t.on("error",u),t.on("end",c),i()})}function rn(...t){w.log("[https-proxy-agent]",...t)}class on extends tn{constructor(t,n){super(n),this.options={},this.proxy="string"==typeof t?new URL(t):t,this.proxyHeaders=n?.headers??{},rn("Creating new HttpsProxyAgent instance: %o",this.proxy.href);const e=(this.proxy.hostname||this.proxy.host).replace(/^\[|\]$/g,""),r=this.proxy.port?parseInt(this.proxy.port,10):"https:"===this.proxy.protocol?443:80;this.connectOpts={ALPNProtocols:["http/1.1"],...n?cn(n,"headers"):null,host:e,port:r}}async connect(t,n){const{proxy:e}=this;if(!n.host)throw new TypeError('No "host" provided');let r;if("https:"===e.protocol){rn("Creating `tls.Socket`: %o",this.connectOpts);const t=this.connectOpts.servername||this.connectOpts.host;r=f.connect({...this.connectOpts,servername:t&&a.isIP(t)?void 0:t})}else rn("Creating `net.Socket`: %o",this.connectOpts),r=a.connect(this.connectOpts);const o="function"==typeof this.proxyHeaders?this.proxyHeaders():{...this.proxyHeaders},i=a.isIPv6(n.host)?`[${n.host}]`:n.host;let s=`CONNECT ${i}:${n.port} HTTP/1.1\r\n`;if(e.username||e.password){const t=`${decodeURIComponent(e.username)}:${decodeURIComponent(e.password)}`;o["Proxy-Authorization"]=`Basic ${Buffer.from(t).toString("base64")}`}o.Host=`${i}:${n.port}`,o["Proxy-Connection"]||(o["Proxy-Connection"]=this.keepAlive?"Keep-Alive":"close");for(const t of Object.keys(o))s+=`${t}: ${o[t]}\r\n`;const c=en(r);r.write(`${s}\r\n`);const{connect:u,buffered:h}=await c;if(t.emit("proxyConnect",u),this.emit("proxyConnect",u,t),200===u.statusCode){if(t.once("socket",sn),n.secureEndpoint){rn("Upgrading socket connection to TLS");const t=n.servername||n.host;return f.connect({...cn(n,"host","path","port"),socket:r,servername:a.isIP(t)?void 0:t})}return r}r.destroy();const p=new a.Socket({writable:!1});return p.readable=!0,t.once("socket",t=>{rn("Replaying proxy buffer for failed request"),t.push(h),t.push(null)}),p}}function sn(t){t.resume()}function cn(t,...n){const e={};let r;for(r in t)n.includes(r)||(e[r]=t[r]);return e}on.protocols=["http","https"];function un(t){return t.replace(/^[A-Z]:/,"").replace(/\\/g,"/")}const an=n;let fn,hn=0,pn={};function dn(t){an.debug&&console.log(`[ANR Worker] ${t}`)}var ln,gn,mn;const yn=function(t){let n;try{n=new URL(t.url)}catch(n){return b(()=>{console.warn("[@sentry/node]: Invalid dsn or tunnel option, will not send any events. The tunnel option must be a full URL when used.")}),Kt(t,()=>Promise.resolve({}))}const e="https:"===n.protocol,r=function(t,n){const{no_proxy:e}=process.env,r=e?.split(",").some(n=>t.host.endsWith(n)||t.hostname.endsWith(n));return r?void 0:n}(n,t.proxy||(e?process.env.https_proxy:void 0)||process.env.http_proxy),o=e?s:i,a=void 0!==t.keepAlive&&t.keepAlive,f=r?new on(r):new o.Agent({keepAlive:a,maxSockets:30,timeout:2e3}),h=function(t,n,e){const{hostname:r,pathname:o,port:i,protocol:s,search:a}=new URL(t.url);return function(f){return new Promise((h,p)=>{Ft(()=>{let d=function(t){return new c({read(){this.push(t),this.push(null)}})}(f.body);const l={...t.headers};f.body.length>32768&&(l["content-encoding"]="gzip",d=d.pipe(u()));const g=r.startsWith("["),m=n.request({method:"POST",agent:e,headers:l,hostname:g?r.slice(1,-1):r,path:`${o}${a}`,port:i,protocol:s,ca:t.caCerts},t=>{t.on("data",()=>{}),t.on("end",()=>{}),t.setEncoding("utf8");const n=t.headers["retry-after"]??null,e=t.headers["x-sentry-rate-limits"]??null;h({statusCode:t.statusCode,headers:{"retry-after":n,"x-sentry-rate-limits":Array.isArray(e)?e[0]||null:e}})});m.on("error",p),d.pipe(m)})})}}(t,t.httpModule??o,f);return Kt(t,h)}({url:(ln=an.dsn,gn=an.tunnel,mn=an.sdkMetadata.sdk,gn||`${function(t){return`${function(t){const n=t.protocol?`${t.protocol}:`:"",e=t.port?`:${t.port}`:"";return`${n}//${t.host}${e}${t.path?`/${t.path}`:""}/api/`}(t)}${t.projectId}/envelope/`}(ln)}?${function(t,n){const e={sentry_version:"7"};return t.publicKey&&(e.sentry_key=t.publicKey),n&&(e.sentry_client=`${n.name}/${n.version}`),new URLSearchParams(e).toString()}(ln,mn)}`)});async function bn(){if(fn){dn("Sending abnormal session"),K(fn,{status:"abnormal",abnormal_mechanism:"anr_foreground",release:an.release,environment:an.environment});const t=function(t,n,e,r){const o=Lt(e);return Tt({sent_at:new Date(P()).toISOString(),...o&&{sdk:o},...!!r&&n&&{dsn:bt(n)}},["aggregates"in t?[{type:"sessions"},t]:[{type:"session"},t.toJSON()]])}(fn,an.dsn,an.sdkMetadata,an.tunnel);dn(JSON.stringify(t)),await yn.send(t);try{e?.postMessage("session-ended")}catch{}}}function vn(t){if(!t)return;const n=function(t){if(!t.length)return[];const n=Array.from(t);return/sentryWrapped/.test(E(n).function||"")&&n.pop(),n.reverse(),$.test(E(n).function||"")&&(n.pop(),$.test(E(n).function||"")&&n.pop()),n.slice(0,50).map(t=>({...t,filename:t.filename||E(n).filename,function:t.function||"?"}))}(t);if(an.appRootPath)for(const t of n)t.filename&&(t.filename=M(t.filename,an.appRootPath));return n}async function _n(t,n){if(hn>=an.maxAnrEvents)return;hn+=1,await bn(),dn("Sending event");const e={event_id:G(),contexts:an.contexts,release:an.release,environment:an.environment,dist:an.dist,platform:"node",level:"error",exception:{values:[{type:"ApplicationNotResponding",value:`Application Not Responding for at least ${an.anrThreshold} ms`,stacktrace:{frames:vn(t)},mechanism:{type:"ANR"}}]},tags:an.staticTags};n&&function(t,n){if(Gt(t,n),!t.contexts?.trace){const{traceId:e,parentSpanId:r,propagationSpanId:o}=n.propagationContext;t.contexts={trace:{trace_id:e,span_id:o||V(),parent_span_id:r},...t.contexts}}}(e,n),function(t){if(0===Object.keys(pn).length)return;const n=an.appRootPath?{}:pn;if(an.appRootPath)for(const[t,e]of Object.entries(pn))n[M(t,an.appRootPath)]=e;const e=new Map;for(const r of t.exception?.values||[])for(const t of r.stacktrace?.frames||[]){const r=t.abs_path||t.filename;r&&n[r]&&e.set(r,n[r])}if(e.size>0){const n=[];for(const[t,r]of e.entries())n.push({type:"sourcemap",code_file:t,debug_id:r});t.debug_meta={images:n}}}(e);const r=Mt(e,an.dsn,an.sdkMetadata,an.tunnel);dn(JSON.stringify(r)),await yn.send(r),await yn.flush(2e3),hn>=an.maxAnrEvents&&setTimeout(()=>{process.exit(0)},5e3)}let Sn;if(dn("Started"),an.captureStackTrace){dn("Connecting to debugger");const n=new t;n.connectToMainThread(),dn("Connected to debugger");const e=new Map;n.on("Debugger.scriptParsed",t=>{e.set(t.params.scriptId,t.params.url)}),n.on("Debugger.paused",t=>{if("other"===t.params.reason)try{dn("Debugger paused");const i=[...t.params.callFrames],s=an.appRootPath?function(t=(process.argv[1]?qt(process.argv[1]):process.cwd()),n="\\"===o){const e=n?un(t):t;return t=>{if(!t)return;const o=n?un(t):t;let{dir:i,base:s,ext:c}=r.parse(o);".js"!==c&&".mjs"!==c&&".cjs"!==c||(s=s.slice(0,-1*c.length));const u=decodeURIComponent(s);i||(i=".");const a=i.lastIndexOf("/node_modules");if(a>-1)return`${i.slice(a+14).replace(/\//g,".")}:${u}`;if(i.startsWith(e)){const t=i.slice(e.length+1).replace(/\//g,".");return t?`${t}:${u}`:u}return u}}(an.appRootPath):()=>{},c=i.map(t=>function(t,n,e){const r=n?n.replace(/^file:\/\//,""):void 0,o=t.location.columnNumber?t.location.columnNumber+1:void 0,i=t.location.lineNumber?t.location.lineNumber+1:void 0;return{filename:r,module:e(r),function:t.functionName||"?",colno:o,lineno:i,in_app:r?Vt(r):void 0}}(t,e.get(t.location.scriptId),s)),u=setTimeout(()=>{_n(c).then(null,()=>{dn("Sending ANR event failed.")})},5e3);n.post("Runtime.evaluate",{expression:"global.__SENTRY_GET_SCOPES__();",silent:!0,returnByValue:!0},(t,e)=>{t&&dn(`Error executing script: '${t.message}'`),clearTimeout(u);const r=e?.result?e.result.value:void 0;n.post("Debugger.resume"),n.post("Debugger.disable"),_n(c,r).then(null,()=>{dn("Sending ANR event failed.")})})}catch(t){throw n.post("Debugger.resume"),n.post("Debugger.disable"),t}}),Sn=()=>{try{n.post("Debugger.enable",()=>{n.post("Debugger.pause")})}catch{}}}const{poll:wn}=function(t,n,e,r){const o=t();let i=!1,s=!0;return setInterval(()=>{const t=o.getTimeMs();!1===i&&t>n+e&&(i=!0,s&&r()),t<n+e&&(i=!1)},20),{poll:()=>{o.reset()},enabled:t=>{s=t}}}(function(){let t=process.hrtime();return{getTimeMs:()=>{const[n,e]=process.hrtime(t);return Math.floor(1e3*n+e/1e6)},reset:()=>{t=process.hrtime()}}},an.pollInterval,an.anrThreshold,function(){dn("Watchdog timeout"),Sn?(dn("Pausing debugger to capture stack trace"),Sn()):(dn("Capturing event without a stack trace"),_n().then(null,()=>{dn("Sending ANR event failed on watchdog timeout.")}))});e?.on("message",t=>{t.session&&(fn=H(t.session)),t.debugImages&&(pn=t.debugImages),wn()});
import * as diagnosticsChannel from 'node:diagnostics_channel';
import { defineIntegration, addBreadcrumb, captureException } from '@sentry/core';
import { defineIntegration, isObjectLike, addBreadcrumb, captureException } from '@sentry/core';

@@ -10,3 +10,3 @@ const INTEGRATION_NAME = "ChildProcess";

diagnosticsChannel.channel("child_process").subscribe((event) => {
if (event && typeof event === "object" && "process" in event) {
if (isObjectLike(event) && "process" in event) {
captureChildProcessEvents(event.process, options);

@@ -16,3 +16,3 @@ }

diagnosticsChannel.channel("worker_threads").subscribe((event) => {
if (event && typeof event === "object" && "worker" in event) {
if (isObjectLike(event) && "worker" in event) {
captureWorkerThreadEvents(event.worker, options);

@@ -19,0 +19,0 @@ }

@@ -1,1 +0,1 @@

{"version":3,"file":"childProcess.js","sources":["../../../src/integrations/childProcess.ts"],"sourcesContent":["import type { ChildProcess } from 'node:child_process';\nimport * as diagnosticsChannel from 'node:diagnostics_channel';\nimport type { Worker } from 'node:worker_threads';\nimport { addBreadcrumb, captureException, defineIntegration } from '@sentry/core';\n\ninterface Options {\n /**\n * Whether to include child process arguments in breadcrumbs data.\n *\n * @default false\n */\n includeChildProcessArgs?: boolean;\n\n /**\n * Whether to capture errors from worker threads.\n *\n * @default true\n */\n captureWorkerErrors?: boolean;\n}\n\nconst INTEGRATION_NAME = 'ChildProcess' as const;\n\n/**\n * Capture breadcrumbs and events for child processes and worker threads.\n */\nexport const childProcessIntegration = defineIntegration((options: Options = {}) => {\n return {\n name: INTEGRATION_NAME,\n setup() {\n diagnosticsChannel.channel('child_process').subscribe((event: unknown) => {\n if (event && typeof event === 'object' && 'process' in event) {\n captureChildProcessEvents(event.process as ChildProcess, options);\n }\n });\n\n diagnosticsChannel.channel('worker_threads').subscribe((event: unknown) => {\n if (event && typeof event === 'object' && 'worker' in event) {\n captureWorkerThreadEvents(event.worker as Worker, options);\n }\n });\n },\n };\n});\n\nfunction captureChildProcessEvents(child: ChildProcess, options: Options): void {\n let hasExited = false;\n let data: Record<string, unknown> | undefined;\n\n child\n .on('spawn', () => {\n // This is Sentry getting macOS OS context\n if (child.spawnfile === '/usr/bin/sw_vers') {\n hasExited = true;\n return;\n }\n\n data = { spawnfile: child.spawnfile };\n if (options.includeChildProcessArgs) {\n data.spawnargs = child.spawnargs;\n }\n })\n .on('exit', code => {\n if (!hasExited) {\n hasExited = true;\n\n // Only log for non-zero exit codes\n if (code !== null && code !== 0) {\n addBreadcrumb({\n category: 'child_process',\n message: `Child process exited with code '${code}'`,\n level: code === 0 ? 'info' : 'warning',\n data,\n });\n }\n }\n })\n .on('error', error => {\n if (!hasExited) {\n hasExited = true;\n\n addBreadcrumb({\n category: 'child_process',\n message: `Child process errored with '${error.message}'`,\n level: 'error',\n data,\n });\n }\n });\n}\n\nfunction captureWorkerThreadEvents(worker: Worker, options: Options): void {\n let threadId: number | undefined;\n\n worker\n .on('online', () => {\n threadId = worker.threadId;\n })\n .on('error', error => {\n if (options.captureWorkerErrors !== false) {\n captureException(error, {\n mechanism: { type: 'auto.child_process.worker_thread', handled: false, data: { threadId: String(threadId) } },\n });\n } else {\n addBreadcrumb({\n category: 'worker_thread',\n message: `Worker thread errored with '${error.message}'`,\n level: 'error',\n data: { threadId },\n });\n }\n });\n}\n"],"names":[],"mappings":"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"}
{"version":3,"file":"childProcess.js","sources":["../../../src/integrations/childProcess.ts"],"sourcesContent":["import type { ChildProcess } from 'node:child_process';\nimport * as diagnosticsChannel from 'node:diagnostics_channel';\nimport type { Worker } from 'node:worker_threads';\nimport { addBreadcrumb, captureException, defineIntegration, isObjectLike } from '@sentry/core';\n\ninterface Options {\n /**\n * Whether to include child process arguments in breadcrumbs data.\n *\n * @default false\n */\n includeChildProcessArgs?: boolean;\n\n /**\n * Whether to capture errors from worker threads.\n *\n * @default true\n */\n captureWorkerErrors?: boolean;\n}\n\nconst INTEGRATION_NAME = 'ChildProcess' as const;\n\n/**\n * Capture breadcrumbs and events for child processes and worker threads.\n */\nexport const childProcessIntegration = defineIntegration((options: Options = {}) => {\n return {\n name: INTEGRATION_NAME,\n setup() {\n diagnosticsChannel.channel('child_process').subscribe((event: unknown) => {\n if (isObjectLike(event) && 'process' in event) {\n captureChildProcessEvents(event.process as ChildProcess, options);\n }\n });\n\n diagnosticsChannel.channel('worker_threads').subscribe((event: unknown) => {\n if (isObjectLike(event) && 'worker' in event) {\n captureWorkerThreadEvents(event.worker as Worker, options);\n }\n });\n },\n };\n});\n\nfunction captureChildProcessEvents(child: ChildProcess, options: Options): void {\n let hasExited = false;\n let data: Record<string, unknown> | undefined;\n\n child\n .on('spawn', () => {\n // This is Sentry getting macOS OS context\n if (child.spawnfile === '/usr/bin/sw_vers') {\n hasExited = true;\n return;\n }\n\n data = { spawnfile: child.spawnfile };\n if (options.includeChildProcessArgs) {\n data.spawnargs = child.spawnargs;\n }\n })\n .on('exit', code => {\n if (!hasExited) {\n hasExited = true;\n\n // Only log for non-zero exit codes\n if (code !== null && code !== 0) {\n addBreadcrumb({\n category: 'child_process',\n message: `Child process exited with code '${code}'`,\n level: code === 0 ? 'info' : 'warning',\n data,\n });\n }\n }\n })\n .on('error', error => {\n if (!hasExited) {\n hasExited = true;\n\n addBreadcrumb({\n category: 'child_process',\n message: `Child process errored with '${error.message}'`,\n level: 'error',\n data,\n });\n }\n });\n}\n\nfunction captureWorkerThreadEvents(worker: Worker, options: Options): void {\n let threadId: number | undefined;\n\n worker\n .on('online', () => {\n threadId = worker.threadId;\n })\n .on('error', error => {\n if (options.captureWorkerErrors !== false) {\n captureException(error, {\n mechanism: { type: 'auto.child_process.worker_thread', handled: false, data: { threadId: String(threadId) } },\n });\n } else {\n addBreadcrumb({\n category: 'worker_thread',\n message: `Worker thread errored with '${error.message}'`,\n level: 'error',\n data: { threadId },\n });\n }\n });\n}\n"],"names":[],"mappings":"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"}
import { defineIntegration } from '@sentry/core';
import { generateInstrumentOnce } from '../../otel/instrument.js';
import { httpServerIntegration } from './httpServerIntegration.js';
import { httpServerSpansIntegration } from './httpServerSpansIntegration.js';
import { SentryHttpInstrumentation } from './SentryHttpInstrumentation.js';
import { instrumentHttpOutgoingRequests } from './SentryHttpInstrumentation.js';
const INTEGRATION_NAME = "Http";
const instrumentSentryHttp = generateInstrumentOnce(
`${INTEGRATION_NAME}.sentry`,
(options) => {
return new SentryHttpInstrumentation(options);
}
);
Object.assign(instrumentHttpOutgoingRequests, {
id: `${INTEGRATION_NAME}.sentry`
});
const httpIntegration = defineIntegration((options = {}) => {
const spans = options.spans ?? false;
const disableIncomingRequestSpans = options.disableIncomingRequestSpans ?? false;
const enabledServerSpans = spans && !disableIncomingRequestSpans;
const serverOptions = {

@@ -29,9 +28,7 @@ sessions: options.trackIncomingRequestsAsSessions,

propagateTraceInOutgoingRequests: options.tracePropagation ?? true,
ignoreOutgoingRequests: options.ignoreOutgoingRequests
ignoreOutgoingRequests: options.ignoreOutgoingRequests,
spans
};
const server = httpServerIntegration(serverOptions);
const serverSpans = httpServerSpansIntegration(serverSpansOptions);
const spans = options.spans ?? false;
const disableIncomingRequestSpans = options.disableIncomingRequestSpans ?? false;
const enabledServerSpans = spans && !disableIncomingRequestSpans;
return {

@@ -46,3 +43,3 @@ name: INTEGRATION_NAME,

server.setupOnce();
instrumentSentryHttp(httpInstrumentationOptions);
instrumentHttpOutgoingRequests(httpInstrumentationOptions);
},

@@ -55,3 +52,3 @@ processEvent(event) {

export { httpIntegration, instrumentSentryHttp };
export { httpIntegration };
//# sourceMappingURL=index.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"index.js","sources":["../../../../src/integrations/http/index.ts"],"sourcesContent":["import type { RequestOptions } from 'node:http';\nimport type { HttpIncomingMessage } from '@sentry/core';\nimport { defineIntegration } from '@sentry/core';\nimport { generateInstrumentOnce } from '../../otel/instrument';\nimport type { NodeClient } from '../../sdk/client';\nimport type { HttpServerIntegrationOptions } from './httpServerIntegration';\nimport { httpServerIntegration } from './httpServerIntegration';\nimport type { HttpServerSpansIntegrationOptions } from './httpServerSpansIntegration';\nimport { httpServerSpansIntegration } from './httpServerSpansIntegration';\nimport type { SentryHttpInstrumentationOptions } from './SentryHttpInstrumentation';\nimport { SentryHttpInstrumentation } from './SentryHttpInstrumentation';\n\nconst INTEGRATION_NAME = 'Http' as const;\n\ninterface HttpOptions {\n /**\n * Whether breadcrumbs should be recorded for outgoing requests.\n * Defaults to true\n */\n breadcrumbs?: boolean;\n\n /**\n * Whether to create spans for requests or not.\n * As of now, creates spans for incoming requests, but not outgoing requests.\n *\n * @default `true`\n */\n spans?: boolean;\n\n /**\n * Whether the integration should create [Sessions](https://docs.sentry.io/product/releases/health/#sessions) for incoming requests to track the health and crash-free rate of your releases in Sentry.\n * Read more about Release Health: https://docs.sentry.io/product/releases/health/\n *\n * Defaults to `true`.\n */\n trackIncomingRequestsAsSessions?: boolean;\n\n /**\n * Number of milliseconds until sessions tracked with `trackIncomingRequestsAsSessions` will be flushed as a session aggregate.\n *\n * Defaults to `60000` (60s).\n */\n sessionFlushingDelayMS?: number;\n\n /**\n * Whether to inject trace propagation headers (sentry-trace, baggage, traceparent) into outgoing HTTP requests.\n *\n * When set to `false`, Sentry will not inject any trace propagation headers, but will still create breadcrumbs\n * (if `breadcrumbs` is enabled).\n *\n * @default `true`\n */\n tracePropagation?: boolean;\n\n /**\n * Do not capture spans or breadcrumbs for outgoing HTTP requests to URLs where the given callback returns `true`.\n * This controls both span & breadcrumb creation - spans will be non recording if tracing is disabled.\n *\n * The `url` param contains the entire URL, including query string (if any), protocol, host, etc. of the outgoing request.\n * For example: `'https://someService.com/users/details?id=123'`\n *\n * The `request` param contains the original {@type RequestOptions} object used to make the outgoing request.\n * You can use it to filter on additional properties like method, headers, etc.\n */\n ignoreOutgoingRequests?: (url: string, request: RequestOptions) => boolean;\n\n /**\n * Do not capture spans for incoming HTTP requests to URLs where the given callback returns `true`.\n * Spans will be non recording if tracing is disabled.\n *\n * The `urlPath` param consists of the URL path and query string (if any) of the incoming request.\n * For example: `'/users/details?id=123'`\n *\n * The `request` param contains the original {@type IncomingMessage} object of the incoming request.\n * You can use it to filter on additional properties like method, headers, etc.\n */\n ignoreIncomingRequests?: (urlPath: string, request: HttpIncomingMessage) => boolean;\n\n /**\n * Do not capture spans for incoming HTTP requests with the given status codes.\n * By default, spans with some 3xx and 4xx status codes are ignored (see @default).\n * Expects an array of status codes or a range of status codes, e.g. [[300,399], 404] would ignore 3xx and 404 status codes.\n *\n * @default `[[401, 404], [301, 303], [305, 399]]`\n */\n dropSpansForIncomingRequestStatusCodes?: (number | [number, number])[];\n\n /**\n * Do not capture the request body for incoming HTTP requests to URLs where the given callback returns `true`.\n * This can be useful for long running requests where the body is not needed and we want to avoid capturing it.\n *\n * @param url Contains the entire URL, including query string (if any), protocol, host, etc. of the incoming request.\n * @param request Contains the {@type RequestOptions} object used to make the incoming request.\n */\n ignoreIncomingRequestBody?: (url: string, request: RequestOptions) => boolean;\n\n /**\n * Whether to automatically ignore common static asset requests like favicon.ico, robots.txt, etc.\n * This helps reduce noise in your transactions.\n *\n * @default `true`\n */\n ignoreStaticAssets?: boolean;\n\n /**\n * Controls the maximum size of incoming HTTP request bodies attached to events.\n *\n * Available options:\n * - 'none': No request bodies will be attached\n * - 'small': Request bodies up to 1,000 bytes will be attached\n * - 'medium': Request bodies up to 10,000 bytes will be attached (default)\n * - 'always': Request bodies will always be attached\n *\n * Note that even with 'always' setting, bodies exceeding 1MB will never be attached\n * for performance and security reasons.\n *\n * @default 'medium'\n */\n maxIncomingRequestBodySize?: 'none' | 'small' | 'medium' | 'always';\n\n /**\n * If true, do not generate spans for incoming requests at all.\n * This is used by Remix to avoid generating spans for incoming requests, as it generates its own spans.\n */\n disableIncomingRequestSpans?: boolean;\n}\n\nexport const instrumentSentryHttp = generateInstrumentOnce<SentryHttpInstrumentationOptions>(\n `${INTEGRATION_NAME}.sentry`,\n options => {\n return new SentryHttpInstrumentation(options);\n },\n);\n\n/**\n * The http integration instruments Node's internal http and https modules.\n * It creates breadcrumbs for outgoing HTTP requests which will be attached to the currently active span.\n */\nexport const httpIntegration = defineIntegration((options: HttpOptions = {}) => {\n const serverOptions: HttpServerIntegrationOptions = {\n sessions: options.trackIncomingRequestsAsSessions,\n sessionFlushingDelayMS: options.sessionFlushingDelayMS,\n ignoreRequestBody: options.ignoreIncomingRequestBody,\n maxRequestBodySize: options.maxIncomingRequestBodySize,\n };\n\n const serverSpansOptions: HttpServerSpansIntegrationOptions = {\n ignoreIncomingRequests: options.ignoreIncomingRequests,\n ignoreStaticAssets: options.ignoreStaticAssets,\n ignoreStatusCodes: options.dropSpansForIncomingRequestStatusCodes,\n };\n\n const httpInstrumentationOptions: SentryHttpInstrumentationOptions = {\n breadcrumbs: options.breadcrumbs,\n propagateTraceInOutgoingRequests: options.tracePropagation ?? true,\n ignoreOutgoingRequests: options.ignoreOutgoingRequests,\n };\n\n const server = httpServerIntegration(serverOptions);\n const serverSpans = httpServerSpansIntegration(serverSpansOptions);\n\n // In node-core, for now we disable incoming requests spans by default\n // we may revisit this in a future release\n const spans = options.spans ?? false;\n const disableIncomingRequestSpans = options.disableIncomingRequestSpans ?? false;\n const enabledServerSpans = spans && !disableIncomingRequestSpans;\n\n return {\n name: INTEGRATION_NAME,\n setup(client: NodeClient) {\n if (enabledServerSpans) {\n serverSpans.setup(client);\n }\n },\n setupOnce() {\n server.setupOnce();\n\n instrumentSentryHttp(httpInstrumentationOptions);\n },\n\n processEvent(event) {\n // Note: We always run this, even if spans are disabled\n // The reason being that e.g. the remix integration disables span creation here but still wants to use the ignore status codes option\n return serverSpans.processEvent(event);\n },\n };\n});\n"],"names":[],"mappings":";;;;;;AAYA,MAAM,gBAAA,GAAmB,MAAA;AAmHlB,MAAM,oBAAA,GAAuB,sBAAA;AAAA,EAClC,GAAG,gBAAgB,CAAA,OAAA,CAAA;AAAA,EACnB,CAAA,OAAA,KAAW;AACT,IAAA,OAAO,IAAI,0BAA0B,OAAO,CAAA;AAAA,EAC9C;AACF;AAMO,MAAM,eAAA,GAAkB,iBAAA,CAAkB,CAAC,OAAA,GAAuB,EAAC,KAAM;AAC9E,EAAA,MAAM,aAAA,GAA8C;AAAA,IAClD,UAAU,OAAA,CAAQ,+BAAA;AAAA,IAClB,wBAAwB,OAAA,CAAQ,sBAAA;AAAA,IAChC,mBAAmB,OAAA,CAAQ,yBAAA;AAAA,IAC3B,oBAAoB,OAAA,CAAQ;AAAA,GAC9B;AAEA,EAAA,MAAM,kBAAA,GAAwD;AAAA,IAC5D,wBAAwB,OAAA,CAAQ,sBAAA;AAAA,IAChC,oBAAoB,OAAA,CAAQ,kBAAA;AAAA,IAC5B,mBAAmB,OAAA,CAAQ;AAAA,GAC7B;AAEA,EAAA,MAAM,0BAAA,GAA+D;AAAA,IACnE,aAAa,OAAA,CAAQ,WAAA;AAAA,IACrB,gCAAA,EAAkC,QAAQ,gBAAA,IAAoB,IAAA;AAAA,IAC9D,wBAAwB,OAAA,CAAQ;AAAA,GAClC;AAEA,EAAA,MAAM,MAAA,GAAS,sBAAsB,aAAa,CAAA;AAClD,EAAA,MAAM,WAAA,GAAc,2BAA2B,kBAAkB,CAAA;AAIjE,EAAA,MAAM,KAAA,GAAQ,QAAQ,KAAA,IAAS,KAAA;AAC/B,EAAA,MAAM,2BAAA,GAA8B,QAAQ,2BAAA,IAA+B,KAAA;AAC3E,EAAA,MAAM,kBAAA,GAAqB,SAAS,CAAC,2BAAA;AAErC,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,gBAAA;AAAA,IACN,MAAM,MAAA,EAAoB;AACxB,MAAA,IAAI,kBAAA,EAAoB;AACtB,QAAA,WAAA,CAAY,MAAM,MAAM,CAAA;AAAA,MAC1B;AAAA,IACF,CAAA;AAAA,IACA,SAAA,GAAY;AACV,MAAA,MAAA,CAAO,SAAA,EAAU;AAEjB,MAAA,oBAAA,CAAqB,0BAA0B,CAAA;AAAA,IACjD,CAAA;AAAA,IAEA,aAAa,KAAA,EAAO;AAGlB,MAAA,OAAO,WAAA,CAAY,aAAa,KAAK,CAAA;AAAA,IACvC;AAAA,GACF;AACF,CAAC;;;;"}
{"version":3,"file":"index.js","sources":["../../../../src/integrations/http/index.ts"],"sourcesContent":["import type { RequestOptions } from 'node:http';\nimport type { HttpIncomingMessage } from '@sentry/core';\nimport { defineIntegration } from '@sentry/core';\nimport type { NodeClient } from '../../sdk/client';\nimport type { HttpServerIntegrationOptions } from './httpServerIntegration';\nimport { httpServerIntegration } from './httpServerIntegration';\nimport type { HttpServerSpansIntegrationOptions } from './httpServerSpansIntegration';\nimport { httpServerSpansIntegration } from './httpServerSpansIntegration';\nimport type { SentryHttpInstrumentationOptions } from './SentryHttpInstrumentation';\nimport { instrumentHttpOutgoingRequests } from './SentryHttpInstrumentation';\n\nconst INTEGRATION_NAME = 'Http' as const;\n\ninterface HttpOptions {\n /**\n * Whether breadcrumbs should be recorded for outgoing requests.\n * Defaults to true\n */\n breadcrumbs?: boolean;\n\n /**\n * Whether to create spans for requests or not.\n * As of now, creates spans for incoming requests, but not outgoing requests.\n *\n * @default `true`\n */\n spans?: boolean;\n\n /**\n * Whether the integration should create [Sessions](https://docs.sentry.io/product/releases/health/#sessions) for incoming requests to track the health and crash-free rate of your releases in Sentry.\n * Read more about Release Health: https://docs.sentry.io/product/releases/health/\n *\n * Defaults to `true`.\n */\n trackIncomingRequestsAsSessions?: boolean;\n\n /**\n * Number of milliseconds until sessions tracked with `trackIncomingRequestsAsSessions` will be flushed as a session aggregate.\n *\n * Defaults to `60000` (60s).\n */\n sessionFlushingDelayMS?: number;\n\n /**\n * Whether to inject trace propagation headers (sentry-trace, baggage, traceparent) into outgoing HTTP requests.\n *\n * When set to `false`, Sentry will not inject any trace propagation headers, but will still create breadcrumbs\n * (if `breadcrumbs` is enabled).\n *\n * @default `true`\n */\n tracePropagation?: boolean;\n\n /**\n * Do not capture spans or breadcrumbs for outgoing HTTP requests to URLs where the given callback returns `true`.\n * This controls both span & breadcrumb creation - spans will be non recording if tracing is disabled.\n *\n * The `url` param contains the entire URL, including query string (if any), protocol, host, etc. of the outgoing request.\n * For example: `'https://someService.com/users/details?id=123'`\n *\n * The `request` param contains the original {@type RequestOptions} object used to make the outgoing request.\n * You can use it to filter on additional properties like method, headers, etc.\n */\n ignoreOutgoingRequests?: (url: string, request: RequestOptions) => boolean;\n\n /**\n * Do not capture spans for incoming HTTP requests to URLs where the given callback returns `true`.\n * Spans will be non recording if tracing is disabled.\n *\n * The `urlPath` param consists of the URL path and query string (if any) of the incoming request.\n * For example: `'/users/details?id=123'`\n *\n * The `request` param contains the original {@type IncomingMessage} object of the incoming request.\n * You can use it to filter on additional properties like method, headers, etc.\n */\n ignoreIncomingRequests?: (urlPath: string, request: HttpIncomingMessage) => boolean;\n\n /**\n * Do not capture spans for incoming HTTP requests with the given status codes.\n * By default, spans with some 3xx and 4xx status codes are ignored (see @default).\n * Expects an array of status codes or a range of status codes, e.g. [[300,399], 404] would ignore 3xx and 404 status codes.\n *\n * @default `[[401, 404], [301, 303], [305, 399]]`\n */\n dropSpansForIncomingRequestStatusCodes?: (number | [number, number])[];\n\n /**\n * Do not capture the request body for incoming HTTP requests to URLs where the given callback returns `true`.\n * This can be useful for long running requests where the body is not needed and we want to avoid capturing it.\n *\n * @param url Contains the entire URL, including query string (if any), protocol, host, etc. of the incoming request.\n * @param request Contains the {@type RequestOptions} object used to make the incoming request.\n */\n ignoreIncomingRequestBody?: (url: string, request: RequestOptions) => boolean;\n\n /**\n * Whether to automatically ignore common static asset requests like favicon.ico, robots.txt, etc.\n * This helps reduce noise in your transactions.\n *\n * @default `true`\n */\n ignoreStaticAssets?: boolean;\n\n /**\n * Controls the maximum size of incoming HTTP request bodies attached to events.\n *\n * Available options:\n * - 'none': No request bodies will be attached\n * - 'small': Request bodies up to 1,000 bytes will be attached\n * - 'medium': Request bodies up to 10,000 bytes will be attached (default)\n * - 'always': Request bodies will always be attached\n *\n * Note that even with 'always' setting, bodies exceeding 1MB will never be attached\n * for performance and security reasons.\n *\n * @default 'medium'\n */\n maxIncomingRequestBodySize?: 'none' | 'small' | 'medium' | 'always';\n\n /**\n * If true, do not generate spans for incoming requests at all.\n * This is used by Remix to avoid generating spans for incoming requests, as it generates its own spans.\n */\n disableIncomingRequestSpans?: boolean;\n}\n\nexport const instrumentSentryHttp = Object.assign(instrumentHttpOutgoingRequests, {\n id: `${INTEGRATION_NAME}.sentry`,\n});\n\n/**\n * The http integration instruments Node's internal http and https modules.\n * It creates breadcrumbs for outgoing HTTP requests which will be attached to the currently active span.\n */\nexport const httpIntegration = defineIntegration((options: HttpOptions = {}) => {\n // In node-core, for now we disable incoming requests spans by default\n // we may revisit this in a future release\n const spans = options.spans ?? false;\n const disableIncomingRequestSpans = options.disableIncomingRequestSpans ?? false;\n const enabledServerSpans = spans && !disableIncomingRequestSpans;\n\n const serverOptions: HttpServerIntegrationOptions = {\n sessions: options.trackIncomingRequestsAsSessions,\n sessionFlushingDelayMS: options.sessionFlushingDelayMS,\n ignoreRequestBody: options.ignoreIncomingRequestBody,\n maxRequestBodySize: options.maxIncomingRequestBodySize,\n };\n\n const serverSpansOptions: HttpServerSpansIntegrationOptions = {\n ignoreIncomingRequests: options.ignoreIncomingRequests,\n ignoreStaticAssets: options.ignoreStaticAssets,\n ignoreStatusCodes: options.dropSpansForIncomingRequestStatusCodes,\n };\n\n const httpInstrumentationOptions: SentryHttpInstrumentationOptions = {\n breadcrumbs: options.breadcrumbs,\n propagateTraceInOutgoingRequests: options.tracePropagation ?? true,\n ignoreOutgoingRequests: options.ignoreOutgoingRequests,\n spans,\n };\n\n const server = httpServerIntegration(serverOptions);\n const serverSpans = httpServerSpansIntegration(serverSpansOptions);\n\n return {\n name: INTEGRATION_NAME,\n setup(client: NodeClient) {\n if (enabledServerSpans) {\n serverSpans.setup(client);\n }\n },\n setupOnce() {\n server.setupOnce();\n\n instrumentHttpOutgoingRequests(httpInstrumentationOptions);\n },\n\n processEvent(event) {\n // Note: We always run this, even if spans are disabled\n // The reason being that e.g. the remix integration disables span creation here but still wants to use the ignore status codes option\n return serverSpans.processEvent(event);\n },\n };\n});\n"],"names":[],"mappings":";;;;;AAWA,MAAM,gBAAA,GAAmB,MAAA;AAmHW,MAAA,CAAO,MAAA,CAAO,8BAAA,EAAgC;AAAA,EAChF,EAAA,EAAI,GAAG,gBAAgB,CAAA,OAAA;AACzB,CAAC;AAMM,MAAM,eAAA,GAAkB,iBAAA,CAAkB,CAAC,OAAA,GAAuB,EAAC,KAAM;AAG9E,EAAA,MAAM,KAAA,GAAQ,QAAQ,KAAA,IAAS,KAAA;AAC/B,EAAA,MAAM,2BAAA,GAA8B,QAAQ,2BAAA,IAA+B,KAAA;AAC3E,EAAA,MAAM,kBAAA,GAAqB,SAAS,CAAC,2BAAA;AAErC,EAAA,MAAM,aAAA,GAA8C;AAAA,IAClD,UAAU,OAAA,CAAQ,+BAAA;AAAA,IAClB,wBAAwB,OAAA,CAAQ,sBAAA;AAAA,IAChC,mBAAmB,OAAA,CAAQ,yBAAA;AAAA,IAC3B,oBAAoB,OAAA,CAAQ;AAAA,GAC9B;AAEA,EAAA,MAAM,kBAAA,GAAwD;AAAA,IAC5D,wBAAwB,OAAA,CAAQ,sBAAA;AAAA,IAChC,oBAAoB,OAAA,CAAQ,kBAAA;AAAA,IAC5B,mBAAmB,OAAA,CAAQ;AAAA,GAC7B;AAEA,EAAA,MAAM,0BAAA,GAA+D;AAAA,IACnE,aAAa,OAAA,CAAQ,WAAA;AAAA,IACrB,gCAAA,EAAkC,QAAQ,gBAAA,IAAoB,IAAA;AAAA,IAC9D,wBAAwB,OAAA,CAAQ,sBAAA;AAAA,IAChC;AAAA,GACF;AAEA,EAAA,MAAM,MAAA,GAAS,sBAAsB,aAAa,CAAA;AAClD,EAAA,MAAM,WAAA,GAAc,2BAA2B,kBAAkB,CAAA;AAEjE,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,gBAAA;AAAA,IACN,MAAM,MAAA,EAAoB;AACxB,MAAA,IAAI,kBAAA,EAAoB;AACtB,QAAA,WAAA,CAAY,MAAM,MAAM,CAAA;AAAA,MAC1B;AAAA,IACF,CAAA;AAAA,IACA,SAAA,GAAY;AACV,MAAA,MAAA,CAAO,SAAA,EAAU;AAEjB,MAAA,8BAAA,CAA+B,0BAA0B,CAAA;AAAA,IAC3D,CAAA;AAAA,IAEA,aAAa,KAAA,EAAO;AAGlB,MAAA,OAAO,WAAA,CAAY,aAAa,KAAK,CAAA;AAAA,IACvC;AAAA,GACF;AACF,CAAC;;;;"}

@@ -1,5 +0,5 @@

import { subscribe } from 'node:diagnostics_channel';
import { subscribe, unsubscribe } from 'node:diagnostics_channel';
import { context, trace } from '@opentelemetry/api';
import { InstrumentationBase, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';
import { SDK_VERSION, getHttpClientSubscriptions, HTTP_ON_CLIENT_REQUEST, isTracingSuppressed, getRequestOptions, patchHttpModuleClient } from '@sentry/core';
import { InstrumentationBase } from '@opentelemetry/instrumentation';
import { getHttpClientSubscriptions, HTTP_ON_CLIENT_REQUEST, patchHttpModuleClient, SDK_VERSION, isTracingSuppressed, getRequestOptions } from '@sentry/core';
import { INSTRUMENTATION_NAME } from './constants.js';

@@ -9,5 +9,59 @@ import { NODE_VERSION } from '../../nodeVersion.js';

import * as http from 'node:http';
import * as https from 'node:https';
const FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL = NODE_VERSION.major === 22 && NODE_VERSION.minor >= 12 || NODE_VERSION.major === 23 && NODE_VERSION.minor >= 2 || NODE_VERSION.major >= 24;
function instrumentHttpOutgoingRequests(instrumentationOptions = {}) {
const { outgoingRequestApplyCustomAttributes: applyCustomAttributesOnSpan, ...options } = instrumentationOptions;
const patchOptions = {
propagateTrace: options.propagateTraceInOutgoingRequests ?? true,
applyCustomAttributesOnSpan,
...options,
// oxlint-disable-next-line typescript/no-deprecated
spans: options.createSpansForOutgoingRequests !== false && (options.spans ?? true),
ignoreOutgoingRequests(url, request) {
return isTracingSuppressed() || !!options.ignoreOutgoingRequests?.(url, getRequestOptions(request));
},
outgoingRequestHook(span, request) {
options.outgoingRequestHook?.(span, request);
const originalOnce = request.once;
const newOnce = new Proxy(originalOnce, {
apply(target, thisArg, args) {
const [event] = args;
if (event !== "response") {
return target.apply(thisArg, args);
}
const parentContext = context.active();
const requestContext = trace.setSpan(parentContext, span);
return context.with(requestContext, () => {
return target.apply(thisArg, args);
});
}
});
request.once = newOnce;
},
outgoingResponseHook(span, response) {
options.outgoingResponseHook?.(span, response);
context.bind(context.active(), response);
},
errorMonitor,
// Pass these in to detect OTel double-wrapping if we're enabling spans
http
};
if (FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL) {
instrumentHttpOutgoingRequestsViaChannel(patchOptions);
} else {
instrumentHttpOutgoingRequestsViaMonkeyPatching(patchOptions);
}
}
let _currentListener;
function instrumentHttpOutgoingRequestsViaChannel(options) {
const { [HTTP_ON_CLIENT_REQUEST]: onHttpClientRequestCreated } = getHttpClientSubscriptions(options);
if (_currentListener) {
unsubscribe(HTTP_ON_CLIENT_REQUEST, _currentListener);
}
subscribe(HTTP_ON_CLIENT_REQUEST, onHttpClientRequestCreated);
_currentListener = onHttpClientRequestCreated;
}
function instrumentHttpOutgoingRequestsViaMonkeyPatching(options) {
patchHttpModuleClient(http, options);
}
class SentryHttpInstrumentation extends InstrumentationBase {

@@ -19,57 +73,7 @@ constructor(config = {}) {

init() {
const { outgoingRequestApplyCustomAttributes: applyCustomAttributesOnSpan, ...options } = this.getConfig();
const patchOptions = {
propagateTrace: options.propagateTraceInOutgoingRequests,
applyCustomAttributesOnSpan,
...options,
spans: options.createSpansForOutgoingRequests && (options.spans ?? true),
ignoreOutgoingRequests(url, request) {
return isTracingSuppressed() || !!options.ignoreOutgoingRequests?.(url, getRequestOptions(request));
},
outgoingRequestHook(span, request) {
options.outgoingRequestHook?.(span, request);
const originalOnce = request.once;
const newOnce = new Proxy(originalOnce, {
apply(target, thisArg, args) {
const [event] = args;
if (event !== "response") {
return target.apply(thisArg, args);
}
const parentContext = context.active();
const requestContext = trace.setSpan(parentContext, span);
return context.with(requestContext, () => {
return target.apply(thisArg, args);
});
}
});
request.once = newOnce;
},
outgoingResponseHook(span, response) {
options.outgoingResponseHook?.(span, response);
context.bind(context.active(), response);
},
errorMonitor,
// Pass these in to detect OTel double-wrapping if we're enabling spans
http,
https
};
const { [HTTP_ON_CLIENT_REQUEST]: onHttpClientRequestCreated } = FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL ? getHttpClientSubscriptions(patchOptions) : {};
let hasRegisteredHandlers = false;
const sub = onHttpClientRequestCreated ? (moduleExports) => {
if (!hasRegisteredHandlers && onHttpClientRequestCreated) {
hasRegisteredHandlers = true;
subscribe(HTTP_ON_CLIENT_REQUEST, onHttpClientRequestCreated);
}
return moduleExports;
} : void 0;
const wrapHttp = sub ?? ((moduleExports) => patchHttpModuleClient(moduleExports, patchOptions));
const wrapHttps = sub ?? ((moduleExports) => patchHttpModuleClient(moduleExports, patchOptions));
return [
new InstrumentationNodeModuleDefinition("http", ["*"], wrapHttp),
new InstrumentationNodeModuleDefinition("https", ["*"], wrapHttps)
];
instrumentHttpOutgoingRequests(this.getConfig());
}
}
export { SentryHttpInstrumentation };
export { SentryHttpInstrumentation, instrumentHttpOutgoingRequests };
//# sourceMappingURL=SentryHttpInstrumentation.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"SentryHttpInstrumentation.js","sources":["../../../../src/integrations/http/SentryHttpInstrumentation.ts"],"sourcesContent":["import { subscribe } from 'node:diagnostics_channel';\nimport { context, trace } from '@opentelemetry/api';\nimport type { InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport { InstrumentationBase, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';\nimport type { ClientRequest, IncomingMessage, ServerResponse } from 'node:http';\nimport type {\n HttpClientRequest,\n HttpIncomingMessage,\n HttpInstrumentationOptions,\n HttpModuleExport,\n Span,\n} from '@sentry/core';\nimport {\n getHttpClientSubscriptions,\n patchHttpModuleClient,\n SDK_VERSION,\n getRequestOptions,\n isTracingSuppressed,\n} from '@sentry/core';\nimport { INSTRUMENTATION_NAME } from './constants';\nimport { HTTP_ON_CLIENT_REQUEST } from '@sentry/core';\nimport { NODE_VERSION } from '../../nodeVersion';\nimport { errorMonitor } from 'node:events';\nimport * as http from 'node:http';\nimport * as https from 'node:https';\n\nconst FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL =\n (NODE_VERSION.major === 22 && NODE_VERSION.minor >= 12) ||\n (NODE_VERSION.major === 23 && NODE_VERSION.minor >= 2) ||\n NODE_VERSION.major >= 24;\n\nexport type SentryHttpInstrumentationOptions = InstrumentationConfig & {\n /**\n * Whether breadcrumbs should be recorded for outgoing requests.\n *\n * @default `true`\n */\n breadcrumbs?: boolean;\n\n /**\n * Whether to propagate Sentry trace headers in outgoing requests.\n * By default this is done by the HttpInstrumentation, but if that is not added (e.g. because tracing is disabled)\n * then this instrumentation can take over.\n *\n * @default `false`\n */\n propagateTraceInOutgoingRequests?: boolean;\n\n /**\n * Whether to enable the capability to create spans for outgoing requests via diagnostic channels.\n * If enabled, spans will only be created if the `spans` option is also enabled (default: true).\n *\n * This is a feature flag that should be enabled by SDKs when the runtime supports it (Node 22.12+).\n * Individual users should not need to configure this directly.\n *\n * @default `false`\n */\n createSpansForOutgoingRequests?: boolean;\n\n /**\n * Whether to create spans for outgoing requests (user preference).\n * This only takes effect if `createSpansForOutgoingRequests` is also enabled.\n * If `createSpansForOutgoingRequests` is not enabled, this option is ignored.\n *\n * @default `true`\n */\n spans?: boolean;\n\n /**\n * Do not capture breadcrumbs for outgoing HTTP requests to URLs where the given callback returns `true`.\n * For the scope of this instrumentation, this callback only controls breadcrumb creation.\n * The same option can be passed to the top-level httpIntegration where it controls both, breadcrumb and\n * span creation.\n *\n * @param url Contains the entire URL, including query string (if any), protocol, host, etc. of the outgoing request.\n * @param request Contains the {@type RequestOptions} object used to make the outgoing request.\n */\n ignoreOutgoingRequests?: (url: string, request: http.RequestOptions) => boolean;\n\n /**\n * Hooks for outgoing request spans, called when `createSpansForOutgoingRequests` is enabled.\n * These mirror the OTEL HttpInstrumentation hooks for backwards compatibility.\n */\n outgoingRequestHook?: (span: Span, request: ClientRequest | HttpClientRequest) => void;\n outgoingResponseHook?: (span: Span, response: IncomingMessage | HttpIncomingMessage) => void;\n outgoingRequestApplyCustomAttributes?: (\n span: Span,\n request: HttpClientRequest,\n response: HttpIncomingMessage,\n ) => void;\n\n // All options below do not do anything anymore in this instrumentation, and will be removed in the future.\n // They are only kept here for backwards compatibility - the respective functionality is now handled by the httpServerIntegration/httpServerSpansIntegration.\n\n /**\n * @deprecated This no longer does anything.\n */\n extractIncomingTraceFromHeader?: boolean;\n\n /**\n * @deprecated This no longer does anything.\n */\n ignoreStaticAssets?: boolean;\n\n /**\n * @deprecated This no longer does anything.\n */\n disableIncomingRequestSpans?: boolean;\n\n /**\n * @deprecated This no longer does anything.\n */\n ignoreSpansForIncomingRequests?: (urlPath: string, request: IncomingMessage) => boolean;\n\n /**\n * @deprecated This no longer does anything.\n */\n ignoreIncomingRequestBody?: (url: string, request: http.RequestOptions) => boolean;\n\n /**\n * @deprecated This no longer does anything.\n */\n maxIncomingRequestBodySize?: 'none' | 'small' | 'medium' | 'always';\n\n /**\n * @deprecated This no longer does anything.\n */\n trackIncomingRequestsAsSessions?: boolean;\n\n /**\n * @deprecated This no longer does anything.\n */\n instrumentation?: {\n requestHook?: (span: Span, req: ClientRequest | IncomingMessage) => void;\n responseHook?: (span: Span, response: IncomingMessage | ServerResponse) => void;\n applyCustomAttributesOnSpan?: (\n span: Span,\n request: ClientRequest | IncomingMessage,\n response: IncomingMessage | ServerResponse,\n ) => void;\n };\n\n /**\n * @deprecated This no longer does anything.\n */\n sessionFlushingDelayMS?: number;\n};\n\n/**\n * This custom HTTP instrumentation handles outgoing HTTP requests.\n *\n * It provides:\n * - Breadcrumbs for all outgoing requests\n * - Trace propagation headers (when enabled)\n * - Span creation for outgoing requests (when createSpansForOutgoingRequests is enabled)\n *\n * Span creation requires Node 22+ and uses diagnostic channels to avoid monkey-patching.\n * By default, this is only enabled in the node SDK, not in node-core or other runtime SDKs.\n *\n * Important note: Contrary to other OTEL instrumentation, this one cannot be unwrapped.\n *\n * This is heavily inspired & adapted from:\n * https://github.com/open-telemetry/opentelemetry-js/blob/f8ab5592ddea5cba0a3b33bf8d74f27872c0367f/experimental/packages/opentelemetry-instrumentation-http/src/http.ts\n */\nexport class SentryHttpInstrumentation extends InstrumentationBase<SentryHttpInstrumentationOptions> {\n public constructor(config: SentryHttpInstrumentationOptions = {}) {\n super(INSTRUMENTATION_NAME, SDK_VERSION, config);\n }\n\n /** @inheritdoc */\n public init(): [InstrumentationNodeModuleDefinition, InstrumentationNodeModuleDefinition] {\n const { outgoingRequestApplyCustomAttributes: applyCustomAttributesOnSpan, ...options } = this.getConfig();\n const patchOptions: HttpInstrumentationOptions = {\n propagateTrace: options.propagateTraceInOutgoingRequests,\n applyCustomAttributesOnSpan,\n ...options,\n spans: options.createSpansForOutgoingRequests && (options.spans ?? true),\n ignoreOutgoingRequests(url, request) {\n return (\n isTracingSuppressed() || !!options.ignoreOutgoingRequests?.(url, getRequestOptions(request as ClientRequest))\n );\n },\n outgoingRequestHook(span, request) {\n options.outgoingRequestHook?.(span, request);\n // We monkey-patch `req.once('response'), which is used to trigger\n // the callback of the request, so that it runs in the active context\n // eslint-disable-next-line @typescript-eslint/unbound-method, typescript/no-deprecated\n const originalOnce = request.once;\n\n const newOnce = new Proxy(originalOnce, {\n apply(target, thisArg, args: Parameters<typeof originalOnce>) {\n const [event] = args;\n if (event !== 'response') {\n return target.apply(thisArg, args);\n }\n\n const parentContext = context.active();\n const requestContext = trace.setSpan(parentContext, span);\n\n return context.with(requestContext, () => {\n return target.apply(thisArg, args);\n });\n },\n });\n\n // eslint-disable-next-line typescript/no-deprecated\n request.once = newOnce;\n },\n outgoingResponseHook(span, response) {\n options.outgoingResponseHook?.(span, response);\n context.bind(context.active(), response);\n },\n errorMonitor,\n // Pass these in to detect OTel double-wrapping if we're enabling spans\n http,\n https,\n };\n\n // only generate the subscriber function if we'll actually use it\n const { [HTTP_ON_CLIENT_REQUEST]: onHttpClientRequestCreated } = FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL\n ? getHttpClientSubscriptions(patchOptions)\n : {};\n\n // guard because we cover both http and https with the same subscribers\n let hasRegisteredHandlers = false;\n const sub = onHttpClientRequestCreated\n ? <T extends HttpModuleExport>(moduleExports: T): T => {\n if (!hasRegisteredHandlers && onHttpClientRequestCreated) {\n hasRegisteredHandlers = true;\n subscribe(HTTP_ON_CLIENT_REQUEST, onHttpClientRequestCreated);\n }\n return moduleExports;\n }\n : undefined;\n\n const wrapHttp = sub ?? ((moduleExports: HttpModuleExport) => patchHttpModuleClient(moduleExports, patchOptions));\n\n const wrapHttps = sub ?? ((moduleExports: HttpModuleExport) => patchHttpModuleClient(moduleExports, patchOptions));\n\n /**\n * You may be wondering why we register these diagnostics-channel listeners\n * in such a convoluted way (as InstrumentationNodeModuleDefinition...)˝,\n * instead of simply subscribing to the events once in here.\n * The reason for this is timing semantics: These functions are called once the http or https module is loaded.\n * If we'd subscribe before that, there seem to be conflicts with the OTEL native instrumentation in some scenarios,\n * especially the \"import-on-top\" pattern of setting up ESM applications.\n */\n return [\n new InstrumentationNodeModuleDefinition('http', ['*'], wrapHttp),\n new InstrumentationNodeModuleDefinition('https', ['*'], wrapHttps),\n ];\n }\n}\n"],"names":[],"mappings":"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"}
{"version":3,"file":"SentryHttpInstrumentation.js","sources":["../../../../src/integrations/http/SentryHttpInstrumentation.ts"],"sourcesContent":["import type { ChannelListener } from 'node:diagnostics_channel';\nimport { subscribe, unsubscribe } from 'node:diagnostics_channel';\nimport { context, trace } from '@opentelemetry/api';\nimport type { InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport { InstrumentationBase } from '@opentelemetry/instrumentation';\nimport type { ClientRequest, IncomingMessage, ServerResponse } from 'node:http';\nimport type { HttpClientRequest, HttpIncomingMessage, HttpInstrumentationOptions, Span } from '@sentry/core';\nimport {\n getHttpClientSubscriptions,\n patchHttpModuleClient,\n SDK_VERSION,\n getRequestOptions,\n isTracingSuppressed,\n} from '@sentry/core';\nimport { INSTRUMENTATION_NAME } from './constants';\nimport { HTTP_ON_CLIENT_REQUEST } from '@sentry/core';\nimport { NODE_VERSION } from '../../nodeVersion';\nimport { errorMonitor } from 'node:events';\nimport * as http from 'node:http';\n\nconst FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL =\n (NODE_VERSION.major === 22 && NODE_VERSION.minor >= 12) ||\n (NODE_VERSION.major === 23 && NODE_VERSION.minor >= 2) ||\n NODE_VERSION.major >= 24;\n\ninterface OutgoingHttpRequestInstrumentationOptions {\n /**\n * Whether breadcrumbs should be recorded for outgoing requests.\n *\n * @default `true`\n */\n breadcrumbs?: boolean;\n\n /**\n * Whether to create spans for outgoing requests (user preference).\n * This only takes effect if `createSpansForOutgoingRequests` is not disabled.\n * If `createSpansForOutgoingRequests` is explicitly set false, this option is ignored.\n *\n * @default `true`\n */\n spans?: boolean;\n\n /**\n * Whether to propagate Sentry trace headers in outgoing requests.\n *\n * @default `true`\n */\n propagateTraceInOutgoingRequests?: boolean;\n\n /**\n * @deprecated Use spans option instead.\n *\n * @default `true`\n */\n createSpansForOutgoingRequests?: boolean;\n\n /**\n * Do not instrument outgoing HTTP requests to URLs where the given callback returns `true`.\n * When it returns `true`, the request is skipped entirely: no breadcrumb and no span are created,\n * and no trace headers are propagated for that request.\n *\n * @param url Contains the entire URL, including query string (if any), protocol, host, etc. of the outgoing request.\n * @param request Contains the {@type RequestOptions} object used to make the outgoing request.\n */\n ignoreOutgoingRequests?: (url: string, request: http.RequestOptions) => boolean;\n\n /**\n * Hooks for outgoing request spans, only called when spans are created for outgoing requests\n * (i.e. when `spans` is enabled).\n * These mirror the OTEL HttpInstrumentation hooks for backwards compatibility.\n */\n outgoingRequestHook?: (span: Span, request: ClientRequest | HttpClientRequest) => void;\n outgoingResponseHook?: (span: Span, response: IncomingMessage | HttpIncomingMessage) => void;\n outgoingRequestApplyCustomAttributes?: (\n span: Span,\n request: HttpClientRequest,\n response: HttpIncomingMessage,\n ) => void;\n}\n\nexport type SentryHttpInstrumentationOptions = InstrumentationConfig &\n OutgoingHttpRequestInstrumentationOptions & {\n // All options below do not do anything anymore in this instrumentation, and will be removed in the future.\n // They are only kept here for backwards compatibility - the respective functionality is now handled by the httpServerIntegration/httpServerSpansIntegration.\n\n /**\n * @deprecated This no longer does anything.\n */\n extractIncomingTraceFromHeader?: boolean;\n\n /**\n * @deprecated This no longer does anything.\n */\n ignoreStaticAssets?: boolean;\n\n /**\n * @deprecated This no longer does anything.\n */\n disableIncomingRequestSpans?: boolean;\n\n /**\n * @deprecated This no longer does anything.\n */\n ignoreSpansForIncomingRequests?: (urlPath: string, request: IncomingMessage) => boolean;\n\n /**\n * @deprecated This no longer does anything.\n */\n ignoreIncomingRequestBody?: (url: string, request: http.RequestOptions) => boolean;\n\n /**\n * @deprecated This no longer does anything.\n */\n maxIncomingRequestBodySize?: 'none' | 'small' | 'medium' | 'always';\n\n /**\n * @deprecated This no longer does anything.\n */\n trackIncomingRequestsAsSessions?: boolean;\n\n /**\n * @deprecated This no longer does anything.\n */\n instrumentation?: {\n requestHook?: (span: Span, req: ClientRequest | IncomingMessage) => void;\n responseHook?: (span: Span, response: IncomingMessage | ServerResponse) => void;\n applyCustomAttributesOnSpan?: (\n span: Span,\n request: ClientRequest | IncomingMessage,\n response: IncomingMessage | ServerResponse,\n ) => void;\n };\n\n /**\n * @deprecated This no longer does anything.\n */\n sessionFlushingDelayMS?: number;\n };\n\n/**\n * This instruments the http modules for outgoing requests.\n * It uses the diagnostics channel if available, otherwise it falls back to monkey-patching.\n *\n * The instrumentation will start spans, create breadcrumbs, and propagate trace headers in outgoing requests (depending on the settings).\n * This can be called multiple times, where the last invocation will have the current options.\n *\n * @TODO Cleanup options in v11\n */\nexport function instrumentHttpOutgoingRequests(\n instrumentationOptions: OutgoingHttpRequestInstrumentationOptions = {},\n): void {\n const { outgoingRequestApplyCustomAttributes: applyCustomAttributesOnSpan, ...options } = instrumentationOptions;\n const patchOptions = {\n propagateTrace: options.propagateTraceInOutgoingRequests ?? true,\n applyCustomAttributesOnSpan,\n ...options,\n // oxlint-disable-next-line typescript/no-deprecated\n spans: options.createSpansForOutgoingRequests !== false && (options.spans ?? true),\n ignoreOutgoingRequests(url, request) {\n return (\n isTracingSuppressed() || !!options.ignoreOutgoingRequests?.(url, getRequestOptions(request as ClientRequest))\n );\n },\n outgoingRequestHook(span, request) {\n options.outgoingRequestHook?.(span, request);\n // We monkey-patch `req.once('response'), which is used to trigger\n // the callback of the request, so that it runs in the active context\n // eslint-disable-next-line @typescript-eslint/unbound-method, typescript/no-deprecated\n const originalOnce = request.once;\n\n const newOnce = new Proxy(originalOnce, {\n apply(target, thisArg, args: Parameters<typeof originalOnce>) {\n const [event] = args;\n if (event !== 'response') {\n return target.apply(thisArg, args);\n }\n\n const parentContext = context.active();\n const requestContext = trace.setSpan(parentContext, span);\n\n return context.with(requestContext, () => {\n return target.apply(thisArg, args);\n });\n },\n });\n\n // eslint-disable-next-line typescript/no-deprecated\n request.once = newOnce;\n },\n outgoingResponseHook(span, response) {\n options.outgoingResponseHook?.(span, response);\n context.bind(context.active(), response);\n },\n errorMonitor,\n // Pass these in to detect OTel double-wrapping if we're enabling spans\n http,\n } satisfies HttpInstrumentationOptions;\n\n if (FULLY_SUPPORTS_HTTP_DIAGNOSTICS_CHANNEL) {\n instrumentHttpOutgoingRequestsViaChannel(patchOptions);\n } else {\n instrumentHttpOutgoingRequestsViaMonkeyPatching(patchOptions);\n }\n}\n\nlet _currentListener: ChannelListener | undefined;\nfunction instrumentHttpOutgoingRequestsViaChannel(options: HttpInstrumentationOptions): void {\n const { [HTTP_ON_CLIENT_REQUEST]: onHttpClientRequestCreated } = getHttpClientSubscriptions(options);\n // If it was previously subscribed, first unsubscribe it\n // TODO(v11): We can likely remove this when we drop preload support\n if (_currentListener) {\n unsubscribe(HTTP_ON_CLIENT_REQUEST, _currentListener);\n }\n\n subscribe(HTTP_ON_CLIENT_REQUEST, onHttpClientRequestCreated);\n _currentListener = onHttpClientRequestCreated;\n}\n\n/**\n * Instrument outgoing HTTP(S) requests by old-school monkey-patching the `http` module.\n * This is the fallback for runtimes that do not fully support the `node:http` client diagnostics channel\n * (Node < 22.12).\n */\nfunction instrumentHttpOutgoingRequestsViaMonkeyPatching(options: HttpInstrumentationOptions): void {\n // Patching http also patches https, as this uses the same underlying object\n patchHttpModuleClient(http, options);\n}\n\n/**\n * This custom HTTP instrumentation handles outgoing HTTP requests.\n *\n * It provides:\n * - Breadcrumbs for all outgoing requests\n * - Trace propagation headers (when enabled)\n * - Span creation for outgoing requests (when createSpansForOutgoingRequests is enabled)\n *\n * Span creation requires Node 22+ and uses diagnostic channels to avoid monkey-patching.\n * By default, this is only enabled in the node SDK, not in node-core or other runtime SDKs.\n *\n * Important note: Contrary to other OTEL instrumentation, this one cannot be unwrapped.\n *\n * This is heavily inspired & adapted from:\n * https://github.com/open-telemetry/opentelemetry-js/blob/f8ab5592ddea5cba0a3b33bf8d74f27872c0367f/experimental/packages/opentelemetry-instrumentation-http/src/http.ts\n *\n * @deprecated This will be removed in v11. Use instrumentHttpOutgoingRequests() instead.\n */\nexport class SentryHttpInstrumentation extends InstrumentationBase<SentryHttpInstrumentationOptions> {\n public constructor(config: SentryHttpInstrumentationOptions = {}) {\n super(INSTRUMENTATION_NAME, SDK_VERSION, config);\n }\n\n /** @inheritdoc */\n public init(): void {\n instrumentHttpOutgoingRequests(this.getConfig());\n }\n}\n"],"names":[],"mappings":"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"}

@@ -6,3 +6,3 @@ import { Worker } from 'node:worker_threads';

const base64WorkerScript = "LyohIEBzZW50cnkvbm9kZS1jb3JlIDEwLjY0LjAgKDU3MzZhMzgpIHwgaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdCAqLwppbXBvcnR7U2Vzc2lvbiBhcyBlfWZyb20ibm9kZTppbnNwZWN0b3IvcHJvbWlzZXMiO2ltcG9ydHt3b3JrZXJEYXRhIGFzIHR9ZnJvbSJub2RlOndvcmtlcl90aHJlYWRzIjtjb25zdCBuPWdsb2JhbFRoaXMsaT17fTtjb25zdCBvPSJfX1NFTlRSWV9FUlJPUl9MT0NBTF9WQVJJQUJMRVNfXyI7Y29uc3QgYT10O2Z1bmN0aW9uIHMoLi4uZSl7YS5kZWJ1ZyYmZnVuY3Rpb24oZSl7aWYoISgiY29uc29sZSJpbiBuKSlyZXR1cm4gZSgpO2NvbnN0IHQ9bi5jb25zb2xlLG89e30sYT1PYmplY3Qua2V5cyhpKTthLmZvckVhY2goZT0+e2NvbnN0IG49aVtlXTtvW2VdPXRbZV0sdFtlXT1ufSk7dHJ5e3JldHVybiBlKCl9ZmluYWxseXthLmZvckVhY2goZT0+e3RbZV09b1tlXX0pfX0oKCk9PmNvbnNvbGUubG9nKCJbTG9jYWxWYXJpYWJsZXMgV29ya2VyXSIsLi4uZSkpfWFzeW5jIGZ1bmN0aW9uIGMoZSx0LG4saSl7Y29uc3Qgbz1hd2FpdCBlLnBvc3QoIlJ1bnRpbWUuZ2V0UHJvcGVydGllcyIse29iamVjdElkOnQsb3duUHJvcGVydGllczohMH0pO2lbbl09by5yZXN1bHQuZmlsdGVyKGU9PiJsZW5ndGgiIT09ZS5uYW1lJiYhaXNOYU4ocGFyc2VJbnQoZS5uYW1lLDEwKSkpLnNvcnQoKGUsdCk9PnBhcnNlSW50KGUubmFtZSwxMCktcGFyc2VJbnQodC5uYW1lLDEwKSkubWFwKGU9PmUudmFsdWU/LnZhbHVlKX1hc3luYyBmdW5jdGlvbiByKGUsdCxuLGkpe2NvbnN0IG89YXdhaXQgZS5wb3N0KCJSdW50aW1lLmdldFByb3BlcnRpZXMiLHtvYmplY3RJZDp0LG93blByb3BlcnRpZXM6ITB9KTtpW25dPW8ucmVzdWx0Lm1hcChlPT5bZS5uYW1lLGUudmFsdWU/LnZhbHVlXSkucmVkdWNlKChlLFt0LG5dKT0+KGVbdF09bixlKSx7fSl9ZnVuY3Rpb24gdShlLHQpe2UudmFsdWUmJigidmFsdWUiaW4gZS52YWx1ZT92b2lkIDA9PT1lLnZhbHVlLnZhbHVlfHxudWxsPT09ZS52YWx1ZS52YWx1ZT90W2UubmFtZV09YDwke2UudmFsdWUudmFsdWV9PmA6dFtlLm5hbWVdPWUudmFsdWUudmFsdWU6ImRlc2NyaXB0aW9uImluIGUudmFsdWUmJiJmdW5jdGlvbiIhPT1lLnZhbHVlLnR5cGU/dFtlLm5hbWVdPWA8JHtlLnZhbHVlLmRlc2NyaXB0aW9ufT5gOiJ1bmRlZmluZWQiPT09ZS52YWx1ZS50eXBlJiYodFtlLm5hbWVdPSI8dW5kZWZpbmVkPiIpKX1hc3luYyBmdW5jdGlvbiBsKGUsdCl7Y29uc3Qgbj1hd2FpdCBlLnBvc3QoIlJ1bnRpbWUuZ2V0UHJvcGVydGllcyIse29iamVjdElkOnQsb3duUHJvcGVydGllczohMH0pLGk9e307Zm9yKGNvbnN0IHQgb2Ygbi5yZXN1bHQpaWYodC52YWx1ZT8ub2JqZWN0SWQmJiJBcnJheSI9PT10LnZhbHVlLmNsYXNzTmFtZSl7Y29uc3Qgbj10LnZhbHVlLm9iamVjdElkO2F3YWl0IGMoZSxuLHQubmFtZSxpKX1lbHNlIGlmKHQudmFsdWU/Lm9iamVjdElkJiYiT2JqZWN0Ij09PXQudmFsdWUuY2xhc3NOYW1lKXtjb25zdCBuPXQudmFsdWUub2JqZWN0SWQ7YXdhaXQgcihlLG4sdC5uYW1lLGkpfWVsc2UgdC52YWx1ZSYmdSh0LGkpO3JldHVybiBpfWxldCBmOyhhc3luYyBmdW5jdGlvbigpe2NvbnN0IHQ9bmV3IGU7dC5jb25uZWN0VG9NYWluVGhyZWFkKCkscygiQ29ubmVjdGVkIHRvIG1haW4gdGhyZWFkIik7bGV0IG49ITE7dC5vbigiRGVidWdnZXIucmVzdW1lZCIsKCk9PntuPSExfSksdC5vbigiRGVidWdnZXIucGF1c2VkIixlPT57bj0hMCxhc3luYyBmdW5jdGlvbihlLHtyZWFzb246dCxkYXRhOntvYmplY3RJZDpufSxjYWxsRnJhbWVzOml9KXtpZigiZXhjZXB0aW9uIiE9PXQmJiJwcm9taXNlUmVqZWN0aW9uIiE9PXQpcmV0dXJuO2lmKGY/LigpLG51bGw9PW4pcmV0dXJuO2NvbnN0IGE9W107Zm9yKGxldCB0PTA7dDxpLmxlbmd0aDt0Kyspe2NvbnN0e3Njb3BlQ2hhaW46bixmdW5jdGlvbk5hbWU6byx0aGlzOnN9PWlbdF0sYz1uLmZpbmQoZT0+ImxvY2FsIj09PWUudHlwZSkscj0iZ2xvYmFsIiE9PXMuY2xhc3NOYW1lJiZzLmNsYXNzTmFtZT9gJHtzLmNsYXNzTmFtZX0uJHtvfWA6bztpZih2b2lkIDA9PT1jPy5vYmplY3Qub2JqZWN0SWQpYVt0XT17ZnVuY3Rpb246cn07ZWxzZXtjb25zdCBuPWF3YWl0IGwoZSxjLm9iamVjdC5vYmplY3RJZCk7YVt0XT17ZnVuY3Rpb246cix2YXJzOm59fX1hd2FpdCBlLnBvc3QoIlJ1bnRpbWUuY2FsbEZ1bmN0aW9uT24iLHtmdW5jdGlvbkRlY2xhcmF0aW9uOmBmdW5jdGlvbigpIHsgdGhpcy4ke299ID0gdGhpcy4ke299IHx8ICR7SlNPTi5zdHJpbmdpZnkoYSl9OyB9YCxzaWxlbnQ6ITAsb2JqZWN0SWQ6bn0pLGF3YWl0IGUucG9zdCgiUnVudGltZS5yZWxlYXNlT2JqZWN0Iix7b2JqZWN0SWQ6bn0pfSh0LGUucGFyYW1zKS50aGVuKGFzeW5jKCk9PntuJiZhd2FpdCB0LnBvc3QoIkRlYnVnZ2VyLnJlc3VtZSIpfSxhc3luYyBlPT57biYmYXdhaXQgdC5wb3N0KCJEZWJ1Z2dlci5yZXN1bWUiKX0pfSksYXdhaXQgdC5wb3N0KCJEZWJ1Z2dlci5lbmFibGUiKTtjb25zdCBpPSExIT09YS5jYXB0dXJlQWxsRXhjZXB0aW9ucztpZihhd2FpdCB0LnBvc3QoIkRlYnVnZ2VyLnNldFBhdXNlT25FeGNlcHRpb25zIix7c3RhdGU6aT8iYWxsIjoidW5jYXVnaHQifSksaSl7Y29uc3QgZT1hLm1heEV4Y2VwdGlvbnNQZXJTZWNvbmR8fDUwO2Y9ZnVuY3Rpb24oZSx0LG4pe2xldCBpPTAsbz01LGE9MDtyZXR1cm4gc2V0SW50ZXJ2YWwoKCk9PnswPT09YT9pPmUmJihvKj0yLG4obyksbz44NjQwMCYmKG89ODY0MDApLGE9byk6KGEtPTEsMD09PWEmJnQoKSksaT0wfSwxZTMpLnVucmVmKCksKCk9PntpKz0xfX0oZSxhc3luYygpPT57cygiUmF0ZS1saW1pdCBsaWZ0ZWQuIiksYXdhaXQgdC5wb3N0KCJEZWJ1Z2dlci5zZXRQYXVzZU9uRXhjZXB0aW9ucyIse3N0YXRlOiJhbGwifSl9LGFzeW5jIGU9PntzKGBSYXRlLWxpbWl0IGV4Y2VlZGVkLiBEaXNhYmxpbmcgY2FwdHVyaW5nIG9mIGNhdWdodCBleGNlcHRpb25zIGZvciAke2V9IHNlY29uZHMuYCksYXdhaXQgdC5wb3N0KCJEZWJ1Z2dlci5zZXRQYXVzZU9uRXhjZXB0aW9ucyIse3N0YXRlOiJ1bmNhdWdodCJ9KX0pfX0pKCkuY2F0Y2goZT0+e3MoIkZhaWxlZCB0byBzdGFydCBkZWJ1Z2dlciIsZSl9KSxzZXRJbnRlcnZhbCgoKT0+e30sMWU0KTs=";
const base64WorkerScript = "LyohIEBzZW50cnkvbm9kZS1jb3JlIDEwLjY1LjAgKGM2NmE4MTUpIHwgaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdCAqLwppbXBvcnR7U2Vzc2lvbiBhcyBlfWZyb20ibm9kZTppbnNwZWN0b3IvcHJvbWlzZXMiO2ltcG9ydHt3b3JrZXJEYXRhIGFzIHR9ZnJvbSJub2RlOndvcmtlcl90aHJlYWRzIjtjb25zdCBuPWdsb2JhbFRoaXMsaT17fTtjb25zdCBvPSJfX1NFTlRSWV9FUlJPUl9MT0NBTF9WQVJJQUJMRVNfXyI7Y29uc3QgYT10O2Z1bmN0aW9uIHMoLi4uZSl7YS5kZWJ1ZyYmZnVuY3Rpb24oZSl7aWYoISgiY29uc29sZSJpbiBuKSlyZXR1cm4gZSgpO2NvbnN0IHQ9bi5jb25zb2xlLG89e30sYT1PYmplY3Qua2V5cyhpKTthLmZvckVhY2goZT0+e2NvbnN0IG49aVtlXTtvW2VdPXRbZV0sdFtlXT1ufSk7dHJ5e3JldHVybiBlKCl9ZmluYWxseXthLmZvckVhY2goZT0+e3RbZV09b1tlXX0pfX0oKCk9PmNvbnNvbGUubG9nKCJbTG9jYWxWYXJpYWJsZXMgV29ya2VyXSIsLi4uZSkpfWFzeW5jIGZ1bmN0aW9uIGMoZSx0LG4saSl7Y29uc3Qgbz1hd2FpdCBlLnBvc3QoIlJ1bnRpbWUuZ2V0UHJvcGVydGllcyIse29iamVjdElkOnQsb3duUHJvcGVydGllczohMH0pO2lbbl09by5yZXN1bHQuZmlsdGVyKGU9PiJsZW5ndGgiIT09ZS5uYW1lJiYhaXNOYU4ocGFyc2VJbnQoZS5uYW1lLDEwKSkpLnNvcnQoKGUsdCk9PnBhcnNlSW50KGUubmFtZSwxMCktcGFyc2VJbnQodC5uYW1lLDEwKSkubWFwKGU9PmUudmFsdWU/LnZhbHVlKX1hc3luYyBmdW5jdGlvbiByKGUsdCxuLGkpe2NvbnN0IG89YXdhaXQgZS5wb3N0KCJSdW50aW1lLmdldFByb3BlcnRpZXMiLHtvYmplY3RJZDp0LG93blByb3BlcnRpZXM6ITB9KTtpW25dPW8ucmVzdWx0Lm1hcChlPT5bZS5uYW1lLGUudmFsdWU/LnZhbHVlXSkucmVkdWNlKChlLFt0LG5dKT0+KGVbdF09bixlKSx7fSl9ZnVuY3Rpb24gdShlLHQpe2UudmFsdWUmJigidmFsdWUiaW4gZS52YWx1ZT92b2lkIDA9PT1lLnZhbHVlLnZhbHVlfHxudWxsPT09ZS52YWx1ZS52YWx1ZT90W2UubmFtZV09YDwke2UudmFsdWUudmFsdWV9PmA6dFtlLm5hbWVdPWUudmFsdWUudmFsdWU6ImRlc2NyaXB0aW9uImluIGUudmFsdWUmJiJmdW5jdGlvbiIhPT1lLnZhbHVlLnR5cGU/dFtlLm5hbWVdPWA8JHtlLnZhbHVlLmRlc2NyaXB0aW9ufT5gOiJ1bmRlZmluZWQiPT09ZS52YWx1ZS50eXBlJiYodFtlLm5hbWVdPSI8dW5kZWZpbmVkPiIpKX1hc3luYyBmdW5jdGlvbiBsKGUsdCl7Y29uc3Qgbj1hd2FpdCBlLnBvc3QoIlJ1bnRpbWUuZ2V0UHJvcGVydGllcyIse29iamVjdElkOnQsb3duUHJvcGVydGllczohMH0pLGk9e307Zm9yKGNvbnN0IHQgb2Ygbi5yZXN1bHQpaWYodC52YWx1ZT8ub2JqZWN0SWQmJiJBcnJheSI9PT10LnZhbHVlLmNsYXNzTmFtZSl7Y29uc3Qgbj10LnZhbHVlLm9iamVjdElkO2F3YWl0IGMoZSxuLHQubmFtZSxpKX1lbHNlIGlmKHQudmFsdWU/Lm9iamVjdElkJiYiT2JqZWN0Ij09PXQudmFsdWUuY2xhc3NOYW1lKXtjb25zdCBuPXQudmFsdWUub2JqZWN0SWQ7YXdhaXQgcihlLG4sdC5uYW1lLGkpfWVsc2UgdC52YWx1ZSYmdSh0LGkpO3JldHVybiBpfWxldCBmOyhhc3luYyBmdW5jdGlvbigpe2NvbnN0IHQ9bmV3IGU7dC5jb25uZWN0VG9NYWluVGhyZWFkKCkscygiQ29ubmVjdGVkIHRvIG1haW4gdGhyZWFkIik7bGV0IG49ITE7dC5vbigiRGVidWdnZXIucmVzdW1lZCIsKCk9PntuPSExfSksdC5vbigiRGVidWdnZXIucGF1c2VkIixlPT57bj0hMCxhc3luYyBmdW5jdGlvbihlLHtyZWFzb246dCxkYXRhOntvYmplY3RJZDpufSxjYWxsRnJhbWVzOml9KXtpZigiZXhjZXB0aW9uIiE9PXQmJiJwcm9taXNlUmVqZWN0aW9uIiE9PXQpcmV0dXJuO2lmKGY/LigpLG51bGw9PW4pcmV0dXJuO2NvbnN0IGE9W107Zm9yKGxldCB0PTA7dDxpLmxlbmd0aDt0Kyspe2NvbnN0e3Njb3BlQ2hhaW46bixmdW5jdGlvbk5hbWU6byx0aGlzOnN9PWlbdF0sYz1uLmZpbmQoZT0+ImxvY2FsIj09PWUudHlwZSkscj0iZ2xvYmFsIiE9PXMuY2xhc3NOYW1lJiZzLmNsYXNzTmFtZT9gJHtzLmNsYXNzTmFtZX0uJHtvfWA6bztpZih2b2lkIDA9PT1jPy5vYmplY3Qub2JqZWN0SWQpYVt0XT17ZnVuY3Rpb246cn07ZWxzZXtjb25zdCBuPWF3YWl0IGwoZSxjLm9iamVjdC5vYmplY3RJZCk7YVt0XT17ZnVuY3Rpb246cix2YXJzOm59fX1hd2FpdCBlLnBvc3QoIlJ1bnRpbWUuY2FsbEZ1bmN0aW9uT24iLHtmdW5jdGlvbkRlY2xhcmF0aW9uOmBmdW5jdGlvbigpIHsgdGhpcy4ke299ID0gdGhpcy4ke299IHx8ICR7SlNPTi5zdHJpbmdpZnkoYSl9OyB9YCxzaWxlbnQ6ITAsb2JqZWN0SWQ6bn0pLGF3YWl0IGUucG9zdCgiUnVudGltZS5yZWxlYXNlT2JqZWN0Iix7b2JqZWN0SWQ6bn0pfSh0LGUucGFyYW1zKS50aGVuKGFzeW5jKCk9PntuJiZhd2FpdCB0LnBvc3QoIkRlYnVnZ2VyLnJlc3VtZSIpfSxhc3luYyBlPT57biYmYXdhaXQgdC5wb3N0KCJEZWJ1Z2dlci5yZXN1bWUiKX0pfSksYXdhaXQgdC5wb3N0KCJEZWJ1Z2dlci5lbmFibGUiKTtjb25zdCBpPSExIT09YS5jYXB0dXJlQWxsRXhjZXB0aW9ucztpZihhd2FpdCB0LnBvc3QoIkRlYnVnZ2VyLnNldFBhdXNlT25FeGNlcHRpb25zIix7c3RhdGU6aT8iYWxsIjoidW5jYXVnaHQifSksaSl7Y29uc3QgZT1hLm1heEV4Y2VwdGlvbnNQZXJTZWNvbmR8fDUwO2Y9ZnVuY3Rpb24oZSx0LG4pe2xldCBpPTAsbz01LGE9MDtyZXR1cm4gc2V0SW50ZXJ2YWwoKCk9PnswPT09YT9pPmUmJihvKj0yLG4obyksbz44NjQwMCYmKG89ODY0MDApLGE9byk6KGEtPTEsMD09PWEmJnQoKSksaT0wfSwxZTMpLnVucmVmKCksKCk9PntpKz0xfX0oZSxhc3luYygpPT57cygiUmF0ZS1saW1pdCBsaWZ0ZWQuIiksYXdhaXQgdC5wb3N0KCJEZWJ1Z2dlci5zZXRQYXVzZU9uRXhjZXB0aW9ucyIse3N0YXRlOiJhbGwifSl9LGFzeW5jIGU9PntzKGBSYXRlLWxpbWl0IGV4Y2VlZGVkLiBEaXNhYmxpbmcgY2FwdHVyaW5nIG9mIGNhdWdodCBleGNlcHRpb25zIGZvciAke2V9IHNlY29uZHMuYCksYXdhaXQgdC5wb3N0KCJEZWJ1Z2dlci5zZXRQYXVzZU9uRXhjZXB0aW9ucyIse3N0YXRlOiJ1bmNhdWdodCJ9KX0pfX0pKCkuY2F0Y2goZT0+e3MoIkZhaWxlZCB0byBzdGFydCBkZWJ1Z2dlciIsZSl9KSxzZXRJbnRlcnZhbCgoKT0+e30sMWU0KTs=";
function log(...args) {

@@ -9,0 +9,0 @@ debug.log("[LocalVariables]", ...args);

@@ -1,2 +0,2 @@

/*! @sentry/node-core 10.64.0 (5736a38) | https://github.com/getsentry/sentry-javascript */
/*! @sentry/node-core 10.65.0 (c66a815) | https://github.com/getsentry/sentry-javascript */
import{Session as e}from"node:inspector/promises";import{workerData as t}from"node:worker_threads";const n=globalThis,i={};const o="__SENTRY_ERROR_LOCAL_VARIABLES__";const a=t;function s(...e){a.debug&&function(e){if(!("console"in n))return e();const t=n.console,o={},a=Object.keys(i);a.forEach(e=>{const n=i[e];o[e]=t[e],t[e]=n});try{return e()}finally{a.forEach(e=>{t[e]=o[e]})}}(()=>console.log("[LocalVariables Worker]",...e))}async function c(e,t,n,i){const o=await e.post("Runtime.getProperties",{objectId:t,ownProperties:!0});i[n]=o.result.filter(e=>"length"!==e.name&&!isNaN(parseInt(e.name,10))).sort((e,t)=>parseInt(e.name,10)-parseInt(t.name,10)).map(e=>e.value?.value)}async function r(e,t,n,i){const o=await e.post("Runtime.getProperties",{objectId:t,ownProperties:!0});i[n]=o.result.map(e=>[e.name,e.value?.value]).reduce((e,[t,n])=>(e[t]=n,e),{})}function u(e,t){e.value&&("value"in e.value?void 0===e.value.value||null===e.value.value?t[e.name]=`<${e.value.value}>`:t[e.name]=e.value.value:"description"in e.value&&"function"!==e.value.type?t[e.name]=`<${e.value.description}>`:"undefined"===e.value.type&&(t[e.name]="<undefined>"))}async function l(e,t){const n=await e.post("Runtime.getProperties",{objectId:t,ownProperties:!0}),i={};for(const t of n.result)if(t.value?.objectId&&"Array"===t.value.className){const n=t.value.objectId;await c(e,n,t.name,i)}else if(t.value?.objectId&&"Object"===t.value.className){const n=t.value.objectId;await r(e,n,t.name,i)}else t.value&&u(t,i);return i}let f;(async function(){const t=new e;t.connectToMainThread(),s("Connected to main thread");let n=!1;t.on("Debugger.resumed",()=>{n=!1}),t.on("Debugger.paused",e=>{n=!0,async function(e,{reason:t,data:{objectId:n},callFrames:i}){if("exception"!==t&&"promiseRejection"!==t)return;if(f?.(),null==n)return;const a=[];for(let t=0;t<i.length;t++){const{scopeChain:n,functionName:o,this:s}=i[t],c=n.find(e=>"local"===e.type),r="global"!==s.className&&s.className?`${s.className}.${o}`:o;if(void 0===c?.object.objectId)a[t]={function:r};else{const n=await l(e,c.object.objectId);a[t]={function:r,vars:n}}}await e.post("Runtime.callFunctionOn",{functionDeclaration:`function() { this.${o} = this.${o} || ${JSON.stringify(a)}; }`,silent:!0,objectId:n}),await e.post("Runtime.releaseObject",{objectId:n})}(t,e.params).then(async()=>{n&&await t.post("Debugger.resume")},async e=>{n&&await t.post("Debugger.resume")})}),await t.post("Debugger.enable");const i=!1!==a.captureAllExceptions;if(await t.post("Debugger.setPauseOnExceptions",{state:i?"all":"uncaught"}),i){const e=a.maxExceptionsPerSecond||50;f=function(e,t,n){let i=0,o=5,a=0;return setInterval(()=>{0===a?i>e&&(o*=2,n(o),o>86400&&(o=86400),a=o):(a-=1,0===a&&t()),i=0},1e3).unref(),()=>{i+=1}}(e,async()=>{s("Rate-limit lifted."),await t.post("Debugger.setPauseOnExceptions",{state:"all"})},async e=>{s(`Rate-limit exceeded. Disabling capturing of caught exceptions for ${e} seconds.`),await t.post("Debugger.setPauseOnExceptions",{state:"uncaught"})})}})().catch(e=>{s("Failed to start debugger",e)}),setInterval(()=>{},1e4);

@@ -1,2 +0,2 @@

import { defineIntegration, getClient, withActiveSpan, consoleSandbox, captureException, isMatchingPattern } from '@sentry/core';
import { defineIntegration, getClient, isObjectLike, withActiveSpan, consoleSandbox, captureException, isMatchingPattern } from '@sentry/core';
import { logAndExitProcess } from '../utils/errorhandling.js';

@@ -29,3 +29,3 @@

function extractErrorInfo(reason) {
if (typeof reason !== "object" || reason === null) {
if (!isObjectLike(reason)) {
return { name: "", message: String(reason ?? "") };

@@ -56,3 +56,3 @@ }

const level = options.mode === "strict" ? "fatal" : "error";
const activeSpanForError = reason && typeof reason === "object" ? reason._sentry_active_span : void 0;
const activeSpanForError = isObjectLike(reason) ? reason._sentry_active_span : void 0;
const activeSpanWrapper = activeSpanForError ? (fn) => withActiveSpan(activeSpanForError, fn) : (fn) => fn();

@@ -80,3 +80,3 @@ activeSpanWrapper(() => {

console.warn(rejectionWarning);
console.error(reason && typeof reason === "object" && "stack" in reason ? reason.stack : reason);
console.error(isObjectLike(reason) && "stack" in reason ? reason.stack : reason);
});

@@ -83,0 +83,0 @@ } else if (mode === "strict") {

@@ -1,1 +0,1 @@

{"version":3,"file":"onunhandledrejection.js","sources":["../../../src/integrations/onunhandledrejection.ts"],"sourcesContent":["import type { Client, IntegrationFn, SeverityLevel, Span } from '@sentry/core';\nimport {\n captureException,\n consoleSandbox,\n defineIntegration,\n getClient,\n isMatchingPattern,\n withActiveSpan,\n} from '@sentry/core';\nimport { logAndExitProcess } from '../utils/errorhandling';\n\ntype UnhandledRejectionMode = 'none' | 'warn' | 'strict';\n\ntype IgnoreMatcher = { name?: string | RegExp; message?: string | RegExp };\n\ninterface OnUnhandledRejectionOptions {\n /**\n * Option deciding what to do after capturing unhandledRejection,\n * that mimicks behavior of node's --unhandled-rejection flag.\n */\n mode: UnhandledRejectionMode;\n /** Rejection Errors to ignore (don't capture or warn). */\n ignore?: IgnoreMatcher[];\n}\n\nconst INTEGRATION_NAME = 'OnUnhandledRejection';\n\nconst DEFAULT_IGNORES: IgnoreMatcher[] = [\n {\n name: 'AI_NoOutputGeneratedError', // When stream aborts in Vercel AI SDK V5, Vercel flush() fails with an error\n },\n {\n name: 'AbortError', // When stream aborts in Vercel AI SDK V6\n },\n];\n\nconst _onUnhandledRejectionIntegration = ((options: Partial<OnUnhandledRejectionOptions> = {}) => {\n const opts: OnUnhandledRejectionOptions = {\n mode: options.mode ?? 'warn',\n ignore: [...DEFAULT_IGNORES, ...(options.ignore ?? [])],\n };\n\n return {\n name: INTEGRATION_NAME,\n setup(client) {\n global.process.on('unhandledRejection', makeUnhandledPromiseHandler(client, opts));\n },\n };\n}) satisfies IntegrationFn;\n\nexport const onUnhandledRejectionIntegration = defineIntegration(_onUnhandledRejectionIntegration);\n\n/** Extract error info safely */\nfunction extractErrorInfo(reason: unknown): { name: string; message: string } {\n // Check if reason is an object (including Error instances, not just plain objects)\n if (typeof reason !== 'object' || reason === null) {\n return { name: '', message: String(reason ?? '') };\n }\n\n const errorLike = reason as Record<string, unknown>;\n const name = typeof errorLike.name === 'string' ? errorLike.name : '';\n const message = typeof errorLike.message === 'string' ? errorLike.message : String(reason);\n\n return { name, message };\n}\n\n/** Check if a matcher matches the reason */\nfunction isMatchingReason(matcher: IgnoreMatcher, errorInfo: ReturnType<typeof extractErrorInfo>): boolean {\n // name/message matcher\n const nameMatches = matcher.name === undefined || isMatchingPattern(errorInfo.name, matcher.name, true);\n\n const messageMatches = matcher.message === undefined || isMatchingPattern(errorInfo.message, matcher.message);\n\n return nameMatches && messageMatches;\n}\n\n/** Match helper */\nfunction matchesIgnore(list: IgnoreMatcher[], reason: unknown): boolean {\n const errorInfo = extractErrorInfo(reason);\n return list.some(matcher => isMatchingReason(matcher, errorInfo));\n}\n\n/** Core handler */\nexport function makeUnhandledPromiseHandler(\n client: Client,\n options: OnUnhandledRejectionOptions,\n): (reason: unknown, promise: unknown) => void {\n return function sendUnhandledPromise(reason: unknown, _promise: unknown): void {\n // Only handle for the active client\n if (getClient() !== client) {\n return;\n }\n\n // Skip if configured to ignore\n if (matchesIgnore(options.ignore ?? [], reason)) {\n return;\n }\n\n const level: SeverityLevel = options.mode === 'strict' ? 'fatal' : 'error';\n\n // this can be set in places where we cannot reliably get access to the active span/error\n // when the error bubbles up to this handler, we can use this to set the active span\n const activeSpanForError =\n reason && typeof reason === 'object' ? (reason as { _sentry_active_span?: Span })._sentry_active_span : undefined;\n\n const activeSpanWrapper = activeSpanForError\n ? (fn: () => void) => withActiveSpan(activeSpanForError, fn)\n : (fn: () => void) => fn();\n\n activeSpanWrapper(() => {\n captureException(reason, {\n originalException: reason,\n captureContext: {\n extra: { unhandledPromiseRejection: true },\n level,\n },\n mechanism: {\n handled: false,\n type: 'auto.node.onunhandledrejection',\n },\n });\n });\n\n handleRejection(reason, options.mode);\n };\n}\n\n/**\n * Handler for `mode` option\n */\nfunction handleRejection(reason: unknown, mode: UnhandledRejectionMode): void {\n // https://github.com/nodejs/node/blob/7cf6f9e964aa00772965391c23acda6d71972a9a/lib/internal/process/promises.js#L234-L240\n const rejectionWarning =\n 'This error originated either by ' +\n 'throwing inside of an async function without a catch block, ' +\n 'or by rejecting a promise which was not handled with .catch().' +\n ' The promise rejected with the reason:';\n\n /* eslint-disable no-console */\n if (mode === 'warn') {\n consoleSandbox(() => {\n console.warn(rejectionWarning);\n console.error(reason && typeof reason === 'object' && 'stack' in reason ? reason.stack : reason);\n });\n } else if (mode === 'strict') {\n consoleSandbox(() => {\n console.warn(rejectionWarning);\n });\n logAndExitProcess(reason);\n }\n /* eslint-enable no-console */\n}\n"],"names":[],"mappings":"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"}
{"version":3,"file":"onunhandledrejection.js","sources":["../../../src/integrations/onunhandledrejection.ts"],"sourcesContent":["import type { Client, IntegrationFn, SeverityLevel, Span } from '@sentry/core';\nimport {\n captureException,\n consoleSandbox,\n defineIntegration,\n getClient,\n isMatchingPattern,\n isObjectLike,\n withActiveSpan,\n} from '@sentry/core';\nimport { logAndExitProcess } from '../utils/errorhandling';\n\ntype UnhandledRejectionMode = 'none' | 'warn' | 'strict';\n\ntype IgnoreMatcher = { name?: string | RegExp; message?: string | RegExp };\n\ninterface OnUnhandledRejectionOptions {\n /**\n * Option deciding what to do after capturing unhandledRejection,\n * that mimicks behavior of node's --unhandled-rejection flag.\n */\n mode: UnhandledRejectionMode;\n /** Rejection Errors to ignore (don't capture or warn). */\n ignore?: IgnoreMatcher[];\n}\n\nconst INTEGRATION_NAME = 'OnUnhandledRejection';\n\nconst DEFAULT_IGNORES: IgnoreMatcher[] = [\n {\n name: 'AI_NoOutputGeneratedError', // When stream aborts in Vercel AI SDK V5, Vercel flush() fails with an error\n },\n {\n name: 'AbortError', // When stream aborts in Vercel AI SDK V6\n },\n];\n\nconst _onUnhandledRejectionIntegration = ((options: Partial<OnUnhandledRejectionOptions> = {}) => {\n const opts: OnUnhandledRejectionOptions = {\n mode: options.mode ?? 'warn',\n ignore: [...DEFAULT_IGNORES, ...(options.ignore ?? [])],\n };\n\n return {\n name: INTEGRATION_NAME,\n setup(client) {\n global.process.on('unhandledRejection', makeUnhandledPromiseHandler(client, opts));\n },\n };\n}) satisfies IntegrationFn;\n\nexport const onUnhandledRejectionIntegration = defineIntegration(_onUnhandledRejectionIntegration);\n\n/** Extract error info safely */\nfunction extractErrorInfo(reason: unknown): { name: string; message: string } {\n // Check if reason is an object (including Error instances, not just plain objects)\n if (!isObjectLike(reason)) {\n return { name: '', message: String(reason ?? '') };\n }\n\n const errorLike = reason as Record<string, unknown>;\n const name = typeof errorLike.name === 'string' ? errorLike.name : '';\n const message = typeof errorLike.message === 'string' ? errorLike.message : String(reason);\n\n return { name, message };\n}\n\n/** Check if a matcher matches the reason */\nfunction isMatchingReason(matcher: IgnoreMatcher, errorInfo: ReturnType<typeof extractErrorInfo>): boolean {\n // name/message matcher\n const nameMatches = matcher.name === undefined || isMatchingPattern(errorInfo.name, matcher.name, true);\n\n const messageMatches = matcher.message === undefined || isMatchingPattern(errorInfo.message, matcher.message);\n\n return nameMatches && messageMatches;\n}\n\n/** Match helper */\nfunction matchesIgnore(list: IgnoreMatcher[], reason: unknown): boolean {\n const errorInfo = extractErrorInfo(reason);\n return list.some(matcher => isMatchingReason(matcher, errorInfo));\n}\n\n/** Core handler */\nexport function makeUnhandledPromiseHandler(\n client: Client,\n options: OnUnhandledRejectionOptions,\n): (reason: unknown, promise: unknown) => void {\n return function sendUnhandledPromise(reason: unknown, _promise: unknown): void {\n // Only handle for the active client\n if (getClient() !== client) {\n return;\n }\n\n // Skip if configured to ignore\n if (matchesIgnore(options.ignore ?? [], reason)) {\n return;\n }\n\n const level: SeverityLevel = options.mode === 'strict' ? 'fatal' : 'error';\n\n // this can be set in places where we cannot reliably get access to the active span/error\n // when the error bubbles up to this handler, we can use this to set the active span\n const activeSpanForError = isObjectLike(reason)\n ? (reason as { _sentry_active_span?: Span })._sentry_active_span\n : undefined;\n\n const activeSpanWrapper = activeSpanForError\n ? (fn: () => void) => withActiveSpan(activeSpanForError, fn)\n : (fn: () => void) => fn();\n\n activeSpanWrapper(() => {\n captureException(reason, {\n originalException: reason,\n captureContext: {\n extra: { unhandledPromiseRejection: true },\n level,\n },\n mechanism: {\n handled: false,\n type: 'auto.node.onunhandledrejection',\n },\n });\n });\n\n handleRejection(reason, options.mode);\n };\n}\n\n/**\n * Handler for `mode` option\n */\nfunction handleRejection(reason: unknown, mode: UnhandledRejectionMode): void {\n // https://github.com/nodejs/node/blob/7cf6f9e964aa00772965391c23acda6d71972a9a/lib/internal/process/promises.js#L234-L240\n const rejectionWarning =\n 'This error originated either by ' +\n 'throwing inside of an async function without a catch block, ' +\n 'or by rejecting a promise which was not handled with .catch().' +\n ' The promise rejected with the reason:';\n\n /* eslint-disable no-console */\n if (mode === 'warn') {\n consoleSandbox(() => {\n console.warn(rejectionWarning);\n console.error(isObjectLike(reason) && 'stack' in reason ? reason.stack : reason);\n });\n } else if (mode === 'strict') {\n consoleSandbox(() => {\n console.warn(rejectionWarning);\n });\n logAndExitProcess(reason);\n }\n /* eslint-enable no-console */\n}\n"],"names":[],"mappings":"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"}
import * as diagnosticsChannel from 'node:diagnostics_channel';
import { defineIntegration, _INTERNAL_captureLog, severityLevelFromString, withScope, addExceptionMechanism, captureException, captureMessage } from '@sentry/core';
import { defineIntegration, isObjectLike, _INTERNAL_captureLog, severityLevelFromString, withScope, addExceptionMechanism, captureException, captureMessage } from '@sentry/core';

@@ -102,3 +102,3 @@ const SENTRY_TRACK_SYMBOL = /* @__PURE__ */ Symbol("sentry-track-pino-logger");

trackLogger(logger) {
if (logger && typeof logger === "object" && "levels" in logger) {
if (isObjectLike(logger) && "levels" in logger) {
logger[SENTRY_TRACK_SYMBOL] = "track";

@@ -108,3 +108,3 @@ }

untrackLogger(logger) {
if (logger && typeof logger === "object" && "levels" in logger) {
if (isObjectLike(logger) && "levels" in logger) {
logger[SENTRY_TRACK_SYMBOL] = "ignore";

@@ -111,0 +111,0 @@ }

@@ -1,1 +0,1 @@

{"version":3,"file":"pino.js","sources":["../../../src/integrations/pino.ts"],"sourcesContent":["import * as diagnosticsChannel from 'node:diagnostics_channel';\nimport type { Integration, IntegrationFn, LogSeverityLevel } from '@sentry/core';\nimport {\n _INTERNAL_captureLog,\n addExceptionMechanism,\n captureException,\n captureMessage,\n defineIntegration,\n severityLevelFromString,\n withScope,\n} from '@sentry/core';\n\nconst SENTRY_TRACK_SYMBOL = Symbol('sentry-track-pino-logger');\n\ntype LevelMapping = {\n // Fortunately pino uses the same levels as Sentry\n labels: { [level: number]: LogSeverityLevel };\n};\n\ntype Pino = {\n [key: symbol]: unknown;\n levels: LevelMapping;\n [SENTRY_TRACK_SYMBOL]?: 'track' | 'ignore';\n};\n\n/**\n * Gets a custom Pino key from a logger instance by searching for the symbol.\n * Pino uses non-global symbols like Symbol('pino.messageKey'): https://github.com/pinojs/pino/blob/8a816c0b1f72de5ae9181f3bb402109b66f7d812/lib/symbols.js\n */\nfunction getPinoKey(logger: Pino, symbolName: string, defaultKey: string): string {\n const symbols = Object.getOwnPropertySymbols(logger);\n const symbolString = `Symbol(${symbolName})`;\n for (const sym of symbols) {\n if (sym.toString() === symbolString) {\n const value = logger[sym];\n return typeof value === 'string' ? value : defaultKey;\n }\n }\n return defaultKey;\n}\n\ntype MergeObject = {\n [key: string]: unknown;\n err?: Error;\n};\n\ntype PinoHookArgs = [MergeObject, string, number];\n\ntype PinoOptions = {\n /**\n * Automatically instrument all Pino loggers.\n *\n * When set to `false`, only loggers marked with `pinoIntegration.trackLogger(logger)` will be captured.\n *\n * @default true\n */\n autoInstrument: boolean;\n /**\n * Options to enable capturing of error events.\n */\n error: {\n /**\n * Levels that trigger capturing of events.\n *\n * @default []\n */\n levels: LogSeverityLevel[];\n /**\n * By default, Sentry will mark captured errors as handled.\n * Set this to `false` if you want to mark them as unhandled instead.\n *\n * @default true\n */\n handled: boolean;\n };\n /**\n * Options to enable capturing of logs.\n */\n log: {\n /**\n * Levels that trigger capturing of logs. Logs are only captured if\n * `enableLogs` is enabled.\n *\n * @default [\"trace\", \"debug\", \"info\", \"warn\", \"error\", \"fatal\"]\n */\n levels: LogSeverityLevel[];\n };\n};\n\nconst DEFAULT_OPTIONS: PinoOptions = {\n autoInstrument: true,\n error: { levels: [], handled: true },\n log: { levels: ['trace', 'debug', 'info', 'warn', 'error', 'fatal'] },\n};\n\ntype DeepPartial<T> = {\n [P in keyof T]?: T[P] extends object ? Partial<T[P]> : T[P];\n};\n\ntype PinoResult = {\n level?: string;\n time?: string;\n pid?: number;\n hostname?: string;\n} & Record<string, unknown>;\n\nfunction stripIgnoredFields(result: PinoResult): PinoResult {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { level, time, pid, hostname, ...rest } = result;\n return rest;\n}\n\nconst _pinoIntegration = defineIntegration((userOptions: DeepPartial<PinoOptions> = {}) => {\n const options: PinoOptions = {\n autoInstrument: userOptions.autoInstrument !== false,\n error: { ...DEFAULT_OPTIONS.error, ...userOptions.error },\n log: { ...DEFAULT_OPTIONS.log, ...userOptions.log },\n };\n\n function shouldTrackLogger(logger: Pino): boolean {\n const override = logger[SENTRY_TRACK_SYMBOL];\n return override === 'track' || (override !== 'ignore' && options.autoInstrument);\n }\n\n return {\n name: 'Pino',\n setup: client => {\n const enableLogs = !!client.getOptions().enableLogs;\n\n const integratedChannel = diagnosticsChannel.tracingChannel('pino_asJson');\n\n function onPinoStart(self: Pino, args: PinoHookArgs, result: PinoResult): void {\n if (!shouldTrackLogger(self)) {\n return;\n }\n\n const resultObj = stripIgnoredFields(result);\n\n const [captureObj, message, levelNumber] = args;\n const level = self?.levels?.labels?.[levelNumber] || 'info';\n const messageKey = getPinoKey(self, 'pino.messageKey', 'msg');\n const logMessage = message || (resultObj?.[messageKey] as string | undefined) || '';\n\n if (enableLogs && options.log.levels.includes(level)) {\n const attributes: Record<string, unknown> = {\n ...resultObj,\n 'sentry.origin': 'auto.log.pino',\n 'pino.logger.level': levelNumber,\n };\n\n _INTERNAL_captureLog({ level, message: logMessage, attributes });\n }\n\n if (options.error.levels.includes(level)) {\n const errorKey = getPinoKey(self, 'pino.errorKey', 'err');\n\n // Attach the log message and remaining log fields (e.g. child logger\n // bindings, merge object fields) to the event. The serialized error is\n // excluded since it is captured as the event exception itself.\n const pinoContext: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(resultObj)) {\n if (key !== errorKey && key !== messageKey) {\n pinoContext[key] = value;\n }\n }\n if (logMessage) {\n pinoContext[messageKey] = logMessage;\n }\n\n const captureContext = {\n level: severityLevelFromString(level),\n contexts: { pino: pinoContext },\n };\n\n withScope(scope => {\n scope.addEventProcessor(event => {\n event.logger = 'pino';\n\n addExceptionMechanism(event, {\n handled: options.error.handled,\n type: 'auto.log.pino',\n });\n\n return event;\n });\n\n const error = captureObj[errorKey];\n if (error) {\n captureException(error, captureContext);\n return;\n }\n\n captureMessage(logMessage, captureContext);\n });\n }\n }\n\n integratedChannel.end.subscribe(data => {\n const {\n instance,\n arguments: args,\n result,\n } = data as { instance: Pino; arguments: PinoHookArgs; result: string };\n onPinoStart(instance, args, JSON.parse(result));\n });\n },\n };\n}) satisfies IntegrationFn;\n\ninterface PinoIntegrationFunction {\n (userOptions?: DeepPartial<PinoOptions>): Integration;\n /**\n * Marks a Pino logger to be tracked by the Pino integration.\n *\n * @param logger A Pino logger instance.\n */\n trackLogger(logger: unknown): void;\n /**\n * Marks a Pino logger to be ignored by the Pino integration.\n *\n * @param logger A Pino logger instance.\n */\n untrackLogger(logger: unknown): void;\n}\n\n/**\n * Integration for Pino logging library.\n * Captures Pino logs as Sentry logs and optionally captures some log levels as events.\n *\n * By default, all Pino loggers will be captured. To ignore a specific logger, use `pinoIntegration.untrackLogger(logger)`.\n *\n * If you disable automatic instrumentation with `autoInstrument: false`, you can mark specific loggers to be tracked with `pinoIntegration.trackLogger(logger)`.\n *\n * Requires Pino >=v8.0.0 and Node >=20.6.0 or >=18.19.0\n */\nexport const pinoIntegration = Object.assign(_pinoIntegration, {\n trackLogger(logger: unknown): void {\n if (logger && typeof logger === 'object' && 'levels' in logger) {\n (logger as Pino)[SENTRY_TRACK_SYMBOL] = 'track';\n }\n },\n untrackLogger(logger: unknown): void {\n if (logger && typeof logger === 'object' && 'levels' in logger) {\n (logger as Pino)[SENTRY_TRACK_SYMBOL] = 'ignore';\n }\n },\n}) as PinoIntegrationFunction;\n"],"names":[],"mappings":"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"}
{"version":3,"file":"pino.js","sources":["../../../src/integrations/pino.ts"],"sourcesContent":["import * as diagnosticsChannel from 'node:diagnostics_channel';\nimport type { Integration, IntegrationFn, LogSeverityLevel } from '@sentry/core';\nimport {\n _INTERNAL_captureLog,\n addExceptionMechanism,\n captureException,\n captureMessage,\n defineIntegration,\n isObjectLike,\n severityLevelFromString,\n withScope,\n} from '@sentry/core';\n\nconst SENTRY_TRACK_SYMBOL = Symbol('sentry-track-pino-logger');\n\ntype LevelMapping = {\n // Fortunately pino uses the same levels as Sentry\n labels: { [level: number]: LogSeverityLevel };\n};\n\ntype Pino = {\n [key: symbol]: unknown;\n levels: LevelMapping;\n [SENTRY_TRACK_SYMBOL]?: 'track' | 'ignore';\n};\n\n/**\n * Gets a custom Pino key from a logger instance by searching for the symbol.\n * Pino uses non-global symbols like Symbol('pino.messageKey'): https://github.com/pinojs/pino/blob/8a816c0b1f72de5ae9181f3bb402109b66f7d812/lib/symbols.js\n */\nfunction getPinoKey(logger: Pino, symbolName: string, defaultKey: string): string {\n const symbols = Object.getOwnPropertySymbols(logger);\n const symbolString = `Symbol(${symbolName})`;\n for (const sym of symbols) {\n if (sym.toString() === symbolString) {\n const value = logger[sym];\n return typeof value === 'string' ? value : defaultKey;\n }\n }\n return defaultKey;\n}\n\ntype MergeObject = {\n [key: string]: unknown;\n err?: Error;\n};\n\ntype PinoHookArgs = [MergeObject, string, number];\n\ntype PinoOptions = {\n /**\n * Automatically instrument all Pino loggers.\n *\n * When set to `false`, only loggers marked with `pinoIntegration.trackLogger(logger)` will be captured.\n *\n * @default true\n */\n autoInstrument: boolean;\n /**\n * Options to enable capturing of error events.\n */\n error: {\n /**\n * Levels that trigger capturing of events.\n *\n * @default []\n */\n levels: LogSeverityLevel[];\n /**\n * By default, Sentry will mark captured errors as handled.\n * Set this to `false` if you want to mark them as unhandled instead.\n *\n * @default true\n */\n handled: boolean;\n };\n /**\n * Options to enable capturing of logs.\n */\n log: {\n /**\n * Levels that trigger capturing of logs. Logs are only captured if\n * `enableLogs` is enabled.\n *\n * @default [\"trace\", \"debug\", \"info\", \"warn\", \"error\", \"fatal\"]\n */\n levels: LogSeverityLevel[];\n };\n};\n\nconst DEFAULT_OPTIONS: PinoOptions = {\n autoInstrument: true,\n error: { levels: [], handled: true },\n log: { levels: ['trace', 'debug', 'info', 'warn', 'error', 'fatal'] },\n};\n\ntype DeepPartial<T> = {\n [P in keyof T]?: T[P] extends object ? Partial<T[P]> : T[P];\n};\n\ntype PinoResult = {\n level?: string;\n time?: string;\n pid?: number;\n hostname?: string;\n} & Record<string, unknown>;\n\nfunction stripIgnoredFields(result: PinoResult): PinoResult {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { level, time, pid, hostname, ...rest } = result;\n return rest;\n}\n\nconst _pinoIntegration = defineIntegration((userOptions: DeepPartial<PinoOptions> = {}) => {\n const options: PinoOptions = {\n autoInstrument: userOptions.autoInstrument !== false,\n error: { ...DEFAULT_OPTIONS.error, ...userOptions.error },\n log: { ...DEFAULT_OPTIONS.log, ...userOptions.log },\n };\n\n function shouldTrackLogger(logger: Pino): boolean {\n const override = logger[SENTRY_TRACK_SYMBOL];\n return override === 'track' || (override !== 'ignore' && options.autoInstrument);\n }\n\n return {\n name: 'Pino',\n setup: client => {\n const enableLogs = !!client.getOptions().enableLogs;\n\n const integratedChannel = diagnosticsChannel.tracingChannel('pino_asJson');\n\n function onPinoStart(self: Pino, args: PinoHookArgs, result: PinoResult): void {\n if (!shouldTrackLogger(self)) {\n return;\n }\n\n const resultObj = stripIgnoredFields(result);\n\n const [captureObj, message, levelNumber] = args;\n const level = self?.levels?.labels?.[levelNumber] || 'info';\n const messageKey = getPinoKey(self, 'pino.messageKey', 'msg');\n const logMessage = message || (resultObj?.[messageKey] as string | undefined) || '';\n\n if (enableLogs && options.log.levels.includes(level)) {\n const attributes: Record<string, unknown> = {\n ...resultObj,\n 'sentry.origin': 'auto.log.pino',\n 'pino.logger.level': levelNumber,\n };\n\n _INTERNAL_captureLog({ level, message: logMessage, attributes });\n }\n\n if (options.error.levels.includes(level)) {\n const errorKey = getPinoKey(self, 'pino.errorKey', 'err');\n\n // Attach the log message and remaining log fields (e.g. child logger\n // bindings, merge object fields) to the event. The serialized error is\n // excluded since it is captured as the event exception itself.\n const pinoContext: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(resultObj)) {\n if (key !== errorKey && key !== messageKey) {\n pinoContext[key] = value;\n }\n }\n if (logMessage) {\n pinoContext[messageKey] = logMessage;\n }\n\n const captureContext = {\n level: severityLevelFromString(level),\n contexts: { pino: pinoContext },\n };\n\n withScope(scope => {\n scope.addEventProcessor(event => {\n event.logger = 'pino';\n\n addExceptionMechanism(event, {\n handled: options.error.handled,\n type: 'auto.log.pino',\n });\n\n return event;\n });\n\n const error = captureObj[errorKey];\n if (error) {\n captureException(error, captureContext);\n return;\n }\n\n captureMessage(logMessage, captureContext);\n });\n }\n }\n\n integratedChannel.end.subscribe(data => {\n const {\n instance,\n arguments: args,\n result,\n } = data as { instance: Pino; arguments: PinoHookArgs; result: string };\n onPinoStart(instance, args, JSON.parse(result));\n });\n },\n };\n}) satisfies IntegrationFn;\n\ninterface PinoIntegrationFunction {\n (userOptions?: DeepPartial<PinoOptions>): Integration;\n /**\n * Marks a Pino logger to be tracked by the Pino integration.\n *\n * @param logger A Pino logger instance.\n */\n trackLogger(logger: unknown): void;\n /**\n * Marks a Pino logger to be ignored by the Pino integration.\n *\n * @param logger A Pino logger instance.\n */\n untrackLogger(logger: unknown): void;\n}\n\n/**\n * Integration for Pino logging library.\n * Captures Pino logs as Sentry logs and optionally captures some log levels as events.\n *\n * By default, all Pino loggers will be captured. To ignore a specific logger, use `pinoIntegration.untrackLogger(logger)`.\n *\n * If you disable automatic instrumentation with `autoInstrument: false`, you can mark specific loggers to be tracked with `pinoIntegration.trackLogger(logger)`.\n *\n * Requires Pino >=v8.0.0 and Node >=20.6.0 or >=18.19.0\n */\nexport const pinoIntegration = Object.assign(_pinoIntegration, {\n trackLogger(logger: unknown): void {\n if (isObjectLike(logger) && 'levels' in logger) {\n (logger as Pino)[SENTRY_TRACK_SYMBOL] = 'track';\n }\n },\n untrackLogger(logger: unknown): void {\n if (isObjectLike(logger) && 'levels' in logger) {\n (logger as Pino)[SENTRY_TRACK_SYMBOL] = 'ignore';\n }\n },\n}) as PinoIntegrationFunction;\n"],"names":[],"mappings":"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"}

@@ -1,2 +0,2 @@

import { debug } from '@sentry/core';
import { isObjectLike, debug } from '@sentry/core';
import { DEBUG_BUILD } from '../debug-build.js';

@@ -24,3 +24,3 @@ import { captureLog } from '../logs/capture.js';

});
if (!isObject(info)) {
if (!isObjectLike(info)) {
return;

@@ -55,5 +55,2 @@ }

}
function isObject(anything) {
return typeof anything === "object" && anything != null;
}
const WINSTON_LEVEL_TO_LOG_SEVERITY_LEVEL_MAP = {

@@ -60,0 +57,0 @@ // npm

@@ -1,1 +0,1 @@

{"version":3,"file":"winston.js","sources":["../../../src/integrations/winston.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/ban-ts-comment */\nimport type { LogSeverityLevel } from '@sentry/core';\nimport { debug } from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { captureLog } from '../logs/capture';\n\nconst DEFAULT_CAPTURED_LEVELS: Array<LogSeverityLevel> = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'];\n\n// See: https://github.com/winstonjs/triple-beam\nconst LEVEL_SYMBOL = Symbol.for('level');\nconst MESSAGE_SYMBOL = Symbol.for('message');\nconst SPLAT_SYMBOL = Symbol.for('splat');\n\n/**\n * Options for the Sentry Winston transport.\n */\ninterface WinstonTransportOptions {\n /**\n * Use this option to filter which levels should be captured. By default, all levels are captured.\n *\n * @example\n * ```ts\n * const SentryWinstonTransport = Sentry.createSentryWinstonTransport(Transport, {\n * // Only capture error and warn logs\n * levels: ['error', 'warn'],\n * });\n * ```\n */\n levels?: Array<LogSeverityLevel>;\n\n /**\n * Use this option to map custom levels to Sentry log severity levels.\n *\n * @example\n * ```ts\n * const SentryWinstonTransport = Sentry.createSentryWinstonTransport(Transport, {\n * customLevelMap: {\n * myCustomLevel: 'info',\n * customError: 'error',\n * },\n * });\n * ```\n */\n customLevelMap?: Record<string, LogSeverityLevel>;\n}\n\n/**\n * Creates a new Sentry Winston transport that fowards logs to Sentry. Requires the `enableLogs` option to be enabled.\n *\n * Supports Winston 3.x.x.\n *\n * @param TransportClass - The Winston transport class to extend.\n * @returns The extended transport class.\n *\n * @example\n * ```ts\n * const winston = require('winston');\n * const Transport = require('winston-transport');\n *\n * const SentryWinstonTransport = Sentry.createSentryWinstonTransport(Transport);\n *\n * const logger = winston.createLogger({\n * transports: [new SentryWinstonTransport()],\n * });\n * ```\n */\nexport function createSentryWinstonTransport<TransportStreamInstance extends object>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n TransportClass: new (options?: any) => TransportStreamInstance,\n sentryWinstonOptions?: WinstonTransportOptions,\n): typeof TransportClass {\n // @ts-ignore - We know this is safe because SentryWinstonTransport extends TransportClass\n class SentryWinstonTransport extends TransportClass {\n private _levels: Set<LogSeverityLevel>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public constructor(options?: any) {\n super(options);\n this._levels = new Set(sentryWinstonOptions?.levels ?? DEFAULT_CAPTURED_LEVELS);\n }\n\n /**\n * Forwards a winston log to the Sentry SDK.\n */\n public log(info: unknown, callback: () => void): void {\n try {\n setImmediate(() => {\n // @ts-ignore - We know this is safe because SentryWinstonTransport extends TransportClass\n this.emit('logged', info);\n });\n\n if (!isObject(info)) {\n return;\n }\n\n const levelFromSymbol = info[LEVEL_SYMBOL];\n\n // See: https://github.com/winstonjs/winston?tab=readme-ov-file#streams-objectmode-and-info-objects\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { level, message, timestamp, ...attributes } = info;\n // Remove all symbols from the remaining attributes\n attributes[LEVEL_SYMBOL] = undefined;\n attributes[MESSAGE_SYMBOL] = undefined;\n attributes[SPLAT_SYMBOL] = undefined;\n\n const customLevel = sentryWinstonOptions?.customLevelMap?.[levelFromSymbol as string];\n const winstonLogLevel = WINSTON_LEVEL_TO_LOG_SEVERITY_LEVEL_MAP[levelFromSymbol as string];\n const logSeverityLevel = customLevel ?? winstonLogLevel ?? 'info';\n\n if (this._levels.has(logSeverityLevel)) {\n captureLog(logSeverityLevel, message as string, {\n ...attributes,\n 'sentry.origin': 'auto.log.winston',\n });\n } else if (!customLevel && !winstonLogLevel) {\n DEBUG_BUILD &&\n debug.log(\n `Winston log level ${levelFromSymbol} is not captured by Sentry. Please add ${levelFromSymbol} to the \"customLevelMap\" option of the Sentry Winston transport.`,\n );\n }\n } catch {\n // do nothing\n }\n\n if (callback) {\n callback();\n }\n }\n }\n\n return SentryWinstonTransport as typeof TransportClass;\n}\n\nfunction isObject(anything: unknown): anything is Record<string | symbol, unknown> {\n return typeof anything === 'object' && anything != null;\n}\n\n// npm\n// {\n// error: 0,\n// warn: 1,\n// info: 2,\n// http: 3,\n// verbose: 4,\n// debug: 5,\n// silly: 6\n// }\n//\n// syslog\n// {\n// emerg: 0,\n// alert: 1,\n// crit: 2,\n// error: 3,\n// warning: 4,\n// notice: 5,\n// info: 6,\n// debug: 7,\n// }\nconst WINSTON_LEVEL_TO_LOG_SEVERITY_LEVEL_MAP: Record<string, LogSeverityLevel> = {\n // npm\n silly: 'trace',\n // npm and syslog\n debug: 'debug',\n // npm\n verbose: 'debug',\n // npm\n http: 'debug',\n // npm and syslog\n info: 'info',\n // syslog\n notice: 'info',\n // npm\n warn: 'warn',\n // syslog\n warning: 'warn',\n // npm and syslog\n error: 'error',\n // syslog\n emerg: 'fatal',\n // syslog\n alert: 'fatal',\n // syslog\n crit: 'fatal',\n};\n"],"names":[],"mappings":"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"}
{"version":3,"file":"winston.js","sources":["../../../src/integrations/winston.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/ban-ts-comment */\nimport type { LogSeverityLevel } from '@sentry/core';\nimport { debug, isObjectLike } from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { captureLog } from '../logs/capture';\n\nconst DEFAULT_CAPTURED_LEVELS: Array<LogSeverityLevel> = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'];\n\n// See: https://github.com/winstonjs/triple-beam\nconst LEVEL_SYMBOL = Symbol.for('level');\nconst MESSAGE_SYMBOL = Symbol.for('message');\nconst SPLAT_SYMBOL = Symbol.for('splat');\n\n/**\n * Options for the Sentry Winston transport.\n */\ninterface WinstonTransportOptions {\n /**\n * Use this option to filter which levels should be captured. By default, all levels are captured.\n *\n * @example\n * ```ts\n * const SentryWinstonTransport = Sentry.createSentryWinstonTransport(Transport, {\n * // Only capture error and warn logs\n * levels: ['error', 'warn'],\n * });\n * ```\n */\n levels?: Array<LogSeverityLevel>;\n\n /**\n * Use this option to map custom levels to Sentry log severity levels.\n *\n * @example\n * ```ts\n * const SentryWinstonTransport = Sentry.createSentryWinstonTransport(Transport, {\n * customLevelMap: {\n * myCustomLevel: 'info',\n * customError: 'error',\n * },\n * });\n * ```\n */\n customLevelMap?: Record<string, LogSeverityLevel>;\n}\n\n/**\n * Creates a new Sentry Winston transport that fowards logs to Sentry. Requires the `enableLogs` option to be enabled.\n *\n * Supports Winston 3.x.x.\n *\n * @param TransportClass - The Winston transport class to extend.\n * @returns The extended transport class.\n *\n * @example\n * ```ts\n * const winston = require('winston');\n * const Transport = require('winston-transport');\n *\n * const SentryWinstonTransport = Sentry.createSentryWinstonTransport(Transport);\n *\n * const logger = winston.createLogger({\n * transports: [new SentryWinstonTransport()],\n * });\n * ```\n */\nexport function createSentryWinstonTransport<TransportStreamInstance extends object>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n TransportClass: new (options?: any) => TransportStreamInstance,\n sentryWinstonOptions?: WinstonTransportOptions,\n): typeof TransportClass {\n // @ts-ignore - We know this is safe because SentryWinstonTransport extends TransportClass\n class SentryWinstonTransport extends TransportClass {\n private _levels: Set<LogSeverityLevel>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public constructor(options?: any) {\n super(options);\n this._levels = new Set(sentryWinstonOptions?.levels ?? DEFAULT_CAPTURED_LEVELS);\n }\n\n /**\n * Forwards a winston log to the Sentry SDK.\n */\n public log(info: unknown, callback: () => void): void {\n try {\n setImmediate(() => {\n // @ts-ignore - We know this is safe because SentryWinstonTransport extends TransportClass\n this.emit('logged', info);\n });\n\n if (!isObjectLike(info)) {\n return;\n }\n\n const levelFromSymbol = info[LEVEL_SYMBOL];\n\n // See: https://github.com/winstonjs/winston?tab=readme-ov-file#streams-objectmode-and-info-objects\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { level, message, timestamp, ...attributes } = info;\n // Remove all symbols from the remaining attributes\n attributes[LEVEL_SYMBOL] = undefined;\n attributes[MESSAGE_SYMBOL] = undefined;\n attributes[SPLAT_SYMBOL] = undefined;\n\n const customLevel = sentryWinstonOptions?.customLevelMap?.[levelFromSymbol as string];\n const winstonLogLevel = WINSTON_LEVEL_TO_LOG_SEVERITY_LEVEL_MAP[levelFromSymbol as string];\n const logSeverityLevel = customLevel ?? winstonLogLevel ?? 'info';\n\n if (this._levels.has(logSeverityLevel)) {\n captureLog(logSeverityLevel, message as string, {\n ...attributes,\n 'sentry.origin': 'auto.log.winston',\n });\n } else if (!customLevel && !winstonLogLevel) {\n DEBUG_BUILD &&\n debug.log(\n `Winston log level ${levelFromSymbol} is not captured by Sentry. Please add ${levelFromSymbol} to the \"customLevelMap\" option of the Sentry Winston transport.`,\n );\n }\n } catch {\n // do nothing\n }\n\n if (callback) {\n callback();\n }\n }\n }\n\n return SentryWinstonTransport as typeof TransportClass;\n}\n\n// npm\n// {\n// error: 0,\n// warn: 1,\n// info: 2,\n// http: 3,\n// verbose: 4,\n// debug: 5,\n// silly: 6\n// }\n//\n// syslog\n// {\n// emerg: 0,\n// alert: 1,\n// crit: 2,\n// error: 3,\n// warning: 4,\n// notice: 5,\n// info: 6,\n// debug: 7,\n// }\nconst WINSTON_LEVEL_TO_LOG_SEVERITY_LEVEL_MAP: Record<string, LogSeverityLevel> = {\n // npm\n silly: 'trace',\n // npm and syslog\n debug: 'debug',\n // npm\n verbose: 'debug',\n // npm\n http: 'debug',\n // npm and syslog\n info: 'info',\n // syslog\n notice: 'info',\n // npm\n warn: 'warn',\n // syslog\n warning: 'warn',\n // npm and syslog\n error: 'error',\n // syslog\n emerg: 'fatal',\n // syslog\n alert: 'fatal',\n // syslog\n crit: 'fatal',\n};\n"],"names":[],"mappings":";;;;AAMA,MAAM,0BAAmD,CAAC,OAAA,EAAS,SAAS,MAAA,EAAQ,MAAA,EAAQ,SAAS,OAAO,CAAA;AAG5G,MAAM,YAAA,mBAAe,MAAA,CAAO,GAAA,CAAI,OAAO,CAAA;AACvC,MAAM,cAAA,mBAAiB,MAAA,CAAO,GAAA,CAAI,SAAS,CAAA;AAC3C,MAAM,YAAA,mBAAe,MAAA,CAAO,GAAA,CAAI,OAAO,CAAA;AAuDhC,SAAS,4BAAA,CAEd,gBACA,oBAAA,EACuB;AAAA,EAEvB,MAAM,+BAA+B,cAAA,CAAe;AAAA;AAAA,IAG3C,YAAY,OAAA,EAAe;AAChC,MAAA,KAAA,CAAM,OAAO,CAAA;AACb,MAAA,IAAA,CAAK,OAAA,GAAU,IAAI,GAAA,CAAI,oBAAA,EAAsB,UAAU,uBAAuB,CAAA;AAAA,IAChF;AAAA;AAAA;AAAA;AAAA,IAKO,GAAA,CAAI,MAAe,QAAA,EAA4B;AACpD,MAAA,IAAI;AACF,QAAA,YAAA,CAAa,MAAM;AAEjB,UAAA,IAAA,CAAK,IAAA,CAAK,UAAU,IAAI,CAAA;AAAA,QAC1B,CAAC,CAAA;AAED,QAAA,IAAI,CAAC,YAAA,CAAa,IAAI,CAAA,EAAG;AACvB,UAAA;AAAA,QACF;AAEA,QAAA,MAAM,eAAA,GAAkB,KAAK,YAAY,CAAA;AAIzC,QAAA,MAAM,EAAE,KAAA,EAAO,OAAA,EAAS,SAAA,EAAW,GAAG,YAAW,GAAI,IAAA;AAErD,QAAA,UAAA,CAAW,YAAY,CAAA,GAAI,KAAA,CAAA;AAC3B,QAAA,UAAA,CAAW,cAAc,CAAA,GAAI,KAAA,CAAA;AAC7B,QAAA,UAAA,CAAW,YAAY,CAAA,GAAI,KAAA,CAAA;AAE3B,QAAA,MAAM,WAAA,GAAc,oBAAA,EAAsB,cAAA,GAAiB,eAAyB,CAAA;AACpF,QAAA,MAAM,eAAA,GAAkB,wCAAwC,eAAyB,CAAA;AACzF,QAAA,MAAM,gBAAA,GAAmB,eAAe,eAAA,IAAmB,MAAA;AAE3D,QAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,gBAAgB,CAAA,EAAG;AACtC,UAAA,UAAA,CAAW,kBAAkB,OAAA,EAAmB;AAAA,YAC9C,GAAG,UAAA;AAAA,YACH,eAAA,EAAiB;AAAA,WAClB,CAAA;AAAA,QACH,CAAA,MAAA,IAAW,CAAC,WAAA,IAAe,CAAC,eAAA,EAAiB;AAC3C,UAAA,WAAA,IACE,KAAA,CAAM,GAAA;AAAA,YACJ,CAAA,kBAAA,EAAqB,eAAe,CAAA,uCAAA,EAA0C,eAAe,CAAA,gEAAA;AAAA,WAC/F;AAAA,QACJ;AAAA,MACF,CAAA,CAAA,MAAQ;AAAA,MAER;AAEA,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,QAAA,EAAS;AAAA,MACX;AAAA,IACF;AAAA;AAGF,EAAA,OAAO,sBAAA;AACT;AAwBA,MAAM,uCAAA,GAA4E;AAAA;AAAA,EAEhF,KAAA,EAAO,OAAA;AAAA;AAAA,EAEP,KAAA,EAAO,OAAA;AAAA;AAAA,EAEP,OAAA,EAAS,OAAA;AAAA;AAAA,EAET,IAAA,EAAM,OAAA;AAAA;AAAA,EAEN,IAAA,EAAM,MAAA;AAAA;AAAA,EAEN,MAAA,EAAQ,MAAA;AAAA;AAAA,EAER,IAAA,EAAM,MAAA;AAAA;AAAA,EAEN,OAAA,EAAS,MAAA;AAAA;AAAA,EAET,KAAA,EAAO,OAAA;AAAA;AAAA,EAEP,KAAA,EAAO,OAAA;AAAA;AAAA,EAEP,KAAA,EAAO,OAAA;AAAA;AAAA,EAEP,IAAA,EAAM;AACR,CAAA;;;;"}

@@ -1,1 +0,1 @@

{"type":"module","version":"10.64.0","sideEffects":false}
{"type":"module","version":"10.65.0","sideEffects":false}

@@ -6,3 +6,3 @@ export { httpIntegration } from './integrations/http';

export { HttpServerSpansIntegrationOptions } from './integrations/http/httpServerSpansIntegration';
export { SentryHttpInstrumentation, SentryHttpInstrumentationOptions } from './integrations/http/SentryHttpInstrumentation';
export { SentryHttpInstrumentation, instrumentHttpOutgoingRequests, SentryHttpInstrumentationOptions } from './integrations/http/SentryHttpInstrumentation';
export { nativeNodeFetchIntegration } from './integrations/node-fetch';

@@ -9,0 +9,0 @@ export { NodeFetchOptions } from './integrations/node-fetch/types';

import { RequestOptions } from 'node:http';
import { HttpIncomingMessage } from '@sentry/core';
import { SentryHttpInstrumentationOptions } from './SentryHttpInstrumentation';
import { instrumentHttpOutgoingRequests } from './SentryHttpInstrumentation';
interface HttpOptions {

@@ -108,3 +108,3 @@ /**

}
export declare const instrumentSentryHttp: ((options?: SentryHttpInstrumentationOptions | undefined) => import("@opentelemetry/instrumentation").Instrumentation<import("@opentelemetry/instrumentation").InstrumentationConfig>) & {
export declare const instrumentSentryHttp: typeof instrumentHttpOutgoingRequests & {
id: string;

@@ -111,0 +111,0 @@ };

import { InstrumentationConfig } from '@opentelemetry/instrumentation';
import { InstrumentationBase, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';
import { InstrumentationBase } from '@opentelemetry/instrumentation';
import { ClientRequest, IncomingMessage, ServerResponse } from 'node:http';
import { HttpClientRequest, HttpIncomingMessage, Span } from '@sentry/core';
import * as http from 'node:http';
export type SentryHttpInstrumentationOptions = InstrumentationConfig & {
interface OutgoingHttpRequestInstrumentationOptions {
/**

@@ -14,32 +14,25 @@ * Whether breadcrumbs should be recorded for outgoing requests.

/**
* Whether to propagate Sentry trace headers in outgoing requests.
* By default this is done by the HttpInstrumentation, but if that is not added (e.g. because tracing is disabled)
* then this instrumentation can take over.
* Whether to create spans for outgoing requests (user preference).
* This only takes effect if `createSpansForOutgoingRequests` is not disabled.
* If `createSpansForOutgoingRequests` is explicitly set false, this option is ignored.
*
* @default `false`
* @default `true`
*/
propagateTraceInOutgoingRequests?: boolean;
spans?: boolean;
/**
* Whether to enable the capability to create spans for outgoing requests via diagnostic channels.
* If enabled, spans will only be created if the `spans` option is also enabled (default: true).
* Whether to propagate Sentry trace headers in outgoing requests.
*
* This is a feature flag that should be enabled by SDKs when the runtime supports it (Node 22.12+).
* Individual users should not need to configure this directly.
*
* @default `false`
* @default `true`
*/
createSpansForOutgoingRequests?: boolean;
propagateTraceInOutgoingRequests?: boolean;
/**
* Whether to create spans for outgoing requests (user preference).
* This only takes effect if `createSpansForOutgoingRequests` is also enabled.
* If `createSpansForOutgoingRequests` is not enabled, this option is ignored.
* @deprecated Use spans option instead.
*
* @default `true`
*/
spans?: boolean;
createSpansForOutgoingRequests?: boolean;
/**
* Do not capture breadcrumbs for outgoing HTTP requests to URLs where the given callback returns `true`.
* For the scope of this instrumentation, this callback only controls breadcrumb creation.
* The same option can be passed to the top-level httpIntegration where it controls both, breadcrumb and
* span creation.
* Do not instrument outgoing HTTP requests to URLs where the given callback returns `true`.
* When it returns `true`, the request is skipped entirely: no breadcrumb and no span are created,
* and no trace headers are propagated for that request.
*

@@ -51,3 +44,4 @@ * @param url Contains the entire URL, including query string (if any), protocol, host, etc. of the outgoing request.

/**
* Hooks for outgoing request spans, called when `createSpansForOutgoingRequests` is enabled.
* Hooks for outgoing request spans, only called when spans are created for outgoing requests
* (i.e. when `spans` is enabled).
* These mirror the OTEL HttpInstrumentation hooks for backwards compatibility.

@@ -58,2 +52,4 @@ */

outgoingRequestApplyCustomAttributes?: (span: Span, request: HttpClientRequest, response: HttpIncomingMessage) => void;
}
export type SentryHttpInstrumentationOptions = InstrumentationConfig & OutgoingHttpRequestInstrumentationOptions & {
/**

@@ -101,2 +97,12 @@ * @deprecated This no longer does anything.

/**
* This instruments the http modules for outgoing requests.
* It uses the diagnostics channel if available, otherwise it falls back to monkey-patching.
*
* The instrumentation will start spans, create breadcrumbs, and propagate trace headers in outgoing requests (depending on the settings).
* This can be called multiple times, where the last invocation will have the current options.
*
* @TODO Cleanup options in v11
*/
export declare function instrumentHttpOutgoingRequests(instrumentationOptions?: OutgoingHttpRequestInstrumentationOptions): void;
/**
* This custom HTTP instrumentation handles outgoing HTTP requests.

@@ -116,2 +122,4 @@ *

* https://github.com/open-telemetry/opentelemetry-js/blob/f8ab5592ddea5cba0a3b33bf8d74f27872c0367f/experimental/packages/opentelemetry-instrumentation-http/src/http.ts
*
* @deprecated This will be removed in v11. Use instrumentHttpOutgoingRequests() instead.
*/

@@ -121,7 +129,5 @@ export declare class SentryHttpInstrumentation extends InstrumentationBase<SentryHttpInstrumentationOptions> {

/** @inheritdoc */
init(): [
InstrumentationNodeModuleDefinition,
InstrumentationNodeModuleDefinition
];
init(): void;
}
export {};
//# sourceMappingURL=SentryHttpInstrumentation.d.ts.map

@@ -6,3 +6,3 @@ export { httpIntegration } from './integrations/http';

export type { HttpServerSpansIntegrationOptions } from './integrations/http/httpServerSpansIntegration';
export { SentryHttpInstrumentation, type SentryHttpInstrumentationOptions, } from './integrations/http/SentryHttpInstrumentation';
export { SentryHttpInstrumentation, instrumentHttpOutgoingRequests, type SentryHttpInstrumentationOptions, } from './integrations/http/SentryHttpInstrumentation';
export { nativeNodeFetchIntegration } from './integrations/node-fetch';

@@ -9,0 +9,0 @@ export type { NodeFetchOptions } from './integrations/node-fetch/types';

@@ -1,1 +0,1 @@

{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,0BAA0B,EAAE,MAAM,gDAAgD,CAAC;AAC5F,OAAO,EAAE,qBAAqB,EAAE,MAAM,2CAA2C,CAAC;AAElF,YAAY,EAAE,4BAA4B,EAAE,MAAM,2CAA2C,CAAC;AAC9F,YAAY,EAAE,iCAAiC,EAAE,MAAM,gDAAgD,CAAC;AAExG,OAAO,EACL,yBAAyB,EACzB,KAAK,gCAAgC,GACtC,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kDAAkD,CAAC;AACpF,OAAO,EAEL,8BAA8B,EAC9B,KAAK,qCAAqC,GAC3C,MAAM,0DAA0D,CAAC;AAElE,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEhG,OAAO,EAAE,IAAI,EAAE,sBAAsB,EAAE,8BAA8B,EAAE,0BAA0B,EAAE,MAAM,OAAO,CAAC;AACjH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAE1E,YAAY,EAAE,iCAAiC,EAAE,MAAM,SAAS,CAAC;AAEjE,OAAO,EAEL,2CAA2C,IAAI,2BAA2B,GAC3E,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EAAE,cAAc,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AAEpF,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAEzD,YAAY,EAAE,kCAAkC,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAGvF,cAAc,kBAAkB,CAAC"}
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,0BAA0B,EAAE,MAAM,gDAAgD,CAAC;AAC5F,OAAO,EAAE,qBAAqB,EAAE,MAAM,2CAA2C,CAAC;AAElF,YAAY,EAAE,4BAA4B,EAAE,MAAM,2CAA2C,CAAC;AAC9F,YAAY,EAAE,iCAAiC,EAAE,MAAM,gDAAgD,CAAC;AAExG,OAAO,EAEL,yBAAyB,EACzB,8BAA8B,EAC9B,KAAK,gCAAgC,GACtC,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kDAAkD,CAAC;AACpF,OAAO,EAEL,8BAA8B,EAC9B,KAAK,qCAAqC,GAC3C,MAAM,0DAA0D,CAAC;AAElE,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEhG,OAAO,EAAE,IAAI,EAAE,sBAAsB,EAAE,8BAA8B,EAAE,0BAA0B,EAAE,MAAM,OAAO,CAAC;AACjH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAE1E,YAAY,EAAE,iCAAiC,EAAE,MAAM,SAAS,CAAC;AAEjE,OAAO,EAEL,2CAA2C,IAAI,2BAA2B,GAC3E,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EAAE,cAAc,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AAEpF,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAEzD,YAAY,EAAE,kCAAkC,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAGvF,cAAc,kBAAkB,CAAC"}
import type { RequestOptions } from 'node:http';
import type { HttpIncomingMessage } from '@sentry/core';
import type { SentryHttpInstrumentationOptions } from './SentryHttpInstrumentation';
import { instrumentHttpOutgoingRequests } from './SentryHttpInstrumentation';
interface HttpOptions {

@@ -105,3 +105,3 @@ /**

}
export declare const instrumentSentryHttp: ((options?: SentryHttpInstrumentationOptions | undefined) => import("@opentelemetry/instrumentation").Instrumentation<import("@opentelemetry/instrumentation").InstrumentationConfig>) & {
export declare const instrumentSentryHttp: typeof instrumentHttpOutgoingRequests & {
id: string;

@@ -108,0 +108,0 @@ };

@@ -1,1 +0,1 @@

{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/integrations/http/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAQxD,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,6BAA6B,CAAC;AAKpF,UAAU,WAAW;IACnB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;;;OAKG;IACH,+BAA+B,CAAC,EAAE,OAAO,CAAC;IAE1C;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAEhC;;;;;;;OAOG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;;;;;;;OASG;IACH,sBAAsB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC;IAE3E;;;;;;;;;OASG;IACH,sBAAsB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,KAAK,OAAO,CAAC;IAEpF;;;;;;OAMG;IACH,sCAAsC,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;IAEvE;;;;;;OAMG;IACH,yBAAyB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC;IAE9E;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;;;;;;;;;;;;OAaG;IACH,0BAA0B,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAEpE;;;OAGG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC;AAED,eAAO,MAAM,oBAAoB;;CAKhC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,eAAe;;CAgD1B,CAAC"}
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/integrations/http/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAQxD,OAAO,EAAE,8BAA8B,EAAE,MAAM,6BAA6B,CAAC;AAI7E,UAAU,WAAW;IACnB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;;;OAKG;IACH,+BAA+B,CAAC,EAAE,OAAO,CAAC;IAE1C;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAEhC;;;;;;;OAOG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;;;;;;;OASG;IACH,sBAAsB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC;IAE3E;;;;;;;;;OASG;IACH,sBAAsB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,KAAK,OAAO,CAAC;IAEpF;;;;;;OAMG;IACH,sCAAsC,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;IAEvE;;;;;;OAMG;IACH,yBAAyB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC;IAE9E;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;;;;;;;;;;;;OAaG;IACH,0BAA0B,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAEpE;;;OAGG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC;AAED,eAAO,MAAM,oBAAoB;;CAE/B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,eAAe;;CAiD1B,CAAC"}
import type { InstrumentationConfig } from '@opentelemetry/instrumentation';
import { InstrumentationBase, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';
import { InstrumentationBase } from '@opentelemetry/instrumentation';
import type { ClientRequest, IncomingMessage, ServerResponse } from 'node:http';
import type { HttpClientRequest, HttpIncomingMessage, Span } from '@sentry/core';
import * as http from 'node:http';
export type SentryHttpInstrumentationOptions = InstrumentationConfig & {
interface OutgoingHttpRequestInstrumentationOptions {
/**

@@ -14,32 +14,25 @@ * Whether breadcrumbs should be recorded for outgoing requests.

/**
* Whether to propagate Sentry trace headers in outgoing requests.
* By default this is done by the HttpInstrumentation, but if that is not added (e.g. because tracing is disabled)
* then this instrumentation can take over.
* Whether to create spans for outgoing requests (user preference).
* This only takes effect if `createSpansForOutgoingRequests` is not disabled.
* If `createSpansForOutgoingRequests` is explicitly set false, this option is ignored.
*
* @default `false`
* @default `true`
*/
propagateTraceInOutgoingRequests?: boolean;
spans?: boolean;
/**
* Whether to enable the capability to create spans for outgoing requests via diagnostic channels.
* If enabled, spans will only be created if the `spans` option is also enabled (default: true).
* Whether to propagate Sentry trace headers in outgoing requests.
*
* This is a feature flag that should be enabled by SDKs when the runtime supports it (Node 22.12+).
* Individual users should not need to configure this directly.
*
* @default `false`
* @default `true`
*/
createSpansForOutgoingRequests?: boolean;
propagateTraceInOutgoingRequests?: boolean;
/**
* Whether to create spans for outgoing requests (user preference).
* This only takes effect if `createSpansForOutgoingRequests` is also enabled.
* If `createSpansForOutgoingRequests` is not enabled, this option is ignored.
* @deprecated Use spans option instead.
*
* @default `true`
*/
spans?: boolean;
createSpansForOutgoingRequests?: boolean;
/**
* Do not capture breadcrumbs for outgoing HTTP requests to URLs where the given callback returns `true`.
* For the scope of this instrumentation, this callback only controls breadcrumb creation.
* The same option can be passed to the top-level httpIntegration where it controls both, breadcrumb and
* span creation.
* Do not instrument outgoing HTTP requests to URLs where the given callback returns `true`.
* When it returns `true`, the request is skipped entirely: no breadcrumb and no span are created,
* and no trace headers are propagated for that request.
*

@@ -51,3 +44,4 @@ * @param url Contains the entire URL, including query string (if any), protocol, host, etc. of the outgoing request.

/**
* Hooks for outgoing request spans, called when `createSpansForOutgoingRequests` is enabled.
* Hooks for outgoing request spans, only called when spans are created for outgoing requests
* (i.e. when `spans` is enabled).
* These mirror the OTEL HttpInstrumentation hooks for backwards compatibility.

@@ -58,2 +52,4 @@ */

outgoingRequestApplyCustomAttributes?: (span: Span, request: HttpClientRequest, response: HttpIncomingMessage) => void;
}
export type SentryHttpInstrumentationOptions = InstrumentationConfig & OutgoingHttpRequestInstrumentationOptions & {
/**

@@ -101,2 +97,12 @@ * @deprecated This no longer does anything.

/**
* This instruments the http modules for outgoing requests.
* It uses the diagnostics channel if available, otherwise it falls back to monkey-patching.
*
* The instrumentation will start spans, create breadcrumbs, and propagate trace headers in outgoing requests (depending on the settings).
* This can be called multiple times, where the last invocation will have the current options.
*
* @TODO Cleanup options in v11
*/
export declare function instrumentHttpOutgoingRequests(instrumentationOptions?: OutgoingHttpRequestInstrumentationOptions): void;
/**
* This custom HTTP instrumentation handles outgoing HTTP requests.

@@ -116,2 +122,4 @@ *

* https://github.com/open-telemetry/opentelemetry-js/blob/f8ab5592ddea5cba0a3b33bf8d74f27872c0367f/experimental/packages/opentelemetry-instrumentation-http/src/http.ts
*
* @deprecated This will be removed in v11. Use instrumentHttpOutgoingRequests() instead.
*/

@@ -121,4 +129,5 @@ export declare class SentryHttpInstrumentation extends InstrumentationBase<SentryHttpInstrumentationOptions> {

/** @inheritdoc */
init(): [InstrumentationNodeModuleDefinition, InstrumentationNodeModuleDefinition];
init(): void;
}
export {};
//# sourceMappingURL=SentryHttpInstrumentation.d.ts.map

@@ -1,1 +0,1 @@

{"version":3,"file":"SentryHttpInstrumentation.d.ts","sourceRoot":"","sources":["../../../../src/integrations/http/SentryHttpInstrumentation.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,mCAAmC,EAAE,MAAM,gCAAgC,CAAC;AAC1G,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChF,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EAGnB,IAAI,EACL,MAAM,cAAc,CAAC;AAYtB,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAQlC,MAAM,MAAM,gCAAgC,GAAG,qBAAqB,GAAG;IACrE;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;;;OAMG;IACH,gCAAgC,CAAC,EAAE,OAAO,CAAC;IAE3C;;;;;;;;OAQG;IACH,8BAA8B,CAAC,EAAE,OAAO,CAAC;IAEzC;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;;;;;;OAQG;IACH,sBAAsB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,cAAc,KAAK,OAAO,CAAC;IAEhF;;;OAGG;IACH,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,GAAG,iBAAiB,KAAK,IAAI,CAAC;IACvF,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,eAAe,GAAG,mBAAmB,KAAK,IAAI,CAAC;IAC7F,oCAAoC,CAAC,EAAE,CACrC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,mBAAmB,KAC1B,IAAI,CAAC;IAKV;;OAEG;IACH,8BAA8B,CAAC,EAAE,OAAO,CAAC;IAEzC;;OAEG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;OAEG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;IAEtC;;OAEG;IACH,8BAA8B,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC;IAExF;;OAEG;IACH,yBAAyB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,cAAc,KAAK,OAAO,CAAC;IAEnF;;OAEG;IACH,0BAA0B,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAEpE;;OAEG;IACH,+BAA+B,CAAC,EAAE,OAAO,CAAC;IAE1C;;OAEG;IACH,eAAe,CAAC,EAAE;QAChB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,aAAa,GAAG,eAAe,KAAK,IAAI,CAAC;QACzE,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,eAAe,GAAG,cAAc,KAAK,IAAI,CAAC;QAChF,2BAA2B,CAAC,EAAE,CAC5B,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,aAAa,GAAG,eAAe,EACxC,QAAQ,EAAE,eAAe,GAAG,cAAc,KACvC,IAAI,CAAC;KACX,CAAC;IAEF;;OAEG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,yBAA0B,SAAQ,mBAAmB,CAAC,gCAAgC,CAAC;gBAC/E,MAAM,GAAE,gCAAqC;IAIhE,kBAAkB;IACX,IAAI,IAAI,CAAC,mCAAmC,EAAE,mCAAmC,CAAC;CAkF1F"}
{"version":3,"file":"SentryHttpInstrumentation.d.ts","sourceRoot":"","sources":["../../../../src/integrations/http/SentryHttpInstrumentation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChF,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAA8B,IAAI,EAAE,MAAM,cAAc,CAAC;AAY7G,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAOlC,UAAU,yCAAyC;IACjD;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;;OAIG;IACH,gCAAgC,CAAC,EAAE,OAAO,CAAC;IAE3C;;;;OAIG;IACH,8BAA8B,CAAC,EAAE,OAAO,CAAC;IAEzC;;;;;;;OAOG;IACH,sBAAsB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,cAAc,KAAK,OAAO,CAAC;IAEhF;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,GAAG,iBAAiB,KAAK,IAAI,CAAC;IACvF,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,eAAe,GAAG,mBAAmB,KAAK,IAAI,CAAC;IAC7F,oCAAoC,CAAC,EAAE,CACrC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,mBAAmB,KAC1B,IAAI,CAAC;CACX;AAED,MAAM,MAAM,gCAAgC,GAAG,qBAAqB,GAClE,yCAAyC,GAAG;IAI1C;;OAEG;IACH,8BAA8B,CAAC,EAAE,OAAO,CAAC;IAEzC;;OAEG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;OAEG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;IAEtC;;OAEG;IACH,8BAA8B,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC;IAExF;;OAEG;IACH,yBAAyB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,cAAc,KAAK,OAAO,CAAC;IAEnF;;OAEG;IACH,0BAA0B,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAEpE;;OAEG;IACH,+BAA+B,CAAC,EAAE,OAAO,CAAC;IAE1C;;OAEG;IACH,eAAe,CAAC,EAAE;QAChB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,aAAa,GAAG,eAAe,KAAK,IAAI,CAAC;QACzE,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,eAAe,GAAG,cAAc,KAAK,IAAI,CAAC;QAChF,2BAA2B,CAAC,EAAE,CAC5B,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,aAAa,GAAG,eAAe,EACxC,QAAQ,EAAE,eAAe,GAAG,cAAc,KACvC,IAAI,CAAC;KACX,CAAC;IAEF;;OAEG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC,CAAC;AAEJ;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAC5C,sBAAsB,GAAE,yCAA8C,GACrE,IAAI,CAqDN;AAyBD;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,yBAA0B,SAAQ,mBAAmB,CAAC,gCAAgC,CAAC;gBAC/E,MAAM,GAAE,gCAAqC;IAIhE,kBAAkB;IACX,IAAI,IAAI,IAAI;CAGpB"}

@@ -1,1 +0,1 @@

{"version":3,"file":"onunhandledrejection.d.ts","sourceRoot":"","sources":["../../../src/integrations/onunhandledrejection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAsC,MAAM,cAAc,CAAC;AAW/E,KAAK,sBAAsB,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEzD,KAAK,aAAa,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC;AAE3E,UAAU,2BAA2B;IACnC;;;OAGG;IACH,IAAI,EAAE,sBAAsB,CAAC;IAC7B,0DAA0D;IAC1D,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;CAC1B;AA2BD,eAAO,MAAM,+BAA+B;;CAAsD,CAAC;AAgCnG,mBAAmB;AACnB,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,2BAA2B,GACnC,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAuC7C"}
{"version":3,"file":"onunhandledrejection.d.ts","sourceRoot":"","sources":["../../../src/integrations/onunhandledrejection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAsC,MAAM,cAAc,CAAC;AAY/E,KAAK,sBAAsB,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEzD,KAAK,aAAa,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC;AAE3E,UAAU,2BAA2B;IACnC;;;OAGG;IACH,IAAI,EAAE,sBAAsB,CAAC;IAC7B,0DAA0D;IAC1D,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;CAC1B;AA2BD,eAAO,MAAM,+BAA+B;;CAAsD,CAAC;AAgCnG,mBAAmB;AACnB,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,2BAA2B,GACnC,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAwC7C"}

@@ -1,1 +0,1 @@

{"version":3,"file":"pino.d.ts","sourceRoot":"","sources":["../../../src/integrations/pino.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAiB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AA+CjF,KAAK,WAAW,GAAG;IACjB;;;;;;OAMG;IACH,cAAc,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,KAAK,EAAE;QACL;;;;WAIG;QACH,MAAM,EAAE,gBAAgB,EAAE,CAAC;QAC3B;;;;;WAKG;QACH,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;IACF;;OAEG;IACH,GAAG,EAAE;QACH;;;;;WAKG;QACH,MAAM,EAAE,gBAAgB,EAAE,CAAC;KAC5B,CAAC;CACH,CAAC;AAQF,KAAK,WAAW,CAAC,CAAC,IAAI;KACnB,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAC5D,CAAC;AAgHF,UAAU,uBAAuB;IAC/B,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,WAAW,CAAC,GAAG,WAAW,CAAC;IACtD;;;;OAIG;IACH,WAAW,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC;;;;OAIG;IACH,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;CACtC;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,EAWtB,uBAAuB,CAAC"}
{"version":3,"file":"pino.d.ts","sourceRoot":"","sources":["../../../src/integrations/pino.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAiB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAgDjF,KAAK,WAAW,GAAG;IACjB;;;;;;OAMG;IACH,cAAc,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,KAAK,EAAE;QACL;;;;WAIG;QACH,MAAM,EAAE,gBAAgB,EAAE,CAAC;QAC3B;;;;;WAKG;QACH,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;IACF;;OAEG;IACH,GAAG,EAAE;QACH;;;;;WAKG;QACH,MAAM,EAAE,gBAAgB,EAAE,CAAC;KAC5B,CAAC;CACH,CAAC;AAQF,KAAK,WAAW,CAAC,CAAC,IAAI;KACnB,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAC5D,CAAC;AAgHF,UAAU,uBAAuB;IAC/B,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,WAAW,CAAC,GAAG,WAAW,CAAC;IACtD;;;;OAIG;IACH,WAAW,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC;;;;OAIG;IACH,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;CACtC;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,EAWtB,uBAAuB,CAAC"}
{
"name": "@sentry/node-core",
"version": "10.64.0",
"version": "10.65.0",
"description": "Sentry Node-Core SDK",

@@ -105,4 +105,4 @@ "repository": "git://github.com/getsentry/sentry-javascript.git",

"@sentry/conventions": "^0.15.1",
"@sentry/core": "10.64.0",
"@sentry/opentelemetry": "10.64.0",
"@sentry/core": "10.65.0",
"@sentry/opentelemetry": "10.65.0",
"import-in-the-middle": "^3.0.0"

@@ -109,0 +109,0 @@ },