@webex/web-client-media-engine 3.34.5 → 3.35.1
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/dist/cjs/index.js +335 -5
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +335 -5
- package/dist/esm/index.js.map +1 -1
- package/dist/types/index.d.ts +17 -2
- package/package.json +4 -3
package/dist/esm/index.js
CHANGED
|
@@ -7154,6 +7154,29 @@ function isValidActiveSpeakerNotificationMsg(msg) {
|
|
|
7154
7154
|
const maybeActiveSpeakerNotificationMsg = msg;
|
|
7155
7155
|
return Boolean(maybeActiveSpeakerNotificationMsg.seqNum && maybeActiveSpeakerNotificationMsg.csis);
|
|
7156
7156
|
}
|
|
7157
|
+
function isValidAV1Codec(msg) {
|
|
7158
|
+
if (typeof msg !== 'object' || msg === null) {
|
|
7159
|
+
return false;
|
|
7160
|
+
}
|
|
7161
|
+
const maybeAV1Codec = msg;
|
|
7162
|
+
return (maybeAV1Codec.levelIdx >= 0 &&
|
|
7163
|
+
maybeAV1Codec.tier >= 0 &&
|
|
7164
|
+
Boolean(maybeAV1Codec.maxWidth) &&
|
|
7165
|
+
Boolean(maybeAV1Codec.maxHeight) &&
|
|
7166
|
+
Boolean(maybeAV1Codec.maxPicSize) &&
|
|
7167
|
+
Boolean(maybeAV1Codec.maxDecodeRate));
|
|
7168
|
+
}
|
|
7169
|
+
function areAV1CodecsEqual(left, right) {
|
|
7170
|
+
if (left === undefined || right === undefined) {
|
|
7171
|
+
return left === right;
|
|
7172
|
+
}
|
|
7173
|
+
return (left.levelIdx === right.levelIdx &&
|
|
7174
|
+
left.tier === right.tier &&
|
|
7175
|
+
left.maxWidth === right.maxWidth &&
|
|
7176
|
+
left.maxHeight === right.maxHeight &&
|
|
7177
|
+
left.maxPicSize === right.maxPicSize &&
|
|
7178
|
+
left.maxDecodeRate === right.maxDecodeRate);
|
|
7179
|
+
}
|
|
7157
7180
|
|
|
7158
7181
|
class H264Codec {
|
|
7159
7182
|
constructor(maxFs, maxFps, maxMbps, maxWidth, maxHeight) {
|
|
@@ -7164,6 +7187,13 @@ class H264Codec {
|
|
|
7164
7187
|
this.maxHeight = maxHeight;
|
|
7165
7188
|
}
|
|
7166
7189
|
}
|
|
7190
|
+
function isValidH264Codec(msg) {
|
|
7191
|
+
if (typeof msg !== 'object' || msg === null) {
|
|
7192
|
+
return false;
|
|
7193
|
+
}
|
|
7194
|
+
const maybeH264Codec = msg;
|
|
7195
|
+
return Boolean(maybeH264Codec.maxFs && maybeH264Codec.maxFps && maybeH264Codec.maxMbps);
|
|
7196
|
+
}
|
|
7167
7197
|
function areH264CodecsEqual(left, right) {
|
|
7168
7198
|
if (left === undefined || right === undefined) {
|
|
7169
7199
|
return left === right;
|
|
@@ -7176,13 +7206,31 @@ function areH264CodecsEqual(left, right) {
|
|
|
7176
7206
|
}
|
|
7177
7207
|
|
|
7178
7208
|
class CodecInfo$1 {
|
|
7179
|
-
constructor(payloadType,
|
|
7209
|
+
constructor(payloadType, codec) {
|
|
7180
7210
|
this.payloadType = payloadType;
|
|
7181
|
-
|
|
7211
|
+
if (isValidAV1Codec(codec))
|
|
7212
|
+
this.av1 = codec;
|
|
7213
|
+
if (isValidH264Codec(codec))
|
|
7214
|
+
this.h264 = codec;
|
|
7215
|
+
}
|
|
7216
|
+
static fromH264(payloadType, h264) {
|
|
7217
|
+
return new CodecInfo$1(payloadType, h264);
|
|
7218
|
+
}
|
|
7219
|
+
static fromAv1(payloadType, av1) {
|
|
7220
|
+
return new CodecInfo$1(payloadType, av1);
|
|
7182
7221
|
}
|
|
7183
7222
|
}
|
|
7184
7223
|
function areCodecInfosEqual(left, right) {
|
|
7185
|
-
|
|
7224
|
+
if (left.payloadType !== right.payloadType) {
|
|
7225
|
+
return false;
|
|
7226
|
+
}
|
|
7227
|
+
if (isValidH264Codec(left.h264) && isValidH264Codec(right.h264)) {
|
|
7228
|
+
return areH264CodecsEqual(left.h264, right.h264);
|
|
7229
|
+
}
|
|
7230
|
+
if (isValidAV1Codec(left.av1) && isValidAV1Codec(right.av1)) {
|
|
7231
|
+
return areAV1CodecsEqual(left.av1, right.av1);
|
|
7232
|
+
}
|
|
7233
|
+
return false;
|
|
7186
7234
|
}
|
|
7187
7235
|
|
|
7188
7236
|
var JmpMsgType;
|
|
@@ -7736,6 +7784,7 @@ var WcmeErrorType;
|
|
|
7736
7784
|
WcmeErrorType["SET_SOURCE_STATE_OVERRIDE_FAILED"] = "SET_SOURCE_STATE_OVERRIDE_FAILED";
|
|
7737
7785
|
WcmeErrorType["DATA_CHANNEL_SEND_FAILED"] = "DATA_CHANNEL_SEND_FAILED";
|
|
7738
7786
|
WcmeErrorType["RENEW_PEER_CONNECTION_FAILED"] = "RENEW_PEER_CONNECTION_FAILED";
|
|
7787
|
+
WcmeErrorType["UNSUPPORTED_CONFIG"] = "UNSUPPORTED_CONFIG";
|
|
7739
7788
|
})(WcmeErrorType || (WcmeErrorType = {}));
|
|
7740
7789
|
class WcmeError {
|
|
7741
7790
|
constructor(type, message = '') {
|
|
@@ -10095,6 +10144,12 @@ class BrowserInfo {
|
|
|
10095
10144
|
}
|
|
10096
10145
|
BrowserInfo.browser = Bowser.getParser(window.navigator.userAgent);
|
|
10097
10146
|
|
|
10147
|
+
class CpuInfo {
|
|
10148
|
+
static getNumLogicalCores() {
|
|
10149
|
+
return navigator.hardwareConcurrency;
|
|
10150
|
+
}
|
|
10151
|
+
}
|
|
10152
|
+
|
|
10098
10153
|
var SystemInfoEvents;
|
|
10099
10154
|
(function (SystemInfoEvents) {
|
|
10100
10155
|
SystemInfoEvents["CpuPressureStateChange"] = "cpu-pressure-state-change";
|
|
@@ -10132,7 +10187,58 @@ var CapabilityState;
|
|
|
10132
10187
|
CapabilityState["NOT_CAPABLE"] = "not capable";
|
|
10133
10188
|
CapabilityState["CAPABLE"] = "capable";
|
|
10134
10189
|
CapabilityState["UNKNOWN"] = "unknown";
|
|
10135
|
-
})(CapabilityState || (CapabilityState = {}));
|
|
10190
|
+
})(CapabilityState || (CapabilityState = {}));
|
|
10191
|
+
class WebCapabilities {
|
|
10192
|
+
static isCapableOfBackgroundNoiseRemoval() {
|
|
10193
|
+
const numCores = CpuInfo.getNumLogicalCores();
|
|
10194
|
+
if (numCores === undefined) {
|
|
10195
|
+
return CapabilityState.UNKNOWN;
|
|
10196
|
+
}
|
|
10197
|
+
if (numCores < 2) {
|
|
10198
|
+
return CapabilityState.NOT_CAPABLE;
|
|
10199
|
+
}
|
|
10200
|
+
return CapabilityState.CAPABLE;
|
|
10201
|
+
}
|
|
10202
|
+
static isCapableOfVirtualBackground() {
|
|
10203
|
+
const numCores = CpuInfo.getNumLogicalCores();
|
|
10204
|
+
if (numCores === undefined) {
|
|
10205
|
+
return CapabilityState.UNKNOWN;
|
|
10206
|
+
}
|
|
10207
|
+
if (numCores < 2) {
|
|
10208
|
+
return CapabilityState.NOT_CAPABLE;
|
|
10209
|
+
}
|
|
10210
|
+
return CapabilityState.CAPABLE;
|
|
10211
|
+
}
|
|
10212
|
+
static isCapableOfReceiving1080pVideo() {
|
|
10213
|
+
const numCores = CpuInfo.getNumLogicalCores();
|
|
10214
|
+
if (numCores === undefined) {
|
|
10215
|
+
return CapabilityState.UNKNOWN;
|
|
10216
|
+
}
|
|
10217
|
+
if (numCores < 2) {
|
|
10218
|
+
return CapabilityState.NOT_CAPABLE;
|
|
10219
|
+
}
|
|
10220
|
+
return CapabilityState.CAPABLE;
|
|
10221
|
+
}
|
|
10222
|
+
static isCapableOfSending1080pVideo() {
|
|
10223
|
+
const numCores = CpuInfo.getNumLogicalCores();
|
|
10224
|
+
if (numCores === undefined) {
|
|
10225
|
+
return CapabilityState.UNKNOWN;
|
|
10226
|
+
}
|
|
10227
|
+
if (numCores < 8) {
|
|
10228
|
+
return CapabilityState.NOT_CAPABLE;
|
|
10229
|
+
}
|
|
10230
|
+
return CapabilityState.CAPABLE;
|
|
10231
|
+
}
|
|
10232
|
+
static supportsEncodedStreamTransforms() {
|
|
10233
|
+
return window.RTCRtpScriptTransform &&
|
|
10234
|
+
window.RTCRtpSender &&
|
|
10235
|
+
'transform' in RTCRtpSender.prototype &&
|
|
10236
|
+
window.RTCRtpReceiver &&
|
|
10237
|
+
'transform' in RTCRtpReceiver.prototype
|
|
10238
|
+
? CapabilityState.CAPABLE
|
|
10239
|
+
: CapabilityState.NOT_CAPABLE;
|
|
10240
|
+
}
|
|
10241
|
+
}
|
|
10136
10242
|
|
|
10137
10243
|
const simulcastMaxFrameSizes = {
|
|
10138
10244
|
0: '240',
|
|
@@ -11056,6 +11162,21 @@ class HomerMsg {
|
|
|
11056
11162
|
}
|
|
11057
11163
|
}
|
|
11058
11164
|
|
|
11165
|
+
var EncodedTransformType;
|
|
11166
|
+
(function (EncodedTransformType) {
|
|
11167
|
+
EncodedTransformType["AudioLevelMonitor"] = "audio-level-monitor";
|
|
11168
|
+
})(EncodedTransformType || (EncodedTransformType = {}));
|
|
11169
|
+
var MainMsgType;
|
|
11170
|
+
(function (MainMsgType) {
|
|
11171
|
+
MainMsgType["GetMetadata"] = "get-metadata";
|
|
11172
|
+
MainMsgType["ClearMetadata"] = "clear-metadata";
|
|
11173
|
+
})(MainMsgType || (MainMsgType = {}));
|
|
11174
|
+
var WorkerMsgType;
|
|
11175
|
+
(function (WorkerMsgType) {
|
|
11176
|
+
WorkerMsgType["Response"] = "response";
|
|
11177
|
+
WorkerMsgType["Log"] = "log";
|
|
11178
|
+
})(WorkerMsgType || (WorkerMsgType = {}));
|
|
11179
|
+
|
|
11059
11180
|
class MidPredictor {
|
|
11060
11181
|
constructor() {
|
|
11061
11182
|
this.currentMid = 0;
|
|
@@ -11236,6 +11357,7 @@ class ReceiveOnlyTransceiver extends Transceiver {
|
|
|
11236
11357
|
constructor(config) {
|
|
11237
11358
|
super(config);
|
|
11238
11359
|
this.metadata = { isActiveSpeaker: false };
|
|
11360
|
+
this.getEncodedStreamMetadataCallback = () => Promise.resolve(undefined);
|
|
11239
11361
|
this.munger = config.munger;
|
|
11240
11362
|
this._receiveSlot = new ReceiveSlot(() => {
|
|
11241
11363
|
if (!this._rtcRtpTransceiver.mid) {
|
|
@@ -11244,6 +11366,9 @@ class ReceiveOnlyTransceiver extends Transceiver {
|
|
|
11244
11366
|
return this.munger.getReceiverId();
|
|
11245
11367
|
}, this._rtcRtpTransceiver.receiver.track);
|
|
11246
11368
|
}
|
|
11369
|
+
setEncodedStreamMetadataCallback(callback) {
|
|
11370
|
+
this.getEncodedStreamMetadataCallback = callback;
|
|
11371
|
+
}
|
|
11247
11372
|
replaceTransceiver(newRtcRtpTransceiver) {
|
|
11248
11373
|
super.replaceTransceiver(newRtcRtpTransceiver);
|
|
11249
11374
|
this._receiveSlot._replaceTrack(newRtcRtpTransceiver.receiver.track);
|
|
@@ -11258,7 +11383,10 @@ class ReceiveOnlyTransceiver extends Transceiver {
|
|
|
11258
11383
|
getStats() {
|
|
11259
11384
|
return __awaiter(this, void 0, void 0, function* () {
|
|
11260
11385
|
const statsMap = new Map();
|
|
11261
|
-
const statsReport = yield
|
|
11386
|
+
const [statsReport, encodedStreamMetadata] = yield Promise.all([
|
|
11387
|
+
this.receiver.getStats(),
|
|
11388
|
+
this.getEncodedStreamMetadataCallback(),
|
|
11389
|
+
]);
|
|
11262
11390
|
statsReport.forEach((stats, key) => {
|
|
11263
11391
|
if (stats.type === 'inbound-rtp') {
|
|
11264
11392
|
stats.mid = this.mid;
|
|
@@ -11272,6 +11400,10 @@ class ReceiveOnlyTransceiver extends Transceiver {
|
|
|
11272
11400
|
stats.lastRequestedUpdateTimestamp = this.metadata.lastRequestedUpdateTimestamp;
|
|
11273
11401
|
stats.isActiveSpeaker = this.metadata.isActiveSpeaker;
|
|
11274
11402
|
stats.lastActiveSpeakerUpdateTimestamp = this.metadata.lastActiveSpeakerUpdateTimestamp;
|
|
11403
|
+
stats.maxAudioLevelFromRtpHeader =
|
|
11404
|
+
encodedStreamMetadata && 'maxAudioLevel' in encodedStreamMetadata
|
|
11405
|
+
? encodedStreamMetadata.maxAudioLevel
|
|
11406
|
+
: undefined;
|
|
11275
11407
|
Object.assign(stats, this.receiverId);
|
|
11276
11408
|
}
|
|
11277
11409
|
statsMap.set(key, stats);
|
|
@@ -15454,6 +15586,154 @@ const organizeTransceiverStats = (sendTransceivers, recvTransceivers, peerConnec
|
|
|
15454
15586
|
return result;
|
|
15455
15587
|
});
|
|
15456
15588
|
|
|
15589
|
+
var WorkerClass = null;
|
|
15590
|
+
|
|
15591
|
+
try {
|
|
15592
|
+
var WorkerThreads =
|
|
15593
|
+
typeof module !== 'undefined' && typeof module.require === 'function' && module.require('worker_threads') ||
|
|
15594
|
+
typeof __non_webpack_require__ === 'function' && __non_webpack_require__('worker_threads') ||
|
|
15595
|
+
typeof require === 'function' && require('worker_threads');
|
|
15596
|
+
WorkerClass = WorkerThreads.Worker;
|
|
15597
|
+
} catch(e) {} // eslint-disable-line
|
|
15598
|
+
|
|
15599
|
+
function decodeBase64$1(base64, enableUnicode) {
|
|
15600
|
+
return Buffer.from(base64, 'base64').toString(enableUnicode ? 'utf16' : 'utf8');
|
|
15601
|
+
}
|
|
15602
|
+
|
|
15603
|
+
function createBase64WorkerFactory$2(base64, sourcemapArg, enableUnicodeArg) {
|
|
15604
|
+
var sourcemap = sourcemapArg === undefined ? null : sourcemapArg;
|
|
15605
|
+
var enableUnicode = enableUnicodeArg === undefined ? false : enableUnicodeArg;
|
|
15606
|
+
var source = decodeBase64$1(base64, enableUnicode);
|
|
15607
|
+
var start = source.indexOf('\n', 10) + 1;
|
|
15608
|
+
var body = source.substring(start) + (sourcemap ? '\/\/# sourceMappingURL=' + sourcemap : '');
|
|
15609
|
+
return function WorkerFactory(options) {
|
|
15610
|
+
return new WorkerClass(body, Object.assign({}, options, { eval: true }));
|
|
15611
|
+
};
|
|
15612
|
+
}
|
|
15613
|
+
|
|
15614
|
+
function decodeBase64(base64, enableUnicode) {
|
|
15615
|
+
var binaryString = atob(base64);
|
|
15616
|
+
if (enableUnicode) {
|
|
15617
|
+
var binaryView = new Uint8Array(binaryString.length);
|
|
15618
|
+
for (var i = 0, n = binaryString.length; i < n; ++i) {
|
|
15619
|
+
binaryView[i] = binaryString.charCodeAt(i);
|
|
15620
|
+
}
|
|
15621
|
+
const decoder = new TextDecoder("utf-16le");
|
|
15622
|
+
return decoder.decode(new Uint16Array(binaryView.buffer));
|
|
15623
|
+
}
|
|
15624
|
+
return binaryString;
|
|
15625
|
+
}
|
|
15626
|
+
|
|
15627
|
+
function createURL(base64, sourcemapArg, enableUnicodeArg) {
|
|
15628
|
+
var sourcemap = sourcemapArg === undefined ? null : sourcemapArg;
|
|
15629
|
+
var enableUnicode = enableUnicodeArg === undefined ? false : enableUnicodeArg;
|
|
15630
|
+
var source = decodeBase64(base64, enableUnicode);
|
|
15631
|
+
var start = source.indexOf('\n', 10) + 1;
|
|
15632
|
+
var body = source.substring(start) + (sourcemap ? '\/\/# sourceMappingURL=' + sourcemap : '');
|
|
15633
|
+
var blob = new Blob([body], { type: 'application/javascript' });
|
|
15634
|
+
return URL.createObjectURL(blob);
|
|
15635
|
+
}
|
|
15636
|
+
|
|
15637
|
+
function createBase64WorkerFactory$1(base64, sourcemapArg, enableUnicodeArg) {
|
|
15638
|
+
var url;
|
|
15639
|
+
return function WorkerFactory(options) {
|
|
15640
|
+
url = url || createURL(base64, sourcemapArg, enableUnicodeArg);
|
|
15641
|
+
return new Worker(url, options);
|
|
15642
|
+
};
|
|
15643
|
+
}
|
|
15644
|
+
|
|
15645
|
+
var kIsNodeJS = Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]';
|
|
15646
|
+
|
|
15647
|
+
function isNodeJS() {
|
|
15648
|
+
return kIsNodeJS;
|
|
15649
|
+
}
|
|
15650
|
+
|
|
15651
|
+
function createBase64WorkerFactory(base64, sourcemapArg, enableUnicodeArg) {
|
|
15652
|
+
if (isNodeJS()) {
|
|
15653
|
+
return createBase64WorkerFactory$2(base64, sourcemapArg, enableUnicodeArg);
|
|
15654
|
+
}
|
|
15655
|
+
return createBase64WorkerFactory$1(base64, sourcemapArg, enableUnicodeArg);
|
|
15656
|
+
}
|
|
15657
|
+
|
|
15658
|
+
var WorkerFactory = /*#__PURE__*/createBase64WorkerFactory('Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24gKCkgewogICAgJ3VzZSBzdHJpY3QnOwoKICAgIHZhciBjb21tb25qc0dsb2JhbCA9IHR5cGVvZiBnbG9iYWxUaGlzICE9PSAndW5kZWZpbmVkJyA/IGdsb2JhbFRoaXMgOiB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdyA6IHR5cGVvZiBnbG9iYWwgIT09ICd1bmRlZmluZWQnID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgIT09ICd1bmRlZmluZWQnID8gc2VsZiA6IHt9OwoKICAgIHZhciBsb2dnZXIgPSB7ZXhwb3J0czoge319OwoKICAgIC8qIQ0KICAgICAqIGpzLWxvZ2dlciAtIGh0dHA6Ly9naXRodWIuY29tL2pvbm55cmVldmVzL2pzLWxvZ2dlcg0KICAgICAqIEpvbm55IFJlZXZlcywgaHR0cDovL2pvbm55cmVldmVzLmNvLnVrLw0KICAgICAqIGpzLWxvZ2dlciBtYXkgYmUgZnJlZWx5IGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS4NCiAgICAgKi8KCiAgICAoZnVuY3Rpb24gKG1vZHVsZSkgewogICAgKGZ1bmN0aW9uIChnbG9iYWwpIHsNCg0KICAgIAkvLyBUb3AgbGV2ZWwgbW9kdWxlIGZvciB0aGUgZ2xvYmFsLCBzdGF0aWMgbG9nZ2VyIGluc3RhbmNlLg0KICAgIAl2YXIgTG9nZ2VyID0geyB9Ow0KDQogICAgCS8vIEZvciB0aG9zZSB0aGF0IGFyZSBhdCBob21lIHRoYXQgYXJlIGtlZXBpbmcgc2NvcmUuDQogICAgCUxvZ2dlci5WRVJTSU9OID0gIjEuNi4xIjsNCg0KICAgIAkvLyBGdW5jdGlvbiB3aGljaCBoYW5kbGVzIGFsbCBpbmNvbWluZyBsb2cgbWVzc2FnZXMuDQogICAgCXZhciBsb2dIYW5kbGVyOw0KDQogICAgCS8vIE1hcCBvZiBDb250ZXh0dWFsTG9nZ2VyIGluc3RhbmNlcyBieSBuYW1lOyB1c2VkIGJ5IExvZ2dlci5nZXQoKSB0byByZXR1cm4gdGhlIHNhbWUgbmFtZWQgaW5zdGFuY2UuDQogICAgCXZhciBjb250ZXh0dWFsTG9nZ2Vyc0J5TmFtZU1hcCA9IHt9Ow0KDQogICAgCS8vIFBvbHlmaWxsIGZvciBFUzUncyBGdW5jdGlvbi5iaW5kLg0KICAgIAl2YXIgYmluZCA9IGZ1bmN0aW9uKHNjb3BlLCBmdW5jKSB7DQogICAgCQlyZXR1cm4gZnVuY3Rpb24oKSB7DQogICAgCQkJcmV0dXJuIGZ1bmMuYXBwbHkoc2NvcGUsIGFyZ3VtZW50cyk7DQogICAgCQl9Ow0KICAgIAl9Ow0KDQogICAgCS8vIFN1cGVyIGV4Y2l0aW5nIG9iamVjdCBtZXJnZXItbWF0cm9uIDkwMDAgYWRkaW5nIGFub3RoZXIgMTAwIGJ5dGVzIHRvIHlvdXIgZG93bmxvYWQuDQogICAgCXZhciBtZXJnZSA9IGZ1bmN0aW9uICgpIHsNCiAgICAJCXZhciBhcmdzID0gYXJndW1lbnRzLCB0YXJnZXQgPSBhcmdzWzBdLCBrZXksIGk7DQogICAgCQlmb3IgKGkgPSAxOyBpIDwgYXJncy5sZW5ndGg7IGkrKykgew0KICAgIAkJCWZvciAoa2V5IGluIGFyZ3NbaV0pIHsNCiAgICAJCQkJaWYgKCEoa2V5IGluIHRhcmdldCkgJiYgYXJnc1tpXS5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7DQogICAgCQkJCQl0YXJnZXRba2V5XSA9IGFyZ3NbaV1ba2V5XTsNCiAgICAJCQkJfQ0KICAgIAkJCX0NCiAgICAJCX0NCiAgICAJCXJldHVybiB0YXJnZXQ7DQogICAgCX07DQoNCiAgICAJLy8gSGVscGVyIHRvIGRlZmluZSBhIGxvZ2dpbmcgbGV2ZWwgb2JqZWN0OyBoZWxwcyB3aXRoIG9wdGltaXNhdGlvbi4NCiAgICAJdmFyIGRlZmluZUxvZ0xldmVsID0gZnVuY3Rpb24odmFsdWUsIG5hbWUpIHsNCiAgICAJCXJldHVybiB7IHZhbHVlOiB2YWx1ZSwgbmFtZTogbmFtZSB9Ow0KICAgIAl9Ow0KDQogICAgCS8vIFByZWRlZmluZWQgbG9nZ2luZyBsZXZlbHMuDQogICAgCUxvZ2dlci5UUkFDRSA9IGRlZmluZUxvZ0xldmVsKDEsICdUUkFDRScpOw0KICAgIAlMb2dnZXIuREVCVUcgPSBkZWZpbmVMb2dMZXZlbCgyLCAnREVCVUcnKTsNCiAgICAJTG9nZ2VyLklORk8gPSBkZWZpbmVMb2dMZXZlbCgzLCAnSU5GTycpOw0KICAgIAlMb2dnZXIuVElNRSA9IGRlZmluZUxvZ0xldmVsKDQsICdUSU1FJyk7DQogICAgCUxvZ2dlci5XQVJOID0gZGVmaW5lTG9nTGV2ZWwoNSwgJ1dBUk4nKTsNCiAgICAJTG9nZ2VyLkVSUk9SID0gZGVmaW5lTG9nTGV2ZWwoOCwgJ0VSUk9SJyk7DQogICAgCUxvZ2dlci5PRkYgPSBkZWZpbmVMb2dMZXZlbCg5OSwgJ09GRicpOw0KDQogICAgCS8vIElubmVyIGNsYXNzIHdoaWNoIHBlcmZvcm1zIHRoZSBidWxrIG9mIHRoZSB3b3JrOyBDb250ZXh0dWFsTG9nZ2VyIGluc3RhbmNlcyBjYW4gYmUgY29uZmlndXJlZCBpbmRlcGVuZGVudGx5DQogICAgCS8vIG9mIGVhY2ggb3RoZXIuDQogICAgCXZhciBDb250ZXh0dWFsTG9nZ2VyID0gZnVuY3Rpb24oZGVmYXVsdENvbnRleHQpIHsNCiAgICAJCXRoaXMuY29udGV4dCA9IGRlZmF1bHRDb250ZXh0Ow0KICAgIAkJdGhpcy5zZXRMZXZlbChkZWZhdWx0Q29udGV4dC5maWx0ZXJMZXZlbCk7DQogICAgCQl0aGlzLmxvZyA9IHRoaXMuaW5mbzsgIC8vIENvbnZlbmllbmNlIGFsaWFzLg0KICAgIAl9Ow0KDQogICAgCUNvbnRleHR1YWxMb2dnZXIucHJvdG90eXBlID0gew0KICAgIAkJLy8gQ2hhbmdlcyB0aGUgY3VycmVudCBsb2dnaW5nIGxldmVsIGZvciB0aGUgbG9nZ2luZyBpbnN0YW5jZS4NCiAgICAJCXNldExldmVsOiBmdW5jdGlvbiAobmV3TGV2ZWwpIHsNCiAgICAJCQkvLyBFbnN1cmUgdGhlIHN1cHBsaWVkIExldmVsIG9iamVjdCBsb29rcyB2YWxpZC4NCiAgICAJCQlpZiAobmV3TGV2ZWwgJiYgInZhbHVlIiBpbiBuZXdMZXZlbCkgew0KICAgIAkJCQl0aGlzLmNvbnRleHQuZmlsdGVyTGV2ZWwgPSBuZXdMZXZlbDsNCiAgICAJCQl9DQogICAgCQl9LA0KICAgIAkJDQogICAgCQkvLyBHZXRzIHRoZSBjdXJyZW50IGxvZ2dpbmcgbGV2ZWwgZm9yIHRoZSBsb2dnaW5nIGluc3RhbmNlDQogICAgCQlnZXRMZXZlbDogZnVuY3Rpb24gKCkgew0KICAgIAkJCXJldHVybiB0aGlzLmNvbnRleHQuZmlsdGVyTGV2ZWw7DQogICAgCQl9LA0KDQogICAgCQkvLyBJcyB0aGUgbG9nZ2VyIGNvbmZpZ3VyZWQgdG8gb3V0cHV0IG1lc3NhZ2VzIGF0IHRoZSBzdXBwbGllZCBsZXZlbD8NCiAgICAJCWVuYWJsZWRGb3I6IGZ1bmN0aW9uIChsdmwpIHsNCiAgICAJCQl2YXIgZmlsdGVyTGV2ZWwgPSB0aGlzLmNvbnRleHQuZmlsdGVyTGV2ZWw7DQogICAgCQkJcmV0dXJuIGx2bC52YWx1ZSA+PSBmaWx0ZXJMZXZlbC52YWx1ZTsNCiAgICAJCX0sDQoNCiAgICAJCXRyYWNlOiBmdW5jdGlvbiAoKSB7DQogICAgCQkJdGhpcy5pbnZva2UoTG9nZ2VyLlRSQUNFLCBhcmd1bWVudHMpOw0KICAgIAkJfSwNCg0KICAgIAkJZGVidWc6IGZ1bmN0aW9uICgpIHsNCiAgICAJCQl0aGlzLmludm9rZShMb2dnZXIuREVCVUcsIGFyZ3VtZW50cyk7DQogICAgCQl9LA0KDQogICAgCQlpbmZvOiBmdW5jdGlvbiAoKSB7DQogICAgCQkJdGhpcy5pbnZva2UoTG9nZ2VyLklORk8sIGFyZ3VtZW50cyk7DQogICAgCQl9LA0KDQogICAgCQl3YXJuOiBmdW5jdGlvbiAoKSB7DQogICAgCQkJdGhpcy5pbnZva2UoTG9nZ2VyLldBUk4sIGFyZ3VtZW50cyk7DQogICAgCQl9LA0KDQogICAgCQllcnJvcjogZnVuY3Rpb24gKCkgew0KICAgIAkJCXRoaXMuaW52b2tlKExvZ2dlci5FUlJPUiwgYXJndW1lbnRzKTsNCiAgICAJCX0sDQoNCiAgICAJCXRpbWU6IGZ1bmN0aW9uIChsYWJlbCkgew0KICAgIAkJCWlmICh0eXBlb2YgbGFiZWwgPT09ICdzdHJpbmcnICYmIGxhYmVsLmxlbmd0aCA+IDApIHsNCiAgICAJCQkJdGhpcy5pbnZva2UoTG9nZ2VyLlRJTUUsIFsgbGFiZWwsICdzdGFydCcgXSk7DQogICAgCQkJfQ0KICAgIAkJfSwNCg0KICAgIAkJdGltZUVuZDogZnVuY3Rpb24gKGxhYmVsKSB7DQogICAgCQkJaWYgKHR5cGVvZiBsYWJlbCA9PT0gJ3N0cmluZycgJiYgbGFiZWwubGVuZ3RoID4gMCkgew0KICAgIAkJCQl0aGlzLmludm9rZShMb2dnZXIuVElNRSwgWyBsYWJlbCwgJ2VuZCcgXSk7DQogICAgCQkJfQ0KICAgIAkJfSwNCg0KICAgIAkJLy8gSW52b2tlcyB0aGUgbG9nZ2VyIGNhbGxiYWNrIGlmIGl0J3Mgbm90IGJlaW5nIGZpbHRlcmVkLg0KICAgIAkJaW52b2tlOiBmdW5jdGlvbiAobGV2ZWwsIG1zZ0FyZ3MpIHsNCiAgICAJCQlpZiAobG9nSGFuZGxlciAmJiB0aGlzLmVuYWJsZWRGb3IobGV2ZWwpKSB7DQogICAgCQkJCWxvZ0hhbmRsZXIobXNnQXJncywgbWVyZ2UoeyBsZXZlbDogbGV2ZWwgfSwgdGhpcy5jb250ZXh0KSk7DQogICAgCQkJfQ0KICAgIAkJfQ0KICAgIAl9Ow0KDQogICAgCS8vIFByb3RlY3RlZCBpbnN0YW5jZSB3aGljaCBhbGwgY2FsbHMgdG8gdGhlIHRvIGxldmVsIGBMb2dnZXJgIG1vZHVsZSB3aWxsIGJlIHJvdXRlZCB0aHJvdWdoLg0KICAgIAl2YXIgZ2xvYmFsTG9nZ2VyID0gbmV3IENvbnRleHR1YWxMb2dnZXIoeyBmaWx0ZXJMZXZlbDogTG9nZ2VyLk9GRiB9KTsNCg0KICAgIAkvLyBDb25maWd1cmUgdGhlIGdsb2JhbCBMb2dnZXIgaW5zdGFuY2UuDQogICAgCShmdW5jdGlvbigpIHsNCiAgICAJCS8vIFNob3J0Y3V0IGZvciBvcHRpbWlzZXJzLg0KICAgIAkJdmFyIEwgPSBMb2dnZXI7DQoNCiAgICAJCUwuZW5hYmxlZEZvciA9IGJpbmQoZ2xvYmFsTG9nZ2VyLCBnbG9iYWxMb2dnZXIuZW5hYmxlZEZvcik7DQogICAgCQlMLnRyYWNlID0gYmluZChnbG9iYWxMb2dnZXIsIGdsb2JhbExvZ2dlci50cmFjZSk7DQogICAgCQlMLmRlYnVnID0gYmluZChnbG9iYWxMb2dnZXIsIGdsb2JhbExvZ2dlci5kZWJ1Zyk7DQogICAgCQlMLnRpbWUgPSBiaW5kKGdsb2JhbExvZ2dlciwgZ2xvYmFsTG9nZ2VyLnRpbWUpOw0KICAgIAkJTC50aW1lRW5kID0gYmluZChnbG9iYWxMb2dnZXIsIGdsb2JhbExvZ2dlci50aW1lRW5kKTsNCiAgICAJCUwuaW5mbyA9IGJpbmQoZ2xvYmFsTG9nZ2VyLCBnbG9iYWxMb2dnZXIuaW5mbyk7DQogICAgCQlMLndhcm4gPSBiaW5kKGdsb2JhbExvZ2dlciwgZ2xvYmFsTG9nZ2VyLndhcm4pOw0KICAgIAkJTC5lcnJvciA9IGJpbmQoZ2xvYmFsTG9nZ2VyLCBnbG9iYWxMb2dnZXIuZXJyb3IpOw0KDQogICAgCQkvLyBEb24ndCBmb3JnZXQgdGhlIGNvbnZlbmllbmNlIGFsaWFzIQ0KICAgIAkJTC5sb2cgPSBMLmluZm87DQogICAgCX0oKSk7DQoNCiAgICAJLy8gU2V0IHRoZSBnbG9iYWwgbG9nZ2luZyBoYW5kbGVyLiAgVGhlIHN1cHBsaWVkIGZ1bmN0aW9uIHNob3VsZCBleHBlY3QgdHdvIGFyZ3VtZW50cywgdGhlIGZpcnN0IGJlaW5nIGFuIGFyZ3VtZW50cw0KICAgIAkvLyBvYmplY3Qgd2l0aCB0aGUgc3VwcGxpZWQgbG9nIG1lc3NhZ2VzIGFuZCB0aGUgc2Vjb25kIGJlaW5nIGEgY29udGV4dCBvYmplY3Qgd2hpY2ggY29udGFpbnMgYSBoYXNoIG9mIHN0YXRlZnVsDQogICAgCS8vIHBhcmFtZXRlcnMgd2hpY2ggdGhlIGxvZ2dpbmcgZnVuY3Rpb24gY2FuIGNvbnN1bWUuDQogICAgCUxvZ2dlci5zZXRIYW5kbGVyID0gZnVuY3Rpb24gKGZ1bmMpIHsNCiAgICAJCWxvZ0hhbmRsZXIgPSBmdW5jOw0KICAgIAl9Ow0KDQogICAgCS8vIFNldHMgdGhlIGdsb2JhbCBsb2dnaW5nIGZpbHRlciBsZXZlbCB3aGljaCBhcHBsaWVzIHRvICphbGwqIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCwgYW5kIGZ1dHVyZSBMb2dnZXIgaW5zdGFuY2VzLg0KICAgIAkvLyAobm90ZSB0aGF0IG5hbWVkIGxvZ2dlcnMgKHJldHJpZXZlZCB2aWEgYExvZ2dlci5nZXRgKSBjYW4gYmUgY29uZmlndXJlZCBpbmRlcGVuZGVudGx5IGlmIHJlcXVpcmVkKS4NCiAgICAJTG9nZ2VyLnNldExldmVsID0gZnVuY3Rpb24obGV2ZWwpIHsNCiAgICAJCS8vIFNldCB0aGUgZ2xvYmFsTG9nZ2VyJ3MgbGV2ZWwuDQogICAgCQlnbG9iYWxMb2dnZXIuc2V0TGV2ZWwobGV2ZWwpOw0KDQogICAgCQkvLyBBcHBseSB0aGlzIGxldmVsIHRvIGFsbCByZWdpc3RlcmVkIGNvbnRleHR1YWwgbG9nZ2Vycy4NCiAgICAJCWZvciAodmFyIGtleSBpbiBjb250ZXh0dWFsTG9nZ2Vyc0J5TmFtZU1hcCkgew0KICAgIAkJCWlmIChjb250ZXh0dWFsTG9nZ2Vyc0J5TmFtZU1hcC5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7DQogICAgCQkJCWNvbnRleHR1YWxMb2dnZXJzQnlOYW1lTWFwW2tleV0uc2V0TGV2ZWwobGV2ZWwpOw0KICAgIAkJCX0NCiAgICAJCX0NCiAgICAJfTsNCg0KICAgIAkvLyBHZXRzIHRoZSBnbG9iYWwgbG9nZ2luZyBmaWx0ZXIgbGV2ZWwNCiAgICAJTG9nZ2VyLmdldExldmVsID0gZnVuY3Rpb24oKSB7DQogICAgCQlyZXR1cm4gZ2xvYmFsTG9nZ2VyLmdldExldmVsKCk7DQogICAgCX07DQoNCiAgICAJLy8gUmV0cmlldmUgYSBDb250ZXh0dWFsTG9nZ2VyIGluc3RhbmNlLiAgTm90ZSB0aGF0IG5hbWVkIGxvZ2dlcnMgYXV0b21hdGljYWxseSBpbmhlcml0IHRoZSBnbG9iYWwgbG9nZ2VyJ3MgbGV2ZWwsDQogICAgCS8vIGRlZmF1bHQgY29udGV4dCBhbmQgbG9nIGhhbmRsZXIuDQogICAgCUxvZ2dlci5nZXQgPSBmdW5jdGlvbiAobmFtZSkgew0KICAgIAkJLy8gQWxsIGxvZ2dlciBpbnN0YW5jZXMgYXJlIGNhY2hlZCBzbyB0aGV5IGNhbiBiZSBjb25maWd1cmVkIGFoZWFkIG9mIHVzZS4NCiAgICAJCXJldHVybiBjb250ZXh0dWFsTG9nZ2Vyc0J5TmFtZU1hcFtuYW1lXSB8fA0KICAgIAkJCShjb250ZXh0dWFsTG9nZ2Vyc0J5TmFtZU1hcFtuYW1lXSA9IG5ldyBDb250ZXh0dWFsTG9nZ2VyKG1lcmdlKHsgbmFtZTogbmFtZSB9LCBnbG9iYWxMb2dnZXIuY29udGV4dCkpKTsNCiAgICAJfTsNCg0KICAgIAkvLyBDcmVhdGVEZWZhdWx0SGFuZGxlciByZXR1cm5zIGEgaGFuZGxlciBmdW5jdGlvbiB3aGljaCBjYW4gYmUgcGFzc2VkIHRvIGBMb2dnZXIuc2V0SGFuZGxlcigpYCB3aGljaCB3aWxsDQogICAgCS8vIHdyaXRlIHRvIHRoZSB3aW5kb3cncyBjb25zb2xlIG9iamVjdCAoaWYgcHJlc2VudCk7IHRoZSBvcHRpb25hbCBvcHRpb25zIG9iamVjdCBjYW4gYmUgdXNlZCB0byBjdXN0b21pc2UgdGhlDQogICAgCS8vIGZvcm1hdHRlciB1c2VkIHRvIGZvcm1hdCBlYWNoIGxvZyBtZXNzYWdlLg0KICAgIAlMb2dnZXIuY3JlYXRlRGVmYXVsdEhhbmRsZXIgPSBmdW5jdGlvbiAob3B0aW9ucykgew0KICAgIAkJb3B0aW9ucyA9IG9wdGlvbnMgfHwge307DQoNCiAgICAJCW9wdGlvbnMuZm9ybWF0dGVyID0gb3B0aW9ucy5mb3JtYXR0ZXIgfHwgZnVuY3Rpb24gZGVmYXVsdE1lc3NhZ2VGb3JtYXR0ZXIobWVzc2FnZXMsIGNvbnRleHQpIHsNCiAgICAJCQkvLyBQcmVwZW5kIHRoZSBsb2dnZXIncyBuYW1lIHRvIHRoZSBsb2cgbWVzc2FnZSBmb3IgZWFzeSBpZGVudGlmaWNhdGlvbi4NCiAgICAJCQlpZiAoY29udGV4dC5uYW1lKSB7DQogICAgCQkJCW1lc3NhZ2VzLnVuc2hpZnQoIlsiICsgY29udGV4dC5uYW1lICsgIl0iKTsNCiAgICAJCQl9DQogICAgCQl9Ow0KDQogICAgCQkvLyBNYXAgb2YgdGltZXN0YW1wcyBieSB0aW1lciBsYWJlbHMgdXNlZCB0byB0cmFjayBgI3RpbWVgIGFuZCBgI3RpbWVFbmQoKWAgaW52b2NhdGlvbnMgaW4gZW52aXJvbm1lbnRzDQogICAgCQkvLyB0aGF0IGRvbid0IG9mZmVyIGEgbmF0aXZlIGNvbnNvbGUgbWV0aG9kLg0KICAgIAkJdmFyIHRpbWVyU3RhcnRUaW1lQnlMYWJlbE1hcCA9IHt9Ow0KDQogICAgCQkvLyBTdXBwb3J0IGZvciBJRTgrIChhbmQgb3RoZXIsIHNsaWdodGx5IG1vcmUgc2FuZSBlbnZpcm9ubWVudHMpDQogICAgCQl2YXIgaW52b2tlQ29uc29sZU1ldGhvZCA9IGZ1bmN0aW9uIChoZGxyLCBtZXNzYWdlcykgew0KICAgIAkJCUZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseS5jYWxsKGhkbHIsIGNvbnNvbGUsIG1lc3NhZ2VzKTsNCiAgICAJCX07DQoNCiAgICAJCS8vIENoZWNrIGZvciB0aGUgcHJlc2VuY2Ugb2YgYSBsb2dnZXIuDQogICAgCQlpZiAodHlwZW9mIGNvbnNvbGUgPT09ICJ1bmRlZmluZWQiKSB7DQogICAgCQkJcmV0dXJuIGZ1bmN0aW9uICgpIHsgLyogbm8gY29uc29sZSAqLyB9Ow0KICAgIAkJfQ0KDQogICAgCQlyZXR1cm4gZnVuY3Rpb24obWVzc2FnZXMsIGNvbnRleHQpIHsNCiAgICAJCQkvLyBDb252ZXJ0IGFyZ3VtZW50cyBvYmplY3QgdG8gQXJyYXkuDQogICAgCQkJbWVzc2FnZXMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChtZXNzYWdlcyk7DQoNCiAgICAJCQl2YXIgaGRsciA9IGNvbnNvbGUubG9nOw0KICAgIAkJCXZhciB0aW1lckxhYmVsOw0KDQogICAgCQkJaWYgKGNvbnRleHQubGV2ZWwgPT09IExvZ2dlci5USU1FKSB7DQogICAgCQkJCXRpbWVyTGFiZWwgPSAoY29udGV4dC5uYW1lID8gJ1snICsgY29udGV4dC5uYW1lICsgJ10gJyA6ICcnKSArIG1lc3NhZ2VzWzBdOw0KDQogICAgCQkJCWlmIChtZXNzYWdlc1sxXSA9PT0gJ3N0YXJ0Jykgew0KICAgIAkJCQkJaWYgKGNvbnNvbGUudGltZSkgew0KICAgIAkJCQkJCWNvbnNvbGUudGltZSh0aW1lckxhYmVsKTsNCiAgICAJCQkJCX0NCiAgICAJCQkJCWVsc2Ugew0KICAgIAkJCQkJCXRpbWVyU3RhcnRUaW1lQnlMYWJlbE1hcFt0aW1lckxhYmVsXSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpOw0KICAgIAkJCQkJfQ0KICAgIAkJCQl9DQogICAgCQkJCWVsc2Ugew0KICAgIAkJCQkJaWYgKGNvbnNvbGUudGltZUVuZCkgew0KICAgIAkJCQkJCWNvbnNvbGUudGltZUVuZCh0aW1lckxhYmVsKTsNCiAgICAJCQkJCX0NCiAgICAJCQkJCWVsc2Ugew0KICAgIAkJCQkJCWludm9rZUNvbnNvbGVNZXRob2QoaGRsciwgWyB0aW1lckxhYmVsICsgJzogJyArDQogICAgCQkJCQkJCShuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIHRpbWVyU3RhcnRUaW1lQnlMYWJlbE1hcFt0aW1lckxhYmVsXSkgKyAnbXMnIF0pOw0KICAgIAkJCQkJfQ0KICAgIAkJCQl9DQogICAgCQkJfQ0KICAgIAkJCWVsc2Ugew0KICAgIAkJCQkvLyBEZWxlZ2F0ZSB0aHJvdWdoIHRvIGN1c3RvbSB3YXJuL2Vycm9yIGxvZ2dlcnMgaWYgcHJlc2VudCBvbiB0aGUgY29uc29sZS4NCiAgICAJCQkJaWYgKGNvbnRleHQubGV2ZWwgPT09IExvZ2dlci5XQVJOICYmIGNvbnNvbGUud2Fybikgew0KICAgIAkJCQkJaGRsciA9IGNvbnNvbGUud2FybjsNCiAgICAJCQkJfSBlbHNlIGlmIChjb250ZXh0LmxldmVsID09PSBMb2dnZXIuRVJST1IgJiYgY29uc29sZS5lcnJvcikgew0KICAgIAkJCQkJaGRsciA9IGNvbnNvbGUuZXJyb3I7DQogICAgCQkJCX0gZWxzZSBpZiAoY29udGV4dC5sZXZlbCA9PT0gTG9nZ2VyLklORk8gJiYgY29uc29sZS5pbmZvKSB7DQogICAgCQkJCQloZGxyID0gY29uc29sZS5pbmZvOw0KICAgIAkJCQl9IGVsc2UgaWYgKGNvbnRleHQubGV2ZWwgPT09IExvZ2dlci5ERUJVRyAmJiBjb25zb2xlLmRlYnVnKSB7DQogICAgCQkJCQloZGxyID0gY29uc29sZS5kZWJ1ZzsNCiAgICAJCQkJfSBlbHNlIGlmIChjb250ZXh0LmxldmVsID09PSBMb2dnZXIuVFJBQ0UgJiYgY29uc29sZS50cmFjZSkgew0KICAgIAkJCQkJaGRsciA9IGNvbnNvbGUudHJhY2U7DQogICAgCQkJCX0NCg0KICAgIAkJCQlvcHRpb25zLmZvcm1hdHRlcihtZXNzYWdlcywgY29udGV4dCk7DQogICAgCQkJCWludm9rZUNvbnNvbGVNZXRob2QoaGRsciwgbWVzc2FnZXMpOw0KICAgIAkJCX0NCiAgICAJCX07DQogICAgCX07DQoNCiAgICAJLy8gQ29uZmlndXJlIGFuZCBleGFtcGxlIGEgRGVmYXVsdCBpbXBsZW1lbnRhdGlvbiB3aGljaCB3cml0ZXMgdG8gdGhlIGB3aW5kb3cuY29uc29sZWAgKGlmIHByZXNlbnQpLiAgVGhlDQogICAgCS8vIGBvcHRpb25zYCBoYXNoIGNhbiBiZSB1c2VkIHRvIGNvbmZpZ3VyZSB0aGUgZGVmYXVsdCBsb2dMZXZlbCBhbmQgcHJvdmlkZSBhIGN1c3RvbSBtZXNzYWdlIGZvcm1hdHRlci4NCiAgICAJTG9nZ2VyLnVzZURlZmF1bHRzID0gZnVuY3Rpb24ob3B0aW9ucykgew0KICAgIAkJTG9nZ2VyLnNldExldmVsKG9wdGlvbnMgJiYgb3B0aW9ucy5kZWZhdWx0TGV2ZWwgfHwgTG9nZ2VyLkRFQlVHKTsNCiAgICAJCUxvZ2dlci5zZXRIYW5kbGVyKExvZ2dlci5jcmVhdGVEZWZhdWx0SGFuZGxlcihvcHRpb25zKSk7DQogICAgCX07DQoNCiAgICAJLy8gQ3JlYXRlYSBhbiBhbGlhcyB0byB1c2VEZWZhdWx0cyB0byBhdm9pZCByZWFraW5nIGEgcmVhY3QtaG9va3MgcnVsZS4NCiAgICAJTG9nZ2VyLnNldERlZmF1bHRzID0gTG9nZ2VyLnVzZURlZmF1bHRzOw0KDQogICAgCS8vIEV4cG9ydCB0byBwb3B1bGFyIGVudmlyb25tZW50cyBib2lsZXJwbGF0ZS4NCiAgICAJaWYgKG1vZHVsZS5leHBvcnRzKSB7DQogICAgCQltb2R1bGUuZXhwb3J0cyA9IExvZ2dlcjsNCiAgICAJfQ0KICAgIAllbHNlIHsNCiAgICAJCUxvZ2dlci5fcHJldkxvZ2dlciA9IGdsb2JhbC5Mb2dnZXI7DQoNCiAgICAJCUxvZ2dlci5ub0NvbmZsaWN0ID0gZnVuY3Rpb24gKCkgew0KICAgIAkJCWdsb2JhbC5Mb2dnZXIgPSBMb2dnZXIuX3ByZXZMb2dnZXI7DQogICAgCQkJcmV0dXJuIExvZ2dlcjsNCiAgICAJCX07DQoNCiAgICAJCWdsb2JhbC5Mb2dnZXIgPSBMb2dnZXI7DQogICAgCX0NCiAgICB9KGNvbW1vbmpzR2xvYmFsKSk7CiAgICB9KGxvZ2dlcikpOwoKICAgIHZhciBMb2dnZXIgPSBsb2dnZXIuZXhwb3J0czsKCiAgICBMb2dnZXIudXNlRGVmYXVsdHMoew0KICAgICAgICBkZWZhdWx0TGV2ZWw6IExvZ2dlci5ERUJVRywNCiAgICAgICAgZm9ybWF0dGVyOiAobWVzc2FnZXMsIGNvbnRleHQpID0+IHsNCiAgICAgICAgICAgIG1lc3NhZ2VzLnVuc2hpZnQoYFske2NvbnRleHQubmFtZX1dIGApOw0KICAgICAgICB9LA0KICAgIH0pOwoKICAgIHZhciBNZWRpYUZhbWlseTsNCiAgICAoZnVuY3Rpb24gKE1lZGlhRmFtaWx5KSB7DQogICAgICAgIE1lZGlhRmFtaWx5WyJBdWRpbyJdID0gIkFVRElPIjsNCiAgICAgICAgTWVkaWFGYW1pbHlbIlZpZGVvIl0gPSAiVklERU8iOw0KICAgIH0pKE1lZGlhRmFtaWx5IHx8IChNZWRpYUZhbWlseSA9IHt9KSk7DQogICAgdmFyIE1lZGlhQ29udGVudDsNCiAgICAoZnVuY3Rpb24gKE1lZGlhQ29udGVudCkgew0KICAgICAgICBNZWRpYUNvbnRlbnRbIk1haW4iXSA9ICJNQUlOIjsNCiAgICAgICAgTWVkaWFDb250ZW50WyJTbGlkZXMiXSA9ICJTTElERVMiOw0KICAgIH0pKE1lZGlhQ29udGVudCB8fCAoTWVkaWFDb250ZW50ID0ge30pKTsNCiAgICB2YXIgUG9saWN5Ow0KICAgIChmdW5jdGlvbiAoUG9saWN5KSB7DQogICAgICAgIFBvbGljeVsiQWN0aXZlU3BlYWtlciJdID0gImFjdGl2ZS1zcGVha2VyIjsNCiAgICAgICAgUG9saWN5WyJSZWNlaXZlclNlbGVjdGVkIl0gPSAicmVjZWl2ZXItc2VsZWN0ZWQiOw0KICAgIH0pKFBvbGljeSB8fCAoUG9saWN5ID0ge30pKTsNCiAgICB2YXIgTWVkaWFUeXBlOw0KICAgIChmdW5jdGlvbiAoTWVkaWFUeXBlKSB7DQogICAgICAgIE1lZGlhVHlwZVsiVmlkZW9NYWluIl0gPSAiVklERU8tTUFJTiI7DQogICAgICAgIE1lZGlhVHlwZVsiVmlkZW9TbGlkZXMiXSA9ICJWSURFTy1TTElERVMiOw0KICAgICAgICBNZWRpYVR5cGVbIkF1ZGlvTWFpbiJdID0gIkFVRElPLU1BSU4iOw0KICAgICAgICBNZWRpYVR5cGVbIkF1ZGlvU2xpZGVzIl0gPSAiQVVESU8tU0xJREVTIjsNCiAgICB9KShNZWRpYVR5cGUgfHwgKE1lZGlhVHlwZSA9IHt9KSk7CgogICAgdmFyIEptcE1zZ1R5cGU7DQogICAgKGZ1bmN0aW9uIChKbXBNc2dUeXBlKSB7DQogICAgICAgIEptcE1zZ1R5cGVbIk1lZGlhUmVxdWVzdCJdID0gIm1lZGlhUmVxdWVzdCI7DQogICAgICAgIEptcE1zZ1R5cGVbIk1lZGlhUmVxdWVzdEFjayJdID0gIm1lZGlhUmVxdWVzdEFjayI7DQogICAgICAgIEptcE1zZ1R5cGVbIk1lZGlhUmVxdWVzdFN0YXR1cyJdID0gIm1lZGlhUmVxdWVzdFN0YXR1cyI7DQogICAgICAgIEptcE1zZ1R5cGVbIk1lZGlhUmVxdWVzdFN0YXR1c0FjayJdID0gIm1lZGlhUmVxdWVzdFN0YXR1c0FjayI7DQogICAgICAgIEptcE1zZ1R5cGVbIlNvdXJjZUFkdmVydGlzZW1lbnQiXSA9ICJzb3VyY2VBZHZlcnRpc2VtZW50IjsNCiAgICAgICAgSm1wTXNnVHlwZVsiU291cmNlQWR2ZXJ0aXNlbWVudEFjayJdID0gInNvdXJjZUFkdmVydGlzZW1lbnRBY2siOw0KICAgICAgICBKbXBNc2dUeXBlWyJBY3RpdmVTcGVha2VyTm90aWZpY2F0aW9uIl0gPSAiYWN0aXZlU3BlYWtlck5vdGlmaWNhdGlvbiI7DQogICAgfSkoSm1wTXNnVHlwZSB8fCAoSm1wTXNnVHlwZSA9IHt9KSk7DQoKICAgIHZhciBKbXBTZXNzaW9uRXZlbnRzOw0KICAgIChmdW5jdGlvbiAoSm1wU2Vzc2lvbkV2ZW50cykgew0KICAgICAgICBKbXBTZXNzaW9uRXZlbnRzWyJBY3RpdmVTcGVha2VyIl0gPSAiYWN0aXZlLXNwZWFrZXIiOw0KICAgICAgICBKbXBTZXNzaW9uRXZlbnRzWyJNZWRpYVJlcXVlc3RSZWNlaXZlZCJdID0gIm1lZGlhLXJlcXVlc3QtcmVjZWl2ZWQiOw0KICAgICAgICBKbXBTZXNzaW9uRXZlbnRzWyJNZWRpYVJlcXVlc3RTdGF0dXNSZWNlaXZlZCJdID0gIm1lZGlhLXJlcXVlc3Qtc3RhdHVzLXJlY2VpdmVkIjsNCiAgICAgICAgSm1wU2Vzc2lvbkV2ZW50c1siU291cmNlQWR2ZXJ0aXNlbWVudFJlY2VpdmVkIl0gPSAic291cmNlLWFkdmVydGlzZW1lbnQtcmVjZWl2ZWQiOw0KICAgIH0pKEptcFNlc3Npb25FdmVudHMgfHwgKEptcFNlc3Npb25FdmVudHMgPSB7fSkpOwoKICAgIHZhciBFbmNvZGVkVHJhbnNmb3JtVHlwZTsNCiAgICAoZnVuY3Rpb24gKEVuY29kZWRUcmFuc2Zvcm1UeXBlKSB7DQogICAgICAgIEVuY29kZWRUcmFuc2Zvcm1UeXBlWyJBdWRpb0xldmVsTW9uaXRvciJdID0gImF1ZGlvLWxldmVsLW1vbml0b3IiOw0KICAgIH0pKEVuY29kZWRUcmFuc2Zvcm1UeXBlIHx8IChFbmNvZGVkVHJhbnNmb3JtVHlwZSA9IHt9KSk7DQogICAgdmFyIE1haW5Nc2dUeXBlOw0KICAgIChmdW5jdGlvbiAoTWFpbk1zZ1R5cGUpIHsNCiAgICAgICAgTWFpbk1zZ1R5cGVbIkdldE1ldGFkYXRhIl0gPSAiZ2V0LW1ldGFkYXRhIjsNCiAgICAgICAgTWFpbk1zZ1R5cGVbIkNsZWFyTWV0YWRhdGEiXSA9ICJjbGVhci1tZXRhZGF0YSI7DQogICAgfSkoTWFpbk1zZ1R5cGUgfHwgKE1haW5Nc2dUeXBlID0ge30pKTsNCiAgICB2YXIgV29ya2VyTXNnVHlwZTsNCiAgICAoZnVuY3Rpb24gKFdvcmtlck1zZ1R5cGUpIHsNCiAgICAgICAgV29ya2VyTXNnVHlwZVsiUmVzcG9uc2UiXSA9ICJyZXNwb25zZSI7DQogICAgICAgIFdvcmtlck1zZ1R5cGVbIkxvZyJdID0gImxvZyI7DQogICAgfSkoV29ya2VyTXNnVHlwZSB8fCAoV29ya2VyTXNnVHlwZSA9IHt9KSk7CgogICAgY29uc3Qgd29ya2VyTG9nZ2VyID0gew0KICAgICAgICBpbmZvOiAoLi4uYXJncykgPT4gew0KICAgICAgICAgICAgcG9zdE1lc3NhZ2UoeyB0eXBlOiBXb3JrZXJNc2dUeXBlLkxvZywgbGV2ZWw6ICdpbmZvJywgbWVzc2FnZUFyZ3M6IGFyZ3MgfSk7DQogICAgICAgIH0sDQogICAgICAgIHdhcm46ICguLi5hcmdzKSA9PiB7DQogICAgICAgICAgICBwb3N0TWVzc2FnZSh7IHR5cGU6IFdvcmtlck1zZ1R5cGUuTG9nLCBsZXZlbDogJ3dhcm4nLCBtZXNzYWdlQXJnczogYXJncyB9KTsNCiAgICAgICAgfSwNCiAgICAgICAgZXJyb3I6ICguLi5hcmdzKSA9PiB7DQogICAgICAgICAgICBwb3N0TWVzc2FnZSh7IHR5cGU6IFdvcmtlck1zZ1R5cGUuTG9nLCBsZXZlbDogJ2Vycm9yJywgbWVzc2FnZUFyZ3M6IGFyZ3MgfSk7DQogICAgICAgIH0sDQogICAgfTsNCiAgICBjb25zdCBjb2xsZWN0ZWRNZXRhZGF0YSA9IHt9Ow0KICAgIGNvbnN0IGNyZWF0ZUF1ZGlvTGV2ZWxNb25pdG9yVHJhbnNmb3JtID0gKG11bHRpc3RyZWFtQ29ubmVjdGlvbklkLCBlbmNvZGVkVHJhbnNmb3JtSWQpID0+IHsNCiAgICAgICAgaWYgKCEobXVsdGlzdHJlYW1Db25uZWN0aW9uSWQgaW4gY29sbGVjdGVkTWV0YWRhdGEpKSB7DQogICAgICAgICAgICBjb2xsZWN0ZWRNZXRhZGF0YVttdWx0aXN0cmVhbUNvbm5lY3Rpb25JZF0gPSB7DQogICAgICAgICAgICAgICAgW01lZGlhVHlwZS5BdWRpb01haW5dOiB7fSwNCiAgICAgICAgICAgICAgICBbTWVkaWFUeXBlLkF1ZGlvU2xpZGVzXToge30sDQogICAgICAgICAgICAgICAgW01lZGlhVHlwZS5WaWRlb01haW5dOiB7fSwNCiAgICAgICAgICAgICAgICBbTWVkaWFUeXBlLlZpZGVvU2xpZGVzXToge30sDQogICAgICAgICAgICB9Ow0KICAgICAgICB9DQogICAgICAgIGNvbGxlY3RlZE1ldGFkYXRhW211bHRpc3RyZWFtQ29ubmVjdGlvbklkXVtNZWRpYVR5cGUuQXVkaW9NYWluXVtlbmNvZGVkVHJhbnNmb3JtSWRdID0gew0KICAgICAgICAgICAgbWF4QXVkaW9MZXZlbDogdW5kZWZpbmVkLA0KICAgICAgICB9Ow0KICAgICAgICBjb25zdCBjb2xsZWN0ZWRTdHJlYW1NZXRhZGF0YSA9IGNvbGxlY3RlZE1ldGFkYXRhW211bHRpc3RyZWFtQ29ubmVjdGlvbklkXVtNZWRpYVR5cGUuQXVkaW9NYWluXVtlbmNvZGVkVHJhbnNmb3JtSWRdOw0KICAgICAgICB3b3JrZXJMb2dnZXIuaW5mbyhgY3JlYXRpbmcgZW5jb2RlZCB0cmFuc2Zvcm0gZm9yICR7bXVsdGlzdHJlYW1Db25uZWN0aW9uSWR9OiR7ZW5jb2RlZFRyYW5zZm9ybUlkfWApOw0KICAgICAgICByZXR1cm4gbmV3IFRyYW5zZm9ybVN0cmVhbSh7DQogICAgICAgICAgICB0cmFuc2Zvcm06IChlbmNvZGVkRnJhbWUsIGNvbnRyb2xsZXIpID0+IHsNCiAgICAgICAgICAgICAgICBjb25zdCBtZXRhZGF0YSA9IGVuY29kZWRGcmFtZS5nZXRNZXRhZGF0YSgpOw0KICAgICAgICAgICAgICAgIGlmICghY29sbGVjdGVkU3RyZWFtTWV0YWRhdGEubWF4QXVkaW9MZXZlbCB8fA0KICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YS5hdWRpb0xldmVsID4gY29sbGVjdGVkU3RyZWFtTWV0YWRhdGEubWF4QXVkaW9MZXZlbCkgew0KICAgICAgICAgICAgICAgICAgICBjb2xsZWN0ZWRTdHJlYW1NZXRhZGF0YS5tYXhBdWRpb0xldmVsID0gbWV0YWRhdGEuYXVkaW9MZXZlbDsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKGVuY29kZWRGcmFtZSk7DQogICAgICAgICAgICB9LA0KICAgICAgICB9KTsNCiAgICB9Ow0KICAgIGFkZEV2ZW50TGlzdGVuZXIoJ3J0Y3RyYW5zZm9ybScsIChldmVudCkgPT4gew0KICAgICAgICBsZXQgdHJhbnNmb3JtOw0KICAgICAgICBpZiAoIWV2ZW50LnRyYW5zZm9ybWVyLm9wdGlvbnMgfHwgIWV2ZW50LnRyYW5zZm9ybWVyLm9wdGlvbnMudHlwZSkgew0KICAgICAgICAgICAgd29ya2VyTG9nZ2VyLndhcm4oJ21pc3Npbmcgb3IgaW52YWxpZCB0cmFuc2Zvcm1lciBvcHRpb25zPScsIGV2ZW50LnRyYW5zZm9ybWVyLm9wdGlvbnMpOw0KICAgICAgICAgICAgcmV0dXJuOw0KICAgICAgICB9DQogICAgICAgIGNvbnN0IG9wdGlvbnMgPSBldmVudC50cmFuc2Zvcm1lci5vcHRpb25zOw0KICAgICAgICBjb25zdCB7IGVuY29kZWRUcmFuc2Zvcm1JZCwgbXVsdGlzdHJlYW1Db25uZWN0aW9uSWQsIHR5cGUgfSA9IG9wdGlvbnM7DQogICAgICAgIHN3aXRjaCAodHlwZSkgew0KICAgICAgICAgICAgY2FzZSBFbmNvZGVkVHJhbnNmb3JtVHlwZS5BdWRpb0xldmVsTW9uaXRvcjoNCiAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSBjcmVhdGVBdWRpb0xldmVsTW9uaXRvclRyYW5zZm9ybShtdWx0aXN0cmVhbUNvbm5lY3Rpb25JZCwgZW5jb2RlZFRyYW5zZm9ybUlkKTsNCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIGRlZmF1bHQ6DQogICAgICAgICAgICAgICAgd29ya2VyTG9nZ2VyLndhcm4oJ3VuZXhwZWN0ZWQgdHJhbnNmb3JtZXIgdHlwZT0nLCB0eXBlKTsNCiAgICAgICAgfQ0KICAgICAgICBpZiAodHJhbnNmb3JtKSB7DQogICAgICAgICAgICBldmVudC50cmFuc2Zvcm1lci5yZWFkYWJsZS5waXBlVGhyb3VnaCh0cmFuc2Zvcm0pLnBpcGVUbyhldmVudC50cmFuc2Zvcm1lci53cml0YWJsZSk7DQogICAgICAgIH0NCiAgICB9KTsNCiAgICBhZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgKGV2ZW50KSA9PiB7DQogICAgICAgIHZhciBfYSwgX2I7DQogICAgICAgIGNvbnN0IHsgcmVxdWVzdElkIH0gPSBldmVudC5kYXRhOw0KICAgICAgICBjb25zdCB7IHR5cGUgfSA9IGV2ZW50LmRhdGEucGF5bG9hZDsNCiAgICAgICAgbGV0IHJlc3BvbnNlRGF0YTsNCiAgICAgICAgc3dpdGNoICh0eXBlKSB7DQogICAgICAgICAgICBjYXNlIE1haW5Nc2dUeXBlLkdldE1ldGFkYXRhOiB7DQogICAgICAgICAgICAgICAgY29uc3QgeyBtdWx0aXN0cmVhbUNvbm5lY3Rpb25JZCwgbWVkaWFUeXBlLCBlbmNvZGVkVHJhbnNmb3JtSWQgfSA9IGV2ZW50LmRhdGEucGF5bG9hZDsNCiAgICAgICAgICAgICAgICByZXNwb25zZURhdGEgPSAoX2IgPSAoX2EgPSBjb2xsZWN0ZWRNZXRhZGF0YVttdWx0aXN0cmVhbUNvbm5lY3Rpb25JZF0pID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYVttZWRpYVR5cGVdKSA9PT0gbnVsbCB8fCBfYiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2JbZW5jb2RlZFRyYW5zZm9ybUlkXTsNCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGNhc2UgTWFpbk1zZ1R5cGUuQ2xlYXJNZXRhZGF0YTogew0KICAgICAgICAgICAgICAgIGNvbnN0IHsgbXVsdGlzdHJlYW1Db25uZWN0aW9uSWQgfSA9IGV2ZW50LmRhdGEucGF5bG9hZDsNCiAgICAgICAgICAgICAgICBkZWxldGUgY29sbGVjdGVkTWV0YWRhdGFbbXVsdGlzdHJlYW1Db25uZWN0aW9uSWRdOw0KICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZGVmYXVsdDoNCiAgICAgICAgICAgICAgICB3b3JrZXJMb2dnZXIud2FybigndW5leHBlY3RlZCBtZXNzYWdlIHR5cGU9JywgdHlwZSk7DQogICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgIH0NCiAgICAgICAgcG9zdE1lc3NhZ2Uoew0KICAgICAgICAgICAgdHlwZTogV29ya2VyTXNnVHlwZS5SZXNwb25zZSwNCiAgICAgICAgICAgIHJlcXVlc3RJZCwNCiAgICAgICAgICAgIHJlc3BvbnNlRGF0YSwNCiAgICAgICAgfSk7DQogICAgfSk7DQogICAgd29ya2VyTG9nZ2VyLmluZm8oJ1dvcmtlciBmdWxseSBzdGFydGVkLicpOwoKfSkoKTsKCg==', null, false);
|
|
15659
|
+
/* eslint-enable */
|
|
15660
|
+
|
|
15661
|
+
class WorkerManager {
|
|
15662
|
+
constructor() {
|
|
15663
|
+
this.requestsInProgress = new Map();
|
|
15664
|
+
this.lastRequestId = 0;
|
|
15665
|
+
}
|
|
15666
|
+
startWorker() {
|
|
15667
|
+
if (this.worker) {
|
|
15668
|
+
logger.info('Worker is already started');
|
|
15669
|
+
return;
|
|
15670
|
+
}
|
|
15671
|
+
logger.info('Starting worker...');
|
|
15672
|
+
this.worker = new WorkerFactory();
|
|
15673
|
+
this.worker.onmessage = this.messageHandler.bind(this);
|
|
15674
|
+
}
|
|
15675
|
+
stopWorker() {
|
|
15676
|
+
}
|
|
15677
|
+
getWorker() {
|
|
15678
|
+
return this.worker;
|
|
15679
|
+
}
|
|
15680
|
+
messageHandler(event) {
|
|
15681
|
+
const { type } = event.data;
|
|
15682
|
+
switch (type) {
|
|
15683
|
+
case WorkerMsgType.Response: {
|
|
15684
|
+
const { requestId, responseData } = event.data;
|
|
15685
|
+
const request = this.requestsInProgress.get(requestId);
|
|
15686
|
+
if (request) {
|
|
15687
|
+
request.resolve(responseData);
|
|
15688
|
+
this.requestsInProgress.delete(requestId);
|
|
15689
|
+
}
|
|
15690
|
+
else {
|
|
15691
|
+
logger.warn(`received response for unknown requestId: ${requestId}`);
|
|
15692
|
+
}
|
|
15693
|
+
break;
|
|
15694
|
+
}
|
|
15695
|
+
case WorkerMsgType.Log: {
|
|
15696
|
+
const { messageArgs, level } = event.data;
|
|
15697
|
+
switch (level) {
|
|
15698
|
+
case 'info':
|
|
15699
|
+
logger.log(`worker: `, ...messageArgs);
|
|
15700
|
+
break;
|
|
15701
|
+
case 'warn':
|
|
15702
|
+
logger.warn(`worker: `, ...messageArgs);
|
|
15703
|
+
break;
|
|
15704
|
+
case 'error':
|
|
15705
|
+
logger.error(`worker: `, ...messageArgs);
|
|
15706
|
+
break;
|
|
15707
|
+
default:
|
|
15708
|
+
logger.log(`worker (unsupported log level ${level}): `, ...messageArgs);
|
|
15709
|
+
break;
|
|
15710
|
+
}
|
|
15711
|
+
break;
|
|
15712
|
+
}
|
|
15713
|
+
default:
|
|
15714
|
+
logger.warn(`received unknown message type from worker: ${type}`);
|
|
15715
|
+
}
|
|
15716
|
+
}
|
|
15717
|
+
sendRequestToWorker(payload) {
|
|
15718
|
+
return new Promise((resolve, reject) => {
|
|
15719
|
+
if (!this.worker) {
|
|
15720
|
+
reject(new Error('Worker is not started'));
|
|
15721
|
+
return;
|
|
15722
|
+
}
|
|
15723
|
+
const requestId = this.lastRequestId++;
|
|
15724
|
+
this.requestsInProgress.set(requestId, { resolve, reject });
|
|
15725
|
+
this.worker.postMessage({
|
|
15726
|
+
requestId,
|
|
15727
|
+
payload,
|
|
15728
|
+
});
|
|
15729
|
+
});
|
|
15730
|
+
}
|
|
15731
|
+
}
|
|
15732
|
+
WorkerManager.workerManagerInstance = new WorkerManager();
|
|
15733
|
+
function getWorkerManager() {
|
|
15734
|
+
return WorkerManager.workerManagerInstance;
|
|
15735
|
+
}
|
|
15736
|
+
|
|
15457
15737
|
function toMediaStreamTrackKind(mediaType) {
|
|
15458
15738
|
return [MediaType.VideoMain, MediaType.VideoSlides].includes(mediaType)
|
|
15459
15739
|
? MediaStreamTrackKind.Video
|
|
@@ -15496,7 +15776,9 @@ const defaultMultistreamConnectionOptions = {
|
|
|
15496
15776
|
disableAudioMainDtx: true,
|
|
15497
15777
|
preferredStartingBitrateKbps: defaultStartBitrateKbps,
|
|
15498
15778
|
metricsCallback: () => { },
|
|
15779
|
+
enableInboundAudioLevelMonitoring: false,
|
|
15499
15780
|
};
|
|
15781
|
+
let staticIdCounter = 0;
|
|
15500
15782
|
class MultistreamConnection extends EventEmitter$2 {
|
|
15501
15783
|
constructor(userOptions = {}) {
|
|
15502
15784
|
super();
|
|
@@ -15509,9 +15791,11 @@ class MultistreamConnection extends EventEmitter$2 {
|
|
|
15509
15791
|
this.offerAnswerQueue = new AsyncQueue();
|
|
15510
15792
|
this.currentCreateOfferId = 0;
|
|
15511
15793
|
this.metadata = { isMediaBypassEdge: false };
|
|
15794
|
+
this.id = `mc-${staticIdCounter++}`;
|
|
15512
15795
|
this.options = Object.assign(Object.assign({}, defaultMultistreamConnectionOptions), userOptions);
|
|
15513
15796
|
logger.info(`Creating multistream connection with options ${JSON.stringify(this.options)}`);
|
|
15514
15797
|
this.metricsCallback = this.options.metricsCallback;
|
|
15798
|
+
this.startWorkerIfNeeded();
|
|
15515
15799
|
this.initializePeerConnection();
|
|
15516
15800
|
this.overuseStateManager = new OveruseStateManager((overuseState) => this.overuseUpdateCallback(overuseState));
|
|
15517
15801
|
this.overuseStateManager.start();
|
|
@@ -15525,6 +15809,15 @@ class MultistreamConnection extends EventEmitter$2 {
|
|
|
15525
15809
|
this.createSendTransceiver(MediaType.VideoSlides, slidesSceneId, videoSlidesEncodingOptions);
|
|
15526
15810
|
this.createSendTransceiver(MediaType.AudioSlides, slidesSceneId);
|
|
15527
15811
|
}
|
|
15812
|
+
startWorkerIfNeeded() {
|
|
15813
|
+
if (this.options.enableInboundAudioLevelMonitoring) {
|
|
15814
|
+
if (WebCapabilities.supportsEncodedStreamTransforms() !== CapabilityState.CAPABLE) {
|
|
15815
|
+
logger.warn('RTCRtpScriptTransform is not supported in this browser, skipping inbound audio level monitoring.');
|
|
15816
|
+
return;
|
|
15817
|
+
}
|
|
15818
|
+
getWorkerManager().startWorker();
|
|
15819
|
+
}
|
|
15820
|
+
}
|
|
15528
15821
|
initializePeerConnection() {
|
|
15529
15822
|
this.pc = new PeerConnection({
|
|
15530
15823
|
iceServers: this.options.iceServers,
|
|
@@ -15848,6 +16141,10 @@ SCTP Max Message Size: ${maxMessageSize}`);
|
|
|
15848
16141
|
});
|
|
15849
16142
|
this.jmpSessions.forEach((jmpSession) => jmpSession.close());
|
|
15850
16143
|
this.pc.close();
|
|
16144
|
+
getWorkerManager().sendRequestToWorker({
|
|
16145
|
+
type: MainMsgType.ClearMetadata,
|
|
16146
|
+
multistreamConnectionId: this.id,
|
|
16147
|
+
});
|
|
15851
16148
|
}
|
|
15852
16149
|
sendMediaRequestStatus(mediaType) {
|
|
15853
16150
|
var _a;
|
|
@@ -15919,6 +16216,7 @@ SCTP Max Message Size: ${maxMessageSize}`);
|
|
|
15919
16216
|
direction: 'recvonly',
|
|
15920
16217
|
});
|
|
15921
16218
|
const mid = this.midPredictor.getNextMid(mediaType);
|
|
16219
|
+
const doAudioLevelMonitoring = this.options.enableInboundAudioLevelMonitoring && mediaType === MediaType.AudioMain;
|
|
15922
16220
|
const munger = new IngressSdpMunger();
|
|
15923
16221
|
const recvOnlyTransceiver = new ReceiveOnlyTransceiver({
|
|
15924
16222
|
rtcRtpTransceiver,
|
|
@@ -15926,6 +16224,23 @@ SCTP Max Message Size: ${maxMessageSize}`);
|
|
|
15926
16224
|
mediaType,
|
|
15927
16225
|
munger,
|
|
15928
16226
|
});
|
|
16227
|
+
if (doAudioLevelMonitoring) {
|
|
16228
|
+
const encodedTransformId = `INBOUND-${mediaType}-${mid}`;
|
|
16229
|
+
try {
|
|
16230
|
+
this.setupEncodedTransform(rtcRtpTransceiver.receiver, encodedTransformId, EncodedTransformType.AudioLevelMonitor);
|
|
16231
|
+
recvOnlyTransceiver.setEncodedStreamMetadataCallback(() => __awaiter(this, void 0, void 0, function* () {
|
|
16232
|
+
return getWorkerManager().sendRequestToWorker({
|
|
16233
|
+
type: MainMsgType.GetMetadata,
|
|
16234
|
+
mediaType,
|
|
16235
|
+
encodedTransformId,
|
|
16236
|
+
multistreamConnectionId: this.id,
|
|
16237
|
+
});
|
|
16238
|
+
}));
|
|
16239
|
+
}
|
|
16240
|
+
catch (e) {
|
|
16241
|
+
logger.warn(`Failed to setup encoded transform for ${encodedTransformId} audio level monitoring: ${e}`);
|
|
16242
|
+
}
|
|
16243
|
+
}
|
|
15929
16244
|
if (getMediaFamily(mediaType) === MediaFamily.Video) {
|
|
15930
16245
|
recvOnlyTransceiver.setCodecParameters({
|
|
15931
16246
|
'sps-pps-idr-in-keyframe': '1',
|
|
@@ -16414,6 +16729,21 @@ SCTP Max Message Size: ${maxMessageSize}`);
|
|
|
16414
16729
|
videoSlides: this.getCsiByMediaType(MediaType.VideoSlides),
|
|
16415
16730
|
};
|
|
16416
16731
|
}
|
|
16732
|
+
setupEncodedTransform(receiverOrSender, id, type) {
|
|
16733
|
+
if (WebCapabilities.supportsEncodedStreamTransforms() !== CapabilityState.CAPABLE) {
|
|
16734
|
+
throw new Error('encoded stream transport is not supported in this browser.');
|
|
16735
|
+
}
|
|
16736
|
+
if (!getWorkerManager().getWorker()) {
|
|
16737
|
+
throw new Error('no worker available for encoded stream transforms.');
|
|
16738
|
+
}
|
|
16739
|
+
const options = {
|
|
16740
|
+
type,
|
|
16741
|
+
encodedTransformId: id,
|
|
16742
|
+
multistreamConnectionId: this.id,
|
|
16743
|
+
};
|
|
16744
|
+
receiverOrSender.transform = new window.RTCRtpScriptTransform(getWorkerManager().getWorker(), options);
|
|
16745
|
+
logger.log(`started "${type}" transform with id=${id} on connection ${this.id}`);
|
|
16746
|
+
}
|
|
16417
16747
|
}
|
|
16418
16748
|
|
|
16419
16749
|
class StreamRequest {
|