@sentry/node 7.107.0 → 7.108.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/cron/cron.js +2 -2
- package/cjs/cron/cron.js.map +1 -1
- package/cjs/integrations/anr/index.js +50 -13
- package/cjs/integrations/anr/index.js.map +1 -1
- package/cjs/integrations/anr/worker-script.js +2 -2
- package/cjs/integrations/local-variables/local-variables-sync.js +3 -3
- package/cjs/integrations/local-variables/local-variables-sync.js.map +1 -1
- package/esm/cron/cron.js +2 -2
- package/esm/cron/cron.js.map +1 -1
- package/esm/integrations/anr/index.js +50 -13
- package/esm/integrations/anr/index.js.map +1 -1
- package/esm/integrations/anr/worker-script.js +2 -2
- package/esm/integrations/local-variables/local-variables-sync.js +3 -3
- package/esm/integrations/local-variables/local-variables-sync.js.map +1 -1
- package/package.json +5 -5
- package/types/index.d.ts +0 -3
- package/types/index.d.ts.map +1 -1
- package/types/integrations/anr/index.d.ts +8 -2
- package/types/integrations/anr/index.d.ts.map +1 -1
- package/types-ts3.8/index.d.ts +0 -3
- package/types-ts3.8/integrations/anr/index.d.ts +8 -2
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! @sentry/node 7.
|
|
2
|
-
export const base64WorkerScript="aW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJ2luc3BlY3Rvcic7CmltcG9ydCB7IHdvcmtlckRhdGEsIHBhcmVudFBvcnQgfSBmcm9tICd3b3JrZXJfdGhyZWFkcyc7CmltcG9ydCB7IHBvc2l4LCBzZXAgfSBmcm9tICdwYXRoJzsKaW1wb3J0ICogYXMgaHR0cCBmcm9tICdodHRwJzsKaW1wb3J0ICogYXMgaHR0cHMgZnJvbSAnaHR0cHMnOwppbXBvcnQgeyBSZWFkYWJsZSB9IGZyb20gJ3N0cmVhbSc7CmltcG9ydCB7IFVSTCB9IGZyb20gJ3VybCc7CmltcG9ydCB7IGNyZWF0ZUd6aXAgfSBmcm9tICd6bGliJzsKaW1wb3J0ICogYXMgbmV0IGZyb20gJ25ldCc7CmltcG9ydCAqIGFzIHRscyBmcm9tICd0bHMnOwoKLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC91bmJvdW5kLW1ldGhvZApjb25zdCBvYmplY3RUb1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUncyB0eXBlIGlzIG9uZSBvZiBhIGZldyBFcnJvciBvciBFcnJvci1saWtlCiAqIHtAbGluayBpc0Vycm9yfS4KICoKICogQHBhcmFtIHdhdCBBIHZhbHVlIHRvIGJlIGNoZWNrZWQuCiAqIEByZXR1cm5zIEEgYm9vbGVhbiByZXByZXNlbnRpbmcgdGhlIHJlc3VsdC4KICovCmZ1bmN0aW9uIGlzRXJyb3Iod2F0KSB7CiAgc3dpdGNoIChvYmplY3RUb1N0cmluZy5jYWxsKHdhdCkpIHsKICAgIGNhc2UgJ1tvYmplY3QgRXJyb3JdJzoKICAgIGNhc2UgJ1tvYmplY3QgRXhjZXB0aW9uXSc6CiAgICBjYXNlICdbb2JqZWN0IERPTUV4Y2VwdGlvbl0nOgogICAgICByZXR1cm4gdHJ1ZTsKICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiBpc0luc3RhbmNlT2Yod2F0LCBFcnJvcik7CiAgfQp9Ci8qKgogKiBDaGVja3Mgd2hldGhlciBnaXZlbiB2YWx1ZSBpcyBhbiBpbnN0YW5jZSBvZiB0aGUgZ2l2ZW4gYnVpbHQtaW4gY2xhc3MuCiAqCiAqIEBwYXJhbSB3YXQgVGhlIHZhbHVlIHRvIGJlIGNoZWNrZWQKICogQHBhcmFtIGNsYXNzTmFtZQogKiBAcmV0dXJucyBBIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSByZXN1bHQuCiAqLwpmdW5jdGlvbiBpc0J1aWx0aW4od2F0LCBjbGFzc05hbWUpIHsKICByZXR1cm4gb2JqZWN0VG9TdHJpbmcuY2FsbCh3YXQpID09PSBgW29iamVjdCAke2NsYXNzTmFtZX1dYDsKfQoKLyoqCiAqIENoZWNrcyB3aGV0aGVyIGdpdmVuIHZhbHVlJ3MgdHlwZSBpcyBhIHN0cmluZwogKiB7QGxpbmsgaXNTdHJpbmd9LgogKgogKiBAcGFyYW0gd2F0IEEgdmFsdWUgdG8gYmUgY2hlY2tlZC4KICogQHJldHVybnMgQSBib29sZWFuIHJlcHJlc2VudGluZyB0aGUgcmVzdWx0LgogKi8KZnVuY3Rpb24gaXNTdHJpbmcod2F0KSB7CiAgcmV0dXJuIGlzQnVpbHRpbih3YXQsICdTdHJpbmcnKTsKfQoKLyoqCiAqIENoZWNrcyB3aGV0aGVyIGdpdmVuIHZhbHVlJ3MgdHlwZSBpcyBhbiBvYmplY3QgbGl0ZXJhbCwgb3IgYSBjbGFzcyBpbnN0YW5jZS4KICoge0BsaW5rIGlzUGxhaW5PYmplY3R9LgogKgogKiBAcGFyYW0gd2F0IEEgdmFsdWUgdG8gYmUgY2hlY2tlZC4KICogQHJldHVybnMgQSBib29sZWFuIHJlcHJlc2VudGluZyB0aGUgcmVzdWx0LgogKi8KZnVuY3Rpb24gaXNQbGFpbk9iamVjdCh3YXQpIHsKICByZXR1cm4gaXNCdWlsdGluKHdhdCwgJ09iamVjdCcpOwp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUncyB0eXBlIGlzIGFuIEV2ZW50IGluc3RhbmNlCiAqIHtAbGluayBpc0V2ZW50fS4KICoKICogQHBhcmFtIHdhdCBBIHZhbHVlIHRvIGJlIGNoZWNrZWQuCiAqIEByZXR1cm5zIEEgYm9vbGVhbiByZXByZXNlbnRpbmcgdGhlIHJlc3VsdC4KICovCmZ1bmN0aW9uIGlzRXZlbnQod2F0KSB7CiAgcmV0dXJuIHR5cGVvZiBFdmVudCAhPT0gJ3VuZGVmaW5lZCcgJiYgaXNJbnN0YW5jZU9mKHdhdCwgRXZlbnQpOwp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUncyB0eXBlIGlzIGFuIEVsZW1lbnQgaW5zdGFuY2UKICoge0BsaW5rIGlzRWxlbWVudH0uCiAqCiAqIEBwYXJhbSB3YXQgQSB2YWx1ZSB0byBiZSBjaGVja2VkLgogKiBAcmV0dXJucyBBIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSByZXN1bHQuCiAqLwpmdW5jdGlvbiBpc0VsZW1lbnQod2F0KSB7CiAgcmV0dXJuIHR5cGVvZiBFbGVtZW50ICE9PSAndW5kZWZpbmVkJyAmJiBpc0luc3RhbmNlT2Yod2F0LCBFbGVtZW50KTsKfQoKLyoqCiAqIENoZWNrcyB3aGV0aGVyIGdpdmVuIHZhbHVlIGhhcyBhIHRoZW4gZnVuY3Rpb24uCiAqIEBwYXJhbSB3YXQgQSB2YWx1ZSB0byBiZSBjaGVja2VkLgogKi8KZnVuY3Rpb24gaXNUaGVuYWJsZSh3YXQpIHsKICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1tZW1iZXItYWNjZXNzCiAgcmV0dXJuIEJvb2xlYW4od2F0ICYmIHdhdC50aGVuICYmIHR5cGVvZiB3YXQudGhlbiA9PT0gJ2Z1bmN0aW9uJyk7Cn0KCi8qKgogKiBDaGVja3Mgd2hldGhlciBnaXZlbiB2YWx1ZSdzIHR5cGUgaXMgYSBTeW50aGV0aWNFdmVudAogKiB7QGxpbmsgaXNTeW50aGV0aWNFdmVudH0uCiAqCiAqIEBwYXJhbSB3YXQgQSB2YWx1ZSB0byBiZSBjaGVja2VkLgogKiBAcmV0dXJucyBBIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSByZXN1bHQuCiAqLwpmdW5jdGlvbiBpc1N5bnRoZXRpY0V2ZW50KHdhdCkgewogIHJldHVybiBpc1BsYWluT2JqZWN0KHdhdCkgJiYgJ25hdGl2ZUV2ZW50JyBpbiB3YXQgJiYgJ3ByZXZlbnREZWZhdWx0JyBpbiB3YXQgJiYgJ3N0b3BQcm9wYWdhdGlvbicgaW4gd2F0Owp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUgaXMgTmFOCiAqIHtAbGluayBpc05hTn0uCiAqCiAqIEBwYXJhbSB3YXQgQSB2YWx1ZSB0byBiZSBjaGVja2VkLgogKiBAcmV0dXJucyBBIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSByZXN1bHQuCiAqLwpmdW5jdGlvbiBpc05hTiQxKHdhdCkgewogIHJldHVybiB0eXBlb2Ygd2F0ID09PSAnbnVtYmVyJyAmJiB3YXQgIT09IHdhdDsKfQoKLyoqCiAqIENoZWNrcyB3aGV0aGVyIGdpdmVuIHZhbHVlJ3MgdHlwZSBpcyBhbiBpbnN0YW5jZSBvZiBwcm92aWRlZCBjb25zdHJ1Y3Rvci4KICoge0BsaW5rIGlzSW5zdGFuY2VPZn0uCiAqCiAqIEBwYXJhbSB3YXQgQSB2YWx1ZSB0byBiZSBjaGVja2VkLgogKiBAcGFyYW0gYmFzZSBBIGNvbnN0cnVjdG9yIHRvIGJlIHVzZWQgaW4gYSBjaGVjay4KICogQHJldHVybnMgQSBib29sZWFuIHJlcHJlc2VudGluZyB0aGUgcmVzdWx0LgogKi8KZnVuY3Rpb24gaXNJbnN0YW5jZU9mKHdhdCwgYmFzZSkgewogIHRyeSB7CiAgICByZXR1cm4gd2F0IGluc3RhbmNlb2YgYmFzZTsKICB9IGNhdGNoIChfZSkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KfQoKLyoqCiAqIENoZWNrcyB3aGV0aGVyIGdpdmVuIHZhbHVlJ3MgdHlwZSBpcyBhIFZ1ZSBWaWV3TW9kZWwuCiAqCiAqIEBwYXJhbSB3YXQgQSB2YWx1ZSB0byBiZSBjaGVja2VkLgogKiBAcmV0dXJucyBBIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSByZXN1bHQuCiAqLwpmdW5jdGlvbiBpc1Z1ZVZpZXdNb2RlbCh3YXQpIHsKICAvLyBOb3QgdXNpbmcgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZyBiZWNhdXNlIGluIFZ1ZSAzIGl0IHdvdWxkIHJlYWQgdGhlIGluc3RhbmNlJ3MgU3ltYm9sKFN5bWJvbC50b1N0cmluZ1RhZykgcHJvcGVydHkuCiAgcmV0dXJuICEhKHR5cGVvZiB3YXQgPT09ICdvYmplY3QnICYmIHdhdCAhPT0gbnVsbCAmJiAoKHdhdCApLl9faXNWdWUgfHwgKHdhdCApLl9pc1Z1ZSkpOwp9CgovKiogSW50ZXJuYWwgZ2xvYmFsIHdpdGggY29tbW9uIHByb3BlcnRpZXMgYW5kIFNlbnRyeSBleHRlbnNpb25zICAqLwoKLy8gVGhlIGNvZGUgYmVsb3cgZm9yICdpc0dsb2JhbE9iaicgYW5kICdHTE9CQUxfT0JKJyB3YXMgY29waWVkIGZyb20gY29yZS1qcyBiZWZvcmUgbW9kaWZpY2F0aW9uCi8vIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2Jsb2IvMWI5NDRkZjU1MjgyY2RjOTljOTBkYjVmNDllYjBiNmVkYTJjYzBhMy9wYWNrYWdlcy9jb3JlLWpzL2ludGVybmFscy9nbG9iYWwuanMKLy8gY29yZS1qcyBoYXMgdGhlIGZvbGxvd2luZyBsaWNlbmNlOgovLwovLyBDb3B5cmlnaHQgKGMpIDIwMTQtMjAyMiBEZW5pcyBQdXNoa2FyZXYKLy8KLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weQovLyBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwgdG8gZGVhbAovLyBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzCi8vIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwKLy8gY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzCi8vIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6Ci8vCi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluCi8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgovLwovLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgovLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCi8vIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKLy8gT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTgovLyBUSEUgU09GVFdBUkUuCgovKiogUmV0dXJucyAnb2JqJyBpZiBpdCdzIHRoZSBnbG9iYWwgb2JqZWN0LCBvdGhlcndpc2UgcmV0dXJucyB1bmRlZmluZWQgKi8KZnVuY3Rpb24gaXNHbG9iYWxPYmoob2JqKSB7CiAgcmV0dXJuIG9iaiAmJiBvYmouTWF0aCA9PSBNYXRoID8gb2JqIDogdW5kZWZpbmVkOwp9CgovKiogR2V0J3MgdGhlIGdsb2JhbCBvYmplY3QgZm9yIHRoZSBjdXJyZW50IEphdmFTY3JpcHQgcnVudGltZSAqLwpjb25zdCBHTE9CQUxfT0JKID0KICAodHlwZW9mIGdsb2JhbFRoaXMgPT0gJ29iamVjdCcgJiYgaXNHbG9iYWxPYmooZ2xvYmFsVGhpcykpIHx8CiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlc3RyaWN0ZWQtZ2xvYmFscwogICh0eXBlb2Ygd2luZG93ID09ICdvYmplY3QnICYmIGlzR2xvYmFsT2JqKHdpbmRvdykpIHx8CiAgKHR5cGVvZiBzZWxmID09ICdvYmplY3QnICYmIGlzR2xvYmFsT2JqKHNlbGYpKSB8fAogICh0eXBlb2YgZ2xvYmFsID09ICdvYmplY3QnICYmIGlzR2xvYmFsT2JqKGdsb2JhbCkpIHx8CiAgKGZ1bmN0aW9uICgpIHsKICAgIHJldHVybiB0aGlzOwogIH0pKCkgfHwKICB7fTsKCi8qKgogKiBAZGVwcmVjYXRlZCBVc2UgR0xPQkFMX09CSiBpbnN0ZWFkIG9yIFdJTkRPVyBmcm9tIEBzZW50cnkvYnJvd3Nlci4gVGhpcyB3aWxsIGJlIHJlbW92ZWQgaW4gdjgKICovCmZ1bmN0aW9uIGdldEdsb2JhbE9iamVjdCgpIHsKICByZXR1cm4gR0xPQkFMX09CSiA7Cn0KCi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgpjb25zdCBXSU5ET1cgPSBnZXRHbG9iYWxPYmplY3QoKTsKCmNvbnN0IERFRkFVTFRfTUFYX1NUUklOR19MRU5HVEggPSA4MDsKCi8qKgogKiBHaXZlbiBhIGNoaWxkIERPTSBlbGVtZW50LCByZXR1cm5zIGEgcXVlcnktc2VsZWN0b3Igc3RhdGVtZW50IGRlc2NyaWJpbmcgdGhhdAogKiBhbmQgaXRzIGFuY2VzdG9ycwogKiBlLmcuIFtIVE1MRWxlbWVudF0gPT4gYm9keSA+IGRpdiA+IGlucHV0I2Zvby5idG5bbmFtZT1iYXpdCiAqIEByZXR1cm5zIGdlbmVyYXRlZCBET00gcGF0aAogKi8KZnVuY3Rpb24gaHRtbFRyZWVBc1N0cmluZygKICBlbGVtLAogIG9wdGlvbnMgPSB7fSwKKSB7CiAgaWYgKCFlbGVtKSB7CiAgICByZXR1cm4gJzx1bmtub3duPic7CiAgfQoKICAvLyB0cnkvY2F0Y2ggYm90aDoKICAvLyAtIGFjY2Vzc2luZyBldmVudC50YXJnZXQgKHNlZSBnZXRzZW50cnkvcmF2ZW4tanMjODM4LCAjNzY4KQogIC8vIC0gYGh0bWxUcmVlQXNTdHJpbmdgIGJlY2F1c2UgaXQncyBjb21wbGV4LCBhbmQganVzdCBhY2Nlc3NpbmcgdGhlIERPTSBpbmNvcnJlY3RseQogIC8vIC0gY2FuIHRocm93IGFuIGV4Y2VwdGlvbiBpbiBzb21lIGNpcmN1bXN0YW5jZXMuCiAgdHJ5IHsKICAgIGxldCBjdXJyZW50RWxlbSA9IGVsZW0gOwogICAgY29uc3QgTUFYX1RSQVZFUlNFX0hFSUdIVCA9IDU7CiAgICBjb25zdCBvdXQgPSBbXTsKICAgIGxldCBoZWlnaHQgPSAwOwogICAgbGV0IGxlbiA9IDA7CiAgICBjb25zdCBzZXBhcmF0b3IgPSAnID4gJzsKICAgIGNvbnN0IHNlcExlbmd0aCA9IHNlcGFyYXRvci5sZW5ndGg7CiAgICBsZXQgbmV4dFN0cjsKICAgIGNvbnN0IGtleUF0dHJzID0gQXJyYXkuaXNBcnJheShvcHRpb25zKSA/IG9wdGlvbnMgOiBvcHRpb25zLmtleUF0dHJzOwogICAgY29uc3QgbWF4U3RyaW5nTGVuZ3RoID0gKCFBcnJheS5pc0FycmF5KG9wdGlvbnMpICYmIG9wdGlvbnMubWF4U3RyaW5nTGVuZ3RoKSB8fCBERUZBVUxUX01BWF9TVFJJTkdfTEVOR1RIOwoKICAgIHdoaWxlIChjdXJyZW50RWxlbSAmJiBoZWlnaHQrKyA8IE1BWF9UUkFWRVJTRV9IRUlHSFQpIHsKICAgICAgbmV4dFN0ciA9IF9odG1sRWxlbWVudEFzU3RyaW5nKGN1cnJlbnRFbGVtLCBrZXlBdHRycyk7CiAgICAgIC8vIGJhaWwgb3V0IGlmCiAgICAgIC8vIC0gbmV4dFN0ciBpcyB0aGUgJ2h0bWwnIGVsZW1lbnQKICAgICAgLy8gLSB0aGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgdGhhdCB3b3VsZCBiZSBjcmVhdGVkIGV4Y2VlZHMgbWF4U3RyaW5nTGVuZ3RoCiAgICAgIC8vICAgKGlnbm9yZSB0aGlzIGxpbWl0IGlmIHdlIGFyZSBvbiB0aGUgZmlyc3QgaXRlcmF0aW9uKQogICAgICBpZiAobmV4dFN0ciA9PT0gJ2h0bWwnIHx8IChoZWlnaHQgPiAxICYmIGxlbiArIG91dC5sZW5ndGggKiBzZXBMZW5ndGggKyBuZXh0U3RyLmxlbmd0aCA+PSBtYXhTdHJpbmdMZW5ndGgpKSB7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KCiAgICAgIG91dC5wdXNoKG5leHRTdHIpOwoKICAgICAgbGVuICs9IG5leHRTdHIubGVuZ3RoOwogICAgICBjdXJyZW50RWxlbSA9IGN1cnJlbnRFbGVtLnBhcmVudE5vZGU7CiAgICB9CgogICAgcmV0dXJuIG91dC5yZXZlcnNlKCkuam9pbihzZXBhcmF0b3IpOwogIH0gY2F0Y2ggKF9vTykgewogICAgcmV0dXJuICc8dW5rbm93bj4nOwogIH0KfQoKLyoqCiAqIFJldHVybnMgYSBzaW1wbGUsIHF1ZXJ5LXNlbGVjdG9yIHJlcHJlc2VudGF0aW9uIG9mIGEgRE9NIGVsZW1lbnQKICogZS5nLiBbSFRNTEVsZW1lbnRdID0+IGlucHV0I2Zvby5idG5bbmFtZT1iYXpdCiAqIEByZXR1cm5zIGdlbmVyYXRlZCBET00gcGF0aAogKi8KZnVuY3Rpb24gX2h0bWxFbGVtZW50QXNTdHJpbmcoZWwsIGtleUF0dHJzKSB7CiAgY29uc3QgZWxlbSA9IGVsCgo7CgogIGNvbnN0IG91dCA9IFtdOwogIGxldCBjbGFzc05hbWU7CiAgbGV0IGNsYXNzZXM7CiAgbGV0IGtleTsKICBsZXQgYXR0cjsKICBsZXQgaTsKCiAgaWYgKCFlbGVtIHx8ICFlbGVtLnRhZ05hbWUpIHsKICAgIHJldHVybiAnJzsKICB9CgogIC8vIEB0cy1leHBlY3QtZXJyb3IgV0lORE9XIGhhcyBIVE1MRWxlbWVudAogIGlmIChXSU5ET1cuSFRNTEVsZW1lbnQpIHsKICAgIC8vIElmIHVzaW5nIHRoZSBjb21wb25lbnQgbmFtZSBhbm5vdGF0aW9uIHBsdWdpbiwgdGhpcyB2YWx1ZSBtYXkgYmUgYXZhaWxhYmxlIG9uIHRoZSBET00gbm9kZQogICAgaWYgKGVsZW0gaW5zdGFuY2VvZiBIVE1MRWxlbWVudCAmJiBlbGVtLmRhdGFzZXQgJiYgZWxlbS5kYXRhc2V0WydzZW50cnlDb21wb25lbnQnXSkgewogICAgICByZXR1cm4gZWxlbS5kYXRhc2V0WydzZW50cnlDb21wb25lbnQnXTsKICAgIH0KICB9CgogIG91dC5wdXNoKGVsZW0udGFnTmFtZS50b0xvd2VyQ2FzZSgpKTsKCiAgLy8gUGFpcnMgb2YgYXR0cmlidXRlIGtleXMgZGVmaW5lZCBpbiBgc2VyaWFsaXplQXR0cmlidXRlYCBhbmQgdGhlaXIgdmFsdWVzIG9uIGVsZW1lbnQuCiAgY29uc3Qga2V5QXR0clBhaXJzID0KICAgIGtleUF0dHJzICYmIGtleUF0dHJzLmxlbmd0aAogICAgICA/IGtleUF0dHJzLmZpbHRlcihrZXlBdHRyID0+IGVsZW0uZ2V0QXR0cmlidXRlKGtleUF0dHIpKS5tYXAoa2V5QXR0ciA9PiBba2V5QXR0ciwgZWxlbS5nZXRBdHRyaWJ1dGUoa2V5QXR0cildKQogICAgICA6IG51bGw7CgogIGlmIChrZXlBdHRyUGFpcnMgJiYga2V5QXR0clBhaXJzLmxlbmd0aCkgewogICAga2V5QXR0clBhaXJzLmZvckVhY2goa2V5QXR0clBhaXIgPT4gewogICAgICBvdXQucHVzaChgWyR7a2V5QXR0clBhaXJbMF19PSIke2tleUF0dHJQYWlyWzFdfSJdYCk7CiAgICB9KTsKICB9IGVsc2UgewogICAgaWYgKGVsZW0uaWQpIHsKICAgICAgb3V0LnB1c2goYCMke2VsZW0uaWR9YCk7CiAgICB9CgogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1jb25zdAogICAgY2xhc3NOYW1lID0gZWxlbS5jbGFzc05hbWU7CiAgICBpZiAoY2xhc3NOYW1lICYmIGlzU3RyaW5nKGNsYXNzTmFtZSkpIHsKICAgICAgY2xhc3NlcyA9IGNsYXNzTmFtZS5zcGxpdCgvXHMrLyk7CiAgICAgIGZvciAoaSA9IDA7IGkgPCBjbGFzc2VzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgb3V0LnB1c2goYC4ke2NsYXNzZXNbaV19YCk7CiAgICAgIH0KICAgIH0KICB9CiAgY29uc3QgYWxsb3dlZEF0dHJzID0gWydhcmlhLWxhYmVsJywgJ3R5cGUnLCAnbmFtZScsICd0aXRsZScsICdhbHQnXTsKICBmb3IgKGkgPSAwOyBpIDwgYWxsb3dlZEF0dHJzLmxlbmd0aDsgaSsrKSB7CiAgICBrZXkgPSBhbGxvd2VkQXR0cnNbaV07CiAgICBhdHRyID0gZWxlbS5nZXRBdHRyaWJ1dGUoa2V5KTsKICAgIGlmIChhdHRyKSB7CiAgICAgIG91dC5wdXNoKGBbJHtrZXl9PSIke2F0dHJ9Il1gKTsKICAgIH0KICB9CiAgcmV0dXJuIG91dC5qb2luKCcnKTsKfQoKLyoqCiAqIFRoaXMgc2VydmVzIGFzIGEgYnVpbGQgdGltZSBmbGFnIHRoYXQgd2lsbCBiZSB0cnVlIGJ5IGRlZmF1bHQsIGJ1dCBmYWxzZSBpbiBub24tZGVidWcgYnVpbGRzIG9yIGlmIHVzZXJzIHJlcGxhY2UgYF9fU0VOVFJZX0RFQlVHX19gIGluIHRoZWlyIGdlbmVyYXRlZCBjb2RlLgogKgogKiBBVFRFTlRJT046IFRoaXMgY29uc3RhbnQgbXVzdCBuZXZlciBjcm9zcyBwYWNrYWdlIGJvdW5kYXJpZXMgKGkuZS4gYmUgZXhwb3J0ZWQpIHRvIGd1YXJhbnRlZSB0aGF0IGl0IGNhbiBiZSB1c2VkIGZvciB0cmVlIHNoYWtpbmcuCiAqLwpjb25zdCBERUJVR19CVUlMRCQxID0gKHR5cGVvZiBfX1NFTlRSWV9ERUJVR19fID09PSAndW5kZWZpbmVkJyB8fCBfX1NFTlRSWV9ERUJVR19fKTsKCi8qKiBQcmVmaXggZm9yIGxvZ2dpbmcgc3RyaW5ncyAqLwpjb25zdCBQUkVGSVggPSAnU2VudHJ5IExvZ2dlciAnOwoKY29uc3QgQ09OU09MRV9MRVZFTFMgPSBbCiAgJ2RlYnVnJywKICAnaW5mbycsCiAgJ3dhcm4nLAogICdlcnJvcicsCiAgJ2xvZycsCiAgJ2Fzc2VydCcsCiAgJ3RyYWNlJywKXSA7CgovKiogVGhpcyBtYXkgYmUgbXV0YXRlZCBieSB0aGUgY29uc29sZSBpbnN0cnVtZW50YXRpb24uICovCmNvbnN0IG9yaWdpbmFsQ29uc29sZU1ldGhvZHMKCiA9IHt9OwoKLyoqIEpTRG9jICovCgovKioKICogVGVtcG9yYXJpbHkgZGlzYWJsZSBzZW50cnkgY29uc29sZSBpbnN0cnVtZW50YXRpb25zLgogKgogKiBAcGFyYW0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIHRvIHJ1biBhZ2FpbnN0IHRoZSBvcmlnaW5hbCBgY29uc29sZWAgbWVzc2FnZXMKICogQHJldHVybnMgVGhlIHJlc3VsdHMgb2YgdGhlIGNhbGxiYWNrCiAqLwpmdW5jdGlvbiBjb25zb2xlU2FuZGJveChjYWxsYmFjaykgewogIGlmICghKCdjb25zb2xlJyBpbiBHTE9CQUxfT0JKKSkgewogICAgcmV0dXJuIGNhbGxiYWNrKCk7CiAgfQoKICBjb25zdCBjb25zb2xlID0gR0xPQkFMX09CSi5jb25zb2xlIDsKICBjb25zdCB3cmFwcGVkRnVuY3MgPSB7fTsKCiAgY29uc3Qgd3JhcHBlZExldmVscyA9IE9iamVjdC5rZXlzKG9yaWdpbmFsQ29uc29sZU1ldGhvZHMpIDsKCiAgLy8gUmVzdG9yZSBhbGwgd3JhcHBlZCBjb25zb2xlIG1ldGhvZHMKICB3cmFwcGVkTGV2ZWxzLmZvckVhY2gobGV2ZWwgPT4gewogICAgY29uc3Qgb3JpZ2luYWxDb25zb2xlTWV0aG9kID0gb3JpZ2luYWxDb25zb2xlTWV0aG9kc1tsZXZlbF0gOwogICAgd3JhcHBlZEZ1bmNzW2xldmVsXSA9IGNvbnNvbGVbbGV2ZWxdIDsKICAgIGNvbnNvbGVbbGV2ZWxdID0gb3JpZ2luYWxDb25zb2xlTWV0aG9kOwogIH0pOwoKICB0cnkgewogICAgcmV0dXJuIGNhbGxiYWNrKCk7CiAgfSBmaW5hbGx5IHsKICAgIC8vIFJldmVydCByZXN0b3JhdGlvbiB0byB3cmFwcGVkIHN0YXRlCiAgICB3cmFwcGVkTGV2ZWxzLmZvckVhY2gobGV2ZWwgPT4gewogICAgICBjb25zb2xlW2xldmVsXSA9IHdyYXBwZWRGdW5jc1tsZXZlbF0gOwogICAgfSk7CiAgfQp9CgpmdW5jdGlvbiBtYWtlTG9nZ2VyKCkgewogIGxldCBlbmFibGVkID0gZmFsc2U7CiAgY29uc3QgbG9nZ2VyID0gewogICAgZW5hYmxlOiAoKSA9PiB7CiAgICAgIGVuYWJsZWQgPSB0cnVlOwogICAgfSwKICAgIGRpc2FibGU6ICgpID0+IHsKICAgICAgZW5hYmxlZCA9IGZhbHNlOwogICAgfSwKICAgIGlzRW5hYmxlZDogKCkgPT4gZW5hYmxlZCwKICB9OwoKICBpZiAoREVCVUdfQlVJTEQkMSkgewogICAgQ09OU09MRV9MRVZFTFMuZm9yRWFjaChuYW1lID0+IHsKICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkKICAgICAgbG9nZ2VyW25hbWVdID0gKC4uLmFyZ3MpID0+IHsKICAgICAgICBpZiAoZW5hYmxlZCkgewogICAgICAgICAgY29uc29sZVNhbmRib3goKCkgPT4gewogICAgICAgICAgICBHTE9CQUxfT0JKLmNvbnNvbGVbbmFtZV0oYCR7UFJFRklYfVske25hbWV9XTpgLCAuLi5hcmdzKTsKICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgfTsKICAgIH0pOwogIH0gZWxzZSB7CiAgICBDT05TT0xFX0xFVkVMUy5mb3JFYWNoKG5hbWUgPT4gewogICAgICBsb2dnZXJbbmFtZV0gPSAoKSA9PiB1bmRlZmluZWQ7CiAgICB9KTsKICB9CgogIHJldHVybiBsb2dnZXIgOwp9Cgpjb25zdCBsb2dnZXIgPSBtYWtlTG9nZ2VyKCk7CgovKioKICogUmVuZGVycyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgRHNuLgogKgogKiBCeSBkZWZhdWx0LCB0aGlzIHdpbGwgcmVuZGVyIHRoZSBwdWJsaWMgcmVwcmVzZW50YXRpb24gd2l0aG91dCB0aGUgcGFzc3dvcmQKICogY29tcG9uZW50LiBUbyBnZXQgdGhlIGRlcHJlY2F0ZWQgcHJpdmF0ZSByZXByZXNlbnRhdGlvbiwgc2V0IGB3aXRoUGFzc3dvcmRgCiAqIHRvIHRydWUuCiAqCiAqIEBwYXJhbSB3aXRoUGFzc3dvcmQgV2hlbiBzZXQgdG8gdHJ1ZSwgdGhlIHBhc3N3b3JkIHdpbGwgYmUgaW5jbHVkZWQuCiAqLwpmdW5jdGlvbiBkc25Ub1N0cmluZyhkc24sIHdpdGhQYXNzd29yZCA9IGZhbHNlKSB7CiAgY29uc3QgeyBob3N0LCBwYXRoLCBwYXNzLCBwb3J0LCBwcm9qZWN0SWQsIHByb3RvY29sLCBwdWJsaWNLZXkgfSA9IGRzbjsKICByZXR1cm4gKAogICAgYCR7cHJvdG9jb2x9Oi8vJHtwdWJsaWNLZXl9JHt3aXRoUGFzc3dvcmQgJiYgcGFzcyA/IGA6JHtwYXNzfWAgOiAnJ31gICsKICAgIGBAJHtob3N0fSR7cG9ydCA/IGA6JHtwb3J0fWAgOiAnJ30vJHtwYXRoID8gYCR7cGF0aH0vYCA6IHBhdGh9JHtwcm9qZWN0SWR9YAogICk7Cn0KCi8qKiBBbiBlcnJvciBlbWl0dGVkIGJ5IFNlbnRyeSBTREtzIGFuZCByZWxhdGVkIHV0aWxpdGllcy4gKi8KY2xhc3MgU2VudHJ5RXJyb3IgZXh0ZW5kcyBFcnJvciB7CiAgLyoqIERpc3BsYXkgbmFtZSBvZiB0aGlzIGVycm9yIGluc3RhbmNlLiAqLwoKICAgY29uc3RydWN0b3IoIG1lc3NhZ2UsIGxvZ0xldmVsID0gJ3dhcm4nKSB7CiAgICBzdXBlcihtZXNzYWdlKTt0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlOwogICAgdGhpcy5uYW1lID0gbmV3LnRhcmdldC5wcm90b3R5cGUuY29uc3RydWN0b3IubmFtZTsKICAgIC8vIFRoaXMgc2V0cyB0aGUgcHJvdG90eXBlIHRvIGJlIGBFcnJvcmAsIG5vdCBgU2VudHJ5RXJyb3JgLiBJdCdzIHVuY2xlYXIgd2h5IHdlIGRvIHRoaXMsIGJ1dCBjb21tZW50aW5nIHRoaXMgbGluZQogICAgLy8gb3V0IGNhdXNlcyB2YXJpb3VzIChzZWVtaW5nbHkgdG90YWxseSB1bnJlbGF0ZWQpIHBsYXl3cmlnaHQgdGVzdHMgY29uc2lzdGVudGx5IHRpbWUgb3V0LiBGWUksIHRoaXMgbWFrZXMKICAgIC8vIGluc3RhbmNlcyBvZiBgU2VudHJ5RXJyb3JgIGZhaWwgYG9iaiBpbnN0YW5jZW9mIFNlbnRyeUVycm9yYCBjaGVja3MuCiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgbmV3LnRhcmdldC5wcm90b3R5cGUpOwogICAgdGhpcy5sb2dMZXZlbCA9IGxvZ0xldmVsOwogIH0KfQoKLyoqCiAqIEVuY29kZXMgZ2l2ZW4gb2JqZWN0IGludG8gdXJsLWZyaWVuZGx5IGZvcm1hdAogKgogKiBAcGFyYW0gb2JqZWN0IEFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIHNlcmlhbGl6YWJsZSB2YWx1ZXMKICogQHJldHVybnMgc3RyaW5nIEVuY29kZWQKICovCmZ1bmN0aW9uIHVybEVuY29kZShvYmplY3QpIHsKICByZXR1cm4gT2JqZWN0LmtleXMob2JqZWN0KQogICAgLm1hcChrZXkgPT4gYCR7ZW5jb2RlVVJJQ29tcG9uZW50KGtleSl9PSR7ZW5jb2RlVVJJQ29tcG9uZW50KG9iamVjdFtrZXldKX1gKQogICAgLmpvaW4oJyYnKTsKfQoKLyoqCiAqIFRyYW5zZm9ybXMgYW55IGBFcnJvcmAgb3IgYEV2ZW50YCBpbnRvIGEgcGxhaW4gb2JqZWN0IHdpdGggYWxsIG9mIHRoZWlyIGVudW1lcmFibGUgcHJvcGVydGllcywgYW5kIHNvbWUgb2YgdGhlaXIKICogbm9uLWVudW1lcmFibGUgcHJvcGVydGllcyBhdHRhY2hlZC4KICoKICogQHBhcmFtIHZhbHVlIEluaXRpYWwgc291cmNlIHRoYXQgd2UgaGF2ZSB0byB0cmFuc2Zvcm0gaW4gb3JkZXIgZm9yIGl0IHRvIGJlIHVzYWJsZSBieSB0aGUgc2VyaWFsaXplcgogKiBAcmV0dXJucyBBbiBFdmVudCBvciBFcnJvciB0dXJuZWQgaW50byBhbiBvYmplY3QgLSBvciB0aGUgdmFsdWUgYXJndXJtZW50IGl0c2VsZiwgd2hlbiB2YWx1ZSBpcyBuZWl0aGVyIGFuIEV2ZW50IG5vcgogKiAgYW4gRXJyb3IuCiAqLwpmdW5jdGlvbiBjb252ZXJ0VG9QbGFpbk9iamVjdCgKICB2YWx1ZSwKKQoKIHsKICBpZiAoaXNFcnJvcih2YWx1ZSkpIHsKICAgIHJldHVybiB7CiAgICAgIG1lc3NhZ2U6IHZhbHVlLm1lc3NhZ2UsCiAgICAgIG5hbWU6IHZhbHVlLm5hbWUsCiAgICAgIHN0YWNrOiB2YWx1ZS5zdGFjaywKICAgICAgLi4uZ2V0T3duUHJvcGVydGllcyh2YWx1ZSksCiAgICB9OwogIH0gZWxzZSBpZiAoaXNFdmVudCh2YWx1ZSkpIHsKICAgIGNvbnN0IG5ld09iagoKID0gewogICAgICB0eXBlOiB2YWx1ZS50eXBlLAogICAgICB0YXJnZXQ6IHNlcmlhbGl6ZUV2ZW50VGFyZ2V0KHZhbHVlLnRhcmdldCksCiAgICAgIGN1cnJlbnRUYXJnZXQ6IHNlcmlhbGl6ZUV2ZW50VGFyZ2V0KHZhbHVlLmN1cnJlbnRUYXJnZXQpLAogICAgICAuLi5nZXRPd25Qcm9wZXJ0aWVzKHZhbHVlKSwKICAgIH07CgogICAgaWYgKHR5cGVvZiBDdXN0b21FdmVudCAhPT0gJ3VuZGVmaW5lZCcgJiYgaXNJbnN0YW5jZU9mKHZhbHVlLCBDdXN0b21FdmVudCkpIHsKICAgICAgbmV3T2JqLmRldGFpbCA9IHZhbHVlLmRldGFpbDsKICAgIH0KCiAgICByZXR1cm4gbmV3T2JqOwogIH0gZWxzZSB7CiAgICByZXR1cm4gdmFsdWU7CiAgfQp9CgovKiogQ3JlYXRlcyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdGFyZ2V0IG9mIGFuIGBFdmVudGAgb2JqZWN0ICovCmZ1bmN0aW9uIHNlcmlhbGl6ZUV2ZW50VGFyZ2V0KHRhcmdldCkgewogIHRyeSB7CiAgICByZXR1cm4gaXNFbGVtZW50KHRhcmdldCkgPyBodG1sVHJlZUFzU3RyaW5nKHRhcmdldCkgOiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodGFyZ2V0KTsKICB9IGNhdGNoIChfb08pIHsKICAgIHJldHVybiAnPHVua25vd24+JzsKICB9Cn0KCi8qKiBGaWx0ZXJzIG91dCBhbGwgYnV0IGFuIG9iamVjdCdzIG93biBwcm9wZXJ0aWVzICovCmZ1bmN0aW9uIGdldE93blByb3BlcnRpZXMob2JqKSB7CiAgaWYgKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIG9iaiAhPT0gbnVsbCkgewogICAgY29uc3QgZXh0cmFjdGVkUHJvcHMgPSB7fTsKICAgIGZvciAoY29uc3QgcHJvcGVydHkgaW4gb2JqKSB7CiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wZXJ0eSkpIHsKICAgICAgICBleHRyYWN0ZWRQcm9wc1twcm9wZXJ0eV0gPSAob2JqIClbcHJvcGVydHldOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gZXh0cmFjdGVkUHJvcHM7CiAgfSBlbHNlIHsKICAgIHJldHVybiB7fTsKICB9Cn0KCi8qKgogKiBHaXZlbiBhbnkgb2JqZWN0LCByZXR1cm4gYSBuZXcgb2JqZWN0IGhhdmluZyByZW1vdmVkIGFsbCBmaWVsZHMgd2hvc2UgdmFsdWUgd2FzIGB1bmRlZmluZWRgLgogKiBXb3JrcyByZWN1cnNpdmVseSBvbiBvYmplY3RzIGFuZCBhcnJheXMuCiAqCiAqIEF0dGVudGlvbjogVGhpcyBmdW5jdGlvbiBrZWVwcyBjaXJjdWxhciByZWZlcmVuY2VzIGluIHRoZSByZXR1cm5lZCBvYmplY3QuCiAqLwpmdW5jdGlvbiBkcm9wVW5kZWZpbmVkS2V5cyhpbnB1dFZhbHVlKSB7CiAgLy8gVGhpcyBtYXAga2VlcHMgdHJhY2sgb2Ygd2hhdCBhbHJlYWR5IHZpc2l0ZWQgbm9kZXMgbWFwIHRvLgogIC8vIE91ciBTZXQgLSBiYXNlZCBtZW1vQnVpbGRlciBkb2Vzbid0IHdvcmsgaGVyZSBiZWNhdXNlIHdlIHdhbnQgdG8gdGhlIG91dHB1dCBvYmplY3QgdG8gaGF2ZSB0aGUgc2FtZSBjaXJjdWxhcgogIC8vIHJlZmVyZW5jZXMgYXMgdGhlIGlucHV0IG9iamVjdC4KICBjb25zdCBtZW1vaXphdGlvbk1hcCA9IG5ldyBNYXAoKTsKCiAgLy8gVGhpcyBmdW5jdGlvbiBqdXN0IHByb3hpZXMgYF9kcm9wVW5kZWZpbmVkS2V5c2AgdG8ga2VlcCB0aGUgYG1lbW9CdWlsZGVyYCBvdXQgb2YgdGhpcyBmdW5jdGlvbidzIEFQSQogIHJldHVybiBfZHJvcFVuZGVmaW5lZEtleXMoaW5wdXRWYWx1ZSwgbWVtb2l6YXRpb25NYXApOwp9CgpmdW5jdGlvbiBfZHJvcFVuZGVmaW5lZEtleXMoaW5wdXRWYWx1ZSwgbWVtb2l6YXRpb25NYXApIHsKICBpZiAoaXNQb2pvKGlucHV0VmFsdWUpKSB7CiAgICAvLyBJZiB0aGlzIG5vZGUgaGFzIGFscmVhZHkgYmVlbiB2aXNpdGVkIGR1ZSB0byBhIGNpcmN1bGFyIHJlZmVyZW5jZSwgcmV0dXJuIHRoZSBvYmplY3QgaXQgd2FzIG1hcHBlZCB0byBpbiB0aGUgbmV3IG9iamVjdAogICAgY29uc3QgbWVtb1ZhbCA9IG1lbW9pemF0aW9uTWFwLmdldChpbnB1dFZhbHVlKTsKICAgIGlmIChtZW1vVmFsICE9PSB1bmRlZmluZWQpIHsKICAgICAgcmV0dXJuIG1lbW9WYWwgOwogICAgfQoKICAgIGNvbnN0IHJldHVyblZhbHVlID0ge307CiAgICAvLyBTdG9yZSB0aGUgbWFwcGluZyBvZiB0aGlzIHZhbHVlIGluIGNhc2Ugd2UgdmlzaXQgaXQgYWdhaW4sIGluIGNhc2Ugb2YgY2lyY3VsYXIgZGF0YQogICAgbWVtb2l6YXRpb25NYXAuc2V0KGlucHV0VmFsdWUsIHJldHVyblZhbHVlKTsKCiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhpbnB1dFZhbHVlKSkgewogICAgICBpZiAodHlwZW9mIGlucHV0VmFsdWVba2V5XSAhPT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgICByZXR1cm5WYWx1ZVtrZXldID0gX2Ryb3BVbmRlZmluZWRLZXlzKGlucHV0VmFsdWVba2V5XSwgbWVtb2l6YXRpb25NYXApOwogICAgICB9CiAgICB9CgogICAgcmV0dXJuIHJldHVyblZhbHVlIDsKICB9CgogIGlmIChBcnJheS5pc0FycmF5KGlucHV0VmFsdWUpKSB7CiAgICAvLyBJZiB0aGlzIG5vZGUgaGFzIGFscmVhZHkgYmVlbiB2aXNpdGVkIGR1ZSB0byBhIGNpcmN1bGFyIHJlZmVyZW5jZSwgcmV0dXJuIHRoZSBhcnJheSBpdCB3YXMgbWFwcGVkIHRvIGluIHRoZSBuZXcgb2JqZWN0CiAgICBjb25zdCBtZW1vVmFsID0gbWVtb2l6YXRpb25NYXAuZ2V0KGlucHV0VmFsdWUpOwogICAgaWYgKG1lbW9WYWwgIT09IHVuZGVmaW5lZCkgewogICAgICByZXR1cm4gbWVtb1ZhbCA7CiAgICB9CgogICAgY29uc3QgcmV0dXJuVmFsdWUgPSBbXTsKICAgIC8vIFN0b3JlIHRoZSBtYXBwaW5nIG9mIHRoaXMgdmFsdWUgaW4gY2FzZSB3ZSB2aXNpdCBpdCBhZ2FpbiwgaW4gY2FzZSBvZiBjaXJjdWxhciBkYXRhCiAgICBtZW1vaXphdGlvbk1hcC5zZXQoaW5wdXRWYWx1ZSwgcmV0dXJuVmFsdWUpOwoKICAgIGlucHV0VmFsdWUuZm9yRWFjaCgoaXRlbSkgPT4gewogICAgICByZXR1cm5WYWx1ZS5wdXNoKF9kcm9wVW5kZWZpbmVkS2V5cyhpdGVtLCBtZW1vaXphdGlvbk1hcCkpOwogICAgfSk7CgogICAgcmV0dXJuIHJldHVyblZhbHVlIDsKICB9CgogIHJldHVybiBpbnB1dFZhbHVlOwp9CgpmdW5jdGlvbiBpc1Bvam8oaW5wdXQpIHsKICBpZiAoIWlzUGxhaW5PYmplY3QoaW5wdXQpKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQoKICB0cnkgewogICAgY29uc3QgbmFtZSA9IChPYmplY3QuZ2V0UHJvdG90eXBlT2YoaW5wdXQpICkuY29uc3RydWN0b3IubmFtZTsKICAgIHJldHVybiAhbmFtZSB8fCBuYW1lID09PSAnT2JqZWN0JzsKICB9IGNhdGNoIChlKSB7CiAgICByZXR1cm4gdHJ1ZTsKICB9Cn0KCi8qKgogKiBEb2VzIHRoaXMgZmlsZW5hbWUgbG9vayBsaWtlIGl0J3MgcGFydCBvZiB0aGUgYXBwIGNvZGU/CiAqLwpmdW5jdGlvbiBmaWxlbmFtZUlzSW5BcHAoZmlsZW5hbWUsIGlzTmF0aXZlID0gZmFsc2UpIHsKICBjb25zdCBpc0ludGVybmFsID0KICAgIGlzTmF0aXZlIHx8CiAgICAoZmlsZW5hbWUgJiYKICAgICAgLy8gSXQncyBub3QgaW50ZXJuYWwgaWYgaXQncyBhbiBhYnNvbHV0ZSBsaW51eCBwYXRoCiAgICAgICFmaWxlbmFtZS5zdGFydHNXaXRoKCcvJykgJiYKICAgICAgLy8gSXQncyBub3QgaW50ZXJuYWwgaWYgaXQncyBhbiBhYnNvbHV0ZSB3aW5kb3dzIHBhdGgKICAgICAgIWZpbGVuYW1lLm1hdGNoKC9eW0EtWl06LykgJiYKICAgICAgLy8gSXQncyBub3QgaW50ZXJuYWwgaWYgdGhlIHBhdGggaXMgc3RhcnRpbmcgd2l0aCBhIGRvdAogICAgICAhZmlsZW5hbWUuc3RhcnRzV2l0aCgnLicpICYmCiAgICAgIC8vIEl0J3Mgbm90IGludGVybmFsIGlmIHRoZSBmcmFtZSBoYXMgYSBwcm90b2NvbC4gSW4gbm9kZSwgdGhpcyBpcyB1c3VhbGx5IHRoZSBjYXNlIGlmIHRoZSBmaWxlIGdvdCBwcmUtcHJvY2Vzc2VkIHdpdGggYSBidW5kbGVyIGxpa2Ugd2VicGFjawogICAgICAhZmlsZW5hbWUubWF0Y2goL15bYS16QS1aXShbYS16QS1aMC05LlwtK10pKjpcL1wvLykpOyAvLyBTY2hlbWEgZnJvbTogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzM2NDE3ODIKCiAgLy8gaW5fYXBwIGlzIGFsbCB0aGF0J3Mgbm90IGFuIGludGVybmFsIE5vZGUgZnVuY3Rpb24gb3IgYSBtb2R1bGUgd2l0aGluIG5vZGVfbW9kdWxlcwogIC8vIG5vdGUgdGhhdCBpc05hdGl2ZSBhcHBlYXJzIHRvIHJldHVybiB0cnVlIGV2ZW4gZm9yIG5vZGUgY29yZSBsaWJyYXJpZXMKICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9yYXZlbi1ub2RlL2lzc3Vlcy8xNzYKCiAgcmV0dXJuICFpc0ludGVybmFsICYmIGZpbGVuYW1lICE9PSB1bmRlZmluZWQgJiYgIWZpbGVuYW1lLmluY2x1ZGVzKCdub2RlX21vZHVsZXMvJyk7Cn0KCmNvbnN0IFNUQUNLVFJBQ0VfRlJBTUVfTElNSVQgPSA1MDsKY29uc3QgU1RSSVBfRlJBTUVfUkVHRVhQID0gL2NhcHR1cmVNZXNzYWdlfGNhcHR1cmVFeGNlcHRpb24vOwoKLyoqCiAqIFJlbW92ZXMgU2VudHJ5IGZyYW1lcyBmcm9tIHRoZSB0b3AgYW5kIGJvdHRvbSBvZiB0aGUgc3RhY2sgaWYgcHJlc2VudCBhbmQgZW5mb3JjZXMgYSBsaW1pdCBvZiBtYXggbnVtYmVyIG9mIGZyYW1lcy4KICogQXNzdW1lcyBzdGFjayBpbnB1dCBpcyBvcmRlcmVkIGZyb20gdG9wIHRvIGJvdHRvbSBhbmQgcmV0dXJucyB0aGUgcmV2ZXJzZSByZXByZXNlbnRhdGlvbiBzbyBjYWxsIHNpdGUgb2YgdGhlCiAqIGZ1bmN0aW9uIHRoYXQgY2F1c2VkIHRoZSBjcmFzaCBpcyB0aGUgbGFzdCBmcmFtZSBpbiB0aGUgYXJyYXkuCiAqIEBoaWRkZW4KICovCmZ1bmN0aW9uIHN0cmlwU2VudHJ5RnJhbWVzQW5kUmV2ZXJzZShzdGFjaykgewogIGlmICghc3RhY2subGVuZ3RoKSB7CiAgICByZXR1cm4gW107CiAgfQoKICBjb25zdCBsb2NhbFN0YWNrID0gQXJyYXkuZnJvbShzdGFjayk7CgogIC8vIElmIHN0YWNrIHN0YXJ0cyB3aXRoIG9uZSBvZiBvdXIgQVBJIGNhbGxzLCByZW1vdmUgaXQgKHN0YXJ0cywgbWVhbmluZyBpdCdzIHRoZSB0b3Agb2YgdGhlIHN0YWNrIC0gYWthIGxhc3QgY2FsbCkKICBpZiAoL3NlbnRyeVdyYXBwZWQvLnRlc3QobG9jYWxTdGFja1tsb2NhbFN0YWNrLmxlbmd0aCAtIDFdLmZ1bmN0aW9uIHx8ICcnKSkgewogICAgbG9jYWxTdGFjay5wb3AoKTsKICB9CgogIC8vIFJldmVyc2luZyBpbiB0aGUgbWlkZGxlIG9mIHRoZSBwcm9jZWR1cmUgYWxsb3dzIHVzIHRvIGp1c3QgcG9wIHRoZSB2YWx1ZXMgb2ZmIHRoZSBzdGFjawogIGxvY2FsU3RhY2sucmV2ZXJzZSgpOwoKICAvLyBJZiBzdGFjayBlbmRzIHdpdGggb25lIG9mIG91ciBpbnRlcm5hbCBBUEkgY2FsbHMsIHJlbW92ZSBpdCAoZW5kcywgbWVhbmluZyBpdCdzIHRoZSBib3R0b20gb2YgdGhlIHN0YWNrIC0gYWthIHRvcC1tb3N0IGNhbGwpCiAgaWYgKFNUUklQX0ZSQU1FX1JFR0VYUC50ZXN0KGxvY2FsU3RhY2tbbG9jYWxTdGFjay5sZW5ndGggLSAxXS5mdW5jdGlvbiB8fCAnJykpIHsKICAgIGxvY2FsU3RhY2sucG9wKCk7CgogICAgLy8gV2hlbiB1c2luZyBzeW50aGV0aWMgZXZlbnRzLCB3ZSB3aWxsIGhhdmUgYSAyIGxldmVscyBkZWVwIHN0YWNrLCBhcyBgbmV3IEVycm9yKCdTZW50cnkgc3ludGhldGljRXhjZXB0aW9uJylgCiAgICAvLyBpcyBwcm9kdWNlZCB3aXRoaW4gdGhlIGh1YiBpdHNlbGYsIG1ha2luZyBpdDoKICAgIC8vCiAgICAvLyAgIFNlbnRyeS5jYXB0dXJlRXhjZXB0aW9uKCkKICAgIC8vICAgZ2V0Q3VycmVudEh1YigpLmNhcHR1cmVFeGNlcHRpb24oKQogICAgLy8KICAgIC8vIGluc3RlYWQgb2YganVzdCB0aGUgdG9wIGBTZW50cnlgIGNhbGwgaXRzZWxmLgogICAgLy8gVGhpcyBmb3JjZXMgdXMgdG8gcG9zc2libHkgc3RyaXAgYW4gYWRkaXRpb25hbCBmcmFtZSBpbiB0aGUgZXhhY3Qgc2FtZSB3YXMgYXMgYWJvdmUuCiAgICBpZiAoU1RSSVBfRlJBTUVfUkVHRVhQLnRlc3QobG9jYWxTdGFja1tsb2NhbFN0YWNrLmxlbmd0aCAtIDFdLmZ1bmN0aW9uIHx8ICcnKSkgewogICAgICBsb2NhbFN0YWNrLnBvcCgpOwogICAgfQogIH0KCiAgcmV0dXJuIGxvY2FsU3RhY2suc2xpY2UoMCwgU1RBQ0tUUkFDRV9GUkFNRV9MSU1JVCkubWFwKGZyYW1lID0+ICh7CiAgICAuLi5mcmFtZSwKICAgIGZpbGVuYW1lOiBmcmFtZS5maWxlbmFtZSB8fCBsb2NhbFN0YWNrW2xvY2FsU3RhY2subGVuZ3RoIC0gMV0uZmlsZW5hbWUsCiAgICBmdW5jdGlvbjogZnJhbWUuZnVuY3Rpb24gfHwgJz8nLAogIH0pKTsKfQoKY29uc3QgZGVmYXVsdEZ1bmN0aW9uTmFtZSA9ICc8YW5vbnltb3VzPic7CgovKioKICogU2FmZWx5IGV4dHJhY3QgZnVuY3Rpb24gbmFtZSBmcm9tIGl0c2VsZgogKi8KZnVuY3Rpb24gZ2V0RnVuY3Rpb25OYW1lKGZuKSB7CiAgdHJ5IHsKICAgIGlmICghZm4gfHwgdHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nKSB7CiAgICAgIHJldHVybiBkZWZhdWx0RnVuY3Rpb25OYW1lOwogICAgfQogICAgcmV0dXJuIGZuLm5hbWUgfHwgZGVmYXVsdEZ1bmN0aW9uTmFtZTsKICB9IGNhdGNoIChlKSB7CiAgICAvLyBKdXN0IGFjY2Vzc2luZyBjdXN0b20gcHJvcHMgaW4gc29tZSBTZWxlbml1bSBlbnZpcm9ubWVudHMKICAgIC8vIGNhbiBjYXVzZSBhICJQZXJtaXNzaW9uIGRlbmllZCIgZXhjZXB0aW9uIChzZWUgcmF2ZW4tanMjNDk1KS4KICAgIHJldHVybiBkZWZhdWx0RnVuY3Rpb25OYW1lOwogIH0KfQoKLyoqCiAqIFVVSUQ0IGdlbmVyYXRvcgogKgogKiBAcmV0dXJucyBzdHJpbmcgR2VuZXJhdGVkIFVVSUQ0LgogKi8KZnVuY3Rpb24gdXVpZDQoKSB7CiAgY29uc3QgZ2JsID0gR0xPQkFMX09CSiA7CiAgY29uc3QgY3J5cHRvID0gZ2JsLmNyeXB0byB8fCBnYmwubXNDcnlwdG87CgogIGxldCBnZXRSYW5kb21CeXRlID0gKCkgPT4gTWF0aC5yYW5kb20oKSAqIDE2OwogIHRyeSB7CiAgICBpZiAoY3J5cHRvICYmIGNyeXB0by5yYW5kb21VVUlEKSB7CiAgICAgIHJldHVybiBjcnlwdG8ucmFuZG9tVVVJRCgpLnJlcGxhY2UoLy0vZywgJycpOwogICAgfQogICAgaWYgKGNyeXB0byAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKSB7CiAgICAgIGdldFJhbmRvbUJ5dGUgPSAoKSA9PiB7CiAgICAgICAgLy8gY3J5cHRvLmdldFJhbmRvbVZhbHVlcyBtaWdodCByZXR1cm4gdW5kZWZpbmVkIGluc3RlYWQgb2YgdGhlIHR5cGVkIGFycmF5CiAgICAgICAgLy8gaW4gb2xkIENocm9taXVtIHZlcnNpb25zIChlLmcuIDIzLjAuMTIzNS4wICgxNTE0MjIpKQogICAgICAgIC8vIEhvd2V2ZXIsIGB0eXBlZEFycmF5YCBpcyBzdGlsbCBmaWxsZWQgaW4tcGxhY2UuCiAgICAgICAgLy8gQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvQ3J5cHRvL2dldFJhbmRvbVZhbHVlcyN0eXBlZGFycmF5CiAgICAgICAgY29uc3QgdHlwZWRBcnJheSA9IG5ldyBVaW50OEFycmF5KDEpOwogICAgICAgIGNyeXB0by5nZXRSYW5kb21WYWx1ZXModHlwZWRBcnJheSk7CiAgICAgICAgcmV0dXJuIHR5cGVkQXJyYXlbMF07CiAgICAgIH07CiAgICB9CiAgfSBjYXRjaCAoXykgewogICAgLy8gc29tZSBydW50aW1lcyBjYW4gY3Jhc2ggaW52b2tpbmcgY3J5cHRvCiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vZ2V0c2VudHJ5L3NlbnRyeS1qYXZhc2NyaXB0L2lzc3Vlcy84OTM1CiAgfQoKICAvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzEwNTAzNC9ob3ctdG8tY3JlYXRlLWEtZ3VpZC11dWlkLWluLWphdmFzY3JpcHQvMjExNzUyMyMyMTE3NTIzCiAgLy8gQ29uY2F0ZW5hdGluZyB0aGUgZm9sbG93aW5nIG51bWJlcnMgYXMgc3RyaW5ncyByZXN1bHRzIGluICcxMDAwMDAwMDEwMDA0MDAwODAwMDEwMDAwMDAwMDAwMCcKICByZXR1cm4gKChbMWU3XSApICsgMWUzICsgNGUzICsgOGUzICsgMWUxMSkucmVwbGFjZSgvWzAxOF0vZywgYyA9PgogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWJpdHdpc2UKICAgICgoYyApIF4gKChnZXRSYW5kb21CeXRlKCkgJiAxNSkgPj4gKChjICkgLyA0KSkpLnRvU3RyaW5nKDE2KSwKICApOwp9CgovKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLW1lbWJlci1hY2Nlc3MgKi8KLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSAqLwoKLyoqCiAqIEhlbHBlciB0byBkZWN5Y2xlIGpzb24gb2JqZWN0cwogKi8KZnVuY3Rpb24gbWVtb0J1aWxkZXIoKSB7CiAgY29uc3QgaGFzV2Vha1NldCA9IHR5cGVvZiBXZWFrU2V0ID09PSAnZnVuY3Rpb24nOwogIGNvbnN0IGlubmVyID0gaGFzV2Vha1NldCA/IG5ldyBXZWFrU2V0KCkgOiBbXTsKICBmdW5jdGlvbiBtZW1vaXplKG9iaikgewogICAgaWYgKGhhc1dlYWtTZXQpIHsKICAgICAgaWYgKGlubmVyLmhhcyhvYmopKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaW5uZXIuYWRkKG9iaik7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvcHJlZmVyLWZvci1vZgogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbm5lci5sZW5ndGg7IGkrKykgewogICAgICBjb25zdCB2YWx1ZSA9IGlubmVyW2ldOwogICAgICBpZiAodmFsdWUgPT09IG9iaikgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICB9CiAgICBpbm5lci5wdXNoKG9iaik7CiAgICByZXR1cm4gZmFsc2U7CiAgfQoKICBmdW5jdGlvbiB1bm1lbW9pemUob2JqKSB7CiAgICBpZiAoaGFzV2Vha1NldCkgewogICAgICBpbm5lci5kZWxldGUob2JqKTsKICAgIH0gZWxzZSB7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5uZXIubGVuZ3RoOyBpKyspIHsKICAgICAgICBpZiAoaW5uZXJbaV0gPT09IG9iaikgewogICAgICAgICAgaW5uZXIuc3BsaWNlKGksIDEpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBbbWVtb2l6ZSwgdW5tZW1vaXplXTsKfQoKLyoqCiAqIFJlY3Vyc2l2ZWx5IG5vcm1hbGl6ZXMgdGhlIGdpdmVuIG9iamVjdC4KICoKICogLSBDcmVhdGVzIGEgY29weSB0byBwcmV2ZW50IG9yaWdpbmFsIGlucHV0IG11dGF0aW9uCiAqIC0gU2tpcHMgbm9uLWVudW1lcmFibGUgcHJvcGVydGllcwogKiAtIFdoZW4gc3RyaW5naWZ5aW5nLCBjYWxscyBgdG9KU09OYCBpZiBpbXBsZW1lbnRlZAogKiAtIFJlbW92ZXMgY2lyY3VsYXIgcmVmZXJlbmNlcwogKiAtIFRyYW5zbGF0ZXMgbm9uLXNlcmlhbGl6YWJsZSB2YWx1ZXMgKGB1bmRlZmluZWRgL2BOYU5gL2Z1bmN0aW9ucykgdG8gc2VyaWFsaXphYmxlIGZvcm1hdAogKiAtIFRyYW5zbGF0ZXMga25vd24gZ2xvYmFsIG9iamVjdHMvY2xhc3NlcyB0byBhIHN0cmluZyByZXByZXNlbnRhdGlvbnMKICogLSBUYWtlcyBjYXJlIG9mIGBFcnJvcmAgb2JqZWN0IHNlcmlhbGl6YXRpb24KICogLSBPcHRpb25hbGx5IGxpbWl0cyBkZXB0aCBvZiBmaW5hbCBvdXRwdXQKICogLSBPcHRpb25hbGx5IGxpbWl0cyBudW1iZXIgb2YgcHJvcGVydGllcy9lbGVtZW50cyBpbmNsdWRlZCBpbiBhbnkgc2luZ2xlIG9iamVjdC9hcnJheQogKgogKiBAcGFyYW0gaW5wdXQgVGhlIG9iamVjdCB0byBiZSBub3JtYWxpemVkLgogKiBAcGFyYW0gZGVwdGggVGhlIG1heCBkZXB0aCB0byB3aGljaCB0byBub3JtYWxpemUgdGhlIG9iamVjdC4gKEFueXRoaW5nIGRlZXBlciBzdHJpbmdpZmllZCB3aG9sZS4pCiAqIEBwYXJhbSBtYXhQcm9wZXJ0aWVzIFRoZSBtYXggbnVtYmVyIG9mIGVsZW1lbnRzIG9yIHByb3BlcnRpZXMgdG8gYmUgaW5jbHVkZWQgaW4gYW55IHNpbmdsZSBhcnJheSBvcgogKiBvYmplY3QgaW4gdGhlIG5vcm1hbGxpemVkIG91dHB1dC4KICogQHJldHVybnMgQSBub3JtYWxpemVkIHZlcnNpb24gb2YgdGhlIG9iamVjdCwgb3IgYCIqKm5vbi1zZXJpYWxpemFibGUqKiJgIGlmIGFueSBlcnJvcnMgYXJlIHRocm93biBkdXJpbmcgbm9ybWFsaXphdGlvbi4KICovCi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55CmZ1bmN0aW9uIG5vcm1hbGl6ZShpbnB1dCwgZGVwdGggPSAxMDAsIG1heFByb3BlcnRpZXMgPSArSW5maW5pdHkpIHsKICB0cnkgewogICAgLy8gc2luY2Ugd2UncmUgYXQgdGhlIG91dGVybW9zdCBsZXZlbCwgd2UgZG9uJ3QgcHJvdmlkZSBhIGtleQogICAgcmV0dXJuIHZpc2l0KCcnLCBpbnB1dCwgZGVwdGgsIG1heFByb3BlcnRpZXMpOwogIH0gY2F0Y2ggKGVycikgewogICAgcmV0dXJuIHsgRVJST1I6IGAqKm5vbi1zZXJpYWxpemFibGUqKiAoJHtlcnJ9KWAgfTsKICB9Cn0KCi8qKgogKiBWaXNpdHMgYSBub2RlIHRvIHBlcmZvcm0gbm9ybWFsaXphdGlvbiBvbiBpdAogKgogKiBAcGFyYW0ga2V5IFRoZSBrZXkgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gbm9kZQogKiBAcGFyYW0gdmFsdWUgVGhlIG5vZGUgdG8gYmUgdmlzaXRlZAogKiBAcGFyYW0gZGVwdGggT3B0aW9uYWwgbnVtYmVyIGluZGljYXRpbmcgdGhlIG1heGltdW0gcmVjdXJzaW9uIGRlcHRoCiAqIEBwYXJhbSBtYXhQcm9wZXJ0aWVzIE9wdGlvbmFsIG1heGltdW0gbnVtYmVyIG9mIHByb3BlcnRpZXMvZWxlbWVudHMgaW5jbHVkZWQgaW4gYW55IHNpbmdsZSBvYmplY3QvYXJyYXkKICogQHBhcmFtIG1lbW8gT3B0aW9uYWwgTWVtbyBjbGFzcyBoYW5kbGluZyBkZWN5Y2xpbmcKICovCmZ1bmN0aW9uIHZpc2l0KAogIGtleSwKICB2YWx1ZSwKICBkZXB0aCA9ICtJbmZpbml0eSwKICBtYXhQcm9wZXJ0aWVzID0gK0luZmluaXR5LAogIG1lbW8gPSBtZW1vQnVpbGRlcigpLAopIHsKICBjb25zdCBbbWVtb2l6ZSwgdW5tZW1vaXplXSA9IG1lbW87CgogIC8vIEdldCB0aGUgc2ltcGxlIGNhc2VzIG91dCBvZiB0aGUgd2F5IGZpcnN0CiAgaWYgKAogICAgdmFsdWUgPT0gbnVsbCB8fCAvLyB0aGlzIG1hdGNoZXMgbnVsbCBhbmQgdW5kZWZpbmVkIC0+IGVxZXEgbm90IGVxZXFlcQogICAgKFsnbnVtYmVyJywgJ2Jvb2xlYW4nLCAnc3RyaW5nJ10uaW5jbHVkZXModHlwZW9mIHZhbHVlKSAmJiAhaXNOYU4kMSh2YWx1ZSkpCiAgKSB7CiAgICByZXR1cm4gdmFsdWUgOwogIH0KCiAgY29uc3Qgc3RyaW5naWZpZWQgPSBzdHJpbmdpZnlWYWx1ZShrZXksIHZhbHVlKTsKCiAgLy8gQW55dGhpbmcgd2UgY291bGQgcG90ZW50aWFsbHkgZGlnIGludG8gbW9yZSAob2JqZWN0cyBvciBhcnJheXMpIHdpbGwgaGF2ZSBjb21lIGJhY2sgYXMgYCJbb2JqZWN0IFhYWFhdImAuCiAgLy8gRXZlcnl0aGluZyBlbHNlIHdpbGwgaGF2ZSBhbHJlYWR5IGJlZW4gc2VyaWFsaXplZCwgc28gaWYgd2UgZG9uJ3Qgc2VlIHRoYXQgcGF0dGVybiwgd2UncmUgZG9uZS4KICBpZiAoIXN0cmluZ2lmaWVkLnN0YXJ0c1dpdGgoJ1tvYmplY3QgJykpIHsKICAgIHJldHVybiBzdHJpbmdpZmllZDsKICB9CgogIC8vIEZyb20gaGVyZSBvbiwgd2UgY2FuIGFzc2VydCB0aGF0IGB2YWx1ZWAgaXMgZWl0aGVyIGFuIG9iamVjdCBvciBhbiBhcnJheS4KCiAgLy8gRG8gbm90IG5vcm1hbGl6ZSBvYmplY3RzIHRoYXQgd2Uga25vdyBoYXZlIGFscmVhZHkgYmVlbiBub3JtYWxpemVkLiBBcyBhIGdlbmVyYWwgcnVsZSwgdGhlCiAgLy8gIl9fc2VudHJ5X3NraXBfbm9ybWFsaXphdGlvbl9fIiBwcm9wZXJ0eSBzaG91bGQgb25seSBiZSB1c2VkIHNwYXJpbmdseSBhbmQgb25seSBzaG91bGQgb25seSBiZSBzZXQgb24gb2JqZWN0cyB0aGF0CiAgLy8gaGF2ZSBhbHJlYWR5IGJlZW4gbm9ybWFsaXplZC4KICBpZiAoKHZhbHVlIClbJ19fc2VudHJ5X3NraXBfbm9ybWFsaXphdGlvbl9fJ10pIHsKICAgIHJldHVybiB2YWx1ZSA7CiAgfQoKICAvLyBXZSBjYW4gc2V0IGBfX3NlbnRyeV9vdmVycmlkZV9ub3JtYWxpemF0aW9uX2RlcHRoX19gIG9uIGFuIG9iamVjdCB0byBlbnN1cmUgdGhhdCBmcm9tIHRoZXJlCiAgLy8gV2Uga2VlcCBhIGNlcnRhaW4gYW1vdW50IG9mIGRlcHRoLgogIC8vIFRoaXMgc2hvdWxkIGJlIHVzZWQgc3BhcmluZ2x5LCBlLmcuIHdlIHVzZSBpdCBmb3IgdGhlIHJlZHV4IGludGVncmF0aW9uIHRvIGVuc3VyZSB3ZSBnZXQgYSBjZXJ0YWluIGFtb3VudCBvZiBzdGF0ZS4KICBjb25zdCByZW1haW5pbmdEZXB0aCA9CiAgICB0eXBlb2YgKHZhbHVlIClbJ19fc2VudHJ5X292ZXJyaWRlX25vcm1hbGl6YXRpb25fZGVwdGhfXyddID09PSAnbnVtYmVyJwogICAgICA/ICgodmFsdWUgKVsnX19zZW50cnlfb3ZlcnJpZGVfbm9ybWFsaXphdGlvbl9kZXB0aF9fJ10gKQogICAgICA6IGRlcHRoOwoKICAvLyBXZSdyZSBhbHNvIGRvbmUgaWYgd2UndmUgcmVhY2hlZCB0aGUgbWF4IGRlcHRoCiAgaWYgKHJlbWFpbmluZ0RlcHRoID09PSAwKSB7CiAgICAvLyBBdCB0aGlzIHBvaW50IHdlIGtub3cgYHNlcmlhbGl6ZWRgIGlzIGEgc3RyaW5nIG9mIHRoZSBmb3JtIGAiW29iamVjdCBYWFhYXSJgLiBDbGVhbiBpdCB1cCBzbyBpdCdzIGp1c3QgYCJbWFhYWF0iYC4KICAgIHJldHVybiBzdHJpbmdpZmllZC5yZXBsYWNlKCdvYmplY3QgJywgJycpOwogIH0KCiAgLy8gSWYgd2UndmUgYWxyZWFkeSB2aXNpdGVkIHRoaXMgYnJhbmNoLCBiYWlsIG91dCwgYXMgaXQncyBjaXJjdWxhciByZWZlcmVuY2UuIElmIG5vdCwgbm90ZSB0aGF0IHdlJ3JlIHNlZWluZyBpdCBub3cuCiAgaWYgKG1lbW9pemUodmFsdWUpKSB7CiAgICByZXR1cm4gJ1tDaXJjdWxhciB+XSc7CiAgfQoKICAvLyBJZiB0aGUgdmFsdWUgaGFzIGEgYHRvSlNPTmAgbWV0aG9kLCB3ZSBjYWxsIGl0IHRvIGV4dHJhY3QgbW9yZSBpbmZvcm1hdGlvbgogIGNvbnN0IHZhbHVlV2l0aFRvSlNPTiA9IHZhbHVlIDsKICBpZiAodmFsdWVXaXRoVG9KU09OICYmIHR5cGVvZiB2YWx1ZVdpdGhUb0pTT04udG9KU09OID09PSAnZnVuY3Rpb24nKSB7CiAgICB0cnkgewogICAgICBjb25zdCBqc29uVmFsdWUgPSB2YWx1ZVdpdGhUb0pTT04udG9KU09OKCk7CiAgICAgIC8vIFdlIG5lZWQgdG8gbm9ybWFsaXplIHRoZSByZXR1cm4gdmFsdWUgb2YgYC50b0pTT04oKWAgaW4gY2FzZSBpdCBoYXMgY2lyY3VsYXIgcmVmZXJlbmNlcwogICAgICByZXR1cm4gdmlzaXQoJycsIGpzb25WYWx1ZSwgcmVtYWluaW5nRGVwdGggLSAxLCBtYXhQcm9wZXJ0aWVzLCBtZW1vKTsKICAgIH0gY2F0Y2ggKGVycikgewogICAgICAvLyBwYXNzIChUaGUgYnVpbHQtaW4gYHRvSlNPTmAgZmFpbGVkLCBidXQgd2UgY2FuIHN0aWxsIHRyeSB0byBkbyBpdCBvdXJzZWx2ZXMpCiAgICB9CiAgfQoKICAvLyBBdCB0aGlzIHBvaW50IHdlIGtub3cgd2UgZWl0aGVyIGhhdmUgYW4gb2JqZWN0IG9yIGFuIGFycmF5LCB3ZSBoYXZlbid0IHNlZW4gaXQgYmVmb3JlLCBhbmQgd2UncmUgZ29pbmcgdG8gcmVjdXJzZQogIC8vIGJlY2F1c2Ugd2UgaGF2ZW4ndCB5ZXQgcmVhY2hlZCB0aGUgbWF4IGRlcHRoLiBDcmVhdGUgYW4gYWNjdW11bGF0b3IgdG8gaG9sZCB0aGUgcmVzdWx0cyBvZiB2aXNpdGluZyBlYWNoCiAgLy8gcHJvcGVydHkvZW50cnksIGFuZCBrZWVwIHRyYWNrIG9mIHRoZSBudW1iZXIgb2YgaXRlbXMgd2UgYWRkIHRvIGl0LgogIGNvbnN0IG5vcm1hbGl6ZWQgPSAoQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyBbXSA6IHt9KSA7CiAgbGV0IG51bUFkZGVkID0gMDsKCiAgLy8gQmVmb3JlIHdlIGJlZ2luLCBjb252ZXJ0YEVycm9yYCBhbmRgRXZlbnRgIGluc3RhbmNlcyBpbnRvIHBsYWluIG9iamVjdHMsIHNpbmNlIHNvbWUgb2YgZWFjaCBvZiB0aGVpciByZWxldmFudAogIC8vIHByb3BlcnRpZXMgYXJlIG5vbi1lbnVtZXJhYmxlIGFuZCBvdGhlcndpc2Ugd291bGQgZ2V0IG1pc3NlZC4KICBjb25zdCB2aXNpdGFibGUgPSBjb252ZXJ0VG9QbGFpbk9iamVjdCh2YWx1ZSApOwoKICBmb3IgKGNvbnN0IHZpc2l0S2V5IGluIHZpc2l0YWJsZSkgewogICAgLy8gQXZvaWQgaXRlcmF0aW5nIG92ZXIgZmllbGRzIGluIHRoZSBwcm90b3R5cGUgaWYgdGhleSd2ZSBzb21laG93IGJlZW4gZXhwb3NlZCB0byBlbnVtZXJhdGlvbi4KICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHZpc2l0YWJsZSwgdmlzaXRLZXkpKSB7CiAgICAgIGNvbnRpbnVlOwogICAgfQoKICAgIGlmIChudW1BZGRlZCA+PSBtYXhQcm9wZXJ0aWVzKSB7CiAgICAgIG5vcm1hbGl6ZWRbdmlzaXRLZXldID0gJ1tNYXhQcm9wZXJ0aWVzIH5dJzsKICAgICAgYnJlYWs7CiAgICB9CgogICAgLy8gUmVjdXJzaXZlbHkgdmlzaXQgYWxsIHRoZSBjaGlsZCBub2RlcwogICAgY29uc3QgdmlzaXRWYWx1ZSA9IHZpc2l0YWJsZVt2aXNpdEtleV07CiAgICBub3JtYWxpemVkW3Zpc2l0S2V5XSA9IHZpc2l0KHZpc2l0S2V5LCB2aXNpdFZhbHVlLCByZW1haW5pbmdEZXB0aCAtIDEsIG1heFByb3BlcnRpZXMsIG1lbW8pOwoKICAgIG51bUFkZGVkKys7CiAgfQoKICAvLyBPbmNlIHdlJ3ZlIHZpc2l0ZWQgYWxsIHRoZSBicmFuY2hlcywgcmVtb3ZlIHRoZSBwYXJlbnQgZnJvbSBtZW1vIHN0b3JhZ2UKICB1bm1lbW9pemUodmFsdWUpOwoKICAvLyBSZXR1cm4gYWNjdW11bGF0ZWQgdmFsdWVzCiAgcmV0dXJuIG5vcm1hbGl6ZWQ7Cn0KCi8qIGVzbGludC1kaXNhYmxlIGNvbXBsZXhpdHkgKi8KLyoqCiAqIFN0cmluZ2lmeSB0aGUgZ2l2ZW4gdmFsdWUuIEhhbmRsZXMgdmFyaW91cyBrbm93biBzcGVjaWFsIHZhbHVlcyBhbmQgdHlwZXMuCiAqCiAqIE5vdCBtZWFudCB0byBiZSB1c2VkIG9uIHNpbXBsZSBwcmltaXRpdmVzIHdoaWNoIGFscmVhZHkgaGF2ZSBhIHN0cmluZyByZXByZXNlbnRhdGlvbiwgYXMgaXQgd2lsbCwgZm9yIGV4YW1wbGUsIHR1cm4KICogdGhlIG51bWJlciAxMjMxIGludG8gIltPYmplY3QgTnVtYmVyXSIsIG5vciBvbiBgbnVsbGAsIGFzIGl0IHdpbGwgdGhyb3cuCiAqCiAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gc3RyaW5naWZ5CiAqIEByZXR1cm5zIEEgc3RyaW5naWZpZWQgcmVwcmVzZW50YXRpb24gb2YgdGhlIGdpdmVuIHZhbHVlCiAqLwpmdW5jdGlvbiBzdHJpbmdpZnlWYWx1ZSgKICBrZXksCiAgLy8gdGhpcyB0eXBlIGlzIGEgdGlueSBiaXQgb2YgYSBjaGVhdCwgc2luY2UgdGhpcyBmdW5jdGlvbiBkb2VzIGhhbmRsZSBOYU4gKHdoaWNoIGlzIHRlY2huaWNhbGx5IGEgbnVtYmVyKSwgYnV0IGZvcgogIC8vIG91ciBpbnRlcm5hbCB1c2UsIGl0J2xsIGRvCiAgdmFsdWUsCikgewogIHRyeSB7CiAgICBpZiAoa2V5ID09PSAnZG9tYWluJyAmJiB2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmICh2YWx1ZSApLl9ldmVudHMpIHsKICAgICAgcmV0dXJuICdbRG9tYWluXSc7CiAgICB9CgogICAgaWYgKGtleSA9PT0gJ2RvbWFpbkVtaXR0ZXInKSB7CiAgICAgIHJldHVybiAnW0RvbWFpbkVtaXR0ZXJdJzsKICAgIH0KCiAgICAvLyBJdCdzIHNhZmUgdG8gdXNlIGBnbG9iYWxgLCBgd2luZG93YCwgYW5kIGBkb2N1bWVudGAgaGVyZSBpbiB0aGlzIG1hbm5lciwgYXMgd2UgYXJlIGFzc2VydGluZyB1c2luZyBgdHlwZW9mYCBmaXJzdAogICAgLy8gd2hpY2ggd29uJ3QgdGhyb3cgaWYgdGhleSBhcmUgbm90IHByZXNlbnQuCgogICAgaWYgKHR5cGVvZiBnbG9iYWwgIT09ICd1bmRlZmluZWQnICYmIHZhbHVlID09PSBnbG9iYWwpIHsKICAgICAgcmV0dXJuICdbR2xvYmFsXSc7CiAgICB9CgogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlc3RyaWN0ZWQtZ2xvYmFscwogICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHZhbHVlID09PSB3aW5kb3cpIHsKICAgICAgcmV0dXJuICdbV2luZG93XSc7CiAgICB9CgogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlc3RyaWN0ZWQtZ2xvYmFscwogICAgaWYgKHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcgJiYgdmFsdWUgPT09IGRvY3VtZW50KSB7CiAgICAgIHJldHVybiAnW0RvY3VtZW50XSc7CiAgICB9CgogICAgaWYgKGlzVnVlVmlld01vZGVsKHZhbHVlKSkgewogICAgICByZXR1cm4gJ1tWdWVWaWV3TW9kZWxdJzsKICAgIH0KCiAgICAvLyBSZWFjdCdzIFN5bnRoZXRpY0V2ZW50IHRoaW5neQogICAgaWYgKGlzU3ludGhldGljRXZlbnQodmFsdWUpKSB7CiAgICAgIHJldHVybiAnW1N5bnRoZXRpY0V2ZW50XSc7CiAgICB9CgogICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgJiYgdmFsdWUgIT09IHZhbHVlKSB7CiAgICAgIHJldHVybiAnW05hTl0nOwogICAgfQoKICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHsKICAgICAgcmV0dXJuIGBbRnVuY3Rpb246ICR7Z2V0RnVuY3Rpb25OYW1lKHZhbHVlKX1dYDsKICAgIH0KCiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3ltYm9sJykgewogICAgICByZXR1cm4gYFske1N0cmluZyh2YWx1ZSl9XWA7CiAgICB9CgogICAgLy8gc3RyaW5naWZpZWQgQmlnSW50cyBhcmUgaW5kaXN0aW5ndWlzaGFibGUgZnJvbSByZWd1bGFyIG51bWJlcnMsIHNvIHdlIG5lZWQgdG8gbGFiZWwgdGhlbSB0byBhdm9pZCBjb25mdXNpb24KICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdiaWdpbnQnKSB7CiAgICAgIHJldHVybiBgW0JpZ0ludDogJHtTdHJpbmcodmFsdWUpfV1gOwogICAgfQoKICAgIC8vIE5vdyB0aGF0IHdlJ3ZlIGtub2NrZWQgb3V0IGFsbCB0aGUgc3BlY2lhbCBjYXNlcyBhbmQgdGhlIHByaW1pdGl2ZXMsIGFsbCB3ZSBoYXZlIGxlZnQgYXJlIG9iamVjdHMuIFNpbXBseSBjYXN0aW5nCiAgICAvLyB0aGVtIHRvIHN0cmluZ3MgbWVhbnMgdGhhdCBpbnN0YW5jZXMgb2YgY2xhc3NlcyB3aGljaCBoYXZlbid0IGRlZmluZWQgdGhlaXIgYHRvU3RyaW5nVGFnYCB3aWxsIGp1c3QgY29tZSBvdXQgYXMKICAgIC8vIGAiW29iamVjdCBPYmplY3RdImAuIElmIHdlIGluc3RlYWQgbG9vayBhdCB0aGUgY29uc3RydWN0b3IncyBuYW1lICh3aGljaCBpcyB0aGUgc2FtZSBhcyB0aGUgbmFtZSBvZiB0aGUgY2xhc3MpLAogICAgLy8gd2UgY2FuIG1ha2Ugc3VyZSB0aGF0IG9ubHkgcGxhaW4gb2JqZWN0cyBjb21lIG91dCB0aGF0IHdheS4KICAgIGNvbnN0IG9iak5hbWUgPSBnZXRDb25zdHJ1Y3Rvck5hbWUodmFsdWUpOwoKICAgIC8vIEhhbmRsZSBIVE1MIEVsZW1lbnRzCiAgICBpZiAoL15IVE1MKFx3KilFbGVtZW50JC8udGVzdChvYmpOYW1lKSkgewogICAgICByZXR1cm4gYFtIVE1MRWxlbWVudDogJHtvYmpOYW1lfV1gOwogICAgfQoKICAgIHJldHVybiBgW29iamVjdCAke29iak5hbWV9XWA7CiAgfSBjYXRjaCAoZXJyKSB7CiAgICByZXR1cm4gYCoqbm9uLXNlcmlhbGl6YWJsZSoqICgke2Vycn0pYDsKICB9Cn0KLyogZXNsaW50LWVuYWJsZSBjb21wbGV4aXR5ICovCgpmdW5jdGlvbiBnZXRDb25zdHJ1Y3Rvck5hbWUodmFsdWUpIHsKICBjb25zdCBwcm90b3R5cGUgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YodmFsdWUpOwoKICByZXR1cm4gcHJvdG90eXBlID8gcHJvdG90eXBlLmNvbnN0cnVjdG9yLm5hbWUgOiAnbnVsbCBwcm90b3R5cGUnOwp9CgovKioKICogTm9ybWFsaXplcyBVUkxzIGluIGV4Y2VwdGlvbnMgYW5kIHN0YWNrdHJhY2VzIHRvIGEgYmFzZSBwYXRoIHNvIFNlbnRyeSBjYW4gZmluZ2VycHJpbnQKICogYWNyb3NzIHBsYXRmb3JtcyBhbmQgd29ya2luZyBkaXJlY3RvcnkuCiAqCiAqIEBwYXJhbSB1cmwgVGhlIFVSTCB0byBiZSBub3JtYWxpemVkLgogKiBAcGFyYW0gYmFzZVBhdGggVGhlIGFwcGxpY2F0aW9uIGJhc2UgcGF0aC4KICogQHJldHVybnMgVGhlIG5vcm1hbGl6ZWQgVVJMLgogKi8KZnVuY3Rpb24gbm9ybWFsaXplVXJsVG9CYXNlKHVybCwgYmFzZVBhdGgpIHsKICBjb25zdCBlc2NhcGVkQmFzZSA9IGJhc2VQYXRoCiAgICAvLyBCYWNrc2xhc2ggdG8gZm9yd2FyZAogICAgLnJlcGxhY2UoL1xcL2csICcvJykKICAgIC8vIEVzY2FwZSBSZWdFeHAgc3BlY2lhbCBjaGFyYWN0ZXJzCiAgICAucmVwbGFjZSgvW3xcXHt9KClbXF1eJCsqPy5dL2csICdcXCQmJyk7CgogIGxldCBuZXdVcmwgPSB1cmw7CiAgdHJ5IHsKICAgIG5ld1VybCA9IGRlY29kZVVSSSh1cmwpOwogIH0gY2F0Y2ggKF9PbykgewogICAgLy8gU29tZXRpbWUgdGhpcyBicmVha3MKICB9CiAgcmV0dXJuICgKICAgIG5ld1VybAogICAgICAucmVwbGFjZSgvXFwvZywgJy8nKQogICAgICAucmVwbGFjZSgvd2VicGFjazpcLz8vZywgJycpIC8vIFJlbW92ZSBpbnRlcm1lZGlhdGUgYmFzZSBwYXRoCiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAc2VudHJ5LWludGVybmFsL3Nkay9uby1yZWdleHAtY29uc3RydWN0b3IKICAgICAgLnJlcGxhY2UobmV3IFJlZ0V4cChgKGZpbGU6Ly8pPy8qJHtlc2NhcGVkQmFzZX0vKmAsICdpZycpLCAnYXBwOi8vLycpCiAgKTsKfQoKLy8gU2xpZ2h0bHkgbW9kaWZpZWQgKG5vIElFOCBzdXBwb3J0LCBFUzYpIGFuZCB0cmFuc2NyaWJlZCB0byBUeXBlU2NyaXB0CgovLyBTcGxpdCBhIGZpbGVuYW1lIGludG8gW3Jvb3QsIGRpciwgYmFzZW5hbWUsIGV4dF0sIHVuaXggdmVyc2lvbgovLyAncm9vdCcgaXMganVzdCBhIHNsYXNoLCBvciBub3RoaW5nLgpjb25zdCBzcGxpdFBhdGhSZSA9IC9eKFxTKzpcXHxcLz8pKFtcc1xTXSo/KSgoPzpcLnsxLDJ9fFteL1xcXSs/fCkoXC5bXi4vXFxdKnwpKSg/OlsvXFxdKikkLzsKLyoqIEpTRG9jICovCmZ1bmN0aW9uIHNwbGl0UGF0aChmaWxlbmFtZSkgewogIC8vIFRydW5jYXRlIGZpbGVzIG5hbWVzIGdyZWF0ZXIgdGhhbiAxMDI0IGNoYXJhY3RlcnMgdG8gYXZvaWQgcmVnZXggZG9zCiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdC9wdWxsLzg3MzcjZGlzY3Vzc2lvbl9yMTI4NTcxOTE3MgogIGNvbnN0IHRydW5jYXRlZCA9IGZpbGVuYW1lLmxlbmd0aCA+IDEwMjQgPyBgPHRydW5jYXRlZD4ke2ZpbGVuYW1lLnNsaWNlKC0xMDI0KX1gIDogZmlsZW5hbWU7CiAgY29uc3QgcGFydHMgPSBzcGxpdFBhdGhSZS5leGVjKHRydW5jYXRlZCk7CiAgcmV0dXJuIHBhcnRzID8gcGFydHMuc2xpY2UoMSkgOiBbXTsKfQoKLyoqIEpTRG9jICovCmZ1bmN0aW9uIGRpcm5hbWUocGF0aCkgewogIGNvbnN0IHJlc3VsdCA9IHNwbGl0UGF0aChwYXRoKTsKICBjb25zdCByb290ID0gcmVzdWx0WzBdOwogIGxldCBkaXIgPSByZXN1bHRbMV07CgogIGlmICghcm9vdCAmJiAhZGlyKSB7CiAgICAvLyBObyBkaXJuYW1lIHdoYXRzb2V2ZXIKICAgIHJldHVybiAnLic7CiAgfQoKICBpZiAoZGlyKSB7CiAgICAvLyBJdCBoYXMgYSBkaXJuYW1lLCBzdHJpcCB0cmFpbGluZyBzbGFzaAogICAgZGlyID0gZGlyLnNsaWNlKDAsIGRpci5sZW5ndGggLSAxKTsKICB9CgogIHJldHVybiByb290ICsgZGlyOwp9CgovKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvZXhwbGljaXQtZnVuY3Rpb24tcmV0dXJuLXR5cGUgKi8KCi8qKiBTeW5jUHJvbWlzZSBpbnRlcm5hbCBzdGF0ZXMgKi8KdmFyIFN0YXRlczsgKGZ1bmN0aW9uIChTdGF0ZXMpIHsKICAvKiogUGVuZGluZyAqLwogIGNvbnN0IFBFTkRJTkcgPSAwOyBTdGF0ZXNbU3RhdGVzWyJQRU5ESU5HIl0gPSBQRU5ESU5HXSA9ICJQRU5ESU5HIjsKICAvKiogUmVzb2x2ZWQgLyBPSyAqLwogIGNvbnN0IFJFU09MVkVEID0gMTsgU3RhdGVzW1N0YXRlc1siUkVTT0xWRUQiXSA9IFJFU09MVkVEXSA9ICJSRVNPTFZFRCI7CiAgLyoqIFJlamVjdGVkIC8gRXJyb3IgKi8KICBjb25zdCBSRUpFQ1RFRCA9IDI7IFN0YXRlc1tTdGF0ZXNbIlJFSkVDVEVEIl0gPSBSRUpFQ1RFRF0gPSAiUkVKRUNURUQiOwp9KShTdGF0ZXMgfHwgKFN0YXRlcyA9IHt9KSk7CgovLyBPdmVybG9hZHMgc28gd2UgY2FuIGNhbGwgcmVzb2x2ZWRTeW5jUHJvbWlzZSB3aXRob3V0IGFyZ3VtZW50cyBhbmQgZ2VuZXJpYyBhcmd1bWVudAoKLyoqCiAqIENyZWF0ZXMgYSByZXNvbHZlZCBzeW5jIHByb21pc2UuCiAqCiAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgdG8gcmVzb2x2ZSB0aGUgcHJvbWlzZSB3aXRoCiAqIEByZXR1cm5zIHRoZSByZXNvbHZlZCBzeW5jIHByb21pc2UKICovCmZ1bmN0aW9uIHJlc29sdmVkU3luY1Byb21pc2UodmFsdWUpIHsKICByZXR1cm4gbmV3IFN5bmNQcm9taXNlKHJlc29sdmUgPT4gewogICAgcmVzb2x2ZSh2YWx1ZSk7CiAgfSk7Cn0KCi8qKgogKiBDcmVhdGVzIGEgcmVqZWN0ZWQgc3luYyBwcm9taXNlLgogKgogKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlIHRvIHJlamVjdCB0aGUgcHJvbWlzZSB3aXRoCiAqIEByZXR1cm5zIHRoZSByZWplY3RlZCBzeW5jIHByb21pc2UKICovCmZ1bmN0aW9uIHJlamVjdGVkU3luY1Byb21pc2UocmVhc29uKSB7CiAgcmV0dXJuIG5ldyBTeW5jUHJvbWlzZSgoXywgcmVqZWN0KSA9PiB7CiAgICByZWplY3QocmVhc29uKTsKICB9KTsKfQoKLyoqCiAqIFRoZW5hYmxlIGNsYXNzIHRoYXQgYmVoYXZlcyBsaWtlIGEgUHJvbWlzZSBhbmQgZm9sbG93cyBpdCdzIGludGVyZmFjZQogKiBidXQgaXMgbm90IGFzeW5jIGludGVybmFsbHkKICovCmNsYXNzIFN5bmNQcm9taXNlIHsKCiAgIGNvbnN0cnVjdG9yKAogICAgZXhlY3V0b3IsCiAgKSB7U3luY1Byb21pc2UucHJvdG90eXBlLl9faW5pdC5jYWxsKHRoaXMpO1N5bmNQcm9taXNlLnByb3RvdHlwZS5fX2luaXQyLmNhbGwodGhpcyk7U3luY1Byb21pc2UucHJvdG90eXBlLl9faW5pdDMuY2FsbCh0aGlzKTtTeW5jUHJvbWlzZS5wcm90b3R5cGUuX19pbml0NC5jYWxsKHRoaXMpOwogICAgdGhpcy5fc3RhdGUgPSBTdGF0ZXMuUEVORElORzsKICAgIHRoaXMuX2hhbmRsZXJzID0gW107CgogICAgdHJ5IHsKICAgICAgZXhlY3V0b3IodGhpcy5fcmVzb2x2ZSwgdGhpcy5fcmVqZWN0KTsKICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgdGhpcy5fcmVqZWN0KGUpOwogICAgfQogIH0KCiAgLyoqIEpTRG9jICovCiAgIHRoZW4oCiAgICBvbmZ1bGZpbGxlZCwKICAgIG9ucmVqZWN0ZWQsCiAgKSB7CiAgICByZXR1cm4gbmV3IFN5bmNQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHsKICAgICAgdGhpcy5faGFuZGxlcnMucHVzaChbCiAgICAgICAgZmFsc2UsCiAgICAgICAgcmVzdWx0ID0+IHsKICAgICAgICAgIGlmICghb25mdWxmaWxsZWQpIHsKICAgICAgICAgICAgLy8gVE9ETzogwq9cXyjjg4QpXy/CrwogICAgICAgICAgICAvLyBUT0RPOiBGSVhNRQogICAgICAgICAgICByZXNvbHZlKHJlc3VsdCApOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICByZXNvbHZlKG9uZnVsZmlsbGVkKHJlc3VsdCkpOwogICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgcmVqZWN0KGUpOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICByZWFzb24gPT4gewogICAgICAgICAgaWYgKCFvbnJlamVjdGVkKSB7CiAgICAgICAgICAgIHJlamVjdChyZWFzb24pOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICByZXNvbHZlKG9ucmVqZWN0ZWQocmVhc29uKSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICByZWplY3QoZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9LAogICAgICBdKTsKICAgICAgdGhpcy5fZXhlY3V0ZUhhbmRsZXJzKCk7CiAgICB9KTsKICB9CgogIC8qKiBKU0RvYyAqLwogICBjYXRjaCgKICAgIG9ucmVqZWN0ZWQsCiAgKSB7CiAgICByZXR1cm4gdGhpcy50aGVuKHZhbCA9PiB2YWwsIG9ucmVqZWN0ZWQpOwogIH0KCiAgLyoqIEpTRG9jICovCiAgIGZpbmFsbHkob25maW5hbGx5KSB7CiAgICByZXR1cm4gbmV3IFN5bmNQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHsKICAgICAgbGV0IHZhbDsKICAgICAgbGV0IGlzUmVqZWN0ZWQ7CgogICAgICByZXR1cm4gdGhpcy50aGVuKAogICAgICAgIHZhbHVlID0+IHsKICAgICAgICAgIGlzUmVqZWN0ZWQgPSBmYWxzZTsKICAgICAgICAgIHZhbCA9IHZhbHVlOwogICAgICAgICAgaWYgKG9uZmluYWxseSkgewogICAgICAgICAgICBvbmZpbmFsbHkoKTsKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHJlYXNvbiA9PiB7CiAgICAgICAgICBpc1JlamVjdGVkID0gdHJ1ZTsKICAgICAgICAgIHZhbCA9IHJlYXNvbjsKICAgICAgICAgIGlmIChvbmZpbmFsbHkpIHsKICAgICAgICAgICAgb25maW5hbGx5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgKS50aGVuKCgpID0+IHsKICAgICAgICBpZiAoaXNSZWplY3RlZCkgewogICAgICAgICAgcmVqZWN0KHZhbCk7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICByZXNvbHZlKHZhbCApOwogICAgICB9KTsKICAgIH0pOwogIH0KCiAgLyoqIEpTRG9jICovCiAgICBfX2luaXQoKSB7dGhpcy5fcmVzb2x2ZSA9ICh2YWx1ZSkgPT4gewogICAgdGhpcy5fc2V0UmVzdWx0KFN0YXRlcy5SRVNPTFZFRCwgdmFsdWUpOwogIH07fQoKICAvKiogSlNEb2MgKi8KICAgIF9faW5pdDIoKSB7dGhpcy5fcmVqZWN0ID0gKHJlYXNvbikgPT4gewogICAgdGhpcy5fc2V0UmVzdWx0KFN0YXRlcy5SRUpFQ1RFRCwgcmVhc29uKTsKICB9O30KCiAgLyoqIEpTRG9jICovCiAgICBfX2luaXQzKCkge3RoaXMuX3NldFJlc3VsdCA9IChzdGF0ZSwgdmFsdWUpID0+IHsKICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gU3RhdGVzLlBFTkRJTkcpIHsKICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmIChpc1RoZW5hYmxlKHZhbHVlKSkgewogICAgICB2b2lkICh2YWx1ZSApLnRoZW4odGhpcy5fcmVzb2x2ZSwgdGhpcy5fcmVqZWN0KTsKICAgICAgcmV0dXJuOwogICAgfQoKICAgIHRoaXMuX3N0YXRlID0gc3RhdGU7CiAgICB0aGlzLl92YWx1ZSA9IHZhbHVlOwoKICAgIHRoaXMuX2V4ZWN1dGVIYW5kbGVycygpOwogIH07fQoKICAvKiogSlNEb2MgKi8KICAgIF9faW5pdDQoKSB7dGhpcy5fZXhlY3V0ZUhhbmRsZXJzID0gKCkgPT4gewogICAgaWYgKHRoaXMuX3N0YXRlID09PSBTdGF0ZXMuUEVORElORykgewogICAgICByZXR1cm47CiAgICB9CgogICAgY29uc3QgY2FjaGVkSGFuZGxlcnMgPSB0aGlzLl9oYW5kbGVycy5zbGljZSgpOwogICAgdGhpcy5faGFuZGxlcnMgPSBbXTsKCiAgICBjYWNoZWRIYW5kbGVycy5mb3JFYWNoKGhhbmRsZXIgPT4gewogICAgICBpZiAoaGFuZGxlclswXSkgewogICAgICAgIHJldHVybjsKICAgICAgfQoKICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSBTdGF0ZXMuUkVTT0xWRUQpIHsKICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWZsb2F0aW5nLXByb21pc2VzCiAgICAgICAgaGFuZGxlclsxXSh0aGlzLl92YWx1ZSApOwogICAgICB9CgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFN0YXRlcy5SRUpFQ1RFRCkgewogICAgICAgIGhhbmRsZXJbMl0odGhpcy5fdmFsdWUpOwogICAgICB9CgogICAgICBoYW5kbGVyWzBdID0gdHJ1ZTsKICAgIH0pOwogIH07fQp9CgovKioKICogQ3JlYXRlcyBhbiBuZXcgUHJvbWlzZUJ1ZmZlciBvYmplY3Qgd2l0aCB0aGUgc3BlY2lmaWVkIGxpbWl0CiAqIEBwYXJhbSBsaW1pdCBtYXggbnVtYmVyIG9mIHByb21pc2VzIHRoYXQgY2FuIGJlIHN0b3JlZCBpbiB0aGUgYnVmZmVyCiAqLwpmdW5jdGlvbiBtYWtlUHJvbWlzZUJ1ZmZlcihsaW1pdCkgewogIGNvbnN0IGJ1ZmZlciA9IFtdOwoKICBmdW5jdGlvbiBpc1JlYWR5KCkgewogICAgcmV0dXJuIGxpbWl0ID09PSB1bmRlZmluZWQgfHwgYnVmZmVyLmxlbmd0aCA8IGxpbWl0OwogIH0KCiAgLyoqCiAgICogUmVtb3ZlIGEgcHJvbWlzZSBmcm9tIHRoZSBxdWV1ZS4KICAgKgogICAqIEBwYXJhbSB0YXNrIENhbiBiZSBhbnkgUHJvbWlzZUxpa2U8VD4KICAgKiBAcmV0dXJucyBSZW1vdmVkIHByb21pc2UuCiAgICovCiAgZnVuY3Rpb24gcmVtb3ZlKHRhc2spIHsKICAgIHJldHVybiBidWZmZXIuc3BsaWNlKGJ1ZmZlci5pbmRleE9mKHRhc2spLCAxKVswXTsKICB9CgogIC8qKgogICAqIEFkZCBhIHByb21pc2UgKHJlcHJlc2VudGluZyBhbiBpbi1mbGlnaHQgYWN0aW9uKSB0byB0aGUgcXVldWUsIGFuZCBzZXQgaXQgdG8gcmVtb3ZlIGl0c2VsZiBvbiBmdWxmaWxsbWVudC4KICAgKgogICAqIEBwYXJhbSB0YXNrUHJvZHVjZXIgQSBmdW5jdGlvbiBwcm9kdWNpbmcgYW55IFByb21pc2VMaWtlPFQ+OyBJbiBwcmV2aW91cyB2ZXJzaW9ucyB0aGlzIHVzZWQgdG8gYmUgYHRhc2s6CiAgICogICAgICAgIFByb21pc2VMaWtlPFQ+YCwgYnV0IHVuZGVyIHRoYXQgbW9kZWwsIFByb21pc2VzIHdlcmUgaW5zdGFudGx5IGNyZWF0ZWQgb24gdGhlIGNhbGwtc2l0ZSBhbmQgdGhlaXIgZXhlY3V0b3IKICAgKiAgICAgICAgZnVuY3Rpb25zIHRoZXJlZm9yZSByYW4gaW1tZWRpYXRlbHkuIFRodXMsIGV2ZW4gaWYgdGhlIGJ1ZmZlciB3YXMgZnVsbCwgdGhlIGFjdGlvbiBzdGlsbCBoYXBwZW5lZC4gQnkKICAgKiAgICAgICAgcmVxdWlyaW5nIHRoZSBwcm9taXNlIHRvIGJlIHdyYXBwZWQgaW4gYSBmdW5jdGlvbiwgd2UgY2FuIGRlZmVyIHByb21pc2UgY3JlYXRpb24gdW50aWwgYWZ0ZXIgdGhlIGJ1ZmZlcgogICAqICAgICAgICBsaW1pdCBjaGVjay4KICAgKiBAcmV0dXJucyBUaGUgb3JpZ2luYWwgcHJvbWlzZS4KICAgKi8KICBmdW5jdGlvbiBhZGQodGFza1Byb2R1Y2VyKSB7CiAgICBpZiAoIWlzUmVhZHkoKSkgewogICAgICByZXR1cm4gcmVqZWN0ZWRTeW5jUHJvbWlzZShuZXcgU2VudHJ5RXJyb3IoJ05vdCBhZGRpbmcgUHJvbWlzZSBiZWNhdXNlIGJ1ZmZlciBsaW1pdCB3YXMgcmVhY2hlZC4nKSk7CiAgICB9CgogICAgLy8gc3RhcnQgdGhlIHRhc2sgYW5kIGFkZCBpdHMgcHJvbWlzZSB0byB0aGUgcXVldWUKICAgIGNvbnN0IHRhc2sgPSB0YXNrUHJvZHVjZXIoKTsKICAgIGlmIChidWZmZXIuaW5kZXhPZih0YXNrKSA9PT0gLTEpIHsKICAgICAgYnVmZmVyLnB1c2godGFzayk7CiAgICB9CiAgICB2b2lkIHRhc2sKICAgICAgLnRoZW4oKCkgPT4gcmVtb3ZlKHRhc2spKQogICAgICAvLyBVc2UgYHRoZW4obnVsbCwgcmVqZWN0aW9uSGFuZGxlcilgIHJhdGhlciB0aGFuIGBjYXRjaChyZWplY3Rpb25IYW5kbGVyKWAgc28gdGhhdCB3ZSBjYW4gdXNlIGBQcm9taXNlTGlrZWAKICAgICAgLy8gcmF0aGVyIHRoYW4gYFByb21pc2VgLiBgUHJvbWlzZUxpa2VgIGRvZXNuJ3QgaGF2ZSBhIGAuY2F0Y2hgIG1ldGhvZCwgbWFraW5nIGl0cyBwb2x5ZmlsbCBzbWFsbGVyLiAoRVM1IGRpZG4ndAogICAgICAvLyBoYXZlIHByb21pc2VzLCBzbyBUUyBoYXMgdG8gcG9seWZpbGwgd2hlbiBkb3duLWNvbXBpbGluZy4pCiAgICAgIC50aGVuKG51bGwsICgpID0+CiAgICAgICAgcmVtb3ZlKHRhc2spLnRoZW4obnVsbCwgKCkgPT4gewogICAgICAgICAgLy8gV2UgaGF2ZSB0byBhZGQgYW5vdGhlciBjYXRjaCBoZXJlIGJlY2F1c2UgYHJlbW92ZSgpYCBzdGFydHMgYSBuZXcgcHJvbWlzZSBjaGFpbi4KICAgICAgICB9KSwKICAgICAgKTsKICAgIHJldHVybiB0YXNrOwogIH0KCiAgLyoqCiAgICogV2FpdCBmb3IgYWxsIHByb21pc2VzIGluIHRoZSBxdWV1ZSB0byByZXNvbHZlIG9yIGZvciB0aW1lb3V0IHRvIGV4cGlyZSwgd2hpY2hldmVyIGNvbWVzIGZpcnN0LgogICAqCiAgICogQHBhcmFtIHRpbWVvdXQgVGhlIHRpbWUsIGluIG1zLCBhZnRlciB3aGljaCB0byByZXNvbHZlIHRvIGBmYWxzZWAgaWYgdGhlIHF1ZXVlIGlzIHN0aWxsIG5vbi1lbXB0eS4gUGFzc2luZyBgMGAgKG9yCiAgICogbm90IHBhc3NpbmcgYW55dGhpbmcpIHdpbGwgbWFrZSB0aGUgcHJvbWlzZSB3YWl0IGFzIGxvbmcgYXMgaXQgdGFrZXMgZm9yIHRoZSBxdWV1ZSB0byBkcmFpbiBiZWZvcmUgcmVzb2x2aW5nIHRvCiAgICogYHRydWVgLgogICAqIEByZXR1cm5zIEEgcHJvbWlzZSB3aGljaCB3aWxsIHJlc29sdmUgdG8gYHRydWVgIGlmIHRoZSBxdWV1ZSBpcyBhbHJlYWR5IGVtcHR5IG9yIGRyYWlucyBiZWZvcmUgdGhlIHRpbWVvdXQsIGFuZAogICAqIGBmYWxzZWAgb3RoZXJ3aXNlCiAgICovCiAgZnVuY3Rpb24gZHJhaW4odGltZW91dCkgewogICAgcmV0dXJuIG5ldyBTeW5jUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7CiAgICAgIGxldCBjb3VudGVyID0gYnVmZmVyLmxlbmd0aDsKCiAgICAgIGlmICghY291bnRlcikgewogICAgICAgIHJldHVybiByZXNvbHZlKHRydWUpOwogICAgICB9CgogICAgICAvLyB3YWl0IGZvciBgdGltZW91dGAgbXMgYW5kIHRoZW4gcmVzb2x2ZSB0byBgZmFsc2VgIChpZiBub3QgY2FuY2VsbGVkIGZpcnN0KQogICAgICBjb25zdCBjYXB0dXJlZFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHsKICAgICAgICBpZiAodGltZW91dCAmJiB0aW1lb3V0ID4gMCkgewogICAgICAgICAgcmVzb2x2ZShmYWxzZSk7CiAgICAgICAgfQogICAgICB9LCB0aW1lb3V0KTsKCiAgICAgIC8vIGlmIGFsbCBwcm9taXNlcyByZXNvbHZlIGluIHRpbWUsIGNhbmNlbCB0aGUgdGltZXIgYW5kIHJlc29sdmUgdG8gYHRydWVgCiAgICAgIGJ1ZmZlci5mb3JFYWNoKGl0ZW0gPT4gewogICAgICAgIHZvaWQgcmVzb2x2ZWRTeW5jUHJvbWlzZShpdGVtKS50aGVuKCgpID0+IHsKICAgICAgICAgIGlmICghLS1jb3VudGVyKSB7CiAgICAgICAgICAgIGNsZWFyVGltZW91dChjYXB0dXJlZFNldFRpbWVvdXQpOwogICAgICAgICAgICByZXNvbHZlKHRydWUpOwogICAgICAgICAgfQogICAgICAgIH0sIHJlamVjdCk7CiAgICAgIH0pOwogICAgfSk7CiAgfQoKICByZXR1cm4gewogICAgJDogYnVmZmVyLAogICAgYWRkLAogICAgZHJhaW4sCiAgfTsKfQoKY29uc3QgT05FX1NFQ09ORF9JTl9NUyA9IDEwMDA7CgovKioKICogQSBwYXJ0aWFsIGRlZmluaXRpb24gb2YgdGhlIFtQZXJmb3JtYW5jZSBXZWIgQVBJXXtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvUGVyZm9ybWFuY2V9CiAqIGZvciBhY2Nlc3NpbmcgYSBoaWdoLXJlc29sdXRpb24gbW9ub3RvbmljIGNsb2NrLgogKi8KCi8qKgogKiBSZXR1cm5zIGEgdGltZXN0YW1wIGluIHNlY29uZHMgc2luY2UgdGhlIFVOSVggZXBvY2ggdXNpbmcgdGhlIERhdGUgQVBJLgogKgogKiBUT0RPKHY4KTogUmV0dXJuIHR5cGUgc2hvdWxkIGJlIHJvdW5kZWQuCiAqLwpmdW5jdGlvbiBkYXRlVGltZXN0YW1wSW5TZWNvbmRzKCkgewogIHJldHVybiBEYXRlLm5vdygpIC8gT05FX1NFQ09ORF9JTl9NUzsKfQoKLyoqCiAqIFJldHVybnMgYSB3cmFwcGVyIGFyb3VuZCB0aGUgbmF0aXZlIFBlcmZvcm1hbmNlIEFQSSBicm93c2VyIGltcGxlbWVudGF0aW9uLCBvciB1bmRlZmluZWQgZm9yIGJyb3dzZXJzIHRoYXQgZG8gbm90CiAqIHN1cHBvcnQgdGhlIEFQSS4KICoKICogV3JhcHBpbmcgdGhlIG5hdGl2ZSBBUEkgd29ya3MgYXJvdW5kIGRpZmZlcmVuY2VzIGluIGJlaGF2aW9yIGZyb20gZGlmZmVyZW50IGJyb3dzZXJzLgogKi8KZnVuY3Rpb24gY3JlYXRlVW5peFRpbWVzdGFtcEluU2Vjb25kc0Z1bmMoKSB7CiAgY29uc3QgeyBwZXJmb3JtYW5jZSB9ID0gR0xPQkFMX09CSiA7CiAgaWYgKCFwZXJmb3JtYW5jZSB8fCAhcGVyZm9ybWFuY2Uubm93KSB7CiAgICByZXR1cm4gZGF0ZVRpbWVzdGFtcEluU2Vjb25kczsKICB9CgogIC8vIFNvbWUgYnJvd3NlciBhbmQgZW52aXJvbm1lbnRzIGRvbid0IGhhdmUgYSB0aW1lT3JpZ2luLCBzbyB3ZSBmYWxsYmFjayB0bwogIC8vIHVzaW5nIERhdGUubm93KCkgdG8gY29tcHV0ZSB0aGUgc3RhcnRpbmcgdGltZS4KICBjb25zdCBhcHByb3hTdGFydGluZ1RpbWVPcmlnaW4gPSBEYXRlLm5vdygpIC0gcGVyZm9ybWFuY2Uubm93KCk7CiAgY29uc3QgdGltZU9yaWdpbiA9IHBlcmZvcm1hbmNlLnRpbWVPcmlnaW4gPT0gdW5kZWZpbmVkID8gYXBwcm94U3RhcnRpbmdUaW1lT3JpZ2luIDogcGVyZm9ybWFuY2UudGltZU9yaWdpbjsKCiAgLy8gcGVyZm9ybWFuY2Uubm93KCkgaXMgYSBtb25vdG9uaWMgY2xvY2ssIHdoaWNoIG1lYW5zIGl0IHN0YXJ0cyBhdCAwIHdoZW4gdGhlIHByb2Nlc3MgYmVnaW5zLiBUbyBnZXQgdGhlIGN1cnJlbnQKICAvLyB3YWxsIGNsb2NrIHRpbWUgKGFjdHVhbCBVTklYIHRpbWVzdGFtcCksIHdlIG5lZWQgdG8gYWRkIHRoZSBzdGFydGluZyB0aW1lIG9yaWdpbiBhbmQgdGhlIGN1cnJlbnQgdGltZSBlbGFwc2VkLgogIC8vCiAgLy8gVE9ETzogVGhpcyBkb2VzIG5vdCBhY2NvdW50IGZvciB0aGUgY2FzZSB3aGVyZSB0aGUgbW9ub3RvbmljIGNsb2NrIHRoYXQgcG93ZXJzIHBlcmZvcm1hbmNlLm5vdygpIGRyaWZ0cyBmcm9tIHRoZQogIC8vIHdhbGwgY2xvY2sgdGltZSwgd2hpY2ggY2F1c2VzIHRoZSByZXR1cm5lZCB0aW1lc3RhbXAgdG8gYmUgaW5hY2N1cmF0ZS4gV2Ugc2hvdWxkIGludmVzdGlnYXRlIGhvdyB0byBkZXRlY3QgYW5kCiAgLy8gY29ycmVjdCBmb3IgdGhpcy4KICAvLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9nZXRzZW50cnkvc2VudHJ5LWphdmFzY3JpcHQvaXNzdWVzLzI1OTAKICAvLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9tZG4vY29udGVudC9pc3N1ZXMvNDcxMwogIC8vIFNlZTogaHR0cHM6Ly9kZXYudG8vbm9hbXIvd2hlbi1hLW1pbGxpc2Vjb25kLWlzLW5vdC1hLW1pbGxpc2Vjb25kLTNoNgogIHJldHVybiAoKSA9PiB7CiAgICByZXR1cm4gKHRpbWVPcmlnaW4gKyBwZXJmb3JtYW5jZS5ub3coKSkgLyBPTkVfU0VDT05EX0lOX01TOwogIH07Cn0KCi8qKgogKiBSZXR1cm5zIGEgdGltZXN0YW1wIGluIHNlY29uZHMgc2luY2UgdGhlIFVOSVggZXBvY2ggdXNpbmcgZWl0aGVyIHRoZSBQZXJmb3JtYW5jZSBvciBEYXRlIEFQSXMsIGRlcGVuZGluZyBvbiB0aGUKICogYXZhaWxhYmlsaXR5IG9mIHRoZSBQZXJmb3JtYW5jZSBBUEkuCiAqCiAqIEJVRzogTm90ZSB0aGF0IGJlY2F1c2Ugb2YgaG93IGJyb3dzZXJzIGltcGxlbWVudCB0aGUgUGVyZm9ybWFuY2UgQVBJLCB0aGUgY2xvY2sgbWlnaHQgc3RvcCB3aGVuIHRoZSBjb21wdXRlciBpcwogKiBhc2xlZXAuIFRoaXMgY3JlYXRlcyBhIHNrZXcgYmV0d2VlbiBgZGF0ZVRpbWVzdGFtcEluU2Vjb25kc2AgYW5kIGB0aW1lc3RhbXBJblNlY29uZHNgLiBUaGUKICogc2tldyBjYW4gZ3JvdyB0byBhcmJpdHJhcnkgYW1vdW50cyBsaWtlIGRheXMsIHdlZWtzIG9yIG1vbnRocy4KICogU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9nZXRzZW50cnkvc2VudHJ5LWphdmFzY3JpcHQvaXNzdWVzLzI1OTAuCiAqLwpjb25zdCB0aW1lc3RhbXBJblNlY29uZHMgPSBjcmVhdGVVbml4VGltZXN0YW1wSW5TZWNvbmRzRnVuYygpOwoKLyoqCiAqIFRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHNpbmNlIHRoZSBVTklYIGVwb2NoLiBUaGlzIHZhbHVlIGlzIG9ubHkgdXNhYmxlIGluIGEgYnJvd3NlciwgYW5kIG9ubHkgd2hlbiB0aGUKICogcGVyZm9ybWFuY2UgQVBJIGlzIGF2YWlsYWJsZS4KICovCigoKSA9PiB7CiAgLy8gVW5mb3J0dW5hdGVseSBicm93c2VycyBtYXkgcmVwb3J0IGFuIGluYWNjdXJhdGUgdGltZSBvcmlnaW4gZGF0YSwgdGhyb3VnaCBlaXRoZXIgcGVyZm9ybWFuY2UudGltZU9yaWdpbiBvcgogIC8vIHBlcmZvcm1hbmNlLnRpbWluZy5uYXZpZ2F0aW9uU3RhcnQsIHdoaWNoIHJlc3VsdHMgaW4gcG9vciByZXN1bHRzIGluIHBlcmZvcm1hbmNlIGRhdGEuIFdlIG9ubHkgdHJlYXQgdGltZSBvcmlnaW4KICAvLyBkYXRhIGFzIHJlbGlhYmxlIGlmIHRoZXkgYXJlIHdpdGhpbiBhIHJlYXNvbmFibGUgdGhyZXNob2xkIG9mIHRoZSBjdXJyZW50IHRpbWUuCgogIGNvbnN0IHsgcGVyZm9ybWFuY2UgfSA9IEdMT0JBTF9PQkogOwogIGlmICghcGVyZm9ybWFuY2UgfHwgIXBlcmZvcm1hbmNlLm5vdykgewogICAgcmV0dXJuIHVuZGVmaW5lZDsKICB9CgogIGNvbnN0IHRocmVzaG9sZCA9IDM2MDAgKiAxMDAwOwogIGNvbnN0IHBlcmZvcm1hbmNlTm93ID0gcGVyZm9ybWFuY2Uubm93KCk7CiAgY29uc3QgZGF0ZU5vdyA9IERhdGUubm93KCk7CgogIC8vIGlmIHRpbWVPcmlnaW4gaXNuJ3QgYXZhaWxhYmxlIHNldCBkZWx0YSB0byB0aHJlc2hvbGQgc28gaXQgaXNuJ3QgdXNlZAogIGNvbnN0IHRpbWVPcmlnaW5EZWx0YSA9IHBlcmZvcm1hbmNlLnRpbWVPcmlnaW4KICAgID8gTWF0aC5hYnMocGVyZm9ybWFuY2UudGltZU9yaWdpbiArIHBlcmZvcm1hbmNlTm93IC0gZGF0ZU5vdykKICAgIDogdGhyZXNob2xkOwogIGNvbnN0IHRpbWVPcmlnaW5Jc1JlbGlhYmxlID0gdGltZU9yaWdpbkRlbHRhIDwgdGhyZXNob2xkOwoKICAvLyBXaGlsZSBwZXJmb3JtYW5jZS50aW1pbmcubmF2aWdhdGlvblN0YXJ0IGlzIGRlcHJlY2F0ZWQgaW4gZmF2b3Igb2YgcGVyZm9ybWFuY2UudGltZU9yaWdpbiwgcGVyZm9ybWFuY2UudGltZU9yaWdpbgogIC8vIGlzIG5vdCBhcyB3aWRlbHkgc3VwcG9ydGVkLiBOYW1lbHksIHBlcmZvcm1hbmNlLnRpbWVPcmlnaW4gaXMgdW5kZWZpbmVkIGluIFNhZmFyaSBhcyBvZiB3cml0aW5nLgogIC8vIEFsc28gYXMgb2Ygd3JpdGluZywgcGVyZm9ybWFuY2UudGltaW5nIGlzIG5vdCBhdmFpbGFibGUgaW4gV2ViIFdvcmtlcnMgaW4gbWFpbnN0cmVhbSBicm93c2Vycywgc28gaXQgaXMgbm90IGFsd2F5cwogIC8vIGEgdmFsaWQgZmFsbGJhY2suIEluIHRoZSBhYnNlbmNlIG9mIGFuIGluaXRpYWwgdGltZSBwcm92aWRlZCBieSB0aGUgYnJvd3NlciwgZmFsbGJhY2sgdG8gdGhlIGN1cnJlbnQgdGltZSBmcm9tIHRoZQogIC8vIERhdGUgQVBJLgogIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogIGNvbnN0IG5hdmlnYXRpb25TdGFydCA9IHBlcmZvcm1hbmNlLnRpbWluZyAmJiBwZXJmb3JtYW5jZS50aW1pbmcubmF2aWdhdGlvblN0YXJ0OwogIGNvbnN0IGhhc05hdmlnYXRpb25TdGFydCA9IHR5cGVvZiBuYXZpZ2F0aW9uU3RhcnQgPT09ICdudW1iZXInOwogIC8vIGlmIG5hdmlnYXRpb25TdGFydCBpc24ndCBhdmFpbGFibGUgc2V0IGRlbHRhIHRvIHRocmVzaG9sZCBzbyBpdCBpc24ndCB1c2VkCiAgY29uc3QgbmF2aWdhdGlvblN0YXJ0RGVsdGEgPSBoYXNOYXZpZ2F0aW9uU3RhcnQgPyBNYXRoLmFicyhuYXZpZ2F0aW9uU3RhcnQgKyBwZXJmb3JtYW5jZU5vdyAtIGRhdGVOb3cpIDogdGhyZXNob2xkOwogIGNvbnN0IG5hdmlnYXRpb25TdGFydElzUmVsaWFibGUgPSBuYXZpZ2F0aW9uU3RhcnREZWx0YSA8IHRocmVzaG9sZDsKCiAgaWYgKHRpbWVPcmlnaW5Jc1JlbGlhYmxlIHx8IG5hdmlnYXRpb25TdGFydElzUmVsaWFibGUpIHsKICAgIC8vIFVzZSB0aGUgbW9yZSByZWxpYWJsZSB0aW1lIG9yaWdpbgogICAgaWYgKHRpbWVPcmlnaW5EZWx0YSA8PSBuYXZpZ2F0aW9uU3RhcnREZWx0YSkgewogICAgICByZXR1cm4gcGVyZm9ybWFuY2UudGltZU9yaWdpbjsKICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiBuYXZpZ2F0aW9uU3RhcnQ7CiAgICB9CiAgfQogIHJldHVybiBkYXRlTm93Owp9KSgpOwoKLyoqCiAqIENyZWF0ZXMgYW4gZW52ZWxvcGUuCiAqIE1ha2Ugc3VyZSB0byBhbHdheXMgZXhwbGljaXRseSBwcm92aWRlIHRoZSBnZW5lcmljIHRvIHRoaXMgZnVuY3Rpb24KICogc28gdGhhdCB0aGUgZW52ZWxvcGUgdHlwZXMgcmVzb2x2ZSBjb3JyZWN0bHkuCiAqLwpmdW5jdGlvbiBjcmVhdGVFbnZlbG9wZShoZWFkZXJzLCBpdGVtcyA9IFtdKSB7CiAgcmV0dXJuIFtoZWFkZXJzLCBpdGVtc10gOwp9CgovKioKICogQ29udmVuaWVuY2UgZnVuY3Rpb24gdG8gbG9vcCB0aHJvdWdoIHRoZSBpdGVtcyBhbmQgaXRlbSB0eXBlcyBvZiBhbiBlbnZlbG9wZS4KICogKFRoaXMgZnVuY3Rpb24gd2FzIG1vc3RseSBjcmVhdGVkIGJlY2F1c2Ugd29ya2luZyB3aXRoIGVudmVsb3BlIHR5cGVzIGlzIHBhaW5mdWwgYXQgdGhlIG1vbWVudCkKICoKICogSWYgdGhlIGNhbGxiYWNrIHJldHVybnMgdHJ1ZSwgdGhlIHJlc3Qgb2YgdGhlIGl0ZW1zIHdpbGwgYmUgc2tpcHBlZC4KICovCmZ1bmN0aW9uIGZvckVhY2hFbnZlbG9wZUl0ZW0oCiAgZW52ZWxvcGUsCiAgY2FsbGJhY2ssCikgewogIGNvbnN0IGVudmVsb3BlSXRlbXMgPSBlbnZlbG9wZVsxXTsKCiAgZm9yIChjb25zdCBlbnZlbG9wZUl0ZW0gb2YgZW52ZWxvcGVJdGVtcykgewogICAgY29uc3QgZW52ZWxvcGVJdGVtVHlwZSA9IGVudmVsb3BlSXRlbVswXS50eXBlOwogICAgY29uc3QgcmVzdWx0ID0gY2FsbGJhY2soZW52ZWxvcGVJdGVtLCBlbnZlbG9wZUl0ZW1UeXBlKTsKCiAgICBpZiAocmVzdWx0KSB7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQogIH0KCiAgcmV0dXJuIGZhbHNlOwp9CgovKioKICogRW5jb2RlIGEgc3RyaW5nIHRvIFVURjguCiAqLwpmdW5jdGlvbiBlbmNvZGVVVEY4KGlucHV0LCB0ZXh0RW5jb2RlcikgewogIGNvbnN0IHV0ZjggPSB0ZXh0RW5jb2RlciB8fCBuZXcgVGV4dEVuY29kZXIoKTsKICByZXR1cm4gdXRmOC5lbmNvZGUoaW5wdXQpOwp9CgovKioKICogU2VyaWFsaXplcyBhbiBlbnZlbG9wZS4KICovCmZ1bmN0aW9uIHNlcmlhbGl6ZUVudmVsb3BlKGVudmVsb3BlLCB0ZXh0RW5jb2RlcikgewogIGNvbnN0IFtlbnZIZWFkZXJzLCBpdGVtc10gPSBlbnZlbG9wZTsKCiAgLy8gSW5pdGlhbGx5IHdlIGNvbnN0cnVjdCBvdXIgZW52ZWxvcGUgYXMgYSBzdHJpbmcgYW5kIG9ubHkgY29udmVydCB0byBiaW5hcnkgY2h1bmtzIGlmIHdlIGVuY291bnRlciBiaW5hcnkgZGF0YQogIGxldCBwYXJ0cyA9IEpTT04uc3RyaW5naWZ5KGVudkhlYWRlcnMpOwoKICBmdW5jdGlvbiBhcHBlbmQobmV4dCkgewogICAgaWYgKHR5cGVvZiBwYXJ0cyA9PT0gJ3N0cmluZycpIHsKICAgICAgcGFydHMgPSB0eXBlb2YgbmV4dCA9PT0gJ3N0cmluZycgPyBwYXJ0cyArIG5leHQgOiBbZW5jb2RlVVRGOChwYXJ0cywgdGV4dEVuY29kZXIpLCBuZXh0XTsKICAgIH0gZWxzZSB7CiAgICAgIHBhcnRzLnB1c2godHlwZW9mIG5leHQgPT09ICdzdHJpbmcnID8gZW5jb2RlVVRGOChuZXh0LCB0ZXh0RW5jb2RlcikgOiBuZXh0KTsKICAgIH0KICB9CgogIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykgewogICAgY29uc3QgW2l0ZW1IZWFkZXJzLCBwYXlsb2FkXSA9IGl0ZW07CgogICAgYXBwZW5kKGBcbiR7SlNPTi5zdHJpbmdpZnkoaXRlbUhlYWRlcnMpfVxuYCk7CgogICAgaWYgKHR5cGVvZiBwYXlsb2FkID09PSAnc3RyaW5nJyB8fCBwYXlsb2FkIGluc3RhbmNlb2YgVWludDhBcnJheSkgewogICAgICBhcHBlbmQocGF5bG9hZCk7CiAgICB9IGVsc2UgewogICAgICBsZXQgc3RyaW5naWZpZWRQYXlsb2FkOwogICAgICB0cnkgewogICAgICAgIHN0cmluZ2lmaWVkUGF5bG9hZCA9IEpTT04uc3RyaW5naWZ5KHBheWxvYWQpOwogICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgLy8gSW4gY2FzZSwgZGVzcGl0ZSBhbGwgb3VyIGVmZm9ydHMgdG8ga2VlcCBgcGF5bG9hZGAgY2lyY3VsYXItZGVwZW5kZW5jeS1mcmVlLCBgSlNPTi5zdHJpbmlmeSgpYCBzdGlsbAogICAgICAgIC8vIGZhaWxzLCB3ZSB0cnkgYWdhaW4gYWZ0ZXIgbm9ybWFsaXppbmcgaXQgYWdhaW4gd2l0aCBpbmZpbml0ZSBub3JtYWxpemF0aW9uIGRlcHRoLiBUaGlzIG9mIGNvdXJzZSBoYXMgYQogICAgICAgIC8vIHBlcmZvcm1hbmNlIGltcGFjdCBidXQgaW4gdGhpcyBjYXNlIGEgcGVyZm9ybWFuY2UgaGl0IGlzIGJldHRlciB0aGFuIHRocm93aW5nLgogICAgICAgIHN0cmluZ2lmaWVkUGF5bG9hZCA9IEpTT04uc3RyaW5naWZ5KG5vcm1hbGl6ZShwYXlsb2FkKSk7CiAgICAgIH0KICAgICAgYXBwZW5kKHN0cmluZ2lmaWVkUGF5bG9hZCk7CiAgICB9CiAgfQoKICByZXR1cm4gdHlwZW9mIHBhcnRzID09PSAnc3RyaW5nJyA/IHBhcnRzIDogY29uY2F0QnVmZmVycyhwYXJ0cyk7Cn0KCmZ1bmN0aW9uIGNvbmNhdEJ1ZmZlcnMoYnVmZmVycykgewogIGNvbnN0IHRvdGFsTGVuZ3RoID0gYnVmZmVycy5yZWR1Y2UoKGFjYywgYnVmKSA9PiBhY2MgKyBidWYubGVuZ3RoLCAwKTsKCiAgY29uc3QgbWVyZ2VkID0gbmV3IFVpbnQ4QXJyYXkodG90YWxMZW5ndGgpOwogIGxldCBvZmZzZXQgPSAwOwogIGZvciAoY29uc3QgYnVmZmVyIG9mIGJ1ZmZlcnMpIHsKICAgIG1lcmdlZC5zZXQoYnVmZmVyLCBvZmZzZXQpOwogICAgb2Zmc2V0ICs9IGJ1ZmZlci5sZW5ndGg7CiAgfQoKICByZXR1cm4gbWVyZ2VkOwp9Cgpjb25zdCBJVEVNX1RZUEVfVE9fREFUQV9DQVRFR09SWV9NQVAgPSB7CiAgc2Vzc2lvbjogJ3Nlc3Npb24nLAogIHNlc3Npb25zOiAnc2Vzc2lvbicsCiAgYXR0YWNobWVudDogJ2F0dGFjaG1lbnQnLAogIHRyYW5zYWN0aW9uOiAndHJhbnNhY3Rpb24nLAogIGV2ZW50OiAnZXJyb3InLAogIGNsaWVudF9yZXBvcnQ6ICdpbnRlcm5hbCcsCiAgdXNlcl9yZXBvcnQ6ICdkZWZhdWx0JywKICBwcm9maWxlOiAncHJvZmlsZScsCiAgcmVwbGF5X2V2ZW50OiAncmVwbGF5JywKICByZXBsYXlfcmVjb3JkaW5nOiAncmVwbGF5JywKICBjaGVja19pbjogJ21vbml0b3InLAogIGZlZWRiYWNrOiAnZmVlZGJhY2snLAogIHNwYW46ICdzcGFuJywKICAvLyBUT0RPOiBUaGlzIGlzIGEgdGVtcG9yYXJ5IHdvcmthcm91bmQgdW50aWwgd2UgaGF2ZSBhIHByb3BlciBkYXRhIGNhdGVnb3J5IGZvciBtZXRyaWNzCiAgc3RhdHNkOiAndW5rbm93bicsCn07CgovKioKICogTWFwcyB0aGUgdHlwZSBvZiBhbiBlbnZlbG9wZSBpdGVtIHRvIGEgZGF0YSBjYXRlZ29yeS4KICovCmZ1bmN0aW9uIGVudmVsb3BlSXRlbVR5cGVUb0RhdGFDYXRlZ29yeSh0eXBlKSB7CiAgcmV0dXJuIElURU1fVFlQRV9UT19EQVRBX0NBVEVHT1JZX01BUFt0eXBlXTsKfQoKLyoqIEV4dHJhY3RzIHRoZSBtaW5pbWFsIFNESyBpbmZvIGZyb20gZnJvbSB0aGUgbWV0YWRhdGEgb3IgYW4gZXZlbnRzICovCmZ1bmN0aW9uIGdldFNka01ldGFkYXRhRm9yRW52ZWxvcGVIZWFkZXIobWV0YWRhdGFPckV2ZW50KSB7CiAgaWYgKCFtZXRhZGF0YU9yRXZlbnQgfHwgIW1ldGFkYXRhT3JFdmVudC5zZGspIHsKICAgIHJldHVybjsKICB9CiAgY29uc3QgeyBuYW1lLCB2ZXJzaW9uIH0gPSBtZXRhZGF0YU9yRXZlbnQuc2RrOwogIHJldHVybiB7IG5hbWUsIHZlcnNpb24gfTsKfQoKLyoqCiAqIENyZWF0ZXMgZXZlbnQgZW52ZWxvcGUgaGVhZGVycywgYmFzZWQgb24gZXZlbnQsIHNkayBpbmZvIGFuZCB0dW5uZWwKICogTm90ZTogVGhpcyBmdW5jdGlvbiB3YXMgZXh0cmFjdGVkIGZyb20gdGhlIGNvcmUgcGFja2FnZSB0byBtYWtlIGl0IGF2YWlsYWJsZSBpbiBSZXBsYXkKICovCmZ1bmN0aW9uIGNyZWF0ZUV2ZW50RW52ZWxvcGVIZWFkZXJzKAogIGV2ZW50LAogIHNka0luZm8sCiAgdHVubmVsLAogIGRzbiwKKSB7CiAgY29uc3QgZHluYW1pY1NhbXBsaW5nQ29udGV4dCA9IGV2ZW50LnNka1Byb2Nlc3NpbmdNZXRhZGF0YSAmJiBldmVudC5zZGtQcm9jZXNzaW5nTWV0YWRhdGEuZHluYW1pY1NhbXBsaW5nQ29udGV4dDsKICByZXR1cm4gewogICAgZXZlbnRfaWQ6IGV2ZW50LmV2ZW50X2lkICwKICAgIHNlbnRfYXQ6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSwKICAgIC4uLihzZGtJbmZvICYmIHsgc2RrOiBzZGtJbmZvIH0pLAogICAgLi4uKCEhdHVubmVsICYmIGRzbiAmJiB7IGRzbjogZHNuVG9TdHJpbmcoZHNuKSB9KSwKICAgIC4uLihkeW5hbWljU2FtcGxpbmdDb250ZXh0ICYmIHsKICAgICAgdHJhY2U6IGRyb3BVbmRlZmluZWRLZXlzKHsgLi4uZHluYW1pY1NhbXBsaW5nQ29udGV4dCB9KSwKICAgIH0pLAogIH07Cn0KCi8vIEludGVudGlvbmFsbHkga2VlcGluZyB0aGUga2V5IGJyb2FkLCBhcyB3ZSBkb24ndCBrbm93IGZvciBzdXJlIHdoYXQgcmF0ZSBsaW1pdCBoZWFkZXJzIGdldCByZXR1cm5lZCBmcm9tIGJhY2tlbmQKCmNvbnN0IERFRkFVTFRfUkVUUllfQUZURVIgPSA2MCAqIDEwMDA7IC8vIDYwIHNlY29uZHMKCi8qKgogKiBFeHRyYWN0cyBSZXRyeS1BZnRlciB2YWx1ZSBmcm9tIHRoZSByZXF1ZXN0IGhlYWRlciBvciByZXR1cm5zIGRlZmF1bHQgdmFsdWUKICogQHBhcmFtIGhlYWRlciBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgJ1JldHJ5LUFmdGVyJyBoZWFkZXIKICogQHBhcmFtIG5vdyBjdXJyZW50IHVuaXggdGltZXN0YW1wCiAqCiAqLwpmdW5jdGlvbiBwYXJzZVJldHJ5QWZ0ZXJIZWFkZXIoaGVhZGVyLCBub3cgPSBEYXRlLm5vdygpKSB7CiAgY29uc3QgaGVhZGVyRGVsYXkgPSBwYXJzZUludChgJHtoZWFkZXJ9YCwgMTApOwogIGlmICghaXNOYU4oaGVhZGVyRGVsYXkpKSB7CiAgICByZXR1cm4gaGVhZGVyRGVsYXkgKiAxMDAwOwogIH0KCiAgY29uc3QgaGVhZGVyRGF0ZSA9IERhdGUucGFyc2UoYCR7aGVhZGVyfWApOwogIGlmICghaXNOYU4oaGVhZGVyRGF0ZSkpIHsKICAgIHJldHVybiBoZWFkZXJEYXRlIC0gbm93OwogIH0KCiAgcmV0dXJuIERFRkFVTFRfUkVUUllfQUZURVI7Cn0KCi8qKgogKiBHZXRzIHRoZSB0aW1lIHRoYXQgdGhlIGdpdmVuIGNhdGVnb3J5IGlzIGRpc2FibGVkIHVudGlsIGZvciByYXRlIGxpbWl0aW5nLgogKiBJbiBjYXNlIG5vIGNhdGVnb3J5LXNwZWNpZmljIGxpbWl0IGlzIHNldCBidXQgYSBnZW5lcmFsIHJhdGUgbGltaXQgYWNyb3NzIGFsbCBjYXRlZ29yaWVzIGlzIGFjdGl2ZSwKICogdGhhdCB0aW1lIGlzIHJldHVybmVkLgogKgogKiBAcmV0dXJuIHRoZSB0aW1lIGluIG1zIHRoYXQgdGhlIGNhdGVnb3J5IGlzIGRpc2FibGVkIHVudGlsIG9yIDAgaWYgdGhlcmUncyBubyBhY3RpdmUgcmF0ZSBsaW1pdC4KICovCmZ1bmN0aW9uIGRpc2FibGVkVW50aWwobGltaXRzLCBjYXRlZ29yeSkgewogIHJldHVybiBsaW1pdHNbY2F0ZWdvcnldIHx8IGxpbWl0cy5hbGwgfHwgMDsKfQoKLyoqCiAqIENoZWNrcyBpZiBhIGNhdGVnb3J5IGlzIHJhdGUgbGltaXRlZAogKi8KZnVuY3Rpb24gaXNSYXRlTGltaXRlZChsaW1pdHMsIGNhdGVnb3J5LCBub3cgPSBEYXRlLm5vdygpKSB7CiAgcmV0dXJuIGRpc2FibGVkVW50aWwobGltaXRzLCBjYXRlZ29yeSkgPiBub3c7Cn0KCi8qKgogKiBVcGRhdGUgcmF0ZWxpbWl0cyBmcm9tIGluY29taW5nIGhlYWRlcnMuCiAqCiAqIEByZXR1cm4gdGhlIHVwZGF0ZWQgUmF0ZUxpbWl0cyBvYmplY3QuCiAqLwpmdW5jdGlvbiB1cGRhdGVSYXRlTGltaXRzKAogIGxpbWl0cywKICB7IHN0YXR1c0NvZGUsIGhlYWRlcnMgfSwKICBub3cgPSBEYXRlLm5vdygpLAopIHsKICBjb25zdCB1cGRhdGVkUmF0ZUxpbWl0cyA9IHsKICAgIC4uLmxpbWl0cywKICB9OwoKICAvLyAiVGhlIG5hbWUgaXMgY2FzZS1pbnNlbnNpdGl2ZS4iCiAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0hlYWRlcnMvZ2V0CiAgY29uc3QgcmF0ZUxpbWl0SGVhZGVyID0gaGVhZGVycyAmJiBoZWFkZXJzWyd4LXNlbnRyeS1yYXRlLWxpbWl0cyddOwogIGNvbnN0IHJldHJ5QWZ0ZXJIZWFkZXIgPSBoZWFkZXJzICYmIGhlYWRlcnNbJ3JldHJ5LWFmdGVyJ107CgogIGlmIChyYXRlTGltaXRIZWFkZXIpIHsKICAgIC8qKgogICAgICogcmF0ZSBsaW1pdCBoZWFkZXJzIGFyZSBvZiB0aGUgZm9ybQogICAgICogICAgIDxoZWFkZXI+LDxoZWFkZXI+LC4uCiAgICAgKiB3aGVyZSBlYWNoIDxoZWFkZXI+IGlzIG9mIHRoZSBmb3JtCiAgICAgKiAgICAgPHJldHJ5X2FmdGVyPjogPGNhdGVnb3JpZXM+OiA8c2NvcGU+OiA8cmVhc29uX2NvZGU+CiAgICAgKiB3aGVyZQogICAgICogICAgIDxyZXRyeV9hZnRlcj4gaXMgYSBkZWxheSBpbiBzZWNvbmRzCiAgICAgKiAgICAgPGNhdGVnb3JpZXM+IGlzIHRoZSBldmVudCB0eXBlKHMpIChlcnJvciwgdHJhbnNhY3Rpb24sIGV0YykgYmVpbmcgcmF0ZSBsaW1pdGVkIGFuZCBpcyBvZiB0aGUgZm9ybQogICAgICogICAgICAgICA8Y2F0ZWdvcnk+OzxjYXRlZ29yeT47Li4uCiAgICAgKiAgICAgPHNjb3BlPiBpcyB3aGF0J3MgYmVpbmcgbGltaXRlZCAob3JnLCBwcm9qZWN0LCBvciBrZXkpIC0gaWdub3JlZCBieSBTREsKICAgICAqICAgICA8cmVhc29uX2NvZGU+IGlzIGFuIGFyYml0cmFyeSBzdHJpbmcgbGlrZSAib3JnX3F1b3RhIiAtIGlnbm9yZWQgYnkgU0RLCiAgICAgKi8KICAgIGZvciAoY29uc3QgbGltaXQgb2YgcmF0ZUxpbWl0SGVhZGVyLnRyaW0oKS5zcGxpdCgnLCcpKSB7CiAgICAgIGNvbnN0IFtyZXRyeUFmdGVyLCBjYXRlZ29yaWVzXSA9IGxpbWl0LnNwbGl0KCc6JywgMik7CiAgICAgIGNvbnN0IGhlYWRlckRlbGF5ID0gcGFyc2VJbnQocmV0cnlBZnRlciwgMTApOwogICAgICBjb25zdCBkZWxheSA9ICghaXNOYU4oaGVhZGVyRGVsYXkpID8gaGVhZGVyRGVsYXkgOiA2MCkgKiAxMDAwOyAvLyA2MHNlYyBkZWZhdWx0CiAgICAgIGlmICghY2F0ZWdvcmllcykgewogICAgICAgIHVwZGF0ZWRSYXRlTGltaXRzLmFsbCA9IG5vdyArIGRlbGF5OwogICAgICB9IGVsc2UgewogICAgICAgIGZvciAoY29uc3QgY2F0ZWdvcnkgb2YgY2F0ZWdvcmllcy5zcGxpdCgnOycpKSB7CiAgICAgICAgICB1cGRhdGVkUmF0ZUxpbWl0c1tjYXRlZ29yeV0gPSBub3cgKyBkZWxheTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9IGVsc2UgaWYgKHJldHJ5QWZ0ZXJIZWFkZXIpIHsKICAgIHVwZGF0ZWRSYXRlTGltaXRzLmFsbCA9IG5vdyArIHBhcnNlUmV0cnlBZnRlckhlYWRlcihyZXRyeUFmdGVySGVhZGVyLCBub3cpOwogIH0gZWxzZSBpZiAoc3RhdHVzQ29kZSA9PT0gNDI5KSB7CiAgICB1cGRhdGVkUmF0ZUxpbWl0cy5hbGwgPSBub3cgKyA2MCAqIDEwMDA7CiAgfQoKICByZXR1cm4gdXBkYXRlZFJhdGVMaW1pdHM7Cn0KCi8qKgogKiBBIG5vZGUuanMgd2F0Y2hkb2cgdGltZXIKICogQHBhcmFtIHBvbGxJbnRlcnZhbCBUaGUgaW50ZXJ2YWwgdGhhdCB3ZSBleHBlY3QgdG8gZ2V0IHBvbGxlZCBhdAogKiBAcGFyYW0gYW5yVGhyZXNob2xkIFRoZSB0aHJlc2hvbGQgZm9yIHdoZW4gd2UgY29uc2lkZXIgQU5SCiAqIEBwYXJhbSBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gY2FsbCBmb3IgQU5SCiAqIEByZXR1cm5zIEFuIG9iamVjdCB3aXRoIGBwb2xsYCBhbmQgYGVuYWJsZWRgIGZ1bmN0aW9ucyB7QGxpbmsgV2F0Y2hkb2dSZXR1cm59CiAqLwpmdW5jdGlvbiB3YXRjaGRvZ1RpbWVyKAogIGNyZWF0ZVRpbWVyLAogIHBvbGxJbnRlcnZhbCwKICBhbnJUaHJlc2hvbGQsCiAgY2FsbGJhY2ssCikgewogIGNvbnN0IHRpbWVyID0gY3JlYXRlVGltZXIoKTsKICBsZXQgdHJpZ2dlcmVkID0gZmFsc2U7CiAgbGV0IGVuYWJsZWQgPSB0cnVlOwoKICBzZXRJbnRlcnZhbCgoKSA9PiB7CiAgICBjb25zdCBkaWZmTXMgPSB0aW1lci5nZXRUaW1lTXMoKTsKCiAgICBpZiAodHJpZ2dlcmVkID09PSBmYWxzZSAmJiBkaWZmTXMgPiBwb2xsSW50ZXJ2YWwgKyBhbnJUaHJlc2hvbGQpIHsKICAgICAgdHJpZ2dlcmVkID0gdHJ1ZTsKICAgICAgaWYgKGVuYWJsZWQpIHsKICAgICAgICBjYWxsYmFjaygpOwogICAgICB9CiAgICB9CgogICAgaWYgKGRpZmZNcyA8IHBvbGxJbnRlcnZhbCArIGFuclRocmVzaG9sZCkgewogICAgICB0cmlnZ2VyZWQgPSBmYWxzZTsKICAgIH0KICB9LCAyMCk7CgogIHJldHVybiB7CiAgICBwb2xsOiAoKSA9PiB7CiAgICAgIHRpbWVyLnJlc2V0KCk7CiAgICB9LAogICAgZW5hYmxlZDogKHN0YXRlKSA9PiB7CiAgICAgIGVuYWJsZWQgPSBzdGF0ZTsKICAgIH0sCiAgfTsKfQoKLy8gdHlwZXMgY29waWVkIGZyb20gaW5zcGVjdG9yLmQudHMKCi8qKgogKiBDb252ZXJ0cyBEZWJ1Z2dlci5DYWxsRnJhbWUgdG8gU2VudHJ5IFN0YWNrRnJhbWUKICovCmZ1bmN0aW9uIGNhbGxGcmFtZVRvU3RhY2tGcmFtZSgKICBmcmFtZSwKICB1cmwsCiAgZ2V0TW9kdWxlRnJvbUZpbGVuYW1lLAopIHsKICBjb25zdCBmaWxlbmFtZSA9IHVybCA/IHVybC5yZXBsYWNlKC9eZmlsZTpcL1wvLywgJycpIDogdW5kZWZpbmVkOwoKICAvLyBDYWxsRnJhbWUgcm93L2NvbCBhcmUgMCBiYXNlZCwgd2hlcmVhcyBTdGFja0ZyYW1lIGFyZSAxIGJhc2VkCiAgY29uc3QgY29sbm8gPSBmcmFtZS5sb2NhdGlvbi5jb2x1bW5OdW1iZXIgPyBmcmFtZS5sb2NhdGlvbi5jb2x1bW5OdW1iZXIgKyAxIDogdW5kZWZpbmVkOwogIGNvbnN0IGxpbmVubyA9IGZyYW1lLmxvY2F0aW9uLmxpbmVOdW1iZXIgPyBmcmFtZS5sb2NhdGlvbi5saW5lTnVtYmVyICsgMSA6IHVuZGVmaW5lZDsKCiAgcmV0dXJuIGRyb3BVbmRlZmluZWRLZXlzKHsKICAgIGZpbGVuYW1lLAogICAgbW9kdWxlOiBnZXRNb2R1bGVGcm9tRmlsZW5hbWUoZmlsZW5hbWUpLAogICAgZnVuY3Rpb246IGZyYW1lLmZ1bmN0aW9uTmFtZSB8fCAnPycsCiAgICBjb2xubywKICAgIGxpbmVubywKICAgIGluX2FwcDogZmlsZW5hbWUgPyBmaWxlbmFtZUlzSW5BcHAoZmlsZW5hbWUpIDogdW5kZWZpbmVkLAogIH0pOwp9CgovKioKICogVGhpcyBzZXJ2ZXMgYXMgYSBidWlsZCB0aW1lIGZsYWcgdGhhdCB3aWxsIGJlIHRydWUgYnkgZGVmYXVsdCwgYnV0IGZhbHNlIGluIG5vbi1kZWJ1ZyBidWlsZHMgb3IgaWYgdXNlcnMgcmVwbGFjZSBgX19TRU5UUllfREVCVUdfX2AgaW4gdGhlaXIgZ2VuZXJhdGVkIGNvZGUuCiAqCiAqIEFUVEVOVElPTjogVGhpcyBjb25zdGFudCBtdXN0IG5ldmVyIGNyb3NzIHBhY2thZ2UgYm91bmRhcmllcyAoaS5lLiBiZSBleHBvcnRlZCkgdG8gZ3VhcmFudGVlIHRoYXQgaXQgY2FuIGJlIHVzZWQgZm9yIHRyZWUgc2hha2luZy4KICovCmNvbnN0IERFQlVHX0JVSUxEID0gKHR5cGVvZiBfX1NFTlRSWV9ERUJVR19fID09PSAndW5kZWZpbmVkJyB8fCBfX1NFTlRSWV9ERUJVR19fKTsKCi8qKgogKiBDcmVhdGVzIGEgbmV3IGBTZXNzaW9uYCBvYmplY3QgYnkgc2V0dGluZyBjZXJ0YWluIGRlZmF1bHQgcGFyYW1ldGVycy4gSWYgb3B0aW9uYWwgQHBhcmFtIGNvbnRleHQKICogaXMgcGFzc2VkLCB0aGUgcGFzc2VkIHByb3BlcnRpZXMgYXJlIGFwcGxpZWQgdG8gdGhlIHNlc3Npb24gb2JqZWN0LgogKgogKiBAcGFyYW0gY29udGV4dCAob3B0aW9uYWwpIGFkZGl0aW9uYWwgcHJvcGVydGllcyB0byBiZSBhcHBsaWVkIHRvIHRoZSByZXR1cm5lZCBzZXNzaW9uIG9iamVjdAogKgogKiBAcmV0dXJucyBhIG5ldyBgU2Vzc2lvbmAgb2JqZWN0CiAqLwpmdW5jdGlvbiBtYWtlU2Vzc2lvbihjb250ZXh0KSB7CiAgLy8gQm90aCB0aW1lc3RhbXAgYW5kIHN0YXJ0ZWQgYXJlIGluIHNlY29uZHMgc2luY2UgdGhlIFVOSVggZXBvY2guCiAgY29uc3Qgc3RhcnRpbmdUaW1lID0gdGltZXN0YW1wSW5TZWNvbmRzKCk7CgogIGNvbnN0IHNlc3Npb24gPSB7CiAgICBzaWQ6IHV1aWQ0KCksCiAgICBpbml0OiB0cnVlLAogICAgdGltZXN0YW1wOiBzdGFydGluZ1RpbWUsCiAgICBzdGFydGVkOiBzdGFydGluZ1RpbWUsCiAgICBkdXJhdGlvbjogMCwKICAgIHN0YXR1czogJ29rJywKICAgIGVycm9yczogMCwKICAgIGlnbm9yZUR1cmF0aW9uOiBmYWxzZSwKICAgIHRvSlNPTjogKCkgPT4gc2Vzc2lvblRvSlNPTihzZXNzaW9uKSwKICB9OwoKICBpZiAoY29udGV4dCkgewogICAgdXBkYXRlU2Vzc2lvbihzZXNzaW9uLCBjb250ZXh0KTsKICB9CgogIHJldHVybiBzZXNzaW9uOwp9CgovKioKICogVXBkYXRlcyBhIHNlc3Npb24gb2JqZWN0IHdpdGggdGhlIHByb3BlcnRpZXMgcGFzc2VkIGluIHRoZSBjb250ZXh0LgogKgogKiBOb3RlIHRoYXQgdGhpcyBmdW5jdGlvbiBtdXRhdGVzIHRoZSBwYXNzZWQgb2JqZWN0IGFuZCByZXR1cm5zIHZvaWQuCiAqIChIYWQgdG8gZG8gdGhpcyBpbnN0ZWFkIG9mIHJldHVybmluZyBhIG5ldyBhbmQgdXBkYXRlZCBzZXNzaW9uIGJlY2F1c2UgY2xvc2luZyBhbmQgc2VuZGluZyBhIHNlc3Npb24KICogbWFrZXMgYW4gdXBkYXRlIHRvIHRoZSBzZXNzaW9uIGFmdGVyIGl0IHdhcyBwYXNzZWQgdG8gdGhlIHNlbmRpbmcgbG9naWMuCiAqIEBzZWUgQmFzZUNsaWVudC5jYXB0dXJlU2Vzc2lvbiApCiAqCiAqIEBwYXJhbSBzZXNzaW9uIHRoZSBgU2Vzc2lvbmAgdG8gdXBkYXRlCiAqIEBwYXJhbSBjb250ZXh0IHRoZSBgU2Vzc2lvbkNvbnRleHRgIGhvbGRpbmcgdGhlIHByb3BlcnRpZXMgdGhhdCBzaG91bGQgYmUgdXBkYXRlZCBpbiBAcGFyYW0gc2Vzc2lvbgogKi8KLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNvbXBsZXhpdHkKZnVuY3Rpb24gdXBkYXRlU2Vzc2lvbihzZXNzaW9uLCBjb250ZXh0ID0ge30pIHsKICBpZiAoY29udGV4dC51c2VyKSB7CiAgICBpZiAoIXNlc3Npb24uaXBBZGRyZXNzICYmIGNvbnRleHQudXNlci5pcF9hZGRyZXNzKSB7CiAgICAgIHNlc3Npb24uaXBBZGRyZXNzID0gY29udGV4dC51c2VyLmlwX2FkZHJlc3M7CiAgICB9CgogICAgaWYgKCFzZXNzaW9uLmRpZCAmJiAhY29udGV4dC5kaWQpIHsKICAgICAgc2Vzc2lvbi5kaWQgPSBjb250ZXh0LnVzZXIuaWQgfHwgY29udGV4dC51c2VyLmVtYWlsIHx8IGNvbnRleHQudXNlci51c2VybmFtZTsKICAgIH0KICB9CgogIHNlc3Npb24udGltZXN0YW1wID0gY29udGV4dC50aW1lc3RhbXAgfHwgdGltZXN0YW1wSW5TZWNvbmRzKCk7CgogIGlmIChjb250ZXh0LmFibm9ybWFsX21lY2hhbmlzbSkgewogICAgc2Vzc2lvbi5hYm5vcm1hbF9tZWNoYW5pc20gPSBjb250ZXh0LmFibm9ybWFsX21lY2hhbmlzbTsKICB9CgogIGlmIChjb250ZXh0Lmlnbm9yZUR1cmF0aW9uKSB7CiAgICBzZXNzaW9uLmlnbm9yZUR1cmF0aW9uID0gY29udGV4dC5pZ25vcmVEdXJhdGlvbjsKICB9CiAgaWYgKGNvbnRleHQuc2lkKSB7CiAgICAvLyBHb29kIGVub3VnaCB1dWlkIHZhbGlkYXRpb24uIOKAlCBLYW1pbAogICAgc2Vzc2lvbi5zaWQgPSBjb250ZXh0LnNpZC5sZW5ndGggPT09IDMyID8gY29udGV4dC5zaWQgOiB1dWlkNCgpOwogIH0KICBpZiAoY29udGV4dC5pbml0ICE9PSB1bmRlZmluZWQpIHsKICAgIHNlc3Npb24uaW5pdCA9IGNvbnRleHQuaW5pdDsKICB9CiAgaWYgKCFzZXNzaW9uLmRpZCAmJiBjb250ZXh0LmRpZCkgewogICAgc2Vzc2lvbi5kaWQgPSBgJHtjb250ZXh0LmRpZH1gOwogIH0KICBpZiAodHlwZW9mIGNvbnRleHQuc3RhcnRlZCA9PT0gJ251bWJlcicpIHsKICAgIHNlc3Npb24uc3RhcnRlZCA9IGNvbnRleHQuc3RhcnRlZDsKICB9CiAgaWYgKHNlc3Npb24uaWdub3JlRHVyYXRpb24pIHsKICAgIHNlc3Npb24uZHVyYXRpb24gPSB1bmRlZmluZWQ7CiAgfSBlbHNlIGlmICh0eXBlb2YgY29udGV4dC5kdXJhdGlvbiA9PT0gJ251bWJlcicpIHsKICAgIHNlc3Npb24uZHVyYXRpb24gPSBjb250ZXh0LmR1cmF0aW9uOwogIH0gZWxzZSB7CiAgICBjb25zdCBkdXJhdGlvbiA9IHNlc3Npb24udGltZXN0YW1wIC0gc2Vzc2lvbi5zdGFydGVkOwogICAgc2Vzc2lvbi5kdXJhdGlvbiA9IGR1cmF0aW9uID49IDAgPyBkdXJhdGlvbiA6IDA7CiAgfQogIGlmIChjb250ZXh0LnJlbGVhc2UpIHsKICAgIHNlc3Npb24ucmVsZWFzZSA9IGNvbnRleHQucmVsZWFzZTsKICB9CiAgaWYgKGNvbnRleHQuZW52aXJvbm1lbnQpIHsKICAgIHNlc3Npb24uZW52aXJvbm1lbnQgPSBjb250ZXh0LmVudmlyb25tZW50OwogIH0KICBpZiAoIXNlc3Npb24uaXBBZGRyZXNzICYmIGNvbnRleHQuaXBBZGRyZXNzKSB7CiAgICBzZXNzaW9uLmlwQWRkcmVzcyA9IGNvbnRleHQuaXBBZGRyZXNzOwogIH0KICBpZiAoIXNlc3Npb24udXNlckFnZW50ICYmIGNvbnRleHQudXNlckFnZW50KSB7CiAgICBzZXNzaW9uLnVzZXJBZ2VudCA9IGNvbnRleHQudXNlckFnZW50OwogIH0KICBpZiAodHlwZW9mIGNvbnRleHQuZXJyb3JzID09PSAnbnVtYmVyJykgewogICAgc2Vzc2lvbi5lcnJvcnMgPSBjb250ZXh0LmVycm9yczsKICB9CiAgaWYgKGNvbnRleHQuc3RhdHVzKSB7CiAgICBzZXNzaW9uLnN0YXR1cyA9IGNvbnRleHQuc3RhdHVzOwogIH0KfQoKLyoqCiAqIFNlcmlhbGl6ZXMgYSBwYXNzZWQgc2Vzc2lvbiBvYmplY3QgdG8gYSBKU09OIG9iamVjdCB3aXRoIGEgc2xpZ2h0bHkgZGlmZmVyZW50IHN0cnVjdHVyZS4KICogVGhpcyBpcyBuZWNlc3NhcnkgYmVjYXVzZSB0aGUgU2VudHJ5IGJhY2tlbmQgcmVxdWlyZXMgYSBzbGlnaHRseSBkaWZmZXJlbnQgc2NoZW1hIG9mIGEgc2Vzc2lvbgogKiB0aGFuIHRoZSBvbmUgdGhlIEpTIFNES3MgdXNlIGludGVybmFsbHkuCiAqCiAqIEBwYXJhbSBzZXNzaW9uIHRoZSBzZXNzaW9uIHRvIGJlIGNvbnZlcnRlZAogKgogKiBAcmV0dXJucyBhIEpTT04gb2JqZWN0IG9mIHRoZSBwYXNzZWQgc2Vzc2lvbgogKi8KZnVuY3Rpb24gc2Vzc2lvblRvSlNPTihzZXNzaW9uKSB7CiAgcmV0dXJuIGRyb3BVbmRlZmluZWRLZXlzKHsKICAgIHNpZDogYCR7c2Vzc2lvbi5zaWR9YCwKICAgIGluaXQ6IHNlc3Npb24uaW5pdCwKICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHNlYyBpcyBjb252ZXJ0ZWQgdG8gbXMgZm9yIGRhdGUgY29uc3RydWN0b3IKICAgIHN0YXJ0ZWQ6IG5ldyBEYXRlKHNlc3Npb24uc3RhcnRlZCAqIDEwMDApLnRvSVNPU3RyaW5nKCksCiAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKHNlc3Npb24udGltZXN0YW1wICogMTAwMCkudG9JU09TdHJpbmcoKSwKICAgIHN0YXR1czogc2Vzc2lvbi5zdGF0dXMsCiAgICBlcnJvcnM6IHNlc3Npb24uZXJyb3JzLAogICAgZGlkOiB0eXBlb2Ygc2Vzc2lvbi5kaWQgPT09ICdudW1iZXInIHx8IHR5cGVvZiBzZXNzaW9uLmRpZCA9PT0gJ3N0cmluZycgPyBgJHtzZXNzaW9uLmRpZH1gIDogdW5kZWZpbmVkLAogICAgZHVyYXRpb246IHNlc3Npb24uZHVyYXRpb24sCiAgICBhYm5vcm1hbF9tZWNoYW5pc206IHNlc3Npb24uYWJub3JtYWxfbWVjaGFuaXNtLAogICAgYXR0cnM6IHsKICAgICAgcmVsZWFzZTogc2Vzc2lvbi5yZWxlYXNlLAogICAgICBlbnZpcm9ubWVudDogc2Vzc2lvbi5lbnZpcm9ubWVudCwKICAgICAgaXBfYWRkcmVzczogc2Vzc2lvbi5pcEFkZHJlc3MsCiAgICAgIHVzZXJfYWdlbnQ6IHNlc3Npb24udXNlckFnZW50LAogICAgfSwKICB9KTsKfQoKLyoqCiAqIEFwcGx5IFNka0luZm8gKG5hbWUsIHZlcnNpb24sIHBhY2thZ2VzLCBpbnRlZ3JhdGlvbnMpIHRvIHRoZSBjb3JyZXNwb25kaW5nIGV2ZW50IGtleS4KICogTWVyZ2Ugd2l0aCBleGlzdGluZyBkYXRhIGlmIGFueS4KICoqLwpmdW5jdGlvbiBlbmhhbmNlRXZlbnRXaXRoU2RrSW5mbyhldmVudCwgc2RrSW5mbykgewogIGlmICghc2RrSW5mbykgewogICAgcmV0dXJuIGV2ZW50OwogIH0KICBldmVudC5zZGsgPSBldmVudC5zZGsgfHwge307CiAgZXZlbnQuc2RrLm5hbWUgPSBldmVudC5zZGsubmFtZSB8fCBzZGtJbmZvLm5hbWU7CiAgZXZlbnQuc2RrLnZlcnNpb24gPSBldmVudC5zZGsudmVyc2lvbiB8fCBzZGtJbmZvLnZlcnNpb247CiAgZXZlbnQuc2RrLmludGVncmF0aW9ucyA9IFsuLi4oZXZlbnQuc2RrLmludGVncmF0aW9ucyB8fCBbXSksIC4uLihzZGtJbmZvLmludGVncmF0aW9ucyB8fCBbXSldOwogIGV2ZW50LnNkay5wYWNrYWdlcyA9IFsuLi4oZXZlbnQuc2RrLnBhY2thZ2VzIHx8IFtdKSwgLi4uKHNka0luZm8ucGFja2FnZXMgfHwgW10pXTsKICByZXR1cm4gZXZlbnQ7Cn0KCi8qKiBDcmVhdGVzIGFuIGVudmVsb3BlIGZyb20gYSBTZXNzaW9uICovCmZ1bmN0aW9uIGNyZWF0ZVNlc3Npb25FbnZlbG9wZSgKICBzZXNzaW9uLAogIGRzbiwKICBtZXRhZGF0YSwKICB0dW5uZWwsCikgewogIGNvbnN0IHNka0luZm8gPSBnZXRTZGtNZXRhZGF0YUZvckVudmVsb3BlSGVhZGVyKG1ldGFkYXRhKTsKICBjb25zdCBlbnZlbG9wZUhlYWRlcnMgPSB7CiAgICBzZW50X2F0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksCiAgICAuLi4oc2RrSW5mbyAmJiB7IHNkazogc2RrSW5mbyB9KSwKICAgIC4uLighIXR1bm5lbCAmJiBkc24gJiYgeyBkc246IGRzblRvU3RyaW5nKGRzbikgfSksCiAgfTsKCiAgY29uc3QgZW52ZWxvcGVJdGVtID0KICAgICdhZ2dyZWdhdGVzJyBpbiBzZXNzaW9uID8gW3sgdHlwZTogJ3Nlc3Npb25zJyB9LCBzZXNzaW9uXSA6IFt7IHR5cGU6ICdzZXNzaW9uJyB9LCBzZXNzaW9uLnRvSlNPTigpXTsKCiAgcmV0dXJuIGNyZWF0ZUVudmVsb3BlKGVudmVsb3BlSGVhZGVycywgW2VudmVsb3BlSXRlbV0pOwp9CgovKioKICogQ3JlYXRlIGFuIEVudmVsb3BlIGZyb20gYW4gZXZlbnQuCiAqLwpmdW5jdGlvbiBjcmVhdGVFdmVudEVudmVsb3BlKAogIGV2ZW50LAogIGRzbiwKICBtZXRhZGF0YSwKICB0dW5uZWwsCikgewogIGNvbnN0IHNka0luZm8gPSBnZXRTZGtNZXRhZGF0YUZvckVudmVsb3BlSGVhZGVyKG1ldGFkYXRhKTsKCiAgLyoKICAgIE5vdGU6IER1ZSB0byBUUywgZXZlbnQudHlwZSBtYXkgYmUgYHJlcGxheV9ldmVudGAsIHRoZW9yZXRpY2FsbHkuCiAgICBJbiBwcmFjdGljZSwgd2UgbmV2ZXIgY2FsbCBgY3JlYXRlRXZlbnRFbnZlbG9wZWAgd2l0aCBgcmVwbGF5X2V2ZW50YCB0eXBlLAogICAgYW5kIHdlJ2QgaGF2ZSB0byBhZGp1dCBhIGxvb290IG9mIHR5cGVzIHRvIG1ha2UgdGhpcyB3b3JrIHByb3Blcmx5LgogICAgV2Ugd2FudCB0byBhdm9pZCBjYXN0aW5nIHRoaXMgYXJvdW5kLCBhcyB0aGF0IGNvdWxkIGxlYWQgdG8gYnVncyAoZS5nLiB3aGVuIHdlIGFkZCBhbm90aGVyIHR5cGUpCiAgICBTbyB0aGUgc2FmZSBjaG9pY2UgaXMgdG8gcmVhbGx5IGd1YXJkIGFnYWluc3QgdGhlIHJlcGxheV9ldmVudCB0eXBlIGhlcmUuCiAgKi8KICBjb25zdCBldmVudFR5cGUgPSBldmVudC50eXBlICYmIGV2ZW50LnR5cGUgIT09ICdyZXBsYXlfZXZlbnQnID8gZXZlbnQudHlwZSA6ICdldmVudCc7CgogIGVuaGFuY2VFdmVudFdpdGhTZGtJbmZvKGV2ZW50LCBtZXRhZGF0YSAmJiBtZXRhZGF0YS5zZGspOwoKICBjb25zdCBlbnZlbG9wZUhlYWRlcnMgPSBjcmVhdGVFdmVudEVudmVsb3BlSGVhZGVycyhldmVudCwgc2RrSW5mbywgdHVubmVsLCBkc24pOwoKICAvLyBQcmV2ZW50IHRoaXMgZGF0YSAod2hpY2gsIGlmIGl0IGV4aXN0cywgd2FzIHVzZWQgaW4gZWFybGllciBzdGVwcyBpbiB0aGUgcHJvY2Vzc2luZyBwaXBlbGluZSkgZnJvbSBiZWluZyBzZW50IHRvCiAgLy8gc2VudHJ5LiAoTm90ZTogT3VyIHVzZSBvZiB0aGlzIHByb3BlcnR5IGNvbWVzIGFuZCBnb2VzIHdpdGggd2hhdGV2ZXIgd2UgbWlnaHQgYmUgZGVidWdnaW5nLCB3aGF0ZXZlciBoYWNrcyB3ZSBtYXkKICAvLyBoYXZlIHRlbXBvcmFyaWx5IGFkZGVkLCBldGMuIEV2ZW4gaWYgd2UgZG9uJ3QgaGFwcGVuIHRvIGJlIHVzaW5nIGl0IGF0IHNvbWUgcG9pbnQgaW4gdGhlIGZ1dHVyZSwgbGV0J3Mgbm90IGdldCByaWQKICAvLyBvZiB0aGlzIGBkZWxldGVgLCBsZXN0IHdlIG1pc3MgcHV0dGluZyBpdCBiYWNrIGluIHRoZSBuZXh0IHRpbWUgdGhlIHByb3BlcnR5IGlzIGluIHVzZS4pCiAgZGVsZXRlIGV2ZW50LnNka1Byb2Nlc3NpbmdNZXRhZGF0YTsKCiAgY29uc3QgZXZlbnRJdGVtID0gW3sgdHlwZTogZXZlbnRUeXBlIH0sIGV2ZW50XTsKICByZXR1cm4gY3JlYXRlRW52ZWxvcGUoZW52ZWxvcGVIZWFkZXJzLCBbZXZlbnRJdGVtXSk7Cn0KCmNvbnN0IFNFTlRSWV9BUElfVkVSU0lPTiA9ICc3JzsKCi8qKiBSZXR1cm5zIHRoZSBwcmVmaXggdG8gY29uc3RydWN0IFNlbnRyeSBpbmdlc3Rpb24gQVBJIGVuZHBvaW50cy4gKi8KZnVuY3Rpb24gZ2V0QmFzZUFwaUVuZHBvaW50KGRzbikgewogIGNvbnN0IHByb3RvY29sID0gZHNuLnByb3RvY29sID8gYCR7ZHNuLnByb3RvY29sfTpgIDogJyc7CiAgY29uc3QgcG9ydCA9IGRzbi5wb3J0ID8gYDoke2Rzbi5wb3J0fWAgOiAnJzsKICByZXR1cm4gYCR7cHJvdG9jb2x9Ly8ke2Rzbi5ob3N0fSR7cG9ydH0ke2Rzbi5wYXRoID8gYC8ke2Rzbi5wYXRofWAgOiAnJ30vYXBpL2A7Cn0KCi8qKiBSZXR1cm5zIHRoZSBpbmdlc3QgQVBJIGVuZHBvaW50IGZvciB0YXJnZXQuICovCmZ1bmN0aW9uIF9nZXRJbmdlc3RFbmRwb2ludChkc24pIHsKICByZXR1cm4gYCR7Z2V0QmFzZUFwaUVuZHBvaW50KGRzbil9JHtkc24ucHJvamVjdElkfS9lbnZlbG9wZS9gOwp9CgovKiogUmV0dXJucyBhIFVSTC1lbmNvZGVkIHN0cmluZyB3aXRoIGF1dGggY29uZmlnIHN1aXRhYmxlIGZvciBhIHF1ZXJ5IHN0cmluZy4gKi8KZnVuY3Rpb24gX2VuY29kZWRBdXRoKGRzbiwgc2RrSW5mbykgewogIHJldHVybiB1cmxFbmNvZGUoewogICAgLy8gV2Ugc2VuZCBvbmx5IHRoZSBtaW5pbXVtIHNldCBvZiByZXF1aXJlZCBpbmZvcm1hdGlvbi4gU2VlCiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vZ2V0c2VudHJ5L3NlbnRyeS1qYXZhc2NyaXB0L2lzc3Vlcy8yNTcyLgogICAgc2VudHJ5X2tleTogZHNuLnB1YmxpY0tleSwKICAgIHNlbnRyeV92ZXJzaW9uOiBTRU5UUllfQVBJX1ZFUlNJT04sCiAgICAuLi4oc2RrSW5mbyAmJiB7IHNlbnRyeV9jbGllbnQ6IGAke3Nka0luZm8ubmFtZX0vJHtzZGtJbmZvLnZlcnNpb259YCB9KSwKICB9KTsKfQoKLyoqCiAqIFJldHVybnMgdGhlIGVudmVsb3BlIGVuZHBvaW50IFVSTCB3aXRoIGF1dGggaW4gdGhlIHF1ZXJ5IHN0cmluZy4KICoKICogU2VuZGluZyBhdXRoIGFzIHBhcnQgb2YgdGhlIHF1ZXJ5IHN0cmluZyBhbmQgbm90IGFzIGN1c3RvbSBIVFRQIGhlYWRlcnMgYXZvaWRzIENPUlMgcHJlZmxpZ2h0IHJlcXVlc3RzLgogKi8KZnVuY3Rpb24gZ2V0RW52ZWxvcGVFbmRwb2ludFdpdGhVcmxFbmNvZGVkQXV0aCgKICBkc24sCiAgLy8gVE9ETyAodjgpOiBSZW1vdmUgYHR1bm5lbE9yT3B0aW9uc2AgaW4gZmF2b3Igb2YgYG9wdGlvbnNgLCBhbmQgdXNlIHRoZSBzdWJzdGl0dXRlIGNvZGUgYmVsb3cKICAvLyBvcHRpb25zOiBDbGllbnRPcHRpb25zID0ge30gYXMgQ2xpZW50T3B0aW9ucywKICB0dW5uZWxPck9wdGlvbnMgPSB7fSAsCikgewogIC8vIFRPRE8gKHY4KTogVXNlIHRoaXMgY29kZSBpbnN0ZWFkCiAgLy8gY29uc3QgeyB0dW5uZWwsIF9tZXRhZGF0YSA9IHt9IH0gPSBvcHRpb25zOwogIC8vIHJldHVybiB0dW5uZWwgPyB0dW5uZWwgOiBgJHtfZ2V0SW5nZXN0RW5kcG9pbnQoZHNuKX0/JHtfZW5jb2RlZEF1dGgoZHNuLCBfbWV0YWRhdGEuc2RrKX1gOwoKICBjb25zdCB0dW5uZWwgPSB0eXBlb2YgdHVubmVsT3JPcHRpb25zID09PSAnc3RyaW5nJyA/IHR1bm5lbE9yT3B0aW9ucyA6IHR1bm5lbE9yT3B0aW9ucy50dW5uZWw7CiAgY29uc3Qgc2RrSW5mbyA9CiAgICB0eXBlb2YgdHVubmVsT3JPcHRpb25zID09PSAnc3RyaW5nJyB8fCAhdHVubmVsT3JPcHRpb25zLl9tZXRhZGF0YSA/IHVuZGVmaW5lZCA6IHR1bm5lbE9yT3B0aW9ucy5fbWV0YWRhdGEuc2RrOwoKICByZXR1cm4gdHVubmVsID8gdHVubmVsIDogYCR7X2dldEluZ2VzdEVuZHBvaW50KGRzbil9PyR7X2VuY29kZWRBdXRoKGRzbiwgc2RrSW5mbyl9YDsKfQoKY29uc3QgREVGQVVMVF9UUkFOU1BPUlRfQlVGRkVSX1NJWkUgPSAzMDsKCi8qKgogKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIGEgU2VudHJ5IGBUcmFuc3BvcnRgCiAqCiAqIEBwYXJhbSBvcHRpb25zCiAqIEBwYXJhbSBtYWtlUmVxdWVzdAogKi8KZnVuY3Rpb24gY3JlYXRlVHJhbnNwb3J0KAogIG9wdGlvbnMsCiAgbWFrZVJlcXVlc3QsCiAgYnVmZmVyID0gbWFrZVByb21pc2VCdWZmZXIoCiAgICBvcHRpb25zLmJ1ZmZlclNpemUgfHwgREVGQVVMVF9UUkFOU1BPUlRfQlVGRkVSX1NJWkUsCiAgKSwKKSB7CiAgbGV0IHJhdGVMaW1pdHMgPSB7fTsKICBjb25zdCBmbHVzaCA9ICh0aW1lb3V0KSA9PiBidWZmZXIuZHJhaW4odGltZW91dCk7CgogIGZ1bmN0aW9uIHNlbmQoZW52ZWxvcGUpIHsKICAgIGNvbnN0IGZpbHRlcmVkRW52ZWxvcGVJdGVtcyA9IFtdOwoKICAgIC8vIERyb3AgcmF0ZSBsaW1pdGVkIGl0ZW1zIGZyb20gZW52ZWxvcGUKICAgIGZvckVhY2hFbnZlbG9wZUl0ZW0oZW52ZWxvcGUsIChpdGVtLCB0eXBlKSA9PiB7CiAgICAgIGNvbnN0IGVudmVsb3BlSXRlbURhdGFDYXRlZ29yeSA9IGVudmVsb3BlSXRlbVR5cGVUb0RhdGFDYXRlZ29yeSh0eXBlKTsKICAgICAgaWYgKGlzUmF0ZUxpbWl0ZWQocmF0ZUxpbWl0cywgZW52ZWxvcGVJdGVtRGF0YUNhdGVnb3J5KSkgewogICAgICAgIGNvbnN0IGV2ZW50ID0gZ2V0RXZlbnRGb3JFbnZlbG9wZUl0ZW0oaXRlbSwgdHlwZSk7CiAgICAgICAgb3B0aW9ucy5yZWNvcmREcm9wcGVkRXZlbnQoJ3JhdGVsaW1pdF9iYWNrb2ZmJywgZW52ZWxvcGVJdGVtRGF0YUNhdGVnb3J5LCBldmVudCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZmlsdGVyZWRFbnZlbG9wZUl0ZW1zLnB1c2goaXRlbSk7CiAgICAgIH0KICAgIH0pOwoKICAgIC8vIFNraXAgc2VuZGluZyBpZiBlbnZlbG9wZSBpcyBlbXB0eSBhZnRlciBmaWx0ZXJpbmcgb3V0IHJhdGUgbGltaXRlZCBldmVudHMKICAgIGlmIChmaWx0ZXJlZEVudmVsb3BlSXRlbXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybiByZXNvbHZlZFN5bmNQcm9taXNlKCk7CiAgICB9CgogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkKICAgIGNvbnN0IGZpbHRlcmVkRW52ZWxvcGUgPSBjcmVhdGVFbnZlbG9wZShlbnZlbG9wZVswXSwgZmlsdGVyZWRFbnZlbG9wZUl0ZW1zICk7CgogICAgLy8gQ3JlYXRlcyBjbGllbnQgcmVwb3J0IGZvciBlYWNoIGl0ZW0gaW4gYW4gZW52ZWxvcGUKICAgIGNvbnN0IHJlY29yZEVudmVsb3BlTG9zcyA9IChyZWFzb24pID0+IHsKICAgICAgZm9yRWFjaEVudmVsb3BlSXRlbShmaWx0ZXJlZEVudmVsb3BlLCAoaXRlbSwgdHlwZSkgPT4gewogICAgICAgIGNvbnN0IGV2ZW50ID0gZ2V0RXZlbnRGb3JFbnZlbG9wZUl0ZW0oaXRlbSwgdHlwZSk7CiAgICAgICAgb3B0aW9ucy5yZWNvcmREcm9wcGVkRXZlbnQocmVhc29uLCBlbnZlbG9wZUl0ZW1UeXBlVG9EYXRhQ2F0ZWdvcnkodHlwZSksIGV2ZW50KTsKICAgICAgfSk7CiAgICB9OwoKICAgIGNvbnN0IHJlcXVlc3RUYXNrID0gKCkgPT4KICAgICAgbWFrZVJlcXVlc3QoeyBib2R5OiBzZXJpYWxpemVFbnZlbG9wZShmaWx0ZXJlZEVudmVsb3BlLCBvcHRpb25zLnRleHRFbmNvZGVyKSB9KS50aGVuKAogICAgICAgIHJlc3BvbnNlID0+IHsKICAgICAgICAgIC8vIFdlIGRvbid0IHdhbnQgdG8gdGhyb3cgb24gTk9LIHJlc3BvbnNlcywgYnV0IHdlIHdhbnQgdG8gYXQgbGVhc3QgbG9nIHRoZW0KICAgICAgICAgIGlmIChyZXNwb25zZS5zdGF0dXNDb2RlICE9PSB1bmRlZmluZWQgJiYgKHJlc3BvbnNlLnN0YXR1c0NvZGUgPCAyMDAgfHwgcmVzcG9uc2Uuc3RhdHVzQ29kZSA+PSAzMDApKSB7CiAgICAgICAgICAgIERFQlVHX0JVSUxEICYmIGxvZ2dlci53YXJuKGBTZW50cnkgcmVzcG9uZGVkIHdpdGggc3RhdHVzIGNvZGUgJHtyZXNwb25zZS5zdGF0dXNDb2RlfSB0byBzZW50IGV2ZW50LmApOwogICAgICAgICAgfQoKICAgICAgICAgIHJhdGVMaW1pdHMgPSB1cGRhdGVSYXRlTGltaXRzKHJhdGVMaW1pdHMsIHJlc3BvbnNlKTsKICAgICAgICAgIHJldHVybiByZXNwb25zZTsKICAgICAgICB9LAogICAgICAgIGVycm9yID0+IHsKICAgICAgICAgIHJlY29yZEVudmVsb3BlTG9zcygnbmV0d29ya19lcnJvcicpOwogICAgICAgICAgdGhyb3cgZXJyb3I7CiAgICAgICAgfSwKICAgICAgKTsKCiAgICByZXR1cm4gYnVmZmVyLmFkZChyZXF1ZXN0VGFzaykudGhlbigKICAgICAgcmVzdWx0ID0+IHJlc3VsdCwKICAgICAgZXJyb3IgPT4gewogICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFNlbnRyeUVycm9yKSB7CiAgICAgICAgICBERUJVR19CVUlMRCAmJiBsb2dnZXIuZXJyb3IoJ1NraXBwZWQgc2VuZGluZyBldmVudCBiZWNhdXNlIGJ1ZmZlciBpcyBmdWxsLicpOwogICAgICAgICAgcmVjb3JkRW52ZWxvcGVMb3NzKCdxdWV1ZV9vdmVyZmxvdycpOwogICAgICAgICAgcmV0dXJuIHJlc29sdmVkU3luY1Byb21pc2UoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgdGhyb3cgZXJyb3I7CiAgICAgICAgfQogICAgICB9LAogICAgKTsKICB9CgogIC8vIFdlIHVzZSB0aGlzIHRvIGlkZW50aWZpZnkgaWYgdGhlIHRyYW5zcG9ydCBpcyB0aGUgYmFzZSB0cmFuc3BvcnQKICAvLyBUT0RPICh2OCk6IFJlbW92ZSB0aGlzIGFnYWluIGFzIHdlJ2xsIG5vIGxvbmdlciBuZWVkIGl0CiAgc2VuZC5fX3NlbnRyeV9fYmFzZVRyYW5zcG9ydF9fID0gdHJ1ZTsKCiAgcmV0dXJuIHsKICAgIHNlbmQsCiAgICBmbHVzaCwKICB9Owp9CgpmdW5jdGlvbiBnZXRFdmVudEZvckVudmVsb3BlSXRlbShpdGVtLCB0eXBlKSB7CiAgaWYgKHR5cGUgIT09ICdldmVudCcgJiYgdHlwZSAhPT0gJ3RyYW5zYWN0aW9uJykgewogICAgcmV0dXJuIHVuZGVmaW5lZDsKICB9CgogIHJldHVybiBBcnJheS5pc0FycmF5KGl0ZW0pID8gKGl0ZW0gKVsxXSA6IHVuZGVmaW5lZDsKfQoKLyoqIG5vcm1hbGl6ZXMgV2luZG93cyBwYXRocyAqLwpmdW5jdGlvbiBub3JtYWxpemVXaW5kb3dzUGF0aChwYXRoKSB7CiAgcmV0dXJuIHBhdGgKICAgIC5yZXBsYWNlKC9eW0EtWl06LywgJycpIC8vIHJlbW92ZSBXaW5kb3dzLXN0eWxlIHByZWZpeAogICAgLnJlcGxhY2UoL1xcL2csICcvJyk7IC8vIHJlcGxhY2UgYWxsIGBcYCBpbnN0YW5jZXMgd2l0aCBgL2AKfQoKLyoqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGdldHMgdGhlIG1vZHVsZSBuYW1lIGZyb20gYSBmaWxlbmFtZSAqLwpmdW5jdGlvbiBjcmVhdGVHZXRNb2R1bGVGcm9tRmlsZW5hbWUoCiAgYmFzZVBhdGggPSBwcm9jZXNzLmFyZ3ZbMV0gPyBkaXJuYW1lKHByb2Nlc3MuYXJndlsxXSkgOiBwcm9jZXNzLmN3ZCgpLAogIGlzV2luZG93cyA9IHNlcCA9PT0gJ1xcJywKKSB7CiAgY29uc3Qgbm9ybWFsaXplZEJhc2UgPSBpc1dpbmRvd3MgPyBub3JtYWxpemVXaW5kb3dzUGF0aChiYXNlUGF0aCkgOiBiYXNlUGF0aDsKCiAgcmV0dXJuIChmaWxlbmFtZSkgPT4gewogICAgaWYgKCFmaWxlbmFtZSkgewogICAgICByZXR1cm47CiAgICB9CgogICAgY29uc3Qgbm9ybWFsaXplZEZpbGVuYW1lID0gaXNXaW5kb3dzID8gbm9ybWFsaXplV2luZG93c1BhdGgoZmlsZW5hbWUpIDogZmlsZW5hbWU7CgogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1jb25zdAogICAgbGV0IHsgZGlyLCBiYXNlOiBmaWxlLCBleHQgfSA9IHBvc2l4LnBhcnNlKG5vcm1hbGl6ZWRGaWxlbmFtZSk7CgogICAgaWYgKGV4dCA9PT0gJy5qcycgfHwgZXh0ID09PSAnLm1qcycgfHwgZXh0ID09PSAnLmNqcycpIHsKICAgICAgZmlsZSA9IGZpbGUuc2xpY2UoMCwgZXh0Lmxlbmd0aCAqIC0xKTsKICAgIH0KCiAgICBpZiAoIWRpcikgewogICAgICAvLyBObyBkaXJuYW1lIHdoYXRzb2V2ZXIKICAgICAgZGlyID0gJy4nOwogICAgfQoKICAgIGNvbnN0IG4gPSBkaXIubGFzdEluZGV4T2YoJy9ub2RlX21vZHVsZXMnKTsKICAgIGlmIChuID4gLTEpIHsKICAgICAgcmV0dXJuIGAke2Rpci5zbGljZShuICsgMTQpLnJlcGxhY2UoL1wvL2csICcuJyl9OiR7ZmlsZX1gOwogICAgfQoKICAgIC8vIExldCdzIHNlZSBpZiBpdCdzIGEgcGFydCBvZiB0aGUgbWFpbiBtb2R1bGUKICAgIC8vIFRvIGJlIGEgcGFydCBvZiBtYWluIG1vZHVsZSwgaXQgaGFzIHRvIHNoYXJlIHRoZSBzYW1lIGJhc2UKICAgIGlmIChkaXIuc3RhcnRzV2l0aChub3JtYWxpemVkQmFzZSkpIHsKICAgICAgbGV0IG1vZHVsZU5hbWUgPSBkaXIuc2xpY2Uobm9ybWFsaXplZEJhc2UubGVuZ3RoICsgMSkucmVwbGFjZSgvXC8vZywgJy4nKTsKCiAgICAgIGlmIChtb2R1bGVOYW1lKSB7CiAgICAgICAgbW9kdWxlTmFtZSArPSAnOic7CiAgICAgIH0KICAgICAgbW9kdWxlTmFtZSArPSBmaWxlOwoKICAgICAgcmV0dXJuIG1vZHVsZU5hbWU7CiAgICB9CgogICAgcmV0dXJuIGZpbGU7CiAgfTsKfQoKZnVuY3Rpb24gX251bGxpc2hDb2FsZXNjZSQyKGxocywgcmhzRm4pIHsgaWYgKGxocyAhPSBudWxsKSB7IHJldHVybiBsaHM7IH0gZWxzZSB7IHJldHVybiByaHNGbigpOyB9IH0vKioKICogVGhpcyBjb2RlIHdhcyBvcmlnaW5hbGx5IGZvcmtlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9Ub29UYWxsTmF0ZS9wcm94eS1hZ2VudHMvdHJlZS9iMTMzMjk1ZmQxNmY2NDc1NTc4YjZiMTViZDliNGUzM2VjYjBkMGI3CiAqIFdpdGggdGhlIGZvbGxvd2luZyBsaWNlbmNlOgogKgogKiAoVGhlIE1JVCBMaWNlbnNlKQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTMgTmF0aGFuIFJhamxpY2ggPG5hdGhhbkB0b290YWxsbmF0ZS5uZXQ+KgogKgogKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcKICogYSBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlCiAqICdTb2Z0d2FyZScpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcKICogd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLAogKiBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8KICogcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvCiAqIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoqCiAqCiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlCiAqIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLioKICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICdBUyBJUycsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsCiAqIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRgogKiBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuCiAqIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZCiAqIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsCiAqIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFCiAqIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLgogKi8KCmNvbnN0IElOVEVSTkFMID0gU3ltYm9sKCdBZ2VudEJhc2VJbnRlcm5hbFN0YXRlJyk7CgpjbGFzcyBBZ2VudCBleHRlbmRzIGh0dHAuQWdlbnQgewoKICAvLyBTZXQgYnkgYGh0dHAuQWdlbnRgIC0gbWlzc2luZyBmcm9tIGBAdHlwZXMvbm9kZWAKCiAgY29uc3RydWN0b3Iob3B0cykgewogICAgc3VwZXIob3B0cyk7CiAgICB0aGlzW0lOVEVSTkFMXSA9IHt9OwogIH0KCiAgLyoqCiAgICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhpcyBpcyBhbiBgaHR0cGAgb3IgYGh0dHBzYCByZXF1ZXN0LgogICAqLwogIGlzU2VjdXJlRW5kcG9pbnQob3B0aW9ucykgewogICAgaWYgKG9wdGlvbnMpIHsKICAgICAgLy8gRmlyc3QgY2hlY2sgdGhlIGBzZWN1cmVFbmRwb2ludGAgcHJvcGVydHkgZXhwbGljaXRseSwgc2luY2UgdGhpcwogICAgICAvLyBtZWFucyB0aGF0IGEgcGFyZW50IGBBZ2VudGAgaXMgInBhc3NpbmcgdGhyb3VnaCIgdG8gdGhpcyBpbnN0YW5jZS4KICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtbWVtYmVyLWFjY2VzcwogICAgICBpZiAodHlwZW9mIChvcHRpb25zICkuc2VjdXJlRW5kcG9pbnQgPT09ICdib29sZWFuJykgewogICAgICAgIHJldHVybiBvcHRpb25zLnNlY3VyZUVuZHBvaW50OwogICAgICB9CgogICAgICAvLyBJZiBubyBleHBsaWNpdCBgc2VjdXJlYCBlbmRwb2ludCwgY2hlY2sgaWYgYHByb3RvY29sYCBwcm9wZXJ0eSBpcwogICAgICAvLyBzZXQuIFRoaXMgd2lsbCB1c3VhbGx5IGJlIHRoZSBjYXNlIHNpbmNlIHVzaW5nIGEgZnVsbCBzdHJpbmcgVVJMCiAgICAgIC8vIG9yIGBVUkxgIGluc3RhbmNlIHNob3VsZCBiZSB0aGUgbW9zdCBjb21tb24gdXNhZ2UuCiAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5wcm90b2NvbCA9PT0gJ3N0cmluZycpIHsKICAgICAgICByZXR1cm4gb3B0aW9ucy5wcm90b2NvbCA9PT0gJ2h0dHBzOic7CiAgICAgIH0KICAgIH0KCiAgICAvLyBGaW5hbGx5LCBpZiBubyBgcHJvdG9jb2xgIHByb3BlcnR5IHdhcyBzZXQsIHRoZW4gZmFsbCBiYWNrIHRvCiAgICAvLyBjaGVja2luZyB0aGUgc3RhY2sgdHJhY2Ugb2YgdGhlIGN1cnJlbnQgY2FsbCBzdGFjaywgYW5kIHRyeSB0bwogICAgLy8gZGV0ZWN0IHRoZSAiaHR0cHMiIG1vZHVsZS4KICAgIGNvbnN0IHsgc3RhY2sgfSA9IG5ldyBFcnJvcigpOwogICAgaWYgKHR5cGVvZiBzdGFjayAhPT0gJ3N0cmluZycpIHJldHVybiBmYWxzZTsKICAgIHJldHVybiBzdGFjay5zcGxpdCgnXG4nKS5zb21lKGwgPT4gbC5pbmRleE9mKCcoaHR0cHMuanM6JykgIT09IC0xIHx8IGwuaW5kZXhPZignbm9kZTpodHRwczonKSAhPT0gLTEpOwogIH0KCiAgY3JlYXRlU29ja2V0KHJlcSwgb3B0aW9ucywgY2IpIHsKICAgIGNvbnN0IGNvbm5lY3RPcHRzID0gewogICAgICAuLi5vcHRpb25zLAogICAgICBzZWN1cmVFbmRwb2ludDogdGhpcy5pc1NlY3VyZUVuZHBvaW50KG9wdGlvbnMpLAogICAgfTsKICAgIFByb21pc2UucmVzb2x2ZSgpCiAgICAgIC50aGVuKCgpID0+IHRoaXMuY29ubmVjdChyZXEsIGNvbm5lY3RPcHRzKSkKICAgICAgLnRoZW4oc29ja2V0ID0+IHsKICAgICAgICBpZiAoc29ja2V0IGluc3RhbmNlb2YgaHR0cC5BZ2VudCkgewogICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBgYWRkUmVxdWVzdCgpYCBpc24ndCBkZWZpbmVkIGluIGBAdHlwZXMvbm9kZWAKICAgICAgICAgIHJldHVybiBzb2NrZXQuYWRkUmVxdWVzdChyZXEsIGNvbm5lY3RPcHRzKTsKICAgICAgICB9CiAgICAgICAgdGhpc1tJTlRFUk5BTF0uY3VycmVudFNvY2tldCA9IHNvY2tldDsKICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGBjcmVhdGVTb2NrZXQoKWAgaXNuJ3QgZGVmaW5lZCBpbiBgQHR5cGVzL25vZGVgCiAgICAgICAgc3VwZXIuY3JlYXRlU29ja2V0KHJlcSwgb3B0aW9ucywgY2IpOwogICAgICB9LCBjYik7CiAgfQoKICBjcmVhdGVDb25uZWN0aW9uKCkgewogICAgY29uc3Qgc29ja2V0ID0gdGhpc1tJTlRFUk5BTF0uY3VycmVudFNvY2tldDsKICAgIHRoaXNbSU5URVJOQUxdLmN1cnJlbnRTb2NrZXQgPSB1bmRlZmluZWQ7CiAgICBpZiAoIXNvY2tldCkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIHNvY2tldCB3YXMgcmV0dXJuZWQgaW4gdGhlIGBjb25uZWN0KClgIGZ1bmN0aW9uJyk7CiAgICB9CiAgICByZXR1cm4gc29ja2V0OwogIH0KCiAgZ2V0IGRlZmF1bHRQb3J0KCkgewogICAgcmV0dXJuIF9udWxsaXNoQ29hbGVzY2UkMih0aGlzW0lOVEVSTkFMXS5kZWZhdWx0UG9ydCwgKCkgPT4gKCAodGhpcy5wcm90b2NvbCA9PT0gJ2h0dHBzOicgPyA0NDMgOiA4MCkpKTsKICB9CgogIHNldCBkZWZhdWx0UG9ydCh2KSB7CiAgICBpZiAodGhpc1tJTlRFUk5BTF0pIHsKICAgICAgdGhpc1tJTlRFUk5BTF0uZGVmYXVsdFBvcnQgPSB2OwogICAgfQogIH0KCiAgZ2V0IHByb3RvY29sKCkgewogICAgcmV0dXJuIF9udWxsaXNoQ29hbGVzY2UkMih0aGlzW0lOVEVSTkFMXS5wcm90b2NvbCwgKCkgPT4gKCAodGhpcy5pc1NlY3VyZUVuZHBvaW50KCkgPyAnaHR0cHM6JyA6ICdodHRwOicpKSk7CiAgfQoKICBzZXQgcHJvdG9jb2wodikgewogICAgaWYgKHRoaXNbSU5URVJOQUxdKSB7CiAgICAgIHRoaXNbSU5URVJOQUxdLnByb3RvY29sID0gdjsKICAgIH0KICB9Cn0KCmZ1bmN0aW9uIGRlYnVnJDEoLi4uYXJncykgewogIGxvZ2dlci5sb2coJ1todHRwcy1wcm94eS1hZ2VudDpwYXJzZS1wcm94eS1yZXNwb25zZV0nLCAuLi5hcmdzKTsKfQoKZnVuY3Rpb24gcGFyc2VQcm94eVJlc3BvbnNlKHNvY2tldCkgewogIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7CiAgICAvLyB3ZSBuZWVkIHRvIGJ1ZmZlciBhbnkgSFRUUCB0cmFmZmljIHRoYXQgaGFwcGVucyB3aXRoIHRoZSBwcm94eSBiZWZvcmUgd2UgZ2V0CiAgICAvLyB0aGUgQ09OTkVDVCByZXNwb25zZSwgc28gdGhhdCBpZiB0aGUgcmVzcG9uc2UgaXMgYW55dGhpbmcgb3RoZXIgdGhhbiBhbiAiMjAwIgogICAgLy8gcmVzcG9uc2UgY29kZSwgdGhlbiB3ZSBjYW4gcmUtcGxheSB0aGUgImRhdGEiIGV2ZW50cyBvbiB0aGUgc29ja2V0IG9uY2UgdGhlCiAgICAvLyBIVFRQIHBhcnNlciBpcyBob29rZWQgdXAuLi4KICAgIGxldCBidWZmZXJzTGVuZ3RoID0gMDsKICAgIGNvbnN0IGJ1ZmZlcnMgPSBbXTsKCiAgICBmdW5jdGlvbiByZWFkKCkgewogICAgICBjb25zdCBiID0gc29ja2V0LnJlYWQoKTsKICAgICAgaWYgKGIpIG9uZGF0YShiKTsKICAgICAgZWxzZSBzb2NrZXQub25jZSgncmVhZGFibGUnLCByZWFkKTsKICAgIH0KCiAgICBmdW5jdGlvbiBjbGVhbnVwKCkgewogICAgICBzb2NrZXQucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIG9uZW5kKTsKICAgICAgc29ja2V0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpOwogICAgICBzb2NrZXQucmVtb3ZlTGlzdGVuZXIoJ3JlYWRhYmxlJywgcmVhZCk7CiAgICB9CgogICAgZnVuY3Rpb24gb25lbmQoKSB7CiAgICAgIGNsZWFudXAoKTsKICAgICAgZGVidWckMSgnb25lbmQnKTsKICAgICAgcmVqZWN0KG5ldyBFcnJvcignUHJveHkgY29ubmVjdGlvbiBlbmRlZCBiZWZvcmUgcmVjZWl2aW5nIENPTk5FQ1QgcmVzcG9uc2UnKSk7CiAgICB9CgogICAgZnVuY3Rpb24gb25lcnJvcihlcnIpIHsKICAgICAgY2xlYW51cCgpOwogICAgICBkZWJ1ZyQxKCdvbmVycm9yICVvJywgZXJyKTsKICAgICAgcmVqZWN0KGVycik7CiAgICB9CgogICAgZnVuY3Rpb24gb25kYXRhKGIpIHsKICAgICAgYnVmZmVycy5wdXNoKGIpOwogICAgICBidWZmZXJzTGVuZ3RoICs9IGIubGVuZ3RoOwoKICAgICAgY29uc3QgYnVmZmVyZWQgPSBCdWZmZXIuY29uY2F0KGJ1ZmZlcnMsIGJ1ZmZlcnNMZW5ndGgpOwogICAgICBjb25zdCBlbmRPZkhlYWRlcnMgPSBidWZmZXJlZC5pbmRleE9mKCdcclxuXHJcbicpOwoKICAgICAgaWYgKGVuZE9mSGVhZGVycyA9PT0gLTEpIHsKICAgICAgICAvLyBrZWVwIGJ1ZmZlcmluZwogICAgICAgIGRlYnVnJDEoJ2hhdmUgbm90IHJlY2VpdmVkIGVuZCBvZiBIVFRQIGhlYWRlcnMgeWV0Li4uJyk7CiAgICAgICAgcmVhZCgpOwogICAgICAgIHJldHVybjsKICAgICAgfQoKICAgICAgY29uc3QgaGVhZGVyUGFydHMgPSBidWZmZXJlZC5zbGljZSgwLCBlbmRPZkhlYWRlcnMpLnRvU3RyaW5nKCdhc2NpaScpLnNwbGl0KCdcclxuJyk7CiAgICAgIGNvbnN0IGZpcnN0TGluZSA9IGhlYWRlclBhcnRzLnNoaWZ0KCk7CiAgICAgIGlmICghZmlyc3RMaW5lKSB7CiAgICAgICAgc29ja2V0LmRlc3Ryb3koKTsKICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcignTm8gaGVhZGVyIHJlY2VpdmVkIGZyb20gcHJveHkgQ09OTkVDVCByZXNwb25zZScpKTsKICAgICAgfQogICAgICBjb25zdCBmaXJzdExpbmVQYXJ0cyA9IGZpcnN0TGluZS5zcGxpdCgnICcpOwogICAgICBjb25zdCBzdGF0dXNDb2RlID0gK2ZpcnN0TGluZVBhcnRzWzFdOwogICAgICBjb25zdCBzdGF0dXNUZXh0ID0gZmlyc3RMaW5lUGFydHMuc2xpY2UoMikuam9pbignICcpOwogICAgICBjb25zdCBoZWFkZXJzID0ge307CiAgICAgIGZvciAoY29uc3QgaGVhZGVyIG9mIGhlYWRlclBhcnRzKSB7CiAgICAgICAgaWYgKCFoZWFkZXIpIGNvbnRpbnVlOwogICAgICAgIGNvbnN0IGZpcnN0Q29sb24gPSBoZWFkZXIuaW5kZXhPZignOicpOwogICAgICAgIGlmIChmaXJzdENvbG9uID09PSAtMSkgewogICAgICAgICAgc29ja2V0LmRlc3Ryb3koKTsKICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKGBJbnZhbGlkIGhlYWRlciBmcm9tIHByb3h5IENPTk5FQ1QgcmVzcG9uc2U6ICIke2hlYWRlcn0iYCkpOwogICAgICAgIH0KICAgICAgICBjb25zdCBrZXkgPSBoZWFkZXIuc2xpY2UoMCwgZmlyc3RDb2xvbikudG9Mb3dlckNhc2UoKTsKICAgICAgICBjb25zdCB2YWx1ZSA9IGhlYWRlci5zbGljZShmaXJzdENvbG9uICsgMSkudHJpbVN0YXJ0KCk7CiAgICAgICAgY29uc3QgY3VycmVudCA9IGhlYWRlcnNba2V5XTsKICAgICAgICBpZiAodHlwZW9mIGN1cnJlbnQgPT09ICdzdHJpbmcnKSB7CiAgICAgICAgICBoZWFkZXJzW2tleV0gPSBbY3VycmVudCwgdmFsdWVdOwogICAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShjdXJyZW50KSkgewogICAgICAgICAgY3VycmVudC5wdXNoKHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaGVhZGVyc1trZXldID0gdmFsdWU7CiAgICAgICAgfQogICAgICB9CiAgICAgIGRlYnVnJDEoJ2dvdCBwcm94eSBzZXJ2ZXIgcmVzcG9uc2U6ICVvICVvJywgZmlyc3RMaW5lLCBoZWFkZXJzKTsKICAgICAgY2xlYW51cCgpOwogICAgICByZXNvbHZlKHsKICAgICAgICBjb25uZWN0OiB7CiAgICAgICAgICBzdGF0dXNDb2RlLAogICAgICAgICAgc3RhdHVzVGV4dCwKICAgICAgICAgIGhlYWRlcnMsCiAgICAgICAgfSwKICAgICAgICBidWZmZXJlZCwKICAgICAgfSk7CiAgICB9CgogICAgc29ja2V0Lm9uKCdlcnJvcicsIG9uZXJyb3IpOwogICAgc29ja2V0Lm9uKCdlbmQnLCBvbmVuZCk7CgogICAgcmVhZCgpOwogIH0pOwp9CgpmdW5jdGlvbiBfbnVsbGlzaENvYWxlc2NlJDEobGhzLCByaHNGbikgeyBpZiAobGhzICE9IG51bGwpIHsgcmV0dXJuIGxoczsgfSBlbHNlIHsgcmV0dXJuIHJoc0ZuKCk7IH0gfSBmdW5jdGlvbiBfb3B0aW9uYWxDaGFpbiQxKG9wcykgeyBsZXQgbGFzdEFjY2Vzc0xIUyA9IHVuZGVmaW5lZDsgbGV0IHZhbHVlID0gb3BzWzBdOyBsZXQgaSA9IDE7IHdoaWxlIChpIDwgb3BzLmxlbmd0aCkgeyBjb25zdCBvcCA9IG9wc1tpXTsgY29uc3QgZm4gPSBvcHNbaSArIDFdOyBpICs9IDI7IGlmICgob3AgPT09ICdvcHRpb25hbEFjY2VzcycgfHwgb3AgPT09ICdvcHRpb25hbENhbGwnKSAmJiB2YWx1ZSA9PSBudWxsKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gaWYgKG9wID09PSAnYWNjZXNzJyB8fCBvcCA9PT0gJ29wdGlvbmFsQWNjZXNzJykgeyBsYXN0QWNjZXNzTEhTID0gdmFsdWU7IHZhbHVlID0gZm4odmFsdWUpOyB9IGVsc2UgaWYgKG9wID09PSAnY2FsbCcgfHwgb3AgPT09ICdvcHRpb25hbENhbGwnKSB7IHZhbHVlID0gZm4oKC4uLmFyZ3MpID0+IHZhbHVlLmNhbGwobGFzdEFjY2Vzc0xIUywgLi4uYXJncykpOyBsYXN0QWNjZXNzTEhTID0gdW5kZWZpbmVkOyB9IH0gcmV0dXJuIHZhbHVlOyB9CgpmdW5jdGlvbiBkZWJ1ZyguLi5hcmdzKSB7CiAgbG9nZ2VyLmxvZygnW2h0dHBzLXByb3h5LWFnZW50XScsIC4uLmFyZ3MpOwp9CgovKioKICogVGhlIGBIdHRwc1Byb3h5QWdlbnRgIGltcGxlbWVudHMgYW4gSFRUUCBBZ2VudCBzdWJjbGFzcyB0aGF0IGNvbm5lY3RzIHRvCiAqIHRoZSBzcGVjaWZpZWQgIkhUVFAocykgcHJveHkgc2VydmVyIiBpbiBvcmRlciB0byBwcm94eSBIVFRQUyByZXF1ZXN0cy4KICoKICogT3V0Z29pbmcgSFRUUCByZXF1ZXN0cyBhcmUgZmlyc3QgdHVubmVsZWQgdGhyb3VnaCB0aGUgcHJveHkgc2VydmVyIHVzaW5nIHRoZQogKiBgQ09OTkVDVGAgSFRUUCByZXF1ZXN0IG1ldGhvZCB0byBlc3RhYmxpc2ggYSBjb25uZWN0aW9uIHRvIHRoZSBwcm94eSBzZXJ2ZXIsCiAqIGFuZCB0aGVuIHRoZSBwcm94eSBzZXJ2ZXIgY29ubmVjdHMgdG8gdGhlIGRlc3RpbmF0aW9uIHRhcmdldCBhbmQgaXNzdWVzIHRoZQogKiBIVFRQIHJlcXVlc3QgZnJvbSB0aGUgcHJveHkgc2VydmVyLgogKgogKiBgaHR0cHM6YCByZXF1ZXN0cyBoYXZlIHRoZWlyIHNvY2tldCBjb25uZWN0aW9uIHVwZ3JhZGVkIHRvIFRMUyBvbmNlCiAqIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBwcm94eSBzZXJ2ZXIgaGFzIGJlZW4gZXN0YWJsaXNoZWQuCiAqLwpjbGFzcyBIdHRwc1Byb3h5QWdlbnQgZXh0ZW5kcyBBZ2VudCB7CiAgc3RhdGljIF9faW5pdFN0YXRpYygpIHt0aGlzLnByb3RvY29scyA9IFsnaHR0cCcsICdodHRwcyddOyB9CgogIGNvbnN0cnVjdG9yKHByb3h5LCBvcHRzKSB7CiAgICBzdXBlcihvcHRzKTsKICAgIHRoaXMub3B0aW9ucyA9IHt9OwogICAgdGhpcy5wcm94eSA9IHR5cGVvZiBwcm94eSA9PT0gJ3N0cmluZycgPyBuZXcgVVJMKHByb3h5KSA6IHByb3h5OwogICAgdGhpcy5wcm94eUhlYWRlcnMgPSBfbnVsbGlzaENvYWxlc2NlJDEoX29wdGlvbmFsQ2hhaW4kMShbb3B0cywgJ29wdGlvbmFsQWNjZXNzJywgXzIgPT4gXzIuaGVhZGVyc10pLCAoKSA9PiAoIHt9KSk7CiAgICBkZWJ1ZygnQ3JlYXRpbmcgbmV3IEh0dHBzUHJveHlBZ2VudCBpbnN0YW5jZTogJW8nLCB0aGlzLnByb3h5LmhyZWYpOwoKICAgIC8vIFRyaW0gb2ZmIHRoZSBicmFja2V0cyBmcm9tIElQdjYgYWRkcmVzc2VzCiAgICBjb25zdCBob3N0ID0gKHRoaXMucHJveHkuaG9zdG5hbWUgfHwgdGhpcy5wcm94eS5ob3N0KS5yZXBsYWNlKC9eXFt8XF0kL2csICcnKTsKICAgIGNvbnN0IHBvcnQgPSB0aGlzLnByb3h5LnBvcnQgPyBwYXJzZUludCh0aGlzLnByb3h5LnBvcnQsIDEwKSA6IHRoaXMucHJveHkucHJvdG9jb2wgPT09ICdodHRwczonID8gNDQzIDogODA7CiAgICB0aGlzLmNvbm5lY3RPcHRzID0gewogICAgICAvLyBBdHRlbXB0IHRvIG5lZ290aWF0ZSBodHRwLzEuMSBmb3IgcHJveHkgc2VydmVycyB0aGF0IHN1cHBvcnQgaHR0cC8yCiAgICAgIEFMUE5Qcm90b2NvbHM6IFsnaHR0cC8xLjEnXSwKICAgICAgLi4uKG9wdHMgPyBvbWl0KG9wdHMsICdoZWFkZXJzJykgOiBudWxsKSwKICAgICAgaG9zdCwKICAgICAgcG9ydCwKICAgIH07CiAgfQoKICAvKioKICAgKiBDYWxsZWQgd2hlbiB0aGUgbm9kZS1jb3JlIEhUVFAgY2xpZW50IGxpYnJhcnkgaXMgY3JlYXRpbmcgYQogICAqIG5ldyBIVFRQIHJlcXVlc3QuCiAgICovCiAgYXN5bmMgY29ubmVjdChyZXEsIG9wdHMpIHsKICAgIGNvbnN0IHsgcHJveHkgfSA9IHRoaXM7CgogICAgaWYgKCFvcHRzLmhvc3QpIHsKICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignTm8gImhvc3QiIHByb3ZpZGVkJyk7CiAgICB9CgogICAgLy8gQ3JlYXRlIGEgc29ja2V0IGNvbm5lY3Rpb24gdG8gdGhlIHByb3h5IHNlcnZlci4KICAgIGxldCBzb2NrZXQ7CiAgICBpZiAocHJveHkucHJvdG9jb2wgPT09ICdodHRwczonKSB7CiAgICAgIGRlYnVnKCdDcmVhdGluZyBgdGxzLlNvY2tldGA6ICVvJywgdGhpcy5jb25uZWN0T3B0cyk7CiAgICAgIGNvbnN0IHNlcnZlcm5hbWUgPSB0aGlzLmNvbm5lY3RPcHRzLnNlcnZlcm5hbWUgfHwgdGhpcy5jb25uZWN0T3B0cy5ob3N0OwogICAgICBzb2NrZXQgPSB0bHMuY29ubmVjdCh7CiAgICAgICAgLi4udGhpcy5jb25uZWN0T3B0cywKICAgICAgICBzZXJ2ZXJuYW1lOiBzZXJ2ZXJuYW1lICYmIG5ldC5pc0lQKHNlcnZlcm5hbWUpID8gdW5kZWZpbmVkIDogc2VydmVybmFtZSwKICAgICAgfSk7CiAgICB9IGVsc2UgewogICAgICBkZWJ1ZygnQ3JlYXRpbmcgYG5ldC5Tb2NrZXRgOiAlbycsIHRoaXMuY29ubmVjdE9wdHMpOwogICAgICBzb2NrZXQgPSBuZXQuY29ubmVjdCh0aGlzLmNvbm5lY3RPcHRzKTsKICAgIH0KCiAgICBjb25zdCBoZWFkZXJzID0KICAgICAgdHlwZW9mIHRoaXMucHJveHlIZWFkZXJzID09PSAnZnVuY3Rpb24nID8gdGhpcy5wcm94eUhlYWRlcnMoKSA6IHsgLi4udGhpcy5wcm94eUhlYWRlcnMgfTsKICAgIGNvbnN0IGhvc3QgPSBuZXQuaXNJUHY2KG9wdHMuaG9zdCkgPyBgWyR7b3B0cy5ob3N0fV1gIDogb3B0cy5ob3N0OwogICAgbGV0IHBheWxvYWQgPSBgQ09OTkVDVCAke2hvc3R9OiR7b3B0cy5wb3J0fSBIVFRQLzEuMVxyXG5gOwoKICAgIC8vIEluamVjdCB0aGUgYFByb3h5LUF1dGhvcml6YXRpb25gIGhlYWRlciBpZiBuZWNlc3NhcnkuCiAgICBpZiAocHJveHkudXNlcm5hbWUgfHwgcHJveHkucGFzc3dvcmQpIHsKICAgICAgY29uc3QgYXV0aCA9IGAke2RlY29kZVVSSUNvbXBvbmVudChwcm94eS51c2VybmFtZSl9OiR7ZGVjb2RlVVJJQ29tcG9uZW50KHByb3h5LnBhc3N3b3JkKX1gOwogICAgICBoZWFkZXJzWydQcm94eS1BdXRob3JpemF0aW9uJ10gPSBgQmFzaWMgJHtCdWZmZXIuZnJvbShhdXRoKS50b1N0cmluZygnYmFzZTY0Jyl9YDsKICAgIH0KCiAgICBoZWFkZXJzLkhvc3QgPSBgJHtob3N0fToke29wdHMucG9ydH1gOwoKICAgIGlmICghaGVhZGVyc1snUHJveHktQ29ubmVjdGlvbiddKSB7CiAgICAgIGhlYWRlcnNbJ1Byb3h5LUNvbm5lY3Rpb24nXSA9IHRoaXMua2VlcEFsaXZlID8gJ0tlZXAtQWxpdmUnIDogJ2Nsb3NlJzsKICAgIH0KICAgIGZvciAoY29uc3QgbmFtZSBvZiBPYmplY3Qua2V5cyhoZWFkZXJzKSkgewogICAgICBwYXlsb2FkICs9IGAke25hbWV9OiAke2hlYWRlcnNbbmFtZV19XHJcbmA7CiAgICB9CgogICAgY29uc3QgcHJveHlSZXNwb25zZVByb21pc2UgPSBwYXJzZVByb3h5UmVzcG9uc2Uoc29ja2V0KTsKCiAgICBzb2NrZXQud3JpdGUoYCR7cGF5bG9hZH1cclxuYCk7CgogICAgY29uc3QgeyBjb25uZWN0LCBidWZmZXJlZCB9ID0gYXdhaXQgcHJveHlSZXNwb25zZVByb21pc2U7CiAgICByZXEuZW1pdCgncHJveHlDb25uZWN0JywgY29ubmVjdCk7CiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L2Jhbi10cy1jb21tZW50CiAgICAvLyBAdHMtaWdub3JlIE5vdCBFdmVudEVtaXR0ZXIgaW4gTm9kZSB0eXBlcwogICAgdGhpcy5lbWl0KCdwcm94eUNvbm5lY3QnLCBjb25uZWN0LCByZXEpOwoKICAgIGlmIChjb25uZWN0LnN0YXR1c0NvZGUgPT09IDIwMCkgewogICAgICByZXEub25jZSgnc29ja2V0JywgcmVzdW1lKTsKCiAgICAgIGlmIChvcHRzLnNlY3VyZUVuZHBvaW50KSB7CiAgICAgICAgLy8gVGhlIHByb3h5IGlzIGNvbm5lY3RpbmcgdG8gYSBUTFMgc2VydmVyLCBzbyB1cGdyYWRlCiAgICAgICAgLy8gdGhpcyBzb2NrZXQgY29ubmVjdGlvbiB0byBhIFRMUyBjb25uZWN0aW9uLgogICAgICAgIGRlYnVnKCdVcGdyYWRpbmcgc29ja2V0IGNvbm5lY3Rpb24gdG8gVExTJyk7CiAgICAgICAgY29uc3Qgc2VydmVybmFtZSA9IG9wdHMuc2VydmVybmFtZSB8fCBvcHRzLmhvc3Q7CiAgICAgICAgcmV0dXJuIHRscy5jb25uZWN0KHsKICAgICAgICAgIC4uLm9taXQob3B0cywgJ2hvc3QnLCAncGF0aCcsICdwb3J0JyksCiAgICAgICAgICBzb2NrZXQsCiAgICAgICAgICBzZXJ2ZXJuYW1lOiBuZXQuaXNJUChzZXJ2ZXJuYW1lKSA/IHVuZGVmaW5lZCA6IHNlcnZlcm5hbWUsCiAgICAgICAgfSk7CiAgICAgIH0KCiAgICAgIHJldHVybiBzb2NrZXQ7CiAgICB9CgogICAgLy8gU29tZSBvdGhlciBzdGF0dXMgY29kZSB0aGF0J3Mgbm90IDIwMC4uLiBuZWVkIHRvIHJlLXBsYXkgdGhlIEhUVFAKICAgIC8vIGhlYWRlciAiZGF0YSIgZXZlbnRzIG9udG8gdGhlIHNvY2tldCBvbmNlIHRoZSBIVFRQIG1hY2hpbmVyeSBpcwogICAgLy8gYXR0YWNoZWQgc28gdGhhdCB0aGUgbm9kZSBjb3JlIGBodHRwYCBjYW4gcGFyc2UgYW5kIGhhbmRsZSB0aGUKICAgIC8vIGVycm9yIHN0YXR1cyBjb2RlLgoKICAgIC8vIENsb3NlIHRoZSBvcmlnaW5hbCBzb2NrZXQsIGFuZCBhIG5ldyAiZmFrZSIgc29ja2V0IGlzIHJldHVybmVkCiAgICAvLyBpbnN0ZWFkLCBzbyB0aGF0IHRoZSBwcm94eSBkb2Vzbid0IGdldCB0aGUgSFRUUCByZXF1ZXN0CiAgICAvLyB3cml0dGVuIHRvIGl0ICh3aGljaCBtYXkgY29udGFpbiBgQXV0aG9yaXphdGlvbmAgaGVhZGVycyBvciBvdGhlcgogICAgLy8gc2Vuc2l0aXZlIGRhdGEpLgogICAgLy8KICAgIC8vIFNlZTogaHR0cHM6Ly9oYWNrZXJvbmUuY29tL3JlcG9ydHMvNTQxNTAyCiAgICBzb2NrZXQuZGVzdHJveSgpOwoKICAgIGNvbnN0IGZha2VTb2NrZXQgPSBuZXcgbmV0LlNvY2tldCh7IHdyaXRhYmxlOiBmYWxzZSB9KTsKICAgIGZha2VTb2NrZXQucmVhZGFibGUgPSB0cnVlOwoKICAgIC8vIE5lZWQgdG8gd2FpdCBmb3IgdGhlICJzb2NrZXQiIGV2ZW50IHRvIHJlLXBsYXkgdGhlICJkYXRhIiBldmVudHMuCiAgICByZXEub25jZSgnc29ja2V0JywgKHMpID0+IHsKICAgICAgZGVidWcoJ1JlcGxheWluZyBwcm94eSBidWZmZXIgZm9yIGZhaWxlZCByZXF1ZXN0Jyk7CiAgICAgIC8vIFJlcGxheSB0aGUgImJ1ZmZlcmVkIiBCdWZmZXIgb250byB0aGUgZmFrZSBgc29ja2V0YCwgc2luY2UgYXQKICAgICAgLy8gdGhpcyBwb2ludCB0aGUgSFRUUCBtb2R1bGUgbWFjaGluZXJ5IGhhcyBiZWVuIGhvb2tlZCB1cCBmb3IKICAgICAgLy8gdGhlIHVzZXIuCiAgICAgIHMucHVzaChidWZmZXJlZCk7CiAgICAgIHMucHVzaChudWxsKTsKICAgIH0pOwoKICAgIHJldHVybiBmYWtlU29ja2V0OwogIH0KfSBIdHRwc1Byb3h5QWdlbnQuX19pbml0U3RhdGljKCk7CgpmdW5jdGlvbiByZXN1bWUoc29ja2V0KSB7CiAgc29ja2V0LnJlc3VtZSgpOwp9CgpmdW5jdGlvbiBvbWl0KAogIG9iaiwKICAuLi5rZXlzCikKCiB7CiAgY29uc3QgcmV0ID0ge30KCjsKICBsZXQga2V5OwogIGZvciAoa2V5IGluIG9iaikgewogICAgaWYgKCFrZXlzLmluY2x1ZGVzKGtleSkpIHsKICAgICAgcmV0W2tleV0gPSBvYmpba2V5XTsKICAgIH0KICB9CiAgcmV0dXJuIHJldDsKfQoKZnVuY3Rpb24gX251bGxpc2hDb2FsZXNjZShsaHMsIHJoc0ZuKSB7IGlmIChsaHMgIT0gbnVsbCkgeyByZXR1cm4gbGhzOyB9IGVsc2UgeyByZXR1cm4gcmhzRm4oKTsgfSB9Ci8vIEVzdGltYXRlZCBtYXhpbXVtIHNpemUgZm9yIHJlYXNvbmFibGUgc3RhbmRhbG9uZSBldmVudApjb25zdCBHWklQX1RIUkVTSE9MRCA9IDEwMjQgKiAzMjsKCi8qKgogKiBHZXRzIGEgc3RyZWFtIGZyb20gYSBVaW50OEFycmF5IG9yIHN0cmluZwogKiBSZWFkYWJsZS5mcm9tIGlzIGlkZWFsIGJ1dCB3YXMgYWRkZWQgaW4gbm9kZS5qcyB2MTIuMy4wIGFuZCB2MTAuMTcuMAogKi8KZnVuY3Rpb24gc3RyZWFtRnJvbUJvZHkoYm9keSkgewogIHJldHVybiBuZXcgUmVhZGFibGUoewogICAgcmVhZCgpIHsKICAgICAgdGhpcy5wdXNoKGJvZHkpOwogICAgICB0aGlzLnB1c2gobnVsbCk7CiAgICB9LAogIH0pOwp9CgovKioKICogQ3JlYXRlcyBhIFRyYW5zcG9ydCB0aGF0IHVzZXMgbmF0aXZlIHRoZSBuYXRpdmUgJ2h0dHAnIGFuZCAnaHR0cHMnIG1vZHVsZXMgdG8gc2VuZCBldmVudHMgdG8gU2VudHJ5LgogKi8KZnVuY3Rpb24gbWFrZU5vZGVUcmFuc3BvcnQob3B0aW9ucykgewogIGxldCB1cmxTZWdtZW50czsKCiAgdHJ5IHsKICAgIHVybFNlZ21lbnRzID0gbmV3IFVSTChvcHRpb25zLnVybCk7CiAgfSBjYXRjaCAoZSkgewogICAgY29uc29sZVNhbmRib3goKCkgPT4gewogICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZQogICAgICBjb25zb2xlLndhcm4oCiAgICAgICAgJ1tAc2VudHJ5L25vZGVdOiBJbnZhbGlkIGRzbiBvciB0dW5uZWwgb3B0aW9uLCB3aWxsIG5vdCBzZW5kIGFueSBldmVudHMuIFRoZSB0dW5uZWwgb3B0aW9uIG11c3QgYmUgYSBmdWxsIFVSTCB3aGVuIHVzZWQuJywKICAgICAgKTsKICAgIH0pOwogICAgcmV0dXJuIGNyZWF0ZVRyYW5zcG9ydChvcHRpb25zLCAoKSA9PiBQcm9taXNlLnJlc29sdmUoe30pKTsKICB9CgogIGNvbnN0IGlzSHR0cHMgPSB1cmxTZWdtZW50cy5wcm90b2NvbCA9PT0gJ2h0dHBzOic7CgogIC8vIFByb3h5IHByaW9yaXRpemF0aW9uOiBodHRwID0+IGBvcHRpb25zLnByb3h5YCB8IGBwcm9jZXNzLmVudi5odHRwX3Byb3h5YAogIC8vIFByb3h5IHByaW9yaXRpemF0aW9uOiBodHRwcyA9PiBgb3B0aW9ucy5wcm94eWAgfCBgcHJvY2Vzcy5lbnYuaHR0cHNfcHJveHlgIHwgYHByb2Nlc3MuZW52Lmh0dHBfcHJveHlgCiAgY29uc3QgcHJveHkgPSBhcHBseU5vUHJveHlPcHRpb24oCiAgICB1cmxTZWdtZW50cywKICAgIG9wdGlvbnMucHJveHkgfHwgKGlzSHR0cHMgPyBwcm9jZXNzLmVudi5odHRwc19wcm94eSA6IHVuZGVmaW5lZCkgfHwgcHJvY2Vzcy5lbnYuaHR0cF9wcm94eSwKICApOwoKICBjb25zdCBuYXRpdmVIdHRwTW9kdWxlID0gaXNIdHRwcyA/IGh0dHBzIDogaHR0cDsKICBjb25zdCBrZWVwQWxpdmUgPSBvcHRpb25zLmtlZXBBbGl2ZSA9PT0gdW5kZWZpbmVkID8gZmFsc2UgOiBvcHRpb25zLmtlZXBBbGl2ZTsKCiAgLy8gVE9ETyh2Nyk6IEV2YWx1YXRlIGlmIHdlIGNhbiBzZXQga2VlcEFsaXZlIHRvIHRydWUuIFRoaXMgd291bGQgaW52b2x2ZSB0ZXN0aW5nIGZvciBtZW1vcnkgbGVha3MgaW4gb2xkZXIgbm9kZQogIC8vIHZlcnNpb25zKD49IDgpIGFzIHRoZXkgaGFkIG1lbW9yeSBsZWFrcyB3aGVuIHVzaW5nIGl0OiAjMjU1NQogIGNvbnN0IGFnZW50ID0gcHJveHkKICAgID8gKG5ldyBIdHRwc1Byb3h5QWdlbnQocHJveHkpICkKICAgIDogbmV3IG5hdGl2ZUh0dHBNb2R1bGUuQWdlbnQoeyBrZWVwQWxpdmUsIG1heFNvY2tldHM6IDMwLCB0aW1lb3V0OiAyMDAwIH0pOwoKICBjb25zdCByZXF1ZXN0RXhlY3V0b3IgPSBjcmVhdGVSZXF1ZXN0RXhlY3V0b3Iob3B0aW9ucywgX251bGxpc2hDb2FsZXNjZShvcHRpb25zLmh0dHBNb2R1bGUsICgpID0+ICggbmF0aXZlSHR0cE1vZHVsZSkpLCBhZ2VudCk7CiAgcmV0dXJuIGNyZWF0ZVRyYW5zcG9ydChvcHRpb25zLCByZXF1ZXN0RXhlY3V0b3IpOwp9CgovKioKICogSG9ub3JzIHRoZSBgbm9fcHJveHlgIGVudiB2YXJpYWJsZSB3aXRoIHRoZSBoaWdoZXN0IHByaW9yaXR5IHRvIGFsbG93IGZvciBob3N0cyBleGNsdXNpb24uCiAqCiAqIEBwYXJhbSB0cmFuc3BvcnRVcmwgVGhlIFVSTCB0aGUgdHJhbnNwb3J0IGludGVuZHMgdG8gc2VuZCBldmVudHMgdG8uCiAqIEBwYXJhbSBwcm94eSBUaGUgY2xpZW50IGNvbmZpZ3VyZWQgcHJveHkuCiAqIEByZXR1cm5zIEEgcHJveHkgdGhlIHRyYW5zcG9ydCBzaG91bGQgdXNlLgogKi8KZnVuY3Rpb24gYXBwbHlOb1Byb3h5T3B0aW9uKHRyYW5zcG9ydFVybFNlZ21lbnRzLCBwcm94eSkgewogIGNvbnN0IHsgbm9fcHJveHkgfSA9IHByb2Nlc3MuZW52OwoKICBjb25zdCB1cmxJc0V4ZW1wdEZyb21Qcm94eSA9CiAgICBub19wcm94eSAmJgogICAgbm9fcHJveHkKICAgICAgLnNwbGl0KCcsJykKICAgICAgLnNvbWUoCiAgICAgICAgZXhlbXB0aW9uID0+IHRyYW5zcG9ydFVybFNlZ21lbnRzLmhvc3QuZW5kc1dpdGgoZXhlbXB0aW9uKSB8fCB0cmFuc3BvcnRVcmxTZWdtZW50cy5ob3N0bmFtZS5lbmRzV2l0aChleGVtcHRpb24pLAogICAgICApOwoKICBpZiAodXJsSXNFeGVtcHRGcm9tUHJveHkpIHsKICAgIHJldHVybiB1bmRlZmluZWQ7CiAgfSBlbHNlIHsKICAgIHJldHVybiBwcm94eTsKICB9Cn0KCi8qKgogKiBDcmVhdGVzIGEgUmVxdWVzdEV4ZWN1dG9yIHRvIGJlIHVzZWQgd2l0aCBgY3JlYXRlVHJhbnNwb3J0YC4KICovCmZ1bmN0aW9uIGNyZWF0ZVJlcXVlc3RFeGVjdXRvcigKICBvcHRpb25zLAogIGh0dHBNb2R1bGUsCiAgYWdlbnQsCikgewogIGNvbnN0IHsgaG9zdG5hbWUsIHBhdGhuYW1lLCBwb3J0LCBwcm90b2NvbCwgc2VhcmNoIH0gPSBuZXcgVVJMKG9wdGlvbnMudXJsKTsKICByZXR1cm4gZnVuY3Rpb24gbWFrZVJlcXVlc3QocmVxdWVzdCkgewogICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHsKICAgICAgbGV0IGJvZHkgPSBzdHJlYW1Gcm9tQm9keShyZXF1ZXN0LmJvZHkpOwoKICAgICAgY29uc3QgaGVhZGVycyA9IHsgLi4ub3B0aW9ucy5oZWFkZXJzIH07CgogICAgICBpZiAocmVxdWVzdC5ib2R5Lmxlbmd0aCA+IEdaSVBfVEhSRVNIT0xEKSB7CiAgICAgICAgaGVhZGVyc1snY29udGVudC1lbmNvZGluZyddID0gJ2d6aXAnOwogICAgICAgIGJvZHkgPSBib2R5LnBpcGUoY3JlYXRlR3ppcCgpKTsKICAgICAgfQoKICAgICAgY29uc3QgcmVxID0gaHR0cE1vZHVsZS5yZXF1ZXN0KAogICAgICAgIHsKICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLAogICAgICAgICAgYWdlbnQsCiAgICAgICAgICBoZWFkZXJzLAogICAgICAgICAgaG9zdG5hbWUsCiAgICAgICAgICBwYXRoOiBgJHtwYXRobmFtZX0ke3NlYXJjaH1gLAogICAgICAgICAgcG9ydCwKICAgICAgICAgIHByb3RvY29sLAogICAgICAgICAgY2E6IG9wdGlvbnMuY2FDZXJ0cywKICAgICAgICB9LAogICAgICAgIHJlcyA9PiB7CiAgICAgICAgICByZXMub24oJ2RhdGEnLCAoKSA9PiB7CiAgICAgICAgICAgIC8vIERyYWluIHNvY2tldAogICAgICAgICAgfSk7CgogICAgICAgICAgcmVzLm9uKCdlbmQnLCAoKSA9PiB7CiAgICAgICAgICAgIC8vIERyYWluIHNvY2tldAogICAgICAgICAgfSk7CgogICAgICAgICAgcmVzLnNldEVuY29kaW5nKCd1dGY4Jyk7CgogICAgICAgICAgLy8gIktleS12YWx1ZSBwYWlycyBvZiBoZWFkZXIgbmFtZXMgYW5kIHZhbHVlcy4gSGVhZGVyIG5hbWVzIGFyZSBsb3dlci1jYXNlZC4iCiAgICAgICAgICAvLyBodHRwczovL25vZGVqcy5vcmcvYXBpL2h0dHAuaHRtbCNodHRwX21lc3NhZ2VfaGVhZGVycwogICAgICAgICAgY29uc3QgcmV0cnlBZnRlckhlYWRlciA9IF9udWxsaXNoQ29hbGVzY2UocmVzLmhlYWRlcnNbJ3JldHJ5LWFmdGVyJ10sICgpID0+ICggbnVsbCkpOwogICAgICAgICAgY29uc3QgcmF0ZUxpbWl0c0hlYWRlciA9IF9udWxsaXNoQ29hbGVzY2UocmVzLmhlYWRlcnNbJ3gtc2VudHJ5LXJhdGUtbGltaXRzJ10sICgpID0+ICggbnVsbCkpOwoKICAgICAgICAgIHJlc29sdmUoewogICAgICAgICAgICBzdGF0dXNDb2RlOiByZXMuc3RhdHVzQ29kZSwKICAgICAgICAgICAgaGVhZGVyczogewogICAgICAgICAgICAgICdyZXRyeS1hZnRlcic6IHJldHJ5QWZ0ZXJIZWFkZXIsCiAgICAgICAgICAgICAgJ3gtc2VudHJ5LXJhdGUtbGltaXRzJzogQXJyYXkuaXNBcnJheShyYXRlTGltaXRzSGVhZGVyKSA/IHJhdGVMaW1pdHNIZWFkZXJbMF0gOiByYXRlTGltaXRzSGVhZGVyLAogICAgICAgICAgICB9LAogICAgICAgICAgfSk7CiAgICAgICAgfSwKICAgICAgKTsKCiAgICAgIHJlcS5vbignZXJyb3InLCByZWplY3QpOwogICAgICBib2R5LnBpcGUocmVxKTsKICAgIH0pOwogIH07Cn0KCmZ1bmN0aW9uIF9vcHRpb25hbENoYWluKG9wcykgeyBsZXQgbGFzdEFjY2Vzc0xIUyA9IHVuZGVmaW5lZDsgbGV0IHZhbHVlID0gb3BzWzBdOyBsZXQgaSA9IDE7IHdoaWxlIChpIDwgb3BzLmxlbmd0aCkgeyBjb25zdCBvcCA9IG9wc1tpXTsgY29uc3QgZm4gPSBvcHNbaSArIDFdOyBpICs9IDI7IGlmICgob3AgPT09ICdvcHRpb25hbEFjY2VzcycgfHwgb3AgPT09ICdvcHRpb25hbENhbGwnKSAmJiB2YWx1ZSA9PSBudWxsKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gaWYgKG9wID09PSAnYWNjZXNzJyB8fCBvcCA9PT0gJ29wdGlvbmFsQWNjZXNzJykgeyBsYXN0QWNjZXNzTEhTID0gdmFsdWU7IHZhbHVlID0gZm4odmFsdWUpOyB9IGVsc2UgaWYgKG9wID09PSAnY2FsbCcgfHwgb3AgPT09ICdvcHRpb25hbENhbGwnKSB7IHZhbHVlID0gZm4oKC4uLmFyZ3MpID0+IHZhbHVlLmNhbGwobGFzdEFjY2Vzc0xIUywgLi4uYXJncykpOyBsYXN0QWNjZXNzTEhTID0gdW5kZWZpbmVkOyB9IH0gcmV0dXJuIHZhbHVlOyB9CmNvbnN0IG9wdGlvbnMgPSB3b3JrZXJEYXRhOwpsZXQgc2Vzc2lvbjsKbGV0IGhhc1NlbnRBbnJFdmVudCA9IGZhbHNlOwoKZnVuY3Rpb24gbG9nKG1zZykgewogIGlmIChvcHRpb25zLmRlYnVnKSB7CiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZQogICAgY29uc29sZS5sb2coYFtBTlIgV29ya2VyXSAke21zZ31gKTsKICB9Cn0KCmNvbnN0IHVybCA9IGdldEVudmVsb3BlRW5kcG9pbnRXaXRoVXJsRW5jb2RlZEF1dGgob3B0aW9ucy5kc24pOwpjb25zdCB0cmFuc3BvcnQgPSBtYWtlTm9kZVRyYW5zcG9ydCh7CiAgdXJsLAogIHJlY29yZERyb3BwZWRFdmVudDogKCkgPT4gewogICAgLy8KICB9LAp9KTsKCmFzeW5jIGZ1bmN0aW9uIHNlbmRBYm5vcm1hbFNlc3Npb24oKSB7CiAgLy8gb2Ygd2UgaGF2ZSBhbiBleGlzdGluZyBzZXNzaW9uIHBhc3NlZCBmcm9tIHRoZSBtYWluIHRocmVhZCwgc2VuZCBpdCBhcyBhYm5vcm1hbAogIGlmIChzZXNzaW9uKSB7CiAgICBsb2coJ1NlbmRpbmcgYWJub3JtYWwgc2Vzc2lvbicpOwogICAgdXBkYXRlU2Vzc2lvbihzZXNzaW9uLCB7IHN0YXR1czogJ2Fibm9ybWFsJywgYWJub3JtYWxfbWVjaGFuaXNtOiAnYW5yX2ZvcmVncm91bmQnIH0pOwoKICAgIGNvbnN0IGVudmVsb3BlID0gY3JlYXRlU2Vzc2lvbkVudmVsb3BlKHNlc3Npb24sIG9wdGlvbnMuZHNuLCBvcHRpb25zLnNka01ldGFkYXRhKTsKICAgIC8vIExvZyB0aGUgZW52ZWxvcGUgc28gdG8gYWlkIGluIHRlc3RpbmcKICAgIGxvZyhKU09OLnN0cmluZ2lmeShlbnZlbG9wZSkpOwoKICAgIGF3YWl0IHRyYW5zcG9ydC5zZW5kKGVudmVsb3BlKTsKCiAgICB0cnkgewogICAgICAvLyBOb3RpZnkgdGhlIG1haW4gcHJvY2VzcyB0aGF0IHRoZSBzZXNzaW9uIGhhcyBlbmRlZCBzbyB0aGUgc2Vzc2lvbiBjYW4gYmUgY2xlYXJlZCBmcm9tIHRoZSBzY29wZQogICAgICBfb3B0aW9uYWxDaGFpbihbcGFyZW50UG9ydCwgJ29wdGlvbmFsQWNjZXNzJywgXzIgPT4gXzIucG9zdE1lc3NhZ2UsICdjYWxsJywgXzMgPT4gXzMoJ3Nlc3Npb24tZW5kZWQnKV0pOwogICAgfSBjYXRjaCAoXykgewogICAgICAvLyBpZ25vcmUKICAgIH0KICB9Cn0KCmxvZygnU3RhcnRlZCcpOwoKZnVuY3Rpb24gcHJlcGFyZVN0YWNrRnJhbWVzKHN0YWNrRnJhbWVzKSB7CiAgaWYgKCFzdGFja0ZyYW1lcykgewogICAgcmV0dXJuIHVuZGVmaW5lZDsKICB9CgogIC8vIFN0cmlwIFNlbnRyeSBmcmFtZXMgYW5kIHJldmVyc2UgdGhlIHN0YWNrIGZyYW1lcyBzbyB0aGV5IGFyZSBpbiB0aGUgY29ycmVjdCBvcmRlcgogIGNvbnN0IHN0cmlwcGVkRnJhbWVzID0gc3RyaXBTZW50cnlGcmFtZXNBbmRSZXZlcnNlKHN0YWNrRnJhbWVzKTsKCiAgLy8gSWYgd2UgaGF2ZSBhbiBhcHAgcm9vdCBwYXRoLCByZXdyaXRlIHRoZSBmaWxlbmFtZXMgdG8gYmUgcmVsYXRpdmUgdG8gdGhlIGFwcCByb290CiAgaWYgKG9wdGlvbnMuYXBwUm9vdFBhdGgpIHsKICAgIGZvciAoY29uc3QgZnJhbWUgb2Ygc3RyaXBwZWRGcmFtZXMpIHsKICAgICAgaWYgKCFmcmFtZS5maWxlbmFtZSkgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CgogICAgICBmcmFtZS5maWxlbmFtZSA9IG5vcm1hbGl6ZVVybFRvQmFzZShmcmFtZS5maWxlbmFtZSwgb3B0aW9ucy5hcHBSb290UGF0aCk7CiAgICB9CiAgfQoKICByZXR1cm4gc3RyaXBwZWRGcmFtZXM7Cn0KCmFzeW5jIGZ1bmN0aW9uIHNlbmRBbnJFdmVudChmcmFtZXMsIHRyYWNlQ29udGV4dCkgewogIGlmIChoYXNTZW50QW5yRXZlbnQpIHsKICAgIHJldHVybjsKICB9CgogIGhhc1NlbnRBbnJFdmVudCA9IHRydWU7CgogIGF3YWl0IHNlbmRBYm5vcm1hbFNlc3Npb24oKTsKCiAgbG9nKCdTZW5kaW5nIGV2ZW50Jyk7CgogIGNvbnN0IGV2ZW50ID0gewogICAgZXZlbnRfaWQ6IHV1aWQ0KCksCiAgICBjb250ZXh0czogeyAuLi5vcHRpb25zLmNvbnRleHRzLCB0cmFjZTogdHJhY2VDb250ZXh0IH0sCiAgICByZWxlYXNlOiBvcHRpb25zLnJlbGVhc2UsCiAgICBlbnZpcm9ubWVudDogb3B0aW9ucy5lbnZpcm9ubWVudCwKICAgIGRpc3Q6IG9wdGlvbnMuZGlzdCwKICAgIHBsYXRmb3JtOiAnbm9kZScsCiAgICBsZXZlbDogJ2Vycm9yJywKICAgIGV4Y2VwdGlvbjogewogICAgICB2YWx1ZXM6IFsKICAgICAgICB7CiAgICAgICAgICB0eXBlOiAnQXBwbGljYXRpb25Ob3RSZXNwb25kaW5nJywKICAgICAgICAgIHZhbHVlOiBgQXBwbGljYXRpb24gTm90IFJlc3BvbmRpbmcgZm9yIGF0IGxlYXN0ICR7b3B0aW9ucy5hbnJUaHJlc2hvbGR9IG1zYCwKICAgICAgICAgIHN0YWNrdHJhY2U6IHsgZnJhbWVzOiBwcmVwYXJlU3RhY2tGcmFtZXMoZnJhbWVzKSB9LAogICAgICAgICAgLy8gVGhpcyBlbnN1cmVzIHRoZSBVSSBkb2Vzbid0IHNheSAnQ3Jhc2hlZCBpbicgZm9yIHRoZSBzdGFjayB0cmFjZQogICAgICAgICAgbWVjaGFuaXNtOiB7IHR5cGU6ICdBTlInIH0sCiAgICAgICAgfSwKICAgICAgXSwKICAgIH0sCiAgICB0YWdzOiBvcHRpb25zLnN0YXRpY1RhZ3MsCiAgfTsKCiAgY29uc3QgZW52ZWxvcGUgPSBjcmVhdGVFdmVudEVudmVsb3BlKGV2ZW50LCBvcHRpb25zLmRzbiwgb3B0aW9ucy5zZGtNZXRhZGF0YSk7CiAgLy8gTG9nIHRoZSBlbnZlbG9wZSBzbyB0byBhaWQgaW4gdGVzdGluZwogIGxvZyhKU09OLnN0cmluZ2lmeShlbnZlbG9wZSkpOwoKICBhd2FpdCB0cmFuc3BvcnQuc2VuZChlbnZlbG9wZSk7CiAgYXdhaXQgdHJhbnNwb3J0LmZsdXNoKDIwMDApOwoKICAvLyBEZWxheSBmb3IgNSBzZWNvbmRzIHNvIHRoYXQgc3RkaW8gY2FuIGZsdXNoIGluIHRoZSBtYWluIGV2ZW50IGxvb3AgZXZlciByZXN0YXJ0cy4KICAvLyBUaGlzIGlzIG1haW5seSBmb3IgdGhlIGJlbmVmaXQgb2YgbG9nZ2luZy9kZWJ1Z2dpbmcgaXNzdWVzLgogIHNldFRpbWVvdXQoKCkgPT4gewogICAgcHJvY2Vzcy5leGl0KDApOwogIH0sIDUwMDApOwp9CgpsZXQgZGVidWdnZXJQYXVzZTsKCmlmIChvcHRpb25zLmNhcHR1cmVTdGFja1RyYWNlKSB7CiAgbG9nKCdDb25uZWN0aW5nIHRvIGRlYnVnZ2VyJyk7CgogIGNvbnN0IHNlc3Npb24gPSBuZXcgU2Vzc2lvbigpIDsKICBzZXNzaW9uLmNvbm5lY3RUb01haW5UaHJlYWQoKTsKCiAgbG9nKCdDb25uZWN0ZWQgdG8gZGVidWdnZXInKTsKCiAgLy8gQ29sbGVjdCBzY3JpcHRJZCAtPiB1cmwgbWFwIHNvIHdlIGNhbiBsb29rIHVwIHRoZSBmaWxlbmFtZXMgbGF0ZXIKICBjb25zdCBzY3JpcHRzID0gbmV3IE1hcCgpOwoKICBzZXNzaW9uLm9uKCdEZWJ1Z2dlci5zY3JpcHRQYXJzZWQnLCBldmVudCA9PiB7CiAgICBzY3JpcHRzLnNldChldmVudC5wYXJhbXMuc2NyaXB0SWQsIGV2ZW50LnBhcmFtcy51cmwpOwogIH0pOwoKICBzZXNzaW9uLm9uKCdEZWJ1Z2dlci5wYXVzZWQnLCBldmVudCA9PiB7CiAgICBpZiAoZXZlbnQucGFyYW1zLnJlYXNvbiAhPT0gJ290aGVyJykgewogICAgICByZXR1cm47CiAgICB9CgogICAgdHJ5IHsKICAgICAgbG9nKCdEZWJ1Z2dlciBwYXVzZWQnKTsKCiAgICAgIC8vIGNvcHkgdGhlIGZyYW1lcwogICAgICBjb25zdCBjYWxsRnJhbWVzID0gWy4uLmV2ZW50LnBhcmFtcy5jYWxsRnJhbWVzXTsKCiAgICAgIGNvbnN0IGdldE1vZHVsZU5hbWUgPSBvcHRpb25zLmFwcFJvb3RQYXRoID8gY3JlYXRlR2V0TW9kdWxlRnJvbUZpbGVuYW1lKG9wdGlvbnMuYXBwUm9vdFBhdGgpIDogKCkgPT4gdW5kZWZpbmVkOwogICAgICBjb25zdCBzdGFja0ZyYW1lcyA9IGNhbGxGcmFtZXMubWFwKGZyYW1lID0+CiAgICAgICAgY2FsbEZyYW1lVG9TdGFja0ZyYW1lKGZyYW1lLCBzY3JpcHRzLmdldChmcmFtZS5sb2NhdGlvbi5zY3JpcHRJZCksIGdldE1vZHVsZU5hbWUpLAogICAgICApOwoKICAgICAgLy8gRXZhbHVhdGUgYSBzY3JpcHQgaW4gdGhlIGN1cnJlbnRseSBwYXVzZWQgY29udGV4dAogICAgICBzZXNzaW9uLnBvc3QoCiAgICAgICAgJ1J1bnRpbWUuZXZhbHVhdGUnLAogICAgICAgIHsKICAgICAgICAgIC8vIEdyYWIgdGhlIHRyYWNlIGNvbnRleHQgZnJvbSB0aGUgY3VycmVudCBzY29wZQogICAgICAgICAgZXhwcmVzc2lvbjoKICAgICAgICAgICAgJ2NvbnN0IGN0eCA9IF9fU0VOVFJZX18uaHViLmdldFNjb3BlKCkuZ2V0UHJvcGFnYXRpb25Db250ZXh0KCk7IGN0eC50cmFjZUlkICsgIi0iICsgY3R4LnNwYW5JZCArICItIiArIGN0eC5wYXJlbnRTcGFuSWQnLAogICAgICAgICAgLy8gRG9uJ3QgcmUtdHJpZ2dlciB0aGUgZGVidWdnZXIgaWYgdGhpcyBjYXVzZXMgYW4gZXJyb3IKICAgICAgICAgIHNpbGVudDogdHJ1ZSwKICAgICAgICB9LAogICAgICAgIChfLCBwYXJhbSkgPT4gewogICAgICAgICAgY29uc3QgdHJhY2VJZCA9IHBhcmFtICYmIHBhcmFtLnJlc3VsdCA/IChwYXJhbS5yZXN1bHQudmFsdWUgKSA6ICctLSc7CiAgICAgICAgICBjb25zdCBbdHJhY2VfaWQsIHNwYW5faWQsIHBhcmVudF9zcGFuX2lkXSA9IHRyYWNlSWQuc3BsaXQoJy0nKSA7CgogICAgICAgICAgc2Vzc2lvbi5wb3N0KCdEZWJ1Z2dlci5yZXN1bWUnKTsKICAgICAgICAgIHNlc3Npb24ucG9zdCgnRGVidWdnZXIuZGlzYWJsZScpOwoKICAgICAgICAgIGNvbnN0IGNvbnRleHQgPSBfb3B0aW9uYWxDaGFpbihbdHJhY2VfaWQsICdvcHRpb25hbEFjY2VzcycsIF80ID0+IF80Lmxlbmd0aF0pICYmIF9vcHRpb25hbENoYWluKFtzcGFuX2lkLCAnb3B0aW9uYWxBY2Nlc3MnLCBfNSA9PiBfNS5sZW5ndGhdKSA/IHsgdHJhY2VfaWQsIHNwYW5faWQsIHBhcmVudF9zcGFuX2lkIH0gOiB1bmRlZmluZWQ7CiAgICAgICAgICBzZW5kQW5yRXZlbnQoc3RhY2tGcmFtZXMsIGNvbnRleHQpLnRoZW4obnVsbCwgKCkgPT4gewogICAgICAgICAgICBsb2coJ1NlbmRpbmcgQU5SIGV2ZW50IGZhaWxlZC4nKTsKICAgICAgICAgIH0pOwogICAgICAgIH0sCiAgICAgICk7CiAgICB9IGNhdGNoIChlKSB7CiAgICAgIHNlc3Npb24ucG9zdCgnRGVidWdnZXIucmVzdW1lJyk7CiAgICAgIHNlc3Npb24ucG9zdCgnRGVidWdnZXIuZGlzYWJsZScpOwogICAgICB0aHJvdyBlOwogICAgfQogIH0pOwoKICBkZWJ1Z2dlclBhdXNlID0gKCkgPT4gewogICAgdHJ5IHsKICAgICAgc2Vzc2lvbi5wb3N0KCdEZWJ1Z2dlci5lbmFibGUnLCAoKSA9PiB7CiAgICAgICAgc2Vzc2lvbi5wb3N0KCdEZWJ1Z2dlci5wYXVzZScpOwogICAgICB9KTsKICAgIH0gY2F0Y2ggKF8pIHsKICAgICAgLy8KICAgIH0KICB9Owp9CgpmdW5jdGlvbiBjcmVhdGVIclRpbWVyKCkgewogIC8vIFRPRE8gKHY4KTogV2UgY2FuIHVzZSBwcm9jZXNzLmhydGltZS5iaWdpbnQoKSBhZnRlciB3ZSBkcm9wIG5vZGUgdjgKICBsZXQgbGFzdFBvbGwgPSBwcm9jZXNzLmhydGltZSgpOwoKICByZXR1cm4gewogICAgZ2V0VGltZU1zOiAoKSA9PiB7CiAgICAgIGNvbnN0IFtzZWNvbmRzLCBuYW5vU2Vjb25kc10gPSBwcm9jZXNzLmhydGltZShsYXN0UG9sbCk7CiAgICAgIHJldHVybiBNYXRoLmZsb29yKHNlY29uZHMgKiAxZTMgKyBuYW5vU2Vjb25kcyAvIDFlNik7CiAgICB9LAogICAgcmVzZXQ6ICgpID0+IHsKICAgICAgbGFzdFBvbGwgPSBwcm9jZXNzLmhydGltZSgpOwogICAgfSwKICB9Owp9CgpmdW5jdGlvbiB3YXRjaGRvZ1RpbWVvdXQoKSB7CiAgbG9nKCdXYXRjaGRvZyB0aW1lb3V0Jyk7CgogIGlmIChkZWJ1Z2dlclBhdXNlKSB7CiAgICBsb2coJ1BhdXNpbmcgZGVidWdnZXIgdG8gY2FwdHVyZSBzdGFjayB0cmFjZScpOwogICAgZGVidWdnZXJQYXVzZSgpOwogIH0gZWxzZSB7CiAgICBsb2coJ0NhcHR1cmluZyBldmVudCB3aXRob3V0IGEgc3RhY2sgdHJhY2UnKTsKICAgIHNlbmRBbnJFdmVudCgpLnRoZW4obnVsbCwgKCkgPT4gewogICAgICBsb2coJ1NlbmRpbmcgQU5SIGV2ZW50IGZhaWxlZCBvbiB3YXRjaGRvZyB0aW1lb3V0LicpOwogICAgfSk7CiAgfQp9Cgpjb25zdCB7IHBvbGwgfSA9IHdhdGNoZG9nVGltZXIoY3JlYXRlSHJUaW1lciwgb3B0aW9ucy5wb2xsSW50ZXJ2YWwsIG9wdGlvbnMuYW5yVGhyZXNob2xkLCB3YXRjaGRvZ1RpbWVvdXQpOwoKX29wdGlvbmFsQ2hhaW4oW3BhcmVudFBvcnQsICdvcHRpb25hbEFjY2VzcycsIF82ID0+IF82Lm9uLCAnY2FsbCcsIF83ID0+IF83KCdtZXNzYWdlJywgKG1zZykgPT4gewogIGlmIChtc2cuc2Vzc2lvbikgewogICAgc2Vzc2lvbiA9IG1ha2VTZXNzaW9uKG1zZy5zZXNzaW9uKTsKICB9CgogIHBvbGwoKTsKfSldKTs=";
|
|
1
|
+
/*! @sentry/node 7.108.0 (009bedc) | https://github.com/getsentry/sentry-javascript */
|
|
2
|
+
export const base64WorkerScript="aW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJ2luc3BlY3Rvcic7CmltcG9ydCB7IHdvcmtlckRhdGEsIHBhcmVudFBvcnQgfSBmcm9tICd3b3JrZXJfdGhyZWFkcyc7CmltcG9ydCB7IHBvc2l4LCBzZXAgfSBmcm9tICdwYXRoJzsKaW1wb3J0ICogYXMgaHR0cCBmcm9tICdodHRwJzsKaW1wb3J0ICogYXMgaHR0cHMgZnJvbSAnaHR0cHMnOwppbXBvcnQgeyBSZWFkYWJsZSB9IGZyb20gJ3N0cmVhbSc7CmltcG9ydCB7IFVSTCB9IGZyb20gJ3VybCc7CmltcG9ydCB7IGNyZWF0ZUd6aXAgfSBmcm9tICd6bGliJzsKaW1wb3J0ICogYXMgbmV0IGZyb20gJ25ldCc7CmltcG9ydCAqIGFzIHRscyBmcm9tICd0bHMnOwoKLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC91bmJvdW5kLW1ldGhvZApjb25zdCBvYmplY3RUb1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUncyB0eXBlIGlzIG9uZSBvZiBhIGZldyBFcnJvciBvciBFcnJvci1saWtlCiAqIHtAbGluayBpc0Vycm9yfS4KICoKICogQHBhcmFtIHdhdCBBIHZhbHVlIHRvIGJlIGNoZWNrZWQuCiAqIEByZXR1cm5zIEEgYm9vbGVhbiByZXByZXNlbnRpbmcgdGhlIHJlc3VsdC4KICovCmZ1bmN0aW9uIGlzRXJyb3Iod2F0KSB7CiAgc3dpdGNoIChvYmplY3RUb1N0cmluZy5jYWxsKHdhdCkpIHsKICAgIGNhc2UgJ1tvYmplY3QgRXJyb3JdJzoKICAgIGNhc2UgJ1tvYmplY3QgRXhjZXB0aW9uXSc6CiAgICBjYXNlICdbb2JqZWN0IERPTUV4Y2VwdGlvbl0nOgogICAgICByZXR1cm4gdHJ1ZTsKICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiBpc0luc3RhbmNlT2Yod2F0LCBFcnJvcik7CiAgfQp9Ci8qKgogKiBDaGVja3Mgd2hldGhlciBnaXZlbiB2YWx1ZSBpcyBhbiBpbnN0YW5jZSBvZiB0aGUgZ2l2ZW4gYnVpbHQtaW4gY2xhc3MuCiAqCiAqIEBwYXJhbSB3YXQgVGhlIHZhbHVlIHRvIGJlIGNoZWNrZWQKICogQHBhcmFtIGNsYXNzTmFtZQogKiBAcmV0dXJucyBBIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSByZXN1bHQuCiAqLwpmdW5jdGlvbiBpc0J1aWx0aW4od2F0LCBjbGFzc05hbWUpIHsKICByZXR1cm4gb2JqZWN0VG9TdHJpbmcuY2FsbCh3YXQpID09PSBgW29iamVjdCAke2NsYXNzTmFtZX1dYDsKfQoKLyoqCiAqIENoZWNrcyB3aGV0aGVyIGdpdmVuIHZhbHVlJ3MgdHlwZSBpcyBhIHN0cmluZwogKiB7QGxpbmsgaXNTdHJpbmd9LgogKgogKiBAcGFyYW0gd2F0IEEgdmFsdWUgdG8gYmUgY2hlY2tlZC4KICogQHJldHVybnMgQSBib29sZWFuIHJlcHJlc2VudGluZyB0aGUgcmVzdWx0LgogKi8KZnVuY3Rpb24gaXNTdHJpbmcod2F0KSB7CiAgcmV0dXJuIGlzQnVpbHRpbih3YXQsICdTdHJpbmcnKTsKfQoKLyoqCiAqIENoZWNrcyB3aGV0aGVyIGdpdmVuIHZhbHVlJ3MgdHlwZSBpcyBhbiBvYmplY3QgbGl0ZXJhbCwgb3IgYSBjbGFzcyBpbnN0YW5jZS4KICoge0BsaW5rIGlzUGxhaW5PYmplY3R9LgogKgogKiBAcGFyYW0gd2F0IEEgdmFsdWUgdG8gYmUgY2hlY2tlZC4KICogQHJldHVybnMgQSBib29sZWFuIHJlcHJlc2VudGluZyB0aGUgcmVzdWx0LgogKi8KZnVuY3Rpb24gaXNQbGFpbk9iamVjdCh3YXQpIHsKICByZXR1cm4gaXNCdWlsdGluKHdhdCwgJ09iamVjdCcpOwp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUncyB0eXBlIGlzIGFuIEV2ZW50IGluc3RhbmNlCiAqIHtAbGluayBpc0V2ZW50fS4KICoKICogQHBhcmFtIHdhdCBBIHZhbHVlIHRvIGJlIGNoZWNrZWQuCiAqIEByZXR1cm5zIEEgYm9vbGVhbiByZXByZXNlbnRpbmcgdGhlIHJlc3VsdC4KICovCmZ1bmN0aW9uIGlzRXZlbnQod2F0KSB7CiAgcmV0dXJuIHR5cGVvZiBFdmVudCAhPT0gJ3VuZGVmaW5lZCcgJiYgaXNJbnN0YW5jZU9mKHdhdCwgRXZlbnQpOwp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUncyB0eXBlIGlzIGFuIEVsZW1lbnQgaW5zdGFuY2UKICoge0BsaW5rIGlzRWxlbWVudH0uCiAqCiAqIEBwYXJhbSB3YXQgQSB2YWx1ZSB0byBiZSBjaGVja2VkLgogKiBAcmV0dXJucyBBIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSByZXN1bHQuCiAqLwpmdW5jdGlvbiBpc0VsZW1lbnQod2F0KSB7CiAgcmV0dXJuIHR5cGVvZiBFbGVtZW50ICE9PSAndW5kZWZpbmVkJyAmJiBpc0luc3RhbmNlT2Yod2F0LCBFbGVtZW50KTsKfQoKLyoqCiAqIENoZWNrcyB3aGV0aGVyIGdpdmVuIHZhbHVlIGhhcyBhIHRoZW4gZnVuY3Rpb24uCiAqIEBwYXJhbSB3YXQgQSB2YWx1ZSB0byBiZSBjaGVja2VkLgogKi8KZnVuY3Rpb24gaXNUaGVuYWJsZSh3YXQpIHsKICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1tZW1iZXItYWNjZXNzCiAgcmV0dXJuIEJvb2xlYW4od2F0ICYmIHdhdC50aGVuICYmIHR5cGVvZiB3YXQudGhlbiA9PT0gJ2Z1bmN0aW9uJyk7Cn0KCi8qKgogKiBDaGVja3Mgd2hldGhlciBnaXZlbiB2YWx1ZSdzIHR5cGUgaXMgYSBTeW50aGV0aWNFdmVudAogKiB7QGxpbmsgaXNTeW50aGV0aWNFdmVudH0uCiAqCiAqIEBwYXJhbSB3YXQgQSB2YWx1ZSB0byBiZSBjaGVja2VkLgogKiBAcmV0dXJucyBBIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSByZXN1bHQuCiAqLwpmdW5jdGlvbiBpc1N5bnRoZXRpY0V2ZW50KHdhdCkgewogIHJldHVybiBpc1BsYWluT2JqZWN0KHdhdCkgJiYgJ25hdGl2ZUV2ZW50JyBpbiB3YXQgJiYgJ3ByZXZlbnREZWZhdWx0JyBpbiB3YXQgJiYgJ3N0b3BQcm9wYWdhdGlvbicgaW4gd2F0Owp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUgaXMgTmFOCiAqIHtAbGluayBpc05hTn0uCiAqCiAqIEBwYXJhbSB3YXQgQSB2YWx1ZSB0byBiZSBjaGVja2VkLgogKiBAcmV0dXJucyBBIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSByZXN1bHQuCiAqLwpmdW5jdGlvbiBpc05hTiQxKHdhdCkgewogIHJldHVybiB0eXBlb2Ygd2F0ID09PSAnbnVtYmVyJyAmJiB3YXQgIT09IHdhdDsKfQoKLyoqCiAqIENoZWNrcyB3aGV0aGVyIGdpdmVuIHZhbHVlJ3MgdHlwZSBpcyBhbiBpbnN0YW5jZSBvZiBwcm92aWRlZCBjb25zdHJ1Y3Rvci4KICoge0BsaW5rIGlzSW5zdGFuY2VPZn0uCiAqCiAqIEBwYXJhbSB3YXQgQSB2YWx1ZSB0byBiZSBjaGVja2VkLgogKiBAcGFyYW0gYmFzZSBBIGNvbnN0cnVjdG9yIHRvIGJlIHVzZWQgaW4gYSBjaGVjay4KICogQHJldHVybnMgQSBib29sZWFuIHJlcHJlc2VudGluZyB0aGUgcmVzdWx0LgogKi8KZnVuY3Rpb24gaXNJbnN0YW5jZU9mKHdhdCwgYmFzZSkgewogIHRyeSB7CiAgICByZXR1cm4gd2F0IGluc3RhbmNlb2YgYmFzZTsKICB9IGNhdGNoIChfZSkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KfQoKLyoqCiAqIENoZWNrcyB3aGV0aGVyIGdpdmVuIHZhbHVlJ3MgdHlwZSBpcyBhIFZ1ZSBWaWV3TW9kZWwuCiAqCiAqIEBwYXJhbSB3YXQgQSB2YWx1ZSB0byBiZSBjaGVja2VkLgogKiBAcmV0dXJucyBBIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSByZXN1bHQuCiAqLwpmdW5jdGlvbiBpc1Z1ZVZpZXdNb2RlbCh3YXQpIHsKICAvLyBOb3QgdXNpbmcgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZyBiZWNhdXNlIGluIFZ1ZSAzIGl0IHdvdWxkIHJlYWQgdGhlIGluc3RhbmNlJ3MgU3ltYm9sKFN5bWJvbC50b1N0cmluZ1RhZykgcHJvcGVydHkuCiAgcmV0dXJuICEhKHR5cGVvZiB3YXQgPT09ICdvYmplY3QnICYmIHdhdCAhPT0gbnVsbCAmJiAoKHdhdCApLl9faXNWdWUgfHwgKHdhdCApLl9pc1Z1ZSkpOwp9CgovKiogSW50ZXJuYWwgZ2xvYmFsIHdpdGggY29tbW9uIHByb3BlcnRpZXMgYW5kIFNlbnRyeSBleHRlbnNpb25zICAqLwoKLy8gVGhlIGNvZGUgYmVsb3cgZm9yICdpc0dsb2JhbE9iaicgYW5kICdHTE9CQUxfT0JKJyB3YXMgY29waWVkIGZyb20gY29yZS1qcyBiZWZvcmUgbW9kaWZpY2F0aW9uCi8vIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2Jsb2IvMWI5NDRkZjU1MjgyY2RjOTljOTBkYjVmNDllYjBiNmVkYTJjYzBhMy9wYWNrYWdlcy9jb3JlLWpzL2ludGVybmFscy9nbG9iYWwuanMKLy8gY29yZS1qcyBoYXMgdGhlIGZvbGxvd2luZyBsaWNlbmNlOgovLwovLyBDb3B5cmlnaHQgKGMpIDIwMTQtMjAyMiBEZW5pcyBQdXNoa2FyZXYKLy8KLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weQovLyBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwgdG8gZGVhbAovLyBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzCi8vIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwKLy8gY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzCi8vIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6Ci8vCi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluCi8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgovLwovLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgovLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCi8vIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKLy8gT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTgovLyBUSEUgU09GVFdBUkUuCgovKiogUmV0dXJucyAnb2JqJyBpZiBpdCdzIHRoZSBnbG9iYWwgb2JqZWN0LCBvdGhlcndpc2UgcmV0dXJucyB1bmRlZmluZWQgKi8KZnVuY3Rpb24gaXNHbG9iYWxPYmoob2JqKSB7CiAgcmV0dXJuIG9iaiAmJiBvYmouTWF0aCA9PSBNYXRoID8gb2JqIDogdW5kZWZpbmVkOwp9CgovKiogR2V0J3MgdGhlIGdsb2JhbCBvYmplY3QgZm9yIHRoZSBjdXJyZW50IEphdmFTY3JpcHQgcnVudGltZSAqLwpjb25zdCBHTE9CQUxfT0JKID0KICAodHlwZW9mIGdsb2JhbFRoaXMgPT0gJ29iamVjdCcgJiYgaXNHbG9iYWxPYmooZ2xvYmFsVGhpcykpIHx8CiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlc3RyaWN0ZWQtZ2xvYmFscwogICh0eXBlb2Ygd2luZG93ID09ICdvYmplY3QnICYmIGlzR2xvYmFsT2JqKHdpbmRvdykpIHx8CiAgKHR5cGVvZiBzZWxmID09ICdvYmplY3QnICYmIGlzR2xvYmFsT2JqKHNlbGYpKSB8fAogICh0eXBlb2YgZ2xvYmFsID09ICdvYmplY3QnICYmIGlzR2xvYmFsT2JqKGdsb2JhbCkpIHx8CiAgKGZ1bmN0aW9uICgpIHsKICAgIHJldHVybiB0aGlzOwogIH0pKCkgfHwKICB7fTsKCi8qKgogKiBAZGVwcmVjYXRlZCBVc2UgR0xPQkFMX09CSiBpbnN0ZWFkIG9yIFdJTkRPVyBmcm9tIEBzZW50cnkvYnJvd3Nlci4gVGhpcyB3aWxsIGJlIHJlbW92ZWQgaW4gdjgKICovCmZ1bmN0aW9uIGdldEdsb2JhbE9iamVjdCgpIHsKICByZXR1cm4gR0xPQkFMX09CSiA7Cn0KCi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgpjb25zdCBXSU5ET1cgPSBnZXRHbG9iYWxPYmplY3QoKTsKCmNvbnN0IERFRkFVTFRfTUFYX1NUUklOR19MRU5HVEggPSA4MDsKCi8qKgogKiBHaXZlbiBhIGNoaWxkIERPTSBlbGVtZW50LCByZXR1cm5zIGEgcXVlcnktc2VsZWN0b3Igc3RhdGVtZW50IGRlc2NyaWJpbmcgdGhhdAogKiBhbmQgaXRzIGFuY2VzdG9ycwogKiBlLmcuIFtIVE1MRWxlbWVudF0gPT4gYm9keSA+IGRpdiA+IGlucHV0I2Zvby5idG5bbmFtZT1iYXpdCiAqIEByZXR1cm5zIGdlbmVyYXRlZCBET00gcGF0aAogKi8KZnVuY3Rpb24gaHRtbFRyZWVBc1N0cmluZygKICBlbGVtLAogIG9wdGlvbnMgPSB7fSwKKSB7CiAgaWYgKCFlbGVtKSB7CiAgICByZXR1cm4gJzx1bmtub3duPic7CiAgfQoKICAvLyB0cnkvY2F0Y2ggYm90aDoKICAvLyAtIGFjY2Vzc2luZyBldmVudC50YXJnZXQgKHNlZSBnZXRzZW50cnkvcmF2ZW4tanMjODM4LCAjNzY4KQogIC8vIC0gYGh0bWxUcmVlQXNTdHJpbmdgIGJlY2F1c2UgaXQncyBjb21wbGV4LCBhbmQganVzdCBhY2Nlc3NpbmcgdGhlIERPTSBpbmNvcnJlY3RseQogIC8vIC0gY2FuIHRocm93IGFuIGV4Y2VwdGlvbiBpbiBzb21lIGNpcmN1bXN0YW5jZXMuCiAgdHJ5IHsKICAgIGxldCBjdXJyZW50RWxlbSA9IGVsZW0gOwogICAgY29uc3QgTUFYX1RSQVZFUlNFX0hFSUdIVCA9IDU7CiAgICBjb25zdCBvdXQgPSBbXTsKICAgIGxldCBoZWlnaHQgPSAwOwogICAgbGV0IGxlbiA9IDA7CiAgICBjb25zdCBzZXBhcmF0b3IgPSAnID4gJzsKICAgIGNvbnN0IHNlcExlbmd0aCA9IHNlcGFyYXRvci5sZW5ndGg7CiAgICBsZXQgbmV4dFN0cjsKICAgIGNvbnN0IGtleUF0dHJzID0gQXJyYXkuaXNBcnJheShvcHRpb25zKSA/IG9wdGlvbnMgOiBvcHRpb25zLmtleUF0dHJzOwogICAgY29uc3QgbWF4U3RyaW5nTGVuZ3RoID0gKCFBcnJheS5pc0FycmF5KG9wdGlvbnMpICYmIG9wdGlvbnMubWF4U3RyaW5nTGVuZ3RoKSB8fCBERUZBVUxUX01BWF9TVFJJTkdfTEVOR1RIOwoKICAgIHdoaWxlIChjdXJyZW50RWxlbSAmJiBoZWlnaHQrKyA8IE1BWF9UUkFWRVJTRV9IRUlHSFQpIHsKICAgICAgbmV4dFN0ciA9IF9odG1sRWxlbWVudEFzU3RyaW5nKGN1cnJlbnRFbGVtLCBrZXlBdHRycyk7CiAgICAgIC8vIGJhaWwgb3V0IGlmCiAgICAgIC8vIC0gbmV4dFN0ciBpcyB0aGUgJ2h0bWwnIGVsZW1lbnQKICAgICAgLy8gLSB0aGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgdGhhdCB3b3VsZCBiZSBjcmVhdGVkIGV4Y2VlZHMgbWF4U3RyaW5nTGVuZ3RoCiAgICAgIC8vICAgKGlnbm9yZSB0aGlzIGxpbWl0IGlmIHdlIGFyZSBvbiB0aGUgZmlyc3QgaXRlcmF0aW9uKQogICAgICBpZiAobmV4dFN0ciA9PT0gJ2h0bWwnIHx8IChoZWlnaHQgPiAxICYmIGxlbiArIG91dC5sZW5ndGggKiBzZXBMZW5ndGggKyBuZXh0U3RyLmxlbmd0aCA+PSBtYXhTdHJpbmdMZW5ndGgpKSB7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KCiAgICAgIG91dC5wdXNoKG5leHRTdHIpOwoKICAgICAgbGVuICs9IG5leHRTdHIubGVuZ3RoOwogICAgICBjdXJyZW50RWxlbSA9IGN1cnJlbnRFbGVtLnBhcmVudE5vZGU7CiAgICB9CgogICAgcmV0dXJuIG91dC5yZXZlcnNlKCkuam9pbihzZXBhcmF0b3IpOwogIH0gY2F0Y2ggKF9vTykgewogICAgcmV0dXJuICc8dW5rbm93bj4nOwogIH0KfQoKLyoqCiAqIFJldHVybnMgYSBzaW1wbGUsIHF1ZXJ5LXNlbGVjdG9yIHJlcHJlc2VudGF0aW9uIG9mIGEgRE9NIGVsZW1lbnQKICogZS5nLiBbSFRNTEVsZW1lbnRdID0+IGlucHV0I2Zvby5idG5bbmFtZT1iYXpdCiAqIEByZXR1cm5zIGdlbmVyYXRlZCBET00gcGF0aAogKi8KZnVuY3Rpb24gX2h0bWxFbGVtZW50QXNTdHJpbmcoZWwsIGtleUF0dHJzKSB7CiAgY29uc3QgZWxlbSA9IGVsCgo7CgogIGNvbnN0IG91dCA9IFtdOwogIGxldCBjbGFzc05hbWU7CiAgbGV0IGNsYXNzZXM7CiAgbGV0IGtleTsKICBsZXQgYXR0cjsKICBsZXQgaTsKCiAgaWYgKCFlbGVtIHx8ICFlbGVtLnRhZ05hbWUpIHsKICAgIHJldHVybiAnJzsKICB9CgogIC8vIEB0cy1leHBlY3QtZXJyb3IgV0lORE9XIGhhcyBIVE1MRWxlbWVudAogIGlmIChXSU5ET1cuSFRNTEVsZW1lbnQpIHsKICAgIC8vIElmIHVzaW5nIHRoZSBjb21wb25lbnQgbmFtZSBhbm5vdGF0aW9uIHBsdWdpbiwgdGhpcyB2YWx1ZSBtYXkgYmUgYXZhaWxhYmxlIG9uIHRoZSBET00gbm9kZQogICAgaWYgKGVsZW0gaW5zdGFuY2VvZiBIVE1MRWxlbWVudCAmJiBlbGVtLmRhdGFzZXQgJiYgZWxlbS5kYXRhc2V0WydzZW50cnlDb21wb25lbnQnXSkgewogICAgICByZXR1cm4gZWxlbS5kYXRhc2V0WydzZW50cnlDb21wb25lbnQnXTsKICAgIH0KICB9CgogIG91dC5wdXNoKGVsZW0udGFnTmFtZS50b0xvd2VyQ2FzZSgpKTsKCiAgLy8gUGFpcnMgb2YgYXR0cmlidXRlIGtleXMgZGVmaW5lZCBpbiBgc2VyaWFsaXplQXR0cmlidXRlYCBhbmQgdGhlaXIgdmFsdWVzIG9uIGVsZW1lbnQuCiAgY29uc3Qga2V5QXR0clBhaXJzID0KICAgIGtleUF0dHJzICYmIGtleUF0dHJzLmxlbmd0aAogICAgICA/IGtleUF0dHJzLmZpbHRlcihrZXlBdHRyID0+IGVsZW0uZ2V0QXR0cmlidXRlKGtleUF0dHIpKS5tYXAoa2V5QXR0ciA9PiBba2V5QXR0ciwgZWxlbS5nZXRBdHRyaWJ1dGUoa2V5QXR0cildKQogICAgICA6IG51bGw7CgogIGlmIChrZXlBdHRyUGFpcnMgJiYga2V5QXR0clBhaXJzLmxlbmd0aCkgewogICAga2V5QXR0clBhaXJzLmZvckVhY2goa2V5QXR0clBhaXIgPT4gewogICAgICBvdXQucHVzaChgWyR7a2V5QXR0clBhaXJbMF19PSIke2tleUF0dHJQYWlyWzFdfSJdYCk7CiAgICB9KTsKICB9IGVsc2UgewogICAgaWYgKGVsZW0uaWQpIHsKICAgICAgb3V0LnB1c2goYCMke2VsZW0uaWR9YCk7CiAgICB9CgogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1jb25zdAogICAgY2xhc3NOYW1lID0gZWxlbS5jbGFzc05hbWU7CiAgICBpZiAoY2xhc3NOYW1lICYmIGlzU3RyaW5nKGNsYXNzTmFtZSkpIHsKICAgICAgY2xhc3NlcyA9IGNsYXNzTmFtZS5zcGxpdCgvXHMrLyk7CiAgICAgIGZvciAoaSA9IDA7IGkgPCBjbGFzc2VzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgb3V0LnB1c2goYC4ke2NsYXNzZXNbaV19YCk7CiAgICAgIH0KICAgIH0KICB9CiAgY29uc3QgYWxsb3dlZEF0dHJzID0gWydhcmlhLWxhYmVsJywgJ3R5cGUnLCAnbmFtZScsICd0aXRsZScsICdhbHQnXTsKICBmb3IgKGkgPSAwOyBpIDwgYWxsb3dlZEF0dHJzLmxlbmd0aDsgaSsrKSB7CiAgICBrZXkgPSBhbGxvd2VkQXR0cnNbaV07CiAgICBhdHRyID0gZWxlbS5nZXRBdHRyaWJ1dGUoa2V5KTsKICAgIGlmIChhdHRyKSB7CiAgICAgIG91dC5wdXNoKGBbJHtrZXl9PSIke2F0dHJ9Il1gKTsKICAgIH0KICB9CiAgcmV0dXJuIG91dC5qb2luKCcnKTsKfQoKLyoqCiAqIFRoaXMgc2VydmVzIGFzIGEgYnVpbGQgdGltZSBmbGFnIHRoYXQgd2lsbCBiZSB0cnVlIGJ5IGRlZmF1bHQsIGJ1dCBmYWxzZSBpbiBub24tZGVidWcgYnVpbGRzIG9yIGlmIHVzZXJzIHJlcGxhY2UgYF9fU0VOVFJZX0RFQlVHX19gIGluIHRoZWlyIGdlbmVyYXRlZCBjb2RlLgogKgogKiBBVFRFTlRJT046IFRoaXMgY29uc3RhbnQgbXVzdCBuZXZlciBjcm9zcyBwYWNrYWdlIGJvdW5kYXJpZXMgKGkuZS4gYmUgZXhwb3J0ZWQpIHRvIGd1YXJhbnRlZSB0aGF0IGl0IGNhbiBiZSB1c2VkIGZvciB0cmVlIHNoYWtpbmcuCiAqLwpjb25zdCBERUJVR19CVUlMRCQxID0gKHR5cGVvZiBfX1NFTlRSWV9ERUJVR19fID09PSAndW5kZWZpbmVkJyB8fCBfX1NFTlRSWV9ERUJVR19fKTsKCi8qKiBQcmVmaXggZm9yIGxvZ2dpbmcgc3RyaW5ncyAqLwpjb25zdCBQUkVGSVggPSAnU2VudHJ5IExvZ2dlciAnOwoKY29uc3QgQ09OU09MRV9MRVZFTFMgPSBbCiAgJ2RlYnVnJywKICAnaW5mbycsCiAgJ3dhcm4nLAogICdlcnJvcicsCiAgJ2xvZycsCiAgJ2Fzc2VydCcsCiAgJ3RyYWNlJywKXSA7CgovKiogVGhpcyBtYXkgYmUgbXV0YXRlZCBieSB0aGUgY29uc29sZSBpbnN0cnVtZW50YXRpb24uICovCmNvbnN0IG9yaWdpbmFsQ29uc29sZU1ldGhvZHMKCiA9IHt9OwoKLyoqIEpTRG9jICovCgovKioKICogVGVtcG9yYXJpbHkgZGlzYWJsZSBzZW50cnkgY29uc29sZSBpbnN0cnVtZW50YXRpb25zLgogKgogKiBAcGFyYW0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIHRvIHJ1biBhZ2FpbnN0IHRoZSBvcmlnaW5hbCBgY29uc29sZWAgbWVzc2FnZXMKICogQHJldHVybnMgVGhlIHJlc3VsdHMgb2YgdGhlIGNhbGxiYWNrCiAqLwpmdW5jdGlvbiBjb25zb2xlU2FuZGJveChjYWxsYmFjaykgewogIGlmICghKCdjb25zb2xlJyBpbiBHTE9CQUxfT0JKKSkgewogICAgcmV0dXJuIGNhbGxiYWNrKCk7CiAgfQoKICBjb25zdCBjb25zb2xlID0gR0xPQkFMX09CSi5jb25zb2xlIDsKICBjb25zdCB3cmFwcGVkRnVuY3MgPSB7fTsKCiAgY29uc3Qgd3JhcHBlZExldmVscyA9IE9iamVjdC5rZXlzKG9yaWdpbmFsQ29uc29sZU1ldGhvZHMpIDsKCiAgLy8gUmVzdG9yZSBhbGwgd3JhcHBlZCBjb25zb2xlIG1ldGhvZHMKICB3cmFwcGVkTGV2ZWxzLmZvckVhY2gobGV2ZWwgPT4gewogICAgY29uc3Qgb3JpZ2luYWxDb25zb2xlTWV0aG9kID0gb3JpZ2luYWxDb25zb2xlTWV0aG9kc1tsZXZlbF0gOwogICAgd3JhcHBlZEZ1bmNzW2xldmVsXSA9IGNvbnNvbGVbbGV2ZWxdIDsKICAgIGNvbnNvbGVbbGV2ZWxdID0gb3JpZ2luYWxDb25zb2xlTWV0aG9kOwogIH0pOwoKICB0cnkgewogICAgcmV0dXJuIGNhbGxiYWNrKCk7CiAgfSBmaW5hbGx5IHsKICAgIC8vIFJldmVydCByZXN0b3JhdGlvbiB0byB3cmFwcGVkIHN0YXRlCiAgICB3cmFwcGVkTGV2ZWxzLmZvckVhY2gobGV2ZWwgPT4gewogICAgICBjb25zb2xlW2xldmVsXSA9IHdyYXBwZWRGdW5jc1tsZXZlbF0gOwogICAgfSk7CiAgfQp9CgpmdW5jdGlvbiBtYWtlTG9nZ2VyKCkgewogIGxldCBlbmFibGVkID0gZmFsc2U7CiAgY29uc3QgbG9nZ2VyID0gewogICAgZW5hYmxlOiAoKSA9PiB7CiAgICAgIGVuYWJsZWQgPSB0cnVlOwogICAgfSwKICAgIGRpc2FibGU6ICgpID0+IHsKICAgICAgZW5hYmxlZCA9IGZhbHNlOwogICAgfSwKICAgIGlzRW5hYmxlZDogKCkgPT4gZW5hYmxlZCwKICB9OwoKICBpZiAoREVCVUdfQlVJTEQkMSkgewogICAgQ09OU09MRV9MRVZFTFMuZm9yRWFjaChuYW1lID0+IHsKICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkKICAgICAgbG9nZ2VyW25hbWVdID0gKC4uLmFyZ3MpID0+IHsKICAgICAgICBpZiAoZW5hYmxlZCkgewogICAgICAgICAgY29uc29sZVNhbmRib3goKCkgPT4gewogICAgICAgICAgICBHTE9CQUxfT0JKLmNvbnNvbGVbbmFtZV0oYCR7UFJFRklYfVske25hbWV9XTpgLCAuLi5hcmdzKTsKICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgfTsKICAgIH0pOwogIH0gZWxzZSB7CiAgICBDT05TT0xFX0xFVkVMUy5mb3JFYWNoKG5hbWUgPT4gewogICAgICBsb2dnZXJbbmFtZV0gPSAoKSA9PiB1bmRlZmluZWQ7CiAgICB9KTsKICB9CgogIHJldHVybiBsb2dnZXIgOwp9Cgpjb25zdCBsb2dnZXIgPSBtYWtlTG9nZ2VyKCk7CgovKioKICogUmVuZGVycyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgRHNuLgogKgogKiBCeSBkZWZhdWx0LCB0aGlzIHdpbGwgcmVuZGVyIHRoZSBwdWJsaWMgcmVwcmVzZW50YXRpb24gd2l0aG91dCB0aGUgcGFzc3dvcmQKICogY29tcG9uZW50LiBUbyBnZXQgdGhlIGRlcHJlY2F0ZWQgcHJpdmF0ZSByZXByZXNlbnRhdGlvbiwgc2V0IGB3aXRoUGFzc3dvcmRgCiAqIHRvIHRydWUuCiAqCiAqIEBwYXJhbSB3aXRoUGFzc3dvcmQgV2hlbiBzZXQgdG8gdHJ1ZSwgdGhlIHBhc3N3b3JkIHdpbGwgYmUgaW5jbHVkZWQuCiAqLwpmdW5jdGlvbiBkc25Ub1N0cmluZyhkc24sIHdpdGhQYXNzd29yZCA9IGZhbHNlKSB7CiAgY29uc3QgeyBob3N0LCBwYXRoLCBwYXNzLCBwb3J0LCBwcm9qZWN0SWQsIHByb3RvY29sLCBwdWJsaWNLZXkgfSA9IGRzbjsKICByZXR1cm4gKAogICAgYCR7cHJvdG9jb2x9Oi8vJHtwdWJsaWNLZXl9JHt3aXRoUGFzc3dvcmQgJiYgcGFzcyA/IGA6JHtwYXNzfWAgOiAnJ31gICsKICAgIGBAJHtob3N0fSR7cG9ydCA/IGA6JHtwb3J0fWAgOiAnJ30vJHtwYXRoID8gYCR7cGF0aH0vYCA6IHBhdGh9JHtwcm9qZWN0SWR9YAogICk7Cn0KCi8qKiBBbiBlcnJvciBlbWl0dGVkIGJ5IFNlbnRyeSBTREtzIGFuZCByZWxhdGVkIHV0aWxpdGllcy4gKi8KY2xhc3MgU2VudHJ5RXJyb3IgZXh0ZW5kcyBFcnJvciB7CiAgLyoqIERpc3BsYXkgbmFtZSBvZiB0aGlzIGVycm9yIGluc3RhbmNlLiAqLwoKICAgY29uc3RydWN0b3IoIG1lc3NhZ2UsIGxvZ0xldmVsID0gJ3dhcm4nKSB7CiAgICBzdXBlcihtZXNzYWdlKTt0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlOwogICAgdGhpcy5uYW1lID0gbmV3LnRhcmdldC5wcm90b3R5cGUuY29uc3RydWN0b3IubmFtZTsKICAgIC8vIFRoaXMgc2V0cyB0aGUgcHJvdG90eXBlIHRvIGJlIGBFcnJvcmAsIG5vdCBgU2VudHJ5RXJyb3JgLiBJdCdzIHVuY2xlYXIgd2h5IHdlIGRvIHRoaXMsIGJ1dCBjb21tZW50aW5nIHRoaXMgbGluZQogICAgLy8gb3V0IGNhdXNlcyB2YXJpb3VzIChzZWVtaW5nbHkgdG90YWxseSB1bnJlbGF0ZWQpIHBsYXl3cmlnaHQgdGVzdHMgY29uc2lzdGVudGx5IHRpbWUgb3V0LiBGWUksIHRoaXMgbWFrZXMKICAgIC8vIGluc3RhbmNlcyBvZiBgU2VudHJ5RXJyb3JgIGZhaWwgYG9iaiBpbnN0YW5jZW9mIFNlbnRyeUVycm9yYCBjaGVja3MuCiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgbmV3LnRhcmdldC5wcm90b3R5cGUpOwogICAgdGhpcy5sb2dMZXZlbCA9IGxvZ0xldmVsOwogIH0KfQoKLyoqCiAqIEVuY29kZXMgZ2l2ZW4gb2JqZWN0IGludG8gdXJsLWZyaWVuZGx5IGZvcm1hdAogKgogKiBAcGFyYW0gb2JqZWN0IEFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIHNlcmlhbGl6YWJsZSB2YWx1ZXMKICogQHJldHVybnMgc3RyaW5nIEVuY29kZWQKICovCmZ1bmN0aW9uIHVybEVuY29kZShvYmplY3QpIHsKICByZXR1cm4gT2JqZWN0LmtleXMob2JqZWN0KQogICAgLm1hcChrZXkgPT4gYCR7ZW5jb2RlVVJJQ29tcG9uZW50KGtleSl9PSR7ZW5jb2RlVVJJQ29tcG9uZW50KG9iamVjdFtrZXldKX1gKQogICAgLmpvaW4oJyYnKTsKfQoKLyoqCiAqIFRyYW5zZm9ybXMgYW55IGBFcnJvcmAgb3IgYEV2ZW50YCBpbnRvIGEgcGxhaW4gb2JqZWN0IHdpdGggYWxsIG9mIHRoZWlyIGVudW1lcmFibGUgcHJvcGVydGllcywgYW5kIHNvbWUgb2YgdGhlaXIKICogbm9uLWVudW1lcmFibGUgcHJvcGVydGllcyBhdHRhY2hlZC4KICoKICogQHBhcmFtIHZhbHVlIEluaXRpYWwgc291cmNlIHRoYXQgd2UgaGF2ZSB0byB0cmFuc2Zvcm0gaW4gb3JkZXIgZm9yIGl0IHRvIGJlIHVzYWJsZSBieSB0aGUgc2VyaWFsaXplcgogKiBAcmV0dXJucyBBbiBFdmVudCBvciBFcnJvciB0dXJuZWQgaW50byBhbiBvYmplY3QgLSBvciB0aGUgdmFsdWUgYXJndXJtZW50IGl0c2VsZiwgd2hlbiB2YWx1ZSBpcyBuZWl0aGVyIGFuIEV2ZW50IG5vcgogKiAgYW4gRXJyb3IuCiAqLwpmdW5jdGlvbiBjb252ZXJ0VG9QbGFpbk9iamVjdCgKICB2YWx1ZSwKKQoKIHsKICBpZiAoaXNFcnJvcih2YWx1ZSkpIHsKICAgIHJldHVybiB7CiAgICAgIG1lc3NhZ2U6IHZhbHVlLm1lc3NhZ2UsCiAgICAgIG5hbWU6IHZhbHVlLm5hbWUsCiAgICAgIHN0YWNrOiB2YWx1ZS5zdGFjaywKICAgICAgLi4uZ2V0T3duUHJvcGVydGllcyh2YWx1ZSksCiAgICB9OwogIH0gZWxzZSBpZiAoaXNFdmVudCh2YWx1ZSkpIHsKICAgIGNvbnN0IG5ld09iagoKID0gewogICAgICB0eXBlOiB2YWx1ZS50eXBlLAogICAgICB0YXJnZXQ6IHNlcmlhbGl6ZUV2ZW50VGFyZ2V0KHZhbHVlLnRhcmdldCksCiAgICAgIGN1cnJlbnRUYXJnZXQ6IHNlcmlhbGl6ZUV2ZW50VGFyZ2V0KHZhbHVlLmN1cnJlbnRUYXJnZXQpLAogICAgICAuLi5nZXRPd25Qcm9wZXJ0aWVzKHZhbHVlKSwKICAgIH07CgogICAgaWYgKHR5cGVvZiBDdXN0b21FdmVudCAhPT0gJ3VuZGVmaW5lZCcgJiYgaXNJbnN0YW5jZU9mKHZhbHVlLCBDdXN0b21FdmVudCkpIHsKICAgICAgbmV3T2JqLmRldGFpbCA9IHZhbHVlLmRldGFpbDsKICAgIH0KCiAgICByZXR1cm4gbmV3T2JqOwogIH0gZWxzZSB7CiAgICByZXR1cm4gdmFsdWU7CiAgfQp9CgovKiogQ3JlYXRlcyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdGFyZ2V0IG9mIGFuIGBFdmVudGAgb2JqZWN0ICovCmZ1bmN0aW9uIHNlcmlhbGl6ZUV2ZW50VGFyZ2V0KHRhcmdldCkgewogIHRyeSB7CiAgICByZXR1cm4gaXNFbGVtZW50KHRhcmdldCkgPyBodG1sVHJlZUFzU3RyaW5nKHRhcmdldCkgOiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodGFyZ2V0KTsKICB9IGNhdGNoIChfb08pIHsKICAgIHJldHVybiAnPHVua25vd24+JzsKICB9Cn0KCi8qKiBGaWx0ZXJzIG91dCBhbGwgYnV0IGFuIG9iamVjdCdzIG93biBwcm9wZXJ0aWVzICovCmZ1bmN0aW9uIGdldE93blByb3BlcnRpZXMob2JqKSB7CiAgaWYgKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIG9iaiAhPT0gbnVsbCkgewogICAgY29uc3QgZXh0cmFjdGVkUHJvcHMgPSB7fTsKICAgIGZvciAoY29uc3QgcHJvcGVydHkgaW4gb2JqKSB7CiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wZXJ0eSkpIHsKICAgICAgICBleHRyYWN0ZWRQcm9wc1twcm9wZXJ0eV0gPSAob2JqIClbcHJvcGVydHldOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gZXh0cmFjdGVkUHJvcHM7CiAgfSBlbHNlIHsKICAgIHJldHVybiB7fTsKICB9Cn0KCi8qKgogKiBHaXZlbiBhbnkgb2JqZWN0LCByZXR1cm4gYSBuZXcgb2JqZWN0IGhhdmluZyByZW1vdmVkIGFsbCBmaWVsZHMgd2hvc2UgdmFsdWUgd2FzIGB1bmRlZmluZWRgLgogKiBXb3JrcyByZWN1cnNpdmVseSBvbiBvYmplY3RzIGFuZCBhcnJheXMuCiAqCiAqIEF0dGVudGlvbjogVGhpcyBmdW5jdGlvbiBrZWVwcyBjaXJjdWxhciByZWZlcmVuY2VzIGluIHRoZSByZXR1cm5lZCBvYmplY3QuCiAqLwpmdW5jdGlvbiBkcm9wVW5kZWZpbmVkS2V5cyhpbnB1dFZhbHVlKSB7CiAgLy8gVGhpcyBtYXAga2VlcHMgdHJhY2sgb2Ygd2hhdCBhbHJlYWR5IHZpc2l0ZWQgbm9kZXMgbWFwIHRvLgogIC8vIE91ciBTZXQgLSBiYXNlZCBtZW1vQnVpbGRlciBkb2Vzbid0IHdvcmsgaGVyZSBiZWNhdXNlIHdlIHdhbnQgdG8gdGhlIG91dHB1dCBvYmplY3QgdG8gaGF2ZSB0aGUgc2FtZSBjaXJjdWxhcgogIC8vIHJlZmVyZW5jZXMgYXMgdGhlIGlucHV0IG9iamVjdC4KICBjb25zdCBtZW1vaXphdGlvbk1hcCA9IG5ldyBNYXAoKTsKCiAgLy8gVGhpcyBmdW5jdGlvbiBqdXN0IHByb3hpZXMgYF9kcm9wVW5kZWZpbmVkS2V5c2AgdG8ga2VlcCB0aGUgYG1lbW9CdWlsZGVyYCBvdXQgb2YgdGhpcyBmdW5jdGlvbidzIEFQSQogIHJldHVybiBfZHJvcFVuZGVmaW5lZEtleXMoaW5wdXRWYWx1ZSwgbWVtb2l6YXRpb25NYXApOwp9CgpmdW5jdGlvbiBfZHJvcFVuZGVmaW5lZEtleXMoaW5wdXRWYWx1ZSwgbWVtb2l6YXRpb25NYXApIHsKICBpZiAoaXNQb2pvKGlucHV0VmFsdWUpKSB7CiAgICAvLyBJZiB0aGlzIG5vZGUgaGFzIGFscmVhZHkgYmVlbiB2aXNpdGVkIGR1ZSB0byBhIGNpcmN1bGFyIHJlZmVyZW5jZSwgcmV0dXJuIHRoZSBvYmplY3QgaXQgd2FzIG1hcHBlZCB0byBpbiB0aGUgbmV3IG9iamVjdAogICAgY29uc3QgbWVtb1ZhbCA9IG1lbW9pemF0aW9uTWFwLmdldChpbnB1dFZhbHVlKTsKICAgIGlmIChtZW1vVmFsICE9PSB1bmRlZmluZWQpIHsKICAgICAgcmV0dXJuIG1lbW9WYWwgOwogICAgfQoKICAgIGNvbnN0IHJldHVyblZhbHVlID0ge307CiAgICAvLyBTdG9yZSB0aGUgbWFwcGluZyBvZiB0aGlzIHZhbHVlIGluIGNhc2Ugd2UgdmlzaXQgaXQgYWdhaW4sIGluIGNhc2Ugb2YgY2lyY3VsYXIgZGF0YQogICAgbWVtb2l6YXRpb25NYXAuc2V0KGlucHV0VmFsdWUsIHJldHVyblZhbHVlKTsKCiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhpbnB1dFZhbHVlKSkgewogICAgICBpZiAodHlwZW9mIGlucHV0VmFsdWVba2V5XSAhPT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgICByZXR1cm5WYWx1ZVtrZXldID0gX2Ryb3BVbmRlZmluZWRLZXlzKGlucHV0VmFsdWVba2V5XSwgbWVtb2l6YXRpb25NYXApOwogICAgICB9CiAgICB9CgogICAgcmV0dXJuIHJldHVyblZhbHVlIDsKICB9CgogIGlmIChBcnJheS5pc0FycmF5KGlucHV0VmFsdWUpKSB7CiAgICAvLyBJZiB0aGlzIG5vZGUgaGFzIGFscmVhZHkgYmVlbiB2aXNpdGVkIGR1ZSB0byBhIGNpcmN1bGFyIHJlZmVyZW5jZSwgcmV0dXJuIHRoZSBhcnJheSBpdCB3YXMgbWFwcGVkIHRvIGluIHRoZSBuZXcgb2JqZWN0CiAgICBjb25zdCBtZW1vVmFsID0gbWVtb2l6YXRpb25NYXAuZ2V0KGlucHV0VmFsdWUpOwogICAgaWYgKG1lbW9WYWwgIT09IHVuZGVmaW5lZCkgewogICAgICByZXR1cm4gbWVtb1ZhbCA7CiAgICB9CgogICAgY29uc3QgcmV0dXJuVmFsdWUgPSBbXTsKICAgIC8vIFN0b3JlIHRoZSBtYXBwaW5nIG9mIHRoaXMgdmFsdWUgaW4gY2FzZSB3ZSB2aXNpdCBpdCBhZ2FpbiwgaW4gY2FzZSBvZiBjaXJjdWxhciBkYXRhCiAgICBtZW1vaXphdGlvbk1hcC5zZXQoaW5wdXRWYWx1ZSwgcmV0dXJuVmFsdWUpOwoKICAgIGlucHV0VmFsdWUuZm9yRWFjaCgoaXRlbSkgPT4gewogICAgICByZXR1cm5WYWx1ZS5wdXNoKF9kcm9wVW5kZWZpbmVkS2V5cyhpdGVtLCBtZW1vaXphdGlvbk1hcCkpOwogICAgfSk7CgogICAgcmV0dXJuIHJldHVyblZhbHVlIDsKICB9CgogIHJldHVybiBpbnB1dFZhbHVlOwp9CgpmdW5jdGlvbiBpc1Bvam8oaW5wdXQpIHsKICBpZiAoIWlzUGxhaW5PYmplY3QoaW5wdXQpKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQoKICB0cnkgewogICAgY29uc3QgbmFtZSA9IChPYmplY3QuZ2V0UHJvdG90eXBlT2YoaW5wdXQpICkuY29uc3RydWN0b3IubmFtZTsKICAgIHJldHVybiAhbmFtZSB8fCBuYW1lID09PSAnT2JqZWN0JzsKICB9IGNhdGNoIChlKSB7CiAgICByZXR1cm4gdHJ1ZTsKICB9Cn0KCi8qKgogKiBEb2VzIHRoaXMgZmlsZW5hbWUgbG9vayBsaWtlIGl0J3MgcGFydCBvZiB0aGUgYXBwIGNvZGU/CiAqLwpmdW5jdGlvbiBmaWxlbmFtZUlzSW5BcHAoZmlsZW5hbWUsIGlzTmF0aXZlID0gZmFsc2UpIHsKICBjb25zdCBpc0ludGVybmFsID0KICAgIGlzTmF0aXZlIHx8CiAgICAoZmlsZW5hbWUgJiYKICAgICAgLy8gSXQncyBub3QgaW50ZXJuYWwgaWYgaXQncyBhbiBhYnNvbHV0ZSBsaW51eCBwYXRoCiAgICAgICFmaWxlbmFtZS5zdGFydHNXaXRoKCcvJykgJiYKICAgICAgLy8gSXQncyBub3QgaW50ZXJuYWwgaWYgaXQncyBhbiBhYnNvbHV0ZSB3aW5kb3dzIHBhdGgKICAgICAgIWZpbGVuYW1lLm1hdGNoKC9eW0EtWl06LykgJiYKICAgICAgLy8gSXQncyBub3QgaW50ZXJuYWwgaWYgdGhlIHBhdGggaXMgc3RhcnRpbmcgd2l0aCBhIGRvdAogICAgICAhZmlsZW5hbWUuc3RhcnRzV2l0aCgnLicpICYmCiAgICAgIC8vIEl0J3Mgbm90IGludGVybmFsIGlmIHRoZSBmcmFtZSBoYXMgYSBwcm90b2NvbC4gSW4gbm9kZSwgdGhpcyBpcyB1c3VhbGx5IHRoZSBjYXNlIGlmIHRoZSBmaWxlIGdvdCBwcmUtcHJvY2Vzc2VkIHdpdGggYSBidW5kbGVyIGxpa2Ugd2VicGFjawogICAgICAhZmlsZW5hbWUubWF0Y2goL15bYS16QS1aXShbYS16QS1aMC05LlwtK10pKjpcL1wvLykpOyAvLyBTY2hlbWEgZnJvbTogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzM2NDE3ODIKCiAgLy8gaW5fYXBwIGlzIGFsbCB0aGF0J3Mgbm90IGFuIGludGVybmFsIE5vZGUgZnVuY3Rpb24gb3IgYSBtb2R1bGUgd2l0aGluIG5vZGVfbW9kdWxlcwogIC8vIG5vdGUgdGhhdCBpc05hdGl2ZSBhcHBlYXJzIHRvIHJldHVybiB0cnVlIGV2ZW4gZm9yIG5vZGUgY29yZSBsaWJyYXJpZXMKICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9yYXZlbi1ub2RlL2lzc3Vlcy8xNzYKCiAgcmV0dXJuICFpc0ludGVybmFsICYmIGZpbGVuYW1lICE9PSB1bmRlZmluZWQgJiYgIWZpbGVuYW1lLmluY2x1ZGVzKCdub2RlX21vZHVsZXMvJyk7Cn0KCmNvbnN0IFNUQUNLVFJBQ0VfRlJBTUVfTElNSVQgPSA1MDsKY29uc3QgU1RSSVBfRlJBTUVfUkVHRVhQID0gL2NhcHR1cmVNZXNzYWdlfGNhcHR1cmVFeGNlcHRpb24vOwoKLyoqCiAqIFJlbW92ZXMgU2VudHJ5IGZyYW1lcyBmcm9tIHRoZSB0b3AgYW5kIGJvdHRvbSBvZiB0aGUgc3RhY2sgaWYgcHJlc2VudCBhbmQgZW5mb3JjZXMgYSBsaW1pdCBvZiBtYXggbnVtYmVyIG9mIGZyYW1lcy4KICogQXNzdW1lcyBzdGFjayBpbnB1dCBpcyBvcmRlcmVkIGZyb20gdG9wIHRvIGJvdHRvbSBhbmQgcmV0dXJucyB0aGUgcmV2ZXJzZSByZXByZXNlbnRhdGlvbiBzbyBjYWxsIHNpdGUgb2YgdGhlCiAqIGZ1bmN0aW9uIHRoYXQgY2F1c2VkIHRoZSBjcmFzaCBpcyB0aGUgbGFzdCBmcmFtZSBpbiB0aGUgYXJyYXkuCiAqIEBoaWRkZW4KICovCmZ1bmN0aW9uIHN0cmlwU2VudHJ5RnJhbWVzQW5kUmV2ZXJzZShzdGFjaykgewogIGlmICghc3RhY2subGVuZ3RoKSB7CiAgICByZXR1cm4gW107CiAgfQoKICBjb25zdCBsb2NhbFN0YWNrID0gQXJyYXkuZnJvbShzdGFjayk7CgogIC8vIElmIHN0YWNrIHN0YXJ0cyB3aXRoIG9uZSBvZiBvdXIgQVBJIGNhbGxzLCByZW1vdmUgaXQgKHN0YXJ0cywgbWVhbmluZyBpdCdzIHRoZSB0b3Agb2YgdGhlIHN0YWNrIC0gYWthIGxhc3QgY2FsbCkKICBpZiAoL3NlbnRyeVdyYXBwZWQvLnRlc3QobG9jYWxTdGFja1tsb2NhbFN0YWNrLmxlbmd0aCAtIDFdLmZ1bmN0aW9uIHx8ICcnKSkgewogICAgbG9jYWxTdGFjay5wb3AoKTsKICB9CgogIC8vIFJldmVyc2luZyBpbiB0aGUgbWlkZGxlIG9mIHRoZSBwcm9jZWR1cmUgYWxsb3dzIHVzIHRvIGp1c3QgcG9wIHRoZSB2YWx1ZXMgb2ZmIHRoZSBzdGFjawogIGxvY2FsU3RhY2sucmV2ZXJzZSgpOwoKICAvLyBJZiBzdGFjayBlbmRzIHdpdGggb25lIG9mIG91ciBpbnRlcm5hbCBBUEkgY2FsbHMsIHJlbW92ZSBpdCAoZW5kcywgbWVhbmluZyBpdCdzIHRoZSBib3R0b20gb2YgdGhlIHN0YWNrIC0gYWthIHRvcC1tb3N0IGNhbGwpCiAgaWYgKFNUUklQX0ZSQU1FX1JFR0VYUC50ZXN0KGxvY2FsU3RhY2tbbG9jYWxTdGFjay5sZW5ndGggLSAxXS5mdW5jdGlvbiB8fCAnJykpIHsKICAgIGxvY2FsU3RhY2sucG9wKCk7CgogICAgLy8gV2hlbiB1c2luZyBzeW50aGV0aWMgZXZlbnRzLCB3ZSB3aWxsIGhhdmUgYSAyIGxldmVscyBkZWVwIHN0YWNrLCBhcyBgbmV3IEVycm9yKCdTZW50cnkgc3ludGhldGljRXhjZXB0aW9uJylgCiAgICAvLyBpcyBwcm9kdWNlZCB3aXRoaW4gdGhlIGh1YiBpdHNlbGYsIG1ha2luZyBpdDoKICAgIC8vCiAgICAvLyAgIFNlbnRyeS5jYXB0dXJlRXhjZXB0aW9uKCkKICAgIC8vICAgZ2V0Q3VycmVudEh1YigpLmNhcHR1cmVFeGNlcHRpb24oKQogICAgLy8KICAgIC8vIGluc3RlYWQgb2YganVzdCB0aGUgdG9wIGBTZW50cnlgIGNhbGwgaXRzZWxmLgogICAgLy8gVGhpcyBmb3JjZXMgdXMgdG8gcG9zc2libHkgc3RyaXAgYW4gYWRkaXRpb25hbCBmcmFtZSBpbiB0aGUgZXhhY3Qgc2FtZSB3YXMgYXMgYWJvdmUuCiAgICBpZiAoU1RSSVBfRlJBTUVfUkVHRVhQLnRlc3QobG9jYWxTdGFja1tsb2NhbFN0YWNrLmxlbmd0aCAtIDFdLmZ1bmN0aW9uIHx8ICcnKSkgewogICAgICBsb2NhbFN0YWNrLnBvcCgpOwogICAgfQogIH0KCiAgcmV0dXJuIGxvY2FsU3RhY2suc2xpY2UoMCwgU1RBQ0tUUkFDRV9GUkFNRV9MSU1JVCkubWFwKGZyYW1lID0+ICh7CiAgICAuLi5mcmFtZSwKICAgIGZpbGVuYW1lOiBmcmFtZS5maWxlbmFtZSB8fCBsb2NhbFN0YWNrW2xvY2FsU3RhY2subGVuZ3RoIC0gMV0uZmlsZW5hbWUsCiAgICBmdW5jdGlvbjogZnJhbWUuZnVuY3Rpb24gfHwgJz8nLAogIH0pKTsKfQoKY29uc3QgZGVmYXVsdEZ1bmN0aW9uTmFtZSA9ICc8YW5vbnltb3VzPic7CgovKioKICogU2FmZWx5IGV4dHJhY3QgZnVuY3Rpb24gbmFtZSBmcm9tIGl0c2VsZgogKi8KZnVuY3Rpb24gZ2V0RnVuY3Rpb25OYW1lKGZuKSB7CiAgdHJ5IHsKICAgIGlmICghZm4gfHwgdHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nKSB7CiAgICAgIHJldHVybiBkZWZhdWx0RnVuY3Rpb25OYW1lOwogICAgfQogICAgcmV0dXJuIGZuLm5hbWUgfHwgZGVmYXVsdEZ1bmN0aW9uTmFtZTsKICB9IGNhdGNoIChlKSB7CiAgICAvLyBKdXN0IGFjY2Vzc2luZyBjdXN0b20gcHJvcHMgaW4gc29tZSBTZWxlbml1bSBlbnZpcm9ubWVudHMKICAgIC8vIGNhbiBjYXVzZSBhICJQZXJtaXNzaW9uIGRlbmllZCIgZXhjZXB0aW9uIChzZWUgcmF2ZW4tanMjNDk1KS4KICAgIHJldHVybiBkZWZhdWx0RnVuY3Rpb25OYW1lOwogIH0KfQoKLyoqCiAqIFVVSUQ0IGdlbmVyYXRvcgogKgogKiBAcmV0dXJucyBzdHJpbmcgR2VuZXJhdGVkIFVVSUQ0LgogKi8KZnVuY3Rpb24gdXVpZDQoKSB7CiAgY29uc3QgZ2JsID0gR0xPQkFMX09CSiA7CiAgY29uc3QgY3J5cHRvID0gZ2JsLmNyeXB0byB8fCBnYmwubXNDcnlwdG87CgogIGxldCBnZXRSYW5kb21CeXRlID0gKCkgPT4gTWF0aC5yYW5kb20oKSAqIDE2OwogIHRyeSB7CiAgICBpZiAoY3J5cHRvICYmIGNyeXB0by5yYW5kb21VVUlEKSB7CiAgICAgIHJldHVybiBjcnlwdG8ucmFuZG9tVVVJRCgpLnJlcGxhY2UoLy0vZywgJycpOwogICAgfQogICAgaWYgKGNyeXB0byAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKSB7CiAgICAgIGdldFJhbmRvbUJ5dGUgPSAoKSA9PiB7CiAgICAgICAgLy8gY3J5cHRvLmdldFJhbmRvbVZhbHVlcyBtaWdodCByZXR1cm4gdW5kZWZpbmVkIGluc3RlYWQgb2YgdGhlIHR5cGVkIGFycmF5CiAgICAgICAgLy8gaW4gb2xkIENocm9taXVtIHZlcnNpb25zIChlLmcuIDIzLjAuMTIzNS4wICgxNTE0MjIpKQogICAgICAgIC8vIEhvd2V2ZXIsIGB0eXBlZEFycmF5YCBpcyBzdGlsbCBmaWxsZWQgaW4tcGxhY2UuCiAgICAgICAgLy8gQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvQ3J5cHRvL2dldFJhbmRvbVZhbHVlcyN0eXBlZGFycmF5CiAgICAgICAgY29uc3QgdHlwZWRBcnJheSA9IG5ldyBVaW50OEFycmF5KDEpOwogICAgICAgIGNyeXB0by5nZXRSYW5kb21WYWx1ZXModHlwZWRBcnJheSk7CiAgICAgICAgcmV0dXJuIHR5cGVkQXJyYXlbMF07CiAgICAgIH07CiAgICB9CiAgfSBjYXRjaCAoXykgewogICAgLy8gc29tZSBydW50aW1lcyBjYW4gY3Jhc2ggaW52b2tpbmcgY3J5cHRvCiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vZ2V0c2VudHJ5L3NlbnRyeS1qYXZhc2NyaXB0L2lzc3Vlcy84OTM1CiAgfQoKICAvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzEwNTAzNC9ob3ctdG8tY3JlYXRlLWEtZ3VpZC11dWlkLWluLWphdmFzY3JpcHQvMjExNzUyMyMyMTE3NTIzCiAgLy8gQ29uY2F0ZW5hdGluZyB0aGUgZm9sbG93aW5nIG51bWJlcnMgYXMgc3RyaW5ncyByZXN1bHRzIGluICcxMDAwMDAwMDEwMDA0MDAwODAwMDEwMDAwMDAwMDAwMCcKICByZXR1cm4gKChbMWU3XSApICsgMWUzICsgNGUzICsgOGUzICsgMWUxMSkucmVwbGFjZSgvWzAxOF0vZywgYyA9PgogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWJpdHdpc2UKICAgICgoYyApIF4gKChnZXRSYW5kb21CeXRlKCkgJiAxNSkgPj4gKChjICkgLyA0KSkpLnRvU3RyaW5nKDE2KSwKICApOwp9CgovKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLW1lbWJlci1hY2Nlc3MgKi8KLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSAqLwoKLyoqCiAqIEhlbHBlciB0byBkZWN5Y2xlIGpzb24gb2JqZWN0cwogKi8KZnVuY3Rpb24gbWVtb0J1aWxkZXIoKSB7CiAgY29uc3QgaGFzV2Vha1NldCA9IHR5cGVvZiBXZWFrU2V0ID09PSAnZnVuY3Rpb24nOwogIGNvbnN0IGlubmVyID0gaGFzV2Vha1NldCA/IG5ldyBXZWFrU2V0KCkgOiBbXTsKICBmdW5jdGlvbiBtZW1vaXplKG9iaikgewogICAgaWYgKGhhc1dlYWtTZXQpIHsKICAgICAgaWYgKGlubmVyLmhhcyhvYmopKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaW5uZXIuYWRkKG9iaik7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvcHJlZmVyLWZvci1vZgogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbm5lci5sZW5ndGg7IGkrKykgewogICAgICBjb25zdCB2YWx1ZSA9IGlubmVyW2ldOwogICAgICBpZiAodmFsdWUgPT09IG9iaikgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICB9CiAgICBpbm5lci5wdXNoKG9iaik7CiAgICByZXR1cm4gZmFsc2U7CiAgfQoKICBmdW5jdGlvbiB1bm1lbW9pemUob2JqKSB7CiAgICBpZiAoaGFzV2Vha1NldCkgewogICAgICBpbm5lci5kZWxldGUob2JqKTsKICAgIH0gZWxzZSB7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5uZXIubGVuZ3RoOyBpKyspIHsKICAgICAgICBpZiAoaW5uZXJbaV0gPT09IG9iaikgewogICAgICAgICAgaW5uZXIuc3BsaWNlKGksIDEpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBbbWVtb2l6ZSwgdW5tZW1vaXplXTsKfQoKLyoqCiAqIFJlY3Vyc2l2ZWx5IG5vcm1hbGl6ZXMgdGhlIGdpdmVuIG9iamVjdC4KICoKICogLSBDcmVhdGVzIGEgY29weSB0byBwcmV2ZW50IG9yaWdpbmFsIGlucHV0IG11dGF0aW9uCiAqIC0gU2tpcHMgbm9uLWVudW1lcmFibGUgcHJvcGVydGllcwogKiAtIFdoZW4gc3RyaW5naWZ5aW5nLCBjYWxscyBgdG9KU09OYCBpZiBpbXBsZW1lbnRlZAogKiAtIFJlbW92ZXMgY2lyY3VsYXIgcmVmZXJlbmNlcwogKiAtIFRyYW5zbGF0ZXMgbm9uLXNlcmlhbGl6YWJsZSB2YWx1ZXMgKGB1bmRlZmluZWRgL2BOYU5gL2Z1bmN0aW9ucykgdG8gc2VyaWFsaXphYmxlIGZvcm1hdAogKiAtIFRyYW5zbGF0ZXMga25vd24gZ2xvYmFsIG9iamVjdHMvY2xhc3NlcyB0byBhIHN0cmluZyByZXByZXNlbnRhdGlvbnMKICogLSBUYWtlcyBjYXJlIG9mIGBFcnJvcmAgb2JqZWN0IHNlcmlhbGl6YXRpb24KICogLSBPcHRpb25hbGx5IGxpbWl0cyBkZXB0aCBvZiBmaW5hbCBvdXRwdXQKICogLSBPcHRpb25hbGx5IGxpbWl0cyBudW1iZXIgb2YgcHJvcGVydGllcy9lbGVtZW50cyBpbmNsdWRlZCBpbiBhbnkgc2luZ2xlIG9iamVjdC9hcnJheQogKgogKiBAcGFyYW0gaW5wdXQgVGhlIG9iamVjdCB0byBiZSBub3JtYWxpemVkLgogKiBAcGFyYW0gZGVwdGggVGhlIG1heCBkZXB0aCB0byB3aGljaCB0byBub3JtYWxpemUgdGhlIG9iamVjdC4gKEFueXRoaW5nIGRlZXBlciBzdHJpbmdpZmllZCB3aG9sZS4pCiAqIEBwYXJhbSBtYXhQcm9wZXJ0aWVzIFRoZSBtYXggbnVtYmVyIG9mIGVsZW1lbnRzIG9yIHByb3BlcnRpZXMgdG8gYmUgaW5jbHVkZWQgaW4gYW55IHNpbmdsZSBhcnJheSBvcgogKiBvYmplY3QgaW4gdGhlIG5vcm1hbGxpemVkIG91dHB1dC4KICogQHJldHVybnMgQSBub3JtYWxpemVkIHZlcnNpb24gb2YgdGhlIG9iamVjdCwgb3IgYCIqKm5vbi1zZXJpYWxpemFibGUqKiJgIGlmIGFueSBlcnJvcnMgYXJlIHRocm93biBkdXJpbmcgbm9ybWFsaXphdGlvbi4KICovCi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55CmZ1bmN0aW9uIG5vcm1hbGl6ZShpbnB1dCwgZGVwdGggPSAxMDAsIG1heFByb3BlcnRpZXMgPSArSW5maW5pdHkpIHsKICB0cnkgewogICAgLy8gc2luY2Ugd2UncmUgYXQgdGhlIG91dGVybW9zdCBsZXZlbCwgd2UgZG9uJ3QgcHJvdmlkZSBhIGtleQogICAgcmV0dXJuIHZpc2l0KCcnLCBpbnB1dCwgZGVwdGgsIG1heFByb3BlcnRpZXMpOwogIH0gY2F0Y2ggKGVycikgewogICAgcmV0dXJuIHsgRVJST1I6IGAqKm5vbi1zZXJpYWxpemFibGUqKiAoJHtlcnJ9KWAgfTsKICB9Cn0KCi8qKgogKiBWaXNpdHMgYSBub2RlIHRvIHBlcmZvcm0gbm9ybWFsaXphdGlvbiBvbiBpdAogKgogKiBAcGFyYW0ga2V5IFRoZSBrZXkgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gbm9kZQogKiBAcGFyYW0gdmFsdWUgVGhlIG5vZGUgdG8gYmUgdmlzaXRlZAogKiBAcGFyYW0gZGVwdGggT3B0aW9uYWwgbnVtYmVyIGluZGljYXRpbmcgdGhlIG1heGltdW0gcmVjdXJzaW9uIGRlcHRoCiAqIEBwYXJhbSBtYXhQcm9wZXJ0aWVzIE9wdGlvbmFsIG1heGltdW0gbnVtYmVyIG9mIHByb3BlcnRpZXMvZWxlbWVudHMgaW5jbHVkZWQgaW4gYW55IHNpbmdsZSBvYmplY3QvYXJyYXkKICogQHBhcmFtIG1lbW8gT3B0aW9uYWwgTWVtbyBjbGFzcyBoYW5kbGluZyBkZWN5Y2xpbmcKICovCmZ1bmN0aW9uIHZpc2l0KAogIGtleSwKICB2YWx1ZSwKICBkZXB0aCA9ICtJbmZpbml0eSwKICBtYXhQcm9wZXJ0aWVzID0gK0luZmluaXR5LAogIG1lbW8gPSBtZW1vQnVpbGRlcigpLAopIHsKICBjb25zdCBbbWVtb2l6ZSwgdW5tZW1vaXplXSA9IG1lbW87CgogIC8vIEdldCB0aGUgc2ltcGxlIGNhc2VzIG91dCBvZiB0aGUgd2F5IGZpcnN0CiAgaWYgKAogICAgdmFsdWUgPT0gbnVsbCB8fCAvLyB0aGlzIG1hdGNoZXMgbnVsbCBhbmQgdW5kZWZpbmVkIC0+IGVxZXEgbm90IGVxZXFlcQogICAgKFsnbnVtYmVyJywgJ2Jvb2xlYW4nLCAnc3RyaW5nJ10uaW5jbHVkZXModHlwZW9mIHZhbHVlKSAmJiAhaXNOYU4kMSh2YWx1ZSkpCiAgKSB7CiAgICByZXR1cm4gdmFsdWUgOwogIH0KCiAgY29uc3Qgc3RyaW5naWZpZWQgPSBzdHJpbmdpZnlWYWx1ZShrZXksIHZhbHVlKTsKCiAgLy8gQW55dGhpbmcgd2UgY291bGQgcG90ZW50aWFsbHkgZGlnIGludG8gbW9yZSAob2JqZWN0cyBvciBhcnJheXMpIHdpbGwgaGF2ZSBjb21lIGJhY2sgYXMgYCJbb2JqZWN0IFhYWFhdImAuCiAgLy8gRXZlcnl0aGluZyBlbHNlIHdpbGwgaGF2ZSBhbHJlYWR5IGJlZW4gc2VyaWFsaXplZCwgc28gaWYgd2UgZG9uJ3Qgc2VlIHRoYXQgcGF0dGVybiwgd2UncmUgZG9uZS4KICBpZiAoIXN0cmluZ2lmaWVkLnN0YXJ0c1dpdGgoJ1tvYmplY3QgJykpIHsKICAgIHJldHVybiBzdHJpbmdpZmllZDsKICB9CgogIC8vIEZyb20gaGVyZSBvbiwgd2UgY2FuIGFzc2VydCB0aGF0IGB2YWx1ZWAgaXMgZWl0aGVyIGFuIG9iamVjdCBvciBhbiBhcnJheS4KCiAgLy8gRG8gbm90IG5vcm1hbGl6ZSBvYmplY3RzIHRoYXQgd2Uga25vdyBoYXZlIGFscmVhZHkgYmVlbiBub3JtYWxpemVkLiBBcyBhIGdlbmVyYWwgcnVsZSwgdGhlCiAgLy8gIl9fc2VudHJ5X3NraXBfbm9ybWFsaXphdGlvbl9fIiBwcm9wZXJ0eSBzaG91bGQgb25seSBiZSB1c2VkIHNwYXJpbmdseSBhbmQgb25seSBzaG91bGQgb25seSBiZSBzZXQgb24gb2JqZWN0cyB0aGF0CiAgLy8gaGF2ZSBhbHJlYWR5IGJlZW4gbm9ybWFsaXplZC4KICBpZiAoKHZhbHVlIClbJ19fc2VudHJ5X3NraXBfbm9ybWFsaXphdGlvbl9fJ10pIHsKICAgIHJldHVybiB2YWx1ZSA7CiAgfQoKICAvLyBXZSBjYW4gc2V0IGBfX3NlbnRyeV9vdmVycmlkZV9ub3JtYWxpemF0aW9uX2RlcHRoX19gIG9uIGFuIG9iamVjdCB0byBlbnN1cmUgdGhhdCBmcm9tIHRoZXJlCiAgLy8gV2Uga2VlcCBhIGNlcnRhaW4gYW1vdW50IG9mIGRlcHRoLgogIC8vIFRoaXMgc2hvdWxkIGJlIHVzZWQgc3BhcmluZ2x5LCBlLmcuIHdlIHVzZSBpdCBmb3IgdGhlIHJlZHV4IGludGVncmF0aW9uIHRvIGVuc3VyZSB3ZSBnZXQgYSBjZXJ0YWluIGFtb3VudCBvZiBzdGF0ZS4KICBjb25zdCByZW1haW5pbmdEZXB0aCA9CiAgICB0eXBlb2YgKHZhbHVlIClbJ19fc2VudHJ5X292ZXJyaWRlX25vcm1hbGl6YXRpb25fZGVwdGhfXyddID09PSAnbnVtYmVyJwogICAgICA/ICgodmFsdWUgKVsnX19zZW50cnlfb3ZlcnJpZGVfbm9ybWFsaXphdGlvbl9kZXB0aF9fJ10gKQogICAgICA6IGRlcHRoOwoKICAvLyBXZSdyZSBhbHNvIGRvbmUgaWYgd2UndmUgcmVhY2hlZCB0aGUgbWF4IGRlcHRoCiAgaWYgKHJlbWFpbmluZ0RlcHRoID09PSAwKSB7CiAgICAvLyBBdCB0aGlzIHBvaW50IHdlIGtub3cgYHNlcmlhbGl6ZWRgIGlzIGEgc3RyaW5nIG9mIHRoZSBmb3JtIGAiW29iamVjdCBYWFhYXSJgLiBDbGVhbiBpdCB1cCBzbyBpdCdzIGp1c3QgYCJbWFhYWF0iYC4KICAgIHJldHVybiBzdHJpbmdpZmllZC5yZXBsYWNlKCdvYmplY3QgJywgJycpOwogIH0KCiAgLy8gSWYgd2UndmUgYWxyZWFkeSB2aXNpdGVkIHRoaXMgYnJhbmNoLCBiYWlsIG91dCwgYXMgaXQncyBjaXJjdWxhciByZWZlcmVuY2UuIElmIG5vdCwgbm90ZSB0aGF0IHdlJ3JlIHNlZWluZyBpdCBub3cuCiAgaWYgKG1lbW9pemUodmFsdWUpKSB7CiAgICByZXR1cm4gJ1tDaXJjdWxhciB+XSc7CiAgfQoKICAvLyBJZiB0aGUgdmFsdWUgaGFzIGEgYHRvSlNPTmAgbWV0aG9kLCB3ZSBjYWxsIGl0IHRvIGV4dHJhY3QgbW9yZSBpbmZvcm1hdGlvbgogIGNvbnN0IHZhbHVlV2l0aFRvSlNPTiA9IHZhbHVlIDsKICBpZiAodmFsdWVXaXRoVG9KU09OICYmIHR5cGVvZiB2YWx1ZVdpdGhUb0pTT04udG9KU09OID09PSAnZnVuY3Rpb24nKSB7CiAgICB0cnkgewogICAgICBjb25zdCBqc29uVmFsdWUgPSB2YWx1ZVdpdGhUb0pTT04udG9KU09OKCk7CiAgICAgIC8vIFdlIG5lZWQgdG8gbm9ybWFsaXplIHRoZSByZXR1cm4gdmFsdWUgb2YgYC50b0pTT04oKWAgaW4gY2FzZSBpdCBoYXMgY2lyY3VsYXIgcmVmZXJlbmNlcwogICAgICByZXR1cm4gdmlzaXQoJycsIGpzb25WYWx1ZSwgcmVtYWluaW5nRGVwdGggLSAxLCBtYXhQcm9wZXJ0aWVzLCBtZW1vKTsKICAgIH0gY2F0Y2ggKGVycikgewogICAgICAvLyBwYXNzIChUaGUgYnVpbHQtaW4gYHRvSlNPTmAgZmFpbGVkLCBidXQgd2UgY2FuIHN0aWxsIHRyeSB0byBkbyBpdCBvdXJzZWx2ZXMpCiAgICB9CiAgfQoKICAvLyBBdCB0aGlzIHBvaW50IHdlIGtub3cgd2UgZWl0aGVyIGhhdmUgYW4gb2JqZWN0IG9yIGFuIGFycmF5LCB3ZSBoYXZlbid0IHNlZW4gaXQgYmVmb3JlLCBhbmQgd2UncmUgZ29pbmcgdG8gcmVjdXJzZQogIC8vIGJlY2F1c2Ugd2UgaGF2ZW4ndCB5ZXQgcmVhY2hlZCB0aGUgbWF4IGRlcHRoLiBDcmVhdGUgYW4gYWNjdW11bGF0b3IgdG8gaG9sZCB0aGUgcmVzdWx0cyBvZiB2aXNpdGluZyBlYWNoCiAgLy8gcHJvcGVydHkvZW50cnksIGFuZCBrZWVwIHRyYWNrIG9mIHRoZSBudW1iZXIgb2YgaXRlbXMgd2UgYWRkIHRvIGl0LgogIGNvbnN0IG5vcm1hbGl6ZWQgPSAoQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyBbXSA6IHt9KSA7CiAgbGV0IG51bUFkZGVkID0gMDsKCiAgLy8gQmVmb3JlIHdlIGJlZ2luLCBjb252ZXJ0YEVycm9yYCBhbmRgRXZlbnRgIGluc3RhbmNlcyBpbnRvIHBsYWluIG9iamVjdHMsIHNpbmNlIHNvbWUgb2YgZWFjaCBvZiB0aGVpciByZWxldmFudAogIC8vIHByb3BlcnRpZXMgYXJlIG5vbi1lbnVtZXJhYmxlIGFuZCBvdGhlcndpc2Ugd291bGQgZ2V0IG1pc3NlZC4KICBjb25zdCB2aXNpdGFibGUgPSBjb252ZXJ0VG9QbGFpbk9iamVjdCh2YWx1ZSApOwoKICBmb3IgKGNvbnN0IHZpc2l0S2V5IGluIHZpc2l0YWJsZSkgewogICAgLy8gQXZvaWQgaXRlcmF0aW5nIG92ZXIgZmllbGRzIGluIHRoZSBwcm90b3R5cGUgaWYgdGhleSd2ZSBzb21laG93IGJlZW4gZXhwb3NlZCB0byBlbnVtZXJhdGlvbi4KICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHZpc2l0YWJsZSwgdmlzaXRLZXkpKSB7CiAgICAgIGNvbnRpbnVlOwogICAgfQoKICAgIGlmIChudW1BZGRlZCA+PSBtYXhQcm9wZXJ0aWVzKSB7CiAgICAgIG5vcm1hbGl6ZWRbdmlzaXRLZXldID0gJ1tNYXhQcm9wZXJ0aWVzIH5dJzsKICAgICAgYnJlYWs7CiAgICB9CgogICAgLy8gUmVjdXJzaXZlbHkgdmlzaXQgYWxsIHRoZSBjaGlsZCBub2RlcwogICAgY29uc3QgdmlzaXRWYWx1ZSA9IHZpc2l0YWJsZVt2aXNpdEtleV07CiAgICBub3JtYWxpemVkW3Zpc2l0S2V5XSA9IHZpc2l0KHZpc2l0S2V5LCB2aXNpdFZhbHVlLCByZW1haW5pbmdEZXB0aCAtIDEsIG1heFByb3BlcnRpZXMsIG1lbW8pOwoKICAgIG51bUFkZGVkKys7CiAgfQoKICAvLyBPbmNlIHdlJ3ZlIHZpc2l0ZWQgYWxsIHRoZSBicmFuY2hlcywgcmVtb3ZlIHRoZSBwYXJlbnQgZnJvbSBtZW1vIHN0b3JhZ2UKICB1bm1lbW9pemUodmFsdWUpOwoKICAvLyBSZXR1cm4gYWNjdW11bGF0ZWQgdmFsdWVzCiAgcmV0dXJuIG5vcm1hbGl6ZWQ7Cn0KCi8qIGVzbGludC1kaXNhYmxlIGNvbXBsZXhpdHkgKi8KLyoqCiAqIFN0cmluZ2lmeSB0aGUgZ2l2ZW4gdmFsdWUuIEhhbmRsZXMgdmFyaW91cyBrbm93biBzcGVjaWFsIHZhbHVlcyBhbmQgdHlwZXMuCiAqCiAqIE5vdCBtZWFudCB0byBiZSB1c2VkIG9uIHNpbXBsZSBwcmltaXRpdmVzIHdoaWNoIGFscmVhZHkgaGF2ZSBhIHN0cmluZyByZXByZXNlbnRhdGlvbiwgYXMgaXQgd2lsbCwgZm9yIGV4YW1wbGUsIHR1cm4KICogdGhlIG51bWJlciAxMjMxIGludG8gIltPYmplY3QgTnVtYmVyXSIsIG5vciBvbiBgbnVsbGAsIGFzIGl0IHdpbGwgdGhyb3cuCiAqCiAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gc3RyaW5naWZ5CiAqIEByZXR1cm5zIEEgc3RyaW5naWZpZWQgcmVwcmVzZW50YXRpb24gb2YgdGhlIGdpdmVuIHZhbHVlCiAqLwpmdW5jdGlvbiBzdHJpbmdpZnlWYWx1ZSgKICBrZXksCiAgLy8gdGhpcyB0eXBlIGlzIGEgdGlueSBiaXQgb2YgYSBjaGVhdCwgc2luY2UgdGhpcyBmdW5jdGlvbiBkb2VzIGhhbmRsZSBOYU4gKHdoaWNoIGlzIHRlY2huaWNhbGx5IGEgbnVtYmVyKSwgYnV0IGZvcgogIC8vIG91ciBpbnRlcm5hbCB1c2UsIGl0J2xsIGRvCiAgdmFsdWUsCikgewogIHRyeSB7CiAgICBpZiAoa2V5ID09PSAnZG9tYWluJyAmJiB2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmICh2YWx1ZSApLl9ldmVudHMpIHsKICAgICAgcmV0dXJuICdbRG9tYWluXSc7CiAgICB9CgogICAgaWYgKGtleSA9PT0gJ2RvbWFpbkVtaXR0ZXInKSB7CiAgICAgIHJldHVybiAnW0RvbWFpbkVtaXR0ZXJdJzsKICAgIH0KCiAgICAvLyBJdCdzIHNhZmUgdG8gdXNlIGBnbG9iYWxgLCBgd2luZG93YCwgYW5kIGBkb2N1bWVudGAgaGVyZSBpbiB0aGlzIG1hbm5lciwgYXMgd2UgYXJlIGFzc2VydGluZyB1c2luZyBgdHlwZW9mYCBmaXJzdAogICAgLy8gd2hpY2ggd29uJ3QgdGhyb3cgaWYgdGhleSBhcmUgbm90IHByZXNlbnQuCgogICAgaWYgKHR5cGVvZiBnbG9iYWwgIT09ICd1bmRlZmluZWQnICYmIHZhbHVlID09PSBnbG9iYWwpIHsKICAgICAgcmV0dXJuICdbR2xvYmFsXSc7CiAgICB9CgogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlc3RyaWN0ZWQtZ2xvYmFscwogICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHZhbHVlID09PSB3aW5kb3cpIHsKICAgICAgcmV0dXJuICdbV2luZG93XSc7CiAgICB9CgogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlc3RyaWN0ZWQtZ2xvYmFscwogICAgaWYgKHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcgJiYgdmFsdWUgPT09IGRvY3VtZW50KSB7CiAgICAgIHJldHVybiAnW0RvY3VtZW50XSc7CiAgICB9CgogICAgaWYgKGlzVnVlVmlld01vZGVsKHZhbHVlKSkgewogICAgICByZXR1cm4gJ1tWdWVWaWV3TW9kZWxdJzsKICAgIH0KCiAgICAvLyBSZWFjdCdzIFN5bnRoZXRpY0V2ZW50IHRoaW5neQogICAgaWYgKGlzU3ludGhldGljRXZlbnQodmFsdWUpKSB7CiAgICAgIHJldHVybiAnW1N5bnRoZXRpY0V2ZW50XSc7CiAgICB9CgogICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgJiYgdmFsdWUgIT09IHZhbHVlKSB7CiAgICAgIHJldHVybiAnW05hTl0nOwogICAgfQoKICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHsKICAgICAgcmV0dXJuIGBbRnVuY3Rpb246ICR7Z2V0RnVuY3Rpb25OYW1lKHZhbHVlKX1dYDsKICAgIH0KCiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3ltYm9sJykgewogICAgICByZXR1cm4gYFske1N0cmluZyh2YWx1ZSl9XWA7CiAgICB9CgogICAgLy8gc3RyaW5naWZpZWQgQmlnSW50cyBhcmUgaW5kaXN0aW5ndWlzaGFibGUgZnJvbSByZWd1bGFyIG51bWJlcnMsIHNvIHdlIG5lZWQgdG8gbGFiZWwgdGhlbSB0byBhdm9pZCBjb25mdXNpb24KICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdiaWdpbnQnKSB7CiAgICAgIHJldHVybiBgW0JpZ0ludDogJHtTdHJpbmcodmFsdWUpfV1gOwogICAgfQoKICAgIC8vIE5vdyB0aGF0IHdlJ3ZlIGtub2NrZWQgb3V0IGFsbCB0aGUgc3BlY2lhbCBjYXNlcyBhbmQgdGhlIHByaW1pdGl2ZXMsIGFsbCB3ZSBoYXZlIGxlZnQgYXJlIG9iamVjdHMuIFNpbXBseSBjYXN0aW5nCiAgICAvLyB0aGVtIHRvIHN0cmluZ3MgbWVhbnMgdGhhdCBpbnN0YW5jZXMgb2YgY2xhc3NlcyB3aGljaCBoYXZlbid0IGRlZmluZWQgdGhlaXIgYHRvU3RyaW5nVGFnYCB3aWxsIGp1c3QgY29tZSBvdXQgYXMKICAgIC8vIGAiW29iamVjdCBPYmplY3RdImAuIElmIHdlIGluc3RlYWQgbG9vayBhdCB0aGUgY29uc3RydWN0b3IncyBuYW1lICh3aGljaCBpcyB0aGUgc2FtZSBhcyB0aGUgbmFtZSBvZiB0aGUgY2xhc3MpLAogICAgLy8gd2UgY2FuIG1ha2Ugc3VyZSB0aGF0IG9ubHkgcGxhaW4gb2JqZWN0cyBjb21lIG91dCB0aGF0IHdheS4KICAgIGNvbnN0IG9iak5hbWUgPSBnZXRDb25zdHJ1Y3Rvck5hbWUodmFsdWUpOwoKICAgIC8vIEhhbmRsZSBIVE1MIEVsZW1lbnRzCiAgICBpZiAoL15IVE1MKFx3KilFbGVtZW50JC8udGVzdChvYmpOYW1lKSkgewogICAgICByZXR1cm4gYFtIVE1MRWxlbWVudDogJHtvYmpOYW1lfV1gOwogICAgfQoKICAgIHJldHVybiBgW29iamVjdCAke29iak5hbWV9XWA7CiAgfSBjYXRjaCAoZXJyKSB7CiAgICByZXR1cm4gYCoqbm9uLXNlcmlhbGl6YWJsZSoqICgke2Vycn0pYDsKICB9Cn0KLyogZXNsaW50LWVuYWJsZSBjb21wbGV4aXR5ICovCgpmdW5jdGlvbiBnZXRDb25zdHJ1Y3Rvck5hbWUodmFsdWUpIHsKICBjb25zdCBwcm90b3R5cGUgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YodmFsdWUpOwoKICByZXR1cm4gcHJvdG90eXBlID8gcHJvdG90eXBlLmNvbnN0cnVjdG9yLm5hbWUgOiAnbnVsbCBwcm90b3R5cGUnOwp9CgovKioKICogTm9ybWFsaXplcyBVUkxzIGluIGV4Y2VwdGlvbnMgYW5kIHN0YWNrdHJhY2VzIHRvIGEgYmFzZSBwYXRoIHNvIFNlbnRyeSBjYW4gZmluZ2VycHJpbnQKICogYWNyb3NzIHBsYXRmb3JtcyBhbmQgd29ya2luZyBkaXJlY3RvcnkuCiAqCiAqIEBwYXJhbSB1cmwgVGhlIFVSTCB0byBiZSBub3JtYWxpemVkLgogKiBAcGFyYW0gYmFzZVBhdGggVGhlIGFwcGxpY2F0aW9uIGJhc2UgcGF0aC4KICogQHJldHVybnMgVGhlIG5vcm1hbGl6ZWQgVVJMLgogKi8KZnVuY3Rpb24gbm9ybWFsaXplVXJsVG9CYXNlKHVybCwgYmFzZVBhdGgpIHsKICBjb25zdCBlc2NhcGVkQmFzZSA9IGJhc2VQYXRoCiAgICAvLyBCYWNrc2xhc2ggdG8gZm9yd2FyZAogICAgLnJlcGxhY2UoL1xcL2csICcvJykKICAgIC8vIEVzY2FwZSBSZWdFeHAgc3BlY2lhbCBjaGFyYWN0ZXJzCiAgICAucmVwbGFjZSgvW3xcXHt9KClbXF1eJCsqPy5dL2csICdcXCQmJyk7CgogIGxldCBuZXdVcmwgPSB1cmw7CiAgdHJ5IHsKICAgIG5ld1VybCA9IGRlY29kZVVSSSh1cmwpOwogIH0gY2F0Y2ggKF9PbykgewogICAgLy8gU29tZXRpbWUgdGhpcyBicmVha3MKICB9CiAgcmV0dXJuICgKICAgIG5ld1VybAogICAgICAucmVwbGFjZSgvXFwvZywgJy8nKQogICAgICAucmVwbGFjZSgvd2VicGFjazpcLz8vZywgJycpIC8vIFJlbW92ZSBpbnRlcm1lZGlhdGUgYmFzZSBwYXRoCiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAc2VudHJ5LWludGVybmFsL3Nkay9uby1yZWdleHAtY29uc3RydWN0b3IKICAgICAgLnJlcGxhY2UobmV3IFJlZ0V4cChgKGZpbGU6Ly8pPy8qJHtlc2NhcGVkQmFzZX0vKmAsICdpZycpLCAnYXBwOi8vLycpCiAgKTsKfQoKLy8gU2xpZ2h0bHkgbW9kaWZpZWQgKG5vIElFOCBzdXBwb3J0LCBFUzYpIGFuZCB0cmFuc2NyaWJlZCB0byBUeXBlU2NyaXB0CgovLyBTcGxpdCBhIGZpbGVuYW1lIGludG8gW3Jvb3QsIGRpciwgYmFzZW5hbWUsIGV4dF0sIHVuaXggdmVyc2lvbgovLyAncm9vdCcgaXMganVzdCBhIHNsYXNoLCBvciBub3RoaW5nLgpjb25zdCBzcGxpdFBhdGhSZSA9IC9eKFxTKzpcXHxcLz8pKFtcc1xTXSo/KSgoPzpcLnsxLDJ9fFteL1xcXSs/fCkoXC5bXi4vXFxdKnwpKSg/OlsvXFxdKikkLzsKLyoqIEpTRG9jICovCmZ1bmN0aW9uIHNwbGl0UGF0aChmaWxlbmFtZSkgewogIC8vIFRydW5jYXRlIGZpbGVzIG5hbWVzIGdyZWF0ZXIgdGhhbiAxMDI0IGNoYXJhY3RlcnMgdG8gYXZvaWQgcmVnZXggZG9zCiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdC9wdWxsLzg3MzcjZGlzY3Vzc2lvbl9yMTI4NTcxOTE3MgogIGNvbnN0IHRydW5jYXRlZCA9IGZpbGVuYW1lLmxlbmd0aCA+IDEwMjQgPyBgPHRydW5jYXRlZD4ke2ZpbGVuYW1lLnNsaWNlKC0xMDI0KX1gIDogZmlsZW5hbWU7CiAgY29uc3QgcGFydHMgPSBzcGxpdFBhdGhSZS5leGVjKHRydW5jYXRlZCk7CiAgcmV0dXJuIHBhcnRzID8gcGFydHMuc2xpY2UoMSkgOiBbXTsKfQoKLyoqIEpTRG9jICovCmZ1bmN0aW9uIGRpcm5hbWUocGF0aCkgewogIGNvbnN0IHJlc3VsdCA9IHNwbGl0UGF0aChwYXRoKTsKICBjb25zdCByb290ID0gcmVzdWx0WzBdOwogIGxldCBkaXIgPSByZXN1bHRbMV07CgogIGlmICghcm9vdCAmJiAhZGlyKSB7CiAgICAvLyBObyBkaXJuYW1lIHdoYXRzb2V2ZXIKICAgIHJldHVybiAnLic7CiAgfQoKICBpZiAoZGlyKSB7CiAgICAvLyBJdCBoYXMgYSBkaXJuYW1lLCBzdHJpcCB0cmFpbGluZyBzbGFzaAogICAgZGlyID0gZGlyLnNsaWNlKDAsIGRpci5sZW5ndGggLSAxKTsKICB9CgogIHJldHVybiByb290ICsgZGlyOwp9CgovKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvZXhwbGljaXQtZnVuY3Rpb24tcmV0dXJuLXR5cGUgKi8KCi8qKiBTeW5jUHJvbWlzZSBpbnRlcm5hbCBzdGF0ZXMgKi8KdmFyIFN0YXRlczsgKGZ1bmN0aW9uIChTdGF0ZXMpIHsKICAvKiogUGVuZGluZyAqLwogIGNvbnN0IFBFTkRJTkcgPSAwOyBTdGF0ZXNbU3RhdGVzWyJQRU5ESU5HIl0gPSBQRU5ESU5HXSA9ICJQRU5ESU5HIjsKICAvKiogUmVzb2x2ZWQgLyBPSyAqLwogIGNvbnN0IFJFU09MVkVEID0gMTsgU3RhdGVzW1N0YXRlc1siUkVTT0xWRUQiXSA9IFJFU09MVkVEXSA9ICJSRVNPTFZFRCI7CiAgLyoqIFJlamVjdGVkIC8gRXJyb3IgKi8KICBjb25zdCBSRUpFQ1RFRCA9IDI7IFN0YXRlc1tTdGF0ZXNbIlJFSkVDVEVEIl0gPSBSRUpFQ1RFRF0gPSAiUkVKRUNURUQiOwp9KShTdGF0ZXMgfHwgKFN0YXRlcyA9IHt9KSk7CgovLyBPdmVybG9hZHMgc28gd2UgY2FuIGNhbGwgcmVzb2x2ZWRTeW5jUHJvbWlzZSB3aXRob3V0IGFyZ3VtZW50cyBhbmQgZ2VuZXJpYyBhcmd1bWVudAoKLyoqCiAqIENyZWF0ZXMgYSByZXNvbHZlZCBzeW5jIHByb21pc2UuCiAqCiAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgdG8gcmVzb2x2ZSB0aGUgcHJvbWlzZSB3aXRoCiAqIEByZXR1cm5zIHRoZSByZXNvbHZlZCBzeW5jIHByb21pc2UKICovCmZ1bmN0aW9uIHJlc29sdmVkU3luY1Byb21pc2UodmFsdWUpIHsKICByZXR1cm4gbmV3IFN5bmNQcm9taXNlKHJlc29sdmUgPT4gewogICAgcmVzb2x2ZSh2YWx1ZSk7CiAgfSk7Cn0KCi8qKgogKiBDcmVhdGVzIGEgcmVqZWN0ZWQgc3luYyBwcm9taXNlLgogKgogKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlIHRvIHJlamVjdCB0aGUgcHJvbWlzZSB3aXRoCiAqIEByZXR1cm5zIHRoZSByZWplY3RlZCBzeW5jIHByb21pc2UKICovCmZ1bmN0aW9uIHJlamVjdGVkU3luY1Byb21pc2UocmVhc29uKSB7CiAgcmV0dXJuIG5ldyBTeW5jUHJvbWlzZSgoXywgcmVqZWN0KSA9PiB7CiAgICByZWplY3QocmVhc29uKTsKICB9KTsKfQoKLyoqCiAqIFRoZW5hYmxlIGNsYXNzIHRoYXQgYmVoYXZlcyBsaWtlIGEgUHJvbWlzZSBhbmQgZm9sbG93cyBpdCdzIGludGVyZmFjZQogKiBidXQgaXMgbm90IGFzeW5jIGludGVybmFsbHkKICovCmNsYXNzIFN5bmNQcm9taXNlIHsKCiAgIGNvbnN0cnVjdG9yKAogICAgZXhlY3V0b3IsCiAgKSB7U3luY1Byb21pc2UucHJvdG90eXBlLl9faW5pdC5jYWxsKHRoaXMpO1N5bmNQcm9taXNlLnByb3RvdHlwZS5fX2luaXQyLmNhbGwodGhpcyk7U3luY1Byb21pc2UucHJvdG90eXBlLl9faW5pdDMuY2FsbCh0aGlzKTtTeW5jUHJvbWlzZS5wcm90b3R5cGUuX19pbml0NC5jYWxsKHRoaXMpOwogICAgdGhpcy5fc3RhdGUgPSBTdGF0ZXMuUEVORElORzsKICAgIHRoaXMuX2hhbmRsZXJzID0gW107CgogICAgdHJ5IHsKICAgICAgZXhlY3V0b3IodGhpcy5fcmVzb2x2ZSwgdGhpcy5fcmVqZWN0KTsKICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgdGhpcy5fcmVqZWN0KGUpOwogICAgfQogIH0KCiAgLyoqIEpTRG9jICovCiAgIHRoZW4oCiAgICBvbmZ1bGZpbGxlZCwKICAgIG9ucmVqZWN0ZWQsCiAgKSB7CiAgICByZXR1cm4gbmV3IFN5bmNQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHsKICAgICAgdGhpcy5faGFuZGxlcnMucHVzaChbCiAgICAgICAgZmFsc2UsCiAgICAgICAgcmVzdWx0ID0+IHsKICAgICAgICAgIGlmICghb25mdWxmaWxsZWQpIHsKICAgICAgICAgICAgLy8gVE9ETzogwq9cXyjjg4QpXy/CrwogICAgICAgICAgICAvLyBUT0RPOiBGSVhNRQogICAgICAgICAgICByZXNvbHZlKHJlc3VsdCApOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICByZXNvbHZlKG9uZnVsZmlsbGVkKHJlc3VsdCkpOwogICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgcmVqZWN0KGUpOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICByZWFzb24gPT4gewogICAgICAgICAgaWYgKCFvbnJlamVjdGVkKSB7CiAgICAgICAgICAgIHJlamVjdChyZWFzb24pOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICByZXNvbHZlKG9ucmVqZWN0ZWQocmVhc29uKSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICByZWplY3QoZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9LAogICAgICBdKTsKICAgICAgdGhpcy5fZXhlY3V0ZUhhbmRsZXJzKCk7CiAgICB9KTsKICB9CgogIC8qKiBKU0RvYyAqLwogICBjYXRjaCgKICAgIG9ucmVqZWN0ZWQsCiAgKSB7CiAgICByZXR1cm4gdGhpcy50aGVuKHZhbCA9PiB2YWwsIG9ucmVqZWN0ZWQpOwogIH0KCiAgLyoqIEpTRG9jICovCiAgIGZpbmFsbHkob25maW5hbGx5KSB7CiAgICByZXR1cm4gbmV3IFN5bmNQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHsKICAgICAgbGV0IHZhbDsKICAgICAgbGV0IGlzUmVqZWN0ZWQ7CgogICAgICByZXR1cm4gdGhpcy50aGVuKAogICAgICAgIHZhbHVlID0+IHsKICAgICAgICAgIGlzUmVqZWN0ZWQgPSBmYWxzZTsKICAgICAgICAgIHZhbCA9IHZhbHVlOwogICAgICAgICAgaWYgKG9uZmluYWxseSkgewogICAgICAgICAgICBvbmZpbmFsbHkoKTsKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHJlYXNvbiA9PiB7CiAgICAgICAgICBpc1JlamVjdGVkID0gdHJ1ZTsKICAgICAgICAgIHZhbCA9IHJlYXNvbjsKICAgICAgICAgIGlmIChvbmZpbmFsbHkpIHsKICAgICAgICAgICAgb25maW5hbGx5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgKS50aGVuKCgpID0+IHsKICAgICAgICBpZiAoaXNSZWplY3RlZCkgewogICAgICAgICAgcmVqZWN0KHZhbCk7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICByZXNvbHZlKHZhbCApOwogICAgICB9KTsKICAgIH0pOwogIH0KCiAgLyoqIEpTRG9jICovCiAgICBfX2luaXQoKSB7dGhpcy5fcmVzb2x2ZSA9ICh2YWx1ZSkgPT4gewogICAgdGhpcy5fc2V0UmVzdWx0KFN0YXRlcy5SRVNPTFZFRCwgdmFsdWUpOwogIH07fQoKICAvKiogSlNEb2MgKi8KICAgIF9faW5pdDIoKSB7dGhpcy5fcmVqZWN0ID0gKHJlYXNvbikgPT4gewogICAgdGhpcy5fc2V0UmVzdWx0KFN0YXRlcy5SRUpFQ1RFRCwgcmVhc29uKTsKICB9O30KCiAgLyoqIEpTRG9jICovCiAgICBfX2luaXQzKCkge3RoaXMuX3NldFJlc3VsdCA9IChzdGF0ZSwgdmFsdWUpID0+IHsKICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gU3RhdGVzLlBFTkRJTkcpIHsKICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmIChpc1RoZW5hYmxlKHZhbHVlKSkgewogICAgICB2b2lkICh2YWx1ZSApLnRoZW4odGhpcy5fcmVzb2x2ZSwgdGhpcy5fcmVqZWN0KTsKICAgICAgcmV0dXJuOwogICAgfQoKICAgIHRoaXMuX3N0YXRlID0gc3RhdGU7CiAgICB0aGlzLl92YWx1ZSA9IHZhbHVlOwoKICAgIHRoaXMuX2V4ZWN1dGVIYW5kbGVycygpOwogIH07fQoKICAvKiogSlNEb2MgKi8KICAgIF9faW5pdDQoKSB7dGhpcy5fZXhlY3V0ZUhhbmRsZXJzID0gKCkgPT4gewogICAgaWYgKHRoaXMuX3N0YXRlID09PSBTdGF0ZXMuUEVORElORykgewogICAgICByZXR1cm47CiAgICB9CgogICAgY29uc3QgY2FjaGVkSGFuZGxlcnMgPSB0aGlzLl9oYW5kbGVycy5zbGljZSgpOwogICAgdGhpcy5faGFuZGxlcnMgPSBbXTsKCiAgICBjYWNoZWRIYW5kbGVycy5mb3JFYWNoKGhhbmRsZXIgPT4gewogICAgICBpZiAoaGFuZGxlclswXSkgewogICAgICAgIHJldHVybjsKICAgICAgfQoKICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSBTdGF0ZXMuUkVTT0xWRUQpIHsKICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWZsb2F0aW5nLXByb21pc2VzCiAgICAgICAgaGFuZGxlclsxXSh0aGlzLl92YWx1ZSApOwogICAgICB9CgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFN0YXRlcy5SRUpFQ1RFRCkgewogICAgICAgIGhhbmRsZXJbMl0odGhpcy5fdmFsdWUpOwogICAgICB9CgogICAgICBoYW5kbGVyWzBdID0gdHJ1ZTsKICAgIH0pOwogIH07fQp9CgovKioKICogQ3JlYXRlcyBhbiBuZXcgUHJvbWlzZUJ1ZmZlciBvYmplY3Qgd2l0aCB0aGUgc3BlY2lmaWVkIGxpbWl0CiAqIEBwYXJhbSBsaW1pdCBtYXggbnVtYmVyIG9mIHByb21pc2VzIHRoYXQgY2FuIGJlIHN0b3JlZCBpbiB0aGUgYnVmZmVyCiAqLwpmdW5jdGlvbiBtYWtlUHJvbWlzZUJ1ZmZlcihsaW1pdCkgewogIGNvbnN0IGJ1ZmZlciA9IFtdOwoKICBmdW5jdGlvbiBpc1JlYWR5KCkgewogICAgcmV0dXJuIGxpbWl0ID09PSB1bmRlZmluZWQgfHwgYnVmZmVyLmxlbmd0aCA8IGxpbWl0OwogIH0KCiAgLyoqCiAgICogUmVtb3ZlIGEgcHJvbWlzZSBmcm9tIHRoZSBxdWV1ZS4KICAgKgogICAqIEBwYXJhbSB0YXNrIENhbiBiZSBhbnkgUHJvbWlzZUxpa2U8VD4KICAgKiBAcmV0dXJucyBSZW1vdmVkIHByb21pc2UuCiAgICovCiAgZnVuY3Rpb24gcmVtb3ZlKHRhc2spIHsKICAgIHJldHVybiBidWZmZXIuc3BsaWNlKGJ1ZmZlci5pbmRleE9mKHRhc2spLCAxKVswXTsKICB9CgogIC8qKgogICAqIEFkZCBhIHByb21pc2UgKHJlcHJlc2VudGluZyBhbiBpbi1mbGlnaHQgYWN0aW9uKSB0byB0aGUgcXVldWUsIGFuZCBzZXQgaXQgdG8gcmVtb3ZlIGl0c2VsZiBvbiBmdWxmaWxsbWVudC4KICAgKgogICAqIEBwYXJhbSB0YXNrUHJvZHVjZXIgQSBmdW5jdGlvbiBwcm9kdWNpbmcgYW55IFByb21pc2VMaWtlPFQ+OyBJbiBwcmV2aW91cyB2ZXJzaW9ucyB0aGlzIHVzZWQgdG8gYmUgYHRhc2s6CiAgICogICAgICAgIFByb21pc2VMaWtlPFQ+YCwgYnV0IHVuZGVyIHRoYXQgbW9kZWwsIFByb21pc2VzIHdlcmUgaW5zdGFudGx5IGNyZWF0ZWQgb24gdGhlIGNhbGwtc2l0ZSBhbmQgdGhlaXIgZXhlY3V0b3IKICAgKiAgICAgICAgZnVuY3Rpb25zIHRoZXJlZm9yZSByYW4gaW1tZWRpYXRlbHkuIFRodXMsIGV2ZW4gaWYgdGhlIGJ1ZmZlciB3YXMgZnVsbCwgdGhlIGFjdGlvbiBzdGlsbCBoYXBwZW5lZC4gQnkKICAgKiAgICAgICAgcmVxdWlyaW5nIHRoZSBwcm9taXNlIHRvIGJlIHdyYXBwZWQgaW4gYSBmdW5jdGlvbiwgd2UgY2FuIGRlZmVyIHByb21pc2UgY3JlYXRpb24gdW50aWwgYWZ0ZXIgdGhlIGJ1ZmZlcgogICAqICAgICAgICBsaW1pdCBjaGVjay4KICAgKiBAcmV0dXJucyBUaGUgb3JpZ2luYWwgcHJvbWlzZS4KICAgKi8KICBmdW5jdGlvbiBhZGQodGFza1Byb2R1Y2VyKSB7CiAgICBpZiAoIWlzUmVhZHkoKSkgewogICAgICByZXR1cm4gcmVqZWN0ZWRTeW5jUHJvbWlzZShuZXcgU2VudHJ5RXJyb3IoJ05vdCBhZGRpbmcgUHJvbWlzZSBiZWNhdXNlIGJ1ZmZlciBsaW1pdCB3YXMgcmVhY2hlZC4nKSk7CiAgICB9CgogICAgLy8gc3RhcnQgdGhlIHRhc2sgYW5kIGFkZCBpdHMgcHJvbWlzZSB0byB0aGUgcXVldWUKICAgIGNvbnN0IHRhc2sgPSB0YXNrUHJvZHVjZXIoKTsKICAgIGlmIChidWZmZXIuaW5kZXhPZih0YXNrKSA9PT0gLTEpIHsKICAgICAgYnVmZmVyLnB1c2godGFzayk7CiAgICB9CiAgICB2b2lkIHRhc2sKICAgICAgLnRoZW4oKCkgPT4gcmVtb3ZlKHRhc2spKQogICAgICAvLyBVc2UgYHRoZW4obnVsbCwgcmVqZWN0aW9uSGFuZGxlcilgIHJhdGhlciB0aGFuIGBjYXRjaChyZWplY3Rpb25IYW5kbGVyKWAgc28gdGhhdCB3ZSBjYW4gdXNlIGBQcm9taXNlTGlrZWAKICAgICAgLy8gcmF0aGVyIHRoYW4gYFByb21pc2VgLiBgUHJvbWlzZUxpa2VgIGRvZXNuJ3QgaGF2ZSBhIGAuY2F0Y2hgIG1ldGhvZCwgbWFraW5nIGl0cyBwb2x5ZmlsbCBzbWFsbGVyLiAoRVM1IGRpZG4ndAogICAgICAvLyBoYXZlIHByb21pc2VzLCBzbyBUUyBoYXMgdG8gcG9seWZpbGwgd2hlbiBkb3duLWNvbXBpbGluZy4pCiAgICAgIC50aGVuKG51bGwsICgpID0+CiAgICAgICAgcmVtb3ZlKHRhc2spLnRoZW4obnVsbCwgKCkgPT4gewogICAgICAgICAgLy8gV2UgaGF2ZSB0byBhZGQgYW5vdGhlciBjYXRjaCBoZXJlIGJlY2F1c2UgYHJlbW92ZSgpYCBzdGFydHMgYSBuZXcgcHJvbWlzZSBjaGFpbi4KICAgICAgICB9KSwKICAgICAgKTsKICAgIHJldHVybiB0YXNrOwogIH0KCiAgLyoqCiAgICogV2FpdCBmb3IgYWxsIHByb21pc2VzIGluIHRoZSBxdWV1ZSB0byByZXNvbHZlIG9yIGZvciB0aW1lb3V0IHRvIGV4cGlyZSwgd2hpY2hldmVyIGNvbWVzIGZpcnN0LgogICAqCiAgICogQHBhcmFtIHRpbWVvdXQgVGhlIHRpbWUsIGluIG1zLCBhZnRlciB3aGljaCB0byByZXNvbHZlIHRvIGBmYWxzZWAgaWYgdGhlIHF1ZXVlIGlzIHN0aWxsIG5vbi1lbXB0eS4gUGFzc2luZyBgMGAgKG9yCiAgICogbm90IHBhc3NpbmcgYW55dGhpbmcpIHdpbGwgbWFrZSB0aGUgcHJvbWlzZSB3YWl0IGFzIGxvbmcgYXMgaXQgdGFrZXMgZm9yIHRoZSBxdWV1ZSB0byBkcmFpbiBiZWZvcmUgcmVzb2x2aW5nIHRvCiAgICogYHRydWVgLgogICAqIEByZXR1cm5zIEEgcHJvbWlzZSB3aGljaCB3aWxsIHJlc29sdmUgdG8gYHRydWVgIGlmIHRoZSBxdWV1ZSBpcyBhbHJlYWR5IGVtcHR5IG9yIGRyYWlucyBiZWZvcmUgdGhlIHRpbWVvdXQsIGFuZAogICAqIGBmYWxzZWAgb3RoZXJ3aXNlCiAgICovCiAgZnVuY3Rpb24gZHJhaW4odGltZW91dCkgewogICAgcmV0dXJuIG5ldyBTeW5jUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7CiAgICAgIGxldCBjb3VudGVyID0gYnVmZmVyLmxlbmd0aDsKCiAgICAgIGlmICghY291bnRlcikgewogICAgICAgIHJldHVybiByZXNvbHZlKHRydWUpOwogICAgICB9CgogICAgICAvLyB3YWl0IGZvciBgdGltZW91dGAgbXMgYW5kIHRoZW4gcmVzb2x2ZSB0byBgZmFsc2VgIChpZiBub3QgY2FuY2VsbGVkIGZpcnN0KQogICAgICBjb25zdCBjYXB0dXJlZFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHsKICAgICAgICBpZiAodGltZW91dCAmJiB0aW1lb3V0ID4gMCkgewogICAgICAgICAgcmVzb2x2ZShmYWxzZSk7CiAgICAgICAgfQogICAgICB9LCB0aW1lb3V0KTsKCiAgICAgIC8vIGlmIGFsbCBwcm9taXNlcyByZXNvbHZlIGluIHRpbWUsIGNhbmNlbCB0aGUgdGltZXIgYW5kIHJlc29sdmUgdG8gYHRydWVgCiAgICAgIGJ1ZmZlci5mb3JFYWNoKGl0ZW0gPT4gewogICAgICAgIHZvaWQgcmVzb2x2ZWRTeW5jUHJvbWlzZShpdGVtKS50aGVuKCgpID0+IHsKICAgICAgICAgIGlmICghLS1jb3VudGVyKSB7CiAgICAgICAgICAgIGNsZWFyVGltZW91dChjYXB0dXJlZFNldFRpbWVvdXQpOwogICAgICAgICAgICByZXNvbHZlKHRydWUpOwogICAgICAgICAgfQogICAgICAgIH0sIHJlamVjdCk7CiAgICAgIH0pOwogICAgfSk7CiAgfQoKICByZXR1cm4gewogICAgJDogYnVmZmVyLAogICAgYWRkLAogICAgZHJhaW4sCiAgfTsKfQoKY29uc3QgT05FX1NFQ09ORF9JTl9NUyA9IDEwMDA7CgovKioKICogQSBwYXJ0aWFsIGRlZmluaXRpb24gb2YgdGhlIFtQZXJmb3JtYW5jZSBXZWIgQVBJXXtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvUGVyZm9ybWFuY2V9CiAqIGZvciBhY2Nlc3NpbmcgYSBoaWdoLXJlc29sdXRpb24gbW9ub3RvbmljIGNsb2NrLgogKi8KCi8qKgogKiBSZXR1cm5zIGEgdGltZXN0YW1wIGluIHNlY29uZHMgc2luY2UgdGhlIFVOSVggZXBvY2ggdXNpbmcgdGhlIERhdGUgQVBJLgogKgogKiBUT0RPKHY4KTogUmV0dXJuIHR5cGUgc2hvdWxkIGJlIHJvdW5kZWQuCiAqLwpmdW5jdGlvbiBkYXRlVGltZXN0YW1wSW5TZWNvbmRzKCkgewogIHJldHVybiBEYXRlLm5vdygpIC8gT05FX1NFQ09ORF9JTl9NUzsKfQoKLyoqCiAqIFJldHVybnMgYSB3cmFwcGVyIGFyb3VuZCB0aGUgbmF0aXZlIFBlcmZvcm1hbmNlIEFQSSBicm93c2VyIGltcGxlbWVudGF0aW9uLCBvciB1bmRlZmluZWQgZm9yIGJyb3dzZXJzIHRoYXQgZG8gbm90CiAqIHN1cHBvcnQgdGhlIEFQSS4KICoKICogV3JhcHBpbmcgdGhlIG5hdGl2ZSBBUEkgd29ya3MgYXJvdW5kIGRpZmZlcmVuY2VzIGluIGJlaGF2aW9yIGZyb20gZGlmZmVyZW50IGJyb3dzZXJzLgogKi8KZnVuY3Rpb24gY3JlYXRlVW5peFRpbWVzdGFtcEluU2Vjb25kc0Z1bmMoKSB7CiAgY29uc3QgeyBwZXJmb3JtYW5jZSB9ID0gR0xPQkFMX09CSiA7CiAgaWYgKCFwZXJmb3JtYW5jZSB8fCAhcGVyZm9ybWFuY2Uubm93KSB7CiAgICByZXR1cm4gZGF0ZVRpbWVzdGFtcEluU2Vjb25kczsKICB9CgogIC8vIFNvbWUgYnJvd3NlciBhbmQgZW52aXJvbm1lbnRzIGRvbid0IGhhdmUgYSB0aW1lT3JpZ2luLCBzbyB3ZSBmYWxsYmFjayB0bwogIC8vIHVzaW5nIERhdGUubm93KCkgdG8gY29tcHV0ZSB0aGUgc3RhcnRpbmcgdGltZS4KICBjb25zdCBhcHByb3hTdGFydGluZ1RpbWVPcmlnaW4gPSBEYXRlLm5vdygpIC0gcGVyZm9ybWFuY2Uubm93KCk7CiAgY29uc3QgdGltZU9yaWdpbiA9IHBlcmZvcm1hbmNlLnRpbWVPcmlnaW4gPT0gdW5kZWZpbmVkID8gYXBwcm94U3RhcnRpbmdUaW1lT3JpZ2luIDogcGVyZm9ybWFuY2UudGltZU9yaWdpbjsKCiAgLy8gcGVyZm9ybWFuY2Uubm93KCkgaXMgYSBtb25vdG9uaWMgY2xvY2ssIHdoaWNoIG1lYW5zIGl0IHN0YXJ0cyBhdCAwIHdoZW4gdGhlIHByb2Nlc3MgYmVnaW5zLiBUbyBnZXQgdGhlIGN1cnJlbnQKICAvLyB3YWxsIGNsb2NrIHRpbWUgKGFjdHVhbCBVTklYIHRpbWVzdGFtcCksIHdlIG5lZWQgdG8gYWRkIHRoZSBzdGFydGluZyB0aW1lIG9yaWdpbiBhbmQgdGhlIGN1cnJlbnQgdGltZSBlbGFwc2VkLgogIC8vCiAgLy8gVE9ETzogVGhpcyBkb2VzIG5vdCBhY2NvdW50IGZvciB0aGUgY2FzZSB3aGVyZSB0aGUgbW9ub3RvbmljIGNsb2NrIHRoYXQgcG93ZXJzIHBlcmZvcm1hbmNlLm5vdygpIGRyaWZ0cyBmcm9tIHRoZQogIC8vIHdhbGwgY2xvY2sgdGltZSwgd2hpY2ggY2F1c2VzIHRoZSByZXR1cm5lZCB0aW1lc3RhbXAgdG8gYmUgaW5hY2N1cmF0ZS4gV2Ugc2hvdWxkIGludmVzdGlnYXRlIGhvdyB0byBkZXRlY3QgYW5kCiAgLy8gY29ycmVjdCBmb3IgdGhpcy4KICAvLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9nZXRzZW50cnkvc2VudHJ5LWphdmFzY3JpcHQvaXNzdWVzLzI1OTAKICAvLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9tZG4vY29udGVudC9pc3N1ZXMvNDcxMwogIC8vIFNlZTogaHR0cHM6Ly9kZXYudG8vbm9hbXIvd2hlbi1hLW1pbGxpc2Vjb25kLWlzLW5vdC1hLW1pbGxpc2Vjb25kLTNoNgogIHJldHVybiAoKSA9PiB7CiAgICByZXR1cm4gKHRpbWVPcmlnaW4gKyBwZXJmb3JtYW5jZS5ub3coKSkgLyBPTkVfU0VDT05EX0lOX01TOwogIH07Cn0KCi8qKgogKiBSZXR1cm5zIGEgdGltZXN0YW1wIGluIHNlY29uZHMgc2luY2UgdGhlIFVOSVggZXBvY2ggdXNpbmcgZWl0aGVyIHRoZSBQZXJmb3JtYW5jZSBvciBEYXRlIEFQSXMsIGRlcGVuZGluZyBvbiB0aGUKICogYXZhaWxhYmlsaXR5IG9mIHRoZSBQZXJmb3JtYW5jZSBBUEkuCiAqCiAqIEJVRzogTm90ZSB0aGF0IGJlY2F1c2Ugb2YgaG93IGJyb3dzZXJzIGltcGxlbWVudCB0aGUgUGVyZm9ybWFuY2UgQVBJLCB0aGUgY2xvY2sgbWlnaHQgc3RvcCB3aGVuIHRoZSBjb21wdXRlciBpcwogKiBhc2xlZXAuIFRoaXMgY3JlYXRlcyBhIHNrZXcgYmV0d2VlbiBgZGF0ZVRpbWVzdGFtcEluU2Vjb25kc2AgYW5kIGB0aW1lc3RhbXBJblNlY29uZHNgLiBUaGUKICogc2tldyBjYW4gZ3JvdyB0byBhcmJpdHJhcnkgYW1vdW50cyBsaWtlIGRheXMsIHdlZWtzIG9yIG1vbnRocy4KICogU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9nZXRzZW50cnkvc2VudHJ5LWphdmFzY3JpcHQvaXNzdWVzLzI1OTAuCiAqLwpjb25zdCB0aW1lc3RhbXBJblNlY29uZHMgPSBjcmVhdGVVbml4VGltZXN0YW1wSW5TZWNvbmRzRnVuYygpOwoKLyoqCiAqIFRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHNpbmNlIHRoZSBVTklYIGVwb2NoLiBUaGlzIHZhbHVlIGlzIG9ubHkgdXNhYmxlIGluIGEgYnJvd3NlciwgYW5kIG9ubHkgd2hlbiB0aGUKICogcGVyZm9ybWFuY2UgQVBJIGlzIGF2YWlsYWJsZS4KICovCigoKSA9PiB7CiAgLy8gVW5mb3J0dW5hdGVseSBicm93c2VycyBtYXkgcmVwb3J0IGFuIGluYWNjdXJhdGUgdGltZSBvcmlnaW4gZGF0YSwgdGhyb3VnaCBlaXRoZXIgcGVyZm9ybWFuY2UudGltZU9yaWdpbiBvcgogIC8vIHBlcmZvcm1hbmNlLnRpbWluZy5uYXZpZ2F0aW9uU3RhcnQsIHdoaWNoIHJlc3VsdHMgaW4gcG9vciByZXN1bHRzIGluIHBlcmZvcm1hbmNlIGRhdGEuIFdlIG9ubHkgdHJlYXQgdGltZSBvcmlnaW4KICAvLyBkYXRhIGFzIHJlbGlhYmxlIGlmIHRoZXkgYXJlIHdpdGhpbiBhIHJlYXNvbmFibGUgdGhyZXNob2xkIG9mIHRoZSBjdXJyZW50IHRpbWUuCgogIGNvbnN0IHsgcGVyZm9ybWFuY2UgfSA9IEdMT0JBTF9PQkogOwogIGlmICghcGVyZm9ybWFuY2UgfHwgIXBlcmZvcm1hbmNlLm5vdykgewogICAgcmV0dXJuIHVuZGVmaW5lZDsKICB9CgogIGNvbnN0IHRocmVzaG9sZCA9IDM2MDAgKiAxMDAwOwogIGNvbnN0IHBlcmZvcm1hbmNlTm93ID0gcGVyZm9ybWFuY2Uubm93KCk7CiAgY29uc3QgZGF0ZU5vdyA9IERhdGUubm93KCk7CgogIC8vIGlmIHRpbWVPcmlnaW4gaXNuJ3QgYXZhaWxhYmxlIHNldCBkZWx0YSB0byB0aHJlc2hvbGQgc28gaXQgaXNuJ3QgdXNlZAogIGNvbnN0IHRpbWVPcmlnaW5EZWx0YSA9IHBlcmZvcm1hbmNlLnRpbWVPcmlnaW4KICAgID8gTWF0aC5hYnMocGVyZm9ybWFuY2UudGltZU9yaWdpbiArIHBlcmZvcm1hbmNlTm93IC0gZGF0ZU5vdykKICAgIDogdGhyZXNob2xkOwogIGNvbnN0IHRpbWVPcmlnaW5Jc1JlbGlhYmxlID0gdGltZU9yaWdpbkRlbHRhIDwgdGhyZXNob2xkOwoKICAvLyBXaGlsZSBwZXJmb3JtYW5jZS50aW1pbmcubmF2aWdhdGlvblN0YXJ0IGlzIGRlcHJlY2F0ZWQgaW4gZmF2b3Igb2YgcGVyZm9ybWFuY2UudGltZU9yaWdpbiwgcGVyZm9ybWFuY2UudGltZU9yaWdpbgogIC8vIGlzIG5vdCBhcyB3aWRlbHkgc3VwcG9ydGVkLiBOYW1lbHksIHBlcmZvcm1hbmNlLnRpbWVPcmlnaW4gaXMgdW5kZWZpbmVkIGluIFNhZmFyaSBhcyBvZiB3cml0aW5nLgogIC8vIEFsc28gYXMgb2Ygd3JpdGluZywgcGVyZm9ybWFuY2UudGltaW5nIGlzIG5vdCBhdmFpbGFibGUgaW4gV2ViIFdvcmtlcnMgaW4gbWFpbnN0cmVhbSBicm93c2Vycywgc28gaXQgaXMgbm90IGFsd2F5cwogIC8vIGEgdmFsaWQgZmFsbGJhY2suIEluIHRoZSBhYnNlbmNlIG9mIGFuIGluaXRpYWwgdGltZSBwcm92aWRlZCBieSB0aGUgYnJvd3NlciwgZmFsbGJhY2sgdG8gdGhlIGN1cnJlbnQgdGltZSBmcm9tIHRoZQogIC8vIERhdGUgQVBJLgogIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkZXByZWNhdGlvbi9kZXByZWNhdGlvbgogIGNvbnN0IG5hdmlnYXRpb25TdGFydCA9IHBlcmZvcm1hbmNlLnRpbWluZyAmJiBwZXJmb3JtYW5jZS50aW1pbmcubmF2aWdhdGlvblN0YXJ0OwogIGNvbnN0IGhhc05hdmlnYXRpb25TdGFydCA9IHR5cGVvZiBuYXZpZ2F0aW9uU3RhcnQgPT09ICdudW1iZXInOwogIC8vIGlmIG5hdmlnYXRpb25TdGFydCBpc24ndCBhdmFpbGFibGUgc2V0IGRlbHRhIHRvIHRocmVzaG9sZCBzbyBpdCBpc24ndCB1c2VkCiAgY29uc3QgbmF2aWdhdGlvblN0YXJ0RGVsdGEgPSBoYXNOYXZpZ2F0aW9uU3RhcnQgPyBNYXRoLmFicyhuYXZpZ2F0aW9uU3RhcnQgKyBwZXJmb3JtYW5jZU5vdyAtIGRhdGVOb3cpIDogdGhyZXNob2xkOwogIGNvbnN0IG5hdmlnYXRpb25TdGFydElzUmVsaWFibGUgPSBuYXZpZ2F0aW9uU3RhcnREZWx0YSA8IHRocmVzaG9sZDsKCiAgaWYgKHRpbWVPcmlnaW5Jc1JlbGlhYmxlIHx8IG5hdmlnYXRpb25TdGFydElzUmVsaWFibGUpIHsKICAgIC8vIFVzZSB0aGUgbW9yZSByZWxpYWJsZSB0aW1lIG9yaWdpbgogICAgaWYgKHRpbWVPcmlnaW5EZWx0YSA8PSBuYXZpZ2F0aW9uU3RhcnREZWx0YSkgewogICAgICByZXR1cm4gcGVyZm9ybWFuY2UudGltZU9yaWdpbjsKICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiBuYXZpZ2F0aW9uU3RhcnQ7CiAgICB9CiAgfQogIHJldHVybiBkYXRlTm93Owp9KSgpOwoKLyoqCiAqIENyZWF0ZXMgYW4gZW52ZWxvcGUuCiAqIE1ha2Ugc3VyZSB0byBhbHdheXMgZXhwbGljaXRseSBwcm92aWRlIHRoZSBnZW5lcmljIHRvIHRoaXMgZnVuY3Rpb24KICogc28gdGhhdCB0aGUgZW52ZWxvcGUgdHlwZXMgcmVzb2x2ZSBjb3JyZWN0bHkuCiAqLwpmdW5jdGlvbiBjcmVhdGVFbnZlbG9wZShoZWFkZXJzLCBpdGVtcyA9IFtdKSB7CiAgcmV0dXJuIFtoZWFkZXJzLCBpdGVtc10gOwp9CgovKioKICogQ29udmVuaWVuY2UgZnVuY3Rpb24gdG8gbG9vcCB0aHJvdWdoIHRoZSBpdGVtcyBhbmQgaXRlbSB0eXBlcyBvZiBhbiBlbnZlbG9wZS4KICogKFRoaXMgZnVuY3Rpb24gd2FzIG1vc3RseSBjcmVhdGVkIGJlY2F1c2Ugd29ya2luZyB3aXRoIGVudmVsb3BlIHR5cGVzIGlzIHBhaW5mdWwgYXQgdGhlIG1vbWVudCkKICoKICogSWYgdGhlIGNhbGxiYWNrIHJldHVybnMgdHJ1ZSwgdGhlIHJlc3Qgb2YgdGhlIGl0ZW1zIHdpbGwgYmUgc2tpcHBlZC4KICovCmZ1bmN0aW9uIGZvckVhY2hFbnZlbG9wZUl0ZW0oCiAgZW52ZWxvcGUsCiAgY2FsbGJhY2ssCikgewogIGNvbnN0IGVudmVsb3BlSXRlbXMgPSBlbnZlbG9wZVsxXTsKCiAgZm9yIChjb25zdCBlbnZlbG9wZUl0ZW0gb2YgZW52ZWxvcGVJdGVtcykgewogICAgY29uc3QgZW52ZWxvcGVJdGVtVHlwZSA9IGVudmVsb3BlSXRlbVswXS50eXBlOwogICAgY29uc3QgcmVzdWx0ID0gY2FsbGJhY2soZW52ZWxvcGVJdGVtLCBlbnZlbG9wZUl0ZW1UeXBlKTsKCiAgICBpZiAocmVzdWx0KSB7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQogIH0KCiAgcmV0dXJuIGZhbHNlOwp9CgovKioKICogRW5jb2RlIGEgc3RyaW5nIHRvIFVURjguCiAqLwpmdW5jdGlvbiBlbmNvZGVVVEY4KGlucHV0LCB0ZXh0RW5jb2RlcikgewogIGNvbnN0IHV0ZjggPSB0ZXh0RW5jb2RlciB8fCBuZXcgVGV4dEVuY29kZXIoKTsKICByZXR1cm4gdXRmOC5lbmNvZGUoaW5wdXQpOwp9CgovKioKICogU2VyaWFsaXplcyBhbiBlbnZlbG9wZS4KICovCmZ1bmN0aW9uIHNlcmlhbGl6ZUVudmVsb3BlKGVudmVsb3BlLCB0ZXh0RW5jb2RlcikgewogIGNvbnN0IFtlbnZIZWFkZXJzLCBpdGVtc10gPSBlbnZlbG9wZTsKCiAgLy8gSW5pdGlhbGx5IHdlIGNvbnN0cnVjdCBvdXIgZW52ZWxvcGUgYXMgYSBzdHJpbmcgYW5kIG9ubHkgY29udmVydCB0byBiaW5hcnkgY2h1bmtzIGlmIHdlIGVuY291bnRlciBiaW5hcnkgZGF0YQogIGxldCBwYXJ0cyA9IEpTT04uc3RyaW5naWZ5KGVudkhlYWRlcnMpOwoKICBmdW5jdGlvbiBhcHBlbmQobmV4dCkgewogICAgaWYgKHR5cGVvZiBwYXJ0cyA9PT0gJ3N0cmluZycpIHsKICAgICAgcGFydHMgPSB0eXBlb2YgbmV4dCA9PT0gJ3N0cmluZycgPyBwYXJ0cyArIG5leHQgOiBbZW5jb2RlVVRGOChwYXJ0cywgdGV4dEVuY29kZXIpLCBuZXh0XTsKICAgIH0gZWxzZSB7CiAgICAgIHBhcnRzLnB1c2godHlwZW9mIG5leHQgPT09ICdzdHJpbmcnID8gZW5jb2RlVVRGOChuZXh0LCB0ZXh0RW5jb2RlcikgOiBuZXh0KTsKICAgIH0KICB9CgogIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykgewogICAgY29uc3QgW2l0ZW1IZWFkZXJzLCBwYXlsb2FkXSA9IGl0ZW07CgogICAgYXBwZW5kKGBcbiR7SlNPTi5zdHJpbmdpZnkoaXRlbUhlYWRlcnMpfVxuYCk7CgogICAgaWYgKHR5cGVvZiBwYXlsb2FkID09PSAnc3RyaW5nJyB8fCBwYXlsb2FkIGluc3RhbmNlb2YgVWludDhBcnJheSkgewogICAgICBhcHBlbmQocGF5bG9hZCk7CiAgICB9IGVsc2UgewogICAgICBsZXQgc3RyaW5naWZpZWRQYXlsb2FkOwogICAgICB0cnkgewogICAgICAgIHN0cmluZ2lmaWVkUGF5bG9hZCA9IEpTT04uc3RyaW5naWZ5KHBheWxvYWQpOwogICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgLy8gSW4gY2FzZSwgZGVzcGl0ZSBhbGwgb3VyIGVmZm9ydHMgdG8ga2VlcCBgcGF5bG9hZGAgY2lyY3VsYXItZGVwZW5kZW5jeS1mcmVlLCBgSlNPTi5zdHJpbmlmeSgpYCBzdGlsbAogICAgICAgIC8vIGZhaWxzLCB3ZSB0cnkgYWdhaW4gYWZ0ZXIgbm9ybWFsaXppbmcgaXQgYWdhaW4gd2l0aCBpbmZpbml0ZSBub3JtYWxpemF0aW9uIGRlcHRoLiBUaGlzIG9mIGNvdXJzZSBoYXMgYQogICAgICAgIC8vIHBlcmZvcm1hbmNlIGltcGFjdCBidXQgaW4gdGhpcyBjYXNlIGEgcGVyZm9ybWFuY2UgaGl0IGlzIGJldHRlciB0aGFuIHRocm93aW5nLgogICAgICAgIHN0cmluZ2lmaWVkUGF5bG9hZCA9IEpTT04uc3RyaW5naWZ5KG5vcm1hbGl6ZShwYXlsb2FkKSk7CiAgICAgIH0KICAgICAgYXBwZW5kKHN0cmluZ2lmaWVkUGF5bG9hZCk7CiAgICB9CiAgfQoKICByZXR1cm4gdHlwZW9mIHBhcnRzID09PSAnc3RyaW5nJyA/IHBhcnRzIDogY29uY2F0QnVmZmVycyhwYXJ0cyk7Cn0KCmZ1bmN0aW9uIGNvbmNhdEJ1ZmZlcnMoYnVmZmVycykgewogIGNvbnN0IHRvdGFsTGVuZ3RoID0gYnVmZmVycy5yZWR1Y2UoKGFjYywgYnVmKSA9PiBhY2MgKyBidWYubGVuZ3RoLCAwKTsKCiAgY29uc3QgbWVyZ2VkID0gbmV3IFVpbnQ4QXJyYXkodG90YWxMZW5ndGgpOwogIGxldCBvZmZzZXQgPSAwOwogIGZvciAoY29uc3QgYnVmZmVyIG9mIGJ1ZmZlcnMpIHsKICAgIG1lcmdlZC5zZXQoYnVmZmVyLCBvZmZzZXQpOwogICAgb2Zmc2V0ICs9IGJ1ZmZlci5sZW5ndGg7CiAgfQoKICByZXR1cm4gbWVyZ2VkOwp9Cgpjb25zdCBJVEVNX1RZUEVfVE9fREFUQV9DQVRFR09SWV9NQVAgPSB7CiAgc2Vzc2lvbjogJ3Nlc3Npb24nLAogIHNlc3Npb25zOiAnc2Vzc2lvbicsCiAgYXR0YWNobWVudDogJ2F0dGFjaG1lbnQnLAogIHRyYW5zYWN0aW9uOiAndHJhbnNhY3Rpb24nLAogIGV2ZW50OiAnZXJyb3InLAogIGNsaWVudF9yZXBvcnQ6ICdpbnRlcm5hbCcsCiAgdXNlcl9yZXBvcnQ6ICdkZWZhdWx0JywKICBwcm9maWxlOiAncHJvZmlsZScsCiAgcmVwbGF5X2V2ZW50OiAncmVwbGF5JywKICByZXBsYXlfcmVjb3JkaW5nOiAncmVwbGF5JywKICBjaGVja19pbjogJ21vbml0b3InLAogIGZlZWRiYWNrOiAnZmVlZGJhY2snLAogIHNwYW46ICdzcGFuJywKICBzdGF0c2Q6ICdzdGF0c2QnLAp9OwoKLyoqCiAqIE1hcHMgdGhlIHR5cGUgb2YgYW4gZW52ZWxvcGUgaXRlbSB0byBhIGRhdGEgY2F0ZWdvcnkuCiAqLwpmdW5jdGlvbiBlbnZlbG9wZUl0ZW1UeXBlVG9EYXRhQ2F0ZWdvcnkodHlwZSkgewogIHJldHVybiBJVEVNX1RZUEVfVE9fREFUQV9DQVRFR09SWV9NQVBbdHlwZV07Cn0KCi8qKiBFeHRyYWN0cyB0aGUgbWluaW1hbCBTREsgaW5mbyBmcm9tIGZyb20gdGhlIG1ldGFkYXRhIG9yIGFuIGV2ZW50cyAqLwpmdW5jdGlvbiBnZXRTZGtNZXRhZGF0YUZvckVudmVsb3BlSGVhZGVyKG1ldGFkYXRhT3JFdmVudCkgewogIGlmICghbWV0YWRhdGFPckV2ZW50IHx8ICFtZXRhZGF0YU9yRXZlbnQuc2RrKSB7CiAgICByZXR1cm47CiAgfQogIGNvbnN0IHsgbmFtZSwgdmVyc2lvbiB9ID0gbWV0YWRhdGFPckV2ZW50LnNkazsKICByZXR1cm4geyBuYW1lLCB2ZXJzaW9uIH07Cn0KCi8qKgogKiBDcmVhdGVzIGV2ZW50IGVudmVsb3BlIGhlYWRlcnMsIGJhc2VkIG9uIGV2ZW50LCBzZGsgaW5mbyBhbmQgdHVubmVsCiAqIE5vdGU6IFRoaXMgZnVuY3Rpb24gd2FzIGV4dHJhY3RlZCBmcm9tIHRoZSBjb3JlIHBhY2thZ2UgdG8gbWFrZSBpdCBhdmFpbGFibGUgaW4gUmVwbGF5CiAqLwpmdW5jdGlvbiBjcmVhdGVFdmVudEVudmVsb3BlSGVhZGVycygKICBldmVudCwKICBzZGtJbmZvLAogIHR1bm5lbCwKICBkc24sCikgewogIGNvbnN0IGR5bmFtaWNTYW1wbGluZ0NvbnRleHQgPSBldmVudC5zZGtQcm9jZXNzaW5nTWV0YWRhdGEgJiYgZXZlbnQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhLmR5bmFtaWNTYW1wbGluZ0NvbnRleHQ7CiAgcmV0dXJuIHsKICAgIGV2ZW50X2lkOiBldmVudC5ldmVudF9pZCAsCiAgICBzZW50X2F0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksCiAgICAuLi4oc2RrSW5mbyAmJiB7IHNkazogc2RrSW5mbyB9KSwKICAgIC4uLighIXR1bm5lbCAmJiBkc24gJiYgeyBkc246IGRzblRvU3RyaW5nKGRzbikgfSksCiAgICAuLi4oZHluYW1pY1NhbXBsaW5nQ29udGV4dCAmJiB7CiAgICAgIHRyYWNlOiBkcm9wVW5kZWZpbmVkS2V5cyh7IC4uLmR5bmFtaWNTYW1wbGluZ0NvbnRleHQgfSksCiAgICB9KSwKICB9Owp9CgovLyBJbnRlbnRpb25hbGx5IGtlZXBpbmcgdGhlIGtleSBicm9hZCwgYXMgd2UgZG9uJ3Qga25vdyBmb3Igc3VyZSB3aGF0IHJhdGUgbGltaXQgaGVhZGVycyBnZXQgcmV0dXJuZWQgZnJvbSBiYWNrZW5kCgpjb25zdCBERUZBVUxUX1JFVFJZX0FGVEVSID0gNjAgKiAxMDAwOyAvLyA2MCBzZWNvbmRzCgovKioKICogRXh0cmFjdHMgUmV0cnktQWZ0ZXIgdmFsdWUgZnJvbSB0aGUgcmVxdWVzdCBoZWFkZXIgb3IgcmV0dXJucyBkZWZhdWx0IHZhbHVlCiAqIEBwYXJhbSBoZWFkZXIgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mICdSZXRyeS1BZnRlcicgaGVhZGVyCiAqIEBwYXJhbSBub3cgY3VycmVudCB1bml4IHRpbWVzdGFtcAogKgogKi8KZnVuY3Rpb24gcGFyc2VSZXRyeUFmdGVySGVhZGVyKGhlYWRlciwgbm93ID0gRGF0ZS5ub3coKSkgewogIGNvbnN0IGhlYWRlckRlbGF5ID0gcGFyc2VJbnQoYCR7aGVhZGVyfWAsIDEwKTsKICBpZiAoIWlzTmFOKGhlYWRlckRlbGF5KSkgewogICAgcmV0dXJuIGhlYWRlckRlbGF5ICogMTAwMDsKICB9CgogIGNvbnN0IGhlYWRlckRhdGUgPSBEYXRlLnBhcnNlKGAke2hlYWRlcn1gKTsKICBpZiAoIWlzTmFOKGhlYWRlckRhdGUpKSB7CiAgICByZXR1cm4gaGVhZGVyRGF0ZSAtIG5vdzsKICB9CgogIHJldHVybiBERUZBVUxUX1JFVFJZX0FGVEVSOwp9CgovKioKICogR2V0cyB0aGUgdGltZSB0aGF0IHRoZSBnaXZlbiBjYXRlZ29yeSBpcyBkaXNhYmxlZCB1bnRpbCBmb3IgcmF0ZSBsaW1pdGluZy4KICogSW4gY2FzZSBubyBjYXRlZ29yeS1zcGVjaWZpYyBsaW1pdCBpcyBzZXQgYnV0IGEgZ2VuZXJhbCByYXRlIGxpbWl0IGFjcm9zcyBhbGwgY2F0ZWdvcmllcyBpcyBhY3RpdmUsCiAqIHRoYXQgdGltZSBpcyByZXR1cm5lZC4KICoKICogQHJldHVybiB0aGUgdGltZSBpbiBtcyB0aGF0IHRoZSBjYXRlZ29yeSBpcyBkaXNhYmxlZCB1bnRpbCBvciAwIGlmIHRoZXJlJ3Mgbm8gYWN0aXZlIHJhdGUgbGltaXQuCiAqLwpmdW5jdGlvbiBkaXNhYmxlZFVudGlsKGxpbWl0cywgY2F0ZWdvcnkpIHsKICByZXR1cm4gbGltaXRzW2NhdGVnb3J5XSB8fCBsaW1pdHMuYWxsIHx8IDA7Cn0KCi8qKgogKiBDaGVja3MgaWYgYSBjYXRlZ29yeSBpcyByYXRlIGxpbWl0ZWQKICovCmZ1bmN0aW9uIGlzUmF0ZUxpbWl0ZWQobGltaXRzLCBjYXRlZ29yeSwgbm93ID0gRGF0ZS5ub3coKSkgewogIHJldHVybiBkaXNhYmxlZFVudGlsKGxpbWl0cywgY2F0ZWdvcnkpID4gbm93Owp9CgovKioKICogVXBkYXRlIHJhdGVsaW1pdHMgZnJvbSBpbmNvbWluZyBoZWFkZXJzLgogKgogKiBAcmV0dXJuIHRoZSB1cGRhdGVkIFJhdGVMaW1pdHMgb2JqZWN0LgogKi8KZnVuY3Rpb24gdXBkYXRlUmF0ZUxpbWl0cygKICBsaW1pdHMsCiAgeyBzdGF0dXNDb2RlLCBoZWFkZXJzIH0sCiAgbm93ID0gRGF0ZS5ub3coKSwKKSB7CiAgY29uc3QgdXBkYXRlZFJhdGVMaW1pdHMgPSB7CiAgICAuLi5saW1pdHMsCiAgfTsKCiAgLy8gIlRoZSBuYW1lIGlzIGNhc2UtaW5zZW5zaXRpdmUuIgogIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9IZWFkZXJzL2dldAogIGNvbnN0IHJhdGVMaW1pdEhlYWRlciA9IGhlYWRlcnMgJiYgaGVhZGVyc1sneC1zZW50cnktcmF0ZS1saW1pdHMnXTsKICBjb25zdCByZXRyeUFmdGVySGVhZGVyID0gaGVhZGVycyAmJiBoZWFkZXJzWydyZXRyeS1hZnRlciddOwoKICBpZiAocmF0ZUxpbWl0SGVhZGVyKSB7CiAgICAvKioKICAgICAqIHJhdGUgbGltaXQgaGVhZGVycyBhcmUgb2YgdGhlIGZvcm0KICAgICAqICAgICA8aGVhZGVyPiw8aGVhZGVyPiwuLgogICAgICogd2hlcmUgZWFjaCA8aGVhZGVyPiBpcyBvZiB0aGUgZm9ybQogICAgICogICAgIDxyZXRyeV9hZnRlcj46IDxjYXRlZ29yaWVzPjogPHNjb3BlPjogPHJlYXNvbl9jb2RlPgogICAgICogd2hlcmUKICAgICAqICAgICA8cmV0cnlfYWZ0ZXI+IGlzIGEgZGVsYXkgaW4gc2Vjb25kcwogICAgICogICAgIDxjYXRlZ29yaWVzPiBpcyB0aGUgZXZlbnQgdHlwZShzKSAoZXJyb3IsIHRyYW5zYWN0aW9uLCBldGMpIGJlaW5nIHJhdGUgbGltaXRlZCBhbmQgaXMgb2YgdGhlIGZvcm0KICAgICAqICAgICAgICAgPGNhdGVnb3J5Pjs8Y2F0ZWdvcnk+Oy4uLgogICAgICogICAgIDxzY29wZT4gaXMgd2hhdCdzIGJlaW5nIGxpbWl0ZWQgKG9yZywgcHJvamVjdCwgb3Iga2V5KSAtIGlnbm9yZWQgYnkgU0RLCiAgICAgKiAgICAgPHJlYXNvbl9jb2RlPiBpcyBhbiBhcmJpdHJhcnkgc3RyaW5nIGxpa2UgIm9yZ19xdW90YSIgLSBpZ25vcmVkIGJ5IFNESwogICAgICovCiAgICBmb3IgKGNvbnN0IGxpbWl0IG9mIHJhdGVMaW1pdEhlYWRlci50cmltKCkuc3BsaXQoJywnKSkgewogICAgICBjb25zdCBbcmV0cnlBZnRlciwgY2F0ZWdvcmllc10gPSBsaW1pdC5zcGxpdCgnOicsIDIpOwogICAgICBjb25zdCBoZWFkZXJEZWxheSA9IHBhcnNlSW50KHJldHJ5QWZ0ZXIsIDEwKTsKICAgICAgY29uc3QgZGVsYXkgPSAoIWlzTmFOKGhlYWRlckRlbGF5KSA/IGhlYWRlckRlbGF5IDogNjApICogMTAwMDsgLy8gNjBzZWMgZGVmYXVsdAogICAgICBpZiAoIWNhdGVnb3JpZXMpIHsKICAgICAgICB1cGRhdGVkUmF0ZUxpbWl0cy5hbGwgPSBub3cgKyBkZWxheTsKICAgICAgfSBlbHNlIHsKICAgICAgICBmb3IgKGNvbnN0IGNhdGVnb3J5IG9mIGNhdGVnb3JpZXMuc3BsaXQoJzsnKSkgewogICAgICAgICAgdXBkYXRlZFJhdGVMaW1pdHNbY2F0ZWdvcnldID0gbm93ICsgZGVsYXk7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfSBlbHNlIGlmIChyZXRyeUFmdGVySGVhZGVyKSB7CiAgICB1cGRhdGVkUmF0ZUxpbWl0cy5hbGwgPSBub3cgKyBwYXJzZVJldHJ5QWZ0ZXJIZWFkZXIocmV0cnlBZnRlckhlYWRlciwgbm93KTsKICB9IGVsc2UgaWYgKHN0YXR1c0NvZGUgPT09IDQyOSkgewogICAgdXBkYXRlZFJhdGVMaW1pdHMuYWxsID0gbm93ICsgNjAgKiAxMDAwOwogIH0KCiAgcmV0dXJuIHVwZGF0ZWRSYXRlTGltaXRzOwp9CgovKioKICogQSBub2RlLmpzIHdhdGNoZG9nIHRpbWVyCiAqIEBwYXJhbSBwb2xsSW50ZXJ2YWwgVGhlIGludGVydmFsIHRoYXQgd2UgZXhwZWN0IHRvIGdldCBwb2xsZWQgYXQKICogQHBhcmFtIGFuclRocmVzaG9sZCBUaGUgdGhyZXNob2xkIGZvciB3aGVuIHdlIGNvbnNpZGVyIEFOUgogKiBAcGFyYW0gY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGNhbGwgZm9yIEFOUgogKiBAcmV0dXJucyBBbiBvYmplY3Qgd2l0aCBgcG9sbGAgYW5kIGBlbmFibGVkYCBmdW5jdGlvbnMge0BsaW5rIFdhdGNoZG9nUmV0dXJufQogKi8KZnVuY3Rpb24gd2F0Y2hkb2dUaW1lcigKICBjcmVhdGVUaW1lciwKICBwb2xsSW50ZXJ2YWwsCiAgYW5yVGhyZXNob2xkLAogIGNhbGxiYWNrLAopIHsKICBjb25zdCB0aW1lciA9IGNyZWF0ZVRpbWVyKCk7CiAgbGV0IHRyaWdnZXJlZCA9IGZhbHNlOwogIGxldCBlbmFibGVkID0gdHJ1ZTsKCiAgc2V0SW50ZXJ2YWwoKCkgPT4gewogICAgY29uc3QgZGlmZk1zID0gdGltZXIuZ2V0VGltZU1zKCk7CgogICAgaWYgKHRyaWdnZXJlZCA9PT0gZmFsc2UgJiYgZGlmZk1zID4gcG9sbEludGVydmFsICsgYW5yVGhyZXNob2xkKSB7CiAgICAgIHRyaWdnZXJlZCA9IHRydWU7CiAgICAgIGlmIChlbmFibGVkKSB7CiAgICAgICAgY2FsbGJhY2soKTsKICAgICAgfQogICAgfQoKICAgIGlmIChkaWZmTXMgPCBwb2xsSW50ZXJ2YWwgKyBhbnJUaHJlc2hvbGQpIHsKICAgICAgdHJpZ2dlcmVkID0gZmFsc2U7CiAgICB9CiAgfSwgMjApOwoKICByZXR1cm4gewogICAgcG9sbDogKCkgPT4gewogICAgICB0aW1lci5yZXNldCgpOwogICAgfSwKICAgIGVuYWJsZWQ6IChzdGF0ZSkgPT4gewogICAgICBlbmFibGVkID0gc3RhdGU7CiAgICB9LAogIH07Cn0KCi8vIHR5cGVzIGNvcGllZCBmcm9tIGluc3BlY3Rvci5kLnRzCgovKioKICogQ29udmVydHMgRGVidWdnZXIuQ2FsbEZyYW1lIHRvIFNlbnRyeSBTdGFja0ZyYW1lCiAqLwpmdW5jdGlvbiBjYWxsRnJhbWVUb1N0YWNrRnJhbWUoCiAgZnJhbWUsCiAgdXJsLAogIGdldE1vZHVsZUZyb21GaWxlbmFtZSwKKSB7CiAgY29uc3QgZmlsZW5hbWUgPSB1cmwgPyB1cmwucmVwbGFjZSgvXmZpbGU6XC9cLy8sICcnKSA6IHVuZGVmaW5lZDsKCiAgLy8gQ2FsbEZyYW1lIHJvdy9jb2wgYXJlIDAgYmFzZWQsIHdoZXJlYXMgU3RhY2tGcmFtZSBhcmUgMSBiYXNlZAogIGNvbnN0IGNvbG5vID0gZnJhbWUubG9jYXRpb24uY29sdW1uTnVtYmVyID8gZnJhbWUubG9jYXRpb24uY29sdW1uTnVtYmVyICsgMSA6IHVuZGVmaW5lZDsKICBjb25zdCBsaW5lbm8gPSBmcmFtZS5sb2NhdGlvbi5saW5lTnVtYmVyID8gZnJhbWUubG9jYXRpb24ubGluZU51bWJlciArIDEgOiB1bmRlZmluZWQ7CgogIHJldHVybiBkcm9wVW5kZWZpbmVkS2V5cyh7CiAgICBmaWxlbmFtZSwKICAgIG1vZHVsZTogZ2V0TW9kdWxlRnJvbUZpbGVuYW1lKGZpbGVuYW1lKSwKICAgIGZ1bmN0aW9uOiBmcmFtZS5mdW5jdGlvbk5hbWUgfHwgJz8nLAogICAgY29sbm8sCiAgICBsaW5lbm8sCiAgICBpbl9hcHA6IGZpbGVuYW1lID8gZmlsZW5hbWVJc0luQXBwKGZpbGVuYW1lKSA6IHVuZGVmaW5lZCwKICB9KTsKfQoKLyoqCiAqIFRoaXMgc2VydmVzIGFzIGEgYnVpbGQgdGltZSBmbGFnIHRoYXQgd2lsbCBiZSB0cnVlIGJ5IGRlZmF1bHQsIGJ1dCBmYWxzZSBpbiBub24tZGVidWcgYnVpbGRzIG9yIGlmIHVzZXJzIHJlcGxhY2UgYF9fU0VOVFJZX0RFQlVHX19gIGluIHRoZWlyIGdlbmVyYXRlZCBjb2RlLgogKgogKiBBVFRFTlRJT046IFRoaXMgY29uc3RhbnQgbXVzdCBuZXZlciBjcm9zcyBwYWNrYWdlIGJvdW5kYXJpZXMgKGkuZS4gYmUgZXhwb3J0ZWQpIHRvIGd1YXJhbnRlZSB0aGF0IGl0IGNhbiBiZSB1c2VkIGZvciB0cmVlIHNoYWtpbmcuCiAqLwpjb25zdCBERUJVR19CVUlMRCA9ICh0eXBlb2YgX19TRU5UUllfREVCVUdfXyA9PT0gJ3VuZGVmaW5lZCcgfHwgX19TRU5UUllfREVCVUdfXyk7CgovKioKICogQ3JlYXRlcyBhIG5ldyBgU2Vzc2lvbmAgb2JqZWN0IGJ5IHNldHRpbmcgY2VydGFpbiBkZWZhdWx0IHBhcmFtZXRlcnMuIElmIG9wdGlvbmFsIEBwYXJhbSBjb250ZXh0CiAqIGlzIHBhc3NlZCwgdGhlIHBhc3NlZCBwcm9wZXJ0aWVzIGFyZSBhcHBsaWVkIHRvIHRoZSBzZXNzaW9uIG9iamVjdC4KICoKICogQHBhcmFtIGNvbnRleHQgKG9wdGlvbmFsKSBhZGRpdGlvbmFsIHByb3BlcnRpZXMgdG8gYmUgYXBwbGllZCB0byB0aGUgcmV0dXJuZWQgc2Vzc2lvbiBvYmplY3QKICoKICogQHJldHVybnMgYSBuZXcgYFNlc3Npb25gIG9iamVjdAogKi8KZnVuY3Rpb24gbWFrZVNlc3Npb24oY29udGV4dCkgewogIC8vIEJvdGggdGltZXN0YW1wIGFuZCBzdGFydGVkIGFyZSBpbiBzZWNvbmRzIHNpbmNlIHRoZSBVTklYIGVwb2NoLgogIGNvbnN0IHN0YXJ0aW5nVGltZSA9IHRpbWVzdGFtcEluU2Vjb25kcygpOwoKICBjb25zdCBzZXNzaW9uID0gewogICAgc2lkOiB1dWlkNCgpLAogICAgaW5pdDogdHJ1ZSwKICAgIHRpbWVzdGFtcDogc3RhcnRpbmdUaW1lLAogICAgc3RhcnRlZDogc3RhcnRpbmdUaW1lLAogICAgZHVyYXRpb246IDAsCiAgICBzdGF0dXM6ICdvaycsCiAgICBlcnJvcnM6IDAsCiAgICBpZ25vcmVEdXJhdGlvbjogZmFsc2UsCiAgICB0b0pTT046ICgpID0+IHNlc3Npb25Ub0pTT04oc2Vzc2lvbiksCiAgfTsKCiAgaWYgKGNvbnRleHQpIHsKICAgIHVwZGF0ZVNlc3Npb24oc2Vzc2lvbiwgY29udGV4dCk7CiAgfQoKICByZXR1cm4gc2Vzc2lvbjsKfQoKLyoqCiAqIFVwZGF0ZXMgYSBzZXNzaW9uIG9iamVjdCB3aXRoIHRoZSBwcm9wZXJ0aWVzIHBhc3NlZCBpbiB0aGUgY29udGV4dC4KICoKICogTm90ZSB0aGF0IHRoaXMgZnVuY3Rpb24gbXV0YXRlcyB0aGUgcGFzc2VkIG9iamVjdCBhbmQgcmV0dXJucyB2b2lkLgogKiAoSGFkIHRvIGRvIHRoaXMgaW5zdGVhZCBvZiByZXR1cm5pbmcgYSBuZXcgYW5kIHVwZGF0ZWQgc2Vzc2lvbiBiZWNhdXNlIGNsb3NpbmcgYW5kIHNlbmRpbmcgYSBzZXNzaW9uCiAqIG1ha2VzIGFuIHVwZGF0ZSB0byB0aGUgc2Vzc2lvbiBhZnRlciBpdCB3YXMgcGFzc2VkIHRvIHRoZSBzZW5kaW5nIGxvZ2ljLgogKiBAc2VlIEJhc2VDbGllbnQuY2FwdHVyZVNlc3Npb24gKQogKgogKiBAcGFyYW0gc2Vzc2lvbiB0aGUgYFNlc3Npb25gIHRvIHVwZGF0ZQogKiBAcGFyYW0gY29udGV4dCB0aGUgYFNlc3Npb25Db250ZXh0YCBob2xkaW5nIHRoZSBwcm9wZXJ0aWVzIHRoYXQgc2hvdWxkIGJlIHVwZGF0ZWQgaW4gQHBhcmFtIHNlc3Npb24KICovCi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb21wbGV4aXR5CmZ1bmN0aW9uIHVwZGF0ZVNlc3Npb24oc2Vzc2lvbiwgY29udGV4dCA9IHt9KSB7CiAgaWYgKGNvbnRleHQudXNlcikgewogICAgaWYgKCFzZXNzaW9uLmlwQWRkcmVzcyAmJiBjb250ZXh0LnVzZXIuaXBfYWRkcmVzcykgewogICAgICBzZXNzaW9uLmlwQWRkcmVzcyA9IGNvbnRleHQudXNlci5pcF9hZGRyZXNzOwogICAgfQoKICAgIGlmICghc2Vzc2lvbi5kaWQgJiYgIWNvbnRleHQuZGlkKSB7CiAgICAgIHNlc3Npb24uZGlkID0gY29udGV4dC51c2VyLmlkIHx8IGNvbnRleHQudXNlci5lbWFpbCB8fCBjb250ZXh0LnVzZXIudXNlcm5hbWU7CiAgICB9CiAgfQoKICBzZXNzaW9uLnRpbWVzdGFtcCA9IGNvbnRleHQudGltZXN0YW1wIHx8IHRpbWVzdGFtcEluU2Vjb25kcygpOwoKICBpZiAoY29udGV4dC5hYm5vcm1hbF9tZWNoYW5pc20pIHsKICAgIHNlc3Npb24uYWJub3JtYWxfbWVjaGFuaXNtID0gY29udGV4dC5hYm5vcm1hbF9tZWNoYW5pc207CiAgfQoKICBpZiAoY29udGV4dC5pZ25vcmVEdXJhdGlvbikgewogICAgc2Vzc2lvbi5pZ25vcmVEdXJhdGlvbiA9IGNvbnRleHQuaWdub3JlRHVyYXRpb247CiAgfQogIGlmIChjb250ZXh0LnNpZCkgewogICAgLy8gR29vZCBlbm91Z2ggdXVpZCB2YWxpZGF0aW9uLiDigJQgS2FtaWwKICAgIHNlc3Npb24uc2lkID0gY29udGV4dC5zaWQubGVuZ3RoID09PSAzMiA/IGNvbnRleHQuc2lkIDogdXVpZDQoKTsKICB9CiAgaWYgKGNvbnRleHQuaW5pdCAhPT0gdW5kZWZpbmVkKSB7CiAgICBzZXNzaW9uLmluaXQgPSBjb250ZXh0LmluaXQ7CiAgfQogIGlmICghc2Vzc2lvbi5kaWQgJiYgY29udGV4dC5kaWQpIHsKICAgIHNlc3Npb24uZGlkID0gYCR7Y29udGV4dC5kaWR9YDsKICB9CiAgaWYgKHR5cGVvZiBjb250ZXh0LnN0YXJ0ZWQgPT09ICdudW1iZXInKSB7CiAgICBzZXNzaW9uLnN0YXJ0ZWQgPSBjb250ZXh0LnN0YXJ0ZWQ7CiAgfQogIGlmIChzZXNzaW9uLmlnbm9yZUR1cmF0aW9uKSB7CiAgICBzZXNzaW9uLmR1cmF0aW9uID0gdW5kZWZpbmVkOwogIH0gZWxzZSBpZiAodHlwZW9mIGNvbnRleHQuZHVyYXRpb24gPT09ICdudW1iZXInKSB7CiAgICBzZXNzaW9uLmR1cmF0aW9uID0gY29udGV4dC5kdXJhdGlvbjsKICB9IGVsc2UgewogICAgY29uc3QgZHVyYXRpb24gPSBzZXNzaW9uLnRpbWVzdGFtcCAtIHNlc3Npb24uc3RhcnRlZDsKICAgIHNlc3Npb24uZHVyYXRpb24gPSBkdXJhdGlvbiA+PSAwID8gZHVyYXRpb24gOiAwOwogIH0KICBpZiAoY29udGV4dC5yZWxlYXNlKSB7CiAgICBzZXNzaW9uLnJlbGVhc2UgPSBjb250ZXh0LnJlbGVhc2U7CiAgfQogIGlmIChjb250ZXh0LmVudmlyb25tZW50KSB7CiAgICBzZXNzaW9uLmVudmlyb25tZW50ID0gY29udGV4dC5lbnZpcm9ubWVudDsKICB9CiAgaWYgKCFzZXNzaW9uLmlwQWRkcmVzcyAmJiBjb250ZXh0LmlwQWRkcmVzcykgewogICAgc2Vzc2lvbi5pcEFkZHJlc3MgPSBjb250ZXh0LmlwQWRkcmVzczsKICB9CiAgaWYgKCFzZXNzaW9uLnVzZXJBZ2VudCAmJiBjb250ZXh0LnVzZXJBZ2VudCkgewogICAgc2Vzc2lvbi51c2VyQWdlbnQgPSBjb250ZXh0LnVzZXJBZ2VudDsKICB9CiAgaWYgKHR5cGVvZiBjb250ZXh0LmVycm9ycyA9PT0gJ251bWJlcicpIHsKICAgIHNlc3Npb24uZXJyb3JzID0gY29udGV4dC5lcnJvcnM7CiAgfQogIGlmIChjb250ZXh0LnN0YXR1cykgewogICAgc2Vzc2lvbi5zdGF0dXMgPSBjb250ZXh0LnN0YXR1czsKICB9Cn0KCi8qKgogKiBTZXJpYWxpemVzIGEgcGFzc2VkIHNlc3Npb24gb2JqZWN0IHRvIGEgSlNPTiBvYmplY3Qgd2l0aCBhIHNsaWdodGx5IGRpZmZlcmVudCBzdHJ1Y3R1cmUuCiAqIFRoaXMgaXMgbmVjZXNzYXJ5IGJlY2F1c2UgdGhlIFNlbnRyeSBiYWNrZW5kIHJlcXVpcmVzIGEgc2xpZ2h0bHkgZGlmZmVyZW50IHNjaGVtYSBvZiBhIHNlc3Npb24KICogdGhhbiB0aGUgb25lIHRoZSBKUyBTREtzIHVzZSBpbnRlcm5hbGx5LgogKgogKiBAcGFyYW0gc2Vzc2lvbiB0aGUgc2Vzc2lvbiB0byBiZSBjb252ZXJ0ZWQKICoKICogQHJldHVybnMgYSBKU09OIG9iamVjdCBvZiB0aGUgcGFzc2VkIHNlc3Npb24KICovCmZ1bmN0aW9uIHNlc3Npb25Ub0pTT04oc2Vzc2lvbikgewogIHJldHVybiBkcm9wVW5kZWZpbmVkS2V5cyh7CiAgICBzaWQ6IGAke3Nlc3Npb24uc2lkfWAsCiAgICBpbml0OiBzZXNzaW9uLmluaXQsCiAgICAvLyBNYWtlIHN1cmUgdGhhdCBzZWMgaXMgY29udmVydGVkIHRvIG1zIGZvciBkYXRlIGNvbnN0cnVjdG9yCiAgICBzdGFydGVkOiBuZXcgRGF0ZShzZXNzaW9uLnN0YXJ0ZWQgKiAxMDAwKS50b0lTT1N0cmluZygpLAogICAgdGltZXN0YW1wOiBuZXcgRGF0ZShzZXNzaW9uLnRpbWVzdGFtcCAqIDEwMDApLnRvSVNPU3RyaW5nKCksCiAgICBzdGF0dXM6IHNlc3Npb24uc3RhdHVzLAogICAgZXJyb3JzOiBzZXNzaW9uLmVycm9ycywKICAgIGRpZDogdHlwZW9mIHNlc3Npb24uZGlkID09PSAnbnVtYmVyJyB8fCB0eXBlb2Ygc2Vzc2lvbi5kaWQgPT09ICdzdHJpbmcnID8gYCR7c2Vzc2lvbi5kaWR9YCA6IHVuZGVmaW5lZCwKICAgIGR1cmF0aW9uOiBzZXNzaW9uLmR1cmF0aW9uLAogICAgYWJub3JtYWxfbWVjaGFuaXNtOiBzZXNzaW9uLmFibm9ybWFsX21lY2hhbmlzbSwKICAgIGF0dHJzOiB7CiAgICAgIHJlbGVhc2U6IHNlc3Npb24ucmVsZWFzZSwKICAgICAgZW52aXJvbm1lbnQ6IHNlc3Npb24uZW52aXJvbm1lbnQsCiAgICAgIGlwX2FkZHJlc3M6IHNlc3Npb24uaXBBZGRyZXNzLAogICAgICB1c2VyX2FnZW50OiBzZXNzaW9uLnVzZXJBZ2VudCwKICAgIH0sCiAgfSk7Cn0KCi8qKgogKiBBcHBseSBTZGtJbmZvIChuYW1lLCB2ZXJzaW9uLCBwYWNrYWdlcywgaW50ZWdyYXRpb25zKSB0byB0aGUgY29ycmVzcG9uZGluZyBldmVudCBrZXkuCiAqIE1lcmdlIHdpdGggZXhpc3RpbmcgZGF0YSBpZiBhbnkuCiAqKi8KZnVuY3Rpb24gZW5oYW5jZUV2ZW50V2l0aFNka0luZm8oZXZlbnQsIHNka0luZm8pIHsKICBpZiAoIXNka0luZm8pIHsKICAgIHJldHVybiBldmVudDsKICB9CiAgZXZlbnQuc2RrID0gZXZlbnQuc2RrIHx8IHt9OwogIGV2ZW50LnNkay5uYW1lID0gZXZlbnQuc2RrLm5hbWUgfHwgc2RrSW5mby5uYW1lOwogIGV2ZW50LnNkay52ZXJzaW9uID0gZXZlbnQuc2RrLnZlcnNpb24gfHwgc2RrSW5mby52ZXJzaW9uOwogIGV2ZW50LnNkay5pbnRlZ3JhdGlvbnMgPSBbLi4uKGV2ZW50LnNkay5pbnRlZ3JhdGlvbnMgfHwgW10pLCAuLi4oc2RrSW5mby5pbnRlZ3JhdGlvbnMgfHwgW10pXTsKICBldmVudC5zZGsucGFja2FnZXMgPSBbLi4uKGV2ZW50LnNkay5wYWNrYWdlcyB8fCBbXSksIC4uLihzZGtJbmZvLnBhY2thZ2VzIHx8IFtdKV07CiAgcmV0dXJuIGV2ZW50Owp9CgovKiogQ3JlYXRlcyBhbiBlbnZlbG9wZSBmcm9tIGEgU2Vzc2lvbiAqLwpmdW5jdGlvbiBjcmVhdGVTZXNzaW9uRW52ZWxvcGUoCiAgc2Vzc2lvbiwKICBkc24sCiAgbWV0YWRhdGEsCiAgdHVubmVsLAopIHsKICBjb25zdCBzZGtJbmZvID0gZ2V0U2RrTWV0YWRhdGFGb3JFbnZlbG9wZUhlYWRlcihtZXRhZGF0YSk7CiAgY29uc3QgZW52ZWxvcGVIZWFkZXJzID0gewogICAgc2VudF9hdDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLAogICAgLi4uKHNka0luZm8gJiYgeyBzZGs6IHNka0luZm8gfSksCiAgICAuLi4oISF0dW5uZWwgJiYgZHNuICYmIHsgZHNuOiBkc25Ub1N0cmluZyhkc24pIH0pLAogIH07CgogIGNvbnN0IGVudmVsb3BlSXRlbSA9CiAgICAnYWdncmVnYXRlcycgaW4gc2Vzc2lvbiA/IFt7IHR5cGU6ICdzZXNzaW9ucycgfSwgc2Vzc2lvbl0gOiBbeyB0eXBlOiAnc2Vzc2lvbicgfSwgc2Vzc2lvbi50b0pTT04oKV07CgogIHJldHVybiBjcmVhdGVFbnZlbG9wZShlbnZlbG9wZUhlYWRlcnMsIFtlbnZlbG9wZUl0ZW1dKTsKfQoKLyoqCiAqIENyZWF0ZSBhbiBFbnZlbG9wZSBmcm9tIGFuIGV2ZW50LgogKi8KZnVuY3Rpb24gY3JlYXRlRXZlbnRFbnZlbG9wZSgKICBldmVudCwKICBkc24sCiAgbWV0YWRhdGEsCiAgdHVubmVsLAopIHsKICBjb25zdCBzZGtJbmZvID0gZ2V0U2RrTWV0YWRhdGFGb3JFbnZlbG9wZUhlYWRlcihtZXRhZGF0YSk7CgogIC8qCiAgICBOb3RlOiBEdWUgdG8gVFMsIGV2ZW50LnR5cGUgbWF5IGJlIGByZXBsYXlfZXZlbnRgLCB0aGVvcmV0aWNhbGx5LgogICAgSW4gcHJhY3RpY2UsIHdlIG5ldmVyIGNhbGwgYGNyZWF0ZUV2ZW50RW52ZWxvcGVgIHdpdGggYHJlcGxheV9ldmVudGAgdHlwZSwKICAgIGFuZCB3ZSdkIGhhdmUgdG8gYWRqdXQgYSBsb29vdCBvZiB0eXBlcyB0byBtYWtlIHRoaXMgd29yayBwcm9wZXJseS4KICAgIFdlIHdhbnQgdG8gYXZvaWQgY2FzdGluZyB0aGlzIGFyb3VuZCwgYXMgdGhhdCBjb3VsZCBsZWFkIHRvIGJ1Z3MgKGUuZy4gd2hlbiB3ZSBhZGQgYW5vdGhlciB0eXBlKQogICAgU28gdGhlIHNhZmUgY2hvaWNlIGlzIHRvIHJlYWxseSBndWFyZCBhZ2FpbnN0IHRoZSByZXBsYXlfZXZlbnQgdHlwZSBoZXJlLgogICovCiAgY29uc3QgZXZlbnRUeXBlID0gZXZlbnQudHlwZSAmJiBldmVudC50eXBlICE9PSAncmVwbGF5X2V2ZW50JyA/IGV2ZW50LnR5cGUgOiAnZXZlbnQnOwoKICBlbmhhbmNlRXZlbnRXaXRoU2RrSW5mbyhldmVudCwgbWV0YWRhdGEgJiYgbWV0YWRhdGEuc2RrKTsKCiAgY29uc3QgZW52ZWxvcGVIZWFkZXJzID0gY3JlYXRlRXZlbnRFbnZlbG9wZUhlYWRlcnMoZXZlbnQsIHNka0luZm8sIHR1bm5lbCwgZHNuKTsKCiAgLy8gUHJldmVudCB0aGlzIGRhdGEgKHdoaWNoLCBpZiBpdCBleGlzdHMsIHdhcyB1c2VkIGluIGVhcmxpZXIgc3RlcHMgaW4gdGhlIHByb2Nlc3NpbmcgcGlwZWxpbmUpIGZyb20gYmVpbmcgc2VudCB0bwogIC8vIHNlbnRyeS4gKE5vdGU6IE91ciB1c2Ugb2YgdGhpcyBwcm9wZXJ0eSBjb21lcyBhbmQgZ29lcyB3aXRoIHdoYXRldmVyIHdlIG1pZ2h0IGJlIGRlYnVnZ2luZywgd2hhdGV2ZXIgaGFja3Mgd2UgbWF5CiAgLy8gaGF2ZSB0ZW1wb3JhcmlseSBhZGRlZCwgZXRjLiBFdmVuIGlmIHdlIGRvbid0IGhhcHBlbiB0byBiZSB1c2luZyBpdCBhdCBzb21lIHBvaW50IGluIHRoZSBmdXR1cmUsIGxldCdzIG5vdCBnZXQgcmlkCiAgLy8gb2YgdGhpcyBgZGVsZXRlYCwgbGVzdCB3ZSBtaXNzIHB1dHRpbmcgaXQgYmFjayBpbiB0aGUgbmV4dCB0aW1lIHRoZSBwcm9wZXJ0eSBpcyBpbiB1c2UuKQogIGRlbGV0ZSBldmVudC5zZGtQcm9jZXNzaW5nTWV0YWRhdGE7CgogIGNvbnN0IGV2ZW50SXRlbSA9IFt7IHR5cGU6IGV2ZW50VHlwZSB9LCBldmVudF07CiAgcmV0dXJuIGNyZWF0ZUVudmVsb3BlKGVudmVsb3BlSGVhZGVycywgW2V2ZW50SXRlbV0pOwp9Cgpjb25zdCBTRU5UUllfQVBJX1ZFUlNJT04gPSAnNyc7CgovKiogUmV0dXJucyB0aGUgcHJlZml4IHRvIGNvbnN0cnVjdCBTZW50cnkgaW5nZXN0aW9uIEFQSSBlbmRwb2ludHMuICovCmZ1bmN0aW9uIGdldEJhc2VBcGlFbmRwb2ludChkc24pIHsKICBjb25zdCBwcm90b2NvbCA9IGRzbi5wcm90b2NvbCA/IGAke2Rzbi5wcm90b2NvbH06YCA6ICcnOwogIGNvbnN0IHBvcnQgPSBkc24ucG9ydCA/IGA6JHtkc24ucG9ydH1gIDogJyc7CiAgcmV0dXJuIGAke3Byb3RvY29sfS8vJHtkc24uaG9zdH0ke3BvcnR9JHtkc24ucGF0aCA/IGAvJHtkc24ucGF0aH1gIDogJyd9L2FwaS9gOwp9CgovKiogUmV0dXJucyB0aGUgaW5nZXN0IEFQSSBlbmRwb2ludCBmb3IgdGFyZ2V0LiAqLwpmdW5jdGlvbiBfZ2V0SW5nZXN0RW5kcG9pbnQoZHNuKSB7CiAgcmV0dXJuIGAke2dldEJhc2VBcGlFbmRwb2ludChkc24pfSR7ZHNuLnByb2plY3RJZH0vZW52ZWxvcGUvYDsKfQoKLyoqIFJldHVybnMgYSBVUkwtZW5jb2RlZCBzdHJpbmcgd2l0aCBhdXRoIGNvbmZpZyBzdWl0YWJsZSBmb3IgYSBxdWVyeSBzdHJpbmcuICovCmZ1bmN0aW9uIF9lbmNvZGVkQXV0aChkc24sIHNka0luZm8pIHsKICByZXR1cm4gdXJsRW5jb2RlKHsKICAgIC8vIFdlIHNlbmQgb25seSB0aGUgbWluaW11bSBzZXQgb2YgcmVxdWlyZWQgaW5mb3JtYXRpb24uIFNlZQogICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdC9pc3N1ZXMvMjU3Mi4KICAgIHNlbnRyeV9rZXk6IGRzbi5wdWJsaWNLZXksCiAgICBzZW50cnlfdmVyc2lvbjogU0VOVFJZX0FQSV9WRVJTSU9OLAogICAgLi4uKHNka0luZm8gJiYgeyBzZW50cnlfY2xpZW50OiBgJHtzZGtJbmZvLm5hbWV9LyR7c2RrSW5mby52ZXJzaW9ufWAgfSksCiAgfSk7Cn0KCi8qKgogKiBSZXR1cm5zIHRoZSBlbnZlbG9wZSBlbmRwb2ludCBVUkwgd2l0aCBhdXRoIGluIHRoZSBxdWVyeSBzdHJpbmcuCiAqCiAqIFNlbmRpbmcgYXV0aCBhcyBwYXJ0IG9mIHRoZSBxdWVyeSBzdHJpbmcgYW5kIG5vdCBhcyBjdXN0b20gSFRUUCBoZWFkZXJzIGF2b2lkcyBDT1JTIHByZWZsaWdodCByZXF1ZXN0cy4KICovCmZ1bmN0aW9uIGdldEVudmVsb3BlRW5kcG9pbnRXaXRoVXJsRW5jb2RlZEF1dGgoCiAgZHNuLAogIC8vIFRPRE8gKHY4KTogUmVtb3ZlIGB0dW5uZWxPck9wdGlvbnNgIGluIGZhdm9yIG9mIGBvcHRpb25zYCwgYW5kIHVzZSB0aGUgc3Vic3RpdHV0ZSBjb2RlIGJlbG93CiAgLy8gb3B0aW9uczogQ2xpZW50T3B0aW9ucyA9IHt9IGFzIENsaWVudE9wdGlvbnMsCiAgdHVubmVsT3JPcHRpb25zID0ge30gLAopIHsKICAvLyBUT0RPICh2OCk6IFVzZSB0aGlzIGNvZGUgaW5zdGVhZAogIC8vIGNvbnN0IHsgdHVubmVsLCBfbWV0YWRhdGEgPSB7fSB9ID0gb3B0aW9uczsKICAvLyByZXR1cm4gdHVubmVsID8gdHVubmVsIDogYCR7X2dldEluZ2VzdEVuZHBvaW50KGRzbil9PyR7X2VuY29kZWRBdXRoKGRzbiwgX21ldGFkYXRhLnNkayl9YDsKCiAgY29uc3QgdHVubmVsID0gdHlwZW9mIHR1bm5lbE9yT3B0aW9ucyA9PT0gJ3N0cmluZycgPyB0dW5uZWxPck9wdGlvbnMgOiB0dW5uZWxPck9wdGlvbnMudHVubmVsOwogIGNvbnN0IHNka0luZm8gPQogICAgdHlwZW9mIHR1bm5lbE9yT3B0aW9ucyA9PT0gJ3N0cmluZycgfHwgIXR1bm5lbE9yT3B0aW9ucy5fbWV0YWRhdGEgPyB1bmRlZmluZWQgOiB0dW5uZWxPck9wdGlvbnMuX21ldGFkYXRhLnNkazsKCiAgcmV0dXJuIHR1bm5lbCA/IHR1bm5lbCA6IGAke19nZXRJbmdlc3RFbmRwb2ludChkc24pfT8ke19lbmNvZGVkQXV0aChkc24sIHNka0luZm8pfWA7Cn0KCmNvbnN0IERFRkFVTFRfVFJBTlNQT1JUX0JVRkZFUl9TSVpFID0gMzA7CgovKioKICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBhIFNlbnRyeSBgVHJhbnNwb3J0YAogKgogKiBAcGFyYW0gb3B0aW9ucwogKiBAcGFyYW0gbWFrZVJlcXVlc3QKICovCmZ1bmN0aW9uIGNyZWF0ZVRyYW5zcG9ydCgKICBvcHRpb25zLAogIG1ha2VSZXF1ZXN0LAogIGJ1ZmZlciA9IG1ha2VQcm9taXNlQnVmZmVyKAogICAgb3B0aW9ucy5idWZmZXJTaXplIHx8IERFRkFVTFRfVFJBTlNQT1JUX0JVRkZFUl9TSVpFLAogICksCikgewogIGxldCByYXRlTGltaXRzID0ge307CiAgY29uc3QgZmx1c2ggPSAodGltZW91dCkgPT4gYnVmZmVyLmRyYWluKHRpbWVvdXQpOwoKICBmdW5jdGlvbiBzZW5kKGVudmVsb3BlKSB7CiAgICBjb25zdCBmaWx0ZXJlZEVudmVsb3BlSXRlbXMgPSBbXTsKCiAgICAvLyBEcm9wIHJhdGUgbGltaXRlZCBpdGVtcyBmcm9tIGVudmVsb3BlCiAgICBmb3JFYWNoRW52ZWxvcGVJdGVtKGVudmVsb3BlLCAoaXRlbSwgdHlwZSkgPT4gewogICAgICBjb25zdCBlbnZlbG9wZUl0ZW1EYXRhQ2F0ZWdvcnkgPSBlbnZlbG9wZUl0ZW1UeXBlVG9EYXRhQ2F0ZWdvcnkodHlwZSk7CiAgICAgIGlmIChpc1JhdGVMaW1pdGVkKHJhdGVMaW1pdHMsIGVudmVsb3BlSXRlbURhdGFDYXRlZ29yeSkpIHsKICAgICAgICBjb25zdCBldmVudCA9IGdldEV2ZW50Rm9yRW52ZWxvcGVJdGVtKGl0ZW0sIHR5cGUpOwogICAgICAgIG9wdGlvbnMucmVjb3JkRHJvcHBlZEV2ZW50KCdyYXRlbGltaXRfYmFja29mZicsIGVudmVsb3BlSXRlbURhdGFDYXRlZ29yeSwgZXZlbnQpOwogICAgICB9IGVsc2UgewogICAgICAgIGZpbHRlcmVkRW52ZWxvcGVJdGVtcy5wdXNoKGl0ZW0pOwogICAgICB9CiAgICB9KTsKCiAgICAvLyBTa2lwIHNlbmRpbmcgaWYgZW52ZWxvcGUgaXMgZW1wdHkgYWZ0ZXIgZmlsdGVyaW5nIG91dCByYXRlIGxpbWl0ZWQgZXZlbnRzCiAgICBpZiAoZmlsdGVyZWRFbnZlbG9wZUl0ZW1zLmxlbmd0aCA9PT0gMCkgewogICAgICByZXR1cm4gcmVzb2x2ZWRTeW5jUHJvbWlzZSgpOwogICAgfQoKICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55CiAgICBjb25zdCBmaWx0ZXJlZEVudmVsb3BlID0gY3JlYXRlRW52ZWxvcGUoZW52ZWxvcGVbMF0sIGZpbHRlcmVkRW52ZWxvcGVJdGVtcyApOwoKICAgIC8vIENyZWF0ZXMgY2xpZW50IHJlcG9ydCBmb3IgZWFjaCBpdGVtIGluIGFuIGVudmVsb3BlCiAgICBjb25zdCByZWNvcmRFbnZlbG9wZUxvc3MgPSAocmVhc29uKSA9PiB7CiAgICAgIGZvckVhY2hFbnZlbG9wZUl0ZW0oZmlsdGVyZWRFbnZlbG9wZSwgKGl0ZW0sIHR5cGUpID0+IHsKICAgICAgICBjb25zdCBldmVudCA9IGdldEV2ZW50Rm9yRW52ZWxvcGVJdGVtKGl0ZW0sIHR5cGUpOwogICAgICAgIG9wdGlvbnMucmVjb3JkRHJvcHBlZEV2ZW50KHJlYXNvbiwgZW52ZWxvcGVJdGVtVHlwZVRvRGF0YUNhdGVnb3J5KHR5cGUpLCBldmVudCk7CiAgICAgIH0pOwogICAgfTsKCiAgICBjb25zdCByZXF1ZXN0VGFzayA9ICgpID0+CiAgICAgIG1ha2VSZXF1ZXN0KHsgYm9keTogc2VyaWFsaXplRW52ZWxvcGUoZmlsdGVyZWRFbnZlbG9wZSwgb3B0aW9ucy50ZXh0RW5jb2RlcikgfSkudGhlbigKICAgICAgICByZXNwb25zZSA9PiB7CiAgICAgICAgICAvLyBXZSBkb24ndCB3YW50IHRvIHRocm93IG9uIE5PSyByZXNwb25zZXMsIGJ1dCB3ZSB3YW50IHRvIGF0IGxlYXN0IGxvZyB0aGVtCiAgICAgICAgICBpZiAocmVzcG9uc2Uuc3RhdHVzQ29kZSAhPT0gdW5kZWZpbmVkICYmIChyZXNwb25zZS5zdGF0dXNDb2RlIDwgMjAwIHx8IHJlc3BvbnNlLnN0YXR1c0NvZGUgPj0gMzAwKSkgewogICAgICAgICAgICBERUJVR19CVUlMRCAmJiBsb2dnZXIud2FybihgU2VudHJ5IHJlc3BvbmRlZCB3aXRoIHN0YXR1cyBjb2RlICR7cmVzcG9uc2Uuc3RhdHVzQ29kZX0gdG8gc2VudCBldmVudC5gKTsKICAgICAgICAgIH0KCiAgICAgICAgICByYXRlTGltaXRzID0gdXBkYXRlUmF0ZUxpbWl0cyhyYXRlTGltaXRzLCByZXNwb25zZSk7CiAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7CiAgICAgICAgfSwKICAgICAgICBlcnJvciA9PiB7CiAgICAgICAgICByZWNvcmRFbnZlbG9wZUxvc3MoJ25ldHdvcmtfZXJyb3InKTsKICAgICAgICAgIHRocm93IGVycm9yOwogICAgICAgIH0sCiAgICAgICk7CgogICAgcmV0dXJuIGJ1ZmZlci5hZGQocmVxdWVzdFRhc2spLnRoZW4oCiAgICAgIHJlc3VsdCA9PiByZXN1bHQsCiAgICAgIGVycm9yID0+IHsKICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBTZW50cnlFcnJvcikgewogICAgICAgICAgREVCVUdfQlVJTEQgJiYgbG9nZ2VyLmVycm9yKCdTa2lwcGVkIHNlbmRpbmcgZXZlbnQgYmVjYXVzZSBidWZmZXIgaXMgZnVsbC4nKTsKICAgICAgICAgIHJlY29yZEVudmVsb3BlTG9zcygncXVldWVfb3ZlcmZsb3cnKTsKICAgICAgICAgIHJldHVybiByZXNvbHZlZFN5bmNQcm9taXNlKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHRocm93IGVycm9yOwogICAgICAgIH0KICAgICAgfSwKICAgICk7CiAgfQoKICAvLyBXZSB1c2UgdGhpcyB0byBpZGVudGlmaWZ5IGlmIHRoZSB0cmFuc3BvcnQgaXMgdGhlIGJhc2UgdHJhbnNwb3J0CiAgLy8gVE9ETyAodjgpOiBSZW1vdmUgdGhpcyBhZ2FpbiBhcyB3ZSdsbCBubyBsb25nZXIgbmVlZCBpdAogIHNlbmQuX19zZW50cnlfX2Jhc2VUcmFuc3BvcnRfXyA9IHRydWU7CgogIHJldHVybiB7CiAgICBzZW5kLAogICAgZmx1c2gsCiAgfTsKfQoKZnVuY3Rpb24gZ2V0RXZlbnRGb3JFbnZlbG9wZUl0ZW0oaXRlbSwgdHlwZSkgewogIGlmICh0eXBlICE9PSAnZXZlbnQnICYmIHR5cGUgIT09ICd0cmFuc2FjdGlvbicpIHsKICAgIHJldHVybiB1bmRlZmluZWQ7CiAgfQoKICByZXR1cm4gQXJyYXkuaXNBcnJheShpdGVtKSA/IChpdGVtIClbMV0gOiB1bmRlZmluZWQ7Cn0KCi8qKiBub3JtYWxpemVzIFdpbmRvd3MgcGF0aHMgKi8KZnVuY3Rpb24gbm9ybWFsaXplV2luZG93c1BhdGgocGF0aCkgewogIHJldHVybiBwYXRoCiAgICAucmVwbGFjZSgvXltBLVpdOi8sICcnKSAvLyByZW1vdmUgV2luZG93cy1zdHlsZSBwcmVmaXgKICAgIC5yZXBsYWNlKC9cXC9nLCAnLycpOyAvLyByZXBsYWNlIGFsbCBgXGAgaW5zdGFuY2VzIHdpdGggYC9gCn0KCi8qKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBnZXRzIHRoZSBtb2R1bGUgbmFtZSBmcm9tIGEgZmlsZW5hbWUgKi8KZnVuY3Rpb24gY3JlYXRlR2V0TW9kdWxlRnJvbUZpbGVuYW1lKAogIGJhc2VQYXRoID0gcHJvY2Vzcy5hcmd2WzFdID8gZGlybmFtZShwcm9jZXNzLmFyZ3ZbMV0pIDogcHJvY2Vzcy5jd2QoKSwKICBpc1dpbmRvd3MgPSBzZXAgPT09ICdcXCcsCikgewogIGNvbnN0IG5vcm1hbGl6ZWRCYXNlID0gaXNXaW5kb3dzID8gbm9ybWFsaXplV2luZG93c1BhdGgoYmFzZVBhdGgpIDogYmFzZVBhdGg7CgogIHJldHVybiAoZmlsZW5hbWUpID0+IHsKICAgIGlmICghZmlsZW5hbWUpIHsKICAgICAgcmV0dXJuOwogICAgfQoKICAgIGNvbnN0IG5vcm1hbGl6ZWRGaWxlbmFtZSA9IGlzV2luZG93cyA/IG5vcm1hbGl6ZVdpbmRvd3NQYXRoKGZpbGVuYW1lKSA6IGZpbGVuYW1lOwoKICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBwcmVmZXItY29uc3QKICAgIGxldCB7IGRpciwgYmFzZTogZmlsZSwgZXh0IH0gPSBwb3NpeC5wYXJzZShub3JtYWxpemVkRmlsZW5hbWUpOwoKICAgIGlmIChleHQgPT09ICcuanMnIHx8IGV4dCA9PT0gJy5tanMnIHx8IGV4dCA9PT0gJy5janMnKSB7CiAgICAgIGZpbGUgPSBmaWxlLnNsaWNlKDAsIGV4dC5sZW5ndGggKiAtMSk7CiAgICB9CgogICAgaWYgKCFkaXIpIHsKICAgICAgLy8gTm8gZGlybmFtZSB3aGF0c29ldmVyCiAgICAgIGRpciA9ICcuJzsKICAgIH0KCiAgICBjb25zdCBuID0gZGlyLmxhc3RJbmRleE9mKCcvbm9kZV9tb2R1bGVzJyk7CiAgICBpZiAobiA+IC0xKSB7CiAgICAgIHJldHVybiBgJHtkaXIuc2xpY2UobiArIDE0KS5yZXBsYWNlKC9cLy9nLCAnLicpfToke2ZpbGV9YDsKICAgIH0KCiAgICAvLyBMZXQncyBzZWUgaWYgaXQncyBhIHBhcnQgb2YgdGhlIG1haW4gbW9kdWxlCiAgICAvLyBUbyBiZSBhIHBhcnQgb2YgbWFpbiBtb2R1bGUsIGl0IGhhcyB0byBzaGFyZSB0aGUgc2FtZSBiYXNlCiAgICBpZiAoZGlyLnN0YXJ0c1dpdGgobm9ybWFsaXplZEJhc2UpKSB7CiAgICAgIGxldCBtb2R1bGVOYW1lID0gZGlyLnNsaWNlKG5vcm1hbGl6ZWRCYXNlLmxlbmd0aCArIDEpLnJlcGxhY2UoL1wvL2csICcuJyk7CgogICAgICBpZiAobW9kdWxlTmFtZSkgewogICAgICAgIG1vZHVsZU5hbWUgKz0gJzonOwogICAgICB9CiAgICAgIG1vZHVsZU5hbWUgKz0gZmlsZTsKCiAgICAgIHJldHVybiBtb2R1bGVOYW1lOwogICAgfQoKICAgIHJldHVybiBmaWxlOwogIH07Cn0KCmZ1bmN0aW9uIF9udWxsaXNoQ29hbGVzY2UkMihsaHMsIHJoc0ZuKSB7IGlmIChsaHMgIT0gbnVsbCkgeyByZXR1cm4gbGhzOyB9IGVsc2UgeyByZXR1cm4gcmhzRm4oKTsgfSB9LyoqCiAqIFRoaXMgY29kZSB3YXMgb3JpZ2luYWxseSBmb3JrZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vVG9vVGFsbE5hdGUvcHJveHktYWdlbnRzL3RyZWUvYjEzMzI5NWZkMTZmNjQ3NTU3OGI2YjE1YmQ5YjRlMzNlY2IwZDBiNwogKiBXaXRoIHRoZSBmb2xsb3dpbmcgbGljZW5jZToKICoKICogKFRoZSBNSVQgTGljZW5zZSkKICoKICogQ29weXJpZ2h0IChjKSAyMDEzIE5hdGhhbiBSYWpsaWNoIDxuYXRoYW5AdG9vdGFsbG5hdGUubmV0PioKICoKICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nCiAqIGEgY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZQogKiAnU29mdHdhcmUnKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nCiAqIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwKICogZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvCiAqIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0bwogKiB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6KgogKgogKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZQogKiBpbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4qCiAqCiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAnQVMgSVMnLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELAogKiBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YKICogTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULgogKiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWQogKiBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULAogKiBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRQogKiBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KICovCgpjb25zdCBJTlRFUk5BTCA9IFN5bWJvbCgnQWdlbnRCYXNlSW50ZXJuYWxTdGF0ZScpOwoKY2xhc3MgQWdlbnQgZXh0ZW5kcyBodHRwLkFnZW50IHsKCiAgLy8gU2V0IGJ5IGBodHRwLkFnZW50YCAtIG1pc3NpbmcgZnJvbSBgQHR5cGVzL25vZGVgCgogIGNvbnN0cnVjdG9yKG9wdHMpIHsKICAgIHN1cGVyKG9wdHMpOwogICAgdGhpc1tJTlRFUk5BTF0gPSB7fTsKICB9CgogIC8qKgogICAqIERldGVybWluZSB3aGV0aGVyIHRoaXMgaXMgYW4gYGh0dHBgIG9yIGBodHRwc2AgcmVxdWVzdC4KICAgKi8KICBpc1NlY3VyZUVuZHBvaW50KG9wdGlvbnMpIHsKICAgIGlmIChvcHRpb25zKSB7CiAgICAgIC8vIEZpcnN0IGNoZWNrIHRoZSBgc2VjdXJlRW5kcG9pbnRgIHByb3BlcnR5IGV4cGxpY2l0bHksIHNpbmNlIHRoaXMKICAgICAgLy8gbWVhbnMgdGhhdCBhIHBhcmVudCBgQWdlbnRgIGlzICJwYXNzaW5nIHRocm91Z2giIHRvIHRoaXMgaW5zdGFuY2UuCiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55LCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLW1lbWJlci1hY2Nlc3MKICAgICAgaWYgKHR5cGVvZiAob3B0aW9ucyApLnNlY3VyZUVuZHBvaW50ID09PSAnYm9vbGVhbicpIHsKICAgICAgICByZXR1cm4gb3B0aW9ucy5zZWN1cmVFbmRwb2ludDsKICAgICAgfQoKICAgICAgLy8gSWYgbm8gZXhwbGljaXQgYHNlY3VyZWAgZW5kcG9pbnQsIGNoZWNrIGlmIGBwcm90b2NvbGAgcHJvcGVydHkgaXMKICAgICAgLy8gc2V0LiBUaGlzIHdpbGwgdXN1YWxseSBiZSB0aGUgY2FzZSBzaW5jZSB1c2luZyBhIGZ1bGwgc3RyaW5nIFVSTAogICAgICAvLyBvciBgVVJMYCBpbnN0YW5jZSBzaG91bGQgYmUgdGhlIG1vc3QgY29tbW9uIHVzYWdlLgogICAgICBpZiAodHlwZW9mIG9wdGlvbnMucHJvdG9jb2wgPT09ICdzdHJpbmcnKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbnMucHJvdG9jb2wgPT09ICdodHRwczonOwogICAgICB9CiAgICB9CgogICAgLy8gRmluYWxseSwgaWYgbm8gYHByb3RvY29sYCBwcm9wZXJ0eSB3YXMgc2V0LCB0aGVuIGZhbGwgYmFjayB0bwogICAgLy8gY2hlY2tpbmcgdGhlIHN0YWNrIHRyYWNlIG9mIHRoZSBjdXJyZW50IGNhbGwgc3RhY2ssIGFuZCB0cnkgdG8KICAgIC8vIGRldGVjdCB0aGUgImh0dHBzIiBtb2R1bGUuCiAgICBjb25zdCB7IHN0YWNrIH0gPSBuZXcgRXJyb3IoKTsKICAgIGlmICh0eXBlb2Ygc3RhY2sgIT09ICdzdHJpbmcnKSByZXR1cm4gZmFsc2U7CiAgICByZXR1cm4gc3RhY2suc3BsaXQoJ1xuJykuc29tZShsID0+IGwuaW5kZXhPZignKGh0dHBzLmpzOicpICE9PSAtMSB8fCBsLmluZGV4T2YoJ25vZGU6aHR0cHM6JykgIT09IC0xKTsKICB9CgogIGNyZWF0ZVNvY2tldChyZXEsIG9wdGlvbnMsIGNiKSB7CiAgICBjb25zdCBjb25uZWN0T3B0cyA9IHsKICAgICAgLi4ub3B0aW9ucywKICAgICAgc2VjdXJlRW5kcG9pbnQ6IHRoaXMuaXNTZWN1cmVFbmRwb2ludChvcHRpb25zKSwKICAgIH07CiAgICBQcm9taXNlLnJlc29sdmUoKQogICAgICAudGhlbigoKSA9PiB0aGlzLmNvbm5lY3QocmVxLCBjb25uZWN0T3B0cykpCiAgICAgIC50aGVuKHNvY2tldCA9PiB7CiAgICAgICAgaWYgKHNvY2tldCBpbnN0YW5jZW9mIGh0dHAuQWdlbnQpIHsKICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgYGFkZFJlcXVlc3QoKWAgaXNuJ3QgZGVmaW5lZCBpbiBgQHR5cGVzL25vZGVgCiAgICAgICAgICByZXR1cm4gc29ja2V0LmFkZFJlcXVlc3QocmVxLCBjb25uZWN0T3B0cyk7CiAgICAgICAgfQogICAgICAgIHRoaXNbSU5URVJOQUxdLmN1cnJlbnRTb2NrZXQgPSBzb2NrZXQ7CiAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBgY3JlYXRlU29ja2V0KClgIGlzbid0IGRlZmluZWQgaW4gYEB0eXBlcy9ub2RlYAogICAgICAgIHN1cGVyLmNyZWF0ZVNvY2tldChyZXEsIG9wdGlvbnMsIGNiKTsKICAgICAgfSwgY2IpOwogIH0KCiAgY3JlYXRlQ29ubmVjdGlvbigpIHsKICAgIGNvbnN0IHNvY2tldCA9IHRoaXNbSU5URVJOQUxdLmN1cnJlbnRTb2NrZXQ7CiAgICB0aGlzW0lOVEVSTkFMXS5jdXJyZW50U29ja2V0ID0gdW5kZWZpbmVkOwogICAgaWYgKCFzb2NrZXQpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBzb2NrZXQgd2FzIHJldHVybmVkIGluIHRoZSBgY29ubmVjdCgpYCBmdW5jdGlvbicpOwogICAgfQogICAgcmV0dXJuIHNvY2tldDsKICB9CgogIGdldCBkZWZhdWx0UG9ydCgpIHsKICAgIHJldHVybiBfbnVsbGlzaENvYWxlc2NlJDIodGhpc1tJTlRFUk5BTF0uZGVmYXVsdFBvcnQsICgpID0+ICggKHRoaXMucHJvdG9jb2wgPT09ICdodHRwczonID8gNDQzIDogODApKSk7CiAgfQoKICBzZXQgZGVmYXVsdFBvcnQodikgewogICAgaWYgKHRoaXNbSU5URVJOQUxdKSB7CiAgICAgIHRoaXNbSU5URVJOQUxdLmRlZmF1bHRQb3J0ID0gdjsKICAgIH0KICB9CgogIGdldCBwcm90b2NvbCgpIHsKICAgIHJldHVybiBfbnVsbGlzaENvYWxlc2NlJDIodGhpc1tJTlRFUk5BTF0ucHJvdG9jb2wsICgpID0+ICggKHRoaXMuaXNTZWN1cmVFbmRwb2ludCgpID8gJ2h0dHBzOicgOiAnaHR0cDonKSkpOwogIH0KCiAgc2V0IHByb3RvY29sKHYpIHsKICAgIGlmICh0aGlzW0lOVEVSTkFMXSkgewogICAgICB0aGlzW0lOVEVSTkFMXS5wcm90b2NvbCA9IHY7CiAgICB9CiAgfQp9CgpmdW5jdGlvbiBkZWJ1ZyQxKC4uLmFyZ3MpIHsKICBsb2dnZXIubG9nKCdbaHR0cHMtcHJveHktYWdlbnQ6cGFyc2UtcHJveHktcmVzcG9uc2VdJywgLi4uYXJncyk7Cn0KCmZ1bmN0aW9uIHBhcnNlUHJveHlSZXNwb25zZShzb2NrZXQpIHsKICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4gewogICAgLy8gd2UgbmVlZCB0byBidWZmZXIgYW55IEhUVFAgdHJhZmZpYyB0aGF0IGhhcHBlbnMgd2l0aCB0aGUgcHJveHkgYmVmb3JlIHdlIGdldAogICAgLy8gdGhlIENPTk5FQ1QgcmVzcG9uc2UsIHNvIHRoYXQgaWYgdGhlIHJlc3BvbnNlIGlzIGFueXRoaW5nIG90aGVyIHRoYW4gYW4gIjIwMCIKICAgIC8vIHJlc3BvbnNlIGNvZGUsIHRoZW4gd2UgY2FuIHJlLXBsYXkgdGhlICJkYXRhIiBldmVudHMgb24gdGhlIHNvY2tldCBvbmNlIHRoZQogICAgLy8gSFRUUCBwYXJzZXIgaXMgaG9va2VkIHVwLi4uCiAgICBsZXQgYnVmZmVyc0xlbmd0aCA9IDA7CiAgICBjb25zdCBidWZmZXJzID0gW107CgogICAgZnVuY3Rpb24gcmVhZCgpIHsKICAgICAgY29uc3QgYiA9IHNvY2tldC5yZWFkKCk7CiAgICAgIGlmIChiKSBvbmRhdGEoYik7CiAgICAgIGVsc2Ugc29ja2V0Lm9uY2UoJ3JlYWRhYmxlJywgcmVhZCk7CiAgICB9CgogICAgZnVuY3Rpb24gY2xlYW51cCgpIHsKICAgICAgc29ja2V0LnJlbW92ZUxpc3RlbmVyKCdlbmQnLCBvbmVuZCk7CiAgICAgIHNvY2tldC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTsKICAgICAgc29ja2V0LnJlbW92ZUxpc3RlbmVyKCdyZWFkYWJsZScsIHJlYWQpOwogICAgfQoKICAgIGZ1bmN0aW9uIG9uZW5kKCkgewogICAgICBjbGVhbnVwKCk7CiAgICAgIGRlYnVnJDEoJ29uZW5kJyk7CiAgICAgIHJlamVjdChuZXcgRXJyb3IoJ1Byb3h5IGNvbm5lY3Rpb24gZW5kZWQgYmVmb3JlIHJlY2VpdmluZyBDT05ORUNUIHJlc3BvbnNlJykpOwogICAgfQoKICAgIGZ1bmN0aW9uIG9uZXJyb3IoZXJyKSB7CiAgICAgIGNsZWFudXAoKTsKICAgICAgZGVidWckMSgnb25lcnJvciAlbycsIGVycik7CiAgICAgIHJlamVjdChlcnIpOwogICAgfQoKICAgIGZ1bmN0aW9uIG9uZGF0YShiKSB7CiAgICAgIGJ1ZmZlcnMucHVzaChiKTsKICAgICAgYnVmZmVyc0xlbmd0aCArPSBiLmxlbmd0aDsKCiAgICAgIGNvbnN0IGJ1ZmZlcmVkID0gQnVmZmVyLmNvbmNhdChidWZmZXJzLCBidWZmZXJzTGVuZ3RoKTsKICAgICAgY29uc3QgZW5kT2ZIZWFkZXJzID0gYnVmZmVyZWQuaW5kZXhPZignXHJcblxyXG4nKTsKCiAgICAgIGlmIChlbmRPZkhlYWRlcnMgPT09IC0xKSB7CiAgICAgICAgLy8ga2VlcCBidWZmZXJpbmcKICAgICAgICBkZWJ1ZyQxKCdoYXZlIG5vdCByZWNlaXZlZCBlbmQgb2YgSFRUUCBoZWFkZXJzIHlldC4uLicpOwogICAgICAgIHJlYWQoKTsKICAgICAgICByZXR1cm47CiAgICAgIH0KCiAgICAgIGNvbnN0IGhlYWRlclBhcnRzID0gYnVmZmVyZWQuc2xpY2UoMCwgZW5kT2ZIZWFkZXJzKS50b1N0cmluZygnYXNjaWknKS5zcGxpdCgnXHJcbicpOwogICAgICBjb25zdCBmaXJzdExpbmUgPSBoZWFkZXJQYXJ0cy5zaGlmdCgpOwogICAgICBpZiAoIWZpcnN0TGluZSkgewogICAgICAgIHNvY2tldC5kZXN0cm95KCk7CiAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoJ05vIGhlYWRlciByZWNlaXZlZCBmcm9tIHByb3h5IENPTk5FQ1QgcmVzcG9uc2UnKSk7CiAgICAgIH0KICAgICAgY29uc3QgZmlyc3RMaW5lUGFydHMgPSBmaXJzdExpbmUuc3BsaXQoJyAnKTsKICAgICAgY29uc3Qgc3RhdHVzQ29kZSA9ICtmaXJzdExpbmVQYXJ0c1sxXTsKICAgICAgY29uc3Qgc3RhdHVzVGV4dCA9IGZpcnN0TGluZVBhcnRzLnNsaWNlKDIpLmpvaW4oJyAnKTsKICAgICAgY29uc3QgaGVhZGVycyA9IHt9OwogICAgICBmb3IgKGNvbnN0IGhlYWRlciBvZiBoZWFkZXJQYXJ0cykgewogICAgICAgIGlmICghaGVhZGVyKSBjb250aW51ZTsKICAgICAgICBjb25zdCBmaXJzdENvbG9uID0gaGVhZGVyLmluZGV4T2YoJzonKTsKICAgICAgICBpZiAoZmlyc3RDb2xvbiA9PT0gLTEpIHsKICAgICAgICAgIHNvY2tldC5kZXN0cm95KCk7CiAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcihgSW52YWxpZCBoZWFkZXIgZnJvbSBwcm94eSBDT05ORUNUIHJlc3BvbnNlOiAiJHtoZWFkZXJ9ImApKTsKICAgICAgICB9CiAgICAgICAgY29uc3Qga2V5ID0gaGVhZGVyLnNsaWNlKDAsIGZpcnN0Q29sb24pLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgY29uc3QgdmFsdWUgPSBoZWFkZXIuc2xpY2UoZmlyc3RDb2xvbiArIDEpLnRyaW1TdGFydCgpOwogICAgICAgIGNvbnN0IGN1cnJlbnQgPSBoZWFkZXJzW2tleV07CiAgICAgICAgaWYgKHR5cGVvZiBjdXJyZW50ID09PSAnc3RyaW5nJykgewogICAgICAgICAgaGVhZGVyc1trZXldID0gW2N1cnJlbnQsIHZhbHVlXTsKICAgICAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoY3VycmVudCkpIHsKICAgICAgICAgIGN1cnJlbnQucHVzaCh2YWx1ZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGhlYWRlcnNba2V5XSA9IHZhbHVlOwogICAgICAgIH0KICAgICAgfQogICAgICBkZWJ1ZyQxKCdnb3QgcHJveHkgc2VydmVyIHJlc3BvbnNlOiAlbyAlbycsIGZpcnN0TGluZSwgaGVhZGVycyk7CiAgICAgIGNsZWFudXAoKTsKICAgICAgcmVzb2x2ZSh7CiAgICAgICAgY29ubmVjdDogewogICAgICAgICAgc3RhdHVzQ29kZSwKICAgICAgICAgIHN0YXR1c1RleHQsCiAgICAgICAgICBoZWFkZXJzLAogICAgICAgIH0sCiAgICAgICAgYnVmZmVyZWQsCiAgICAgIH0pOwogICAgfQoKICAgIHNvY2tldC5vbignZXJyb3InLCBvbmVycm9yKTsKICAgIHNvY2tldC5vbignZW5kJywgb25lbmQpOwoKICAgIHJlYWQoKTsKICB9KTsKfQoKZnVuY3Rpb24gX251bGxpc2hDb2FsZXNjZSQxKGxocywgcmhzRm4pIHsgaWYgKGxocyAhPSBudWxsKSB7IHJldHVybiBsaHM7IH0gZWxzZSB7IHJldHVybiByaHNGbigpOyB9IH0gZnVuY3Rpb24gX29wdGlvbmFsQ2hhaW4kMShvcHMpIHsgbGV0IGxhc3RBY2Nlc3NMSFMgPSB1bmRlZmluZWQ7IGxldCB2YWx1ZSA9IG9wc1swXTsgbGV0IGkgPSAxOyB3aGlsZSAoaSA8IG9wcy5sZW5ndGgpIHsgY29uc3Qgb3AgPSBvcHNbaV07IGNvbnN0IGZuID0gb3BzW2kgKyAxXTsgaSArPSAyOyBpZiAoKG9wID09PSAnb3B0aW9uYWxBY2Nlc3MnIHx8IG9wID09PSAnb3B0aW9uYWxDYWxsJykgJiYgdmFsdWUgPT0gbnVsbCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IGlmIChvcCA9PT0gJ2FjY2VzcycgfHwgb3AgPT09ICdvcHRpb25hbEFjY2VzcycpIHsgbGFzdEFjY2Vzc0xIUyA9IHZhbHVlOyB2YWx1ZSA9IGZuKHZhbHVlKTsgfSBlbHNlIGlmIChvcCA9PT0gJ2NhbGwnIHx8IG9wID09PSAnb3B0aW9uYWxDYWxsJykgeyB2YWx1ZSA9IGZuKCguLi5hcmdzKSA9PiB2YWx1ZS5jYWxsKGxhc3RBY2Nlc3NMSFMsIC4uLmFyZ3MpKTsgbGFzdEFjY2Vzc0xIUyA9IHVuZGVmaW5lZDsgfSB9IHJldHVybiB2YWx1ZTsgfQoKZnVuY3Rpb24gZGVidWcoLi4uYXJncykgewogIGxvZ2dlci5sb2coJ1todHRwcy1wcm94eS1hZ2VudF0nLCAuLi5hcmdzKTsKfQoKLyoqCiAqIFRoZSBgSHR0cHNQcm94eUFnZW50YCBpbXBsZW1lbnRzIGFuIEhUVFAgQWdlbnQgc3ViY2xhc3MgdGhhdCBjb25uZWN0cyB0bwogKiB0aGUgc3BlY2lmaWVkICJIVFRQKHMpIHByb3h5IHNlcnZlciIgaW4gb3JkZXIgdG8gcHJveHkgSFRUUFMgcmVxdWVzdHMuCiAqCiAqIE91dGdvaW5nIEhUVFAgcmVxdWVzdHMgYXJlIGZpcnN0IHR1bm5lbGVkIHRocm91Z2ggdGhlIHByb3h5IHNlcnZlciB1c2luZyB0aGUKICogYENPTk5FQ1RgIEhUVFAgcmVxdWVzdCBtZXRob2QgdG8gZXN0YWJsaXNoIGEgY29ubmVjdGlvbiB0byB0aGUgcHJveHkgc2VydmVyLAogKiBhbmQgdGhlbiB0aGUgcHJveHkgc2VydmVyIGNvbm5lY3RzIHRvIHRoZSBkZXN0aW5hdGlvbiB0YXJnZXQgYW5kIGlzc3VlcyB0aGUKICogSFRUUCByZXF1ZXN0IGZyb20gdGhlIHByb3h5IHNlcnZlci4KICoKICogYGh0dHBzOmAgcmVxdWVzdHMgaGF2ZSB0aGVpciBzb2NrZXQgY29ubmVjdGlvbiB1cGdyYWRlZCB0byBUTFMgb25jZQogKiB0aGUgY29ubmVjdGlvbiB0byB0aGUgcHJveHkgc2VydmVyIGhhcyBiZWVuIGVzdGFibGlzaGVkLgogKi8KY2xhc3MgSHR0cHNQcm94eUFnZW50IGV4dGVuZHMgQWdlbnQgewogIHN0YXRpYyBfX2luaXRTdGF0aWMoKSB7dGhpcy5wcm90b2NvbHMgPSBbJ2h0dHAnLCAnaHR0cHMnXTsgfQoKICBjb25zdHJ1Y3Rvcihwcm94eSwgb3B0cykgewogICAgc3VwZXIob3B0cyk7CiAgICB0aGlzLm9wdGlvbnMgPSB7fTsKICAgIHRoaXMucHJveHkgPSB0eXBlb2YgcHJveHkgPT09ICdzdHJpbmcnID8gbmV3IFVSTChwcm94eSkgOiBwcm94eTsKICAgIHRoaXMucHJveHlIZWFkZXJzID0gX251bGxpc2hDb2FsZXNjZSQxKF9vcHRpb25hbENoYWluJDEoW29wdHMsICdvcHRpb25hbEFjY2VzcycsIF8yID0+IF8yLmhlYWRlcnNdKSwgKCkgPT4gKCB7fSkpOwogICAgZGVidWcoJ0NyZWF0aW5nIG5ldyBIdHRwc1Byb3h5QWdlbnQgaW5zdGFuY2U6ICVvJywgdGhpcy5wcm94eS5ocmVmKTsKCiAgICAvLyBUcmltIG9mZiB0aGUgYnJhY2tldHMgZnJvbSBJUHY2IGFkZHJlc3NlcwogICAgY29uc3QgaG9zdCA9ICh0aGlzLnByb3h5Lmhvc3RuYW1lIHx8IHRoaXMucHJveHkuaG9zdCkucmVwbGFjZSgvXlxbfFxdJC9nLCAnJyk7CiAgICBjb25zdCBwb3J0ID0gdGhpcy5wcm94eS5wb3J0ID8gcGFyc2VJbnQodGhpcy5wcm94eS5wb3J0LCAxMCkgOiB0aGlzLnByb3h5LnByb3RvY29sID09PSAnaHR0cHM6JyA/IDQ0MyA6IDgwOwogICAgdGhpcy5jb25uZWN0T3B0cyA9IHsKICAgICAgLy8gQXR0ZW1wdCB0byBuZWdvdGlhdGUgaHR0cC8xLjEgZm9yIHByb3h5IHNlcnZlcnMgdGhhdCBzdXBwb3J0IGh0dHAvMgogICAgICBBTFBOUHJvdG9jb2xzOiBbJ2h0dHAvMS4xJ10sCiAgICAgIC4uLihvcHRzID8gb21pdChvcHRzLCAnaGVhZGVycycpIDogbnVsbCksCiAgICAgIGhvc3QsCiAgICAgIHBvcnQsCiAgICB9OwogIH0KCiAgLyoqCiAgICogQ2FsbGVkIHdoZW4gdGhlIG5vZGUtY29yZSBIVFRQIGNsaWVudCBsaWJyYXJ5IGlzIGNyZWF0aW5nIGEKICAgKiBuZXcgSFRUUCByZXF1ZXN0LgogICAqLwogIGFzeW5jIGNvbm5lY3QocmVxLCBvcHRzKSB7CiAgICBjb25zdCB7IHByb3h5IH0gPSB0aGlzOwoKICAgIGlmICghb3B0cy5ob3N0KSB7CiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ05vICJob3N0IiBwcm92aWRlZCcpOwogICAgfQoKICAgIC8vIENyZWF0ZSBhIHNvY2tldCBjb25uZWN0aW9uIHRvIHRoZSBwcm94eSBzZXJ2ZXIuCiAgICBsZXQgc29ja2V0OwogICAgaWYgKHByb3h5LnByb3RvY29sID09PSAnaHR0cHM6JykgewogICAgICBkZWJ1ZygnQ3JlYXRpbmcgYHRscy5Tb2NrZXRgOiAlbycsIHRoaXMuY29ubmVjdE9wdHMpOwogICAgICBjb25zdCBzZXJ2ZXJuYW1lID0gdGhpcy5jb25uZWN0T3B0cy5zZXJ2ZXJuYW1lIHx8IHRoaXMuY29ubmVjdE9wdHMuaG9zdDsKICAgICAgc29ja2V0ID0gdGxzLmNvbm5lY3QoewogICAgICAgIC4uLnRoaXMuY29ubmVjdE9wdHMsCiAgICAgICAgc2VydmVybmFtZTogc2VydmVybmFtZSAmJiBuZXQuaXNJUChzZXJ2ZXJuYW1lKSA/IHVuZGVmaW5lZCA6IHNlcnZlcm5hbWUsCiAgICAgIH0pOwogICAgfSBlbHNlIHsKICAgICAgZGVidWcoJ0NyZWF0aW5nIGBuZXQuU29ja2V0YDogJW8nLCB0aGlzLmNvbm5lY3RPcHRzKTsKICAgICAgc29ja2V0ID0gbmV0LmNvbm5lY3QodGhpcy5jb25uZWN0T3B0cyk7CiAgICB9CgogICAgY29uc3QgaGVhZGVycyA9CiAgICAgIHR5cGVvZiB0aGlzLnByb3h5SGVhZGVycyA9PT0gJ2Z1bmN0aW9uJyA/IHRoaXMucHJveHlIZWFkZXJzKCkgOiB7IC4uLnRoaXMucHJveHlIZWFkZXJzIH07CiAgICBjb25zdCBob3N0ID0gbmV0LmlzSVB2NihvcHRzLmhvc3QpID8gYFske29wdHMuaG9zdH1dYCA6IG9wdHMuaG9zdDsKICAgIGxldCBwYXlsb2FkID0gYENPTk5FQ1QgJHtob3N0fToke29wdHMucG9ydH0gSFRUUC8xLjFcclxuYDsKCiAgICAvLyBJbmplY3QgdGhlIGBQcm94eS1BdXRob3JpemF0aW9uYCBoZWFkZXIgaWYgbmVjZXNzYXJ5LgogICAgaWYgKHByb3h5LnVzZXJuYW1lIHx8IHByb3h5LnBhc3N3b3JkKSB7CiAgICAgIGNvbnN0IGF1dGggPSBgJHtkZWNvZGVVUklDb21wb25lbnQocHJveHkudXNlcm5hbWUpfToke2RlY29kZVVSSUNvbXBvbmVudChwcm94eS5wYXNzd29yZCl9YDsKICAgICAgaGVhZGVyc1snUHJveHktQXV0aG9yaXphdGlvbiddID0gYEJhc2ljICR7QnVmZmVyLmZyb20oYXV0aCkudG9TdHJpbmcoJ2Jhc2U2NCcpfWA7CiAgICB9CgogICAgaGVhZGVycy5Ib3N0ID0gYCR7aG9zdH06JHtvcHRzLnBvcnR9YDsKCiAgICBpZiAoIWhlYWRlcnNbJ1Byb3h5LUNvbm5lY3Rpb24nXSkgewogICAgICBoZWFkZXJzWydQcm94eS1Db25uZWN0aW9uJ10gPSB0aGlzLmtlZXBBbGl2ZSA/ICdLZWVwLUFsaXZlJyA6ICdjbG9zZSc7CiAgICB9CiAgICBmb3IgKGNvbnN0IG5hbWUgb2YgT2JqZWN0LmtleXMoaGVhZGVycykpIHsKICAgICAgcGF5bG9hZCArPSBgJHtuYW1lfTogJHtoZWFkZXJzW25hbWVdfVxyXG5gOwogICAgfQoKICAgIGNvbnN0IHByb3h5UmVzcG9uc2VQcm9taXNlID0gcGFyc2VQcm94eVJlc3BvbnNlKHNvY2tldCk7CgogICAgc29ja2V0LndyaXRlKGAke3BheWxvYWR9XHJcbmApOwoKICAgIGNvbnN0IHsgY29ubmVjdCwgYnVmZmVyZWQgfSA9IGF3YWl0IHByb3h5UmVzcG9uc2VQcm9taXNlOwogICAgcmVxLmVtaXQoJ3Byb3h5Q29ubmVjdCcsIGNvbm5lY3QpOwogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9iYW4tdHMtY29tbWVudAogICAgLy8gQHRzLWlnbm9yZSBOb3QgRXZlbnRFbWl0dGVyIGluIE5vZGUgdHlwZXMKICAgIHRoaXMuZW1pdCgncHJveHlDb25uZWN0JywgY29ubmVjdCwgcmVxKTsKCiAgICBpZiAoY29ubmVjdC5zdGF0dXNDb2RlID09PSAyMDApIHsKICAgICAgcmVxLm9uY2UoJ3NvY2tldCcsIHJlc3VtZSk7CgogICAgICBpZiAob3B0cy5zZWN1cmVFbmRwb2ludCkgewogICAgICAgIC8vIFRoZSBwcm94eSBpcyBjb25uZWN0aW5nIHRvIGEgVExTIHNlcnZlciwgc28gdXBncmFkZQogICAgICAgIC8vIHRoaXMgc29ja2V0IGNvbm5lY3Rpb24gdG8gYSBUTFMgY29ubmVjdGlvbi4KICAgICAgICBkZWJ1ZygnVXBncmFkaW5nIHNvY2tldCBjb25uZWN0aW9uIHRvIFRMUycpOwogICAgICAgIGNvbnN0IHNlcnZlcm5hbWUgPSBvcHRzLnNlcnZlcm5hbWUgfHwgb3B0cy5ob3N0OwogICAgICAgIHJldHVybiB0bHMuY29ubmVjdCh7CiAgICAgICAgICAuLi5vbWl0KG9wdHMsICdob3N0JywgJ3BhdGgnLCAncG9ydCcpLAogICAgICAgICAgc29ja2V0LAogICAgICAgICAgc2VydmVybmFtZTogbmV0LmlzSVAoc2VydmVybmFtZSkgPyB1bmRlZmluZWQgOiBzZXJ2ZXJuYW1lLAogICAgICAgIH0pOwogICAgICB9CgogICAgICByZXR1cm4gc29ja2V0OwogICAgfQoKICAgIC8vIFNvbWUgb3RoZXIgc3RhdHVzIGNvZGUgdGhhdCdzIG5vdCAyMDAuLi4gbmVlZCB0byByZS1wbGF5IHRoZSBIVFRQCiAgICAvLyBoZWFkZXIgImRhdGEiIGV2ZW50cyBvbnRvIHRoZSBzb2NrZXQgb25jZSB0aGUgSFRUUCBtYWNoaW5lcnkgaXMKICAgIC8vIGF0dGFjaGVkIHNvIHRoYXQgdGhlIG5vZGUgY29yZSBgaHR0cGAgY2FuIHBhcnNlIGFuZCBoYW5kbGUgdGhlCiAgICAvLyBlcnJvciBzdGF0dXMgY29kZS4KCiAgICAvLyBDbG9zZSB0aGUgb3JpZ2luYWwgc29ja2V0LCBhbmQgYSBuZXcgImZha2UiIHNvY2tldCBpcyByZXR1cm5lZAogICAgLy8gaW5zdGVhZCwgc28gdGhhdCB0aGUgcHJveHkgZG9lc24ndCBnZXQgdGhlIEhUVFAgcmVxdWVzdAogICAgLy8gd3JpdHRlbiB0byBpdCAod2hpY2ggbWF5IGNvbnRhaW4gYEF1dGhvcml6YXRpb25gIGhlYWRlcnMgb3Igb3RoZXIKICAgIC8vIHNlbnNpdGl2ZSBkYXRhKS4KICAgIC8vCiAgICAvLyBTZWU6IGh0dHBzOi8vaGFja2Vyb25lLmNvbS9yZXBvcnRzLzU0MTUwMgogICAgc29ja2V0LmRlc3Ryb3koKTsKCiAgICBjb25zdCBmYWtlU29ja2V0ID0gbmV3IG5ldC5Tb2NrZXQoeyB3cml0YWJsZTogZmFsc2UgfSk7CiAgICBmYWtlU29ja2V0LnJlYWRhYmxlID0gdHJ1ZTsKCiAgICAvLyBOZWVkIHRvIHdhaXQgZm9yIHRoZSAic29ja2V0IiBldmVudCB0byByZS1wbGF5IHRoZSAiZGF0YSIgZXZlbnRzLgogICAgcmVxLm9uY2UoJ3NvY2tldCcsIChzKSA9PiB7CiAgICAgIGRlYnVnKCdSZXBsYXlpbmcgcHJveHkgYnVmZmVyIGZvciBmYWlsZWQgcmVxdWVzdCcpOwogICAgICAvLyBSZXBsYXkgdGhlICJidWZmZXJlZCIgQnVmZmVyIG9udG8gdGhlIGZha2UgYHNvY2tldGAsIHNpbmNlIGF0CiAgICAgIC8vIHRoaXMgcG9pbnQgdGhlIEhUVFAgbW9kdWxlIG1hY2hpbmVyeSBoYXMgYmVlbiBob29rZWQgdXAgZm9yCiAgICAgIC8vIHRoZSB1c2VyLgogICAgICBzLnB1c2goYnVmZmVyZWQpOwogICAgICBzLnB1c2gobnVsbCk7CiAgICB9KTsKCiAgICByZXR1cm4gZmFrZVNvY2tldDsKICB9Cn0gSHR0cHNQcm94eUFnZW50Ll9faW5pdFN0YXRpYygpOwoKZnVuY3Rpb24gcmVzdW1lKHNvY2tldCkgewogIHNvY2tldC5yZXN1bWUoKTsKfQoKZnVuY3Rpb24gb21pdCgKICBvYmosCiAgLi4ua2V5cwopCgogewogIGNvbnN0IHJldCA9IHt9Cgo7CiAgbGV0IGtleTsKICBmb3IgKGtleSBpbiBvYmopIHsKICAgIGlmICgha2V5cy5pbmNsdWRlcyhrZXkpKSB7CiAgICAgIHJldFtrZXldID0gb2JqW2tleV07CiAgICB9CiAgfQogIHJldHVybiByZXQ7Cn0KCmZ1bmN0aW9uIF9udWxsaXNoQ29hbGVzY2UobGhzLCByaHNGbikgeyBpZiAobGhzICE9IG51bGwpIHsgcmV0dXJuIGxoczsgfSBlbHNlIHsgcmV0dXJuIHJoc0ZuKCk7IH0gfQovLyBFc3RpbWF0ZWQgbWF4aW11bSBzaXplIGZvciByZWFzb25hYmxlIHN0YW5kYWxvbmUgZXZlbnQKY29uc3QgR1pJUF9USFJFU0hPTEQgPSAxMDI0ICogMzI7CgovKioKICogR2V0cyBhIHN0cmVhbSBmcm9tIGEgVWludDhBcnJheSBvciBzdHJpbmcKICogUmVhZGFibGUuZnJvbSBpcyBpZGVhbCBidXQgd2FzIGFkZGVkIGluIG5vZGUuanMgdjEyLjMuMCBhbmQgdjEwLjE3LjAKICovCmZ1bmN0aW9uIHN0cmVhbUZyb21Cb2R5KGJvZHkpIHsKICByZXR1cm4gbmV3IFJlYWRhYmxlKHsKICAgIHJlYWQoKSB7CiAgICAgIHRoaXMucHVzaChib2R5KTsKICAgICAgdGhpcy5wdXNoKG51bGwpOwogICAgfSwKICB9KTsKfQoKLyoqCiAqIENyZWF0ZXMgYSBUcmFuc3BvcnQgdGhhdCB1c2VzIG5hdGl2ZSB0aGUgbmF0aXZlICdodHRwJyBhbmQgJ2h0dHBzJyBtb2R1bGVzIHRvIHNlbmQgZXZlbnRzIHRvIFNlbnRyeS4KICovCmZ1bmN0aW9uIG1ha2VOb2RlVHJhbnNwb3J0KG9wdGlvbnMpIHsKICBsZXQgdXJsU2VnbWVudHM7CgogIHRyeSB7CiAgICB1cmxTZWdtZW50cyA9IG5ldyBVUkwob3B0aW9ucy51cmwpOwogIH0gY2F0Y2ggKGUpIHsKICAgIGNvbnNvbGVTYW5kYm94KCgpID0+IHsKICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGUKICAgICAgY29uc29sZS53YXJuKAogICAgICAgICdbQHNlbnRyeS9ub2RlXTogSW52YWxpZCBkc24gb3IgdHVubmVsIG9wdGlvbiwgd2lsbCBub3Qgc2VuZCBhbnkgZXZlbnRzLiBUaGUgdHVubmVsIG9wdGlvbiBtdXN0IGJlIGEgZnVsbCBVUkwgd2hlbiB1c2VkLicsCiAgICAgICk7CiAgICB9KTsKICAgIHJldHVybiBjcmVhdGVUcmFuc3BvcnQob3B0aW9ucywgKCkgPT4gUHJvbWlzZS5yZXNvbHZlKHt9KSk7CiAgfQoKICBjb25zdCBpc0h0dHBzID0gdXJsU2VnbWVudHMucHJvdG9jb2wgPT09ICdodHRwczonOwoKICAvLyBQcm94eSBwcmlvcml0aXphdGlvbjogaHR0cCA9PiBgb3B0aW9ucy5wcm94eWAgfCBgcHJvY2Vzcy5lbnYuaHR0cF9wcm94eWAKICAvLyBQcm94eSBwcmlvcml0aXphdGlvbjogaHR0cHMgPT4gYG9wdGlvbnMucHJveHlgIHwgYHByb2Nlc3MuZW52Lmh0dHBzX3Byb3h5YCB8IGBwcm9jZXNzLmVudi5odHRwX3Byb3h5YAogIGNvbnN0IHByb3h5ID0gYXBwbHlOb1Byb3h5T3B0aW9uKAogICAgdXJsU2VnbWVudHMsCiAgICBvcHRpb25zLnByb3h5IHx8IChpc0h0dHBzID8gcHJvY2Vzcy5lbnYuaHR0cHNfcHJveHkgOiB1bmRlZmluZWQpIHx8IHByb2Nlc3MuZW52Lmh0dHBfcHJveHksCiAgKTsKCiAgY29uc3QgbmF0aXZlSHR0cE1vZHVsZSA9IGlzSHR0cHMgPyBodHRwcyA6IGh0dHA7CiAgY29uc3Qga2VlcEFsaXZlID0gb3B0aW9ucy5rZWVwQWxpdmUgPT09IHVuZGVmaW5lZCA/IGZhbHNlIDogb3B0aW9ucy5rZWVwQWxpdmU7CgogIC8vIFRPRE8odjcpOiBFdmFsdWF0ZSBpZiB3ZSBjYW4gc2V0IGtlZXBBbGl2ZSB0byB0cnVlLiBUaGlzIHdvdWxkIGludm9sdmUgdGVzdGluZyBmb3IgbWVtb3J5IGxlYWtzIGluIG9sZGVyIG5vZGUKICAvLyB2ZXJzaW9ucyg+PSA4KSBhcyB0aGV5IGhhZCBtZW1vcnkgbGVha3Mgd2hlbiB1c2luZyBpdDogIzI1NTUKICBjb25zdCBhZ2VudCA9IHByb3h5CiAgICA/IChuZXcgSHR0cHNQcm94eUFnZW50KHByb3h5KSApCiAgICA6IG5ldyBuYXRpdmVIdHRwTW9kdWxlLkFnZW50KHsga2VlcEFsaXZlLCBtYXhTb2NrZXRzOiAzMCwgdGltZW91dDogMjAwMCB9KTsKCiAgY29uc3QgcmVxdWVzdEV4ZWN1dG9yID0gY3JlYXRlUmVxdWVzdEV4ZWN1dG9yKG9wdGlvbnMsIF9udWxsaXNoQ29hbGVzY2Uob3B0aW9ucy5odHRwTW9kdWxlLCAoKSA9PiAoIG5hdGl2ZUh0dHBNb2R1bGUpKSwgYWdlbnQpOwogIHJldHVybiBjcmVhdGVUcmFuc3BvcnQob3B0aW9ucywgcmVxdWVzdEV4ZWN1dG9yKTsKfQoKLyoqCiAqIEhvbm9ycyB0aGUgYG5vX3Byb3h5YCBlbnYgdmFyaWFibGUgd2l0aCB0aGUgaGlnaGVzdCBwcmlvcml0eSB0byBhbGxvdyBmb3IgaG9zdHMgZXhjbHVzaW9uLgogKgogKiBAcGFyYW0gdHJhbnNwb3J0VXJsIFRoZSBVUkwgdGhlIHRyYW5zcG9ydCBpbnRlbmRzIHRvIHNlbmQgZXZlbnRzIHRvLgogKiBAcGFyYW0gcHJveHkgVGhlIGNsaWVudCBjb25maWd1cmVkIHByb3h5LgogKiBAcmV0dXJucyBBIHByb3h5IHRoZSB0cmFuc3BvcnQgc2hvdWxkIHVzZS4KICovCmZ1bmN0aW9uIGFwcGx5Tm9Qcm94eU9wdGlvbih0cmFuc3BvcnRVcmxTZWdtZW50cywgcHJveHkpIHsKICBjb25zdCB7IG5vX3Byb3h5IH0gPSBwcm9jZXNzLmVudjsKCiAgY29uc3QgdXJsSXNFeGVtcHRGcm9tUHJveHkgPQogICAgbm9fcHJveHkgJiYKICAgIG5vX3Byb3h5CiAgICAgIC5zcGxpdCgnLCcpCiAgICAgIC5zb21lKAogICAgICAgIGV4ZW1wdGlvbiA9PiB0cmFuc3BvcnRVcmxTZWdtZW50cy5ob3N0LmVuZHNXaXRoKGV4ZW1wdGlvbikgfHwgdHJhbnNwb3J0VXJsU2VnbWVudHMuaG9zdG5hbWUuZW5kc1dpdGgoZXhlbXB0aW9uKSwKICAgICAgKTsKCiAgaWYgKHVybElzRXhlbXB0RnJvbVByb3h5KSB7CiAgICByZXR1cm4gdW5kZWZpbmVkOwogIH0gZWxzZSB7CiAgICByZXR1cm4gcHJveHk7CiAgfQp9CgovKioKICogQ3JlYXRlcyBhIFJlcXVlc3RFeGVjdXRvciB0byBiZSB1c2VkIHdpdGggYGNyZWF0ZVRyYW5zcG9ydGAuCiAqLwpmdW5jdGlvbiBjcmVhdGVSZXF1ZXN0RXhlY3V0b3IoCiAgb3B0aW9ucywKICBodHRwTW9kdWxlLAogIGFnZW50LAopIHsKICBjb25zdCB7IGhvc3RuYW1lLCBwYXRobmFtZSwgcG9ydCwgcHJvdG9jb2wsIHNlYXJjaCB9ID0gbmV3IFVSTChvcHRpb25zLnVybCk7CiAgcmV0dXJuIGZ1bmN0aW9uIG1ha2VSZXF1ZXN0KHJlcXVlc3QpIHsKICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7CiAgICAgIGxldCBib2R5ID0gc3RyZWFtRnJvbUJvZHkocmVxdWVzdC5ib2R5KTsKCiAgICAgIGNvbnN0IGhlYWRlcnMgPSB7IC4uLm9wdGlvbnMuaGVhZGVycyB9OwoKICAgICAgaWYgKHJlcXVlc3QuYm9keS5sZW5ndGggPiBHWklQX1RIUkVTSE9MRCkgewogICAgICAgIGhlYWRlcnNbJ2NvbnRlbnQtZW5jb2RpbmcnXSA9ICdnemlwJzsKICAgICAgICBib2R5ID0gYm9keS5waXBlKGNyZWF0ZUd6aXAoKSk7CiAgICAgIH0KCiAgICAgIGNvbnN0IHJlcSA9IGh0dHBNb2R1bGUucmVxdWVzdCgKICAgICAgICB7CiAgICAgICAgICBtZXRob2Q6ICdQT1NUJywKICAgICAgICAgIGFnZW50LAogICAgICAgICAgaGVhZGVycywKICAgICAgICAgIGhvc3RuYW1lLAogICAgICAgICAgcGF0aDogYCR7cGF0aG5hbWV9JHtzZWFyY2h9YCwKICAgICAgICAgIHBvcnQsCiAgICAgICAgICBwcm90b2NvbCwKICAgICAgICAgIGNhOiBvcHRpb25zLmNhQ2VydHMsCiAgICAgICAgfSwKICAgICAgICByZXMgPT4gewogICAgICAgICAgcmVzLm9uKCdkYXRhJywgKCkgPT4gewogICAgICAgICAgICAvLyBEcmFpbiBzb2NrZXQKICAgICAgICAgIH0pOwoKICAgICAgICAgIHJlcy5vbignZW5kJywgKCkgPT4gewogICAgICAgICAgICAvLyBEcmFpbiBzb2NrZXQKICAgICAgICAgIH0pOwoKICAgICAgICAgIHJlcy5zZXRFbmNvZGluZygndXRmOCcpOwoKICAgICAgICAgIC8vICJLZXktdmFsdWUgcGFpcnMgb2YgaGVhZGVyIG5hbWVzIGFuZCB2YWx1ZXMuIEhlYWRlciBuYW1lcyBhcmUgbG93ZXItY2FzZWQuIgogICAgICAgICAgLy8gaHR0cHM6Ly9ub2RlanMub3JnL2FwaS9odHRwLmh0bWwjaHR0cF9tZXNzYWdlX2hlYWRlcnMKICAgICAgICAgIGNvbnN0IHJldHJ5QWZ0ZXJIZWFkZXIgPSBfbnVsbGlzaENvYWxlc2NlKHJlcy5oZWFkZXJzWydyZXRyeS1hZnRlciddLCAoKSA9PiAoIG51bGwpKTsKICAgICAgICAgIGNvbnN0IHJhdGVMaW1pdHNIZWFkZXIgPSBfbnVsbGlzaENvYWxlc2NlKHJlcy5oZWFkZXJzWyd4LXNlbnRyeS1yYXRlLWxpbWl0cyddLCAoKSA9PiAoIG51bGwpKTsKCiAgICAgICAgICByZXNvbHZlKHsKICAgICAgICAgICAgc3RhdHVzQ29kZTogcmVzLnN0YXR1c0NvZGUsCiAgICAgICAgICAgIGhlYWRlcnM6IHsKICAgICAgICAgICAgICAncmV0cnktYWZ0ZXInOiByZXRyeUFmdGVySGVhZGVyLAogICAgICAgICAgICAgICd4LXNlbnRyeS1yYXRlLWxpbWl0cyc6IEFycmF5LmlzQXJyYXkocmF0ZUxpbWl0c0hlYWRlcikgPyByYXRlTGltaXRzSGVhZGVyWzBdIDogcmF0ZUxpbWl0c0hlYWRlciwKICAgICAgICAgICAgfSwKICAgICAgICAgIH0pOwogICAgICAgIH0sCiAgICAgICk7CgogICAgICByZXEub24oJ2Vycm9yJywgcmVqZWN0KTsKICAgICAgYm9keS5waXBlKHJlcSk7CiAgICB9KTsKICB9Owp9CgpmdW5jdGlvbiBfb3B0aW9uYWxDaGFpbihvcHMpIHsgbGV0IGxhc3RBY2Nlc3NMSFMgPSB1bmRlZmluZWQ7IGxldCB2YWx1ZSA9IG9wc1swXTsgbGV0IGkgPSAxOyB3aGlsZSAoaSA8IG9wcy5sZW5ndGgpIHsgY29uc3Qgb3AgPSBvcHNbaV07IGNvbnN0IGZuID0gb3BzW2kgKyAxXTsgaSArPSAyOyBpZiAoKG9wID09PSAnb3B0aW9uYWxBY2Nlc3MnIHx8IG9wID09PSAnb3B0aW9uYWxDYWxsJykgJiYgdmFsdWUgPT0gbnVsbCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IGlmIChvcCA9PT0gJ2FjY2VzcycgfHwgb3AgPT09ICdvcHRpb25hbEFjY2VzcycpIHsgbGFzdEFjY2Vzc0xIUyA9IHZhbHVlOyB2YWx1ZSA9IGZuKHZhbHVlKTsgfSBlbHNlIGlmIChvcCA9PT0gJ2NhbGwnIHx8IG9wID09PSAnb3B0aW9uYWxDYWxsJykgeyB2YWx1ZSA9IGZuKCguLi5hcmdzKSA9PiB2YWx1ZS5jYWxsKGxhc3RBY2Nlc3NMSFMsIC4uLmFyZ3MpKTsgbGFzdEFjY2Vzc0xIUyA9IHVuZGVmaW5lZDsgfSB9IHJldHVybiB2YWx1ZTsgfQpjb25zdCBvcHRpb25zID0gd29ya2VyRGF0YTsKbGV0IHNlc3Npb247CmxldCBoYXNTZW50QW5yRXZlbnQgPSBmYWxzZTsKCmZ1bmN0aW9uIGxvZyhtc2cpIHsKICBpZiAob3B0aW9ucy5kZWJ1ZykgewogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGUKICAgIGNvbnNvbGUubG9nKGBbQU5SIFdvcmtlcl0gJHttc2d9YCk7CiAgfQp9Cgpjb25zdCB1cmwgPSBnZXRFbnZlbG9wZUVuZHBvaW50V2l0aFVybEVuY29kZWRBdXRoKG9wdGlvbnMuZHNuKTsKY29uc3QgdHJhbnNwb3J0ID0gbWFrZU5vZGVUcmFuc3BvcnQoewogIHVybCwKICByZWNvcmREcm9wcGVkRXZlbnQ6ICgpID0+IHsKICAgIC8vCiAgfSwKfSk7Cgphc3luYyBmdW5jdGlvbiBzZW5kQWJub3JtYWxTZXNzaW9uKCkgewogIC8vIG9mIHdlIGhhdmUgYW4gZXhpc3Rpbmcgc2Vzc2lvbiBwYXNzZWQgZnJvbSB0aGUgbWFpbiB0aHJlYWQsIHNlbmQgaXQgYXMgYWJub3JtYWwKICBpZiAoc2Vzc2lvbikgewogICAgbG9nKCdTZW5kaW5nIGFibm9ybWFsIHNlc3Npb24nKTsKICAgIHVwZGF0ZVNlc3Npb24oc2Vzc2lvbiwgeyBzdGF0dXM6ICdhYm5vcm1hbCcsIGFibm9ybWFsX21lY2hhbmlzbTogJ2Fucl9mb3JlZ3JvdW5kJyB9KTsKCiAgICBjb25zdCBlbnZlbG9wZSA9IGNyZWF0ZVNlc3Npb25FbnZlbG9wZShzZXNzaW9uLCBvcHRpb25zLmRzbiwgb3B0aW9ucy5zZGtNZXRhZGF0YSk7CiAgICAvLyBMb2cgdGhlIGVudmVsb3BlIHNvIHRvIGFpZCBpbiB0ZXN0aW5nCiAgICBsb2coSlNPTi5zdHJpbmdpZnkoZW52ZWxvcGUpKTsKCiAgICBhd2FpdCB0cmFuc3BvcnQuc2VuZChlbnZlbG9wZSk7CgogICAgdHJ5IHsKICAgICAgLy8gTm90aWZ5IHRoZSBtYWluIHByb2Nlc3MgdGhhdCB0aGUgc2Vzc2lvbiBoYXMgZW5kZWQgc28gdGhlIHNlc3Npb24gY2FuIGJlIGNsZWFyZWQgZnJvbSB0aGUgc2NvcGUKICAgICAgX29wdGlvbmFsQ2hhaW4oW3BhcmVudFBvcnQsICdvcHRpb25hbEFjY2VzcycsIF8yID0+IF8yLnBvc3RNZXNzYWdlLCAnY2FsbCcsIF8zID0+IF8zKCdzZXNzaW9uLWVuZGVkJyldKTsKICAgIH0gY2F0Y2ggKF8pIHsKICAgICAgLy8gaWdub3JlCiAgICB9CiAgfQp9Cgpsb2coJ1N0YXJ0ZWQnKTsKCmZ1bmN0aW9uIHByZXBhcmVTdGFja0ZyYW1lcyhzdGFja0ZyYW1lcykgewogIGlmICghc3RhY2tGcmFtZXMpIHsKICAgIHJldHVybiB1bmRlZmluZWQ7CiAgfQoKICAvLyBTdHJpcCBTZW50cnkgZnJhbWVzIGFuZCByZXZlcnNlIHRoZSBzdGFjayBmcmFtZXMgc28gdGhleSBhcmUgaW4gdGhlIGNvcnJlY3Qgb3JkZXIKICBjb25zdCBzdHJpcHBlZEZyYW1lcyA9IHN0cmlwU2VudHJ5RnJhbWVzQW5kUmV2ZXJzZShzdGFja0ZyYW1lcyk7CgogIC8vIElmIHdlIGhhdmUgYW4gYXBwIHJvb3QgcGF0aCwgcmV3cml0ZSB0aGUgZmlsZW5hbWVzIHRvIGJlIHJlbGF0aXZlIHRvIHRoZSBhcHAgcm9vdAogIGlmIChvcHRpb25zLmFwcFJvb3RQYXRoKSB7CiAgICBmb3IgKGNvbnN0IGZyYW1lIG9mIHN0cmlwcGVkRnJhbWVzKSB7CiAgICAgIGlmICghZnJhbWUuZmlsZW5hbWUpIHsKICAgICAgICBjb250aW51ZTsKICAgICAgfQoKICAgICAgZnJhbWUuZmlsZW5hbWUgPSBub3JtYWxpemVVcmxUb0Jhc2UoZnJhbWUuZmlsZW5hbWUsIG9wdGlvbnMuYXBwUm9vdFBhdGgpOwogICAgfQogIH0KCiAgcmV0dXJuIHN0cmlwcGVkRnJhbWVzOwp9Cgphc3luYyBmdW5jdGlvbiBzZW5kQW5yRXZlbnQoZnJhbWVzLCB0cmFjZUNvbnRleHQpIHsKICBpZiAoaGFzU2VudEFuckV2ZW50KSB7CiAgICByZXR1cm47CiAgfQoKICBoYXNTZW50QW5yRXZlbnQgPSB0cnVlOwoKICBhd2FpdCBzZW5kQWJub3JtYWxTZXNzaW9uKCk7CgogIGxvZygnU2VuZGluZyBldmVudCcpOwoKICBjb25zdCBldmVudCA9IHsKICAgIGV2ZW50X2lkOiB1dWlkNCgpLAogICAgY29udGV4dHM6IHsgLi4ub3B0aW9ucy5jb250ZXh0cywgdHJhY2U6IHRyYWNlQ29udGV4dCB9LAogICAgcmVsZWFzZTogb3B0aW9ucy5yZWxlYXNlLAogICAgZW52aXJvbm1lbnQ6IG9wdGlvbnMuZW52aXJvbm1lbnQsCiAgICBkaXN0OiBvcHRpb25zLmRpc3QsCiAgICBwbGF0Zm9ybTogJ25vZGUnLAogICAgbGV2ZWw6ICdlcnJvcicsCiAgICBleGNlcHRpb246IHsKICAgICAgdmFsdWVzOiBbCiAgICAgICAgewogICAgICAgICAgdHlwZTogJ0FwcGxpY2F0aW9uTm90UmVzcG9uZGluZycsCiAgICAgICAgICB2YWx1ZTogYEFwcGxpY2F0aW9uIE5vdCBSZXNwb25kaW5nIGZvciBhdCBsZWFzdCAke29wdGlvbnMuYW5yVGhyZXNob2xkfSBtc2AsCiAgICAgICAgICBzdGFja3RyYWNlOiB7IGZyYW1lczogcHJlcGFyZVN0YWNrRnJhbWVzKGZyYW1lcykgfSwKICAgICAgICAgIC8vIFRoaXMgZW5zdXJlcyB0aGUgVUkgZG9lc24ndCBzYXkgJ0NyYXNoZWQgaW4nIGZvciB0aGUgc3RhY2sgdHJhY2UKICAgICAgICAgIG1lY2hhbmlzbTogeyB0eXBlOiAnQU5SJyB9LAogICAgICAgIH0sCiAgICAgIF0sCiAgICB9LAogICAgdGFnczogb3B0aW9ucy5zdGF0aWNUYWdzLAogIH07CgogIGNvbnN0IGVudmVsb3BlID0gY3JlYXRlRXZlbnRFbnZlbG9wZShldmVudCwgb3B0aW9ucy5kc24sIG9wdGlvbnMuc2RrTWV0YWRhdGEpOwogIC8vIExvZyB0aGUgZW52ZWxvcGUgc28gdG8gYWlkIGluIHRlc3RpbmcKICBsb2coSlNPTi5zdHJpbmdpZnkoZW52ZWxvcGUpKTsKCiAgYXdhaXQgdHJhbnNwb3J0LnNlbmQoZW52ZWxvcGUpOwogIGF3YWl0IHRyYW5zcG9ydC5mbHVzaCgyMDAwKTsKCiAgLy8gRGVsYXkgZm9yIDUgc2Vjb25kcyBzbyB0aGF0IHN0ZGlvIGNhbiBmbHVzaCBpbiB0aGUgbWFpbiBldmVudCBsb29wIGV2ZXIgcmVzdGFydHMuCiAgLy8gVGhpcyBpcyBtYWlubHkgZm9yIHRoZSBiZW5lZml0IG9mIGxvZ2dpbmcvZGVidWdnaW5nIGlzc3Vlcy4KICBzZXRUaW1lb3V0KCgpID0+IHsKICAgIHByb2Nlc3MuZXhpdCgwKTsKICB9LCA1MDAwKTsKfQoKbGV0IGRlYnVnZ2VyUGF1c2U7CgppZiAob3B0aW9ucy5jYXB0dXJlU3RhY2tUcmFjZSkgewogIGxvZygnQ29ubmVjdGluZyB0byBkZWJ1Z2dlcicpOwoKICBjb25zdCBzZXNzaW9uID0gbmV3IFNlc3Npb24oKSA7CiAgc2Vzc2lvbi5jb25uZWN0VG9NYWluVGhyZWFkKCk7CgogIGxvZygnQ29ubmVjdGVkIHRvIGRlYnVnZ2VyJyk7CgogIC8vIENvbGxlY3Qgc2NyaXB0SWQgLT4gdXJsIG1hcCBzbyB3ZSBjYW4gbG9vayB1cCB0aGUgZmlsZW5hbWVzIGxhdGVyCiAgY29uc3Qgc2NyaXB0cyA9IG5ldyBNYXAoKTsKCiAgc2Vzc2lvbi5vbignRGVidWdnZXIuc2NyaXB0UGFyc2VkJywgZXZlbnQgPT4gewogICAgc2NyaXB0cy5zZXQoZXZlbnQucGFyYW1zLnNjcmlwdElkLCBldmVudC5wYXJhbXMudXJsKTsKICB9KTsKCiAgc2Vzc2lvbi5vbignRGVidWdnZXIucGF1c2VkJywgZXZlbnQgPT4gewogICAgaWYgKGV2ZW50LnBhcmFtcy5yZWFzb24gIT09ICdvdGhlcicpIHsKICAgICAgcmV0dXJuOwogICAgfQoKICAgIHRyeSB7CiAgICAgIGxvZygnRGVidWdnZXIgcGF1c2VkJyk7CgogICAgICAvLyBjb3B5IHRoZSBmcmFtZXMKICAgICAgY29uc3QgY2FsbEZyYW1lcyA9IFsuLi5ldmVudC5wYXJhbXMuY2FsbEZyYW1lc107CgogICAgICBjb25zdCBnZXRNb2R1bGVOYW1lID0gb3B0aW9ucy5hcHBSb290UGF0aCA/IGNyZWF0ZUdldE1vZHVsZUZyb21GaWxlbmFtZShvcHRpb25zLmFwcFJvb3RQYXRoKSA6ICgpID0+IHVuZGVmaW5lZDsKICAgICAgY29uc3Qgc3RhY2tGcmFtZXMgPSBjYWxsRnJhbWVzLm1hcChmcmFtZSA9PgogICAgICAgIGNhbGxGcmFtZVRvU3RhY2tGcmFtZShmcmFtZSwgc2NyaXB0cy5nZXQoZnJhbWUubG9jYXRpb24uc2NyaXB0SWQpLCBnZXRNb2R1bGVOYW1lKSwKICAgICAgKTsKCiAgICAgIC8vIEV2YWx1YXRlIGEgc2NyaXB0IGluIHRoZSBjdXJyZW50bHkgcGF1c2VkIGNvbnRleHQKICAgICAgc2Vzc2lvbi5wb3N0KAogICAgICAgICdSdW50aW1lLmV2YWx1YXRlJywKICAgICAgICB7CiAgICAgICAgICAvLyBHcmFiIHRoZSB0cmFjZSBjb250ZXh0IGZyb20gdGhlIGN1cnJlbnQgc2NvcGUKICAgICAgICAgIGV4cHJlc3Npb246CiAgICAgICAgICAgICd2YXIgX19zZW50cnlfY3R4ID0gX19TRU5UUllfXy5odWIuZ2V0U2NvcGUoKS5nZXRQcm9wYWdhdGlvbkNvbnRleHQoKTsgX19zZW50cnlfY3R4LnRyYWNlSWQgKyAiLSIgKyBfX3NlbnRyeV9jdHguc3BhbklkICsgIi0iICsgX19zZW50cnlfY3R4LnBhcmVudFNwYW5JZCcsCiAgICAgICAgICAvLyBEb24ndCByZS10cmlnZ2VyIHRoZSBkZWJ1Z2dlciBpZiB0aGlzIGNhdXNlcyBhbiBlcnJvcgogICAgICAgICAgc2lsZW50OiB0cnVlLAogICAgICAgIH0sCiAgICAgICAgKF8sIHBhcmFtKSA9PiB7CiAgICAgICAgICBjb25zdCB0cmFjZUlkID0gcGFyYW0gJiYgcGFyYW0ucmVzdWx0ID8gKHBhcmFtLnJlc3VsdC52YWx1ZSApIDogJy0tJzsKICAgICAgICAgIGNvbnN0IFt0cmFjZV9pZCwgc3Bhbl9pZCwgcGFyZW50X3NwYW5faWRdID0gdHJhY2VJZC5zcGxpdCgnLScpIDsKCiAgICAgICAgICBzZXNzaW9uLnBvc3QoJ0RlYnVnZ2VyLnJlc3VtZScpOwogICAgICAgICAgc2Vzc2lvbi5wb3N0KCdEZWJ1Z2dlci5kaXNhYmxlJyk7CgogICAgICAgICAgY29uc3QgY29udGV4dCA9IF9vcHRpb25hbENoYWluKFt0cmFjZV9pZCwgJ29wdGlvbmFsQWNjZXNzJywgXzQgPT4gXzQubGVuZ3RoXSkgJiYgX29wdGlvbmFsQ2hhaW4oW3NwYW5faWQsICdvcHRpb25hbEFjY2VzcycsIF81ID0+IF81Lmxlbmd0aF0pID8geyB0cmFjZV9pZCwgc3Bhbl9pZCwgcGFyZW50X3NwYW5faWQgfSA6IHVuZGVmaW5lZDsKICAgICAgICAgIHNlbmRBbnJFdmVudChzdGFja0ZyYW1lcywgY29udGV4dCkudGhlbihudWxsLCAoKSA9PiB7CiAgICAgICAgICAgIGxvZygnU2VuZGluZyBBTlIgZXZlbnQgZmFpbGVkLicpOwogICAgICAgICAgfSk7CiAgICAgICAgfSwKICAgICAgKTsKICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgc2Vzc2lvbi5wb3N0KCdEZWJ1Z2dlci5yZXN1bWUnKTsKICAgICAgc2Vzc2lvbi5wb3N0KCdEZWJ1Z2dlci5kaXNhYmxlJyk7CiAgICAgIHRocm93IGU7CiAgICB9CiAgfSk7CgogIGRlYnVnZ2VyUGF1c2UgPSAoKSA9PiB7CiAgICB0cnkgewogICAgICBzZXNzaW9uLnBvc3QoJ0RlYnVnZ2VyLmVuYWJsZScsICgpID0+IHsKICAgICAgICBzZXNzaW9uLnBvc3QoJ0RlYnVnZ2VyLnBhdXNlJyk7CiAgICAgIH0pOwogICAgfSBjYXRjaCAoXykgewogICAgICAvLwogICAgfQogIH07Cn0KCmZ1bmN0aW9uIGNyZWF0ZUhyVGltZXIoKSB7CiAgLy8gVE9ETyAodjgpOiBXZSBjYW4gdXNlIHByb2Nlc3MuaHJ0aW1lLmJpZ2ludCgpIGFmdGVyIHdlIGRyb3Agbm9kZSB2OAogIGxldCBsYXN0UG9sbCA9IHByb2Nlc3MuaHJ0aW1lKCk7CgogIHJldHVybiB7CiAgICBnZXRUaW1lTXM6ICgpID0+IHsKICAgICAgY29uc3QgW3NlY29uZHMsIG5hbm9TZWNvbmRzXSA9IHByb2Nlc3MuaHJ0aW1lKGxhc3RQb2xsKTsKICAgICAgcmV0dXJuIE1hdGguZmxvb3Ioc2Vjb25kcyAqIDFlMyArIG5hbm9TZWNvbmRzIC8gMWU2KTsKICAgIH0sCiAgICByZXNldDogKCkgPT4gewogICAgICBsYXN0UG9sbCA9IHByb2Nlc3MuaHJ0aW1lKCk7CiAgICB9LAogIH07Cn0KCmZ1bmN0aW9uIHdhdGNoZG9nVGltZW91dCgpIHsKICBsb2coJ1dhdGNoZG9nIHRpbWVvdXQnKTsKCiAgaWYgKGRlYnVnZ2VyUGF1c2UpIHsKICAgIGxvZygnUGF1c2luZyBkZWJ1Z2dlciB0byBjYXB0dXJlIHN0YWNrIHRyYWNlJyk7CiAgICBkZWJ1Z2dlclBhdXNlKCk7CiAgfSBlbHNlIHsKICAgIGxvZygnQ2FwdHVyaW5nIGV2ZW50IHdpdGhvdXQgYSBzdGFjayB0cmFjZScpOwogICAgc2VuZEFuckV2ZW50KCkudGhlbihudWxsLCAoKSA9PiB7CiAgICAgIGxvZygnU2VuZGluZyBBTlIgZXZlbnQgZmFpbGVkIG9uIHdhdGNoZG9nIHRpbWVvdXQuJyk7CiAgICB9KTsKICB9Cn0KCmNvbnN0IHsgcG9sbCB9ID0gd2F0Y2hkb2dUaW1lcihjcmVhdGVIclRpbWVyLCBvcHRpb25zLnBvbGxJbnRlcnZhbCwgb3B0aW9ucy5hbnJUaHJlc2hvbGQsIHdhdGNoZG9nVGltZW91dCk7Cgpfb3B0aW9uYWxDaGFpbihbcGFyZW50UG9ydCwgJ29wdGlvbmFsQWNjZXNzJywgXzYgPT4gXzYub24sICdjYWxsJywgXzcgPT4gXzcoJ21lc3NhZ2UnLCAobXNnKSA9PiB7CiAgaWYgKG1zZy5zZXNzaW9uKSB7CiAgICBzZXNzaW9uID0gbWFrZVNlc3Npb24obXNnLnNlc3Npb24pOwogIH0KCiAgcG9sbCgpOwp9KV0pOw==";
|
|
@@ -105,7 +105,7 @@ class AsyncSession {
|
|
|
105
105
|
} else if (_optionalChain([prop, 'optionalAccess', _6 => _6.value, 'optionalAccess', _7 => _7.objectId]) && _optionalChain([prop, 'optionalAccess', _8 => _8.value, 'optionalAccess', _9 => _9.className]) === 'Object') {
|
|
106
106
|
const id = prop.value.objectId;
|
|
107
107
|
add(vars => this._unrollObject(id, prop.name, vars, next));
|
|
108
|
-
} else if (_optionalChain([prop, 'optionalAccess', _10 => _10.value, 'optionalAccess', _11 => _11.value]) || _optionalChain([prop, 'optionalAccess', _12 => _12.value, 'optionalAccess', _13 => _13.description])) {
|
|
108
|
+
} else if (_optionalChain([prop, 'optionalAccess', _10 => _10.value, 'optionalAccess', _11 => _11.value]) != null || _optionalChain([prop, 'optionalAccess', _12 => _12.value, 'optionalAccess', _13 => _13.description]) != null) {
|
|
109
109
|
add(vars => this._unrollOther(prop, vars, next));
|
|
110
110
|
}
|
|
111
111
|
}
|
|
@@ -168,9 +168,9 @@ class AsyncSession {
|
|
|
168
168
|
* Unrolls other properties
|
|
169
169
|
*/
|
|
170
170
|
_unrollOther(prop, vars, next) {
|
|
171
|
-
if (_optionalChain([prop, 'optionalAccess', _18 => _18.value, 'optionalAccess', _19 => _19.value])) {
|
|
171
|
+
if (_optionalChain([prop, 'optionalAccess', _18 => _18.value, 'optionalAccess', _19 => _19.value]) != null) {
|
|
172
172
|
vars[prop.name] = prop.value.value;
|
|
173
|
-
} else if (_optionalChain([prop, 'optionalAccess', _20 => _20.value, 'optionalAccess', _21 => _21.description]) && _optionalChain([prop, 'optionalAccess', _22 => _22.value, 'optionalAccess', _23 => _23.type]) !== 'function') {
|
|
173
|
+
} else if (_optionalChain([prop, 'optionalAccess', _20 => _20.value, 'optionalAccess', _21 => _21.description]) != null && _optionalChain([prop, 'optionalAccess', _22 => _22.value, 'optionalAccess', _23 => _23.type]) !== 'function') {
|
|
174
174
|
vars[prop.name] = `<${prop.value.description}>`;
|
|
175
175
|
}
|
|
176
176
|
|