1 | ;
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const tslib_1 = require("tslib");
|
4 | const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
5 | const FETCH_TIMEOUT_MS = 20000;
|
6 | const QUEUE_SIZE = 1000;
|
7 | const BATCH_SIZE = 10;
|
8 | class AsyncBlockIterator {
|
9 | constructor({ client, options: { indexStart, indexStop, monitor }, fetchTimeoutMS = FETCH_TIMEOUT_MS, batchSize = BATCH_SIZE, }) {
|
10 | this.client = client;
|
11 | this.mutableItems = [];
|
12 | this.mutableResolvers = [];
|
13 | this.mutableDone = false;
|
14 | this.mutableCurrentIndex = indexStart;
|
15 | this.mutableFetching = false;
|
16 | this.indexStop = indexStop;
|
17 | this.fetchTimeoutMS = fetchTimeoutMS;
|
18 | this.batchSize = batchSize;
|
19 | this.monitor = monitor === undefined ? undefined : monitor.at('async_block_iterator');
|
20 | }
|
21 | [Symbol.asyncIterator]() {
|
22 | return this;
|
23 | }
|
24 | async next() {
|
25 | if (!this.mutableDone) {
|
26 | this.fetch();
|
27 | }
|
28 | const item = this.mutableItems.shift();
|
29 | if (item !== undefined) {
|
30 | if (item.type === 'error') {
|
31 | return Promise.reject(item.error);
|
32 | }
|
33 | return Promise.resolve({ done: false, value: item.value });
|
34 | }
|
35 | if (this.mutableDone) {
|
36 | // tslint:disable-next-line no-any
|
37 | return Promise.resolve({ done: true });
|
38 | }
|
39 | // tslint:disable-next-line promise-must-complete
|
40 | return new Promise((resolve, reject) => {
|
41 | this.mutableResolvers.push({ resolve, reject });
|
42 | });
|
43 | }
|
44 | write(value) {
|
45 | this.push({ type: 'value', value });
|
46 | }
|
47 | error(error) {
|
48 | this.push({ type: 'error', error });
|
49 | }
|
50 | push(item) {
|
51 | if (this.mutableDone) {
|
52 | /* istanbul ignore next */
|
53 | throw new Error('AsyncBlockIterator already ended');
|
54 | }
|
55 | const resolver = this.mutableResolvers.shift();
|
56 | if (resolver !== undefined) {
|
57 | const { resolve, reject } = resolver;
|
58 | if (item.type === 'error') {
|
59 | reject(item.error);
|
60 | }
|
61 | else {
|
62 | resolve({ done: false, value: item.value });
|
63 | }
|
64 | }
|
65 | else {
|
66 | this.mutableItems.push(item);
|
67 | }
|
68 | }
|
69 | done() {
|
70 | // tslint:disable-next-line no-any
|
71 | this.mutableResolvers.forEach(({ resolve }) => resolve({ done: true }));
|
72 | // tslint:disable-next-line no-any
|
73 | this.mutableResolvers = [];
|
74 | this.mutableDone = true;
|
75 | }
|
76 | fetch() {
|
77 | if (this.mutableFetching) {
|
78 | return;
|
79 | }
|
80 | this.mutableFetching = true;
|
81 | this.asyncFetch()
|
82 | .then(() => {
|
83 | this.mutableFetching = false;
|
84 | })
|
85 | .catch((error) => {
|
86 | this.mutableFetching = false;
|
87 | this.error(error);
|
88 | });
|
89 | }
|
90 | async asyncFetch() {
|
91 | let startHeight = this.mutableStartHeight;
|
92 | let indexIn = this.mutableCurrentIndex;
|
93 | if (startHeight === undefined || indexIn === undefined) {
|
94 | const blockCount = await this.client.getBlockCount(this.monitor);
|
95 | if (startHeight === undefined) {
|
96 | startHeight = blockCount - 1;
|
97 | this.mutableStartHeight = startHeight;
|
98 | }
|
99 | if (indexIn === undefined) {
|
100 | indexIn = blockCount - 1;
|
101 | this.mutableCurrentIndex = indexIn;
|
102 | }
|
103 | }
|
104 | const index = indexIn;
|
105 | const incIndex = (value) => {
|
106 | if (this.mutableCurrentIndex === undefined) {
|
107 | throw new Error('Something went wrong!');
|
108 | }
|
109 | this.mutableCurrentIndex += value;
|
110 | };
|
111 | if (this.indexStop !== undefined && index >= this.indexStop) {
|
112 | this.done();
|
113 | }
|
114 | else if (index >= startHeight) {
|
115 | const [block, newStartHeight] = await Promise.all([
|
116 | this.fetchOne(index),
|
117 | // Refresh the block count in case we got behind somehow
|
118 | this.client.getBlockCount(this.monitor),
|
119 | ]);
|
120 | incIndex(1);
|
121 | this.write(block);
|
122 | this.mutableStartHeight = newStartHeight;
|
123 | }
|
124 | else {
|
125 | let toFetch = Math.min(QUEUE_SIZE - this.mutableItems.length, startHeight - index);
|
126 | if (this.indexStop !== undefined) {
|
127 | toFetch = Math.min(toFetch, this.indexStop - index);
|
128 | }
|
129 | // tslint:disable-next-line no-loop-statement
|
130 | for (const chunk of lodash_1.default.chunk(lodash_1.default.range(0, toFetch), this.batchSize)) {
|
131 | const blocks = await Promise.all(chunk.map(async (offset) => this.fetchOne(index + offset, true)));
|
132 | incIndex(chunk.length);
|
133 | blocks.forEach((block) => this.write(block));
|
134 | }
|
135 | }
|
136 | }
|
137 | async fetchOne(index, isBatch = false) {
|
138 | try {
|
139 | // tslint:disable-next-line no-unnecessary-local-variable prefer-immediate-return
|
140 | const block = await this.client.getBlock(index, isBatch
|
141 | ? {
|
142 | monitor: this.monitor,
|
143 | }
|
144 | : {
|
145 | timeoutMS: this.fetchTimeoutMS,
|
146 | monitor: this.monitor,
|
147 | });
|
148 | // tslint:disable-next-line no-var-before-return
|
149 | return block;
|
150 | }
|
151 | catch (error) {
|
152 | if (error.code === 'UNKNOWN_BLOCK') {
|
153 | return this.fetchOne(index, isBatch);
|
154 | }
|
155 | throw error;
|
156 | }
|
157 | }
|
158 | }
|
159 | exports.AsyncBlockIterator = AsyncBlockIterator;
|
160 |
|
161 | //# sourceMappingURL=data:application/json;charset=utf8;base64,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dkIsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO2FBQzlDO1NBQ0Y7SUFDSCxDQUFDO0lBRU8sS0FBSyxDQUFDLFFBQVEsQ0FBQyxLQUFhLEVBQUUsT0FBTyxHQUFHLEtBQUs7UUFDbkQsSUFBSTtZQUNGLGlGQUFpRjtZQUNqRixNQUFNLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUN0QyxLQUFLLEVBQ0wsT0FBTztnQkFDTCxDQUFDLENBQUM7b0JBQ0UsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO2lCQUN0QjtnQkFDSCxDQUFDLENBQUM7b0JBQ0UsU0FBUyxFQUFFLElBQUksQ0FBQyxjQUFjO29CQUM5QixPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU87aUJBQ3RCLENBQ04sQ0FBQztZQUVGLGdEQUFnRDtZQUNoRCxPQUFPLEtBQUssQ0FBQztTQUNkO1FBQUMsT0FBTyxLQUFLLEVBQUU7WUFDZCxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssZUFBZSxFQUFFO2dCQUNsQyxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO2FBQ3RDO1lBRUQsTUFBTSxLQUFjLENBQUM7U0FDdEI7SUFDSCxDQUFDO0NBQ0Y7QUEzTEQsZ0RBMkxDIiwiZmlsZSI6Im5lby1vbmUtY2xpZW50LWNvcmUvc3JjL0FzeW5jQmxvY2tJdGVyYXRvci5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJsb2NrLCBHZXRPcHRpb25zLCBJdGVyT3B0aW9ucyB9IGZyb20gJ0BuZW8tb25lL2NsaWVudC1jb21tb24nO1xuaW1wb3J0IHsgTW9uaXRvciB9IGZyb20gJ0BuZW8tb25lL21vbml0b3InO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcblxudHlwZSBJdGVtID0geyByZWFkb25seSB0eXBlOiAndmFsdWUnOyByZWFkb25seSB2YWx1ZTogQmxvY2sgfSB8IHsgcmVhZG9ubHkgdHlwZTogJ2Vycm9yJzsgcmVhZG9ubHkgZXJyb3I6IEVycm9yIH07XG5pbnRlcmZhY2UgUmVzb2x2ZXIge1xuICByZWFkb25seSByZXNvbHZlOiAodmFsdWU6IEl0ZXJhdG9yUmVzdWx0PEJsb2NrPikgPT4gdm9pZDtcbiAgcmVhZG9ubHkgcmVqZWN0OiAocmVhc29uOiBFcnJvcikgPT4gdm9pZDtcbn1cblxuaW50ZXJmYWNlIENsaWVudCB7XG4gIHJlYWRvbmx5IGdldEJsb2NrQ291bnQ6IChtb25pdG9yPzogTW9uaXRvcikgPT4gUHJvbWlzZTxudW1iZXI+O1xuICByZWFkb25seSBnZXRCbG9jazogKGluZGV4OiBudW1iZXIsIG9wdGlvbnM/OiBHZXRPcHRpb25zKSA9PiBQcm9taXNlPEJsb2NrPjtcbn1cblxuaW50ZXJmYWNlIEFzeW5jQmxvY2tJdGVyYXRvck9wdGlvbnMge1xuICByZWFkb25seSBjbGllbnQ6IENsaWVudDtcbiAgcmVhZG9ubHkgb3B0aW9uczogSXRlck9wdGlvbnM7XG4gIHJlYWRvbmx5IGZldGNoVGltZW91dE1TPzogbnVtYmVyO1xuICByZWFkb25seSBiYXRjaFNpemU/OiBudW1iZXI7XG59XG5cbmNvbnN0IEZFVENIX1RJTUVPVVRfTVMgPSAyMDAwMDtcbmNvbnN0IFFVRVVFX1NJWkUgPSAxMDAwO1xuY29uc3QgQkFUQ0hfU0laRSA9IDEwO1xuXG5leHBvcnQgY2xhc3MgQXN5bmNCbG9ja0l0ZXJhdG9yIGltcGxlbWVudHMgQXN5bmNJdGVyYXRvcjxCbG9jaz4ge1xuICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudDogQ2xpZW50O1xuICBwcml2YXRlIHJlYWRvbmx5IG11dGFibGVJdGVtczogSXRlbVtdO1xuICBwcml2YXRlIG11dGFibGVSZXNvbHZlcnM6IFJlc29sdmVyW107XG4gIHByaXZhdGUgbXV0YWJsZURvbmU6IGJvb2xlYW47XG4gIHByaXZhdGUgbXV0YWJsZUN1cnJlbnRJbmRleDogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIG11dGFibGVGZXRjaGluZzogYm9vbGVhbjtcbiAgcHJpdmF0ZSBtdXRhYmxlU3RhcnRIZWlnaHQ6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSByZWFkb25seSBpbmRleFN0b3A6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSByZWFkb25seSBmZXRjaFRpbWVvdXRNUzogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IGJhdGNoU2l6ZTogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IG1vbml0b3I6IE1vbml0b3IgfCB1bmRlZmluZWQ7XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKHtcbiAgICBjbGllbnQsXG4gICAgb3B0aW9uczogeyBpbmRleFN0YXJ0LCBpbmRleFN0b3AsIG1vbml0b3IgfSxcbiAgICBmZXRjaFRpbWVvdXRNUyA9IEZFVENIX1RJTUVPVVRfTVMsXG4gICAgYmF0Y2hTaXplID0gQkFUQ0hfU0laRSxcbiAgfTogQXN5bmNCbG9ja0l0ZXJhdG9yT3B0aW9ucykge1xuICAgIHRoaXMuY2xpZW50ID0gY2xpZW50O1xuICAgIHRoaXMubXV0YWJsZUl0ZW1zID0gW107XG4gICAgdGhpcy5tdXRhYmxlUmVzb2x2ZXJzID0gW107XG4gICAgdGhpcy5tdXRhYmxlRG9uZSA9IGZhbHNlO1xuICAgIHRoaXMubXV0YWJsZUN1cnJlbnRJbmRleCA9IGluZGV4U3RhcnQ7XG4gICAgdGhpcy5tdXRhYmxlRmV0Y2hpbmcgPSBmYWxzZTtcbiAgICB0aGlzLmluZGV4U3RvcCA9IGluZGV4U3RvcDtcbiAgICB0aGlzLmZldGNoVGltZW91dE1TID0gZmV0Y2hUaW1lb3V0TVM7XG4gICAgdGhpcy5iYXRjaFNpemUgPSBiYXRjaFNpemU7XG4gICAgdGhpcy5tb25pdG9yID0gbW9uaXRvciA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogbW9uaXRvci5hdCgnYXN5bmNfYmxvY2tfaXRlcmF0b3InKTtcbiAgfVxuXG4gIHB1YmxpYyBbU3ltYm9sLmFzeW5jSXRlcmF0b3JdKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIG5leHQoKTogUHJvbWlzZTxJdGVyYXRvclJlc3VsdDxCbG9jaz4+IHtcbiAgICBpZiAoIXRoaXMubXV0YWJsZURvbmUpIHtcbiAgICAgIHRoaXMuZmV0Y2goKTtcbiAgICB9XG5cbiAgICBjb25zdCBpdGVtID0gdGhpcy5tdXRhYmxlSXRlbXMuc2hpZnQoKTtcbiAgICBpZiAoaXRlbSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoaXRlbS50eXBlID09PSAnZXJyb3InKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChpdGVtLmVycm9yKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IGRvbmU6IGZhbHNlLCB2YWx1ZTogaXRlbS52YWx1ZSB9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5tdXRhYmxlRG9uZSkge1xuICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLWFueVxuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IGRvbmU6IHRydWUgfSBhcyBhbnkpO1xuICAgIH1cblxuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBwcm9taXNlLW11c3QtY29tcGxldGVcbiAgICByZXR1cm4gbmV3IFByb21pc2U8SXRlcmF0b3JSZXN1bHQ8QmxvY2s+PigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLm11dGFibGVSZXNvbHZlcnMucHVzaCh7IHJlc29sdmUsIHJlamVjdCB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgd3JpdGUodmFsdWU6IEJsb2NrKTogdm9pZCB7XG4gICAgdGhpcy5wdXNoKHsgdHlwZTogJ3ZhbHVlJywgdmFsdWUgfSk7XG4gIH1cblxuICBwcml2YXRlIGVycm9yKGVycm9yOiBFcnJvcik6IHZvaWQge1xuICAgIHRoaXMucHVzaCh7IHR5cGU6ICdlcnJvcicsIGVycm9yIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBwdXNoKGl0ZW06IEl0ZW0pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5tdXRhYmxlRG9uZSkge1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgIHRocm93IG5ldyBFcnJvcignQXN5bmNCbG9ja0l0ZXJhdG9yIGFscmVhZHkgZW5kZWQnKTtcbiAgICB9XG5cbiAgICBjb25zdCByZXNvbHZlciA9IHRoaXMubXV0YWJsZVJlc29sdmVycy5zaGlmdCgpO1xuICAgIGlmIChyZXNvbHZlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCB7IHJlc29sdmUsIHJlamVjdCB9ID0gcmVzb2x2ZXI7XG4gICAgICBpZiAoaXRlbS50eXBlID09PSAnZXJyb3InKSB7XG4gICAgICAgIHJlamVjdChpdGVtLmVycm9yKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc29sdmUoeyBkb25lOiBmYWxzZSwgdmFsdWU6IGl0ZW0udmFsdWUgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubXV0YWJsZUl0ZW1zLnB1c2goaXRlbSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBkb25lKCk6IHZvaWQge1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBuby1hbnlcbiAgICB0aGlzLm11dGFibGVSZXNvbHZlcnMuZm9yRWFjaCgoeyByZXNvbHZlIH0pID0+IHJlc29sdmUoeyBkb25lOiB0cnVlIH0gYXMgYW55KSk7XG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLWFueVxuICAgIHRoaXMubXV0YWJsZVJlc29sdmVycyA9IFtdO1xuICAgIHRoaXMubXV0YWJsZURvbmUgPSB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBmZXRjaCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5tdXRhYmxlRmV0Y2hpbmcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5tdXRhYmxlRmV0Y2hpbmcgPSB0cnVlO1xuICAgIHRoaXMuYXN5bmNGZXRjaCgpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHRoaXMubXV0YWJsZUZldGNoaW5nID0gZmFsc2U7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICB0aGlzLm11dGFibGVGZXRjaGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmVycm9yKGVycm9yKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBhc3luY0ZldGNoKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxldCBzdGFydEhlaWdodCA9IHRoaXMubXV0YWJsZVN0YXJ0SGVpZ2h0O1xuICAgIGxldCBpbmRleEluID0gdGhpcy5tdXRhYmxlQ3VycmVudEluZGV4O1xuICAgIGlmIChzdGFydEhlaWdodCA9PT0gdW5kZWZpbmVkIHx8IGluZGV4SW4gPT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgYmxvY2tDb3VudCA9IGF3YWl0IHRoaXMuY2xpZW50LmdldEJsb2NrQ291bnQodGhpcy5tb25pdG9yKTtcbiAgICAgIGlmIChzdGFydEhlaWdodCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHN0YXJ0SGVpZ2h0ID0gYmxvY2tDb3VudCAtIDE7XG4gICAgICAgIHRoaXMubXV0YWJsZVN0YXJ0SGVpZ2h0ID0gc3RhcnRIZWlnaHQ7XG4gICAgICB9XG4gICAgICBpZiAoaW5kZXhJbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGluZGV4SW4gPSBibG9ja0NvdW50IC0gMTtcbiAgICAgICAgdGhpcy5tdXRhYmxlQ3VycmVudEluZGV4ID0gaW5kZXhJbjtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgaW5kZXggPSBpbmRleEluO1xuXG4gICAgY29uc3QgaW5jSW5kZXggPSAodmFsdWU6IG51bWJlcikgPT4ge1xuICAgICAgaWYgKHRoaXMubXV0YWJsZUN1cnJlbnRJbmRleCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignU29tZXRoaW5nIHdlbnQgd3JvbmchJyk7XG4gICAgICB9XG4gICAgICB0aGlzLm11dGFibGVDdXJyZW50SW5kZXggKz0gdmFsdWU7XG4gICAgfTtcblxuICAgIGlmICh0aGlzLmluZGV4U3RvcCAhPT0gdW5kZWZpbmVkICYmIGluZGV4ID49IHRoaXMuaW5kZXhTdG9wKSB7XG4gICAgICB0aGlzLmRvbmUoKTtcbiAgICB9IGVsc2UgaWYgKGluZGV4ID49IHN0YXJ0SGVpZ2h0KSB7XG4gICAgICBjb25zdCBbYmxvY2ssIG5ld1N0YXJ0SGVpZ2h0XSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgdGhpcy5mZXRjaE9uZShpbmRleCksXG4gICAgICAgIC8vIFJlZnJlc2ggdGhlIGJsb2NrIGNvdW50IGluIGNhc2Ugd2UgZ290IGJlaGluZCBzb21laG93XG4gICAgICAgIHRoaXMuY2xpZW50LmdldEJsb2NrQ291bnQodGhpcy5tb25pdG9yKSxcbiAgICAgIF0pO1xuXG4gICAgICBpbmNJbmRleCgxKTtcbiAgICAgIHRoaXMud3JpdGUoYmxvY2spO1xuICAgICAgdGhpcy5tdXRhYmxlU3RhcnRIZWlnaHQgPSBuZXdTdGFydEhlaWdodDtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IHRvRmV0Y2ggPSBNYXRoLm1pbihRVUVVRV9TSVpFIC0gdGhpcy5tdXRhYmxlSXRlbXMubGVuZ3RoLCBzdGFydEhlaWdodCAtIGluZGV4KTtcblxuICAgICAgaWYgKHRoaXMuaW5kZXhTdG9wICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdG9GZXRjaCA9IE1hdGgubWluKHRvRmV0Y2gsIHRoaXMuaW5kZXhTdG9wIC0gaW5kZXgpO1xuICAgICAgfVxuXG4gICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmUgbm8tbG9vcC1zdGF0ZW1lbnRcbiAgICAgIGZvciAoY29uc3QgY2h1bmsgb2YgXy5jaHVuayhfLnJhbmdlKDAsIHRvRmV0Y2gpLCB0aGlzLmJhdGNoU2l6ZSkpIHtcbiAgICAgICAgY29uc3QgYmxvY2tzID0gYXdhaXQgUHJvbWlzZS5hbGwoY2h1bmsubWFwKGFzeW5jIChvZmZzZXQpID0+IHRoaXMuZmV0Y2hPbmUoaW5kZXggKyBvZmZzZXQsIHRydWUpKSk7XG5cbiAgICAgICAgaW5jSW5kZXgoY2h1bmsubGVuZ3RoKTtcbiAgICAgICAgYmxvY2tzLmZvckVhY2goKGJsb2NrKSA9PiB0aGlzLndyaXRlKGJsb2NrKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBmZXRjaE9uZShpbmRleDogbnVtYmVyLCBpc0JhdGNoID0gZmFsc2UpOiBQcm9taXNlPEJsb2NrPiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBuby11bm5lY2Vzc2FyeS1sb2NhbC12YXJpYWJsZSBwcmVmZXItaW1tZWRpYXRlLXJldHVyblxuICAgICAgY29uc3QgYmxvY2sgPSBhd2FpdCB0aGlzLmNsaWVudC5nZXRCbG9jayhcbiAgICAgICAgaW5kZXgsXG4gICAgICAgIGlzQmF0Y2hcbiAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgbW9uaXRvcjogdGhpcy5tb25pdG9yLFxuICAgICAgICAgICAgfVxuICAgICAgICAgIDoge1xuICAgICAgICAgICAgICB0aW1lb3V0TVM6IHRoaXMuZmV0Y2hUaW1lb3V0TVMsXG4gICAgICAgICAgICAgIG1vbml0b3I6IHRoaXMubW9uaXRvcixcbiAgICAgICAgICAgIH0sXG4gICAgICApO1xuXG4gICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmUgbm8tdmFyLWJlZm9yZS1yZXR1cm5cbiAgICAgIHJldHVybiBibG9jaztcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yLmNvZGUgPT09ICdVTktOT1dOX0JMT0NLJykge1xuICAgICAgICByZXR1cm4gdGhpcy5mZXRjaE9uZShpbmRleCwgaXNCYXRjaCk7XG4gICAgICB9XG5cbiAgICAgIHRocm93IGVycm9yIGFzIEVycm9yO1xuICAgIH1cbiAgfVxufVxuIl19
|