mjpeg.js
15.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.MJpegStream = void 0;
require("source-map-support/register");
var _lodash = _interopRequireDefault(require("lodash"));
var _logger = _interopRequireDefault(require("./logger"));
var _bluebird = _interopRequireDefault(require("bluebird"));
var _imageUtil = require("./image-util");
var _stream = require("stream");
var _node = require("./node");
var _axios = _interopRequireDefault(require("axios"));
let MJpegConsumer = null;
async function initMJpegConsumer() {
if (!MJpegConsumer) {
try {
MJpegConsumer = await (0, _node.requirePackage)('mjpeg-consumer');
} catch (ign) {}
}
if (!MJpegConsumer) {
throw new Error('mjpeg-consumer module is required to use MJPEG-over-HTTP features. ' + 'Please install it first (npm i -g mjpeg-consumer) and restart Appium.');
}
}
const MJPEG_SERVER_TIMEOUT_MS = 10000;
class MJpegStream extends _stream.Writable {
constructor(mJpegUrl, errorHandler = _lodash.default.noop, options = {}) {
super(options);
this.errorHandler = errorHandler;
this.url = mJpegUrl;
this.clear();
}
get lastChunkBase64() {
return !_lodash.default.isEmpty(this.lastChunk) && _lodash.default.isBuffer(this.lastChunk) ? this.lastChunk.toString('base64') : null;
}
async lastChunkPNG() {
if (_lodash.default.isEmpty(this.lastChunk) || !_lodash.default.isBuffer(this.lastChunk)) {
return null;
}
try {
const jpg = await (0, _imageUtil.getJimpImage)(this.lastChunk);
return await jpg.getBuffer(_imageUtil.MIME_PNG);
} catch (e) {
return null;
}
}
async lastChunkPNGBase64() {
const png = await this.lastChunkPNG();
return png ? png.toString('base64') : null;
}
clear() {
this.registerStartSuccess = null;
this.registerStartFailure = null;
this.responseStream = null;
this.consumer = null;
this.lastChunk = null;
this.updateCount = 0;
}
async start(serverTimeout = MJPEG_SERVER_TIMEOUT_MS) {
this.stop();
await initMJpegConsumer();
this.consumer = new MJpegConsumer();
const startPromise = new _bluebird.default((res, rej) => {
this.registerStartSuccess = res;
this.registerStartFailure = rej;
}).timeout(serverTimeout, `Waited ${serverTimeout}ms but the MJPEG server never sent any images`);
const url = this.url;
const onErr = err => {
this.lastChunk = null;
_logger.default.error(`Error getting MJpeg screenshot chunk: ${err.message}`);
this.errorHandler(err);
if (this.registerStartFailure) {
this.registerStartFailure(err);
}
};
const onClose = () => {
_logger.default.debug(`The connection to MJPEG server at ${url} has been closed`);
this.lastChunk = null;
};
try {
this.responseStream = (await (0, _axios.default)({
url,
responseType: 'stream',
timeout: serverTimeout
})).data;
} catch (e) {
return onErr(e);
}
this.responseStream.once('close', onClose).on('error', onErr).pipe(this.consumer).pipe(this);
await startPromise;
}
stop() {
if (!this.consumer) {
return;
}
this.responseStream.unpipe(this.consumer);
this.consumer.unpipe(this);
this.responseStream.destroy();
this.clear();
}
write(data) {
this.lastChunk = data;
this.updateCount++;
if (this.registerStartSuccess) {
this.registerStartSuccess();
this.registerStartSuccess = null;
}
}
}
exports.MJpegStream = MJpegStream;require('source-map-support').install();
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9tanBlZy5qcyJdLCJuYW1lcyI6WyJNSnBlZ0NvbnN1bWVyIiwiaW5pdE1KcGVnQ29uc3VtZXIiLCJpZ24iLCJFcnJvciIsIk1KUEVHX1NFUlZFUl9USU1FT1VUX01TIiwiTUpwZWdTdHJlYW0iLCJXcml0YWJsZSIsImNvbnN0cnVjdG9yIiwibUpwZWdVcmwiLCJlcnJvckhhbmRsZXIiLCJfIiwibm9vcCIsIm9wdGlvbnMiLCJ1cmwiLCJjbGVhciIsImxhc3RDaHVua0Jhc2U2NCIsImlzRW1wdHkiLCJsYXN0Q2h1bmsiLCJpc0J1ZmZlciIsInRvU3RyaW5nIiwibGFzdENodW5rUE5HIiwianBnIiwiZ2V0QnVmZmVyIiwiTUlNRV9QTkciLCJlIiwibGFzdENodW5rUE5HQmFzZTY0IiwicG5nIiwicmVnaXN0ZXJTdGFydFN1Y2Nlc3MiLCJyZWdpc3RlclN0YXJ0RmFpbHVyZSIsInJlc3BvbnNlU3RyZWFtIiwiY29uc3VtZXIiLCJ1cGRhdGVDb3VudCIsInN0YXJ0Iiwic2VydmVyVGltZW91dCIsInN0b3AiLCJzdGFydFByb21pc2UiLCJCIiwicmVzIiwicmVqIiwidGltZW91dCIsIm9uRXJyIiwiZXJyIiwibG9nIiwiZXJyb3IiLCJtZXNzYWdlIiwib25DbG9zZSIsImRlYnVnIiwicmVzcG9uc2VUeXBlIiwiZGF0YSIsIm9uY2UiLCJvbiIsInBpcGUiLCJ1bnBpcGUiLCJkZXN0cm95Iiwid3JpdGUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBR0EsSUFBSUEsYUFBYSxHQUFHLElBQXBCOztBQUtBLGVBQWVDLGlCQUFmLEdBQW9DO0FBQ2xDLE1BQUksQ0FBQ0QsYUFBTCxFQUFvQjtBQUNsQixRQUFJO0FBQ0ZBLE1BQUFBLGFBQWEsR0FBRyxNQUFNLDBCQUFlLGdCQUFmLENBQXRCO0FBQ0QsS0FGRCxDQUVFLE9BQU9FLEdBQVAsRUFBWSxDQUFFO0FBQ2pCOztBQUNELE1BQUks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U0FBTCxHQUFpQixJQUFqQjtBQUNELEtBSEQ7O0FBS0EsUUFBSTtBQUNGLFdBQUtZLGNBQUwsR0FBc0IsQ0FBQyxNQUFNLG9CQUFNO0FBQ2pDaEIsUUFBQUEsR0FEaUM7QUFFakNrQyxRQUFBQSxZQUFZLEVBQUUsUUFGbUI7QUFHakNSLFFBQUFBLE9BQU8sRUFBRU47QUFId0IsT0FBTixDQUFQLEVBSWxCZSxJQUpKO0FBS0QsS0FORCxDQU1FLE9BQU94QixDQUFQLEVBQVU7QUFDVixhQUFPZ0IsS0FBSyxDQUFDaEIsQ0FBRCxDQUFaO0FBQ0Q7O0FBRUQsU0FBS0ssY0FBTCxDQUNHb0IsSUFESCxDQUNRLE9BRFIsRUFDaUJKLE9BRGpCLEVBRUdLLEVBRkgsQ0FFTSxPQUZOLEVBRWVWLEtBRmYsRUFHR1csSUFISCxDQUdRLEtBQUtyQixRQUhiLEVBSUdxQixJQUpILENBSVEsSUFKUjtBQU1BLFVBQU1oQixZQUFOO0FBQ0Q7O0FBTURELEVBQUFBLElBQUksR0FBSTtBQUNOLFFBQUksQ0FBQyxLQUFLSixRQUFWLEVBQW9CO0FBQ2xCO0FBQ0Q7O0FBRUQsU0FBS0QsY0FBTCxDQUFvQnVCLE1BQXBCLENBQTJCLEtBQUt0QixRQUFoQztBQUNBLFNBQUtBLFFBQUwsQ0FBY3NCLE1BQWQsQ0FBcUIsSUFBckI7QUFDQSxTQUFLdkIsY0FBTCxDQUFvQndCLE9BQXBCO0FBQ0EsU0FBS3ZDLEtBQUw7QUFDRDs7QUFRRHdDLEVBQUFBLEtBQUssQ0FBRU4sSUFBRixFQUFRO0FBQ1gsU0FBSy9CLFNBQUwsR0FBaUIrQixJQUFqQjtBQUNBLFNBQUtqQixXQUFMOztBQUVBLFFBQUksS0FBS0osb0JBQVQsRUFBK0I7QUFDN0IsV0FBS0Esb0JBQUw7QUFDQSxXQUFLQSxvQkFBTCxHQUE0QixJQUE1QjtBQUNEO0FBQ0Y7O0FBN0pnQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgbG9nIGZyb20gJy4vbG9nZ2VyJztcbmltcG9ydCBCIGZyb20gJ2JsdWViaXJkJztcbmltcG9ydCB7IGdldEppbXBJbWFnZSwgTUlNRV9QTkcgfSBmcm9tICcuL2ltYWdlLXV0aWwnO1xuaW1wb3J0IHsgV3JpdGFibGUgfSBmcm9tICdzdHJlYW0nO1xuaW1wb3J0IHsgcmVxdWlyZVBhY2thZ2UgfSBmcm9tICcuL25vZGUnO1xuaW1wb3J0IGF4aW9zIGZyb20gJ2F4aW9zJztcblxuLy8gbGF6eSBsb2FkIHRoaXMsIGFzIGl0IG1pZ2h0IG5vdCBiZSBhdmFpbGFibGVcbmxldCBNSnBlZ0NvbnN1bWVyID0gbnVsbDtcblxuLyoqXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgYG1qcGVnLWNvbnN1bWVyYCBtb2R1bGUgaXMgbm90IGluc3RhbGxlZCBvciBjYW5ub3QgYmUgbG9hZGVkXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGluaXRNSnBlZ0NvbnN1bWVyICgpIHtcbiAgaWYgKCFNSnBlZ0NvbnN1bWVyKSB7XG4gICAgdHJ5IHtcbiAgICAgIE1KcGVnQ29uc3VtZXIgPSBhd2FpdCByZXF1aXJlUGFja2FnZSgnbWpwZWctY29uc3VtZXInKTtcbiAgICB9IGNhdGNoIChpZ24pIHt9XG4gIH1cbiAgaWYgKCFNSnBlZ0NvbnN1bWVyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdtanBlZy1jb25zdW1lciBtb2R1bGUgaXMgcmVxdWlyZWQgdG8gdXNlIE1KUEVHLW92ZXItSFRUUCBmZWF0dXJlcy4gJyArXG4gICAgICAgICAgICAgICAgICAgICdQbGVhc2UgaW5zdGFsbCBpdCBmaXJzdCAobnBtIGkgLWcgbWpwZWctY29uc3VtZXIpIGFuZCByZXN0YXJ0IEFwcGl1bS4nKTtcbiAgfVxufVxuXG4vLyBhbW91bnQgb2YgdGltZSB0byB3YWl0IGZvciB0aGUgZmlyc3QgaW1hZ2UgaW4gdGhlIHN0cmVhbVxuY29uc3QgTUpQRUdfU0VSVkVSX1RJTUVPVVRfTVMgPSAxMDAwMDtcblxuLyoqIENsYXNzIHdoaWNoIHN0b3JlcyB0aGUgbGFzdCBiaXQgb2YgZGF0YSBzdHJlYW1lZCBpbnRvIGl0ICovXG5jbGFzcyBNSnBlZ1N0cmVhbSBleHRlbmRzIFdyaXRhYmxlIHtcblxuICAvKipcbiAgICogQ3JlYXRlIGFuIE1KcGVnU3RyZWFtXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtSnBlZ1VybCAtIFVSTCBvZiBNSlBFRy1vdmVyLUhUVFAgc3RyZWFtXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb259IFtlcnJvckhhbmRsZXI9bm9vcF0gLSBhZGRpdGlvbmFsIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZVxuICAgKiBjYWxsZWQgaW4gdGhlIGNhc2Ugb2YgYW55IGVycm9ycy5cbiAgICogQHBhcmFtIHtvYmplY3R9IFtvcHRpb25zPXt9XSAtIE9wdGlvbnMgdG8gcGFzcyB0byB0aGUgV3JpdGFibGUgY29uc3RydWN0b3JcbiAgICovXG4gIGNvbnN0cnVjdG9yIChtSnBlZ1VybCwgZXJyb3JIYW5kbGVyID0gXy5ub29wLCBvcHRpb25zID0ge30pIHtcbiAgICBzdXBlcihvcHRpb25zKTtcblxuICAgIHRoaXMuZXJyb3JIYW5kbGVyID0gZXJyb3JIYW5kbGVyO1xuICAgIHRoaXMudXJsID0gbUpwZWdVcmw7XG4gICAgdGhpcy5jbGVhcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgYmFzZTY0LWVuY29kZWQgdmVyc2lvbiBvZiB0aGUgSlBFR1xuICAgKlxuICAgKiBAcmV0dXJucyB7P3N0cmluZ30gYmFzZTY0LWVuY29kZWQgSlBFRyBpbWFnZSBkYXRhXG4gICAqIG9yIGBudWxsYCBpZiBubyBpbWFnZSBjYW4gYmUgcGFyc2VkXG4gICAqL1xuICBnZXQgbGFzdENodW5rQmFzZTY0ICgpIHtcbiAgICByZXR1cm4gIV8uaXNFbXB0eSh0aGlzLmxhc3RDaHVuaykgJiYgXy5pc0J1ZmZlcih0aGlzLmxhc3RDaHVuaylcbiAgICAgID8gdGhpcy5sYXN0Q2h1bmsudG9TdHJpbmcoJ2Jhc2U2NCcpXG4gICAgICA6IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBQTkcgdmVyc2lvbiBvZiB0aGUgSlBFRyBidWZmZXJcbiAgICpcbiAgICogQHJldHVybnMgez9CdWZmZXJ9IFBORyBpbWFnZSBkYXRhIG9yIGBudWxsYCBpZiBubyBQTkdcbiAgICogaW1hZ2UgY2FuIGJlIHBhcnNlZFxuICAgKi9cbiAgYXN5bmMgbGFzdENodW5rUE5HICgpIHtcbiAgICBpZiAoXy5pc0VtcHR5KHRoaXMubGFzdENodW5rKSB8fCAhXy5pc0J1ZmZlcih0aGlzLmxhc3RDaHVuaykpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBqcGcgPSBhd2FpdCBnZXRKaW1wSW1hZ2UodGhpcy5sYXN0Q2h1bmspO1xuICAgICAgcmV0dXJuIGF3YWl0IGpwZy5nZXRCdWZmZXIoTUlNRV9QTkcpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGJhc2U2NC1lbmNvZGVkIHZlcnNpb24gb2YgdGhlIFBOR1xuICAgKlxuICAgKiBAcmV0dXJucyB7P3N0cmluZ30gYmFzZTY0LWVuY29kZWQgUE5HIGltYWdlIGRhdGFcbiAgICogb3IgYG51bGxgIGlmIG5vIGltYWdlIGNhbiBiZSBwYXJzZWRcbiAgICovXG4gIGFzeW5jIGxhc3RDaHVua1BOR0Jhc2U2NCAoKSB7XG4gICAgY29uc3QgcG5nID0gYXdhaXQgdGhpcy5sYXN0Q2h1bmtQTkcoKTtcbiAgICByZXR1cm4gcG5nID8gcG5nLnRvU3RyaW5nKCdiYXNlNjQnKSA6IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogUmVzZXQgaW50ZXJuYWwgc3RhdGVcbiAgICovXG4gIGNsZWFyICgpIHtcbiAgICB0aGlzLnJlZ2lzdGVyU3RhcnRTdWNjZXNzID0gbnVsbDtcbiAgICB0aGlzLnJlZ2lzdGVyU3RhcnRGYWlsdXJlID0gbnVsbDtcbiAgICB0aGlzLnJlc3BvbnNlU3RyZWFtID0gbnVsbDtcbiAgICB0aGlzLmNvbnN1bWVyID0gbnVsbDtcbiAgICB0aGlzLmxhc3RDaHVuayA9IG51bGw7XG4gICAgdGhpcy51cGRhdGVDb3VudCA9IDA7XG4gIH1cblxuICAvKipcbiAgICogU3RhcnQgcmVhZGluZyB0aGUgTUpwZWcgc3RyZWFtIGFuZCBzdG9yaW5nIHRoZSBsYXN0IGltYWdlXG4gICAqL1xuICBhc3luYyBzdGFydCAoc2VydmVyVGltZW91dCA9IE1KUEVHX1NFUlZFUl9USU1FT1VUX01TKSB7XG4gICAgLy8gZW5zdXJlIHdlJ3JlIG5vdCBzdGFydGVkIGFscmVhZHlcbiAgICB0aGlzLnN0b3AoKTtcblxuICAgIGF3YWl0IGluaXRNSnBlZ0NvbnN1bWVyKCk7XG5cbiAgICB0aGlzLmNvbnN1bWVyID0gbmV3IE1KcGVnQ29uc3VtZXIoKTtcblxuICAgIC8vIHVzZSB0aGUgZGVmZXJyZWQgcGF0dGVybiBzbyB3ZSBjYW4gd2FpdCBmb3IgdGhlIHN0YXJ0IG9mIHRoZSBzdHJlYW1cbiAgICAvLyBiYXNlZCBvbiB3aGF0IGNvbWVzIGluIGZyb20gYW4gZXh0ZXJuYWwgcGlwZVxuICAgIGNvbnN0IHN0YXJ0UHJvbWlzZSA9IG5ldyBCKChyZXMsIHJlaikgPT4ge1xuICAgICAgdGhpcy5yZWdpc3RlclN0YXJ0U3VjY2VzcyA9IHJlcztcbiAgICAgIHRoaXMucmVnaXN0ZXJTdGFydEZhaWx1cmUgPSByZWo7XG4gICAgfSlcbiAgICAvLyBzdGFydCBhIHRpbWVvdXQgc28gdGhhdCBpZiB0aGUgc2VydmVyIGRvZXMgbm90IHJldHVybiBkYXRhLCB3ZSBkb24ndFxuICAgIC8vIGJsb2NrIGZvcmV2ZXIuXG4gICAgICAudGltZW91dChzZXJ2ZXJUaW1lb3V0LFxuICAgICAgICBgV2FpdGVkICR7c2VydmVyVGltZW91dH1tcyBidXQgdGhlIE1KUEVHIHNlcnZlciBuZXZlciBzZW50IGFueSBpbWFnZXNgKTtcblxuICAgIGNvbnN0IHVybCA9IHRoaXMudXJsO1xuICAgIGNvbnN0IG9uRXJyID0gKGVycikgPT4ge1xuICAgICAgLy8gTWFrZSBzdXJlIHdlIGRvbid0IGdldCBhbiBvdXRkYXRlZCBzY3JlZW5zaG90IGlmIHRoZXJlIHdhcyBhbiBlcnJvclxuICAgICAgdGhpcy5sYXN0Q2h1bmsgPSBudWxsO1xuXG4gICAgICBsb2cuZXJyb3IoYEVycm9yIGdldHRpbmcgTUpwZWcgc2NyZWVuc2hvdCBjaHVuazogJHtlcnIubWVzc2FnZX1gKTtcbiAgICAgIHRoaXMuZXJyb3JIYW5kbGVyKGVycik7XG4gICAgICBpZiAodGhpcy5yZWdpc3RlclN0YXJ0RmFpbHVyZSkge1xuICAgICAgICB0aGlzLnJlZ2lzdGVyU3RhcnRGYWlsdXJlKGVycik7XG4gICAgICB9XG4gICAgfTtcbiAgICBjb25zdCBvbkNsb3NlID0gKCkgPT4ge1xuICAgICAgbG9nLmRlYnVnKGBUaGUgY29ubmVjdGlvbiB0byBNSlBFRyBzZXJ2ZXIgYXQgJHt1cmx9IGhhcyBiZWVuIGNsb3NlZGApO1xuICAgICAgdGhpcy5sYXN0Q2h1bmsgPSBudWxsO1xuICAgIH07XG5cbiAgICB0cnkge1xuICAgICAgdGhpcy5yZXNwb25zZVN0cmVhbSA9IChhd2FpdCBheGlvcyh7XG4gICAgICAgIHVybCxcbiAgICAgICAgcmVzcG9uc2VUeXBlOiAnc3RyZWFtJyxcbiAgICAgICAgdGltZW91dDogc2VydmVyVGltZW91dCxcbiAgICAgIH0pKS5kYXRhO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiBvbkVycihlKTtcbiAgICB9XG5cbiAgICB0aGlzLnJlc3BvbnNlU3RyZWFtXG4gICAgICAub25jZSgnY2xvc2UnLCBvbkNsb3NlKVxuICAgICAgLm9uKCdlcnJvcicsIG9uRXJyKSAvLyBlbnN1cmUgd2UgZG8gc29tZXRoaW5nIHdpdGggZXJyb3JzXG4gICAgICAucGlwZSh0aGlzLmNvbnN1bWVyKSAvLyBhbGxvdyBjaHVua2luZyBhbmQgdHJhbnNmb3JtaW5nIG9mIGpwZWcgZGF0YVxuICAgICAgLnBpcGUodGhpcyk7IC8vIHNlbmQgdGhlIGFjdHVhbCBqcGVncyB0byBvdXJzZWxmXG5cbiAgICBhd2FpdCBzdGFydFByb21pc2U7XG4gIH1cblxuICAvKipcbiAgICogU3RvcCByZWFkaW5nIHRoZSBNSnBlZyBzdHJlYW0uIEVuc3VyZSB3ZSBkaXNjb25uZWN0IGFsbCB0aGUgcGlwZXMgYW5kIHN0b3BcbiAgICogdGhlIEhUVFAgcmVxdWVzdCBpdHNlbGYuIFRoZW4gcmVzZXQgdGhlIHN0YXRlLlxuICAgKi9cbiAgc3RvcCAoKSB7XG4gICAgaWYgKCF0aGlzLmNvbnN1bWVyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5yZXNwb25zZVN0cmVhbS51bnBpcGUodGhpcy5jb25zdW1lcik7XG4gICAgdGhpcy5jb25zdW1lci51bnBpcGUodGhpcyk7XG4gICAgdGhpcy5yZXNwb25zZVN0cmVhbS5kZXN0cm95KCk7XG4gICAgdGhpcy5jbGVhcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIE92ZXJyaWRlIHRoZSBXcml0YWJsZSB3cml0ZSgpIG1ldGhvZCBpbiBvcmRlciB0byBzYXZlIHRoZSBsYXN0IGltYWdlIGFuZFxuICAgKiBsb2cgdGhlIG51bWJlciBvZiBpbWFnZXMgd2UgaGF2ZSByZWNlaXZlZFxuICAgKiBAb3ZlcnJpZGVcbiAgICogQHBhcmFtIHtCdWZmZXJ9IGRhdGEgLSBiaW5hcnkgZGF0YSBzdHJlYW1lZCBmcm9tIHRoZSBNSnBlZyBjb25zdW1lclxuICAgKi9cbiAgd3JpdGUgKGRhdGEpIHtcbiAgICB0aGlzLmxhc3RDaHVuayA9IGRhdGE7XG4gICAgdGhpcy51cGRhdGVDb3VudCsrO1xuXG4gICAgaWYgKHRoaXMucmVnaXN0ZXJTdGFydFN1Y2Nlc3MpIHtcbiAgICAgIHRoaXMucmVnaXN0ZXJTdGFydFN1Y2Nlc3MoKTtcbiAgICAgIHRoaXMucmVnaXN0ZXJTdGFydFN1Y2Nlc3MgPSBudWxsO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgeyBNSnBlZ1N0cmVhbSB9O1xuIl0sImZpbGUiOiJsaWIvbWpwZWcuanMiLCJzb3VyY2VSb290IjoiLi4vLi4ifQ==