@sentry/node 8.11.0 → 8.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/integrations/anr/index.js +1 -1
- package/cjs/integrations/local-variables/local-variables-async.js +1 -1
- package/cjs/integrations/node-fetch.js +1 -1
- package/cjs/integrations/node-fetch.js.map +1 -1
- package/cjs/integrations/tracing/koa.js +1 -0
- package/cjs/integrations/tracing/koa.js.map +1 -1
- package/cjs/sdk/index.js +2 -0
- package/cjs/sdk/index.js.map +1 -1
- package/cjs/sdk/initOtel.js +5 -1
- package/cjs/sdk/initOtel.js.map +1 -1
- package/esm/integrations/anr/index.js +1 -1
- package/esm/integrations/anr/worker-script.js +2 -2
- package/esm/integrations/local-variables/local-variables-async.js +1 -1
- package/esm/integrations/local-variables/worker-script.js +1 -1
- package/esm/integrations/node-fetch.js +1 -1
- package/esm/integrations/node-fetch.js.map +1 -1
- package/esm/integrations/tracing/koa.js +1 -0
- package/esm/integrations/tracing/koa.js.map +1 -1
- package/esm/sdk/index.js +2 -0
- package/esm/sdk/index.js.map +1 -1
- package/esm/sdk/initOtel.js +5 -1
- package/esm/sdk/initOtel.js.map +1 -1
- package/package.json +5 -5
- package/types/integrations/tracing/koa.d.ts.map +1 -1
- package/types/sdk/index.d.ts +3 -2
- package/types/sdk/index.d.ts.map +1 -1
- package/types/sdk/initOtel.d.ts.map +1 -1
- package/types/types.d.ts +10 -0
- package/types/types.d.ts.map +1 -1
- package/types-ts3.8/sdk/index.d.ts +3 -2
- package/types-ts3.8/types.d.ts +10 -0
|
@@ -11,7 +11,7 @@ const utils = require('@sentry/utils');
|
|
|
11
11
|
const nodeVersion = require('../../nodeVersion.js');
|
|
12
12
|
|
|
13
13
|
// This string is a placeholder that gets overwritten with the worker code.
|
|
14
|
-
const base64WorkerScript = 'LyohIEBzZW50cnkvbm9kZSA4LjExLjAgKGRkMDgzMGIpIHwgaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdCAqLwppbXBvcnR7U2Vzc2lvbiBhcyB0fWZyb20ibm9kZTppbnNwZWN0b3IiO2ltcG9ydHtwYXJlbnRQb3J0IGFzIG4sd29ya2VyRGF0YSBhcyBlfWZyb20ibm9kZTp3b3JrZXJfdGhyZWFkcyI7aW1wb3J0e3Bvc2l4IGFzIHIsc2VwIGFzIG99ZnJvbSJub2RlOnBhdGgiO2ltcG9ydCphcyBzIGZyb20ibm9kZTpodHRwIjtpbXBvcnQqYXMgaSBmcm9tIm5vZGU6aHR0cHMiO2ltcG9ydHtSZWFkYWJsZSBhcyBjfWZyb20ibm9kZTpzdHJlYW0iO2ltcG9ydHtjcmVhdGVHemlwIGFzIHV9ZnJvbSJub2RlOnpsaWIiO2ltcG9ydCphcyBhIGZyb20ibm9kZTpuZXQiO2ltcG9ydCphcyBmIGZyb20ibm9kZTp0bHMiO2NvbnN0IGg9T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztmdW5jdGlvbiBwKHQsbil7cmV0dXJuIGguY2FsbCh0KT09PWBbb2JqZWN0ICR7bn1dYH1mdW5jdGlvbiBkKHQpe3JldHVybiBwKHQsIlN0cmluZyIpfWZ1bmN0aW9uIGwodCl7cmV0dXJuIHAodCwiT2JqZWN0Iil9ZnVuY3Rpb24gbSh0KXtyZXR1cm4gQm9vbGVhbih0JiZ0LnRoZW4mJiJmdW5jdGlvbiI9PXR5cGVvZiB0LnRoZW4pfWZ1bmN0aW9uIHkodCxuKXt0cnl7cmV0dXJuIHQgaW5zdGFuY2VvZiBufWNhdGNoKHQpe3JldHVybiExfX1jb25zdCBnPSI4LjExLjAiLGI9Z2xvYmFsVGhpcztmdW5jdGlvbiB2KHQsbixlKXtjb25zdCByPWV8fGIsbz1yLl9fU0VOVFJZX189ci5fX1NFTlRSWV9ffHx7fSxzPW9bZ109b1tnXXx8e307cmV0dXJuIHNbdF18fChzW3RdPW4oKSl9Y29uc3QgXz1iLHc9ODA7ZnVuY3Rpb24gUyh0LG4pe2NvbnN0IGU9dCxyPVtdO2lmKCFlfHwhZS50YWdOYW1lKXJldHVybiIiO2lmKF8uSFRNTEVsZW1lbnQmJmUgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCYmZS5kYXRhc2V0KXtpZihlLmRhdGFzZXQuc2VudHJ5Q29tcG9uZW50KXJldHVybiBlLmRhdGFzZXQuc2VudHJ5Q29tcG9uZW50O2lmKGUuZGF0YXNldC5zZW50cnlFbGVtZW50KXJldHVybiBlLmRhdGFzZXQuc2VudHJ5RWxlbWVudH1yLnB1c2goZS50YWdOYW1lLnRvTG93ZXJDYXNlKCkpO2NvbnN0IG89biYmbi5sZW5ndGg/bi5maWx0ZXIoKHQ9PmUuZ2V0QXR0cmlidXRlKHQpKSkubWFwKCh0PT5bdCxlLmdldEF0dHJpYnV0ZSh0KV0pKTpudWxsO2lmKG8mJm8ubGVuZ3RoKW8uZm9yRWFjaCgodD0+e3IucHVzaChgWyR7dFswXX09IiR7dFsxXX0iXWApfSkpO2Vsc2V7ZS5pZCYmci5wdXNoKGAjJHtlLmlkfWApO2NvbnN0IHQ9ZS5jbGFzc05hbWU7aWYodCYmZCh0KSl7Y29uc3Qgbj10LnNwbGl0KC9ccysvKTtmb3IoY29uc3QgdCBvZiBuKXIucHVzaChgLiR7dH1gKX19Y29uc3Qgcz1bImFyaWEtbGFiZWwiLCJ0eXBlIiwibmFtZSIsInRpdGxlIiwiYWx0Il07Zm9yKGNvbnN0IHQgb2Ygcyl7Y29uc3Qgbj1lLmdldEF0dHJpYnV0ZSh0KTtuJiZyLnB1c2goYFske3R9PSIke259Il1gKX1yZXR1cm4gci5qb2luKCIiKX1jb25zdCAkPSJ1bmRlZmluZWQiPT10eXBlb2YgX19TRU5UUllfREVCVUdfX3x8X19TRU5UUllfREVCVUdfXyxFPVsiZGVidWciLCJpbmZvIiwid2FybiIsImVycm9yIiwibG9nIiwiYXNzZXJ0IiwidHJhY2UiXSx4PXt9O2Z1bmN0aW9uIE4odCl7aWYoISgiY29uc29sZSJpbiBiKSlyZXR1cm4gdCgpO2NvbnN0IG49Yi5jb25zb2xlLGU9e30scj1PYmplY3Qua2V5cyh4KTtyLmZvckVhY2goKHQ9Pntjb25zdCByPXhbdF07ZVt0XT1uW3RdLG5bdF09cn0pKTt0cnl7cmV0dXJuIHQoKX1maW5hbGx5e3IuZm9yRWFjaCgodD0+e25bdF09ZVt0XX0pKX19Y29uc3Qgaz1mdW5jdGlvbigpe2xldCB0PSExO2NvbnN0IG49e2VuYWJsZTooKT0+e3Q9ITB9LGRpc2FibGU6KCk9Pnt0PSExfSxpc0VuYWJsZWQ6KCk9PnR9O3JldHVybiAkP0UuZm9yRWFjaCgoZT0+e25bZV09KC4uLm4pPT57dCYmTigoKCk9PntiLmNvbnNvbGVbZV0oYFNlbnRyeSBMb2dnZXIgWyR7ZX1dOmAsLi4ubil9KSl9fSkpOkUuZm9yRWFjaCgodD0+e25bdF09KCk9Pnt9fSkpLG59KCk7ZnVuY3Rpb24gQyh0LG49ITEpe2NvbnN0e2hvc3Q6ZSxwYXRoOnIscGFzczpvLHBvcnQ6cyxwcm9qZWN0SWQ6aSxwcm90b2NvbDpjLHB1YmxpY0tleTp1fT10O3JldHVybmAke2N9Oi8vJHt1fSR7biYmbz9gOiR7b31gOiIifUAke2V9JHtzP2A6JHtzfWA6IiJ9LyR7cj9gJHtyfS9gOnJ9JHtpfWB9Y2xhc3MgRCBleHRlbmRzIEVycm9ye2NvbnN0cnVjdG9yKHQsbj0id2FybiIpe3N1cGVyKHQpLHRoaXMubWVzc2FnZT10LHRoaXMubmFtZT1uZXcudGFyZ2V0LnByb3RvdHlwZS5jb25zdHJ1Y3Rvci5uYW1lLE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLG5ldy50YXJnZXQucHJvdG90eXBlKSx0aGlzLmxvZ0xldmVsPW59fWZ1bmN0aW9uIFQodCl7aWYoZnVuY3Rpb24odCl7c3dpdGNoKGguY2FsbCh0KSl7Y2FzZSJbb2JqZWN0IEVycm9yXSI6Y2FzZSJbb2JqZWN0IEV4Y2VwdGlvbl0iOmNhc2UiW29iamVjdCBET01FeGNlcHRpb25dIjpyZXR1cm4hMDtkZWZhdWx0OnJldHVybiB5KHQsRXJyb3IpfX0odCkpcmV0dXJue21lc3NhZ2U6dC5tZXNzYWdlLG5hbWU6dC5uYW1lLHN0YWNrOnQuc3RhY2ssLi4uaih0KX07aWYobj10LCJ1bmRlZmluZWQiIT10eXBlb2YgRXZlbnQmJnkobixFdmVudCkpe2NvbnN0IG49e3R5cGU6dC50eXBlLHRhcmdldDpPKHQudGFyZ2V0KSxjdXJyZW50VGFyZ2V0Ok8odC5jdXJyZW50VGFyZ2V0KSwuLi5qKHQpfTtyZXR1cm4idW5kZWZpbmVkIiE9dHlwZW9mIEN1c3RvbUV2ZW50JiZ5KHQsQ3VzdG9tRXZlbnQpJiYobi5kZXRhaWw9dC5kZXRhaWwpLG59cmV0dXJuIHQ7dmFyIG59ZnVuY3Rpb24gTyh0KXt0cnl7cmV0dXJuIG49dCwidW5kZWZpbmVkIiE9dHlwZW9mIEVsZW1lbnQmJnkobixFbGVtZW50KT9mdW5jdGlvbih0LG49e30pe2lmKCF0KXJldHVybiI8dW5rbm93bj4iO3RyeXtsZXQgZT10O2NvbnN0IHI9NSxvPVtdO2xldCBzPTAsaT0wO2NvbnN0IGM9IiA+ICIsdT1jLmxlbmd0aDtsZXQgYTtjb25zdCBmPUFycmF5LmlzQXJyYXkobik/bjpuLmtleUF0dHJzLGg9IUFycmF5LmlzQXJyYXkobikmJm4ubWF4U3RyaW5nTGVuZ3RofHx3O2Zvcig7ZSYmcysrPHImJihhPVMoZSxmKSwhKCJodG1sIj09PWF8fHM+MSYmaStvLmxlbmd0aCp1K2EubGVuZ3RoPj1oKSk7KW8ucHVzaChhKSxpKz1hLmxlbmd0aCxlPWUucGFyZW50Tm9kZTtyZXR1cm4gby5yZXZlcnNlKCkuam9pbihjKX1jYXRjaCh0KXtyZXR1cm4iPHVua25vd24+In19KHQpOk9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0KX1jYXRjaCh0KXtyZXR1cm4iPHVua25vd24+In12YXIgbn1mdW5jdGlvbiBqKHQpe2lmKCJvYmplY3QiPT10eXBlb2YgdCYmbnVsbCE9PXQpe2NvbnN0IG49e307Zm9yKGNvbnN0IGUgaW4gdClPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodCxlKSYmKG5bZV09dFtlXSk7cmV0dXJuIG59cmV0dXJue319ZnVuY3Rpb24gUih0KXtyZXR1cm4gQSh0LG5ldyBNYXApfWZ1bmN0aW9uIEEodCxuKXtpZihmdW5jdGlvbih0KXtpZighbCh0KSlyZXR1cm4hMTt0cnl7Y29uc3Qgbj1PYmplY3QuZ2V0UHJvdG90eXBlT2YodCkuY29uc3RydWN0b3IubmFtZTtyZXR1cm4hbnx8Ik9iamVjdCI9PT1ufWNhdGNoKHQpe3JldHVybiEwfX0odCkpe2NvbnN0IGU9bi5nZXQodCk7aWYodm9pZCAwIT09ZSlyZXR1cm4gZTtjb25zdCByPXt9O24uc2V0KHQscik7Zm9yKGNvbnN0IGUgb2YgT2JqZWN0LmtleXModCkpdm9pZCAwIT09dFtlXSYmKHJbZV09QSh0W2VdLG4pKTtyZXR1cm4gcn1pZihBcnJheS5pc0FycmF5KHQpKXtjb25zdCBlPW4uZ2V0KHQpO2lmKHZvaWQgMCE9PWUpcmV0dXJuIGU7Y29uc3Qgcj1bXTtyZXR1cm4gbi5zZXQodCxyKSx0LmZvckVhY2goKHQ9PntyLnB1c2goQSh0LG4pKX0pKSxyfXJldHVybiB0fWNvbnN0IEk9NTAsUD0iPyIsVT0vY2FwdHVyZU1lc3NhZ2V8Y2FwdHVyZUV4Y2VwdGlvbi87ZnVuY3Rpb24gTSh0KXtyZXR1cm4gdFt0Lmxlbmd0aC0xXXx8e319Y29uc3QgTD0iPGFub255bW91cz4iO2NvbnN0IEI9MWUzO2Z1bmN0aW9uIEcoKXtyZXR1cm4gRGF0ZS5ub3coKS9CfWNvbnN0IEo9ZnVuY3Rpb24oKXtjb25zdHtwZXJmb3JtYW5jZTp0fT1iO2lmKCF0fHwhdC5ub3cpcmV0dXJuIEc7Y29uc3Qgbj1EYXRlLm5vdygpLXQubm93KCksZT1udWxsPT10LnRpbWVPcmlnaW4/bjp0LnRpbWVPcmlnaW47cmV0dXJuKCk9PihlK3Qubm93KCkpL0J9KCk7ZnVuY3Rpb24geigpe2NvbnN0IHQ9YixuPXQuY3J5cHRvfHx0Lm1zQ3J5cHRvO2xldCBlPSgpPT4xNipNYXRoLnJhbmRvbSgpO3RyeXtpZihuJiZuLnJhbmRvbVVVSUQpcmV0dXJuIG4ucmFuZG9tVVVJRCgpLnJlcGxhY2UoLy0vZywiIik7biYmbi5nZXRSYW5kb21WYWx1ZXMmJihlPSgpPT57Y29uc3QgdD1uZXcgVWludDhBcnJheSgxKTtyZXR1cm4gbi5nZXRSYW5kb21WYWx1ZXModCksdFswXX0pfWNhdGNoKHQpe31yZXR1cm4oWzFlN10rMWUzKzRlMys4ZTMrMWUxMSkucmVwbGFjZSgvWzAxOF0vZywodD0+KHReKDE1JmUoKSk+PnQvNCkudG9TdHJpbmcoMTYpKSl9ZnVuY3Rpb24gSCh0LG49MTAwLGU9MS8wKXt0cnl7cmV0dXJuIFcoIiIsdCxuLGUpfWNhdGNoKHQpe3JldHVybntFUlJPUjpgKipub24tc2VyaWFsaXphYmxlKiogKCR7dH0pYH19fWZ1bmN0aW9uIFcodCxuLGU9MS8wLHI9MS8wLG89ZnVuY3Rpb24oKXtjb25zdCB0PSJmdW5jdGlvbiI9PXR5cGVvZiBXZWFrU2V0LG49dD9uZXcgV2Vha1NldDpbXTtyZXR1cm5bZnVuY3Rpb24oZSl7aWYodClyZXR1cm4hIW4uaGFzKGUpfHwobi5hZGQoZSksITEpO2ZvcihsZXQgdD0wO3Q8bi5sZW5ndGg7dCsrKWlmKG5bdF09PT1lKXJldHVybiEwO3JldHVybiBuLnB1c2goZSksITF9LGZ1bmN0aW9uKGUpe2lmKHQpbi5kZWxldGUoZSk7ZWxzZSBmb3IobGV0IHQ9MDt0PG4ubGVuZ3RoO3QrKylpZihuW3RdPT09ZSl7bi5zcGxpY2UodCwxKTticmVha319XX0oKSl7Y29uc3RbcyxpXT1vO2lmKG51bGw9PW58fFsibnVtYmVyIiwiYm9vbGVhbiIsInN0cmluZyJdLmluY2x1ZGVzKHR5cGVvZiBuKSYmIU51bWJlci5pc05hTihuKSlyZXR1cm4gbjtjb25zdCBjPWZ1bmN0aW9uKHQsbil7dHJ5e2lmKCJkb21haW4iPT09dCYmbiYmIm9iamVjdCI9PXR5cGVvZiBuJiZuLnQpcmV0dXJuIltEb21haW5dIjtpZigiZG9tYWluRW1pdHRlciI9PT10KXJldHVybiJbRG9tYWluRW1pdHRlcl0iO2lmKCJ1bmRlZmluZWQiIT10eXBlb2YgZ2xvYmFsJiZuPT09Z2xvYmFsKXJldHVybiJbR2xvYmFsXSI7aWYoInVuZGVmaW5lZCIhPXR5cGVvZiB3aW5kb3cmJm49PT13aW5kb3cpcmV0dXJuIltXaW5kb3ddIjtpZigidW5kZWZpbmVkIiE9dHlwZW9mIGRvY3VtZW50JiZuPT09ZG9jdW1lbnQpcmV0dXJuIltEb2N1bWVudF0iO2lmKCJvYmplY3QiPT10eXBlb2YoZT1uKSYmbnVsbCE9PWUmJihlLl9faXNWdWV8fGUubykpcmV0dXJuIltWdWVWaWV3TW9kZWxdIjtpZihmdW5jdGlvbih0KXtyZXR1cm4gbCh0KSYmIm5hdGl2ZUV2ZW50ImluIHQmJiJwcmV2ZW50RGVmYXVsdCJpbiB0JiYic3RvcFByb3BhZ2F0aW9uImluIHR9KG4pKXJldHVybiJbU3ludGhldGljRXZlbnRdIjtpZigibnVtYmVyIj09dHlwZW9mIG4mJm4hPW4pcmV0dXJuIltOYU5dIjtpZigiZnVuY3Rpb24iPT10eXBlb2YgbilyZXR1cm5gW0Z1bmN0aW9uOiAke2Z1bmN0aW9uKHQpe3RyeXtyZXR1cm4gdCYmImZ1bmN0aW9uIj09dHlwZW9mIHQmJnQubmFtZXx8TH1jYXRjaCh0KXtyZXR1cm4gTH19KG4pfV1gO2lmKCJzeW1ib2wiPT10eXBlb2YgbilyZXR1cm5gWyR7U3RyaW5nKG4pfV1gO2lmKCJiaWdpbnQiPT10eXBlb2YgbilyZXR1cm5gW0JpZ0ludDogJHtTdHJpbmcobil9XWA7Y29uc3Qgcj1mdW5jdGlvbih0KXtjb25zdCBuPU9iamVjdC5nZXRQcm90b3R5cGVPZih0KTtyZXR1cm4gbj9uLmNvbnN0cnVjdG9yLm5hbWU6Im51bGwgcHJvdG90eXBlIn0obik7cmV0dXJuL15IVE1MKFx3KilFbGVtZW50JC8udGVzdChyKT9gW0hUTUxFbGVtZW50OiAke3J9XWA6YFtvYmplY3QgJHtyfV1gfWNhdGNoKHQpe3JldHVybmAqKm5vbi1zZXJpYWxpemFibGUqKiAoJHt0fSlgfXZhciBlfSh0LG4pO2lmKCFjLnN0YXJ0c1dpdGgoIltvYmplY3QgIikpcmV0dXJuIGM7aWYobi5fX3NlbnRyeV9za2lwX25vcm1hbGl6YXRpb25fXylyZXR1cm4gbjtjb25zdCB1PSJudW1iZXIiPT10eXBlb2Ygbi5fX3NlbnRyeV9vdmVycmlkZV9ub3JtYWxpemF0aW9uX2RlcHRoX18/bi5fX3NlbnRyeV9vdmVycmlkZV9ub3JtYWxpemF0aW9uX2RlcHRoX186ZTtpZigwPT09dSlyZXR1cm4gYy5yZXBsYWNlKCJvYmplY3QgIiwiIik7aWYocyhuKSlyZXR1cm4iW0NpcmN1bGFyIH5dIjtjb25zdCBhPW47aWYoYSYmImZ1bmN0aW9uIj09dHlwZW9mIGEudG9KU09OKXRyeXtyZXR1cm4gVygiIixhLnRvSlNPTigpLHUtMSxyLG8pfWNhdGNoKHQpe31jb25zdCBmPUFycmF5LmlzQXJyYXkobik/W106e307bGV0IGg9MDtjb25zdCBwPVQobik7Zm9yKGNvbnN0IHQgaW4gcCl7aWYoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChwLHQpKWNvbnRpbnVlO2lmKGg+PXIpe2ZbdF09IltNYXhQcm9wZXJ0aWVzIH5dIjticmVha31jb25zdCBuPXBbdF07Zlt0XT1XKHQsbix1LTEscixvKSxoKyt9cmV0dXJuIGkobiksZn1mdW5jdGlvbiBZKHQsbil7Y29uc3QgZT1uLnJlcGxhY2UoL1xcL2csIi8iKS5yZXBsYWNlKC9bfFxce30oKVtcXV4kKyo/Ll0vZywiXFwkJiIpO2xldCByPXQ7dHJ5e3I9ZGVjb2RlVVJJKHQpfWNhdGNoKHQpe31yZXR1cm4gci5yZXBsYWNlKC9cXC9nLCIvIikucmVwbGFjZSgvd2VicGFjazpcLz8vZywiIikucmVwbGFjZShuZXcgUmVnRXhwKGAoZmlsZTovLyk/Lyoke2V9LypgLCJpZyIpLCJhcHA6Ly8vIil9KCgpPT57Y29uc3R7cGVyZm9ybWFuY2U6dH09YjtpZighdHx8IXQubm93KXJldHVybjtjb25zdCBuPTM2ZTUsZT10Lm5vdygpLHI9RGF0ZS5ub3coKSxvPXQudGltZU9yaWdpbj9NYXRoLmFicyh0LnRpbWVPcmlnaW4rZS1yKTpuLHM9bzxuLGk9dC50aW1pbmcmJnQudGltaW5nLm5hdmlnYXRpb25TdGFydCxjPSJudW1iZXIiPT10eXBlb2YgaT9NYXRoLmFicyhpK2Utcik6bjsoc3x8YzxuKSYmKG88PWMmJnQudGltZU9yaWdpbil9KSgpO2NvbnN0IHE9L14oXFMrOlxcfFwvPykoW1xzXFNdKj8pKCg/OlwuezEsMn18W14vXFxdKz98KShcLlteLi9cXF0qfCkpKD86Wy9cXF0qKSQvO2Z1bmN0aW9uIEYodCl7Y29uc3Qgbj1mdW5jdGlvbih0KXtjb25zdCBuPXQubGVuZ3RoPjEwMjQ/YDx0cnVuY2F0ZWQ+JHt0LnNsaWNlKC0xMDI0KX1gOnQsZT1xLmV4ZWMobik7cmV0dXJuIGU/ZS5zbGljZSgxKTpbXX0odCksZT1uWzBdfHwiIjtsZXQgcj1uWzFdO3JldHVybiBlfHxyPyhyJiYocj1yLnNsaWNlKDAsci5sZW5ndGgtMSkpLGUrcik6Ii4ifXZhciBLO2Z1bmN0aW9uIFYodCl7cmV0dXJuIG5ldyBaKChuPT57bih0KX0pKX0hZnVuY3Rpb24odCl7dFt0LlBFTkRJTkc9MF09IlBFTkRJTkciO3RbdC5SRVNPTFZFRD0xXT0iUkVTT0xWRUQiO3RbdC5SRUpFQ1RFRD0yXT0iUkVKRUNURUQifShLfHwoSz17fSkpO2NsYXNzIFp7Y29uc3RydWN0b3IodCl7Wi5wcm90b3R5cGUuX19pbml0LmNhbGwodGhpcyksWi5wcm90b3R5cGUuX19pbml0Mi5jYWxsKHRoaXMpLFoucHJvdG90eXBlLl9faW5pdDMuY2FsbCh0aGlzKSxaLnByb3RvdHlwZS5fX2luaXQ0LmNhbGwodGhpcyksdGhpcy5pPUsuUEVORElORyx0aGlzLnU9W107dHJ5e3QodGhpcy5oLHRoaXMucCl9Y2F0Y2godCl7dGhpcy5wKHQpfX10aGVuKHQsbil7cmV0dXJuIG5ldyBaKCgoZSxyKT0+e3RoaXMudS5wdXNoKFshMSxuPT57aWYodCl0cnl7ZSh0KG4pKX1jYXRjaCh0KXtyKHQpfWVsc2UgZShuKX0sdD0+e2lmKG4pdHJ5e2Uobih0KSl9Y2F0Y2godCl7cih0KX1lbHNlIHIodCl9XSksdGhpcy5sKCl9KSl9Y2F0Y2godCl7cmV0dXJuIHRoaXMudGhlbigodD0+dCksdCl9ZmluYWxseSh0KXtyZXR1cm4gbmV3IFooKChuLGUpPT57bGV0IHIsbztyZXR1cm4gdGhpcy50aGVuKChuPT57bz0hMSxyPW4sdCYmdCgpfSksKG49PntvPSEwLHI9bix0JiZ0KCl9KSkudGhlbigoKCk9PntvP2Uocik6bihyKX0pKX0pKX1fX2luaXQoKXt0aGlzLmg9dD0+e3RoaXMubShLLlJFU09MVkVELHQpfX1fX2luaXQyKCl7dGhpcy5wPXQ9Pnt0aGlzLm0oSy5SRUpFQ1RFRCx0KX19X19pbml0Mygpe3RoaXMubT0odCxuKT0+e3RoaXMuaT09PUsuUEVORElORyYmKG0obik/bi50aGVuKHRoaXMuaCx0aGlzLnApOih0aGlzLmk9dCx0aGlzLnY9bix0aGlzLmwoKSkpfX1fX2luaXQ0KCl7dGhpcy5sPSgpPT57aWYodGhpcy5pPT09Sy5QRU5ESU5HKXJldHVybjtjb25zdCB0PXRoaXMudS5zbGljZSgpO3RoaXMudT1bXSx0LmZvckVhY2goKHQ9Pnt0WzBdfHwodGhpcy5pPT09Sy5SRVNPTFZFRCYmdFsxXSh0aGlzLnYpLHRoaXMuaT09PUsuUkVKRUNURUQmJnRbMl0odGhpcy52KSx0WzBdPSEwKX0pKX19fWZ1bmN0aW9uIFEodCl7Y29uc3Qgbj1bXTtmdW5jdGlvbiBlKHQpe3JldHVybiBuLnNwbGljZShuLmluZGV4T2YodCksMSlbMF18fFByb21pc2UucmVzb2x2ZSh2b2lkIDApfXJldHVybnskOm4sYWRkOmZ1bmN0aW9uKHIpe2lmKCEodm9pZCAwPT09dHx8bi5sZW5ndGg8dCkpcmV0dXJuIG89bmV3IEQoIk5vdCBhZGRpbmcgUHJvbWlzZSBiZWNhdXNlIGJ1ZmZlciBsaW1pdCB3YXMgcmVhY2hlZC4iKSxuZXcgWigoKHQsbik9PntuKG8pfSkpO3ZhciBvO2NvbnN0IHM9cigpO3JldHVybi0xPT09bi5pbmRleE9mKHMpJiZuLnB1c2gocykscy50aGVuKCgoKT0+ZShzKSkpLnRoZW4obnVsbCwoKCk9PmUocykudGhlbihudWxsLCgoKT0+e30pKSkpLHN9LGRyYWluOmZ1bmN0aW9uKHQpe3JldHVybiBuZXcgWigoKGUscik9PntsZXQgbz1uLmxlbmd0aDtpZighbylyZXR1cm4gZSghMCk7Y29uc3Qgcz1zZXRUaW1lb3V0KCgoKT0+e3QmJnQ+MCYmZSghMSl9KSx0KTtuLmZvckVhY2goKHQ9PntWKHQpLnRoZW4oKCgpPT57LS1vfHwoY2xlYXJUaW1lb3V0KHMpLGUoITApKX0pLHIpfSkpfSkpfX19ZnVuY3Rpb24gWCh0LG49ITEpe3JldHVybiEobnx8dCYmIXQuc3RhcnRzV2l0aCgiLyIpJiYhdC5tYXRjaCgvXltBLVpdOi8pJiYhdC5zdGFydHNXaXRoKCIuIikmJiF0Lm1hdGNoKC9eW2EtekEtWl0oW2EtekEtWjAtOS5cLStdKSo6XC9cLy8pKSYmdm9pZCAwIT09dCYmIXQuaW5jbHVkZXMoIm5vZGVfbW9kdWxlcy8iKX1jb25zdCB0dD0ic2VudHJ5LSIsbnQ9L15zZW50cnktLztmdW5jdGlvbiBldCh0KXtjb25zdCBuPWZ1bmN0aW9uKHQpe2lmKCF0fHwhZCh0KSYmIUFycmF5LmlzQXJyYXkodCkpcmV0dXJuO2lmKEFycmF5LmlzQXJyYXkodCkpcmV0dXJuIHQucmVkdWNlKCgodCxuKT0+e2NvbnN0IGU9cnQobik7cmV0dXJuIE9iamVjdC5lbnRyaWVzKGUpLmZvckVhY2goKChbbixlXSk9Pnt0W25dPWV9KSksdH0pLHt9KTtyZXR1cm4gcnQodCl9KHQpO2lmKCFuKXJldHVybjtjb25zdCBlPU9iamVjdC5lbnRyaWVzKG4pLnJlZHVjZSgoKHQsW24sZV0pPT57aWYobi5tYXRjaChudCkpe3Rbbi5zbGljZSh0dC5sZW5ndGgpXT1lfXJldHVybiB0fSkse30pO3JldHVybiBPYmplY3Qua2V5cyhlKS5sZW5ndGg+MD9lOnZvaWQgMH1mdW5jdGlvbiBydCh0KXtyZXR1cm4gdC5zcGxpdCgiLCIpLm1hcCgodD0+dC5zcGxpdCgiPSIpLm1hcCgodD0+ZGVjb2RlVVJJQ29tcG9uZW50KHQudHJpbSgpKSkpKSkucmVkdWNlKCgodCxbbixlXSk9PihuJiZlJiYodFtuXT1lKSx0KSkse30pfWZ1bmN0aW9uIG90KHQsbj1bXSl7cmV0dXJuW3Qsbl19ZnVuY3Rpb24gc3QodCxuKXtjb25zdCBlPXRbMV07Zm9yKGNvbnN0IHQgb2YgZSl7aWYobih0LHRbMF0udHlwZSkpcmV0dXJuITB9cmV0dXJuITF9ZnVuY3Rpb24gaXQodCl7cmV0dXJuIGIuX19TRU5UUllfXyYmYi5fX1NFTlRSWV9fLmVuY29kZVBvbHlmaWxsP2IuX19TRU5UUllfXy5lbmNvZGVQb2x5ZmlsbCh0KToobmV3IFRleHRFbmNvZGVyKS5lbmNvZGUodCl9ZnVuY3Rpb24gY3QodCl7Y29uc3RbbixlXT10O2xldCByPUpTT04uc3RyaW5naWZ5KG4pO2Z1bmN0aW9uIG8odCl7InN0cmluZyI9PXR5cGVvZiByP3I9InN0cmluZyI9PXR5cGVvZiB0P3IrdDpbaXQociksdF06ci5wdXNoKCJzdHJpbmciPT10eXBlb2YgdD9pdCh0KTp0KX1mb3IoY29uc3QgdCBvZiBlKXtjb25zdFtuLGVdPXQ7aWYobyhgXG4ke0pTT04uc3RyaW5naWZ5KG4pfVxuYCksInN0cmluZyI9PXR5cGVvZiBlfHxlIGluc3RhbmNlb2YgVWludDhBcnJheSlvKGUpO2Vsc2V7bGV0IHQ7dHJ5e3Q9SlNPTi5zdHJpbmdpZnkoZSl9Y2F0Y2gobil7dD1KU09OLnN0cmluZ2lmeShIKGUpKX1vKHQpfX1yZXR1cm4ic3RyaW5nIj09dHlwZW9mIHI/cjpmdW5jdGlvbih0KXtjb25zdCBuPXQucmVkdWNlKCgodCxuKT0+dCtuLmxlbmd0aCksMCksZT1uZXcgVWludDhBcnJheShuKTtsZXQgcj0wO2Zvcihjb25zdCBuIG9mIHQpZS5zZXQobixyKSxyKz1uLmxlbmd0aDtyZXR1cm4gZX0ocil9Y29uc3QgdXQ9e3Nlc3Npb246InNlc3Npb24iLHNlc3Npb25zOiJzZXNzaW9uIixhdHRhY2htZW50OiJhdHRhY2htZW50Iix0cmFuc2FjdGlvbjoidHJhbnNhY3Rpb24iLGV2ZW50OiJlcnJvciIsY2xpZW50X3JlcG9ydDoiaW50ZXJuYWwiLHVzZXJfcmVwb3J0OiJkZWZhdWx0Iixwcm9maWxlOiJwcm9maWxlIixwcm9maWxlX2NodW5rOiJwcm9maWxlIixyZXBsYXlfZXZlbnQ6InJlcGxheSIscmVwbGF5X3JlY29yZGluZzoicmVwbGF5IixjaGVja19pbjoibW9uaXRvciIsZmVlZGJhY2s6ImZlZWRiYWNrIixzcGFuOiJzcGFuIixzdGF0c2Q6Im1ldHJpY19idWNrZXQifTtmdW5jdGlvbiBhdCh0KXtyZXR1cm4gdXRbdF19ZnVuY3Rpb24gZnQodCl7aWYoIXR8fCF0LnNkaylyZXR1cm47Y29uc3R7bmFtZTpuLHZlcnNpb246ZX09dC5zZGs7cmV0dXJue25hbWU6bix2ZXJzaW9uOmV9fWNvbnN0IGh0PTZlNDtmdW5jdGlvbiBwdCh0LHtzdGF0dXNDb2RlOm4saGVhZGVyczplfSxyPURhdGUubm93KCkpe2NvbnN0IG89ey4uLnR9LHM9ZSYmZVsieC1zZW50cnktcmF0ZS1saW1pdHMiXSxpPWUmJmVbInJldHJ5LWFmdGVyIl07aWYocylmb3IoY29uc3QgdCBvZiBzLnRyaW0oKS5zcGxpdCgiLCIpKXtjb25zdFtuLGUsLCxzXT10LnNwbGl0KCI6Iiw1KSxpPXBhcnNlSW50KG4sMTApLGM9MWUzKihpc05hTihpKT82MDppKTtpZihlKWZvcihjb25zdCB0IG9mIGUuc3BsaXQoIjsiKSkibWV0cmljX2J1Y2tldCI9PT10JiZzJiYhcy5zcGxpdCgiOyIpLmluY2x1ZGVzKCJjdXN0b20iKXx8KG9bdF09citjKTtlbHNlIG8uYWxsPXIrY31lbHNlIGk/by5hbGw9citmdW5jdGlvbih0LG49RGF0ZS5ub3coKSl7Y29uc3QgZT1wYXJzZUludChgJHt0fWAsMTApO2lmKCFpc05hTihlKSlyZXR1cm4gMWUzKmU7Y29uc3Qgcj1EYXRlLnBhcnNlKGAke3R9YCk7cmV0dXJuIGlzTmFOKHIpP2h0OnItbn0oaSxyKTo0Mjk9PT1uJiYoby5hbGw9cis2ZTQpO3JldHVybiBvfWZ1bmN0aW9uIGR0KCl7cmV0dXJue3RyYWNlSWQ6eigpLHNwYW5JZDp6KCkuc3Vic3RyaW5nKDE2KX19Y29uc3QgbHQ9InVuZGVmaW5lZCI9PXR5cGVvZiBfX1NFTlRSWV9ERUJVR19ffHxfX1NFTlRSWV9ERUJVR19fO2Z1bmN0aW9uIG10KCl7cmV0dXJuIHl0KGIpLGJ9ZnVuY3Rpb24geXQodCl7Y29uc3Qgbj10Ll9fU0VOVFJZX189dC5fX1NFTlRSWV9ffHx7fTtyZXR1cm4gbi52ZXJzaW9uPW4udmVyc2lvbnx8ZyxuW2ddPW5bZ118fHt9fWZ1bmN0aW9uIGd0KHQpe2NvbnN0IG49SigpLGU9e3NpZDp6KCksaW5pdDohMCx0aW1lc3RhbXA6bixzdGFydGVkOm4sZHVyYXRpb246MCxzdGF0dXM6Im9rIixlcnJvcnM6MCxpZ25vcmVEdXJhdGlvbjohMSx0b0pTT046KCk9PmZ1bmN0aW9uKHQpe3JldHVybiBSKHtzaWQ6YCR7dC5zaWR9YCxpbml0OnQuaW5pdCxzdGFydGVkOm5ldyBEYXRlKDFlMyp0LnN0YXJ0ZWQpLnRvSVNPU3RyaW5nKCksdGltZXN0YW1wOm5ldyBEYXRlKDFlMyp0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxzdGF0dXM6dC5zdGF0dXMsZXJyb3JzOnQuZXJyb3JzLGRpZDoibnVtYmVyIj09dHlwZW9mIHQuZGlkfHwic3RyaW5nIj09dHlwZW9mIHQuZGlkP2Ake3QuZGlkfWA6dm9pZCAwLGR1cmF0aW9uOnQuZHVyYXRpb24sYWJub3JtYWxfbWVjaGFuaXNtOnQuYWJub3JtYWxfbWVjaGFuaXNtLGF0dHJzOntyZWxlYXNlOnQucmVsZWFzZSxlbnZpcm9ubWVudDp0LmVudmlyb25tZW50LGlwX2FkZHJlc3M6dC5pcEFkZHJlc3MsdXNlcl9hZ2VudDp0LnVzZXJBZ2VudH19KX0oZSl9O3JldHVybiB0JiZidChlLHQpLGV9ZnVuY3Rpb24gYnQodCxuPXt9KXtpZihuLnVzZXImJighdC5pcEFkZHJlc3MmJm4udXNlci5pcF9hZGRyZXNzJiYodC5pcEFkZHJlc3M9bi51c2VyLmlwX2FkZHJlc3MpLHQuZGlkfHxuLmRpZHx8KHQuZGlkPW4udXNlci5pZHx8bi51c2VyLmVtYWlsfHxuLnVzZXIudXNlcm5hbWUpKSx0LnRpbWVzdGFtcD1uLnRpbWVzdGFtcHx8SigpLG4uYWJub3JtYWxfbWVjaGFuaXNtJiYodC5hYm5vcm1hbF9tZWNoYW5pc209bi5hYm5vcm1hbF9tZWNoYW5pc20pLG4uaWdub3JlRHVyYXRpb24mJih0Lmlnbm9yZUR1cmF0aW9uPW4uaWdub3JlRHVyYXRpb24pLG4uc2lkJiYodC5zaWQ9MzI9PT1uLnNpZC5sZW5ndGg/bi5zaWQ6eigpKSx2b2lkIDAhPT1uLmluaXQmJih0LmluaXQ9bi5pbml0KSwhdC5kaWQmJm4uZGlkJiYodC5kaWQ9YCR7bi5kaWR9YCksIm51bWJlciI9PXR5cGVvZiBuLnN0YXJ0ZWQmJih0LnN0YXJ0ZWQ9bi5zdGFydGVkKSx0Lmlnbm9yZUR1cmF0aW9uKXQuZHVyYXRpb249dm9pZCAwO2Vsc2UgaWYoIm51bWJlciI9PXR5cGVvZiBuLmR1cmF0aW9uKXQuZHVyYXRpb249bi5kdXJhdGlvbjtlbHNle2NvbnN0IG49dC50aW1lc3RhbXAtdC5zdGFydGVkO3QuZHVyYXRpb249bj49MD9uOjB9bi5yZWxlYXNlJiYodC5yZWxlYXNlPW4ucmVsZWFzZSksbi5lbnZpcm9ubWVudCYmKHQuZW52aXJvbm1lbnQ9bi5lbnZpcm9ubWVudCksIXQuaXBBZGRyZXNzJiZuLmlwQWRkcmVzcyYmKHQuaXBBZGRyZXNzPW4uaXBBZGRyZXNzKSwhdC51c2VyQWdlbnQmJm4udXNlckFnZW50JiYodC51c2VyQWdlbnQ9bi51c2VyQWdlbnQpLCJudW1iZXIiPT10eXBlb2Ygbi5lcnJvcnMmJih0LmVycm9ycz1uLmVycm9ycyksbi5zdGF0dXMmJih0LnN0YXR1cz1uLnN0YXR1cyl9Y29uc3QgdnQ9Il9zZW50cnlTcGFuIjtmdW5jdGlvbiBfdCh0LG4pe24/ZnVuY3Rpb24odCxuLGUpe3RyeXtPYmplY3QuZGVmaW5lUHJvcGVydHkodCxuLHt2YWx1ZTplLHdyaXRhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMH0pfWNhdGNoKGUpeyQmJmsubG9nKGBGYWlsZWQgdG8gYWRkIG5vbi1lbnVtZXJhYmxlIHByb3BlcnR5ICIke259IiB0byBvYmplY3RgLHQpfX0odCx2dCxuKTpkZWxldGUgdFt2dF19ZnVuY3Rpb24gd3QodCl7cmV0dXJuIHRbdnRdfWNsYXNzIFN0e2NvbnN0cnVjdG9yKCl7dGhpcy5fPSExLHRoaXMuUz1bXSx0aGlzLk49W10sdGhpcy5rPVtdLHRoaXMuQz1bXSx0aGlzLkQ9e30sdGhpcy5UPXt9LHRoaXMuTz17fSx0aGlzLmo9e30sdGhpcy5SPXt9LHRoaXMuQT1kdCgpfWNsb25lKCl7Y29uc3QgdD1uZXcgU3Q7cmV0dXJuIHQuaz1bLi4udGhpcy5rXSx0LlQ9ey4uLnRoaXMuVH0sdC5PPXsuLi50aGlzLk99LHQuaj17Li4udGhpcy5qfSx0LkQ9dGhpcy5ELHQuST10aGlzLkksdC5QPXRoaXMuUCx0LlU9dGhpcy5VLHQuTT10aGlzLk0sdC5OPVsuLi50aGlzLk5dLHQuTD10aGlzLkwsdC5DPVsuLi50aGlzLkNdLHQuUj17Li4udGhpcy5SfSx0LkE9ey4uLnRoaXMuQX0sdC5CPXRoaXMuQix0Lkc9dGhpcy5HLF90KHQsd3QodGhpcykpLHR9c2V0Q2xpZW50KHQpe3RoaXMuQj10fXNldExhc3RFdmVudElkKHQpe3RoaXMuRz10fWdldENsaWVudCgpe3JldHVybiB0aGlzLkJ9bGFzdEV2ZW50SWQoKXtyZXR1cm4gdGhpcy5HfWFkZFNjb3BlTGlzdGVuZXIodCl7dGhpcy5TLnB1c2godCl9YWRkRXZlbnRQcm9jZXNzb3IodCl7cmV0dXJuIHRoaXMuTi5wdXNoKHQpLHRoaXN9c2V0VXNlcih0KXtyZXR1cm4gdGhpcy5EPXR8fHtlbWFpbDp2b2lkIDAsaWQ6dm9pZCAwLGlwX2FkZHJlc3M6dm9pZCAwLHVzZXJuYW1lOnZvaWQgMH0sdGhpcy5QJiZidCh0aGlzLlAse3VzZXI6dH0pLHRoaXMuSigpLHRoaXN9Z2V0VXNlcigpe3JldHVybiB0aGlzLkR9Z2V0UmVxdWVzdFNlc3Npb24oKXtyZXR1cm4gdGhpcy5MfXNldFJlcXVlc3RTZXNzaW9uKHQpe3JldHVybiB0aGlzLkw9dCx0aGlzfXNldFRhZ3ModCl7cmV0dXJuIHRoaXMuVD17Li4udGhpcy5ULC4uLnR9LHRoaXMuSigpLHRoaXN9c2V0VGFnKHQsbil7cmV0dXJuIHRoaXMuVD17Li4udGhpcy5ULFt0XTpufSx0aGlzLkooKSx0aGlzfXNldEV4dHJhcyh0KXtyZXR1cm4gdGhpcy5PPXsuLi50aGlzLk8sLi4udH0sdGhpcy5KKCksdGhpc31zZXRFeHRyYSh0LG4pe3JldHVybiB0aGlzLk89ey4uLnRoaXMuTyxbdF06bn0sdGhpcy5KKCksdGhpc31zZXRGaW5nZXJwcmludCh0KXtyZXR1cm4gdGhpcy5NPXQsdGhpcy5KKCksdGhpc31zZXRMZXZlbCh0KXtyZXR1cm4gdGhpcy5JPXQsdGhpcy5KKCksdGhpc31zZXRUcmFuc2FjdGlvbk5hbWUodCl7cmV0dXJuIHRoaXMuVT10LHRoaXMuSigpLHRoaXN9c2V0Q29udGV4dCh0LG4pe3JldHVybiBudWxsPT09bj9kZWxldGUgdGhpcy5qW3RdOnRoaXMualt0XT1uLHRoaXMuSigpLHRoaXN9c2V0U2Vzc2lvbih0KXtyZXR1cm4gdD90aGlzLlA9dDpkZWxldGUgdGhpcy5QLHRoaXMuSigpLHRoaXN9Z2V0U2Vzc2lvbigpe3JldHVybiB0aGlzLlB9dXBkYXRlKHQpe2lmKCF0KXJldHVybiB0aGlzO2NvbnN0IG49ImZ1bmN0aW9uIj09dHlwZW9mIHQ/dCh0aGlzKTp0LFtlLHJdPW4gaW5zdGFuY2VvZiAkdD9bbi5nZXRTY29wZURhdGEoKSxuLmdldFJlcXVlc3RTZXNzaW9uKCldOmwobik/W3QsdC5yZXF1ZXN0U2Vzc2lvbl06W10se3RhZ3M6byxleHRyYTpzLHVzZXI6aSxjb250ZXh0czpjLGxldmVsOnUsZmluZ2VycHJpbnQ6YT1bXSxwcm9wYWdhdGlvbkNvbnRleHQ6Zn09ZXx8e307cmV0dXJuIHRoaXMuVD17Li4udGhpcy5ULC4uLm99LHRoaXMuTz17Li4udGhpcy5PLC4uLnN9LHRoaXMuaj17Li4udGhpcy5qLC4uLmN9LGkmJk9iamVjdC5rZXlzKGkpLmxlbmd0aCYmKHRoaXMuRD1pKSx1JiYodGhpcy5JPXUpLGEubGVuZ3RoJiYodGhpcy5NPWEpLGYmJih0aGlzLkE9ZiksciYmKHRoaXMuTD1yKSx0aGlzfWNsZWFyKCl7cmV0dXJuIHRoaXMuaz1bXSx0aGlzLlQ9e30sdGhpcy5PPXt9LHRoaXMuRD17fSx0aGlzLmo9e30sdGhpcy5JPXZvaWQgMCx0aGlzLlU9dm9pZCAwLHRoaXMuTT12b2lkIDAsdGhpcy5MPXZvaWQgMCx0aGlzLlA9dm9pZCAwLF90KHRoaXMsdm9pZCAwKSx0aGlzLkM9W10sdGhpcy5BPWR0KCksdGhpcy5KKCksdGhpc31hZGRCcmVhZGNydW1iKHQsbil7Y29uc3QgZT0ibnVtYmVyIj09dHlwZW9mIG4/bjoxMDA7aWYoZTw9MClyZXR1cm4gdGhpcztjb25zdCByPXt0aW1lc3RhbXA6RygpLC4uLnR9LG89dGhpcy5rO3JldHVybiBvLnB1c2gociksdGhpcy5rPW8ubGVuZ3RoPmU/by5zbGljZSgtZSk6byx0aGlzLkooKSx0aGlzfWdldExhc3RCcmVhZGNydW1iKCl7cmV0dXJuIHRoaXMua1t0aGlzLmsubGVuZ3RoLTFdfWNsZWFyQnJlYWRjcnVtYnMoKXtyZXR1cm4gdGhpcy5rPVtdLHRoaXMuSigpLHRoaXN9YWRkQXR0YWNobWVudCh0KXtyZXR1cm4gdGhpcy5DLnB1c2godCksdGhpc31jbGVhckF0dGFjaG1lbnRzKCl7cmV0dXJuIHRoaXMuQz1bXSx0aGlzfWdldFNjb3BlRGF0YSgpe3JldHVybnticmVhZGNydW1iczp0aGlzLmssYXR0YWNobWVudHM6dGhpcy5DLGNvbnRleHRzOnRoaXMuaix0YWdzOnRoaXMuVCxleHRyYTp0aGlzLk8sdXNlcjp0aGlzLkQsbGV2ZWw6dGhpcy5JLGZpbmdlcnByaW50OnRoaXMuTXx8W10sZXZlbnRQcm9jZXNzb3JzOnRoaXMuTixwcm9wYWdhdGlvbkNvbnRleHQ6dGhpcy5BLHNka1Byb2Nlc3NpbmdNZXRhZGF0YTp0aGlzLlIsdHJhbnNhY3Rpb25OYW1lOnRoaXMuVSxzcGFuOnd0KHRoaXMpfX1zZXRTREtQcm9jZXNzaW5nTWV0YWRhdGEodCl7cmV0dXJuIHRoaXMuUj17Li4udGhpcy5SLC4uLnR9LHRoaXN9c2V0UHJvcGFnYXRpb25Db250ZXh0KHQpe3JldHVybiB0aGlzLkE9dCx0aGlzfWdldFByb3BhZ2F0aW9uQ29udGV4dCgpe3JldHVybiB0aGlzLkF9Y2FwdHVyZUV4Y2VwdGlvbih0LG4pe2NvbnN0IGU9biYmbi5ldmVudF9pZD9uLmV2ZW50X2lkOnooKTtpZighdGhpcy5CKXJldHVybiBrLndhcm4oIk5vIGNsaWVudCBjb25maWd1cmVkIG9uIHNjb3BlIC0gd2lsbCBub3QgY2FwdHVyZSBleGNlcHRpb24hIiksZTtjb25zdCByPW5ldyBFcnJvcigiU2VudHJ5IHN5bnRoZXRpY0V4Y2VwdGlvbiIpO3JldHVybiB0aGlzLkIuY2FwdHVyZUV4Y2VwdGlvbih0LHtvcmlnaW5hbEV4Y2VwdGlvbjp0LHN5bnRoZXRpY0V4Y2VwdGlvbjpyLC4uLm4sZXZlbnRfaWQ6ZX0sdGhpcyksZX1jYXB0dXJlTWVzc2FnZSh0LG4sZSl7Y29uc3Qgcj1lJiZlLmV2ZW50X2lkP2UuZXZlbnRfaWQ6eigpO2lmKCF0aGlzLkIpcmV0dXJuIGsud2FybigiTm8gY2xpZW50IGNvbmZpZ3VyZWQgb24gc2NvcGUgLSB3aWxsIG5vdCBjYXB0dXJlIG1lc3NhZ2UhIikscjtjb25zdCBvPW5ldyBFcnJvcih0KTtyZXR1cm4gdGhpcy5CLmNhcHR1cmVNZXNzYWdlKHQsbix7b3JpZ2luYWxFeGNlcHRpb246dCxzeW50aGV0aWNFeGNlcHRpb246bywuLi5lLGV2ZW50X2lkOnJ9LHRoaXMpLHJ9Y2FwdHVyZUV2ZW50KHQsbil7Y29uc3QgZT1uJiZuLmV2ZW50X2lkP24uZXZlbnRfaWQ6eigpO3JldHVybiB0aGlzLkI/KHRoaXMuQi5jYXB0dXJlRXZlbnQodCx7Li4ubixldmVudF9pZDplfSx0aGlzKSxlKTooay53YXJuKCJObyBjbGllbnQgY29uZmlndXJlZCBvbiBzY29wZSAtIHdpbGwgbm90IGNhcHR1cmUgZXZlbnQhIiksZSl9Sigpe3RoaXMuX3x8KHRoaXMuXz0hMCx0aGlzLlMuZm9yRWFjaCgodD0+e3QodGhpcyl9KSksdGhpcy5fPSExKX19Y29uc3QgJHQ9U3Q7Y2xhc3MgRXR7Y29uc3RydWN0b3IodCxuKXtsZXQgZSxyO2U9dHx8bmV3ICR0LHI9bnx8bmV3ICR0LHRoaXMuSD1be3Njb3BlOmV9XSx0aGlzLlc9cn13aXRoU2NvcGUodCl7Y29uc3Qgbj10aGlzLlkoKTtsZXQgZTt0cnl7ZT10KG4pfWNhdGNoKHQpe3Rocm93IHRoaXMucSgpLHR9cmV0dXJuIG0oZSk/ZS50aGVuKCh0PT4odGhpcy5xKCksdCkpLCh0PT57dGhyb3cgdGhpcy5xKCksdH0pKToodGhpcy5xKCksZSl9Z2V0Q2xpZW50KCl7cmV0dXJuIHRoaXMuZ2V0U3RhY2tUb3AoKS5jbGllbnR9Z2V0U2NvcGUoKXtyZXR1cm4gdGhpcy5nZXRTdGFja1RvcCgpLnNjb3BlfWdldElzb2xhdGlvblNjb3BlKCl7cmV0dXJuIHRoaXMuV31nZXRTdGFjaygpe3JldHVybiB0aGlzLkh9Z2V0U3RhY2tUb3AoKXtyZXR1cm4gdGhpcy5IW3RoaXMuSC5sZW5ndGgtMV19WSgpe2NvbnN0IHQ9dGhpcy5nZXRTY29wZSgpLmNsb25lKCk7cmV0dXJuIHRoaXMuZ2V0U3RhY2soKS5wdXNoKHtjbGllbnQ6dGhpcy5nZXRDbGllbnQoKSxzY29wZTp0fSksdH1xKCl7cmV0dXJuISh0aGlzLmdldFN0YWNrKCkubGVuZ3RoPD0xKSYmISF0aGlzLmdldFN0YWNrKCkucG9wKCl9fWZ1bmN0aW9uIHh0KCl7Y29uc3QgdD15dChtdCgpKTtyZXR1cm4gdC5zdGFjaz10LnN0YWNrfHxuZXcgRXQodigiZGVmYXVsdEN1cnJlbnRTY29wZSIsKCgpPT5uZXcgJHQpKSx2KCJkZWZhdWx0SXNvbGF0aW9uU2NvcGUiLCgoKT0+bmV3ICR0KSkpfWZ1bmN0aW9uIE50KHQpe3JldHVybiB4dCgpLndpdGhTY29wZSh0KX1mdW5jdGlvbiBrdCh0LG4pe2NvbnN0IGU9eHQoKTtyZXR1cm4gZS53aXRoU2NvcGUoKCgpPT4oZS5nZXRTdGFja1RvcCgpLnNjb3BlPXQsbih0KSkpKX1mdW5jdGlvbiBDdCh0KXtyZXR1cm4geHQoKS53aXRoU2NvcGUoKCgpPT50KHh0KCkuZ2V0SXNvbGF0aW9uU2NvcGUoKSkpKX1mdW5jdGlvbiBEdCh0KXtjb25zdCBuPXl0KHQpO3JldHVybiBuLmFjcz9uLmFjczp7d2l0aElzb2xhdGlvblNjb3BlOkN0LHdpdGhTY29wZTpOdCx3aXRoU2V0U2NvcGU6a3Qsd2l0aFNldElzb2xhdGlvblNjb3BlOih0LG4pPT5DdChuKSxnZXRDdXJyZW50U2NvcGU6KCk9Pnh0KCkuZ2V0U2NvcGUoKSxnZXRJc29sYXRpb25TY29wZTooKT0+eHQoKS5nZXRJc29sYXRpb25TY29wZSgpfX1mdW5jdGlvbiBUdCgpe3JldHVybiBEdChtdCgpKS5nZXRDdXJyZW50U2NvcGUoKS5nZXRDbGllbnQoKX1jb25zdCBPdD0iX3NlbnRyeU1ldHJpY3MiO2Z1bmN0aW9uIGp0KHQpe2NvbnN0IG49dFtPdF07aWYoIW4pcmV0dXJuO2NvbnN0IGU9e307Zm9yKGNvbnN0WyxbdCxyXV1vZiBuKXsoZVt0XXx8KGVbdF09W10pKS5wdXNoKFIocikpfXJldHVybiBlfWNvbnN0IFJ0PSJzZW50cnkuc291cmNlIixBdD0ic2VudHJ5LnNhbXBsZV9yYXRlIixJdD0ic2VudHJ5Lm9wIixQdD0ic2VudHJ5Lm9yaWdpbiIsVXQ9MCxNdD0xLEx0PTE7ZnVuY3Rpb24gQnQodCl7Y29uc3R7c3BhbklkOm4sdHJhY2VJZDplfT10LnNwYW5Db250ZXh0KCkse3BhcmVudF9zcGFuX2lkOnJ9PXp0KHQpO3JldHVybiBSKHtwYXJlbnRfc3Bhbl9pZDpyLHNwYW5faWQ6bix0cmFjZV9pZDplfSl9ZnVuY3Rpb24gR3QodCl7cmV0dXJuIm51bWJlciI9PXR5cGVvZiB0P0p0KHQpOkFycmF5LmlzQXJyYXkodCk/dFswXSt0WzFdLzFlOTp0IGluc3RhbmNlb2YgRGF0ZT9KdCh0LmdldFRpbWUoKSk6SigpfWZ1bmN0aW9uIEp0KHQpe3JldHVybiB0Pjk5OTk5OTk5OTk/dC8xZTM6dH1mdW5jdGlvbiB6dCh0KXtpZihmdW5jdGlvbih0KXtyZXR1cm4iZnVuY3Rpb24iPT10eXBlb2YgdC5nZXRTcGFuSlNPTn0odCkpcmV0dXJuIHQuZ2V0U3BhbkpTT04oKTt0cnl7Y29uc3R7c3BhbklkOm4sdHJhY2VJZDplfT10LnNwYW5Db250ZXh0KCk7aWYoZnVuY3Rpb24odCl7Y29uc3Qgbj10O3JldHVybiEhKG4uYXR0cmlidXRlcyYmbi5zdGFydFRpbWUmJm4ubmFtZSYmbi5lbmRUaW1lJiZuLnN0YXR1cyl9KHQpKXtjb25zdHthdHRyaWJ1dGVzOnIsc3RhcnRUaW1lOm8sbmFtZTpzLGVuZFRpbWU6aSxwYXJlbnRTcGFuSWQ6YyxzdGF0dXM6dX09dDtyZXR1cm4gUih7c3Bhbl9pZDpuLHRyYWNlX2lkOmUsZGF0YTpyLGRlc2NyaXB0aW9uOnMscGFyZW50X3NwYW5faWQ6YyxzdGFydF90aW1lc3RhbXA6R3QobyksdGltZXN0YW1wOkd0KGkpfHx2b2lkIDAsc3RhdHVzOkh0KHUpLG9wOnJbSXRdLG9yaWdpbjpyW1B0XSxfbWV0cmljc19zdW1tYXJ5Omp0KHQpfSl9cmV0dXJue3NwYW5faWQ6bix0cmFjZV9pZDplfX1jYXRjaCh0KXtyZXR1cm57fX19ZnVuY3Rpb24gSHQodCl7aWYodCYmdC5jb2RlIT09VXQpcmV0dXJuIHQuY29kZT09PU10PyJvayI6dC5tZXNzYWdlfHwidW5rbm93bl9lcnJvciJ9Y29uc3QgV3Q9Il9zZW50cnlSb290U3BhbiI7ZnVuY3Rpb24gWXQodCl7cmV0dXJuIHRbV3RdfHx0fWNvbnN0IHF0PSJwcm9kdWN0aW9uIixGdD0iX2Zyb3plbkRzYyI7ZnVuY3Rpb24gS3QodCl7Y29uc3Qgbj1UdCgpO2lmKCFuKXJldHVybnt9O2NvbnN0IGU9ZnVuY3Rpb24odCxuKXtjb25zdCBlPW4uZ2V0T3B0aW9ucygpLHtwdWJsaWNLZXk6cn09bi5nZXREc24oKXx8e30sbz1SKHtlbnZpcm9ubWVudDplLmVudmlyb25tZW50fHxxdCxyZWxlYXNlOmUucmVsZWFzZSxwdWJsaWNfa2V5OnIsdHJhY2VfaWQ6dH0pO3JldHVybiBuLmVtaXQoImNyZWF0ZURzYyIsbyksb30oenQodCkudHJhY2VfaWR8fCIiLG4pLHI9WXQodCksbz1yW0Z0XTtpZihvKXJldHVybiBvO2NvbnN0IHM9ci5zcGFuQ29udGV4dCgpLnRyYWNlU3RhdGUsaT1zJiZzLmdldCgic2VudHJ5LmRzYyIpLGM9aSYmZXQoaSk7aWYoYylyZXR1cm4gYztjb25zdCB1PXp0KHIpLGE9dS5kYXRhfHx7fSxmPWFbQXRdO251bGwhPWYmJihlLnNhbXBsZV9yYXRlPWAke2Z9YCk7Y29uc3QgaD1hW1J0XSxwPXUuZGVzY3JpcHRpb247cmV0dXJuInVybCIhPT1oJiZwJiYoZS50cmFuc2FjdGlvbj1wKSxlLnNhbXBsZWQ9U3RyaW5nKGZ1bmN0aW9uKHQpe2NvbnN0e3RyYWNlRmxhZ3M6bn09dC5zcGFuQ29udGV4dCgpO3JldHVybiBuPT09THR9KHIpKSxuLmVtaXQoImNyZWF0ZURzYyIsZSxyKSxlfWZ1bmN0aW9uIFZ0KHQsbixlLHIpe2NvbnN0IG89ZnQoZSkscz10LnR5cGUmJiJyZXBsYXlfZXZlbnQiIT09dC50eXBlP3QudHlwZToiZXZlbnQiOyFmdW5jdGlvbih0LG4pe24mJih0LnNkaz10LnNka3x8e30sdC5zZGsubmFtZT10LnNkay5uYW1lfHxuLm5hbWUsdC5zZGsudmVyc2lvbj10LnNkay52ZXJzaW9ufHxuLnZlcnNpb24sdC5zZGsuaW50ZWdyYXRpb25zPVsuLi50LnNkay5pbnRlZ3JhdGlvbnN8fFtdLC4uLm4uaW50ZWdyYXRpb25zfHxbXV0sdC5zZGsucGFja2FnZXM9Wy4uLnQuc2RrLnBhY2thZ2VzfHxbXSwuLi5uLnBhY2thZ2VzfHxbXV0pfSh0LGUmJmUuc2RrKTtjb25zdCBpPWZ1bmN0aW9uKHQsbixlLHIpe2NvbnN0IG89dC5zZGtQcm9jZXNzaW5nTWV0YWRhdGEmJnQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhLmR5bmFtaWNTYW1wbGluZ0NvbnRleHQ7cmV0dXJue2V2ZW50X2lkOnQuZXZlbnRfaWQsc2VudF9hdDoobmV3IERhdGUpLnRvSVNPU3RyaW5nKCksLi4ubiYme3NkazpufSwuLi4hIWUmJnImJntkc246QyhyKX0sLi4ubyYme3RyYWNlOlIoey4uLm99KX19fSh0LG8scixuKTtkZWxldGUgdC5zZGtQcm9jZXNzaW5nTWV0YWRhdGE7cmV0dXJuIG90KGksW1t7dHlwZTpzfSx0XV0pfWNvbnN0IFp0PSJfX1NFTlRSWV9TVVBQUkVTU19UUkFDSU5HX18iO2Z1bmN0aW9uIFF0KHQpe2NvbnN0IG49RHQobXQoKSk7cmV0dXJuIG4uc3VwcHJlc3NUcmFjaW5nP24uc3VwcHJlc3NUcmFjaW5nKHQpOmZ1bmN0aW9uKC4uLnQpe2NvbnN0IG49RHQobXQoKSk7aWYoMj09PXQubGVuZ3RoKXtjb25zdFtlLHJdPXQ7cmV0dXJuIGU/bi53aXRoU2V0U2NvcGUoZSxyKTpuLndpdGhTY29wZShyKX1yZXR1cm4gbi53aXRoU2NvcGUodFswXSl9KChuPT4obi5zZXRTREtQcm9jZXNzaW5nTWV0YWRhdGEoe1tadF06ITB9KSx0KCkpKSl9ZnVuY3Rpb24gWHQodCxuKXtjb25zdHtmaW5nZXJwcmludDplLHNwYW46cixicmVhZGNydW1iczpvLHNka1Byb2Nlc3NpbmdNZXRhZGF0YTpzfT1uOyFmdW5jdGlvbih0LG4pe2NvbnN0e2V4dHJhOmUsdGFnczpyLHVzZXI6byxjb250ZXh0czpzLGxldmVsOmksdHJhbnNhY3Rpb25OYW1lOmN9PW4sdT1SKGUpO3UmJk9iamVjdC5rZXlzKHUpLmxlbmd0aCYmKHQuZXh0cmE9ey4uLnUsLi4udC5leHRyYX0pO2NvbnN0IGE9UihyKTthJiZPYmplY3Qua2V5cyhhKS5sZW5ndGgmJih0LnRhZ3M9ey4uLmEsLi4udC50YWdzfSk7Y29uc3QgZj1SKG8pO2YmJk9iamVjdC5rZXlzKGYpLmxlbmd0aCYmKHQudXNlcj17Li4uZiwuLi50LnVzZXJ9KTtjb25zdCBoPVIocyk7aCYmT2JqZWN0LmtleXMoaCkubGVuZ3RoJiYodC5jb250ZXh0cz17Li4uaCwuLi50LmNvbnRleHRzfSk7aSYmKHQubGV2ZWw9aSk7YyYmInRyYW5zYWN0aW9uIiE9PXQudHlwZSYmKHQudHJhbnNhY3Rpb249Yyl9KHQsbiksciYmZnVuY3Rpb24odCxuKXt0LmNvbnRleHRzPXt0cmFjZTpCdChuKSwuLi50LmNvbnRleHRzfSx0LnNka1Byb2Nlc3NpbmdNZXRhZGF0YT17ZHluYW1pY1NhbXBsaW5nQ29udGV4dDpLdChuKSwuLi50LnNka1Byb2Nlc3NpbmdNZXRhZGF0YX07Y29uc3QgZT1ZdChuKSxyPXp0KGUpLmRlc2NyaXB0aW9uO3ImJiF0LnRyYW5zYWN0aW9uJiYidHJhbnNhY3Rpb24iPT09dC50eXBlJiYodC50cmFuc2FjdGlvbj1yKX0odCxyKSxmdW5jdGlvbih0LG4pe3QuZmluZ2VycHJpbnQ9dC5maW5nZXJwcmludD9mdW5jdGlvbih0KXtyZXR1cm4gQXJyYXkuaXNBcnJheSh0KT90Olt0XX0odC5maW5nZXJwcmludCk6W10sbiYmKHQuZmluZ2VycHJpbnQ9dC5maW5nZXJwcmludC5jb25jYXQobikpO3QuZmluZ2VycHJpbnQmJiF0LmZpbmdlcnByaW50Lmxlbmd0aCYmZGVsZXRlIHQuZmluZ2VycHJpbnR9KHQsZSksZnVuY3Rpb24odCxuKXtjb25zdCBlPVsuLi50LmJyZWFkY3J1bWJzfHxbXSwuLi5uXTt0LmJyZWFkY3J1bWJzPWUubGVuZ3RoP2U6dm9pZCAwfSh0LG8pLGZ1bmN0aW9uKHQsbil7dC5zZGtQcm9jZXNzaW5nTWV0YWRhdGE9ey4uLnQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhLC4uLm59fSh0LHMpfWNvbnN0IHRuPSI3IjtmdW5jdGlvbiBubih0LG4pe3JldHVybiBlPXtzZW50cnlfa2V5OnQucHVibGljS2V5LHNlbnRyeV92ZXJzaW9uOnRuLC4uLm4mJntzZW50cnlfY2xpZW50OmAke24ubmFtZX0vJHtuLnZlcnNpb259YH19LE9iamVjdC5rZXlzKGUpLm1hcCgodD0+YCR7ZW5jb2RlVVJJQ29tcG9uZW50KHQpfT0ke2VuY29kZVVSSUNvbXBvbmVudChlW3RdKX1gKSkuam9pbigiJiIpO3ZhciBlfWNvbnN0IGVuPTY0O2Z1bmN0aW9uIHJuKHQsbixlPVEodC5idWZmZXJTaXplfHxlbikpe2xldCByPXt9O3JldHVybntzZW5kOmZ1bmN0aW9uKG8pe2NvbnN0IHM9W107aWYoc3QobywoKG4sZSk9Pntjb25zdCBvPWF0KGUpO2lmKGZ1bmN0aW9uKHQsbixlPURhdGUubm93KCkpe3JldHVybiBmdW5jdGlvbih0LG4pe3JldHVybiB0W25dfHx0LmFsbHx8MH0odCxuKT5lfShyLG8pKXtjb25zdCByPW9uKG4sZSk7dC5yZWNvcmREcm9wcGVkRXZlbnQoInJhdGVsaW1pdF9iYWNrb2ZmIixvLHIpfWVsc2Ugcy5wdXNoKG4pfSkpLDA9PT1zLmxlbmd0aClyZXR1cm4gVih7fSk7Y29uc3QgaT1vdChvWzBdLHMpLGM9bj0+e3N0KGksKChlLHIpPT57Y29uc3Qgbz1vbihlLHIpO3QucmVjb3JkRHJvcHBlZEV2ZW50KG4sYXQociksbyl9KSl9O3JldHVybiBlLmFkZCgoKCk9Pm4oe2JvZHk6Y3QoaSl9KS50aGVuKCh0PT4odm9pZCAwIT09dC5zdGF0dXNDb2RlJiYodC5zdGF0dXNDb2RlPDIwMHx8dC5zdGF0dXNDb2RlPj0zMDApJiZsdCYmay53YXJuKGBTZW50cnkgcmVzcG9uZGVkIHdpdGggc3RhdHVzIGNvZGUgJHt0LnN0YXR1c0NvZGV9IHRvIHNlbnQgZXZlbnQuYCkscj1wdChyLHQpLHQpKSwodD0+e3Rocm93IGMoIm5ldHdvcmtfZXJyb3IiKSx0fSkpKSkudGhlbigodD0+dCksKHQ9PntpZih0IGluc3RhbmNlb2YgRClyZXR1cm4gbHQmJmsuZXJyb3IoIlNraXBwZWQgc2VuZGluZyBldmVudCBiZWNhdXNlIGJ1ZmZlciBpcyBmdWxsLiIpLGMoInF1ZXVlX292ZXJmbG93IiksVih7fSk7dGhyb3cgdH0pKX0sZmx1c2g6dD0+ZS5kcmFpbih0KX19ZnVuY3Rpb24gb24odCxuKXtpZigiZXZlbnQiPT09bnx8InRyYW5zYWN0aW9uIj09PW4pcmV0dXJuIEFycmF5LmlzQXJyYXkodCk/dFsxXTp2b2lkIDB9Y29uc3Qgc249U3ltYm9sKCJBZ2VudEJhc2VJbnRlcm5hbFN0YXRlIik7Y2xhc3MgY24gZXh0ZW5kcyBzLkFnZW50e1tzbl07b3B0aW9ucztrZWVwQWxpdmU7Y29uc3RydWN0b3IodCl7c3VwZXIodCksdGhpc1tzbl09e319aXNTZWN1cmVFbmRwb2ludCh0KXtpZih0KXtpZigiYm9vbGVhbiI9PXR5cGVvZiB0LnNlY3VyZUVuZHBvaW50KXJldHVybiB0LnNlY3VyZUVuZHBvaW50O2lmKCJzdHJpbmciPT10eXBlb2YgdC5wcm90b2NvbClyZXR1cm4iaHR0cHM6Ij09PXQucHJvdG9jb2x9Y29uc3R7c3RhY2s6bn09bmV3IEVycm9yO3JldHVybiJzdHJpbmciPT10eXBlb2YgbiYmbi5zcGxpdCgiXG4iKS5zb21lKCh0PT4tMSE9PXQuaW5kZXhPZigiKGh0dHBzLmpzOiIpfHwtMSE9PXQuaW5kZXhPZigibm9kZTpodHRwczoiKSkpfWNyZWF0ZVNvY2tldCh0LG4sZSl7Y29uc3Qgcj17Li4ubixzZWN1cmVFbmRwb2ludDp0aGlzLmlzU2VjdXJlRW5kcG9pbnQobil9O1Byb21pc2UucmVzb2x2ZSgpLnRoZW4oKCgpPT50aGlzLmNvbm5lY3QodCxyKSkpLnRoZW4oKG89PntpZihvIGluc3RhbmNlb2Ygcy5BZ2VudClyZXR1cm4gby5hZGRSZXF1ZXN0KHQscik7dGhpc1tzbl0uY3VycmVudFNvY2tldD1vLHN1cGVyLmNyZWF0ZVNvY2tldCh0LG4sZSl9KSxlKX1jcmVhdGVDb25uZWN0aW9uKCl7Y29uc3QgdD10aGlzW3NuXS5jdXJyZW50U29ja2V0O2lmKHRoaXNbc25dLmN1cnJlbnRTb2NrZXQ9dm9pZCAwLCF0KXRocm93IG5ldyBFcnJvcigiTm8gc29ja2V0IHdhcyByZXR1cm5lZCBpbiB0aGUgYGNvbm5lY3QoKWAgZnVuY3Rpb24iKTtyZXR1cm4gdH1nZXQgZGVmYXVsdFBvcnQoKXtyZXR1cm4gdGhpc1tzbl0uZGVmYXVsdFBvcnQ/PygiaHR0cHM6Ij09PXRoaXMucHJvdG9jb2w/NDQzOjgwKX1zZXQgZGVmYXVsdFBvcnQodCl7dGhpc1tzbl0mJih0aGlzW3NuXS5kZWZhdWx0UG9ydD10KX1nZXQgcHJvdG9jb2woKXtyZXR1cm4gdGhpc1tzbl0ucHJvdG9jb2w/Pyh0aGlzLmlzU2VjdXJlRW5kcG9pbnQoKT8iaHR0cHM6IjoiaHR0cDoiKX1zZXQgcHJvdG9jb2wodCl7dGhpc1tzbl0mJih0aGlzW3NuXS5wcm90b2NvbD10KX19ZnVuY3Rpb24gdW4oLi4udCl7ay5sb2coIltodHRwcy1wcm94eS1hZ2VudDpwYXJzZS1wcm94eS1yZXNwb25zZV0iLC4uLnQpfWZ1bmN0aW9uIGFuKHQpe3JldHVybiBuZXcgUHJvbWlzZSgoKG4sZSk9PntsZXQgcj0wO2NvbnN0IG89W107ZnVuY3Rpb24gcygpe2NvbnN0IGM9dC5yZWFkKCk7Yz9mdW5jdGlvbihjKXtvLnB1c2goYykscis9Yy5sZW5ndGg7Y29uc3QgdT1CdWZmZXIuY29uY2F0KG8sciksYT11LmluZGV4T2YoIlxyXG5cclxuIik7aWYoLTE9PT1hKXJldHVybiB1bigiaGF2ZSBub3QgcmVjZWl2ZWQgZW5kIG9mIEhUVFAgaGVhZGVycyB5ZXQuLi4iKSx2b2lkIHMoKTtjb25zdCBmPXUuc2xpY2UoMCxhKS50b1N0cmluZygiYXNjaWkiKS5zcGxpdCgiXHJcbiIpLGg9Zi5zaGlmdCgpO2lmKCFoKXJldHVybiB0LmRlc3Ryb3koKSxlKG5ldyBFcnJvcigiTm8gaGVhZGVyIHJlY2VpdmVkIGZyb20gcHJveHkgQ09OTkVDVCByZXNwb25zZSIpKTtjb25zdCBwPWguc3BsaXQoIiAiKSxkPSsocFsxXXx8MCksbD1wLnNsaWNlKDIpLmpvaW4oIiAiKSxtPXt9O2Zvcihjb25zdCBuIG9mIGYpe2lmKCFuKWNvbnRpbnVlO2NvbnN0IHI9bi5pbmRleE9mKCI6Iik7aWYoLTE9PT1yKXJldHVybiB0LmRlc3Ryb3koKSxlKG5ldyBFcnJvcihgSW52YWxpZCBoZWFkZXIgZnJvbSBwcm94eSBDT05ORUNUIHJlc3BvbnNlOiAiJHtufSJgKSk7Y29uc3Qgbz1uLnNsaWNlKDAscikudG9Mb3dlckNhc2UoKSxzPW4uc2xpY2UocisxKS50cmltU3RhcnQoKSxpPW1bb107InN0cmluZyI9PXR5cGVvZiBpP21bb109W2ksc106QXJyYXkuaXNBcnJheShpKT9pLnB1c2gocyk6bVtvXT1zfXVuKCJnb3QgcHJveHkgc2VydmVyIHJlc3BvbnNlOiAlbyAlbyIsaCxtKSxpKCksbih7Y29ubmVjdDp7c3RhdHVzQ29kZTpkLHN0YXR1c1RleHQ6bCxoZWFkZXJzOm19LGJ1ZmZlcmVkOnV9KX0oYyk6dC5vbmNlKCJyZWFkYWJsZSIscyl9ZnVuY3Rpb24gaSgpe3QucmVtb3ZlTGlzdGVuZXIoImVuZCIsYyksdC5yZW1vdmVMaXN0ZW5lcigiZXJyb3IiLHUpLHQucmVtb3ZlTGlzdGVuZXIoInJlYWRhYmxlIixzKX1mdW5jdGlvbiBjKCl7aSgpLHVuKCJvbmVuZCIpLGUobmV3IEVycm9yKCJQcm94eSBjb25uZWN0aW9uIGVuZGVkIGJlZm9yZSByZWNlaXZpbmcgQ09OTkVDVCByZXNwb25zZSIpKX1mdW5jdGlvbiB1KHQpe2koKSx1bigib25lcnJvciAlbyIsdCksZSh0KX10Lm9uKCJlcnJvciIsdSksdC5vbigiZW5kIixjKSxzKCl9KSl9ZnVuY3Rpb24gZm4oLi4udCl7ay5sb2coIltodHRwcy1wcm94eS1hZ2VudF0iLC4uLnQpfWNsYXNzIGhuIGV4dGVuZHMgY257c3RhdGljIHByb3RvY29scz1bImh0dHAiLCJodHRwcyJdO3Byb3h5O3Byb3h5SGVhZGVycztjb25uZWN0T3B0cztjb25zdHJ1Y3Rvcih0LG4pe3N1cGVyKG4pLHRoaXMub3B0aW9ucz17fSx0aGlzLnByb3h5PSJzdHJpbmciPT10eXBlb2YgdD9uZXcgVVJMKHQpOnQsdGhpcy5wcm94eUhlYWRlcnM9bj8uaGVhZGVycz8/e30sZm4oIkNyZWF0aW5nIG5ldyBIdHRwc1Byb3h5QWdlbnQgaW5zdGFuY2U6ICVvIix0aGlzLnByb3h5LmhyZWYpO2NvbnN0IGU9KHRoaXMucHJveHkuaG9zdG5hbWV8fHRoaXMucHJveHkuaG9zdCkucmVwbGFjZSgvXlxbfFxdJC9nLCIiKSxyPXRoaXMucHJveHkucG9ydD9wYXJzZUludCh0aGlzLnByb3h5LnBvcnQsMTApOiJodHRwczoiPT09dGhpcy5wcm94eS5wcm90b2NvbD80NDM6ODA7dGhpcy5jb25uZWN0T3B0cz17QUxQTlByb3RvY29sczpbImh0dHAvMS4xIl0sLi4ubj9kbihuLCJoZWFkZXJzIik6bnVsbCxob3N0OmUscG9ydDpyfX1hc3luYyBjb25uZWN0KHQsbil7Y29uc3R7cHJveHk6ZX09dGhpcztpZighbi5ob3N0KXRocm93IG5ldyBUeXBlRXJyb3IoJ05vICJob3N0IiBwcm92aWRlZCcpO2xldCByO2lmKCJodHRwczoiPT09ZS5wcm90b2NvbCl7Zm4oIkNyZWF0aW5nIGB0bHMuU29ja2V0YDogJW8iLHRoaXMuY29ubmVjdE9wdHMpO2NvbnN0IHQ9dGhpcy5jb25uZWN0T3B0cy5zZXJ2ZXJuYW1lfHx0aGlzLmNvbm5lY3RPcHRzLmhvc3Q7cj1mLmNvbm5lY3Qoey4uLnRoaXMuY29ubmVjdE9wdHMsc2VydmVybmFtZTp0JiZhLmlzSVAodCk/dm9pZCAwOnR9KX1lbHNlIGZuKCJDcmVhdGluZyBgbmV0LlNvY2tldGA6ICVvIix0aGlzLmNvbm5lY3RPcHRzKSxyPWEuY29ubmVjdCh0aGlzLmNvbm5lY3RPcHRzKTtjb25zdCBvPSJmdW5jdGlvbiI9PXR5cGVvZiB0aGlzLnByb3h5SGVhZGVycz90aGlzLnByb3h5SGVhZGVycygpOnsuLi50aGlzLnByb3h5SGVhZGVyc30scz1hLmlzSVB2NihuLmhvc3QpP2BbJHtuLmhvc3R9XWA6bi5ob3N0O2xldCBpPWBDT05ORUNUICR7c306JHtuLnBvcnR9IEhUVFAvMS4xXHJcbmA7aWYoZS51c2VybmFtZXx8ZS5wYXNzd29yZCl7Y29uc3QgdD1gJHtkZWNvZGVVUklDb21wb25lbnQoZS51c2VybmFtZSl9OiR7ZGVjb2RlVVJJQ29tcG9uZW50KGUucGFzc3dvcmQpfWA7b1siUHJveHktQXV0aG9yaXphdGlvbiJdPWBCYXNpYyAke0J1ZmZlci5mcm9tKHQpLnRvU3RyaW5nKCJiYXNlNjQiKX1gfW8uSG9zdD1gJHtzfToke24ucG9ydH1gLG9bIlByb3h5LUNvbm5lY3Rpb24iXXx8KG9bIlByb3h5LUNvbm5lY3Rpb24iXT10aGlzLmtlZXBBbGl2ZT8iS2VlcC1BbGl2ZSI6ImNsb3NlIik7Zm9yKGNvbnN0IHQgb2YgT2JqZWN0LmtleXMobykpaSs9YCR7dH06ICR7b1t0XX1cclxuYDtjb25zdCBjPWFuKHIpO3Iud3JpdGUoYCR7aX1cclxuYCk7Y29uc3R7Y29ubmVjdDp1LGJ1ZmZlcmVkOmh9PWF3YWl0IGM7aWYodC5lbWl0KCJwcm94eUNvbm5lY3QiLHUpLHRoaXMuZW1pdCgicHJveHlDb25uZWN0Iix1LHQpLDIwMD09PXUuc3RhdHVzQ29kZSl7aWYodC5vbmNlKCJzb2NrZXQiLHBuKSxuLnNlY3VyZUVuZHBvaW50KXtmbigiVXBncmFkaW5nIHNvY2tldCBjb25uZWN0aW9uIHRvIFRMUyIpO2NvbnN0IHQ9bi5zZXJ2ZXJuYW1lfHxuLmhvc3Q7cmV0dXJuIGYuY29ubmVjdCh7Li4uZG4obiwiaG9zdCIsInBhdGgiLCJwb3J0Iiksc29ja2V0OnIsc2VydmVybmFtZTphLmlzSVAodCk/dm9pZCAwOnR9KX1yZXR1cm4gcn1yLmRlc3Ryb3koKTtjb25zdCBwPW5ldyBhLlNvY2tldCh7d3JpdGFibGU6ITF9KTtyZXR1cm4gcC5yZWFkYWJsZT0hMCx0Lm9uY2UoInNvY2tldCIsKHQ9PntmbigiUmVwbGF5aW5nIHByb3h5IGJ1ZmZlciBmb3IgZmFpbGVkIHJlcXVlc3QiKSx0LnB1c2goaCksdC5wdXNoKG51bGwpfSkpLHB9fWZ1bmN0aW9uIHBuKHQpe3QucmVzdW1lKCl9ZnVuY3Rpb24gZG4odCwuLi5uKXtjb25zdCBlPXt9O2xldCByO2ZvcihyIGluIHQpbi5pbmNsdWRlcyhyKXx8KGVbcl09dFtyXSk7cmV0dXJuIGV9Y29uc3QgbG49MzI3Njg7ZnVuY3Rpb24gbW4odCl7cmV0dXJuIHQucmVwbGFjZSgvXltBLVpdOi8sIiIpLnJlcGxhY2UoL1xcL2csIi8iKX1jb25zdCB5bj1lO2xldCBnbixibj0hMTtmdW5jdGlvbiB2bih0KXt5bi5kZWJ1ZyYmY29uc29sZS5sb2coYFtBTlIgV29ya2VyXSAke3R9YCl9dmFyIF9uLHduLFNuO2NvbnN0ICRuPWZ1bmN0aW9uKHQpe2xldCBuO3RyeXtuPW5ldyBVUkwodC51cmwpfWNhdGNoKG4pe3JldHVybiBOKCgoKT0+e2NvbnNvbGUud2FybigiW0BzZW50cnkvbm9kZV06IEludmFsaWQgZHNuIG9yIHR1bm5lbCBvcHRpb24sIHdpbGwgbm90IHNlbmQgYW55IGV2ZW50cy4gVGhlIHR1bm5lbCBvcHRpb24gbXVzdCBiZSBhIGZ1bGwgVVJMIHdoZW4gdXNlZC4iKX0pKSxybih0LCgoKT0+UHJvbWlzZS5yZXNvbHZlKHt9KSkpfWNvbnN0IGU9Imh0dHBzOiI9PT1uLnByb3RvY29sLHI9ZnVuY3Rpb24odCxuKXtjb25zdHtub19wcm94eTplfT1wcm9jZXNzLmVudjtyZXR1cm4gZSYmZS5zcGxpdCgiLCIpLnNvbWUoKG49PnQuaG9zdC5lbmRzV2l0aChuKXx8dC5ob3N0bmFtZS5lbmRzV2l0aChuKSkpP3ZvaWQgMDpufShuLHQucHJveHl8fChlP3Byb2Nlc3MuZW52Lmh0dHBzX3Byb3h5OnZvaWQgMCl8fHByb2Nlc3MuZW52Lmh0dHBfcHJveHkpLG89ZT9pOnMsYT12b2lkIDAhPT10LmtlZXBBbGl2ZSYmdC5rZWVwQWxpdmUsZj1yP25ldyBobihyKTpuZXcgby5BZ2VudCh7a2VlcEFsaXZlOmEsbWF4U29ja2V0czozMCx0aW1lb3V0OjJlM30pO3JldHVybiBRdCgoKCk9Pntjb25zdCBuPWZ1bmN0aW9uKHQsbixlKXtjb25zdHtob3N0bmFtZTpyLHBhdGhuYW1lOm8scG9ydDpzLHByb3RvY29sOmksc2VhcmNoOmF9PW5ldyBVUkwodC51cmwpO3JldHVybiBmdW5jdGlvbihmKXtyZXR1cm4gbmV3IFByb21pc2UoKChoLHApPT57bGV0IGQ9ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyBjKHtyZWFkKCl7dGhpcy5wdXNoKHQpLHRoaXMucHVzaChudWxsKX19KX0oZi5ib2R5KTtjb25zdCBsPXsuLi50LmhlYWRlcnN9O2YuYm9keS5sZW5ndGg+bG4mJihsWyJjb250ZW50LWVuY29kaW5nIl09Imd6aXAiLGQ9ZC5waXBlKHUoKSkpO2NvbnN0IG09bi5yZXF1ZXN0KHttZXRob2Q6IlBPU1QiLGFnZW50OmUsaGVhZGVyczpsLGhvc3RuYW1lOnIscGF0aDpgJHtvfSR7YX1gLHBvcnQ6cyxwcm90b2NvbDppLGNhOnQuY2FDZXJ0c30sKHQ9Pnt0Lm9uKCJkYXRhIiwoKCk9Pnt9KSksdC5vbigiZW5kIiwoKCk9Pnt9KSksdC5zZXRFbmNvZGluZygidXRmOCIpO2NvbnN0IG49dC5oZWFkZXJzWyJyZXRyeS1hZnRlciJdPz9udWxsLGU9dC5oZWFkZXJzWyJ4LXNlbnRyeS1yYXRlLWxpbWl0cyJdPz9udWxsO2goe3N0YXR1c0NvZGU6dC5zdGF0dXNDb2RlLGhlYWRlcnM6eyJyZXRyeS1hZnRlciI6biwieC1zZW50cnktcmF0ZS1saW1pdHMiOkFycmF5LmlzQXJyYXkoZSk/ZVswXXx8bnVsbDplfX0pfSkpO20ub24oImVycm9yIixwKSxkLnBpcGUobSl9KSl9fSh0LHQuaHR0cE1vZHVsZT8/byxmKTtyZXR1cm4gcm4odCxuKX0pKX0oe3VybDooX249eW4uZHNuLHduPXluLnR1bm5lbCxTbj15bi5zZGtNZXRhZGF0YS5zZGssd258fGAke2Z1bmN0aW9uKHQpe3JldHVybmAke2Z1bmN0aW9uKHQpe2NvbnN0IG49dC5wcm90b2NvbD9gJHt0LnByb3RvY29sfTpgOiIiLGU9dC5wb3J0P2A6JHt0LnBvcnR9YDoiIjtyZXR1cm5gJHtufS8vJHt0Lmhvc3R9JHtlfSR7dC5wYXRoP2AvJHt0LnBhdGh9YDoiIn0vYXBpL2B9KHQpfSR7dC5wcm9qZWN0SWR9L2VudmVsb3BlL2B9KF9uKX0/JHtubihfbixTbil9YCkscmVjb3JkRHJvcHBlZEV2ZW50OigpPT57fX0pO2FzeW5jIGZ1bmN0aW9uIEVuKCl7aWYoZ24pe3ZuKCJTZW5kaW5nIGFibm9ybWFsIHNlc3Npb24iKSxidChnbix7c3RhdHVzOiJhYm5vcm1hbCIsYWJub3JtYWxfbWVjaGFuaXNtOiJhbnJfZm9yZWdyb3VuZCJ9KTtjb25zdCB0PWZ1bmN0aW9uKHQsbixlLHIpe2NvbnN0IG89ZnQoZSk7cmV0dXJuIG90KHtzZW50X2F0OihuZXcgRGF0ZSkudG9JU09TdHJpbmcoKSwuLi5vJiZ7c2RrOm99LC4uLiEhciYmbiYme2RzbjpDKG4pfX0sWyJhZ2dyZWdhdGVzImluIHQ/W3t0eXBlOiJzZXNzaW9ucyJ9LHRdOlt7dHlwZToic2Vzc2lvbiJ9LHQudG9KU09OKCldXSl9KGduLHluLmRzbix5bi5zZGtNZXRhZGF0YSx5bi50dW5uZWwpO3ZuKEpTT04uc3RyaW5naWZ5KHQpKSxhd2FpdCAkbi5zZW5kKHQpO3RyeXtuPy5wb3N0TWVzc2FnZSgic2Vzc2lvbi1lbmRlZCIpfWNhdGNoKHQpe319fWZ1bmN0aW9uIHhuKHQpe2lmKCF0KXJldHVybjtjb25zdCBuPWZ1bmN0aW9uKHQpe2lmKCF0Lmxlbmd0aClyZXR1cm5bXTtjb25zdCBuPUFycmF5LmZyb20odCk7cmV0dXJuL3NlbnRyeVdyYXBwZWQvLnRlc3QoTShuKS5mdW5jdGlvbnx8IiIpJiZuLnBvcCgpLG4ucmV2ZXJzZSgpLFUudGVzdChNKG4pLmZ1bmN0aW9ufHwiIikmJihuLnBvcCgpLFUudGVzdChNKG4pLmZ1bmN0aW9ufHwiIikmJm4ucG9wKCkpLG4uc2xpY2UoMCxJKS5tYXAoKHQ9Pih7Li4udCxmaWxlbmFtZTp0LmZpbGVuYW1lfHxNKG4pLmZpbGVuYW1lLGZ1bmN0aW9uOnQuZnVuY3Rpb258fFB9KSkpfSh0KTtpZih5bi5hcHBSb290UGF0aClmb3IoY29uc3QgdCBvZiBuKXQuZmlsZW5hbWUmJih0LmZpbGVuYW1lPVkodC5maWxlbmFtZSx5bi5hcHBSb290UGF0aCkpO3JldHVybiBufWFzeW5jIGZ1bmN0aW9uIE5uKHQsbil7aWYoYm4pcmV0dXJuO2JuPSEwLGF3YWl0IEVuKCksdm4oIlNlbmRpbmcgZXZlbnQiKTtjb25zdCBlPXtldmVudF9pZDp6KCksY29udGV4dHM6eW4uY29udGV4dHMscmVsZWFzZTp5bi5yZWxlYXNlLGVudmlyb25tZW50OnluLmVudmlyb25tZW50LGRpc3Q6eW4uZGlzdCxwbGF0Zm9ybToibm9kZSIsbGV2ZWw6ImVycm9yIixleGNlcHRpb246e3ZhbHVlczpbe3R5cGU6IkFwcGxpY2F0aW9uTm90UmVzcG9uZGluZyIsdmFsdWU6YEFwcGxpY2F0aW9uIE5vdCBSZXNwb25kaW5nIGZvciBhdCBsZWFzdCAke3luLmFuclRocmVzaG9sZH0gbXNgLHN0YWNrdHJhY2U6e2ZyYW1lczp4bih0KX0sbWVjaGFuaXNtOnt0eXBlOiJBTlIifX1dfSx0YWdzOnluLnN0YXRpY1RhZ3N9O24mJmZ1bmN0aW9uKHQsbil7aWYoWHQodCxuKSwhdC5jb250ZXh0cz8udHJhY2Upe2NvbnN0e3RyYWNlSWQ6ZSxzcGFuSWQ6cixwYXJlbnRTcGFuSWQ6b309bi5wcm9wYWdhdGlvbkNvbnRleHQ7dC5jb250ZXh0cz17dHJhY2U6e3RyYWNlX2lkOmUsc3Bhbl9pZDpyLHBhcmVudF9zcGFuX2lkOm99LC4uLnQuY29udGV4dHN9fX0oZSxuKTtjb25zdCByPVZ0KGUseW4uZHNuLHluLnNka01ldGFkYXRhLHluLnR1bm5lbCk7dm4oSlNPTi5zdHJpbmdpZnkocikpLGF3YWl0ICRuLnNlbmQociksYXdhaXQgJG4uZmx1c2goMmUzKSxzZXRUaW1lb3V0KCgoKT0+e3Byb2Nlc3MuZXhpdCgwKX0pLDVlMyl9bGV0IGtuO2lmKHZuKCJTdGFydGVkIikseW4uY2FwdHVyZVN0YWNrVHJhY2Upe3ZuKCJDb25uZWN0aW5nIHRvIGRlYnVnZ2VyIik7Y29uc3Qgbj1uZXcgdDtuLmNvbm5lY3RUb01haW5UaHJlYWQoKSx2bigiQ29ubmVjdGVkIHRvIGRlYnVnZ2VyIik7Y29uc3QgZT1uZXcgTWFwO24ub24oIkRlYnVnZ2VyLnNjcmlwdFBhcnNlZCIsKHQ9PntlLnNldCh0LnBhcmFtcy5zY3JpcHRJZCx0LnBhcmFtcy51cmwpfSkpLG4ub24oIkRlYnVnZ2VyLnBhdXNlZCIsKHQ9PntpZigib3RoZXIiPT09dC5wYXJhbXMucmVhc29uKXRyeXt2bigiRGVidWdnZXIgcGF1c2VkIik7Y29uc3Qgcz1bLi4udC5wYXJhbXMuY2FsbEZyYW1lc10saT15bi5hcHBSb290UGF0aD9mdW5jdGlvbih0PShwcm9jZXNzLmFyZ3ZbMV0/Rihwcm9jZXNzLmFyZ3ZbMV0pOnByb2Nlc3MuY3dkKCkpLG49IlxcIj09PW8pe2NvbnN0IGU9bj9tbih0KTp0O3JldHVybiB0PT57aWYoIXQpcmV0dXJuO2NvbnN0IG89bj9tbih0KTp0O2xldHtkaXI6cyxiYXNlOmksZXh0OmN9PXIucGFyc2Uobyk7Ii5qcyIhPT1jJiYiLm1qcyIhPT1jJiYiLmNqcyIhPT1jfHwoaT1pLnNsaWNlKDAsLTEqYy5sZW5ndGgpKSxzfHwocz0iLiIpO2NvbnN0IHU9cy5sYXN0SW5kZXhPZigiL25vZGVfbW9kdWxlcyIpO2lmKHU+LTEpcmV0dXJuYCR7cy5zbGljZSh1KzE0KS5yZXBsYWNlKC9cLy9nLCIuIil9OiR7aX1gO2lmKHMuc3RhcnRzV2l0aChlKSl7bGV0IHQ9cy5zbGljZShlLmxlbmd0aCsxKS5yZXBsYWNlKC9cLy9nLCIuIik7cmV0dXJuIHQmJih0Kz0iOiIpLHQrPWksdH1yZXR1cm4gaX19KHluLmFwcFJvb3RQYXRoKTooKT0+e30sYz1zLm1hcCgodD0+ZnVuY3Rpb24odCxuLGUpe2NvbnN0IHI9bj9uLnJlcGxhY2UoL15maWxlOlwvXC8vLCIiKTp2b2lkIDAsbz10LmxvY2F0aW9uLmNvbHVtbk51bWJlcj90LmxvY2F0aW9uLmNvbHVtbk51bWJlcisxOnZvaWQgMCxzPXQubG9jYXRpb24ubGluZU51bWJlcj90LmxvY2F0aW9uLmxpbmVOdW1iZXIrMTp2b2lkIDA7cmV0dXJuIFIoe2ZpbGVuYW1lOnIsbW9kdWxlOmUociksZnVuY3Rpb246dC5mdW5jdGlvbk5hbWV8fFAsY29sbm86byxsaW5lbm86cyxpbl9hcHA6cj9YKHIpOnZvaWQgMH0pfSh0LGUuZ2V0KHQubG9jYXRpb24uc2NyaXB0SWQpLGkpKSksdT1zZXRUaW1lb3V0KCgoKT0+e05uKGMpLnRoZW4obnVsbCwoKCk9Pnt2bigiU2VuZGluZyBBTlIgZXZlbnQgZmFpbGVkLiIpfSkpfSksNWUzKTtuLnBvc3QoIlJ1bnRpbWUuZXZhbHVhdGUiLHtleHByZXNzaW9uOiJnbG9iYWwuX19TRU5UUllfR0VUX1NDT1BFU19fKCk7IixzaWxlbnQ6ITAscmV0dXJuQnlWYWx1ZTohMH0sKCh0LGUpPT57dCYmdm4oYEVycm9yIGV4ZWN1dGluZyBzY3JpcHQ6ICcke3QubWVzc2FnZX0nYCksY2xlYXJUaW1lb3V0KHUpO2NvbnN0IHI9ZSYmZS5yZXN1bHQ/ZS5yZXN1bHQudmFsdWU6dm9pZCAwO24ucG9zdCgiRGVidWdnZXIucmVzdW1lIiksbi5wb3N0KCJEZWJ1Z2dlci5kaXNhYmxlIiksTm4oYyxyKS50aGVuKG51bGwsKCgpPT57dm4oIlNlbmRpbmcgQU5SIGV2ZW50IGZhaWxlZC4iKX0pKX0pKX1jYXRjaCh0KXt0aHJvdyBuLnBvc3QoIkRlYnVnZ2VyLnJlc3VtZSIpLG4ucG9zdCgiRGVidWdnZXIuZGlzYWJsZSIpLHR9fSkpLGtuPSgpPT57dHJ5e24ucG9zdCgiRGVidWdnZXIuZW5hYmxlIiwoKCk9PntuLnBvc3QoIkRlYnVnZ2VyLnBhdXNlIil9KSl9Y2F0Y2godCl7fX19Y29uc3R7cG9sbDpDbn09ZnVuY3Rpb24odCxuLGUscil7Y29uc3Qgbz10KCk7bGV0IHM9ITEsaT0hMDtyZXR1cm4gc2V0SW50ZXJ2YWwoKCgpPT57Y29uc3QgdD1vLmdldFRpbWVNcygpOyExPT09cyYmdD5uK2UmJihzPSEwLGkmJnIoKSksdDxuK2UmJihzPSExKX0pLDIwKSx7cG9sbDooKT0+e28ucmVzZXQoKX0sZW5hYmxlZDp0PT57aT10fX19KChmdW5jdGlvbigpe2xldCB0PXByb2Nlc3MuaHJ0aW1lKCk7cmV0dXJue2dldFRpbWVNczooKT0+e2NvbnN0W24sZV09cHJvY2Vzcy5ocnRpbWUodCk7cmV0dXJuIE1hdGguZmxvb3IoMWUzKm4rZS8xZTYpfSxyZXNldDooKT0+e3Q9cHJvY2Vzcy5ocnRpbWUoKX19fSkseW4ucG9sbEludGVydmFsLHluLmFuclRocmVzaG9sZCwoZnVuY3Rpb24oKXt2bigiV2F0Y2hkb2cgdGltZW91dCIpLGtuPyh2bigiUGF1c2luZyBkZWJ1Z2dlciB0byBjYXB0dXJlIHN0YWNrIHRyYWNlIiksa24oKSk6KHZuKCJDYXB0dXJpbmcgZXZlbnQgd2l0aG91dCBhIHN0YWNrIHRyYWNlIiksTm4oKS50aGVuKG51bGwsKCgpPT57dm4oIlNlbmRpbmcgQU5SIGV2ZW50IGZhaWxlZCBvbiB3YXRjaGRvZyB0aW1lb3V0LiIpfSkpKX0pKTtuPy5vbigibWVzc2FnZSIsKHQ9Pnt0LnNlc3Npb24mJihnbj1ndCh0LnNlc3Npb24pKSxDbigpfSkpOw==';
|
|
14
|
+
const base64WorkerScript = 'LyohIEBzZW50cnkvbm9kZSA4LjEyLjAgKGEzOGFjODgpIHwgaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdCAqLwppbXBvcnR7U2Vzc2lvbiBhcyB0fWZyb20ibm9kZTppbnNwZWN0b3IiO2ltcG9ydHtwYXJlbnRQb3J0IGFzIG4sd29ya2VyRGF0YSBhcyBlfWZyb20ibm9kZTp3b3JrZXJfdGhyZWFkcyI7aW1wb3J0e3Bvc2l4IGFzIHIsc2VwIGFzIG99ZnJvbSJub2RlOnBhdGgiO2ltcG9ydCphcyBzIGZyb20ibm9kZTpodHRwIjtpbXBvcnQqYXMgaSBmcm9tIm5vZGU6aHR0cHMiO2ltcG9ydHtSZWFkYWJsZSBhcyBjfWZyb20ibm9kZTpzdHJlYW0iO2ltcG9ydHtjcmVhdGVHemlwIGFzIHV9ZnJvbSJub2RlOnpsaWIiO2ltcG9ydCphcyBhIGZyb20ibm9kZTpuZXQiO2ltcG9ydCphcyBmIGZyb20ibm9kZTp0bHMiO2NvbnN0IGg9T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztmdW5jdGlvbiBwKHQsbil7cmV0dXJuIGguY2FsbCh0KT09PWBbb2JqZWN0ICR7bn1dYH1mdW5jdGlvbiBkKHQpe3JldHVybiBwKHQsIlN0cmluZyIpfWZ1bmN0aW9uIGwodCl7cmV0dXJuIHAodCwiT2JqZWN0Iil9ZnVuY3Rpb24gbSh0KXtyZXR1cm4gQm9vbGVhbih0JiZ0LnRoZW4mJiJmdW5jdGlvbiI9PXR5cGVvZiB0LnRoZW4pfWZ1bmN0aW9uIHkodCxuKXt0cnl7cmV0dXJuIHQgaW5zdGFuY2VvZiBufWNhdGNoKHQpe3JldHVybiExfX1jb25zdCBnPSI4LjEyLjAiLGI9Z2xvYmFsVGhpcztmdW5jdGlvbiB2KHQsbixlKXtjb25zdCByPWV8fGIsbz1yLl9fU0VOVFJZX189ci5fX1NFTlRSWV9ffHx7fSxzPW9bZ109b1tnXXx8e307cmV0dXJuIHNbdF18fChzW3RdPW4oKSl9Y29uc3QgXz1iLHc9ODA7ZnVuY3Rpb24gUyh0LG4pe2NvbnN0IGU9dCxyPVtdO2lmKCFlfHwhZS50YWdOYW1lKXJldHVybiIiO2lmKF8uSFRNTEVsZW1lbnQmJmUgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCYmZS5kYXRhc2V0KXtpZihlLmRhdGFzZXQuc2VudHJ5Q29tcG9uZW50KXJldHVybiBlLmRhdGFzZXQuc2VudHJ5Q29tcG9uZW50O2lmKGUuZGF0YXNldC5zZW50cnlFbGVtZW50KXJldHVybiBlLmRhdGFzZXQuc2VudHJ5RWxlbWVudH1yLnB1c2goZS50YWdOYW1lLnRvTG93ZXJDYXNlKCkpO2NvbnN0IG89biYmbi5sZW5ndGg/bi5maWx0ZXIoKHQ9PmUuZ2V0QXR0cmlidXRlKHQpKSkubWFwKCh0PT5bdCxlLmdldEF0dHJpYnV0ZSh0KV0pKTpudWxsO2lmKG8mJm8ubGVuZ3RoKW8uZm9yRWFjaCgodD0+e3IucHVzaChgWyR7dFswXX09IiR7dFsxXX0iXWApfSkpO2Vsc2V7ZS5pZCYmci5wdXNoKGAjJHtlLmlkfWApO2NvbnN0IHQ9ZS5jbGFzc05hbWU7aWYodCYmZCh0KSl7Y29uc3Qgbj10LnNwbGl0KC9ccysvKTtmb3IoY29uc3QgdCBvZiBuKXIucHVzaChgLiR7dH1gKX19Y29uc3Qgcz1bImFyaWEtbGFiZWwiLCJ0eXBlIiwibmFtZSIsInRpdGxlIiwiYWx0Il07Zm9yKGNvbnN0IHQgb2Ygcyl7Y29uc3Qgbj1lLmdldEF0dHJpYnV0ZSh0KTtuJiZyLnB1c2goYFske3R9PSIke259Il1gKX1yZXR1cm4gci5qb2luKCIiKX1jb25zdCAkPSJ1bmRlZmluZWQiPT10eXBlb2YgX19TRU5UUllfREVCVUdfX3x8X19TRU5UUllfREVCVUdfXyxFPVsiZGVidWciLCJpbmZvIiwid2FybiIsImVycm9yIiwibG9nIiwiYXNzZXJ0IiwidHJhY2UiXSx4PXt9O2Z1bmN0aW9uIE4odCl7aWYoISgiY29uc29sZSJpbiBiKSlyZXR1cm4gdCgpO2NvbnN0IG49Yi5jb25zb2xlLGU9e30scj1PYmplY3Qua2V5cyh4KTtyLmZvckVhY2goKHQ9Pntjb25zdCByPXhbdF07ZVt0XT1uW3RdLG5bdF09cn0pKTt0cnl7cmV0dXJuIHQoKX1maW5hbGx5e3IuZm9yRWFjaCgodD0+e25bdF09ZVt0XX0pKX19Y29uc3Qgaz1mdW5jdGlvbigpe2xldCB0PSExO2NvbnN0IG49e2VuYWJsZTooKT0+e3Q9ITB9LGRpc2FibGU6KCk9Pnt0PSExfSxpc0VuYWJsZWQ6KCk9PnR9O3JldHVybiAkP0UuZm9yRWFjaCgoZT0+e25bZV09KC4uLm4pPT57dCYmTigoKCk9PntiLmNvbnNvbGVbZV0oYFNlbnRyeSBMb2dnZXIgWyR7ZX1dOmAsLi4ubil9KSl9fSkpOkUuZm9yRWFjaCgodD0+e25bdF09KCk9Pnt9fSkpLG59KCk7ZnVuY3Rpb24gQyh0LG49ITEpe2NvbnN0e2hvc3Q6ZSxwYXRoOnIscGFzczpvLHBvcnQ6cyxwcm9qZWN0SWQ6aSxwcm90b2NvbDpjLHB1YmxpY0tleTp1fT10O3JldHVybmAke2N9Oi8vJHt1fSR7biYmbz9gOiR7b31gOiIifUAke2V9JHtzP2A6JHtzfWA6IiJ9LyR7cj9gJHtyfS9gOnJ9JHtpfWB9Y2xhc3MgRCBleHRlbmRzIEVycm9ye2NvbnN0cnVjdG9yKHQsbj0id2FybiIpe3N1cGVyKHQpLHRoaXMubWVzc2FnZT10LHRoaXMubmFtZT1uZXcudGFyZ2V0LnByb3RvdHlwZS5jb25zdHJ1Y3Rvci5uYW1lLE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLG5ldy50YXJnZXQucHJvdG90eXBlKSx0aGlzLmxvZ0xldmVsPW59fWZ1bmN0aW9uIFQodCl7aWYoZnVuY3Rpb24odCl7c3dpdGNoKGguY2FsbCh0KSl7Y2FzZSJbb2JqZWN0IEVycm9yXSI6Y2FzZSJbb2JqZWN0IEV4Y2VwdGlvbl0iOmNhc2UiW29iamVjdCBET01FeGNlcHRpb25dIjpyZXR1cm4hMDtkZWZhdWx0OnJldHVybiB5KHQsRXJyb3IpfX0odCkpcmV0dXJue21lc3NhZ2U6dC5tZXNzYWdlLG5hbWU6dC5uYW1lLHN0YWNrOnQuc3RhY2ssLi4uaih0KX07aWYobj10LCJ1bmRlZmluZWQiIT10eXBlb2YgRXZlbnQmJnkobixFdmVudCkpe2NvbnN0IG49e3R5cGU6dC50eXBlLHRhcmdldDpPKHQudGFyZ2V0KSxjdXJyZW50VGFyZ2V0Ok8odC5jdXJyZW50VGFyZ2V0KSwuLi5qKHQpfTtyZXR1cm4idW5kZWZpbmVkIiE9dHlwZW9mIEN1c3RvbUV2ZW50JiZ5KHQsQ3VzdG9tRXZlbnQpJiYobi5kZXRhaWw9dC5kZXRhaWwpLG59cmV0dXJuIHQ7dmFyIG59ZnVuY3Rpb24gTyh0KXt0cnl7cmV0dXJuIG49dCwidW5kZWZpbmVkIiE9dHlwZW9mIEVsZW1lbnQmJnkobixFbGVtZW50KT9mdW5jdGlvbih0LG49e30pe2lmKCF0KXJldHVybiI8dW5rbm93bj4iO3RyeXtsZXQgZT10O2NvbnN0IHI9NSxvPVtdO2xldCBzPTAsaT0wO2NvbnN0IGM9IiA+ICIsdT1jLmxlbmd0aDtsZXQgYTtjb25zdCBmPUFycmF5LmlzQXJyYXkobik/bjpuLmtleUF0dHJzLGg9IUFycmF5LmlzQXJyYXkobikmJm4ubWF4U3RyaW5nTGVuZ3RofHx3O2Zvcig7ZSYmcysrPHImJihhPVMoZSxmKSwhKCJodG1sIj09PWF8fHM+MSYmaStvLmxlbmd0aCp1K2EubGVuZ3RoPj1oKSk7KW8ucHVzaChhKSxpKz1hLmxlbmd0aCxlPWUucGFyZW50Tm9kZTtyZXR1cm4gby5yZXZlcnNlKCkuam9pbihjKX1jYXRjaCh0KXtyZXR1cm4iPHVua25vd24+In19KHQpOk9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0KX1jYXRjaCh0KXtyZXR1cm4iPHVua25vd24+In12YXIgbn1mdW5jdGlvbiBqKHQpe2lmKCJvYmplY3QiPT10eXBlb2YgdCYmbnVsbCE9PXQpe2NvbnN0IG49e307Zm9yKGNvbnN0IGUgaW4gdClPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodCxlKSYmKG5bZV09dFtlXSk7cmV0dXJuIG59cmV0dXJue319ZnVuY3Rpb24gUih0KXtyZXR1cm4gQSh0LG5ldyBNYXApfWZ1bmN0aW9uIEEodCxuKXtpZihmdW5jdGlvbih0KXtpZighbCh0KSlyZXR1cm4hMTt0cnl7Y29uc3Qgbj1PYmplY3QuZ2V0UHJvdG90eXBlT2YodCkuY29uc3RydWN0b3IubmFtZTtyZXR1cm4hbnx8Ik9iamVjdCI9PT1ufWNhdGNoKHQpe3JldHVybiEwfX0odCkpe2NvbnN0IGU9bi5nZXQodCk7aWYodm9pZCAwIT09ZSlyZXR1cm4gZTtjb25zdCByPXt9O24uc2V0KHQscik7Zm9yKGNvbnN0IGUgb2YgT2JqZWN0LmtleXModCkpdm9pZCAwIT09dFtlXSYmKHJbZV09QSh0W2VdLG4pKTtyZXR1cm4gcn1pZihBcnJheS5pc0FycmF5KHQpKXtjb25zdCBlPW4uZ2V0KHQpO2lmKHZvaWQgMCE9PWUpcmV0dXJuIGU7Y29uc3Qgcj1bXTtyZXR1cm4gbi5zZXQodCxyKSx0LmZvckVhY2goKHQ9PntyLnB1c2goQSh0LG4pKX0pKSxyfXJldHVybiB0fWNvbnN0IEk9NTAsUD0iPyIsVT0vY2FwdHVyZU1lc3NhZ2V8Y2FwdHVyZUV4Y2VwdGlvbi87ZnVuY3Rpb24gTSh0KXtyZXR1cm4gdFt0Lmxlbmd0aC0xXXx8e319Y29uc3QgTD0iPGFub255bW91cz4iO2NvbnN0IEI9MWUzO2Z1bmN0aW9uIEcoKXtyZXR1cm4gRGF0ZS5ub3coKS9CfWNvbnN0IEo9ZnVuY3Rpb24oKXtjb25zdHtwZXJmb3JtYW5jZTp0fT1iO2lmKCF0fHwhdC5ub3cpcmV0dXJuIEc7Y29uc3Qgbj1EYXRlLm5vdygpLXQubm93KCksZT1udWxsPT10LnRpbWVPcmlnaW4/bjp0LnRpbWVPcmlnaW47cmV0dXJuKCk9PihlK3Qubm93KCkpL0J9KCk7ZnVuY3Rpb24geigpe2NvbnN0IHQ9YixuPXQuY3J5cHRvfHx0Lm1zQ3J5cHRvO2xldCBlPSgpPT4xNipNYXRoLnJhbmRvbSgpO3RyeXtpZihuJiZuLnJhbmRvbVVVSUQpcmV0dXJuIG4ucmFuZG9tVVVJRCgpLnJlcGxhY2UoLy0vZywiIik7biYmbi5nZXRSYW5kb21WYWx1ZXMmJihlPSgpPT57Y29uc3QgdD1uZXcgVWludDhBcnJheSgxKTtyZXR1cm4gbi5nZXRSYW5kb21WYWx1ZXModCksdFswXX0pfWNhdGNoKHQpe31yZXR1cm4oWzFlN10rMWUzKzRlMys4ZTMrMWUxMSkucmVwbGFjZSgvWzAxOF0vZywodD0+KHReKDE1JmUoKSk+PnQvNCkudG9TdHJpbmcoMTYpKSl9ZnVuY3Rpb24gSCh0LG49MTAwLGU9MS8wKXt0cnl7cmV0dXJuIFcoIiIsdCxuLGUpfWNhdGNoKHQpe3JldHVybntFUlJPUjpgKipub24tc2VyaWFsaXphYmxlKiogKCR7dH0pYH19fWZ1bmN0aW9uIFcodCxuLGU9MS8wLHI9MS8wLG89ZnVuY3Rpb24oKXtjb25zdCB0PSJmdW5jdGlvbiI9PXR5cGVvZiBXZWFrU2V0LG49dD9uZXcgV2Vha1NldDpbXTtyZXR1cm5bZnVuY3Rpb24oZSl7aWYodClyZXR1cm4hIW4uaGFzKGUpfHwobi5hZGQoZSksITEpO2ZvcihsZXQgdD0wO3Q8bi5sZW5ndGg7dCsrKWlmKG5bdF09PT1lKXJldHVybiEwO3JldHVybiBuLnB1c2goZSksITF9LGZ1bmN0aW9uKGUpe2lmKHQpbi5kZWxldGUoZSk7ZWxzZSBmb3IobGV0IHQ9MDt0PG4ubGVuZ3RoO3QrKylpZihuW3RdPT09ZSl7bi5zcGxpY2UodCwxKTticmVha319XX0oKSl7Y29uc3RbcyxpXT1vO2lmKG51bGw9PW58fFsibnVtYmVyIiwiYm9vbGVhbiIsInN0cmluZyJdLmluY2x1ZGVzKHR5cGVvZiBuKSYmIU51bWJlci5pc05hTihuKSlyZXR1cm4gbjtjb25zdCBjPWZ1bmN0aW9uKHQsbil7dHJ5e2lmKCJkb21haW4iPT09dCYmbiYmIm9iamVjdCI9PXR5cGVvZiBuJiZuLnQpcmV0dXJuIltEb21haW5dIjtpZigiZG9tYWluRW1pdHRlciI9PT10KXJldHVybiJbRG9tYWluRW1pdHRlcl0iO2lmKCJ1bmRlZmluZWQiIT10eXBlb2YgZ2xvYmFsJiZuPT09Z2xvYmFsKXJldHVybiJbR2xvYmFsXSI7aWYoInVuZGVmaW5lZCIhPXR5cGVvZiB3aW5kb3cmJm49PT13aW5kb3cpcmV0dXJuIltXaW5kb3ddIjtpZigidW5kZWZpbmVkIiE9dHlwZW9mIGRvY3VtZW50JiZuPT09ZG9jdW1lbnQpcmV0dXJuIltEb2N1bWVudF0iO2lmKCJvYmplY3QiPT10eXBlb2YoZT1uKSYmbnVsbCE9PWUmJihlLl9faXNWdWV8fGUubykpcmV0dXJuIltWdWVWaWV3TW9kZWxdIjtpZihmdW5jdGlvbih0KXtyZXR1cm4gbCh0KSYmIm5hdGl2ZUV2ZW50ImluIHQmJiJwcmV2ZW50RGVmYXVsdCJpbiB0JiYic3RvcFByb3BhZ2F0aW9uImluIHR9KG4pKXJldHVybiJbU3ludGhldGljRXZlbnRdIjtpZigibnVtYmVyIj09dHlwZW9mIG4mJm4hPW4pcmV0dXJuIltOYU5dIjtpZigiZnVuY3Rpb24iPT10eXBlb2YgbilyZXR1cm5gW0Z1bmN0aW9uOiAke2Z1bmN0aW9uKHQpe3RyeXtyZXR1cm4gdCYmImZ1bmN0aW9uIj09dHlwZW9mIHQmJnQubmFtZXx8TH1jYXRjaCh0KXtyZXR1cm4gTH19KG4pfV1gO2lmKCJzeW1ib2wiPT10eXBlb2YgbilyZXR1cm5gWyR7U3RyaW5nKG4pfV1gO2lmKCJiaWdpbnQiPT10eXBlb2YgbilyZXR1cm5gW0JpZ0ludDogJHtTdHJpbmcobil9XWA7Y29uc3Qgcj1mdW5jdGlvbih0KXtjb25zdCBuPU9iamVjdC5nZXRQcm90b3R5cGVPZih0KTtyZXR1cm4gbj9uLmNvbnN0cnVjdG9yLm5hbWU6Im51bGwgcHJvdG90eXBlIn0obik7cmV0dXJuL15IVE1MKFx3KilFbGVtZW50JC8udGVzdChyKT9gW0hUTUxFbGVtZW50OiAke3J9XWA6YFtvYmplY3QgJHtyfV1gfWNhdGNoKHQpe3JldHVybmAqKm5vbi1zZXJpYWxpemFibGUqKiAoJHt0fSlgfXZhciBlfSh0LG4pO2lmKCFjLnN0YXJ0c1dpdGgoIltvYmplY3QgIikpcmV0dXJuIGM7aWYobi5fX3NlbnRyeV9za2lwX25vcm1hbGl6YXRpb25fXylyZXR1cm4gbjtjb25zdCB1PSJudW1iZXIiPT10eXBlb2Ygbi5fX3NlbnRyeV9vdmVycmlkZV9ub3JtYWxpemF0aW9uX2RlcHRoX18/bi5fX3NlbnRyeV9vdmVycmlkZV9ub3JtYWxpemF0aW9uX2RlcHRoX186ZTtpZigwPT09dSlyZXR1cm4gYy5yZXBsYWNlKCJvYmplY3QgIiwiIik7aWYocyhuKSlyZXR1cm4iW0NpcmN1bGFyIH5dIjtjb25zdCBhPW47aWYoYSYmImZ1bmN0aW9uIj09dHlwZW9mIGEudG9KU09OKXRyeXtyZXR1cm4gVygiIixhLnRvSlNPTigpLHUtMSxyLG8pfWNhdGNoKHQpe31jb25zdCBmPUFycmF5LmlzQXJyYXkobik/W106e307bGV0IGg9MDtjb25zdCBwPVQobik7Zm9yKGNvbnN0IHQgaW4gcCl7aWYoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChwLHQpKWNvbnRpbnVlO2lmKGg+PXIpe2ZbdF09IltNYXhQcm9wZXJ0aWVzIH5dIjticmVha31jb25zdCBuPXBbdF07Zlt0XT1XKHQsbix1LTEscixvKSxoKyt9cmV0dXJuIGkobiksZn1mdW5jdGlvbiBZKHQsbil7Y29uc3QgZT1uLnJlcGxhY2UoL1xcL2csIi8iKS5yZXBsYWNlKC9bfFxce30oKVtcXV4kKyo/Ll0vZywiXFwkJiIpO2xldCByPXQ7dHJ5e3I9ZGVjb2RlVVJJKHQpfWNhdGNoKHQpe31yZXR1cm4gci5yZXBsYWNlKC9cXC9nLCIvIikucmVwbGFjZSgvd2VicGFjazpcLz8vZywiIikucmVwbGFjZShuZXcgUmVnRXhwKGAoZmlsZTovLyk/Lyoke2V9LypgLCJpZyIpLCJhcHA6Ly8vIil9KCgpPT57Y29uc3R7cGVyZm9ybWFuY2U6dH09YjtpZighdHx8IXQubm93KXJldHVybjtjb25zdCBuPTM2ZTUsZT10Lm5vdygpLHI9RGF0ZS5ub3coKSxvPXQudGltZU9yaWdpbj9NYXRoLmFicyh0LnRpbWVPcmlnaW4rZS1yKTpuLHM9bzxuLGk9dC50aW1pbmcmJnQudGltaW5nLm5hdmlnYXRpb25TdGFydCxjPSJudW1iZXIiPT10eXBlb2YgaT9NYXRoLmFicyhpK2Utcik6bjsoc3x8YzxuKSYmKG88PWMmJnQudGltZU9yaWdpbil9KSgpO2NvbnN0IHE9L14oXFMrOlxcfFwvPykoW1xzXFNdKj8pKCg/OlwuezEsMn18W14vXFxdKz98KShcLlteLi9cXF0qfCkpKD86Wy9cXF0qKSQvO2Z1bmN0aW9uIEYodCl7Y29uc3Qgbj1mdW5jdGlvbih0KXtjb25zdCBuPXQubGVuZ3RoPjEwMjQ/YDx0cnVuY2F0ZWQ+JHt0LnNsaWNlKC0xMDI0KX1gOnQsZT1xLmV4ZWMobik7cmV0dXJuIGU/ZS5zbGljZSgxKTpbXX0odCksZT1uWzBdfHwiIjtsZXQgcj1uWzFdO3JldHVybiBlfHxyPyhyJiYocj1yLnNsaWNlKDAsci5sZW5ndGgtMSkpLGUrcik6Ii4ifXZhciBLO2Z1bmN0aW9uIFYodCl7cmV0dXJuIG5ldyBaKChuPT57bih0KX0pKX0hZnVuY3Rpb24odCl7dFt0LlBFTkRJTkc9MF09IlBFTkRJTkciO3RbdC5SRVNPTFZFRD0xXT0iUkVTT0xWRUQiO3RbdC5SRUpFQ1RFRD0yXT0iUkVKRUNURUQifShLfHwoSz17fSkpO2NsYXNzIFp7Y29uc3RydWN0b3IodCl7Wi5wcm90b3R5cGUuX19pbml0LmNhbGwodGhpcyksWi5wcm90b3R5cGUuX19pbml0Mi5jYWxsKHRoaXMpLFoucHJvdG90eXBlLl9faW5pdDMuY2FsbCh0aGlzKSxaLnByb3RvdHlwZS5fX2luaXQ0LmNhbGwodGhpcyksdGhpcy5pPUsuUEVORElORyx0aGlzLnU9W107dHJ5e3QodGhpcy5oLHRoaXMucCl9Y2F0Y2godCl7dGhpcy5wKHQpfX10aGVuKHQsbil7cmV0dXJuIG5ldyBaKCgoZSxyKT0+e3RoaXMudS5wdXNoKFshMSxuPT57aWYodCl0cnl7ZSh0KG4pKX1jYXRjaCh0KXtyKHQpfWVsc2UgZShuKX0sdD0+e2lmKG4pdHJ5e2Uobih0KSl9Y2F0Y2godCl7cih0KX1lbHNlIHIodCl9XSksdGhpcy5sKCl9KSl9Y2F0Y2godCl7cmV0dXJuIHRoaXMudGhlbigodD0+dCksdCl9ZmluYWxseSh0KXtyZXR1cm4gbmV3IFooKChuLGUpPT57bGV0IHIsbztyZXR1cm4gdGhpcy50aGVuKChuPT57bz0hMSxyPW4sdCYmdCgpfSksKG49PntvPSEwLHI9bix0JiZ0KCl9KSkudGhlbigoKCk9PntvP2Uocik6bihyKX0pKX0pKX1fX2luaXQoKXt0aGlzLmg9dD0+e3RoaXMubShLLlJFU09MVkVELHQpfX1fX2luaXQyKCl7dGhpcy5wPXQ9Pnt0aGlzLm0oSy5SRUpFQ1RFRCx0KX19X19pbml0Mygpe3RoaXMubT0odCxuKT0+e3RoaXMuaT09PUsuUEVORElORyYmKG0obik/bi50aGVuKHRoaXMuaCx0aGlzLnApOih0aGlzLmk9dCx0aGlzLnY9bix0aGlzLmwoKSkpfX1fX2luaXQ0KCl7dGhpcy5sPSgpPT57aWYodGhpcy5pPT09Sy5QRU5ESU5HKXJldHVybjtjb25zdCB0PXRoaXMudS5zbGljZSgpO3RoaXMudT1bXSx0LmZvckVhY2goKHQ9Pnt0WzBdfHwodGhpcy5pPT09Sy5SRVNPTFZFRCYmdFsxXSh0aGlzLnYpLHRoaXMuaT09PUsuUkVKRUNURUQmJnRbMl0odGhpcy52KSx0WzBdPSEwKX0pKX19fWZ1bmN0aW9uIFEodCl7Y29uc3Qgbj1bXTtmdW5jdGlvbiBlKHQpe3JldHVybiBuLnNwbGljZShuLmluZGV4T2YodCksMSlbMF18fFByb21pc2UucmVzb2x2ZSh2b2lkIDApfXJldHVybnskOm4sYWRkOmZ1bmN0aW9uKHIpe2lmKCEodm9pZCAwPT09dHx8bi5sZW5ndGg8dCkpcmV0dXJuIG89bmV3IEQoIk5vdCBhZGRpbmcgUHJvbWlzZSBiZWNhdXNlIGJ1ZmZlciBsaW1pdCB3YXMgcmVhY2hlZC4iKSxuZXcgWigoKHQsbik9PntuKG8pfSkpO3ZhciBvO2NvbnN0IHM9cigpO3JldHVybi0xPT09bi5pbmRleE9mKHMpJiZuLnB1c2gocykscy50aGVuKCgoKT0+ZShzKSkpLnRoZW4obnVsbCwoKCk9PmUocykudGhlbihudWxsLCgoKT0+e30pKSkpLHN9LGRyYWluOmZ1bmN0aW9uKHQpe3JldHVybiBuZXcgWigoKGUscik9PntsZXQgbz1uLmxlbmd0aDtpZighbylyZXR1cm4gZSghMCk7Y29uc3Qgcz1zZXRUaW1lb3V0KCgoKT0+e3QmJnQ+MCYmZSghMSl9KSx0KTtuLmZvckVhY2goKHQ9PntWKHQpLnRoZW4oKCgpPT57LS1vfHwoY2xlYXJUaW1lb3V0KHMpLGUoITApKX0pLHIpfSkpfSkpfX19ZnVuY3Rpb24gWCh0LG49ITEpe3JldHVybiEobnx8dCYmIXQuc3RhcnRzV2l0aCgiLyIpJiYhdC5tYXRjaCgvXltBLVpdOi8pJiYhdC5zdGFydHNXaXRoKCIuIikmJiF0Lm1hdGNoKC9eW2EtekEtWl0oW2EtekEtWjAtOS5cLStdKSo6XC9cLy8pKSYmdm9pZCAwIT09dCYmIXQuaW5jbHVkZXMoIm5vZGVfbW9kdWxlcy8iKX1jb25zdCB0dD0ic2VudHJ5LSIsbnQ9L15zZW50cnktLztmdW5jdGlvbiBldCh0KXtjb25zdCBuPWZ1bmN0aW9uKHQpe2lmKCF0fHwhZCh0KSYmIUFycmF5LmlzQXJyYXkodCkpcmV0dXJuO2lmKEFycmF5LmlzQXJyYXkodCkpcmV0dXJuIHQucmVkdWNlKCgodCxuKT0+e2NvbnN0IGU9cnQobik7cmV0dXJuIE9iamVjdC5lbnRyaWVzKGUpLmZvckVhY2goKChbbixlXSk9Pnt0W25dPWV9KSksdH0pLHt9KTtyZXR1cm4gcnQodCl9KHQpO2lmKCFuKXJldHVybjtjb25zdCBlPU9iamVjdC5lbnRyaWVzKG4pLnJlZHVjZSgoKHQsW24sZV0pPT57aWYobi5tYXRjaChudCkpe3Rbbi5zbGljZSh0dC5sZW5ndGgpXT1lfXJldHVybiB0fSkse30pO3JldHVybiBPYmplY3Qua2V5cyhlKS5sZW5ndGg+MD9lOnZvaWQgMH1mdW5jdGlvbiBydCh0KXtyZXR1cm4gdC5zcGxpdCgiLCIpLm1hcCgodD0+dC5zcGxpdCgiPSIpLm1hcCgodD0+ZGVjb2RlVVJJQ29tcG9uZW50KHQudHJpbSgpKSkpKSkucmVkdWNlKCgodCxbbixlXSk9PihuJiZlJiYodFtuXT1lKSx0KSkse30pfWZ1bmN0aW9uIG90KHQsbj1bXSl7cmV0dXJuW3Qsbl19ZnVuY3Rpb24gc3QodCxuKXtjb25zdCBlPXRbMV07Zm9yKGNvbnN0IHQgb2YgZSl7aWYobih0LHRbMF0udHlwZSkpcmV0dXJuITB9cmV0dXJuITF9ZnVuY3Rpb24gaXQodCl7cmV0dXJuIGIuX19TRU5UUllfXyYmYi5fX1NFTlRSWV9fLmVuY29kZVBvbHlmaWxsP2IuX19TRU5UUllfXy5lbmNvZGVQb2x5ZmlsbCh0KToobmV3IFRleHRFbmNvZGVyKS5lbmNvZGUodCl9ZnVuY3Rpb24gY3QodCl7Y29uc3RbbixlXT10O2xldCByPUpTT04uc3RyaW5naWZ5KG4pO2Z1bmN0aW9uIG8odCl7InN0cmluZyI9PXR5cGVvZiByP3I9InN0cmluZyI9PXR5cGVvZiB0P3IrdDpbaXQociksdF06ci5wdXNoKCJzdHJpbmciPT10eXBlb2YgdD9pdCh0KTp0KX1mb3IoY29uc3QgdCBvZiBlKXtjb25zdFtuLGVdPXQ7aWYobyhgXG4ke0pTT04uc3RyaW5naWZ5KG4pfVxuYCksInN0cmluZyI9PXR5cGVvZiBlfHxlIGluc3RhbmNlb2YgVWludDhBcnJheSlvKGUpO2Vsc2V7bGV0IHQ7dHJ5e3Q9SlNPTi5zdHJpbmdpZnkoZSl9Y2F0Y2gobil7dD1KU09OLnN0cmluZ2lmeShIKGUpKX1vKHQpfX1yZXR1cm4ic3RyaW5nIj09dHlwZW9mIHI/cjpmdW5jdGlvbih0KXtjb25zdCBuPXQucmVkdWNlKCgodCxuKT0+dCtuLmxlbmd0aCksMCksZT1uZXcgVWludDhBcnJheShuKTtsZXQgcj0wO2Zvcihjb25zdCBuIG9mIHQpZS5zZXQobixyKSxyKz1uLmxlbmd0aDtyZXR1cm4gZX0ocil9Y29uc3QgdXQ9e3Nlc3Npb246InNlc3Npb24iLHNlc3Npb25zOiJzZXNzaW9uIixhdHRhY2htZW50OiJhdHRhY2htZW50Iix0cmFuc2FjdGlvbjoidHJhbnNhY3Rpb24iLGV2ZW50OiJlcnJvciIsY2xpZW50X3JlcG9ydDoiaW50ZXJuYWwiLHVzZXJfcmVwb3J0OiJkZWZhdWx0Iixwcm9maWxlOiJwcm9maWxlIixwcm9maWxlX2NodW5rOiJwcm9maWxlIixyZXBsYXlfZXZlbnQ6InJlcGxheSIscmVwbGF5X3JlY29yZGluZzoicmVwbGF5IixjaGVja19pbjoibW9uaXRvciIsZmVlZGJhY2s6ImZlZWRiYWNrIixzcGFuOiJzcGFuIixzdGF0c2Q6Im1ldHJpY19idWNrZXQifTtmdW5jdGlvbiBhdCh0KXtyZXR1cm4gdXRbdF19ZnVuY3Rpb24gZnQodCl7aWYoIXR8fCF0LnNkaylyZXR1cm47Y29uc3R7bmFtZTpuLHZlcnNpb246ZX09dC5zZGs7cmV0dXJue25hbWU6bix2ZXJzaW9uOmV9fWNvbnN0IGh0PTZlNDtmdW5jdGlvbiBwdCh0LHtzdGF0dXNDb2RlOm4saGVhZGVyczplfSxyPURhdGUubm93KCkpe2NvbnN0IG89ey4uLnR9LHM9ZSYmZVsieC1zZW50cnktcmF0ZS1saW1pdHMiXSxpPWUmJmVbInJldHJ5LWFmdGVyIl07aWYocylmb3IoY29uc3QgdCBvZiBzLnRyaW0oKS5zcGxpdCgiLCIpKXtjb25zdFtuLGUsLCxzXT10LnNwbGl0KCI6Iiw1KSxpPXBhcnNlSW50KG4sMTApLGM9MWUzKihpc05hTihpKT82MDppKTtpZihlKWZvcihjb25zdCB0IG9mIGUuc3BsaXQoIjsiKSkibWV0cmljX2J1Y2tldCI9PT10JiZzJiYhcy5zcGxpdCgiOyIpLmluY2x1ZGVzKCJjdXN0b20iKXx8KG9bdF09citjKTtlbHNlIG8uYWxsPXIrY31lbHNlIGk/by5hbGw9citmdW5jdGlvbih0LG49RGF0ZS5ub3coKSl7Y29uc3QgZT1wYXJzZUludChgJHt0fWAsMTApO2lmKCFpc05hTihlKSlyZXR1cm4gMWUzKmU7Y29uc3Qgcj1EYXRlLnBhcnNlKGAke3R9YCk7cmV0dXJuIGlzTmFOKHIpP2h0OnItbn0oaSxyKTo0Mjk9PT1uJiYoby5hbGw9cis2ZTQpO3JldHVybiBvfWZ1bmN0aW9uIGR0KCl7cmV0dXJue3RyYWNlSWQ6eigpLHNwYW5JZDp6KCkuc3Vic3RyaW5nKDE2KX19Y29uc3QgbHQ9InVuZGVmaW5lZCI9PXR5cGVvZiBfX1NFTlRSWV9ERUJVR19ffHxfX1NFTlRSWV9ERUJVR19fO2Z1bmN0aW9uIG10KCl7cmV0dXJuIHl0KGIpLGJ9ZnVuY3Rpb24geXQodCl7Y29uc3Qgbj10Ll9fU0VOVFJZX189dC5fX1NFTlRSWV9ffHx7fTtyZXR1cm4gbi52ZXJzaW9uPW4udmVyc2lvbnx8ZyxuW2ddPW5bZ118fHt9fWZ1bmN0aW9uIGd0KHQpe2NvbnN0IG49SigpLGU9e3NpZDp6KCksaW5pdDohMCx0aW1lc3RhbXA6bixzdGFydGVkOm4sZHVyYXRpb246MCxzdGF0dXM6Im9rIixlcnJvcnM6MCxpZ25vcmVEdXJhdGlvbjohMSx0b0pTT046KCk9PmZ1bmN0aW9uKHQpe3JldHVybiBSKHtzaWQ6YCR7dC5zaWR9YCxpbml0OnQuaW5pdCxzdGFydGVkOm5ldyBEYXRlKDFlMyp0LnN0YXJ0ZWQpLnRvSVNPU3RyaW5nKCksdGltZXN0YW1wOm5ldyBEYXRlKDFlMyp0LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKSxzdGF0dXM6dC5zdGF0dXMsZXJyb3JzOnQuZXJyb3JzLGRpZDoibnVtYmVyIj09dHlwZW9mIHQuZGlkfHwic3RyaW5nIj09dHlwZW9mIHQuZGlkP2Ake3QuZGlkfWA6dm9pZCAwLGR1cmF0aW9uOnQuZHVyYXRpb24sYWJub3JtYWxfbWVjaGFuaXNtOnQuYWJub3JtYWxfbWVjaGFuaXNtLGF0dHJzOntyZWxlYXNlOnQucmVsZWFzZSxlbnZpcm9ubWVudDp0LmVudmlyb25tZW50LGlwX2FkZHJlc3M6dC5pcEFkZHJlc3MsdXNlcl9hZ2VudDp0LnVzZXJBZ2VudH19KX0oZSl9O3JldHVybiB0JiZidChlLHQpLGV9ZnVuY3Rpb24gYnQodCxuPXt9KXtpZihuLnVzZXImJighdC5pcEFkZHJlc3MmJm4udXNlci5pcF9hZGRyZXNzJiYodC5pcEFkZHJlc3M9bi51c2VyLmlwX2FkZHJlc3MpLHQuZGlkfHxuLmRpZHx8KHQuZGlkPW4udXNlci5pZHx8bi51c2VyLmVtYWlsfHxuLnVzZXIudXNlcm5hbWUpKSx0LnRpbWVzdGFtcD1uLnRpbWVzdGFtcHx8SigpLG4uYWJub3JtYWxfbWVjaGFuaXNtJiYodC5hYm5vcm1hbF9tZWNoYW5pc209bi5hYm5vcm1hbF9tZWNoYW5pc20pLG4uaWdub3JlRHVyYXRpb24mJih0Lmlnbm9yZUR1cmF0aW9uPW4uaWdub3JlRHVyYXRpb24pLG4uc2lkJiYodC5zaWQ9MzI9PT1uLnNpZC5sZW5ndGg/bi5zaWQ6eigpKSx2b2lkIDAhPT1uLmluaXQmJih0LmluaXQ9bi5pbml0KSwhdC5kaWQmJm4uZGlkJiYodC5kaWQ9YCR7bi5kaWR9YCksIm51bWJlciI9PXR5cGVvZiBuLnN0YXJ0ZWQmJih0LnN0YXJ0ZWQ9bi5zdGFydGVkKSx0Lmlnbm9yZUR1cmF0aW9uKXQuZHVyYXRpb249dm9pZCAwO2Vsc2UgaWYoIm51bWJlciI9PXR5cGVvZiBuLmR1cmF0aW9uKXQuZHVyYXRpb249bi5kdXJhdGlvbjtlbHNle2NvbnN0IG49dC50aW1lc3RhbXAtdC5zdGFydGVkO3QuZHVyYXRpb249bj49MD9uOjB9bi5yZWxlYXNlJiYodC5yZWxlYXNlPW4ucmVsZWFzZSksbi5lbnZpcm9ubWVudCYmKHQuZW52aXJvbm1lbnQ9bi5lbnZpcm9ubWVudCksIXQuaXBBZGRyZXNzJiZuLmlwQWRkcmVzcyYmKHQuaXBBZGRyZXNzPW4uaXBBZGRyZXNzKSwhdC51c2VyQWdlbnQmJm4udXNlckFnZW50JiYodC51c2VyQWdlbnQ9bi51c2VyQWdlbnQpLCJudW1iZXIiPT10eXBlb2Ygbi5lcnJvcnMmJih0LmVycm9ycz1uLmVycm9ycyksbi5zdGF0dXMmJih0LnN0YXR1cz1uLnN0YXR1cyl9Y29uc3QgdnQ9Il9zZW50cnlTcGFuIjtmdW5jdGlvbiBfdCh0LG4pe24/ZnVuY3Rpb24odCxuLGUpe3RyeXtPYmplY3QuZGVmaW5lUHJvcGVydHkodCxuLHt2YWx1ZTplLHdyaXRhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMH0pfWNhdGNoKGUpeyQmJmsubG9nKGBGYWlsZWQgdG8gYWRkIG5vbi1lbnVtZXJhYmxlIHByb3BlcnR5ICIke259IiB0byBvYmplY3RgLHQpfX0odCx2dCxuKTpkZWxldGUgdFt2dF19ZnVuY3Rpb24gd3QodCl7cmV0dXJuIHRbdnRdfWNsYXNzIFN0e2NvbnN0cnVjdG9yKCl7dGhpcy5fPSExLHRoaXMuUz1bXSx0aGlzLk49W10sdGhpcy5rPVtdLHRoaXMuQz1bXSx0aGlzLkQ9e30sdGhpcy5UPXt9LHRoaXMuTz17fSx0aGlzLmo9e30sdGhpcy5SPXt9LHRoaXMuQT1kdCgpfWNsb25lKCl7Y29uc3QgdD1uZXcgU3Q7cmV0dXJuIHQuaz1bLi4udGhpcy5rXSx0LlQ9ey4uLnRoaXMuVH0sdC5PPXsuLi50aGlzLk99LHQuaj17Li4udGhpcy5qfSx0LkQ9dGhpcy5ELHQuST10aGlzLkksdC5QPXRoaXMuUCx0LlU9dGhpcy5VLHQuTT10aGlzLk0sdC5OPVsuLi50aGlzLk5dLHQuTD10aGlzLkwsdC5DPVsuLi50aGlzLkNdLHQuUj17Li4udGhpcy5SfSx0LkE9ey4uLnRoaXMuQX0sdC5CPXRoaXMuQix0Lkc9dGhpcy5HLF90KHQsd3QodGhpcykpLHR9c2V0Q2xpZW50KHQpe3RoaXMuQj10fXNldExhc3RFdmVudElkKHQpe3RoaXMuRz10fWdldENsaWVudCgpe3JldHVybiB0aGlzLkJ9bGFzdEV2ZW50SWQoKXtyZXR1cm4gdGhpcy5HfWFkZFNjb3BlTGlzdGVuZXIodCl7dGhpcy5TLnB1c2godCl9YWRkRXZlbnRQcm9jZXNzb3IodCl7cmV0dXJuIHRoaXMuTi5wdXNoKHQpLHRoaXN9c2V0VXNlcih0KXtyZXR1cm4gdGhpcy5EPXR8fHtlbWFpbDp2b2lkIDAsaWQ6dm9pZCAwLGlwX2FkZHJlc3M6dm9pZCAwLHVzZXJuYW1lOnZvaWQgMH0sdGhpcy5QJiZidCh0aGlzLlAse3VzZXI6dH0pLHRoaXMuSigpLHRoaXN9Z2V0VXNlcigpe3JldHVybiB0aGlzLkR9Z2V0UmVxdWVzdFNlc3Npb24oKXtyZXR1cm4gdGhpcy5MfXNldFJlcXVlc3RTZXNzaW9uKHQpe3JldHVybiB0aGlzLkw9dCx0aGlzfXNldFRhZ3ModCl7cmV0dXJuIHRoaXMuVD17Li4udGhpcy5ULC4uLnR9LHRoaXMuSigpLHRoaXN9c2V0VGFnKHQsbil7cmV0dXJuIHRoaXMuVD17Li4udGhpcy5ULFt0XTpufSx0aGlzLkooKSx0aGlzfXNldEV4dHJhcyh0KXtyZXR1cm4gdGhpcy5PPXsuLi50aGlzLk8sLi4udH0sdGhpcy5KKCksdGhpc31zZXRFeHRyYSh0LG4pe3JldHVybiB0aGlzLk89ey4uLnRoaXMuTyxbdF06bn0sdGhpcy5KKCksdGhpc31zZXRGaW5nZXJwcmludCh0KXtyZXR1cm4gdGhpcy5NPXQsdGhpcy5KKCksdGhpc31zZXRMZXZlbCh0KXtyZXR1cm4gdGhpcy5JPXQsdGhpcy5KKCksdGhpc31zZXRUcmFuc2FjdGlvbk5hbWUodCl7cmV0dXJuIHRoaXMuVT10LHRoaXMuSigpLHRoaXN9c2V0Q29udGV4dCh0LG4pe3JldHVybiBudWxsPT09bj9kZWxldGUgdGhpcy5qW3RdOnRoaXMualt0XT1uLHRoaXMuSigpLHRoaXN9c2V0U2Vzc2lvbih0KXtyZXR1cm4gdD90aGlzLlA9dDpkZWxldGUgdGhpcy5QLHRoaXMuSigpLHRoaXN9Z2V0U2Vzc2lvbigpe3JldHVybiB0aGlzLlB9dXBkYXRlKHQpe2lmKCF0KXJldHVybiB0aGlzO2NvbnN0IG49ImZ1bmN0aW9uIj09dHlwZW9mIHQ/dCh0aGlzKTp0LFtlLHJdPW4gaW5zdGFuY2VvZiAkdD9bbi5nZXRTY29wZURhdGEoKSxuLmdldFJlcXVlc3RTZXNzaW9uKCldOmwobik/W3QsdC5yZXF1ZXN0U2Vzc2lvbl06W10se3RhZ3M6byxleHRyYTpzLHVzZXI6aSxjb250ZXh0czpjLGxldmVsOnUsZmluZ2VycHJpbnQ6YT1bXSxwcm9wYWdhdGlvbkNvbnRleHQ6Zn09ZXx8e307cmV0dXJuIHRoaXMuVD17Li4udGhpcy5ULC4uLm99LHRoaXMuTz17Li4udGhpcy5PLC4uLnN9LHRoaXMuaj17Li4udGhpcy5qLC4uLmN9LGkmJk9iamVjdC5rZXlzKGkpLmxlbmd0aCYmKHRoaXMuRD1pKSx1JiYodGhpcy5JPXUpLGEubGVuZ3RoJiYodGhpcy5NPWEpLGYmJih0aGlzLkE9ZiksciYmKHRoaXMuTD1yKSx0aGlzfWNsZWFyKCl7cmV0dXJuIHRoaXMuaz1bXSx0aGlzLlQ9e30sdGhpcy5PPXt9LHRoaXMuRD17fSx0aGlzLmo9e30sdGhpcy5JPXZvaWQgMCx0aGlzLlU9dm9pZCAwLHRoaXMuTT12b2lkIDAsdGhpcy5MPXZvaWQgMCx0aGlzLlA9dm9pZCAwLF90KHRoaXMsdm9pZCAwKSx0aGlzLkM9W10sdGhpcy5BPWR0KCksdGhpcy5KKCksdGhpc31hZGRCcmVhZGNydW1iKHQsbil7Y29uc3QgZT0ibnVtYmVyIj09dHlwZW9mIG4/bjoxMDA7aWYoZTw9MClyZXR1cm4gdGhpcztjb25zdCByPXt0aW1lc3RhbXA6RygpLC4uLnR9LG89dGhpcy5rO3JldHVybiBvLnB1c2gociksdGhpcy5rPW8ubGVuZ3RoPmU/by5zbGljZSgtZSk6byx0aGlzLkooKSx0aGlzfWdldExhc3RCcmVhZGNydW1iKCl7cmV0dXJuIHRoaXMua1t0aGlzLmsubGVuZ3RoLTFdfWNsZWFyQnJlYWRjcnVtYnMoKXtyZXR1cm4gdGhpcy5rPVtdLHRoaXMuSigpLHRoaXN9YWRkQXR0YWNobWVudCh0KXtyZXR1cm4gdGhpcy5DLnB1c2godCksdGhpc31jbGVhckF0dGFjaG1lbnRzKCl7cmV0dXJuIHRoaXMuQz1bXSx0aGlzfWdldFNjb3BlRGF0YSgpe3JldHVybnticmVhZGNydW1iczp0aGlzLmssYXR0YWNobWVudHM6dGhpcy5DLGNvbnRleHRzOnRoaXMuaix0YWdzOnRoaXMuVCxleHRyYTp0aGlzLk8sdXNlcjp0aGlzLkQsbGV2ZWw6dGhpcy5JLGZpbmdlcnByaW50OnRoaXMuTXx8W10sZXZlbnRQcm9jZXNzb3JzOnRoaXMuTixwcm9wYWdhdGlvbkNvbnRleHQ6dGhpcy5BLHNka1Byb2Nlc3NpbmdNZXRhZGF0YTp0aGlzLlIsdHJhbnNhY3Rpb25OYW1lOnRoaXMuVSxzcGFuOnd0KHRoaXMpfX1zZXRTREtQcm9jZXNzaW5nTWV0YWRhdGEodCl7cmV0dXJuIHRoaXMuUj17Li4udGhpcy5SLC4uLnR9LHRoaXN9c2V0UHJvcGFnYXRpb25Db250ZXh0KHQpe3JldHVybiB0aGlzLkE9dCx0aGlzfWdldFByb3BhZ2F0aW9uQ29udGV4dCgpe3JldHVybiB0aGlzLkF9Y2FwdHVyZUV4Y2VwdGlvbih0LG4pe2NvbnN0IGU9biYmbi5ldmVudF9pZD9uLmV2ZW50X2lkOnooKTtpZighdGhpcy5CKXJldHVybiBrLndhcm4oIk5vIGNsaWVudCBjb25maWd1cmVkIG9uIHNjb3BlIC0gd2lsbCBub3QgY2FwdHVyZSBleGNlcHRpb24hIiksZTtjb25zdCByPW5ldyBFcnJvcigiU2VudHJ5IHN5bnRoZXRpY0V4Y2VwdGlvbiIpO3JldHVybiB0aGlzLkIuY2FwdHVyZUV4Y2VwdGlvbih0LHtvcmlnaW5hbEV4Y2VwdGlvbjp0LHN5bnRoZXRpY0V4Y2VwdGlvbjpyLC4uLm4sZXZlbnRfaWQ6ZX0sdGhpcyksZX1jYXB0dXJlTWVzc2FnZSh0LG4sZSl7Y29uc3Qgcj1lJiZlLmV2ZW50X2lkP2UuZXZlbnRfaWQ6eigpO2lmKCF0aGlzLkIpcmV0dXJuIGsud2FybigiTm8gY2xpZW50IGNvbmZpZ3VyZWQgb24gc2NvcGUgLSB3aWxsIG5vdCBjYXB0dXJlIG1lc3NhZ2UhIikscjtjb25zdCBvPW5ldyBFcnJvcih0KTtyZXR1cm4gdGhpcy5CLmNhcHR1cmVNZXNzYWdlKHQsbix7b3JpZ2luYWxFeGNlcHRpb246dCxzeW50aGV0aWNFeGNlcHRpb246bywuLi5lLGV2ZW50X2lkOnJ9LHRoaXMpLHJ9Y2FwdHVyZUV2ZW50KHQsbil7Y29uc3QgZT1uJiZuLmV2ZW50X2lkP24uZXZlbnRfaWQ6eigpO3JldHVybiB0aGlzLkI/KHRoaXMuQi5jYXB0dXJlRXZlbnQodCx7Li4ubixldmVudF9pZDplfSx0aGlzKSxlKTooay53YXJuKCJObyBjbGllbnQgY29uZmlndXJlZCBvbiBzY29wZSAtIHdpbGwgbm90IGNhcHR1cmUgZXZlbnQhIiksZSl9Sigpe3RoaXMuX3x8KHRoaXMuXz0hMCx0aGlzLlMuZm9yRWFjaCgodD0+e3QodGhpcyl9KSksdGhpcy5fPSExKX19Y29uc3QgJHQ9U3Q7Y2xhc3MgRXR7Y29uc3RydWN0b3IodCxuKXtsZXQgZSxyO2U9dHx8bmV3ICR0LHI9bnx8bmV3ICR0LHRoaXMuSD1be3Njb3BlOmV9XSx0aGlzLlc9cn13aXRoU2NvcGUodCl7Y29uc3Qgbj10aGlzLlkoKTtsZXQgZTt0cnl7ZT10KG4pfWNhdGNoKHQpe3Rocm93IHRoaXMucSgpLHR9cmV0dXJuIG0oZSk/ZS50aGVuKCh0PT4odGhpcy5xKCksdCkpLCh0PT57dGhyb3cgdGhpcy5xKCksdH0pKToodGhpcy5xKCksZSl9Z2V0Q2xpZW50KCl7cmV0dXJuIHRoaXMuZ2V0U3RhY2tUb3AoKS5jbGllbnR9Z2V0U2NvcGUoKXtyZXR1cm4gdGhpcy5nZXRTdGFja1RvcCgpLnNjb3BlfWdldElzb2xhdGlvblNjb3BlKCl7cmV0dXJuIHRoaXMuV31nZXRTdGFjaygpe3JldHVybiB0aGlzLkh9Z2V0U3RhY2tUb3AoKXtyZXR1cm4gdGhpcy5IW3RoaXMuSC5sZW5ndGgtMV19WSgpe2NvbnN0IHQ9dGhpcy5nZXRTY29wZSgpLmNsb25lKCk7cmV0dXJuIHRoaXMuZ2V0U3RhY2soKS5wdXNoKHtjbGllbnQ6dGhpcy5nZXRDbGllbnQoKSxzY29wZTp0fSksdH1xKCl7cmV0dXJuISh0aGlzLmdldFN0YWNrKCkubGVuZ3RoPD0xKSYmISF0aGlzLmdldFN0YWNrKCkucG9wKCl9fWZ1bmN0aW9uIHh0KCl7Y29uc3QgdD15dChtdCgpKTtyZXR1cm4gdC5zdGFjaz10LnN0YWNrfHxuZXcgRXQodigiZGVmYXVsdEN1cnJlbnRTY29wZSIsKCgpPT5uZXcgJHQpKSx2KCJkZWZhdWx0SXNvbGF0aW9uU2NvcGUiLCgoKT0+bmV3ICR0KSkpfWZ1bmN0aW9uIE50KHQpe3JldHVybiB4dCgpLndpdGhTY29wZSh0KX1mdW5jdGlvbiBrdCh0LG4pe2NvbnN0IGU9eHQoKTtyZXR1cm4gZS53aXRoU2NvcGUoKCgpPT4oZS5nZXRTdGFja1RvcCgpLnNjb3BlPXQsbih0KSkpKX1mdW5jdGlvbiBDdCh0KXtyZXR1cm4geHQoKS53aXRoU2NvcGUoKCgpPT50KHh0KCkuZ2V0SXNvbGF0aW9uU2NvcGUoKSkpKX1mdW5jdGlvbiBEdCh0KXtjb25zdCBuPXl0KHQpO3JldHVybiBuLmFjcz9uLmFjczp7d2l0aElzb2xhdGlvblNjb3BlOkN0LHdpdGhTY29wZTpOdCx3aXRoU2V0U2NvcGU6a3Qsd2l0aFNldElzb2xhdGlvblNjb3BlOih0LG4pPT5DdChuKSxnZXRDdXJyZW50U2NvcGU6KCk9Pnh0KCkuZ2V0U2NvcGUoKSxnZXRJc29sYXRpb25TY29wZTooKT0+eHQoKS5nZXRJc29sYXRpb25TY29wZSgpfX1mdW5jdGlvbiBUdCgpe3JldHVybiBEdChtdCgpKS5nZXRDdXJyZW50U2NvcGUoKS5nZXRDbGllbnQoKX1jb25zdCBPdD0iX3NlbnRyeU1ldHJpY3MiO2Z1bmN0aW9uIGp0KHQpe2NvbnN0IG49dFtPdF07aWYoIW4pcmV0dXJuO2NvbnN0IGU9e307Zm9yKGNvbnN0WyxbdCxyXV1vZiBuKXsoZVt0XXx8KGVbdF09W10pKS5wdXNoKFIocikpfXJldHVybiBlfWNvbnN0IFJ0PSJzZW50cnkuc291cmNlIixBdD0ic2VudHJ5LnNhbXBsZV9yYXRlIixJdD0ic2VudHJ5Lm9wIixQdD0ic2VudHJ5Lm9yaWdpbiIsVXQ9MCxNdD0xLEx0PTE7ZnVuY3Rpb24gQnQodCl7Y29uc3R7c3BhbklkOm4sdHJhY2VJZDplfT10LnNwYW5Db250ZXh0KCkse3BhcmVudF9zcGFuX2lkOnJ9PXp0KHQpO3JldHVybiBSKHtwYXJlbnRfc3Bhbl9pZDpyLHNwYW5faWQ6bix0cmFjZV9pZDplfSl9ZnVuY3Rpb24gR3QodCl7cmV0dXJuIm51bWJlciI9PXR5cGVvZiB0P0p0KHQpOkFycmF5LmlzQXJyYXkodCk/dFswXSt0WzFdLzFlOTp0IGluc3RhbmNlb2YgRGF0ZT9KdCh0LmdldFRpbWUoKSk6SigpfWZ1bmN0aW9uIEp0KHQpe3JldHVybiB0Pjk5OTk5OTk5OTk/dC8xZTM6dH1mdW5jdGlvbiB6dCh0KXtpZihmdW5jdGlvbih0KXtyZXR1cm4iZnVuY3Rpb24iPT10eXBlb2YgdC5nZXRTcGFuSlNPTn0odCkpcmV0dXJuIHQuZ2V0U3BhbkpTT04oKTt0cnl7Y29uc3R7c3BhbklkOm4sdHJhY2VJZDplfT10LnNwYW5Db250ZXh0KCk7aWYoZnVuY3Rpb24odCl7Y29uc3Qgbj10O3JldHVybiEhKG4uYXR0cmlidXRlcyYmbi5zdGFydFRpbWUmJm4ubmFtZSYmbi5lbmRUaW1lJiZuLnN0YXR1cyl9KHQpKXtjb25zdHthdHRyaWJ1dGVzOnIsc3RhcnRUaW1lOm8sbmFtZTpzLGVuZFRpbWU6aSxwYXJlbnRTcGFuSWQ6YyxzdGF0dXM6dX09dDtyZXR1cm4gUih7c3Bhbl9pZDpuLHRyYWNlX2lkOmUsZGF0YTpyLGRlc2NyaXB0aW9uOnMscGFyZW50X3NwYW5faWQ6YyxzdGFydF90aW1lc3RhbXA6R3QobyksdGltZXN0YW1wOkd0KGkpfHx2b2lkIDAsc3RhdHVzOkh0KHUpLG9wOnJbSXRdLG9yaWdpbjpyW1B0XSxfbWV0cmljc19zdW1tYXJ5Omp0KHQpfSl9cmV0dXJue3NwYW5faWQ6bix0cmFjZV9pZDplfX1jYXRjaCh0KXtyZXR1cm57fX19ZnVuY3Rpb24gSHQodCl7aWYodCYmdC5jb2RlIT09VXQpcmV0dXJuIHQuY29kZT09PU10PyJvayI6dC5tZXNzYWdlfHwidW5rbm93bl9lcnJvciJ9Y29uc3QgV3Q9Il9zZW50cnlSb290U3BhbiI7ZnVuY3Rpb24gWXQodCl7cmV0dXJuIHRbV3RdfHx0fWNvbnN0IHF0PSJwcm9kdWN0aW9uIixGdD0iX2Zyb3plbkRzYyI7ZnVuY3Rpb24gS3QodCl7Y29uc3Qgbj1UdCgpO2lmKCFuKXJldHVybnt9O2NvbnN0IGU9ZnVuY3Rpb24odCxuKXtjb25zdCBlPW4uZ2V0T3B0aW9ucygpLHtwdWJsaWNLZXk6cn09bi5nZXREc24oKXx8e30sbz1SKHtlbnZpcm9ubWVudDplLmVudmlyb25tZW50fHxxdCxyZWxlYXNlOmUucmVsZWFzZSxwdWJsaWNfa2V5OnIsdHJhY2VfaWQ6dH0pO3JldHVybiBuLmVtaXQoImNyZWF0ZURzYyIsbyksb30oenQodCkudHJhY2VfaWR8fCIiLG4pLHI9WXQodCksbz1yW0Z0XTtpZihvKXJldHVybiBvO2NvbnN0IHM9ci5zcGFuQ29udGV4dCgpLnRyYWNlU3RhdGUsaT1zJiZzLmdldCgic2VudHJ5LmRzYyIpLGM9aSYmZXQoaSk7aWYoYylyZXR1cm4gYztjb25zdCB1PXp0KHIpLGE9dS5kYXRhfHx7fSxmPWFbQXRdO251bGwhPWYmJihlLnNhbXBsZV9yYXRlPWAke2Z9YCk7Y29uc3QgaD1hW1J0XSxwPXUuZGVzY3JpcHRpb247cmV0dXJuInVybCIhPT1oJiZwJiYoZS50cmFuc2FjdGlvbj1wKSxlLnNhbXBsZWQ9U3RyaW5nKGZ1bmN0aW9uKHQpe2NvbnN0e3RyYWNlRmxhZ3M6bn09dC5zcGFuQ29udGV4dCgpO3JldHVybiBuPT09THR9KHIpKSxuLmVtaXQoImNyZWF0ZURzYyIsZSxyKSxlfWZ1bmN0aW9uIFZ0KHQsbixlLHIpe2NvbnN0IG89ZnQoZSkscz10LnR5cGUmJiJyZXBsYXlfZXZlbnQiIT09dC50eXBlP3QudHlwZToiZXZlbnQiOyFmdW5jdGlvbih0LG4pe24mJih0LnNkaz10LnNka3x8e30sdC5zZGsubmFtZT10LnNkay5uYW1lfHxuLm5hbWUsdC5zZGsudmVyc2lvbj10LnNkay52ZXJzaW9ufHxuLnZlcnNpb24sdC5zZGsuaW50ZWdyYXRpb25zPVsuLi50LnNkay5pbnRlZ3JhdGlvbnN8fFtdLC4uLm4uaW50ZWdyYXRpb25zfHxbXV0sdC5zZGsucGFja2FnZXM9Wy4uLnQuc2RrLnBhY2thZ2VzfHxbXSwuLi5uLnBhY2thZ2VzfHxbXV0pfSh0LGUmJmUuc2RrKTtjb25zdCBpPWZ1bmN0aW9uKHQsbixlLHIpe2NvbnN0IG89dC5zZGtQcm9jZXNzaW5nTWV0YWRhdGEmJnQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhLmR5bmFtaWNTYW1wbGluZ0NvbnRleHQ7cmV0dXJue2V2ZW50X2lkOnQuZXZlbnRfaWQsc2VudF9hdDoobmV3IERhdGUpLnRvSVNPU3RyaW5nKCksLi4ubiYme3NkazpufSwuLi4hIWUmJnImJntkc246QyhyKX0sLi4ubyYme3RyYWNlOlIoey4uLm99KX19fSh0LG8scixuKTtkZWxldGUgdC5zZGtQcm9jZXNzaW5nTWV0YWRhdGE7cmV0dXJuIG90KGksW1t7dHlwZTpzfSx0XV0pfWNvbnN0IFp0PSJfX1NFTlRSWV9TVVBQUkVTU19UUkFDSU5HX18iO2Z1bmN0aW9uIFF0KHQpe2NvbnN0IG49RHQobXQoKSk7cmV0dXJuIG4uc3VwcHJlc3NUcmFjaW5nP24uc3VwcHJlc3NUcmFjaW5nKHQpOmZ1bmN0aW9uKC4uLnQpe2NvbnN0IG49RHQobXQoKSk7aWYoMj09PXQubGVuZ3RoKXtjb25zdFtlLHJdPXQ7cmV0dXJuIGU/bi53aXRoU2V0U2NvcGUoZSxyKTpuLndpdGhTY29wZShyKX1yZXR1cm4gbi53aXRoU2NvcGUodFswXSl9KChuPT4obi5zZXRTREtQcm9jZXNzaW5nTWV0YWRhdGEoe1tadF06ITB9KSx0KCkpKSl9ZnVuY3Rpb24gWHQodCxuKXtjb25zdHtmaW5nZXJwcmludDplLHNwYW46cixicmVhZGNydW1iczpvLHNka1Byb2Nlc3NpbmdNZXRhZGF0YTpzfT1uOyFmdW5jdGlvbih0LG4pe2NvbnN0e2V4dHJhOmUsdGFnczpyLHVzZXI6byxjb250ZXh0czpzLGxldmVsOmksdHJhbnNhY3Rpb25OYW1lOmN9PW4sdT1SKGUpO3UmJk9iamVjdC5rZXlzKHUpLmxlbmd0aCYmKHQuZXh0cmE9ey4uLnUsLi4udC5leHRyYX0pO2NvbnN0IGE9UihyKTthJiZPYmplY3Qua2V5cyhhKS5sZW5ndGgmJih0LnRhZ3M9ey4uLmEsLi4udC50YWdzfSk7Y29uc3QgZj1SKG8pO2YmJk9iamVjdC5rZXlzKGYpLmxlbmd0aCYmKHQudXNlcj17Li4uZiwuLi50LnVzZXJ9KTtjb25zdCBoPVIocyk7aCYmT2JqZWN0LmtleXMoaCkubGVuZ3RoJiYodC5jb250ZXh0cz17Li4uaCwuLi50LmNvbnRleHRzfSk7aSYmKHQubGV2ZWw9aSk7YyYmInRyYW5zYWN0aW9uIiE9PXQudHlwZSYmKHQudHJhbnNhY3Rpb249Yyl9KHQsbiksciYmZnVuY3Rpb24odCxuKXt0LmNvbnRleHRzPXt0cmFjZTpCdChuKSwuLi50LmNvbnRleHRzfSx0LnNka1Byb2Nlc3NpbmdNZXRhZGF0YT17ZHluYW1pY1NhbXBsaW5nQ29udGV4dDpLdChuKSwuLi50LnNka1Byb2Nlc3NpbmdNZXRhZGF0YX07Y29uc3QgZT1ZdChuKSxyPXp0KGUpLmRlc2NyaXB0aW9uO3ImJiF0LnRyYW5zYWN0aW9uJiYidHJhbnNhY3Rpb24iPT09dC50eXBlJiYodC50cmFuc2FjdGlvbj1yKX0odCxyKSxmdW5jdGlvbih0LG4pe3QuZmluZ2VycHJpbnQ9dC5maW5nZXJwcmludD9mdW5jdGlvbih0KXtyZXR1cm4gQXJyYXkuaXNBcnJheSh0KT90Olt0XX0odC5maW5nZXJwcmludCk6W10sbiYmKHQuZmluZ2VycHJpbnQ9dC5maW5nZXJwcmludC5jb25jYXQobikpO3QuZmluZ2VycHJpbnQmJiF0LmZpbmdlcnByaW50Lmxlbmd0aCYmZGVsZXRlIHQuZmluZ2VycHJpbnR9KHQsZSksZnVuY3Rpb24odCxuKXtjb25zdCBlPVsuLi50LmJyZWFkY3J1bWJzfHxbXSwuLi5uXTt0LmJyZWFkY3J1bWJzPWUubGVuZ3RoP2U6dm9pZCAwfSh0LG8pLGZ1bmN0aW9uKHQsbil7dC5zZGtQcm9jZXNzaW5nTWV0YWRhdGE9ey4uLnQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhLC4uLm59fSh0LHMpfWNvbnN0IHRuPSI3IjtmdW5jdGlvbiBubih0LG4pe3JldHVybiBlPXtzZW50cnlfa2V5OnQucHVibGljS2V5LHNlbnRyeV92ZXJzaW9uOnRuLC4uLm4mJntzZW50cnlfY2xpZW50OmAke24ubmFtZX0vJHtuLnZlcnNpb259YH19LE9iamVjdC5rZXlzKGUpLm1hcCgodD0+YCR7ZW5jb2RlVVJJQ29tcG9uZW50KHQpfT0ke2VuY29kZVVSSUNvbXBvbmVudChlW3RdKX1gKSkuam9pbigiJiIpO3ZhciBlfWNvbnN0IGVuPTY0O2Z1bmN0aW9uIHJuKHQsbixlPVEodC5idWZmZXJTaXplfHxlbikpe2xldCByPXt9O3JldHVybntzZW5kOmZ1bmN0aW9uKG8pe2NvbnN0IHM9W107aWYoc3QobywoKG4sZSk9Pntjb25zdCBvPWF0KGUpO2lmKGZ1bmN0aW9uKHQsbixlPURhdGUubm93KCkpe3JldHVybiBmdW5jdGlvbih0LG4pe3JldHVybiB0W25dfHx0LmFsbHx8MH0odCxuKT5lfShyLG8pKXtjb25zdCByPW9uKG4sZSk7dC5yZWNvcmREcm9wcGVkRXZlbnQoInJhdGVsaW1pdF9iYWNrb2ZmIixvLHIpfWVsc2Ugcy5wdXNoKG4pfSkpLDA9PT1zLmxlbmd0aClyZXR1cm4gVih7fSk7Y29uc3QgaT1vdChvWzBdLHMpLGM9bj0+e3N0KGksKChlLHIpPT57Y29uc3Qgbz1vbihlLHIpO3QucmVjb3JkRHJvcHBlZEV2ZW50KG4sYXQociksbyl9KSl9O3JldHVybiBlLmFkZCgoKCk9Pm4oe2JvZHk6Y3QoaSl9KS50aGVuKCh0PT4odm9pZCAwIT09dC5zdGF0dXNDb2RlJiYodC5zdGF0dXNDb2RlPDIwMHx8dC5zdGF0dXNDb2RlPj0zMDApJiZsdCYmay53YXJuKGBTZW50cnkgcmVzcG9uZGVkIHdpdGggc3RhdHVzIGNvZGUgJHt0LnN0YXR1c0NvZGV9IHRvIHNlbnQgZXZlbnQuYCkscj1wdChyLHQpLHQpKSwodD0+e3Rocm93IGMoIm5ldHdvcmtfZXJyb3IiKSx0fSkpKSkudGhlbigodD0+dCksKHQ9PntpZih0IGluc3RhbmNlb2YgRClyZXR1cm4gbHQmJmsuZXJyb3IoIlNraXBwZWQgc2VuZGluZyBldmVudCBiZWNhdXNlIGJ1ZmZlciBpcyBmdWxsLiIpLGMoInF1ZXVlX292ZXJmbG93IiksVih7fSk7dGhyb3cgdH0pKX0sZmx1c2g6dD0+ZS5kcmFpbih0KX19ZnVuY3Rpb24gb24odCxuKXtpZigiZXZlbnQiPT09bnx8InRyYW5zYWN0aW9uIj09PW4pcmV0dXJuIEFycmF5LmlzQXJyYXkodCk/dFsxXTp2b2lkIDB9Y29uc3Qgc249U3ltYm9sKCJBZ2VudEJhc2VJbnRlcm5hbFN0YXRlIik7Y2xhc3MgY24gZXh0ZW5kcyBzLkFnZW50e1tzbl07b3B0aW9ucztrZWVwQWxpdmU7Y29uc3RydWN0b3IodCl7c3VwZXIodCksdGhpc1tzbl09e319aXNTZWN1cmVFbmRwb2ludCh0KXtpZih0KXtpZigiYm9vbGVhbiI9PXR5cGVvZiB0LnNlY3VyZUVuZHBvaW50KXJldHVybiB0LnNlY3VyZUVuZHBvaW50O2lmKCJzdHJpbmciPT10eXBlb2YgdC5wcm90b2NvbClyZXR1cm4iaHR0cHM6Ij09PXQucHJvdG9jb2x9Y29uc3R7c3RhY2s6bn09bmV3IEVycm9yO3JldHVybiJzdHJpbmciPT10eXBlb2YgbiYmbi5zcGxpdCgiXG4iKS5zb21lKCh0PT4tMSE9PXQuaW5kZXhPZigiKGh0dHBzLmpzOiIpfHwtMSE9PXQuaW5kZXhPZigibm9kZTpodHRwczoiKSkpfWNyZWF0ZVNvY2tldCh0LG4sZSl7Y29uc3Qgcj17Li4ubixzZWN1cmVFbmRwb2ludDp0aGlzLmlzU2VjdXJlRW5kcG9pbnQobil9O1Byb21pc2UucmVzb2x2ZSgpLnRoZW4oKCgpPT50aGlzLmNvbm5lY3QodCxyKSkpLnRoZW4oKG89PntpZihvIGluc3RhbmNlb2Ygcy5BZ2VudClyZXR1cm4gby5hZGRSZXF1ZXN0KHQscik7dGhpc1tzbl0uY3VycmVudFNvY2tldD1vLHN1cGVyLmNyZWF0ZVNvY2tldCh0LG4sZSl9KSxlKX1jcmVhdGVDb25uZWN0aW9uKCl7Y29uc3QgdD10aGlzW3NuXS5jdXJyZW50U29ja2V0O2lmKHRoaXNbc25dLmN1cnJlbnRTb2NrZXQ9dm9pZCAwLCF0KXRocm93IG5ldyBFcnJvcigiTm8gc29ja2V0IHdhcyByZXR1cm5lZCBpbiB0aGUgYGNvbm5lY3QoKWAgZnVuY3Rpb24iKTtyZXR1cm4gdH1nZXQgZGVmYXVsdFBvcnQoKXtyZXR1cm4gdGhpc1tzbl0uZGVmYXVsdFBvcnQ/PygiaHR0cHM6Ij09PXRoaXMucHJvdG9jb2w/NDQzOjgwKX1zZXQgZGVmYXVsdFBvcnQodCl7dGhpc1tzbl0mJih0aGlzW3NuXS5kZWZhdWx0UG9ydD10KX1nZXQgcHJvdG9jb2woKXtyZXR1cm4gdGhpc1tzbl0ucHJvdG9jb2w/Pyh0aGlzLmlzU2VjdXJlRW5kcG9pbnQoKT8iaHR0cHM6IjoiaHR0cDoiKX1zZXQgcHJvdG9jb2wodCl7dGhpc1tzbl0mJih0aGlzW3NuXS5wcm90b2NvbD10KX19ZnVuY3Rpb24gdW4oLi4udCl7ay5sb2coIltodHRwcy1wcm94eS1hZ2VudDpwYXJzZS1wcm94eS1yZXNwb25zZV0iLC4uLnQpfWZ1bmN0aW9uIGFuKHQpe3JldHVybiBuZXcgUHJvbWlzZSgoKG4sZSk9PntsZXQgcj0wO2NvbnN0IG89W107ZnVuY3Rpb24gcygpe2NvbnN0IGM9dC5yZWFkKCk7Yz9mdW5jdGlvbihjKXtvLnB1c2goYykscis9Yy5sZW5ndGg7Y29uc3QgdT1CdWZmZXIuY29uY2F0KG8sciksYT11LmluZGV4T2YoIlxyXG5cclxuIik7aWYoLTE9PT1hKXJldHVybiB1bigiaGF2ZSBub3QgcmVjZWl2ZWQgZW5kIG9mIEhUVFAgaGVhZGVycyB5ZXQuLi4iKSx2b2lkIHMoKTtjb25zdCBmPXUuc2xpY2UoMCxhKS50b1N0cmluZygiYXNjaWkiKS5zcGxpdCgiXHJcbiIpLGg9Zi5zaGlmdCgpO2lmKCFoKXJldHVybiB0LmRlc3Ryb3koKSxlKG5ldyBFcnJvcigiTm8gaGVhZGVyIHJlY2VpdmVkIGZyb20gcHJveHkgQ09OTkVDVCByZXNwb25zZSIpKTtjb25zdCBwPWguc3BsaXQoIiAiKSxkPSsocFsxXXx8MCksbD1wLnNsaWNlKDIpLmpvaW4oIiAiKSxtPXt9O2Zvcihjb25zdCBuIG9mIGYpe2lmKCFuKWNvbnRpbnVlO2NvbnN0IHI9bi5pbmRleE9mKCI6Iik7aWYoLTE9PT1yKXJldHVybiB0LmRlc3Ryb3koKSxlKG5ldyBFcnJvcihgSW52YWxpZCBoZWFkZXIgZnJvbSBwcm94eSBDT05ORUNUIHJlc3BvbnNlOiAiJHtufSJgKSk7Y29uc3Qgbz1uLnNsaWNlKDAscikudG9Mb3dlckNhc2UoKSxzPW4uc2xpY2UocisxKS50cmltU3RhcnQoKSxpPW1bb107InN0cmluZyI9PXR5cGVvZiBpP21bb109W2ksc106QXJyYXkuaXNBcnJheShpKT9pLnB1c2gocyk6bVtvXT1zfXVuKCJnb3QgcHJveHkgc2VydmVyIHJlc3BvbnNlOiAlbyAlbyIsaCxtKSxpKCksbih7Y29ubmVjdDp7c3RhdHVzQ29kZTpkLHN0YXR1c1RleHQ6bCxoZWFkZXJzOm19LGJ1ZmZlcmVkOnV9KX0oYyk6dC5vbmNlKCJyZWFkYWJsZSIscyl9ZnVuY3Rpb24gaSgpe3QucmVtb3ZlTGlzdGVuZXIoImVuZCIsYyksdC5yZW1vdmVMaXN0ZW5lcigiZXJyb3IiLHUpLHQucmVtb3ZlTGlzdGVuZXIoInJlYWRhYmxlIixzKX1mdW5jdGlvbiBjKCl7aSgpLHVuKCJvbmVuZCIpLGUobmV3IEVycm9yKCJQcm94eSBjb25uZWN0aW9uIGVuZGVkIGJlZm9yZSByZWNlaXZpbmcgQ09OTkVDVCByZXNwb25zZSIpKX1mdW5jdGlvbiB1KHQpe2koKSx1bigib25lcnJvciAlbyIsdCksZSh0KX10Lm9uKCJlcnJvciIsdSksdC5vbigiZW5kIixjKSxzKCl9KSl9ZnVuY3Rpb24gZm4oLi4udCl7ay5sb2coIltodHRwcy1wcm94eS1hZ2VudF0iLC4uLnQpfWNsYXNzIGhuIGV4dGVuZHMgY257c3RhdGljIHByb3RvY29scz1bImh0dHAiLCJodHRwcyJdO3Byb3h5O3Byb3h5SGVhZGVycztjb25uZWN0T3B0cztjb25zdHJ1Y3Rvcih0LG4pe3N1cGVyKG4pLHRoaXMub3B0aW9ucz17fSx0aGlzLnByb3h5PSJzdHJpbmciPT10eXBlb2YgdD9uZXcgVVJMKHQpOnQsdGhpcy5wcm94eUhlYWRlcnM9bj8uaGVhZGVycz8/e30sZm4oIkNyZWF0aW5nIG5ldyBIdHRwc1Byb3h5QWdlbnQgaW5zdGFuY2U6ICVvIix0aGlzLnByb3h5LmhyZWYpO2NvbnN0IGU9KHRoaXMucHJveHkuaG9zdG5hbWV8fHRoaXMucHJveHkuaG9zdCkucmVwbGFjZSgvXlxbfFxdJC9nLCIiKSxyPXRoaXMucHJveHkucG9ydD9wYXJzZUludCh0aGlzLnByb3h5LnBvcnQsMTApOiJodHRwczoiPT09dGhpcy5wcm94eS5wcm90b2NvbD80NDM6ODA7dGhpcy5jb25uZWN0T3B0cz17QUxQTlByb3RvY29sczpbImh0dHAvMS4xIl0sLi4ubj9kbihuLCJoZWFkZXJzIik6bnVsbCxob3N0OmUscG9ydDpyfX1hc3luYyBjb25uZWN0KHQsbil7Y29uc3R7cHJveHk6ZX09dGhpcztpZighbi5ob3N0KXRocm93IG5ldyBUeXBlRXJyb3IoJ05vICJob3N0IiBwcm92aWRlZCcpO2xldCByO2lmKCJodHRwczoiPT09ZS5wcm90b2NvbCl7Zm4oIkNyZWF0aW5nIGB0bHMuU29ja2V0YDogJW8iLHRoaXMuY29ubmVjdE9wdHMpO2NvbnN0IHQ9dGhpcy5jb25uZWN0T3B0cy5zZXJ2ZXJuYW1lfHx0aGlzLmNvbm5lY3RPcHRzLmhvc3Q7cj1mLmNvbm5lY3Qoey4uLnRoaXMuY29ubmVjdE9wdHMsc2VydmVybmFtZTp0JiZhLmlzSVAodCk/dm9pZCAwOnR9KX1lbHNlIGZuKCJDcmVhdGluZyBgbmV0LlNvY2tldGA6ICVvIix0aGlzLmNvbm5lY3RPcHRzKSxyPWEuY29ubmVjdCh0aGlzLmNvbm5lY3RPcHRzKTtjb25zdCBvPSJmdW5jdGlvbiI9PXR5cGVvZiB0aGlzLnByb3h5SGVhZGVycz90aGlzLnByb3h5SGVhZGVycygpOnsuLi50aGlzLnByb3h5SGVhZGVyc30scz1hLmlzSVB2NihuLmhvc3QpP2BbJHtuLmhvc3R9XWA6bi5ob3N0O2xldCBpPWBDT05ORUNUICR7c306JHtuLnBvcnR9IEhUVFAvMS4xXHJcbmA7aWYoZS51c2VybmFtZXx8ZS5wYXNzd29yZCl7Y29uc3QgdD1gJHtkZWNvZGVVUklDb21wb25lbnQoZS51c2VybmFtZSl9OiR7ZGVjb2RlVVJJQ29tcG9uZW50KGUucGFzc3dvcmQpfWA7b1siUHJveHktQXV0aG9yaXphdGlvbiJdPWBCYXNpYyAke0J1ZmZlci5mcm9tKHQpLnRvU3RyaW5nKCJiYXNlNjQiKX1gfW8uSG9zdD1gJHtzfToke24ucG9ydH1gLG9bIlByb3h5LUNvbm5lY3Rpb24iXXx8KG9bIlByb3h5LUNvbm5lY3Rpb24iXT10aGlzLmtlZXBBbGl2ZT8iS2VlcC1BbGl2ZSI6ImNsb3NlIik7Zm9yKGNvbnN0IHQgb2YgT2JqZWN0LmtleXMobykpaSs9YCR7dH06ICR7b1t0XX1cclxuYDtjb25zdCBjPWFuKHIpO3Iud3JpdGUoYCR7aX1cclxuYCk7Y29uc3R7Y29ubmVjdDp1LGJ1ZmZlcmVkOmh9PWF3YWl0IGM7aWYodC5lbWl0KCJwcm94eUNvbm5lY3QiLHUpLHRoaXMuZW1pdCgicHJveHlDb25uZWN0Iix1LHQpLDIwMD09PXUuc3RhdHVzQ29kZSl7aWYodC5vbmNlKCJzb2NrZXQiLHBuKSxuLnNlY3VyZUVuZHBvaW50KXtmbigiVXBncmFkaW5nIHNvY2tldCBjb25uZWN0aW9uIHRvIFRMUyIpO2NvbnN0IHQ9bi5zZXJ2ZXJuYW1lfHxuLmhvc3Q7cmV0dXJuIGYuY29ubmVjdCh7Li4uZG4obiwiaG9zdCIsInBhdGgiLCJwb3J0Iiksc29ja2V0OnIsc2VydmVybmFtZTphLmlzSVAodCk/dm9pZCAwOnR9KX1yZXR1cm4gcn1yLmRlc3Ryb3koKTtjb25zdCBwPW5ldyBhLlNvY2tldCh7d3JpdGFibGU6ITF9KTtyZXR1cm4gcC5yZWFkYWJsZT0hMCx0Lm9uY2UoInNvY2tldCIsKHQ9PntmbigiUmVwbGF5aW5nIHByb3h5IGJ1ZmZlciBmb3IgZmFpbGVkIHJlcXVlc3QiKSx0LnB1c2goaCksdC5wdXNoKG51bGwpfSkpLHB9fWZ1bmN0aW9uIHBuKHQpe3QucmVzdW1lKCl9ZnVuY3Rpb24gZG4odCwuLi5uKXtjb25zdCBlPXt9O2xldCByO2ZvcihyIGluIHQpbi5pbmNsdWRlcyhyKXx8KGVbcl09dFtyXSk7cmV0dXJuIGV9Y29uc3QgbG49MzI3Njg7ZnVuY3Rpb24gbW4odCl7cmV0dXJuIHQucmVwbGFjZSgvXltBLVpdOi8sIiIpLnJlcGxhY2UoL1xcL2csIi8iKX1jb25zdCB5bj1lO2xldCBnbixibj0hMTtmdW5jdGlvbiB2bih0KXt5bi5kZWJ1ZyYmY29uc29sZS5sb2coYFtBTlIgV29ya2VyXSAke3R9YCl9dmFyIF9uLHduLFNuO2NvbnN0ICRuPWZ1bmN0aW9uKHQpe2xldCBuO3RyeXtuPW5ldyBVUkwodC51cmwpfWNhdGNoKG4pe3JldHVybiBOKCgoKT0+e2NvbnNvbGUud2FybigiW0BzZW50cnkvbm9kZV06IEludmFsaWQgZHNuIG9yIHR1bm5lbCBvcHRpb24sIHdpbGwgbm90IHNlbmQgYW55IGV2ZW50cy4gVGhlIHR1bm5lbCBvcHRpb24gbXVzdCBiZSBhIGZ1bGwgVVJMIHdoZW4gdXNlZC4iKX0pKSxybih0LCgoKT0+UHJvbWlzZS5yZXNvbHZlKHt9KSkpfWNvbnN0IGU9Imh0dHBzOiI9PT1uLnByb3RvY29sLHI9ZnVuY3Rpb24odCxuKXtjb25zdHtub19wcm94eTplfT1wcm9jZXNzLmVudjtyZXR1cm4gZSYmZS5zcGxpdCgiLCIpLnNvbWUoKG49PnQuaG9zdC5lbmRzV2l0aChuKXx8dC5ob3N0bmFtZS5lbmRzV2l0aChuKSkpP3ZvaWQgMDpufShuLHQucHJveHl8fChlP3Byb2Nlc3MuZW52Lmh0dHBzX3Byb3h5OnZvaWQgMCl8fHByb2Nlc3MuZW52Lmh0dHBfcHJveHkpLG89ZT9pOnMsYT12b2lkIDAhPT10LmtlZXBBbGl2ZSYmdC5rZWVwQWxpdmUsZj1yP25ldyBobihyKTpuZXcgby5BZ2VudCh7a2VlcEFsaXZlOmEsbWF4U29ja2V0czozMCx0aW1lb3V0OjJlM30pO3JldHVybiBRdCgoKCk9Pntjb25zdCBuPWZ1bmN0aW9uKHQsbixlKXtjb25zdHtob3N0bmFtZTpyLHBhdGhuYW1lOm8scG9ydDpzLHByb3RvY29sOmksc2VhcmNoOmF9PW5ldyBVUkwodC51cmwpO3JldHVybiBmdW5jdGlvbihmKXtyZXR1cm4gbmV3IFByb21pc2UoKChoLHApPT57bGV0IGQ9ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyBjKHtyZWFkKCl7dGhpcy5wdXNoKHQpLHRoaXMucHVzaChudWxsKX19KX0oZi5ib2R5KTtjb25zdCBsPXsuLi50LmhlYWRlcnN9O2YuYm9keS5sZW5ndGg+bG4mJihsWyJjb250ZW50LWVuY29kaW5nIl09Imd6aXAiLGQ9ZC5waXBlKHUoKSkpO2NvbnN0IG09bi5yZXF1ZXN0KHttZXRob2Q6IlBPU1QiLGFnZW50OmUsaGVhZGVyczpsLGhvc3RuYW1lOnIscGF0aDpgJHtvfSR7YX1gLHBvcnQ6cyxwcm90b2NvbDppLGNhOnQuY2FDZXJ0c30sKHQ9Pnt0Lm9uKCJkYXRhIiwoKCk9Pnt9KSksdC5vbigiZW5kIiwoKCk9Pnt9KSksdC5zZXRFbmNvZGluZygidXRmOCIpO2NvbnN0IG49dC5oZWFkZXJzWyJyZXRyeS1hZnRlciJdPz9udWxsLGU9dC5oZWFkZXJzWyJ4LXNlbnRyeS1yYXRlLWxpbWl0cyJdPz9udWxsO2goe3N0YXR1c0NvZGU6dC5zdGF0dXNDb2RlLGhlYWRlcnM6eyJyZXRyeS1hZnRlciI6biwieC1zZW50cnktcmF0ZS1saW1pdHMiOkFycmF5LmlzQXJyYXkoZSk/ZVswXXx8bnVsbDplfX0pfSkpO20ub24oImVycm9yIixwKSxkLnBpcGUobSl9KSl9fSh0LHQuaHR0cE1vZHVsZT8/byxmKTtyZXR1cm4gcm4odCxuKX0pKX0oe3VybDooX249eW4uZHNuLHduPXluLnR1bm5lbCxTbj15bi5zZGtNZXRhZGF0YS5zZGssd258fGAke2Z1bmN0aW9uKHQpe3JldHVybmAke2Z1bmN0aW9uKHQpe2NvbnN0IG49dC5wcm90b2NvbD9gJHt0LnByb3RvY29sfTpgOiIiLGU9dC5wb3J0P2A6JHt0LnBvcnR9YDoiIjtyZXR1cm5gJHtufS8vJHt0Lmhvc3R9JHtlfSR7dC5wYXRoP2AvJHt0LnBhdGh9YDoiIn0vYXBpL2B9KHQpfSR7dC5wcm9qZWN0SWR9L2VudmVsb3BlL2B9KF9uKX0/JHtubihfbixTbil9YCkscmVjb3JkRHJvcHBlZEV2ZW50OigpPT57fX0pO2FzeW5jIGZ1bmN0aW9uIEVuKCl7aWYoZ24pe3ZuKCJTZW5kaW5nIGFibm9ybWFsIHNlc3Npb24iKSxidChnbix7c3RhdHVzOiJhYm5vcm1hbCIsYWJub3JtYWxfbWVjaGFuaXNtOiJhbnJfZm9yZWdyb3VuZCJ9KTtjb25zdCB0PWZ1bmN0aW9uKHQsbixlLHIpe2NvbnN0IG89ZnQoZSk7cmV0dXJuIG90KHtzZW50X2F0OihuZXcgRGF0ZSkudG9JU09TdHJpbmcoKSwuLi5vJiZ7c2RrOm99LC4uLiEhciYmbiYme2RzbjpDKG4pfX0sWyJhZ2dyZWdhdGVzImluIHQ/W3t0eXBlOiJzZXNzaW9ucyJ9LHRdOlt7dHlwZToic2Vzc2lvbiJ9LHQudG9KU09OKCldXSl9KGduLHluLmRzbix5bi5zZGtNZXRhZGF0YSx5bi50dW5uZWwpO3ZuKEpTT04uc3RyaW5naWZ5KHQpKSxhd2FpdCAkbi5zZW5kKHQpO3RyeXtuPy5wb3N0TWVzc2FnZSgic2Vzc2lvbi1lbmRlZCIpfWNhdGNoKHQpe319fWZ1bmN0aW9uIHhuKHQpe2lmKCF0KXJldHVybjtjb25zdCBuPWZ1bmN0aW9uKHQpe2lmKCF0Lmxlbmd0aClyZXR1cm5bXTtjb25zdCBuPUFycmF5LmZyb20odCk7cmV0dXJuL3NlbnRyeVdyYXBwZWQvLnRlc3QoTShuKS5mdW5jdGlvbnx8IiIpJiZuLnBvcCgpLG4ucmV2ZXJzZSgpLFUudGVzdChNKG4pLmZ1bmN0aW9ufHwiIikmJihuLnBvcCgpLFUudGVzdChNKG4pLmZ1bmN0aW9ufHwiIikmJm4ucG9wKCkpLG4uc2xpY2UoMCxJKS5tYXAoKHQ9Pih7Li4udCxmaWxlbmFtZTp0LmZpbGVuYW1lfHxNKG4pLmZpbGVuYW1lLGZ1bmN0aW9uOnQuZnVuY3Rpb258fFB9KSkpfSh0KTtpZih5bi5hcHBSb290UGF0aClmb3IoY29uc3QgdCBvZiBuKXQuZmlsZW5hbWUmJih0LmZpbGVuYW1lPVkodC5maWxlbmFtZSx5bi5hcHBSb290UGF0aCkpO3JldHVybiBufWFzeW5jIGZ1bmN0aW9uIE5uKHQsbil7aWYoYm4pcmV0dXJuO2JuPSEwLGF3YWl0IEVuKCksdm4oIlNlbmRpbmcgZXZlbnQiKTtjb25zdCBlPXtldmVudF9pZDp6KCksY29udGV4dHM6eW4uY29udGV4dHMscmVsZWFzZTp5bi5yZWxlYXNlLGVudmlyb25tZW50OnluLmVudmlyb25tZW50LGRpc3Q6eW4uZGlzdCxwbGF0Zm9ybToibm9kZSIsbGV2ZWw6ImVycm9yIixleGNlcHRpb246e3ZhbHVlczpbe3R5cGU6IkFwcGxpY2F0aW9uTm90UmVzcG9uZGluZyIsdmFsdWU6YEFwcGxpY2F0aW9uIE5vdCBSZXNwb25kaW5nIGZvciBhdCBsZWFzdCAke3luLmFuclRocmVzaG9sZH0gbXNgLHN0YWNrdHJhY2U6e2ZyYW1lczp4bih0KX0sbWVjaGFuaXNtOnt0eXBlOiJBTlIifX1dfSx0YWdzOnluLnN0YXRpY1RhZ3N9O24mJmZ1bmN0aW9uKHQsbil7aWYoWHQodCxuKSwhdC5jb250ZXh0cz8udHJhY2Upe2NvbnN0e3RyYWNlSWQ6ZSxzcGFuSWQ6cixwYXJlbnRTcGFuSWQ6b309bi5wcm9wYWdhdGlvbkNvbnRleHQ7dC5jb250ZXh0cz17dHJhY2U6e3RyYWNlX2lkOmUsc3Bhbl9pZDpyLHBhcmVudF9zcGFuX2lkOm99LC4uLnQuY29udGV4dHN9fX0oZSxuKTtjb25zdCByPVZ0KGUseW4uZHNuLHluLnNka01ldGFkYXRhLHluLnR1bm5lbCk7dm4oSlNPTi5zdHJpbmdpZnkocikpLGF3YWl0ICRuLnNlbmQociksYXdhaXQgJG4uZmx1c2goMmUzKSxzZXRUaW1lb3V0KCgoKT0+e3Byb2Nlc3MuZXhpdCgwKX0pLDVlMyl9bGV0IGtuO2lmKHZuKCJTdGFydGVkIikseW4uY2FwdHVyZVN0YWNrVHJhY2Upe3ZuKCJDb25uZWN0aW5nIHRvIGRlYnVnZ2VyIik7Y29uc3Qgbj1uZXcgdDtuLmNvbm5lY3RUb01haW5UaHJlYWQoKSx2bigiQ29ubmVjdGVkIHRvIGRlYnVnZ2VyIik7Y29uc3QgZT1uZXcgTWFwO24ub24oIkRlYnVnZ2VyLnNjcmlwdFBhcnNlZCIsKHQ9PntlLnNldCh0LnBhcmFtcy5zY3JpcHRJZCx0LnBhcmFtcy51cmwpfSkpLG4ub24oIkRlYnVnZ2VyLnBhdXNlZCIsKHQ9PntpZigib3RoZXIiPT09dC5wYXJhbXMucmVhc29uKXRyeXt2bigiRGVidWdnZXIgcGF1c2VkIik7Y29uc3Qgcz1bLi4udC5wYXJhbXMuY2FsbEZyYW1lc10saT15bi5hcHBSb290UGF0aD9mdW5jdGlvbih0PShwcm9jZXNzLmFyZ3ZbMV0/Rihwcm9jZXNzLmFyZ3ZbMV0pOnByb2Nlc3MuY3dkKCkpLG49IlxcIj09PW8pe2NvbnN0IGU9bj9tbih0KTp0O3JldHVybiB0PT57aWYoIXQpcmV0dXJuO2NvbnN0IG89bj9tbih0KTp0O2xldHtkaXI6cyxiYXNlOmksZXh0OmN9PXIucGFyc2Uobyk7Ii5qcyIhPT1jJiYiLm1qcyIhPT1jJiYiLmNqcyIhPT1jfHwoaT1pLnNsaWNlKDAsLTEqYy5sZW5ndGgpKSxzfHwocz0iLiIpO2NvbnN0IHU9cy5sYXN0SW5kZXhPZigiL25vZGVfbW9kdWxlcyIpO2lmKHU+LTEpcmV0dXJuYCR7cy5zbGljZSh1KzE0KS5yZXBsYWNlKC9cLy9nLCIuIil9OiR7aX1gO2lmKHMuc3RhcnRzV2l0aChlKSl7bGV0IHQ9cy5zbGljZShlLmxlbmd0aCsxKS5yZXBsYWNlKC9cLy9nLCIuIik7cmV0dXJuIHQmJih0Kz0iOiIpLHQrPWksdH1yZXR1cm4gaX19KHluLmFwcFJvb3RQYXRoKTooKT0+e30sYz1zLm1hcCgodD0+ZnVuY3Rpb24odCxuLGUpe2NvbnN0IHI9bj9uLnJlcGxhY2UoL15maWxlOlwvXC8vLCIiKTp2b2lkIDAsbz10LmxvY2F0aW9uLmNvbHVtbk51bWJlcj90LmxvY2F0aW9uLmNvbHVtbk51bWJlcisxOnZvaWQgMCxzPXQubG9jYXRpb24ubGluZU51bWJlcj90LmxvY2F0aW9uLmxpbmVOdW1iZXIrMTp2b2lkIDA7cmV0dXJuIFIoe2ZpbGVuYW1lOnIsbW9kdWxlOmUociksZnVuY3Rpb246dC5mdW5jdGlvbk5hbWV8fFAsY29sbm86byxsaW5lbm86cyxpbl9hcHA6cj9YKHIpOnZvaWQgMH0pfSh0LGUuZ2V0KHQubG9jYXRpb24uc2NyaXB0SWQpLGkpKSksdT1zZXRUaW1lb3V0KCgoKT0+e05uKGMpLnRoZW4obnVsbCwoKCk9Pnt2bigiU2VuZGluZyBBTlIgZXZlbnQgZmFpbGVkLiIpfSkpfSksNWUzKTtuLnBvc3QoIlJ1bnRpbWUuZXZhbHVhdGUiLHtleHByZXNzaW9uOiJnbG9iYWwuX19TRU5UUllfR0VUX1NDT1BFU19fKCk7IixzaWxlbnQ6ITAscmV0dXJuQnlWYWx1ZTohMH0sKCh0LGUpPT57dCYmdm4oYEVycm9yIGV4ZWN1dGluZyBzY3JpcHQ6ICcke3QubWVzc2FnZX0nYCksY2xlYXJUaW1lb3V0KHUpO2NvbnN0IHI9ZSYmZS5yZXN1bHQ/ZS5yZXN1bHQudmFsdWU6dm9pZCAwO24ucG9zdCgiRGVidWdnZXIucmVzdW1lIiksbi5wb3N0KCJEZWJ1Z2dlci5kaXNhYmxlIiksTm4oYyxyKS50aGVuKG51bGwsKCgpPT57dm4oIlNlbmRpbmcgQU5SIGV2ZW50IGZhaWxlZC4iKX0pKX0pKX1jYXRjaCh0KXt0aHJvdyBuLnBvc3QoIkRlYnVnZ2VyLnJlc3VtZSIpLG4ucG9zdCgiRGVidWdnZXIuZGlzYWJsZSIpLHR9fSkpLGtuPSgpPT57dHJ5e24ucG9zdCgiRGVidWdnZXIuZW5hYmxlIiwoKCk9PntuLnBvc3QoIkRlYnVnZ2VyLnBhdXNlIil9KSl9Y2F0Y2godCl7fX19Y29uc3R7cG9sbDpDbn09ZnVuY3Rpb24odCxuLGUscil7Y29uc3Qgbz10KCk7bGV0IHM9ITEsaT0hMDtyZXR1cm4gc2V0SW50ZXJ2YWwoKCgpPT57Y29uc3QgdD1vLmdldFRpbWVNcygpOyExPT09cyYmdD5uK2UmJihzPSEwLGkmJnIoKSksdDxuK2UmJihzPSExKX0pLDIwKSx7cG9sbDooKT0+e28ucmVzZXQoKX0sZW5hYmxlZDp0PT57aT10fX19KChmdW5jdGlvbigpe2xldCB0PXByb2Nlc3MuaHJ0aW1lKCk7cmV0dXJue2dldFRpbWVNczooKT0+e2NvbnN0W24sZV09cHJvY2Vzcy5ocnRpbWUodCk7cmV0dXJuIE1hdGguZmxvb3IoMWUzKm4rZS8xZTYpfSxyZXNldDooKT0+e3Q9cHJvY2Vzcy5ocnRpbWUoKX19fSkseW4ucG9sbEludGVydmFsLHluLmFuclRocmVzaG9sZCwoZnVuY3Rpb24oKXt2bigiV2F0Y2hkb2cgdGltZW91dCIpLGtuPyh2bigiUGF1c2luZyBkZWJ1Z2dlciB0byBjYXB0dXJlIHN0YWNrIHRyYWNlIiksa24oKSk6KHZuKCJDYXB0dXJpbmcgZXZlbnQgd2l0aG91dCBhIHN0YWNrIHRyYWNlIiksTm4oKS50aGVuKG51bGwsKCgpPT57dm4oIlNlbmRpbmcgQU5SIGV2ZW50IGZhaWxlZCBvbiB3YXRjaGRvZyB0aW1lb3V0LiIpfSkpKX0pKTtuPy5vbigibWVzc2FnZSIsKHQ9Pnt0LnNlc3Npb24mJihnbj1ndCh0LnNlc3Npb24pKSxDbigpfSkpOw==';
|
|
15
15
|
|
|
16
16
|
const DEFAULT_INTERVAL = 50;
|
|
17
17
|
const DEFAULT_HANG_THRESHOLD = 5000;
|
|
@@ -10,7 +10,7 @@ const utils = require('@sentry/utils');
|
|
|
10
10
|
const common = require('./common.js');
|
|
11
11
|
|
|
12
12
|
// This string is a placeholder that gets overwritten with the worker code.
|
|
13
|
-
const base64WorkerScript = '
|
|
13
|
+
const base64WorkerScript = 'LyohIEBzZW50cnkvbm9kZSA4LjEyLjAgKGEzOGFjODgpIHwgaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdCAqLwppbXBvcnR7U2Vzc2lvbiBhcyBlfWZyb20ibm9kZTppbnNwZWN0b3IvcHJvbWlzZXMiO2ltcG9ydHt3b3JrZXJEYXRhIGFzIG4scGFyZW50UG9ydCBhcyB0fWZyb20ibm9kZTp3b3JrZXJfdGhyZWFkcyI7aW1wb3J0e3Bvc2l4IGFzIG8sc2VwIGFzIHJ9ZnJvbSJub2RlOnBhdGgiO2NvbnN0IGk9NTAscz0iPyIsYz0vXChlcnJvcjogKC4qKVwpLyxhPS9jYXB0dXJlTWVzc2FnZXxjYXB0dXJlRXhjZXB0aW9uLztmdW5jdGlvbiB1KGUpe3JldHVybiBlW2UubGVuZ3RoLTFdfHx7fX1jb25zdCBmPS9eKFxTKzpcXHxcLz8pKFtcc1xTXSo/KSgoPzpcLnsxLDJ9fFteL1xcXSs/fCkoXC5bXi4vXFxdKnwpKSg/OlsvXFxdKikkLztmdW5jdGlvbiBsKGUpe2NvbnN0IG49ZnVuY3Rpb24oZSl7Y29uc3Qgbj1lLmxlbmd0aD4xMDI0P2A8dHJ1bmNhdGVkPiR7ZS5zbGljZSgtMTAyNCl9YDplLHQ9Zi5leGVjKG4pO3JldHVybiB0P3Quc2xpY2UoMSk6W119KGUpLHQ9blswXXx8IiI7bGV0IG89blsxXTtyZXR1cm4gdHx8bz8obyYmKG89by5zbGljZSgwLG8ubGVuZ3RoLTEpKSx0K28pOiIuIn1mdW5jdGlvbiBkKGUsbj0hMSl7cmV0dXJuIShufHxlJiYhZS5zdGFydHNXaXRoKCIvIikmJiFlLm1hdGNoKC9eW0EtWl06LykmJiFlLnN0YXJ0c1dpdGgoIi4iKSYmIWUubWF0Y2goL15bYS16QS1aXShbYS16QS1aMC05LlwtK10pKjpcL1wvLykpJiZ2b2lkIDAhPT1lJiYhZS5pbmNsdWRlcygibm9kZV9tb2R1bGVzLyIpfWZ1bmN0aW9uIHAoZSl7Y29uc3Qgbj0vXlxzKlstXXs0LH0kLyx0PS9hdCAoPzphc3luYyApPyg/OiguKz8pXHMrXCgpPyg/OiguKyk6KFxkKyk6KFxkKyk/fChbXildKykpXCk/LztyZXR1cm4gbz0+e2NvbnN0IHI9by5tYXRjaCh0KTtpZihyKXtsZXQgbix0LG8saSxjO2lmKHJbMV0pe289clsxXTtsZXQgZT1vLmxhc3RJbmRleE9mKCIuIik7aWYoIi4iPT09b1tlLTFdJiZlLS0sZT4wKXtuPW8uc2xpY2UoMCxlKSx0PW8uc2xpY2UoZSsxKTtjb25zdCByPW4uaW5kZXhPZigiLk1vZHVsZSIpO3I+MCYmKG89by5zbGljZShyKzEpLG49bi5zbGljZSgwLHIpKX1pPXZvaWQgMH10JiYoaT1uLGM9dCksIjxhbm9ueW1vdXM+Ij09PXQmJihjPXZvaWQgMCxvPXZvaWQgMCksdm9pZCAwPT09byYmKGM9Y3x8cyxvPWk/YCR7aX0uJHtjfWA6Yyk7bGV0IGE9clsyXSYmclsyXS5zdGFydHNXaXRoKCJmaWxlOi8vIik/clsyXS5zbGljZSg3KTpyWzJdO2NvbnN0IHU9Im5hdGl2ZSI9PT1yWzVdO3JldHVybiBhJiZhLm1hdGNoKC9cL1tBLVpdOi8pJiYoYT1hLnNsaWNlKDEpKSxhfHwhcls1XXx8dXx8KGE9cls1XSkse2ZpbGVuYW1lOmEsbW9kdWxlOmU/ZShhKTp2b2lkIDAsZnVuY3Rpb246byxsaW5lbm86ZyhyWzNdKSxjb2xubzpnKHJbNF0pLGluX2FwcDpkKGF8fCIiLHUpfX1pZihvLm1hdGNoKG4pKXJldHVybntmaWxlbmFtZTpvfX19ZnVuY3Rpb24gZyhlKXtyZXR1cm4gcGFyc2VJbnQoZXx8IiIsMTApfHx2b2lkIDB9ZnVuY3Rpb24gbShlKXtyZXR1cm4gZS5yZXBsYWNlKC9eW0EtWl06LywiIikucmVwbGFjZSgvXFwvZywiLyIpfWNvbnN0IGI9biwkPWZ1bmN0aW9uKC4uLmUpe2NvbnN0IG49ZS5zb3J0KCgoZSxuKT0+ZVswXS1uWzBdKSkubWFwKChlPT5lWzFdKSk7cmV0dXJuKGUsdD0wLG89MCk9Pntjb25zdCByPVtdLGY9ZS5zcGxpdCgiXG4iKTtmb3IobGV0IGU9dDtlPGYubGVuZ3RoO2UrKyl7Y29uc3QgdD1mW2VdO2lmKHQubGVuZ3RoPjEwMjQpY29udGludWU7Y29uc3Qgcz1jLnRlc3QodCk/dC5yZXBsYWNlKGMsIiQxIik6dDtpZighcy5tYXRjaCgvXFMqRXJyb3I6IC8pKXtmb3IoY29uc3QgZSBvZiBuKXtjb25zdCBuPWUocyk7aWYobil7ci5wdXNoKG4pO2JyZWFrfX1pZihyLmxlbmd0aD49aStvKWJyZWFrfX1yZXR1cm4gZnVuY3Rpb24oZSl7aWYoIWUubGVuZ3RoKXJldHVybltdO2NvbnN0IG49QXJyYXkuZnJvbShlKTsvc2VudHJ5V3JhcHBlZC8udGVzdCh1KG4pLmZ1bmN0aW9ufHwiIikmJm4ucG9wKCk7bi5yZXZlcnNlKCksYS50ZXN0KHUobikuZnVuY3Rpb258fCIiKSYmKG4ucG9wKCksYS50ZXN0KHUobikuZnVuY3Rpb258fCIiKSYmbi5wb3AoKSk7cmV0dXJuIG4uc2xpY2UoMCxpKS5tYXAoKGU9Pih7Li4uZSxmaWxlbmFtZTplLmZpbGVuYW1lfHx1KG4pLmZpbGVuYW1lLGZ1bmN0aW9uOmUuZnVuY3Rpb258fHN9KSkpfShyLnNsaWNlKG8pKX19KFs5MCxwKGZ1bmN0aW9uKGU9KHByb2Nlc3MuYXJndlsxXT9sKHByb2Nlc3MuYXJndlsxXSk6cHJvY2Vzcy5jd2QoKSksbj0iXFwiPT09cil7Y29uc3QgdD1uP20oZSk6ZTtyZXR1cm4gZT0+e2lmKCFlKXJldHVybjtjb25zdCByPW4/bShlKTplO2xldHtkaXI6aSxiYXNlOnMsZXh0OmN9PW8ucGFyc2Uocik7Ii5qcyIhPT1jJiYiLm1qcyIhPT1jJiYiLmNqcyIhPT1jfHwocz1zLnNsaWNlKDAsLTEqYy5sZW5ndGgpKSxpfHwoaT0iLiIpO2NvbnN0IGE9aS5sYXN0SW5kZXhPZigiL25vZGVfbW9kdWxlcyIpO2lmKGE+LTEpcmV0dXJuYCR7aS5zbGljZShhKzE0KS5yZXBsYWNlKC9cLy9nLCIuIil9OiR7c31gO2lmKGkuc3RhcnRzV2l0aCh0KSl7bGV0IGU9aS5zbGljZSh0Lmxlbmd0aCsxKS5yZXBsYWNlKC9cLy9nLCIuIik7cmV0dXJuIGUmJihlKz0iOiIpLGUrPXMsZX1yZXR1cm4gc319KGIuYmFzZVBhdGgpKV0pO2Z1bmN0aW9uIHYoLi4uZSl7Yi5kZWJ1ZyYmY29uc29sZS5sb2coIltMb2NhbFZhcmlhYmxlcyBXb3JrZXJdIiwuLi5lKX1hc3luYyBmdW5jdGlvbiB3KGUsbix0LG8pe2NvbnN0IHI9YXdhaXQgZS5wb3N0KCJSdW50aW1lLmdldFByb3BlcnRpZXMiLHtvYmplY3RJZDpuLG93blByb3BlcnRpZXM6ITB9KTtvW3RdPXIucmVzdWx0LmZpbHRlcigoZT0+Imxlbmd0aCIhPT1lLm5hbWUmJiFpc05hTihwYXJzZUludChlLm5hbWUsMTApKSkpLnNvcnQoKChlLG4pPT5wYXJzZUludChlLm5hbWUsMTApLXBhcnNlSW50KG4ubmFtZSwxMCkpKS5tYXAoKGU9PmUudmFsdWU/LnZhbHVlKSl9YXN5bmMgZnVuY3Rpb24geShlLG4sdCxvKXtjb25zdCByPWF3YWl0IGUucG9zdCgiUnVudGltZS5nZXRQcm9wZXJ0aWVzIix7b2JqZWN0SWQ6bixvd25Qcm9wZXJ0aWVzOiEwfSk7b1t0XT1yLnJlc3VsdC5tYXAoKGU9PltlLm5hbWUsZS52YWx1ZT8udmFsdWVdKSkucmVkdWNlKCgoZSxbbix0XSk9PihlW25dPXQsZSkpLHt9KX1mdW5jdGlvbiBoKGUsbil7ZS52YWx1ZSYmKCJ2YWx1ZSJpbiBlLnZhbHVlP3ZvaWQgMD09PWUudmFsdWUudmFsdWV8fG51bGw9PT1lLnZhbHVlLnZhbHVlP25bZS5uYW1lXT1gPCR7ZS52YWx1ZS52YWx1ZX0+YDpuW2UubmFtZV09ZS52YWx1ZS52YWx1ZToiZGVzY3JpcHRpb24iaW4gZS52YWx1ZSYmImZ1bmN0aW9uIiE9PWUudmFsdWUudHlwZT9uW2UubmFtZV09YDwke2UudmFsdWUuZGVzY3JpcHRpb259PmA6InVuZGVmaW5lZCI9PT1lLnZhbHVlLnR5cGUmJihuW2UubmFtZV09Ijx1bmRlZmluZWQ+IikpfWFzeW5jIGZ1bmN0aW9uIFAoZSxuKXtjb25zdCB0PWF3YWl0IGUucG9zdCgiUnVudGltZS5nZXRQcm9wZXJ0aWVzIix7b2JqZWN0SWQ6bixvd25Qcm9wZXJ0aWVzOiEwfSksbz17fTtmb3IoY29uc3QgbiBvZiB0LnJlc3VsdClpZihuPy52YWx1ZT8ub2JqZWN0SWQmJiJBcnJheSI9PT1uPy52YWx1ZS5jbGFzc05hbWUpe2NvbnN0IHQ9bi52YWx1ZS5vYmplY3RJZDthd2FpdCB3KGUsdCxuLm5hbWUsbyl9ZWxzZSBpZihuPy52YWx1ZT8ub2JqZWN0SWQmJiJPYmplY3QiPT09bj8udmFsdWU/LmNsYXNzTmFtZSl7Y29uc3QgdD1uLnZhbHVlLm9iamVjdElkO2F3YWl0IHkoZSx0LG4ubmFtZSxvKX1lbHNlIG4/LnZhbHVlJiZoKG4sbyk7cmV0dXJuIG99bGV0IHg7KGFzeW5jIGZ1bmN0aW9uKCl7Y29uc3Qgbj1uZXcgZTtuLmNvbm5lY3RUb01haW5UaHJlYWQoKSx2KCJDb25uZWN0ZWQgdG8gbWFpbiB0aHJlYWQiKTtsZXQgbz0hMTtuLm9uKCJEZWJ1Z2dlci5yZXN1bWVkIiwoKCk9PntvPSExfSkpLG4ub24oIkRlYnVnZ2VyLnBhdXNlZCIsKGU9PntvPSEwLGFzeW5jIGZ1bmN0aW9uKGUsbix7cmVhc29uOm8sZGF0YTpyLGNhbGxGcmFtZXM6aX0pe2lmKCJleGNlcHRpb24iIT09byYmInByb21pc2VSZWplY3Rpb24iIT09bylyZXR1cm47eD8uKCk7Y29uc3Qgcz1mdW5jdGlvbihlLG4pe2lmKHZvaWQgMCE9PW4pcmV0dXJuIGZ1bmN0aW9uKGUpe2lmKHZvaWQgMCE9PWUpcmV0dXJuIGUuc2xpY2UoLTEwKS5yZWR1Y2UoKChlLG4pPT5gJHtlfSwke24uZnVuY3Rpb259LCR7bi5saW5lbm99LCR7bi5jb2xub31gKSwiIil9KGUobiwxKSl9KG4scj8uZGVzY3JpcHRpb24pO2lmKG51bGw9PXMpcmV0dXJuO2NvbnN0IGM9W107Zm9yKGxldCBuPTA7bjxpLmxlbmd0aDtuKyspe2NvbnN0e3Njb3BlQ2hhaW46dCxmdW5jdGlvbk5hbWU6byx0aGlzOnJ9PWlbbl0scz10LmZpbmQoKGU9PiJsb2NhbCI9PT1lLnR5cGUpKSxhPSJnbG9iYWwiIT09ci5jbGFzc05hbWUmJnIuY2xhc3NOYW1lP2Ake3IuY2xhc3NOYW1lfS4ke299YDpvO2lmKHZvaWQgMD09PXM/Lm9iamVjdC5vYmplY3RJZCljW25dPXtmdW5jdGlvbjphfTtlbHNle2NvbnN0IHQ9YXdhaXQgUChlLHMub2JqZWN0Lm9iamVjdElkKTtjW25dPXtmdW5jdGlvbjphLHZhcnM6dH19fXQ/LnBvc3RNZXNzYWdlKHtleGNlcHRpb25IYXNoOnMsZnJhbWVzOmN9KX0obiwkLGUucGFyYW1zKS50aGVuKCgoKT0+bz9uLnBvc3QoIkRlYnVnZ2VyLnJlc3VtZSIpOlByb21pc2UucmVzb2x2ZSgpKSwoZT0+e30pKX0pKSxhd2FpdCBuLnBvc3QoIkRlYnVnZ2VyLmVuYWJsZSIpO2NvbnN0IHI9ITEhPT1iLmNhcHR1cmVBbGxFeGNlcHRpb25zO2lmKGF3YWl0IG4ucG9zdCgiRGVidWdnZXIuc2V0UGF1c2VPbkV4Y2VwdGlvbnMiLHtzdGF0ZTpyPyJhbGwiOiJ1bmNhdWdodCJ9KSxyKXtjb25zdCBlPWIubWF4RXhjZXB0aW9uc1BlclNlY29uZHx8NTA7eD1mdW5jdGlvbihlLG4sdCl7bGV0IG89MCxyPTUsaT0wO3JldHVybiBzZXRJbnRlcnZhbCgoKCk9PnswPT09aT9vPmUmJihyKj0yLHQocikscj44NjQwMCYmKHI9ODY0MDApLGk9cik6KGktPTEsMD09PWkmJm4oKSksbz0wfSksMWUzKS51bnJlZigpLCgpPT57bys9MX19KGUsKGFzeW5jKCk9Pnt2KCJSYXRlLWxpbWl0IGxpZnRlZC4iKSxhd2FpdCBuLnBvc3QoIkRlYnVnZ2VyLnNldFBhdXNlT25FeGNlcHRpb25zIix7c3RhdGU6ImFsbCJ9KX0pLChhc3luYyBlPT57dihgUmF0ZS1saW1pdCBleGNlZWRlZC4gRGlzYWJsaW5nIGNhcHR1cmluZyBvZiBjYXVnaHQgZXhjZXB0aW9ucyBmb3IgJHtlfSBzZWNvbmRzLmApLGF3YWl0IG4ucG9zdCgiRGVidWdnZXIuc2V0UGF1c2VPbkV4Y2VwdGlvbnMiLHtzdGF0ZToidW5jYXVnaHQifSl9KSl9fSkoKS5jYXRjaCgoZT0+e3YoIkZhaWxlZCB0byBzdGFydCBkZWJ1Z2dlciIsZSl9KSksc2V0SW50ZXJ2YWwoKCgpPT57fSksMWU0KTs=';
|
|
14
14
|
|
|
15
15
|
function log(...args) {
|
|
16
16
|
utils.logger.log('[LocalVariables]', ...args);
|
|
@@ -45,7 +45,7 @@ const _nativeNodeFetchIntegration = ((options = {}) => {
|
|
|
45
45
|
} );
|
|
46
46
|
} catch (error) {
|
|
47
47
|
// Could not load instrumentation
|
|
48
|
-
debugBuild.DEBUG_BUILD && utils.logger.log('
|
|
48
|
+
debugBuild.DEBUG_BUILD && utils.logger.log('Error while loading NodeFetch instrumentation: \n', error);
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-fetch.js","sources":["../../../src/integrations/node-fetch.ts"],"sourcesContent":["import type { Span } from '@opentelemetry/api';\nimport { addBreadcrumb, defineIntegration } from '@sentry/core';\nimport { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry';\nimport type { IntegrationFn, SanitizedRequestData } from '@sentry/types';\nimport { getSanitizedUrlString, logger, parseUrl } from '@sentry/utils';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { NODE_MAJOR } from '../nodeVersion';\n\nimport type { FetchInstrumentation } from 'opentelemetry-instrumentation-fetch-node';\n\nimport { addOriginToSpan } from '../utils/addOriginToSpan';\n\ninterface FetchRequest {\n method: string;\n origin: string;\n path: string;\n headers: string | string[];\n}\n\ninterface FetchResponse {\n headers: Buffer[];\n statusCode: number;\n}\n\ninterface NodeFetchOptions {\n /**\n * Whether breadcrumbs should be recorded for requests.\n * Defaults to true\n */\n breadcrumbs?: boolean;\n\n /**\n * Do not capture spans or breadcrumbs for outgoing fetch 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 ignoreOutgoingRequests?: (url: string) => boolean;\n}\n\nconst _nativeNodeFetchIntegration = ((options: NodeFetchOptions = {}) => {\n const _breadcrumbs = typeof options.breadcrumbs === 'undefined' ? true : options.breadcrumbs;\n const _ignoreOutgoingRequests = options.ignoreOutgoingRequests;\n\n async function getInstrumentation(): Promise<FetchInstrumentation | void> {\n // Only add NodeFetch if Node >= 18, as previous versions do not support it\n if (NODE_MAJOR < 18) {\n DEBUG_BUILD && logger.log('NodeFetch is not supported on Node < 18, skipping instrumentation...');\n return;\n }\n\n try {\n const pkg = await import('opentelemetry-instrumentation-fetch-node');\n const { FetchInstrumentation } = pkg;\n\n class SentryNodeFetchInstrumentation extends FetchInstrumentation {\n // We extend this method so we have access to request _and_ response for the breadcrumb\n public onHeaders({ request, response }: { request: FetchRequest; response: FetchResponse }): void {\n if (_breadcrumbs) {\n _addRequestBreadcrumb(request, response);\n }\n\n return super.onHeaders({ request, response });\n }\n }\n\n return new SentryNodeFetchInstrumentation({\n ignoreRequestHook: (request: { origin?: string }) => {\n const url = request.origin;\n return _ignoreOutgoingRequests && url && _ignoreOutgoingRequests(url);\n },\n onRequest: ({ span }: { span: Span }) => {\n _updateSpan(span);\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as any);\n } catch (error) {\n // Could not load instrumentation\n DEBUG_BUILD && logger.log('
|
|
1
|
+
{"version":3,"file":"node-fetch.js","sources":["../../../src/integrations/node-fetch.ts"],"sourcesContent":["import type { Span } from '@opentelemetry/api';\nimport { addBreadcrumb, defineIntegration } from '@sentry/core';\nimport { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry';\nimport type { IntegrationFn, SanitizedRequestData } from '@sentry/types';\nimport { getSanitizedUrlString, logger, parseUrl } from '@sentry/utils';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { NODE_MAJOR } from '../nodeVersion';\n\nimport type { FetchInstrumentation } from 'opentelemetry-instrumentation-fetch-node';\n\nimport { addOriginToSpan } from '../utils/addOriginToSpan';\n\ninterface FetchRequest {\n method: string;\n origin: string;\n path: string;\n headers: string | string[];\n}\n\ninterface FetchResponse {\n headers: Buffer[];\n statusCode: number;\n}\n\ninterface NodeFetchOptions {\n /**\n * Whether breadcrumbs should be recorded for requests.\n * Defaults to true\n */\n breadcrumbs?: boolean;\n\n /**\n * Do not capture spans or breadcrumbs for outgoing fetch 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 ignoreOutgoingRequests?: (url: string) => boolean;\n}\n\nconst _nativeNodeFetchIntegration = ((options: NodeFetchOptions = {}) => {\n const _breadcrumbs = typeof options.breadcrumbs === 'undefined' ? true : options.breadcrumbs;\n const _ignoreOutgoingRequests = options.ignoreOutgoingRequests;\n\n async function getInstrumentation(): Promise<FetchInstrumentation | void> {\n // Only add NodeFetch if Node >= 18, as previous versions do not support it\n if (NODE_MAJOR < 18) {\n DEBUG_BUILD && logger.log('NodeFetch is not supported on Node < 18, skipping instrumentation...');\n return;\n }\n\n try {\n const pkg = await import('opentelemetry-instrumentation-fetch-node');\n const { FetchInstrumentation } = pkg;\n\n class SentryNodeFetchInstrumentation extends FetchInstrumentation {\n // We extend this method so we have access to request _and_ response for the breadcrumb\n public onHeaders({ request, response }: { request: FetchRequest; response: FetchResponse }): void {\n if (_breadcrumbs) {\n _addRequestBreadcrumb(request, response);\n }\n\n return super.onHeaders({ request, response });\n }\n }\n\n return new SentryNodeFetchInstrumentation({\n ignoreRequestHook: (request: { origin?: string }) => {\n const url = request.origin;\n return _ignoreOutgoingRequests && url && _ignoreOutgoingRequests(url);\n },\n onRequest: ({ span }: { span: Span }) => {\n _updateSpan(span);\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as any);\n } catch (error) {\n // Could not load instrumentation\n DEBUG_BUILD && logger.log('Error while loading NodeFetch instrumentation: \\n', error);\n }\n }\n\n return {\n name: 'NodeFetch',\n setupOnce() {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n getInstrumentation().then(instrumentation => {\n if (instrumentation) {\n addOpenTelemetryInstrumentation(instrumentation);\n }\n });\n },\n };\n}) satisfies IntegrationFn;\n\nexport const nativeNodeFetchIntegration = defineIntegration(_nativeNodeFetchIntegration);\n\n/** Update the span with data we need. */\nfunction _updateSpan(span: Span): void {\n addOriginToSpan(span, 'auto.http.otel.node_fetch');\n}\n\n/** Add a breadcrumb for outgoing requests. */\nfunction _addRequestBreadcrumb(request: FetchRequest, response: FetchResponse): void {\n const data = getBreadcrumbData(request);\n\n addBreadcrumb(\n {\n category: 'http',\n data: {\n status_code: response.statusCode,\n ...data,\n },\n type: 'http',\n },\n {\n event: 'response',\n request,\n response,\n },\n );\n}\n\nfunction getBreadcrumbData(request: FetchRequest): Partial<SanitizedRequestData> {\n try {\n const url = new URL(request.path, request.origin);\n const parsedUrl = parseUrl(url.toString());\n\n const data: Partial<SanitizedRequestData> = {\n url: getSanitizedUrlString(parsedUrl),\n 'http.method': request.method || 'GET',\n };\n\n if (parsedUrl.search) {\n data['http.query'] = parsedUrl.search;\n }\n if (parsedUrl.hash) {\n data['http.fragment'] = parsedUrl.hash;\n }\n\n return data;\n } catch {\n return {};\n }\n}\n"],"names":["NODE_MAJOR","DEBUG_BUILD","logger","addOpenTelemetryInstrumentation","defineIntegration","addOriginToSpan","addBreadcrumb","parseUrl","getSanitizedUrlString"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"koa.js","sources":["../../../../src/integrations/tracing/koa.ts"],"sourcesContent":["import { KoaInstrumentation } from '@opentelemetry/instrumentation-koa';\nimport { SEMATTRS_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';\nimport {\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n captureException,\n defineIntegration,\n getDefaultIsolationScope,\n getIsolationScope,\n spanToJSON,\n} from '@sentry/core';\nimport type { IntegrationFn, Span } from '@sentry/types';\nimport { logger } from '@sentry/utils';\nimport { DEBUG_BUILD } from '../../debug-build';\nimport { generateInstrumentOnce } from '../../otel/instrument';\nimport { ensureIsWrapped } from '../../utils/ensureIsWrapped';\n\nconst INTEGRATION_NAME = 'Koa';\n\nexport const instrumentKoa = generateInstrumentOnce(\n INTEGRATION_NAME,\n () =>\n new KoaInstrumentation({\n requestHook(span, info) {\n addKoaSpanAttributes(span);\n\n if (getIsolationScope() === getDefaultIsolationScope()) {\n DEBUG_BUILD && logger.warn('Isolation scope is default isolation scope - skipping setting transactionName');\n return;\n }\n const attributes = spanToJSON(span).data;\n const route = attributes && attributes[SEMATTRS_HTTP_ROUTE];\n const method = info.context.request.method.toUpperCase() || 'GET';\n if (route) {\n getIsolationScope().setTransactionName(`${method} ${route}`);\n }\n },\n }),\n);\n\nconst _koaIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentKoa();\n },\n };\n}) satisfies IntegrationFn;\n\nexport const koaIntegration = defineIntegration(_koaIntegration);\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const setupKoaErrorHandler = (app: { use: (arg0: (ctx: any, next: any) => Promise<void>) => void }): void => {\n app.use(async (ctx, next) => {\n try {\n await next();\n } catch (error) {\n captureException(error);\n }\n });\n\n ensureIsWrapped(app.use, 'koa');\n};\n\nfunction addKoaSpanAttributes(span: Span): void {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.http.otel.koa');\n\n const attributes = spanToJSON(span).data || {};\n\n // this is one of: middleware, router\n const type = attributes['koa.type'];\n\n if (type) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, `${type}.koa`);\n }\n\n // Also update the name\n const name = attributes['koa.name'];\n if (typeof name === 'string') {\n // Somehow, name is sometimes `''` for middleware spans\n // See: https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2220\n span.updateName(name || '< unknown >');\n }\n}\n"],"names":["generateInstrumentOnce","KoaInstrumentation","getIsolationScope","getDefaultIsolationScope","DEBUG_BUILD","logger","spanToJSON","SEMATTRS_HTTP_ROUTE","defineIntegration","captureException","ensureIsWrapped","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_OP"],"mappings":";;;;;;;;;;AAiBA,MAAM,gBAAA,GAAmB,KAAK,CAAA;AAC9B;AACO,MAAM,aAAc,GAAEA,iCAAsB;AACnD,EAAE,gBAAgB;AAClB,EAAE;AACF,IAAI,IAAIC,qCAAkB,CAAC;AAC3B,MAAM,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE;AAC9B,QAAQ,oBAAoB,CAAC,IAAI,CAAC,CAAA;AAClC;AACA,QAAQ,IAAIC,sBAAiB,OAAOC,6BAAwB,EAAE,EAAE;AAChE,UAAUC,0BAAeC,YAAM,CAAC,IAAI,CAAC,+EAA+E,CAAC,CAAA;AACrH,UAAU,OAAM;AAChB,SAAQ;AACR,QAAQ,MAAM,aAAaC,eAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAA;AAChD,QAAQ,MAAM,QAAQ,UAAA,IAAc,UAAU,CAACC,uCAAmB,CAAC,CAAA;AACnE,QAAQ,MAAM,MAAA,GAAS,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,EAAC,IAAK,KAAK,CAAA;AACzE,QAAQ,IAAI,KAAK,EAAE;AACnB,UAAUL,sBAAiB,EAAE,CAAC,kBAAkB,CAAC,CAAC,EAAA,MAAA,CAAA,CAAA,EAAA,KAAA,CAAA,CAAA,CAAA,CAAA;AACA,SAAA;AACA,OAAA;AACA,KAAA,CAAA;AACA,EAAA;AACA;AACA,MAAA,eAAA,IAAA,MAAA;AACA,EAAA,OAAA;AACA,IAAA,IAAA,EAAA,gBAAA;AACA,IAAA,SAAA,GAAA;AACA,MAAA,aAAA,EAAA,CAAA;AACA,KAAA;AACA,GAAA,CAAA;AACA,CAAA,CAAA,EAAA;AACA;AACA,MAAA,cAAA,GAAAM,sBAAA,CAAA,eAAA,EAAA;AACA;AACA;AACA,MAAA,oBAAA,GAAA,CAAA,GAAA,KAAA;AACA,EAAA,GAAA,CAAA,GAAA,CAAA,OAAA,GAAA,EAAA,IAAA,KAAA;AACA,IAAA,IAAA;AACA,MAAA,MAAA,IAAA,EAAA,CAAA;AACA,KAAA,CAAA,OAAA,KAAA,EAAA;AACA,MAAAC,qBAAA,CAAA,KAAA,CAAA,CAAA;AACA,KAAA;AACA,GAAA,CAAA,CAAA;AACA;AACA,EAAAC,+BAAA,CAAA,GAAA,CAAA,GAAA,EAAA,KAAA,CAAA,CAAA;AACA,EAAA;AACA;AACA,SAAA,oBAAA,CAAA,IAAA,EAAA;AACA,EAAA,IAAA,CAAA,YAAA,CAAAC,qCAAA,EAAA,oBAAA,CAAA,CAAA;AACA;AACA,EAAA,MAAA,UAAA,GAAAL,eAAA,CAAA,IAAA,CAAA,CAAA,IAAA,IAAA,EAAA,CAAA;AACA;AACA;AACA,EAAA,MAAA,IAAA,GAAA,UAAA,CAAA,UAAA,CAAA,CAAA;AACA;AACA,EAAA,IAAA,IAAA,EAAA;AACA,IAAA,IAAA,CAAA,YAAA,CAAAM,iCAAA,EAAA,CAAA,EAAA,IAAA,CAAA,IAAA,CAAA,CAAA,CAAA;AACA,GAAA;AACA;AACA;AACA,EAAA,MAAA,IAAA,GAAA,UAAA,CAAA,UAAA,CAAA,CAAA;AACA,EAAA,IAAA,OAAA,IAAA,KAAA,QAAA,EAAA;AACA;AACA;AACA,IAAA,IAAA,CAAA,UAAA,CAAA,IAAA,IAAA,aAAA,CAAA,CAAA;AACA,GAAA;AACA;;;;;;"}
|
|
1
|
+
{"version":3,"file":"koa.js","sources":["../../../../src/integrations/tracing/koa.ts"],"sourcesContent":["import { KoaInstrumentation } from '@opentelemetry/instrumentation-koa';\nimport { SEMATTRS_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';\nimport {\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n captureException,\n defineIntegration,\n getDefaultIsolationScope,\n getIsolationScope,\n spanToJSON,\n} from '@sentry/core';\nimport type { IntegrationFn, Span } from '@sentry/types';\nimport { logger } from '@sentry/utils';\nimport { DEBUG_BUILD } from '../../debug-build';\nimport { generateInstrumentOnce } from '../../otel/instrument';\nimport { ensureIsWrapped } from '../../utils/ensureIsWrapped';\n\nconst INTEGRATION_NAME = 'Koa';\n\nexport const instrumentKoa = generateInstrumentOnce(\n INTEGRATION_NAME,\n () =>\n new KoaInstrumentation({\n requestHook(span, info) {\n addKoaSpanAttributes(span);\n\n if (getIsolationScope() === getDefaultIsolationScope()) {\n DEBUG_BUILD && logger.warn('Isolation scope is default isolation scope - skipping setting transactionName');\n return;\n }\n const attributes = spanToJSON(span).data;\n const route = attributes && attributes[SEMATTRS_HTTP_ROUTE];\n const method = info.context.request.method.toUpperCase() || 'GET';\n if (route) {\n getIsolationScope().setTransactionName(`${method} ${route}`);\n }\n },\n }),\n);\n\nconst _koaIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentKoa();\n },\n };\n}) satisfies IntegrationFn;\n\nexport const koaIntegration = defineIntegration(_koaIntegration);\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const setupKoaErrorHandler = (app: { use: (arg0: (ctx: any, next: any) => Promise<void>) => void }): void => {\n app.use(async (ctx, next) => {\n try {\n await next();\n } catch (error) {\n captureException(error);\n throw error;\n }\n });\n\n ensureIsWrapped(app.use, 'koa');\n};\n\nfunction addKoaSpanAttributes(span: Span): void {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.http.otel.koa');\n\n const attributes = spanToJSON(span).data || {};\n\n // this is one of: middleware, router\n const type = attributes['koa.type'];\n\n if (type) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, `${type}.koa`);\n }\n\n // Also update the name\n const name = attributes['koa.name'];\n if (typeof name === 'string') {\n // Somehow, name is sometimes `''` for middleware spans\n // See: https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2220\n span.updateName(name || '< unknown >');\n }\n}\n"],"names":["generateInstrumentOnce","KoaInstrumentation","getIsolationScope","getDefaultIsolationScope","DEBUG_BUILD","logger","spanToJSON","SEMATTRS_HTTP_ROUTE","defineIntegration","captureException","ensureIsWrapped","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_OP"],"mappings":";;;;;;;;;;AAiBA,MAAM,gBAAA,GAAmB,KAAK,CAAA;AAC9B;AACO,MAAM,aAAc,GAAEA,iCAAsB;AACnD,EAAE,gBAAgB;AAClB,EAAE;AACF,IAAI,IAAIC,qCAAkB,CAAC;AAC3B,MAAM,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE;AAC9B,QAAQ,oBAAoB,CAAC,IAAI,CAAC,CAAA;AAClC;AACA,QAAQ,IAAIC,sBAAiB,OAAOC,6BAAwB,EAAE,EAAE;AAChE,UAAUC,0BAAeC,YAAM,CAAC,IAAI,CAAC,+EAA+E,CAAC,CAAA;AACrH,UAAU,OAAM;AAChB,SAAQ;AACR,QAAQ,MAAM,aAAaC,eAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAA;AAChD,QAAQ,MAAM,QAAQ,UAAA,IAAc,UAAU,CAACC,uCAAmB,CAAC,CAAA;AACnE,QAAQ,MAAM,MAAA,GAAS,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,EAAC,IAAK,KAAK,CAAA;AACzE,QAAQ,IAAI,KAAK,EAAE;AACnB,UAAUL,sBAAiB,EAAE,CAAC,kBAAkB,CAAC,CAAC,EAAA,MAAA,CAAA,CAAA,EAAA,KAAA,CAAA,CAAA,CAAA,CAAA;AACA,SAAA;AACA,OAAA;AACA,KAAA,CAAA;AACA,EAAA;AACA;AACA,MAAA,eAAA,IAAA,MAAA;AACA,EAAA,OAAA;AACA,IAAA,IAAA,EAAA,gBAAA;AACA,IAAA,SAAA,GAAA;AACA,MAAA,aAAA,EAAA,CAAA;AACA,KAAA;AACA,GAAA,CAAA;AACA,CAAA,CAAA,EAAA;AACA;AACA,MAAA,cAAA,GAAAM,sBAAA,CAAA,eAAA,EAAA;AACA;AACA;AACA,MAAA,oBAAA,GAAA,CAAA,GAAA,KAAA;AACA,EAAA,GAAA,CAAA,GAAA,CAAA,OAAA,GAAA,EAAA,IAAA,KAAA;AACA,IAAA,IAAA;AACA,MAAA,MAAA,IAAA,EAAA,CAAA;AACA,KAAA,CAAA,OAAA,KAAA,EAAA;AACA,MAAAC,qBAAA,CAAA,KAAA,CAAA,CAAA;AACA,MAAA,MAAA,KAAA,CAAA;AACA,KAAA;AACA,GAAA,CAAA,CAAA;AACA;AACA,EAAAC,+BAAA,CAAA,GAAA,CAAA,GAAA,EAAA,KAAA,CAAA,CAAA;AACA,EAAA;AACA;AACA,SAAA,oBAAA,CAAA,IAAA,EAAA;AACA,EAAA,IAAA,CAAA,YAAA,CAAAC,qCAAA,EAAA,oBAAA,CAAA,CAAA;AACA;AACA,EAAA,MAAA,UAAA,GAAAL,eAAA,CAAA,IAAA,CAAA,CAAA,IAAA,IAAA,EAAA,CAAA;AACA;AACA;AACA,EAAA,MAAA,IAAA,GAAA,UAAA,CAAA,UAAA,CAAA,CAAA;AACA;AACA,EAAA,IAAA,IAAA,EAAA;AACA,IAAA,IAAA,CAAA,YAAA,CAAAM,iCAAA,EAAA,CAAA,EAAA,IAAA,CAAA,IAAA,CAAA,CAAA,CAAA;AACA,GAAA;AACA;AACA;AACA,EAAA,MAAA,IAAA,GAAA,UAAA,CAAA,UAAA,CAAA,CAAA;AACA,EAAA,IAAA,OAAA,IAAA,KAAA,QAAA,EAAA;AACA;AACA;AACA,IAAA,IAAA,CAAA,UAAA,CAAA,IAAA,IAAA,aAAA,CAAA,CAAA;AACA,GAAA;AACA;;;;;;"}
|
package/cjs/sdk/index.js
CHANGED
package/cjs/sdk/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/sdk/index.ts"],"sourcesContent":["import {\n endSession,\n functionToStringIntegration,\n getClient,\n getCurrentScope,\n getIntegrationsToSetup,\n getIsolationScope,\n hasTracingEnabled,\n inboundFiltersIntegration,\n linkedErrorsIntegration,\n requestDataIntegration,\n startSession,\n} from '@sentry/core';\nimport {\n enhanceDscWithOpenTelemetryRootSpanName,\n openTelemetrySetupCheck,\n setOpenTelemetryContextAsyncContextStrategy,\n setupEventContextTrace,\n} from '@sentry/opentelemetry';\nimport type { Client, Integration, Options } from '@sentry/types';\nimport {\n consoleSandbox,\n dropUndefinedKeys,\n logger,\n propagationContextFromHeaders,\n stackParserFromStackParserOptions,\n} from '@sentry/utils';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { consoleIntegration } from '../integrations/console';\nimport { nodeContextIntegration } from '../integrations/context';\nimport { contextLinesIntegration } from '../integrations/contextlines';\n\nimport { httpIntegration } from '../integrations/http';\nimport { localVariablesIntegration } from '../integrations/local-variables';\nimport { modulesIntegration } from '../integrations/modules';\nimport { nativeNodeFetchIntegration } from '../integrations/node-fetch';\nimport { onUncaughtExceptionIntegration } from '../integrations/onuncaughtexception';\nimport { onUnhandledRejectionIntegration } from '../integrations/onunhandledrejection';\nimport { spotlightIntegration } from '../integrations/spotlight';\nimport { getAutoPerformanceIntegrations } from '../integrations/tracing';\nimport { makeNodeTransport } from '../transports';\nimport type { NodeClientOptions, NodeOptions } from '../types';\nimport { isCjs } from '../utils/commonjs';\nimport { defaultStackParser, getSentryRelease } from './api';\nimport { NodeClient } from './client';\nimport { initOpenTelemetry, maybeInitializeEsmLoader } from './initOtel';\n\nfunction getCjsOnlyIntegrations(): Integration[] {\n return isCjs() ? [modulesIntegration()] : [];\n}\n\n/**\n * Get default integrations, excluding performance.\n */\nexport function getDefaultIntegrationsWithoutPerformance(): Integration[] {\n return [\n // Common\n inboundFiltersIntegration(),\n functionToStringIntegration(),\n linkedErrorsIntegration(),\n requestDataIntegration(),\n // Native Wrappers\n consoleIntegration(),\n httpIntegration(),\n nativeNodeFetchIntegration(),\n // Global Handlers\n onUncaughtExceptionIntegration(),\n onUnhandledRejectionIntegration(),\n // Event Info\n contextLinesIntegration(),\n localVariablesIntegration(),\n nodeContextIntegration(),\n ...getCjsOnlyIntegrations(),\n ];\n}\n\n/** Get the default integrations for the Node SDK. */\nexport function getDefaultIntegrations(options: Options): Integration[] {\n return [\n ...getDefaultIntegrationsWithoutPerformance(),\n // We only add performance integrations if tracing is enabled\n // Note that this means that without tracing enabled, e.g. `expressIntegration()` will not be added\n // This means that generally request isolation will work (because that is done by httpIntegration)\n // But `transactionName` will not be set automatically\n ...(shouldAddPerformanceIntegrations(options) ? getAutoPerformanceIntegrations() : []),\n ];\n}\n\nfunction shouldAddPerformanceIntegrations(options: Options): boolean {\n if (!hasTracingEnabled(options)) {\n return false;\n }\n\n // We want to ensure `tracesSampleRate` is not just undefined/null here\n return options.enableTracing || options.tracesSampleRate != null || 'tracesSampler' in options;\n}\n\n/**\n * Initialize Sentry for Node.\n */\nexport function init(options: NodeOptions | undefined = {}): void {\n return _init(options, getDefaultIntegrations);\n}\n\n/**\n * Initialize Sentry for Node, without any integrations added by default.\n */\nexport function initWithoutDefaultIntegrations(options: NodeOptions | undefined = {}): void {\n return _init(options, () => []);\n}\n\n/**\n * Initialize Sentry for Node, without performance instrumentation.\n */\nfunction _init(\n options: NodeOptions | undefined = {},\n getDefaultIntegrationsImpl: (options: Options) => Integration[],\n): void {\n const clientOptions = getClientOptions(options, getDefaultIntegrationsImpl);\n\n if (clientOptions.debug === true) {\n if (DEBUG_BUILD) {\n logger.enable();\n } else {\n // use `console.warn` rather than `logger.warn` since by non-debug bundles have all `logger.x` statements stripped\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn('[Sentry] Cannot initialize SDK with `debug` option using a non-debug bundle.');\n });\n }\n }\n\n if (!isCjs()) {\n maybeInitializeEsmLoader();\n }\n\n setOpenTelemetryContextAsyncContextStrategy();\n\n const scope = getCurrentScope();\n scope.update(options.initialScope);\n\n const client = new NodeClient(clientOptions);\n // The client is on the current scope, from where it generally is inherited\n getCurrentScope().setClient(client);\n\n if (isEnabled(client)) {\n client.init();\n }\n\n logger.log(`Running in ${isCjs() ? 'CommonJS' : 'ESM'} mode.`);\n\n if (options.autoSessionTracking) {\n startSessionTracking();\n }\n\n updateScopeFromEnvVariables();\n\n if (options.spotlight) {\n // force integrations to be setup even if no DSN was set\n // If they have already been added before, they will be ignored anyhow\n const integrations = client.getOptions().integrations;\n for (const integration of integrations) {\n client.addIntegration(integration);\n }\n client.addIntegration(\n spotlightIntegration({\n sidecarUrl: typeof options.spotlight === 'string' ? options.spotlight : undefined,\n }),\n );\n }\n\n // If users opt-out of this, they _have_ to set up OpenTelemetry themselves\n // There is no way to use this SDK without OpenTelemetry!\n if (!options.skipOpenTelemetrySetup) {\n initOpenTelemetry(client);\n validateOpenTelemetrySetup();\n }\n\n enhanceDscWithOpenTelemetryRootSpanName(client);\n setupEventContextTrace(client);\n}\n\n/**\n * Validate that your OpenTelemetry setup is correct.\n */\nexport function validateOpenTelemetrySetup(): void {\n if (!DEBUG_BUILD) {\n return;\n }\n\n const setup = openTelemetrySetupCheck();\n\n const required = ['SentrySpanProcessor', 'SentryContextManager', 'SentryPropagator'] as const;\n for (const k of required) {\n if (!setup.includes(k)) {\n logger.error(\n `You have to set up the ${k}. Without this, the OpenTelemetry & Sentry integration will not work properly.`,\n );\n }\n }\n\n if (!setup.includes('SentrySampler')) {\n logger.warn(\n 'You have to set up the SentrySampler. Without this, the OpenTelemetry & Sentry integration may still work, but sample rates set for the Sentry SDK will not be respected.',\n );\n }\n}\n\nfunction getClientOptions(\n options: NodeOptions,\n getDefaultIntegrationsImpl: (options: Options) => Integration[],\n): NodeClientOptions {\n const release = getRelease(options.release);\n\n const autoSessionTracking =\n typeof release !== 'string'\n ? false\n : options.autoSessionTracking === undefined\n ? true\n : options.autoSessionTracking;\n\n const tracesSampleRate = getTracesSampleRate(options.tracesSampleRate);\n\n const baseOptions = dropUndefinedKeys({\n transport: makeNodeTransport,\n dsn: process.env.SENTRY_DSN,\n environment: process.env.SENTRY_ENVIRONMENT,\n });\n\n const overwriteOptions = dropUndefinedKeys({\n release,\n autoSessionTracking,\n tracesSampleRate,\n });\n\n const mergedOptions = {\n ...baseOptions,\n ...options,\n ...overwriteOptions,\n };\n\n if (options.defaultIntegrations === undefined) {\n options.defaultIntegrations = getDefaultIntegrationsImpl(mergedOptions);\n }\n\n const clientOptions: NodeClientOptions = {\n ...mergedOptions,\n stackParser: stackParserFromStackParserOptions(options.stackParser || defaultStackParser),\n integrations: getIntegrationsToSetup({\n defaultIntegrations: options.defaultIntegrations,\n integrations: options.integrations,\n }),\n };\n\n return clientOptions;\n}\n\nfunction getRelease(release: NodeOptions['release']): string | undefined {\n if (release !== undefined) {\n return release;\n }\n\n const detectedRelease = getSentryRelease();\n if (detectedRelease !== undefined) {\n return detectedRelease;\n }\n\n return undefined;\n}\n\nfunction getTracesSampleRate(tracesSampleRate: NodeOptions['tracesSampleRate']): number | undefined {\n if (tracesSampleRate !== undefined) {\n return tracesSampleRate;\n }\n\n const sampleRateFromEnv = process.env.SENTRY_TRACES_SAMPLE_RATE;\n if (!sampleRateFromEnv) {\n return undefined;\n }\n\n const parsed = parseFloat(sampleRateFromEnv);\n return isFinite(parsed) ? parsed : undefined;\n}\n\n/**\n * Update scope and propagation context based on environmental variables.\n *\n * See https://github.com/getsentry/rfcs/blob/main/text/0071-continue-trace-over-process-boundaries.md\n * for more details.\n */\nfunction updateScopeFromEnvVariables(): void {\n const sentryUseEnvironment = (process.env.SENTRY_USE_ENVIRONMENT || '').toLowerCase();\n if (!['false', 'n', 'no', 'off', '0'].includes(sentryUseEnvironment)) {\n const sentryTraceEnv = process.env.SENTRY_TRACE;\n const baggageEnv = process.env.SENTRY_BAGGAGE;\n const propagationContext = propagationContextFromHeaders(sentryTraceEnv, baggageEnv);\n getCurrentScope().setPropagationContext(propagationContext);\n }\n}\n\n/**\n * Enable automatic Session Tracking for the node process.\n */\nfunction startSessionTracking(): void {\n const client = getClient<NodeClient>();\n if (client && client.getOptions().autoSessionTracking) {\n client.initSessionFlusher();\n }\n\n startSession();\n\n // Emitted in the case of healthy sessions, error of `mechanism.handled: true` and unhandledrejections because\n // The 'beforeExit' event is not emitted for conditions causing explicit termination,\n // such as calling process.exit() or uncaught exceptions.\n // Ref: https://nodejs.org/api/process.html#process_event_beforeexit\n process.on('beforeExit', () => {\n const session = getIsolationScope().getSession();\n\n // Only call endSession, if the Session exists on Scope and SessionStatus is not a\n // Terminal Status i.e. Exited or Crashed because\n // \"When a session is moved away from ok it must not be updated anymore.\"\n // Ref: https://develop.sentry.dev/sdk/sessions/\n if (session && session.status !== 'ok') {\n endSession();\n }\n });\n}\n\nfunction isEnabled(client: Client): boolean {\n return client.getOptions().enabled !== false && client.getTransport() !== undefined;\n}\n"],"names":["isCjs","modulesIntegration","inboundFiltersIntegration","functionToStringIntegration","linkedErrorsIntegration","requestDataIntegration","consoleIntegration","httpIntegration","nativeNodeFetchIntegration","onUncaughtExceptionIntegration","onUnhandledRejectionIntegration","contextLinesIntegration","localVariablesIntegration","nodeContextIntegration","getAutoPerformanceIntegrations","hasTracingEnabled","DEBUG_BUILD","logger","consoleSandbox","maybeInitializeEsmLoader","setOpenTelemetryContextAsyncContextStrategy","getCurrentScope","client","NodeClient","spotlightIntegration","initOpenTelemetry","enhanceDscWithOpenTelemetryRootSpanName","setupEventContextTrace","openTelemetrySetupCheck","dropUndefinedKeys","makeNodeTransport","stackParserFromStackParserOptions","defaultStackParser","getIntegrationsToSetup","getSentryRelease","propagationContextFromHeaders","getClient","startSession","getIsolationScope","endSession"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/sdk/index.ts"],"sourcesContent":["import {\n endSession,\n functionToStringIntegration,\n getClient,\n getCurrentScope,\n getIntegrationsToSetup,\n getIsolationScope,\n hasTracingEnabled,\n inboundFiltersIntegration,\n linkedErrorsIntegration,\n requestDataIntegration,\n startSession,\n} from '@sentry/core';\nimport {\n enhanceDscWithOpenTelemetryRootSpanName,\n openTelemetrySetupCheck,\n setOpenTelemetryContextAsyncContextStrategy,\n setupEventContextTrace,\n} from '@sentry/opentelemetry';\nimport type { Client, Integration, Options } from '@sentry/types';\nimport {\n consoleSandbox,\n dropUndefinedKeys,\n logger,\n propagationContextFromHeaders,\n stackParserFromStackParserOptions,\n} from '@sentry/utils';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { consoleIntegration } from '../integrations/console';\nimport { nodeContextIntegration } from '../integrations/context';\nimport { contextLinesIntegration } from '../integrations/contextlines';\n\nimport { httpIntegration } from '../integrations/http';\nimport { localVariablesIntegration } from '../integrations/local-variables';\nimport { modulesIntegration } from '../integrations/modules';\nimport { nativeNodeFetchIntegration } from '../integrations/node-fetch';\nimport { onUncaughtExceptionIntegration } from '../integrations/onuncaughtexception';\nimport { onUnhandledRejectionIntegration } from '../integrations/onunhandledrejection';\nimport { spotlightIntegration } from '../integrations/spotlight';\nimport { getAutoPerformanceIntegrations } from '../integrations/tracing';\nimport { makeNodeTransport } from '../transports';\nimport type { NodeClientOptions, NodeOptions } from '../types';\nimport { isCjs } from '../utils/commonjs';\nimport { defaultStackParser, getSentryRelease } from './api';\nimport { NodeClient } from './client';\nimport { initOpenTelemetry, maybeInitializeEsmLoader } from './initOtel';\n\nfunction getCjsOnlyIntegrations(): Integration[] {\n return isCjs() ? [modulesIntegration()] : [];\n}\n\n/**\n * Get default integrations, excluding performance.\n */\nexport function getDefaultIntegrationsWithoutPerformance(): Integration[] {\n return [\n // Common\n inboundFiltersIntegration(),\n functionToStringIntegration(),\n linkedErrorsIntegration(),\n requestDataIntegration(),\n // Native Wrappers\n consoleIntegration(),\n httpIntegration(),\n nativeNodeFetchIntegration(),\n // Global Handlers\n onUncaughtExceptionIntegration(),\n onUnhandledRejectionIntegration(),\n // Event Info\n contextLinesIntegration(),\n localVariablesIntegration(),\n nodeContextIntegration(),\n ...getCjsOnlyIntegrations(),\n ];\n}\n\n/** Get the default integrations for the Node SDK. */\nexport function getDefaultIntegrations(options: Options): Integration[] {\n return [\n ...getDefaultIntegrationsWithoutPerformance(),\n // We only add performance integrations if tracing is enabled\n // Note that this means that without tracing enabled, e.g. `expressIntegration()` will not be added\n // This means that generally request isolation will work (because that is done by httpIntegration)\n // But `transactionName` will not be set automatically\n ...(shouldAddPerformanceIntegrations(options) ? getAutoPerformanceIntegrations() : []),\n ];\n}\n\nfunction shouldAddPerformanceIntegrations(options: Options): boolean {\n if (!hasTracingEnabled(options)) {\n return false;\n }\n\n // We want to ensure `tracesSampleRate` is not just undefined/null here\n return options.enableTracing || options.tracesSampleRate != null || 'tracesSampler' in options;\n}\n\n/**\n * Initialize Sentry for Node.\n */\nexport function init(options: NodeOptions | undefined = {}): NodeClient | undefined {\n return _init(options, getDefaultIntegrations);\n}\n\n/**\n * Initialize Sentry for Node, without any integrations added by default.\n */\nexport function initWithoutDefaultIntegrations(options: NodeOptions | undefined = {}): NodeClient {\n return _init(options, () => []);\n}\n\n/**\n * Initialize Sentry for Node, without performance instrumentation.\n */\nfunction _init(\n options: NodeOptions | undefined = {},\n getDefaultIntegrationsImpl: (options: Options) => Integration[],\n): NodeClient {\n const clientOptions = getClientOptions(options, getDefaultIntegrationsImpl);\n\n if (clientOptions.debug === true) {\n if (DEBUG_BUILD) {\n logger.enable();\n } else {\n // use `console.warn` rather than `logger.warn` since by non-debug bundles have all `logger.x` statements stripped\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn('[Sentry] Cannot initialize SDK with `debug` option using a non-debug bundle.');\n });\n }\n }\n\n if (!isCjs()) {\n maybeInitializeEsmLoader();\n }\n\n setOpenTelemetryContextAsyncContextStrategy();\n\n const scope = getCurrentScope();\n scope.update(options.initialScope);\n\n const client = new NodeClient(clientOptions);\n // The client is on the current scope, from where it generally is inherited\n getCurrentScope().setClient(client);\n\n if (isEnabled(client)) {\n client.init();\n }\n\n logger.log(`Running in ${isCjs() ? 'CommonJS' : 'ESM'} mode.`);\n\n if (options.autoSessionTracking) {\n startSessionTracking();\n }\n\n updateScopeFromEnvVariables();\n\n if (options.spotlight) {\n // force integrations to be setup even if no DSN was set\n // If they have already been added before, they will be ignored anyhow\n const integrations = client.getOptions().integrations;\n for (const integration of integrations) {\n client.addIntegration(integration);\n }\n client.addIntegration(\n spotlightIntegration({\n sidecarUrl: typeof options.spotlight === 'string' ? options.spotlight : undefined,\n }),\n );\n }\n\n // If users opt-out of this, they _have_ to set up OpenTelemetry themselves\n // There is no way to use this SDK without OpenTelemetry!\n if (!options.skipOpenTelemetrySetup) {\n initOpenTelemetry(client);\n validateOpenTelemetrySetup();\n }\n\n enhanceDscWithOpenTelemetryRootSpanName(client);\n setupEventContextTrace(client);\n\n return client;\n}\n\n/**\n * Validate that your OpenTelemetry setup is correct.\n */\nexport function validateOpenTelemetrySetup(): void {\n if (!DEBUG_BUILD) {\n return;\n }\n\n const setup = openTelemetrySetupCheck();\n\n const required = ['SentrySpanProcessor', 'SentryContextManager', 'SentryPropagator'] as const;\n for (const k of required) {\n if (!setup.includes(k)) {\n logger.error(\n `You have to set up the ${k}. Without this, the OpenTelemetry & Sentry integration will not work properly.`,\n );\n }\n }\n\n if (!setup.includes('SentrySampler')) {\n logger.warn(\n 'You have to set up the SentrySampler. Without this, the OpenTelemetry & Sentry integration may still work, but sample rates set for the Sentry SDK will not be respected.',\n );\n }\n}\n\nfunction getClientOptions(\n options: NodeOptions,\n getDefaultIntegrationsImpl: (options: Options) => Integration[],\n): NodeClientOptions {\n const release = getRelease(options.release);\n\n const autoSessionTracking =\n typeof release !== 'string'\n ? false\n : options.autoSessionTracking === undefined\n ? true\n : options.autoSessionTracking;\n\n const tracesSampleRate = getTracesSampleRate(options.tracesSampleRate);\n\n const baseOptions = dropUndefinedKeys({\n transport: makeNodeTransport,\n dsn: process.env.SENTRY_DSN,\n environment: process.env.SENTRY_ENVIRONMENT,\n });\n\n const overwriteOptions = dropUndefinedKeys({\n release,\n autoSessionTracking,\n tracesSampleRate,\n });\n\n const mergedOptions = {\n ...baseOptions,\n ...options,\n ...overwriteOptions,\n };\n\n if (options.defaultIntegrations === undefined) {\n options.defaultIntegrations = getDefaultIntegrationsImpl(mergedOptions);\n }\n\n const clientOptions: NodeClientOptions = {\n ...mergedOptions,\n stackParser: stackParserFromStackParserOptions(options.stackParser || defaultStackParser),\n integrations: getIntegrationsToSetup({\n defaultIntegrations: options.defaultIntegrations,\n integrations: options.integrations,\n }),\n };\n\n return clientOptions;\n}\n\nfunction getRelease(release: NodeOptions['release']): string | undefined {\n if (release !== undefined) {\n return release;\n }\n\n const detectedRelease = getSentryRelease();\n if (detectedRelease !== undefined) {\n return detectedRelease;\n }\n\n return undefined;\n}\n\nfunction getTracesSampleRate(tracesSampleRate: NodeOptions['tracesSampleRate']): number | undefined {\n if (tracesSampleRate !== undefined) {\n return tracesSampleRate;\n }\n\n const sampleRateFromEnv = process.env.SENTRY_TRACES_SAMPLE_RATE;\n if (!sampleRateFromEnv) {\n return undefined;\n }\n\n const parsed = parseFloat(sampleRateFromEnv);\n return isFinite(parsed) ? parsed : undefined;\n}\n\n/**\n * Update scope and propagation context based on environmental variables.\n *\n * See https://github.com/getsentry/rfcs/blob/main/text/0071-continue-trace-over-process-boundaries.md\n * for more details.\n */\nfunction updateScopeFromEnvVariables(): void {\n const sentryUseEnvironment = (process.env.SENTRY_USE_ENVIRONMENT || '').toLowerCase();\n if (!['false', 'n', 'no', 'off', '0'].includes(sentryUseEnvironment)) {\n const sentryTraceEnv = process.env.SENTRY_TRACE;\n const baggageEnv = process.env.SENTRY_BAGGAGE;\n const propagationContext = propagationContextFromHeaders(sentryTraceEnv, baggageEnv);\n getCurrentScope().setPropagationContext(propagationContext);\n }\n}\n\n/**\n * Enable automatic Session Tracking for the node process.\n */\nfunction startSessionTracking(): void {\n const client = getClient<NodeClient>();\n if (client && client.getOptions().autoSessionTracking) {\n client.initSessionFlusher();\n }\n\n startSession();\n\n // Emitted in the case of healthy sessions, error of `mechanism.handled: true` and unhandledrejections because\n // The 'beforeExit' event is not emitted for conditions causing explicit termination,\n // such as calling process.exit() or uncaught exceptions.\n // Ref: https://nodejs.org/api/process.html#process_event_beforeexit\n process.on('beforeExit', () => {\n const session = getIsolationScope().getSession();\n\n // Only call endSession, if the Session exists on Scope and SessionStatus is not a\n // Terminal Status i.e. Exited or Crashed because\n // \"When a session is moved away from ok it must not be updated anymore.\"\n // Ref: https://develop.sentry.dev/sdk/sessions/\n if (session && session.status !== 'ok') {\n endSession();\n }\n });\n}\n\nfunction isEnabled(client: Client): boolean {\n return client.getOptions().enabled !== false && client.getTransport() !== undefined;\n}\n"],"names":["isCjs","modulesIntegration","inboundFiltersIntegration","functionToStringIntegration","linkedErrorsIntegration","requestDataIntegration","consoleIntegration","httpIntegration","nativeNodeFetchIntegration","onUncaughtExceptionIntegration","onUnhandledRejectionIntegration","contextLinesIntegration","localVariablesIntegration","nodeContextIntegration","getAutoPerformanceIntegrations","hasTracingEnabled","DEBUG_BUILD","logger","consoleSandbox","maybeInitializeEsmLoader","setOpenTelemetryContextAsyncContextStrategy","getCurrentScope","client","NodeClient","spotlightIntegration","initOpenTelemetry","enhanceDscWithOpenTelemetryRootSpanName","setupEventContextTrace","openTelemetrySetupCheck","dropUndefinedKeys","makeNodeTransport","stackParserFromStackParserOptions","defaultStackParser","getIntegrationsToSetup","getSentryRelease","propagationContextFromHeaders","getClient","startSession","getIsolationScope","endSession"],"mappings":"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"}
|
package/cjs/sdk/initOtel.js
CHANGED
|
@@ -103,7 +103,11 @@ function setupOtel(client) {
|
|
|
103
103
|
}),
|
|
104
104
|
forceFlushTimeoutMillis: 500,
|
|
105
105
|
});
|
|
106
|
-
provider.addSpanProcessor(
|
|
106
|
+
provider.addSpanProcessor(
|
|
107
|
+
new opentelemetry.SentrySpanProcessor({
|
|
108
|
+
timeout: client.getOptions().maxSpanWaitDuration,
|
|
109
|
+
}),
|
|
110
|
+
);
|
|
107
111
|
|
|
108
112
|
// Initialize the provider
|
|
109
113
|
provider.register({
|
package/cjs/sdk/initOtel.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initOtel.js","sources":["../../../src/sdk/initOtel.ts"],"sourcesContent":["import moduleModule from 'module';\nimport { DiagLogLevel, diag } from '@opentelemetry/api';\nimport { Resource } from '@opentelemetry/resources';\nimport { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';\nimport {\n SEMRESATTRS_SERVICE_NAME,\n SEMRESATTRS_SERVICE_NAMESPACE,\n SEMRESATTRS_SERVICE_VERSION,\n} from '@opentelemetry/semantic-conventions';\nimport { SDK_VERSION } from '@sentry/core';\nimport { SentryPropagator, SentrySampler, SentrySpanProcessor } from '@sentry/opentelemetry';\nimport { GLOBAL_OBJ, consoleSandbox, logger } from '@sentry/utils';\n\nimport { getOpenTelemetryInstrumentationToPreload } from '../integrations/tracing';\nimport { SentryContextManager } from '../otel/contextManager';\nimport { isCjs } from '../utils/commonjs';\nimport type { NodeClient } from './client';\n\ndeclare const __IMPORT_META_URL_REPLACEMENT__: string;\n\n/**\n * Initialize OpenTelemetry for Node.\n */\nexport function initOpenTelemetry(client: NodeClient): void {\n if (client.getOptions().debug) {\n setupOpenTelemetryLogger();\n }\n\n const provider = setupOtel(client);\n client.traceProvider = provider;\n}\n\n/** Initialize the ESM loader. */\nexport function maybeInitializeEsmLoader(): void {\n const [nodeMajor = 0, nodeMinor = 0] = process.versions.node.split('.').map(Number);\n\n // Register hook was added in v20.6.0 and v18.19.0\n if (nodeMajor >= 22 || (nodeMajor === 20 && nodeMinor >= 6) || (nodeMajor === 18 && nodeMinor >= 19)) {\n // We need to work around using import.meta.url directly because jest complains about it.\n const importMetaUrl =\n typeof __IMPORT_META_URL_REPLACEMENT__ !== 'undefined' ? __IMPORT_META_URL_REPLACEMENT__ : undefined;\n\n if (!GLOBAL_OBJ._sentryEsmLoaderHookRegistered && importMetaUrl) {\n try {\n // @ts-expect-error register is available in these versions\n moduleModule.register('@opentelemetry/instrumentation/hook.mjs', importMetaUrl);\n GLOBAL_OBJ._sentryEsmLoaderHookRegistered = true;\n } catch (error) {\n logger.warn('Failed to register ESM hook', error);\n }\n }\n } else {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn(\n '[Sentry] You are using Node.js in ESM mode (\"import syntax\"). The Sentry Node.js SDK is not compatible with ESM in Node.js versions before 18.19.0 or before 20.6.0. Please either build your application with CommonJS (\"require() syntax\"), or use version 7.x of the Sentry Node.js SDK.',\n );\n });\n }\n}\n\ninterface NodePreloadOptions {\n debug?: boolean;\n integrations?: string[];\n}\n\n/**\n * Preload OpenTelemetry for Node.\n * This can be used to preload instrumentation early, but set up Sentry later.\n * By preloading the OTEL instrumentation wrapping still happens early enough that everything works.\n */\nexport function preloadOpenTelemetry(options: NodePreloadOptions = {}): void {\n const { debug } = options;\n\n if (debug) {\n logger.enable();\n setupOpenTelemetryLogger();\n }\n\n if (!isCjs()) {\n maybeInitializeEsmLoader();\n }\n\n // These are all integrations that we need to pre-load to ensure they are set up before any other code runs\n getPreloadMethods(options.integrations).forEach(fn => {\n fn();\n\n if (debug) {\n logger.log(`[Sentry] Preloaded ${fn.id} instrumentation`);\n }\n });\n}\n\nfunction getPreloadMethods(integrationNames?: string[]): ((() => void) & { id: string })[] {\n const instruments = getOpenTelemetryInstrumentationToPreload();\n\n if (!integrationNames) {\n return instruments;\n }\n\n return instruments.filter(instrumentation => integrationNames.includes(instrumentation.id));\n}\n\n/** Just exported for tests. */\nexport function setupOtel(client: NodeClient): BasicTracerProvider {\n // Create and configure NodeTracerProvider\n const provider = new BasicTracerProvider({\n sampler: new SentrySampler(client),\n resource: new Resource({\n [SEMRESATTRS_SERVICE_NAME]: 'node',\n [SEMRESATTRS_SERVICE_NAMESPACE]: 'sentry',\n [SEMRESATTRS_SERVICE_VERSION]: SDK_VERSION,\n }),\n forceFlushTimeoutMillis: 500,\n });\n provider.addSpanProcessor(new SentrySpanProcessor());\n\n // Initialize the provider\n provider.register({\n propagator: new SentryPropagator(),\n contextManager: new SentryContextManager(),\n });\n\n return provider;\n}\n\n/**\n * Setup the OTEL logger to use our own logger.\n */\nfunction setupOpenTelemetryLogger(): void {\n const otelLogger = new Proxy(logger as typeof logger & { verbose: (typeof logger)['debug'] }, {\n get(target, prop, receiver) {\n const actualProp = prop === 'verbose' ? 'debug' : prop;\n return Reflect.get(target, actualProp, receiver);\n },\n });\n\n // Disable diag, to ensure this works even if called multiple times\n diag.disable();\n diag.setLogger(otelLogger, DiagLogLevel.DEBUG);\n}\n"],"names":["GLOBAL_OBJ","moduleModule","logger","consoleSandbox","isCjs","getOpenTelemetryInstrumentationToPreload","BasicTracerProvider","SentrySampler","Resource","SEMRESATTRS_SERVICE_NAME","SEMRESATTRS_SERVICE_NAMESPACE","SEMRESATTRS_SERVICE_VERSION","SDK_VERSION","SentrySpanProcessor","SentryPropagator","SentryContextManager","diag","DiagLogLevel"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"initOtel.js","sources":["../../../src/sdk/initOtel.ts"],"sourcesContent":["import moduleModule from 'module';\nimport { DiagLogLevel, diag } from '@opentelemetry/api';\nimport { Resource } from '@opentelemetry/resources';\nimport { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';\nimport {\n SEMRESATTRS_SERVICE_NAME,\n SEMRESATTRS_SERVICE_NAMESPACE,\n SEMRESATTRS_SERVICE_VERSION,\n} from '@opentelemetry/semantic-conventions';\nimport { SDK_VERSION } from '@sentry/core';\nimport { SentryPropagator, SentrySampler, SentrySpanProcessor } from '@sentry/opentelemetry';\nimport { GLOBAL_OBJ, consoleSandbox, logger } from '@sentry/utils';\n\nimport { getOpenTelemetryInstrumentationToPreload } from '../integrations/tracing';\nimport { SentryContextManager } from '../otel/contextManager';\nimport { isCjs } from '../utils/commonjs';\nimport type { NodeClient } from './client';\n\ndeclare const __IMPORT_META_URL_REPLACEMENT__: string;\n\n/**\n * Initialize OpenTelemetry for Node.\n */\nexport function initOpenTelemetry(client: NodeClient): void {\n if (client.getOptions().debug) {\n setupOpenTelemetryLogger();\n }\n\n const provider = setupOtel(client);\n client.traceProvider = provider;\n}\n\n/** Initialize the ESM loader. */\nexport function maybeInitializeEsmLoader(): void {\n const [nodeMajor = 0, nodeMinor = 0] = process.versions.node.split('.').map(Number);\n\n // Register hook was added in v20.6.0 and v18.19.0\n if (nodeMajor >= 22 || (nodeMajor === 20 && nodeMinor >= 6) || (nodeMajor === 18 && nodeMinor >= 19)) {\n // We need to work around using import.meta.url directly because jest complains about it.\n const importMetaUrl =\n typeof __IMPORT_META_URL_REPLACEMENT__ !== 'undefined' ? __IMPORT_META_URL_REPLACEMENT__ : undefined;\n\n if (!GLOBAL_OBJ._sentryEsmLoaderHookRegistered && importMetaUrl) {\n try {\n // @ts-expect-error register is available in these versions\n moduleModule.register('@opentelemetry/instrumentation/hook.mjs', importMetaUrl);\n GLOBAL_OBJ._sentryEsmLoaderHookRegistered = true;\n } catch (error) {\n logger.warn('Failed to register ESM hook', error);\n }\n }\n } else {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn(\n '[Sentry] You are using Node.js in ESM mode (\"import syntax\"). The Sentry Node.js SDK is not compatible with ESM in Node.js versions before 18.19.0 or before 20.6.0. Please either build your application with CommonJS (\"require() syntax\"), or use version 7.x of the Sentry Node.js SDK.',\n );\n });\n }\n}\n\ninterface NodePreloadOptions {\n debug?: boolean;\n integrations?: string[];\n}\n\n/**\n * Preload OpenTelemetry for Node.\n * This can be used to preload instrumentation early, but set up Sentry later.\n * By preloading the OTEL instrumentation wrapping still happens early enough that everything works.\n */\nexport function preloadOpenTelemetry(options: NodePreloadOptions = {}): void {\n const { debug } = options;\n\n if (debug) {\n logger.enable();\n setupOpenTelemetryLogger();\n }\n\n if (!isCjs()) {\n maybeInitializeEsmLoader();\n }\n\n // These are all integrations that we need to pre-load to ensure they are set up before any other code runs\n getPreloadMethods(options.integrations).forEach(fn => {\n fn();\n\n if (debug) {\n logger.log(`[Sentry] Preloaded ${fn.id} instrumentation`);\n }\n });\n}\n\nfunction getPreloadMethods(integrationNames?: string[]): ((() => void) & { id: string })[] {\n const instruments = getOpenTelemetryInstrumentationToPreload();\n\n if (!integrationNames) {\n return instruments;\n }\n\n return instruments.filter(instrumentation => integrationNames.includes(instrumentation.id));\n}\n\n/** Just exported for tests. */\nexport function setupOtel(client: NodeClient): BasicTracerProvider {\n // Create and configure NodeTracerProvider\n const provider = new BasicTracerProvider({\n sampler: new SentrySampler(client),\n resource: new Resource({\n [SEMRESATTRS_SERVICE_NAME]: 'node',\n [SEMRESATTRS_SERVICE_NAMESPACE]: 'sentry',\n [SEMRESATTRS_SERVICE_VERSION]: SDK_VERSION,\n }),\n forceFlushTimeoutMillis: 500,\n });\n provider.addSpanProcessor(\n new SentrySpanProcessor({\n timeout: client.getOptions().maxSpanWaitDuration,\n }),\n );\n\n // Initialize the provider\n provider.register({\n propagator: new SentryPropagator(),\n contextManager: new SentryContextManager(),\n });\n\n return provider;\n}\n\n/**\n * Setup the OTEL logger to use our own logger.\n */\nfunction setupOpenTelemetryLogger(): void {\n const otelLogger = new Proxy(logger as typeof logger & { verbose: (typeof logger)['debug'] }, {\n get(target, prop, receiver) {\n const actualProp = prop === 'verbose' ? 'debug' : prop;\n return Reflect.get(target, actualProp, receiver);\n },\n });\n\n // Disable diag, to ensure this works even if called multiple times\n diag.disable();\n diag.setLogger(otelLogger, DiagLogLevel.DEBUG);\n}\n"],"names":["GLOBAL_OBJ","moduleModule","logger","consoleSandbox","isCjs","getOpenTelemetryInstrumentationToPreload","BasicTracerProvider","SentrySampler","Resource","SEMRESATTRS_SERVICE_NAME","SEMRESATTRS_SERVICE_NAMESPACE","SEMRESATTRS_SERVICE_VERSION","SDK_VERSION","SentrySpanProcessor","SentryPropagator","SentryContextManager","diag","DiagLogLevel"],"mappings":"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"}
|