From f248288e90959f078b1938c6eda4efb21b127aa2 Mon Sep 17 00:00:00 2001 From: Bryan Roe Date: Fri, 29 May 2020 04:46:40 -0700 Subject: [PATCH] Updated promise to correctly implement uncaught rejection --- microscript/ILibDuktape_Polyfills.c | 2 +- modules/promise.js | 85 +++++++++++++++++++++++++++-- 2 files changed, 82 insertions(+), 5 deletions(-) diff --git a/microscript/ILibDuktape_Polyfills.c b/microscript/ILibDuktape_Polyfills.c index 384b455..a01bfed 100644 --- a/microscript/ILibDuktape_Polyfills.c +++ b/microscript/ILibDuktape_Polyfills.c @@ -2099,7 +2099,7 @@ void ILibDuktape_Polyfills_JS_Init(duk_context *ctx) free(_clipboard); // Promise: This is very important, as it is used everywhere. Refer to /modules/promise.js to see a human readable version of promise.js - duk_peval_string_noresult(ctx, "addModule('promise', Buffer.from('LyoNCkNvcHlyaWdodCAyMDE4IEludGVsIENvcnBvcmF0aW9uDQoNCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOw0KeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLg0KWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0DQoNCiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjANCg0KVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQ0KZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywNCldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLg0KU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZA0KbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuDQoqLw0KDQp2YXIgcmVmVGFibGUgPSB7fTsNCg0KZnVuY3Rpb24gZXZlbnRfc3dpdGNoZXJfaGVscGVyKGRlc2lyZWRfY2FsbGVlLCB0YXJnZXQsIGZvcndhcmQpDQp7DQogICAgdGhpcy5fT2JqZWN0SUQgPSAnZXZlbnRfc3dpdGNoZXInOw0KICAgIHRoaXMuZnVuYyA9IGZ1bmN0aW9uIGZ1bmMoKQ0KICAgIHsNCiAgICAgICAgdmFyIGFyZ3MgPSBbXTsNCiAgICAgICAgaWYgKGZ1bmMuZm9yd2FyZCAhPSBudWxsKSB7IGFyZ3MucHVzaChmdW5jLmZvcndhcmQpOyB9DQogICAgICAgIGZvcih2YXIgaSBpbiBhcmd1bWVudHMpDQogICAgICAgIHsNCiAgICAgICAgICAgIGFyZ3MucHVzaChhcmd1bWVudHNbaV0pOw0KICAgICAgICB9DQogICAgICAgIHJldHVybiAoZnVuYy50YXJnZXQuYXBwbHkoZnVuYy5kZXNpcmVkLCBhcmdzKSk7DQogICAgfTsNCiAgICB0aGlzLmZ1bmMuZGVzaXJlZCA9IGRlc2lyZWRfY2FsbGVlOw0KICAgIHRoaXMuZnVuYy50YXJnZXQgPSB0YXJnZXQ7DQogICAgdGhpcy5mdW5jLmZvcndhcmQgPSBmb3J3YXJkOw0KICAgIHRoaXMuZnVuYy5zZWxmID0gdGhpczsNCn0NCmZ1bmN0aW9uIGV2ZW50X3N3aXRjaGVyKGRlc2lyZWRfY2FsbGVlLCB0YXJnZXQpDQp7DQogICAgcmV0dXJuIChuZXcgZXZlbnRfc3dpdGNoZXJfaGVscGVyKGRlc2lyZWRfY2FsbGVlLCB0YXJnZXQpKTsNCn0NCg0KZnVuY3Rpb24gZXZlbnRfZm9yd2FyZGVyKHNvdXJjZU9iaiwgc291cmNlTmFtZSwgdGFyZ2V0T2JqLCB0YXJnZXROYW1lKQ0Kew0KICAgIHNvdXJjZU9iai5vbihzb3VyY2VOYW1lLCAgIChuZXcgZXZlbnRfc3dpdGNoZXJfaGVscGVyKHRhcmdldE9iaiwgdGFyZ2V0T2JqLmVtaXQsIHRhcmdldE5hbWUpKS5mdW5jKTsgICAgICANCn0NCg0KZnVuY3Rpb24gUHJvbWlzZShwcm9taXNlRnVuYykNCnsNCiAgICB0aGlzLl9PYmplY3RJRCA9ICdwcm9taXNlJzsNCiAgICB0aGlzLnByb21pc2UgPSB0aGlzOw0KICAgIHRoaXMuX2ludGVybmFsID0geyBfT2JqZWN0SUQ6ICdwcm9taXNlLmludGVybmFsJywgcHJvbWlzZTogdGhpcywgZnVuYzogcHJvbWlzZUZ1bmMsIGNvbXBsZXRlZDogZmFsc2UsIGVycm9yczogZmFsc2UsIGNvbXBsZXRlZEFyZ3M6IFtdIH07DQogICAgcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyLmNhbGwodGhpcy5faW50ZXJuYWwpOw0KICAgIHRoaXMuX2ludGVybmFsLm9uKCduZXdMaXN0ZW5lcicsIGZ1bmN0aW9uIChldmVudE5hbWUsIGV2ZW50Q2FsbGJhY2spDQogICAgew0KICAgICAgICAvL2NvbnNvbGUubG9nKCduZXdMaXN0ZW5lcicsIGV2ZW50TmFtZSwgJ2Vycm9ycy8nICsgdGhpcy5lcnJvcnMgKyAnIGNvbXBsZXRlZC8nICsgdGhpcy5jb21wbGV0ZWQpOw0KICAgICAgICB2YXIgciA9IG51bGw7DQoNCiAgICAgICAgaWYgKGV2ZW50TmFtZSA9PSAncmVzb2x2ZWQnICYmICF0aGlzLmVycm9ycyAmJiB0aGlzLmNvbXBsZXRlZCkNCiAgICAgICAgew0KICAgICAgICAgICAgciA9IGV2ZW50Q2FsbGJhY2suYXBwbHkodGhpcywgdGhpcy5jb21wbGV0ZWRBcmdzKTsNCiAgICAgICAgICAgIGlmKHIhPW51bGwpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdGhpcy5lbWl0X3JldHVyblZhbHVlKCdyZXNvbHZlZCcsIHIpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGlmIChldmVudE5hbWUgPT0gJ3JlamVjdGVkJyAmJiB0aGlzLmVycm9ycyAmJiB0aGlzLmNvbXBsZXRlZCkNCiAgICAgICAgew0KICAgICAgICAgICAgZXZlbnRDYWxsYmFjay5hcHBseSh0aGlzLCB0aGlzLmNvbXBsZXRlZEFyZ3MpOw0KICAgICAgICB9DQogICAgICAgIGlmIChldmVudE5hbWUgPT0gJ3NldHRsZWQnICYmIHRoaXMuY29tcGxldGVkKQ0KICAgICAgICB7DQogICAgICAgICAgICBldmVudENhbGxiYWNrLmFwcGx5KHRoaXMsIFtdKTsNCiAgICAgICAgfQ0KICAgIH0pOw0KICAgIHRoaXMuX2ludGVybmFsLnJlc29sdmVyID0gZnVuY3Rpb24gX3Jlc29sdmVyKCkNCiAgICB7DQogICAgICAgIGlmIChfcmVzb2x2ZXIuX3NlbGYuY29tcGxldGVkKSB7IHJldHVybjsgfQ0KICAgICAgICBfcmVzb2x2ZXIuX3NlbGYuZXJyb3JzID0gZmFsc2U7DQogICAgICAgIF9yZXNvbHZlci5fc2VsZi5jb21wbGV0ZWQgPSB0cnVlOw0KICAgICAgICBfcmVzb2x2ZXIuX3NlbGYuY29tcGxldGVkQXJncyA9IFtdOw0KICAgICAgICB2YXIgYXJncyA9IFsncmVzb2x2ZWQnXTsNCiAgICAgICAgaWYgKHRoaXMuZW1pdF9yZXR1cm5WYWx1ZSAmJiB0aGlzLmVtaXRfcmV0dXJuVmFsdWUoJ3Jlc29sdmVkJykgIT0gbnVsbCkNCiAgICAgICAgew0KICAgICAgICAgICAgX3Jlc29sdmVyLl9zZWxmLmNvbXBsZXRlZEFyZ3MucHVzaCh0aGlzLmVtaXRfcmV0dXJuVmFsdWUoJ3Jlc29sdmVkJykpOw0KICAgICAgICAgICAgYXJncy5wdXNoKHRoaXMuZW1pdF9yZXR1cm5WYWx1ZSgncmVzb2x2ZWQnKSk7DQogICAgICAgIH0NCiAgICAgICAgZWxzZQ0KICAgICAgICB7DQogICAgICAgICAgICBmb3IgKHZhciBhIGluIGFyZ3VtZW50cykNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBfcmVzb2x2ZXIuX3NlbGYuY29tcGxldGVkQXJncy5wdXNoKGFyZ3VtZW50c1thXSk7DQogICAgICAgICAgICAgICAgYXJncy5wdXNoKGFyZ3VtZW50c1thXSk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID09IDIgJiYgYXJnc1sxXS5fT2JqZWN0SUQgPT0gJ3Byb21pc2UnKQ0KICAgICAgICB7DQogICAgICAgICAgICBhcmdzWzFdLnRoZW4oZnVuY3Rpb24gKCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICB2YXIgcGFybXMgPSBbJ3Jlc29sdmVkJ107DQogICAgICAgICAgICAgICAgZm9yKHZhciBhaSBpbiBhcmd1bWVudHMpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICBwYXJtcy5wdXNoKGFyZ3VtZW50c1thaV0pOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB0aGlzLl9YU0xGLmVtaXQuYXBwbHkodGhpcy5fWFNMRiwgcGFybXMpOw0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIGZ1bmN0aW9uIChlKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHZhciBwYXJtcyA9IFsncmVqZWN0ZWQnLCBlXTsNCiAgICAgICAgICAgICAgICB0aGlzLl9YU0xGLmVtaXQuYXBwbHkodGhpcy5fWFNMRiwgcGFybXMpOw0KICAgICAgICAgICAgfSkucGFyZW50UHJvbWlzZS5fWFNMRiA9IF9yZXNvbHZlci5fc2VsZjsNCiAgICAgICAgfQ0KICAgICAgICBlbHNlDQogICAgICAgIHsNCiAgICAgICAgICAgIF9yZXNvbHZlci5fc2VsZi5lbWl0LmFwcGx5KF9yZXNvbHZlci5fc2VsZiwgYXJncyk7DQogICAgICAgICAgICBfcmVzb2x2ZXIuX3NlbGYuZW1pdCgnc2V0dGxlZCcpOw0KICAgICAgICB9DQogICAgfTsNCiAgICB0aGlzLl9pbnRlcm5hbC5yZWplY3RvciA9IGZ1bmN0aW9uIF9yZWplY3RvcigpDQogICAgew0KICAgICAgICBpZiAoX3JlamVjdG9yLl9zZWxmLmNvbXBsZXRlZCkgeyByZXR1cm47IH0NCiAgICAgICAgX3JlamVjdG9yLl9zZWxmLmVycm9ycyA9IHRydWU7DQogICAgICAgIF9yZWplY3Rvci5fc2VsZi5jb21wbGV0ZWQgPSB0cnVlOw0KICAgICAgICBfcmVqZWN0b3IuX3NlbGYuY29tcGxldGVkQXJncyA9IFtdOw0KICAgICAgICB2YXIgYXJncyA9IFsncmVqZWN0ZWQnXTsNCiAgICAgICAgZm9yICh2YXIgYSBpbiBhcmd1bWVudHMpDQogICAgICAgIHsNCiAgICAgICAgICAgIF9yZWplY3Rvci5fc2VsZi5jb21wbGV0ZWRBcmdzLnB1c2goYXJndW1lbnRzW2FdKTsNCiAgICAgICAgICAgIGFyZ3MucHVzaChhcmd1bWVudHNbYV0pOw0KICAgICAgICB9DQoNCiAgICAgICAgX3JlamVjdG9yLl9zZWxmLmVtaXQuYXBwbHkoX3JlamVjdG9yLl9zZWxmLCBhcmdzKTsNCiAgICAgICAgX3JlamVjdG9yLl9zZWxmLmVtaXQoJ3NldHRsZWQnKTsNCiAgICB9Ow0KICAgIHRoaXMuY2F0Y2ggPSBmdW5jdGlvbihmdW5jKQ0KICAgIHsNCiAgICAgICAgdGhpcy5faW50ZXJuYWwub25jZSgncmVqZWN0ZWQnLCBldmVudF9zd2l0Y2hlcih0aGlzLCBmdW5jKS5mdW5jKTsNCiAgICB9DQogICAgdGhpcy5maW5hbGx5ID0gZnVuY3Rpb24gKGZ1bmMpDQogICAgew0KICAgICAgICB0aGlzLl9pbnRlcm5hbC5vbmNlKCdzZXR0bGVkJywgZXZlbnRfc3dpdGNoZXIodGhpcywgZnVuYykuZnVuYyk7DQogICAgfTsNCiAgICB0aGlzLnRoZW4gPSBmdW5jdGlvbiAocmVzb2x2ZWQsIHJlamVjdGVkKQ0KICAgIHsNCiAgICAgICAgaWYgKHJlc29sdmVkKSB7IHRoaXMuX2ludGVybmFsLm9uY2UoJ3Jlc29sdmVkJywgZXZlbnRfc3dpdGNoZXIodGhpcywgcmVzb2x2ZWQpLmZ1bmMpOyB9DQogICAgICAgIGlmIChyZWplY3RlZCkNCiAgICAgICAgew0KICAgICAgICAgICAgdGhpcy5faW50ZXJuYWwub25jZSgncmVqZWN0ZWQnLCBldmVudF9zd2l0Y2hlcih0aGlzLCByZWplY3RlZCkuZnVuYyk7DQogICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgdmFyIHJldFZhbCA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyLCBqKSB7IH0pOw0KICAgICAgICB0aGlzLl9pbnRlcm5hbC5vbmNlKCdyZXNvbHZlZCcsIHJldFZhbC5faW50ZXJuYWwucmVzb2x2ZXIpOw0KICAgICAgICB0aGlzLl9pbnRlcm5hbC5vbmNlKCdyZWplY3RlZCcsIHJldFZhbC5faW50ZXJuYWwucmVqZWN0b3IpOw0KICAgICAgICByZXRWYWwucGFyZW50UHJvbWlzZSA9IHRoaXM7DQogICAgICAgIHJldHVybiAocmV0VmFsKTsNCiAgICB9Ow0KDQogICAgdGhpcy5faW50ZXJuYWwucmVzb2x2ZXIuX3NlbGYgPSB0aGlzLl9pbnRlcm5hbDsNCiAgICB0aGlzLl9pbnRlcm5hbC5yZWplY3Rvci5fc2VsZiA9IHRoaXMuX2ludGVybmFsOzsNCg0KICAgIHRyeQ0KICAgIHsNCiAgICAgICAgcHJvbWlzZUZ1bmMuY2FsbCh0aGlzLCB0aGlzLl9pbnRlcm5hbC5yZXNvbHZlciwgdGhpcy5faW50ZXJuYWwucmVqZWN0b3IpOw0KICAgIH0NCiAgICBjYXRjaChlKQ0KICAgIHsNCiAgICAgICAgdGhpcy5faW50ZXJuYWwuZXJyb3JzID0gdHJ1ZTsNCiAgICAgICAgdGhpcy5faW50ZXJuYWwuY29tcGxldGVkID0gdHJ1ZTsNCiAgICAgICAgdGhpcy5faW50ZXJuYWwuY29tcGxldGVkQXJncyA9IFtlXTsNCiAgICAgICAgdGhpcy5faW50ZXJuYWwuZW1pdCgncmVqZWN0ZWQnLCBlKTsNCiAgICAgICAgdGhpcy5faW50ZXJuYWwuZW1pdCgnc2V0dGxlZCcpOw0KICAgIH0NCg0KICAgIGlmKCF0aGlzLl9pbnRlcm5hbC5jb21wbGV0ZWQpDQogICAgew0KICAgICAgICAvLyBTYXZlIHJlZmVyZW5jZSBvZiB0aGlzIG9iamVjdA0KICAgICAgICByZWZUYWJsZVt0aGlzLl9pbnRlcm5hbC5faGFzaENvZGUoKV0gPSB0aGlzLl9pbnRlcm5hbDsNCiAgICAgICAgdGhpcy5faW50ZXJuYWwub25jZSgnc2V0dGxlZCcsIGZ1bmN0aW9uICgpIHsgcmVmVGFibGVbdGhpcy5faGFzaENvZGUoKV0gPSBudWxsOyB9KTsNCiAgICB9DQogICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICJjb21wbGV0ZWQiLCB7DQogICAgICAgIGdldDogZnVuY3Rpb24gKCkNCiAgICAgICAgew0KICAgICAgICAgICAgcmV0dXJuICh0aGlzLl9pbnRlcm5hbC5jb21wbGV0ZWQpOw0KICAgICAgICB9DQogICAgfSk7DQp9DQoNClByb21pc2UucmVzb2x2ZSA9IGZ1bmN0aW9uIHJlc29sdmUoKQ0Kew0KICAgIHZhciByZXRWYWwgPSBuZXcgUHJvbWlzZShmdW5jdGlvbiAociwgaikgeyB9KTsNCiAgICB2YXIgYXJncyA9IFtdOw0KICAgIGZvciAodmFyIGkgaW4gYXJndW1lbnRzKQ0KICAgIHsNCiAgICAgICAgYXJncy5wdXNoKGFyZ3VtZW50c1tpXSk7DQogICAgfQ0KICAgIHJldFZhbC5faW50ZXJuYWwucmVzb2x2ZXIuYXBwbHkocmV0VmFsLl9pbnRlcm5hbCwgYXJncyk7DQogICAgcmV0dXJuIChyZXRWYWwpOw0KfTsNClByb21pc2UucmVqZWN0ID0gZnVuY3Rpb24gcmVqZWN0KCkgew0KICAgIHZhciByZXRWYWwgPSBuZXcgUHJvbWlzZShmdW5jdGlvbiAociwgaikgeyB9KTsNCiAgICB2YXIgYXJncyA9IFtdOw0KICAgIGZvciAodmFyIGkgaW4gYXJndW1lbnRzKSB7DQogICAgICAgIGFyZ3MucHVzaChhcmd1bWVudHNbaV0pOw0KICAgIH0NCiAgICByZXRWYWwuX2ludGVybmFsLnJlamVjdG9yLmFwcGx5KHJldFZhbC5faW50ZXJuYWwsIGFyZ3MpOw0KICAgIHJldHVybiAocmV0VmFsKTsNCn07DQpQcm9taXNlLmFsbCA9IGZ1bmN0aW9uIGFsbChwcm9taXNlTGlzdCkNCnsNCiAgICB2YXIgcmV0ID0gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlcywgcmVqKQ0KICAgIHsNCiAgICAgICAgdGhpcy5fX3JlamVjdG9yID0gcmVqOw0KICAgICAgICB0aGlzLl9fcmVzb2x2ZXIgPSByZXM7DQogICAgICAgIHRoaXMuX19wcm9taXNlTGlzdCA9IHByb21pc2VMaXN0Ow0KICAgICAgICB0aGlzLl9fZG9uZSA9IGZhbHNlOw0KICAgICAgICB0aGlzLl9fY291bnQgPSAwOw0KICAgIH0pOw0KDQogICAgZm9yICh2YXIgaSBpbiBwcm9taXNlTGlzdCkNCiAgICB7DQogICAgICAgIHByb21pc2VMaXN0W2ldLnRoZW4oZnVuY3Rpb24gKCkNCiAgICAgICAgew0KICAgICAgICAgICAgLy8gU3VjY2Vzcw0KICAgICAgICAgICAgaWYoKytyZXQuX19jb3VudCA9PSByZXQuX19wcm9taXNlTGlzdC5sZW5ndGgpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgcmV0Ll9fZG9uZSA9IHRydWU7DQogICAgICAgICAgICAgICAgcmV0Ll9fcmVzb2x2ZXIocmV0Ll9fcHJvbWlzZUxpc3QpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9LCBmdW5jdGlvbiAoYXJnKQ0KICAgICAgICB7DQogICAgICAgICAgICAvLyBGYWlsdXJlDQogICAgICAgICAgICBpZighcmV0Ll9fZG9uZSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICByZXQuX19kb25lID0gdHJ1ZTsNCiAgICAgICAgICAgICAgICByZXQuX19yZWplY3RvcihhcmcpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9KTsNCiAgICB9DQogICAgaWYgKHByb21pc2VMaXN0Lmxlbmd0aCA9PSAwKQ0KICAgIHsNCiAgICAgICAgcmV0Ll9fcmVzb2x2ZXIocHJvbWlzZUxpc3QpOw0KICAgIH0NCiAgICByZXR1cm4gKHJldCk7DQp9Ow0KDQptb2R1bGUuZXhwb3J0cyA9IFByb21pc2U7DQptb2R1bGUuZXhwb3J0cy5ldmVudF9zd2l0Y2hlciA9IGV2ZW50X3N3aXRjaGVyOw0KbW9kdWxlLmV4cG9ydHMuZXZlbnRfZm9yd2FyZGVyID0gZXZlbnRfZm9yd2FyZGVyOw==', 'base64').toString());"); + duk_peval_string_noresult(ctx, "addModule('promise', Buffer.from('LyoNCkNvcHlyaWdodCAyMDE4IEludGVsIENvcnBvcmF0aW9uDQoNCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOw0KeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLg0KWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0DQoNCiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjANCg0KVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQ0KZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywNCldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLg0KU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZA0KbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuDQoqLw0KDQp2YXIgcmVmVGFibGUgPSB7fTsNCg0KZnVuY3Rpb24gZ2V0Um9vdFByb21pc2Uob2JqKQ0Kew0KICAgIHdoaWxlKG9iai5wYXJlbnRQcm9taXNlKQ0KICAgIHsNCiAgICAgICAgb2JqID0gb2JqLnBhcmVudFByb21pc2U7DQogICAgfQ0KICAgIHJldHVybiAob2JqKTsNCn0NCmZ1bmN0aW9uIGdldERlcHRoKG9iaikNCnsNCiAgICB2YXIgY291bnQgPSAxOw0KICAgIHdoaWxlIChvYmoucGFyZW50UHJvbWlzZSkNCiAgICB7DQogICAgICAgICsrY291bnQ7DQogICAgICAgIG9iaiA9IG9iai5wYXJlbnRQcm9taXNlOw0KICAgIH0NCiAgICByZXR1cm4gKGNvdW50KTsNCn0NCg0KZnVuY3Rpb24gZXZlbnRfc3dpdGNoZXJfaGVscGVyKGRlc2lyZWRfY2FsbGVlLCB0YXJnZXQsIGZvcndhcmQpDQp7DQogICAgdGhpcy5fT2JqZWN0SUQgPSAnZXZlbnRfc3dpdGNoZXInOw0KICAgIHRoaXMuZnVuYyA9IGZ1bmN0aW9uIGZ1bmMoKQ0KICAgIHsNCiAgICAgICAgdmFyIGFyZ3MgPSBbXTsNCiAgICAgICAgaWYgKGZ1bmMuZm9yd2FyZCAhPSBudWxsKSB7IGFyZ3MucHVzaChmdW5jLmZvcndhcmQpOyB9DQogICAgICAgIGZvcih2YXIgaSBpbiBhcmd1bWVudHMpDQogICAgICAgIHsNCiAgICAgICAgICAgIGFyZ3MucHVzaChhcmd1bWVudHNbaV0pOw0KICAgICAgICB9DQogICAgICAgIHJldHVybiAoZnVuYy50YXJnZXQuYXBwbHkoZnVuYy5kZXNpcmVkLCBhcmdzKSk7DQogICAgfTsNCiAgICB0aGlzLmZ1bmMuZGVzaXJlZCA9IGRlc2lyZWRfY2FsbGVlOw0KICAgIHRoaXMuZnVuYy50YXJnZXQgPSB0YXJnZXQ7DQogICAgdGhpcy5mdW5jLmZvcndhcmQgPSBmb3J3YXJkOw0KICAgIHRoaXMuZnVuYy5zZWxmID0gdGhpczsNCn0NCmZ1bmN0aW9uIGV2ZW50X3N3aXRjaGVyKGRlc2lyZWRfY2FsbGVlLCB0YXJnZXQpDQp7DQogICAgcmV0dXJuIChuZXcgZXZlbnRfc3dpdGNoZXJfaGVscGVyKGRlc2lyZWRfY2FsbGVlLCB0YXJnZXQpKTsNCn0NCg0KZnVuY3Rpb24gZXZlbnRfZm9yd2FyZGVyKHNvdXJjZU9iaiwgc291cmNlTmFtZSwgdGFyZ2V0T2JqLCB0YXJnZXROYW1lKQ0Kew0KICAgIHNvdXJjZU9iai5vbihzb3VyY2VOYW1lLCAgIChuZXcgZXZlbnRfc3dpdGNoZXJfaGVscGVyKHRhcmdldE9iaiwgdGFyZ2V0T2JqLmVtaXQsIHRhcmdldE5hbWUpKS5mdW5jKTsgICAgICANCn0NCg0KZnVuY3Rpb24gUHJvbWlzZShwcm9taXNlRnVuYykNCnsNCiAgICB0aGlzLl9PYmplY3RJRCA9ICdwcm9taXNlJzsNCiAgICB0aGlzLnByb21pc2UgPSB0aGlzOw0KICAgIHRoaXMuX2ludGVybmFsID0geyBfT2JqZWN0SUQ6ICdwcm9taXNlLmludGVybmFsJywgcHJvbWlzZTogdGhpcywgZnVuYzogcHJvbWlzZUZ1bmMsIGNvbXBsZXRlZDogZmFsc2UsIGVycm9yczogZmFsc2UsIGNvbXBsZXRlZEFyZ3M6IFtdLCByZWpTdGFydGVkOiBmYWxzZSwgcmVqQ291bnQ6IDAsIGRlcHRoOiAwIH07DQogICAgcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyLmNhbGwodGhpcy5faW50ZXJuYWwpOw0KICAgIHRoaXMuX2ludGVybmFsLm9uKCduZXdMaXN0ZW5lcicsIGZ1bmN0aW9uIChldmVudE5hbWUsIGV2ZW50Q2FsbGJhY2spDQogICAgew0KICAgICAgICAvL2NvbnNvbGUubG9nKCduZXdMaXN0ZW5lcicsIGV2ZW50TmFtZSwgJ2Vycm9ycy8nICsgdGhpcy5lcnJvcnMgKyAnIGNvbXBsZXRlZC8nICsgdGhpcy5jb21wbGV0ZWQpOw0KICAgICAgICB2YXIgciA9IG51bGw7DQoNCiAgICAgICAgaWYgKGV2ZW50TmFtZSA9PSAncmVzb2x2ZWQnICYmICF0aGlzLmVycm9ycyAmJiB0aGlzLmNvbXBsZXRlZCkNCiAgICAgICAgew0KICAgICAgICAgICAgciA9IGV2ZW50Q2FsbGJhY2suYXBwbHkodGhpcywgdGhpcy5jb21wbGV0ZWRBcmdzKTsNCiAgICAgICAgICAgIGlmKHIhPW51bGwpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdGhpcy5lbWl0X3JldHVyblZhbHVlKCdyZXNvbHZlZCcsIHIpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGlmIChldmVudE5hbWUgPT0gJ3JlamVjdGVkJyAmJiB0aGlzLmVycm9ycyAmJiB0aGlzLmNvbXBsZXRlZCkNCiAgICAgICAgew0KICAgICAgICAgICAgdmFyIHJ0ID0gZ2V0Um9vdFByb21pc2UodGhpcy5wcm9taXNlKTsNCiAgICAgICAgICAgIHZhciBjaCA9IHJ0Ow0KICAgICAgICAgICAgdmFyIGNoeCA9IDE7DQogICAgICAgICAgICB2YXIgbmNudCA9IDE7DQogICAgICAgICAgICB3aGlsZShjaCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBpZiAoY2guX2ludGVybmFsLmxpc3RlbmVyQ291bnQoJ3JlamVjdGVkJykgPiAwKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgbmNudCArPSBjaC5faW50ZXJuYWwubGlzdGVuZXJDb3VudCgncmVqZWN0ZWQnKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgY2h4Kys7DQogICAgICAgICAgICAgICAgY2ggPSBjaC5fX2NoaWxkUHJvbWlzZTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmIChjaHggPiBydC5faW50ZXJuYWwuZGVwdGgpIHsgcnQuX2ludGVybmFsLmRlcHRoID0gY2h4OyB9DQogICAgICAgICAgICBpZiAobmNudCA+IHJ0Ll9pbnRlcm5hbC5yZWpDb3VudCkgeyBydC5faW50ZXJuYWwucmVqQ291bnQgPSBuY250OyB9DQoNCiAgICAgICAgICAgIGlmIChydC5faW50ZXJuYWwuX2ltbSAmJiBydC5faW50ZXJuYWwucmVqQ291bnQgPj0gcnQuX2ludGVybmFsLmRlcHRoKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGNsZWFySW1tZWRpYXRlKHJ0Ll9pbnRlcm5hbC5faW1tKTsNCiAgICAgICAgICAgICAgICBydC5faW50ZXJuYWwuX2ltbSA9IG51bGw7DQogICAgICAgICAgICAgICAgcnQuX2ludGVybmFsLl9oYWx0VW5jYXVnaHQgPSB0cnVlOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZXZlbnRDYWxsYmFjay5hcHBseSh0aGlzLCB0aGlzLmNvbXBsZXRlZEFyZ3MpOw0KICAgICAgICB9DQogICAgICAgIGlmIChldmVudE5hbWUgPT0gJ3NldHRsZWQnICYmIHRoaXMuY29tcGxldGVkKQ0KICAgICAgICB7DQogICAgICAgICAgICBldmVudENhbGxiYWNrLmFwcGx5KHRoaXMsIFtdKTsNCiAgICAgICAgfQ0KICAgIH0pOw0KICAgIHRoaXMuX2ludGVybmFsLnJlc29sdmVyID0gZnVuY3Rpb24gX3Jlc29sdmVyKCkNCiAgICB7DQogICAgICAgIGlmIChfcmVzb2x2ZXIuX3NlbGYuY29tcGxldGVkKSB7IHJldHVybjsgfQ0KICAgICAgICBfcmVzb2x2ZXIuX3NlbGYuZXJyb3JzID0gZmFsc2U7DQogICAgICAgIF9yZXNvbHZlci5fc2VsZi5jb21wbGV0ZWQgPSB0cnVlOw0KICAgICAgICBfcmVzb2x2ZXIuX3NlbGYuY29tcGxldGVkQXJncyA9IFtdOw0KICAgICAgICB2YXIgYXJncyA9IFsncmVzb2x2ZWQnXTsNCiAgICAgICAgaWYgKHRoaXMuZW1pdF9yZXR1cm5WYWx1ZSAmJiB0aGlzLmVtaXRfcmV0dXJuVmFsdWUoJ3Jlc29sdmVkJykgIT0gbnVsbCkNCiAgICAgICAgew0KICAgICAgICAgICAgX3Jlc29sdmVyLl9zZWxmLmNvbXBsZXRlZEFyZ3MucHVzaCh0aGlzLmVtaXRfcmV0dXJuVmFsdWUoJ3Jlc29sdmVkJykpOw0KICAgICAgICAgICAgYXJncy5wdXNoKHRoaXMuZW1pdF9yZXR1cm5WYWx1ZSgncmVzb2x2ZWQnKSk7DQogICAgICAgIH0NCiAgICAgICAgZWxzZQ0KICAgICAgICB7DQogICAgICAgICAgICBmb3IgKHZhciBhIGluIGFyZ3VtZW50cykNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBfcmVzb2x2ZXIuX3NlbGYuY29tcGxldGVkQXJncy5wdXNoKGFyZ3VtZW50c1thXSk7DQogICAgICAgICAgICAgICAgYXJncy5wdXNoKGFyZ3VtZW50c1thXSk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID09IDIgJiYgYXJnc1sxXS5fT2JqZWN0SUQgPT0gJ3Byb21pc2UnKQ0KICAgICAgICB7DQogICAgICAgICAgICB2YXIgcHIgPSBnZXRSb290UHJvbWlzZShfcmVzb2x2ZXIuX3NlbGYucHJvbWlzZSk7DQogICAgICAgICAgICBwci5faW50ZXJuYWwuX2hhbHRVbmNhdWdodCA9IHRydWU7DQogICAgICAgICAgICBhcmdzWzFdLnRoZW4oZnVuY3Rpb24gKCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICB2YXIgcGFybXMgPSBbJ3Jlc29sdmVkJ107DQogICAgICAgICAgICAgICAgZm9yKHZhciBhaSBpbiBhcmd1bWVudHMpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICBwYXJtcy5wdXNoKGFyZ3VtZW50c1thaV0pOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB0aGlzLl9YU0xGLmVtaXQuYXBwbHkodGhpcy5fWFNMRiwgcGFybXMpOw0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIGZ1bmN0aW9uIChlKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHRoaXMuX1hTTEYucHJvbWlzZS5fX2NoaWxkUHJvbWlzZS5wYXJlbnRQcm9taXNlID0gbnVsbDsNCiAgICAgICAgICAgICAgICB0aGlzLl9YU0xGLnByb21pc2UuX19jaGlsZFByb21pc2UuX2ludGVybmFsLl9oYWx0VW5jYXVnaHQgPSBmYWxzZTsNCiAgICAgICAgICAgICAgICB0aGlzLl9YU0xGLnByb21pc2UuX19jaGlsZFByb21pc2UuX3JlaihlKTsNCiAgICAgICAgICAgICAgICAvL3ZhciBwYXJtcyA9IFsncmVqZWN0ZWQnLCBlXTsNCiAgICAgICAgICAgICAgICAvL3RoaXMuX1hTTEYuZW1pdC5hcHBseSh0aGlzLl9YU0xGLCBwYXJtcyk7DQogICAgICAgICAgICB9KS5wYXJlbnRQcm9taXNlLl9YU0xGID0gX3Jlc29sdmVyLl9zZWxmOw0KICAgICAgICB9DQogICAgICAgIGVsc2UNCiAgICAgICAgew0KICAgICAgICAgICAgX3Jlc29sdmVyLl9zZWxmLmVtaXQuYXBwbHkoX3Jlc29sdmVyLl9zZWxmLCBhcmdzKTsNCiAgICAgICAgICAgIF9yZXNvbHZlci5fc2VsZi5lbWl0KCdzZXR0bGVkJyk7DQogICAgICAgIH0NCiAgICB9Ow0KICAgIHRoaXMuX2ludGVybmFsLnJlamVjdG9yID0gZnVuY3Rpb24gX3JlamVjdG9yKCkNCiAgICB7DQogICAgICAgIGlmIChfcmVqZWN0b3IuX3NlbGYuY29tcGxldGVkKSB7IHJldHVybjsgfQ0KICAgICAgICBfcmVqZWN0b3IuX3NlbGYuZXJyb3JzID0gdHJ1ZTsNCiAgICAgICAgX3JlamVjdG9yLl9zZWxmLmNvbXBsZXRlZCA9IHRydWU7DQogICAgICAgIF9yZWplY3Rvci5fc2VsZi5jb21wbGV0ZWRBcmdzID0gW107DQogICAgICAgIHZhciBhcmdzID0gWydyZWplY3RlZCddOw0KICAgICAgICBmb3IgKHZhciBhIGluIGFyZ3VtZW50cykNCiAgICAgICAgew0KICAgICAgICAgICAgX3JlamVjdG9yLl9zZWxmLmNvbXBsZXRlZEFyZ3MucHVzaChhcmd1bWVudHNbYV0pOw0KICAgICAgICAgICAgYXJncy5wdXNoKGFyZ3VtZW50c1thXSk7DQogICAgICAgIH0NCg0KICAgICAgICB2YXIgciA9IGdldFJvb3RQcm9taXNlKF9yZWplY3Rvci5fc2VsZi5wcm9taXNlKTsNCiAgICAgICAgdmFyIG1lID0gZmFsc2U7DQogICAgICAgIGlmIChyLl9pbnRlcm5hbC5yZWpTdGFydGVkID09IGZhbHNlKQ0KICAgICAgICB7DQogICAgICAgICAgICByLl9pbnRlcm5hbC5yZWpTdGFydGVkID0gdHJ1ZTsNCiAgICAgICAgICAgIHIuX2ludGVybmFsLnJlakNvdW50ID0gMDsNCiAgICAgICAgICAgIHIuX2ludGVybmFsLmRlcHRoID0gMDsNCiAgICAgICAgICAgIG1lID0gdHJ1ZTsNCiAgICAgICAgfQ0KDQogICAgICAgIHZhciBkID0gZ2V0RGVwdGgoX3JlamVjdG9yLl9zZWxmLnByb21pc2UpOw0KICAgICAgICBpZiAoZCA+IHIuX2ludGVybmFsLmRlcHRoKSB7IHIuX2ludGVybmFsLmRlcHRoID0gZDsgfQ0KDQogICAgICAgIGlmIChfcmVqZWN0b3IuX3NlbGYubGlzdGVuZXJDb3VudCgncmVqZWN0ZWQnKSA+IDApDQogICAgICAgIHsNCiAgICAgICAgICAgIHIuX2ludGVybmFsLnJlakNvdW50ICs9IF9yZWplY3Rvci5fc2VsZi5saXN0ZW5lckNvdW50KCdyZWplY3RlZCcpOw0KICAgICAgICB9DQoNCiAgICAgICAgX3JlamVjdG9yLl9zZWxmLmVtaXQuYXBwbHkoX3JlamVjdG9yLl9zZWxmLCBhcmdzKTsNCiAgICAgICAgaWYgKG1lKQ0KICAgICAgICB7DQogICAgICAgICAgICByLl9pbnRlcm5hbC5yZWpTdGFydGVkID0gZmFsc2U7DQogICAgICAgICAgICBpZihyLl9pbnRlcm5hbC5yZWpDb3VudCA8IHIuX2ludGVybmFsLmRlcHRoICYmICFyLl9pbnRlcm5hbC5faW1tICYmICFyLl9pbnRlcm5hbC5faGFsdFVuY2F1Z2h0KQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHIuX2ludGVybmFsLl9pbW0gPSBzZXRJbW1lZGlhdGUoZnVuY3Rpb24gKGUsIGkpIHsgaS5faW1tID0gbnVsbDsgcHJvY2Vzcy5lbWl0KCd1bmNhdWdodEV4Y2VwdGlvbicsICdwcm9taXNlLnVuY2F1Z2h0UmVqZWN0aW9uOiAnICsgZSk7IH0sIGFyZ3NbMV0sIHIuX2ludGVybmFsKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIF9yZWplY3Rvci5fc2VsZi5lbWl0KCdzZXR0bGVkJyk7DQogICAgfTsNCiAgICB0aGlzLmNhdGNoID0gZnVuY3Rpb24oZnVuYykNCiAgICB7DQogICAgICAgIHZhciBydCA9IGdldFJvb3RQcm9taXNlKHRoaXMpOw0KICAgICAgICBpZiAocnQuX2ludGVybmFsLl9pbW0pIHsgY2xlYXJJbnRlcnZhbChydC5faW50ZXJuYWwuX2ltbSk7IHJ0Ll9pbnRlcm5hbC5faW1tID0gbnVsbDsgfQ0KICAgICAgICB0aGlzLl9pbnRlcm5hbC5vbmNlKCdyZWplY3RlZCcsIGV2ZW50X3N3aXRjaGVyKHRoaXMsIGZ1bmMpLmZ1bmMpOw0KICAgIH0NCiAgICB0aGlzLmZpbmFsbHkgPSBmdW5jdGlvbiAoZnVuYykNCiAgICB7DQogICAgICAgIHRoaXMuX2ludGVybmFsLm9uY2UoJ3NldHRsZWQnLCBldmVudF9zd2l0Y2hlcih0aGlzLCBmdW5jKS5mdW5jKTsNCiAgICB9Ow0KICAgIHRoaXMudGhlbiA9IGZ1bmN0aW9uIChyZXNvbHZlZCwgcmVqZWN0ZWQpDQogICAgew0KICAgICAgICBpZiAocmVzb2x2ZWQpIHsgdGhpcy5faW50ZXJuYWwub25jZSgncmVzb2x2ZWQnLCBldmVudF9zd2l0Y2hlcih0aGlzLCByZXNvbHZlZCkuZnVuYyk7IH0NCiAgICAgICAgaWYgKHJlamVjdGVkKQ0KICAgICAgICB7DQogICAgICAgICAgICB0aGlzLl9pbnRlcm5hbC5vbmNlKCdyZWplY3RlZCcsIGV2ZW50X3N3aXRjaGVyKHRoaXMsIHJlamVjdGVkKS5mdW5jKTsNCiAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICB2YXIgcmV0VmFsID0gbmV3IFByb21pc2UoZnVuY3Rpb24gKHIsIGopIHsgdGhpcy5fcmVqID0gajsgfSk7DQogICAgICAgIHJldFZhbC5faW50ZXJuYWwuX2hhbHRVbmNhdWdodCA9IHRydWU7DQogICAgICAgIHRoaXMuX2ludGVybmFsLm9uY2UoJ3Jlc29sdmVkJywgcmV0VmFsLl9pbnRlcm5hbC5yZXNvbHZlcik7DQogICAgICAgIHRoaXMuX2ludGVybmFsLm9uY2UoJ3JlamVjdGVkJywgcmV0VmFsLl9pbnRlcm5hbC5yZWplY3Rvcik7DQogICAgICAgIHJldFZhbC5wYXJlbnRQcm9taXNlID0gdGhpczsNCiAgICAgICAgdGhpcy5fX2NoaWxkUHJvbWlzZSA9IHJldFZhbDsNCiAgICAgICAgcmV0dXJuIChyZXRWYWwpOw0KICAgIH07DQoNCiAgICB0aGlzLl9pbnRlcm5hbC5yZXNvbHZlci5fc2VsZiA9IHRoaXMuX2ludGVybmFsOw0KICAgIHRoaXMuX2ludGVybmFsLnJlamVjdG9yLl9zZWxmID0gdGhpcy5faW50ZXJuYWw7Ow0KDQogICAgdHJ5DQogICAgew0KICAgICAgICBwcm9taXNlRnVuYy5jYWxsKHRoaXMsIHRoaXMuX2ludGVybmFsLnJlc29sdmVyLCB0aGlzLl9pbnRlcm5hbC5yZWplY3Rvcik7DQogICAgfQ0KICAgIGNhdGNoKGUpDQogICAgew0KICAgICAgICB0aGlzLl9pbnRlcm5hbC5lcnJvcnMgPSB0cnVlOw0KICAgICAgICB0aGlzLl9pbnRlcm5hbC5jb21wbGV0ZWQgPSB0cnVlOw0KICAgICAgICB0aGlzLl9pbnRlcm5hbC5jb21wbGV0ZWRBcmdzID0gW2VdOw0KICAgICAgICB0aGlzLl9pbnRlcm5hbC5lbWl0KCdyZWplY3RlZCcsIGUpOw0KICAgICAgICB0aGlzLl9pbnRlcm5hbC5lbWl0KCdzZXR0bGVkJyk7DQogICAgfQ0KDQogICAgaWYoIXRoaXMuX2ludGVybmFsLmNvbXBsZXRlZCkNCiAgICB7DQogICAgICAgIC8vIFNhdmUgcmVmZXJlbmNlIG9mIHRoaXMgb2JqZWN0DQogICAgICAgIHJlZlRhYmxlW3RoaXMuX2ludGVybmFsLl9oYXNoQ29kZSgpXSA9IHRoaXMuX2ludGVybmFsOw0KICAgICAgICB0aGlzLl9pbnRlcm5hbC5vbmNlKCdzZXR0bGVkJywgZnVuY3Rpb24gKCkgeyByZWZUYWJsZVt0aGlzLl9oYXNoQ29kZSgpXSA9IG51bGw7IH0pOw0KICAgIH0NCiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgImNvbXBsZXRlZCIsIHsNCiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKQ0KICAgICAgICB7DQogICAgICAgICAgICByZXR1cm4gKHRoaXMuX2ludGVybmFsLmNvbXBsZXRlZCk7DQogICAgICAgIH0NCiAgICB9KTsNCn0NCg0KUHJvbWlzZS5yZXNvbHZlID0gZnVuY3Rpb24gcmVzb2x2ZSgpDQp7DQogICAgdmFyIHJldFZhbCA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyLCBqKSB7IH0pOw0KICAgIHZhciBhcmdzID0gW107DQogICAgZm9yICh2YXIgaSBpbiBhcmd1bWVudHMpDQogICAgew0KICAgICAgICBhcmdzLnB1c2goYXJndW1lbnRzW2ldKTsNCiAgICB9DQogICAgcmV0VmFsLl9pbnRlcm5hbC5yZXNvbHZlci5hcHBseShyZXRWYWwuX2ludGVybmFsLCBhcmdzKTsNCiAgICByZXR1cm4gKHJldFZhbCk7DQp9Ow0KUHJvbWlzZS5yZWplY3QgPSBmdW5jdGlvbiByZWplY3QoKSB7DQogICAgdmFyIHJldFZhbCA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyLCBqKSB7IH0pOw0KICAgIHZhciBhcmdzID0gW107DQogICAgZm9yICh2YXIgaSBpbiBhcmd1bWVudHMpIHsNCiAgICAgICAgYXJncy5wdXNoKGFyZ3VtZW50c1tpXSk7DQogICAgfQ0KICAgIHJldFZhbC5faW50ZXJuYWwucmVqZWN0b3IuYXBwbHkocmV0VmFsLl9pbnRlcm5hbCwgYXJncyk7DQogICAgcmV0dXJuIChyZXRWYWwpOw0KfTsNClByb21pc2UuYWxsID0gZnVuY3Rpb24gYWxsKHByb21pc2VMaXN0KQ0Kew0KICAgIHZhciByZXQgPSBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzLCByZWopDQogICAgew0KICAgICAgICB0aGlzLl9fcmVqZWN0b3IgPSByZWo7DQogICAgICAgIHRoaXMuX19yZXNvbHZlciA9IHJlczsNCiAgICAgICAgdGhpcy5fX3Byb21pc2VMaXN0ID0gcHJvbWlzZUxpc3Q7DQogICAgICAgIHRoaXMuX19kb25lID0gZmFsc2U7DQogICAgICAgIHRoaXMuX19jb3VudCA9IDA7DQogICAgfSk7DQoNCiAgICBmb3IgKHZhciBpIGluIHByb21pc2VMaXN0KQ0KICAgIHsNCiAgICAgICAgcHJvbWlzZUxpc3RbaV0udGhlbihmdW5jdGlvbiAoKQ0KICAgICAgICB7DQogICAgICAgICAgICAvLyBTdWNjZXNzDQogICAgICAgICAgICBpZigrK3JldC5fX2NvdW50ID09IHJldC5fX3Byb21pc2VMaXN0Lmxlbmd0aCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICByZXQuX19kb25lID0gdHJ1ZTsNCiAgICAgICAgICAgICAgICByZXQuX19yZXNvbHZlcihyZXQuX19wcm9taXNlTGlzdCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0sIGZ1bmN0aW9uIChhcmcpDQogICAgICAgIHsNCiAgICAgICAgICAgIC8vIEZhaWx1cmUNCiAgICAgICAgICAgIGlmKCFyZXQuX19kb25lKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHJldC5fX2RvbmUgPSB0cnVlOw0KICAgICAgICAgICAgICAgIHJldC5fX3JlamVjdG9yKGFyZyk7DQogICAgICAgICAgICB9DQogICAgICAgIH0pOw0KICAgIH0NCiAgICBpZiAocHJvbWlzZUxpc3QubGVuZ3RoID09IDApDQogICAgew0KICAgICAgICByZXQuX19yZXNvbHZlcihwcm9taXNlTGlzdCk7DQogICAgfQ0KICAgIHJldHVybiAocmV0KTsNCn07DQoNCm1vZHVsZS5leHBvcnRzID0gUHJvbWlzZTsNCm1vZHVsZS5leHBvcnRzLmV2ZW50X3N3aXRjaGVyID0gZXZlbnRfc3dpdGNoZXI7DQptb2R1bGUuZXhwb3J0cy5ldmVudF9mb3J3YXJkZXIgPSBldmVudF9mb3J3YXJkZXI7', 'base64').toString());"); #ifdef WIN32 // Adding win-registry, since it is very useful for windows... Refer to /modules/win-registry.js to see a human readable version diff --git a/modules/promise.js b/modules/promise.js index 0537fb7..4050536 100644 --- a/modules/promise.js +++ b/modules/promise.js @@ -16,6 +16,25 @@ limitations under the License. var refTable = {}; +function getRootPromise(obj) +{ + while(obj.parentPromise) + { + obj = obj.parentPromise; + } + return (obj); +} +function getDepth(obj) +{ + var count = 1; + while (obj.parentPromise) + { + ++count; + obj = obj.parentPromise; + } + return (count); +} + function event_switcher_helper(desired_callee, target, forward) { this._ObjectID = 'event_switcher'; @@ -48,7 +67,7 @@ function Promise(promiseFunc) { this._ObjectID = 'promise'; this.promise = this; - this._internal = { _ObjectID: 'promise.internal', promise: this, func: promiseFunc, completed: false, errors: false, completedArgs: [] }; + this._internal = { _ObjectID: 'promise.internal', promise: this, func: promiseFunc, completed: false, errors: false, completedArgs: [], rejStarted: false, rejCount: 0, depth: 0 }; require('events').EventEmitter.call(this._internal); this._internal.on('newListener', function (eventName, eventCallback) { @@ -65,6 +84,28 @@ function Promise(promiseFunc) } if (eventName == 'rejected' && this.errors && this.completed) { + var rt = getRootPromise(this.promise); + var ch = rt; + var chx = 1; + var ncnt = 1; + while(ch) + { + if (ch._internal.listenerCount('rejected') > 0) + { + ncnt += ch._internal.listenerCount('rejected'); + } + chx++; + ch = ch.__childPromise; + } + if (chx > rt._internal.depth) { rt._internal.depth = chx; } + if (ncnt > rt._internal.rejCount) { rt._internal.rejCount = ncnt; } + + if (rt._internal._imm && rt._internal.rejCount >= rt._internal.depth) + { + clearImmediate(rt._internal._imm); + rt._internal._imm = null; + rt._internal._haltUncaught = true; + } eventCallback.apply(this, this.completedArgs); } if (eventName == 'settled' && this.completed) @@ -94,6 +135,8 @@ function Promise(promiseFunc) } if (args.length == 2 && args[1]._ObjectID == 'promise') { + var pr = getRootPromise(_resolver._self.promise); + pr._internal._haltUncaught = true; args[1].then(function () { var parms = ['resolved']; @@ -105,8 +148,11 @@ function Promise(promiseFunc) }, function (e) { - var parms = ['rejected', e]; - this._XSLF.emit.apply(this._XSLF, parms); + this._XSLF.promise.__childPromise.parentPromise = null; + this._XSLF.promise.__childPromise._internal._haltUncaught = false; + this._XSLF.promise.__childPromise._rej(e); + //var parms = ['rejected', e]; + //this._XSLF.emit.apply(this._XSLF, parms); }).parentPromise._XSLF = _resolver._self; } else @@ -128,11 +174,40 @@ function Promise(promiseFunc) args.push(arguments[a]); } + var r = getRootPromise(_rejector._self.promise); + var me = false; + if (r._internal.rejStarted == false) + { + r._internal.rejStarted = true; + r._internal.rejCount = 0; + r._internal.depth = 0; + me = true; + } + + var d = getDepth(_rejector._self.promise); + if (d > r._internal.depth) { r._internal.depth = d; } + + if (_rejector._self.listenerCount('rejected') > 0) + { + r._internal.rejCount += _rejector._self.listenerCount('rejected'); + } + _rejector._self.emit.apply(_rejector._self, args); + if (me) + { + r._internal.rejStarted = false; + if(r._internal.rejCount < r._internal.depth && !r._internal._imm && !r._internal._haltUncaught) + { + r._internal._imm = setImmediate(function (e, i) { i._imm = null; process.emit('uncaughtException', 'promise.uncaughtRejection: ' + e); }, args[1], r._internal); + } + } + _rejector._self.emit('settled'); }; this.catch = function(func) { + var rt = getRootPromise(this); + if (rt._internal._imm) { clearInterval(rt._internal._imm); rt._internal._imm = null; } this._internal.once('rejected', event_switcher(this, func).func); } this.finally = function (func) @@ -147,10 +222,12 @@ function Promise(promiseFunc) this._internal.once('rejected', event_switcher(this, rejected).func); } - var retVal = new Promise(function (r, j) { }); + var retVal = new Promise(function (r, j) { this._rej = j; }); + retVal._internal._haltUncaught = true; this._internal.once('resolved', retVal._internal.resolver); this._internal.once('rejected', retVal._internal.rejector); retVal.parentPromise = this; + this.__childPromise = retVal; return (retVal); };